From: Slava Barinov Date: Tue, 4 Dec 2018 14:23:42 +0000 (+0300) Subject: Imported Upstream version 5.18.16 X-Git-Tag: upstream/5.18.16^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=38b9aa4ec4c81e288b4a6606a064bd4eb04c69be;p=platform%2Fupstream%2Fautogen.git Imported Upstream version 5.18.16 --- diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..594d24f --- /dev/null +++ b/AUTHORS @@ -0,0 +1,36 @@ +Original authors are also attributed in each source file... + +Bruce Korb: + +agen5/*, getdefs/*, autoopts/*, columns/*, rehacked compat/pathfind.c +to be SVR4 compatible. reworked compat/strsignal to use a shell script +to extract the local information and generate a static version. (It +uses autogen, so a generated version must be distributed also. :) + +Bruce Korb and Gary V. Vaughan: +In the directory config, regcomp.m4 and bootstrap. + +Gary V. Vaughan: +changes throughout to aid portability of C code. +wrote the autoconf files, Makefile.am and configure.in. +in the directory config; ctime.m4, make.m4 and release. +in the directory compat; basename.c, dirname.c, compat.h, + pathfind.c, libgen.h +in the directory tests; almost *.test +snprintfv/* + +Greg Harvey: +agen5/schemedef.scm, enabling Scheme syntax definitions + +Brian Fox, Chet Ramey: +sections of files borrowed from bash-2.0 incorporated into +compat/compat.h; (posixstat.h, posixjmp.h) + +Fred Fish, Gary V. Vaughan and Bruce Korb: +in the directory compat; strsignal.c + +James R. Van Zandt: +The Debianization of AutoGen + +Daniel Schregenberger +More GNU-ish usage text for AutoOpts. diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..94a9ed0 --- /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/ChangeLog b/ChangeLog new file mode 100644 index 0000000..e69de29 diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..98fa4fd --- /dev/null +++ b/INSTALL @@ -0,0 +1,47 @@ +This is the build instructions for autogen. If you're viewing it with +Emacs, try doing Ctl-C Ctl-t and browsing through the outline headers. +Ctl-C Ctl-a will unfold them again. + +** Building from a release tarball + +If you have downloaded a release tarball, + + configure; make; make install + +should do it. The usual configure options are available, notably inckuding +the --prefix option. The generated Makefile inckludes both "install" and +"uninstall" instructions. + +** Building from a repository clone + +To build from a repository clone, you must first have gperf (the GNU +Perfect Hash Function Generator) and gnulib (the GNU +Portability Library) installed. Then run + + bootstrap + +in the top-level directory. Note that for this to work, a precompiled +autogen binary needs to be in your $PATH. + +[To be continued]] + +** Known issues + +1. Whatever's going on with local-install + +2. autogen requiring itself to build is a problem we need to solve. + The standard way to solve this is check in its build products, + then rebuild those only when the *.def or *tpl files change. Of + course the INSTALL file needs to explicit about which stuff is + generated + +3. I'm going to want an easy, documented way to produce a *static* + build outogen so I can experiment with NTP builds without + colliding with an older shared library. bkorb replies: + '"cd $top_builddir/agen5 ; rm autogen ; make LDFLAGS=-static" + will do what you ask.'. + +Local variables: +mode: outline +paragraph-separate: "[ ]*$" +end: diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..3b0c433 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,95 @@ +## -*- Mode: Makefile -*- +## Makefile.am --- process this file with automake to produce Makefile.in +## +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen 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. +## +## AutoGen is distributed in the hope that 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 . + +ACLOCAL_AMFLAGS = -I config + +SUBDIRS = compat snprintfv autoopts agen5 + +if DO_SHELL_CMDS +if HAVE_XML_LIB +SUBDIRS += columns getdefs xml2ag doc pkg +else +SUBDIRS += columns getdefs pkg +endif +else + +## Without shell commands, you cannot build docs or packages and the +## columns and getdefs commands are unworkable. +## +if HAVE_XML_LIB +SUBDIRS += xml2ag +endif +endif + +pkgdata_DATA = config/liboptschk.m4 +misc_extra = \ + VERSION autoopts/gettext.h \ + autoopts/parse-duration.c autoopts/parse-duration.h \ + config/ag_macros.m4 config/bootstrap \ + config/bootstrap.local config/bootstrap.shlib \ + config/config.rpath config/gnulib-cache.m4 \ + config/gnulib-cache.m4 config/gnulib-comp.m4 \ + config/guile.m4 config/install-defs.sh \ + config/lib-link.m4 config/libopts.m4 \ + config/liboptschk.m4 config/mk-shdefs.in \ + config/pkg.m4 config/snprintfv.m4 \ + config/unlocked-io.m4 build-aux/run-ag.sh + +EXTRA_DIST = $(misc_extra) $(pkgdata_DATA) +DISTCLEANFILES = stamp-h + +distcleancheck_listfiles = \ + find -type f -exec 'test -f $(srcdir)/{} || echo {} ;' + +configure : VERSION + +pkg : package +package : + cd pkg && $(MAKE) $@ pkgtype="$(pkgtype)" + +docs : gnudocs doxydocs +gnudoc : gnudocs +gnudocs : + cd doc && $(MAKE) gnudocs + +doxydocs : + test -f Doxyfile || cp ~/.Doxyfile ./Doxyfile ; \ + doxygen + +usage-txt.po: gettext +gettext : + cd autoopts && $(MAKE) usage-txt.po + +all : shdefs +shdefs : $(top_builddir)/config/shdefs +$(top_builddir)/config/shdefs: $(top_builddir)/config/mk-shdefs + $(SHELL) $< $@ + +if HAVE_XML_LIB +release : distcheck +else +release : + echo "Distributions cannot be made with a partial build" >&2 + exit 1 +endif + +.NOTPARALLEL: +.PHONY: all pkg package docs gnudoc gnudocs shdefs doxydocs gettext usage-txt.po + +## Makefile.am ends here diff --git a/Makefile.in b/Makefile.in new file mode 100644 index 0000000..68bdd99 --- /dev/null +++ b/Makefile.in @@ -0,0 +1,1007 @@ +# Makefile.in generated by automake 1.16.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2018 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +@DO_SHELL_CMDS_TRUE@@HAVE_XML_LIB_TRUE@am__append_1 = columns getdefs xml2ag doc pkg +@DO_SHELL_CMDS_TRUE@@HAVE_XML_LIB_FALSE@am__append_2 = columns getdefs pkg +@DO_SHELL_CMDS_FALSE@@HAVE_XML_LIB_TRUE@am__append_3 = xml2ag +subdir = . +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/config/ag_macros.m4 \ + $(top_srcdir)/config/asm-underscore.m4 \ + $(top_srcdir)/config/extensions.m4 \ + $(top_srcdir)/config/guile.m4 \ + $(top_srcdir)/config/host-cpu-c-abi.m4 \ + $(top_srcdir)/config/lib-ld.m4 \ + $(top_srcdir)/config/lib-link.m4 \ + $(top_srcdir)/config/lib-prefix.m4 \ + $(top_srcdir)/config/libopts.m4 \ + $(top_srcdir)/config/libtool.m4 \ + $(top_srcdir)/config/ltoptions.m4 \ + $(top_srcdir)/config/ltsugar.m4 \ + $(top_srcdir)/config/ltversion.m4 \ + $(top_srcdir)/config/lt~obsolete.m4 \ + $(top_srcdir)/config/onceonly.m4 $(top_srcdir)/config/pkg.m4 \ + $(top_srcdir)/config/snprintfv.m4 \ + $(top_srcdir)/config/stdnoreturn.m4 \ + $(top_srcdir)/config/unlocked-io.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \ + $(am__configure_deps) $(am__DIST_COMMON) +am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ + configure.lineno config.status.lineno +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = config.h +CONFIG_CLEAN_FILES = autoopts/tpl/tpl-config.tlib config/mk-shdefs +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(pkgdatadir)" +DATA = $(pkgdata_DATA) +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ + cscope distdir distdir-am dist dist-all distcheck +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \ + $(LISP)config-h.in +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +CSCOPE = cscope +DIST_SUBDIRS = compat snprintfv autoopts agen5 columns getdefs xml2ag \ + doc pkg +am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config-h.in \ + $(top_srcdir)/autoopts/tpl/tpl-config-tlib.in \ + $(top_srcdir)/config/compile $(top_srcdir)/config/config.guess \ + $(top_srcdir)/config/config.rpath \ + $(top_srcdir)/config/config.sub \ + $(top_srcdir)/config/install-sh $(top_srcdir)/config/ltmain.sh \ + $(top_srcdir)/config/missing $(top_srcdir)/config/mk-shdefs.in \ + AUTHORS COPYING ChangeLog INSTALL NEWS README THANKS TODO \ + config/compile config/config.guess config/config.rpath \ + config/config.sub config/install-sh config/ltmain.sh \ + config/missing +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) +am__remove_distdir = \ + if test -d "$(distdir)"; then \ + find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ + && rm -rf "$(distdir)" \ + || { sleep 5 && rm -rf "$(distdir)"; }; \ + else :; fi +am__post_remove_distdir = $(am__remove_distdir) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +DIST_ARCHIVES = $(distdir).tar.gz $(distdir).tar.xz +GZIP_ENV = --best +DIST_TARGETS = dist-xz dist-gzip +distuninstallcheck_listfiles = find . -type f -print +am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ + | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' +ACLOCAL = @ACLOCAL@ +AGEN5_TESTS = @AGEN5_TESTS@ +AG_LDFLAGS = @AG_LDFLAGS@ +AG_MAJOR_VERSION = @AG_MAJOR_VERSION@ +AG_MINOR_VERSION = @AG_MINOR_VERSION@ +AG_STATIC_AUTOGEN = @AG_STATIC_AUTOGEN@ +AG_TIMEOUT = @AG_TIMEOUT@ +AG_VERSION = @AG_VERSION@ +AG_XML2 = @AG_XML2@ +AGexe = @AGexe@ +AGnam = @AGnam@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AO_AGE = @AO_AGE@ +AO_CURRENT = @AO_CURRENT@ +AO_REVISION = @AO_REVISION@ +AO_TEMPLATE_VERSION = @AO_TEMPLATE_VERSION@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CLexe = @CLexe@ +CLnam = @CLnam@ +CONFIG_SHELL = @CONFIG_SHELL@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEBUG_ENABLED = @DEBUG_ENABLED@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +DYNAMIC_AG = @DYNAMIC_AG@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ENABLE_STATIC = @ENABLE_STATIC@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GDexe = @GDexe@ +GDnam = @GDnam@ +GO_AGE = @GO_AGE@ +GO_CURRENT = @GO_CURRENT@ +GO_REVISION = @GO_REVISION@ +GREP = @GREP@ +GUILE_CFLAGS = @GUILE_CFLAGS@ +GUILE_EFFECTIVE_VERSION = @GUILE_EFFECTIVE_VERSION@ +GUILE_LDFLAGS = @GUILE_LDFLAGS@ +GUILE_LIBS = @GUILE_LIBS@ +GUILE_LTLIBS = @GUILE_LTLIBS@ +HOST_CPU = @HOST_CPU@ +HOST_CPU_C_ABI = @HOST_CPU_C_ABI@ +INCLIST = @INCLIST@ +INCSNPRINTFV = @INCSNPRINTFV@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSNPRINTFV = @LIBSNPRINTFV@ +LIBTOOL = @LIBTOOL@ +LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ +LIBXML2_LIBS = @LIBXML2_LIBS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +M4_SRC = @M4_SRC@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPTS_TESTDIR = @OPTS_TESTDIR@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POSIX_SHELL = @POSIX_SHELL@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STDNORETURN_H = @STDNORETURN_H@ +STRIP = @STRIP@ +TEXI2HTML = @TEXI2HTML@ +VERSION = @VERSION@ +WARN_CFLAGS = @WARN_CFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_aux_dir = @ac_aux_dir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +ACLOCAL_AMFLAGS = -I config +SUBDIRS = compat snprintfv autoopts agen5 $(am__append_1) \ + $(am__append_2) $(am__append_3) +pkgdata_DATA = config/liboptschk.m4 +misc_extra = \ + VERSION autoopts/gettext.h \ + autoopts/parse-duration.c autoopts/parse-duration.h \ + config/ag_macros.m4 config/bootstrap \ + config/bootstrap.local config/bootstrap.shlib \ + config/config.rpath config/gnulib-cache.m4 \ + config/gnulib-cache.m4 config/gnulib-comp.m4 \ + config/guile.m4 config/install-defs.sh \ + config/lib-link.m4 config/libopts.m4 \ + config/liboptschk.m4 config/mk-shdefs.in \ + config/pkg.m4 config/snprintfv.m4 \ + config/unlocked-io.m4 build-aux/run-ag.sh + +EXTRA_DIST = $(misc_extra) $(pkgdata_DATA) +DISTCLEANFILES = stamp-h +distcleancheck_listfiles = \ + find -type f -exec 'test -f $(srcdir)/{} || echo {} ;' + +all: config.h + $(MAKE) $(AM_MAKEFLAGS) all-recursive + +.SUFFIXES: +am--refresh: Makefile + @: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + echo ' cd $(srcdir) && $(AUTOMAKE) --gnu'; \ + $(am__cd) $(srcdir) && $(AUTOMAKE) --gnu \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + echo ' $(SHELL) ./config.status'; \ + $(SHELL) ./config.status;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck + +$(top_srcdir)/configure: $(am__configure_deps) + $(am__cd) $(srcdir) && $(AUTOCONF) +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) +$(am__aclocal_m4_deps): + +config.h: stamp-h1 + @test -f $@ || rm -f stamp-h1 + @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1 + +stamp-h1: $(srcdir)/config-h.in $(top_builddir)/config.status + @rm -f stamp-h1 + cd $(top_builddir) && $(SHELL) ./config.status config.h +$(srcdir)/config-h.in: $(am__configure_deps) + ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) + rm -f stamp-h1 + touch $@ + +distclean-hdr: + -rm -f config.h stamp-h1 +autoopts/tpl/tpl-config.tlib: $(top_builddir)/config.status $(top_srcdir)/autoopts/tpl/tpl-config-tlib.in + cd $(top_builddir) && $(SHELL) ./config.status $@ +config/mk-shdefs: $(top_builddir)/config.status $(top_srcdir)/config/mk-shdefs.in + cd $(top_builddir) && $(SHELL) ./config.status $@ + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool config.lt +install-pkgdataDATA: $(pkgdata_DATA) + @$(NORMAL_INSTALL) + @list='$(pkgdata_DATA)'; test -n "$(pkgdatadir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkgdatadir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkgdatadir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgdatadir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgdatadir)" || exit $$?; \ + done + +uninstall-pkgdataDATA: + @$(NORMAL_UNINSTALL) + @list='$(pkgdata_DATA)'; test -n "$(pkgdatadir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(pkgdatadir)'; $(am__uninstall_files_from_dir) + +# This directory's subdirectories are mostly independent; you can cd +# into them and run 'make' without going through this Makefile. +# To change the values of 'make' variables: instead of editing Makefiles, +# (1) if the variable is set in 'config.status', edit 'config.status' +# (which will cause the Makefiles to be regenerated when you run 'make'); +# (2) otherwise, pass the desired values on the 'make' command line. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-recursive + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscope: cscope.files + test ! -s cscope.files \ + || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) +clean-cscope: + -rm -f cscope.files +cscope.files: clean-cscope cscopelist +cscopelist: cscopelist-recursive + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + -rm -f cscope.out cscope.in.out cscope.po.out cscope.files + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @case `sed 15q $(srcdir)/NEWS` in \ + *"$(VERSION)"*) : ;; \ + *) \ + echo "NEWS not updated; not releasing" 1>&2; \ + exit 1;; \ + esac + $(am__remove_distdir) + test -d "$(distdir)" || mkdir "$(distdir)" + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done + -test -n "$(am__skip_mode_fix)" \ + || find "$(distdir)" -type d ! -perm -755 \ + -exec chmod u+rwx,go+rx {} \; -o \ + ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ + || chmod -R a+r "$(distdir)" +dist-gzip: distdir + tardir=$(distdir) && $(am__tar) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).tar.gz + $(am__post_remove_distdir) + +dist-bzip2: distdir + tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 + $(am__post_remove_distdir) + +dist-lzip: distdir + tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz + $(am__post_remove_distdir) +dist-xz: distdir + tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz + $(am__post_remove_distdir) + +dist-tarZ: distdir + @echo WARNING: "Support for distribution archives compressed with" \ + "legacy program 'compress' is deprecated." >&2 + @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 + tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z + $(am__post_remove_distdir) + +dist-shar: distdir + @echo WARNING: "Support for shar distribution archives is" \ + "deprecated." >&2 + @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 + shar $(distdir) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).shar.gz + $(am__post_remove_distdir) + +dist-zip: distdir + -rm -f $(distdir).zip + zip -rq $(distdir).zip $(distdir) + $(am__post_remove_distdir) + +dist dist-all: + $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' + $(am__post_remove_distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + case '$(DIST_ARCHIVES)' in \ + *.tar.gz*) \ + eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).tar.gz | $(am__untar) ;;\ + *.tar.bz2*) \ + bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ + *.tar.lz*) \ + lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ + *.tar.xz*) \ + xz -dc $(distdir).tar.xz | $(am__untar) ;;\ + *.tar.Z*) \ + uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ + *.shar.gz*) \ + eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\ + *.zip*) \ + unzip $(distdir).zip ;;\ + esac + chmod -R a-w $(distdir) + chmod u+w $(distdir) + mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst + chmod a-w $(distdir) + test -d $(distdir)/_build || exit 0; \ + dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ + && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ + && am__cwd=`pwd` \ + && $(am__cd) $(distdir)/_build/sub \ + && ../../configure \ + $(AM_DISTCHECK_CONFIGURE_FLAGS) \ + $(DISTCHECK_CONFIGURE_FLAGS) \ + --srcdir=../.. --prefix="$$dc_install_base" \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) dvi \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ + distuninstallcheck \ + && chmod -R a-w "$$dc_install_base" \ + && ({ \ + (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ + distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ + } || { rm -rf "$$dc_destdir"; exit 1; }) \ + && rm -rf "$$dc_destdir" \ + && $(MAKE) $(AM_MAKEFLAGS) dist \ + && rm -rf $(DIST_ARCHIVES) \ + && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ + && cd "$$am__cwd" \ + || exit 1 + $(am__post_remove_distdir) + @(echo "$(distdir) archives ready for distribution: "; \ + list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ + sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' +distuninstallcheck: + @test -n '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: trying to run $@ with an empty' \ + '$$(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + $(am__cd) '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left after uninstall:" ; \ + if test -n "$(DESTDIR)"; then \ + echo " (check DESTDIR support)"; \ + fi ; \ + $(distuninstallcheck_listfiles) ; \ + exit 1; } >&2 +distcleancheck: distclean + @if test '$(srcdir)' = . ; then \ + echo "ERROR: distcleancheck can only run from a VPATH build" ; \ + exit 1 ; \ + fi + @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left in build directory after distclean:" ; \ + $(distcleancheck_listfiles) ; \ + exit 1; } >&2 +check-am: all-am +check: check-recursive +all-am: Makefile $(DATA) config.h +installdirs: installdirs-recursive +installdirs-am: + for dir in "$(DESTDIR)$(pkgdatadir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-hdr \ + distclean-libtool distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: install-pkgdataDATA + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf $(top_srcdir)/autom4te.cache + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: uninstall-pkgdataDATA + +.MAKE: $(am__recursive_targets) all install-am install-strip + +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ + am--refresh check check-am clean clean-cscope clean-generic \ + clean-libtool cscope cscopelist-am ctags ctags-am dist \ + dist-all dist-bzip2 dist-gzip dist-lzip dist-shar dist-tarZ \ + dist-xz dist-zip distcheck distclean distclean-generic \ + distclean-hdr distclean-libtool distclean-tags distcleancheck \ + distdir distuninstallcheck dvi dvi-am html html-am info \ + info-am install install-am install-data install-data-am \ + install-dvi install-dvi-am install-exec install-exec-am \ + install-html install-html-am install-info install-info-am \ + install-man install-pdf install-pdf-am install-pkgdataDATA \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs installdirs-am maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-pkgdataDATA + +.PRECIOUS: Makefile + + +configure : VERSION + +pkg : package +package : + cd pkg && $(MAKE) $@ pkgtype="$(pkgtype)" + +docs : gnudocs doxydocs +gnudoc : gnudocs +gnudocs : + cd doc && $(MAKE) gnudocs + +doxydocs : + test -f Doxyfile || cp ~/.Doxyfile ./Doxyfile ; \ + doxygen + +usage-txt.po: gettext +gettext : + cd autoopts && $(MAKE) usage-txt.po + +all : shdefs +shdefs : $(top_builddir)/config/shdefs +$(top_builddir)/config/shdefs: $(top_builddir)/config/mk-shdefs + $(SHELL) $< $@ + +@HAVE_XML_LIB_TRUE@release : distcheck +@HAVE_XML_LIB_FALSE@release : +@HAVE_XML_LIB_FALSE@ echo "Distributions cannot be made with a partial build" >&2 +@HAVE_XML_LIB_FALSE@ exit 1 + +.NOTPARALLEL: +.PHONY: all pkg package docs gnudoc gnudocs shdefs doxydocs gettext usage-txt.po + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/NEWS b/NEWS new file mode 100644 index 0000000..f67e59a --- /dev/null +++ b/NEWS @@ -0,0 +1,6 @@ +New in 5.18.16 - August 2018 + +Bootstrap and configure code has been revamped to work with the +new flavors of the autotools. + +Guile 2.2 works like 2.0, so accept it, too. diff --git a/README b/README new file mode 100644 index 0000000..a2ba45e --- /dev/null +++ b/README @@ -0,0 +1,115 @@ +This is AutoGen, an automated text file generator. It was inspired out of +frustration and hassle with maintaining syncronization between option flag +lists, global variables and usage information. The desire for more than +#define macros came about when it became apparent that macros alone were +insufficient for reducing the maintenance into a single option list. The +impetus to actually start something finally came when I had to maintain a +large callout procedure table and associated lookup tables. + +Rev 1 of this utility was a set of #define macro expansions. +Rev 2 was a shell script that sort-of did a prototype. + Much better than just #defines, but still clearly lacking. +Rev 3 had a very kludgy macro definition syntax. +Rev 4 a reworking and simplification of the declarations +Rev 5 the addition of Guile expression processing + +Mailing lists can be found on SourceForge: + + autogen-users@lists.sourceforge.net + + +*** AutoGen requires: *** + +1. POSIX regular expression library. If not available by default, use + the --with-regex-* options to specify how to find, use and link to it. +2. an ANSI C compiler +3. The Guile version of a Scheme processing language. + + +*** Installation note: *** + +AutoGen does *NOT* contain any compiled-in configuration information. +Therefore, in order to use the templates that come bundled with it, +you must tell AutoGen how to find those templates when you build +applications that use those templates. + +1. by doing nothing. If you do not alter the default data directory, + AutoGen will search for templates in the directory ../share/autogen, + relative to the executable directory. That should generally work. + +2. You can tell AutoGen where to look with an environment variable: + + export AUTOGEN_TEMPL_DIR=$prefix/share/autogen + +3. You can use an RC file: + + autogen -L $prefix/share/autogen --save=$HOME/.autogenrc + +4. If you have an old Guile library, you will find that its error reporting + does not work so well. Consequently, you will see "make check" failures + in the output text where you would expect to find file name and line + number references for the invalid input. Please upgrade your Guile lib. + +5. You can build and install AutoGen, ensuring you have the + automake/autoconf/libtool-s needed, and then editing + agen5/opts.def thus: + + echo "homerc = $prefix/share/autogen;" >> agen5/opts.def + +and then rebuilding AutoGen. However, if you do this latter +"fix", you will have an immobile product. I hate that, others +like it. It is, however, up to you. + + +*** Build note: *** + +Sometimes, configure believes it has done a good job when it really hasn't. +It is possible to configure a system in such a way that the Guile headers and +libguile are linked against correctly, but the loader cannot find +libguile.so.xxx. This is because GCC will silently find the library for +linking, but not set the library dependencies correctly. The consequence is +that the configure script believes that standard links will produce working +executables. It won't. The simplest solution is: + + .../configure --disable-shared + +the best solution is to examine the output of ``guile-config link'', +duplicate the ``-L/path/to/lib'' argument, but changing the "-L" to +"-R" or "-Wl,-rpath," or "-rpath" or whatever it happens to be that +works for your platform, and hand that off to configure as the argument +to ``--with-libguile-link''. "libtool" won't fix it and it's too hard +for me. Sorry. Anyway, for example, assume: + + guile-config link + +produces: + + -L/opt/sfw/lib -lguile -lm + +now run configure as follows: + + .../configure \ + --with-libguile-link='-L/opt/sfw/lib -lguile -lm -R/opt/sfw/lib' + +Isn't that special? + + +*** Bootstrap note: *** + +I have some private tools referenced in the various bootstrap scripts. +Unless you have these tools, bootstrap won't work for you. I intend +to fix this as time permits. Meanwhile, there is also a tarball in CVS +of all the bootstrap-generated files: + noag-boot.sh + +*** Licensing: *** + + autogen is under GPL, but that does not cause the output produced by + autogen to be under GPL. The reason is that the output contains next to + nothing that comes directly from autogen's source code. Thus, the output + is not a "derivative work" of autogen (in the sense of U.S.@: copyright + law). The output is primarily a derivative of the input templates. + + On the other hand, the output produced by autogen contains essentially all + of the input template. Therefore the output is under the same license, + with the same copyright holder, as the input that was passed to autogen. diff --git a/THANKS b/THANKS new file mode 100644 index 0000000..c23af9f --- /dev/null +++ b/THANKS @@ -0,0 +1,16 @@ +AutoGen would not be what it is without the invaluable help of +many people: + +Everybody who was kind enough to spend time testing it, +using it with the GCC fixincludes and reporting bugs. + +The following people made especially gracious contributions of their +time and energy in helping to track down bugs, port to new systems, +and generally assist in the maintainership process: + +Gary V. Vaughan +Robert Lipe +Alexandre Oliva +James R. Van Zandt +Thomas Steudten +Harlan Stenn diff --git a/TODO b/TODO new file mode 100644 index 0000000..1e022b6 --- /dev/null +++ b/TODO @@ -0,0 +1,4 @@ +# -*- Mode: Outline -*- + +* add test for new license. +* add manywarnings gnulib module diff --git a/VERSION b/VERSION new file mode 100644 index 0000000..ffc7bf0 --- /dev/null +++ b/VERSION @@ -0,0 +1,69 @@ +#! /bin/echo this_should_be_sourced +# -*- Mode: sh -*- +# VERSION --- Set version info for GNU-ish tool use + +MAINTAINER='Bruce Korb ' + +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen 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. +## +## AutoGen is distributed in the hope that 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 . + +AG_MAJOR_VERSION=5 +AG_MINOR_VERSION=18 +AG_REVISION=$AG_MAJOR_VERSION.$AG_MINOR_VERSION +AG_PATCHLEVEL=.16 +AG_VERSION=$AG_REVISION$AG_PATCHLEVEL + +# AutoOpts versioning: +# +# AO_CURRENT represents the number of visible changes to the interface +# AO_REVISION represents the number of times the library has been +# modified with an unchanged interface. +# AO_AGE represents the number of older revisions the current library +# is capable of handling. +# +AO_LIBRARY=libopts.la +AO_CURRENT=42 +AO_REVISION=1 +AO_AGE=17 + +# For automake +# +VERSION=${AG_VERSION} +PACKAGE='GNU AutoGen' +EADDR=autogen-users@lists.sourceforge.net + +# Display version numbers banner for my sanity! +# +AO_SOVERS=${AO_CURRENT}:${AO_REVISION}:${AO_AGE} +AO_SONAME=${AO_LIBRARY}-${AO_SOVERS} +w=`expr \( ${COLUMNS:-80} - 1 \) / 2` +h=`expr $w \* 2` +h=`printf "*%${h}s" '' | sed 's/ /-*/g'` +ag=`echo AUTOGEN | sed 's/\(.\)/\1 /g;s/ *$//'` +ag_off=`printf "$ag"|wc -c` +ag_off=`expr $w - \( $ag_off / 2 \)` +ag=`printf "%${ag_off}s${ag}" ""` + +cat < + @%:@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=no], + [:]) + fi + fi]) + 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, and can be faster +# than what's in Autoconf 2.62 through 2.68. + +# 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_cv_type_unsigned_long_long_int=yes + if test "x${ac_cv_prog_cc_c99-no}" = xno; then + AC_LINK_IFELSE( + [_AC_TYPE_LONG_LONG_SNIPPET], + [], + [ac_cv_type_unsigned_long_long_int=no]) + fi]) + 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));]]) +]) + +# Copyright (C) 2002-2018 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_AUTOMAKE_VERSION(VERSION) +# ---------------------------- +# Automake X.Y traces this macro to ensure aclocal.m4 has been +# generated from the m4 files accompanying Automake X.Y. +# (This private macro should not be called outside this file.) +AC_DEFUN([AM_AUTOMAKE_VERSION], +[am__api_version='1.16' +dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to +dnl require some minimum version. Point them to the right macro. +m4_if([$1], [1.16.1], [], + [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl +]) + +# _AM_AUTOCONF_VERSION(VERSION) +# ----------------------------- +# aclocal traces this macro to find the Autoconf version. +# This is a private macro too. Using m4_define simplifies +# the logic in aclocal, which can simply ignore this definition. +m4_define([_AM_AUTOCONF_VERSION], []) + +# AM_SET_CURRENT_AUTOMAKE_VERSION +# ------------------------------- +# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. +# This function is AC_REQUIREd by AM_INIT_AUTOMAKE. +AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], +[AM_AUTOMAKE_VERSION([1.16.1])dnl +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) + +# AM_AUX_DIR_EXPAND -*- Autoconf -*- + +# Copyright (C) 2001-2018 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets +# $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to +# '$srcdir', '$srcdir/..', or '$srcdir/../..'. +# +# Of course, Automake must honor this variable whenever it calls a +# tool from the auxiliary directory. The problem is that $srcdir (and +# therefore $ac_aux_dir as well) can be either absolute or relative, +# depending on how configure is run. This is pretty annoying, since +# it makes $ac_aux_dir quite unusable in subdirectories: in the top +# source directory, any form will work fine, but in subdirectories a +# relative path needs to be adjusted first. +# +# $ac_aux_dir/missing +# fails when called from a subdirectory if $ac_aux_dir is relative +# $top_srcdir/$ac_aux_dir/missing +# fails if $ac_aux_dir is absolute, +# fails when called from a subdirectory in a VPATH build with +# a relative $ac_aux_dir +# +# The reason of the latter failure is that $top_srcdir and $ac_aux_dir +# are both prefixed by $srcdir. In an in-source build this is usually +# harmless because $srcdir is '.', but things will broke when you +# start a VPATH build or use an absolute $srcdir. +# +# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, +# iff we strip the leading $srcdir from $ac_aux_dir. That would be: +# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` +# and then we would define $MISSING as +# MISSING="\${SHELL} $am_aux_dir/missing" +# This will work as long as MISSING is not called from configure, because +# unfortunately $(top_srcdir) has no meaning in configure. +# However there are other variables, like CC, which are often used in +# configure, and could therefore not use this "fixed" $ac_aux_dir. +# +# Another solution, used here, is to always expand $ac_aux_dir to an +# absolute PATH. The drawback is that using absolute paths prevent a +# configured tree to be moved without reconfiguration. + +AC_DEFUN([AM_AUX_DIR_EXPAND], +[AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl +# Expand $ac_aux_dir to an absolute path. +am_aux_dir=`cd "$ac_aux_dir" && pwd` +]) + +# AM_CONDITIONAL -*- Autoconf -*- + +# Copyright (C) 1997-2018 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_CONDITIONAL(NAME, SHELL-CONDITION) +# ------------------------------------- +# Define a conditional. +AC_DEFUN([AM_CONDITIONAL], +[AC_PREREQ([2.52])dnl + m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +AC_SUBST([$1_TRUE])dnl +AC_SUBST([$1_FALSE])dnl +_AM_SUBST_NOTMAKE([$1_TRUE])dnl +_AM_SUBST_NOTMAKE([$1_FALSE])dnl +m4_define([_AM_COND_VALUE_$1], [$2])dnl +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi +AC_CONFIG_COMMANDS_PRE( +[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then + AC_MSG_ERROR([[conditional "$1" was never defined. +Usually this means the macro was only invoked conditionally.]]) +fi])]) + +# Copyright (C) 1999-2018 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. + + +# There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be +# written in clear, in which case automake, when reading aclocal.m4, +# will think it sees a *use*, and therefore will trigger all it's +# C support machinery. Also note that it means that autoscan, seeing +# CC etc. in the Makefile, will ask for an AC_PROG_CC use... + + +# _AM_DEPENDENCIES(NAME) +# ---------------------- +# See how the compiler implements dependency checking. +# NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC". +# We try a few techniques and use that to set a single cache variable. +# +# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was +# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular +# dependency, and given that the user is not expected to run this macro, +# just rely on AC_PROG_CC. +AC_DEFUN([_AM_DEPENDENCIES], +[AC_REQUIRE([AM_SET_DEPDIR])dnl +AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl +AC_REQUIRE([AM_MAKE_INCLUDE])dnl +AC_REQUIRE([AM_DEP_TRACK])dnl + +m4_if([$1], [CC], [depcc="$CC" am_compiler_list=], + [$1], [CXX], [depcc="$CXX" am_compiler_list=], + [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'], + [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'], + [$1], [UPC], [depcc="$UPC" am_compiler_list=], + [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'], + [depcc="$$1" am_compiler_list=]) + +AC_CACHE_CHECK([dependency style of $depcc], + [am_cv_$1_dependencies_compiler_type], +[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_$1_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` + fi + am__universal=false + m4_case([$1], [CC], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac], + [CXX], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac]) + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with '-c' and '-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_$1_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_$1_dependencies_compiler_type=none +fi +]) +AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) +AM_CONDITIONAL([am__fastdep$1], [ + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) +]) + + +# AM_SET_DEPDIR +# ------------- +# Choose a directory name for dependency files. +# This macro is AC_REQUIREd in _AM_DEPENDENCIES. +AC_DEFUN([AM_SET_DEPDIR], +[AC_REQUIRE([AM_SET_LEADING_DOT])dnl +AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl +]) + + +# AM_DEP_TRACK +# ------------ +AC_DEFUN([AM_DEP_TRACK], +[AC_ARG_ENABLE([dependency-tracking], [dnl +AS_HELP_STRING( + [--enable-dependency-tracking], + [do not reject slow dependency extractors]) +AS_HELP_STRING( + [--disable-dependency-tracking], + [speeds up one-time build])]) +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' + am__nodep='_no' +fi +AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) +AC_SUBST([AMDEPBACKSLASH])dnl +_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl +AC_SUBST([am__nodep])dnl +_AM_SUBST_NOTMAKE([am__nodep])dnl +]) + +# Generate code to set up dependency tracking. -*- Autoconf -*- + +# Copyright (C) 1999-2018 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_OUTPUT_DEPENDENCY_COMMANDS +# ------------------------------ +AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], +[{ + # Older Autoconf quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + # TODO: see whether this extra hack can be removed once we start + # requiring Autoconf 2.70 or later. + AS_CASE([$CONFIG_FILES], + [*\'*], [eval set x "$CONFIG_FILES"], + [*], [set x $CONFIG_FILES]) + shift + # Used to flag and report bootstrapping failures. + am_rc=0 + for am_mf + do + # Strip MF so we end up with the name of the file. + am_mf=`AS_ECHO(["$am_mf"]) | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile which includes + # dependency-tracking related rules and includes. + # Grep'ing the whole file directly is not great: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \ + || continue + am_dirpart=`AS_DIRNAME(["$am_mf"])` + am_filepart=`AS_BASENAME(["$am_mf"])` + AM_RUN_LOG([cd "$am_dirpart" \ + && sed -e '/# am--include-marker/d' "$am_filepart" \ + | $MAKE -f - am--depfiles]) || am_rc=$? + done + if test $am_rc -ne 0; then + AC_MSG_FAILURE([Something went wrong bootstrapping makefile fragments + for automatic dependency tracking. Try re-running configure with the + '--disable-dependency-tracking' option to at least be able to build + the package (albeit without support for automatic dependency tracking).]) + fi + AS_UNSET([am_dirpart]) + AS_UNSET([am_filepart]) + AS_UNSET([am_mf]) + AS_UNSET([am_rc]) + rm -f conftest-deps.mk +} +])# _AM_OUTPUT_DEPENDENCY_COMMANDS + + +# AM_OUTPUT_DEPENDENCY_COMMANDS +# ----------------------------- +# This macro should only be invoked once -- use via AC_REQUIRE. +# +# This code is only required when automatic dependency tracking is enabled. +# This creates each '.Po' and '.Plo' makefile fragment that we'll need in +# order to bootstrap the dependency handling code. +AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], +[AC_CONFIG_COMMANDS([depfiles], + [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], + [AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}"])]) + + +# Copyright (C) 1996-2018 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. + +AC_DEFUN([AM_WITH_DMALLOC], +[AC_MSG_CHECKING([if malloc debugging is wanted]) +AC_ARG_WITH([dmalloc], +[AS_HELP_STRING([--with-dmalloc], + [use dmalloc, as in http://www.dmalloc.com])], +[if test "$withval" = yes; then + AC_MSG_RESULT([yes]) + AC_DEFINE([WITH_DMALLOC], [1], + [Define if using the dmalloc debugging malloc package]) + LIBS="$LIBS -ldmalloc" + LDFLAGS="$LDFLAGS -g" +else + AC_MSG_RESULT([no]) +fi], [AC_MSG_RESULT([no])]) +]) + +# Do all the work for Automake. -*- Autoconf -*- + +# Copyright (C) 1996-2018 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This macro actually does too much. Some checks are only needed if +# your package does certain things. But this isn't really a big deal. + +dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O. +m4_define([AC_PROG_CC], +m4_defn([AC_PROG_CC]) +[_AM_PROG_CC_C_O +]) + +# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) +# AM_INIT_AUTOMAKE([OPTIONS]) +# ----------------------------------------------- +# The call with PACKAGE and VERSION arguments is the old style +# call (pre autoconf-2.50), which is being phased out. PACKAGE +# and VERSION should now be passed to AC_INIT and removed from +# the call to AM_INIT_AUTOMAKE. +# We support both call styles for the transition. After +# the next Automake release, Autoconf can make the AC_INIT +# arguments mandatory, and then we can depend on a new Autoconf +# release and drop the old call support. +AC_DEFUN([AM_INIT_AUTOMAKE], +[AC_PREREQ([2.65])dnl +dnl Autoconf wants to disallow AM_ names. We explicitly allow +dnl the ones we care about. +m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl +AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl +AC_REQUIRE([AC_PROG_INSTALL])dnl +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi +AC_SUBST([CYGPATH_W]) + +# Define the identity of the package. +dnl Distinguish between old-style and new-style calls. +m4_ifval([$2], +[AC_DIAGNOSE([obsolete], + [$0: two- and three-arguments forms are deprecated.]) +m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl + AC_SUBST([PACKAGE], [$1])dnl + AC_SUBST([VERSION], [$2])], +[_AM_SET_OPTIONS([$1])dnl +dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. +m4_if( + m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]), + [ok:ok],, + [m4_fatal([AC_INIT should be called with package and version arguments])])dnl + AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl + AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl + +_AM_IF_OPTION([no-define],, +[AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) + AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl + +# Some tools Automake needs. +AC_REQUIRE([AM_SANITY_CHECK])dnl +AC_REQUIRE([AC_ARG_PROGRAM])dnl +AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) +AM_MISSING_PROG([AUTOCONF], [autoconf]) +AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) +AM_MISSING_PROG([AUTOHEADER], [autoheader]) +AM_MISSING_PROG([MAKEINFO], [makeinfo]) +AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl +AC_REQUIRE([AC_PROG_MKDIR_P])dnl +# For better backward compatibility. To be removed once Automake 1.9.x +# dies out for good. For more background, see: +# +# +AC_SUBST([mkdir_p], ['$(MKDIR_P)']) +# We need awk for the "check" target (and possibly the TAP driver). The +# system "awk" is bad on some platforms. +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([AC_PROG_MAKE_SET])dnl +AC_REQUIRE([AM_SET_LEADING_DOT])dnl +_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], + [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], + [_AM_PROG_TAR([v7])])]) +_AM_IF_OPTION([no-dependencies],, +[AC_PROVIDE_IFELSE([AC_PROG_CC], + [_AM_DEPENDENCIES([CC])], + [m4_define([AC_PROG_CC], + m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl +AC_PROVIDE_IFELSE([AC_PROG_CXX], + [_AM_DEPENDENCIES([CXX])], + [m4_define([AC_PROG_CXX], + m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJC], + [_AM_DEPENDENCIES([OBJC])], + [m4_define([AC_PROG_OBJC], + m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], + [_AM_DEPENDENCIES([OBJCXX])], + [m4_define([AC_PROG_OBJCXX], + m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl +]) +AC_REQUIRE([AM_SILENT_RULES])dnl +dnl The testsuite driver may need to know about EXEEXT, so add the +dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This +dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. +AC_CONFIG_COMMANDS_PRE(dnl +[m4_provide_if([_AM_COMPILER_EXEEXT], + [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl + +# POSIX will say in a future version that running "rm -f" with no argument +# is OK; and we want to be able to make that assumption in our Makefile +# recipes. So use an aggressive probe to check that the usage we want is +# actually supported "in the wild" to an acceptable degree. +# See automake bug#10828. +# To make any issue more visible, cause the running configure to be aborted +# by default if the 'rm' program in use doesn't match our expectations; the +# user can still override this though. +if rm -f && rm -fr && rm -rf; then : OK; else + cat >&2 <<'END' +Oops! + +Your 'rm' program seems unable to run without file operands specified +on the command line, even when the '-f' option is present. This is contrary +to the behaviour of most rm programs out there, and not conforming with +the upcoming POSIX standard: + +Please tell bug-automake@gnu.org about your system, including the value +of your $PATH and any error possibly output before this message. This +can help us improve future automake versions. + +END + if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then + echo 'Configuration will proceed anyway, since you have set the' >&2 + echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 + echo >&2 + else + cat >&2 <<'END' +Aborting the configuration process, to ensure you take notice of the issue. + +You can download and install GNU coreutils to get an 'rm' implementation +that behaves properly: . + +If you want to complete the configuration process using your problematic +'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM +to "yes", and re-run configure. + +END + AC_MSG_ERROR([Your 'rm' program is bad, sorry.]) + fi +fi +dnl The trailing newline in this macro's definition is deliberate, for +dnl backward compatibility and to allow trailing 'dnl'-style comments +dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841. +]) + +dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not +dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further +dnl mangled by Autoconf and run in a shell conditional statement. +m4_define([_AC_COMPILER_EXEEXT], +m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) + +# When config.status generates a header, we must update the stamp-h file. +# This file resides in the same directory as the config header +# that is generated. The stamp files are numbered to have different names. + +# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the +# loop where config.status creates the headers, so we can generate +# our stamp files there. +AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], +[# Compute $1's index in $config_headers. +_am_arg=$1 +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) + +# Copyright (C) 2001-2018 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_SH +# ------------------ +# Define $install_sh. +AC_DEFUN([AM_PROG_INSTALL_SH], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +if test x"${install_sh+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi +AC_SUBST([install_sh])]) + +# Copyright (C) 2003-2018 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. + +# Check whether the underlying file-system supports filenames +# with a leading dot. For instance MS-DOS doesn't. +AC_DEFUN([AM_SET_LEADING_DOT], +[rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null +AC_SUBST([am__leading_dot])]) + +# Check to see how 'make' treats includes. -*- Autoconf -*- + +# Copyright (C) 2001-2018 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_MAKE_INCLUDE() +# ----------------- +# Check whether make has an 'include' directive that can support all +# the idioms we need for our automatic dependency tracking code. +AC_DEFUN([AM_MAKE_INCLUDE], +[AC_MSG_CHECKING([whether ${MAKE-make} supports the include directive]) +cat > confinc.mk << 'END' +am__doit: + @echo this is the am__doit target >confinc.out +.PHONY: am__doit +END +am__include="#" +am__quote= +# BSD make does it like this. +echo '.include "confinc.mk" # ignored' > confmf.BSD +# Other make implementations (GNU, Solaris 10, AIX) do it like this. +echo 'include confinc.mk # ignored' > confmf.GNU +_am_result=no +for s in GNU BSD; do + AM_RUN_LOG([${MAKE-make} -f confmf.$s && cat confinc.out]) + AS_CASE([$?:`cat confinc.out 2>/dev/null`], + ['0:this is the am__doit target'], + [AS_CASE([$s], + [BSD], [am__include='.include' am__quote='"'], + [am__include='include' am__quote=''])]) + if test "$am__include" != "#"; then + _am_result="yes ($s style)" + break + fi +done +rm -f confinc.* confmf.* +AC_MSG_RESULT([${_am_result}]) +AC_SUBST([am__include])]) +AC_SUBST([am__quote])]) + +# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- + +# Copyright (C) 1997-2018 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_MISSING_PROG(NAME, PROGRAM) +# ------------------------------ +AC_DEFUN([AM_MISSING_PROG], +[AC_REQUIRE([AM_MISSING_HAS_RUN]) +$1=${$1-"${am_missing_run}$2"} +AC_SUBST($1)]) + +# AM_MISSING_HAS_RUN +# ------------------ +# Define MISSING if not defined so far and test if it is modern enough. +# If it is, set am_missing_run to use it, otherwise, to nothing. +AC_DEFUN([AM_MISSING_HAS_RUN], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([missing])dnl +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --is-lightweight"; then + am_missing_run="$MISSING " +else + am_missing_run= + AC_MSG_WARN(['missing' script is too old or missing]) +fi +]) + +# Helper functions for option handling. -*- Autoconf -*- + +# Copyright (C) 2001-2018 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_MANGLE_OPTION(NAME) +# ----------------------- +AC_DEFUN([_AM_MANGLE_OPTION], +[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) + +# _AM_SET_OPTION(NAME) +# -------------------- +# Set option NAME. Presently that only means defining a flag for this option. +AC_DEFUN([_AM_SET_OPTION], +[m4_define(_AM_MANGLE_OPTION([$1]), [1])]) + +# _AM_SET_OPTIONS(OPTIONS) +# ------------------------ +# OPTIONS is a space-separated list of Automake options. +AC_DEFUN([_AM_SET_OPTIONS], +[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) + +# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) +# ------------------------------------------- +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +AC_DEFUN([_AM_IF_OPTION], +[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) + +# Copyright (C) 1999-2018 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_PROG_CC_C_O +# --------------- +# Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC +# to automatically call this. +AC_DEFUN([_AM_PROG_CC_C_O], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([compile])dnl +AC_LANG_PUSH([C])dnl +AC_CACHE_CHECK( + [whether $CC understands -c and -o together], + [am_cv_prog_cc_c_o], + [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])]) + # Make sure it works both with $CC and with simple cc. + # Following AC_PROG_CC_C_O, we do the test twice because some + # compilers refuse to overwrite an existing .o file with -o, + # though they will create one. + am_cv_prog_cc_c_o=yes + for am_i in 1 2; do + if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \ + && test -f conftest2.$ac_objext; then + : OK + else + am_cv_prog_cc_c_o=no + break + fi + done + rm -f core conftest* + unset am_i]) +if test "$am_cv_prog_cc_c_o" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi +AC_LANG_POP([C])]) + +# For backward compatibility. +AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) + +# Copyright (C) 2001-2018 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_RUN_LOG(COMMAND) +# ------------------- +# Run COMMAND, save the exit status in ac_status, and log it. +# (This has been adapted from Autoconf's _AC_RUN_LOG macro.) +AC_DEFUN([AM_RUN_LOG], +[{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD + ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + (exit $ac_status); }]) + +# Check to make sure that the build environment is sane. -*- Autoconf -*- + +# Copyright (C) 1996-2018 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_SANITY_CHECK +# --------------- +AC_DEFUN([AM_SANITY_CHECK], +[AC_MSG_CHECKING([whether build environment is sane]) +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[[\\\"\#\$\&\'\`$am_lf]]*) + AC_MSG_ERROR([unsafe absolute working directory name]);; +esac +case $srcdir in + *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) + AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);; +esac + +# Do 'set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + am_has_slept=no + for am_try in 1 2; do + echo "timestamp, slept: $am_has_slept" > conftest.file + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$[*]" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + if test "$[*]" != "X $srcdir/configure conftest.file" \ + && test "$[*]" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken + alias in your environment]) + fi + if test "$[2]" = conftest.file || test $am_try -eq 2; then + break + fi + # Just in case. + sleep 1 + am_has_slept=yes + done + test "$[2]" = conftest.file + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +AC_MSG_RESULT([yes]) +# If we didn't sleep, we still need to ensure time stamps of config.status and +# generated files are strictly newer. +am_sleep_pid= +if grep 'slept: no' conftest.file >/dev/null 2>&1; then + ( sleep 1 ) & + am_sleep_pid=$! +fi +AC_CONFIG_COMMANDS_PRE( + [AC_MSG_CHECKING([that generated files are newer than configure]) + if test -n "$am_sleep_pid"; then + # Hide warnings about reused PIDs. + wait $am_sleep_pid 2>/dev/null + fi + AC_MSG_RESULT([done])]) +rm -f conftest.file +]) + +# Copyright (C) 2009-2018 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_SILENT_RULES([DEFAULT]) +# -------------------------- +# Enable less verbose build rules; with the default set to DEFAULT +# ("yes" being less verbose, "no" or empty being verbose). +AC_DEFUN([AM_SILENT_RULES], +[AC_ARG_ENABLE([silent-rules], [dnl +AS_HELP_STRING( + [--enable-silent-rules], + [less verbose build output (undo: "make V=1")]) +AS_HELP_STRING( + [--disable-silent-rules], + [verbose build output (undo: "make V=0")])dnl +]) +case $enable_silent_rules in @%:@ ((( + yes) AM_DEFAULT_VERBOSITY=0;; + no) AM_DEFAULT_VERBOSITY=1;; + *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; +esac +dnl +dnl A few 'make' implementations (e.g., NonStop OS and NextStep) +dnl do not support nested variable expansions. +dnl See automake bug#9928 and bug#10237. +am_make=${MAKE-make} +AC_CACHE_CHECK([whether $am_make supports nested variables], + [am_cv_make_support_nested_variables], + [if AS_ECHO([['TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi]) +if test $am_cv_make_support_nested_variables = yes; then + dnl Using '$V' instead of '$(V)' breaks IRIX make. + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AC_SUBST([AM_V])dnl +AM_SUBST_NOTMAKE([AM_V])dnl +AC_SUBST([AM_DEFAULT_V])dnl +AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl +AC_SUBST([AM_DEFAULT_VERBOSITY])dnl +AM_BACKSLASH='\' +AC_SUBST([AM_BACKSLASH])dnl +_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl +]) + +# Copyright (C) 2001-2018 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_STRIP +# --------------------- +# One issue with vendor 'install' (even GNU) is that you can't +# specify the program used to strip binaries. This is especially +# annoying in cross-compiling environments, where the build's strip +# is unlikely to handle the host's binaries. +# Fortunately install-sh will honor a STRIPPROG variable, so we +# always use install-sh in "make install-strip", and initialize +# STRIPPROG with the value of the STRIP variable (set by the user). +AC_DEFUN([AM_PROG_INSTALL_STRIP], +[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +# Installed binaries are usually stripped using 'strip' when the user +# run "make install-strip". However 'strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the 'STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. +if test "$cross_compiling" != no; then + AC_CHECK_TOOL([STRIP], [strip], :) +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" +AC_SUBST([INSTALL_STRIP_PROGRAM])]) + +# Copyright (C) 2006-2018 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_SUBST_NOTMAKE(VARIABLE) +# --------------------------- +# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. +# This macro is traced by Automake. +AC_DEFUN([_AM_SUBST_NOTMAKE]) + +# AM_SUBST_NOTMAKE(VARIABLE) +# -------------------------- +# Public sister of _AM_SUBST_NOTMAKE. +AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) + +# Check how to create a tarball. -*- Autoconf -*- + +# Copyright (C) 2004-2018 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_PROG_TAR(FORMAT) +# -------------------- +# Check how to create a tarball in format FORMAT. +# FORMAT should be one of 'v7', 'ustar', or 'pax'. +# +# Substitute a variable $(am__tar) that is a command +# writing to stdout a FORMAT-tarball containing the directory +# $tardir. +# tardir=directory && $(am__tar) > result.tar +# +# Substitute a variable $(am__untar) that extract such +# a tarball read from stdin. +# $(am__untar) < result.tar +# +AC_DEFUN([_AM_PROG_TAR], +[# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AC_SUBST([AMTAR], ['$${TAR-tar}']) + +# We'll loop over all known methods to create a tar archive until one works. +_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' + +m4_if([$1], [v7], + [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], + + [m4_case([$1], + [ustar], + [# The POSIX 1988 'ustar' format is defined with fixed-size fields. + # There is notably a 21 bits limit for the UID and the GID. In fact, + # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343 + # and bug#13588). + am_max_uid=2097151 # 2^21 - 1 + am_max_gid=$am_max_uid + # The $UID and $GID variables are not portable, so we need to resort + # to the POSIX-mandated id(1) utility. Errors in the 'id' calls + # below are definitely unexpected, so allow the users to see them + # (that is, avoid stderr redirection). + am_uid=`id -u || echo unknown` + am_gid=`id -g || echo unknown` + AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format]) + if test $am_uid -le $am_max_uid; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + _am_tools=none + fi + AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format]) + if test $am_gid -le $am_max_gid; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + _am_tools=none + fi], + + [pax], + [], + + [m4_fatal([Unknown tar format])]) + + AC_MSG_CHECKING([how to create a $1 tar archive]) + + # Go ahead even if we have the value already cached. We do so because we + # need to set the values for the 'am__tar' and 'am__untar' variables. + _am_tools=${am_cv_prog_tar_$1-$_am_tools} + + for _am_tool in $_am_tools; do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; do + AM_RUN_LOG([$_am_tar --version]) && break + done + am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x $1 -w "$$tardir"' + am__tar_='pax -L -x $1 -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H $1 -L' + am__tar_='find "$tardir" -print | cpio -o -H $1 -L' + am__untar='cpio -i -H $1 -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac + + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_$1}" && break + + # tar/untar a dummy directory, and stop if the command works. + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + rm -rf conftest.dir + if test -s conftest.tar; then + AM_RUN_LOG([$am__untar /dev/null 2>&1 && break + fi + done + rm -rf conftest.dir + + AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) + AC_MSG_RESULT([$am_cv_prog_tar_$1])]) + +AC_SUBST([am__tar]) +AC_SUBST([am__untar]) +]) # _AM_PROG_TAR + +m4_include([config/ag_macros.m4]) +m4_include([config/asm-underscore.m4]) +m4_include([config/extensions.m4]) +m4_include([config/guile.m4]) +m4_include([config/host-cpu-c-abi.m4]) +m4_include([config/lib-ld.m4]) +m4_include([config/lib-link.m4]) +m4_include([config/lib-prefix.m4]) +m4_include([config/libopts.m4]) +m4_include([config/libtool.m4]) +m4_include([config/ltoptions.m4]) +m4_include([config/ltsugar.m4]) +m4_include([config/ltversion.m4]) +m4_include([config/lt~obsolete.m4]) +m4_include([config/onceonly.m4]) +m4_include([config/pkg.m4]) +m4_include([config/snprintfv.m4]) +m4_include([config/stdnoreturn.m4]) +m4_include([config/unlocked-io.m4]) diff --git a/agen5/Makefile.am b/agen5/Makefile.am new file mode 100644 index 0000000..cf2ed90 --- /dev/null +++ b/agen5/Makefile.am @@ -0,0 +1,232 @@ +## -*- Mode: Makefile -*- +## +## Makefile.am -- process this file with automake to produce Makefile.in +## +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen 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. +## +## AutoGen is distributed in the hope that 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 . + +libdatadir = $(libdir)/@PACKAGE@ +SUBDIRS = test +AM_CPPFLAGS = @INCLIST@ +AM_CFLAGS = @WARN_CFLAGS@ +FSMTPL = fsm.tpl fsm-macro.tlib fsm-trans.tlib +templates = snarf.tpl $(FSMTPL) guile-iface.tpl +definitions = cgi.def opts.def pseudo.def guile-iface.def defParse.def \ + ag-text.def +ghdr = ag-text.h cgi-fsm.h defParse-fsm.h directive.h expr.h \ + functions.h guile-iface.h opts.h proto.h pseudo-fsm.h +gen_csrc = expr.ini defParse.x $(ghdr) +pkgdata_DATA = $(FSMTPL) +man_MANS = autogen.1 +DISTCLEANFILES = stamp-* ag.c +bin_PROGRAMS = autogen + +# The list of source files with AutoGen functions +# +FUNCLIST = funcCase.c funcDef.c funcEval.c funcFor.c funcIf.c functions.c + +# The list of source files with Guile expression functions defined, +# plus the parse/lex modules that must be in this order. +# +exprlist = defParse-fsm.c defLex.c directive.c $(FUNCLIST) \ + expExtract.c expFormat.c expGperf.c expGuile.c expMake.c \ + expOutput.c expPrint.c expState.c expString.c agShell.c + +csrc = autogen.c $(exprlist) \ + ag-text.c agCgi.c agDep.c agInit.c agUtils.c \ + cgi-fsm.c defDirect.c defFind.c defLoad.c fmemopen.c \ + loadPseudo.c opts.c scribble.c tpLoad.c tpParse.c \ + tpProcess.c + +all_src = $(csrc) $(gen_csrc) autogen.h scribble.h + +EXTRA_DIST = $(all_src) $(definitions) $(templates) $(man_MANS) \ + bootstrap.dir schemedef.scm \ + invoke-autogen.texi mk-stamps.sh + +LO_LIB = $(top_builddir)/autoopts/libopts.la +SNV_LIB = $(top_builddir)/snprintfv/libsnprintfv.la + +nodist_autogen_SOURCES = ag.c +autogen_SOURCES = $(gen_csrc) +autogen_LDADD = $(LO_LIB) $(SNV_LIB) $(GUILE_LIBS) +autogen_LDFLAGS = $(DYNAMIC_AG) $(AG_STATIC_AUTOGEN) -no-install +autogen_CFLAGS = $(GUILE_CFLAGS) +stamp_script = $(srcdir)/mk-stamps.sh + +AM_YFLAGS = -d + +ag.c : Makefile + exec > $@ ; \ + echo '#undef PKGDATADIR' ; \ + echo '#define PKGDATADIR "$(pkgdatadir)"' ; \ + echo '#undef LIBDATADIR' ; \ + echo '#define LIBDATADIR "$(libdatadir)"' ; \ + mk=`set -- $(MAKE) ; command -v $$1` ; \ + echo 'static char const make_prog[] = "'$$mk'";' ; \ + printf '\n#define DEFINING 1\n' ; \ + printf '#include "%s"\n' autoopts/project.h autogen.h ; \ + printf '#include "%s"\n' $(csrc) + +STAMPENV = top_srcdir="$(top_srcdir)" top_builddir="$(top_builddir)" \ + srcdir="$(srcdir)" AGexe="$(AGexe)" GDexe="$(GDexe)" CLexe="$(CLexe)" \ + DEPDIR="$(DEPDIR)" AG_TIMEOUT=$(AG_TIMEOUT) + +stamp-env : + $(STAMPENV) $(POSIX_SHELL) $(stamp_script) + +../snprintfv/snprintfv.h : + @if [ ! -f ../snprintfv/snprintfv.h ] ; then cd ../snprintfv ; \ + ln -s $(top_srcdir)/snprintfv/snprintfv/snprintfv.h . ; fi + +../snprintfv/libsnprintfv.la : + cd ../snprintfv ; $(MAKE) libsnprintfv.la + +.PHONY : stamp-env +.NOTPARALLEL: + +# start-generated-text + +if AMDEP +DEPFL_STAMP_OPTS= $(DEPDIR)/dep-stamp-opts.mk +$(DEPFL_STAMP_OPTS) : + $(SHELL) $(stamp_script) "$@" +include $(DEPFL_STAMP_OPTS) +DEPFL_STAMP_PROTO= $(DEPDIR)/dep-stamp-proto.mk +$(DEPFL_STAMP_PROTO) : + $(SHELL) $(stamp_script) "$@" +include $(DEPFL_STAMP_PROTO) +DEPFL_STAMP_PARSE= $(DEPDIR)/dep-stamp-parse.mk +$(DEPFL_STAMP_PARSE) : + $(SHELL) $(stamp_script) "$@" +include $(DEPFL_STAMP_PARSE) +DEPFL_STAMP_CGI= $(DEPDIR)/dep-stamp-cgi.mk +$(DEPFL_STAMP_CGI) : + $(SHELL) $(stamp_script) "$@" +include $(DEPFL_STAMP_CGI) +DEPFL_STAMP_PSEUDO= $(DEPDIR)/dep-stamp-pseudo.mk +$(DEPFL_STAMP_PSEUDO) : + $(SHELL) $(stamp_script) "$@" +include $(DEPFL_STAMP_PSEUDO) +DEPFL_STAMP_EXPRINI= $(DEPDIR)/dep-stamp-exprini.mk +$(DEPFL_STAMP_EXPRINI) : + $(SHELL) $(stamp_script) "$@" +include $(DEPFL_STAMP_EXPRINI) +DEPFL_STAMP_DIRECTIVE= $(DEPDIR)/dep-stamp-directive.mk +$(DEPFL_STAMP_DIRECTIVE) : + $(SHELL) $(stamp_script) "$@" +include $(DEPFL_STAMP_DIRECTIVE) +DEPFL_STAMP_TEXI= $(DEPDIR)/dep-stamp-texi.mk +$(DEPFL_STAMP_TEXI) : + $(SHELL) $(stamp_script) "$@" +include $(DEPFL_STAMP_TEXI) +DEPFL_STAMP_AG_TEXT= $(DEPDIR)/dep-stamp-ag_text.mk +$(DEPFL_STAMP_AG_TEXT) : + $(SHELL) $(stamp_script) "$@" +include $(DEPFL_STAMP_AG_TEXT) +DEPFL_STAMP_FMEM= $(DEPDIR)/dep-stamp-fmem.mk +$(DEPFL_STAMP_FMEM) : + $(SHELL) $(stamp_script) "$@" +include $(DEPFL_STAMP_FMEM) +DEPFL_STAMP_MAN= $(DEPDIR)/dep-stamp-man.mk +$(DEPFL_STAMP_MAN) : + $(SHELL) $(stamp_script) "$@" +include $(DEPFL_STAMP_MAN) +DEPFL_STAMP_FUNC= $(DEPDIR)/dep-stamp-func.mk +$(DEPFL_STAMP_FUNC) : + $(SHELL) $(stamp_script) "$@" +include $(DEPFL_STAMP_FUNC) +DEPFL_STAMP_GVER= $(DEPDIR)/dep-stamp-gver.mk +$(DEPFL_STAMP_GVER) : + $(SHELL) $(stamp_script) "$@" +include $(DEPFL_STAMP_GVER) +else +DEPFL_STAMP_OPTS= "$@" +DEPFL_STAMP_PROTO= "$@" +DEPFL_STAMP_PARSE= "$@" +DEPFL_STAMP_CGI= "$@" +DEPFL_STAMP_PSEUDO= "$@" +DEPFL_STAMP_EXPRINI= "$@" +DEPFL_STAMP_DIRECTIVE= "$@" +DEPFL_STAMP_TEXI= "$@" +DEPFL_STAMP_AG_TEXT= "$@" +DEPFL_STAMP_FMEM= "$@" +DEPFL_STAMP_MAN= "$@" +DEPFL_STAMP_FUNC= "$@" +DEPFL_STAMP_GVER= "$@" +endif +list_stamps = \ + stamp-opts stamp-proto stamp-parse stamp-cgi \ + stamp-pseudo stamp-exprini stamp-directive stamp-texi \ + stamp-ag_text stamp-fmem stamp-man stamp-func \ + stamp-gver + +stamp-opts: + @target="$(AUTOGEN_stamp_opts_TList)" \ + $(MAKE_STAMP) + +stamp-proto: + @target="$(AUTOGEN_stamp_proto_TList)" \ + $(MAKE_STAMP) + +stamp-parse: + @target="$(AUTOGEN_stamp_parse_TList)" \ + $(MAKE_STAMP) + +stamp-cgi: + @target="$(AUTOGEN_stamp_cgi_TList)" \ + $(MAKE_STAMP) + +stamp-pseudo: + @target="$(AUTOGEN_stamp_pseudo_TList)" \ + $(MAKE_STAMP) + +stamp-exprini: + @target="$(AUTOGEN_stamp_exprini_TList)" \ + $(MAKE_STAMP) + +stamp-directive: + @target="$(AUTOGEN_stamp_directive_TList)" \ + $(MAKE_STAMP) + +stamp-texi: + @target="$(AUTOGEN_stamp_texi_TList)" \ + $(MAKE_STAMP) + +stamp-ag_text: + @target="$(AUTOGEN_stamp_ag_text_TList)" \ + $(MAKE_STAMP) + +stamp-fmem: + @target="$(AUTOGEN_stamp_fmem_TList)" \ + $(MAKE_STAMP) + +stamp-man: + @target="$(AUTOGEN_stamp_man_TList)" \ + $(MAKE_STAMP) + +stamp-func: + @target="$(AUTOGEN_stamp_func_TList)" \ + $(MAKE_STAMP) + +stamp-gver: + @target="$(AUTOGEN_stamp_gver_TList)" \ + $(MAKE_STAMP) +.PHONY: stamps +stamps: $(list_stamps) + +# end-generated-text +# end of Makefile.am diff --git a/agen5/Makefile.in b/agen5/Makefile.in new file mode 100644 index 0000000..e423fb7 --- /dev/null +++ b/agen5/Makefile.in @@ -0,0 +1,1147 @@ +# Makefile.in generated by automake 1.16.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2018 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +bin_PROGRAMS = autogen$(EXEEXT) +subdir = agen5 +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/config/ag_macros.m4 \ + $(top_srcdir)/config/asm-underscore.m4 \ + $(top_srcdir)/config/extensions.m4 \ + $(top_srcdir)/config/guile.m4 \ + $(top_srcdir)/config/host-cpu-c-abi.m4 \ + $(top_srcdir)/config/lib-ld.m4 \ + $(top_srcdir)/config/lib-link.m4 \ + $(top_srcdir)/config/lib-prefix.m4 \ + $(top_srcdir)/config/libopts.m4 \ + $(top_srcdir)/config/libtool.m4 \ + $(top_srcdir)/config/ltoptions.m4 \ + $(top_srcdir)/config/ltsugar.m4 \ + $(top_srcdir)/config/ltversion.m4 \ + $(top_srcdir)/config/lt~obsolete.m4 \ + $(top_srcdir)/config/onceonly.m4 $(top_srcdir)/config/pkg.m4 \ + $(top_srcdir)/config/snprintfv.m4 \ + $(top_srcdir)/config/stdnoreturn.m4 \ + $(top_srcdir)/config/unlocked-io.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" \ + "$(DESTDIR)$(pkgdatadir)" +PROGRAMS = $(bin_PROGRAMS) +am__objects_1 = +am__objects_2 = $(am__objects_1) +am_autogen_OBJECTS = $(am__objects_2) +nodist_autogen_OBJECTS = autogen-ag.$(OBJEXT) +autogen_OBJECTS = $(am_autogen_OBJECTS) $(nodist_autogen_OBJECTS) +am__DEPENDENCIES_1 = +autogen_DEPENDENCIES = $(LO_LIB) $(SNV_LIB) $(am__DEPENDENCIES_1) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +autogen_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(autogen_CFLAGS) \ + $(CFLAGS) $(autogen_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/config/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/autogen-ag.Po +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(autogen_SOURCES) $(nodist_autogen_SOURCES) +DIST_SOURCES = $(autogen_SOURCES) +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +man1dir = $(mandir)/man1 +NROFF = nroff +MANS = $(man_MANS) +DATA = $(pkgdata_DATA) +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ + distdir distdir-am +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = $(SUBDIRS) +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/config/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +ACLOCAL = @ACLOCAL@ +AGEN5_TESTS = @AGEN5_TESTS@ +AG_LDFLAGS = @AG_LDFLAGS@ +AG_MAJOR_VERSION = @AG_MAJOR_VERSION@ +AG_MINOR_VERSION = @AG_MINOR_VERSION@ +AG_STATIC_AUTOGEN = @AG_STATIC_AUTOGEN@ +AG_TIMEOUT = @AG_TIMEOUT@ +AG_VERSION = @AG_VERSION@ +AG_XML2 = @AG_XML2@ +AGexe = @AGexe@ +AGnam = @AGnam@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AO_AGE = @AO_AGE@ +AO_CURRENT = @AO_CURRENT@ +AO_REVISION = @AO_REVISION@ +AO_TEMPLATE_VERSION = @AO_TEMPLATE_VERSION@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CLexe = @CLexe@ +CLnam = @CLnam@ +CONFIG_SHELL = @CONFIG_SHELL@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEBUG_ENABLED = @DEBUG_ENABLED@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +DYNAMIC_AG = @DYNAMIC_AG@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ENABLE_STATIC = @ENABLE_STATIC@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GDexe = @GDexe@ +GDnam = @GDnam@ +GO_AGE = @GO_AGE@ +GO_CURRENT = @GO_CURRENT@ +GO_REVISION = @GO_REVISION@ +GREP = @GREP@ +GUILE_CFLAGS = @GUILE_CFLAGS@ +GUILE_EFFECTIVE_VERSION = @GUILE_EFFECTIVE_VERSION@ +GUILE_LDFLAGS = @GUILE_LDFLAGS@ +GUILE_LIBS = @GUILE_LIBS@ +GUILE_LTLIBS = @GUILE_LTLIBS@ +HOST_CPU = @HOST_CPU@ +HOST_CPU_C_ABI = @HOST_CPU_C_ABI@ +INCLIST = @INCLIST@ +INCSNPRINTFV = @INCSNPRINTFV@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSNPRINTFV = @LIBSNPRINTFV@ +LIBTOOL = @LIBTOOL@ +LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ +LIBXML2_LIBS = @LIBXML2_LIBS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +M4_SRC = @M4_SRC@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPTS_TESTDIR = @OPTS_TESTDIR@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POSIX_SHELL = @POSIX_SHELL@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STDNORETURN_H = @STDNORETURN_H@ +STRIP = @STRIP@ +TEXI2HTML = @TEXI2HTML@ +VERSION = @VERSION@ +WARN_CFLAGS = @WARN_CFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_aux_dir = @ac_aux_dir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +libdatadir = $(libdir)/@PACKAGE@ +SUBDIRS = test +AM_CPPFLAGS = @INCLIST@ +AM_CFLAGS = @WARN_CFLAGS@ +FSMTPL = fsm.tpl fsm-macro.tlib fsm-trans.tlib +templates = snarf.tpl $(FSMTPL) guile-iface.tpl +definitions = cgi.def opts.def pseudo.def guile-iface.def defParse.def \ + ag-text.def + +ghdr = ag-text.h cgi-fsm.h defParse-fsm.h directive.h expr.h \ + functions.h guile-iface.h opts.h proto.h pseudo-fsm.h + +gen_csrc = expr.ini defParse.x $(ghdr) +pkgdata_DATA = $(FSMTPL) +man_MANS = autogen.1 +DISTCLEANFILES = stamp-* ag.c + +# The list of source files with AutoGen functions +# +FUNCLIST = funcCase.c funcDef.c funcEval.c funcFor.c funcIf.c functions.c + +# The list of source files with Guile expression functions defined, +# plus the parse/lex modules that must be in this order. +# +exprlist = defParse-fsm.c defLex.c directive.c $(FUNCLIST) \ + expExtract.c expFormat.c expGperf.c expGuile.c expMake.c \ + expOutput.c expPrint.c expState.c expString.c agShell.c + +csrc = autogen.c $(exprlist) \ + ag-text.c agCgi.c agDep.c agInit.c agUtils.c \ + cgi-fsm.c defDirect.c defFind.c defLoad.c fmemopen.c \ + loadPseudo.c opts.c scribble.c tpLoad.c tpParse.c \ + tpProcess.c + +all_src = $(csrc) $(gen_csrc) autogen.h scribble.h +EXTRA_DIST = $(all_src) $(definitions) $(templates) $(man_MANS) \ + bootstrap.dir schemedef.scm \ + invoke-autogen.texi mk-stamps.sh + +LO_LIB = $(top_builddir)/autoopts/libopts.la +SNV_LIB = $(top_builddir)/snprintfv/libsnprintfv.la +nodist_autogen_SOURCES = ag.c +autogen_SOURCES = $(gen_csrc) +autogen_LDADD = $(LO_LIB) $(SNV_LIB) $(GUILE_LIBS) +autogen_LDFLAGS = $(DYNAMIC_AG) $(AG_STATIC_AUTOGEN) -no-install +autogen_CFLAGS = $(GUILE_CFLAGS) +stamp_script = $(srcdir)/mk-stamps.sh +AM_YFLAGS = -d +STAMPENV = top_srcdir="$(top_srcdir)" top_builddir="$(top_builddir)" \ + srcdir="$(srcdir)" AGexe="$(AGexe)" GDexe="$(GDexe)" CLexe="$(CLexe)" \ + DEPDIR="$(DEPDIR)" AG_TIMEOUT=$(AG_TIMEOUT) + +@AMDEP_FALSE@DEPFL_STAMP_OPTS = "$@" + +# start-generated-text +@AMDEP_TRUE@DEPFL_STAMP_OPTS = $(DEPDIR)/dep-stamp-opts.mk +@AMDEP_FALSE@DEPFL_STAMP_PROTO = "$@" +@AMDEP_TRUE@DEPFL_STAMP_PROTO = $(DEPDIR)/dep-stamp-proto.mk +@AMDEP_FALSE@DEPFL_STAMP_PARSE = "$@" +@AMDEP_TRUE@DEPFL_STAMP_PARSE = $(DEPDIR)/dep-stamp-parse.mk +@AMDEP_FALSE@DEPFL_STAMP_CGI = "$@" +@AMDEP_TRUE@DEPFL_STAMP_CGI = $(DEPDIR)/dep-stamp-cgi.mk +@AMDEP_FALSE@DEPFL_STAMP_PSEUDO = "$@" +@AMDEP_TRUE@DEPFL_STAMP_PSEUDO = $(DEPDIR)/dep-stamp-pseudo.mk +@AMDEP_FALSE@DEPFL_STAMP_EXPRINI = "$@" +@AMDEP_TRUE@DEPFL_STAMP_EXPRINI = $(DEPDIR)/dep-stamp-exprini.mk +@AMDEP_FALSE@DEPFL_STAMP_DIRECTIVE = "$@" +@AMDEP_TRUE@DEPFL_STAMP_DIRECTIVE = $(DEPDIR)/dep-stamp-directive.mk +@AMDEP_FALSE@DEPFL_STAMP_TEXI = "$@" +@AMDEP_TRUE@DEPFL_STAMP_TEXI = $(DEPDIR)/dep-stamp-texi.mk +@AMDEP_FALSE@DEPFL_STAMP_AG_TEXT = "$@" +@AMDEP_TRUE@DEPFL_STAMP_AG_TEXT = $(DEPDIR)/dep-stamp-ag_text.mk +@AMDEP_FALSE@DEPFL_STAMP_FMEM = "$@" +@AMDEP_TRUE@DEPFL_STAMP_FMEM = $(DEPDIR)/dep-stamp-fmem.mk +@AMDEP_FALSE@DEPFL_STAMP_MAN = "$@" +@AMDEP_TRUE@DEPFL_STAMP_MAN = $(DEPDIR)/dep-stamp-man.mk +@AMDEP_FALSE@DEPFL_STAMP_FUNC = "$@" +@AMDEP_TRUE@DEPFL_STAMP_FUNC = $(DEPDIR)/dep-stamp-func.mk +@AMDEP_FALSE@DEPFL_STAMP_GVER = "$@" +@AMDEP_TRUE@DEPFL_STAMP_GVER = $(DEPDIR)/dep-stamp-gver.mk +list_stamps = \ + stamp-opts stamp-proto stamp-parse stamp-cgi \ + stamp-pseudo stamp-exprini stamp-directive stamp-texi \ + stamp-ag_text stamp-fmem stamp-man stamp-func \ + stamp-gver + +all: all-recursive + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu agen5/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu agen5/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ + fi; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p \ + || test -f $$p1 \ + ; then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' \ + -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' \ + `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(bindir)" && rm -f $$files + +clean-binPROGRAMS: + @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list + +autogen$(EXEEXT): $(autogen_OBJECTS) $(autogen_DEPENDENCIES) $(EXTRA_autogen_DEPENDENCIES) + @rm -f autogen$(EXEEXT) + $(AM_V_CCLD)$(autogen_LINK) $(autogen_OBJECTS) $(autogen_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/autogen-ag.Po@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +autogen-ag.o: ag.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(autogen_CFLAGS) $(CFLAGS) -MT autogen-ag.o -MD -MP -MF $(DEPDIR)/autogen-ag.Tpo -c -o autogen-ag.o `test -f 'ag.c' || echo '$(srcdir)/'`ag.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/autogen-ag.Tpo $(DEPDIR)/autogen-ag.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ag.c' object='autogen-ag.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(autogen_CFLAGS) $(CFLAGS) -c -o autogen-ag.o `test -f 'ag.c' || echo '$(srcdir)/'`ag.c + +autogen-ag.obj: ag.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(autogen_CFLAGS) $(CFLAGS) -MT autogen-ag.obj -MD -MP -MF $(DEPDIR)/autogen-ag.Tpo -c -o autogen-ag.obj `if test -f 'ag.c'; then $(CYGPATH_W) 'ag.c'; else $(CYGPATH_W) '$(srcdir)/ag.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/autogen-ag.Tpo $(DEPDIR)/autogen-ag.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ag.c' object='autogen-ag.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(autogen_CFLAGS) $(CFLAGS) -c -o autogen-ag.obj `if test -f 'ag.c'; then $(CYGPATH_W) 'ag.c'; else $(CYGPATH_W) '$(srcdir)/ag.c'; fi` + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-man1: $(man_MANS) + @$(NORMAL_INSTALL) + @list1=''; \ + list2='$(man_MANS)'; \ + test -n "$(man1dir)" \ + && test -n "`echo $$list1$$list2`" \ + || exit 0; \ + echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \ + { for i in $$list1; do echo "$$i"; done; \ + if test -n "$$list2"; then \ + for i in $$list2; do echo "$$i"; done \ + | sed -n '/\.1[a-z]*$$/p'; \ + fi; \ + } | while read p; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; echo "$$p"; \ + done | \ + sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ + sed 'N;N;s,\n, ,g' | { \ + list=; while read file base inst; do \ + if test "$$base" = "$$inst"; then list="$$list $$file"; else \ + echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ + $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ + fi; \ + done; \ + for i in $$list; do echo "$$i"; done | $(am__base_list) | \ + while read files; do \ + test -z "$$files" || { \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ + done; } + +uninstall-man1: + @$(NORMAL_UNINSTALL) + @list=''; test -n "$(man1dir)" || exit 0; \ + files=`{ for i in $$list; do echo "$$i"; done; \ + l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ + sed -n '/\.1[a-z]*$$/p'; \ + } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ + dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir) +install-pkgdataDATA: $(pkgdata_DATA) + @$(NORMAL_INSTALL) + @list='$(pkgdata_DATA)'; test -n "$(pkgdatadir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkgdatadir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkgdatadir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgdatadir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgdatadir)" || exit $$?; \ + done + +uninstall-pkgdataDATA: + @$(NORMAL_UNINSTALL) + @list='$(pkgdata_DATA)'; test -n "$(pkgdatadir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(pkgdatadir)'; $(am__uninstall_files_from_dir) + +# This directory's subdirectories are mostly independent; you can cd +# into them and run 'make' without going through this Makefile. +# To change the values of 'make' variables: instead of editing Makefiles, +# (1) if the variable is set in 'config.status', edit 'config.status' +# (which will cause the Makefiles to be regenerated when you run 'make'); +# (2) otherwise, pass the desired values on the 'make' command line. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-recursive + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-recursive + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-recursive +all-am: Makefile $(PROGRAMS) $(MANS) $(DATA) +installdirs: installdirs-recursive +installdirs-am: + for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(pkgdatadir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am + +distclean: distclean-recursive + -rm -f ./$(DEPDIR)/autogen-ag.Po + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: install-man install-pkgdataDATA + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: install-binPROGRAMS + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: install-man1 + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f ./$(DEPDIR)/autogen-ag.Po + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: uninstall-binPROGRAMS uninstall-man \ + uninstall-pkgdataDATA + +uninstall-man: uninstall-man1 + +.MAKE: $(am__recursive_targets) install-am install-strip + +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ + am--depfiles check check-am clean clean-binPROGRAMS \ + clean-generic clean-libtool cscopelist-am ctags ctags-am \ + distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-binPROGRAMS \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-man1 \ + install-pdf install-pdf-am install-pkgdataDATA install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs installdirs-am maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am uninstall-binPROGRAMS \ + uninstall-man uninstall-man1 uninstall-pkgdataDATA + +.PRECIOUS: Makefile + + +ag.c : Makefile + exec > $@ ; \ + echo '#undef PKGDATADIR' ; \ + echo '#define PKGDATADIR "$(pkgdatadir)"' ; \ + echo '#undef LIBDATADIR' ; \ + echo '#define LIBDATADIR "$(libdatadir)"' ; \ + mk=`set -- $(MAKE) ; command -v $$1` ; \ + echo 'static char const make_prog[] = "'$$mk'";' ; \ + printf '\n#define DEFINING 1\n' ; \ + printf '#include "%s"\n' autoopts/project.h autogen.h ; \ + printf '#include "%s"\n' $(csrc) + +stamp-env : + $(STAMPENV) $(POSIX_SHELL) $(stamp_script) + +../snprintfv/snprintfv.h : + @if [ ! -f ../snprintfv/snprintfv.h ] ; then cd ../snprintfv ; \ + ln -s $(top_srcdir)/snprintfv/snprintfv/snprintfv.h . ; fi + +../snprintfv/libsnprintfv.la : + cd ../snprintfv ; $(MAKE) libsnprintfv.la + +.PHONY : stamp-env +.NOTPARALLEL: +@AMDEP_TRUE@$(DEPFL_STAMP_OPTS) : +@AMDEP_TRUE@ $(SHELL) $(stamp_script) "$@" +@AMDEP_TRUE@include $(DEPFL_STAMP_OPTS) +@AMDEP_TRUE@$(DEPFL_STAMP_PROTO) : +@AMDEP_TRUE@ $(SHELL) $(stamp_script) "$@" +@AMDEP_TRUE@include $(DEPFL_STAMP_PROTO) +@AMDEP_TRUE@$(DEPFL_STAMP_PARSE) : +@AMDEP_TRUE@ $(SHELL) $(stamp_script) "$@" +@AMDEP_TRUE@include $(DEPFL_STAMP_PARSE) +@AMDEP_TRUE@$(DEPFL_STAMP_CGI) : +@AMDEP_TRUE@ $(SHELL) $(stamp_script) "$@" +@AMDEP_TRUE@include $(DEPFL_STAMP_CGI) +@AMDEP_TRUE@$(DEPFL_STAMP_PSEUDO) : +@AMDEP_TRUE@ $(SHELL) $(stamp_script) "$@" +@AMDEP_TRUE@include $(DEPFL_STAMP_PSEUDO) +@AMDEP_TRUE@$(DEPFL_STAMP_EXPRINI) : +@AMDEP_TRUE@ $(SHELL) $(stamp_script) "$@" +@AMDEP_TRUE@include $(DEPFL_STAMP_EXPRINI) +@AMDEP_TRUE@$(DEPFL_STAMP_DIRECTIVE) : +@AMDEP_TRUE@ $(SHELL) $(stamp_script) "$@" +@AMDEP_TRUE@include $(DEPFL_STAMP_DIRECTIVE) +@AMDEP_TRUE@$(DEPFL_STAMP_TEXI) : +@AMDEP_TRUE@ $(SHELL) $(stamp_script) "$@" +@AMDEP_TRUE@include $(DEPFL_STAMP_TEXI) +@AMDEP_TRUE@$(DEPFL_STAMP_AG_TEXT) : +@AMDEP_TRUE@ $(SHELL) $(stamp_script) "$@" +@AMDEP_TRUE@include $(DEPFL_STAMP_AG_TEXT) +@AMDEP_TRUE@$(DEPFL_STAMP_FMEM) : +@AMDEP_TRUE@ $(SHELL) $(stamp_script) "$@" +@AMDEP_TRUE@include $(DEPFL_STAMP_FMEM) +@AMDEP_TRUE@$(DEPFL_STAMP_MAN) : +@AMDEP_TRUE@ $(SHELL) $(stamp_script) "$@" +@AMDEP_TRUE@include $(DEPFL_STAMP_MAN) +@AMDEP_TRUE@$(DEPFL_STAMP_FUNC) : +@AMDEP_TRUE@ $(SHELL) $(stamp_script) "$@" +@AMDEP_TRUE@include $(DEPFL_STAMP_FUNC) +@AMDEP_TRUE@$(DEPFL_STAMP_GVER) : +@AMDEP_TRUE@ $(SHELL) $(stamp_script) "$@" +@AMDEP_TRUE@include $(DEPFL_STAMP_GVER) + +stamp-opts: + @target="$(AUTOGEN_stamp_opts_TList)" \ + $(MAKE_STAMP) + +stamp-proto: + @target="$(AUTOGEN_stamp_proto_TList)" \ + $(MAKE_STAMP) + +stamp-parse: + @target="$(AUTOGEN_stamp_parse_TList)" \ + $(MAKE_STAMP) + +stamp-cgi: + @target="$(AUTOGEN_stamp_cgi_TList)" \ + $(MAKE_STAMP) + +stamp-pseudo: + @target="$(AUTOGEN_stamp_pseudo_TList)" \ + $(MAKE_STAMP) + +stamp-exprini: + @target="$(AUTOGEN_stamp_exprini_TList)" \ + $(MAKE_STAMP) + +stamp-directive: + @target="$(AUTOGEN_stamp_directive_TList)" \ + $(MAKE_STAMP) + +stamp-texi: + @target="$(AUTOGEN_stamp_texi_TList)" \ + $(MAKE_STAMP) + +stamp-ag_text: + @target="$(AUTOGEN_stamp_ag_text_TList)" \ + $(MAKE_STAMP) + +stamp-fmem: + @target="$(AUTOGEN_stamp_fmem_TList)" \ + $(MAKE_STAMP) + +stamp-man: + @target="$(AUTOGEN_stamp_man_TList)" \ + $(MAKE_STAMP) + +stamp-func: + @target="$(AUTOGEN_stamp_func_TList)" \ + $(MAKE_STAMP) + +stamp-gver: + @target="$(AUTOGEN_stamp_gver_TList)" \ + $(MAKE_STAMP) +.PHONY: stamps +stamps: $(list_stamps) + +# end-generated-text +# end of Makefile.am + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/agen5/ag-text.c b/agen5/ag-text.c new file mode 100644 index 0000000..47cfca5 --- /dev/null +++ b/agen5/ag-text.c @@ -0,0 +1,753 @@ +/* -*- buffer-read-only: t -*- vi: set ro: + * + * DO NOT EDIT THIS FILE (ag-text.c) + * + * It has been AutoGen-ed + * From the definitions /u/bkorb/tools/ag/autogen-bld/agen5/ag-text.def + * and the template file strings + * + * Copyright (C) 2011-2018 Bruce Korb, all rights reserved. + * This is free software. It is licensed for use, modification and + * redistribution under the terms of the + * Modified (3 clause) Berkeley Software Distribution License + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name ``Bruce Korb'' nor the name of any other + * contributor may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * strings IS PROVIDED BY Bruce Korb ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL Bruce Korb OR ANY OTHER CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "ag-text.h" + +char const ag_text_strtable[16331] = +/* 0 */ "ag-text.c\0" +/* 10 */ "The '%d' address family cannot be handled\0" +/* 52 */ "%s__\0" +/* 57 */ "%s=1\0" +/* 62 */ "ABEND-ing in %s state\n\0" +/* 85 */ "processing template %s\n" + " on line %d\n" + " for function %s (%d)\n\0" +/* 160 */ "ag-fprintf: 'port' is invalid\0" +/* 190 */ "AUTOGEN_MAKE_DEP\0" +/* 207 */ "autogen5\0" +/* 216 */ "AutoGen caught signal %d (%s) before initialization completed\n\0" +/* 279 */ "AutoGen aborting on signal %d (%s) in state %s\n\0" +/* 327 */ "Scheme definition expression does not yield string:\n\0" +/* 380 */ "Scheme Computed Definitions\0" +/* 408 */ "(alist->autogen-def %s)\0" +/* 432 */ "could not allocate for or formatting failed on:\n" + "%s\0" +/* 483 */ "asprintfv returned 0x%08X\n\0" +/* 510 */ "%s Error: Invalid input char '%c' in %s on line %d\n\0" +/* 562 */ "Cannot %s from outside a loop\0" +/* 592 */ "Could not resolve macro name: '%s'\0" +/* 627 */ "??? indecipherable error message ???\0" +/* 664 */ "Ill formed name '%s' in %s line %d\n\0" +/* 700 */ "Invalid regular expression: error %d (%s):\n" + "%s\0" +/* 747 */ "--base-name name is too long\0" +/* 776 */ "** BOGUS **\0" +/* 788 */ "break\0" +/* 794 */ "%lu\0" +/* 798 */ "fserr %d: cannot %s %s: %s\n\0" +/* 827 */ "duplicate make target\0" +/* 849 */ "unknown dependency type: %s\0" +/* 878 */ "Content-type: text/plain\n\n" + "AutoGen form processing error:\n\0" +/* 936 */ "CGI parsing error: %s\0" +/* 959 */ "/tmp/cgi-stderr-XXXXXX\0" +/* 982 */ "CLOSING SHELL SERVER - command failure:\n" + "\t%s\n\0" +/* 1027 */ "%s Error: %s in %s on line %d\n\0" +/* 1059 */ "DEFINITIONS %s in %s line %d for %s:\n" + "\t%s\n\0" +/* 1101 */ "Bad regular expression\0" +/* 1124 */ "continue\0" +/* 1133 */ "\\n\"\n" + " \"\0" +/* 1146 */ "from %s line %d\0" +/* 1162 */ "block\0" +/* 1168 */ "INVALID\0" +/* 1176 */ "text\0" +/* 1181 */ "unknown\0" +/* 1189 */ " \\\n\0" +/* 1193 */ "\n" + ".PHONY : clean-%1$s\n\n" + "clean-%1$s :\n" + "\trm -f %3$s $(%2$s_TList)\n" + "\t@-touch -t 199912312359 %1$s\n\0" +/* 1285 */ "\n" + "%2$s : $(%1$s_SList)\n\n" + "$(%1$s_TList) : %2$s\n" + "\t@:\n\0" +/* 1334 */ " \\\n" + "\t%s\0" +/* 1341 */ "DEPENDENCIES_OUTPUT\0" +/* 1361 */ "\n\n" + "%s_SList =\0" +/* 1374 */ "%s_TList =\0" +/* 1385 */ "/dev/null\0" +/* 1395 */ "baseless\0" +/* 1404 */ "-\0" +/* 1406 */ "=1\0" +/* 1409 */ "$@\0" +/* 1412 */ "$$/../share/autogen\0" +/* 1432 */ "\n" + "#\0" +/* 1435 */ "#assert yielded \"%s\":\n" + "\t`%s`\0" +/* 1463 */ "'#%s' directive encountered out of context\n" + "\tin %s on line %d\n\0" +/* 1525 */ "#error directive -- in %s on line %d\n" + "\t%s\n\0" +/* 1567 */ "open\0" +/* 1572 */ "read\0" +/* 1577 */ "def\0" +/* 1581 */ "WARNING: fserr %d (%s) performing '%s' on %s\n\0" +/* 1627 */ "Definition error: in %s line %d, #endif not found\n\0" +/* 1679 */ "Definition error: in %s line %d, #%s no matching start/if directive\n\0" +/* 1749 */ "Missing #endshell after '#shell' in %s on line %d\n\0" +/* 1800 */ "Computed Definitions\0" +/* 1821 */ "\n" + "#endshell\0" +/* 1832 */ "done_check done\n\0" +/* 1849 */ "done_check re-done\n\0" +/* 1869 */ "%s.%s\0" +/* 1875 */ "\n\n\0" +/* 1878 */ "%s ERROR: Too many definition files\n\0" +/* 1916 */ "%soutput was abandoned\n\0" +/* 1940 */ "%sBogus return from setjmp\n\0" +/* 1968 */ "content-type: text/html\n\n\0" +/* 1994 */ "* NONE *\0" +/* 2003 */ "Starting stdout template\n\0" +/* 2029 */ "stdout\0" +/* 2036 */ "invalid chars in suffix format: %s\0" +/* 2072 */ "Empty suffix format\0" +/* 2092 */ "Duplicate value index for %s: %d\0" +/* 2126 */ "#elif directive found out of context\0" +/* 2163 */ "invalid emission port: %lu\0" +/* 2190 */ "*/\0" +/* 2193 */ "ERROR\0" +/* 2199 */ "Error in template %s, line %d\n" + "\t\0" +/* 2231 */ "attempted to use block macro in eval expression\0" +/* 2279 */ "PROGRAM ERROR: ambiguous expr code\0" +/* 2315 */ "exit_cleanup %s done\n" + "===AutoGen ends - %u\n\n\0" +/* 2359 */ "false\0" +/* 2365 */ "exit_cleanup re-done\n\0" +/* 2387 */ "no waiting\0" +/* 2398 */ "(if (> (string-length shell-cleanup) 0) (shellf \"( (%s) & >/dev/null 2>&1 )\" shell-cleanup) )\0" +/* 2492 */ "waited\0" +/* 2499 */ "an unknown license\0" +/* 2518 */ "%6$s%1$sDO NOT EDIT THIS FILE (%2$s)\n" + "%1$s\n" + "%1$sIt has been AutoGen-ed%3$s\n" + "%1$sFrom the definitions %4$s\n" + "%1$sand the template file %5$s\0" +/* 2659 */ "%s -*- buffer-read-only: t -*- vi: set ro:\n" + "%s\n\0" +/* 2706 */ "%6$s%1$sEDIT THIS FILE WITH CAUTION (%2$s)\n" + "%1$s\n" + "%1$sIt has been AutoGen-ed%3$s\n" + "%1$sFrom the definitions %4$s\n" + "%1$sand the template file %5$s\0" +/* 2852 */ "WARNING: in %s on line %d unknown directive:\n" + "\t#%s\n\0" +/* 2904 */ "DO NOT CHANGE THIS COMMENT\0" +/* 2931 */ "name not followed by '='\0" +/* 2956 */ "no space separating entries\0" +/* 2984 */ "END \0" +/* 2990 */ "START\0" +/* 2996 */ "# %2$d \"%1$s\"\0" +/* 3010 */ "failed\n\0" +/* 3018 */ "SUCCESS\n\0" +/* 3027 */ ".\0" +/* 3029 */ "%s/%s\0" +/* 3035 */ "find-file\0" +/* 3045 */ "agpl\0" +/* 3050 */ "read full file\0" +/* 3065 */ "invalid license file: %s\0" +/* 3090 */ "lgpl\0" +/* 3095 */ "mbsd\0" +/* 3100 */ "stat file\0" +/* 3110 */ "lic\0" +/* 3114 */ "macros cannot nest\0" +/* 3133 */ "macro has no end\0" +/* 3150 */ "WARNING: empty macro in %s line %d\n\0" +/* 3186 */ " -- DEBUG %s -- FOR index %d\0" +/* 3217 */ "%d (%s) is an unknown macro function, or has no handler\0" +/* 3273 */ "? Say, what ?\0" +/* 3287 */ " (%c)\0" +/* 3293 */ "ELSE clause\0" +/* 3305 */ "FOR x IN ... has no list\0" +/* 3330 */ "_GUARD\0" +/* 3337 */ " - FOR-%s %s[%d] it#%d: Nxt %d, first=%s, last=%s\n\0" +/* 3390 */ "'get' invoked with no name in %s line %u\n\0" +/* 3432 */ "'get %s' retrieved in %s line %u\n\0" +/* 3466 */ "Failing Guile command: = = = = =\n\n" + "%s\n\n" + "=================================\n\0" +/* 3540 */ "Could not decipher Guile version: %s\n\0" +/* 3578 */ "Compiled Guile version does not match: %s vs %s\n\0" +/* 3627 */ "GUILE_WARN_DEPRECATED\0" +/* 3649 */ "GUILE_WARN_DEPRECATED=no\0" +/* 3674 */ "els\0" +/* 3678 */ "the\0" +/* 3682 */ "Invalid template file\0" +/* 3704 */ "SHELL=\0" +/* 3711 */ "lse\0" +/* 3715 */ "ndif\0" +/* 3720 */ "fdef \0" +/* 3726 */ "fndef \0" +/* 3733 */ "HEADER\0" +/* 3740 */ "Unterminated HereString\0" +/* 3764 */ "HereString missing the mark\0" +/* 3792 */ "&#%d;\0" +/* 3798 */ "(debug-enable 'backtrace)\0" +/* 3824 */ "HereString mark 64 or more chars\0" +/* 3857 */ "');\n" + "document.write('\" >%s');\n" + "//-->\n" + "\0" +/* 3906 */ ""; }; + +string = { nm = HIDE_EMAIL_START_STR; + str = " +_EOF_ + +export AUTOGEN_DNE_DATE=false + run_ag x ${testname}.def || failure autogen failed +cmp -s ${testname}.base ${testname}.test || \ + failure "`diff ${testname}.base ${testname}.test`" + +AUTOGEN_DNE_DATE=true + run_ag x ${testname}.def || failure autogen failed +dte=`sed -n 's/.*It has been AutoGen-ed *//p' ${testname}.test` +test "X${dte}" = "X" && \ + failure "expected a date on the 'It has been AutoGen-ed' line${nl}` + cat ${testname}.testln`" + +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## sh-basic-offset: 2 +## End: + +# end of format.test diff --git a/agen5/test/get.test b/agen5/test/get.test new file mode 100755 index 0000000..45b0d48 --- /dev/null +++ b/agen5/test/get.test @@ -0,0 +1,94 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# get.test --- test get functionality +# +# Author: Bruce Korb +## +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen 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. +## +## AutoGen is distributed in the hope that 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 . +## +# +# ---------------------------------------------------------------------- + +. ./defs + +# # # # # # # # # # TEMPLATE FILE # # # # # # # # # + +echo creating $testname.tpl +cat > $testname.tpl <<_EOF_ +[= AutoGen5 template test =] +[= + +IF (not (exist? "foo.bar.baz")) =][= + (error "foo.bar.baz does, too, exist!") =][= + +ELIF (not (= "mumble" (get "foo.bar.baz"))) =][= + (error (sprintf "We got the wrong baz. We got: %s" + (get "foo.bar.baz"))) =][= +ELSE + =]A OK[= +ENDIF =][= + +- bogus "\nA OK2" =][= +- foo "\nBOGUS" =] +[= (get "fuz-zy") =] +[= (get "fuz_zy") =] +[= (get "fuz^zy") =] +[= (get-c-name "fuz-zy") =] +[= (get-up-name "fuz-zy") =] +[= (get-down-name "fuz-zy") =] +_EOF_ + +# # # # # # # # # # DEFINITIONS FILE # # # # # # # # # + +echo creating $testname.def +cat > $testname.def <<_EOF_ +AutoGen definitions $testname; + +foo = { bar = { nada = nothing; }; }; +foo = { bar = { baz = mumble; }; }; /* this is the one */ +foo = { bar = { baz = grumble; }; }; +fuz-zy = Mum-Ble; +_EOF_ + +# # # # # # # # # # EXPECTED OUTPUT FILE # # # # # # # +set -x +echo creating $testname.out +# this is the output we should expect to see +cat > $testname.out <<'_EOF_' +A OK +A OK2 +Mum-Ble +Mum-Ble +Mum-Ble +Mum_Ble +MUM_BLE +mum_ble +_EOF_ + +run_ag x $testname.def || failure autogen failed +cmp -s $testname.test $testname.out || failure unexpected output + +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## sh-basic-offset: 2 +## End: + +# end of get.test diff --git a/agen5/test/gperf.test b/agen5/test/gperf.test new file mode 100755 index 0000000..cb6a0aa --- /dev/null +++ b/agen5/test/gperf.test @@ -0,0 +1,94 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# gperf.test --- test functionality of `gperf' +# +# Author: Bruce Korb +## +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen 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. +## +## AutoGen is distributed in the hope that 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 . +# ---------------------------------------------------------------------- + +if gperf --version > /dev/null 2>&1 +then : +else + echo gperf functionality does not work without gperf >&2 + exit 0 +fi + +. ./defs + +# # # # # # # # # # TEMPLATE FILE # # # # # # # # # + +echo creating ${testname}.tpl +cat > ${testname}.tpl <<_EOF_ +<= AutoGen5 template test => +<= + +(if (not (make-gperf "${testname}" (stack "foo.bar"))) + (error "cannot make gperf")) =><= + +FOR foo "\n" =><= + + FOR bar => +<=bar=> yields: <=(gperf "${testname}" (get "bar"))=><= + ENDFOR =><= + +ENDFOR =><= +\`tar cf - .${testname}.* > ${testname}-prog.tar || \ + die 'cannot save gperf files'\`=><= +(out-push-new "${testname}-code.c") +(emit (gperf-code "${testname}")) (emit "\n") +(out-pop) +=> +_EOF_ + + +# Create the files we need in the test environment +cat > ${testname}.def <<_EOF_ +AutoGen Definitions ${testname}; +foo = { bar = first; bar = second; }; +foo = { bar = third; bar = fourth; }; +_EOF_ + +# this is the output we should expect to see +cat > ${testname}.base <<_EOF_ + +first yields: 0x01 +second yields: 0x02 + +third yields: 0x03 +fourth yields: 0x04 +_EOF_ + +if ${VERBOSE:-false} +then opts="x --trace=server-shell ${testname}.def" +else opts="x ${testname}.def" +fi + +run_ag ${opts} || failure AutoGen failed +cmp -s ${testname}.base ${testname}.test || \ + failure "`diff ${testname}.base ${testname}.test`" + +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## sh-basic-offset: 2 +## End: + +# end of gperf.test diff --git a/agen5/test/heredef.test b/agen5/test/heredef.test new file mode 100755 index 0000000..8e8f06f --- /dev/null +++ b/agen5/test/heredef.test @@ -0,0 +1,101 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# heredef.test --- definition reference testing +# +# Author: Bruce Korb +## +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen 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. +## +## AutoGen is distributed in the hope that 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 . +## +# +# ---------------------------------------------------------------------- + +. ./defs + +# # # # # # # # # # TEMPLATE FILE # # # # # # # # # + +${SED} 's/^ *[0-9]*: //' > ${testname}.tpl <<\_EOF_ + 1: <= AutoGen5 template test => + 2: <= + 3: + 4: (if (not (= (get "string1") (get "string2"))) + 5: (error (sprintf "`%s' <> `%s'" + 6: (get "string1") (get "string2") )) ) + 7: + 8: =><= + 9: +10: (if (not (= (get "string2") (get "string3"))) +11: (error (sprintf "`%s' <> `%s'" +12: (get "string1") (get "string2") )) ) +13: =>OKAY: <= (c-string (get "string3")) => +14: FROM: string1 extracted <= (def-file-line "string1") => +15: string2 extracted +16: <= (def-file-line "string2" c-file-line-fmt) => +17: string3 extracted <= +18: (def-file-line "string3" "From %1$s on line %2$d") => +_EOF_ + +# # # # # # # # # # SAMPLE FILE # # # # # # # # # +cat > ${testname}.sample <<\_EOF_ +OKAY: "\"`Testing'" +FROM: string1 extracted from heredef.def line 11 + string2 extracted +#line 15 "heredef.def" + + string3 extracted From heredef.def on line 18 +_EOF_ + +# # # # # # # # # # DEFINITIONS FILE # # # # # # # # # + +# Create the files we need in the test environment +echo "AutoGen definitions ${testname};" > ${testname}.def +${SED} 's/^ *[0-9]*: //' >> ${testname}.def <<\_EOF_ + 2: #ifdef BOGUS + 3: /* Line 3 */ + 4: #else + 5: #ifdef WRONG + 6: /* line 6 */ + 7: #endif + 8: #endif + 9: /* line 9 */ +10: string1 = <<- AG_EOF +11: "`Testing' +12: AG_EOF; /* " */ +13: /* line 13 */ +14: string2 = <<- AG_EOF +15: "`Testing' +16: AG_EOF; /* " */ +17: +18: string3 = "\"`Testing'"; /* line 18 */ +19: +_EOF_ + +run_ag x ${testname}.def || failure ${testname} AutoGen failed + +if cmp ${testname}.test ${testname}.sample +then cleanup +else failure "`diff ${testname}.sample ${testname}.test`" +fi + + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## sh-basic-offset: 2 +## End: + +# end of heredef.test diff --git a/agen5/test/html.test b/agen5/test/html.test new file mode 100755 index 0000000..6a81a71 --- /dev/null +++ b/agen5/test/html.test @@ -0,0 +1,129 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# ---------------------------------------------------------------------- +# html.test --- test html generation +# +# Author: Bruce Korb +## +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen 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. +## +## AutoGen is distributed in the hope that 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 . +## +# +# ---------------------------------------------------------------------- + +. ./defs + +# # # # # # # # # # TEMPLATE FILES # # # # # # # # # + +echo creating cgi.tpl +cat > cgi.tpl <<'_EOF_' + +HTTP/1.0 500 AutoGen Forms Error +Content-Type: text/plain + +The submitted form does not contain a valid template () . +_EOF_ + +echo creating ${testname}.tpl +cat > ${testname}.tpl <<'_EOF_' + +Mumble: +Foolish: +_EOF_ + +# # # # # # # SAMPLE OUTPUT FILE # # # # # # + +echo creating ${testname}.out in `pwd` +# this is the output we should expect to see +cat > ${testname}.samp <<'_EOF_' +content-type: text/html + +Mumble: fumble bumble +Foolish: bar +_EOF_ + +# # # # # # # RUN AUTOGEN # # # # # # + +REQUEST_METHOD=GET +QUERY_STRING="mumble=fumble+bumble&foo=bar&template=${testname}" +CONTENT_LENGTH=`expr "${QUERY_STRING}" : ".*"` + +export CONTENT_LENGTH REQUEST_METHOD QUERY_STRING + +run_ag x1 | ${EGREP} -v '^in state' > ${testname}.test + +cmp -s ${testname}.samp ${testname}.test || \ + failure "`diff ${testname}.samp ${testname}.test`" + +# # # # # # # SECOND RUN # # # # # # + +QUERY_STRING="${QUERY_STRING}&break=true" +CONTENT_LENGTH=`expr "${QUERY_STRING}" : ".*"` + +run_ag x2 > ${testname}-2.test +fgrep 'AutoGen form processing error' ${testname}-2.test || \ + failure autogen unexpectedly succeeded + +cat > ${testname}-2.samp <<'_EOF_' +Content-type: text/plain + +AutoGen form processing error: +cgi.tpl:9:22: In expression (define foo bogus): +cgi.tpl:9:22: Unbound variable: bogus +Scheme evaluation error. AutoGen ABEND-ing in template + cgi.tpl on line 9 +Failing Guile command: = = = = = + +(define foo "") + (if (exist? "break") (set! foo bogus)) + +================================= +_EOF_ +${EGREP} -v '^in state' ${testname}-2.test > ${testname}-2.res +cmp -s ${testname}-2.samp ${testname}-2.res || { + exec >&2 + echo Your Guile library does not handle error traps correctly and causes + echo garbage to be emitted instead. Do not use this autogen as a CGI service. +} + +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## sh-basic-offset: 2 +## End: + +# end of html.test diff --git a/agen5/test/in.test b/agen5/test/in.test new file mode 100755 index 0000000..79bca0c --- /dev/null +++ b/agen5/test/in.test @@ -0,0 +1,94 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# ---------------------------------------------------------------------- +# in.test --- Verify that the "in?" predicate works +# +# Author: Bruce Korb +## +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen 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. +## +## AutoGen is distributed in the hope that 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 . +## +# +# ---------------------------------------------------------------------- + +. ./defs + +# # # # # # # # # # TEMPLATE FILE # # # # # # # # # + +echo creating ${testname}.tpl +cat > ${testname}.tpl <<_EOF_ +[++ AutoGen5 template out ++][++ + +(define stack-list (stack "foo.bar")) +(string-append + (if (in? (get "baz") stack-list) "success" "FAIL") + "\n" + (if (in? (get "oops") stack-list) "FAIL" "success") +) ++][++ + +IF .true ++] +success[++ +ELSE ++] +FAILURE[++ +ENDIF ++]-[++ .true ++][++ + +IF .false ++] +FAILURE[++ +ELSE ++] +success[++ +ENDIF ++]-[++ .false ++] +_EOF_ + +# # # # # # # # # # DEFINITIONS FILE # # # # # # # # # + +echo creating ${testname}.def +cat > ${testname}.def <<_EOF_ +AutoGen definitions ${testname}; +foo = { bar = one; }; +foo = { bar = two; }; +foo = { bar = three; }; +foo = { bar = four; }; +baz = three; +oops = oops; +true = true; +false = false; +_EOF_ + +# # # # # # # # # # EXPECTED OUTPUT FILE # # # # # # # +set -x +echo creating ${testname}.ok +# this is the output we should expect to see +cat > ${testname}.ok <<'_EOF_' +success +success +success-true +success-false +_EOF_ + +run_ag x ${testname}.def || failure autogen failed +cmp -s ${testname}.ok ${testname}.out || \ + failure "`diff ${testname}.ok ${testname}.test`" + +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## sh-basic-offset: 2 +## End: + +# end of in.test diff --git a/agen5/test/include.test b/agen5/test/include.test new file mode 100755 index 0000000..1bc484d --- /dev/null +++ b/agen5/test/include.test @@ -0,0 +1,79 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# include.test --- test include functionality +# +# Author: Bruce Korb +## +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen 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. +## +## AutoGen is distributed in the hope that 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 . +## +# +# ---------------------------------------------------------------------- + +. ./defs + +# # # # # # # # # # TEMPLATE FILE # # # # # # # # # + +echo creating ${testname}.in +cat > ${testname}.in <<_EOF_ +<= AutoGen5 Template +# this is just a test +test => +<= v-name =>: <= \`echo This is an ${testname} test\` => +_EOF_ + +echo creating ${testname}.tpl +cat > ${testname}.tpl <<_EOF_ +[= AutoGen5 Template +# this is just a test + +test =] +[= Include "${testname}.in" =] +_EOF_ + +mkdir ${testname}.d ${testname}.d/good +cat > ${testname}.d/${testname}.def <<- _EOF_ + AutoGen Definitions ${testname}.tpl; + #include good/${testname}-aux.def + _EOF_ + +echo "v-name = Verify;" > ${testname}.d/good/${testname}-aux.def + +# # # # # # # # # # EXPECTED OUTPUT FILE # # # # # # # + +echo creating ${testname}.ok +# this is the output we should expect to see +cat > ${testname}.ok <<_EOF_ +Verify: This is an ${testname} test +_EOF_ + +AGCMD="-L ${testname}.d/bad -L ${testname}.d/bad/good" + +run_ag x ${AGCMD} ${testname}.d/${testname}.def || \ + failure ${AGCMD} failed +cmp -s ${testname}.test ${testname}.ok || \ + failure "unexpected output + `diff -u ${testname}.test ${testname}.ok `" +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## sh-basic-offset: 2 +## End: + +# end of include.test diff --git a/agen5/test/leave.test b/agen5/test/leave.test new file mode 100755 index 0000000..bf25b23 --- /dev/null +++ b/agen5/test/leave.test @@ -0,0 +1,104 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# leave.test --- test return/next/break functionality +# +# Author: Bruce Korb +## +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen 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. +## +## AutoGen is distributed in the hope that 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 . + +. ./defs + +# # # # # # # # # # TEMPLATE FILES # # # # # # # # # + +echo creating $testname.tlib +cat > $testname.tlib <<'_EOF_' +[= AutoGen5 Template test =] +[= RETURN =] +BOGUS +_EOF_ + +echo creating $testname.tpl +cat > $testname.tpl <<_EOF_ +[= AutoGen5 Template test =] +[= +INVOKE macro +=][= +DEFINE macro =][= + +FOR value =][= + IF (= 1 (for-index)) =][= BREAK =][= ENDIF =] +BOGUS +[= ENDFOR =][= + +FOR value =][= + CASE (for-index) =][= + == 4 =][= + * =][= CONTINUE =][= + ESAC =][= (for-index) =] Okay.[= + INCLUDE "$testname.tlib" =][= + + RETURN \=] + +BOGUS +[= ENDFOR =][= ENDDEF =] +_EOF_ + + +# # # # # # # # # # DEFINITIONS FILE # # # # # # # # # + +echo creating $testname.def +cat > $testname.def <<_EOF_ +autogen definitions $testname; + +value[1] = first; +value[2] = secondary; +value[4] = tertiary; +value[6] = last; + +_EOF_ + +# this is the output we should expect to see +echo 4 Okay. > $testname.samp + +run_ag x $testname.def || \ + failure "autogen failed" +set -x +cmp -s $testname.samp $testname.test || \ + failure "`diff $testname.samp $testname.test`" + +# # # # # # # # # # TEMPLATE FILES # # # # # # # # # + +echo creating $testname.tlib +cat > $testname.tlib <<'_EOF_' +[= AutoGen5 Template test =] +[= BREAK =] +BOGUS +_EOF_ + +run_ag x -b $testname-bad $testname.def 2>/dev/null && \ + failure "processed broken template" + +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## sh-basic-offset: 2 +## End: + +# end of leave.test diff --git a/agen5/test/license.test b/agen5/test/license.test new file mode 100755 index 0000000..1b78940 --- /dev/null +++ b/agen5/test/license.test @@ -0,0 +1,113 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# license.test --- test license functionality +# +# Author: Bruce Korb +## +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen 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. +## +## AutoGen is distributed in the hope that 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 . +## +# +# ---------------------------------------------------------------------- + +. ./defs + +# # # # # # # # # # TEMPLATE FILE # # # # # # # # # + +echo creating ${testname}.tpl +cat > ${testname}.tpl <<_EOF_ +[= AutoGen5 template test =] +/* +[= (license "${testname}" "${testname}" "Auto-Gen" " * " ) =] + */ +_EOF_ + +# # # # # # # # # # LICENSE FILE # # # # # # # # # + +echo creating ${testname}.lic +cat > ${testname}.lic <<'_EOF_' +This is a bogus license granted by %2$s for %1$s. +Use it in good health +_EOF_ + +# # # # # # # # # # EXTEND FILES TO PAGESIZE # # # # # # # # # + +cat > ${testname}-extend.c <<- _EOF_ + #define HAVE_CONFIG_H 1 + #include "config.h" + #include "compat/compat.h" + + int main( int argc, char** argv ) { + char z_tail[] = "=]\n */\n"; + long offset = 0L - (sizeof(z_tail) - 1); + struct stat sb; + char* file; + size_t sz; + FILE* fp; + + file = *++argv; + fp = fopen(file, "a"); + if (fp == NULL) return 1; + if (stat(file, &sb) != 0) return 1; + sz = 0x2000 - (sb.st_size & 0x1FFFUL); + while (sz > 0) { putc( '\n', fp ); sz--; } + fclose(fp); + + file = *++argv; + fp = fopen( file, "r+" ); + if (fp == NULL) return 1; + if (stat(file, &sb) != 0) return 1; + fseek(fp, offset, SEEK_END); + sz = 0x2000 - (sb.st_size & 0x1FFFUL); + while (sz > 0) { putc( '\n', fp ); sz--; } + fputs(z_tail, fp); + fclose(fp); + + return 0; } + _EOF_ + +Csrc=${testname}-extend +compile + +./${testname}-extend ${testname}.lic ${testname}.tpl || \ + failure "Could not extend license/template files to 8KB" +ls -l ${testname}.??? + +# # # # # # # # # # EXPECTED OUTPUT FILE # # # # # # # +set -x +echo creating ${testname}.out +# this is the output we should expect to see +cat > ${testname}.out <<_EOF_ +/* + * This is a bogus license granted by Auto-Gen for ${testname}. + * Use it in good health + */ +_EOF_ + +run_ag x -b ${testname} --no-def -T ${testname}.tpl || \ + failure autogen failed +cmp -s ${testname}.test ${testname}.out || failure unexpected output + +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## sh-basic-offset: 2 +## End: + +# end of license.test diff --git a/agen5/test/line.test b/agen5/test/line.test new file mode 100755 index 0000000..53f4f84 --- /dev/null +++ b/agen5/test/line.test @@ -0,0 +1,67 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# line.test --- test (tpl-file-line) functionality +# +# Author: Bruce Korb +## +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen 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. +## +## AutoGen is distributed in the hope that 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 . +## +# ---------------------------------------------------------------------- + +. ./defs + +# # # # # # # # # # TEMPLATE FILE # # # # # # # # # + +echo creating ${testname}.tpl +${SED} 's/^ *[0-9]*: //' > ${testname}.tpl << _EOTPL_ + 1: [= AutoGen5 Template txt =] + 2: ${testname} Test + 3: [= (define ix 0) (define ct 63) =] + 4: [=WHILE (< ix ct) \=] + 5: [= (set! ix (+ ix 1)) + 6: (sprintf "test %2d of %2d: %s\n" ix ct (tpl-file-line "%2\$d")) + 7: \=] + 8: [=ENDWHILE \=] + 9: End ${testname} Test +_EOTPL_ + +# # # # # # # # # # EXPECTED OUTPUT FILE # # # # # # # +set -x +echo creating ${testname}.out +# this is the output we should expect to see +cat > ${testname}.out <<- \_EOF_ + line Test + + End line Test + _EOF_ + +run_ag x --base=${testname} --no-def --override=${testname}.tpl || \ + failure autogen failed +${EGREP} -v ' of 63: 5$' ${testname}.txt > ${testname}.test + +cmp -s ${testname}.test ${testname}.out || failure unexpected output + +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## sh-basic-offset: 2 +## End: + +# end of line.test diff --git a/agen5/test/loop.test b/agen5/test/loop.test new file mode 100755 index 0000000..6649db9 --- /dev/null +++ b/agen5/test/loop.test @@ -0,0 +1,77 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# loop.test --- test FOR loop +# +# Author: Bruce Korb +## +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen 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. +## +## AutoGen is distributed in the hope that 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 . +## +# +# ---------------------------------------------------------------------- + +. ./defs + +# # # # # # # # # # TEMPLATE FILE # # # # # # # # # + +echo creating ${testname}.tpl +limit=32 +cat > ${testname}.tpl <<- _EOTPL_ + [= AutoGen5 Template test =] + ${testname} Test + [= (define ix 0) (define ct ${limit}) =][= + + WHILE (< ix ct) =][= + (set! ix (+ ix 1)) =][= + (sprintf "test %2d of %2d: %s\n" + ix ct (tpl-file-line "%2\$d")) =][= + ENDWHILE + + =]End ${testname} Test + _EOTPL_ + +# # # # # # # # # # EXPECTED OUTPUT FILE # # # # # # # +set -x +echo creating ${testname}.base + +# this is the output we should expect to see +# +exec 3> ${testname}.base +echo "${testname} Test" >&3 +ix=1 +while test $ix -le $limit +do printf "test %2d of ${limit}: 7\n" $ix + ix=`expr $ix + 1` +done >&3 +echo "End ${testname} Test" >&3 +exec 3>&- + +run_ag x --base=${testname} --no-def --override=${testname}.tpl || \ + failure autogen failed + +cmp -s ${testname}.base ${testname}.test || \ + failure "unexpected output: `diff ${testname}.base ${testname}.test`" + +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## sh-basic-offset: 2 +## End: + +# end of loop.test diff --git a/agen5/test/make.test b/agen5/test/make.test new file mode 100755 index 0000000..c1572b8 --- /dev/null +++ b/agen5/test/make.test @@ -0,0 +1,90 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# make.test --- test makefile script manufacture +# +# Author: Bruce Korb +## +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen 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. +## +## AutoGen is distributed in the hope that 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 . +## +# +# ---------------------------------------------------------------------- + +. ./defs + +# # # # # # # # # # TEMPLATE FILE # # # # # # # # # + +echo creating ${testname}.tpl +cat > ${testname}.tpl <<'_EOF_' +[= AutoGen5 Template + +=] +== This source: +[= + + (out-push-new) + +=] +foo=`pwd` && ls -l $foo +bar=$foo continue=command \ +make macros: $(MAKE) $* $@ $< $% $? +shell vars: ${MAKE} $# $F ${?} ${*} $$ +[= +(define txt (out-pop #t)) +(string-append txt "\n== converts to:\n\n" (makefile-script txt)) +=] +_EOF_ + +# # # # # # # SAMPLE OUTPUT FILE # # # # # # + +echo creating ${testname}.out in `pwd` +# this is the output we should expect to see +cat > ${testname}.samp <<'_EOF_' +== This source: + +foo=`pwd` && ls -l $foo +bar=$foo continue=command \ +make macros: $(MAKE) $* $@ $< $% $? +shell vars: ${MAKE} $# $F ${?} ${*} $$ + +== converts to: + + foo=`pwd` && ls -l $$foo ; \ + bar=$$foo continue=command \ + make macros: $(MAKE) $* $@ $< $% $? ; \ + shell vars: $${MAKE} $$# $$F $${?} $${*} $$$$ +_EOF_ + +# # # # # # # RUN AUTOGEN # # # # # # + +run_ag x -T ${testname}.tpl --no-def > ${testname}.test || \ + failure autogen failed + +# # # # # # # TEST RESULTS # # # # # # + +cmp -s ${testname}.samp ${testname}.test || \ + failure "`diff ${testname}.samp ${testname}.test`" + +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## sh-basic-offset: 2 +## End: + +# end of make.test diff --git a/agen5/test/match.test b/agen5/test/match.test new file mode 100755 index 0000000..f10f1b8 --- /dev/null +++ b/agen5/test/match.test @@ -0,0 +1,71 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# match.test --- test the "match-value?" scheme +# +# Author: Bruce Korb +## +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen 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. +## +## AutoGen is distributed in the hope that 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 . +## +# +# ---------------------------------------------------------------------- + +. ./defs + +# # # # # # # # # # TEMPLATE FILE # # # # # # # # # + +echo creating ${testname}.tpl +cat > ${testname}.tpl <<'_EOF_' +[= AutoGen5 Template test =] + ==* "sec" [= IF (match-value? ==* "foo.valu" "sec" ) + =]YES[=ELSE=]FAIL[=ENDIF=] + ==* "SEC" [= IF (match-value? ==* "foo.valu" "SEC" ) + =]FAIL[=ELSE=]YES[=ENDIF=] + *=* "rST" [= IF (match-value? *=* "foo.valu" "rST" ) + =]YES[=ELSE=]FAIL[=ENDIF=] + *==* "rST" [= IF (match-value? *==* "foo.valu" "rST" ) + =]FAIL[=ELSE=]YES[=ENDIF=] +_EOF_ + +# # # # # # # # # # DEFINITIONS FILE # # # # # # # # # + +echo creating ${testname}.def +cat > ${testname}.def <<_EOF_ +autogen definitions ${testname}.tpl; + +foo = { valu = first.0; valu = primary.0; }; +foo = { valu = first.1; valu = secondary.1; }; +foo = { valu = first.2; }; +foo = { valu = first.3; valu = tertiery.3; }; +_EOF_ + +# # # # # # # # # # EXPECTED OUTPUT FILE # # # # # # # + +run_ag x ${testname}.def || \ + failure could not generate output +${EGREP} FAIL ${testname}.test && \ + failure some ${testname} tests failed + +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## sh-basic-offset: 2 +## End: + +# end of match.test diff --git a/agen5/test/opts.test b/agen5/test/opts.test new file mode 100755 index 0000000..59f5679 --- /dev/null +++ b/agen5/test/opts.test @@ -0,0 +1,90 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# ---------------------------------------------------------------------- +# opts.test --- Verify the handling of options +# +# Author: Bruce Korb +## +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen 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. +## +## AutoGen is distributed in the hope that 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 . + +. ./defs + +# Fetch the options files +# +unstamp() +{ + # The "zDetail" and zCopyrightNotice text gets formatted with "fmt -w 75". + # The different "fmt" implementations behave differently. + # + ${SED} -e "${sed_omit_license}" \ + -e '/ extracted from.* line [1-9]/d' \ + -e '/static char const zDetail/,/";$/d' \ + -e '/static char const zCopyright/,/";$/d' \ + -e '/static char const zLicenseDescrip/,/";$/d' \ + -e '/ "autogen is free software: /,/www\.gnu\.org\/licenses/d' \ + $1 > $2 || + failure Cannot remove stamps from $1 +} + +workdir=`pwd` +rm -f ../VERSION ./opts.* || : + +cd ${top_srcdir}/agen5 +unstamp opts.c ${workdir}/opts.c.base +unstamp opts.h ${workdir}/opts.h.base +cp opts.def ${workdir}/. +cp -f ${top_srcdir}/VERSION ${workdir}/.. + +cd ${workdir} +set -x +ls -l * ../VERSION > $testname.log + +echo Checking for "'define DEBUG'" options +if ${GREP} 'define DEBUG' ${srcdir}/../opts.h +then + AGCMD="-DDEBUG=1" +else + AGCMD="" +fi + +run_ag x ${AGCMD} opts.def || { + rm -f ../VERSION + failure ${AGCMD} opts.def +} + +rm -f ../VERSION + +unstamp opts.c opts.c.res +echo diff opts.c.base opts.c.res +diff opts.c.base opts.c.res || \ + failure "`diff -c opts.c.base opts.c.res`" + +unstamp opts.h opts.h.res +echo diff opts.h.base opts.h.res +diff opts.h.base opts.h.res || \ + failure "`diff -c opts.h.base opts.h.res`" + +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## sh-basic-offset: 2 +## End: + +# end of opts.test diff --git a/agen5/test/output.test b/agen5/test/output.test new file mode 100755 index 0000000..1e0b9c9 --- /dev/null +++ b/agen5/test/output.test @@ -0,0 +1,119 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# include.test --- test include functionality +# +# Author: Bruce Korb +## +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen 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. +## +## AutoGen is distributed in the hope that 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 . +## +# +# ---------------------------------------------------------------------- + +. ./defs + +# # # # # # # # # # TEMPLATE FILE # # # # # # # # # + +echo creating $testname.tpl +cat > $testname.tpl <<'EOF' +<= AutoGen5 template test => +<=(out-push-new) + +=>This is sample output +<= `echo echoed text.` =><= +(out-suspend "here") +(out-push-new) +=>This text is from another diversion. +<= +(out-suspend "there") +=>This is the first output text. +<=(out-resume "here") +=> +Final text<= + +(define text (out-pop #t)) =><= + +DEFINE wrapper + +=>BEGIN +<=(out-resume "there") (out-pop #t) +=><= +(. text)=> +END<= + +ENDDEF wrapper =><= + +wrapper => +Done. +EOF + +# # # # # # # SAMPLE OUTPUT FILE # # # # # # + +echo creating $testname.out in `pwd` +# this is the output we should expect to see +cat > $testname.samp <<'EOF' +This is the first output text. +BEGIN +This text is from another diversion. +This is sample output +echoed text. +Final text +END +Done. +EOF + +# # # # # # # RUN AUTOGEN # # # # # # + +run_ag nodef -b $testname -T $testname.tpl --no-def || \ + failure autogen failed + +# # # # # # # TEST RESULTS # # # # # # + +cmp -s $testname.samp $testname.test || \ + failure "`diff $testname.samp $testname.test`" + +# # # # # # # EMPTY DEFINITIONS FILE # # # # # # + +cat > $testname.def < +## +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen 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. +## +## AutoGen is distributed in the hope that 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 . +## +# +# ---------------------------------------------------------------------- + +. ./defs + +# # # # # # # # # # TEMPLATE FILE # # # # # # # # # + +echo creating ${testname}.tpl +cat > ${testname}.tpl <<- \_EOF_ + [= AutoGen5 Template + + (define f-name "") + + h=(begin + (set! f-name (getenv "incdir")) + (if (not (string? f-name)) (set! f-name ".")) + (set! f-name (string-append f-name "/%s-hdr.%s")) + (shellf + "d=`dirname %s` + test -d ${d} || mkdir -p $d || die cannot mkdir $d" + f-name) + f-name + ) + + c=(begin + (set! f-name (getenv "srcdir")) + (if (not (string? f-name)) (set! f-name ".")) + (set! f-name (string-append f-name "/%s-body.%s")) + (shellf + "d=`dirname %s` + test -d ${d} || mkdir -p $d || die cannot mkdir $d" + f-name) + f-name + ) + + # end of pseudo + =] + [= + + (sprintf "two file create %s: " (suffix)) =][= + + CASE (suffix) =][= + + == h =]HEADER FILE[= + == c =]BODY 4 FILE[= + * =][= (error "woops") =][= + + ESAC =] + _EOF_ + +# # # # # # # # # # RUN TESTS # # # # # # # + +incdir=${testname}-inc +srcdir=${testname}-src + +export incdir srcdir + +run_ag x --no-def -T${testname}.tpl -b${testname} || \ + failure autogen --no-def -T${testname}.tpl -b${testname} + +f=${incdir}/${testname}-hdr.h +test -f ${f} || \ + failure missing file: ${f} +${FGREP} 'two file create h: HEADER FILE' ${f} || failure bad contents for $f + +f=${srcdir}/${testname}-body.c +test -f ${f} || \ + failure missing file: ${f} +${FGREP} 'two file create c: BODY 4 FILE' ${f} || failure bad contents for $f + +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## sh-basic-offset: 2 +## End: + +# end of pseudo.test diff --git a/agen5/test/reorder.test b/agen5/test/reorder.test new file mode 100755 index 0000000..ddb6e3c --- /dev/null +++ b/agen5/test/reorder.test @@ -0,0 +1,106 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# reorder.test --- test reorder functionality +# +# Author: Bruce Korb +## +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen 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. +## +## AutoGen is distributed in the hope that 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 . +## +# +# ---------------------------------------------------------------------- + +. ./defs + +# # # # # # # # # # TEMPLATE FILE # # # # # # # # # + +echo creating $testname.tpl +cat > $testname.tpl <<'_EOF_' +<= AutoGen5 template test => +From zero:<= + +FOR a (for-from 0) (for-by 1) (for-sep ",")=> +<=(sprintf "%5d: " (for-index))=><= + ?% elt %s absent =><= + IF (first-for?) => first loop<= ENDIF =><= + IF (last-for? ) => last loop<= ENDIF =><= +ENDFOR => + +From start by two:<= + +FOR a (for-by 2) (for-sep ",")=> +<=(sprintf "%5d: " (for-index)) =><= + ?% elt %s absent =><= + IF (first-for?) => first loop<= ENDIF =><= + IF (last-for? ) => last loop<= ENDIF =><= +ENDFOR => +_EOF_ + +# # # # # # # # # # DEFINITIONS FILE # # # # # # # # # + +echo creating $testname.def +cat > $testname.def <<_EOF_ +autogen definitions $testname; +a[ 3] = { elt = three; }; +a[ 5] = { elt = five; }; +a[12] = { elt = twelve; }; +a[ 8] = { elt = eight; }; +a[ 1] = { elt = one; }; +a[ 2] = { elt = two; }; +_EOF_ + +# # # # # # # # # # EXPECTED OUTPUT FILE # # # # # # # + +echo creating $testname.out +# this is the output we should expect to see +cat > $testname.out <<_EOF_ +From zero: + 0: absent first loop, + 1: one, + 2: two, + 3: three, + 4: absent, + 5: five, + 6: absent, + 7: absent, + 8: eight, + 9: absent, + 10: absent, + 11: absent, + 12: twelve last loop + +From start by two: + 1: one first loop, + 3: three, + 5: five, + 7: absent, + 9: absent, + 11: absent last loop +_EOF_ + +run_ag x $testname.def || failure autogen failed +cmp -s $testname.test $testname.out || failure unexpected output + +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## sh-basic-offset: 2 +## End: + +# end of reorder.test diff --git a/agen5/test/return.test b/agen5/test/return.test new file mode 100755 index 0000000..909de98 --- /dev/null +++ b/agen5/test/return.test @@ -0,0 +1,72 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# for.test --- test functionality of `for' function +# +# Author: Bruce Korb +## +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen 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. +## +## AutoGen is distributed in the hope that 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 . +## +# +# ---------------------------------------------------------------------- + +. ./defs + +# # # # # # # # # # TEMPLATE FILE # # # # # # # # # + +echo creating $testname.tpl +cat > $testname.tpl <<_EOF_ +[= AutoGen5 template test =] +[= INVOKE my-mac \=] +[= (if (exist? "list") (emit "ok")) =] +Done. +[= DEFINE my-mac \=] +[= FOR list \=] +[= IF (exist? "leave") \=] +[= RETURN \=] +[= ENDIF \=] +[= ENDFOR list \=] +[= ENDDEF my-mac \=] +_EOF_ + + +# Create the files we need in the test environment +cat > $testname.def <<_EOF_ +AutoGen definitions $testname; +list = { elt = one; }; +list = { leave; }; +_EOF_ + +# this is the output we should expect to see +cat > $testname.sample <<_EOF_ +ok +Done. +_EOF_ + +run_ag x $testname.def || failure AutoGen failed +cmp -s $testname.test $testname.sample || \ + failure "`diff -c $testname.test $testname.sample`" + +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## sh-basic-offset: 2 +## End: + +# end of for.test diff --git a/agen5/test/shell.test b/agen5/test/shell.test new file mode 100755 index 0000000..b750469 --- /dev/null +++ b/agen5/test/shell.test @@ -0,0 +1,164 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# shell.test --- test functionality of switching shells +# +# Author: Bruce Korb +## +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen 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. +## +## AutoGen is distributed in the hope that 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 . +## +# +# The test will verify that a real shell processes the declarations +# and our weirdo shell handles the template. +# +# ---------------------------------------------------------------------- + +exec 9>&2 + +. ./defs + +${FGREP} '#define SHELL_ENABLED ' ${top_builddir}/config.h > /dev/null 2>&1 +test $? -eq 0 || exit 0 + +# # # # # # # # # # TEMPLATE FILE # # # # # # # # # + +cat > ${testname}.c <<- \_EOF_ + #include + #include + #include + #define NUL '\0' + char buf[ 4096 ]; + int + main( int argc, char** argv ) + { + char *pz; + for (;;) { + pz = fgets(buf, sizeof(buf),stdin); + if (pz == NULL) + return 1; /* must get something every time */ + while (isspace(*pz)) pz++; + if (*pz != NUL) break; /* ignore initial blank lines */ + } + + for (;;) { + if (*pz == '#') goto next_line; + if (strncmp( pz, "cd ", 3 ) == 0) goto next_line; + if ((strncmp( pz, "echo", 4 ) == 0) && isspace( pz[4] )) { + pz += 5; + while (isspace(*pz)) pz++; /* suppress the 'echo' */ + } + if (*pz == '\0') pz--; /* always force a newline */ + fputs( pz, stdout ); + fflush( stdout ); + + next_line: + pz = fgets(buf, sizeof(buf),stdin); + if (pz == NULL) + break; + while (isspace(*pz)) pz++; + } + return 0; + } + _EOF_ + +compile + +# The backslashes are stripped by the here-doc processing +# +echo creating ${testname}.tpl +cat > ${testname}.tpl <<- _EOF_ + <= AutoGen5 template test + (setenv "SHELL" "./${testname}") => + <=\` echo SHELL=\$SHELL \`=> + Some <=dummy=> text + <= FOR foo => + foo[<=(for-index)=>] = <=foo=> + raw-shell-str: <=(raw-shell-str (get "foo"))=> + shell-str: <=(shell-str (get "foo"))=> + sub-shell-str: <=(sub-shell-str (get "foo"))=> + <= ENDFOR => + <=\` : This is a final test \`=> + _EOF_ + +echo creating ${testname}.def +cat >${testname}.def <<- \_EOF_ + AutoGen Definitions shell.tpl; + + foo = "''foo'' 'foo' \"foo\" `foo` $foo"; + foo = '\\\'bar\\\' \\"bar\\" \`bar\` \$bar'; + foo = '\\\\\'BAZ\\\\\' \\\\"BAZ\\\\" \\\`BAZ\\\` \\\$BAZ'; + dummy = `echo "mumble"`; /* processed with regular shell */ + _EOF_ + +# this is the output we should expect to see +cat > ${testname}.sample <<- \_EOF_ + SHELL=$SHELL + Some "mumble" text + + foo[0] = ''foo'' 'foo' "foo" `foo` $foo + raw-shell-str: \'\''foo'\'\'' '\''foo'\'' "foo" `foo` $foo' + shell-str: "''foo'' 'foo' \"foo\" `foo` $foo" + sub-shell-str: `''foo'' 'foo' "foo" \`foo\` $foo` + + foo[1] = \'bar\' \"bar\" \`bar\` \$bar + raw-shell-str: '\'\''bar\'\'' \"bar\" \`bar\` \$bar' + shell-str: "\\'bar\\' \\\"bar\\\" \`bar\` \$bar" + sub-shell-str: `\\'bar\\' \"bar\" \\\`bar\\\` \$bar` + + foo[2] = \\'BAZ\\' \\"BAZ\\" \\`BAZ\\` \\$BAZ + raw-shell-str: '\\'\''BAZ\\'\'' \\"BAZ\\" \\`BAZ\\` \\$BAZ' + shell-str: "\\\\'BAZ\\\\' \\\\\"BAZ\\\\\" \\\`BAZ\\\` \\\$BAZ" + sub-shell-str: `\\\\'BAZ\\\\' \\\"BAZ\\\" \\\\\`BAZ\\\\\` \\\$BAZ` + + : This is a final test + _EOF_ + +run_ag x --shell=$PWD/shell ${testname}.def || \ + failure "autogen ${testname}.def" + +${GREP} -v '^AGexe=' ${testname}.test > ${testname}.XX +mv -f ${testname}.XX ${testname}.test +if cmp -s ${testname}.test ${testname}.sample +then cleanup + exit 0 +fi + +if ${FGREP} 'SHELL=' ${testname}.test > /dev/null 2>&1 +then + if ${FGREP} 'SHELL=$SHELL' ${testname}.test > /dev/null 2>&1 + then : ; else + cat >&9 <<- _EOF_ + The ${testname}.test output file does not start with "SHELL=\$SHELL" + This is because you have a Guile library that cannot modify + the environment. This is a known breakage on some platforms + (viz., BSD derivatives). Sorry. + _EOF_ + ${FGREP} 'SHELL=' ${testname}.test >&9 + cleanup + exit 0 + fi +fi + +failure "`set +x;diff -c ${testname}.sample ${testname}.test`" + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## sh-basic-offset: 2 +## End: + +# end of shell.test diff --git a/agen5/test/snarf.test b/agen5/test/snarf.test new file mode 100755 index 0000000..30dea07 --- /dev/null +++ b/agen5/test/snarf.test @@ -0,0 +1,278 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# snarf.test --- test the extraction of scm-type definitions +# +# Author: Bruce Korb +## +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen 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. +## +## AutoGen is distributed in the hope that 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 . +## +# ---------------------------------------------------------------------- + +. ./defs + +# # # # # # # # # # SOURCE FILE # # # # # # # # # + +echo creating ${testname}.c +cat > ${testname}.c <<_EOF_ +#include "${testname}.h" +#include "${testname}.ini" +/*=gfunc test_to_example_x + * + * exparg: in, test input arg desc, optional, list + * +=*/ +SCM +test_scm_test_to_example_x(SCM in) +{ + return in; +} + +/*=symbol mumble_check + * + * init_val: SCM_BOOL_T +=*/ +/*=symbol bumble_it + * + * const_val: 100L + * global: +=*/ +/*=syntax guile_syntax_ele + * + * type: scm_makacro + * cfn: scm_m_undefine +=*/ +_EOF_ + +# # # # # # # # # # PROCESS SOURCE FILE # # # # # # # # # + +f=`echo ${AGexe} | ${SED} 's/ .*//'` + +agsrc=`cd $top_srcdir/agen5 && pwd` +tplsrc=`cd $top_srcdir/autoopts/tpl && pwd` + +cat > ${testname}.cfg <<- _EOF_ + subblock exparg=arg_name,arg_desc,arg_optional,arg_list + template snarf.tpl + srcfile + assign group = ${testname}_grp + assign init = Chosen_init + base-name ${testname} + agarg -L$agsrc + agarg -L$tplsrc + input ${testname}.c + autogen ${f} + _EOF_ +unset DEBUG_ENABLED + +echo "getdefs load=${testname}.cfg ${testname}.c" +${VERBOSE} && { + AUTOGEN_TRACE=everything + AUTOGEN_TRACE_OUT=">>${testname}-ag-log.txt" + export AUTOGEN_TRACE AUTOGEN_TRACE_OUT +} +${GDexe} load=${testname}.cfg || \ + failure getdefs load=${testname}.cfg + +${SED} -e "${sed_omit_license}" -e '/^#undef *NEW_PROC *$/,$d' \ + ${testname}.ini > ${testname}.ini.tst1 + +${SED} "${sed_omit_license}" ${testname}.h > ${testname}.h.tst1 + +# # # # # # # # # # EXPECTED INI FILE # # # # # # # # # + +echo creating ${testname}.ini.OK1 +cat > ${testname}.ini.OK1 <<'_EOF_' +/** \file snarf.ini + * + * Guile Initializations - snarf_grp Global Variables + */ +#include "snarf.h" +typedef SCM (*scm_callback_t)(void); +void Chosen_init(void); + +extern SCM snarf_grp_scm_sym_bumble_it = SCM_BOOL_F; +static SCM snarf_grp_scm_sym_mumble_check = SCM_BOOL_F; +#if GUILE_VERSION >= 108000 +#define NEW_PROC(_As, _Ar, _Ao, _Ax, _An) \ + scm_c_define_gsubr((char *)(_As), \ + _Ar, _Ao, _Ax, (scm_callback_t)VOIDP(ag_scm_ ## _An)) +#else +#define NEW_PROC(_As, _Ar, _Ao, _Ax, _An) \ + gh_new_procedure((char *)(_As), (scm_callback_t)VOIDP(ag_scm_ ## _An), \ + _Ar, _Ao, _Ax) +#endif + +/** + * snarf_grp Initialization procedure. + */ +void +Chosen_init(void) +{ +static char const g_nm[55] = +/* 0 */ "test->example!\0" +/* 15 */ "guile-syntax-ele\0" +/* 32 */ "bumble-it\0" +/* 42 */ "mumble-check"; + + NEW_PROC(g_nm + 0, 0, 0, 1, test_to_example_x); + scm_make_synt(g_nm+15, scm_makacro, scm_m_undefine); + snarf_grp_scm_sym_bumble_it = scm_permanent_object(SCM_CAR (scm_intern0 (g_nm+32))); + snarf_grp_scm_sym_mumble_check = scm_permanent_object(SCM_CAR (scm_intern0 (g_nm+42))); +} +_EOF_ + +cmp ${testname}.ini.tst1 ${testname}.ini.OK1 || \ + failure "`diff ${testname}.ini.tst1 ${testname}.ini.OK1`" + +# # # # # # # # # # EXPECTED HEADER FILE # # # # # # # + +echo creating ${testname}.h.OK +cat > ${testname}.h.OK <<_EOF_ +/** \file snarf.h + * Guile Implementation Routines - for the snarf_grp group + */ +#ifndef GUILE_PROCS_SNARF_H_GUARD +#define GUILE_PROCS_SNARF_H_GUARD 1 + +#if GUILE_VERSION >= 108000 +# include +#else +# include +#endif + +typedef enum { + GH_TYPE_UNDEFINED = 0, + GH_TYPE_BOOLEAN, + GH_TYPE_SYMBOL, + GH_TYPE_CHAR, + GH_TYPE_VECTOR, + GH_TYPE_PAIR, + GH_TYPE_NUMBER, + GH_TYPE_STRING, + GH_TYPE_PROCEDURE, + GH_TYPE_LIST, + GH_TYPE_INEXACT, + GH_TYPE_EXACT +} teGuileType; + +extern SCM snarf_grp_scm_test_to_example_x(SCM); +extern SCM snarf_grp_scm_sym_bumble_it; + +#endif /* GUILE_PROCS_SNARF_H_GUARD */ +_EOF_ + +cmp ${testname}.h.* || \ + failure "`diff ${testname}.h.*`" + +# # # # # # # # # # PROCESS SOURCE FILE AGAIN # # # # # # # # # + +cp ${testname}.cfg ${testname}.cfg1 + +echo 'assign debug-enabled = true' >> ${testname}.cfg +DEBUG_ENABLED=true +export DEBUG_ENABLED + +${GDexe} load=${testname}.cfg || \ + failure getdefs load=${testname}.cfg + +${SED} -e "${sed_omit_license}" \ + -e '/^#undef *NEW_PROC$/,$d' \ + ${testname}.ini > ${testname}.ini.tst2 + +${SED} "${sed_omit_license}" ${testname}.h > ${testname}.h.tst2 + +# # # # # # # # # # EXPECTED INI FILE # # # # # # # # # + +echo creating ${testname}.ini.OK2 +cat > ${testname}.ini.OK2 <<'_EOF_' +/** \file snarf.ini + * + * Guile Initializations - snarf_grp Global Variables + */ +#include "snarf.h" +typedef SCM (*scm_callback_t)(void); +void Chosen_init(void); + +extern SCM snarf_grp_scm_sym_bumble_it = SCM_BOOL_F; +static SCM snarf_grp_scm_sym_mumble_check = SCM_BOOL_F; +#ifdef DEBUG_ENABLED +static SCM +agrelay_scm_test_to_example_x(SCM scm0) +{ + if (OPT_VALUE_TRACE >= TRACE_EVERYTHING) { + static char const proc_z[] = + "Called ag_scm_test_to_example_x()\n"; + fwrite(proc_z, sizeof(proc_z) - 1, 1, trace_fp); + } + return ag_scm_test_to_example_x(scm0); +} + +#if GUILE_VERSION >= 108000 +#define NEW_PROC(_As, _Ar, _Ao, _Ax, _An) \ + scm_c_define_gsubr((char *)(_As), \ + _Ar, _Ao, _Ax, (scm_callback_t)VOIDP(agrelay_scm_ ## _An)) +#else +#define NEW_PROC(_As, _Ar, _Ao, _Ax, _An) \ + gh_new_procedure((char *)(_As), (scm_callback_t)VOIDP(agrelay_scm_ ## _An), \ + _Ar, _Ao, _Ax) +#endif + +#else /* DEBUG_ENABLED *not* */ +#if GUILE_VERSION >= 108000 +#define NEW_PROC(_As, _Ar, _Ao, _Ax, _An) \ + scm_c_define_gsubr((char *)(_As), \ + _Ar, _Ao, _Ax, (scm_callback_t)VOIDP(ag_scm_ ## _An)) +#else +#define NEW_PROC(_As, _Ar, _Ao, _Ax, _An) \ + gh_new_procedure((char *)(_As), (scm_callback_t)VOIDP(ag_scm_ ## _An), \ + _Ar, _Ao, _Ax) +#endif +#endif /* DEBUG_ENABLED */ + +/** + * snarf_grp Initialization procedure. + */ +void +Chosen_init(void) +{ +static char const g_nm[55] = +/* 0 */ "test->example!\0" +/* 15 */ "guile-syntax-ele\0" +/* 32 */ "bumble-it\0" +/* 42 */ "mumble-check"; + + NEW_PROC(g_nm + 0, 0, 0, 1, test_to_example_x); + scm_make_synt(g_nm+15, scm_makacro, scm_m_undefine); + snarf_grp_scm_sym_bumble_it = scm_permanent_object(SCM_CAR (scm_intern0 (g_nm+32))); + snarf_grp_scm_sym_mumble_check = scm_permanent_object(SCM_CAR (scm_intern0 (g_nm+42))); +} +_EOF_ + +cmp ${testname}.ini.tst2 ${testname}.ini.OK2 || \ + failure "`diff ${testname}.ini.tst2 ${testname}.ini.OK2`" + +cleanup + +## +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## sh-basic-offset: 2 +## End: + +# end of snarf.test diff --git a/agen5/test/stack.test b/agen5/test/stack.test new file mode 100755 index 0000000..299f349 --- /dev/null +++ b/agen5/test/stack.test @@ -0,0 +1,92 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# ---------------------------------------------------------------------- +# stack.test --- test stack and join functionality +# +# Author: Bruce Korb +## +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen 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. +## +## AutoGen is distributed in the hope that 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 . +## +# ---------------------------------------------------------------------- + +. ./defs + +# # # # # # # # # # TEMPLATE FILE # # # # # # # # # + +echo creating ${testname}.tpl +cat > ${testname}.tpl <<_EOF_ +[= AutoGen5 template test =] +[= + + (join ", " (stack "foo.bar.baz")) + +=] +[= + + (join ",\n" "one" "two" "three" "four" ) + +=] +[= + + (join ", " "foo" (stack "foo.bar.baz") "bar" "baz") + +=] +[= (string-substitute (join "\n" (stack "foo.bar.baz")) + '("umb" "le") '("_UMB_" "<=") ) =] +_EOF_ + +# # # # # # # # # # DEFINITIONS FILE # # # # # # # # # + +echo creating ${testname}.def +cat > ${testname}.def <<_EOF_ +AutoGen definitions ${testname}; + +foo = { bar = { baz = fumble; }; }; +foo = { bar = { baz = mumble; }; }; +foo = { bar = { baz = grumble; }; }; +_EOF_ + +# # # # # # # # # # EXPECTED OUTPUT FILE # # # # # # # +set -x +echo creating ${testname}.out +# this is the output we should expect to see +cat > ${testname}.out <<'_EOF_' +fumble, mumble, grumble +one, +two, +three, +four +foo, fumble, mumble, grumble, bar, baz +f_UMB_<= +m_UMB_<= +gr_UMB_<= +_EOF_ + +run_ag x ${testname}.def || failure autogen failed +cmp -s ${testname}.test ${testname}.out || \ + failure "`diff ${testname}.*t`" + +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## sh-basic-offset: 2 +## End: + +# end of stack.test diff --git a/agen5/test/str2m.test b/agen5/test/str2m.test new file mode 100755 index 0000000..23bdf63 --- /dev/null +++ b/agen5/test/str2m.test @@ -0,0 +1,415 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# str2m.test --- test str2enum and str2mask functionality +# +# Author: Bruce Korb +## +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen 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. +## +## AutoGen is distributed in the hope that 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 . +## +# +# ---------------------------------------------------------------------- + +. ./defs +gperf=`command -v gperf` +test -x "$gperf" || { + echo "$0 - cannot run without gperf installed" >&2 + exit 0 +} + +# # # # # # # # # # DEFINITIONS FILE # # # # # # # # # + +echo creating $testname.def +cat > $testname.def <<'_EOF_' +AutoGen Definitions str2enum; + +cmd[0] = one; +cmd[3] = three; +cmd[7] = seven; +cmd[11] = eleven; +cmd[19] = ninteen; + +type = kwd; +mask = { m-name = one-seven; m-bit = one, seven; }; +mask = { m-name = not-one-seven; m-bit = three, eleven, ninteen; m-invert; }; +_EOF_ + +cmd_list=`${SED} -n '/^cmd/{s/.*= *//;s/;//;p;}' $testname.def` +cmd_list=`echo $cmd_list` +# # # # # # # # # # EXPECTED OUTPUT FILES # # # # # # # + +echo creating $testname-h.base +# this is the output we should expect to see +cat > $testname-h.base <<- _EOF_ + typedef enum { + STR2M_INVALID_KWD = 0, + STR2M_KWD_ONE = 1, + STR2M_KWD_THREE = 4, + STR2M_KWD_SEVEN = 8, + STR2M_KWD_ELEVEN = 12, + STR2M_KWD_NINTEEN = 20, + STR2M_COUNT_KWD + } str2m_enum_t; + + extern str2m_enum_t + find_str2m_kwd(char const * str, size_t len); + + extern char const * + str2m_name(str2m_enum_t id); + + #endif /* STR2ENUM_STR2M_H_GUARD */ + _EOF_ + +cat > $testname-c.base <<- _EOF_ + * Convert a command (keyword) to a str2m_enum_t enumeration value. + * + * @param[in] str a string that should start with a known key word. + * @param[in] len the provided length of the keyword at \a str. + * @returns the enumeration value. + * If not found, that value is STR2M_INVALID_KWD. + */ + str2m_enum_t + find_str2m_kwd(char const * str, size_t len) + { + str2m_map_t const * map; + + map = find_str2m_name(str, (unsigned int)len); + return (map == NULL) ? STR2M_INVALID_KWD : map->str2m_id; + } + + /** + * Convert an str2m_enum_t value into a string. + * + * @param[in] id the enumeration value + * @returns the associated string, or "* UNDEFINED *" if \a id + * is out of range. + */ + char const * + str2m_name(str2m_enum_t id) + { + static char const undef[] = "* UNDEFINED *"; + static char const * const nm_table[] = { + [STR2M_KWD_ELEVEN ] = "eleven", + [STR2M_KWD_NINTEEN ] = "ninteen", + [STR2M_KWD_ONE ] = "one", + [STR2M_KWD_SEVEN ] = "seven", + [STR2M_KWD_THREE ] = "three" }; + char const * res = undef; + if (id < STR2M_COUNT_KWD) { + res = nm_table[id]; + if (res == NULL) + res = undef; + } + return res; + } + + /* end of str2m.c */ + _EOF_ + +# # # # # # # # # # RUN THE TEST # # # # # # # + +AGCMD="-L ${srcdir}/.. -L ${top_srcdir}/autoopts/tpl" +echo run_ag x ${AGCMD} $testname.def +run_ag x ${AGCMD} $testname.def || \ + failure ${AGCMD} failed + +get_h_text="/^typedef enum/,/#endif.*GUARD/p" +${SED} -n "${get_h_text}" $testname.h > $testname-h.res +fpair="$testname-h.base $testname-h.res" +cmp -s $fpair || \ + failure "$testname $fpair failed`echo + diff $fpair`" +get_c_text="/ Convert .*to a ${testname}_enum_t/,/end of $testname.c/p" +${SED} -n "${get_c_text}" $testname.c > $testname-c.res + +fpair="$testname-c.base $testname-c.res" +cmp -s $fpair || \ + failure "$testname $fpair failed`echo + diff $fpair`" + +# # # # # # # # # # OUTPUT FILES PART 2 # # # # # # # + +echo creating $testname-h2.base +TNAME=`echo $testname | tr '[a-z]' '[A-Z]'` +rep_name="s/${testname}/${testname}_2/g;s/${TNAME}/${TNAME}_2/g" +cat > $testname-h2.base <<- _EOF_ + #ifndef STR2ENUM_STR2M_2_H_GUARD + #define STR2ENUM_STR2M_2_H_GUARD 1 + #include + #include + + /** integral type for holding str2m_2 masks */ + typedef uint32_t str2m_2_mask_t; + + /** bits defined for str2m_2_mask_t */ + #define STR2M_2_KWD_ONE 0x00001U + #define STR2M_2_KWD_THREE 0x00008U + #define STR2M_2_KWD_SEVEN 0x00080U + #define STR2M_2_KWD_ELEVEN 0x00800U + #define STR2M_2_KWD_NINTEEN 0x80000U + + /** bits in ONE_SEVEN mask: + * one seven */ + #define STR2M_2_KWD_ONE_SEVEN_MASK 0x00081U + + /** bits omitted from NOT_ONE_SEVEN mask: + * three eleven ninteen */ + #define STR2M_2_KWD_NOT_ONE_SEVEN_MASK 0x00081U + + /** all bits in str2m_2_mask_t masks */ + #define STR2M_2_KWD_MASK_ALL 0x80889U + + /** no bits in str2m_2_mask_t */ + #define STR2M_2_KWD_EMPTY 0x00000U + + /** buffer size needed to hold all bit names for str2m_2_mask_t masks */ + #define MAX_STR2M_2_NAME_SIZE 31 + + extern str2m_2_mask_t + str2m_2_str2mask(char const * str, str2m_2_mask_t old); + + extern size_t + str2m_2_mask2str(str2m_2_mask_t mask, char * buf, size_t len); + + #endif /* STR2ENUM_STR2M_2_H_GUARD */ + _EOF_ + +mask_all=` + sed -n '/KWD_MASK_ALL/{;s/.*0x/0x/;s/UL*$//;p;q;}' $testname-h2.base` + +cat > $testname-c2.base <<- _EOF_ + * Convert a command (keyword) to a str2m_2_enum_t enumeration value. + * + * @param[in] str a string that should start with a known key word. + * @param[in] len the provided length of the keyword at \a str. + * @returns the enumeration value. + * If not found, that value is STR2M_2_COUNT_KWDBNM. + */ + static str2m_2_enum_t + find_str2m_2_kwdbnm(char const * str, size_t len) + { + str2m_2_map_t const * map; + + map = find_str2m_2_name(str, (unsigned int)len); + return (map == NULL) ? STR2M_2_COUNT_KWDBNM : map->str2m_2_id; + } + + /** + * Convert an str2m_2_enum_t value into a string. + * + * @param[in] id the enumeration value + * @returns the associated string, or "* UNDEFINED *" if \a id + * is out of range. + */ + static char const * + str2m_2_name(str2m_2_enum_t id) + { + static char const undef[] = "* UNDEFINED *"; + static char const * const nm_table[] = { + [STR2M_2_KWDBNM_ELEVEN ] = "eleven", + [STR2M_2_KWDBNM_NINTEEN ] = "ninteen", + [STR2M_2_KWDBNM_ONE ] = "one", + [STR2M_2_KWDBNM_SEVEN ] = "seven", + [STR2M_2_KWDBNM_THREE ] = "three" }; + char const * res = undef; + if (id < STR2M_2_COUNT_KWDBNM) { + res = nm_table[id]; + if (res == NULL) + res = undef; + } + return res; + } + + /** + * Convert a string to a str2m_2_mask_t mask. + * Bit names prefixed with a hyphen have the bit removed from the mask. + * If the string starts with a '-', '+' or '|' character, then + * the old value is used as a base, otherwise the result mask + * is initialized to zero. Separating bit names with '+' or '|' + * characters is optional. By default, the bits are "or"-ed into the + * result. + * + * @param[in] str string with a list of bit names + * @param[in] old previous value, used if \a str starts with a '+' or '-'. + * + * @returns an unsigned integer with the bits set. + */ + str2m_2_mask_t + str2m_2_str2mask(char const * str, str2m_2_mask_t old) + { + static char const white[] = ", \t\f"; + static char const name_chars[] = + "ehilnorstv" + "EHILNORSTV"; + + str2m_2_mask_t res = 0; + int have_data = 0; + + for (;;) { + str2m_2_enum_t val; + unsigned int val_len; + unsigned int invert = 0; + + str += strspn(str, white); + switch (*str) { + case NUL: return res; + case '-': case '~': + invert = 1; + /* FALLTHROUGH */ + + case '+': case '|': + if (have_data == 0) + res = old; + + str += 1 + strspn(str + 1, white); + if (*str == NUL) + return 0; + } + + val_len = strspn(str, name_chars); + if (val_len == 0) + return 0; + val = find_str2m_2_kwdbnm(str, val_len); + if (val == STR2M_2_COUNT_KWDBNM) + return 0; + if (invert) + res &= ~((str2m_2_mask_t)1 << val); + else + res |= (str2m_2_mask_t)1 << val; + have_data = 1; + str += val_len; + } + } + + /** + * Convert a str2m_2_mask_t mask to a string. + * + * @param[in] mask the mask with the bits to be named + * @param[out] buf where to store the result. This may be NULL. + * @param[in] len size of the output buffer + * @results The full length of the space needed for the result, + * including the terminating NUL byte. The actual result will not + * overwrite \a len bytes at \a buf. This value will also never + * exceed MAX_STR2M_2_NAME_SIZE. + */ + size_t + str2m_2_mask2str(str2m_2_mask_t mask, char * buf, size_t len) + { + str2m_2_enum_t val = (str2m_2_enum_t)0; + size_t res = 0; + if (buf == NULL) len = 0; + + for (; mask != 0; val++, mask >>= 1) { + char const * p; + size_t l; + + if (val >= STR2M_2_COUNT_KWDBNM) + break; + + if ((mask & 1) == 0) + continue; + + p = str2m_2_name(val); + if (*p == '*') + continue; /* ignore invalid bits */ + + l = strlen(p) + 1; /* includes NUL byte or spacer byte */ + if (l <= len) { + if (res > 0) + *(buf++) = ' '; + memcpy(buf, p, l); + buf += l - 1; + len -= l; + } + res += l; + } + return (res == 0) ? 1 : res; + } + /* end of str2m-2.c */ + _EOF_ + +# # # # # # # # # # RUN THE TEST PART 2 # # # # # # # + +echo run_ag x ${AGCMD} -T str2mask $testname.def +echo "base-name = '$testname-2'; prefix = '${testname}_2';" >> $testname.def +run_ag x ${AGCMD} -T str2mask $testname.def || \ + failure ${AGCMD} failed +get_h_text='/#ifndef .*_GUARD/,/#endif .*_GUARD/p' +${SED} -n "${get_h_text}" $testname-2.h > $testname-h2.res +get_c_text=`echo "$get_c_text" | ${SED} "$rep_name"` +${SED} -n "/_names+/d;${get_c_text}" $testname-2.c > $testname-c2.res + +fpair="$testname-h2.base $testname-h2.res" +cmp -s $fpair || \ + failure "$testname-2 $fpair failed`echo + diff $fpair`" + +fpair="$testname-c2.base $testname-c2.res" +cmp -s $fpair || \ + failure "$testname-2 $fpair failed`echo + diff $fpair`" + +# # # # # # # # # # RUN THE TEST PART 3 # # # # # # # + +echo running $testname-2.c program +chmod 666 $testname-2.c +cmd_sum=`echo $cmd_list | sed 's/ / + /g'` +cat > $testname-main.c <<- _EOF_ + #include + #include "$testname-2.c" + int main(int argc, char ** argv) { + str2m_2_mask_t mask = + str2m_2_str2mask("${cmd_sum}", 0); + char buf[MAX_STR2M_2_NAME_SIZE]; + size_t l = str2m_2_mask2str(mask, buf, MAX_STR2M_2_NAME_SIZE); + + printf("0x%04X --> %u bytes: '%s'\n", + (unsigned int)mask, (unsigned int)l, buf); + if (l != MAX_STR2M_2_NAME_SIZE) { + fprintf(stderr, "expected len: %u, actual: %u\n", + MAX_STR2M_2_NAME_SIZE, (unsigned int)l); + return 1; + } + mask = str2m_2_str2mask("- three - eleven - ninteen", mask); + if (mask != STR2M_2_KWD_NOT_ONE_SEVEN_MASK) { + fprintf(stderr, "0x%04X != 0x%04X\n", mask, + STR2M_2_KWD_NOT_ONE_SEVEN_MASK); + return 1; + } + return 0; + } + _EOF_ + +${CC:-cc} -o ${testname} $testname-main.c || \ + failure "cannot compile $testname-2.c" +./${testname} > ${testname}-btest +echo "$mask_all --> $(( ${#cmd_list} + 1 )) bytes: '$cmd_list'" \ + > ${testname}-bbase +fpair="${testname}-bbase ${testname}-btest" +cmp -s $fpair || \ + failure "$testname $fpair run failed`echo + diff $fpair`" + +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 4 +## sh-basic-offset: 4 +## End: + +# end of str2m.test diff --git a/agen5/test/stress.test b/agen5/test/stress.test new file mode 100755 index 0000000..84e44e0 --- /dev/null +++ b/agen5/test/stress.test @@ -0,0 +1,67 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# ---------------------------------------------------------------------- +# stress.test --- stress test +# +# Author: Bruce Korb +## +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen 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. +## +## AutoGen is distributed in the hope that 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 . +## +# ---------------------------------------------------------------------- + +. ./defs + +# # # # # # # # # # TEMPLATE FILE # # # # # # # # # + +echo creating ${testname}.tpl +cat > ${testname}.tpl <<_EOF_ +[= AutoGen5 template test =] +Entry Count = [= (count "entry") =]. +_EOF_ + +# # # # # # # # # # EXPECTED OUTPUT FILE # # # # # # # +set -x +echo creating ${testname}.samp +ecount=${STRESS_COUNT:-1000} +# this is the output we should expect to see +echo "Entry Count = ${ecount}." > ${testname}.samp + +( + set +x + echo "AutoGen Definitions ${testname};" + idx=1 + while test $idx -le ${ecount} + do + echo "entry = { value = 'val-${idx}'; depth = '${idx}'; const = xx; };" + idx=`expr $idx + 1` + done +) | run_ag x -b ${testname} - +test $? -eq 0 || failure autogen failed + +cmp -s ${testname}.test ${testname}.samp || \ + failure "`diff ${testname}.test ${testname}.samp`" + +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## sh-basic-offset: 2 +## End: + +# end of stress.test diff --git a/agen5/test/string.test b/agen5/test/string.test new file mode 100755 index 0000000..ad651c4 --- /dev/null +++ b/agen5/test/string.test @@ -0,0 +1,248 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# string.test --- test string formation rules +# +# Author: Bruce Korb +## +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen 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. +## +## AutoGen is distributed in the hope that 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 . +## +# ---------------------------------------------------------------------- + +. ./defs + +# There are five different things we need to examine: +# +# 1. That the autogen internal string. +# 2. What we expect that string to contain. +# 3. What is generated as the "C" representation +# 4. What is generated for raw shell strings +# 5. What is generated for "cooked" shell strings +# +# We will compare all these things by generating a C program that +# will test the various strings and a shell script to invoke the +# program with the two shell string formats for arguments. +# The program will also write out the expected string value. +# That value will be compared with what autogen wrote out +# as its internal value. +# +# All this stuff must be generated carefully. +# Specifically, the '${testname}' expressions need to +# be expanded in certain parts of the output file. +# In those areas, the eof marker must *not* be quoted. +# In other places (e.g., where defining the strings), +# rather than hassle with understanding shell quoting rules, +# instead we *will* quote the EOF marker to avoid +# any shell interpretation at all!! +# +# # # # # # # # # # TEMPLATE FILE # # # # # # # # # + +echo creating $testname.tpl +exec 4> $testname.tpl +cat >&4 <<_EOF_ +[= AutoGen5 Template c sh =] +[= + +CASE (suffix) =][= + + == c + +=]#include +#include +#include + +#ifndef STDOUT_FILENO +# define STDOUT_FILENO 1 +#endif[= + + + ;; Create a file containing nothing but the + ;; autogen internal contents of the string + ;; + (out-push-new "${testname}.raw") + + =][=string=][= + + (out-pop) + +=] +_EOF_ + +test -z "$LINENO" && LINENO=` + ${GREP} -n FIND-THIS-LINE-NUMBER $0 | sed 's/:.*//'` # close enough +printf '\nchar zTestFile[] = "%s";\n' \ + ${testname}.raw >&4 + +test "X$LINENO" = X || \ + echo "#line `expr $LINENO - 1` \"$(basename $0)\"" >&4 +cat >&4 <<'_EOF_' +char zGened[] = [=(c-string (get "string"))=]; +char zKrGen[] = [=(kr-string (get "string"))=]; +char zExpect[] = "'\f\r\b\v\t\a\n\n" + "\\f\\r\\b\\v\\t\\a\\n\n" + "\"Wow!\" This'll be \\hard\\'\n" + "#endif /* .\n" + "and it'll be a \"hassle\"." + "\001\002\003\n'"; +#define expectSize ((int)(sizeof(zExpect) - 1)) +int checkStr( char* pz, char const* pzWhat ); +int checkStr( char* pz, char const* pzWhat ) +{ + static char const zNotMatch[] = + "%s generated string mismatches at offset %d of %d\n" + "Expected char: 0x%02X saw char: 0x%02X\n" + "Expected string:\n==>%s<==\n\n" + "Generated string:\n-->%s<--\n\n"; + + char* pzE = zExpect; + char* pzR = pz; + int ix = (int)strlen(pz); + int res = 0; + + if (ix != expectSize) { + fprintf( stderr, "%s is %d bytes, not %d\n", pzWhat, ix, expectSize ); + res = 1; + } + + for (ix = 0; ix < expectSize; ix++) { + if (*(pzE++) != *(pzR++)) { + fprintf(stderr, zNotMatch, pzWhat, ix, expectSize, + (unsigned char)pzE[-1], (unsigned char)pzR[-1], zExpect, pz); + return 1; + } + } + if (*pzE != '\0') { + fputs( "compile error: expected string too long\n", stderr); + res = 1; + } else if (*pzR != '\0') { + fprintf(stderr, "%s has %d residual characters:\n==>%s<==\n", + pzWhat, (int)strlen(pzR), pzR); + res = 1; + } + return res; +} + + +int main( int argc, char** argv ) +{ + int resCode = 0; + + /* + * Write out the expected value to a file. + * The "cmp" program will compare it with the + * internal version autogen wrote out itself. + */ + write( STDOUT_FILENO, zExpect, sizeof( zExpect )-1); + close( STDOUT_FILENO ); + + if (sizeof( zGened ) != sizeof( zExpect )) { + fputs( "Expected and generated string sizes do not match.\n", + stderr ); + resCode = 1; + } + + if (strlen( zGened ) != sizeof( zGened )-1) { + fputs( "The generated string contains a NUL.\n", stderr ); + resCode++; + } + + if (checkStr( zGened, "'C' program" )) + resCode++; + + if (checkStr( zKrGen, "K&R 'C' program" )) + resCode++; + + if (checkStr( argv[1], "Raw shell" )) + resCode++; + + if (checkStr( argv[2], "Cooked shell" )) + resCode++; + + return resCode; +}[= + + == sh + +=]#! /bin/sh +set -x +_EOF_ + +cat 1>&4 <<_EOF_ +./${testname} [=(raw-shell-str (get "string")) + =] [=(shell-str (get "string"))=] > ${testname}.out +res=\$? +cmp ${testname}.out ${testname}.raw > /dev/null 2>&1 + +if [ \$? -ne 0 ] +then + echo the AutoGen internal content did not match expectations + res=\`expr \$res + 1\` +fi +if [ \$res -eq 0 ] +then + echo All string comparisons pass +else + echo There were \$res string test failures + exit \$res +fi[= + +ESAC + +=] +_EOF_ +exec 4>&- + +# # # # # # # # # # DEFINITIONS FILE # # # # # # # # # + +echo creating $testname.def +echo "autogen definitions $testname.tpl;" > $testname.def +cat >> $testname.def <<'_EOF_' + +string = + "'\f\r\b\v\t\a\n +" + '\f\r\b\v\t\a\n +' + '"Wow!" This\'ll be \\hard\\\' +\#endif /* . +' + "and it'll be a \"hassle\"." + "\001\x02\X03\n'"; + +_EOF_ + +# # # # # # # # # # RUN THE TESTS # # # # # # # # # # # + +SHELL=${SHELL-/bin/sh} + +run_ag x $testname.def || failure autogen failed + +compile + +chmod +x *.sh + +./${testname}.sh || failure strings do not match + +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 4 +## sh-basic-offset: 4 +## End: + +# end of string.test diff --git a/agen5/test/strtable.test b/agen5/test/strtable.test new file mode 100755 index 0000000..9504611 --- /dev/null +++ b/agen5/test/strtable.test @@ -0,0 +1,96 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# strtable.test --- test string-table functionality +# +# Author: Bruce Korb +## +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen 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. +## +## AutoGen is distributed in the hope that 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 . +## +# ---------------------------------------------------------------------- + +. ./defs + +# # # # # # # # # # TEMPLATE FILE # # # # # # # # # + +echo creating ${testname}.tpl +cat > ${testname}.tpl <<_EOF_ +[= AutoGen5 template test =] +[= + +(string-table-new "scribble") +(out-push-new) ;; redirect output to temporary +(define ct 1) + +=][= + +FOR str IN that was the week that was + +=][= (set! ct (+ ct 1)) =] + [= (string-table-add-ref "scribble" (get "str")) =],[= + +ENDFOR + +=][= + (out-suspend "main") + (emit-string-table "scribble") + (emit (sprintf "\n#define STRING_CT %d\n" (- ct 1))) + (ag-fprintf 0 "\nchar const * const ap[%d] = {" ct) + (out-resume "main") + (out-pop #t) ;; now dump out the redirected output + ;; and finish: =] + NULL }; +_EOF_ + +# # # # # # # # # # EXPECTED OUTPUT FILE # # # # # # # +set -x +echo creating ${testname}.base +# this is the output we should expect to see +cat > ${testname}.base <<'_EOF_' + +static char const scribble[18] = +/* 0 */ "that\0" +/* 5 */ "was\0" +/* 9 */ "the\0" +/* 13 */ "week"; + +#define STRING_CT 6 + +char const * const ap[7] = { + scribble+0, + scribble+5, + scribble+9, + scribble+13, + scribble+0, + scribble+5, + NULL }; +_EOF_ + +run_ag x -b ${testname} -T ${testname}.tpl --no-defin || \ + failure autogen failed +cmp -s ${testname}.base ${testname}.test || \ + failure "bad output: `diff -c ${testname}.base ${testname}.test`" + +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## sh-basic-offset: 2 +## End: + +# end of strtable.test diff --git a/agen5/test/strxform.test b/agen5/test/strxform.test new file mode 100755 index 0000000..3290e2c --- /dev/null +++ b/agen5/test/strxform.test @@ -0,0 +1,86 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# strxform.test --- test string transformation functionality +# +# Author: Bruce Korb +## +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen 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. +## +## AutoGen is distributed in the hope that 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 . +## +# +# ---------------------------------------------------------------------- + +. ./defs + +# # # # # # # # # # TEMPLATE FILE # # # # # # # # # + +echo creating ${testname}.tpl +${SED} 's/^ *[0-9]*: //' > ${testname}.tpl <<- _EOTPL_ + 1: [= AutoGen5 Template test =] + 2: string input: [= in-str =] + 3: + 4: string->c-name! [= (string->c-name! (get "in-str")) =] + 5: string-upcase! [= (string-upcase! (get "in-str")) =] + 6: string-capitalize! [= (string-capitalize! (get "in-str")) =] + 7: string-capitalize [= (string-capitalize (get "in-str")) =] + 8: string-downcase! [= (string-downcase! (get "in-str")) =] + 9: string-downcase [= (string-downcase (get "in-str")) =] +10: string->camelcase [= (string->camelcase (get "in-str")) =] +_EOTPL_ + +cat > ${testname}.def <<- _EOF_ + AutoGen Definitions ${testname}.tpl; + in-str = "The 10quick\tfoxes-jumped/very=\n=high9indeed!"; + _EOF_ + +# # # # # # # # # # # EXPECTED OUTPUT FILE # # # # # # # +set -x +echo creating ${testname}.out +# this is the output we should expect to see +cat > ${testname}.out <<- \_EOF_ + string input: The 10quick foxes-jumped/very= + =high9indeed! + + string->c-name! The 10quick foxes_jumped_very_ + _high9indeed_ + string-upcase! THE 10QUICK FOXES-JUMPED/VERY= + =HIGH9INDEED! + string-capitalize! The 10quick Foxes-Jumped/Very= + =High9indeed! + string-capitalize The 10quick Foxes-Jumped/Very= + =High9indeed! + string-downcase! the 10quick foxes-jumped/very= + =high9indeed! + string-downcase the 10quick foxes-jumped/very= + =high9indeed! + string->camelcase The10QuickFoxesJumpedVeryHigh9Indeed + _EOF_ + +run_ag x ${testname}.def || failure autogen failed + +cmp -s ${testname}.test ${testname}.out || \ + failure "unexpected output:${nl}`diff ${testname}.out ${testname}.test`" + +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## sh-basic-offset: 2 +## End: + +# end of strxform.test diff --git a/agen5/test/suffix.test b/agen5/test/suffix.test new file mode 100755 index 0000000..225618c --- /dev/null +++ b/agen5/test/suffix.test @@ -0,0 +1,89 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# suffix.test --- test the select suffix option +# +# Author: Bruce Korb +## +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen 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. +## +## AutoGen is distributed in the hope that 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 . +## +# ---------------------------------------------------------------------- + +. ./defs + +# # # # # # # # # # TEMPLATE FILE # # # # # # # # # + +echo creating ${testname}.tpl +cat > ${testname}.tpl <<'_EOF_' +[= AutoGen5 Template test =] +[= + +CASE (suffix) =][= + +== test =]BOGUS[= +== "* NONE *" =]No Suffix[= +== Example =]Example[= +* =]Bogon ``[=(suffix)=]''[= + +ESAC =] +_EOF_ + +# # # # # # # # # # EXPECTED OUTPUT FILE # # # # # # # + +echo "Example" > ${testname}.Example.test +echo "No Suffix" > ${testname}.stdout.test + +# # # # # # # # # # RUN TESTS # # # # # # # +nodefopt="--no-def -T${testname}.tpl" +run_ag ex ${nodefopt} -oExample -b${testname} || \ + failure autogen ${nodefopt} -oExample -b${testname} + +cmp ${testname}.Example* || \ + failure `diff -c cmp ${testname}.Example*` + +# # # # # # # # # # STDOUT TEMPLATE # # # # # # # # # + +echo creating ${testname}.tpl +cat > ${testname}.tpl <<'_EOF_' +[= AutoGen5 Template =] +[= +text =] +_EOF_ + +cat > ${testname}.samp <<- EOF + This is some text. + This should appear in the output. +EOF + +cat > ${testname}.def <<\EOF +AutoGen Definitions suffix; +text = `cat suffix.samp`; +EOF + +run_ag sfx ${testname}.def | ${EGREP} -v '^in state ' > ${testname}.out +cmp ${testname}.out ${testname}.samp || \ + failure "`diff ${testname}.out ${testname}.samp`" + +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## sh-basic-offset: 2 +## End: + +# end of suffix.test diff --git a/agen5/test/time.test b/agen5/test/time.test new file mode 100755 index 0000000..2ee9e81 --- /dev/null +++ b/agen5/test/time.test @@ -0,0 +1,63 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# ---------------------------------------------------------------------- +# time.test --- test modification time settings +# +# Author: Bruce Korb +## +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen 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. +## +## AutoGen is distributed in the hope that 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 . +## +# ---------------------------------------------------------------------- + +. ./defs + +# # # # # # # # # # TEMPLATE FILE # # # # # # # # # + +echo creating ${testname}.tpl +cat > ${testname}.tpl <<_EOF_ +[= AutoGen5 template test =] +Plain text template. +_EOF_ + +touch -t 200109110846.00 ${testname}.tpl + +run_ag time --source-time -b ${testname} -T ${testname}.tpl --no-definitions || \ + failure autogen failed + +touch -t 200109110846.02 ${testname}.taaa + +set -- `ls -t ${testname}.t*` + +while : +do + test "${3}" = ${testname}.tpl || break + test "${2}" = ${testname}.test || break + test "${1}" = ${testname}.taaa || break + cleanup + exit 0 +done + +failure "wrong file time ordering: $*" + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## sh-basic-offset: 2 +## End: + +# end of time.test diff --git a/agen5/tpLoad.c b/agen5/tpLoad.c new file mode 100644 index 0000000..4eb5b32 --- /dev/null +++ b/agen5/tpLoad.c @@ -0,0 +1,560 @@ + +/** + * @file tpLoad.c + * + * This module will load a template and return a template structure. + * + * @addtogroup autogen + * @{ + */ +/* + * This file is part of AutoGen. + * Copyright (C) 1992-2018 Bruce Korb - all rights reserved + * + * AutoGen 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. + * + * AutoGen is distributed in the hope that 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 . + */ + +/** + * Return the template structure matching the name passed in. + */ +static templ_t * +find_tpl(char const * tpl_name) +{ + templ_t * pT = named_tpls; + while (pT != NULL) { + if (streqvcmp(tpl_name, pT->td_name) == 0) + break; + pT = C(templ_t *, (pT->td_scan)); + } + return pT; +} + +/** + * the name is a regular file with read access. + * @param[in] fname file name to check + * @returns \a true when the named file exists and is a regular file + * @returns \a false otherwise. + */ +static bool +read_okay(char const * fname) +{ + struct stat stbf; + if (stat(fname, &stbf) != 0) + return false; + if (! S_ISREG(stbf.st_mode)) + return false; + return (access(fname, R_OK) == 0) ? true : false; +} + +/** + * Expand a directory name that starts with '$'. + * + * @param[in,out] dir_pp pointer to pointer to directory name + * @returns the resulting pointer + */ +static char const * +expand_dir(char const ** dir_pp, char * name_buf) +{ + char * res = VOIDP(*dir_pp); + + if (res[1] == NUL) + AG_ABEND(aprf(LOAD_FILE_SHORT_NAME, res)); + + if (! optionMakePath(name_buf, (int)AG_PATH_MAX, res, + autogenOptions.pzProgPath)) { + /* + * The name expanded to "empty", so substitute curdir. + */ + strcpy(res, FIND_FILE_CURDIR); + + } else { + free(res); + AGDUPSTR(res, name_buf, "find dir name"); + *dir_pp = res; /* save computed name for later */ + } + + return res; +} + +static inline bool +file_search_dirs( + char const * in_name, + char * res_name, + char const * const * sfx_list, + char const * referring_tpl, + size_t nm_len, + bool no_suffix) +{ + /* + * Search each directory in our directory search list for the file. + * We always force two copies of this option, so we know it exists. + * Later entries are more recently added and are searched first. + * We start the "dirlist" pointing to the real last entry. + */ + int ct = STACKCT_OPT(TEMPL_DIRS); + char const ** dirlist = STACKLST_OPT(TEMPL_DIRS) + ct - 1; + char const * c_dir = FIND_FILE_CURDIR; + + /* + * IF the file name starts with a directory separator, + * then we only search once, looking for the exact file name. + */ + if (*in_name == '/') + ct = -1; + + for (;;) { + char * pzEnd; + + /* + * c_dir is always FIND_FILE_CURDIR the first time through + * and is never that value after that. + */ + if (c_dir == FIND_FILE_CURDIR) { + + memcpy(res_name, in_name, nm_len); + pzEnd = res_name + nm_len; + *pzEnd = NUL; + + } else { + unsigned int fmt_len; + + /* + * IF one of our template paths starts with '$', then expand it + * and replace it now and forever (the rest of this run, anyway). + */ + if (*c_dir == '$') + c_dir = expand_dir(dirlist+1, res_name); + + fmt_len = (unsigned)snprintf( + res_name, AG_PATH_MAX - MAX_SUFFIX_LEN, + FIND_FILE_DIR_FMT, c_dir, in_name); + if (fmt_len >= AG_PATH_MAX - MAX_SUFFIX_LEN) + break; // fail-return + pzEnd = res_name + fmt_len; + } + + if (read_okay(res_name)) + return true; + + /* + * IF the file does not already have a suffix, + * THEN try the ones that are okay for this file. + */ + if (no_suffix && (sfx_list != NULL)) { + char const * const * sfxl = sfx_list; + *(pzEnd++) = '.'; + + do { + strcpy(pzEnd, *(sfxl++)); /* must fit */ + if (read_okay(res_name)) + return true; + + } while (*sfxl != NULL); + } + + /* + * IF we've exhausted the search list, + * THEN see if we're done, else go through search dir list. + * + * We try one more thing if there is a referrer. + * If the searched-for file is a full path, "ct" will + * start at -1 and we will leave the loop here and now. + */ + if (--ct < 0) { + if ((referring_tpl == NULL) || (ct != -1)) + break; + c_dir = referring_tpl; + + } else { + c_dir = *(dirlist--); + } + } + + return false; +} + +/** + * Search for a file. + * + * Starting with the current directory, search the directory list trying to + * find the base template file name. If there is a referring template (a + * template with an "INCLUDE" macro), then try that, too, before giving up. + * + * @param[in] in_name the file name we are looking for. + * @param[out] res_name where we stash the file name we found. + * @param[in] sfx_list a list of suffixes to try, if \a in_name has none. + * @param[in] referring_tpl file name of the template with a INCLUDE macro. + * + * @returns \a SUCCESS when \a res_name is valid + * @returns \a FAILURE when the file is not found. + */ +static tSuccess +find_file(char const * in_name, + char * res_name, + char const * const * sfx_list, + char const * referring_tpl) +{ + bool no_suffix; + void * free_me = NULL; + tSuccess res = SUCCESS; + + size_t nm_len = strlen(in_name); + if (nm_len >= AG_PATH_MAX - MAX_SUFFIX_LEN) + return FAILURE; + + /* + * Expand leading environment variables. + * We will not mess with embedded ones. + */ + if (*in_name == '$') { + if (! optionMakePath(res_name, (int)AG_PATH_MAX, in_name, + autogenOptions.pzProgPath)) + return FAILURE; + + AGDUPSTR(in_name, res_name, "find file name"); + free_me = VOIDP(in_name); + + /* + * in_name now points to the name the file system can use. + * It must _not_ point to res_name because we will likely + * rewrite that value using this pointer! + */ + nm_len = strlen(in_name); + } + + /* + * Not a complete file name. If there is not already + * a suffix for the file name, then append ".tpl". + * Check for immediate access once again. + */ + { + char * bf = strrchr(in_name, '/'); + bf = (bf != NULL) ? strchr(bf, '.') : strchr(in_name, '.'); + no_suffix = (bf == NULL); + } + + /* + * The referrer is useful only if it includes a directory name. + * If not NULL, referring_tpl becomes an allocated directory name. + */ + if (referring_tpl != NULL) { + char * pz = strrchr(referring_tpl, '/'); + if (pz == NULL) + referring_tpl = NULL; + else { + AGDUPSTR(referring_tpl, referring_tpl, "refer tpl"); + pz = strrchr(referring_tpl, '/'); + *pz = NUL; + } + } + + if (! file_search_dirs(in_name, res_name, sfx_list, referring_tpl, + nm_len, no_suffix)) + res = FAILURE; + + AGFREE(free_me); + AGFREE(referring_tpl); + return res; +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/** + * Count the macros in a template. + * We need to allocate the right number of pointers. + */ +static size_t +cnt_macros(char const * pz) +{ + size_t ct = 2; + for (;;) { + pz = strstr(pz, st_mac_mark); + if (pz == NULL) + break; + ct += 2; + if (strncmp(pz - end_mac_len, end_mac_mark, end_mac_len) == 0) + ct--; + pz += st_mac_len; + } + return ct; +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/** + * Load the macro array and file name. + * @param[in,out] tpl the template to load + * @param[in] fname the source file name of the template + * @param[in] pzN someting + * @param[in] data the template text + */ +static void +load_macs(templ_t * tpl, char const * fname, char const * pzData) +{ + macro_t * pMac = tpl->td_macros; + + { + char * txt = (char *)(pMac + tpl->td_mac_ct); + + AGDUPSTR(tpl->td_file, fname, "templ file"); + + memcpy(txt, PSEUDO_MAC_TPL_FILE, PSEUDO_MAC_TPL_FILE_LEN+1); + tpl->td_name = txt; + tpl->td_text = (txt += PSEUDO_MAC_TPL_FILE_LEN); + tpl->td_scan = txt + 1; + } + + current_tpl = tpl; + + { + macro_t * e_mac = parse_tpl(pMac, &pzData); + int ct; + + /* + * Make sure all of the input string was scanned. + */ + if (pzData != NULL) + AG_ABEND(LOAD_MACS_BAD_PARSE); + + ct = (int)(e_mac - pMac); + + /* + * IF there are empty macro slots, + * THEN pack the text + */ + if (ct < tpl->td_mac_ct) { + int delta = + (int)(sizeof(macro_t) * (size_t)(tpl->td_mac_ct - ct)); + void * data = + (tpl->td_name == NULL) ? tpl->td_text : tpl->td_name; + size_t size = (size_t)(tpl->td_scan - (char *)data); + memmove(VOIDP(e_mac), data, size); + + tpl->td_text -= delta; + tpl->td_scan -= delta; + tpl->td_name -= delta; + tpl->td_mac_ct = ct; + } + } + + tpl->td_size = (size_t)(tpl->td_scan - (char *)tpl); + tpl->td_scan = NULL; + + /* + * We cannot reallocate a smaller array because + * the entries are all linked together and + * realloc-ing it may cause it to move. + */ +#if defined(DEBUG_ENABLED) + if (HAVE_OPT(SHOW_DEFS)) { + static char const zSum[] = + "loaded %d macros from %s\n" + "\tBinary template size: 0x%zX\n\n"; + fprintf(trace_fp, zSum, tpl->td_mac_ct, fname, tpl->td_size); + } +#endif +} + +/** + * Load a template from mapped memory. Load up the pseudo macro, + * count the macros, allocate the data, and parse all the macros. + * + * @param[in] minfo information about the mapped memory. + * @param[in] fname the full path input file name. + * + * @returns the digested data + */ +static templ_t * +digest_tpl(tmap_info_t * minfo, char * fname) +{ + templ_t * res; + + /* + * Count the number of macros in the template. Compute + * the output data size as a function of the number of macros + * and the size of the template data. These may get reduced + * by comments. + */ + char const * dta = + load_pseudo_mac((char const *)minfo->txt_data, fname); + + size_t mac_ct = cnt_macros(dta); + size_t alloc_sz = (sizeof(*res) + (mac_ct * sizeof(macro_t)) + + minfo->txt_size + - (size_t)(dta - (char const *)minfo->txt_data) + + strlen(fname) + 0x10) + & (size_t)(~0x0F); + + res = (templ_t *)AGALOC(alloc_sz, "main template"); + memset(VOIDP(res), 0, alloc_sz); + + /* + * Initialize the values: + */ + res->td_magic = magic_marker; + res->td_size = alloc_sz; + res->td_mac_ct = (int)mac_ct; + + strcpy(res->td_start_mac, st_mac_mark); /* must fit */ + strcpy(res->td_end_mac, end_mac_mark); /* must fit */ + load_macs(res, fname, dta); + + res->td_name -= (long)res; + res->td_text -= (long)res; + res = (templ_t *)AGREALOC(VOIDP(res), res->td_size, + "resize template"); + res->td_name += (long)res; + res->td_text += (long)res; + + return res; +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/** + * Starting with the current directory, search the directory + * list trying to find the base template file name. + */ +static templ_t * +tpl_load(char const * fname, char const * referrer) +{ + static tmap_info_t map_info; + static char tpl_file[ AG_PATH_MAX ]; + + /* + * Find the template file somewhere + */ + { + static char const * const sfx_list[] = { + LOAD_TPL_SFX_TPL, LOAD_TPL_SFX_AGL, NULL }; + if (! SUCCESSFUL(find_file(fname, tpl_file, sfx_list, referrer))) { + errno = ENOENT; + AG_CANT(LOAD_TPL_CANNOT_MAP, fname); + } + } + + /* + * Make sure the specified file is a regular file. + * Make sure the output time stamp is at least as recent. + */ + { + struct stat stbf; + if (stat(tpl_file, &stbf) != 0) + AG_CANT(LOAD_TPL_CANNOT_STAT, fname); + + if (! S_ISREG(stbf.st_mode)) { + errno = EINVAL; + AG_CANT(LOAD_TPL_IRREGULAR, fname); + } + + if (time_is_before(outfile_time, stbf.st_mtime)) + outfile_time = stbf.st_mtime; + if (time_is_before(maxfile_time, stbf.st_mtime)) + maxfile_time = stbf.st_mtime; + } + + text_mmap(tpl_file, PROT_READ|PROT_WRITE, MAP_PRIVATE, &map_info); + if (TEXT_MMAP_FAILED_ADDR(map_info.txt_data)) + AG_ABEND(aprf(LOAD_TPL_CANNOT_OPEN, tpl_file)); + + if (dep_fp != NULL) + add_source_file(tpl_file); + + /* + * Process the leading pseudo-macro. The template proper + * starts immediately after it. + */ + { + macro_t * sv_mac = cur_macro; + templ_t * res; + cur_macro = NULL; + + res = digest_tpl(&map_info, tpl_file); + cur_macro = sv_mac; + text_munmap(&map_info); + + return res; + } +} + +/** + * Deallocate anything related to a template. + * This includes the pointer passed in and any macros that have an + * unload procedure associated with it. + * + * @param[in] tpl the template to unload + */ +static void +tpl_unload(templ_t * tpl) +{ + macro_t * mac = tpl->td_macros; + int ct = tpl->td_mac_ct; + + while (--ct >= 0) { + unload_proc_p_t proc; + unsigned int ix = mac->md_code; + + /* + * "select" functions get remapped, depending on the alias used for + * the selection. See the "mac_func_t" enumeration in functions.h. + */ + if (ix >= FUNC_CT) + ix = FTYP_SELECT; + + proc = unload_procs[ ix ]; + if (proc != NULL) + (*proc)(mac); + + mac++; + } + + AGFREE(tpl->td_file); + AGFREE(tpl); +} + +/** + * This gets called when all is well at the end. + * The supplied template and all named templates are unloaded. + * + * @param[in] tpl the last template standing + */ +static void +cleanup(templ_t * tpl) +{ + if (HAVE_OPT(USED_DEFINES)) + print_used_defines(); + + if (dep_fp != NULL) + wrap_up_depends(); + + optionFree(&autogenOptions); + + for (;;) { + tpl_unload(tpl); + tpl = named_tpls; + if (tpl == NULL) + break; + named_tpls = C(templ_t *, (tpl->td_scan)); + } + + free_for_context(INT_MAX); + unload_defs(); +} + +/** + * @} + * + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of agen5/tpLoad.c */ diff --git a/agen5/tpParse.c b/agen5/tpParse.c new file mode 100644 index 0000000..ce35294 --- /dev/null +++ b/agen5/tpParse.c @@ -0,0 +1,412 @@ + +/** + * @file tpParse.c + * + * This module will load a template and return a template structure. + * + * @addtogroup autogen + * @{ + */ +/* + * This file is part of AutoGen. + * Copyright (C) 1992-2018 Bruce Korb - all rights reserved + * + * AutoGen 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. + * + * AutoGen is distributed in the hope that 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 . + */ + +#if defined(DEBUG_ENABLED) + static char const zTUndef[] = "%-10s (%d) line %d - MARKER\n"; + + static int tpl_nest_lvl = 0; + + static char const tpl_def_fmt[] = "%-10s (%d) line %d end=%d, strlen=%d\n"; +#endif + +/** + * Return the enumerated function type corresponding + * to a name pointed to by the input argument. + */ +static mac_func_t +func_code(char const ** pscan) +{ + fn_name_type_t const * pNT; + char const * pzFuncName = *pscan; + int hi, lo, av; + int cmp; + + /* + * IF the name starts with a punctuation, then it is some sort of + * alias. Find the function in the alias portion of the table. + */ + if (IS_PUNCTUATION_CHAR(*pzFuncName)) { + hi = FUNC_ALIAS_HIGH_INDEX; + lo = FUNC_ALIAS_LOW_INDEX; + do { + av = (hi + lo)/2; + pNT = fn_name_types + av; + cmp = (int)(*(pNT->pName)) - (int)(*pzFuncName); + + /* + * For strings that start with a punctuation, we + * do not need to test for the end of token + * We will not strip off the marker and the load function + * will figure out what to do with the code. + */ + if (cmp == 0) + return pNT->fType; + if (cmp > 0) + hi = av - 1; + else lo = av + 1; + } while (hi >= lo); + return FTYP_BOGUS; + } + + if (! IS_VAR_FIRST_CHAR(*pzFuncName)) + return FTYP_BOGUS; + + hi = FUNC_NAMES_HIGH_INDEX; + lo = FUNC_NAMES_LOW_INDEX; + + do { + av = (hi + lo)/2; + pNT = fn_name_types + av; + cmp = strneqvcmp(pNT->pName, pzFuncName, (int)pNT->cmpLen); + if (cmp == 0) { + /* + * Make sure we matched to the end of the token. + */ + if (IS_VARIABLE_NAME_CHAR(pzFuncName[pNT->cmpLen])) + break; + + /* + * Advance the scanner past the macro name. + * The name is encoded in the "fType". + */ + *pscan = pzFuncName + pNT->cmpLen; + return pNT->fType; + } + if (cmp > 0) + hi = av - 1; + else lo = av + 1; + } while (hi >= lo); + + /* + * Save the name for later lookup + */ + cur_macro->md_name_off = + (size_t)(current_tpl->td_scan - current_tpl->td_text); + { + char * pzCopy = current_tpl->td_scan; + char * pe = SPN_VALUE_NAME_CHARS(pzFuncName); + size_t l = (size_t)(pe - pzFuncName); + memcpy(pzCopy, pzFuncName, l); + pzCopy += l; + pzFuncName += l; + + /* + * Names are allowed to contain colons, but not end with them. + */ + if (pzCopy[-1] == ':') + pzCopy--, pzFuncName--; + + *(pzCopy++) = NUL; + *pscan = pzFuncName; + current_tpl->td_scan = pzCopy; + } + + /* + * "Unknown" means we have to check again before we + * know whether to assign it to "FTYP_INVOKE" or "FTYP_COND". + * That depends on whether or not we find a named template + * at template instantiation time. + */ + return FTYP_UNKNOWN; +} + +static char const * +find_mac_end(char const ** ppzMark) +{ + char const * pzMark = *ppzMark + st_mac_len; + char const * pzFunc; + char const * pzNextMark; + char const * pzEndMark; + + /* + * Set our pointers to the start of the macro text + */ + for (;;) { + pzMark = SPN_NON_NL_WHITE_CHARS(pzMark); + if (*pzMark != NL) + break; + tpl_line++; + pzMark++; + } + + pzFunc = pzMark; + cur_macro->md_code = func_code(&pzMark); + cur_macro->md_line = tpl_line; + *ppzMark = pzMark; + + /* + * Find the end. (We must.) If the thing is empty, treat as a comment, + * but warn about it. + */ + pzEndMark = strstr(pzMark, end_mac_mark); + if (pzEndMark == NULL) + AG_ABEND(FIND_MAC_END_NOPE); + + if (pzEndMark == pzFunc) { + cur_macro->md_code = FTYP_COMMENT; + fprintf(trace_fp, FIND_MAC_END_EMPTY, + current_tpl->td_file, tpl_line); + return pzEndMark; + } + + /* + * Back up over a preceding backslash. It is a flag to indicate the + * removal of the end of line white space. + */ + if (pzEndMark[-1] == '\\') + pzEndMark--; + + pzNextMark = strstr(pzMark, st_mac_mark); + if (pzNextMark == NULL) + return pzEndMark; + + if (pzEndMark > pzNextMark) + AG_ABEND(FIND_MAC_END_NESTED); + + return pzEndMark; +} + +static char const * +find_mac_start(char const * pz, macro_t ** ppm, templ_t * tpl) +{ + char * pzCopy; + char const * pzEnd; + char const * res = strstr(pz, st_mac_mark); + macro_t * mac = *ppm; + + if (res == pz) + return res; + + /* + * There is some text here. Make a text macro entry. + */ + pzCopy = tpl->td_scan; + pzEnd = (res != NULL) ? res : pz + strlen(pz); + mac->md_txt_off = (uintptr_t)(pzCopy - tpl->td_text); + mac->md_code = FTYP_TEXT; + mac->md_line = tpl_line; + +#if defined(DEBUG_ENABLED) + if (HAVE_OPT(SHOW_DEFS)) { + int ct = tpl_nest_lvl; + fprintf(trace_fp, "%3u ", (unsigned int)(mac - tpl->td_macros)); + do { fputs(" ", trace_fp); } while (--ct > 0); + + fprintf(trace_fp, tpl_def_fmt, ag_fun_names[ FTYP_TEXT ], FTYP_TEXT, + mac->md_line, mac->md_end_idx, (unsigned int)(pzEnd - pz)); + } +#endif + + do { + if ((*(pzCopy++) = *(pz++)) == NL) + tpl_line++; + } while (pz < pzEnd); + + *(pzCopy++) = NUL; + *ppm = mac + 1; + tpl->td_scan = pzCopy; + + return res; /* may be NULL, if there are no more macros */ +} + +static char const * +find_macro(templ_t * tpl, macro_t ** ppm, char const ** pscan) +{ + char const * scan = *pscan; + char const * pzMark; + + pzMark = find_mac_start(scan, ppm, tpl); + + /* + * IF no more macro marks are found, THEN we are done... + */ + if (pzMark == NULL) + return pzMark; + + /* + * Find the macro code and the end of the macro invocation + */ + cur_macro = *ppm; + scan = find_mac_end(&pzMark); + + /* + * Count the lines in the macro text and advance the + * text pointer to after the marker. + */ + { + char const * pzMacEnd = scan; + char const * pz = pzMark; + + for (;;pz++) { + pz = strchr(pz, NL); + if ((pz == NULL) || (pz > pzMacEnd)) + break; + tpl_line++; + } + + /* + * Strip white space from the macro + */ + pzMark = SPN_WHITESPACE_CHARS(pzMark); + + if (pzMark != pzMacEnd) { + pzMacEnd = SPN_WHITESPACE_BACK( pzMark, pzMacEnd); + (*ppm)->md_txt_off = (uintptr_t)pzMark; + (*ppm)->md_res = (uintptr_t)(pzMacEnd - pzMark); + } + } + + /* + * IF the end macro mark was preceded by a backslash, then we remove + * trailing white space from there to the end of the line. + */ + if ((*scan != '\\') || (strncmp(end_mac_mark, scan, end_mac_len) == 0)) + scan += end_mac_len; + + else { + char const * pz; + scan += end_mac_len + 1; + pz = SPN_NON_NL_WHITE_CHARS(scan); + if (*pz == NL) { + scan = pz + 1; + tpl_line++; + } + } + + *pscan = scan; + return pzMark; +} + +#if defined(DEBUG_ENABLED) + static void +print_indentation(templ_t * tpl, macro_t * mac, int idx) +{ + static char const fmt_fmt[] = "%%%us"; + char fmt[16]; + + if (idx < 0) + fputs(" ", trace_fp); + else fprintf(trace_fp, "%3u ", (unsigned int)idx); + snprintf(fmt, sizeof(fmt), fmt_fmt, tpl_nest_lvl); + fprintf(trace_fp, fmt, ""); + (void)tpl; + (void)mac; +} + + static void +print_ag_defs(templ_t * tpl, macro_t * mac) +{ + mac_func_t ft = mac->md_code; + int ln = mac->md_line; + int idx = (mac->md_code == FTYP_BOGUS) ? -1 : (int)(mac - tpl->td_macros); + + print_indentation(tpl, mac, idx); + + if (mac->md_code == FTYP_BOGUS) + fprintf(trace_fp, zTUndef, ag_fun_names[ ft ], ft, ln); + else { + char const * pz; + if (ft >= FUNC_CT) + ft = FTYP_SELECT; + pz = (mac->md_txt_off == 0) + ? zNil + : (tpl->td_text + mac->md_txt_off); + fprintf(trace_fp, tpl_def_fmt, ag_fun_names[ft], mac->md_code, + ln, mac->md_end_idx, (unsigned int)strlen(pz)); + } +} +#endif + +/** + * Parse the template. + * @param[out] mac array of macro descriptors to fill in + * @param[in,out] p_scan pointer to string scanning address + */ +static macro_t * +parse_tpl(macro_t * mac, char const ** p_scan) +{ + char const * scan = *p_scan; + templ_t * tpl = current_tpl; + +#if defined(DEBUG_ENABLED) + + #define DEBUG_DEC(l) l-- + + if ( ((tpl_nest_lvl++) > 0) + && HAVE_OPT(SHOW_DEFS)) { + int idx = (int)(mac - tpl->td_macros); + macro_t * m = mac - 1; + + print_indentation(tpl, m, idx); + + fprintf(trace_fp, zTUndef, ag_fun_names[m->md_code], + m->md_code, m->md_line); + } +#else + #define DEBUG_DEC(l) +#endif + + while (find_macro(tpl, &mac, &scan) != NULL) { + /* + * IF the called function returns a NULL next macro pointer, + * THEN some block has completed. The returned scanning pointer + * will be non-NULL. + */ + load_proc_p_t const fn = load_proc_table[mac->md_code]; + macro_t * nxt_mac = fn(tpl, mac, &scan); + +#if defined(DEBUG_ENABLED) + if (HAVE_OPT(SHOW_DEFS)) + print_ag_defs(tpl, mac); +#endif + + if (nxt_mac == NULL) { + *p_scan = scan; + DEBUG_DEC(tpl_nest_lvl); + return mac; + } + mac = nxt_mac; + } + + DEBUG_DEC(tpl_nest_lvl); + + /* + * We reached the end of the input string. + * Return a NULL scanning pointer and a pointer to the end. + */ + *p_scan = NULL; + return mac; +} +/** + * @} + * + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of agen5/tpParse.c */ diff --git a/agen5/tpProcess.c b/agen5/tpProcess.c new file mode 100644 index 0000000..5558745 --- /dev/null +++ b/agen5/tpProcess.c @@ -0,0 +1,444 @@ + +/** + * @file tpProcess.c + * + * Parse and process the template data descriptions + * + * @addtogroup autogen + * @{ + */ +/* + * This file is part of AutoGen. + * AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoGen 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. + * + * AutoGen is distributed in the hope that 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 . + */ + +/** + * Generate all the text within a block. + * The caller must know the exact bounds of the block. + * + * @param tpl template containing block of macros + * @param mac first macro in series + * @param emac one past last macro in series + */ +static void +gen_block(templ_t * tpl, macro_t * mac, macro_t * emac) +{ + /* + * Set up the processing context for this block of macros. + * It is used by the Guile callback routines and the exception + * handling code. It is all for user friendly diagnostics. + */ + current_tpl = tpl; + + while ((mac != NULL) && (mac < emac)) { + mac_func_t fc = mac->md_code; + if (fc >= FUNC_CT) + fc = FTYP_BOGUS; + + scribble_free(); + if (OPT_VALUE_TRACE >= TRACE_EVERYTHING) + trace_macro(tpl, mac); + + cur_macro = mac; + mac = (*(load_procs[ fc ]))(tpl, mac); + } +} + +/** + * Print out information about the invocation of a macro. + * Print up to the first 32 characters in the macro, for context. + * + * @param tpl template containing macros + * @param mac first macro in series + */ +static void +trace_macro(templ_t * tpl, macro_t * mac) +{ + mac_func_t fc = mac->md_code; + if (fc >= FUNC_CT) + fc = FTYP_BOGUS; + + fprintf(trace_fp, TRACE_MACRO_FMT, ag_fun_names[fc], mac->md_code, + tpl->td_file, mac->md_line); + + if (mac->md_txt_off > 0) { + char * pz = tpl->td_text + mac->md_txt_off; + char * pe = BRK_NEWLINE_CHARS(pz); + if (pe > pz + 32) + pz = pz + 32; + + putc(' ', trace_fp); putc(' ', trace_fp); + fwrite(pz, (size_t)(pe - pz), 1, trace_fp); + putc(NL, trace_fp); + } +} + +/** + * The template output goes to stdout. Perhaps because output + * is for a CGI script. In any case, this case must be handled + * specially. + * + * @param tpl template to be processed + */ +static void +do_stdout_tpl(templ_t * tpl) +{ + SCM res; + + last_scm_cmd = NULL; /* We cannot be in Scheme processing */ + + switch (setjmp(abort_jmp_buf)) { + case SUCCESS: + break; + + case PROBLEM: + if (*oops_pfx != NUL) { + fprintf(stdout, DO_STDOUT_TPL_ABANDONED, oops_pfx); + oops_pfx = zNil; + } + fclose(stdout); + return; + + default: + fserr(AUTOGEN_EXIT_FS_ERROR, DO_STDOUT_TPL_BADR, oops_pfx); + + case FAILURE: + exit(EXIT_FAILURE); + /* NOTREACHED */ + } + + curr_sfx = DO_STDOUT_TPL_NOSFX; + curr_def_ctx = root_def_ctx; + cur_fpstack = &out_root; + out_root.stk_fp = stdout; + out_root.stk_fname = DO_STDOUT_TPL_STDOUT; + out_root.stk_flags = FPF_NOUNLINK | FPF_STATIC_NM; + if (OPT_VALUE_TRACE >= TRACE_EVERYTHING) + fputs(DO_STDOUT_TPL_START_STD, trace_fp); + + /* + * IF there is a CGI prefix for error messages, + * THEN divert all output to a temporary file so that + * the output will be clean for any error messages we have to emit. + */ + if (*oops_pfx == NUL) + gen_block(tpl, tpl->td_macros, tpl->td_macros + tpl->td_mac_ct); + + else { + char const * pzRes; + (void)ag_scm_out_push_new(SCM_UNDEFINED); + + gen_block(tpl, tpl->td_macros, tpl->td_macros + tpl->td_mac_ct); + + /* + * Read back in the spooled output. Make sure it starts with + * a content-type: prefix. If not, we supply our own HTML prefix. + */ + res = ag_scm_out_pop(SCM_BOOL_T); + pzRes = scm_i_string_chars(res); + + /* 13 char prefix is: "content-type:" */ + if (strneqvcmp(pzRes, DO_STDOUT_TPL_CONTENT, 13) != 0) + fputs(DO_STDOUT_TPL_CONTENT, stdout); + + fwrite(pzRes, scm_c_string_length(res), 1, stdout); + } + + fclose(stdout); +} + +/** + * pop the current output spec structure. Deallocate it and the + * file name, too, if necessary. + */ +static out_spec_t * +next_out_spec(out_spec_t * os) +{ + out_spec_t * res = os->os_next; + + if (os->os_dealloc_fmt) + AGFREE(os->os_file_fmt); + + AGFREE(os); + return res; +} + +static void +process_tpl(templ_t * tpl) +{ + /* + * IF the template file does not specify any output suffixes, + * THEN we will generate to standard out with the suffix set to zNoSfx. + * With output going to stdout, we don't try to remove output on errors. + */ + if (output_specs == NULL) { + do_stdout_tpl(tpl); + return; + } + + do { + out_spec_t * os; + + /* + * We cannot be in Scheme processing. We've either just started + * or we've made a long jump from our own code. If we've made a + * long jump, we've printed a message that is sufficient and we + * don't need to print any scheme expressions. + */ + last_scm_cmd = NULL; + + /* + * HOW was that we got here? + */ + switch (setjmp(abort_jmp_buf)) { + case SUCCESS: + os = output_specs; + + if (OPT_VALUE_TRACE >= TRACE_EVERYTHING) { + fprintf(trace_fp, PROC_TPL_START, os->os_sfx); + fflush(trace_fp); + } + /* + * Set the output file name buffer. + * It may get switched inside open_output. + */ + open_output(os); + memcpy(&out_root, cur_fpstack, sizeof(out_root)); + AGFREE(cur_fpstack); + cur_fpstack = &out_root; + curr_sfx = os->os_sfx; + curr_def_ctx = root_def_ctx; + cur_fpstack->stk_flags &= ~FPF_FREE; + cur_fpstack->stk_prev = NULL; + gen_block(tpl, tpl->td_macros, tpl->td_macros+tpl->td_mac_ct); + + do { + out_close(false); /* keep output */ + } while (cur_fpstack->stk_prev != NULL); + + output_specs = next_out_spec(os); + break; + + case PROBLEM: + os = output_specs; + /* + * We got here by a long jump. Close/purge the open files + * and go on to the next output. + */ + do { + out_close(true); /* discard output */ + } while (cur_fpstack->stk_prev != NULL); + last_scm_cmd = NULL; /* "problem" means "drop current output". */ + output_specs = next_out_spec(os); + break; + + default: + fprintf(trace_fp, PROC_TPL_BOGUS_RET, oops_pfx); + oops_pfx = zNil; + /* FALLTHROUGH */ + + case FAILURE: + os = output_specs; + + /* + * We got here by a long jump. Close/purge the open files. + */ + do { + out_close(true); /* discard output */ + } while (cur_fpstack->stk_prev != NULL); + + /* + * On failure (or unknown jump type), we quit the program, too. + */ + processing_state = PROC_STATE_ABORTING; + while (os != NULL) + os = next_out_spec(os); + + exit(EXIT_FAILURE); + /* NOTREACHED */ + } + } while (output_specs != NULL); +} + +static void +set_utime(char const * fname) +{ +#ifdef HAVE_UTIMENSAT + enum { ACCESS_IDX = 0, MODIFY_IDX = 1 }; + struct timespec const times[2] = { + [ACCESS_IDX] = { + .tv_sec = 0, + .tv_nsec = UTIME_OMIT + }, + [MODIFY_IDX] = { + .tv_sec = outfile_time.tv_sec, + .tv_nsec = outfile_time.tv_nsec + } + }; + utimensat(AT_FDCWD, fname, times, 0); + +#else + struct utimbuf const tbuf = { + .actime = time(NULL), + .modtime = outfile_time + }; + + /* + * The putative start time is one second earlier than the + * earliest output file time, regardless of when that is. + */ + if (outfile_time <= start_time) + start_time = outfile_time - 1; + + utime(fname, &tbuf); +#endif +} + +/** + * close current output file + * + * @param purge "true" means the output is to be discarded + * + * Most output files will be set to read only, though that may + * get overridden. If the file name has been allocated, then it + * is also freed. The current output is set to the next in the + * stack. + */ +static void +out_close(bool purge) +{ + if ((cur_fpstack->stk_flags & FPF_NOCHMOD) == 0) + make_readonly(); + + if (OPT_VALUE_TRACE > TRACE_DEBUG_MESSAGE) + fprintf(trace_fp, OUT_CLOSE_TRACE_WRAP, __func__, + cur_fpstack->stk_fname); + + fclose(cur_fpstack->stk_fp); + + /* + * Only stdout and /dev/null are marked, "NOUNLINK" + */ + if ((cur_fpstack->stk_flags & FPF_NOUNLINK) == 0) { + /* + * IF we are told to purge the file OR the file is an AutoGen temp + * file, then get rid of the output. + */ + if (purge || ((cur_fpstack->stk_flags & FPF_UNLINK) != 0)) + unlink(cur_fpstack->stk_fname); + + else + set_utime(cur_fpstack->stk_fname); + } + + /* + * Do not deallocate statically allocated names + */ + if ((cur_fpstack->stk_flags & FPF_STATIC_NM) == 0) + AGFREE(cur_fpstack->stk_fname); + + /* + * Do not deallocate the root entry. It is not allocated!! + */ + if ((cur_fpstack->stk_flags & FPF_FREE) != 0) { + out_stack_t * p = cur_fpstack; + cur_fpstack = p->stk_prev; + AGFREE(p); + } +} + +/** + * Figure out what to use as the base name of the output file. + * If an argument is not provided, we use the base name of + * the definitions file. + */ +static void +open_output(out_spec_t * spec) +{ + static char const write_mode[] = "w" FOPEN_BINARY_FLAG "+"; + + char const * out_file = NULL; + + if (strcmp(spec->os_sfx, OPEN_OUTPUT_NULL) == 0) { + static int const flags = FPF_NOUNLINK | FPF_NOCHMOD | FPF_TEMPFILE; + null_open: + open_output_file(DEV_NULL, DEV_NULL_LEN, write_mode, flags); + return; + } + + /* + * IF we are to skip the current suffix, + * we will redirect the output to /dev/null and + * perform all the work. There may be side effects. + */ + if (HAVE_OPT(SKIP_SUFFIX)) { + int ct = STACKCT_OPT(SKIP_SUFFIX); + const char ** ppz = STACKLST_OPT(SKIP_SUFFIX); + + while (--ct >= 0) { + if (strcmp(spec->os_sfx, *ppz++) == 0) + goto null_open; + } + } + + /* + * Remove any suffixes in the last file name + */ + { + char const * def_file = OPT_ARG(BASE_NAME); + char z[AG_PATH_MAX]; + const char * pst = strrchr(def_file, '/'); + char * end; + + pst = (pst == NULL) ? def_file : (pst + 1); + + /* + * We allow users to specify a suffix with '-' and '_', but when + * stripping a suffix from the "base name", we do not recognize 'em. + */ + end = strchr(pst, '.'); + if (end != NULL) { + size_t len = (unsigned)(end - pst); + if (len >= sizeof(z)) + AG_ABEND(BASE_NAME_TOO_LONG); + + memcpy(z, pst, len); + z[ end - pst ] = NUL; + pst = z; + } + + /* + * Now formulate the output file name in the buffer + * provided as the input argument. + */ + out_file = aprf(spec->os_file_fmt, pst, spec->os_sfx); + if (out_file == NULL) + AG_ABEND(aprf(OPEN_OUTPUT_BAD_FMT, spec->os_file_fmt, pst, + spec->os_sfx)); + } + + open_output_file(out_file, strlen(out_file), write_mode, 0); + free(VOIDP(out_file)); +} +/** + * @} + * + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of agen5/tpProcess.c */ diff --git a/autoopts/Makefile.am b/autoopts/Makefile.am new file mode 100644 index 0000000..5562e78 --- /dev/null +++ b/autoopts/Makefile.am @@ -0,0 +1,244 @@ +## -*- Mode: Makefile -*- +## +## Author: Bruce Korb +## +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + +BUILT_SOURCES = +MOSTLYCLEANFILES = +libdatadir = $(libdir)/@PACKAGE@ +SUBDIRS = @OPTS_TESTDIR@ +AM_CPPFLAGS = @INCLIST@ +AM_CFLAGS = @WARN_CFLAGS@ +libsrc = libopts-@AO_CURRENT@.@AO_REVISION@.@AO_AGE@.tar.gz +LIBOPTS_VER = @AO_CURRENT@:@AO_REVISION@:@AO_AGE@ + +if NEED_PATHFIND +PATHFIND_MAN = pathfind.3 +else +PATHFIND_MAN = +endif + +MAN_STAMP = man3-stamp +GENTEXI = libopts.texi libopts.menu +TEXI_STAMP = texi-stamp +EXTRA_DIST = +GENMAN = $(PATHFIND_MAN) \ + ao_string_tokenize.3 configFileLoad.3 \ + optionFileLoad.3 optionFindNextValue.3 \ + optionFindValue.3 optionFree.3 \ + optionGetValue.3 optionLoadLine.3 \ + optionMemberList.3 optionNextValue.3 \ + optionOnlyUsage.3 optionPrintVersion.3 \ + optionPrintVersionAndReturn.3 optionProcess.3 \ + optionRestore.3 optionSaveFile.3 \ + optionSaveState.3 optionUnloadNested.3 \ + optionVersion.3 strequate.3 \ + streqvcmp.3 streqvmap.3 \ + strneqvcmp.3 strtransform.3 + +nodist_pkgdata_DATA = $(libsrc) \ + tpl/man2mdoc tpl/man2texi tpl/mdoc2man \ + tpl/mdoc2texi tpl/texi2man tpl/texi2mdoc \ + tpl/tpl-config.tlib + +nodist_libdata_DATA = tpl/tpl-config.tlib + +pkgdata_DATA = \ + autoopts.m4 tpl/aginfo3.tpl tpl/aginfo.tpl \ + tpl/agman1.tpl tpl/agman3.tpl tpl/agman-cmd.tpl \ + tpl/agman-file.tpl tpl/agman.tlib tpl/agmdoc-cmd.tpl \ + tpl/agmdoc-file.tpl tpl/agpl.lic tpl/agtexi-cmd.tpl \ + tpl/agtexi-file.tpl tpl/bits.tpl tpl/cmd-doc.tlib \ + tpl/def2pot.tpl tpl/getopt.tpl tpl/gpl.lic \ + tpl/gplv2.lic tpl/lgpl.lic tpl/lgplv2.lic \ + tpl/mbsd.lic tpl/Mdoc.pm tpl/optcode.tlib \ + tpl/opthead.tlib tpl/options.tpl tpl/optlib.tlib \ + tpl/optmain.tlib tpl/perlopt.tpl tpl/rc-sample.tpl \ + tpl/stdoptions.def tpl/str2enum.tpl tpl/str2init.tlib \ + tpl/str2mask.tpl tpl/strings.tpl tpl/usage.tlib + +EXTRA_DATA = $(pkgdata_DATA) \ + autogen.map autoopts-config.in bootstrap.dir \ + install-hook.sh mk-autoopts-pc.in mk-tpl-config.sh \ + po tpl/man2mdoc.pl tpl/man2texi.sh \ + tpl/mdoc2man.pl tpl/mdoc2texi.pl tpl/texi2man.sh \ + tpl/texi2mdoc.sh tpl/tpl-config-tlib.in + +GENSCRIPTS = $(srcdir)/funcs.def \ + tpl/man2man tpl/man2mdoc tpl/man2texi tpl/mdoc2man tpl/mdoc2mdoc \ + tpl/mdoc2texi tpl/texi2man tpl/texi2mdoc tpl/texi2texi + +EXTRA_DIST += $(top_srcdir)/config/gendocs.sh +EXTRA_DIST += gettext.h +EXTRA_DIST += $(top_srcdir)/config/config.rpath +EXTRA_DIST += intprops.h +EXTRA_DIST += parse-duration.c +EXTRA_DIST += parse-duration.h +# Because this Makefile snippet defines a variable used by other +# gnulib Makefile snippets, it must be present in all makefiles that +# need it. This is ensured by the applicability 'all' defined above. +_NORETURN_H=$(srcdir)/_Noreturn.h +EXTRA_DIST += _Noreturn.h +BUILT_SOURCES += $(STDNORETURN_H) +# We need the following in order to create when the system +# doesn't have one that works. +if GL_GENERATE_STDNORETURN_H +stdnoreturn.h: stdnoreturn.in.h $(top_builddir)/config.status $(_NORETURN_H) + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ + sed -e '/definition of _Noreturn/r $(_NORETURN_H)' \ + < $(srcdir)/stdnoreturn.in.h; \ + } > $@-t && \ + mv $@-t $@ +else +stdnoreturn.h: $(top_builddir)/config.status + rm -f $@ +endif +MOSTLYCLEANFILES += stdnoreturn.h stdnoreturn.h-t +EXTRA_DIST += stdnoreturn.in.h + +GENHDRS = autoopts/options.h autoopts/usage-txt.h genshell.h \ + option-xat-attribute.h option-value-type.h ao-strs.h \ + ag-char-map.h save-flags.h +HDRS = $(GENHDRS) autoopts.h project.h proto.h +GEN_SRC = ao-strs.c option-value-type.c option-xat-attribute.c \ + save-flags.c + +## The primary source (autoopts.c) must be by itself on the first line after +## "CSRC". 'sed' does some magic here to get the list of source files for the +## documentation. Files without documentation are on the CSRC = line. +## +CSRC = parse-duration.c $(GEN_SRC) \ + autoopts.c \ + alias.c boolean.c check.c configfile.c cook.c \ + enum.c env.c file.c find.c genshell.c \ + load.c makeshell.c nested.c numeric.c pgusage.c \ + putshell.c reset.c restore.c save.c sort.c \ + stack.c streqvcmp.c text_mmap.c time.c tokenize.c \ + usage.c version.c init.c + +SRC = $(HDRS) $(CSRC) $(GENSRC) +DEF_FILES = genshell.def $(srcdir)/funcs.def ao-strs.def +pkgconfigdir =$(libdir)/pkgconfig + +## # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +## +## A U T O M A K E V A R S +## +## # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + +CLEANFILES = tmp-* libopts.c +DISTCLEANFILES = $(GENMAN) $(GENTEXI) *-stamp +MAINTAINERCLEANFILES = $(GENHDRS) $(GENSRC) $(GENSCRIPTS) +m4datadir = $(datadir)/aclocal + +nodist_libopts_la_SOURCES = libopts.c +libopts_la_SOURCES = $(HDRS) +libopts_la_CFLAGS = -DPKGDATADIR='"$(pkgdatadir)"' $(AM_CFLAGS) +libopts_la_LDFLAGS = -version-info $(LIBOPTS_VER) +libopts_la_LIBADD = $(top_builddir)/snprintfv/libsnprintfv.la + +EXTRA_DIST += $(SRC) $(EXTRA_DATA) $(man_MANS) $(DEF_FILES) + +INST_MANS = autoopts-config.1 $(GENMAN) +INST_PKGCFG = pkgconfig/autoopts.pc +INST_LIBS = libopts.la +INST_HDRS = autoopts/options.h autoopts/usage-txt.h +INST_SH = autoopts-config + +man_MANS = $(INST_MANS) +m4data_DATA = autoopts.m4 +pkgconfig_DATA = $(INST_PKGCFG) +lib_LTLIBRARIES = $(INST_LIBS) +nobase_include_HEADERS = $(INST_HDRS) +bin_SCRIPTS = $(INST_SH) + +BOOTENV = AGexe="$(AGexe)" GDexe="$(GDexe)" CLexe="$(CLexe)" \ + srcdir="$(srcdir)" top_srcdir="$(top_srcdir)" \ + builddir="$(builddir)" top_builddir="$(top_builddir)" \ + AO_AGE="$(AO_AGE)" AO_CURRENT="$(AO_CURRENT)" \ + AO_REVISION="$(AO_REVISION)" POSIX_SHELL="$(POSIX_SHELL)" + +## # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +## +## M A K E F I L E R U L E S +## +## # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + +libopts.c : tpl-config-stamp +$(GENSCRIPTS) : tpl-config-stamp + +tpl-config-stamp: $(HDRS) $(CSRC) \ + $(top_builddir)/config.h $(srcdir)/mk-tpl-config.sh + LGCFLAGS="$(GUILE_CFLAGS)" \ + $(BOOTENV) \ + $(POSIX_SHELL) $(srcdir)/mk-tpl-config.sh $@ $(HDRS) $(CSRC) + +makeshell.lo : genshell.c +genshell.c : $(srcdir)/genshell.def + $(BOOTENV) \ + $(POSIX_SHELL) $(srcdir)/bootstrap.dir $@ + +strcspn.lo : $(top_srcdir)/compat/strcspn.c + $(LTCOMPILE) -o $@ -c $(top_srcdir)/compat/strcspn.c + +install-data-local : install-man3 + +$(GENMAN) : $(MAN_STAMP) +$(MAN_STAMP) : $(srcdir)/funcs.def + @test -x ../agen5/autogen || exit 0 ; \ + touch tmp-$@ ; \ + opts='-L$(srcdir)/tpl -L$(builddir)/tpl -Tagman3.tpl' ; \ + echo ! $(AGexe) $${opts} $(srcdir)/funcs.def ; \ + $(AGexe) $${opts} $(srcdir)/funcs.def ; \ + mv -f tmp-$@ $@ + +$(GENTEXI) : $(TEXI_STAMP) +$(TEXI_STAMP) : ../agen5/autogen $(srcdir)/funcs.def + @touch tmp-$@ ; \ + opts='-L$(srcdir)/tpl -L$(builddir)/tpl -Taginfo3.tpl' ; \ + cmd="$(AGexe) $${opts} -DLEVEL=subsection -blibopts" ; \ + cmd="$${cmd} -L$(srcdir) $(srcdir)/funcs.def" ; \ + echo ! $$cmd ; $$cmd ; mv -f tmp-$@ $@ + +libsrc : $(libsrc) +$(libsrc) : + @$(BOOTENV) \ + AO_AGE=@AO_AGE@ AO_CURRENT=@AO_CURRENT@ AO_REVISION=@AO_REVISION@ \ + $(POSIX_SHELL) $(top_srcdir)/pkg/libopts/mklibsrc.sh + +pkgconfig/autoopts.pc : mk-autoopts-pc + $(POSIX_SHELL) mk-autoopts-pc $@ + +install-data-hook: + @DESTdestdir='$(DESTDIR)$(includedir)/autoopts' \ + DESTpkgdatadir='$(DESTDIR)$(pkgdatadir)' \ + DESTlibdatadir='$(DESTDIR)$(pkglibdir)' \ + top_builddir='$(top_builddir)' \ + LIBOPTS_VER='$(LIBOPTS_VER)' \ + POSIX_SHELL='$(POSIX_SHELL)' \ + bindir='$(bindir)' \ + $(POSIX_SHELL) $(srcdir)/install-hook.sh + +.NOTPARALLEL: + +# Makefile.am ends here diff --git a/autoopts/Makefile.in b/autoopts/Makefile.in new file mode 100644 index 0000000..4082dd9 --- /dev/null +++ b/autoopts/Makefile.in @@ -0,0 +1,1323 @@ +# Makefile.in generated by automake 1.16.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2018 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + + + + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +subdir = autoopts +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/config/ag_macros.m4 \ + $(top_srcdir)/config/asm-underscore.m4 \ + $(top_srcdir)/config/extensions.m4 \ + $(top_srcdir)/config/guile.m4 \ + $(top_srcdir)/config/host-cpu-c-abi.m4 \ + $(top_srcdir)/config/lib-ld.m4 \ + $(top_srcdir)/config/lib-link.m4 \ + $(top_srcdir)/config/lib-prefix.m4 \ + $(top_srcdir)/config/libopts.m4 \ + $(top_srcdir)/config/libtool.m4 \ + $(top_srcdir)/config/ltoptions.m4 \ + $(top_srcdir)/config/ltsugar.m4 \ + $(top_srcdir)/config/ltversion.m4 \ + $(top_srcdir)/config/lt~obsolete.m4 \ + $(top_srcdir)/config/onceonly.m4 $(top_srcdir)/config/pkg.m4 \ + $(top_srcdir)/config/snprintfv.m4 \ + $(top_srcdir)/config/stdnoreturn.m4 \ + $(top_srcdir)/config/unlocked-io.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(nobase_include_HEADERS) \ + $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = mk-autoopts-pc autoopts-config +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" \ + "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man3dir)" \ + "$(DESTDIR)$(m4datadir)" "$(DESTDIR)$(libdatadir)" \ + "$(DESTDIR)$(pkgdatadir)" "$(DESTDIR)$(pkgconfigdir)" \ + "$(DESTDIR)$(pkgdatadir)" "$(DESTDIR)$(includedir)" +LTLIBRARIES = $(lib_LTLIBRARIES) +libopts_la_DEPENDENCIES = $(top_builddir)/snprintfv/libsnprintfv.la +am__objects_1 = +am__objects_2 = $(am__objects_1) +am_libopts_la_OBJECTS = $(am__objects_2) +nodist_libopts_la_OBJECTS = libopts_la-libopts.lo +libopts_la_OBJECTS = $(am_libopts_la_OBJECTS) \ + $(nodist_libopts_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +libopts_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(libopts_la_CFLAGS) \ + $(CFLAGS) $(libopts_la_LDFLAGS) $(LDFLAGS) -o $@ +SCRIPTS = $(bin_SCRIPTS) +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/config/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/libopts_la-libopts.Plo +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libopts_la_SOURCES) $(nodist_libopts_la_SOURCES) +DIST_SOURCES = $(libopts_la_SOURCES) +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +man1dir = $(mandir)/man1 +man3dir = $(mandir)/man3 +NROFF = nroff +MANS = $(man_MANS) +DATA = $(m4data_DATA) $(nodist_libdata_DATA) $(nodist_pkgdata_DATA) \ + $(pkgconfig_DATA) $(pkgdata_DATA) +HEADERS = $(nobase_include_HEADERS) +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ + distdir distdir-am +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = $(SUBDIRS) +am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/autoopts-config.in \ + $(srcdir)/mk-autoopts-pc.in $(top_srcdir)/config/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +ACLOCAL = @ACLOCAL@ +AGEN5_TESTS = @AGEN5_TESTS@ +AG_LDFLAGS = @AG_LDFLAGS@ +AG_MAJOR_VERSION = @AG_MAJOR_VERSION@ +AG_MINOR_VERSION = @AG_MINOR_VERSION@ +AG_STATIC_AUTOGEN = @AG_STATIC_AUTOGEN@ +AG_TIMEOUT = @AG_TIMEOUT@ +AG_VERSION = @AG_VERSION@ +AG_XML2 = @AG_XML2@ +AGexe = @AGexe@ +AGnam = @AGnam@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AO_AGE = @AO_AGE@ +AO_CURRENT = @AO_CURRENT@ +AO_REVISION = @AO_REVISION@ +AO_TEMPLATE_VERSION = @AO_TEMPLATE_VERSION@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CLexe = @CLexe@ +CLnam = @CLnam@ +CONFIG_SHELL = @CONFIG_SHELL@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEBUG_ENABLED = @DEBUG_ENABLED@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +DYNAMIC_AG = @DYNAMIC_AG@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ENABLE_STATIC = @ENABLE_STATIC@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GDexe = @GDexe@ +GDnam = @GDnam@ +GO_AGE = @GO_AGE@ +GO_CURRENT = @GO_CURRENT@ +GO_REVISION = @GO_REVISION@ +GREP = @GREP@ +GUILE_CFLAGS = @GUILE_CFLAGS@ +GUILE_EFFECTIVE_VERSION = @GUILE_EFFECTIVE_VERSION@ +GUILE_LDFLAGS = @GUILE_LDFLAGS@ +GUILE_LIBS = @GUILE_LIBS@ +GUILE_LTLIBS = @GUILE_LTLIBS@ +HOST_CPU = @HOST_CPU@ +HOST_CPU_C_ABI = @HOST_CPU_C_ABI@ +INCLIST = @INCLIST@ +INCSNPRINTFV = @INCSNPRINTFV@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSNPRINTFV = @LIBSNPRINTFV@ +LIBTOOL = @LIBTOOL@ +LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ +LIBXML2_LIBS = @LIBXML2_LIBS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +M4_SRC = @M4_SRC@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPTS_TESTDIR = @OPTS_TESTDIR@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POSIX_SHELL = @POSIX_SHELL@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STDNORETURN_H = @STDNORETURN_H@ +STRIP = @STRIP@ +TEXI2HTML = @TEXI2HTML@ +VERSION = @VERSION@ +WARN_CFLAGS = @WARN_CFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_aux_dir = @ac_aux_dir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +BUILT_SOURCES = $(STDNORETURN_H) +MOSTLYCLEANFILES = stdnoreturn.h stdnoreturn.h-t +libdatadir = $(libdir)/@PACKAGE@ +SUBDIRS = @OPTS_TESTDIR@ +AM_CPPFLAGS = @INCLIST@ +AM_CFLAGS = @WARN_CFLAGS@ +libsrc = libopts-@AO_CURRENT@.@AO_REVISION@.@AO_AGE@.tar.gz +LIBOPTS_VER = @AO_CURRENT@:@AO_REVISION@:@AO_AGE@ +@NEED_PATHFIND_FALSE@PATHFIND_MAN = +@NEED_PATHFIND_TRUE@PATHFIND_MAN = pathfind.3 +MAN_STAMP = man3-stamp +GENTEXI = libopts.texi libopts.menu +TEXI_STAMP = texi-stamp +EXTRA_DIST = $(top_srcdir)/config/gendocs.sh gettext.h \ + $(top_srcdir)/config/config.rpath intprops.h parse-duration.c \ + parse-duration.h _Noreturn.h stdnoreturn.in.h $(SRC) \ + $(EXTRA_DATA) $(man_MANS) $(DEF_FILES) +GENMAN = $(PATHFIND_MAN) \ + ao_string_tokenize.3 configFileLoad.3 \ + optionFileLoad.3 optionFindNextValue.3 \ + optionFindValue.3 optionFree.3 \ + optionGetValue.3 optionLoadLine.3 \ + optionMemberList.3 optionNextValue.3 \ + optionOnlyUsage.3 optionPrintVersion.3 \ + optionPrintVersionAndReturn.3 optionProcess.3 \ + optionRestore.3 optionSaveFile.3 \ + optionSaveState.3 optionUnloadNested.3 \ + optionVersion.3 strequate.3 \ + streqvcmp.3 streqvmap.3 \ + strneqvcmp.3 strtransform.3 + +nodist_pkgdata_DATA = $(libsrc) \ + tpl/man2mdoc tpl/man2texi tpl/mdoc2man \ + tpl/mdoc2texi tpl/texi2man tpl/texi2mdoc \ + tpl/tpl-config.tlib + +nodist_libdata_DATA = tpl/tpl-config.tlib +pkgdata_DATA = \ + autoopts.m4 tpl/aginfo3.tpl tpl/aginfo.tpl \ + tpl/agman1.tpl tpl/agman3.tpl tpl/agman-cmd.tpl \ + tpl/agman-file.tpl tpl/agman.tlib tpl/agmdoc-cmd.tpl \ + tpl/agmdoc-file.tpl tpl/agpl.lic tpl/agtexi-cmd.tpl \ + tpl/agtexi-file.tpl tpl/bits.tpl tpl/cmd-doc.tlib \ + tpl/def2pot.tpl tpl/getopt.tpl tpl/gpl.lic \ + tpl/gplv2.lic tpl/lgpl.lic tpl/lgplv2.lic \ + tpl/mbsd.lic tpl/Mdoc.pm tpl/optcode.tlib \ + tpl/opthead.tlib tpl/options.tpl tpl/optlib.tlib \ + tpl/optmain.tlib tpl/perlopt.tpl tpl/rc-sample.tpl \ + tpl/stdoptions.def tpl/str2enum.tpl tpl/str2init.tlib \ + tpl/str2mask.tpl tpl/strings.tpl tpl/usage.tlib + +EXTRA_DATA = $(pkgdata_DATA) \ + autogen.map autoopts-config.in bootstrap.dir \ + install-hook.sh mk-autoopts-pc.in mk-tpl-config.sh \ + po tpl/man2mdoc.pl tpl/man2texi.sh \ + tpl/mdoc2man.pl tpl/mdoc2texi.pl tpl/texi2man.sh \ + tpl/texi2mdoc.sh tpl/tpl-config-tlib.in + +GENSCRIPTS = $(srcdir)/funcs.def \ + tpl/man2man tpl/man2mdoc tpl/man2texi tpl/mdoc2man tpl/mdoc2mdoc \ + tpl/mdoc2texi tpl/texi2man tpl/texi2mdoc tpl/texi2texi + +# Because this Makefile snippet defines a variable used by other +# gnulib Makefile snippets, it must be present in all makefiles that +# need it. This is ensured by the applicability 'all' defined above. +_NORETURN_H = $(srcdir)/_Noreturn.h +GENHDRS = autoopts/options.h autoopts/usage-txt.h genshell.h \ + option-xat-attribute.h option-value-type.h ao-strs.h \ + ag-char-map.h save-flags.h + +HDRS = $(GENHDRS) autoopts.h project.h proto.h +GEN_SRC = ao-strs.c option-value-type.c option-xat-attribute.c \ + save-flags.c + +CSRC = parse-duration.c $(GEN_SRC) \ + autoopts.c \ + alias.c boolean.c check.c configfile.c cook.c \ + enum.c env.c file.c find.c genshell.c \ + load.c makeshell.c nested.c numeric.c pgusage.c \ + putshell.c reset.c restore.c save.c sort.c \ + stack.c streqvcmp.c text_mmap.c time.c tokenize.c \ + usage.c version.c init.c + +SRC = $(HDRS) $(CSRC) $(GENSRC) +DEF_FILES = genshell.def $(srcdir)/funcs.def ao-strs.def +pkgconfigdir = $(libdir)/pkgconfig +CLEANFILES = tmp-* libopts.c +DISTCLEANFILES = $(GENMAN) $(GENTEXI) *-stamp +MAINTAINERCLEANFILES = $(GENHDRS) $(GENSRC) $(GENSCRIPTS) +m4datadir = $(datadir)/aclocal +nodist_libopts_la_SOURCES = libopts.c +libopts_la_SOURCES = $(HDRS) +libopts_la_CFLAGS = -DPKGDATADIR='"$(pkgdatadir)"' $(AM_CFLAGS) +libopts_la_LDFLAGS = -version-info $(LIBOPTS_VER) +libopts_la_LIBADD = $(top_builddir)/snprintfv/libsnprintfv.la +INST_MANS = autoopts-config.1 $(GENMAN) +INST_PKGCFG = pkgconfig/autoopts.pc +INST_LIBS = libopts.la +INST_HDRS = autoopts/options.h autoopts/usage-txt.h +INST_SH = autoopts-config +man_MANS = $(INST_MANS) +m4data_DATA = autoopts.m4 +pkgconfig_DATA = $(INST_PKGCFG) +lib_LTLIBRARIES = $(INST_LIBS) +nobase_include_HEADERS = $(INST_HDRS) +bin_SCRIPTS = $(INST_SH) +BOOTENV = AGexe="$(AGexe)" GDexe="$(GDexe)" CLexe="$(CLexe)" \ + srcdir="$(srcdir)" top_srcdir="$(top_srcdir)" \ + builddir="$(builddir)" top_builddir="$(top_builddir)" \ + AO_AGE="$(AO_AGE)" AO_CURRENT="$(AO_CURRENT)" \ + AO_REVISION="$(AO_REVISION)" POSIX_SHELL="$(POSIX_SHELL)" + +all: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) all-recursive + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu autoopts/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu autoopts/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +mk-autoopts-pc: $(top_builddir)/config.status $(srcdir)/mk-autoopts-pc.in + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ +autoopts-config: $(top_builddir)/config.status $(srcdir)/autoopts-config.in + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ + +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ + } + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ + done + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + @list='$(lib_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +libopts.la: $(libopts_la_OBJECTS) $(libopts_la_DEPENDENCIES) $(EXTRA_libopts_la_DEPENDENCIES) + $(AM_V_CCLD)$(libopts_la_LINK) -rpath $(libdir) $(libopts_la_OBJECTS) $(libopts_la_LIBADD) $(LIBS) +install-binSCRIPTS: $(bin_SCRIPTS) + @$(NORMAL_INSTALL) + @list='$(bin_SCRIPTS)'; test -n "$(bindir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n' \ + -e 'h;s|.*|.|' \ + -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) { files[d] = files[d] " " $$1; \ + if (++n[d] == $(am__install_max)) { \ + print "f", d, files[d]; n[d] = 0; files[d] = "" } } \ + else { print "f", d "/" $$4, $$1 } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(bindir)$$dir'"; \ + $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-binSCRIPTS: + @$(NORMAL_UNINSTALL) + @list='$(bin_SCRIPTS)'; test -n "$(bindir)" || exit 0; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 's,.*/,,;$(transform)'`; \ + dir='$(DESTDIR)$(bindir)'; $(am__uninstall_files_from_dir) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libopts_la-libopts.Plo@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +libopts_la-libopts.lo: libopts.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libopts_la_CFLAGS) $(CFLAGS) -MT libopts_la-libopts.lo -MD -MP -MF $(DEPDIR)/libopts_la-libopts.Tpo -c -o libopts_la-libopts.lo `test -f 'libopts.c' || echo '$(srcdir)/'`libopts.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libopts_la-libopts.Tpo $(DEPDIR)/libopts_la-libopts.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libopts.c' object='libopts_la-libopts.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libopts_la_CFLAGS) $(CFLAGS) -c -o libopts_la-libopts.lo `test -f 'libopts.c' || echo '$(srcdir)/'`libopts.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-man1: $(man_MANS) + @$(NORMAL_INSTALL) + @list1=''; \ + list2='$(man_MANS)'; \ + test -n "$(man1dir)" \ + && test -n "`echo $$list1$$list2`" \ + || exit 0; \ + echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \ + { for i in $$list1; do echo "$$i"; done; \ + if test -n "$$list2"; then \ + for i in $$list2; do echo "$$i"; done \ + | sed -n '/\.1[a-z]*$$/p'; \ + fi; \ + } | while read p; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; echo "$$p"; \ + done | \ + sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ + sed 'N;N;s,\n, ,g' | { \ + list=; while read file base inst; do \ + if test "$$base" = "$$inst"; then list="$$list $$file"; else \ + echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ + $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ + fi; \ + done; \ + for i in $$list; do echo "$$i"; done | $(am__base_list) | \ + while read files; do \ + test -z "$$files" || { \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ + done; } + +uninstall-man1: + @$(NORMAL_UNINSTALL) + @list=''; test -n "$(man1dir)" || exit 0; \ + files=`{ for i in $$list; do echo "$$i"; done; \ + l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ + sed -n '/\.1[a-z]*$$/p'; \ + } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ + dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir) +install-man3: $(man_MANS) + @$(NORMAL_INSTALL) + @list1=''; \ + list2='$(man_MANS)'; \ + test -n "$(man3dir)" \ + && test -n "`echo $$list1$$list2`" \ + || exit 0; \ + echo " $(MKDIR_P) '$(DESTDIR)$(man3dir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(man3dir)" || exit 1; \ + { for i in $$list1; do echo "$$i"; done; \ + if test -n "$$list2"; then \ + for i in $$list2; do echo "$$i"; done \ + | sed -n '/\.3[a-z]*$$/p'; \ + fi; \ + } | while read p; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; echo "$$p"; \ + done | \ + sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^3][0-9a-z]*$$,3,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ + sed 'N;N;s,\n, ,g' | { \ + list=; while read file base inst; do \ + if test "$$base" = "$$inst"; then list="$$list $$file"; else \ + echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man3dir)/$$inst'"; \ + $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man3dir)/$$inst" || exit $$?; \ + fi; \ + done; \ + for i in $$list; do echo "$$i"; done | $(am__base_list) | \ + while read files; do \ + test -z "$$files" || { \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man3dir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(man3dir)" || exit $$?; }; \ + done; } + +uninstall-man3: + @$(NORMAL_UNINSTALL) + @list=''; test -n "$(man3dir)" || exit 0; \ + files=`{ for i in $$list; do echo "$$i"; done; \ + l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ + sed -n '/\.3[a-z]*$$/p'; \ + } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^3][0-9a-z]*$$,3,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ + dir='$(DESTDIR)$(man3dir)'; $(am__uninstall_files_from_dir) +install-m4dataDATA: $(m4data_DATA) + @$(NORMAL_INSTALL) + @list='$(m4data_DATA)'; test -n "$(m4datadir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(m4datadir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(m4datadir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(m4datadir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(m4datadir)" || exit $$?; \ + done + +uninstall-m4dataDATA: + @$(NORMAL_UNINSTALL) + @list='$(m4data_DATA)'; test -n "$(m4datadir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(m4datadir)'; $(am__uninstall_files_from_dir) +install-nodist_libdataDATA: $(nodist_libdata_DATA) + @$(NORMAL_INSTALL) + @list='$(nodist_libdata_DATA)'; test -n "$(libdatadir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(libdatadir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(libdatadir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(libdatadir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(libdatadir)" || exit $$?; \ + done + +uninstall-nodist_libdataDATA: + @$(NORMAL_UNINSTALL) + @list='$(nodist_libdata_DATA)'; test -n "$(libdatadir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(libdatadir)'; $(am__uninstall_files_from_dir) +install-nodist_pkgdataDATA: $(nodist_pkgdata_DATA) + @$(NORMAL_INSTALL) + @list='$(nodist_pkgdata_DATA)'; test -n "$(pkgdatadir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkgdatadir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkgdatadir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgdatadir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgdatadir)" || exit $$?; \ + done + +uninstall-nodist_pkgdataDATA: + @$(NORMAL_UNINSTALL) + @list='$(nodist_pkgdata_DATA)'; test -n "$(pkgdatadir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(pkgdatadir)'; $(am__uninstall_files_from_dir) +install-pkgconfigDATA: $(pkgconfig_DATA) + @$(NORMAL_INSTALL) + @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkgconfigdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigdir)" || exit $$?; \ + done + +uninstall-pkgconfigDATA: + @$(NORMAL_UNINSTALL) + @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(pkgconfigdir)'; $(am__uninstall_files_from_dir) +install-pkgdataDATA: $(pkgdata_DATA) + @$(NORMAL_INSTALL) + @list='$(pkgdata_DATA)'; test -n "$(pkgdatadir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkgdatadir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkgdatadir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgdatadir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgdatadir)" || exit $$?; \ + done + +uninstall-pkgdataDATA: + @$(NORMAL_UNINSTALL) + @list='$(pkgdata_DATA)'; test -n "$(pkgdatadir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(pkgdatadir)'; $(am__uninstall_files_from_dir) +install-nobase_includeHEADERS: $(nobase_include_HEADERS) + @$(NORMAL_INSTALL) + @list='$(nobase_include_HEADERS)'; test -n "$(includedir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(includedir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(includedir)" || exit 1; \ + fi; \ + $(am__nobase_list) | while read dir files; do \ + xfiles=; for file in $$files; do \ + if test -f "$$file"; then xfiles="$$xfiles $$file"; \ + else xfiles="$$xfiles $(srcdir)/$$file"; fi; done; \ + test -z "$$xfiles" || { \ + test "x$$dir" = x. || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(includedir)/$$dir'"; \ + $(MKDIR_P) "$(DESTDIR)$(includedir)/$$dir"; }; \ + echo " $(INSTALL_HEADER) $$xfiles '$(DESTDIR)$(includedir)/$$dir'"; \ + $(INSTALL_HEADER) $$xfiles "$(DESTDIR)$(includedir)/$$dir" || exit $$?; }; \ + done + +uninstall-nobase_includeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(nobase_include_HEADERS)'; test -n "$(includedir)" || list=; \ + $(am__nobase_strip_setup); files=`$(am__nobase_strip)`; \ + dir='$(DESTDIR)$(includedir)'; $(am__uninstall_files_from_dir) + +# This directory's subdirectories are mostly independent; you can cd +# into them and run 'make' without going through this Makefile. +# To change the values of 'make' variables: instead of editing Makefiles, +# (1) if the variable is set in 'config.status', edit 'config.status' +# (which will cause the Makefiles to be regenerated when you run 'make'); +# (2) otherwise, pass the desired values on the 'make' command line. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-recursive + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-recursive + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) check-recursive +all-am: Makefile $(LTLIBRARIES) $(SCRIPTS) $(MANS) $(DATA) $(HEADERS) +installdirs: installdirs-recursive +installdirs-am: + for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man3dir)" "$(DESTDIR)$(m4datadir)" "$(DESTDIR)$(libdatadir)" "$(DESTDIR)$(pkgdatadir)" "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(pkgdatadir)" "$(DESTDIR)$(includedir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) +clean: clean-recursive + +clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ + mostlyclean-am + +distclean: distclean-recursive + -rm -f ./$(DEPDIR)/libopts_la-libopts.Plo + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: install-data-local install-m4dataDATA install-man \ + install-nobase_includeHEADERS install-nodist_libdataDATA \ + install-nodist_pkgdataDATA install-pkgconfigDATA \ + install-pkgdataDATA + @$(NORMAL_INSTALL) + $(MAKE) $(AM_MAKEFLAGS) install-data-hook +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: install-binSCRIPTS install-libLTLIBRARIES + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: install-man1 install-man3 + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f ./$(DEPDIR)/libopts_la-libopts.Plo + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: uninstall-binSCRIPTS uninstall-libLTLIBRARIES \ + uninstall-m4dataDATA uninstall-man \ + uninstall-nobase_includeHEADERS uninstall-nodist_libdataDATA \ + uninstall-nodist_pkgdataDATA uninstall-pkgconfigDATA \ + uninstall-pkgdataDATA + +uninstall-man: uninstall-man1 uninstall-man3 + +.MAKE: $(am__recursive_targets) all check install install-am \ + install-data-am install-strip + +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ + am--depfiles check check-am clean clean-generic \ + clean-libLTLIBRARIES clean-libtool cscopelist-am ctags \ + ctags-am distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-binSCRIPTS \ + install-data install-data-am install-data-hook \ + install-data-local install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-libLTLIBRARIES install-m4dataDATA \ + install-man install-man1 install-man3 \ + install-nobase_includeHEADERS install-nodist_libdataDATA \ + install-nodist_pkgdataDATA install-pdf install-pdf-am \ + install-pkgconfigDATA install-pkgdataDATA install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs installdirs-am maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am uninstall-binSCRIPTS \ + uninstall-libLTLIBRARIES uninstall-m4dataDATA uninstall-man \ + uninstall-man1 uninstall-man3 uninstall-nobase_includeHEADERS \ + uninstall-nodist_libdataDATA uninstall-nodist_pkgdataDATA \ + uninstall-pkgconfigDATA uninstall-pkgdataDATA + +.PRECIOUS: Makefile + +# We need the following in order to create when the system +# doesn't have one that works. +@GL_GENERATE_STDNORETURN_H_TRUE@stdnoreturn.h: stdnoreturn.in.h $(top_builddir)/config.status $(_NORETURN_H) +@GL_GENERATE_STDNORETURN_H_TRUE@ $(AM_V_GEN)rm -f $@-t $@ && \ +@GL_GENERATE_STDNORETURN_H_TRUE@ { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ +@GL_GENERATE_STDNORETURN_H_TRUE@ sed -e '/definition of _Noreturn/r $(_NORETURN_H)' \ +@GL_GENERATE_STDNORETURN_H_TRUE@ < $(srcdir)/stdnoreturn.in.h; \ +@GL_GENERATE_STDNORETURN_H_TRUE@ } > $@-t && \ +@GL_GENERATE_STDNORETURN_H_TRUE@ mv $@-t $@ +@GL_GENERATE_STDNORETURN_H_FALSE@stdnoreturn.h: $(top_builddir)/config.status +@GL_GENERATE_STDNORETURN_H_FALSE@ rm -f $@ + +libopts.c : tpl-config-stamp +$(GENSCRIPTS) : tpl-config-stamp + +tpl-config-stamp: $(HDRS) $(CSRC) \ + $(top_builddir)/config.h $(srcdir)/mk-tpl-config.sh + LGCFLAGS="$(GUILE_CFLAGS)" \ + $(BOOTENV) \ + $(POSIX_SHELL) $(srcdir)/mk-tpl-config.sh $@ $(HDRS) $(CSRC) + +makeshell.lo : genshell.c +genshell.c : $(srcdir)/genshell.def + $(BOOTENV) \ + $(POSIX_SHELL) $(srcdir)/bootstrap.dir $@ + +strcspn.lo : $(top_srcdir)/compat/strcspn.c + $(LTCOMPILE) -o $@ -c $(top_srcdir)/compat/strcspn.c + +install-data-local : install-man3 + +$(GENMAN) : $(MAN_STAMP) +$(MAN_STAMP) : $(srcdir)/funcs.def + @test -x ../agen5/autogen || exit 0 ; \ + touch tmp-$@ ; \ + opts='-L$(srcdir)/tpl -L$(builddir)/tpl -Tagman3.tpl' ; \ + echo ! $(AGexe) $${opts} $(srcdir)/funcs.def ; \ + $(AGexe) $${opts} $(srcdir)/funcs.def ; \ + mv -f tmp-$@ $@ + +$(GENTEXI) : $(TEXI_STAMP) +$(TEXI_STAMP) : ../agen5/autogen $(srcdir)/funcs.def + @touch tmp-$@ ; \ + opts='-L$(srcdir)/tpl -L$(builddir)/tpl -Taginfo3.tpl' ; \ + cmd="$(AGexe) $${opts} -DLEVEL=subsection -blibopts" ; \ + cmd="$${cmd} -L$(srcdir) $(srcdir)/funcs.def" ; \ + echo ! $$cmd ; $$cmd ; mv -f tmp-$@ $@ + +libsrc : $(libsrc) +$(libsrc) : + @$(BOOTENV) \ + AO_AGE=@AO_AGE@ AO_CURRENT=@AO_CURRENT@ AO_REVISION=@AO_REVISION@ \ + $(POSIX_SHELL) $(top_srcdir)/pkg/libopts/mklibsrc.sh + +pkgconfig/autoopts.pc : mk-autoopts-pc + $(POSIX_SHELL) mk-autoopts-pc $@ + +install-data-hook: + @DESTdestdir='$(DESTDIR)$(includedir)/autoopts' \ + DESTpkgdatadir='$(DESTDIR)$(pkgdatadir)' \ + DESTlibdatadir='$(DESTDIR)$(pkglibdir)' \ + top_builddir='$(top_builddir)' \ + LIBOPTS_VER='$(LIBOPTS_VER)' \ + POSIX_SHELL='$(POSIX_SHELL)' \ + bindir='$(bindir)' \ + $(POSIX_SHELL) $(srcdir)/install-hook.sh + +.NOTPARALLEL: + +# Makefile.am ends here + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/autoopts/_Noreturn.h b/autoopts/_Noreturn.h new file mode 100644 index 0000000..c44ad89 --- /dev/null +++ b/autoopts/_Noreturn.h @@ -0,0 +1,10 @@ +#if !defined _Noreturn && __STDC_VERSION__ < 201112 +# if (3 <= __GNUC__ || (__GNUC__ == 2 && 8 <= __GNUC_MINOR__) \ + || 0x5110 <= __SUNPRO_C) +# define _Noreturn __attribute__ ((__noreturn__)) +# elif 1200 <= _MSC_VER +# define _Noreturn __declspec (noreturn) +# else +# define _Noreturn +# endif +#endif diff --git a/autoopts/ag-char-map.h b/autoopts/ag-char-map.h new file mode 100644 index 0000000..cced230 --- /dev/null +++ b/autoopts/ag-char-map.h @@ -0,0 +1,526 @@ +/* + * 29 bits for 46 character classifications + * generated by char-mapper on 08/26/18 at 10:44:22 + * + * This file contains the character classifications + * used by AutoGen and AutoOpts for identifying tokens. + * The table is static scope, so %guard is empty. + * + * This file is part of AutoOpts, a companion to AutoGen. + * AutoOpts is free software. + * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoOpts is available under any one of two licenses. The license + * in use must be one of these two and the choice is under the control + * of the user of the license. + * + * The GNU Lesser General Public License, version 3 or later + * See the files "COPYING.lgplv3" and "COPYING.gplv3" + * + * The Modified Berkeley Software Distribution License + * See the file "COPYING.mbsd" + * + * These files have the following sha256 sums: + * + * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 + * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 + * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + */ +#ifndef AG_CHAR_MAP_H_GUARD +#define AG_CHAR_MAP_H_GUARD 1 + +#ifdef HAVE_CONFIG_H +# if defined(HAVE_INTTYPES_H) +# include + +# elif defined(HAVE_STDINT_H) +# include + +# elif !defined(HAVE_UINT32_T) +# if SIZEOF_INT == 4 + typedef unsigned int uint32_t; +# elif SIZEOF_LONG == 4 + typedef unsigned long uint32_t; +# endif +# endif /* HAVE_*INT*_H header */ + +#else /* not HAVE_CONFIG_H -- */ +# include +#endif /* HAVE_CONFIG_H */ + +#if 0 /* mapping specification source (from autogen.map) */ +// +// %guard +// %file ag-char-map.h +// %backup +// %optimize +// +// %comment -- see above +// % +// +// newline "\n" +// nul-byte "\x00" +// dir-sep "/\\" +// percent "%" +// comma "," +// colon ":" +// underscore "_" +// plus "+" +// dollar "$" +// option-marker "-" +// +// horiz-white "\t " +// alt-white "\v\f\r\b" +// whitespace +horiz-white +newline +alt-white +// non-nl-white +horiz-white +alt-white +// quote "'\"" +// parentheses "()" +// +// graphic "!-~" +// inversion "~-" +// oct-digit "0-7" +// dec-digit "89" +oct-digit +// hex-digit "a-fA-F" +dec-digit +// lower-case "a-z" +// upper-case "A-Z" +// alphabetic +lower-case +upper-case +// alphanumeric +alphabetic +dec-digit +// var-first +underscore +alphabetic +// variable-name +var-first +dec-digit +// option-name "^-" +variable-name +// value-name +colon +option-name +// name-sep "[.]" +// compound-name +value-name +name-sep +horiz-white +// scheme-note +parentheses +quote +// +// unquotable "!-~" -"#,;<=>[\\]`{}?*" -quote -parentheses +// end-xml-token "/>" +whitespace +// plus-n-space +plus +whitespace +// punctuation "!-~" -alphanumeric -"_" +// suffix "-._" +alphanumeric +// suffix-fmt +percent +suffix +dir-sep +// false-type "nNfF0" +nul-byte +// file-name +dir-sep +suffix +// end-token +nul-byte +whitespace +// end-list-entry +comma +end-token +// set-separator "|+-!" +end-list-entry +// signed-number +inversion +dec-digit +// make-script +dollar +newline +// load-line-skip +horiz-white +option-marker +// +#endif /* 0 -- mapping spec. source */ + + +typedef uint32_t ag_char_map_mask_t; + +#define IS_NEWLINE_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00000001) +#define SPN_NEWLINE_CHARS(_s) spn_ag_char_map_chars(_s, 0) +#define BRK_NEWLINE_CHARS(_s) brk_ag_char_map_chars(_s, 0) +#define SPN_NEWLINE_BACK(s,e) spn_ag_char_map_back(s, e, 0) +#define BRK_NEWLINE_BACK(s,e) brk_ag_char_map_back(s, e, 0) +#define IS_NUL_BYTE_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00000002) +#define SPN_NUL_BYTE_CHARS(_s) spn_ag_char_map_chars(_s, 1) +#define BRK_NUL_BYTE_CHARS(_s) brk_ag_char_map_chars(_s, 1) +#define SPN_NUL_BYTE_BACK(s,e) spn_ag_char_map_back(s, e, 1) +#define BRK_NUL_BYTE_BACK(s,e) brk_ag_char_map_back(s, e, 1) +#define IS_DIR_SEP_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00000004) +#define SPN_DIR_SEP_CHARS(_s) spn_ag_char_map_chars(_s, 2) +#define BRK_DIR_SEP_CHARS(_s) brk_ag_char_map_chars(_s, 2) +#define SPN_DIR_SEP_BACK(s,e) spn_ag_char_map_back(s, e, 2) +#define BRK_DIR_SEP_BACK(s,e) brk_ag_char_map_back(s, e, 2) +#define IS_PERCENT_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00000008) +#define SPN_PERCENT_CHARS(_s) spn_ag_char_map_chars(_s, 3) +#define BRK_PERCENT_CHARS(_s) brk_ag_char_map_chars(_s, 3) +#define SPN_PERCENT_BACK(s,e) spn_ag_char_map_back(s, e, 3) +#define BRK_PERCENT_BACK(s,e) brk_ag_char_map_back(s, e, 3) +#define IS_COMMA_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00000010) +#define SPN_COMMA_CHARS(_s) spn_ag_char_map_chars(_s, 4) +#define BRK_COMMA_CHARS(_s) brk_ag_char_map_chars(_s, 4) +#define SPN_COMMA_BACK(s,e) spn_ag_char_map_back(s, e, 4) +#define BRK_COMMA_BACK(s,e) brk_ag_char_map_back(s, e, 4) +#define IS_COLON_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00000020) +#define SPN_COLON_CHARS(_s) spn_ag_char_map_chars(_s, 5) +#define BRK_COLON_CHARS(_s) brk_ag_char_map_chars(_s, 5) +#define SPN_COLON_BACK(s,e) spn_ag_char_map_back(s, e, 5) +#define BRK_COLON_BACK(s,e) brk_ag_char_map_back(s, e, 5) +#define IS_UNDERSCORE_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00000040) +#define SPN_UNDERSCORE_CHARS(_s) spn_ag_char_map_chars(_s, 6) +#define BRK_UNDERSCORE_CHARS(_s) brk_ag_char_map_chars(_s, 6) +#define SPN_UNDERSCORE_BACK(s,e) spn_ag_char_map_back(s, e, 6) +#define BRK_UNDERSCORE_BACK(s,e) brk_ag_char_map_back(s, e, 6) +#define IS_PLUS_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00000080) +#define SPN_PLUS_CHARS(_s) spn_ag_char_map_chars(_s, 7) +#define BRK_PLUS_CHARS(_s) brk_ag_char_map_chars(_s, 7) +#define SPN_PLUS_BACK(s,e) spn_ag_char_map_back(s, e, 7) +#define BRK_PLUS_BACK(s,e) brk_ag_char_map_back(s, e, 7) +#define IS_DOLLAR_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00000100) +#define SPN_DOLLAR_CHARS(_s) spn_ag_char_map_chars(_s, 8) +#define BRK_DOLLAR_CHARS(_s) brk_ag_char_map_chars(_s, 8) +#define SPN_DOLLAR_BACK(s,e) spn_ag_char_map_back(s, e, 8) +#define BRK_DOLLAR_BACK(s,e) brk_ag_char_map_back(s, e, 8) +#define IS_OPTION_MARKER_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00000200) +#define SPN_OPTION_MARKER_CHARS(_s) spn_ag_char_map_chars(_s, 9) +#define BRK_OPTION_MARKER_CHARS(_s) brk_ag_char_map_chars(_s, 9) +#define SPN_OPTION_MARKER_BACK(s,e) spn_ag_char_map_back(s, e, 9) +#define BRK_OPTION_MARKER_BACK(s,e) brk_ag_char_map_back(s, e, 9) +#define IS_HORIZ_WHITE_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00000400) +#define SPN_HORIZ_WHITE_CHARS(_s) spn_ag_char_map_chars(_s, 10) +#define BRK_HORIZ_WHITE_CHARS(_s) brk_ag_char_map_chars(_s, 10) +#define SPN_HORIZ_WHITE_BACK(s,e) spn_ag_char_map_back(s, e, 10) +#define BRK_HORIZ_WHITE_BACK(s,e) brk_ag_char_map_back(s, e, 10) +#define IS_ALT_WHITE_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00000800) +#define SPN_ALT_WHITE_CHARS(_s) spn_ag_char_map_chars(_s, 11) +#define BRK_ALT_WHITE_CHARS(_s) brk_ag_char_map_chars(_s, 11) +#define SPN_ALT_WHITE_BACK(s,e) spn_ag_char_map_back(s, e, 11) +#define BRK_ALT_WHITE_BACK(s,e) brk_ag_char_map_back(s, e, 11) +#define IS_WHITESPACE_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00000C01) +#define SPN_WHITESPACE_CHARS(_s) spn_ag_char_map_chars(_s, 12) +#define BRK_WHITESPACE_CHARS(_s) brk_ag_char_map_chars(_s, 12) +#define SPN_WHITESPACE_BACK(s,e) spn_ag_char_map_back(s, e, 12) +#define BRK_WHITESPACE_BACK(s,e) brk_ag_char_map_back(s, e, 12) +#define IS_NON_NL_WHITE_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00000C00) +#define SPN_NON_NL_WHITE_CHARS(_s) spn_ag_char_map_chars(_s, 13) +#define BRK_NON_NL_WHITE_CHARS(_s) brk_ag_char_map_chars(_s, 13) +#define SPN_NON_NL_WHITE_BACK(s,e) spn_ag_char_map_back(s, e, 13) +#define BRK_NON_NL_WHITE_BACK(s,e) brk_ag_char_map_back(s, e, 13) +#define IS_QUOTE_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00001000) +#define SPN_QUOTE_CHARS(_s) spn_ag_char_map_chars(_s, 14) +#define BRK_QUOTE_CHARS(_s) brk_ag_char_map_chars(_s, 14) +#define SPN_QUOTE_BACK(s,e) spn_ag_char_map_back(s, e, 14) +#define BRK_QUOTE_BACK(s,e) brk_ag_char_map_back(s, e, 14) +#define IS_PARENTHESES_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00002000) +#define SPN_PARENTHESES_CHARS(_s) spn_ag_char_map_chars(_s, 15) +#define BRK_PARENTHESES_CHARS(_s) brk_ag_char_map_chars(_s, 15) +#define SPN_PARENTHESES_BACK(s,e) spn_ag_char_map_back(s, e, 15) +#define BRK_PARENTHESES_BACK(s,e) brk_ag_char_map_back(s, e, 15) +#define IS_GRAPHIC_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00004000) +#define SPN_GRAPHIC_CHARS(_s) spn_ag_char_map_chars(_s, 16) +#define BRK_GRAPHIC_CHARS(_s) brk_ag_char_map_chars(_s, 16) +#define SPN_GRAPHIC_BACK(s,e) spn_ag_char_map_back(s, e, 16) +#define BRK_GRAPHIC_BACK(s,e) brk_ag_char_map_back(s, e, 16) +#define IS_INVERSION_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00008000) +#define SPN_INVERSION_CHARS(_s) spn_ag_char_map_chars(_s, 17) +#define BRK_INVERSION_CHARS(_s) brk_ag_char_map_chars(_s, 17) +#define SPN_INVERSION_BACK(s,e) spn_ag_char_map_back(s, e, 17) +#define BRK_INVERSION_BACK(s,e) brk_ag_char_map_back(s, e, 17) +#define IS_OCT_DIGIT_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00010000) +#define SPN_OCT_DIGIT_CHARS(_s) spn_ag_char_map_chars(_s, 18) +#define BRK_OCT_DIGIT_CHARS(_s) brk_ag_char_map_chars(_s, 18) +#define SPN_OCT_DIGIT_BACK(s,e) spn_ag_char_map_back(s, e, 18) +#define BRK_OCT_DIGIT_BACK(s,e) brk_ag_char_map_back(s, e, 18) +#define IS_DEC_DIGIT_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00030000) +#define SPN_DEC_DIGIT_CHARS(_s) spn_ag_char_map_chars(_s, 19) +#define BRK_DEC_DIGIT_CHARS(_s) brk_ag_char_map_chars(_s, 19) +#define SPN_DEC_DIGIT_BACK(s,e) spn_ag_char_map_back(s, e, 19) +#define BRK_DEC_DIGIT_BACK(s,e) brk_ag_char_map_back(s, e, 19) +#define IS_HEX_DIGIT_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00070000) +#define SPN_HEX_DIGIT_CHARS(_s) spn_ag_char_map_chars(_s, 20) +#define BRK_HEX_DIGIT_CHARS(_s) brk_ag_char_map_chars(_s, 20) +#define SPN_HEX_DIGIT_BACK(s,e) spn_ag_char_map_back(s, e, 20) +#define BRK_HEX_DIGIT_BACK(s,e) brk_ag_char_map_back(s, e, 20) +#define IS_LOWER_CASE_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00080000) +#define SPN_LOWER_CASE_CHARS(_s) spn_ag_char_map_chars(_s, 21) +#define BRK_LOWER_CASE_CHARS(_s) brk_ag_char_map_chars(_s, 21) +#define SPN_LOWER_CASE_BACK(s,e) spn_ag_char_map_back(s, e, 21) +#define BRK_LOWER_CASE_BACK(s,e) brk_ag_char_map_back(s, e, 21) +#define IS_UPPER_CASE_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00100000) +#define SPN_UPPER_CASE_CHARS(_s) spn_ag_char_map_chars(_s, 22) +#define BRK_UPPER_CASE_CHARS(_s) brk_ag_char_map_chars(_s, 22) +#define SPN_UPPER_CASE_BACK(s,e) spn_ag_char_map_back(s, e, 22) +#define BRK_UPPER_CASE_BACK(s,e) brk_ag_char_map_back(s, e, 22) +#define IS_ALPHABETIC_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00180000) +#define SPN_ALPHABETIC_CHARS(_s) spn_ag_char_map_chars(_s, 23) +#define BRK_ALPHABETIC_CHARS(_s) brk_ag_char_map_chars(_s, 23) +#define SPN_ALPHABETIC_BACK(s,e) spn_ag_char_map_back(s, e, 23) +#define BRK_ALPHABETIC_BACK(s,e) brk_ag_char_map_back(s, e, 23) +#define IS_ALPHANUMERIC_CHAR( _c) is_ag_char_map_char((char)(_c), 0x001B0000) +#define SPN_ALPHANUMERIC_CHARS(_s) spn_ag_char_map_chars(_s, 24) +#define BRK_ALPHANUMERIC_CHARS(_s) brk_ag_char_map_chars(_s, 24) +#define SPN_ALPHANUMERIC_BACK(s,e) spn_ag_char_map_back(s, e, 24) +#define BRK_ALPHANUMERIC_BACK(s,e) brk_ag_char_map_back(s, e, 24) +#define IS_VAR_FIRST_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00180040) +#define SPN_VAR_FIRST_CHARS(_s) spn_ag_char_map_chars(_s, 25) +#define BRK_VAR_FIRST_CHARS(_s) brk_ag_char_map_chars(_s, 25) +#define SPN_VAR_FIRST_BACK(s,e) spn_ag_char_map_back(s, e, 25) +#define BRK_VAR_FIRST_BACK(s,e) brk_ag_char_map_back(s, e, 25) +#define IS_VARIABLE_NAME_CHAR( _c) is_ag_char_map_char((char)(_c), 0x001B0040) +#define SPN_VARIABLE_NAME_CHARS(_s) spn_ag_char_map_chars(_s, 26) +#define BRK_VARIABLE_NAME_CHARS(_s) brk_ag_char_map_chars(_s, 26) +#define SPN_VARIABLE_NAME_BACK(s,e) spn_ag_char_map_back(s, e, 26) +#define BRK_VARIABLE_NAME_BACK(s,e) brk_ag_char_map_back(s, e, 26) +#define IS_OPTION_NAME_CHAR( _c) is_ag_char_map_char((char)(_c), 0x003B0040) +#define SPN_OPTION_NAME_CHARS(_s) spn_ag_char_map_chars(_s, 27) +#define BRK_OPTION_NAME_CHARS(_s) brk_ag_char_map_chars(_s, 27) +#define SPN_OPTION_NAME_BACK(s,e) spn_ag_char_map_back(s, e, 27) +#define BRK_OPTION_NAME_BACK(s,e) brk_ag_char_map_back(s, e, 27) +#define IS_VALUE_NAME_CHAR( _c) is_ag_char_map_char((char)(_c), 0x003B0060) +#define SPN_VALUE_NAME_CHARS(_s) spn_ag_char_map_chars(_s, 28) +#define BRK_VALUE_NAME_CHARS(_s) brk_ag_char_map_chars(_s, 28) +#define SPN_VALUE_NAME_BACK(s,e) spn_ag_char_map_back(s, e, 28) +#define BRK_VALUE_NAME_BACK(s,e) brk_ag_char_map_back(s, e, 28) +#define IS_NAME_SEP_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00400000) +#define SPN_NAME_SEP_CHARS(_s) spn_ag_char_map_chars(_s, 29) +#define BRK_NAME_SEP_CHARS(_s) brk_ag_char_map_chars(_s, 29) +#define SPN_NAME_SEP_BACK(s,e) spn_ag_char_map_back(s, e, 29) +#define BRK_NAME_SEP_BACK(s,e) brk_ag_char_map_back(s, e, 29) +#define IS_COMPOUND_NAME_CHAR( _c) is_ag_char_map_char((char)(_c), 0x007B0460) +#define SPN_COMPOUND_NAME_CHARS(_s) spn_ag_char_map_chars(_s, 30) +#define BRK_COMPOUND_NAME_CHARS(_s) brk_ag_char_map_chars(_s, 30) +#define SPN_COMPOUND_NAME_BACK(s,e) spn_ag_char_map_back(s, e, 30) +#define BRK_COMPOUND_NAME_BACK(s,e) brk_ag_char_map_back(s, e, 30) +#define IS_SCHEME_NOTE_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00003000) +#define SPN_SCHEME_NOTE_CHARS(_s) spn_ag_char_map_chars(_s, 31) +#define BRK_SCHEME_NOTE_CHARS(_s) brk_ag_char_map_chars(_s, 31) +#define SPN_SCHEME_NOTE_BACK(s,e) spn_ag_char_map_back(s, e, 31) +#define BRK_SCHEME_NOTE_BACK(s,e) brk_ag_char_map_back(s, e, 31) +#define IS_UNQUOTABLE_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00800000) +#define SPN_UNQUOTABLE_CHARS(_s) spn_ag_char_map_chars(_s, 32) +#define BRK_UNQUOTABLE_CHARS(_s) brk_ag_char_map_chars(_s, 32) +#define SPN_UNQUOTABLE_BACK(s,e) spn_ag_char_map_back(s, e, 32) +#define BRK_UNQUOTABLE_BACK(s,e) brk_ag_char_map_back(s, e, 32) +#define IS_END_XML_TOKEN_CHAR( _c) is_ag_char_map_char((char)(_c), 0x01000C01) +#define SPN_END_XML_TOKEN_CHARS(_s) spn_ag_char_map_chars(_s, 33) +#define BRK_END_XML_TOKEN_CHARS(_s) brk_ag_char_map_chars(_s, 33) +#define SPN_END_XML_TOKEN_BACK(s,e) spn_ag_char_map_back(s, e, 33) +#define BRK_END_XML_TOKEN_BACK(s,e) brk_ag_char_map_back(s, e, 33) +#define IS_PLUS_N_SPACE_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00000C81) +#define SPN_PLUS_N_SPACE_CHARS(_s) spn_ag_char_map_chars(_s, 34) +#define BRK_PLUS_N_SPACE_CHARS(_s) brk_ag_char_map_chars(_s, 34) +#define SPN_PLUS_N_SPACE_BACK(s,e) spn_ag_char_map_back(s, e, 34) +#define BRK_PLUS_N_SPACE_BACK(s,e) brk_ag_char_map_back(s, e, 34) +#define IS_PUNCTUATION_CHAR( _c) is_ag_char_map_char((char)(_c), 0x02000000) +#define SPN_PUNCTUATION_CHARS(_s) spn_ag_char_map_chars(_s, 35) +#define BRK_PUNCTUATION_CHARS(_s) brk_ag_char_map_chars(_s, 35) +#define SPN_PUNCTUATION_BACK(s,e) spn_ag_char_map_back(s, e, 35) +#define BRK_PUNCTUATION_BACK(s,e) brk_ag_char_map_back(s, e, 35) +#define IS_SUFFIX_CHAR( _c) is_ag_char_map_char((char)(_c), 0x041B0000) +#define SPN_SUFFIX_CHARS(_s) spn_ag_char_map_chars(_s, 36) +#define BRK_SUFFIX_CHARS(_s) brk_ag_char_map_chars(_s, 36) +#define SPN_SUFFIX_BACK(s,e) spn_ag_char_map_back(s, e, 36) +#define BRK_SUFFIX_BACK(s,e) brk_ag_char_map_back(s, e, 36) +#define IS_SUFFIX_FMT_CHAR( _c) is_ag_char_map_char((char)(_c), 0x041B000C) +#define SPN_SUFFIX_FMT_CHARS(_s) spn_ag_char_map_chars(_s, 37) +#define BRK_SUFFIX_FMT_CHARS(_s) brk_ag_char_map_chars(_s, 37) +#define SPN_SUFFIX_FMT_BACK(s,e) spn_ag_char_map_back(s, e, 37) +#define BRK_SUFFIX_FMT_BACK(s,e) brk_ag_char_map_back(s, e, 37) +#define IS_FALSE_TYPE_CHAR( _c) is_ag_char_map_char((char)(_c), 0x08000002) +#define SPN_FALSE_TYPE_CHARS(_s) spn_ag_char_map_chars(_s, 38) +#define BRK_FALSE_TYPE_CHARS(_s) brk_ag_char_map_chars(_s, 38) +#define SPN_FALSE_TYPE_BACK(s,e) spn_ag_char_map_back(s, e, 38) +#define BRK_FALSE_TYPE_BACK(s,e) brk_ag_char_map_back(s, e, 38) +#define IS_FILE_NAME_CHAR( _c) is_ag_char_map_char((char)(_c), 0x041B0004) +#define SPN_FILE_NAME_CHARS(_s) spn_ag_char_map_chars(_s, 39) +#define BRK_FILE_NAME_CHARS(_s) brk_ag_char_map_chars(_s, 39) +#define SPN_FILE_NAME_BACK(s,e) spn_ag_char_map_back(s, e, 39) +#define BRK_FILE_NAME_BACK(s,e) brk_ag_char_map_back(s, e, 39) +#define IS_END_TOKEN_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00000C03) +#define SPN_END_TOKEN_CHARS(_s) spn_ag_char_map_chars(_s, 40) +#define BRK_END_TOKEN_CHARS(_s) brk_ag_char_map_chars(_s, 40) +#define SPN_END_TOKEN_BACK(s,e) spn_ag_char_map_back(s, e, 40) +#define BRK_END_TOKEN_BACK(s,e) brk_ag_char_map_back(s, e, 40) +#define IS_END_LIST_ENTRY_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00000C13) +#define SPN_END_LIST_ENTRY_CHARS(_s) spn_ag_char_map_chars(_s, 41) +#define BRK_END_LIST_ENTRY_CHARS(_s) brk_ag_char_map_chars(_s, 41) +#define SPN_END_LIST_ENTRY_BACK(s,e) spn_ag_char_map_back(s, e, 41) +#define BRK_END_LIST_ENTRY_BACK(s,e) brk_ag_char_map_back(s, e, 41) +#define IS_SET_SEPARATOR_CHAR( _c) is_ag_char_map_char((char)(_c), 0x10000C13) +#define SPN_SET_SEPARATOR_CHARS(_s) spn_ag_char_map_chars(_s, 42) +#define BRK_SET_SEPARATOR_CHARS(_s) brk_ag_char_map_chars(_s, 42) +#define SPN_SET_SEPARATOR_BACK(s,e) spn_ag_char_map_back(s, e, 42) +#define BRK_SET_SEPARATOR_BACK(s,e) brk_ag_char_map_back(s, e, 42) +#define IS_SIGNED_NUMBER_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00038000) +#define SPN_SIGNED_NUMBER_CHARS(_s) spn_ag_char_map_chars(_s, 43) +#define BRK_SIGNED_NUMBER_CHARS(_s) brk_ag_char_map_chars(_s, 43) +#define SPN_SIGNED_NUMBER_BACK(s,e) spn_ag_char_map_back(s, e, 43) +#define BRK_SIGNED_NUMBER_BACK(s,e) brk_ag_char_map_back(s, e, 43) +#define IS_MAKE_SCRIPT_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00000101) +#define SPN_MAKE_SCRIPT_CHARS(_s) spn_ag_char_map_chars(_s, 44) +#define BRK_MAKE_SCRIPT_CHARS(_s) brk_ag_char_map_chars(_s, 44) +#define SPN_MAKE_SCRIPT_BACK(s,e) spn_ag_char_map_back(s, e, 44) +#define BRK_MAKE_SCRIPT_BACK(s,e) brk_ag_char_map_back(s, e, 44) +#define IS_LOAD_LINE_SKIP_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00000600) +#define SPN_LOAD_LINE_SKIP_CHARS(_s) spn_ag_char_map_chars(_s, 45) +#define BRK_LOAD_LINE_SKIP_CHARS(_s) brk_ag_char_map_chars(_s, 45) +#define SPN_LOAD_LINE_SKIP_BACK(s,e) spn_ag_char_map_back(s, e, 45) +#define BRK_LOAD_LINE_SKIP_BACK(s,e) brk_ag_char_map_back(s, e, 45) + +static ag_char_map_mask_t const ag_char_map_table[128] = { + /*NUL*/ 0x00000002, /*x01*/ 0x00000000, /*x02*/ 0x00000000, /*x03*/ 0x00000000, + /*x04*/ 0x00000000, /*x05*/ 0x00000000, /*x06*/ 0x00000000, /*BEL*/ 0x00000000, + /* BS*/ 0x00000800, /* HT*/ 0x00000400, /* NL*/ 0x00000001, /* VT*/ 0x00000800, + /* FF*/ 0x00000800, /* CR*/ 0x00000800, /*x0E*/ 0x00000000, /*x0F*/ 0x00000000, + /*x10*/ 0x00000000, /*x11*/ 0x00000000, /*x12*/ 0x00000000, /*x13*/ 0x00000000, + /*x14*/ 0x00000000, /*x15*/ 0x00000000, /*x16*/ 0x00000000, /*x17*/ 0x00000000, + /*x18*/ 0x00000000, /*x19*/ 0x00000000, /*x1A*/ 0x00000000, /*ESC*/ 0x00000000, + /*x1C*/ 0x00000000, /*x1D*/ 0x00000000, /*x1E*/ 0x00000000, /*x1F*/ 0x00000000, + /* */ 0x00000400, /* ! */ 0x02804000, /* " */ 0x02005000, /* # */ 0x02004000, + /* $ */ 0x02804100, /* % */ 0x02804008, /* & */ 0x02804000, /* ' */ 0x02005000, + /* ( */ 0x02006000, /* ) */ 0x02006000, /* * */ 0x02004000, /* + */ 0x12804080, + /* , */ 0x02004010, /* - */ 0x06A0C200, /* . */ 0x06C04000, /* / */ 0x03804004, + /* 0 */ 0x08814000, /* 1 */ 0x00814000, /* 2 */ 0x00814000, /* 3 */ 0x00814000, + /* 4 */ 0x00814000, /* 5 */ 0x00814000, /* 6 */ 0x00814000, /* 7 */ 0x00814000, + /* 8 */ 0x00824000, /* 9 */ 0x00824000, /* : */ 0x02804020, /* ; */ 0x02004000, + /* < */ 0x02004000, /* = */ 0x02004000, /* > */ 0x03004000, /* ? */ 0x02004000, + /* @ */ 0x02804000, /* A */ 0x00944000, /* B */ 0x00944000, /* C */ 0x00944000, + /* D */ 0x00944000, /* E */ 0x00944000, /* F */ 0x08944000, /* G */ 0x00904000, + /* H */ 0x00904000, /* I */ 0x00904000, /* J */ 0x00904000, /* K */ 0x00904000, + /* L */ 0x00904000, /* M */ 0x00904000, /* N */ 0x08904000, /* O */ 0x00904000, + /* P */ 0x00904000, /* Q */ 0x00904000, /* R */ 0x00904000, /* S */ 0x00904000, + /* T */ 0x00904000, /* U */ 0x00904000, /* V */ 0x00904000, /* W */ 0x00904000, + /* X */ 0x00904000, /* Y */ 0x00904000, /* Z */ 0x00904000, /* [ */ 0x02404000, + /* \ */ 0x02004004, /* ] */ 0x02404000, /* ^ */ 0x02A04000, /* _ */ 0x04804040, + /* ` */ 0x02004000, /* a */ 0x008C4000, /* b */ 0x008C4000, /* c */ 0x008C4000, + /* d */ 0x008C4000, /* e */ 0x008C4000, /* f */ 0x088C4000, /* g */ 0x00884000, + /* h */ 0x00884000, /* i */ 0x00884000, /* j */ 0x00884000, /* k */ 0x00884000, + /* l */ 0x00884000, /* m */ 0x00884000, /* n */ 0x08884000, /* o */ 0x00884000, + /* p */ 0x00884000, /* q */ 0x00884000, /* r */ 0x00884000, /* s */ 0x00884000, + /* t */ 0x00884000, /* u */ 0x00884000, /* v */ 0x00884000, /* w */ 0x00884000, + /* x */ 0x00884000, /* y */ 0x00884000, /* z */ 0x00884000, /* { */ 0x02004000, + /* | */ 0x12804000, /* } */ 0x02004000, /* ~ */ 0x0280C000, /*x7F*/ 0x00000000 +}; + +#include +#include +#include + +#ifndef _ +# define _(_s) _s +#endif + +static unsigned char const * ag_char_map_spanners[46]; +/** + * Character category masks. Some categories may have multiple bits, + * if their definition incorporates other character categories. + * This mask array is only used by calc_ag_char_map_spanners(). + */ +static ag_char_map_mask_t const ag_char_map_masks[46] = { + 0x00000001, /* NEWLINE */ + 0x00000002, /* NUL_BYTE */ + 0x00000004, /* DIR_SEP */ + 0x00000008, /* PERCENT */ + 0x00000010, /* COMMA */ + 0x00000020, /* COLON */ + 0x00000040, /* UNDERSCORE */ + 0x00000080, /* PLUS */ + 0x00000100, /* DOLLAR */ + 0x00000200, /* OPTION_MARKER */ + 0x00000400, /* HORIZ_WHITE */ + 0x00000800, /* ALT_WHITE */ + 0x00000C01, /* WHITESPACE */ + 0x00000C00, /* NON_NL_WHITE */ + 0x00001000, /* QUOTE */ + 0x00002000, /* PARENTHESES */ + 0x00004000, /* GRAPHIC */ + 0x00008000, /* INVERSION */ + 0x00010000, /* OCT_DIGIT */ + 0x00030000, /* DEC_DIGIT */ + 0x00070000, /* HEX_DIGIT */ + 0x00080000, /* LOWER_CASE */ + 0x00100000, /* UPPER_CASE */ + 0x00180000, /* ALPHABETIC */ + 0x001B0000, /* ALPHANUMERIC */ + 0x00180040, /* VAR_FIRST */ + 0x001B0040, /* VARIABLE_NAME */ + 0x003B0040, /* OPTION_NAME */ + 0x003B0060, /* VALUE_NAME */ + 0x00400000, /* NAME_SEP */ + 0x007B0460, /* COMPOUND_NAME */ + 0x00003000, /* SCHEME_NOTE */ + 0x00800000, /* UNQUOTABLE */ + 0x01000C01, /* END_XML_TOKEN */ + 0x00000C81, /* PLUS_N_SPACE */ + 0x02000000, /* PUNCTUATION */ + 0x041B0000, /* SUFFIX */ + 0x041B000C, /* SUFFIX_FMT */ + 0x08000002, /* FALSE_TYPE */ + 0x041B0004, /* FILE_NAME */ + 0x00000C03, /* END_TOKEN */ + 0x00000C13, /* END_LIST_ENTRY */ + 0x10000C13, /* SET_SEPARATOR */ + 0x00038000, /* SIGNED_NUMBER */ + 0x00000101, /* MAKE_SCRIPT */ + 0x00000600, /* LOAD_LINE_SKIP */ +}; +#undef LOCK_SPANNER_TABLES + +static unsigned char const * +calc_ag_char_map_spanners(unsigned int mask_ix) +{ +#ifdef LOCK_SPANNER_TABLES + if (ag_char_map_spanners[mask_ix] != NULL) + return ag_char_map_spanners[mask_ix]; + + pthread_mutex_lock(&ag_char_map_mutex); + if (ag_char_map_spanners[mask_ix] == NULL) +#endif + { + int ix = 1; + ag_char_map_mask_t mask = ag_char_map_masks[mask_ix]; + unsigned char * res = malloc(256 /* 1 << NBBY */); + if (res == NULL) { + fputs(_("no memory for char-mapper span map\n"), stderr); + exit(EXIT_FAILURE); + } + + memset(res, 0, 256); + for (; ix < 128; ix++) + if (ag_char_map_table[ix] & mask) + res[ix] = 1; + ag_char_map_spanners[mask_ix] = res; + } +#ifdef LOCK_SPANNER_TABLES + pthread_mutex_unlock(&ag_char_map_mutex); +#endif + return ag_char_map_spanners[mask_ix]; +} +#define ag_char_map_masks POISONED_ag_char_map_masks + +static inline int +is_ag_char_map_char(char ch, ag_char_map_mask_t mask) +{ + unsigned int ix = (unsigned char)ch; + return ((ix < 128) && ((ag_char_map_table[ix] & mask) != 0)); +} + +static inline char * +spn_ag_char_map_chars(char const * p, unsigned int mask_ix) +{ + unsigned char const * v = ag_char_map_spanners[mask_ix]; + if (v == NULL) + v = calc_ag_char_map_spanners(mask_ix); + while (v[(unsigned char)*p]) p++; + return (char *)(uintptr_t)p; +} + +static inline char * +brk_ag_char_map_chars(char const * p, unsigned int mask_ix) +{ + unsigned char const * v = ag_char_map_spanners[mask_ix]; + if (v == NULL) + v = calc_ag_char_map_spanners(mask_ix); + while ((*p != '\0') && (! v[(unsigned char)*p])) p++; + return (char *)(uintptr_t)p; +} + +static inline char * +spn_ag_char_map_back(char const * s, char const * e, unsigned int mask_ix) +{ + unsigned char const * v = ag_char_map_spanners[mask_ix]; + if (v == NULL) + v = calc_ag_char_map_spanners(mask_ix); + if (s >= e) e = s + strlen(s); + while ((e > s) && v[(unsigned char)e[-1]]) e--; + return (char *)(uintptr_t)e; +} + +static inline char * +brk_ag_char_map_back(char const * s, char const * e, unsigned int mask_ix) +{ + unsigned char const * v = ag_char_map_spanners[mask_ix]; + if (v == NULL) + v = calc_ag_char_map_spanners(mask_ix); + if (s == e) e += strlen(e); + while ((e > s) && (! v[(unsigned char)e[-1]])) e--; + return (char *)(uintptr_t)e; +} +#endif /* AG_CHAR_MAP_H_GUARD */ diff --git a/autoopts/alias.c b/autoopts/alias.c new file mode 100644 index 0000000..231f275 --- /dev/null +++ b/autoopts/alias.c @@ -0,0 +1,116 @@ + +/** + * \file alias.c + * + * Handle options that are aliases for another option. + * + * @addtogroup autoopts + * @{ + */ +/* + * This routine will forward an option alias to the correct option code. + * + * This file is part of AutoOpts, a companion to AutoGen. + * AutoOpts is free software. + * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoOpts is available under any one of two licenses. The license + * in use must be one of these two and the choice is under the control + * of the user of the license. + * + * The GNU Lesser General Public License, version 3 or later + * See the files "COPYING.lgplv3" and "COPYING.gplv3" + * + * The Modified Berkeley Software Distribution License + * See the file "COPYING.mbsd" + * + * These files have the following sha256 sums: + * + * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 + * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 + * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + */ + +static tSuccess +too_many_occurrences(tOptions * opts, tOptDesc * od) +{ + if ((opts->fOptSet & OPTPROC_ERRSTOP) != 0) { + char const * eqv = (od->optEquivIndex != NO_EQUIVALENT) ? zequiv : zNil; + + fprintf(stderr, ztoo_often_fmt, opts->pzProgName); + + if (od->optMaxCt > 1) + fprintf(stderr, zat_most, od->optMaxCt, od->pz_Name, eqv); + else + fprintf(stderr, zonly_one, od->pz_Name, eqv); + (*opts->pUsageProc)(opts, EXIT_FAILURE); + /* NOTREACHED */ + } + + return FAILURE; +} + +/*=export_func optionAlias + * private: + * + * what: relay an option to its alias + * arg: + tOptions * + opts + program options descriptor + + * arg: + tOptDesc * + old_od + the descriptor for this arg + + * arg: + unsigned int + alias + the aliased-to option index + + * ret-type: int + * + * doc: + * Handle one option as if it had been specified as another. Exactly. + * Returns "-1" if the aliased-to option has appeared too many times. +=*/ +int +optionAlias(tOptions * opts, tOptDesc * old_od, unsigned int alias) +{ + tOptDesc * new_od; + + if (opts <= OPTPROC_EMIT_LIMIT) + return 0; + + new_od = opts->pOptDesc + alias; + if ((unsigned)opts->optCt <= alias) { + fputs(zbad_alias_id, stderr); + option_exits(EXIT_FAILURE); + } + + /* + * Copy over the option instance flags + */ + new_od->fOptState &= OPTST_PERSISTENT_MASK; + new_od->fOptState |= (old_od->fOptState & ~OPTST_PERSISTENT_MASK); + new_od->optArg.argString = old_od->optArg.argString; + + /* + * Keep track of count only for DEFINED (command line) options. + * IF we have too many, build up an error message and bail. + */ + if ( (new_od->fOptState & OPTST_DEFINED) + && (++new_od->optOccCt > new_od->optMaxCt) ) + return too_many_occurrences(opts, new_od); + + /* + * Clear the state bits and counters + */ + old_od->fOptState &= OPTST_PERSISTENT_MASK; + old_od->optOccCt = 0; + + /* + * If there is a procedure to call, call it + */ + if (new_od->pOptProc != NULL) + (*new_od->pOptProc)(opts, new_od); + return 0; +} + +/** @} + * + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of autoopts/alias.c */ diff --git a/autoopts/ao-strs.c b/autoopts/ao-strs.c new file mode 100644 index 0000000..7f59372 --- /dev/null +++ b/autoopts/ao-strs.c @@ -0,0 +1,379 @@ +/* -*- buffer-read-only: t -*- vi: set ro: + * + * DO NOT EDIT THIS FILE (ao-strs.c) + * + * It has been AutoGen-ed + * From the definitions ao-strs.def + * and the template file strings + * + * Copyright (C) 2011-2018 Bruce Korb, all rights reserved. + * This is free software. It is licensed for use, modification and + * redistribution under the terms of the + * Modified (3 clause) Berkeley Software Distribution License + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name ``Bruce Korb'' nor the name of any other + * contributor may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * strings IS PROVIDED BY Bruce Korb ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL Bruce Korb OR ANY OTHER CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "ao-strs.h" + +char const ao_strs_strtable[6714] = +/* 0 */ "-_^\0" +/* 4 */ " %s%s\n\0" +/* 12 */ "\n\0" +/* 64 */ "\n" + "%s\n\n\0" +/* 70 */ "=file\0" +/* 76 */ "=Mbr\0" +/* 81 */ "=Cplx\0" +/* 87 */ "[=arg]\0" +/* 94 */ "--%2$s%1$s\0" +/* 105 */ "=Tim\0" +/* 110 */ "none\0" +/* 115 */ "# preset/initialization file\n" + "# %s#\n\0" +/* 153 */ " %3s %-14s %s\0" +/* 167 */ "%s\0" +/* 170 */ "T/F\0" +/* 174 */ "\n" + "%s\n\n" + "%s\0" +/* 182 */ "Fil\0" +/* 186 */ "KWd\0" +/* 190 */ "Mbr\0" +/* 194 */ "Cpx\0" +/* 198 */ "no \0" +/* 202 */ "Num\0" +/* 206 */ "opt\0" +/* 210 */ "YES\0" +/* 214 */ "Str\0" +/* 218 */ "Tim\0" +/* 222 */ "\t\t\t\t- \0" +/* 229 */ "\t\t\t\t \0" +/* 236 */ "\t\t\t\t-- and \0" +/* 248 */ "\t\t\t\t%s\n\0" +/* 256 */ " \0" +/* 263 */ " \0" +/* 269 */ " \0" +/* 273 */ " \0" +/* 276 */ "all\0" +/* 280 */ " \t\n" + ":=\0" +/* 286 */ "%s_%s_%d=\0" +/* 296 */ "''\0" +/* 299 */ " ;;\n\n\0" +/* 312 */ "'\n\n\0" +/* 316 */ "\n\0" +/* 323 */ " %s\n\0" +/* 329 */ "%%-%ds\0" +/* 336 */ "\n" + "export %s_%s_%d\n\0" +/* 354 */ "false\0" +/* 360 */ " -* )\n\0" +/* 370 */ "flag\0" +/* 375 */ "INVALID-%d\0" +/* 386 */ "*INVALID*\0" +/* 396 */ "\\n\\\n\0" +/* 401 */ " --* )\n\0" +/* 412 */ "--\0" +/* 415 */ "LONGUSAGE\0" +/* 425 */ " %s\n\0" +/* 441 */ "\\%03o\0" +/* 447 */ "more\0" +/* 452 */ "<%s type=nested>\n\0" +/* 470 */ "%s\n\0" +/* 474 */ "%s\n" + " \0" +/* 480 */ "OPT_ARG_NEEDED=NO\0" +/* 498 */ "<%s/>\n\0" +/* 505 */ "OPT_ARG_NEEDED=OK\0" +/* 523 */ "\t\0" +/* 525 */ "<%s>\0" +/* 530 */ "option\0" +/* 537 */ "\n" + "export %s_%s\n\0" +/* 552 */ "%s_%s=\0" +/* 559 */ " | \0" +/* 563 */ "PAGER\0" +/* 569 */ "%1$s %2$s ; rm -f %2$s\0" +/* 592 */ " + \0" +/* 596 */ " puts(_(%s));\n\0" +/* 612 */ "\\'\0" +/* 615 */ "'%s'\0" +/* 620 */ " -- %s\0" +/* 627 */ "%s_%s_TEXT='\0" +/* 640 */ "#! %s\n\0" +/* 647 */ "\n" + "env | grep '^%s_'\n\0" +/* 667 */ "=%1$lu # 0x%1$lX\n\0" +/* 685 */ "stdout\0" +/* 692 */ "%A %B %e, %Y at %r %Z\0" +/* 714 */ "TMPDIR\0" +/* 721 */ "%s/use-%u.XXXXXX\0" +/* 738 */ "true\0" +/* 743 */ "<%s type=%s>\0" +/* 756 */ "VERSION\0" +/* 764 */ "#x%02X;\0" +/* 772 */ "OPT_ARG_NEEDED=YES\0" +/* 791 */ "\n" + "# %s -- %s\n\0" +/* 804 */ "# DEFAULT: \0" +/* 816 */ "'\\''\0" +/* 821 */ " '%s'\0" +/* 827 */ "libopts misguessed length of string\n\0" +/* 864 */ "\n" + "OPTION_CT=0\n\0" +/* 878 */ "set --\0" +/* 885 */ "/tmp\0" +/* 890 */ " ;;\n\n\0" +/* 907 */ " '%c' )\n\0" +/* 923 */ " '%s' )\n\0" +/* 939 */ " '%s' | \\\n\0" +/* 957 */ "<%1$s type=boolean>%2$s\n\0" +/* 989 */ "# From the %s option definitions\n" + "#\n\0" +/* 1026 */ "echo 'Warning: Cannot load options files' >&2\0" +/* 1073 */ "echo 'Warning: Cannot save options files' >&2\0" +/* 1120 */ "echo 'Warning: Cannot suppress the loading of options files' >&2\0" +/* 1186 */ "<%1$s type=integer>0x%2$lX\n\0" +/* 1221 */ "%1$s_%2$s_TEXT='no %2$s text'\n\0" +/* 1252 */ "%1$s_%2$s_MODE='%3$s'\n" + "export %1$s_%2$s_MODE\n\0" +/* 1297 */ "%1$s_%2$s='%3$s'\n" + "export %1$s_%2$s\n\0" +/* 1332 */ "%1$s_%2$s_CT=%3$d\n" + "export %1$s_%2$s_CT\n\0" +/* 1371 */ "OPTION_CT=%d\n" + "export OPTION_CT\n\0" +/* 1402 */ "%1$s_%2$s=%3$s\n" + "export %1$s_%2$s\n\0" +/* 1435 */ "%1$s_%2$s=%3$d # 0x%3$X\n" + "export %1$s_%2$s\n\0" +/* 1477 */ " case \"${OPT_CODE}\" in\n\0" +/* 1508 */ " if [ $%1$s_%2$s_CT -gt %3$u ] ; then\n" + " echo 'Error: more than %3$d %2$s options'\n" + " echo \"$%1$s_USAGE_TEXT\"\n" + " exit 1\n" + " fi >&2\n\0" +/* 1699 */ "test ${%1$s_%2$s_CT-0} -ge %3$u || {\n" + " echo %1$s_%2$s has not been set\n" + " exit 1\n" + "} 1>&2\n\0" +/* 1791 */ "test -n \"$%1$s_%2$s\" || {\n" + " echo %1$s_%2$s has not been set\n" + " exit 1\n" + "} 1>&2\n\0" +/* 1872 */ " echo \"$%s_%s_TEXT\"\n" + " exit 0\n\0" +/* 1923 */ "\n" + "# # # # # # # # # #\n" + "#\n" + "# END OF AUTOMATED OPTION PROCESSING\n" + "#\n" + "# # # # # # # # # # -- do not modify this marker --\n\0" +/* 2039 */ " if [ -n \"${OPT_ARG_VAL}\" ]\n" + " then\n" + " eval %1$s_${OPT_NAME}${OPT_ELEMENT}=\"'${OPT_ARG_VAL}'\"\n" + " export %1$s_${OPT_NAME}${OPT_ELEMENT}\n" + " fi\n" + "done\n" + "OPTION_COUNT=`expr $ARG_COUNT - $#`\n" + "OPERAND_COUNT=$#\n" + "unset OPT_PROCESS || :\n" + "unset OPT_ELEMENT || :\n" + "unset OPT_ARG || :\n" + "unset OPT_ARG_NEEDED || :\n" + "unset OPT_NAME || :\n" + "unset OPT_CODE || :\n" + "unset OPT_ARG_VAL || :\n\0" +/* 2418 */ " OPT_CODE=`echo \"X${OPT_ARG}\"|sed 's/^X-*//'`\n" + " shift\n" + " OPT_ARG=$1\n" + " case \"${OPT_CODE}\" in *=* )\n" + " OPT_ARG_VAL=`echo \"${OPT_CODE}\"|sed 's/^[^=]*=//'`\n" + " OPT_CODE=`echo \"${OPT_CODE}\"|sed 's/=.*$//'` ;; esac\n\0" +/* 2669 */ " OPT_CODE=`echo \"X${OPT_ARG}\" | sed 's/X-\\(.\\).*/\\1/'`\n" + " OPT_ARG=` echo \"X${OPT_ARG}\" | sed 's/X-.//'`\n\0" +/* 2786 */ "\n" + "ARG_COUNT=$#\n" + "OPT_PROCESS=true\n" + "OPT_ARG=$1\n" + "while ${OPT_PROCESS} && [ $# -gt 0 ]\n" + "do\n" + " OPT_ELEMENT=''\n" + " OPT_ARG_VAL=''\n\n" + " case \"${OPT_ARG}\" in\n" + " -- )\n" + " OPT_PROCESS=false\n" + " shift\n" + " ;;\n\0" +/* 2993 */ " case \"${OPT_ARG_NEEDED}\" in\n" + " NO )\n" + " OPT_ARG_VAL=''\n" + " ;;\n" + " YES )\n" + " if [ -z \"${OPT_ARG_VAL}\" ]\n" + " then\n" + " if [ $# -eq 0 ]\n" + " then\n" + " echo No argument provided for ${OPT_NAME} option\n" + " echo \"$%s_USAGE_TEXT\"\n" + " exit 1\n" + " fi >&2\n" + " OPT_ARG_VAL=${OPT_ARG}\n" + " shift\n" + " OPT_ARG=$1\n" + " fi\n" + " ;;\n" + " OK )\n" + " if [ -z \"${OPT_ARG_VAL}\" ] && [ $# -gt 0 ]\n" + " then\n" + " case \"${OPT_ARG}\" in -* ) ;; * )\n" + " OPT_ARG_VAL=${OPT_ARG}\n" + " shift\n" + " OPT_ARG=$1 ;; esac\n" + " fi\n" + " ;;\n" + " esac\n\0" +/* 3772 */ " %1$s_%2$s_CT=`expr ${%1$s_%2$s_CT} + 1`\n" + " OPT_ELEMENT=\"_${%1$s_%2$s_CT}\"\n" + " OPT_NAME='%2$s'\n\0" +/* 3896 */ "\n" + "if test -z \"${%1$s_%2$s}\"\n" + "then\n" + " %1$s_%2$s_CT=0\n" + " export %1$s_%2$s_CT\n" + "else\n" + " %1$s_%2$s_CT=1\n" + " %1$s_%2$s_1=${%1$s_%2$s}\n" + " export %1$s_%2$s_CT %1$s_%2$s_1\n" + "fi\n\0" +/* 4054 */ " * )\n" + " OPT_PROCESS=false\n" + " ;;\n" + " esac\n\0" +/* 4111 */ " %1$s_%2$s_CT=0\n" + " OPT_ELEMENT=''\n" + " %1$s_%2$s='%3$s'\n" + " export %1$s_%2$s\n" + " OPT_NAME='%2$s'\n\0" +/* 4252 */ " if [ -n \"${%1$s_%2$s}\" ] && ${%1$s_%2$s_set} ; then\n" + " echo 'Error: duplicate %2$s option'\n" + " echo \"$%1$s_USAGE_TEXT\"\n" + " exit 1\n" + " fi >&2\n" + " %1$s_%2$s_set=true\n" + " %1$s_%2$s='%3$s'\n" + " export %1$s_%2$s\n" + " OPT_NAME='%2$s'\n\0" +/* 4569 */ "\n" + "ARG_COUNT=$#\n" + "OPT_ARG=$1\n" + "while [ $# -gt 0 ]\n" + "do\n" + " OPT_ELEMENT=''\n" + " OPT_ARG_VAL=''\n" + " OPT_ARG=${1}\n\0" +/* 4672 */ " case \"${OPT_ARG_NEEDED}\" in\n" + " NO )\n" + " if [ -n \"${OPT_ARG}\" ]\n" + " then\n" + " OPT_ARG=-${OPT_ARG}\n" + " else\n" + " shift\n" + " OPT_ARG=$1\n" + " fi\n" + " ;;\n" + " YES )\n" + " if [ -n \"${OPT_ARG}\" ]\n" + " then\n" + " OPT_ARG_VAL=${OPT_ARG}\n" + " else\n" + " if [ $# -eq 0 ]\n" + " then\n" + " echo No argument provided for ${OPT_NAME} option\n" + " echo \"$%s_USAGE_TEXT\"\n" + " exit 1\n" + " fi >&2\n" + " shift\n" + " OPT_ARG_VAL=$1\n" + " fi\n" + " shift\n" + " OPT_ARG=$1\n" + " ;;\n" + " OK )\n" + " if [ -n \"${OPT_ARG}\" ]\n" + " then\n" + " OPT_ARG_VAL=${OPT_ARG}\n" + " shift\n" + " OPT_ARG=$1\n" + " else\n" + " shift\n" + " if [ $# -gt 0 ]\n" + " then\n" + " case \"$1\" in -* ) ;; * )\n" + " OPT_ARG_VAL=$1\n" + " shift ;; esac\n" + " OPT_ARG=$1\n" + " fi\n" + " fi\n" + " ;;\n" + " esac\n\0" +/* 5826 */ " echo \"$%s_LONGUSAGE_TEXT\" | ${PAGER-more}\n" + " exit 0\n\0" +/* 5900 */ "%s OF %s\n" + "#\n" + "# From here to the next `-- do not modify this marker --',\n" + "# the text has been generated %s\n\0" +/* 6006 */ " eval %1$s_%2$s${OPT_ELEMENT}=true\n" + " export %1$s_%2$s${OPT_ELEMENT}\n\0" +/* 6096 */ " if [ -n \"${%1$s_%2$s}\" ] && ${%1$s_%2$s_set} ; then\n" + " echo 'Error: duplicate %2$s option'\n" + " echo \"$%1$s_USAGE_TEXT\"\n" + " exit 1\n" + " fi >&2\n" + " %1$s_%2$s_set=true\n" + " OPT_NAME='%2$s'\n\0" +/* 6355 */ "\n" + "%1$s_%2$s=${%1$s_%2$s-'%3$s'}\n" + "%1$s_%2$s_set=false\n" + "export %1$s_%2$s\n\0" +/* 6424 */ "\n" + "%1$s_%2$s=${%1$s_%2$s}\n" + "%1$s_%2$s_set=false\n" + "export %1$s_%2$s\n\0" +/* 6486 */ "# # # # # # # # # # -- do not modify this marker --\n" + "#\n" + "# DO NOT EDIT THIS SECTION\n\0" +/* 6569 */ " * )\n" + " echo Unknown %s: \"${OPT_CODE}\" >&2\n" + " echo \"$%s_USAGE_TEXT\" >&2\n" + " exit 1\n" + " ;;\n" + " esac\n"; + +/* end of ao-strs.c */ diff --git a/autoopts/ao-strs.def b/autoopts/ao-strs.def new file mode 100644 index 0000000..3271af1 --- /dev/null +++ b/autoopts/ao-strs.def @@ -0,0 +1,545 @@ +AutoGen Definitions strings; + +/** + * \file ao-strs.def + * + * This file is part of AutoOpts, a companion to AutoGen. + * It contains static immutable strings that are used throughout + * the libopts library code. The strings are split into two groups: + * strings for generating a shell script to parse arguments, and + * everything else. + * + * AutoOpts is free software. + * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoOpts is available under any one of two licenses. The license + * in use must be one of these two and the choice is under the control + * of the user of the license. + * + * The GNU Lesser General Public License, version 3 or later + * See the files "COPYING.lgplv3" and "COPYING.gplv3" + * + * The Modified Berkeley Software Distribution License + * See the file "COPYING.mbsd" + * + * These files have the following sha256 sums: + * + * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 + * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 + * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + */ + +#if 0 +string = { nm = ; + str = << _EOStr_ + +_EOStr_; +}; +#endif + +string = { nm = zSepChars; str = "-_^"; }; +string = { nm = zambig_file; str = " %s%s\n"; }; +string = { nm = zCfgAO_Flags; str = "\n"; }; +string = { nm = zGnuBreak; str = "\n%s\n\n"; }; +string = { nm = zGnuFileArg; str = "=file"; }; +string = { nm = zGnuKeyLArg; str = "=Mbr"; }; +string = { nm = zGnuNestArg; str = "=Cplx"; }; +string = { nm = zGnuOptArg; str = "[=arg]"; }; +string = { nm = zGnuOptFmt; str = "--%2$s%1$s"; }; +string = { nm = zGnuTimeArg; str = "=Tim"; }; +string = { nm = zNone; str = "none"; }; +string = { nm = zPresetFile; str = "# preset/initialization file\n# %s#\n";}; +string = { nm = zReqOptFmt; str = " %3s %-14s %s"; }; +string = { nm = zShrtGnuOptFmt; str = "%s"; }; +string = { nm = zStdBoolArg; str = "T/F"; }; +string = { nm = zStdBreak; str = "\n%s\n\n%s"; }; +string = { nm = zStdFileArg; str = "Fil"; }; +string = { nm = zStdKeyArg; str = "KWd"; }; +string = { nm = zStdKeyLArg; str = "Mbr"; }; +string = { nm = zStdNestArg; str = "Cpx"; }; +string = { nm = zStdNoArg; str = "no "; }; +string = { nm = zStdNumArg; str = "Num"; }; +string = { nm = zStdOptArg; str = "opt"; }; +string = { nm = zStdReqArg; str = "YES"; }; +string = { nm = zStdStrArg; str = "Str"; }; +string = { nm = zStdTimeArg; str = "Tim"; }; +string = { nm = zTabHyp; str = "\t\t\t\t- "; }; +string = { nm = zTabSpace; str = "\t\t\t\t "; }; +string = { nm = zTabHypAnd; str = "\t\t\t\t-- and "; }; +string = { nm = zTabout; str = "\t\t\t\t%s\n"; }; +string = { nm = zSixSpaces; str = " "; }; +string = { nm = zFiveSpaces; str = " "; }; +string = { nm = zThreeSpaces; str = " "; }; +string = { nm = zTwoSpaces; str = " "; }; +string = { nm = zAll; str = "all"; }; + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * STRINGS USED IN CREATING OPTION PARSING SHELL CODE + */ +string = { nm = ARG_BREAK_STR; str = " \t\n:="; }; +string = { nm = ARG_BY_NUM_FMT; str = "%s_%s_%d="; }; +string = { nm = EMPTY_ARG; str = "''"; }; +string = { nm = END_OPT_SEL_STR; str = " ;;\n\n"; }; +string = { nm = END_SET_TEXT; str = "'\n\n"; }; +string = { nm = END_XML_FMT; str = "\n"; }; +string = { nm = ENUM_ERR_LINE; str = " %s\n"; }; +string = { nm = ENUM_ERR_WIDTH; str = "%%-%ds"; }; +string = { nm = EXPORT_ARG_FMT; str = "\nexport %s_%s_%d\n"; }; +string = { nm = FALSE_STR; str = "false"; }; +string = { nm = FLAG_OPT_MARK; str = " -* )\n"; }; +string = { nm = FLAG_STR; str = "flag"; }; +string = { nm = INVALID_FMT; str = "INVALID-%d"; }; +string = { nm = INVALID_STR; str = "*INVALID*"; }; +string = { nm = LINE_SPLICE; str = "\\n\\\n"; }; +string = { nm = LONG_OPT_MARK; str = " --* )\n"; }; +string = { nm = LONG_OPT_MARKER; str = "--"; }; +string = { nm = LONG_USE_STR; str = "LONGUSAGE"; }; +string = { nm = LVL3_CMD; str = " %s\n"; }; +string = { nm = MK_STR_OCT_FMT; str = "\\%03o"; }; +string = { nm = MORE_STR; str = "more"; }; +string = { nm = NESTED_OPT_FMT; str = "<%s type=nested>\n"; }; +string = { nm = NLSTR_FMT; str = "%s\n"; }; +string = { nm = NLSTR_SPACE_FMT; str = "%s\n "; }; +string = { nm = NONE_STR; str = "none"; }; +string = { nm = NO_ARG_NEEDED; str = "OPT_ARG_NEEDED=NO"; }; +string = { nm = NULL_ATR_FMT; str = "<%s/>\n"; }; +string = { nm = OK_NEED_OPT_ARG; str = "OPT_ARG_NEEDED=OK"; }; +string = { nm = ONE_TAB_STR; str = "\t"; }; +string = { nm = OPEN_CLOSE_FMT; str = "<%s/>\n"; }; +string = { nm = OPEN_XML_FMT; str = "<%s>"; }; +string = { nm = OPTION_STR; str = "option"; }; +string = { nm = OPT_END_FMT; str = "\nexport %s_%s\n"; }; +string = { nm = OPT_VAL_FMT; str = "%s_%s="; }; +string = { nm = OR_STR; str = " | "; }; +string = { nm = PAGER_NAME; str = "PAGER"; }; +string = { nm = PAGE_USAGE_FMT; str = "%1$s %2$s ; rm -f %2$s"; }; +string = { nm = PLUS_STR; str = " + "; }; +string = { nm = PUTS_FMT; str = " puts(_(%s));\n"; }; +string = { nm = QUOT_APOS; str = "\\'"; }; +string = { nm = QUOT_ARG_FMT; str = "'%s'"; }; +string = { nm = SET_OFF_FMT; str = " -- %s"; }; +string = { nm = SET_TEXT_FMT; str = "%s_%s_TEXT='"; }; +string = { nm = SHELL_MAGIC; str = "#! %s\n"; }; +string = { nm = SHOW_PROG_ENV; str = "\nenv | grep '^%s_'\n"; }; +string = { nm = SHOW_VAL_FMT; str = "=%1$lu # 0x%1$lX\n"; }; +string = { nm = STDOUT; str = "stdout"; }; +string = { nm = TIME_FMT; str = "%A %B %e, %Y at %r %Z"; }; +string = { nm = TMPDIR; str = "TMPDIR"; }; +string = { nm = TMP_FILE_FMT; str = "%s/use-%u.XXXXXX"; }; +string = { nm = TMP_USAGE_FMT; str = "%s/use-%u.XXXXXX"; }; +string = { nm = TRUE_STR; str = "true"; }; +string = { nm = TWO_SPACES_STR; str = " "; }; +string = { nm = TYPE_ATR_FMT; str = "<%s type=%s>"; }; +string = { nm = VER_STR; str = "VERSION"; }; +string = { nm = XML_HEX_BYTE_FMT; str = "#x%02X;"; }; +string = { nm = YES_NEED_OPT_ARG; str = "OPT_ARG_NEEDED=YES"; }; +string = { nm = ao_name_use_fmt; str = "\n# %s -- %s\n"; }; +string = { nm = ao_default_use; str = "# DEFAULT: "; }; +string = { nm = apostrophe; str = "'\\''"; }; +string = { nm = arg_fmt; str = " '%s'"; }; +string = { nm = misguess_len; str = "libopts misguessed length of string\n"; }; +string = { nm = init_optct; str = "\nOPTION_CT=0\n"; }; +string = { nm = set_dash; str = "set --"; }; +string = { nm = tmp_dir; str = "/tmp"; }; +string = { nm = zOptionEndSelect; str = " ;;\n\n"; }; +string = { nm = zOptionFlag; str = " '%c' )\n"; }; +string = { nm = zOptionFullName; str = " '%s' )\n"; }; +string = { nm = zOptionPartName; str = " '%s' | \\\n"; }; + +string = { nm = BOOL_ATR_FMT; + str = "<%1$s type=boolean>%2$s\n"; }; + +string = { nm = END_PRE_FMT; + str = "# From the %s option definitions\n#\n"; }; + +string = { nm = NO_LOAD_WARN; + str = "echo 'Warning: Cannot load options files' >&2"; }; + +string = { nm = NO_SAVE_OPTS; + str = "echo 'Warning: Cannot save options files' >&2"; }; + +string = { nm = NO_SUPPRESS_LOAD; + str = "echo 'Warning: Cannot suppress the loading of options files' >&2"; }; + +string = { nm = NUMB_ATR_FMT; + str = "<%1$s type=integer>0x%2$lX\n"; }; + +string = { nm = SET_NO_TEXT_FMT; + str = "%1$s_%2$s_TEXT='no %2$s text'\n"; }; + +string = { nm = zEquivMode; + str = "%1$s_%2$s_MODE='%3$s'\nexport %1$s_%2$s_MODE\n"; }; + +string = { nm = zFullOptFmt; + str = "%1$s_%2$s='%3$s'\nexport %1$s_%2$s\n"; }; + +string = { nm = zOptCookieCt; + str = "%1$s_%2$s_CT=%3$d\nexport %1$s_%2$s_CT\n"; }; + +string = { nm = zOptCtFmt; + str = "OPTION_CT=%d\nexport OPTION_CT\n"; }; + +string = { nm = zOptDisabl; + str = "%1$s_%2$s=%3$s\nexport %1$s_%2$s\n"; }; + +string = { nm = zOptNumFmt; + str = "%1$s_%2$s=%3$d # 0x%3$X\nexport %1$s_%2$s\n"; }; + +string = { nm = zOptionCase; + str = " case \"${OPT_CODE}\" in\n"; }; + +string = { nm = CHK_MAX_COUNT; + str = << _EOStr_ + if [ $%1$s_%2$s_CT -gt %3$u ] ; then + echo 'Error: more than %3$d %2$s options' + echo "$%1$s_USAGE_TEXT" + exit 1 + fi >&2 + +_EOStr_; +}; + +string = { nm = CHK_MIN_COUNT; + str = <<- _EOStr_ + test ${%1$s_%2$s_CT-0} -ge %3$u || { + echo %1$s_%2$s has not been set + exit 1 + } 1>&2 + + _EOStr_; +}; + +string = { nm = CHK_ONE_REQUIRED; + str = <<- _EOStr_ + test -n "$%1$s_%2$s" || { + echo %1$s_%2$s has not been set + exit 1 + } 1>&2 + + _EOStr_; +}; + +string = { nm = ECHO_N_EXIT; + str = << _EOStr_ + echo "$%s_%s_TEXT" + exit 0 + +_EOStr_; +}; + +string = { nm = END_MARK; + str = <<- _EOStr_ + + # # # # # # # # # # + # + # END OF AUTOMATED OPTION PROCESSING + # + # # # # # # # # # # -- do not modify this marker -- + + _EOStr_; +}; + +string = { nm = FINISH_LOOP; + str = <<- _EOStr_ + if [ -n "${OPT_ARG_VAL}" ] + then + eval %1$s_${OPT_NAME}${OPT_ELEMENT}="'${OPT_ARG_VAL}'" + export %1$s_${OPT_NAME}${OPT_ELEMENT} + fi + done + OPTION_COUNT=`expr $ARG_COUNT - $#` + OPERAND_COUNT=$# + unset OPT_PROCESS || : + unset OPT_ELEMENT || : + unset OPT_ARG || : + unset OPT_ARG_NEEDED || : + unset OPT_NAME || : + unset OPT_CODE || : + unset OPT_ARG_VAL || : + + _EOStr_; +}; + +string = { nm = INIT_LOPT_STR; + str = << _EOStr_ + OPT_CODE=`echo "X${OPT_ARG}"|sed 's/^X-*//'` + shift + OPT_ARG=$1 + case "${OPT_CODE}" in *=* ) + OPT_ARG_VAL=`echo "${OPT_CODE}"|sed 's/^[^=]*=//'` + OPT_CODE=`echo "${OPT_CODE}"|sed 's/=.*$//'` ;; esac + +_EOStr_; +}; + +string = { nm = INIT_OPT_STR; + str = << _EOStr_ + OPT_CODE=`echo "X${OPT_ARG}" | sed 's/X-\(.\).*/\1/'` + OPT_ARG=` echo "X${OPT_ARG}" | sed 's/X-.//'` + +_EOStr_; +}; + +string = { nm = LOOP_STR; + str = <<- _EOStr_ + + ARG_COUNT=$# + OPT_PROCESS=true + OPT_ARG=$1 + while ${OPT_PROCESS} && [ $# -gt 0 ] + do + OPT_ELEMENT='' + OPT_ARG_VAL='' + + case "${OPT_ARG}" in + -- ) + OPT_PROCESS=false + shift + ;; + + _EOStr_; +}; + +string = { nm = LOPT_ARG_FMT; + str = << _EOStr_ + case "${OPT_ARG_NEEDED}" in + NO ) + OPT_ARG_VAL='' + ;; + YES ) + if [ -z "${OPT_ARG_VAL}" ] + then + if [ $# -eq 0 ] + then + echo No argument provided for ${OPT_NAME} option + echo "$%s_USAGE_TEXT" + exit 1 + fi >&2 + OPT_ARG_VAL=${OPT_ARG} + shift + OPT_ARG=$1 + fi + ;; + OK ) + if [ -z "${OPT_ARG_VAL}" ] && [ $# -gt 0 ] + then + case "${OPT_ARG}" in -* ) ;; * ) + OPT_ARG_VAL=${OPT_ARG} + shift + OPT_ARG=$1 ;; esac + fi + ;; + esac + +_EOStr_; +}; + +string = { nm = MULTI_ARG_FMT; + str = << _EOStr_ + %1$s_%2$s_CT=`expr ${%1$s_%2$s_CT} + 1` + OPT_ELEMENT="_${%1$s_%2$s_CT}" + OPT_NAME='%2$s' + +_EOStr_; +}; + +string = { nm = MULTI_DEF_FMT; + str = <<- _EOStr_ + + if test -z "${%1$s_%2$s}" + then + %1$s_%2$s_CT=0 + export %1$s_%2$s_CT + else + %1$s_%2$s_CT=1 + %1$s_%2$s_1=${%1$s_%2$s} + export %1$s_%2$s_CT %1$s_%2$s_1 + fi + + _EOStr_; +}; + +string = { nm = NOT_FOUND_STR; + str = <<- _EOStr_ + * ) + OPT_PROCESS=false + ;; + esac + + _EOStr_; +}; + +string = { nm = NO_MULTI_ARG_FMT; + str = << _EOStr_ + %1$s_%2$s_CT=0 + OPT_ELEMENT='' + %1$s_%2$s='%3$s' + export %1$s_%2$s + OPT_NAME='%2$s' + +_EOStr_; +}; + +string = { nm = NO_SGL_ARG_FMT; + str = << _EOStr_ + if [ -n "${%1$s_%2$s}" ] && ${%1$s_%2$s_set} ; then + echo 'Error: duplicate %2$s option' + echo "$%1$s_USAGE_TEXT" + exit 1 + fi >&2 + %1$s_%2$s_set=true + %1$s_%2$s='%3$s' + export %1$s_%2$s + OPT_NAME='%2$s' + +_EOStr_; +}; + +string = { nm = ONLY_OPTS_LOOP; + str = <<- _EOStr_ + + ARG_COUNT=$# + OPT_ARG=$1 + while [ $# -gt 0 ] + do + OPT_ELEMENT='' + OPT_ARG_VAL='' + OPT_ARG=${1} + + _EOStr_; +}; + +string = { nm = OPT_ARG_FMT; + str = <<- _EOStr_ + case "${OPT_ARG_NEEDED}" in + NO ) + if [ -n "${OPT_ARG}" ] + then + OPT_ARG=-${OPT_ARG} + else + shift + OPT_ARG=$1 + fi + ;; + YES ) + if [ -n "${OPT_ARG}" ] + then + OPT_ARG_VAL=${OPT_ARG} + else + if [ $# -eq 0 ] + then + echo No argument provided for ${OPT_NAME} option + echo "$%s_USAGE_TEXT" + exit 1 + fi >&2 + shift + OPT_ARG_VAL=$1 + fi + shift + OPT_ARG=$1 + ;; + OK ) + if [ -n "${OPT_ARG}" ] + then + OPT_ARG_VAL=${OPT_ARG} + shift + OPT_ARG=$1 + else + shift + if [ $# -gt 0 ] + then + case "$1" in -* ) ;; * ) + OPT_ARG_VAL=$1 + shift ;; esac + OPT_ARG=$1 + fi + fi + ;; + esac + + _EOStr_; +}; + +string = { nm = PAGE_USAGE_TEXT; + str = << _EOStr_ + echo "$%s_LONGUSAGE_TEXT" | ${PAGER-more} + exit 0 + +_EOStr_; +}; + +string = { nm = PREAMBLE_FMT; + str = <<- _EOStr_ + %s OF %s + # + # From here to the next `-- do not modify this marker --', + # the text has been generated %s + + _EOStr_; +}; + +string = { nm = SET_MULTI_ARG; + str = << _EOStr_ + eval %1$s_%2$s${OPT_ELEMENT}=true + export %1$s_%2$s${OPT_ELEMENT} + +_EOStr_; +}; + +string = { nm = SGL_ARG_FMT; + str = << _EOStr_ + if [ -n "${%1$s_%2$s}" ] && ${%1$s_%2$s_set} ; then + echo 'Error: duplicate %2$s option' + echo "$%1$s_USAGE_TEXT" + exit 1 + fi >&2 + %1$s_%2$s_set=true + OPT_NAME='%2$s' + +_EOStr_; +}; + +string = { nm = SGL_DEF_FMT; + str = <<- _EOStr_ + + %1$s_%2$s=${%1$s_%2$s-'%3$s'} + %1$s_%2$s_set=false + export %1$s_%2$s + + _EOStr_; +}; + +string = { nm = SGL_NO_DEF_FMT; + str = <<- _EOStr_ + + %1$s_%2$s=${%1$s_%2$s} + %1$s_%2$s_set=false + export %1$s_%2$s + + _EOStr_; +}; + +string = { nm = START_MARK; + str = <<- _EOStr_ + # # # # # # # # # # -- do not modify this marker -- + # + # DO NOT EDIT THIS SECTION + + _EOStr_; +}; + +string = { nm = UNK_OPT_FMT; + str = <<- _EOStr_ + * ) + echo Unknown %s: "${OPT_CODE}" >&2 + echo "$%s_USAGE_TEXT" >&2 + exit 1 + ;; + esac + + _EOStr_; +}; diff --git a/autoopts/ao-strs.h b/autoopts/ao-strs.h new file mode 100644 index 0000000..95036ef --- /dev/null +++ b/autoopts/ao-strs.h @@ -0,0 +1,338 @@ +/* -*- buffer-read-only: t -*- vi: set ro: + * + * DO NOT EDIT THIS FILE (ao-strs.h) + * + * It has been AutoGen-ed + * From the definitions ao-strs.def + * and the template file strings + * + * Copyright (C) 2011-2018 Bruce Korb, all rights reserved. + * This is free software. It is licensed for use, modification and + * redistribution under the terms of the + * Modified (3 clause) Berkeley Software Distribution License + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name ``Bruce Korb'' nor the name of any other + * contributor may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * strings IS PROVIDED BY Bruce Korb ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL Bruce Korb OR ANY OTHER CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef STRINGS_AO_STRS_H_GUARD +#define STRINGS_AO_STRS_H_GUARD 1 +/* + * 146 strings in ao_strs_strtable string table + */ +#define ARG_BREAK_STR (ao_strs_strtable+280) +#define ARG_BREAK_STR_LEN 5 +#define ARG_BY_NUM_FMT (ao_strs_strtable+286) +#define ARG_BY_NUM_FMT_LEN 9 +#define BOOL_ATR_FMT (ao_strs_strtable+957) +#define BOOL_ATR_FMT_LEN 31 +#define CHK_MAX_COUNT (ao_strs_strtable+1508) +#define CHK_MAX_COUNT_LEN 190 +#define CHK_MIN_COUNT (ao_strs_strtable+1699) +#define CHK_MIN_COUNT_LEN 91 +#define CHK_ONE_REQUIRED (ao_strs_strtable+1791) +#define CHK_ONE_REQUIRED_LEN 80 +#define ECHO_N_EXIT (ao_strs_strtable+1872) +#define ECHO_N_EXIT_LEN 50 +#define EMPTY_ARG (ao_strs_strtable+296) +#define EMPTY_ARG_LEN 2 +#define END_MARK (ao_strs_strtable+1923) +#define END_MARK_LEN 115 +#define END_OPT_SEL_STR (ao_strs_strtable+299) +#define END_OPT_SEL_STR_LEN 12 +#define END_PRE_FMT (ao_strs_strtable+989) +#define END_PRE_FMT_LEN 36 +#define END_SET_TEXT (ao_strs_strtable+312) +#define END_SET_TEXT_LEN 3 +#define END_XML_FMT (ao_strs_strtable+316) +#define END_XML_FMT_LEN 6 +#define ENUM_ERR_LINE (ao_strs_strtable+323) +#define ENUM_ERR_LINE_LEN 5 +#define ENUM_ERR_WIDTH (ao_strs_strtable+329) +#define ENUM_ERR_WIDTH_LEN 6 +#define EXPORT_ARG_FMT (ao_strs_strtable+336) +#define EXPORT_ARG_FMT_LEN 17 +#define FALSE_STR (ao_strs_strtable+354) +#define FALSE_STR_LEN 5 +#define FINISH_LOOP (ao_strs_strtable+2039) +#define FINISH_LOOP_LEN 378 +#define FLAG_OPT_MARK (ao_strs_strtable+360) +#define FLAG_OPT_MARK_LEN 9 +#define FLAG_STR (ao_strs_strtable+370) +#define FLAG_STR_LEN 4 +#define INIT_LOPT_STR (ao_strs_strtable+2418) +#define INIT_LOPT_STR_LEN 250 +#define INIT_OPT_STR (ao_strs_strtable+2669) +#define INIT_OPT_STR_LEN 116 +#define INVALID_FMT (ao_strs_strtable+375) +#define INVALID_FMT_LEN 10 +#define INVALID_STR (ao_strs_strtable+386) +#define INVALID_STR_LEN 9 +#define LINE_SPLICE (ao_strs_strtable+396) +#define LINE_SPLICE_LEN 4 +#define LONG_OPT_MARK (ao_strs_strtable+401) +#define LONG_OPT_MARKER (ao_strs_strtable+412) +#define LONG_OPT_MARKER_LEN 2 +#define LONG_OPT_MARK_LEN 10 +#define LONG_USE_STR (ao_strs_strtable+415) +#define LONG_USE_STR_LEN 9 +#define LOOP_STR (ao_strs_strtable+2786) +#define LOOP_STR_LEN 206 +#define LOPT_ARG_FMT (ao_strs_strtable+2993) +#define LOPT_ARG_FMT_LEN 778 +#define LVL3_CMD (ao_strs_strtable+425) +#define LVL3_CMD_LEN 15 +#define MK_STR_OCT_FMT (ao_strs_strtable+441) +#define MK_STR_OCT_FMT_LEN 5 +#define MORE_STR (ao_strs_strtable+447) +#define MORE_STR_LEN 4 +#define MULTI_ARG_FMT (ao_strs_strtable+3772) +#define MULTI_ARG_FMT_LEN 123 +#define MULTI_DEF_FMT (ao_strs_strtable+3896) +#define MULTI_DEF_FMT_LEN 157 +#define NESTED_OPT_FMT (ao_strs_strtable+452) +#define NESTED_OPT_FMT_LEN 17 +#define NLSTR_FMT (ao_strs_strtable+470) +#define NLSTR_FMT_LEN 3 +#define NLSTR_SPACE_FMT (ao_strs_strtable+474) +#define NLSTR_SPACE_FMT_LEN 5 +#define NONE_STR (ao_strs_strtable+110) +#define NONE_STR_LEN 4 +#define NOT_FOUND_STR (ao_strs_strtable+4054) +#define NOT_FOUND_STR_LEN 56 +#define NO_ARG_NEEDED (ao_strs_strtable+480) +#define NO_ARG_NEEDED_LEN 17 +#define NO_LOAD_WARN (ao_strs_strtable+1026) +#define NO_LOAD_WARN_LEN 46 +#define NO_MULTI_ARG_FMT (ao_strs_strtable+4111) +#define NO_MULTI_ARG_FMT_LEN 140 +#define NO_SAVE_OPTS (ao_strs_strtable+1073) +#define NO_SAVE_OPTS_LEN 46 +#define NO_SGL_ARG_FMT (ao_strs_strtable+4252) +#define NO_SGL_ARG_FMT_LEN 316 +#define NO_SUPPRESS_LOAD (ao_strs_strtable+1120) +#define NO_SUPPRESS_LOAD_LEN 65 +#define NULL_ATR_FMT (ao_strs_strtable+498) +#define NULL_ATR_FMT_LEN 6 +#define NUMB_ATR_FMT (ao_strs_strtable+1186) +#define NUMB_ATR_FMT_LEN 34 +#define OK_NEED_OPT_ARG (ao_strs_strtable+505) +#define OK_NEED_OPT_ARG_LEN 17 +#define ONE_TAB_STR (ao_strs_strtable+523) +#define ONE_TAB_STR_LEN 1 +#define ONLY_OPTS_LOOP (ao_strs_strtable+4569) +#define ONLY_OPTS_LOOP_LEN 102 +#define OPEN_CLOSE_FMT (ao_strs_strtable+498) +#define OPEN_CLOSE_FMT_LEN 6 +#define OPEN_XML_FMT (ao_strs_strtable+525) +#define OPEN_XML_FMT_LEN 4 +#define OPTION_STR (ao_strs_strtable+530) +#define OPTION_STR_LEN 6 +#define OPT_ARG_FMT (ao_strs_strtable+4672) +#define OPT_ARG_FMT_LEN 1153 +#define OPT_END_FMT (ao_strs_strtable+537) +#define OPT_END_FMT_LEN 14 +#define OPT_VAL_FMT (ao_strs_strtable+552) +#define OPT_VAL_FMT_LEN 6 +#define OR_STR (ao_strs_strtable+559) +#define OR_STR_LEN 3 +#define PAGER_NAME (ao_strs_strtable+563) +#define PAGER_NAME_LEN 5 +#define PAGE_USAGE_FMT (ao_strs_strtable+569) +#define PAGE_USAGE_FMT_LEN 22 +#define PAGE_USAGE_TEXT (ao_strs_strtable+5826) +#define PAGE_USAGE_TEXT_LEN 73 +#define PLUS_STR (ao_strs_strtable+592) +#define PLUS_STR_LEN 3 +#define PREAMBLE_FMT (ao_strs_strtable+5900) +#define PREAMBLE_FMT_LEN 105 +#define PUTS_FMT (ao_strs_strtable+596) +#define PUTS_FMT_LEN 15 +#define QUOT_APOS (ao_strs_strtable+612) +#define QUOT_APOS_LEN 2 +#define QUOT_ARG_FMT (ao_strs_strtable+615) +#define QUOT_ARG_FMT_LEN 4 +#define SET_MULTI_ARG (ao_strs_strtable+6006) +#define SET_MULTI_ARG_LEN 89 +#define SET_NO_TEXT_FMT (ao_strs_strtable+1221) +#define SET_NO_TEXT_FMT_LEN 30 +#define SET_OFF_FMT (ao_strs_strtable+620) +#define SET_OFF_FMT_LEN 6 +#define SET_TEXT_FMT (ao_strs_strtable+627) +#define SET_TEXT_FMT_LEN 12 +#define SGL_ARG_FMT (ao_strs_strtable+6096) +#define SGL_ARG_FMT_LEN 258 +#define SGL_DEF_FMT (ao_strs_strtable+6355) +#define SGL_DEF_FMT_LEN 68 +#define SGL_NO_DEF_FMT (ao_strs_strtable+6424) +#define SGL_NO_DEF_FMT_LEN 61 +#define SHELL_MAGIC (ao_strs_strtable+640) +#define SHELL_MAGIC_LEN 6 +#define SHOW_PROG_ENV (ao_strs_strtable+647) +#define SHOW_PROG_ENV_LEN 19 +#define SHOW_VAL_FMT (ao_strs_strtable+667) +#define SHOW_VAL_FMT_LEN 17 +#define START_MARK (ao_strs_strtable+6486) +#define START_MARK_LEN 82 +#define STDOUT (ao_strs_strtable+685) +#define STDOUT_LEN 6 +#define TIME_FMT (ao_strs_strtable+692) +#define TIME_FMT_LEN 21 +#define TMPDIR (ao_strs_strtable+714) +#define TMPDIR_LEN 6 +#define TMP_FILE_FMT (ao_strs_strtable+721) +#define TMP_FILE_FMT_LEN 16 +#define TMP_USAGE_FMT (ao_strs_strtable+721) +#define TMP_USAGE_FMT_LEN 16 +#define TRUE_STR (ao_strs_strtable+738) +#define TRUE_STR_LEN 4 +#define TWO_SPACES_STR (ao_strs_strtable+273) +#define TWO_SPACES_STR_LEN 2 +#define TYPE_ATR_FMT (ao_strs_strtable+743) +#define TYPE_ATR_FMT_LEN 12 +#define UNK_OPT_FMT (ao_strs_strtable+6569) +#define UNK_OPT_FMT_LEN 144 +#define VER_STR (ao_strs_strtable+756) +#define VER_STR_LEN 7 +#define XML_HEX_BYTE_FMT (ao_strs_strtable+764) +#define XML_HEX_BYTE_FMT_LEN 7 +#define YES_NEED_OPT_ARG (ao_strs_strtable+772) +#define YES_NEED_OPT_ARG_LEN 18 +#define ao_default_use (ao_strs_strtable+804) +#define ao_default_use_LEN 11 +#define ao_name_use_fmt (ao_strs_strtable+791) +#define ao_name_use_fmt_LEN 12 +#define apostrophe (ao_strs_strtable+816) +#define apostrophe_LEN 4 +#define arg_fmt (ao_strs_strtable+821) +#define arg_fmt_LEN 5 +#define init_optct (ao_strs_strtable+864) +#define init_optct_LEN 13 +#define misguess_len (ao_strs_strtable+827) +#define misguess_len_LEN 36 +#define set_dash (ao_strs_strtable+878) +#define set_dash_LEN 6 +#define tmp_dir (ao_strs_strtable+885) +#define tmp_dir_LEN 4 +#define zAll (ao_strs_strtable+276) +#define zAll_LEN 3 +#define zCfgAO_Flags (ao_strs_strtable+12) +#define zCfgAO_Flags_LEN 14 +#define zCfgProg (ao_strs_strtable+27) +#define zCfgProg_LEN 9 +#define zEquivMode (ao_strs_strtable+1252) +#define zEquivMode_LEN 44 +#define zFiveSpaces (ao_strs_strtable+263) +#define zFiveSpaces_LEN 5 +#define zFmtFmt (ao_strs_strtable+37) +#define zFmtFmt_LEN 11 +#define zFmtProg (ao_strs_strtable+49) +#define zFmtProg_LEN 14 +#define zFullOptFmt (ao_strs_strtable+1297) +#define zFullOptFmt_LEN 34 +#define zGnuBreak (ao_strs_strtable+64) +#define zGnuBreak_LEN 5 +#define zGnuFileArg (ao_strs_strtable+70) +#define zGnuFileArg_LEN 5 +#define zGnuKeyLArg (ao_strs_strtable+76) +#define zGnuKeyLArg_LEN 4 +#define zGnuNestArg (ao_strs_strtable+81) +#define zGnuNestArg_LEN 5 +#define zGnuOptArg (ao_strs_strtable+87) +#define zGnuOptArg_LEN 6 +#define zGnuOptFmt (ao_strs_strtable+94) +#define zGnuOptFmt_LEN 10 +#define zGnuTimeArg (ao_strs_strtable+105) +#define zGnuTimeArg_LEN 4 +#define zNone (ao_strs_strtable+110) +#define zNone_LEN 4 +#define zOptCookieCt (ao_strs_strtable+1332) +#define zOptCookieCt_LEN 38 +#define zOptCtFmt (ao_strs_strtable+1371) +#define zOptCtFmt_LEN 30 +#define zOptDisabl (ao_strs_strtable+1402) +#define zOptDisabl_LEN 32 +#define zOptNumFmt (ao_strs_strtable+1435) +#define zOptNumFmt_LEN 41 +#define zOptionCase (ao_strs_strtable+1477) +#define zOptionCase_LEN 30 +#define zOptionEndSelect (ao_strs_strtable+890) +#define zOptionEndSelect_LEN 16 +#define zOptionFlag (ao_strs_strtable+907) +#define zOptionFlag_LEN 15 +#define zOptionFullName (ao_strs_strtable+923) +#define zOptionFullName_LEN 15 +#define zOptionPartName (ao_strs_strtable+939) +#define zOptionPartName_LEN 17 +#define zPresetFile (ao_strs_strtable+115) +#define zPresetFile_LEN 37 +#define zReqOptFmt (ao_strs_strtable+153) +#define zReqOptFmt_LEN 13 +#define zSepChars (ao_strs_strtable+0) +#define zSepChars_LEN 3 +#define zShrtGnuOptFmt (ao_strs_strtable+167) +#define zShrtGnuOptFmt_LEN 2 +#define zSixSpaces (ao_strs_strtable+256) +#define zSixSpaces_LEN 6 +#define zStdBoolArg (ao_strs_strtable+170) +#define zStdBoolArg_LEN 3 +#define zStdBreak (ao_strs_strtable+174) +#define zStdBreak_LEN 7 +#define zStdFileArg (ao_strs_strtable+182) +#define zStdFileArg_LEN 3 +#define zStdKeyArg (ao_strs_strtable+186) +#define zStdKeyArg_LEN 3 +#define zStdKeyLArg (ao_strs_strtable+190) +#define zStdKeyLArg_LEN 3 +#define zStdNestArg (ao_strs_strtable+194) +#define zStdNestArg_LEN 3 +#define zStdNoArg (ao_strs_strtable+198) +#define zStdNoArg_LEN 3 +#define zStdNumArg (ao_strs_strtable+202) +#define zStdNumArg_LEN 3 +#define zStdOptArg (ao_strs_strtable+206) +#define zStdOptArg_LEN 3 +#define zStdReqArg (ao_strs_strtable+210) +#define zStdReqArg_LEN 3 +#define zStdStrArg (ao_strs_strtable+214) +#define zStdStrArg_LEN 3 +#define zStdTimeArg (ao_strs_strtable+218) +#define zStdTimeArg_LEN 3 +#define zTabHyp (ao_strs_strtable+222) +#define zTabHypAnd (ao_strs_strtable+236) +#define zTabHypAnd_LEN 11 +#define zTabHyp_LEN 6 +#define zTabSpace (ao_strs_strtable+229) +#define zTabSpace_LEN 6 +#define zTabout (ao_strs_strtable+248) +#define zTabout_LEN 7 +#define zThreeSpaces (ao_strs_strtable+269) +#define zThreeSpaces_LEN 3 +#define zTwoSpaces (ao_strs_strtable+273) +#define zTwoSpaces_LEN 2 +#define zambig_file (ao_strs_strtable+4) +#define zambig_file_LEN 7 +extern char const ao_strs_strtable[6714]; + +#endif /* STRINGS_AO_STRS_H_GUARD */ diff --git a/autoopts/ao_string_tokenize.3 b/autoopts/ao_string_tokenize.3 new file mode 100644 index 0000000..fad6dff --- /dev/null +++ b/autoopts/ao_string_tokenize.3 @@ -0,0 +1,86 @@ +.TH ao_string_tokenize 3 2018-08-26 "" "Programmer's Manual" +.\" DO NOT EDIT THIS FILE (ao_string_tokenize.3) +.\" +.\" It has been AutoGen-ed +.\" From the definitions ./funcs.def +.\" and the template file agman3.tpl +.SH NAME +ao_string_tokenize - tokenize an input string +.sp 1 +.SH SYNOPSIS + +#include <\fIyour-opts.h\fP> +.br +cc [...] -o outfile infile.c -l\fBopts\fP [...] +.sp 1 +token_list_t * \fBao_string_tokenize\fP(char const * \fIstring\fP); +.sp 1 +.SH DESCRIPTION +This function will convert one input string into a list of strings. +The list of strings is derived by separating the input based on +white space separation. However, if the input contains either single +or double quote characters, then the text after that character up to +a matching quote will become the string in the list. + +The returned pointer should be deallocated with \fBfree(3C)\fP when +are done using the data. The data are placed in a single block of +allocated memory. Do not deallocate individual token/strings. + +The structure pointed to will contain at least these two fields: +.sp +.IR "tkn_ct" +The number of tokens found in the input string. +.sp +.IR "tok_list" +An array of \fBtkn_ct + 1\fP pointers to substring tokens, with +the last pointer set to NULL. +.br + +There are two types of quoted strings: single quoted (\fB'\fP) and +double quoted (\fB"\fP). Singly quoted strings are fairly raw in that +escape characters (\fB\\\fP) are simply another character, except when +preceding the following characters: +.nf + \fB\\\fP double backslashes reduce to one + \fB'\fP incorporates the single quote into the string + \fB\n\fP suppresses both the backslash and newline character +.fi + +Double quote strings are formed according to the rules of string +constants in ANSI-C programs. +.TP +.IR string +string to be tokenized +.sp 1 +.SH RETURN VALUE +pointer to a structure that lists each token +.sp 1 +.SH ERRORS +NULL is returned and \fBerrno\fP will be set to indicate the problem: +.sp 1ize @bullet +.sp 1 +\fBEINVAL\fP \- There was an unterminated quoted string. +.sp 1 +\fBENOENT\fP \- The input string was empty. +.sp 1 +\fBENOMEM\fP \- There is not enough memory. +@end itemize +.sp 1 +.SH EXAMPLES +.nf +.in +5 +.nf + #include + int ix; + token_list_t * ptl = ao_string_tokenize(some_string) + for (ix = 0; ix < ptl->tkn_ct; ix++) + do_something_with_tkn(ptl->tkn_list[ix]); + free(ptl); +.fi +Note that everything is freed with the one call to \fBfree(3C)\fP. +.in -5 +.fi +.SH SEE ALSO +The \fIinfo\fP documentation for the -l\fIopts\fP library. +.br +configFileLoad(3), optionFileLoad(3), optionFindNextValue(3), optionFindValue(3), optionFree(3), optionGetValue(3), optionLoadLine(3), optionMemberList(3), optionNextValue(3), optionOnlyUsage(3), optionPrintVersion(3), optionPrintVersionAndReturn(3), optionProcess(3), optionRestore(3), optionSaveFile(3), optionSaveState(3), optionUnloadNested(3), optionVersion(3), strequate(3), streqvcmp(3), streqvmap(3), strneqvcmp(3), strtransform(3), diff --git a/autoopts/autogen.map b/autoopts/autogen.map new file mode 100644 index 0000000..328b6c7 --- /dev/null +++ b/autoopts/autogen.map @@ -0,0 +1,81 @@ + +%guard +%file ag-char-map.h +%backup +%optimize + +%comment + This file contains the character classifications + used by AutoGen and AutoOpts for identifying tokens. + The table is static scope, so %guard is empty. + + This file is part of AutoOpts, a companion to AutoGen. + AutoOpts is free software. + AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + + AutoOpts is available under any one of two licenses. The license + in use must be one of these two and the choice is under the control + of the user of the license. + + The GNU Lesser General Public License, version 3 or later + See the files "COPYING.lgplv3" and "COPYING.gplv3" + + The Modified Berkeley Software Distribution License + See the file "COPYING.mbsd" + + These files have the following sha256 sums: + + 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 + 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 + 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd +% + +newline "\n" +nul-byte "\x00" +dir-sep "/\\" +percent "%" +comma "," +colon ":" +underscore "_" +plus "+" +dollar "$" +option-marker "-" + +horiz-white "\t " +alt-white "\v\f\r\b" +whitespace +horiz-white +newline +alt-white +non-nl-white +horiz-white +alt-white +quote "'\"" +parentheses "()" + +graphic "!-~" +inversion "~-" +oct-digit "0-7" +dec-digit "89" +oct-digit +hex-digit "a-fA-F" +dec-digit +lower-case "a-z" +upper-case "A-Z" +alphabetic +lower-case +upper-case +alphanumeric +alphabetic +dec-digit +var-first +underscore +alphabetic +variable-name +var-first +dec-digit +option-name "^-" +variable-name +value-name +colon +option-name +name-sep "[.]" +compound-name +value-name +name-sep +horiz-white +scheme-note +parentheses +quote + +unquotable "!-~" -"#,;<=>[\\]`{}?*" -quote -parentheses +end-xml-token "/>" +whitespace +plus-n-space +plus +whitespace +punctuation "!-~" -alphanumeric -"_" +suffix "-._" +alphanumeric +suffix-fmt +percent +suffix +dir-sep +false-type "nNfF0" +nul-byte +file-name +dir-sep +suffix +end-token +nul-byte +whitespace +end-list-entry +comma +end-token +set-separator "|+-!" +end-list-entry +signed-number +inversion +dec-digit +make-script +dollar +newline +load-line-skip +horiz-white +option-marker diff --git a/autoopts/autoopts-config.1 b/autoopts/autoopts-config.1 new file mode 100644 index 0000000..dddf661 --- /dev/null +++ b/autoopts/autoopts-config.1 @@ -0,0 +1,161 @@ +\" -*- buffer-read-only: t -*- vi: set ro: +\" +\" DO NOT EDIT THIS FILE (autoopts-config.1) +\" +\" It has been AutoGen-ed +\" From the definitions aoconf.def +\" and the template file aoconf.tpl +\" +.TH autoopts-config 1 2018-08-26 "" "Programmer's Manual" +.SH NAME +autoopts-config \- script to get information about installed version of +autoopts +.SH SYNOPSIS +.B autoopts-config +.B { [...] | everything } +.PP +.SH DESCRIPTION +\fBautoopts-config\fP is a tool that is used by configure to determine +the compile and linker flags that should be used to compile and link +programs that use autoopts. \fIvalue-name\fPs may be preceded by +one or more hyphens. They are silently ignored. +.SH "VALUE NAMES" +.TP +.BR autogen +.sp +Print the full path name of the autogen executable. +.br +The unconfigured value is: ${bindir}/autogen${exeext} +.TP +.BR bindir +.sp +The destination directory for executable scripts and programs +installed by the \fIautogen\fP package. +.br +The unconfigured value is: @bindir@ +.TP +.BR cflags +.sp +Print the compiler flags that are necessary to compile an autoopts program. +.br +The unconfigured value is: -I${includedir} +.TP +.BR datadir +.sp +The directory for various data directories. +.br +The unconfigured value is: @datadir@ +.TP +.BR datarootdir +.sp +The root directory for various data directories. +In this case, there is only one, "datadir". +.br +The unconfigured value is: @datarootdir@ +.TP +.BR dotver +.sp +Print the currently installed version of autoopts, in dotted format. +.br +The unconfigured value is: @AO_CURRENT@.@AO_REVISION@.@AO_AGE@ +.TP +.BR everything +.sp +Print the list of all names and values, one per line. +.TP +.BR exec_prefix +.sp +The installation root for libraries and executables. +.br +The unconfigured value is: @exec_prefix@ +.TP +.BR exeext +.sp +The executable file extension used for the autogen executable. +.br +The unconfigured value is: @EXEEXT@ +.TP +.BR includedir +.sp +The directory where the AutoOpts headers are stored. +This does not include the "-I" prefix gotten by specifying "cflags". +.br +The unconfigured value is: @includedir@ +.TP +.BR ldflags +.sp +Print the linker flags that are necessary to link an autoopts program +in the default installation mode (static or dynamic). +.br +The unconfigured value is: -L${libdir} -lopts +.TP +.BR ldopts +.sp +The linker options to use when linking a program to libopts. +.br +The unconfigured value is: @AG_LDFLAGS@ +.TP +.BR libdir +.sp +The libopts installation directory. +.br +The unconfigured value is: @libdir@ +.TP +.BR libs +.sp +an alternate spelling of "\fIldflags\fP". +.br +The unconfigured value is: ${ldflags} +.TP +.BR libsrc +.sp +The full path of the redistributable, tear-off libopts library source. +This file is in gzipped-tarball format. +.br +The unconfigured value is: ${pkgdatadir}/libopts-${dotver}.tar.gz +.TP +.BR package +.sp +The name of the package that provides \fBautoopts\fP. This is always +"\fIautogen\fP". +.br +The unconfigured value is: @PACKAGE@ +.TP +.BR pkgdatadir +.sp +The directory containing support files used by autogen. +.br +The unconfigured value is: ${datadir}/${package} +.TP +.BR prefix +.sp +The \fIautogen\fP package installation prefix. +.br +The unconfigured value is: @prefix@ +.TP +.BR static_libs +.sp +The name of the AR archive of the libopts object code. +.br +The unconfigured value is: ${libdir}/libopts.a +.TP +.BR version +.sp +Print the currently installed version of autoopts. +.br +The unconfigured value is: @AO_CURRENT@:@AO_REVISION@:@AO_AGE@ +.SH "SEE ALSO" +.IR Autogen +Info system documentation. +.SH AUTHORS +AutoGen is the work of Bruce Korb . +.br +Bruce Korb and +.br +Luca Filipozzi +created this manpage. +.PP +AutoOpts is released under either the GNU General Public License with the +Library exception (LGPL), or else the advertising clause free BSD license. +Which license used is at the discretion of the licensee. +\" end of autoopts-config.1 diff --git a/autoopts/autoopts-config.in b/autoopts/autoopts-config.in new file mode 100644 index 0000000..3c966d1 --- /dev/null +++ b/autoopts/autoopts-config.in @@ -0,0 +1,113 @@ +#! @CONFIG_SHELL@ +## --------------------------------------------------------------------- +## autoopts-config.in -- Describe AutoOpts configuration +## +## Autoopts Copyright (C) 1992-2018 by Bruce Korb +## +## DO NOT EDIT THIS FILE (autoopts-config.in) +## +## It has been AutoGen-ed +## From the definitions aoconf.def +## and the template file aoconf.tpl +## + prefix="@prefix@" + datarootdir="@datarootdir@" + datadir="@datadir@" + package="@PACKAGE@" + includedir="@includedir@" + exec_prefix="@exec_prefix@" + bindir="@bindir@" + libdir="@libdir@" + ldopts="@AG_LDFLAGS@" + exeext="@EXEEXT@" + version="@AO_CURRENT@:@AO_REVISION@:@AO_AGE@" + dotver="@AO_CURRENT@.@AO_REVISION@.@AO_AGE@" + pkgdatadir="${datadir}/${package}" + autogen="${bindir}/autogen${exeext}" + ldflags="-L${libdir} -lopts" + libs="${ldflags}" + libsrc="${pkgdatadir}/libopts-${dotver}.tar.gz" + static_libs="${libdir}/libopts.a" + cflags="-I${includedir}" +test 'X@ENABLE_STATIC@' = Xno && static_libs='' +case "${libdir}" in +/lib | /lib64 | /usr/lib | /usr/lib64 | /usr/lib/* ) + ldopts='' + ldflags=-lopts + ;; + +* ) + ldflags="${ldopts} ${ldflags}" + ;; +esac +libs=${ldflags} +test "${includedir}" = "/usr/include" && cflags="" +optlist="\ + autogen bindir cflags datadir datarootdir dotver + everything exec_prefix exeext includedir ldflags ldopts + libdir libs libsrc package pkgdatadir prefix + static_libs version" + +usage() +{ + test $# -gt 0 && { + exec 1>&2 + echo autoopts-config error: "$*" + } + + echo Usage: autoopts-config \<\\> [ ... ] + echo Options may be one or more of: + + for o in $optlist + do echo " ${o}" + done | sed 's,_,-,g' + echo 'NB: "everything" will print out the list of all names and values.' + exit $# +} + +test $# -gt 0 || usage "No value specified" + +# Figure out what's wanted +# +val='' +for o in "$@" ; do + o=`echo ${o} | sed 's,^-*,,;s/-/_/g'` + case "$o" in + help | h | \? ) usage ;; + *[!a-zA-Z0-9_]* ) usage "Invalid name: ${o}" ;; + + prefix ) val="${val} ${prefix}" ;; + datarootdir ) val="${val} ${datarootdir}" ;; + datadir ) val="${val} ${datadir}" ;; + package ) val="${val} ${package}" ;; + includedir ) val="${val} ${includedir}" ;; + exec_prefix ) val="${val} ${exec_prefix}" ;; + bindir ) val="${val} ${bindir}" ;; + libdir ) val="${val} ${libdir}" ;; + ldopts ) val="${val} ${ldopts}" ;; + exeext ) val="${val} ${exeext}" ;; + version ) val="${val} ${version}" ;; + dotver ) val="${val} ${dotver}" ;; + pkgdatadir ) val="${val} ${pkgdatadir}" ;; + autogen ) val="${val} ${autogen}" ;; + ldflags ) val="${val} ${ldflags}" ;; + libs ) val="${val} ${libs}" ;; + libsrc ) val="${val} ${libsrc}" ;; + static_libs ) val="${val} ${static_libs}" ;; + cflags ) val="${val} ${cflags}" ;; + everything ) + for o in ${optlist} + do test ${o} = everything && continue + eval v=\"\${${o}}\" + test -z "${v}" && echo ${o} || \ + printf "%-12s $v\n" ${o} + done + exit 0 + ;; + + * ) usage "Unknown value name: ${o}" ;; + esac +done + +echo "${val}" +## end of autoopts-config.in diff --git a/autoopts/autoopts.c b/autoopts/autoopts.c new file mode 100644 index 0000000..643d277 --- /dev/null +++ b/autoopts/autoopts.c @@ -0,0 +1,391 @@ + +/** + * \file autoopts.c + * + * This file contains all of the routines that must be linked into + * an executable to use the generated option processing. The optional + * routines are in separately compiled modules so that they will not + * necessarily be linked in. + * + * @addtogroup autoopts + * @{ + */ +/* + * This file is part of AutoOpts, a companion to AutoGen. + * AutoOpts is free software. + * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoOpts is available under any one of two licenses. The license + * in use must be one of these two and the choice is under the control + * of the user of the license. + * + * The GNU Lesser General Public License, version 3 or later + * See the files "COPYING.lgplv3" and "COPYING.gplv3" + * + * The Modified Berkeley Software Distribution License + * See the file "COPYING.mbsd" + * + * These files have the following sha256 sums: + * + * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 + * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 + * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + */ + +/** + * The number of tab characters to skip when printing continuation lines. + */ + static unsigned int tab_skip_ct = 0; + +#ifndef HAVE_PATHFIND +# define pathfind(_p, _n, _m) option_pathfind(_p, _n, _m) +# include "compat/pathfind.c" +#endif + +#ifndef HAVE_SNPRINTF +# define vsnprintf option_vsnprintf +# define snprintf option_snprintf +# include "compat/snprintf.c" +#endif + +#ifndef HAVE_STRDUP +# define strdup(_s) option_strdup(_s) +# include "compat/strdup.c" +#endif + +#ifndef HAVE_STRCHR +# define strrchr(_s, _c) option_strrchr(_s, _c) +# define strchr(_s, _c) option_strchr(_s, _c) +# include "compat/strchr.c" +#endif + +static void * +ao_malloc(size_t sz) +{ + void * res = malloc(sz); + if (res == NULL) { + fprintf(stderr, zalloc_fail, (int)sz); + option_exits(EXIT_FAILURE); + } + return res; +} + +static void * +ao_realloc(void *p, size_t sz) +{ + void * res = (p == NULL) ? malloc(sz) : realloc(p, sz); + if (res == NULL) { + fprintf(stderr, zrealloc_fail, (int)sz, p); + option_exits(EXIT_FAILURE); + } + return res; +} + +static char * +ao_strdup(char const *str) +{ + char * res = strdup(str); + if (res == NULL) { + fprintf(stderr, zalloc_fail, (int)strlen(str)); + option_exits(EXIT_FAILURE); + } + return res; +} + +/** + * handle an option. + * + * This routine handles equivalencing, sets the option state flags and + * invokes the handler procedure, if any. + */ +static tSuccess +handle_opt(tOptions * opts, tOptState * o_st) +{ + /* + * Save a copy of the option procedure pointer. + * If this is an equivalence class option, we still want this proc. + */ + tOptDesc * od = o_st->pOD; + tOptProc * opt_proc = od->pOptProc; + if (od->fOptState & OPTST_ALLOC_ARG) + AGFREE(od->optArg.argString); + + od->optArg.argString = o_st->pzOptArg; + + /* + * IF we are presetting options, then we will ignore any un-presettable + * options. They are the ones either marked as such. + */ + if ( ((opts->fOptSet & OPTPROC_PRESETTING) != 0) + && ((od->fOptState & OPTST_NO_INIT) != 0) + ) + return PROBLEM; + + /* + * IF this is an equivalence class option, + * THEN + * Save the option value that got us to this option + * entry. (It may not be od->optChar[0], if this is an + * equivalence entry.) + * set the pointer to the equivalence class base + */ + if (od->optEquivIndex != NO_EQUIVALENT) { + tOptDesc * eqv_od = opts->pOptDesc + od->optEquivIndex; + + /* + * IF the current option state has not been defined (set on the + * command line), THEN we will allow continued resetting of + * the value. Once "defined", then it must not change. + */ + if ((od->fOptState & OPTST_DEFINED) != 0) { + /* + * The equivalenced-to option has been found on the command + * line before. Make sure new occurrences are the same type. + * + * IF this option has been previously equivalenced and + * it was not the same equivalenced-to option, + * THEN we have a usage problem. + */ + if (eqv_od->optActualIndex != od->optIndex) { + fprintf(stderr, zmultiway_bug, eqv_od->pz_Name, od->pz_Name, + (opts->pOptDesc + eqv_od->optActualIndex)->pz_Name); + return FAILURE; + } + } else { + /* + * Set the equivalenced-to actual option index to no-equivalent + * so that we set all the entries below. This option may either + * never have been selected before, or else it was selected by + * some sort of "presetting" mechanism. + */ + eqv_od->optActualIndex = NO_EQUIVALENT; + } + + if (eqv_od->optActualIndex != od->optIndex) { + /* + * First time through, copy over the state + * and add in the equivalence flag + */ + eqv_od->optActualValue = od->optValue; + eqv_od->optActualIndex = od->optIndex; + o_st->flags |= OPTST_EQUIVALENCE; + } + + /* + * Copy the most recent option argument. set membership state + * is kept in 'eqv_od->optCookie'. Do not overwrite. + */ + eqv_od->optArg.argString = od->optArg.argString; + od = eqv_od; + + } else { + od->optActualValue = od->optValue; + od->optActualIndex = od->optIndex; + } + + od->fOptState &= OPTST_PERSISTENT_MASK; + od->fOptState |= (o_st->flags & ~OPTST_PERSISTENT_MASK); + + /* + * Keep track of count only for DEFINED (command line) options. + * IF we have too many, build up an error message and bail. + */ + if ( (od->fOptState & OPTST_DEFINED) + && (++od->optOccCt > od->optMaxCt) ) + return too_many_occurrences(opts, od); + /* + * If provided a procedure to call, call it + */ + if (opt_proc != NULL) + (*opt_proc)(opts, od); + + return SUCCESS; +} + +/** + * Find the option descriptor and option argument (if any) for the + * next command line argument. DO NOT modify the descriptor. Put + * all the state in the state argument so that the option can be skipped + * without consequence (side effect). + * + * @param opts the program option descriptor + * @param o_st the state of the next found option + */ +static tSuccess +next_opt(tOptions * opts, tOptState * o_st) +{ + { + tSuccess res = find_opt(opts, o_st); + if (! SUCCESSFUL(res)) + return res; + } + + if ( ((o_st->flags & OPTST_DEFINED) != 0) + && ((o_st->pOD->fOptState & OPTST_NO_COMMAND) != 0)) { + fprintf(stderr, zNotCmdOpt, o_st->pOD->pz_Name); + return FAILURE; + } + + return get_opt_arg(opts, o_st); +} + +/** + * Process all the options from our current position onward. (This allows + * interspersed options and arguments for the few non-standard programs that + * require it.) Thus, do not rewind option indexes because some programs + * choose to re-invoke after a non-option. + * + * @param[in,out] opts program options descriptor + * @returns SUCCESS or FAILURE + */ +static tSuccess +regular_opts(tOptions * opts) +{ + /* assert: opts->fOptSet & OPTPROC_IMMEDIATE == 0 */ + for (;;) { + tOptState opt_st = OPTSTATE_INITIALIZER(DEFINED); + + switch (next_opt(opts, &opt_st)) { + case FAILURE: goto failed_option; + case PROBLEM: return SUCCESS; /* no more args */ + case SUCCESS: break; + } + + /* + * IF this is an immediate action option, + * THEN skip it (unless we are supposed to do it a second time). + */ + if (! DO_NORMALLY(opt_st.flags)) { + if (! DO_SECOND_TIME(opt_st.flags)) + continue; + opt_st.pOD->optOccCt--; /* don't count this repetition */ + } + + if (! SUCCESSFUL(handle_opt(opts, &opt_st))) + break; + } failed_option:; + + if ((opts->fOptSet & OPTPROC_ERRSTOP) != 0) + (*opts->pUsageProc)(opts, EXIT_FAILURE); + + return FAILURE; +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * THESE ROUTINES ARE CALLABLE FROM THE GENERATED OPTION PROCESSING CODE + */ +/*=--subblock=arg=arg_type,arg_name,arg_desc =*/ +/*=* + * library: opts + * header: your-opts.h + * + * lib_description: + * + * These are the routines that libopts users may call directly from their + * code. There are several other routines that can be called by code + * generated by the libopts option templates, but they are not to be + * called from any other user code. The @file{options.h} header is + * fairly clear about this, too. +=*/ + +/*=export_func optionProcess + * + * what: this is the main option processing routine + * + * arg: + tOptions * + opts + program options descriptor + + * arg: + int + a_ct + program arg count + + * arg: + char ** + a_v + program arg vector + + * + * ret_type: int + * ret_desc: the count of the arguments processed + * + * doc: + * + * This is the main entry point for processing options. It is intended + * that this procedure be called once at the beginning of the execution of + * a program. Depending on options selected earlier, it is sometimes + * necessary to stop and restart option processing, or to select completely + * different sets of options. This can be done easily, but you generally + * do not want to do this. + * + * The number of arguments processed always includes the program name. + * If one of the arguments is "--", then it is counted and the processing + * stops. If an error was encountered and errors are to be tolerated, then + * the returned value is the index of the argument causing the error. + * A hyphen by itself ("-") will also cause processing to stop and will + * @emph{not} be counted among the processed arguments. A hyphen by itself + * is treated as an operand. Encountering an operand stops option + * processing. + * + * err: Errors will cause diagnostics to be printed. @code{exit(3)} may + * or may not be called. It depends upon whether or not the options + * were generated with the "allow-errors" attribute, or if the + * ERRSKIP_OPTERR or ERRSTOP_OPTERR macros were invoked. +=*/ +int +optionProcess(tOptions * opts, int a_ct, char ** a_v) +{ + if (! SUCCESSFUL(validate_struct(opts, a_v[0]))) + ao_bug(zbad_data_msg); + + /* + * Establish the real program name, the program full path, + * and do all the presetting the first time thru only. + */ + if (! ao_initialize(opts, a_ct, a_v)) + return 0; + + /* + * IF we are (re)starting, + * THEN reset option location + */ + if (opts->curOptIdx <= 0) { + opts->curOptIdx = 1; + opts->pzCurOpt = NULL; + } + + if (! SUCCESSFUL(regular_opts(opts))) + return (int)opts->origArgCt; + + /* + * IF there were no errors + * AND we have RC/INI files + * AND there is a request to save the files + * THEN do that now before testing for conflicts. + * (conflicts are ignored in preset options) + */ + switch (opts->specOptIdx.save_opts) { + case 0: + case NO_EQUIVALENT: + break; + default: + { + tOptDesc * od = opts->pOptDesc + opts->specOptIdx.save_opts; + + if (SELECTED_OPT(od)) { + optionSaveFile(opts); + option_exits(EXIT_SUCCESS); + } + } + } + + /* + * IF we are checking for errors, + * THEN look for too few occurrences of required options + */ + if (((opts->fOptSet & OPTPROC_ERRSTOP) != 0) + && (! is_consistent(opts))) + (*opts->pUsageProc)(opts, EXIT_FAILURE); + + return (int)opts->curOptIdx; +} + +/** @} + * + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of autoopts/autoopts.c */ diff --git a/autoopts/autoopts.h b/autoopts/autoopts.h new file mode 100644 index 0000000..36bb43f --- /dev/null +++ b/autoopts/autoopts.h @@ -0,0 +1,494 @@ + +/* + * \file autoopts.h + * + * This file defines all the global structures and special values + * used in the automated option processing library. + * + * @group autoopts + * @{ + */ +/* + * This file is part of AutoOpts, a companion to AutoGen. + * AutoOpts is free software. + * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoOpts is available under any one of two licenses. The license + * in use must be one of these two and the choice is under the control + * of the user of the license. + * + * The GNU Lesser General Public License, version 3 or later + * See the files "COPYING.lgplv3" and "COPYING.gplv3" + * + * The Modified Berkeley Software Distribution License + * See the file "COPYING.mbsd" + * + * These files have the following sha256 sums: + * + * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 + * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 + * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + */ + +#ifndef AUTOGEN_AUTOOPTS_H +#define AUTOGEN_AUTOOPTS_H +#include + +#define AO_NAME_LIMIT 127 +#define AO_NAME_SIZE ((size_t)(AO_NAME_LIMIT + 1)) + +#ifndef AG_PATH_MAX +# ifdef PATH_MAX +# define AG_PATH_MAX ((size_t)PATH_MAX) +# else +# ifdef __gnu_hurd__ +# define size_t unsigned long +# endif +# define AG_PATH_MAX ((size_t)4096) +# endif +#else +# if defined(PATH_MAX) && (PATH_MAX > MAXPATHLEN) +# undef AG_PATH_MAX +# define AG_PATH_MAX ((size_t)PATH_MAX) +# endif +#endif + +#undef EXPORT +#define EXPORT + +#ifndef NUL +#define NUL '\0' +#endif +#define BEL '\a' +#define BS '\b' +#define HT '\t' +#define LF '\n' +#define VT '\v' +#define FF '\f' +#define CR '\r' + +#if defined(_WIN32) && !defined(__CYGWIN__) +# define DIRCH '\\' +#else +# define DIRCH '/' +#endif + +#ifndef EX_USAGE + /** + * Command line usage problem + */ +# define EX_USAGE 64 +#endif +#ifndef EX_DATAERR + /** + * The input data was incorrect in some way. + */ +# define EX_DATAERR 64 +#endif +#ifndef EX_NOINPUT + /** + * option state was requested from a file that cannot be loaded. + */ +# define EX_NOINPUT 66 +#endif +#ifndef EX_SOFTWARE + /** + * AutoOpts Software failure. + */ +# define EX_SOFTWARE 70 +#endif +#ifndef EX_OSERR + /** + * Command line usage problem + */ +# define EX_OSERR 71 +#endif + +#define NL '\n' +#ifndef C +/** + * Coercive cast. Compel an address to be interpreted as the type + * of the first argument. No complaints, just do it. + */ +#define C(_t,_p) ((_t)VOIDP(_p)) +#endif + +/* The __attribute__((__warn_unused_result__)) feature + is available in gcc versions 3.4 and newer, + while the typeof feature has been available since 2.7 at least. */ +# if __GNUC__ < 3 || (__GNUC__ == 3 && __GNUC_MINOR__ < 4) +# define ignore_val(x) ((void) (x)) +# else +# define ignore_val(x) (({ __typeof__ (x) __x = (x); (void) __x; })) +# endif + +/* + * Convert the number to a list usable in a printf call + */ +#define NUM_TO_VER(n) ((n) >> 12), ((n) >> 7) & 0x001F, (n) & 0x007F + +#define NAMED_OPTS(po) \ + (((po)->fOptSet & (OPTPROC_SHORTOPT | OPTPROC_LONGOPT)) == 0) + +#define SKIP_OPT(p) (((p)->fOptState & OPTST_IMMUTABLE_MASK) != 0) + +typedef int tDirection; +/** + * handling option presets. Start with command line and work through + * config settings in reverse order. + */ +#define DIRECTION_PRESET -1 +/** + * handling normal options. Start with first config file, then environment + * variables and finally the command line. + */ +#define DIRECTION_PROCESS 1 +/** + * An initialzation phase or an option being loaded from program sources. + */ +#define DIRECTION_CALLED 0 + +#define PROCESSING(d) ((d)>0) +#define PRESETTING(d) ((d)<0) +#define CALLED(d) ((d)==0) + +/** + * When loading a line (or block) of text as an option, the value can + * be processed in any of several modes. + */ +typedef enum { + /** + * If the value looks like a quoted string, then process it. Double + * quoted strings are processed the way strings are in "C" programs, + * except they are treated as regular characters if the following + * character is not a well-established escape sequence. Single quoted + * strings (quoted with apostrophies) are handled the way strings are + * handled in shell scripts, *except* that backslash escapes are + * honored before backslash escapes and apostrophies. + */ + OPTION_LOAD_COOKED, + + /** + * Even if the value begins with quote characters, do not do quote + * processing. Strip leading and trailing white space. + */ + OPTION_LOAD_UNCOOKED, + + /** + * Keep every part of the value between the delimiters. + */ + OPTION_LOAD_KEEP +} tOptionLoadMode; + +static tOptionLoadMode option_load_mode; + +/** + * The pager state is used by optionPagedUsage() procedure. + * When it runs, it sets itself up to be called again on exit. + * If, however, a routine needs a child process to do some work + * before it is done, then 'pagerState' must be set to + * 'PAGER_STATE_CHILD' so that optionPagedUsage() will not try + * to run the pager program before its time. + */ +typedef enum { + PAGER_STATE_INITIAL, //@< initial option paging state + + /** + * temp file created and optionPagedUsage is scheduled to run at exit + */ + PAGER_STATE_READY, + + /** + * This is a child process used in creating shell script usage. + */ + PAGER_STATE_CHILD +} tePagerState; + +typedef enum { + ENV_ALL, + ENV_IMM, + ENV_NON_IMM +} teEnvPresetType; + +typedef enum { + TOPT_UNDEFINED = 0, + TOPT_SHORT, + TOPT_LONG, + TOPT_DEFAULT +} teOptType; + +typedef struct { + tOptDesc * pOD; + char const * pzOptArg; + opt_state_mask_t flags; + teOptType optType; +} tOptState; +#define OPTSTATE_INITIALIZER(st) \ + { NULL, NULL, OPTST_ ## st, TOPT_UNDEFINED } + +#define TEXTTO_TABLE \ + _TT_(LONGUSAGE) \ + _TT_(USAGE) \ + _TT_(VERSION) +#define _TT_(n) \ + TT_ ## n , + +typedef enum { TEXTTO_TABLE COUNT_TT } teTextTo; + +#undef _TT_ + +/** + * option argument types. Used to create usage information for + * particular options. + */ +typedef struct { + char const * pzStr; + char const * pzReq; + char const * pzNum; + char const * pzFile; + char const * pzKey; + char const * pzKeyL; + char const * pzBool; + char const * pzNest; + char const * pzOpt; + char const * pzNo; + char const * pzBrk; + char const * pzNoF; + char const * pzSpc; + char const * pzOptFmt; + char const * pzTime; +} arg_types_t; + +#define AGALOC(_c, _w) ao_malloc((size_t)_c) +#define AGREALOC(_p, _c, _w) ao_realloc(VOIDP(_p), (size_t)_c) +#define AGFREE(_p) free(VOIDP(_p)) +#define AGDUPSTR(_p, _s, _w) (_p = ao_strdup(_s)) + +static void * +ao_malloc(size_t sz); + +static void * +ao_realloc(void *p, size_t sz); + +#define ao_free(_p) free(VOIDP(_p)) + +static char * +ao_strdup(char const * str); + +/** + * DO option handling? + * + * Options are examined at two times: at immediate handling time and at + * normal handling time. If an option is disabled, the timing may be + * different from the handling of the undisabled option. The OPTST_DIABLED + * bit indicates the state of the currently discovered option. + * So, here's how it works: + * + * A) handling at "immediate" time, either 1 or 2: + * + * 1. OPTST_DISABLED is not set: + * IMM must be set + * DISABLE_IMM don't care + * TWICE don't care + * DISABLE_TWICE don't care + * 0 -and- 1 x x x + * + * 2. OPTST_DISABLED is set: + * IMM don't care + * DISABLE_IMM must be set + * TWICE don't care + * DISABLE_TWICE don't care + * 1 -and- x 1 x x + */ +#define DO_IMMEDIATELY(_flg) \ + ( (((_flg) & (OPTST_DISABLED|OPTST_IMM)) == OPTST_IMM) \ + || ( ((_flg) & (OPTST_DISABLED|OPTST_DISABLE_IMM)) \ + == (OPTST_DISABLED|OPTST_DISABLE_IMM) )) + +/** + * B) handling at "regular" time because it was not immediate + * + * 1. OPTST_DISABLED is not set: + * IMM must *NOT* be set + * DISABLE_IMM don't care + * TWICE don't care + * DISABLE_TWICE don't care + * 0 -and- 0 x x x + * + * 2. OPTST_DISABLED is set: + * IMM don't care + * DISABLE_IMM don't care + * TWICE must be set + * DISABLE_TWICE don't care + * 1 -and- x x 1 x + */ +#define DO_NORMALLY(_flg) ( \ + (((_flg) & (OPTST_DISABLED|OPTST_IMM)) == 0) \ + || (((_flg) & (OPTST_DISABLED|OPTST_DISABLE_IMM)) == \ + OPTST_DISABLED) ) + +/** + * C) handling at "regular" time because it is to be handled twice. + * The immediate bit was already tested and found to be set: + * + * 3. OPTST_DISABLED is not set: + * IMM is set (but don't care) + * DISABLE_IMM don't care + * TWICE must be set + * DISABLE_TWICE don't care + * 0 -and- ? x 1 x + * + * 4. OPTST_DISABLED is set: + * IMM don't care + * DISABLE_IMM is set (but don't care) + * TWICE don't care + * DISABLE_TWICE must be set + * 1 -and- x ? x 1 + */ +#define DO_SECOND_TIME(_flg) ( \ + (((_flg) & (OPTST_DISABLED|OPTST_TWICE)) == \ + OPTST_TWICE) \ + || (((_flg) & (OPTST_DISABLED|OPTST_DISABLE_TWICE)) == \ + (OPTST_DISABLED|OPTST_DISABLE_TWICE) )) + +/* + * text_mmap structure. Only active on platforms with mmap(2). + */ +#ifdef HAVE_SYS_MMAN_H +# include +#else +# ifndef PROT_READ +# define PROT_READ 0x01 +# endif +# ifndef PROT_WRITE +# define PROT_WRITE 0x02 +# endif +# ifndef MAP_SHARED +# define MAP_SHARED 0x01 +# endif +# ifndef MAP_PRIVATE +# define MAP_PRIVATE 0x02 +# endif +#endif + +#ifndef MAP_FAILED +# define MAP_FAILED VOIDP(-1) +#endif + +#ifndef _SC_PAGESIZE +# ifdef _SC_PAGE_SIZE +# define _SC_PAGESIZE _SC_PAGE_SIZE +# endif +#endif + +#ifndef HAVE_STRCHR +extern char * strchr(char const * s, int c); +extern char * strrchr(char const * s, int c); +#endif + +/** + * INQUERY_CALL() tests whether the option handling function has been + * called by an inquery (help text needed, or option being reset), + * or called by a set-the-option operation. + */ +#define INQUERY_CALL(_o, _d) ( \ + ((_o) <= OPTPROC_EMIT_LIMIT) \ + || ((_d) == NULL) \ + || (((_d)->fOptState & OPTST_RESET) != 0) ) + +/** + * Define and initialize all the user visible strings. + * We do not do translations. If translations are to be done, then + * the client will provide a callback for that purpose. + */ +#undef DO_TRANSLATIONS +#include "autoopts/usage-txt.h" + +/** + * File pointer for usage output + */ +FILE * option_usage_fp; +/** + * If provided in the option structure + */ +static char const * program_pkgdatadir; +/** + * privately exported functions + */ +extern tOptProc optionPrintVersion, optionPagedUsage, optionLoadOpt; + +#ifdef AUTOOPTS_INTERNAL + +#ifndef PKGDATADIR +# define PKGDATADIR "" +#endif +#define APOSTROPHE '\'' + +#define OPTPROC_L_N_S (OPTPROC_LONGOPT | OPTPROC_SHORTOPT) +#if defined(ENABLE_NLS) && defined(HAVE_LIBINTL_H) +# include +#endif + +typedef struct { + size_t fnm_len; + uint32_t fnm_mask; + char const * fnm_name; +} ao_flag_names_t; + +/** + * Automated Options Usage Flags. + * NB: no entry may be a prefix of another entry + */ +#define AOFLAG_TABLE \ + _aof_(gnu, OPTPROC_GNUUSAGE ) \ + _aof_(autoopts, ~OPTPROC_GNUUSAGE) \ + _aof_(no_misuse_usage, OPTPROC_MISUSE ) \ + _aof_(misuse_usage, ~OPTPROC_MISUSE ) \ + _aof_(compute, OPTPROC_COMPUTE ) + +#define _aof_(_n, _f) AOUF_ ## _n ## _ID, +typedef enum { AOFLAG_TABLE AOUF_COUNT } ao_flag_id_t; +#undef _aof_ + +#define _aof_(_n, _f) AOUF_ ## _n = (1 << AOUF_ ## _n ## _ID), +typedef enum { AOFLAG_TABLE } ao_flags_t; +#undef _aof_ + +static char const zNil[] = ""; +static arg_types_t argTypes = { NULL }; +static char line_fmt_buf[32]; +static bool displayEnum = false; +static char const pkgdatadir_default[] = PKGDATADIR; +static char const * program_pkgdatadir = pkgdatadir_default; +static tOptionLoadMode option_load_mode = OPTION_LOAD_UNCOOKED; +static tePagerState pagerState = PAGER_STATE_INITIAL; + +static noreturn void option_exits(int exit_code); +static noreturn void fserr_exit(char const * prog, char const * op, + char const * fname); +static void fserr_warn(char const * prog, char const * op, + char const * fname); +static noreturn void ao_bug(char const * msg); + + FILE * option_usage_fp = NULL; + +static char const * pz_enum_err_fmt; + +tOptions * optionParseShellOptions = NULL; + +static char const * shell_prog = NULL; +static char * script_leader = NULL; +static char * script_trailer = NULL; +static char * script_text = NULL; +static bool print_exit = false; +#endif /* AUTOOPTS_INTERNAL */ + +#endif /* AUTOGEN_AUTOOPTS_H */ +/** + * @} + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of autoopts/autoopts.h */ diff --git a/autoopts/autoopts.m4 b/autoopts/autoopts.m4 new file mode 100644 index 0000000..065f4c3 --- /dev/null +++ b/autoopts/autoopts.m4 @@ -0,0 +1,223 @@ +dnl -*- Mode: M4 -*- +dnl -------------------------------------------------------------------- +dnl autoopts.m4 --- Configure paths for autoopts +dnl +dnl Author: Gary V. Vaughan +dnl This file is part of AutoOpts, a companion to AutoGen. +dnl AutoOpts is free software. +dnl AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +dnl +dnl AutoOpts is available under any one of two licenses. The license +dnl in use must be one of these two and the choice is under the control +dnl of the user of the license. +dnl +dnl The GNU Lesser General Public License, version 3 or later +dnl See the files "COPYING.lgplv3" and "COPYING.gplv3" +dnl +dnl The Modified Berkeley Software Distribution License +dnl See the file "COPYING.mbsd" +dnl +dnl These files have the following sha256 sums: +dnl +dnl 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +dnl 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +dnl 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd +dnl -------------------------------------------------------------------- +dnl Code: + +# serial 1 + +dnl AG_PATH_AUTOOPTS([MIN-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]]) +dnl Test for AUTOOPTS, and define AUTOGEN, AUTOOPTS_CFLAGS, AUTOGEN_LDFLAGS +dnl and AUTOOPTS_LIBS. +dnl +AC_DEFUN([AG_PATH_AUTOOPTS], +[dnl Get the cflags and libraries from the autoopts-config script +AC_ARG_WITH(opts-prefix, +[ --with-opts-prefix=PFX Prefix where autoopts is installed (optional)]) + +AC_ARG_WITH(opts-exec-prefix, +[ --with-opts-exec-prefix=PFX + Exec prefix where autoopts is installed (optional)]) + +AC_ARG_ENABLE(opts-test, +[ --disable-opts-test Do not try to run a test AutoOpts program]) + + if test x$with_opts_exec_prefix != x ; then + aocfg_args="$aocfg_args --exec-prefix=$with_opts_exec_prefix" + if test x${AUTOOPTS_CONFIG+set} != xset ; then + AUTOOPTS_CONFIG=$with_opts_exec_prefix/bin/autoopts-config + fi + fi + if test x$with_opts_prefix != x ; then + aocfg_args="$aocfg_args --prefix=$with_opts_prefix" + if test x${AUTOOPTS_CONFIG+set} != xset ; then + AUTOOPTS_CONFIG=$with_opts_prefix/bin/autoopts-config + fi + fi + if test -n "$AUTOOPTS_CONFIG"; then + : + else + AC_PATH_PROG(AUTOOPTS_CONFIG, autoopts-config, no) + fi + AC_MSG_CHECKING(for compatible autoopts version)[ + no_autoopts="" + if test "$AUTOOPTS_CONFIG" = "no" ; then + no_autoopts=yes + else + AUTOGEN=`$AUTOOPTS_CONFIG $aocfg_args --autogen` + AUTOOPTS_CFLAGS=`$AUTOOPTS_CONFIG $aocfg_args --cflags` + AUTOGEN_LDFLAGS=`$AUTOOPTS_CONFIG $aocfg_args --pkgdatadir` + AUTOOPTS_LIBS=`$AUTOOPTS_CONFIG $aocfg_args --libs` + aocfg_version=`$AUTOOPTS_CONFIG $aocfg_args --version` + save_IFS=$IFS + IFS=' :' + set -- $aocfg_version + IFS=$save_IFS + aocfg_current=$1 + aocfg_revision=$2 + aocfg_age=$3 + aocfg_currev=$1.$2 + if test "x$enable_opts_test" != "xno" ; then + AC_LANG_SAVE + AC_LANG_C + ac_save_CFLAGS="$CFLAGS" + ac_save_LDFLAGS="$LDFLAGS" + ac_save_LIBS="$LIBS" + CFLAGS="$CFLAGS $AUTOOPTS_CFLAGS" + LDFLAGS="$LDFLAGS $AUTOOPTS $CFLAGS" + LIBS="$LIBS $AUTOOPTS_LIBS"] + dnl + dnl Now check if the installed AUTOOPTS is sufficiently new. (Also + dnl sanity checks the results of autoopts-config to some extent. + dnl + rm -f confopts.def conf.optstest + AC_TRY_RUN([ +#include +#include +#include +#include +#ifndef OPTIONS_VER_TO_NUM +#define OPTIONS_VER_TO_NUM(_v, _r) (((_v) * 4096) + (_r)) +#endif + +static char const zBadVer[] = "\n\\ +*** 'autoopts-config --version' returned $aocfg_version,\n\\ +*** but autoopts returned %d:%d:0\n\\ +*** and the header file says %s\n\\ +*** These should all be consistent.\n\n\\ +*** If autoopts-config was correct, then it is best to remove the old version\n\\ +*** of autoopts. You may also be able to fix the error by modifying your\n\\ +*** LD_LIBRARY_PATH enviroment variable, or by editing /etc/ld.so.conf.\n\\ +*** Make sure you have run ldconfig if that is required on your system.\n\\ +*** Otherwise, set the environment variable AUTOOPTS_CONFIG to point to\n\\ +*** the correct copy of autoopts-config, and remove the file config.cache\n\\ +*** before re-running configure.\n"; + +int +main (int argc, char ** argv) +{ + int current, revision, ct; + char tmp_version[256]; + + system ("touch conf.optstest"); + + /* + * Test liked library against header file + */ + strcpy(tmp_version, optionVersion()); + ct = sscanf(tmp_version, "%d.%d", ¤t, &revision); + if (ct != 2) { + printf("bad version string: -->>%s<<-- != -->>$aocfg_currev<<--\n", + optionVersion()); + return 1; + } + + if (OPTIONS_VER_TO_NUM(current, revision) != OPTIONS_STRUCT_VERSION) { + printf(zBadVer, current, revision, OPTIONS_VERSION_STRING); + return 1; + } + + /* + * Test autoopts-config against header version + */ + if ( OPTIONS_VER_TO_NUM($aocfg_current, $aocfg_revision) + != OPTIONS_STRUCT_VERSION) { + printf("*** autoopts header file version "OPTIONS_VERSION_STRING"\n" + "*** does not match autoopts-config value $aocfg_version\n" + "*** library version is %d:%d\n", current, revision); + return 1; + } + + return 0; +} +],, no_autoopts=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"]) + CFLAGS="$ac_save_CFLAGS" + LDFLAGS="$ac_save_LDFLAGS" + LIBS="$ac_save_LIBS" + AC_LANG_RESTORE + fi + fi + + if test "x$no_autoopts" = x ; then + AC_MSG_RESULT(yes) + ifelse([$2], , :, [$2]) + else + AC_MSG_RESULT(no) + if test "$AUTOOPTS_CONFIG" = "no" ; then + cat <<- _EOF_ + *** The autoopts-config script installed by AutoGen could not be found + *** If AutoGen was installed in PREFIX, make sure PREFIX/bin is in + *** your path, or set the AUTOOPTS_CONFIG environment variable to the + *** full path to autoopts-config. + _EOF_ + else + if test -f conf.optstest ; then + : + else + echo "*** Could not run autoopts test program, checking why..." + CFLAGS="$CFLAGS $AUTOOPTS_CFLAGS" + LIBS="$LIBS $AUTOOPTS_LIBS" + AC_LANG_SAVE + AC_LANG_C + AC_TRY_LINK([ +#include +#include +], [return strcmp("$aocfg_current:$aocfg_revision:$aocfg_age", optionVersion());], + [ cat << _EOF_ +*** The test program compiled, but did not run. This usually means that +*** the run-time linker is not finding libopts or finding the wrong version +*** of libopts. If it is not finding libopts, you'll need to set your +*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point +*** to the installed location Also, make sure you have run ldconfig if that +*** is required on your system +*** +*** If you have an old version installed, it is best to remove it, although +*** you may also be able to get things to work by modifying LD_LIBRARY_PATH +_EOF_ +], [cat << _EOF_ +*** The test program failed to compile or link. See the file config.log for +*** the exact error that occured. This usually means AutoGen was incorrectly +*** installed or that you have moved libopts since it was installed. In the +*** latter case, you may want to edit the autoopts-config script: +*** $AUTOOPTS_CONFIG +_EOF_ +]) + CFLAGS="$ac_save_CFLAGS" + LIBS="$ac_save_LIBS" + AC_LANG_RESTORE + fi + fi + AUTOGEN=: + AUTOOPTS_CFLAGS="" + AUTOOPTS_LIBS="" + ifelse([$3], , :, [$3]) + fi + AC_SUBST(AUTOGEN) + AC_SUBST(AUTOOPTS_CFLAGS) + AC_SUBST(AUTOGEN_LDFLAGS) + AC_SUBST(AUTOOPTS_LIBS) + rm -f confopts.def conf.optstest +]) +dnl +dnl autoopts.m4 ends here diff --git a/autoopts/autoopts/options.h b/autoopts/autoopts/options.h new file mode 100644 index 0000000..08dc546 --- /dev/null +++ b/autoopts/autoopts/options.h @@ -0,0 +1,1263 @@ +/* -*- buffer-read-only: t -*- vi: set ro: + * + * DO NOT EDIT THIS FILE (options.h) + * + * It has been AutoGen-ed + * From the definitions funcs.def + * and the template file options_h + * + * This file defines all the global structures and special values + * used in the automated option processing library. + * + * Automated Options Copyright (C) 1992-2018 by Bruce Korb + * + * This file is part of AutoOpts, a companion to AutoGen. + * AutoOpts is free software. + * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoOpts is available under any one of two licenses. The license + * in use must be one of these two and the choice is under the control + * of the user of the license. + * + * The GNU Lesser General Public License, version 3 or later + * See the files "COPYING.lgplv3" and "COPYING.gplv3" + * + * The Modified Berkeley Software Distribution License + * See the file "COPYING.mbsd" + * + * These files have the following sha256 sums: + * + * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 + * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 + * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + */ +#ifndef AUTOOPTS_OPTIONS_H_GUARD +#define AUTOOPTS_OPTIONS_H_GUARD 1 +/** \file options.h + * + * @addtogroup autoopts + * @{ + */ +#include +#include + +#ifndef COMPAT_H_GUARD +/* + * This is needed for test compilations where the "compat.h" + * header is not usually available. + */ +# if defined(HAVE_STDINT_H) +# include +# elif defined(HAVE_INTTYPES_H) +# include +# endif /* HAVE_STDINT/INTTYPES_H */ + +# if defined(HAVE_LIMITS_H) +# include +# elif defined(HAVE_SYS_LIMITS_H) +# include +# endif /* HAVE_LIMITS/SYS_LIMITS_H */ + +# if defined(HAVE_SYSEXITS_H) +# include +# endif /* HAVE_SYSEXITS_H */ + +# if defined(HAVE_STDBOOL_H) +# include +# elif ! defined(bool) + typedef enum { false = 0, true = 1 } _Bool; +# define bool _Bool + + /* The other macros must be usable in preprocessor directives. */ +# define false 0 +# define true 1 +# endif /* HAVE_SYSEXITS_H */ +#endif /* COMPAT_H_GUARD */ +// END-CONFIGURED-HEADERS + +/** + * Defined to abnormal value of EX_USAGE. Used to indicate that paged usage + * was requested. It is used to distinguish a --usage from a --help request. + * --usage is abbreviated and --help gives as much help as possible. + */ +#define AO_EXIT_REQ_USAGE 10064 + +#undef VOIDP +/** + * Coerce a value into a void pointer with no const or volatile attributes. + * Somewhere along the line, the above set of includes need to set up + * the "uintptr_t" type. + */ +#define VOIDP(_a) ((void *)(uintptr_t)(_a)) + +/** + * PUBLIC DEFINES + * + * The following defines may be used in applications that need to test the + * state of an option. To test against these masks and values, a pointer + * to an option descriptor must be obtained. There are two ways: + * + * 1. inside an option processing procedure, it is the second argument, + * conventionally "tOptDesc * pOD". + * + * 2. Outside of an option procedure (or to reference a different option + * descriptor), use either "&DESC( opt_name )" or "&pfx_DESC( opt_name )". + * + * See the relevant generated header file to determine which and what + * values for "opt_name" are available. + * @group version + * @{ + */ +/// autoopts structure version +#define OPTIONS_STRUCT_VERSION 172033 +/// autoopts structure version string +#define OPTIONS_VERSION_STRING "42:1:17" +/// minimum version the autoopts library supports +#define OPTIONS_MINIMUM_VERSION 102400 +/// minimum version the autoopts library supports as a string +#define OPTIONS_MIN_VER_STRING "25:0:0" +/// the display version of the autoopts library, as a string +#define OPTIONS_DOTTED_VERSION "42.1" +/// convert a version/release number pair to an integer value +#define OPTIONS_VER_TO_NUM(_v, _r) (((_v) * 4096) + (_r)) +/// @} + +/** + * Option argument types. This must fit in the OPTST_ARG_TYPE_MASK + * field of the fOptState field of an option descriptor (tOptDesc). + * It will be a problem to extend beyond 4 bits. + */ +typedef enum { + OPARG_TYPE_NONE = 0, ///< does not take an argument + OPARG_TYPE_STRING = 1, ///< default type/ vanilla string + OPARG_TYPE_ENUMERATION = 2, ///< opt arg is an enum (keyword list) + OPARG_TYPE_BOOLEAN = 3, ///< opt arg is boolean-valued + OPARG_TYPE_MEMBERSHIP = 4, ///< opt arg sets set membership bits + OPARG_TYPE_NUMERIC = 5, ///< opt arg is a long int + OPARG_TYPE_HIERARCHY = 6, ///< option arg is hierarchical value + OPARG_TYPE_FILE = 7, ///< option arg names a file + OPARG_TYPE_TIME = 8, ///< opt arg is a time duration + OPARG_TYPE_FLOAT = 9, ///< opt arg is a floating point num + OPARG_TYPE_DOUBLE = 10, ///< opt arg is a double prec. float + OPARG_TYPE_LONG_DOUBLE = 11, ///< opt arg is a long double prec. + OPARG_TYPE_LONG_LONG = 12, ///< opt arg is a long long int + OPARG_TYPE_STATIC = 13 ///< +} teOptArgType; + +/** + * value descriptor for sub options + */ +typedef struct optionValue { + teOptArgType valType; ///< which argument type + char * pzName; ///< name of the sub-option + union { + char strVal[1]; ///< OPARG_TYPE_STRING + unsigned int enumVal; ///< OPARG_TYPE_ENUMERATION + unsigned int boolVal; ///< OPARG_TYPE_BOOLEAN + unsigned long setVal; ///< OPARG_TYPE_MEMBERSHIP + long longVal; ///< OPARG_TYPE_NUMERIC + void * nestVal; ///< OPARG_TYPE_HIERARCHY + } v; +} tOptionValue; + +/** + * file argument state and handling. + */ +typedef enum { + FTYPE_MODE_MAY_EXIST = 0x00, ///< may or may not exist + FTYPE_MODE_MUST_EXIST = 0x01, ///< must pre-exist + FTYPE_MODE_MUST_NOT_EXIST = 0x02, ///< must *not* pre-exist + FTYPE_MODE_EXIST_MASK = 0x03, ///< mask for these bits + FTYPE_MODE_NO_OPEN = 0x00, ///< leave file closed + FTYPE_MODE_OPEN_FD = 0x10, ///< call open(2) + FTYPE_MODE_FOPEN_FP = 0x20, ///< call fopen(3) + FTYPE_MODE_OPEN_MASK = 0x30 ///< open/fopen/not open +} teOptFileType; + +/** + * the open flag bits or the mode string, depending on the open type. + */ +typedef union { + int file_flags; ///< open(2) flag bits + char const * file_mode; ///< fopen(3) mode string +} tuFileMode; + +/// initial number of option argument holders to allocate +#define MIN_ARG_ALLOC_CT 6 +/// amount by which to increment the argument holder allocation. +#define INCR_ARG_ALLOC_CT 8 +/** + * an argument list. When an option appears multiple times and + * the values get "stacked". \a apzArgs holds 8 pointers initially + * and is incremented by \a INCR_ARG_ALLOC_CT as needed. + */ +typedef struct { + int useCt; ///< elements in use + + /// allocated elements, mininum \a MIN_ARG_ALLOC_CT + /// steps by \a INCR_ARG_ALLOC_CT + int allocCt; + char const * apzArgs[MIN_ARG_ALLOC_CT]; ///< element array +} tArgList; + +/** + * Bits in the fOptState option descriptor field. + * @{ + */ + +/** integral type for holding opt_state masks */ +typedef uint32_t opt_state_mask_t; + +#define OPTST_ARG_TYPE_SHIFT 12 +/** bits defined for opt_state_mask_t */ +/** Set via the "SET_OPT()" macro */ +#define OPTST_SET 0x0000001U +/** Set via an RC/INI file */ +#define OPTST_PRESET 0x0000002U +/** Set via a command line option */ +#define OPTST_DEFINED 0x0000004U +/** Reset via command line option */ +#define OPTST_RESET 0x0000008U +/** selected by equiv'ed option */ +#define OPTST_EQUIVALENCE 0x0000010U +/** option is in disabled state */ +#define OPTST_DISABLED 0x0000020U +/** pzOptArg was allocated */ +#define OPTST_ALLOC_ARG 0x0000040U +/** option cannot be preset */ +#define OPTST_NO_INIT 0x0000100U +/** opt value (flag) is any digit */ +#define OPTST_NUMBER_OPT 0x0000200U +/** opt uses optionStackArg proc */ +#define OPTST_STACKED 0x0000400U +/** option defaults to enabled */ +#define OPTST_INITENABLED 0x0000800U +/** bit 1 of arg type enum */ +#define OPTST_ARG_TYPE_1 0x0001000U +/** bit 2 of arg type enum */ +#define OPTST_ARG_TYPE_2 0x0002000U +/** bit 3 of arg type enum */ +#define OPTST_ARG_TYPE_3 0x0004000U +/** bit 4 of arg type enum */ +#define OPTST_ARG_TYPE_4 0x0008000U +/** the option arg not required */ +#define OPTST_ARG_OPTIONAL 0x0010000U +/** process opt on first pass */ +#define OPTST_IMM 0x0020000U +/** process disablement immed. */ +#define OPTST_DISABLE_IMM 0x0040000U +/** compiled out of program */ +#define OPTST_OMITTED 0x0080000U +/** must be set or pre-set */ +#define OPTST_MUST_SET 0x0100000U +/** opt is for doc only */ +#define OPTST_DOCUMENT 0x0200000U +/** process opt twice - imm + reg */ +#define OPTST_TWICE 0x0400000U +/** process disabled option twice */ +#define OPTST_DISABLE_TWICE 0x0800000U +/** scaled integer value */ +#define OPTST_SCALED_NUM 0x1000000U +/** disable from cmd line */ +#define OPTST_NO_COMMAND 0x2000000U +/** support is being removed */ +#define OPTST_DEPRECATED 0x4000000U +/** alias for other option */ +#define OPTST_ALIAS 0x8000000U + +/** bits in SET mask: + * set preset reset defined */ +#define OPTST_SET_MASK 0x000000FU + +/** bits in MUTABLE mask: + * set preset reset defined equivalence disabled + * alloc_arg */ +#define OPTST_MUTABLE_MASK 0x000007FU + +/** bits omitted from PERSISTENT mask: + * mutable_mask */ +#define OPTST_PERSISTENT_MASK 0xFFFFF00U + +/** bits in SELECTED mask: + * set defined */ +#define OPTST_SELECTED_MASK 0x0000005U + +/** bits in ARG_TYPE mask: + * arg_type_1 arg_type_2 arg_type_3 arg_type_4 */ +#define OPTST_ARG_TYPE_MASK 0x000F000U + +/** bits in NO_USAGE mask: + * omitted no_command deprecated */ +#define OPTST_NO_USAGE_MASK 0x6080000U + +/** bits in IMMUTABLE mask: + * document omitted */ +#define OPTST_IMMUTABLE_MASK 0x0280000U + +/** bits in DO_NOT_SAVE mask: + * document omitted no_init */ +#define OPTST_DO_NOT_SAVE_MASK 0x0280100U + +/** bits in NO_OUTPUT mask: + * document omitted alias */ +#define OPTST_NO_OUTPUT_MASK 0x8280000U + +/** all bits in opt_state_mask_t masks */ +#define OPTST_MASK_ALL 0xFFFFF7FU + +/** no bits in opt_state_mask_t */ +#define OPTST_INIT 0x0000000U +/** @} */ + +#ifdef NO_OPTIONAL_OPT_ARGS +# undef OPTST_ARG_OPTIONAL +# define OPTST_ARG_OPTIONAL 0 +#endif + +#define VENDOR_OPTION_VALUE 'W' + +#define SELECTED_OPT(_od) ((_od)->fOptState & OPTST_SELECTED_MASK) +#define UNUSED_OPT( _od) (((_od)->fOptState & OPTST_SET_MASK) == 0) +#define DISABLED_OPT(_od) ((_od)->fOptState & OPTST_DISABLED) +#define OPTION_STATE(_od) ((_od)->fOptState) +#define OPTST_SET_ARGTYPE(_n) ((_n) << OPTST_ARG_TYPE_SHIFT) +#define OPTST_GET_ARGTYPE(_f) \ + (((_f)&OPTST_ARG_TYPE_MASK) >> OPTST_ARG_TYPE_SHIFT) + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * PRIVATE INTERFACES + * + * The following values are used in the generated code to communicate + * with the option library procedures. They are not for public use + * and may be subject to change. + */ + +/** + * Define the processing state flags + * @{ + */ + +/** integral type for holding proc_state masks */ +typedef uint32_t proc_state_mask_t; + +/** bits defined for proc_state_mask_t */ +/** Process long style options */ +#define OPTPROC_LONGOPT 0x000001U +/** Process short style "flags" */ +#define OPTPROC_SHORTOPT 0x000002U +/** Stop on argument errors */ +#define OPTPROC_ERRSTOP 0x000004U +/** Current option is disabled */ +#define OPTPROC_DISABLEDOPT 0x000008U +/** no options are required */ +#define OPTPROC_NO_REQ_OPT 0x000010U +/** there is a number option */ +#define OPTPROC_NUM_OPT 0x000020U +/** have inits been done? */ +#define OPTPROC_INITDONE 0x000040U +/** any negation options? */ +#define OPTPROC_NEGATIONS 0x000080U +/** check environment? */ +#define OPTPROC_ENVIRON 0x000100U +/** Disallow remaining arguments */ +#define OPTPROC_NO_ARGS 0x000200U +/** Require args after options */ +#define OPTPROC_ARGS_REQ 0x000400U +/** reorder operands after opts */ +#define OPTPROC_REORDER 0x000800U +/** emit usage in GNU style */ +#define OPTPROC_GNUUSAGE 0x001000U +/** Translate strings in tOptions */ +#define OPTPROC_TRANSLATE 0x002000U +/** no usage on usage error */ +#define OPTPROC_MISUSE 0x004000U +/** immediate options active */ +#define OPTPROC_IMMEDIATE 0x008000U +/** suppress for config only */ +#define OPTPROC_NXLAT_OPT_CFG 0x010000U +/** suppress xlation always */ +#define OPTPROC_NXLAT_OPT 0x020000U +/** vendor options active */ +#define OPTPROC_VENDOR_OPT 0x040000U +/** opt processing in preset state */ +#define OPTPROC_PRESETTING 0x080000U +/** Ignore pzFullUsage, compute usage text */ +#define OPTPROC_COMPUTE 0x100000U +/** Program outputs digested option state for shell scripts. Usage text + * always written to stderr */ +#define OPTPROC_SHELL_OUTPUT 0x200000U + +/** bits in NO_XLAT mask: + * nxlat_opt_cfg nxlat_opt */ +#define OPTPROC_NO_XLAT_MASK 0x030000U + +/** all bits in proc_state_mask_t masks */ +#define OPTPROC_MASK_ALL 0x3FFFFFU + +/** no bits in proc_state_mask_t */ +#define OPTPROC_NONE 0x000000U +/** @} */ + +#define STMTS(s) do { s; } while (false) + +/** + * Abbreviation for const memory character. + */ +#define tCC char const + +/** + * Magical values for the program's option pointer + * @{ + */ +typedef enum { + OP_VAL_EMIT_USAGE = 1, ///< request for usage + OP_VAL_EMIT_SHELL = 2, ///< emit value for Bourne shell evaluation + OP_VAL_RETURN_VALNAME = 3, ///< return the value as a string + OP_VAL_EMIT_LIMIT = 15 ///< limit for magic values +} opt_proc_vals_t; + +/// \a OPT_VAL_EMIT_USAGE cast as a pointer +#define OPTPROC_EMIT_USAGE ((tOptions *)OP_VAL_EMIT_USAGE) + +/// \a OPT_VAL_EMIT_SHELL cast as a pointer +#define OPTPROC_EMIT_SHELL ((tOptions *)OP_VAL_EMIT_SHELL) + +/// \a OPT_VAL_RETURN_VALNAME cast as a pointer +#define OPTPROC_RETURN_VALNAME ((tOptions *)OP_VAL_RETURN_VALNAME) + +/// \a OPT_VAL_EMIT_LIMIT cast as a pointer +#define OPTPROC_EMIT_LIMIT ((tOptions *)OP_VAL_EMIT_LIMIT) +/** @} */ + +/** group option processing procedure types + * @{ + */ +/** forward declaration for tOptDesc */ +typedef struct opt_desc tOptDesc; +/** forward declaration for tOptiond */ +typedef struct options tOptions; + +/** + * The option procedures do the special processing for each + * option flag that needs it. + */ +typedef void (tOptProc)(tOptions * pOpts, tOptDesc * pOptDesc); + +/** + * a pointer to an option processing procedure + */ +typedef tOptProc * tpOptProc; + +/** + * The usage procedure will never return. It calls "exit(2)" + * with the "exitCode" argument passed to it. + */ +// coverity[+kill] +typedef void (tUsageProc)(tOptions * pOpts, int exitCode); + +/** + * a pointer to a procedure that prints usage and exits. + */ +typedef tUsageProc * tpUsageProc; +/** @} */ + +/** + * Special definitions. "NOLIMIT" is the 'max' value to use when + * a flag may appear multiple times without limit. "NO_EQUIVALENT" + * is an illegal value for 'optIndex' (option description index). + * @{ + */ +#define NOLIMIT USHRT_MAX ///< no occurrance count limit +#define OPTION_LIMIT SHRT_MAX ///< maximum number of option types +/// option index to indicate no equivalance or alias +#define NO_EQUIVALENT (OPTION_LIMIT+1) +/** @} */ + +/** + * Option argument value. Which is valid is determined by: + * (fOptState & OPTST_ARG_TYPE_MASK) >> OPTST_ARG_TYPE_SHIFT + * which will yield one of the teOptArgType values. + */ +typedef union { + char const * argString; ///< as a string + uintptr_t argEnum; ///< as an enumeration value + uintptr_t argIntptr; ///< as an integer big enough to hold pointer + long argInt; ///< as a long integer + unsigned long argUint; ///< as an unsigned long ingeger + unsigned int argBool; ///< as a boolean value + FILE * argFp; ///< as a FILE * pointer + int argFd; ///< as a file descriptor (int) +} opt_arg_union_t; + +/// Compatibility define: \a pzLastArg is now \a optArg.argString +#define pzLastArg optArg.argString +/// The old amorphous argument bucket is now the opt_arg_union_t union. +#define optArgBucket_t opt_arg_union_t + +/** + * Enumeration of AutoOpts defined options. The enumeration is used in + * marking each option that is defined by AutoOpts so libopts can find + * the correct descriptor. This renders \a option_spec_idx_t redundant. + */ +typedef enum { + AOUSE_USER_DEFINED = 0, ///< user specified option + AOUSE_RESET_OPTION, ///< reset option state option + AOUSE_VERSION, ///< request version + AOUSE_HELP, ///< request usage help + AOUSE_MORE_HELP, ///< request paged usage + AOUSE_USAGE, ///< request short usage + AOUSE_SAVE_OPTS, ///< save option state + AOUSE_LOAD_OPTS, ///< load options from file + AOUSE_VENDOR_OPT ///< specify a vendor option +} opt_usage_t; + +/** + * Descriptor structure for each option. + * Only the fields marked "PUBLIC" are for public use. + */ +struct opt_desc { + /// Public, the index of this descriptor + uint16_t const optIndex; + /// Public, the flag character (value) + uint16_t const optValue; + /// Public, the index of the option used to activate option + uint16_t optActualIndex; + /// Public, the flag character of the activating option + uint16_t optActualValue; + + /// Public, the index of the equivalenced-to option. + /// This is NO_EQUIVALENT unless activated. + uint16_t const optEquivIndex; + /// Private, the minimum occurrance count + uint16_t const optMinCt; + /// Private, the maximum occurrance count (NOLIMIT, if unlimited) + uint16_t const optMaxCt; + /// Public, the actual occurrance count + uint16_t optOccCt; + + /// Public, the option processing state + opt_state_mask_t fOptState; + /// Private, how the option is used (opt_usage_t) + uint32_t optUsage; + /// Public, The current option argument value + opt_arg_union_t optArg; + /// Public, data that is actually private to the code that handles + /// this particular option. It is public IFF you have your own + /// handling function. + void * optCookie; + + /// Private, a list of options that must be specified when this option + /// has been specified + int const * const pOptMust; + + /// Private, a list of options that cannot be specified when this option + /// has been specified + int const * const pOptCant; + + /// Private, the function to call for handling this option + tpOptProc const pOptProc; + + /// Private, usage information about this option + char const * const pzText; + + /// Public, the UPPER CASE, shell variable name syntax name of the option + char const * const pz_NAME; + + /// the unmodified name of the option + char const * const pz_Name; + + /// the option name to use to disable the option. Long options names + /// must be active. + char const * const pz_DisableName; + + /// the special prefix that makes the normal option name become the + /// disablement name. + char const * const pz_DisablePfx; +}; + +/** + * Some options need special processing, so we store their + * indexes in a known place. + */ +typedef struct { + uint16_t const more_help; ///< passes help text through pager + uint16_t const save_opts; ///< stores option state to a file + uint16_t const number_option; ///< the option "name" is an integer + /// all arguments are options, this is the default option that must + /// take an argument. That argument is the unrecognized option. + uint16_t const default_opt; +} option_spec_idx_t; + +/** + * The procedure generated for translating option text + */ +typedef void (tOptionXlateProc)(void); + +/** + * Everything marked "PUBLIC" is also marked "const". Public access is not + * a license to modify. Other fields are used and modified by the library. + * They are also subject to change without any notice. + * Do not even look at these outside of libopts. + */ +struct options { + int const structVersion; ///< The version of this struct + unsigned int origArgCt; ///< program argument count + char ** origArgVect; ///< program argument vector + proc_state_mask_t fOptSet; ///< option proc. state flags + unsigned int curOptIdx; ///< current option index + char * pzCurOpt; ///< current option text + + /// Public, the full path of the program + char const * const pzProgPath; + /// Public, the name of the executable, without any path + char const * const pzProgName; + /// Public, the upper-cased, shell variable syntax-ed program name + char const * const pzPROGNAME; + /// the name of the "rc file" (configuration file) + char const * const pzRcName; + /// the copyright text + char const * const pzCopyright; + /// the full copyright notice + char const * const pzCopyNotice; + /// a string with the program name, project name and version + char const * const pzFullVersion; + /// a list of pointers to directories to search for the config file + char const * const * const papzHomeList; + /// the title line for usage + char const * const pzUsageTitle; + /// some added explanation for what this program is trying to do + char const * const pzExplain; + /// a detailed explanation of the program's purpose, for use when + /// full help has been requested + char const * const pzDetail; + /// The public array of option descriptors + tOptDesc * const pOptDesc; + /// the email address for reporting bugs + char const * const pzBugAddr; + + /// Reserved for future use + void * pExtensions; + /// A copy of the option state when optionSaveState was called. + void * pSavedState; + + /// The procedure to call to print usage text + /* __attribute__((__noreturn__)) */ + // coverity[+kill] + tpUsageProc pUsageProc; + /// The procedure to call to translate translatable option messages + tOptionXlateProc * pTransProc; + + /// Special option indexes. + option_spec_idx_t specOptIdx; + /// the total number of options for the program + int const optCt; + /// The number of "presettable" options, though some may be marked + /// "no-preset". Includes all user specified options, plus a few + /// that are specified by AutoOpts. + int const presetOptCt; + /// user specified full usage text + char const * pzFullUsage; + /// user specifed short usage (usage error triggered) message + char const * pzShortUsage; + /// The option argument settings active when optionSaveState was called + opt_arg_union_t const * const originalOptArgArray; + /// any saved cookie value + void * const * const originalOptArgCookie; + /// the package data directory (e.g. global configuration files) + char const * const pzPkgDataDir; + /// email address of the project packager + char const * const pzPackager; +}; + +/* + * Versions where in various fields first appear: + * ($AO_CURRENT * 4096 + $AO_REVISION, but $AO_REVISION must be zero) + */ +/** + * The version that first stored the original argument vector + */ +#define originalOptArgArray_STRUCT_VERSION 0x20000 /* AO_CURRENT = 32 */ +#define HAS_originalOptArgArray(_opt) \ + ((_opt)->structVersion >= originalOptArgArray_STRUCT_VERSION) + +/** + * The version that first stored the package data directory + */ +#define pzPkgDataDir_STRUCT_VERSION 0x22000 /* AO_CURRENT = 34 */ +#define HAS_pzPkgDataDir(_opt) \ + ((_opt)->structVersion >= pzPkgDataDir_STRUCT_VERSION) + +/** + * The version that first stored the option usage in each option descriptor + */ +#define opt_usage_t_STRUCT_VERSION 0x26000 /* AO_CURRENT = 38 */ +#define HAS_opt_usage_t(_opt) \ + ((_opt)->structVersion >= opt_usage_t_STRUCT_VERSION) + +/** + * "token list" structure returned by "string_tokenize()" + */ +typedef struct { + unsigned long tkn_ct; ///< number of tokens found + unsigned char * tkn_list[1]; ///< array of pointers to tokens +} token_list_t; + +/* + * Hide the interface - it pollutes a POSIX claim, but leave it for + * anyone #include-ing this header + */ +#define strneqvcmp option_strneqvcmp +#define streqvcmp option_streqvcmp +#define streqvmap option_streqvmap +#define strequate option_strequate +#define strtransform option_strtransform + +/** + * Everything needed to be known about an mmap-ed file. + * + * This is an output only structure used by text_mmap and text_munmap. + * Clients must not alter the contents and must provide it to both + * the text_mmap and text_munmap procedures. BE ADVISED: if you are + * mapping the file with PROT_WRITE the NUL byte at the end MIGHT NOT + * BE WRITABLE. In any event, that byte is not be written back + * to the source file. ALSO: if "txt_data" is valid and "txt_errno" + * is not zero, then there *may* not be a terminating NUL. + */ +typedef struct { + void * txt_data; ///< text file data + size_t txt_size; ///< actual file size + size_t txt_full_size; ///< mmaped mem size + int txt_fd; ///< file descriptor + int txt_zero_fd; ///< fd for /dev/zero + int txt_errno; ///< warning code + int txt_prot; ///< "prot" flags + int txt_flags; ///< mapping type +} tmap_info_t; + +/** + * mmap result wrapper that yields "true" when mmap has failed. + */ +#define TEXT_MMAP_FAILED_ADDR(a) (VOIDP(a) == VOIDP(MAP_FAILED)) + +#ifdef __cplusplus +#define CPLUSPLUS_OPENER extern "C" { +CPLUSPLUS_OPENER +#define CPLUSPLUS_CLOSER } +#else +#define CPLUSPLUS_CLOSER +#endif + +/** + * The following routines may be coded into AutoOpts client code: + */ + +/** + * ao_string_tokenize - tokenize an input string + * + * This function will convert one input string into a list of strings. + * The list of strings is derived by separating the input based on + * white space separation. However, if the input contains either single + * or double quote characters, then the text after that character up to + * a matching quote will become the string in the list. + * + * The returned pointer should be deallocated with @code{free(3C)} when + * are done using the data. The data are placed in a single block of + * allocated memory. Do not deallocate individual token/strings. + * + * The structure pointed to will contain at least these two fields: + * @table @samp + * @item tkn_ct + * The number of tokens found in the input string. + * @item tok_list + * An array of @code{tkn_ct + 1} pointers to substring tokens, with + * the last pointer set to NULL. + * @end table + * + * There are two types of quoted strings: single quoted (@code{'}) and + * double quoted (@code{"}). Singly quoted strings are fairly raw in that + * escape characters (@code{\\}) are simply another character, except when + * preceding the following characters: + * @example + * @code{\\} double backslashes reduce to one + * @code{'} incorporates the single quote into the string + * @code{\n} suppresses both the backslash and newline character + * @end example + * + * Double quote strings are formed according to the rules of string + * constants in ANSI-C programs. + * + * @param string string to be tokenized + * + * @return token_list_t * - pointer to a structure that lists each token + */ +extern token_list_t * ao_string_tokenize(char const *); + + +/** + * configFileLoad - parse a configuration file + * + * This routine will load a named configuration file and parse the + * text as a hierarchically valued option. The option descriptor + * created from an option definition file is not used via this interface. + * The returned value is "named" with the input file name and is of + * type "@code{OPARG_TYPE_HIERARCHY}". It may be used in calls to + * @code{optionGetValue()}, @code{optionNextValue()} and + * @code{optionUnloadNested()}. + * + * @param fname the file to load + * + * @return const tOptionValue * - An allocated, compound value structure + */ +extern const tOptionValue * configFileLoad(char const *); + + +/** + * optionFileLoad - Load the locatable config files, in order + * + * This function looks in all the specified directories for a configuration + * file ("rc" file or "ini" file) and processes any found twice. The first + * time through, they are processed in reverse order (last file first). At + * that time, only "immediate action" configurables are processed. For + * example, if the last named file specifies not processing any more + * configuration files, then no more configuration files will be processed. + * Such an option in the @strong{first} named directory will have no effect. + * + * Once the immediate action configurables have been handled, then the + * directories are handled in normal, forward order. In that way, later + * config files can override the settings of earlier config files. + * + * See the AutoOpts documentation for a thorough discussion of the + * config file format. + * + * Configuration files not found or not decipherable are simply ignored. + * + * @param opts program options descriptor + * @param prog program name + * + * @return int - 0 -> SUCCESS, -1 -> FAILURE + */ +extern int optionFileLoad(tOptions *, char const *); + + +/** + * optionFindNextValue - find a hierarcicaly valued option instance + * + * This routine will find the next entry in a nested value option or + * configurable. It will search through the list and return the next entry + * that matches the criteria. + * + * @param odesc an option with a nested arg type + * @param pPrevVal the last entry + * @param name name of value to find + * @param value the matching value + * + * @return const tOptionValue * - a compound value structure + */ +extern const tOptionValue * optionFindNextValue(const tOptDesc *, const tOptionValue *, char const *, char const *); + + +/** + * optionFindValue - find a hierarcicaly valued option instance + * + * This routine will find an entry in a nested value option or configurable. + * It will search through the list and return a matching entry. + * + * @param odesc an option with a nested arg type + * @param name name of value to find + * @param val the matching value + * + * @return const tOptionValue * - a compound value structure + */ +extern const tOptionValue * optionFindValue(const tOptDesc *, char const *, char const *); + + +/** + * optionFree - free allocated option processing memory + * + * AutoOpts sometimes allocates memory and puts pointers to it in the + * option state structures. This routine deallocates all such memory. + * + * @param pOpts program options descriptor + */ +extern void optionFree(tOptions *); + + +/** + * optionGetValue - get a specific value from a hierarcical list + * + * This routine will find an entry in a nested value option or configurable. + * If "valueName" is NULL, then the first entry is returned. Otherwise, + * the first entry with a name that exactly matches the argument will be + * returned. If there is no matching value, NULL is returned and errno is + * set to ENOENT. If the provided option value is not a hierarchical value, + * NULL is also returned and errno is set to EINVAL. + * + * @param pOptValue a hierarchcal value + * @param valueName name of value to get + * + * @return const tOptionValue * - a compound value structure + */ +extern const tOptionValue * optionGetValue(const tOptionValue *, char const *); + + +/** + * optionLoadLine - process a string for an option name and value + * + * This is a client program callable routine for setting options from, for + * example, the contents of a file that they read in. Only one option may + * appear in the text. It will be treated as a normal (non-preset) option. + * + * When passed a pointer to the option struct and a string, it will find + * the option named by the first token on the string and set the option + * argument to the remainder of the string. The caller must NUL terminate + * the string. The caller need not skip over any introductory hyphens. + * Any embedded new lines will be included in the option + * argument. If the input looks like one or more quoted strings, then the + * input will be "cooked". The "cooking" is identical to the string + * formation used in AutoGen definition files (@pxref{basic expression}), + * except that you may not use backquotes. + * + * @param opts program options descriptor + * @param line NUL-terminated text + */ +extern void optionLoadLine(tOptions *, char const *); + + +/** + * optionMemberList - Get the list of members of a bit mask set + * + * This converts the OPT_VALUE_name mask value to a allocated string. + * It is the caller's responsibility to free the string. + * + * @param od the set membership option description + * + * @return char * - the names of the set bits + */ +extern char * optionMemberList(tOptDesc *); + + +/** + * optionNextValue - get the next value from a hierarchical list + * + * This routine will return the next entry after the entry passed in. At the + * end of the list, NULL will be returned. If the entry is not found on the + * list, NULL will be returned and "@var{errno}" will be set to EINVAL. + * The "@var{pOldValue}" must have been gotten from a prior call to this + * routine or to "@code{opitonGetValue()}". + * + * @param pOptValue a hierarchcal list value + * @param pOldValue a value from this list + * + * @return const tOptionValue * - a compound value structure + */ +extern const tOptionValue * optionNextValue(const tOptionValue *, const tOptionValue *); + + +/** + * optionOnlyUsage - Print usage text for just the options + * + * This routine will print only the usage for each option. + * This function may be used when the emitted usage must incorporate + * information not available to AutoOpts. + * + * @param pOpts program options descriptor + * @param ex_code exit code for calling exit(3) + */ +extern void optionOnlyUsage(tOptions *, int); + + +/** + * optionPrintVersion - Print the program version + * + * This routine will print the version to stdout. + * + * @param opts program options descriptor + * @param od the descriptor for this arg + */ +extern void optionPrintVersion(tOptions *, tOptDesc *); + + +/** + * optionPrintVersionAndReturn - Print the program version + * + * This routine will print the version to stdout and return + * instead of exiting. Please see the source for the + * @code{print_ver} funtion for details on selecting how + * verbose to be after this function returns. + * + * @param opts program options descriptor + * @param od the descriptor for this arg + */ +extern void optionPrintVersionAndReturn(tOptions *, tOptDesc *); + + +/** + * optionProcess - this is the main option processing routine + * + * This is the main entry point for processing options. It is intended + * that this procedure be called once at the beginning of the execution of + * a program. Depending on options selected earlier, it is sometimes + * necessary to stop and restart option processing, or to select completely + * different sets of options. This can be done easily, but you generally + * do not want to do this. + * + * The number of arguments processed always includes the program name. + * If one of the arguments is "--", then it is counted and the processing + * stops. If an error was encountered and errors are to be tolerated, then + * the returned value is the index of the argument causing the error. + * A hyphen by itself ("-") will also cause processing to stop and will + * @emph{not} be counted among the processed arguments. A hyphen by itself + * is treated as an operand. Encountering an operand stops option + * processing. + * + * @param opts program options descriptor + * @param a_ct program arg count + * @param a_v program arg vector + * + * @return int - the count of the arguments processed + */ +extern int optionProcess(tOptions *, int, char **); + + +/** + * optionRestore - restore option state from memory copy + * + * Copy back the option state from saved memory. + * The allocated memory is left intact, so this routine can be + * called repeatedly without having to call optionSaveState again. + * If you are restoring a state that was saved before the first call + * to optionProcess(3AO), then you may change the contents of the + * argc/argv parameters to optionProcess. + * + * @param pOpts program options descriptor + */ +extern void optionRestore(tOptions *); + + +/** + * optionSaveFile - saves the option state to a file + * + * This routine will save the state of option processing to a file. The name + * of that file can be specified with the argument to the @code{--save-opts} + * option, or by appending the @code{rcfile} attribute to the last + * @code{homerc} attribute. If no @code{rcfile} attribute was specified, it + * will default to @code{.@i{programname}rc}. If you wish to specify another + * file, you should invoke the @code{SET_OPT_SAVE_OPTS(@i{filename})} macro. + * + * The recommend usage is as follows: + * @example + * optionProcess(&progOptions, argc, argv); + * if (i_want_a_non_standard_place_for_this) + * SET_OPT_SAVE_OPTS("myfilename"); + * optionSaveFile(&progOptions); + * @end example + * + * @param opts program options descriptor + */ +extern void optionSaveFile(tOptions *); + + +/** + * optionSaveState - saves the option state to memory + * + * This routine will allocate enough memory to save the current option + * processing state. If this routine has been called before, that memory + * will be reused. You may only save one copy of the option state. This + * routine may be called before optionProcess(3AO). If you do call it + * before the first call to optionProcess, then you may also change the + * contents of argc/argv after you call optionRestore(3AO) + * + * In fact, more strongly put: it is safest to only use this function + * before having processed any options. In particular, the saving and + * restoring of stacked string arguments and hierarchical values is + * disabled. The values are not saved. + * + * @param pOpts program options descriptor + */ +extern void optionSaveState(tOptions *); + + +/** + * optionUnloadNested - Deallocate the memory for a nested value + * + * A nested value needs to be deallocated. The pointer passed in should + * have been gotten from a call to @code{configFileLoad()} (See + * @pxref{libopts-configFileLoad}). + * + * @param pOptVal the hierarchical value + */ +extern void optionUnloadNested(tOptionValue const *); + + +/** + * optionVersion - return the compiled AutoOpts version number + * + * Returns the full version string compiled into the library. + * The returned string cannot be modified. + * + * @return char const * - the version string in constant memory + */ +extern char const * optionVersion(void); + + +/** + * strequate - map a list of characters to the same value + * + * Each character in the input string get mapped to the first character + * in the string. + * This function name is mapped to option_strequate so as to not conflict + * with the POSIX name space. + * + * @param ch_list characters to equivalence + */ +extern void strequate(char const *); + + +/** + * streqvcmp - compare two strings with an equivalence mapping + * + * Using a character mapping, two strings are compared for "equivalence". + * Each input character is mapped to a comparison character and the + * mapped-to characters are compared for the two NUL terminated input strings. + * This function name is mapped to option_streqvcmp so as to not conflict + * with the POSIX name space. + * + * @param str1 first string + * @param str2 second string + * + * @return int - the difference between two differing characters + */ +extern int streqvcmp(char const *, char const *); + + +/** + * streqvmap - Set the character mappings for the streqv functions + * + * Set the character mapping. If the count (@code{ct}) is set to zero, then + * the map is cleared by setting all entries in the map to their index + * value. Otherwise, the "@code{From}" character is mapped to the "@code{To}" + * character. If @code{ct} is greater than 1, then @code{From} and @code{To} + * are incremented and the process repeated until @code{ct} entries have been + * set. For example, + * @example + * streqvmap('a', 'A', 26); + * @end example + * @noindent + * will alter the mapping so that all English lower case letters + * will map to upper case. + * + * This function name is mapped to option_streqvmap so as to not conflict + * with the POSIX name space. + * + * @param from Input character + * @param to Mapped-to character + * @param ct compare length + */ +extern void streqvmap(char, char, int); + + +/** + * strneqvcmp - compare two strings with an equivalence mapping + * + * Using a character mapping, two strings are compared for "equivalence". + * Each input character is mapped to a comparison character and the + * mapped-to characters are compared for the two NUL terminated input strings. + * The comparison is limited to @code{ct} bytes. + * This function name is mapped to option_strneqvcmp so as to not conflict + * with the POSIX name space. + * + * @param str1 first string + * @param str2 second string + * @param ct compare length + * + * @return int - the difference between two differing characters + */ +extern int strneqvcmp(char const *, char const *, int); + + +/** + * strtransform - convert a string into its mapped-to value + * + * Each character in the input string is mapped and the mapped-to + * character is put into the output. + * This function name is mapped to option_strtransform so as to not conflict + * with the POSIX name space. + * + * The source and destination may be the same. + * + * @param dest output string + * @param src input string + */ +extern void strtransform(char *, char const *); + +/* AutoOpts PRIVATE FUNCTIONS: */ +tOptProc optionStackArg, optionUnstackArg, optionBooleanVal, optionNumericVal; + +extern char * ao_string_cook(char *, int *); + +extern unsigned int ao_string_cook_escape_char(char const *, char *, unsigned int); + +extern void genshelloptUsage(tOptions *, int); + +extern int optionAlias(tOptions *, tOptDesc *, unsigned int); + +extern void optionBooleanVal(tOptions *, tOptDesc *); + +extern uintptr_t optionEnumerationVal(tOptions *, tOptDesc *, char const * const *, unsigned int); + +extern void optionFileCheck(tOptions *, tOptDesc *, teOptFileType, tuFileMode); + +extern char const * optionKeywordName(tOptDesc *, unsigned int); + +extern void optionLoadOpt(tOptions *, tOptDesc *); + +extern bool optionMakePath(char *, int, char const *, char const *); + +extern void optionNestedVal(tOptions *, tOptDesc *); + +extern void optionNumericVal(tOptions *, tOptDesc *); + +extern void optionPagedUsage(tOptions *, tOptDesc *); + +extern void optionParseShell(tOptions *); + +extern void optionPrintParagraphs(char const *, bool, FILE *); + +extern void optionPutShell(tOptions *); + +extern char const * optionQuoteString(char const *, char const *); + +extern void optionResetOpt(tOptions *, tOptDesc *); + +extern void optionSetMembers(tOptions *, tOptDesc *, char const * const *, unsigned int); + +extern void optionShowRange(tOptions *, tOptDesc *, void *, int); + +extern void optionStackArg(tOptions *, tOptDesc *); + +extern void optionTimeDate(tOptions *, tOptDesc *); + +extern void optionTimeVal(tOptions *, tOptDesc *); + +extern void optionUnstackArg(tOptions *, tOptDesc *); + +extern void optionUsage(tOptions *, int); + +extern void optionVendorOption(tOptions *, tOptDesc *); + +extern void optionVersionStderr(tOptions *, tOptDesc *); + +extern void * text_mmap(char const *, int, int, tmap_info_t *); + +extern int text_munmap(tmap_info_t *); + +CPLUSPLUS_CLOSER +#endif /* AUTOOPTS_OPTIONS_H_GUARD */ +/** @} + * + * Local Variables: + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * options.h ends here */ diff --git a/autoopts/autoopts/usage-txt.h b/autoopts/autoopts/usage-txt.h new file mode 100644 index 0000000..e94337d --- /dev/null +++ b/autoopts/autoopts/usage-txt.h @@ -0,0 +1,651 @@ +/* -*- buffer-read-only: t -*- vi: set ro: + * + * DO NOT EDIT THIS FILE (usage-txt.h) + * + * It has been AutoGen-ed + * From the definitions usage-txt.def + * and the template file usage-txt.tpl + * + * This file is part of AutoOpts, a companion to AutoGen. + * AutoOpts is free software. + * AutoOpts is Copyright (C) 1992-2017 by Bruce Korb - all rights reserved + * + * AutoOpts is available under any one of two licenses. The license + * in use must be one of these two and the choice is under the control + * of the user of the license. + * + * The GNU Lesser General Public License, version 3 or later + * See the files "COPYING.lgplv3" and "COPYING.gplv3" + * + * The Modified Berkeley Software Distribution License + * See the file "COPYING.mbsd" + * + * These files have the following sha256 sums: + * + * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 + * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 + * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + */ +/** @file usage-txt.h + * + * This file handles all the bookkeeping required for tracking all the little + * tiny strings used by the AutoOpts library. There are 107 + * of them. This is not versioned because it is entirely internal to the + * library and accessed by client code only in a very well-controlled way: + * they may substitute translated strings using a procedure that steps through + * all the string pointers. + */ +#ifndef AUTOOPTS_USAGE_TXT_H_GUARD +#define AUTOOPTS_USAGE_TXT_H_GUARD 1 + +/* + * One structure to hold all the pointers to all the translatable strings. + */ +typedef struct { + int field_ct; + char * utpz_GnuBoolArg; + char * utpz_GnuKeyArg; + char * utpz_GnuNumArg; + char * utpz_GnuStrArg; + char const * apz_str[103]; +} usage_text_t; + +/* + * Declare the global structure with all the pointers to translatable + * strings and the text array containing untranslatable strings. + */ +extern usage_text_t option_xlateable_txt; +extern char const option_lib_text[4267]; + +#if defined(AUTOOPTS_INTERNAL) +/* + * Provide a mapping from a short name to either the text directly + * (for untranslatable strings), or to pointers to the text, rendering + * them translatable. + */ +#define zalloc_fail (option_xlateable_txt.apz_str[ 0]) +#define zno_opt_arg (option_xlateable_txt.apz_str[ 1]) +#define ztoo_new (option_xlateable_txt.apz_str[ 2]) +#define zwrong_ver (option_xlateable_txt.apz_str[ 3]) +#define zrealloc_fail (option_xlateable_txt.apz_str[ 4]) +#define ztoo_old (option_xlateable_txt.apz_str[ 5]) +#define zao_ver_fmt (option_xlateable_txt.apz_str[ 6]) +#define zao_bug_msg (option_xlateable_txt.apz_str[ 7]) +#define zno_reset (option_xlateable_txt.apz_str[ 8]) +#define zmissing_help_msg (option_xlateable_txt.apz_str[ 9]) +#define zbad_data_msg (option_xlateable_txt.apz_str[ 10]) +#define zbad_arg_type_msg (option_xlateable_txt.apz_str[ 11]) +#define zbad_default_msg (option_xlateable_txt.apz_str[ 12]) +#define zbad_alias_id (option_xlateable_txt.apz_str[ 13]) +#define zambiguous_key (option_xlateable_txt.apz_str[ 14]) +#define zambig_list_msg (option_xlateable_txt.apz_str[ 15]) +#define zambig_opt_fmt (option_xlateable_txt.apz_str[ 16]) +#define zargs_must (option_xlateable_txt.apz_str[ 17]) +#define zat_most (option_xlateable_txt.apz_str[ 18]) +#define zfserr_fmt (option_xlateable_txt.apz_str[ 19]) +#define zinter_proc_pipe (option_xlateable_txt.apz_str[ 20]) +#define zBadVerArg (option_xlateable_txt.apz_str[ 21]) +#define zconflict_fmt (option_xlateable_txt.apz_str[ 22]) +#define zDisabledErr (option_xlateable_txt.apz_str[ 23]) +#define zequiv (option_xlateable_txt.apz_str[ 24]) +#define zGnuBoolArg (option_xlateable_txt.utpz_GnuBoolArg) +#define zGnuKeyArg (option_xlateable_txt.utpz_GnuKeyArg) +#define zGnuNumArg (option_xlateable_txt.utpz_GnuNumArg) +#define zGnuStrArg (option_xlateable_txt.utpz_GnuStrArg) +#define zIllOptChr (option_xlateable_txt.apz_str[ 25]) +#define zIllOptStr (option_xlateable_txt.apz_str[ 26]) +#define zIllVendOptStr (option_xlateable_txt.apz_str[ 27]) +#define zIntRange (option_xlateable_txt.apz_str[ 28]) +#define zbad_od (option_xlateable_txt.apz_str[ 29]) +#define zInvalOptName (option_xlateable_txt.apz_str[ 30]) +#define zMisArg (option_xlateable_txt.apz_str[ 31]) +#define zmultiway_bug (option_xlateable_txt.apz_str[ 32]) +#define zneed_one (option_xlateable_txt.apz_str[ 33]) +#define zNoArg (option_xlateable_txt.apz_str[ 34]) +#define zNoArgs (option_xlateable_txt.apz_str[ 35]) +#define zNoCreat (option_xlateable_txt.apz_str[ 36]) +#define zNoKey (option_xlateable_txt.apz_str[ 37]) +#define zreset_arg (option_xlateable_txt.apz_str[ 38]) +#define zNoStat (option_xlateable_txt.apz_str[ 39]) +#define zNoState (option_xlateable_txt.apz_str[ 40]) +#define zNotCmdOpt (option_xlateable_txt.apz_str[ 41]) +#define zNotDate (option_xlateable_txt.apz_str[ 42]) +#define zNotDuration (option_xlateable_txt.apz_str[ 43]) +#define zneed_more (option_xlateable_txt.apz_str[ 44]) +#define zNotNumber (option_xlateable_txt.apz_str[ 45]) +#define znum_too_large (option_xlateable_txt.apz_str[ 46]) +#define zoffer_usage_fmt (option_xlateable_txt.apz_str[ 47]) +#define zonly_one (option_xlateable_txt.apz_str[ 48]) +#define zstdout_name (option_xlateable_txt.apz_str[ 49]) +#define zstderr_name (option_xlateable_txt.apz_str[ 50]) +#define zwriting (option_xlateable_txt.apz_str[ 51]) +#define zRangeErr (option_xlateable_txt.apz_str[ 52]) +#define zneed_fmt (option_xlateable_txt.apz_str[ 53]) +#define zsave_warn (option_xlateable_txt.apz_str[ 54]) +#define zalt_opt (option_xlateable_txt.apz_str[ 55]) +#define zAuto (option_xlateable_txt.apz_str[ 56]) +#define zDefaultOpt (option_xlateable_txt.apz_str[ 57]) +#define zDis (option_xlateable_txt.apz_str[ 58]) +#define zDisabledOpt (option_xlateable_txt.apz_str[ 59]) +#define zDisabledWhy (option_xlateable_txt.apz_str[ 60]) +#define zEnab (option_xlateable_txt.apz_str[ 61]) +#define ztoo_often_fmt (option_xlateable_txt.apz_str[ 62]) +#define zExamineFmt (option_xlateable_txt.apz_str[ 63]) +#define zFileCannotExist (option_xlateable_txt.apz_str[ 64]) +#define zFileMustExist (option_xlateable_txt.apz_str[ 65]) +#define zFlagOkay (option_xlateable_txt.apz_str[ 66]) +#define zGenshell (option_xlateable_txt.apz_str[ 67]) +#define zLowerBits (option_xlateable_txt.apz_str[ 68]) +#define zMembers (option_xlateable_txt.apz_str[ 69]) +#define zMust (option_xlateable_txt.apz_str[ 70]) +#define zNoFlags (option_xlateable_txt.apz_str[ 71]) +#define zNoLim (option_xlateable_txt.apz_str[ 72]) +#define zNoPreset (option_xlateable_txt.apz_str[ 73]) +#define zNoRq_NoShrtTtl (option_xlateable_txt.apz_str[ 74]) +#define zNoRq_ShrtTtl (option_xlateable_txt.apz_str[ 75]) +#define zNrmOptFmt (option_xlateable_txt.apz_str[ 76]) +#define zNumberOpt (option_xlateable_txt.apz_str[ 77]) +#define zOptsOnly (option_xlateable_txt.apz_str[ 78]) +#define zPathFmt (option_xlateable_txt.apz_str[ 79]) +#define zPlsSendBugs (option_xlateable_txt.apz_str[ 80]) +#define zPreset (option_xlateable_txt.apz_str[ 81]) +#define zPresetIntro (option_xlateable_txt.apz_str[ 82]) +#define zProhib (option_xlateable_txt.apz_str[ 83]) +#define zProhibOne (option_xlateable_txt.apz_str[ 84]) +#define zRange (option_xlateable_txt.apz_str[ 85]) +#define zRangeAbove (option_xlateable_txt.apz_str[ 86]) +#define zRangeExact (option_xlateable_txt.apz_str[ 87]) +#define zRangeLie (option_xlateable_txt.apz_str[ 88]) +#define zRangeOnly (option_xlateable_txt.apz_str[ 89]) +#define zRangeOr (option_xlateable_txt.apz_str[ 90]) +#define zRangeScaled (option_xlateable_txt.apz_str[ 91]) +#define zRangeUpto (option_xlateable_txt.apz_str[ 92]) +#define zReorder (option_xlateable_txt.apz_str[ 93]) +#define zReqOne (option_xlateable_txt.apz_str[ 94]) +#define zReqThese (option_xlateable_txt.apz_str[ 95]) +#define zReq_NoShrtTtl (option_xlateable_txt.apz_str[ 96]) +#define zReq_ShrtTtl (option_xlateable_txt.apz_str[ 97]) +#define zSetMemberSettings (option_xlateable_txt.apz_str[ 98]) +#define zUpTo (option_xlateable_txt.apz_str[ 99]) +#define zValidKeys (option_xlateable_txt.apz_str[100]) +#define zVendIntro (option_xlateable_txt.apz_str[101]) +#define zVendOptsAre (option_xlateable_txt.apz_str[102]) + + /* + * First, set up the strings. Some of these are writable. These are all in + * English. This gets compiled into libopts and is distributed here so that + * xgettext (or equivalents) can extract these strings for translation. + */ +static char eng_zGnuBoolArg[] = "=T/F"; +static char eng_zGnuKeyArg[] = "=KWd"; +static char eng_zGnuNumArg[] = "=num"; +static char eng_zGnuStrArg[] = "=str"; +char const option_lib_text[4267] = +/* 0 */ "allocation of %d bytes failed\n\0" +/* 31 */ "AutoOpts function called without option descriptor\n\0" +/* 83 */ "\tThis exceeds the compiled library version: \0" +/* 129 */ "Automated Options Processing Error!\n" + "\t%s called AutoOpts function with structure version %d:%d:%d.\n\0" +/* 228 */ "realloc of %d bytes at 0x%p failed\n\0" +/* 264 */ "\tThis is less than the minimum library version: \0" +/* 314 */ "Automated Options version %s\n" + "\tCopyright (C) 1999-2017 by Bruce Korb - all rights reserved\n\0" +/* 405 */ "(AutoOpts bug): %s.\n\0" +/* 427 */ "optionResetOpt() called, but reset-option not configured\0" +/* 484 */ "could not locate the 'help' option\0" +/* 519 */ "optionProcess() was called with invalid data\0" +/* 564 */ "invalid argument type specified\0" +/* 596 */ "defaulted to option with optional arg\0" +/* 634 */ "aliasing option is out of range.\0" +/* 667 */ "%s error: the keyword '%s' is ambiguous for %s\n\0" +/* 716 */ " The following options match:\n\0" +/* 748 */ "%s: ambiguous option name: %s (matches %d options)\n\0" +/* 800 */ "%s: Command line arguments required\n\0" +/* 837 */ "%d %s%s options allowed\n\0" +/* 862 */ "%s error %d (%s) calling %s for '%s'\n\0" +/* 900 */ "interprocess pipe\0" +/* 918 */ "error: version option argument '%c' invalid. Use:\n" + "\t'v' - version only\n" + "\t'c' - version and copyright\n" + "\t'n' - version and full copyright notice\n\0" +/* 1060 */ "%s error: the '%s' and '%s' options conflict\n\0" +/* 1107 */ "%s: The '%s' option has been disabled.\0" +/* 1146 */ "-equivalence\0" +/* 1159 */ "%s: illegal option -- %c\n\0" +/* 1185 */ "%s: illegal option -- %s\n\0" +/* 1211 */ "%s: unknown vendor extension option -- %s\n\0" +/* 1254 */ " or an integer from %d through %d\n\0" +/* 1290 */ "%s error: invalid option descriptor for %s\n\0" +/* 1335 */ "%s: invalid option name: %s\n\0" +/* 1364 */ "%s: The '%s' option requires an argument.\n\0" +/* 1407 */ "(AutoOpts bug): Equivalenced option '%s' was equivalenced to both\n" + "\t'%s' and '%s'.\0" +/* 1490 */ "%s error: The %s option is required\n\0" +/* 1528 */ "%s: The '%s' option cannot have an argument.\n\0" +/* 1574 */ "%s: Command line arguments are not allowed.\n\0" +/* 1619 */ "error %d (%s) creating %s\n\0" +/* 1646 */ "%s error: '%s' does not match any %s keywords.\n\0" +/* 1695 */ "%s error: The '%s' option requires an argument.\n\0" +/* 1744 */ "error %d (%s) stat-ing %s\n\0" +/* 1771 */ "%s error: no saved option state\n\0" +/* 1804 */ "'%s' is not a command line option.\n\0" +/* 1840 */ "%s error: '%s' is not a recognizable date/time.\n\0" +/* 1890 */ "%s error: '%s' is not a recognizable time duration.\n\0" +/* 1944 */ "%s error: The %s option must appear %d times.\n\0" +/* 1992 */ "%s error: '%s' is not a recognizable number.\n\0" +/* 2039 */ "%s error: %s exceeds %s keyword count\n\0" +/* 2079 */ "Try '%s %s' for more information.\n\0" +/* 2114 */ "one %s%s option allowed\n\0" +/* 2139 */ "standard output\0" +/* 2155 */ "standard error\0" +/* 2170 */ "write\0" +/* 2176 */ "%s error: %s option value %ld is out of range.\n\0" +/* 2225 */ "%s error: %s option requires the %s option\n\0" +/* 2270 */ "%s warning: cannot save options - %s not regular file\n\0" +/* 2326 */ "\t\t\t\t- an alternate for '%s'\n\0" +/* 2355 */ "Version, usage and configuration options:\0" +/* 2397 */ "\t\t\t\t- default option for unnamed options\n\0" +/* 2439 */ "\t\t\t\t- disabled as '--%s'\n\0" +/* 2465 */ " --- %-14s %s\n\0" +/* 2480 */ "This option has been disabled\0" +/* 2510 */ "\t\t\t\t- enabled by default\n\0" +/* 2536 */ "%s error: only \0" +/* 2553 */ " - examining environment variables named %s_*\n\0" +/* 2600 */ "\t\t\t\t- file must not pre-exist\n\0" +/* 2631 */ "\t\t\t\t- file must pre-exist\n\0" +/* 2658 */ "Options are specified by doubled hyphens and their name or by a single\n" + "hyphen and the flag character.\n\0" +/* 2761 */ "\n" + "= = = = = = = =\n\n" + "This incarnation of genshell will produce\n" + "a shell script to parse the options for %s:\n\n\0" +/* 2867 */ " or an integer mask with any of the lower %d bits set\n\0" +/* 2923 */ "\t\t\t\t- is a set membership option\n\0" +/* 2957 */ "\t\t\t\t- must appear between %d and %d times\n\0" +/* 3000 */ "Options are specified by single or double hyphens and their name.\n\0" +/* 3067 */ "\t\t\t\t- may appear multiple times\n\0" +/* 3100 */ "\t\t\t\t- may not be preset\n\0" +/* 3125 */ " Arg Option-Name Description\n\0" +/* 3160 */ " Flg Arg Option-Name Description\n\0" +/* 3198 */ " %3s %s\0" +/* 3206 */ "The '-#' option may omit the hash char\n\0" +/* 3254 */ "All arguments are named options.\n\0" +/* 3288 */ " - reading file %s\0" +/* 3307 */ "\n" + "Please send bug reports to: <%s>\n\0" +/* 3343 */ "\t\t\t\t- may NOT appear - preset only\n\0" +/* 3379 */ "\n" + "The following option preset mechanisms are supported:\n\0" +/* 3435 */ "prohibits these options:\n\0" +/* 3461 */ "prohibits the option '%s'\n\0" +/* 3488 */ "%s%ld to %ld\0" +/* 3501 */ "%sgreater than or equal to %ld\0" +/* 3532 */ "%s%ld exactly\0" +/* 3546 */ "%sit must lie in one of the ranges:\n\0" +/* 3583 */ "%sit must be in the range:\n\0" +/* 3611 */ ", or\n\0" +/* 3617 */ "%sis scalable with a suffix: k/K/m/M/g/G/t/T\n\0" +/* 3663 */ "%sless than or equal to %ld\0" +/* 3691 */ "Operands and options may be intermixed. They will be reordered.\n\0" +/* 3757 */ "requires the option '%s'\n\0" +/* 3783 */ "requires these options:\n\0" +/* 3808 */ " Arg Option-Name Req? Description\n\0" +/* 3848 */ " Flg Arg Option-Name Req? Description\n\0" +/* 3891 */ "or you may use a numeric representation. Preceding these with a '!'\n" + "will clear the bits, specifying 'none' will clear all bits, and 'all'\n" + "will set them all. Multiple entries may be passed as an option\n" + "argument list.\n\0" +/* 4110 */ "\t\t\t\t- may appear up to %d times\n\0" +/* 4143 */ "The valid \"%s\" option keywords are:\n\0" +/* 4180 */ "The next option supports vendor supported extra options:\0" +/* 4237 */ "These additional options are:"; + +/* + * Now, define (and initialize) the structure that contains + * the pointers to all these strings. + * Aren't you glad you don't maintain this by hand? + */ +usage_text_t option_xlateable_txt = { + 107, + eng_zGnuBoolArg, eng_zGnuKeyArg, eng_zGnuNumArg, eng_zGnuStrArg, + { + option_lib_text + 0, option_lib_text + 31, option_lib_text + 83, + option_lib_text + 129, option_lib_text + 228, option_lib_text + 264, + option_lib_text + 314, option_lib_text + 405, option_lib_text + 427, + option_lib_text + 484, option_lib_text + 519, option_lib_text + 564, + option_lib_text + 596, option_lib_text + 634, option_lib_text + 667, + option_lib_text + 716, option_lib_text + 748, option_lib_text + 800, + option_lib_text + 837, option_lib_text + 862, option_lib_text + 900, + option_lib_text + 918, option_lib_text + 1060, option_lib_text + 1107, + option_lib_text + 1146, option_lib_text + 1159, option_lib_text + 1185, + option_lib_text + 1211, option_lib_text + 1254, option_lib_text + 1290, + option_lib_text + 1335, option_lib_text + 1364, option_lib_text + 1407, + option_lib_text + 1490, option_lib_text + 1528, option_lib_text + 1574, + option_lib_text + 1619, option_lib_text + 1646, option_lib_text + 1695, + option_lib_text + 1744, option_lib_text + 1771, option_lib_text + 1804, + option_lib_text + 1840, option_lib_text + 1890, option_lib_text + 1944, + option_lib_text + 1992, option_lib_text + 2039, option_lib_text + 2079, + option_lib_text + 2114, option_lib_text + 2139, option_lib_text + 2155, + option_lib_text + 2170, option_lib_text + 2176, option_lib_text + 2225, + option_lib_text + 2270, option_lib_text + 2326, option_lib_text + 2355, + option_lib_text + 2397, option_lib_text + 2439, option_lib_text + 2465, + option_lib_text + 2480, option_lib_text + 2510, option_lib_text + 2536, + option_lib_text + 2553, option_lib_text + 2600, option_lib_text + 2631, + option_lib_text + 2658, option_lib_text + 2761, option_lib_text + 2867, + option_lib_text + 2923, option_lib_text + 2957, option_lib_text + 3000, + option_lib_text + 3067, option_lib_text + 3100, option_lib_text + 3125, + option_lib_text + 3160, option_lib_text + 3198, option_lib_text + 3206, + option_lib_text + 3254, option_lib_text + 3288, option_lib_text + 3307, + option_lib_text + 3343, option_lib_text + 3379, option_lib_text + 3435, + option_lib_text + 3461, option_lib_text + 3488, option_lib_text + 3501, + option_lib_text + 3532, option_lib_text + 3546, option_lib_text + 3583, + option_lib_text + 3611, option_lib_text + 3617, option_lib_text + 3663, + option_lib_text + 3691, option_lib_text + 3757, option_lib_text + 3783, + option_lib_text + 3808, option_lib_text + 3848, option_lib_text + 3891, + option_lib_text + 4110, option_lib_text + 4143, option_lib_text + 4180, + option_lib_text + 4237 + } }; +#endif /* AUTOOPTS_INTERNAL */ + +#ifdef XGETTEXT_SCAN_DO_NOT_COMPILE +do not compile this section. +/* TRANSLATORS: The following dummy functions were crated solely so that + * xgettext can extract the correct strings. These strings are actually + * referenced where the preceding "#line" directive states, though you will + * not see the literal string there. The literal string is defined above in + * the @code{option_lib_text} table and referenced via a #define name that + * redirects into the @code{option_xlateable_txt} structure above. When + * translating is activated, the pointers in @code{option_xlateable_txt} are + * updated to point to translated strings. + */ +static void dummy_func(void) { + /* LIBOPTS-MESSAGES: */ +#line 67 "../autoopts.c" + puts(_("allocation of %d bytes failed\n")); +#line 89 "../autoopts.c" + puts(_("allocation of %d bytes failed\n")); +#line 48 "../init.c" + puts(_("AutoOpts function called without option descriptor\n")); +#line 81 "../init.c" + puts(_("\tThis exceeds the compiled library version: ")); +#line 79 "../init.c" + puts(_("Automated Options Processing Error!\n" + "\t%s called AutoOpts function with structure version %d:%d:%d.\n")); +#line 78 "../autoopts.c" + puts(_("realloc of %d bytes at 0x%p failed\n")); +#line 83 "../init.c" + puts(_("\tThis is less than the minimum library version: ")); +#line 121 "../version.c" + puts(_("Automated Options version %s\n" + "\tCopyright (C) 1999-2017 by Bruce Korb - all rights reserved\n")); +#line 49 "../makeshell.c" + puts(_("(AutoOpts bug): %s.\n")); +#line 90 "../reset.c" + puts(_("optionResetOpt() called, but reset-option not configured")); +#line 241 "../usage.c" + puts(_("could not locate the 'help' option")); +#line 330 "../autoopts.c" + puts(_("optionProcess() was called with invalid data")); +#line 697 "../usage.c" + puts(_("invalid argument type specified")); +#line 568 "../find.c" + puts(_("defaulted to option with optional arg")); +#line 76 "../alias.c" + puts(_("aliasing option is out of range.")); +#line 210 "../enum.c" + puts(_("%s error: the keyword '%s' is ambiguous for %s\n")); +#line 78 "../find.c" + puts(_(" The following options match:\n")); +#line 263 "../find.c" + puts(_("%s: ambiguous option name: %s (matches %d options)\n")); +#line 161 "../check.c" + puts(_("%s: Command line arguments required\n")); +#line 43 "../alias.c" + puts(_("%d %s%s options allowed\n")); +#line 56 "../makeshell.c" + puts(_("%s error %d (%s) calling %s for '%s'\n")); +#line 268 "../makeshell.c" + puts(_("interprocess pipe")); +#line 171 "../version.c" + puts(_("error: version option argument '%c' invalid. Use:\n" + "\t'v' - version only\n" + "\t'c' - version and copyright\n" + "\t'n' - version and full copyright notice\n")); +#line 58 "../check.c" + puts(_("%s error: the '%s' and '%s' options conflict\n")); +#line 187 "../find.c" + puts(_("%s: The '%s' option has been disabled.")); +#line 400 "../find.c" + puts(_("%s: The '%s' option has been disabled.")); +#line 38 "../alias.c" + puts(_("-equivalence")); +#line 439 "../find.c" + puts(_("%s: illegal option -- %c\n")); +#line 110 "../reset.c" + puts(_("%s: illegal option -- %c\n")); +#line 241 "../find.c" + puts(_("%s: illegal option -- %s\n")); +#line 740 "../find.c" + puts(_("%s: illegal option -- %s\n")); +#line 118 "../reset.c" + puts(_("%s: illegal option -- %s\n")); +#line 305 "../find.c" + puts(_("%s: unknown vendor extension option -- %s\n")); +#line 135 "../enum.c" + puts(_(" or an integer from %d through %d\n")); +#line 145 "../enum.c" + puts(_(" or an integer from %d through %d\n")); +#line 696 "../usage.c" + puts(_("%s error: invalid option descriptor for %s\n")); +#line 1030 "../usage.c" + puts(_("%s error: invalid option descriptor for %s\n")); +#line 355 "../find.c" + puts(_("%s: invalid option name: %s\n")); +#line 497 "../find.c" + puts(_("%s: The '%s' option requires an argument.\n")); +#line 150 "../autoopts.c" + puts(_("(AutoOpts bug): Equivalenced option '%s' was equivalenced to both\n" + "\t'%s' and '%s'.")); +#line 94 "../check.c" + puts(_("%s error: The %s option is required\n")); +#line 602 "../find.c" + puts(_("%s: The '%s' option cannot have an argument.\n")); +#line 151 "../check.c" + puts(_("%s: Command line arguments are not allowed.\n")); +#line 568 "../save.c" + puts(_("error %d (%s) creating %s\n")); +#line 210 "../enum.c" + puts(_("%s error: '%s' does not match any %s keywords.\n")); +#line 93 "../reset.c" + puts(_("%s error: The '%s' option requires an argument.\n")); +#line 122 "../save.c" + puts(_("error %d (%s) stat-ing %s\n")); +#line 175 "../save.c" + puts(_("error %d (%s) stat-ing %s\n")); +#line 143 "../restore.c" + puts(_("%s error: no saved option state\n")); +#line 225 "../autoopts.c" + puts(_("'%s' is not a command line option.\n")); +#line 113 "../time.c" + puts(_("%s error: '%s' is not a recognizable date/time.\n")); +#line 50 "../time.c" + puts(_("%s error: '%s' is not a recognizable time duration.\n")); +#line 92 "../check.c" + puts(_("%s error: The %s option must appear %d times.\n")); +#line 165 "../numeric.c" + puts(_("%s error: '%s' is not a recognizable number.\n")); +#line 176 "../enum.c" + puts(_("%s error: %s exceeds %s keyword count\n")); +#line 279 "../usage.c" + puts(_("Try '%s %s' for more information.\n")); +#line 45 "../alias.c" + puts(_("one %s%s option allowed\n")); +#line 170 "../makeshell.c" + puts(_("standard output")); +#line 905 "../makeshell.c" + puts(_("standard output")); +#line 223 "../usage.c" + puts(_("standard output")); +#line 364 "../usage.c" + puts(_("standard output")); +#line 574 "../usage.c" + puts(_("standard output")); +#line 178 "../version.c" + puts(_("standard output")); +#line 223 "../usage.c" + puts(_("standard error")); +#line 364 "../usage.c" + puts(_("standard error")); +#line 574 "../usage.c" + puts(_("standard error")); +#line 178 "../version.c" + puts(_("standard error")); +#line 170 "../makeshell.c" + puts(_("write")); +#line 905 "../makeshell.c" + puts(_("write")); +#line 222 "../usage.c" + puts(_("write")); +#line 363 "../usage.c" + puts(_("write")); +#line 573 "../usage.c" + puts(_("write")); +#line 177 "../version.c" + puts(_("write")); +#line 60 "../numeric.c" + puts(_("%s error: %s option value %ld is out of range.\n")); +#line 44 "../check.c" + puts(_("%s error: %s option requires the %s option\n")); +#line 121 "../save.c" + puts(_("%s warning: cannot save options - %s not regular file\n")); +#line 174 "../save.c" + puts(_("%s warning: cannot save options - %s not regular file\n")); +#line 193 "../save.c" + puts(_("%s warning: cannot save options - %s not regular file\n")); +#line 567 "../save.c" + puts(_("%s warning: cannot save options - %s not regular file\n")); + /* END-LIBOPTS-MESSAGES */ + + /* USAGE-TEXT: */ +#line 822 "../usage.c" + puts(_("\t\t\t\t- an alternate for '%s'\n")); +#line 1097 "../usage.c" + puts(_("Version, usage and configuration options:")); +#line 873 "../usage.c" + puts(_("\t\t\t\t- default option for unnamed options\n")); +#line 786 "../usage.c" + puts(_("\t\t\t\t- disabled as '--%s'\n")); +#line 1066 "../usage.c" + puts(_(" --- %-14s %s\n")); +#line 1064 "../usage.c" + puts(_("This option has been disabled")); +#line 813 "../usage.c" + puts(_("\t\t\t\t- enabled by default\n")); +#line 40 "../alias.c" + puts(_("%s error: only ")); +#line 1143 "../usage.c" + puts(_(" - examining environment variables named %s_*\n")); +#line 168 "../file.c" + puts(_("\t\t\t\t- file must not pre-exist\n")); +#line 172 "../file.c" + puts(_("\t\t\t\t- file must pre-exist\n")); +#line 329 "../usage.c" + puts(_("Options are specified by doubled hyphens and their name or by a single\n" + "hyphen and the flag character.\n")); +#line 882 "../makeshell.c" + puts(_("\n" + "= = = = = = = =\n\n" + "This incarnation of genshell will produce\n" + "a shell script to parse the options for %s:\n\n")); +#line 142 "../enum.c" + puts(_(" or an integer mask with any of the lower %d bits set\n")); +#line 846 "../usage.c" + puts(_("\t\t\t\t- is a set membership option\n")); +#line 867 "../usage.c" + puts(_("\t\t\t\t- must appear between %d and %d times\n")); +#line 331 "../usage.c" + puts(_("Options are specified by single or double hyphens and their name.\n")); +#line 853 "../usage.c" + puts(_("\t\t\t\t- may appear multiple times\n")); +#line 840 "../usage.c" + puts(_("\t\t\t\t- may not be preset\n")); +#line 1258 "../usage.c" + puts(_(" Arg Option-Name Description\n")); +#line 1194 "../usage.c" + puts(_(" Flg Arg Option-Name Description\n")); +#line 1252 "../usage.c" + puts(_(" Flg Arg Option-Name Description\n")); +#line 1253 "../usage.c" + puts(_(" %3s %s")); +#line 1259 "../usage.c" + puts(_(" %3s %s")); +#line 336 "../usage.c" + puts(_("The '-#' option may omit the hash char\n")); +#line 332 "../usage.c" + puts(_("All arguments are named options.\n")); +#line 920 "../usage.c" + puts(_(" - reading file %s")); +#line 358 "../usage.c" + puts(_("\n" + "Please send bug reports to: <%s>\n")); +#line 100 "../version.c" + puts(_("\n" + "Please send bug reports to: <%s>\n")); +#line 129 "../version.c" + puts(_("\n" + "Please send bug reports to: <%s>\n")); +#line 852 "../usage.c" + puts(_("\t\t\t\t- may NOT appear - preset only\n")); +#line 893 "../usage.c" + puts(_("\n" + "The following option preset mechanisms are supported:\n")); +#line 1141 "../usage.c" + puts(_("\n" + "The following option preset mechanisms are supported:\n")); +#line 631 "../usage.c" + puts(_("prohibits these options:\n")); +#line 626 "../usage.c" + puts(_("prohibits the option '%s'\n")); +#line 81 "../numeric.c" + puts(_("%s%ld to %ld")); +#line 79 "../numeric.c" + puts(_("%sgreater than or equal to %ld")); +#line 75 "../numeric.c" + puts(_("%s%ld exactly")); +#line 68 "../numeric.c" + puts(_("%sit must lie in one of the ranges:\n")); +#line 68 "../numeric.c" + puts(_("%sit must be in the range:\n")); +#line 88 "../numeric.c" + puts(_(", or\n")); +#line 66 "../numeric.c" + puts(_("%sis scalable with a suffix: k/K/m/M/g/G/t/T\n")); +#line 77 "../numeric.c" + puts(_("%sless than or equal to %ld")); +#line 339 "../usage.c" + puts(_("Operands and options may be intermixed. They will be reordered.\n")); +#line 601 "../usage.c" + puts(_("requires the option '%s'\n")); +#line 604 "../usage.c" + puts(_("requires these options:\n")); +#line 1270 "../usage.c" + puts(_(" Arg Option-Name Req? Description\n")); +#line 1264 "../usage.c" + puts(_(" Flg Arg Option-Name Req? Description\n")); +#line 143 "../enum.c" + puts(_("or you may use a numeric representation. Preceding these with a '!'\n" + "will clear the bits, specifying 'none' will clear all bits, and 'all'\n" + "will set them all. Multiple entries may be passed as an option\n" + "argument list.\n")); +#line 859 "../usage.c" + puts(_("\t\t\t\t- may appear up to %d times\n")); +#line 52 "../enum.c" + puts(_("The valid \"%s\" option keywords are:\n")); +#line 1101 "../usage.c" + puts(_("The next option supports vendor supported extra options:")); +#line 722 "../usage.c" + puts(_("These additional options are:")); + /* END-USAGE-TEXT */ +} +#endif /* XGETTEXT_SCAN_DO_NOT_COMPILE */ +#endif /* AUTOOPTS_USAGE_TXT_H_GUARD */ diff --git a/autoopts/boolean.c b/autoopts/boolean.c new file mode 100644 index 0000000..80e0b0e --- /dev/null +++ b/autoopts/boolean.c @@ -0,0 +1,95 @@ + +/** + * \file boolean.c + * + * Handle options with true/false values for arguments. + * + * @addtogroup autoopts + * @{ + */ +/* + * This routine will run run-on options through a pager so the + * user may examine, print or edit them at their leisure. + * + * This file is part of AutoOpts, a companion to AutoGen. + * AutoOpts is free software. + * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoOpts is available under any one of two licenses. The license + * in use must be one of these two and the choice is under the control + * of the user of the license. + * + * The GNU Lesser General Public License, version 3 or later + * See the files "COPYING.lgplv3" and "COPYING.gplv3" + * + * The Modified Berkeley Software Distribution License + * See the file "COPYING.mbsd" + * + * These files have the following sha256 sums: + * + * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 + * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 + * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + */ + +/*=export_func optionBooleanVal + * private: + * + * what: Decipher a boolean value + * arg: + tOptions * + opts + program options descriptor + + * arg: + tOptDesc * + od + the descriptor for this arg + + * + * doc: + * Decipher a true or false value for a boolean valued option argument. + * The value is true, unless it starts with 'n' or 'f' or "#f" or + * it is an empty string or it is a number that evaluates to zero. +=*/ +void +optionBooleanVal(tOptions * opts, tOptDesc * od) +{ + char * pz; + bool res = true; + + if (INQUERY_CALL(opts, od)) + return; + + if (od->optArg.argString == NULL) { + od->optArg.argBool = false; + return; + } + + switch (*(od->optArg.argString)) { + case '0': + { + long val = strtol(od->optArg.argString, &pz, 0); + if ((val != 0) || (*pz != NUL)) + break; + } + /* FALLTHROUGH */ + case 'N': + case 'n': + case 'F': + case 'f': + case NUL: + res = false; + break; + case '#': + if (od->optArg.argString[1] != 'f') + break; + res = false; + } + + if (od->fOptState & OPTST_ALLOC_ARG) { + AGFREE(od->optArg.argString); + od->fOptState &= ~OPTST_ALLOC_ARG; + } + od->optArg.argBool = res; +} +/** @} + * + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of autoopts/boolean.c */ diff --git a/autoopts/bootstrap.dir b/autoopts/bootstrap.dir new file mode 100644 index 0000000..8eb579e --- /dev/null +++ b/autoopts/bootstrap.dir @@ -0,0 +1,259 @@ +#! /bin/echo This_file_must_be_sourced,_not_executed +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + +burn_aover() { + agvars=$(egrep '^A[GO]_' ../VERSION) + eval "${agvars}" + vers_curr=$(expr '(' $AO_CURRENT '*' 4096 ')' + $AO_REVISION) + + cd tpl + for f in *.sh *.pl *.pm + do g=${f%.sh} ; g=${g%.pl} + test "$f" = "$g" || { + cat $f > $g + chmod +x $g + } + done + cd - +} + +add_files_to_mf() { + # Regenerate the "genshell.h" 'cuz we just altered the template to + # contain the header version number. + # + ${ag_aopts} -Tagman3.tpl funcs.def || \ + die "FAILED: ${ag_aopts} -Tagman3.tpl funcs.def" + + local tmpl=$( + ndst="" + sfil='' + pdta="autoopts.m4${nl}tpl/usage.tlib${nl}" + edta="bootstrap.dir${nl}autoopts-config.in${nl}autogen.map${nl}" + edta="${edta}mk-tpl-config.sh${nl}mk-autoopts-pc.in${nl}" + edta="${edta}install-hook.sh${nl}po${nl}" + + for f in man mdoc texi + do + for g in man mdoc texi + do + sfil=${sfil}tpl/${f}2${g}${nl} + done + done + + for f in tpl/*.* + do + case $f in + ( tpl-config* ) : ;; + + ( *.in | *.pl | *.sh ) + g=${f%.??} + g=${g//-tlib/.tlib} + ndst+=${g}${nl} # installed file + edta+=${f}${nl} # distributed file + ;; + + ( *tpl-config.tlib | *tpl/usage* ) : ;; + + ( *.tlib | *.tpl | *.def | *.lic | *.pm ) + pdta=${pdta}${f}${nl} ;; # installed & distributed file + esac + done + + echo "local ndst='${ndst%${nl}}'" + echo "local pdta='${pdta%${nl}}'" + echo "local edta='${edta%${nl}}'" + echo "local sfil='${sfil%${nl}}'" + ) + + eval "$tmpl" + + { + ls -1 *.3 | \ + sed '/^pathfind.3$/d' | \ + columns -I4 --spread=1 --line=' \' + + printf '\nnodist_pkgdata_DATA = $(libsrc) \\\n' + echo "${ndst}" | sort -u | columns -I4 --spread=1 --line=' \' + + printf '\nnodist_libdata_DATA = %s\n' tpl/tpl-config.tlib + + printf '\npkgdata_DATA = \\\n' + echo "${pdta}" | sort -u | columns -I4 --spread=1 --line=' \' + + printf '\nEXTRA_DATA = $(pkgdata_DATA) \\\n' + echo "${edta}" | sort -u | columns -I4 --spread=1 --line=' \' + + printf '\nGENSCRIPTS = $(srcdir)/funcs.def \\\n' + echo "${sfil}" | columns -I4 --spread=1 --line=' \' + echo + + sed -n '/^## begin/,/^## end/{ + s/^##.*// + /^$/d + p + }' gnulib.mk + + } > Makefile.lists + + sed '/^GENMAN /r Makefile.lists' Makefile.am.pre > Makefile.am + rm -f Makefile.lists gnulib.mk *.3 +} + +make_funcs_def() +{ + ${char_mapper:-char-mapper} autogen.map || die "FAILED: char-mapper" + ${ag_aopts} save-flags.def || die "cannot rebuild save-flags - exited $?" + ${ag_aopts} ao-strs.def || die "cannot make strings - exited $?" + + declare cmd_list=$( + sed -n '/case *XAT_CMD_/{;s/.*XAT_CMD_/cmd = /;s/:/;/;p;}' \ + configfile.c | tr '[A-Z_]' '[a-z-]') + + ${ag_aopts} <<- _EOF_ + AutoGen Definitions str2enum; + base-name = option-xat-attribute; + prefix = xat; + no-name; + $cmd_list + _EOF_ + test $? -eq 0 || \ + die "FAILED: option-xat-attribute enumeration" + + cmd_list=$( + sed -n '/case *VTP_CMD_/{;s/.*VTP_CMD_/cmd = /;s/:/;/;p;}' \ + configfile.c | tr '[A-Z_]' '[a-z-]') + ${ag_aopts} <<- _EOF_ + AutoGen Definitions str2enum; + base-name = option-value-type; + prefix = vtp; + no-name; + $cmd_list + _EOF_ + test $? -eq 0 || \ + die "FAILED: ${s2enum} --base-name=option-value-type" + burn_aover + + test -d autoopts || mkdir autoopts + test -d po || mkdir po + ${ag_aopts} genshell.def || \ + die "FAILED: ${ag_aopts} genshell.def" + + ${ag_aopts} usage-txt.def || \ + die "FAILED: ${ag_aopts} usage-txt.def" + mv -f usage-txt.h autoopts/. + mv -f usage-txt.pot po/. + + files=$(sed -n '/^CSRC/,/\.c$/p' Makefile.am.pre | \ + sed '/^CSRC/d;s/[=\\]//' + ) + + getdefs linenum srcfile template=options_h output=funcs.def $files + chmod u+w funcs.def + vers_min=$(expr '(' $AO_CURRENT - $AO_AGE ')' '*' 4096) + cat >> funcs.def <<- _END_VERS_INFO_ + vers-curr = "${vers_curr}"; + vers-min = "${vers_min}"; + vers-min-str = "$(expr $AO_CURRENT - $AO_AGE):0:0"; + vers-sovers = "${AO_SOVERS}"; + display-ver = "${AO_CURRENT}.${AO_REVISION}"; + library = opts; + + /* + * THIS FILE IS DISTRIBUTED + * + * This file is used to construct options.h + doc files. Because it is + * such a nuisance to get the build ordering correct, we distribute + * this. It should be constructed after all binaries are built. + */ + _END_VERS_INFO_ + + ${ag_aopts} funcs.def || \ + die "FAILED: ${ag_aopts} funcs.def" + test -f options.h || \ + die "options.h not created" + mv -f options.h autoopts/. + cp project.h autoopts/. + + add_files_to_mf + make_proto + + ${ag_aopts} aoconf.def || \ + die "FAILED: ${ag_aopts} aoconf.def" +} + +test "X${mainpid}" = X && { + echo SOURCING BOOTSTRAP.SHLIB + \cd ${top_srcdir-..} + top_srcdir=`pwd` + . config/bootstrap.shlib + cd autoopts + free_trap=true + echo DONE SOURCING BOOTSTRAP.SHLIB +} || { + free_trap=false +} + +${skip_gen} || \ + export ag_aopts=${AGexe-autogen}\ -L${top_srcdir}/autoopts/tpl + +case "$1" in +*genshell.c ) + if ${skip_gen} + then + test -f ${top_srcdir}/autoopts/genshell.c || \ + die "No autogen for building genshell.c" + else + ${ag_aopts} genshell.def || \ + die "FAILED: ${ag_aopts} genshell.def" + fi + ;; + +*libopts.texi ) + if ${skip_gen} + then + test -f ${top_srcdir}/autoopts/libopts.texi || \ + die "No autogen for building libopts.texi" + else + agopts='-Taginfo3.tpl -DLEVEL=subsection -blibopts funcs.def' + ${ag_aopts} ${agopts} || \ + die "FAILED: ${ag_aopts} ${agopts}" + fi + ;; + +aoconf ) + if ${skip_gen} + then untar_touch gen-src.tgz + else make_funcs_def + fi || die "could not rebuild files in $PWD" + ;; +esac + +${free_trap} && trap '' 0 +true + +# Local Variables: +# mode:shell-script +# sh-indentation:4 +# sh-basic-offset:4 +# indent-tabs-mode: nil +# End: + +# bootstrap.dir ends here diff --git a/autoopts/check.c b/autoopts/check.c new file mode 100644 index 0000000..7e75e7e --- /dev/null +++ b/autoopts/check.c @@ -0,0 +1,177 @@ +/** + * @file check.c + * + * @brief option consistency checks. + * + * @addtogroup autoopts + * @{ + */ +/* + * This file is part of AutoOpts, a companion to AutoGen. + * AutoOpts is free software. + * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoOpts is available under any one of two licenses. The license + * in use must be one of these two and the choice is under the control + * of the user of the license. + * + * The GNU Lesser General Public License, version 3 or later + * See the files "COPYING.lgplv3" and "COPYING.gplv3" + * + * The Modified Berkeley Software Distribution License + * See the file "COPYING.mbsd" + * + * These files have the following sha256 sums: + * + * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 + * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 + * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + */ + +/** + * Check for conflicts based on "must" and "cannot" attributes. + */ +static bool +has_conflict(tOptions * pOpts, tOptDesc * od) +{ + if (od->pOptMust != NULL) { + int const * must = od->pOptMust; + + while (*must != NO_EQUIVALENT) { + tOptDesc * p = pOpts->pOptDesc + *(must++); + if (UNUSED_OPT(p)) { + const tOptDesc * ood = pOpts->pOptDesc + must[-1]; + fprintf(stderr, zneed_fmt, pOpts->pzProgName, + od->pz_Name, ood->pz_Name); + return true; + } + } + } + + if (od->pOptCant != NULL) { + int const * cant = od->pOptCant; + + while (*cant != NO_EQUIVALENT) { + tOptDesc * p = pOpts->pOptDesc + *(cant++); + if (SELECTED_OPT(p)) { + const tOptDesc * ood = pOpts->pOptDesc + cant[-1]; + fprintf(stderr, zconflict_fmt, pOpts->pzProgName, + od->pz_Name, ood->pz_Name); + return true; + } + } + } + + return false; +} + +/** + * Check that the option occurs often enough. Too often is already checked. + */ +static bool +occurs_enough(tOptions * pOpts, tOptDesc * pOD) +{ + (void)pOpts; + + /* + * IF the occurrence counts have been satisfied, + * THEN there is no problem. + */ + if (pOD->optOccCt >= pOD->optMinCt) + return true; + + /* + * IF MUST_SET means SET and PRESET are okay, + * so min occurrence count doesn't count + */ + if ( (pOD->fOptState & OPTST_MUST_SET) + && (pOD->fOptState & (OPTST_PRESET | OPTST_SET)) ) + return true; + + if (pOD->optMinCt > 1) + fprintf(stderr, zneed_more, pOpts->pzProgName, pOD->pz_Name, + pOD->optMinCt); + else fprintf(stderr, zneed_one, pOpts->pzProgName, pOD->pz_Name); + return false; +} + +/** + * Verify option consistency. + * + * Make sure that the argument list passes our consistency tests. + */ +static bool +is_consistent(tOptions * pOpts) +{ + tOptDesc * pOD = pOpts->pOptDesc; + int oCt = pOpts->presetOptCt; + + /* + * FOR each of "oCt" options, ... + */ + for (;;) { + /* + * IF the current option was provided on the command line + * THEN ensure that any "MUST" requirements are not + * "DEFAULT" (unspecified) *AND* ensure that any + * "CANT" options have not been SET or DEFINED. + */ + if (SELECTED_OPT(pOD)) { + if (has_conflict(pOpts, pOD)) + return false; + } + + /* + * IF this option is not equivalenced to another, + * OR it is equivalenced to itself (is the equiv. root) + * THEN we need to make sure it occurs often enough. + */ + if ( (pOD->optEquivIndex == NO_EQUIVALENT) + || (pOD->optEquivIndex == pOD->optIndex) ) + + if (! occurs_enough(pOpts, pOD)) + return false; + + if (--oCt <= 0) + break; + pOD++; + } + + /* + * IF we are stopping on errors, check to see if any remaining + * arguments are required to be there or prohibited from being there. + */ + if ((pOpts->fOptSet & OPTPROC_ERRSTOP) != 0) { + + /* + * Check for prohibition + */ + if ((pOpts->fOptSet & OPTPROC_NO_ARGS) != 0) { + if (pOpts->origArgCt > pOpts->curOptIdx) { + fprintf(stderr, zNoArgs, pOpts->pzProgName); + return false; + } + } + + /* + * ELSE not prohibited, check for being required + */ + else if ((pOpts->fOptSet & OPTPROC_ARGS_REQ) != 0) { + if (pOpts->origArgCt <= pOpts->curOptIdx) { + fprintf(stderr, zargs_must, pOpts->pzProgName); + return false; + } + } + } + + return true; +} + +/** @} + * + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of autoopts/check.c */ diff --git a/autoopts/configFileLoad.3 b/autoopts/configFileLoad.3 new file mode 100644 index 0000000..5a85983 --- /dev/null +++ b/autoopts/configFileLoad.3 @@ -0,0 +1,50 @@ +.TH configFileLoad 3 2018-08-26 "" "Programmer's Manual" +.\" DO NOT EDIT THIS FILE (configFileLoad.3) +.\" +.\" It has been AutoGen-ed +.\" From the definitions ./funcs.def +.\" and the template file agman3.tpl +.SH NAME +configFileLoad - parse a configuration file +.sp 1 +.SH SYNOPSIS + +#include <\fIyour-opts.h\fP> +.br +cc [...] -o outfile infile.c -l\fBopts\fP [...] +.sp 1 +const tOptionValue * \fBconfigFileLoad\fP(char const * \fIfname\fP); +.sp 1 +.SH DESCRIPTION +This routine will load a named configuration file and parse the +text as a hierarchically valued option. The option descriptor +created from an option definition file is not used via this interface. +The returned value is "named" with the input file name and is of +type "\fBOPARG_TYPE_HIERARCHY\fP". It may be used in calls to +\fBoptionGetValue()\fP, \fBoptionNextValue()\fP and +\fBoptionUnloadNested()\fP. +.TP +.IR fname +the file to load +.sp 1 +.SH RETURN VALUE +An allocated, compound value structure +.sp 1 +.SH ERRORS +If the file cannot be loaded or processed, \fBNULL\fP is returned and +\fBerrno\fP is set. It may be set by a call to either \fBopen(2)\fP +\fBmmap(2)\fP or other file system calls, or it may be: +.sp 1ize @bullet +.sp 1 +\fBENOENT\fP \- the file was not found. +.sp 1 +\fBENOMSG\fP \- the file was empty. +.sp 1 +\fBEINVAL\fP \- the file contents are invalid \-- not properly formed. +.sp 1 +\fBENOMEM\fP \- not enough memory to allocate the needed structures. +@end itemize +.SH SEE ALSO +The \fIinfo\fP documentation for the -l\fIopts\fP library. +.br +ao_string_tokenize(3), optionFileLoad(3), optionFindNextValue(3), optionFindValue(3), optionFree(3), optionGetValue(3), optionLoadLine(3), optionMemberList(3), optionNextValue(3), optionOnlyUsage(3), optionPrintVersion(3), optionPrintVersionAndReturn(3), optionProcess(3), optionRestore(3), optionSaveFile(3), optionSaveState(3), optionUnloadNested(3), optionVersion(3), strequate(3), streqvcmp(3), streqvmap(3), strneqvcmp(3), strtransform(3), diff --git a/autoopts/configfile.c b/autoopts/configfile.c new file mode 100644 index 0000000..783a9d8 --- /dev/null +++ b/autoopts/configfile.c @@ -0,0 +1,1337 @@ +/** + * \file configfile.c + * + * configuration/rc/ini file handling. + * + * @addtogroup autoopts + * @{ + */ +/* + * This file is part of AutoOpts, a companion to AutoGen. + * AutoOpts is free software. + * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoOpts is available under any one of two licenses. The license + * in use must be one of these two and the choice is under the control + * of the user of the license. + * + * The GNU Lesser General Public License, version 3 or later + * See the files "COPYING.lgplv3" and "COPYING.gplv3" + * + * The Modified Berkeley Software Distribution License + * See the file "COPYING.mbsd" + * + * These files have the following sha256 sums: + * + * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 + * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 + * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + */ + +/** + * Skip over some unknown attribute + * @param[in] txt start of skpped text + * @returns character after skipped text + */ +inline static char const * +skip_unkn(char const * txt) +{ + txt = BRK_END_XML_TOKEN_CHARS(txt); + return (*txt == NUL) ? NULL : txt; +} + +/*=export_func configFileLoad + * + * what: parse a configuration file + * arg: + char const * + fname + the file to load + + * + * ret_type: const tOptionValue * + * ret_desc: An allocated, compound value structure + * + * doc: + * This routine will load a named configuration file and parse the + * text as a hierarchically valued option. The option descriptor + * created from an option definition file is not used via this interface. + * The returned value is "named" with the input file name and is of + * type "@code{OPARG_TYPE_HIERARCHY}". It may be used in calls to + * @code{optionGetValue()}, @code{optionNextValue()} and + * @code{optionUnloadNested()}. + * + * err: + * If the file cannot be loaded or processed, @code{NULL} is returned and + * @var{errno} is set. It may be set by a call to either @code{open(2)} + * @code{mmap(2)} or other file system calls, or it may be: + * @itemize @bullet + * @item + * @code{ENOENT} - the file was not found. + * @item + * @code{ENOMSG} - the file was empty. + * @item + * @code{EINVAL} - the file contents are invalid -- not properly formed. + * @item + * @code{ENOMEM} - not enough memory to allocate the needed structures. + * @end itemize +=*/ +const tOptionValue * +configFileLoad(char const * fname) +{ + tmap_info_t cfgfile; + tOptionValue * res = NULL; + tOptionLoadMode save_mode = option_load_mode; + + char * txt = text_mmap(fname, PROT_READ, MAP_PRIVATE, &cfgfile); + + if (TEXT_MMAP_FAILED_ADDR(txt)) + return NULL; /* errno is set */ + + option_load_mode = OPTION_LOAD_COOKED; + res = optionLoadNested(txt, fname, strlen(fname)); + + if (res == NULL) { + int err = errno; + text_munmap(&cfgfile); + errno = err; + } else + text_munmap(&cfgfile); + + option_load_mode = save_mode; + return res; +} + + +/*=export_func optionFindValue + * + * what: find a hierarcicaly valued option instance + * arg: + const tOptDesc * + odesc + an option with a nested arg type + + * arg: + char const * + name + name of value to find + + * arg: + char const * + val + the matching value + + * + * ret_type: const tOptionValue * + * ret_desc: a compound value structure + * + * doc: + * This routine will find an entry in a nested value option or configurable. + * It will search through the list and return a matching entry. + * + * err: + * The returned result is NULL and errno is set: + * @itemize @bullet + * @item + * @code{EINVAL} - the @code{pOptValue} does not point to a valid + * hierarchical option value. + * @item + * @code{ENOENT} - no entry matched the given name. + * @end itemize +=*/ +const tOptionValue * +optionFindValue(const tOptDesc * odesc, char const * name, char const * val) +{ + const tOptionValue * res = NULL; + + if ( (odesc == NULL) + || (OPTST_GET_ARGTYPE(odesc->fOptState) != OPARG_TYPE_HIERARCHY)) { + errno = EINVAL; + } + + else if (odesc->optCookie == NULL) { + errno = ENOENT; + } + + else do { + tArgList * argl = odesc->optCookie; + int argct = argl->useCt; + void ** poptv = (void **)(argl->apzArgs); + + if (argct == 0) { + errno = ENOENT; + break; + } + + if (name == NULL) { + res = (tOptionValue *)*poptv; + break; + } + + while (--argct >= 0) { + const tOptionValue * ov = *(poptv++); + const tOptionValue * rv = optionGetValue(ov, name); + + if (rv == NULL) + continue; + + if (val == NULL) { + res = ov; + break; + } + } + if (res == NULL) + errno = ENOENT; + } while (false); + + return res; +} + + +/*=export_func optionFindNextValue + * + * FIXME: the handling of 'pzName' and 'pzVal' is just wrong. + * + * what: find a hierarcicaly valued option instance + * arg: + const tOptDesc * + odesc + an option with a nested arg type + + * arg: + const tOptionValue * + pPrevVal + the last entry + + * arg: + char const * + name + name of value to find + + * arg: + char const * + value + the matching value + + * + * ret_type: const tOptionValue * + * ret_desc: a compound value structure + * + * doc: + * This routine will find the next entry in a nested value option or + * configurable. It will search through the list and return the next entry + * that matches the criteria. + * + * err: + * The returned result is NULL and errno is set: + * @itemize @bullet + * @item + * @code{EINVAL} - the @code{pOptValue} does not point to a valid + * hierarchical option value. + * @item + * @code{ENOENT} - no entry matched the given name. + * @end itemize +=*/ +tOptionValue const * +optionFindNextValue(const tOptDesc * odesc, const tOptionValue * pPrevVal, + char const * pzName, char const * pzVal) +{ + bool old_found = false; + tOptionValue * res = NULL; + + (void)pzName; + (void)pzVal; + + if ( (odesc == NULL) + || (OPTST_GET_ARGTYPE(odesc->fOptState) != OPARG_TYPE_HIERARCHY)) { + errno = EINVAL; + } + + else if (odesc->optCookie == NULL) { + errno = ENOENT; + } + + else do { + tArgList * argl = odesc->optCookie; + int ct = argl->useCt; + void ** poptv = (void **)argl->apzArgs; + + while (--ct >= 0) { + tOptionValue * pOV = *(poptv++); + if (old_found) { + res = pOV; + break; + } + if (pOV == pPrevVal) + old_found = true; + } + if (res == NULL) + errno = ENOENT; + } while (false); + + return res; +} + + +/*=export_func optionGetValue + * + * what: get a specific value from a hierarcical list + * arg: + const tOptionValue * + pOptValue + a hierarchcal value + + * arg: + char const * + valueName + name of value to get + + * + * ret_type: const tOptionValue * + * ret_desc: a compound value structure + * + * doc: + * This routine will find an entry in a nested value option or configurable. + * If "valueName" is NULL, then the first entry is returned. Otherwise, + * the first entry with a name that exactly matches the argument will be + * returned. If there is no matching value, NULL is returned and errno is + * set to ENOENT. If the provided option value is not a hierarchical value, + * NULL is also returned and errno is set to EINVAL. + * + * err: + * The returned result is NULL and errno is set: + * @itemize @bullet + * @item + * @code{EINVAL} - the @code{pOptValue} does not point to a valid + * hierarchical option value. + * @item + * @code{ENOENT} - no entry matched the given name. + * @end itemize +=*/ +tOptionValue const * +optionGetValue(tOptionValue const * oov, char const * vname) +{ + tArgList * arg_list; + tOptionValue * res = NULL; + + if ((oov == NULL) || (oov->valType != OPARG_TYPE_HIERARCHY)) { + errno = EINVAL; + return res; + } + arg_list = oov->v.nestVal; + + if (arg_list->useCt > 0) { + int ct = arg_list->useCt; + void ** ovlist = (void **)(arg_list->apzArgs); + + if (vname == NULL) { + res = (tOptionValue *)*ovlist; + + } else do { + tOptionValue * opt_val = *(ovlist++); + if (strcmp(opt_val->pzName, vname) == 0) { + res = opt_val; + break; + } + } while (--ct > 0); + } + if (res == NULL) + errno = ENOENT; + return res; +} + +/*=export_func optionNextValue + * + * what: get the next value from a hierarchical list + * arg: + const tOptionValue * + pOptValue + a hierarchcal list value + + * arg: + const tOptionValue * + pOldValue + a value from this list + + * + * ret_type: const tOptionValue * + * ret_desc: a compound value structure + * + * doc: + * This routine will return the next entry after the entry passed in. At the + * end of the list, NULL will be returned. If the entry is not found on the + * list, NULL will be returned and "@var{errno}" will be set to EINVAL. + * The "@var{pOldValue}" must have been gotten from a prior call to this + * routine or to "@code{opitonGetValue()}". + * + * err: + * The returned result is NULL and errno is set: + * @itemize @bullet + * @item + * @code{EINVAL} - the @code{pOptValue} does not point to a valid + * hierarchical option value or @code{pOldValue} does not point to a + * member of that option value. + * @item + * @code{ENOENT} - the supplied @code{pOldValue} pointed to the last entry. + * @end itemize +=*/ +tOptionValue const * +optionNextValue(tOptionValue const * ov_list,tOptionValue const * oov ) +{ + tArgList * arg_list; + tOptionValue * res = NULL; + int err = EINVAL; + + if ((ov_list == NULL) || (ov_list->valType != OPARG_TYPE_HIERARCHY)) { + errno = EINVAL; + return NULL; + } + arg_list = ov_list->v.nestVal; + { + int ct = arg_list->useCt; + void ** o_list = (void **)(arg_list->apzArgs); + + while (ct-- > 0) { + tOptionValue * nov = *(o_list++); + if (nov == oov) { + if (ct == 0) { + err = ENOENT; + + } else { + err = 0; + res = (tOptionValue *)*o_list; + } + break; + } + } + } + if (err != 0) + errno = err; + return res; +} + +/** + * Load a file containing presetting information (a configuration file). + */ +static void +file_preset(tOptions * opts, char const * fname, int dir) +{ + tmap_info_t cfgfile; + tOptState optst = OPTSTATE_INITIALIZER(PRESET); + opt_state_mask_t st_flags = optst.flags; + opt_state_mask_t fl_save = opts->fOptSet; + char * ftext = + text_mmap(fname, PROT_READ|PROT_WRITE, MAP_PRIVATE, &cfgfile); + + if (TEXT_MMAP_FAILED_ADDR(ftext)) + return; + + /* + * While processing config files, we ignore errors. + */ + opts->fOptSet &= ~OPTPROC_ERRSTOP; + + if (dir == DIRECTION_CALLED) { + st_flags = OPTST_DEFINED; + dir = DIRECTION_PROCESS; + } + + /* + * IF this is called via "optionProcess", then we are presetting. + * This is the default and the PRESETTING bit will be set. + * If this is called via "optionFileLoad", then the bit is not set + * and we consider stuff set herein to be "set" by the client program. + */ + if ((opts->fOptSet & OPTPROC_PRESETTING) == 0) + st_flags = OPTST_SET; + + do { + optst.flags = st_flags; + ftext = SPN_WHITESPACE_CHARS(ftext); + + if (IS_VAR_FIRST_CHAR(*ftext)) { + ftext = handle_cfg(opts, &optst, ftext, dir); + + } else switch (*ftext) { + case '<': + if (IS_VAR_FIRST_CHAR(ftext[1])) + ftext = handle_struct(opts, &optst, ftext, dir); + + else switch (ftext[1]) { + case '?': + ftext = handle_directive(opts, ftext); + break; + + case '!': + ftext = handle_comment(ftext); + break; + + case '/': + ftext = strchr(ftext + 2, '>'); + if (ftext++ != NULL) + break; + /* FALLTHROUGH */ + + default: + ftext = NULL; + } + if (ftext == NULL) + goto all_done; + break; + + case '[': + ftext = handle_section(opts, ftext); + break; + + case '#': + ftext = strchr(ftext + 1, NL); + break; + + default: + goto all_done; /* invalid format */ + } + } while (ftext != NULL); + + all_done: + text_munmap(&cfgfile); + opts->fOptSet = fl_save; +} + +/** + * "txt" points to a "". + */ +static char * +handle_comment(char * txt) +{ + char * pz = strstr(txt, "-->"); + if (pz != NULL) + pz += 3; + return pz; +} + +/** + * "txt" points to the start of some value name. + * The end of the entry is the end of the line that is not preceded by + * a backslash escape character. The string value is always processed + * in "cooked" mode. + */ +static char * +handle_cfg(tOptions * opts, tOptState * ost, char * txt, int dir) +{ + char * pzName = txt++; + char * pzEnd = strchr(txt, NL); + + if (pzEnd == NULL) + return txt + strlen(txt); + + txt = SPN_VALUE_NAME_CHARS(txt); + txt = SPN_WHITESPACE_CHARS(txt); + if (txt > pzEnd) { + name_only: + *pzEnd++ = NUL; + load_opt_line(opts, ost, pzName, dir, OPTION_LOAD_UNCOOKED); + return pzEnd; + } + + /* + * Either the first character after the name is a ':' or '=', + * or else we must have skipped over white space. Anything else + * is an invalid format and we give up parsing the text. + */ + if ((*txt == '=') || (*txt == ':')) { + txt = SPN_WHITESPACE_CHARS(txt+1); + if (txt > pzEnd) + goto name_only; + } else if (! IS_WHITESPACE_CHAR(txt[-1])) + return NULL; + + /* + * IF the value is continued, remove the backslash escape and push "pzEnd" + * on to a newline *not* preceded by a backslash. + */ + if (pzEnd[-1] == '\\') { + char * pcD = pzEnd-1; + char * pcS = pzEnd; + + for (;;) { + char ch = *(pcS++); + switch (ch) { + case NUL: + pcS = NULL; + /* FALLTHROUGH */ + + case NL: + *pcD = NUL; + pzEnd = pcS; + goto copy_done; + + case '\\': + if (*pcS == NL) + ch = *(pcS++); + /* FALLTHROUGH */ + default: + *(pcD++) = ch; + } + } copy_done:; + + } else { + /* + * The newline was not preceded by a backslash. NUL it out + */ + *(pzEnd++) = NUL; + } + + /* + * "pzName" points to what looks like text for one option/configurable. + * It is NUL terminated. Process it. + */ + load_opt_line(opts, ost, pzName, dir, OPTION_LOAD_UNCOOKED); + + return pzEnd; +} + +/** + * "txt" points to a "'); + if (txt != NULL) + txt++; + return txt; +# undef DIRECTIVE_TABLE +} + +/** + * handle AutoOpts mode flags. + * + * @param[in,out] opts program option descriptor + * @param[in] txt scanning pointer + * @returns the next character to look at + */ +static char * +aoflags_directive(tOptions * opts, char * txt) +{ + char * pz; + + pz = SPN_WHITESPACE_CHARS(txt+1); + txt = strchr(pz, '>'); + if (txt != NULL) { + + size_t len = (unsigned)(txt - pz); + char * ftxt = AGALOC(len + 1, "aoflags"); + + memcpy(ftxt, pz, len); + ftxt[len] = NUL; + set_usage_flags(opts, ftxt); + AGFREE(ftxt); + + txt++; + } + + return txt; +} + +/** + * handle program segmentation of config file. + * + * @param[in,out] opts program option descriptor + * @param[in] txt scanning pointer + * @returns the next character to look at + */ +static char * +program_directive(tOptions * opts, char * txt) +{ + size_t name_len = strlen(opts->pzProgName); + + for (;; txt += zCfgProg_LEN) { + txt = SPN_WHITESPACE_CHARS(txt); + + if ( (strneqvcmp(txt, opts->pzProgName, (int)name_len) == 0) + && (IS_END_XML_TOKEN_CHAR(txt[name_len])) ) + + return txt + name_len; + + txt = strstr(txt, zCfgProg); + if (txt == NULL) + return txt; + } + + for (;;) { + if (*txt == NUL) + return NULL; + + if (*(txt++) == '>') + return txt; + } +} + +/** + * "txt" points to a '[' character. + * The "traditional" [PROG_NAME] segmentation of the config file. + * Do not ever mix with the "" variation. + * The templates reject program names over 16 characters. + * + * @param[in,out] opts program option descriptor + * @param[in] txt scanning pointer + * @returns the next character to look at + */ +static char * +handle_section(tOptions * opts, char * txt) +{ + size_t len = strlen(opts->pzPROGNAME); + if ( (strncmp(txt+1, opts->pzPROGNAME, len) == 0) + && (txt[len+1] == ']')) + return strchr(txt + len + 2, NL); + + if (len > 16) + return NULL; + + { + char z[24] = "["; + memcpy(z+1, opts->pzPROGNAME, len); + z[++len] = ']'; + z[++len] = NUL; + txt = strstr(txt, z); + } + + if (txt != NULL) + txt = strchr(txt, NL); + return txt; +} + +/** + * parse XML encodings + */ +static int +parse_xml_encoding(char ** ppz) +{ +# define XMLTABLE \ + _xmlNm_(amp, '&') \ + _xmlNm_(lt, '<') \ + _xmlNm_(gt, '>') \ + _xmlNm_(ff, '\f') \ + _xmlNm_(ht, '\t') \ + _xmlNm_(cr, '\r') \ + _xmlNm_(vt, '\v') \ + _xmlNm_(bel, '\a') \ + _xmlNm_(nl, NL) \ + _xmlNm_(space, ' ') \ + _xmlNm_(quot, '"') \ + _xmlNm_(apos, '\'') + + static struct { + char const * const nm_str; + unsigned short nm_len; + short nm_val; + } const xml_names[] = { +# define _xmlNm_(_n, _v) { #_n ";", sizeof(#_n), _v }, + XMLTABLE +# undef _xmlNm_ +# undef XMLTABLE + }; + + static int const nm_ct = sizeof(xml_names) / sizeof(xml_names[0]); + int base = 10; + + char * pz = *ppz; + + if (*pz == '#') { + pz++; + goto parse_number; + } + + if (IS_DEC_DIGIT_CHAR(*pz)) { + unsigned long v; + + parse_number: + switch (*pz) { + case 'x': case 'X': + /* + * Some forms specify hex with: &#xNN; + */ + base = 16; + pz++; + break; + + case '0': + /* + *  is hex and  is decimal. Cool. + * Ya gotta love it. + */ + if (pz[1] == '0') + base = 16; + break; + } + + v = strtoul(pz, &pz, base); + if ((*pz != ';') || (v > 0x7F)) + return NUL; + *ppz = pz + 1; + return (int)v; + } + + { + int ix = 0; + do { + if (strncmp(pz, xml_names[ix].nm_str, xml_names[ix].nm_len) + == 0) { + *ppz = pz + xml_names[ix].nm_len; + return xml_names[ix].nm_val; + } + } while (++ix < nm_ct); + } + + return NUL; +} + +/** + * Find the end marker for the named section of XML. + * Trim that text there, trimming trailing white space for all modes + * except for OPTION_LOAD_UNCOOKED. + */ +static char * +trim_xml_text(char * intxt, char const * pznm, tOptionLoadMode mode) +{ + size_t nm_len = strlen(pznm); + char * etext; + + { + char z[64], *pz = z; + + if (nm_len + 4 >= sizeof(z)) + pz = AGALOC(nm_len + 4, "scan name"); + + pz[0] = '<'; + pz[1] = '/'; + memcpy(pz+2, pznm, nm_len); + nm_len += 2; + pz[nm_len++] = '>'; + pz[nm_len] = NUL; + + *intxt = ' '; + etext = strstr(intxt, pz); + if (pz != z) AGFREE(pz); + } + + if (etext == NULL) + return etext; + + { + char * result = etext + nm_len; + + if (mode != OPTION_LOAD_UNCOOKED) + etext = SPN_WHITESPACE_BACK(intxt, etext); + + *etext = NUL; + return result; + } +} + +/** + */ +static void +cook_xml_text(char * pzData) +{ + char * pzs = pzData; + char * pzd = pzData; + char bf[4]; + bf[2] = NUL; + + for (;;) { + int ch = ((int)*(pzs++)) & 0xFF; + switch (ch) { + case NUL: + *pzd = NUL; + return; + + case '&': + ch = parse_xml_encoding(&pzs); + *(pzd++) = (char)ch; + if (ch == NUL) + return; + break; + + case '%': + bf[0] = *(pzs++); + bf[1] = *(pzs++); + if ((bf[0] == NUL) || (bf[1] == NUL)) { + *pzd = NUL; + return; + } + + ch = (int)strtoul(bf, NULL, 16); + /* FALLTHROUGH */ + + default: + *(pzd++) = (char)ch; + } + } +} + +/** + * "txt" points to a '<' character, followed by an alpha. + * The end of the entry is either the "/>" following the name, or else a + * "" string. + */ +static char * +handle_struct(tOptions * opts, tOptState * ost, char * txt, int dir) +{ + tOptionLoadMode mode = option_load_mode; + tOptionValue valu; + + char * pzName = ++txt; + char * pzData; + char * pcNulPoint; + + txt = SPN_VALUE_NAME_CHARS(txt); + pcNulPoint = txt; + valu.valType = OPARG_TYPE_STRING; + + switch (*txt) { + case ' ': + case '\t': + txt = VOIDP(parse_attrs( + opts, SPN_WHITESPACE_CHARS(txt), &mode, &valu)); + if (txt == NULL) + return txt; + if (*txt == '>') + break; + if (*txt != '/') + return NULL; + /* FALLTHROUGH */ + + case '/': + if (txt[1] != '>') + return NULL; + *txt = NUL; + txt += 2; + load_opt_line(opts, ost, pzName, dir, mode); + return txt; + + case '>': + break; + + default: + txt = strchr(txt, '>'); + if (txt != NULL) + txt++; + return txt; + } + + /* + * If we are here, we have a value. "txt" points to a closing angle + * bracket. Separate the name from the value for a moment. + */ + *pcNulPoint = NUL; + pzData = ++txt; + txt = trim_xml_text(txt, pzName, mode); + if (txt == NULL) + return txt; + + /* + * Rejoin the name and value for parsing by "load_opt_line()". + * Erase any attributes parsed by "parse_attrs()". + */ + memset(pcNulPoint, ' ', (size_t)(pzData - pcNulPoint)); + + /* + * If we are getting a "string" value that is to be cooked, + * then process the XML-ish &xx; XML-ish and %XX hex characters. + */ + if ( (valu.valType == OPARG_TYPE_STRING) + && (mode == OPTION_LOAD_COOKED)) + cook_xml_text(pzData); + + /* + * "pzName" points to what looks like text for one option/configurable. + * It is NUL terminated. Process it. + */ + load_opt_line(opts, ost, pzName, dir, mode); + + return txt; +} + +/** + * Load a configuration file. This may be invoked either from + * scanning the "homerc" list, or from a specific file request. + * (see "optionFileLoad()", the implementation for --load-opts) + */ +static void +intern_file_load(tOptions * opts) +{ + uint32_t svfl; + int idx; + int inc; + char f_name[ AG_PATH_MAX+1 ]; + + if (opts->papzHomeList == NULL) + return; + + svfl = opts->fOptSet; + inc = DIRECTION_PRESET; + + /* + * Never stop on errors in config files. + */ + opts->fOptSet &= ~OPTPROC_ERRSTOP; + + /* + * Find the last RC entry (highest priority entry) + */ + for (idx = 0; opts->papzHomeList[ idx+1 ] != NULL; ++idx) ; + + /* + * For every path in the home list, ... *TWICE* We start at the last + * (highest priority) entry, work our way down to the lowest priority, + * handling the immediate options. + * Then we go back up, doing the normal options. + */ + for (;;) { + struct stat sb; + cch_t * path; + + /* + * IF we've reached the bottom end, change direction + */ + if (idx < 0) { + inc = DIRECTION_PROCESS; + idx = 0; + } + + path = opts->papzHomeList[ idx ]; + + /* + * IF we've reached the top end, bail out + */ + if (path == NULL) + break; + + idx += inc; + + if (! optionMakePath(f_name, (int)sizeof(f_name), + path, opts->pzProgPath)) + continue; + + /* + * IF the file name we constructed is a directory, + * THEN append the Resource Configuration file name + * ELSE we must have the complete file name + */ + if (stat(f_name, &sb) != 0) + continue; /* bogus name - skip the home list entry */ + + if (S_ISDIR(sb.st_mode)) { + size_t len = strlen(f_name); + size_t nln = strlen(opts->pzRcName) + 1; + char * pz = f_name + len; + + if (len + 1 + nln >= sizeof(f_name)) + continue; + + if (pz[-1] != DIRCH) + *(pz++) = DIRCH; + memcpy(pz, opts->pzRcName, nln); + } + + file_preset(opts, f_name, inc); + + /* + * IF we are now to skip config files AND we are presetting, + * THEN change direction. We must go the other way. + */ + { + tOptDesc * od = opts->pOptDesc + opts->specOptIdx.save_opts + 1; + if (DISABLED_OPT(od) && PRESETTING(inc)) { + idx -= inc; /* go back and reprocess current file */ + inc = DIRECTION_PROCESS; + } + } + } /* twice for every path in the home list, ... */ + + opts->fOptSet = svfl; +} + +/*=export_func optionFileLoad + * + * what: Load the locatable config files, in order + * + * arg: + tOptions * + opts + program options descriptor + + * arg: + char const * + prog + program name + + * + * ret_type: int + * ret_desc: 0 -> SUCCESS, -1 -> FAILURE + * + * doc: + * + * This function looks in all the specified directories for a configuration + * file ("rc" file or "ini" file) and processes any found twice. The first + * time through, they are processed in reverse order (last file first). At + * that time, only "immediate action" configurables are processed. For + * example, if the last named file specifies not processing any more + * configuration files, then no more configuration files will be processed. + * Such an option in the @strong{first} named directory will have no effect. + * + * Once the immediate action configurables have been handled, then the + * directories are handled in normal, forward order. In that way, later + * config files can override the settings of earlier config files. + * + * See the AutoOpts documentation for a thorough discussion of the + * config file format. + * + * Configuration files not found or not decipherable are simply ignored. + * + * err: Returns the value, "-1" if the program options descriptor + * is out of date or indecipherable. Otherwise, the value "0" will + * always be returned. +=*/ +int +optionFileLoad(tOptions * opts, char const * prog) +{ + if (! SUCCESSFUL(validate_struct(opts, prog))) + return -1; + + /* + * The pointer to the program name is "const". However, the + * structure is in writable memory, so we coerce the address + * of this pointer to point to writable memory. + */ + { + char const ** pp = VOIDP(&(opts->pzProgName)); + *pp = prog; + } + + intern_file_load(opts); + return 0; +} + +/*=export_func optionLoadOpt + * private: + * + * what: Load an option rc/ini file + * arg: + tOptions * + opts + program options descriptor + + * arg: + tOptDesc * + odesc + the descriptor for this arg + + * + * doc: + * Processes the options found in the file named with + * odesc->optArg.argString. +=*/ +void +optionLoadOpt(tOptions * opts, tOptDesc * odesc) +{ + struct stat sb; + + if (opts <= OPTPROC_EMIT_LIMIT) + return; + + /* + * IF the option is not being disabled, THEN load the file. There must + * be a file. (If it is being disabled, then the disablement processing + * already took place. It must be done to suppress preloading of ini/rc + * files.) + */ + if ( DISABLED_OPT(odesc) + || ((odesc->fOptState & OPTST_RESET) != 0)) + return; + + if (stat(odesc->optArg.argString, &sb) != 0) { + if ((opts->fOptSet & OPTPROC_ERRSTOP) == 0) + return; + + fserr_exit(opts->pzProgName, "stat", odesc->optArg.argString); + /* NOT REACHED */ + } + + if (! S_ISREG(sb.st_mode)) { + if ((opts->fOptSet & OPTPROC_ERRSTOP) == 0) + return; + errno = EINVAL; + fserr_exit(opts->pzProgName, "stat", odesc->optArg.argString); + /* NOT REACHED */ + } + + file_preset(opts, odesc->optArg.argString, DIRECTION_CALLED); +} + +/** + * Parse the various attributes of an XML-styled config file entry + * + * @returns NULL on failure, otherwise the scan point + */ +static char const * +parse_attrs(tOptions * opts, char const * txt, tOptionLoadMode * pMode, + tOptionValue * pType) +{ + size_t len = 0; + + for (;;) { + len = (size_t)(SPN_LOWER_CASE_CHARS(txt) - txt); + + /* + * The enumeration used in this switch is derived from this switch + * statement itself. The "find_option_xat_attribute_cmd" function + * will return XAT_CMD_MEMBERS for the "txt" string value + * "members", etc. + */ + switch (find_option_xat_attribute_cmd(txt, len)) { + case XAT_CMD_TYPE: + txt = parse_value(txt+len, pType); + break; + + case XAT_CMD_WORDS: + txt = parse_keyword(opts, txt+len, pType); + break; + + case XAT_CMD_MEMBERS: + txt = parse_set_mem(opts, txt+len, pType); + break; + + case XAT_CMD_COOKED: + txt += len; + if (! IS_END_XML_TOKEN_CHAR(*txt)) + goto invalid_kwd; + + *pMode = OPTION_LOAD_COOKED; + break; + + case XAT_CMD_UNCOOKED: + txt += len; + if (! IS_END_XML_TOKEN_CHAR(*txt)) + goto invalid_kwd; + + *pMode = OPTION_LOAD_UNCOOKED; + break; + + case XAT_CMD_KEEP: + txt += len; + if (! IS_END_XML_TOKEN_CHAR(*txt)) + goto invalid_kwd; + + *pMode = OPTION_LOAD_KEEP; + break; + + default: + case XAT_INVALID_CMD: + invalid_kwd: + pType->valType = OPARG_TYPE_NONE; + return skip_unkn(txt); + } + + if (txt == NULL) + return NULL; + txt = SPN_WHITESPACE_CHARS(txt); + switch (*txt) { + case '/': pType->valType = OPARG_TYPE_NONE; + /* FALLTHROUGH */ + case '>': return txt; + } + if (! IS_LOWER_CASE_CHAR(*txt)) + return NULL; + } +} + +/** + * "txt" points to the character after "words=". + * What should follow is a name of a keyword (enumeration) list. + * + * @param opts unused + * @param[in] txt keyword to skip over + * @param type unused value type + * @returns pointer after skipped text + */ +static char const * +parse_keyword(tOptions * opts, char const * txt, tOptionValue * typ) +{ + (void)opts; + (void)typ; + + return skip_unkn(txt); +} + +/** + * "txt" points to the character after "members=" + * What should follow is a name of a "set membership". + * A collection of bit flags. + * + * @param opts unused + * @param[in] txt keyword to skip over + * @param type unused value type + * @returns pointer after skipped text + */ +static char const * +parse_set_mem(tOptions * opts, char const * txt, tOptionValue * typ) +{ + (void)opts; + (void)typ; + + return skip_unkn(txt); +} + +/** + * parse the type. The keyword "type" was found, now figure out + * the type that follows the type. + * + * @param[in] txt points to the '=' character after the "type" keyword. + * @param[out] typ where to store the type found + * @returns the next byte after the type name + */ +static char const * +parse_value(char const * txt, tOptionValue * typ) +{ + size_t len = 0; + + if (*(txt++) != '=') + goto woops; + + len = (size_t)(SPN_OPTION_NAME_CHARS(txt) - txt); + + if ((len == 0) || (! IS_END_XML_TOKEN_CHAR(txt[len]))) { + woops: + typ->valType = OPARG_TYPE_NONE; + return skip_unkn(txt + len); + } + + /* + * The enumeration used in this switch is derived from this switch + * statement itself. The "find_option_value_type_cmd" function + * will return VTP_CMD_INTEGER for the "txt" string value + * "integer", etc. + */ + switch (find_option_value_type_cmd(txt, len)) { + default: + case VTP_INVALID_CMD: goto woops; + + case VTP_CMD_STRING: + typ->valType = OPARG_TYPE_STRING; + break; + + case VTP_CMD_INTEGER: + typ->valType = OPARG_TYPE_NUMERIC; + break; + + case VTP_CMD_BOOL: + case VTP_CMD_BOOLEAN: + typ->valType = OPARG_TYPE_BOOLEAN; + break; + + case VTP_CMD_KEYWORD: + typ->valType = OPARG_TYPE_ENUMERATION; + break; + + case VTP_CMD_SET: + case VTP_CMD_SET_MEMBERSHIP: + typ->valType = OPARG_TYPE_MEMBERSHIP; + break; + + case VTP_CMD_NESTED: + case VTP_CMD_HIERARCHY: + typ->valType = OPARG_TYPE_HIERARCHY; + } + + return txt + len; +} + +/** @} + * + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of autoopts/configfile.c */ diff --git a/autoopts/cook.c b/autoopts/cook.c new file mode 100644 index 0000000..5240540 --- /dev/null +++ b/autoopts/cook.c @@ -0,0 +1,320 @@ +/** + * \file cook.c + * + * This file contains the routines that deal with processing quoted strings + * into an internal format. + * + * @addtogroup autoopts + * @{ + */ +/* + * This file is part of AutoOpts, a companion to AutoGen. + * AutoOpts is free software. + * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoOpts is available under any one of two licenses. The license + * in use must be one of these two and the choice is under the control + * of the user of the license. + * + * The GNU Lesser General Public License, version 3 or later + * See the files "COPYING.lgplv3" and "COPYING.gplv3" + * + * The Modified Berkeley Software Distribution License + * See the file "COPYING.mbsd" + * + * These files have the following sha256 sums: + * + * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 + * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 + * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + */ + +/*=export_func ao_string_cook_escape_char + * private: + * + * what: escape-process a string fragment + * arg: + char const * + pzScan + points to character after the escape + + * arg: + char * + pRes + Where to put the result byte + + * arg: + unsigned int + nl_ch + replacement char if scanned char is \n + + * + * ret-type: unsigned int + * ret-desc: The number of bytes consumed processing the escaped character. + * + * doc: + * + * This function converts "t" into "\t" and all your other favorite + * escapes, including numeric ones: hex and ocatal, too. + * The returned result tells the caller how far to advance the + * scan pointer (passed in). The default is to just pass through the + * escaped character and advance the scan by one. + * + * Some applications need to keep an escaped newline, others need to + * suppress it. This is accomplished by supplying a '\n' replacement + * character that is different from \n, if need be. For example, use + * 0x7F and never emit a 0x7F. + * + * err: @code{NULL} is returned if the string is mal-formed. +=*/ +unsigned int +ao_string_cook_escape_char(char const * pzIn, char * pRes, uint_t nl) +{ + unsigned int res = 1; + + switch (*pRes = *pzIn++) { + case NUL: /* NUL - end of input string */ + return 0; + case '\r': + if (*pzIn != NL) + return 1; + res++; + /* FALLTHROUGH */ + case NL: /* NL - emit newline */ + *pRes = (char)nl; + return res; + + case 'a': *pRes = '\a'; break; + case 'b': *pRes = '\b'; break; + case 'f': *pRes = '\f'; break; + case 'n': *pRes = NL; break; + case 'r': *pRes = '\r'; break; + case 't': *pRes = '\t'; break; + case 'v': *pRes = '\v'; break; + + case 'x': + case 'X': /* HEX Escape */ + if (IS_HEX_DIGIT_CHAR(*pzIn)) { + char z[4]; + unsigned int ct = 0; + + do { + z[ct] = pzIn[ct]; + if (++ct >= 2) + break; + } while (IS_HEX_DIGIT_CHAR(pzIn[ct])); + z[ct] = NUL; + *pRes = (char)strtoul(z, NULL, 16); + return ct + 1; + } + break; + + case '0': case '1': case '2': case '3': + case '4': case '5': case '6': case '7': + { + /* + * IF the character copied was an octal digit, + * THEN set the output character to an octal value. + * The 3 octal digit result might exceed 0xFF, so check it. + */ + char z[4]; + unsigned long val; + unsigned int ct = 0; + + z[ct++] = *--pzIn; + while (IS_OCT_DIGIT_CHAR(pzIn[ct])) { + z[ct] = pzIn[ct]; + if (++ct >= 3) + break; + } + + z[ct] = NUL; + val = strtoul(z, NULL, 8); + if (val > 0xFF) + val = 0xFF; + *pRes = (char)val; + return ct; + } + + default: /* quoted character is result character */; + } + + return res; +} + +/** + * count newlines between start and end + */ +static char * +nl_count(char * start, char * end, int * lnct_p) +{ + while (start < end) { + if (*(start++) == NL) + (*lnct_p)++; + } + return end; +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * A quoted string has been found. + * Find the end of it and compress any escape sequences. + */ +static bool +contiguous_quote(char ** pps, char * pq, int * lnct_p) +{ + char * ps = *pps + 1; + + for (;;) { + while (IS_WHITESPACE_CHAR(*ps)) + if (*(ps++) == NL) + (*lnct_p)++; + + /* + * IF the next character is a quote character, + * THEN we will concatenate the strings. + */ + switch (*ps) { + case '"': + case '\'': + *pq = *(ps++); /* assign new quote character and return */ + *pps = ps; + return true; + + case '/': + /* + * Allow for a comment embedded in the concatenated string. + */ + switch (ps[1]) { + default: + goto fail_return; + + case '/': + /* + * Skip to end of line + */ + ps = strchr(ps, NL); + if (ps == NULL) + goto fail_return; + break; + + case '*': + ps = nl_count(ps + 2, strstr(ps + 2, "*/"), lnct_p); + if (ps == NULL) + goto fail_return; + ps += 2; + } + continue; + + default: + /* + * The next non-whitespace character is not a quote. + * The series of quoted strings has come to an end. + */ + *pps = ps; + return false; + } + } + + fail_return: + *pps = NULL; + return false; +} + +/*=export_func ao_string_cook + * private: + * + * what: concatenate and escape-process strings + * arg: + char * + pzScan + The *MODIFIABLE* input buffer + + * arg: + int * + lnct_p + The (possibly NULL) pointer to a line count + + * + * ret-type: char * + * ret-desc: The address of the text following the processed strings. + * The return value is NULL if the strings are ill-formed. + * + * doc: + * + * A series of one or more quoted strings are concatenated together. + * If they are quoted with double quotes (@code{"}), then backslash + * escapes are processed per the C programming language. If they are + * single quote strings, then the backslashes are honored only when they + * precede another backslash or a single quote character. + * + * err: @code{NULL} is returned if the string(s) is/are mal-formed. +=*/ +char * +ao_string_cook(char * pzScan, int * lnct_p) +{ + int l = 0; + char q = *pzScan; + + /* + * It is a quoted string. Process the escape sequence characters + * (in the set "abfnrtv") and make sure we find a closing quote. + */ + char * pzD = pzScan++; + char * pzS = pzScan; + + if (lnct_p == NULL) + lnct_p = &l; + + for (;;) { + /* + * IF the next character is the quote character, THEN we may end the + * string. We end it unless the next non-blank character *after* the + * string happens to also be a quote. If it is, then we will change + * our quote character to the new quote character and continue + * condensing text. + */ + while (*pzS == q) { + *pzD = NUL; /* This is probably the end of the line */ + if (! contiguous_quote(&pzS, &q, lnct_p)) + return pzS; + } + + /* + * We are inside a quoted string. Copy text. + */ + switch (*(pzD++) = *(pzS++)) { + case NUL: + return NULL; + + case NL: + (*lnct_p)++; + break; + + case '\\': + /* + * IF we are escaping a new line, + * THEN drop both the escape and the newline from + * the result string. + */ + if (*pzS == NL) { + pzS++; + pzD--; + (*lnct_p)++; + } + + /* + * ELSE IF the quote character is '"' or '`', + * THEN we do the full escape character processing + */ + else if (q != '\'') { + unsigned int ct; + ct = ao_string_cook_escape_char(pzS, pzD-1, (uint_t)NL); + if (ct == 0) + return NULL; + + pzS += ct; + } /* if (q != '\'') */ + + /* + * OTHERWISE, we only process "\\", "\'" and "\#" sequences. + * The latter only to easily hide preprocessing directives. + */ + else switch (*pzS) { + case '\\': + case '\'': + case '#': + pzD[-1] = *pzS++; + } + } /* switch (*(pzD++) = *(pzS++)) */ + } /* for (;;) */ +} + +/** @} + * + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of autoopts/cook.c */ diff --git a/autoopts/enum.c b/autoopts/enum.c new file mode 100644 index 0000000..7f92e0b --- /dev/null +++ b/autoopts/enum.c @@ -0,0 +1,628 @@ + +/** + * \file enumeration.c + * + * Handle options with enumeration names and bit mask bit names + * for their arguments. + * + * @addtogroup autoopts + * @{ + */ +/* + * This routine will run run-on options through a pager so the + * user may examine, print or edit them at their leisure. + * + * This file is part of AutoOpts, a companion to AutoGen. + * AutoOpts is free software. + * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoOpts is available under any one of two licenses. The license + * in use must be one of these two and the choice is under the control + * of the user of the license. + * + * The GNU Lesser General Public License, version 3 or later + * See the files "COPYING.lgplv3" and "COPYING.gplv3" + * + * The Modified Berkeley Software Distribution License + * See the file "COPYING.mbsd" + * + * These files have the following sha256 sums: + * + * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 + * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 + * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + */ + +static void +enum_err(tOptions * pOpts, tOptDesc * pOD, + char const * const * paz_names, int name_ct) +{ + size_t max_len = 0; + size_t ttl_len = 0; + int ct_down = name_ct; + int hidden = 0; + + /* + * A real "pOpts" pointer means someone messed up. Give a real error. + */ + if (pOpts > OPTPROC_EMIT_LIMIT) + fprintf(option_usage_fp, pz_enum_err_fmt, pOpts->pzProgName, + pOD->optArg.argString, pOD->pz_Name); + + fprintf(option_usage_fp, zValidKeys, pOD->pz_Name); + + /* + * If the first name starts with this funny character, then we have + * a first value with an unspellable name. You cannot specify it. + * So, we don't list it either. + */ + if (**paz_names == 0x7F) { + paz_names++; + hidden = 1; + ct_down = --name_ct; + } + + /* + * Figure out the maximum length of any name, plus the total length + * of all the names. + */ + { + char const * const * paz = paz_names; + + do { + size_t len = strlen(*(paz++)) + 1; + if (len > max_len) + max_len = len; + ttl_len += len; + } while (--ct_down > 0); + + ct_down = name_ct; + } + + /* + * IF any one entry is about 1/2 line or longer, print one per line + */ + if (max_len > 35) { + do { + fprintf(option_usage_fp, ENUM_ERR_LINE, *(paz_names++)); + } while (--ct_down > 0); + } + + /* + * ELSE IF they all fit on one line, then do so. + */ + else if (ttl_len < 76) { + fputc(' ', option_usage_fp); + do { + fputc(' ', option_usage_fp); + fputs(*(paz_names++), option_usage_fp); + } while (--ct_down > 0); + fputc(NL, option_usage_fp); + } + + /* + * Otherwise, columnize the output + */ + else { + unsigned int ent_no = 0; + char fmt[16]; /* format for all-but-last entries on a line */ + + if (snprintf(fmt, 16, ENUM_ERR_WIDTH, (int)max_len) >= 16) + option_exits(EXIT_FAILURE); + max_len = 78 / max_len; /* max_len is now max entries on a line */ + fputs(TWO_SPACES_STR, option_usage_fp); + + /* + * Loop through all but the last entry + */ + ct_down = name_ct; + while (--ct_down > 0) { + if (++ent_no == max_len) { + /* + * Last entry on a line. Start next line, too. + */ + fprintf(option_usage_fp, NLSTR_SPACE_FMT, *(paz_names++)); + ent_no = 0; + } + + else + fprintf(option_usage_fp, fmt, *(paz_names++) ); + } + fprintf(option_usage_fp, NLSTR_FMT, *paz_names); + } + + if (pOpts > OPTPROC_EMIT_LIMIT) { + fprintf(option_usage_fp, zIntRange, hidden, name_ct - 1 + hidden); + + (*(pOpts->pUsageProc))(pOpts, EXIT_FAILURE); + /* NOTREACHED */ + } + + if (OPTST_GET_ARGTYPE(pOD->fOptState) == OPARG_TYPE_MEMBERSHIP) { + fprintf(option_usage_fp, zLowerBits, name_ct); + fputs(zSetMemberSettings, option_usage_fp); + } else { + fprintf(option_usage_fp, zIntRange, hidden, name_ct - 1 + hidden); + } +} + +/** + * Convert a name or number into a binary number. + * "~0" and "-1" will be converted to the largest value in the enumeration. + * + * @param name the keyword name (number) to convert + * @param pOpts the program's option descriptor + * @param pOD the option descriptor for this option + * @param paz_names the list of keywords for this option + * @param name_ct the count of keywords + */ +static uintptr_t +find_name(char const * name, tOptions * pOpts, tOptDesc * pOD, + char const * const * paz_names, unsigned int name_ct) +{ + /* + * Return the matching index as a pointer sized integer. + * The result gets stashed in a char * pointer. + */ + uintptr_t res = name_ct; + size_t len = strlen((char *)name); + uintptr_t idx; + + if (IS_DEC_DIGIT_CHAR(*name)) { + char * pz = VOIDP(name); + unsigned long val = strtoul(pz, &pz, 0); + if ((*pz == NUL) && (val < name_ct)) + return (uintptr_t)val; + pz_enum_err_fmt = znum_too_large; + option_usage_fp = stderr; + enum_err(pOpts, pOD, paz_names, (int)name_ct); + return name_ct; + } + + if (IS_INVERSION_CHAR(*name) && (name[2] == NUL)) { + if ( ((name[0] == '~') && (name[1] == '0')) + || ((name[0] == '-') && (name[1] == '1'))) + return (uintptr_t)(name_ct - 1); + goto oops; + } + + /* + * Look for an exact match, but remember any partial matches. + * Multiple partial matches means we have an ambiguous match. + */ + for (idx = 0; idx < name_ct; idx++) { + if (strncmp((char *)paz_names[idx], (char *)name, len) == 0) { + if (paz_names[idx][len] == NUL) + return idx; /* full match */ + + if (res == name_ct) + res = idx; /* save partial match */ + else + res = (uintptr_t)~0; /* may yet find full match */ + } + } + + if (res < name_ct) + return res; /* partial match */ + + oops: + + pz_enum_err_fmt = (res == name_ct) ? zNoKey : zambiguous_key; + option_usage_fp = stderr; + enum_err(pOpts, pOD, paz_names, (int)name_ct); + return name_ct; +} + + +/*=export_func optionKeywordName + * what: Convert between enumeration values and strings + * private: + * + * arg: tOptDesc *, pOD, enumeration option description + * arg: unsigned int, enum_val, the enumeration value to map + * + * ret_type: char const * + * ret_desc: the enumeration name from const memory + * + * doc: This converts an enumeration value into the matching string. +=*/ +char const * +optionKeywordName(tOptDesc * pOD, unsigned int enum_val) +{ + tOptDesc od = { 0 }; + od.optArg.argEnum = enum_val; + + (*(pOD->pOptProc))(OPTPROC_RETURN_VALNAME, &od ); + return od.optArg.argString; +} + + +/*=export_func optionEnumerationVal + * what: Convert from a string to an enumeration value + * private: + * + * arg: tOptions *, pOpts, the program options descriptor + * arg: tOptDesc *, pOD, enumeration option description + * arg: char const * const *, paz_names, list of enumeration names + * arg: unsigned int, name_ct, number of names in list + * + * ret_type: uintptr_t + * ret_desc: the enumeration value + * + * doc: This converts the optArg.argString string from the option description + * into the index corresponding to an entry in the name list. + * This will match the generated enumeration value. + * Full matches are always accepted. Partial matches are accepted + * if there is only one partial match. +=*/ +uintptr_t +optionEnumerationVal(tOptions * pOpts, tOptDesc * pOD, + char const * const * paz_names, unsigned int name_ct) +{ + uintptr_t res = 0UL; + + /* + * IF the program option descriptor pointer is invalid, + * then it is some sort of special request. + */ + switch ((uintptr_t)pOpts) { + case (uintptr_t)OPTPROC_EMIT_USAGE: + /* + * print the list of enumeration names. + */ + enum_err(pOpts, pOD, paz_names, (int)name_ct); + break; + + case (uintptr_t)OPTPROC_EMIT_SHELL: + { + unsigned int ix = (unsigned int)pOD->optArg.argEnum; + /* + * print the name string. + */ + if (ix >= name_ct) + printf(INVALID_FMT, ix); + else + fputs(paz_names[ ix ], stdout); + + break; + } + + case (uintptr_t)OPTPROC_RETURN_VALNAME: + { + unsigned int ix = (unsigned int)pOD->optArg.argEnum; + /* + * Replace the enumeration value with the name string. + */ + if (ix >= name_ct) + return (uintptr_t)INVALID_STR; + + pOD->optArg.argString = paz_names[ix]; + break; + } + + default: + if ((pOD->fOptState & OPTST_RESET) != 0) + break; + + res = find_name(pOD->optArg.argString, pOpts, pOD, paz_names, name_ct); + + if (pOD->fOptState & OPTST_ALLOC_ARG) { + AGFREE(pOD->optArg.argString); + pOD->fOptState &= ~OPTST_ALLOC_ARG; + pOD->optArg.argString = NULL; + } + } + + return res; +} + +static void +set_memb_shell(tOptions * pOpts, tOptDesc * pOD, char const * const * paz_names, + unsigned int name_ct) +{ + /* + * print the name string. + */ + unsigned int ix = 0; + uintptr_t bits = (uintptr_t)pOD->optCookie; + size_t len = 0; + + (void)pOpts; + bits &= ((uintptr_t)1 << (uintptr_t)name_ct) - (uintptr_t)1; + + while (bits != 0) { + if (bits & 1) { + if (len++ > 0) fputs(OR_STR, stdout); + fputs(paz_names[ix], stdout); + } + if (++ix >= name_ct) break; + bits >>= 1; + } +} + +static void +set_memb_names(tOptions * opts, tOptDesc * od, char const * const * nm_list, + unsigned int nm_ct) +{ + char * pz; + uintptr_t mask = (1UL << (uintptr_t)nm_ct) - 1UL; + uintptr_t bits = (uintptr_t)od->optCookie & mask; + unsigned int ix = 0; + size_t len = 1; + + /* + * Replace the enumeration value with the name string. + * First, determine the needed length, then allocate and fill in. + */ + while (bits != 0) { + if (bits & 1) + len += strlen(nm_list[ix]) + PLUS_STR_LEN + 1; + if (++ix >= nm_ct) break; + bits >>= 1; + } + + od->optArg.argString = pz = AGALOC(len, "enum"); + bits = (uintptr_t)od->optCookie & mask; + if (bits == 0) { + *pz = NUL; + return; + } + + for (ix = 0; ; ix++) { + size_t nln; + int doit = bits & 1; + + bits >>= 1; + if (doit == 0) + continue; + + nln = strlen(nm_list[ix]); + memcpy(pz, nm_list[ix], nln); + pz += nln; + if (bits == 0) + break; + memcpy(pz, PLUS_STR, PLUS_STR_LEN); + pz += PLUS_STR_LEN; + } + *pz = NUL; + (void)opts; +} + +/** + * Check membership start conditions. An equal character (@samp{=}) says to + * clear the result and not carry over any residual value. A carat + * (@samp{^}), which may follow the equal character, says to invert the + * result. The scanning pointer is advanced past these characters and any + * leading white space. Invalid sequences are indicated by setting the + * scanning pointer to NULL. + * + * @param od the set membership option description + * @param argp a pointer to the string scanning pointer + * @param invert a pointer to the boolean inversion indicator + * + * @returns either zero or the original value for the optCookie. + */ +static uintptr_t +check_membership_start(tOptDesc * od, char const ** argp, bool * invert) +{ + uintptr_t res = (uintptr_t)od->optCookie; + char const * arg = SPN_WHITESPACE_CHARS(od->optArg.argString); + if ((arg == NULL) || (*arg == NUL)) + goto member_start_fail; + + *invert = false; + + switch (*arg) { + case '=': + res = 0UL; + arg = SPN_WHITESPACE_CHARS(arg + 1); + switch (*arg) { + case '=': case ',': + goto member_start_fail; + case '^': + goto inversion; + default: + break; + } + break; + + case '^': + inversion: + *invert = true; + arg = SPN_WHITESPACE_CHARS(arg + 1); + if (*arg != ',') + break; + /* FALLTHROUGH */ + + case ',': + goto member_start_fail; + + default: + break; + } + + *argp = arg; + return res; + +member_start_fail: + *argp = NULL; + return 0UL; +} + +/** + * convert a name to a bit. Look up a name string to get a bit number + * and shift the value "1" left that number of bits. + * + * @param opts program options descriptor + * @param od the set membership option description + * @param pz address of the start of the bit name + * @param nm_list the list of names for this option + * @param nm_ct the number of entries in this list + * + * @returns 0UL on error, other an unsigned long with the correct bit set. + */ +static uintptr_t +find_member_bit(tOptions * opts, tOptDesc * od, char const * pz, int len, + char const * const * nm_list, unsigned int nm_ct) +{ + char nm_buf[ AO_NAME_SIZE ]; + + memcpy(nm_buf, pz, len); + nm_buf[len] = NUL; + + { + unsigned int shift_ct = (unsigned int) + find_name(nm_buf, opts, od, nm_list, nm_ct); + if (shift_ct >= nm_ct) + return 0UL; + + return 1UL << shift_ct; + } +} + +/*=export_func optionMemberList + * what: Get the list of members of a bit mask set + * + * arg: tOptDesc *, od, the set membership option description + * + * ret_type: char * + * ret_desc: the names of the set bits + * + * doc: This converts the OPT_VALUE_name mask value to a allocated string. + * It is the caller's responsibility to free the string. +=*/ +char * +optionMemberList(tOptDesc * od) +{ + uintptr_t sv = od->optArg.argIntptr; + char * res; + (*(od->pOptProc))(OPTPROC_RETURN_VALNAME, od); + res = VOIDP(od->optArg.argString); + od->optArg.argIntptr = sv; + return res; +} + +/*=export_func optionSetMembers + * what: Convert between bit flag values and strings + * private: + * + * arg: tOptions *, opts, the program options descriptor + * arg: tOptDesc *, od, the set membership option description + * arg: char const * const *, + * nm_list, list of enumeration names + * arg: unsigned int, nm_ct, number of names in list + * + * doc: This converts the optArg.argString string from the option description + * into the index corresponding to an entry in the name list. + * This will match the generated enumeration value. + * Full matches are always accepted. Partial matches are accepted + * if there is only one partial match. +=*/ +void +optionSetMembers(tOptions * opts, tOptDesc * od, + char const * const * nm_list, unsigned int nm_ct) +{ + /* + * IF the program option descriptor pointer is invalid, + * then it is some sort of special request. + */ + switch ((uintptr_t)opts) { + case (uintptr_t)OPTPROC_EMIT_USAGE: + enum_err(OPTPROC_EMIT_USAGE, od, nm_list, nm_ct); + return; + + case (uintptr_t)OPTPROC_EMIT_SHELL: + set_memb_shell(opts, od, nm_list, nm_ct); + return; + + case (uintptr_t)OPTPROC_RETURN_VALNAME: + set_memb_names(opts, od, nm_list, nm_ct); + return; + + default: + break; + } + + if ((od->fOptState & OPTST_RESET) != 0) + return; + + { + char const * arg; + bool invert; + uintptr_t res = check_membership_start(od, &arg, &invert); + if (arg == NULL) + goto fail_return; + + while (*arg != NUL) { + bool inv_val = false; + int len; + + switch (*arg) { + case ',': + arg = SPN_WHITESPACE_CHARS(arg+1); + if ((*arg == ',') || (*arg == '|')) + goto fail_return; + continue; + + case '-': + case '!': + inv_val = true; + /* FALLTHROUGH */ + + case '+': + case '|': + arg = SPN_WHITESPACE_CHARS(arg+1); + } + + len = (int)(BRK_SET_SEPARATOR_CHARS(arg) - arg); + if (len == 0) + break; + + if ((len == 3) && (strncmp(arg, zAll, 3) == 0)) { + if (inv_val) + res = 0; + else res = ~0UL; + } + else if ((len == 4) && (strncmp(arg, zNone, 4) == 0)) { + if (! inv_val) + res = 0; + } + else do { + char * pz; + uintptr_t bit = strtoul(arg, &pz, 0); + + if (pz != arg + len) { + bit = find_member_bit(opts, od, pz, len, nm_list, nm_ct); + if (bit == 0UL) + goto fail_return; + } + if (inv_val) + res &= ~bit; + else res |= bit; + } while (false); + + arg = SPN_WHITESPACE_CHARS(arg + len); + } + + if (invert) + res ^= ~0UL; + + if (nm_ct < (8 * sizeof(uintptr_t))) + res &= (1UL << nm_ct) - 1UL; + + od->optCookie = VOIDP(res); + } + return; + +fail_return: + od->optCookie = VOIDP(0); +} + +/** @} + * + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of autoopts/enum.c */ diff --git a/autoopts/env.c b/autoopts/env.c new file mode 100644 index 0000000..16f0e95 --- /dev/null +++ b/autoopts/env.c @@ -0,0 +1,261 @@ + +/** + * \file environment.c + * + * This file contains all of the routines that must be linked into + * an executable to use the generated option processing. The optional + * routines are in separately compiled modules so that they will not + * necessarily be linked in. + * + * @addtogroup autoopts + * @{ + */ +/* + * This file is part of AutoOpts, a companion to AutoGen. + * AutoOpts is free software. + * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoOpts is available under any one of two licenses. The license + * in use must be one of these two and the choice is under the control + * of the user of the license. + * + * The GNU Lesser General Public License, version 3 or later + * See the files "COPYING.lgplv3" and "COPYING.gplv3" + * + * The Modified Berkeley Software Distribution License + * See the file "COPYING.mbsd" + * + * These files have the following sha256 sums: + * + * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 + * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 + * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + */ + +/* + * doPrognameEnv - check for preset values from the ${PROGNAME} + * environment variable. This is accomplished by parsing the text into + * tokens, temporarily replacing the arg vector and calling + * immediate_opts and/or regular_opts. + */ +static void +doPrognameEnv(tOptions * pOpts, teEnvPresetType type) +{ + char const * env_opts = getenv(pOpts->pzPROGNAME); + token_list_t * pTL; + int sv_argc; + proc_state_mask_t sv_flag; + char ** sv_argv; + + /* + * No such beast? Then bail now. + */ + if (env_opts == NULL) + return; + + /* + * Tokenize the string. If there's nothing of interest, we'll bail + * here immediately. + */ + pTL = ao_string_tokenize(env_opts); + if (pTL == NULL) + return; + + /* + * Substitute our $PROGNAME argument list for the real one + */ + sv_argc = (int)pOpts->origArgCt; + sv_argv = pOpts->origArgVect; + sv_flag = pOpts->fOptSet; + + /* + * We add a bogus pointer to the start of the list. The program name + * has already been pulled from "argv", so it won't get dereferenced. + * The option scanning code will skip the "program name" at the start + * of this list of tokens, so we accommodate this way .... + */ + { + uintptr_t v = (uintptr_t)(pTL->tkn_list); + pOpts->origArgVect = VOIDP(v - sizeof(char *)); + } + pOpts->origArgCt = (unsigned int)pTL->tkn_ct + 1; + pOpts->fOptSet &= ~OPTPROC_ERRSTOP; + + pOpts->curOptIdx = 1; + pOpts->pzCurOpt = NULL; + + switch (type) { + case ENV_IMM: + (void)immediate_opts(pOpts); + break; + + case ENV_ALL: + (void)immediate_opts(pOpts); + pOpts->curOptIdx = 1; + pOpts->pzCurOpt = NULL; + /* FALLTHROUGH */ + + case ENV_NON_IMM: + (void)regular_opts(pOpts); + } + + /* + * Free up the temporary arg vector and restore the original program args. + */ + free(pTL); + pOpts->origArgVect = sv_argv; + pOpts->origArgCt = (unsigned int)sv_argc; + pOpts->fOptSet = sv_flag; +} + +static void +do_env_opt(tOptState * os, char * env_name, + tOptions * pOpts, teEnvPresetType type) +{ + os->pzOptArg = getenv(env_name); + if (os->pzOptArg == NULL) + return; + + os->flags = OPTST_PRESET | OPTST_ALLOC_ARG | os->pOD->fOptState; + os->optType = TOPT_UNDEFINED; + + if ( (os->pOD->pz_DisablePfx != NULL) + && (streqvcmp(os->pzOptArg, os->pOD->pz_DisablePfx) == 0)) { + os->flags |= OPTST_DISABLED; + os->pzOptArg = NULL; + handle_opt(pOpts, os); + return; + } + + switch (type) { + case ENV_IMM: + /* + * Process only immediate actions + */ + if (DO_IMMEDIATELY(os->flags)) + break; + return; + + case ENV_NON_IMM: + /* + * Process only NON immediate actions + */ + if (DO_NORMALLY(os->flags) || DO_SECOND_TIME(os->flags)) + break; + return; + + default: /* process everything */ + break; + } + + /* + * Make sure the option value string is persistent and consistent. + * + * The interpretation of the option value depends + * on the type of value argument the option takes + */ + if (OPTST_GET_ARGTYPE(os->pOD->fOptState) == OPARG_TYPE_NONE) { + /* + * Ignore any value. + */ + os->pzOptArg = NULL; + + } else if (os->pzOptArg[0] == NUL) { + /* + * If the argument is the empty string and the argument is + * optional, then treat it as if the option was not specified. + */ + if ((os->pOD->fOptState & OPTST_ARG_OPTIONAL) == 0) + return; + os->pzOptArg = NULL; + + } else { + AGDUPSTR(os->pzOptArg, os->pzOptArg, "option argument"); + os->flags |= OPTST_ALLOC_ARG; + } + + handle_opt(pOpts, os); +} + +/* + * env_presets - check for preset values from the envrionment + * This routine should process in all, immediate or normal modes.... + */ +static void +env_presets(tOptions * pOpts, teEnvPresetType type) +{ + int ct; + tOptState st; + char * pzFlagName; + size_t spaceLeft; + char zEnvName[ AO_NAME_SIZE ]; + + /* + * Finally, see if we are to look at the environment + * variables for initial values. + */ + if ((pOpts->fOptSet & OPTPROC_ENVIRON) == 0) + return; + + doPrognameEnv(pOpts, type); + + ct = pOpts->presetOptCt; + st.pOD = pOpts->pOptDesc; + + pzFlagName = zEnvName + + snprintf(zEnvName, sizeof(zEnvName), "%s_", pOpts->pzPROGNAME); + spaceLeft = AO_NAME_SIZE - (unsigned long)(pzFlagName - zEnvName) - 1; + + for (;ct-- > 0; st.pOD++) { + size_t nln; + + /* + * If presetting is disallowed, then skip this entry + */ + if ( ((st.pOD->fOptState & OPTST_NO_INIT) != 0) + || (st.pOD->optEquivIndex != NO_EQUIVALENT) ) + continue; + + /* + * IF there is no such environment variable, + * THEN skip this entry, too. + */ + nln = strlen(st.pOD->pz_NAME) + 1; + if (nln <= spaceLeft) { + /* + * Set up the option state + */ + memcpy(pzFlagName, st.pOD->pz_NAME, nln); + do_env_opt(&st, zEnvName, pOpts, type); + } + } + + /* + * Special handling for ${PROGNAME_LOAD_OPTS} + */ + if ( (pOpts->specOptIdx.save_opts != NO_EQUIVALENT) + && (pOpts->specOptIdx.save_opts != 0)) { + size_t nln; + st.pOD = pOpts->pOptDesc + pOpts->specOptIdx.save_opts + 1; + + if (st.pOD->pz_NAME == NULL) + return; + + nln = strlen(st.pOD->pz_NAME) + 1; + + if (nln > spaceLeft) + return; + + memcpy(pzFlagName, st.pOD->pz_NAME, nln); + do_env_opt(&st, zEnvName, pOpts, type); + } +} + +/** @} + * + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of autoopts/environment.c */ diff --git a/autoopts/file.c b/autoopts/file.c new file mode 100644 index 0000000..14efe8f --- /dev/null +++ b/autoopts/file.c @@ -0,0 +1,201 @@ + +/** + * \file file.c + * + * Handle options that have file names for arguments. + * + * @addtogroup autoopts + * @{ + */ +/* + * This file is part of AutoOpts, a companion to AutoGen. + * AutoOpts is free software. + * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoOpts is available under any one of two licenses. The license + * in use must be one of these two and the choice is under the control + * of the user of the license. + * + * The GNU Lesser General Public License, version 3 or later + * See the files "COPYING.lgplv3" and "COPYING.gplv3" + * + * The Modified Berkeley Software Distribution License + * See the file "COPYING.mbsd" + * + * These files have the following sha256 sums: + * + * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 + * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 + * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + */ + +/** + * Make sure the directory containing the subject file exists and that + * the file exists or does not exist, per the option requirements. + * + * @param ftype file existence type flags + * @param pOpts program option descriptor + * @param pOD the option descriptor + */ +static void +check_existence(teOptFileType ftype, tOptions * pOpts, tOptDesc * pOD) +{ + char const * fname = pOD->optArg.argString; + struct stat sb; + + errno = 0; + + switch (ftype & FTYPE_MODE_EXIST_MASK) { + case FTYPE_MODE_MUST_NOT_EXIST: + if ((stat(fname, &sb) == 0) || (errno != ENOENT)) { + if (errno == 0) + errno = EINVAL; + fserr_exit(pOpts->pzProgName, "stat", fname); + /* NOTREACHED */ + } + /* FALLTHROUGH */ + + default: + case FTYPE_MODE_MAY_EXIST: + { + char * p = strrchr(fname, DIRCH); + size_t l; + + if (p == NULL) + /* + * The file may or may not exist and its directory is ".". + * Assume that "." exists. + */ + break; + + l = (size_t)(p - fname); + p = AGALOC(l + 1, "fname"); + memcpy(p, fname, l); + p[l] = NUL; + + if ((stat(p, &sb) != 0) || (errno = EINVAL, ! S_ISDIR(sb.st_mode))) + fserr_exit(pOpts->pzProgName, "stat", p); + /* NOTREACHED */ + + AGFREE(p); + break; + } + + case FTYPE_MODE_MUST_EXIST: + if ( (stat(fname, &sb) != 0) + || (errno = EINVAL, ! S_ISREG(sb.st_mode)) ) + fserr_exit(pOpts->pzProgName, "stat", fname); + /* NOTREACHED */ + + break; + } +} + +/** + * Open the specified file with open(2) and save the FD. + * + * @param pOpts program option descriptor + * @param pOD the option descriptor + * @param mode the open mode (uses int flags value) + */ +static void +open_file_fd(tOptions * pOpts, tOptDesc * pOD, tuFileMode mode) +{ + int fd = open(pOD->optArg.argString, mode.file_flags); + if (fd < 0) + fserr_exit(pOpts->pzProgName, "open", pOD->optArg.argString); + /* NOTREACHED */ + + if ((pOD->fOptState & OPTST_ALLOC_ARG) != 0) + pOD->optCookie = VOIDP(pOD->optArg.argString); + else + AGDUPSTR(pOD->optCookie, pOD->optArg.argString, "file name"); + + pOD->optArg.argFd = fd; + pOD->fOptState &= ~OPTST_ALLOC_ARG; +} + +/** + * Open the specified file with open(2) and save the FD. + * + * @param pOpts program option descriptor + * @param pOD the option descriptor + * @param mode the open mode (uses "char *" mode value) + */ +static void +fopen_file_fp(tOptions * pOpts, tOptDesc * pOD, tuFileMode mode) +{ + FILE * fp = fopen(pOD->optArg.argString, mode.file_mode); + if (fp == NULL) + fserr_exit(pOpts->pzProgName, "fopen", pOD->optArg.argString); + /* NOTREACHED */ + + if ((pOD->fOptState & OPTST_ALLOC_ARG) != 0) + pOD->optCookie = VOIDP(pOD->optArg.argString); + else + AGDUPSTR(pOD->optCookie, pOD->optArg.argString, "file name"); + + pOD->optArg.argFp = fp; + pOD->fOptState &= ~OPTST_ALLOC_ARG; +} + +/*=export_func optionFileCheck + * private: + * + * what: Decipher a boolean value + * arg: + tOptions * + pOpts + program options descriptor + + * arg: + tOptDesc * + pOptDesc + the descriptor for this arg + + * arg: + teOptFileType + ftype + File handling type + + * arg: + tuFileMode + mode + file open mode (if needed) + + * + * doc: + * Make sure the named file conforms with the file type mode. + * The mode specifies if the file must exist, must not exist or may + * (or may not) exist. The mode may also specify opening the + * file: don't, open just the descriptor (fd), or open as a stream + * (FILE * pointer). +=*/ +void +optionFileCheck(tOptions * pOpts, tOptDesc * pOD, + teOptFileType ftype, tuFileMode mode) +{ + if (pOpts <= OPTPROC_EMIT_LIMIT) { + if (pOpts != OPTPROC_EMIT_USAGE) + return; + + switch (ftype & FTYPE_MODE_EXIST_MASK) { + case FTYPE_MODE_MUST_NOT_EXIST: + fputs(zFileCannotExist + tab_skip_ct, option_usage_fp); + break; + + case FTYPE_MODE_MUST_EXIST: + fputs(zFileMustExist + tab_skip_ct, option_usage_fp); + break; + } + return; + } + + if ((pOD->fOptState & OPTST_RESET) != 0) { + if (pOD->optCookie != NULL) + AGFREE(pOD->optCookie); + return; + } + + check_existence(ftype, pOpts, pOD); + + switch (ftype & FTYPE_MODE_OPEN_MASK) { + default: + case FTYPE_MODE_NO_OPEN: break; + case FTYPE_MODE_OPEN_FD: open_file_fd( pOpts, pOD, mode); break; + case FTYPE_MODE_FOPEN_FP: fopen_file_fp(pOpts, pOD, mode); break; + } +} + +/** @} + * + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of autoopts/file.c */ diff --git a/autoopts/find.c b/autoopts/find.c new file mode 100644 index 0000000..03ae103 --- /dev/null +++ b/autoopts/find.c @@ -0,0 +1,765 @@ +/** + * @file check.c + * + * @brief Hunt for options in the option descriptor list + * + * This file contains the routines that deal with processing quoted strings + * into an internal format. + * + * @addtogroup autoopts + * @{ + */ +/* + * This file is part of AutoOpts, a companion to AutoGen. + * AutoOpts is free software. + * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoOpts is available under any one of two licenses. The license + * in use must be one of these two and the choice is under the control + * of the user of the license. + * + * The GNU Lesser General Public License, version 3 or later + * See the files "COPYING.lgplv3" and "COPYING.gplv3" + * + * The Modified Berkeley Software Distribution License + * See the file "COPYING.mbsd" + * + * These files have the following sha256 sums: + * + * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 + * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 + * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + */ + +/** + * find the name and name length we are looking for + */ +static int +parse_opt(char const ** nm_pp, char ** arg_pp, char * buf, size_t bufsz) +{ + int res = 0; + char const * p = *nm_pp; + *arg_pp = NULL; + + for (;;) { + switch (*(p++)) { + case NUL: return res; + + case '=': + memcpy(buf, *nm_pp, (size_t)res); + + buf[res] = NUL; + *nm_pp = buf; + *arg_pp = (char *)p; + return res; + + default: + if (++res >= (int)bufsz) + return -1; + } + } +} + +/** + * print out the options that match the given name. + * + * @param pOpts option data + * @param opt_name name of option to look for + */ +static void +opt_ambiguities(tOptions * opts, char const * name, int nm_len) +{ + char const * const hyph = + NAMED_OPTS(opts) ? "" : LONG_OPT_MARKER; + + tOptDesc * pOD = opts->pOptDesc; + int idx = 0; + + fputs(zambig_list_msg, stderr); + do { + if (pOD->pz_Name == NULL) + continue; /* doc option */ + + if (strneqvcmp(name, pOD->pz_Name, nm_len) == 0) + fprintf(stderr, zambig_file, hyph, pOD->pz_Name); + + else if ( (pOD->pz_DisableName != NULL) + && (strneqvcmp(name, pOD->pz_DisableName, nm_len) == 0) + ) + fprintf(stderr, zambig_file, hyph, pOD->pz_DisableName); + } while (pOD++, (++idx < opts->optCt)); +} + +/** + * Determine the number of options that match the name + * + * @param pOpts option data + * @param opt_name name of option to look for + * @param nm_len length of provided name + * @param index pointer to int for option index + * @param disable pointer to bool to mark disabled option + * @return count of options that match + */ +static int +opt_match_ct(tOptions * opts, char const * name, int nm_len, + int * ixp, bool * disable) +{ + int matchCt = 0; + int idx = 0; + int idxLim = opts->optCt; + tOptDesc * pOD = opts->pOptDesc; + + do { + /* + * If option disabled or a doc option, skip to next + */ + if (pOD->pz_Name == NULL) + continue; + + if ( SKIP_OPT(pOD) + && (pOD->fOptState != (OPTST_OMITTED | OPTST_NO_INIT))) + continue; + + if (strneqvcmp(name, pOD->pz_Name, nm_len) == 0) { + /* + * IF we have a complete match + * THEN it takes priority over any already located partial + */ + if (pOD->pz_Name[ nm_len ] == NUL) { + *ixp = idx; + return 1; + } + } + + /* + * IF there is a disable name + * *AND* the option name matches the disable name + * THEN ... + */ + else if ( (pOD->pz_DisableName != NULL) + && (strneqvcmp(name, pOD->pz_DisableName, nm_len) == 0) + ) { + *disable = true; + + /* + * IF we have a complete match + * THEN it takes priority over any already located partial + */ + if (pOD->pz_DisableName[ nm_len ] == NUL) { + *ixp = idx; + return 1; + } + } + + else + continue; /* does not match any option */ + + /* + * We found a full or partial match, either regular or disabling. + * Remember the index for later. + */ + *ixp = idx; + ++matchCt; + + } while (pOD++, (++idx < idxLim)); + + return matchCt; +} + +/** + * Set the option to the indicated option number. + * + * @param opts option data + * @param arg option argument (if glued to name) + * @param idx option index + * @param disable mark disabled option + * @param st state about current option + */ +static tSuccess +opt_set(tOptions * opts, char * arg, int idx, bool disable, tOptState * st) +{ + tOptDesc * pOD = opts->pOptDesc + idx; + + if (SKIP_OPT(pOD)) { + if ((opts->fOptSet & OPTPROC_ERRSTOP) == 0) + return FAILURE; + + fprintf(stderr, zDisabledErr, opts->pzProgName, pOD->pz_Name); + if (pOD->pzText != NULL) + fprintf(stderr, SET_OFF_FMT, pOD->pzText); + fputc(NL, stderr); + (*opts->pUsageProc)(opts, EXIT_FAILURE); + /* NOTREACHED */ + _exit(EXIT_FAILURE); /* to be certain */ + } + + /* + * IF we found a disablement name, + * THEN set the bit in the callers' flag word + */ + if (disable) + st->flags |= OPTST_DISABLED; + + st->pOD = pOD; + st->pzOptArg = arg; + st->optType = TOPT_LONG; + + return SUCCESS; +} + +/** + * An option was not found. Check for default option and set it + * if there is one. Otherwise, handle the error. + * + * @param opts option data + * @param name name of option to look for + * @param arg option argument + * @param st state about current option + * + * @return success status + */ +static tSuccess +opt_unknown(tOptions * opts, char const * name, char * arg, tOptState * st) +{ + /* + * IF there is no equal sign + * *AND* we are using named arguments + * *AND* there is a default named option, + * THEN return that option. + */ + if ( (arg == NULL) + && NAMED_OPTS(opts) + && (opts->specOptIdx.default_opt != NO_EQUIVALENT)) { + + st->pOD = opts->pOptDesc + opts->specOptIdx.default_opt; + st->pzOptArg = name; + st->optType = TOPT_DEFAULT; + return SUCCESS; + } + + if ((opts->fOptSet & OPTPROC_ERRSTOP) != 0) { + fprintf(stderr, zIllOptStr, opts->pzProgPath, name); + (*opts->pUsageProc)(opts, EXIT_FAILURE); + /* NOTREACHED */ + _exit(EXIT_FAILURE); /* to be certain */ + } + + return FAILURE; +} + +/** + * Several options match the provided name. + * + * @param opts option data + * @param name name of option to look for + * @param match_ct number of matching options + * + * @return success status (always FAILURE, if it returns) + */ +static tSuccess +opt_ambiguous(tOptions * opts, char const * name, int match_ct) +{ + if ((opts->fOptSet & OPTPROC_ERRSTOP) != 0) { + fprintf(stderr, zambig_opt_fmt, opts->pzProgPath, name, match_ct); + if (match_ct <= 4) + opt_ambiguities(opts, name, (int)strlen(name)); + (*opts->pUsageProc)(opts, EXIT_FAILURE); + /* NOTREACHED */ + _exit(EXIT_FAILURE); /* to be certain */ + } + return FAILURE; +} + +/*=export_func optionVendorOption + * private: + * + * what: Process a vendor option + * arg: + tOptions * + pOpts + program options descriptor + + * arg: + tOptDesc * + pOptDesc + the descriptor for this arg + + * + * doc: + * For POSIX specified utilities, the options are constrained to the options, + * @xref{config attributes, Program Configuration}. AutoOpts clients should + * never specify this directly. It gets referenced when the option + * definitions contain a "vendor-opt" attribute. +=*/ +void +optionVendorOption(tOptions * pOpts, tOptDesc * pOD) +{ + tOptState opt_st = OPTSTATE_INITIALIZER(PRESET); + char const * vopt_str = pOD->optArg.argString; + + if (pOpts <= OPTPROC_EMIT_LIMIT) + return; + + if ((pOD->fOptState & OPTST_RESET) != 0) + return; + + if ((pOD->fOptState & OPTPROC_IMMEDIATE) == 0) + opt_st.flags = OPTST_DEFINED; + + if ( ((pOpts->fOptSet & OPTPROC_VENDOR_OPT) == 0) + || ! SUCCESSFUL(opt_find_long(pOpts, vopt_str, &opt_st)) + || ! SUCCESSFUL(get_opt_arg(pOpts, &opt_st)) ) + { + fprintf(stderr, zIllVendOptStr, pOpts->pzProgName, vopt_str); + (*pOpts->pUsageProc)(pOpts, EXIT_FAILURE); + /* NOTREACHED */ + _exit(EXIT_FAILURE); /* to be certain */ + } + + /* + * See if we are in immediate handling state. + */ + if (pOpts->fOptSet & OPTPROC_IMMEDIATE) { + /* + * See if the enclosed option is okay with that state. + */ + if (DO_IMMEDIATELY(opt_st.flags)) + (void)handle_opt(pOpts, &opt_st); + + } else { + /* + * non-immediate direction. + * See if the enclosed option is okay with that state. + */ + if (DO_NORMALLY(opt_st.flags) || DO_SECOND_TIME(opt_st.flags)) + (void)handle_opt(pOpts, &opt_st); + } +} + +/** + * Find the option descriptor by full name. + * + * @param opts option data + * @param opt_name name of option to look for + * @param state state about current option + * + * @return success status + */ +static tSuccess +opt_find_long(tOptions * opts, char const * opt_name, tOptState * state) +{ + char name_buf[128]; + char * opt_arg; + int nm_len = parse_opt(&opt_name, &opt_arg, name_buf, sizeof(name_buf)); + + int idx = 0; + bool disable = false; + int ct; + + if (nm_len <= 1) { + if ((opts->fOptSet & OPTPROC_ERRSTOP) == 0) + return FAILURE; + + fprintf(stderr, zInvalOptName, opts->pzProgName, opt_name); + (*opts->pUsageProc)(opts, EXIT_FAILURE); + /* NOTREACHED */ + _exit(EXIT_FAILURE); /* to be certain */ + } + + ct = opt_match_ct(opts, opt_name, nm_len, &idx, &disable); + + /* + * See if we found one match, no matches or multiple matches. + */ + switch (ct) { + case 1: return opt_set(opts, opt_arg, idx, disable, state); + case 0: return opt_unknown(opts, opt_name, opt_arg, state); + default: return opt_ambiguous(opts, opt_name, ct); + } +} + + +/** + * Find the short option descriptor for the current option + * + * @param pOpts option data + * @param optValue option flag character + * @param pOptState state about current option + */ +static tSuccess +opt_find_short(tOptions * pOpts, uint_t optValue, tOptState * pOptState) +{ + tOptDesc * pRes = pOpts->pOptDesc; + int ct = pOpts->optCt; + + /* + * Search the option list + */ + do { + if (optValue != pRes->optValue) + continue; + + if (SKIP_OPT(pRes)) { + if ( (pRes->fOptState == (OPTST_OMITTED | OPTST_NO_INIT)) + && (pRes->pz_Name != NULL)) { + if ((pOpts->fOptSet & OPTPROC_ERRSTOP) == 0) + return FAILURE; + + fprintf(stderr, zDisabledErr, pOpts->pzProgPath, pRes->pz_Name); + if (pRes->pzText != NULL) + fprintf(stderr, SET_OFF_FMT, pRes->pzText); + fputc(NL, stderr); + (*pOpts->pUsageProc)(pOpts, EXIT_FAILURE); + /* NOTREACHED */ + _exit(EXIT_FAILURE); /* to be certain */ + } + goto short_opt_error; + } + + pOptState->pOD = pRes; + pOptState->optType = TOPT_SHORT; + return SUCCESS; + + } while (pRes++, --ct > 0); + + /* + * IF the character value is a digit + * AND there is a special number option ("-n") + * THEN the result is the "option" itself and the + * option is the specially marked "number" option. + */ + if ( IS_DEC_DIGIT_CHAR(optValue) + && (pOpts->specOptIdx.number_option != NO_EQUIVALENT) ) { + pOptState->pOD = \ + pRes = pOpts->pOptDesc + pOpts->specOptIdx.number_option; + (pOpts->pzCurOpt)--; + pOptState->optType = TOPT_SHORT; + return SUCCESS; + } + + short_opt_error: + + /* + * IF we are to stop on errors (the default, actually) + * THEN call the usage procedure. + */ + if ((pOpts->fOptSet & OPTPROC_ERRSTOP) != 0) { + fprintf(stderr, zIllOptChr, pOpts->pzProgPath, optValue); + (*pOpts->pUsageProc)(pOpts, EXIT_FAILURE); + /* NOTREACHED */ + _exit(EXIT_FAILURE); /* to be certain */ + } + + return FAILURE; +} + +/** + * Process option with a required argument. Long options can either have a + * separate command line argument, or an argument attached by the '=' + * character. Figure out which. + * + * @param[in,out] opts the program option descriptor + * @param[in,out] o_st the option processing state + * @returns SUCCESS or FAILURE + */ +static tSuccess +get_opt_arg_must(tOptions * opts, tOptState * o_st) +{ + switch (o_st->optType) { + case TOPT_SHORT: + /* + * See if an arg string follows the flag character + */ + if (*++(opts->pzCurOpt) == NUL) + opts->pzCurOpt = opts->origArgVect[ opts->curOptIdx++ ]; + o_st->pzOptArg = opts->pzCurOpt; + break; + + case TOPT_LONG: + /* + * See if an arg string has already been assigned (glued on + * with an `=' character) + */ + if (o_st->pzOptArg == NULL) + o_st->pzOptArg = opts->origArgVect[ opts->curOptIdx++ ]; + break; + + default: +#ifdef DEBUG + fputs("AutoOpts lib error: option type not selected\n", stderr); + option_exits(EXIT_FAILURE); +#endif + + case TOPT_DEFAULT: + /* + * The option was selected by default. The current token is + * the option argument. + */ + break; + } + + /* + * Make sure we did not overflow the argument list. + */ + if (opts->curOptIdx > opts->origArgCt) { + fprintf(stderr, zMisArg, opts->pzProgPath, o_st->pOD->pz_Name); + return FAILURE; + } + + opts->pzCurOpt = NULL; /* next time advance to next arg */ + return SUCCESS; +} + +/** + * Process an option with an optional argument. For short options, it looks + * at the character after the option character, or it consumes the next full + * argument. For long options, it looks for an '=' character attachment to + * the long option name before deciding to take the next command line + * argument. + * + * @param pOpts the option descriptor + * @param o_st a structure for managing the current processing state + * @returns SUCCESS or does not return + */ +static tSuccess +get_opt_arg_may(tOptions * pOpts, tOptState * o_st) +{ + /* + * An option argument is optional. + */ + switch (o_st->optType) { + case TOPT_SHORT: + if (*++pOpts->pzCurOpt != NUL) + o_st->pzOptArg = pOpts->pzCurOpt; + else { + char * pzLA = pOpts->origArgVect[ pOpts->curOptIdx ]; + + /* + * BECAUSE it is optional, we must make sure + * we did not find another flag and that there + * is such an argument. + */ + if ((pzLA == NULL) || (*pzLA == '-')) + o_st->pzOptArg = NULL; + else { + pOpts->curOptIdx++; /* argument found */ + o_st->pzOptArg = pzLA; + } + } + break; + + case TOPT_LONG: + /* + * Look for an argument if we don't already have one (glued on + * with a `=' character) *AND* we are not in named argument mode + */ + if ( (o_st->pzOptArg == NULL) + && (! NAMED_OPTS(pOpts))) { + char * pzLA = pOpts->origArgVect[ pOpts->curOptIdx ]; + + /* + * BECAUSE it is optional, we must make sure + * we did not find another flag and that there + * is such an argument. + */ + if ((pzLA == NULL) || (*pzLA == '-')) + o_st->pzOptArg = NULL; + else { + pOpts->curOptIdx++; /* argument found */ + o_st->pzOptArg = pzLA; + } + } + break; + + default: + case TOPT_DEFAULT: + ao_bug(zbad_default_msg); + } + + /* + * After an option with an optional argument, we will + * *always* start with the next option because if there + * were any characters following the option name/flag, + * they would be interpreted as the argument. + */ + pOpts->pzCurOpt = NULL; + return SUCCESS; +} + +/** + * Process option that does not have an argument. + * + * @param[in,out] opts the program option descriptor + * @param[in,out] o_st the option processing state + * @returns SUCCESS or FAILURE + */ +static tSuccess +get_opt_arg_none(tOptions * pOpts, tOptState * o_st) +{ + /* + * No option argument. Make sure next time around we find + * the correct option flag character for short options + */ + if (o_st->optType == TOPT_SHORT) + (pOpts->pzCurOpt)++; + + /* + * It is a long option. Make sure there was no ``=xxx'' argument + */ + else if (o_st->pzOptArg != NULL) { + fprintf(stderr, zNoArg, pOpts->pzProgPath, o_st->pOD->pz_Name); + return FAILURE; + } + + /* + * It is a long option. Advance to next command line argument. + */ + else + pOpts->pzCurOpt = NULL; + + return SUCCESS; +} + +/** + * Process option. Figure out whether or not to look for an option argument. + * + * @param[in,out] opts the program option descriptor + * @param[in,out] o_st the option processing state + * @returns SUCCESS or FAILURE + */ +static tSuccess +get_opt_arg(tOptions * opts, tOptState * o_st) +{ + o_st->flags |= (o_st->pOD->fOptState & OPTST_PERSISTENT_MASK); + + /* + * Disabled options and options specified to not have arguments + * are handled with the "none" procedure. Otherwise, check the + * optional flag and call either the "may" or "must" function. + */ + if ((o_st->flags & OPTST_DISABLED) != 0) + return get_opt_arg_none(opts, o_st); + + switch (OPTST_GET_ARGTYPE(o_st->flags)) { + case OPARG_TYPE_STATIC: + { + /* + * Propagate the static arg + */ + tSuccess res = get_opt_arg_none(opts, o_st); + o_st->pzOptArg = o_st->pOD->optArg.argString; + return res; + } + + case OPARG_TYPE_NONE: + return get_opt_arg_none(opts, o_st); + } + + if (o_st->flags & OPTST_ARG_OPTIONAL) + return get_opt_arg_may( opts, o_st); + + return get_opt_arg_must(opts, o_st); +} + +/** + * Find the option descriptor for the current option. + * + * @param[in,out] opts the program option descriptor + * @param[in,out] o_st the option processing state + * @returns SUCCESS or FAILURE + */ +static tSuccess +find_opt(tOptions * opts, tOptState * o_st) +{ + /* + * IF we are continuing a short option list (e.g. -xyz...) + * THEN continue a single flag option. + * OTHERWISE see if there is room to advance and then do so. + */ + if ((opts->pzCurOpt != NULL) && (*opts->pzCurOpt != NUL)) + return opt_find_short(opts, (uint8_t)*(opts->pzCurOpt), o_st); + + if (opts->curOptIdx >= opts->origArgCt) + return PROBLEM; /* NORMAL COMPLETION */ + + opts->pzCurOpt = opts->origArgVect[ opts->curOptIdx ]; + + /* + * IF all arguments must be named options, ... + */ + if (NAMED_OPTS(opts)) { + char * pz = opts->pzCurOpt; + int def; + tSuccess res; + uint16_t * def_opt; + + opts->curOptIdx++; + + if (*pz != '-') + return opt_find_long(opts, pz, o_st); + + /* + * The name is prefixed with one or more hyphens. Strip them off + * and disable the "default_opt" setting. Use heavy recasting to + * strip off the "const" quality of the "default_opt" field. + */ + while (*(++pz) == '-') ; + def_opt = VOIDP(&(opts->specOptIdx.default_opt)); + def = *def_opt; + *def_opt = NO_EQUIVALENT; + res = opt_find_long(opts, pz, o_st); + *def_opt = (uint16_t)def; + return res; + } + + /* + * Note the kind of flag/option marker + */ + if (*((opts->pzCurOpt)++) != '-') + return PROBLEM; /* NORMAL COMPLETION - this + rest are operands */ + + /* + * Special hack for a hyphen by itself + */ + if (*(opts->pzCurOpt) == NUL) + return PROBLEM; /* NORMAL COMPLETION - this + rest are operands */ + + /* + * The current argument is to be processed as an option argument + */ + opts->curOptIdx++; + + /* + * We have an option marker. + * Test the next character for long option indication + */ + if (opts->pzCurOpt[0] == '-') { + if (*++(opts->pzCurOpt) == NUL) + /* + * NORMAL COMPLETION - NOT this arg, but rest are operands + */ + return PROBLEM; + + /* + * We do not allow the hyphen to be used as a flag value. + * Therefore, if long options are not to be accepted, we punt. + */ + if ((opts->fOptSet & OPTPROC_LONGOPT) == 0) { + fprintf(stderr, zIllOptStr, opts->pzProgPath, opts->pzCurOpt-2); + return FAILURE; + } + + return opt_find_long(opts, opts->pzCurOpt, o_st); + } + + /* + * If short options are not allowed, then do long + * option processing. Otherwise the character must be a + * short (i.e. single character) option. + */ + if ((opts->fOptSet & OPTPROC_SHORTOPT) != 0) + return opt_find_short(opts, (uint8_t)*(opts->pzCurOpt), o_st); + + return opt_find_long(opts, opts->pzCurOpt, o_st); +} + +/** @} + * + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of autoopts/find.c */ diff --git a/autoopts/funcs.def b/autoopts/funcs.def new file mode 100644 index 0000000..f820c26 --- /dev/null +++ b/autoopts/funcs.def @@ -0,0 +1,1666 @@ +/* -*- buffer-read-only: t -*- vi: set ro: + * + * + * DO NOT EDIT THIS FILE (funcs.def) + * + * It has been extracted by getdefs from the following files: + * + * autoopts.c + * alias.c + * boolean.c + * check.c + * configfile.c + * cook.c + * enum.c + * env.c + * file.c + * find.c + * genshell.c + * load.c + * makeshell.c + * nested.c + * numeric.c + * pgusage.c + * putshell.c + * reset.c + * restore.c + * save.c + * sort.c + * stack.c + * streqvcmp.c + * text_mmap.c + * time.c + * tokenize.c + * usage.c + * version.c + * init.c + */ +autogen definitions options_h; + +/* GLOBALDEFS */ + +#line 279 "autoopts.c" + library = 'opts'; + header = 'your-opts.h'; + lib_description = +'These are the routines that libopts users may call directly from their +code. There are several other routines that can be called by code +generated by the libopts option templates, but they are not to be +called from any other user code. The @file{options.h} header is +fairly clear about this, too.'; + + +#line 212 "cook.c" +export_func = { + name = 'ao_string_cook'; + private; + what = 'concatenate and escape-process strings'; + arg = { + arg_type = 'char *'; + arg_name = 'pzScan'; + arg_desc = 'The *MODIFIABLE* input buffer'; + }; + arg = { + arg_type = 'int *'; + arg_name = 'lnct_p'; + arg_desc = 'The (possibly NULL) pointer to a line count'; + }; + ret-type = 'char *'; + ret-desc = 'The address of the text following the processed strings. +The return value is NULL if the strings are ill-formed.'; + doc = +'A series of one or more quoted strings are concatenated together. +If they are quoted with double quotes (@code{"}), then backslash +escapes are processed per the C programming language. If they are +single quote strings, then the backslashes are honored only when they +precede another backslash or a single quote character.'; + err = '@code{NULL} is returned if the string(s) is/are mal-formed.'; + srcfile = 'cook.c'; + linenum = '212'; +}; + + +#line 32 "cook.c" +export_func = { + name = 'ao_string_cook_escape_char'; + private; + what = 'escape-process a string fragment'; + arg = { + arg_type = 'char const *'; + arg_name = 'pzScan'; + arg_desc = 'points to character after the escape'; + }; + arg = { + arg_type = 'char *'; + arg_name = 'pRes'; + arg_desc = 'Where to put the result byte'; + }; + arg = { + arg_type = 'unsigned int'; + arg_name = 'nl_ch'; + arg_desc = 'replacement char if scanned char is \n'; + }; + ret-type = 'unsigned int'; + ret-desc = 'The number of bytes consumed processing the escaped character.'; + doc = +'This function converts "t" into "\\t" and all your other favorite +escapes, including numeric ones: hex and ocatal, too. +The returned result tells the caller how far to advance the +scan pointer (passed in). The default is to just pass through the +escaped character and advance the scan by one. + +Some applications need to keep an escaped newline, others need to +suppress it. This is accomplished by supplying a \'\\n\' replacement +character that is different from \\n, if need be. For example, use +0x7F and never emit a 0x7F.'; + err = '@code{NULL} is returned if the string is mal-formed.'; + srcfile = 'cook.c'; + linenum = '32'; +}; + + +#line 152 "tokenize.c" +export_func = { + name = 'ao_string_tokenize'; + what = 'tokenize an input string'; + arg = { + arg_type = 'char const *'; + arg_name = 'string'; + arg_desc = 'string to be tokenized'; + }; + ret_type = 'token_list_t *'; + ret_desc = 'pointer to a structure that lists each token'; + doc = +'This function will convert one input string into a list of strings. +The list of strings is derived by separating the input based on +white space separation. However, if the input contains either single +or double quote characters, then the text after that character up to +a matching quote will become the string in the list. + +The returned pointer should be deallocated with @code{free(3C)} when +are done using the data. The data are placed in a single block of +allocated memory. Do not deallocate individual token/strings. + +The structure pointed to will contain at least these two fields: +@table @samp +@item tkn_ct +The number of tokens found in the input string. +@item tok_list +An array of @code{tkn_ct + 1} pointers to substring tokens, with +the last pointer set to NULL. +@end table + +There are two types of quoted strings: single quoted (@code{\'}) and +double quoted (@code{"}). Singly quoted strings are fairly raw in that +escape characters (@code{\\\\}) are simply another character, except when +preceding the following characters: +@example +@code{\\\\} double backslashes reduce to one +@code{\'} incorporates the single quote into the string +@code{\\n} suppresses both the backslash and newline character +@end example + +Double quote strings are formed according to the rules of string +constants in ANSI-C programs.'; + example = +'@example +#include +int ix; +token_list_t * ptl = ao_string_tokenize(some_string) +for (ix = 0; ix < ptl->tkn_ct; ix++) +do_something_with_tkn(ptl->tkn_list[ix]); +free(ptl); +@end example +Note that everything is freed with the one call to @code{free(3C)}.'; + err = +'NULL is returned and @code{errno} will be set to indicate the problem: +@itemize @bullet +@item +@code{EINVAL} - There was an unterminated quoted string. +@item +@code{ENOENT} - The input string was empty. +@item +@code{ENOMEM} - There is not enough memory. +@end itemize'; + srcfile = 'tokenize.c'; + linenum = '152'; +}; + + +#line 43 "configfile.c" +export_func = { + name = 'configFileLoad'; + what = 'parse a configuration file'; + arg = { + arg_type = 'char const *'; + arg_name = 'fname'; + arg_desc = 'the file to load'; + }; + ret_type = 'const tOptionValue *'; + ret_desc = 'An allocated, compound value structure'; + doc = +'This routine will load a named configuration file and parse the +text as a hierarchically valued option. The option descriptor +created from an option definition file is not used via this interface. +The returned value is "named" with the input file name and is of +type "@code{OPARG_TYPE_HIERARCHY}". It may be used in calls to +@code{optionGetValue()}, @code{optionNextValue()} and +@code{optionUnloadNested()}.'; + err = +'If the file cannot be loaded or processed, @code{NULL} is returned and +@var{errno} is set. It may be set by a call to either @code{open(2)} +@code{mmap(2)} or other file system calls, or it may be: +@itemize @bullet +@item +@code{ENOENT} - the file was not found. +@item +@code{ENOMSG} - the file was empty. +@item +@code{EINVAL} - the file contents are invalid -- not properly formed. +@item +@code{ENOMEM} - not enough memory to allocate the needed structures. +@end itemize'; + srcfile = 'configfile.c'; + linenum = '43'; +}; + + +#line 811 "makeshell.c" +export_func = { + name = 'genshelloptUsage'; + private; + what = 'The usage function for the genshellopt generated program'; + arg = { + arg_type = 'tOptions *'; + arg_name = 'opts'; + arg_desc = 'program options descriptor'; + }; + arg = { + arg_type = 'int'; + arg_name = 'exit_cd'; + arg_desc = 'usage text type to produce'; + }; + doc = +'This function is used to create the usage strings for the option +processing shell script code. Two child processes are spawned +each emitting the usage text in either the short (error exit) +style or the long style. The generated program will capture this +and create shell script variables containing the two types of text.'; + srcfile = 'makeshell.c'; + linenum = '811'; +}; + + +#line 53 "alias.c" +export_func = { + name = 'optionAlias'; + private; + what = 'relay an option to its alias'; + arg = { + arg_type = 'tOptions *'; + arg_name = 'opts'; + arg_desc = 'program options descriptor'; + }; + arg = { + arg_type = 'tOptDesc *'; + arg_name = 'old_od'; + arg_desc = 'the descriptor for this arg'; + }; + arg = { + arg_type = 'unsigned int'; + arg_name = 'alias'; + arg_desc = 'the aliased-to option index'; + }; + ret-type = 'int'; + doc = +'Handle one option as if it had been specified as another. Exactly. +Returns "-1" if the aliased-to option has appeared too many times.'; + srcfile = 'alias.c'; + linenum = '53'; +}; + + +#line 35 "boolean.c" +export_func = { + name = 'optionBooleanVal'; + private; + what = 'Decipher a boolean value'; + arg = { + arg_type = 'tOptions *'; + arg_name = 'opts'; + arg_desc = 'program options descriptor'; + }; + arg = { + arg_type = 'tOptDesc *'; + arg_name = 'od'; + arg_desc = 'the descriptor for this arg'; + }; + doc = +'Decipher a true or false value for a boolean valued option argument. +The value is true, unless it starts with \'n\' or \'f\' or "#f" or +it is an empty string or it is a number that evaluates to zero.'; + srcfile = 'boolean.c'; + linenum = '35'; +}; + + +#line 240 "enum.c" +export_func = { + name = 'optionEnumerationVal'; + what = 'Convert from a string to an enumeration value'; + private; + arg = { + arg_type = 'tOptions *'; + arg_name = 'pOpts'; + arg_desc = 'the program options descriptor'; + }; + arg = { + arg_type = 'tOptDesc *'; + arg_name = 'pOD'; + arg_desc = 'enumeration option description'; + }; + arg = { + arg_type = 'char const * const *'; + arg_name = 'paz_names'; + arg_desc = 'list of enumeration names'; + }; + arg = { + arg_type = 'unsigned int'; + arg_name = 'name_ct'; + arg_desc = 'number of names in list'; + }; + ret_type = 'uintptr_t'; + ret_desc = 'the enumeration value'; + doc = 'This converts the optArg.argString string from the option description +into the index corresponding to an entry in the name list. +This will match the generated enumeration value. +Full matches are always accepted. Partial matches are accepted +if there is only one partial match.'; + srcfile = 'enum.c'; + linenum = '240'; +}; + + +#line 142 "file.c" +export_func = { + name = 'optionFileCheck'; + private; + what = 'Decipher a boolean value'; + arg = { + arg_type = 'tOptions *'; + arg_name = 'pOpts'; + arg_desc = 'program options descriptor'; + }; + arg = { + arg_type = 'tOptDesc *'; + arg_name = 'pOptDesc'; + arg_desc = 'the descriptor for this arg'; + }; + arg = { + arg_type = 'teOptFileType'; + arg_name = 'ftype'; + arg_desc = 'File handling type'; + }; + arg = { + arg_type = 'tuFileMode'; + arg_name = 'mode'; + arg_desc = 'file open mode (if needed)'; + }; + doc = +'Make sure the named file conforms with the file type mode. +The mode specifies if the file must exist, must not exist or may +(or may not) exist. The mode may also specify opening the'; + file = 'don\'t, open just the descriptor (fd), or open as a stream +(FILE * pointer).'; + srcfile = 'file.c'; + linenum = '142'; +}; + + +#line 1051 "configfile.c" +export_func = { + name = 'optionFileLoad'; + what = 'Load the locatable config files, in order'; + arg = { + arg_type = 'tOptions *'; + arg_name = 'opts'; + arg_desc = 'program options descriptor'; + }; + arg = { + arg_type = 'char const *'; + arg_name = 'prog'; + arg_desc = 'program name'; + }; + ret_type = 'int'; + ret_desc = '0 -> SUCCESS, -1 -> FAILURE'; + doc = +'This function looks in all the specified directories for a configuration +file ("rc" file or "ini" file) and processes any found twice. The first +time through, they are processed in reverse order (last file first). At +that time, only "immediate action" configurables are processed. For +example, if the last named file specifies not processing any more +configuration files, then no more configuration files will be processed. +Such an option in the @strong{first} named directory will have no effect. + +Once the immediate action configurables have been handled, then the +directories are handled in normal, forward order. In that way, later +config files can override the settings of earlier config files. + +See the AutoOpts documentation for a thorough discussion of the +config file format. + +Configuration files not found or not decipherable are simply ignored.'; + err = 'Returns the value, "-1" if the program options descriptor +is out of date or indecipherable. Otherwise, the value "0" will +always be returned.'; + srcfile = 'configfile.c'; + linenum = '1051'; +}; + + +#line 175 "configfile.c" +export_func = { + name = 'optionFindNextValue'; + FIXME = 'the handling of \'pzName\' and \'pzVal\' is just wrong.'; + what = 'find a hierarcicaly valued option instance'; + arg = { + arg_type = 'const tOptDesc *'; + arg_name = 'odesc'; + arg_desc = 'an option with a nested arg type'; + }; + arg = { + arg_type = 'const tOptionValue *'; + arg_name = 'pPrevVal'; + arg_desc = 'the last entry'; + }; + arg = { + arg_type = 'char const *'; + arg_name = 'name'; + arg_desc = 'name of value to find'; + }; + arg = { + arg_type = 'char const *'; + arg_name = 'value'; + arg_desc = 'the matching value'; + }; + ret_type = 'const tOptionValue *'; + ret_desc = 'a compound value structure'; + doc = +'This routine will find the next entry in a nested value option or +configurable. It will search through the list and return the next entry +that matches the criteria.'; + err = +'The returned result is NULL and errno is set: +@itemize @bullet +@item +@code{EINVAL} - the @code{pOptValue} does not point to a valid +hierarchical option value. +@item +@code{ENOENT} - no entry matched the given name. +@end itemize'; + srcfile = 'configfile.c'; + linenum = '175'; +}; + + +#line 102 "configfile.c" +export_func = { + name = 'optionFindValue'; + what = 'find a hierarcicaly valued option instance'; + arg = { + arg_type = 'const tOptDesc *'; + arg_name = 'odesc'; + arg_desc = 'an option with a nested arg type'; + }; + arg = { + arg_type = 'char const *'; + arg_name = 'name'; + arg_desc = 'name of value to find'; + }; + arg = { + arg_type = 'char const *'; + arg_name = 'val'; + arg_desc = 'the matching value'; + }; + ret_type = 'const tOptionValue *'; + ret_desc = 'a compound value structure'; + doc = +'This routine will find an entry in a nested value option or configurable. +It will search through the list and return a matching entry.'; + err = +'The returned result is NULL and errno is set: +@itemize @bullet +@item +@code{EINVAL} - the @code{pOptValue} does not point to a valid +hierarchical option value. +@item +@code{ENOENT} - no entry matched the given name. +@end itemize'; + srcfile = 'configfile.c'; + linenum = '102'; +}; + + +#line 159 "restore.c" +export_func = { + name = 'optionFree'; + what = 'free allocated option processing memory'; + arg = { + arg_type = 'tOptions *'; + arg_name = 'pOpts'; + arg_desc = 'program options descriptor'; + }; + doc = 'AutoOpts sometimes allocates memory and puts pointers to it in the +option state structures. This routine deallocates all such memory.'; + err = 'As long as memory has not been corrupted, +this routine is always successful.'; + srcfile = 'restore.c'; + linenum = '159'; +}; + + +#line 244 "configfile.c" +export_func = { + name = 'optionGetValue'; + what = 'get a specific value from a hierarcical list'; + arg = { + arg_type = 'const tOptionValue *'; + arg_name = 'pOptValue'; + arg_desc = 'a hierarchcal value'; + }; + arg = { + arg_type = 'char const *'; + arg_name = 'valueName'; + arg_desc = 'name of value to get'; + }; + ret_type = 'const tOptionValue *'; + ret_desc = 'a compound value structure'; + doc = +'This routine will find an entry in a nested value option or configurable. +If "valueName" is NULL, then the first entry is returned. Otherwise, +the first entry with a name that exactly matches the argument will be +returned. If there is no matching value, NULL is returned and errno is +set to ENOENT. If the provided option value is not a hierarchical value, +NULL is also returned and errno is set to EINVAL.'; + err = +'The returned result is NULL and errno is set: +@itemize @bullet +@item +@code{EINVAL} - the @code{pOptValue} does not point to a valid +hierarchical option value. +@item +@code{ENOENT} - no entry matched the given name. +@end itemize'; + srcfile = 'configfile.c'; + linenum = '244'; +}; + + +#line 217 "enum.c" +export_func = { + name = 'optionKeywordName'; + what = 'Convert between enumeration values and strings'; + private; + arg = { + arg_type = 'tOptDesc *'; + arg_name = 'pOD'; + arg_desc = 'enumeration option description'; + }; + arg = { + arg_type = 'unsigned int'; + arg_name = 'enum_val'; + arg_desc = 'the enumeration value to map'; + }; + ret_type = 'char const *'; + ret_desc = 'the enumeration name from const memory'; + doc = 'This converts an enumeration value into the matching string.'; + srcfile = 'enum.c'; + linenum = '217'; +}; + + +#line 533 "load.c" +export_func = { + name = 'optionLoadLine'; + what = 'process a string for an option name and value'; + arg = { + arg_type = 'tOptions *'; + arg_name = 'opts'; + arg_desc = 'program options descriptor'; + }; + arg = { + arg_type = 'char const *'; + arg_name = 'line'; + arg_desc = 'NUL-terminated text'; + }; + doc = +'This is a client program callable routine for setting options from, for +example, the contents of a file that they read in. Only one option may +appear in the text. It will be treated as a normal (non-preset) option. + +When passed a pointer to the option struct and a string, it will find +the option named by the first token on the string and set the option +argument to the remainder of the string. The caller must NUL terminate +the string. The caller need not skip over any introductory hyphens. +Any embedded new lines will be included in the option +argument. If the input looks like one or more quoted strings, then the +input will be "cooked". The "cooking" is identical to the string +formation used in AutoGen definition files (@pxref{basic expression}), +except that you may not use backquotes.'; + err = 'Invalid options are silently ignored. Invalid option arguments +will cause a warning to print, but the function should return.'; + srcfile = 'load.c'; + linenum = '533'; +}; + + +#line 1104 "configfile.c" +export_func = { + name = 'optionLoadOpt'; + private; + what = 'Load an option rc/ini file'; + arg = { + arg_type = 'tOptions *'; + arg_name = 'opts'; + arg_desc = 'program options descriptor'; + }; + arg = { + arg_type = 'tOptDesc *'; + arg_name = 'odesc'; + arg_desc = 'the descriptor for this arg'; + }; + doc = +'Processes the options found in the file named with +odesc->optArg.argString.'; + srcfile = 'configfile.c'; + linenum = '1104'; +}; + + +#line 73 "load.c" +export_func = { + name = 'optionMakePath'; + private; + what = 'translate and construct a path'; + arg = { + arg_type = 'char *'; + arg_name = 'p_buf'; + arg_desc = 'The result buffer'; + }; + arg = { + arg_type = 'int'; + arg_name = 'b_sz'; + arg_desc = 'The size of this buffer'; + }; + arg = { + arg_type = 'char const *'; + arg_name = 'fname'; + arg_desc = 'The input name'; + }; + arg = { + arg_type = 'char const *'; + arg_name = 'prg_path'; + arg_desc = 'The full path of the current program'; + }; + ret-type = 'bool'; + ret-desc = 'true if the name was handled, otherwise false. +If the name does not start with ``$\'\', then it is handled +simply by copying the input name to the output buffer and +resolving the name with either +@code{canonicalize_file_name(3GLIBC)} or @code{realpath(3C)}.'; + doc = +'This routine will copy the @code{pzName} input name into the +@code{pzBuf} output buffer, not exceeding @code{bufSize} bytes. If the +first character of the input name is a @code{\'$\'} character, then there +is special handling: +@* +@code{$$} is replaced with the directory name of the @code{pzProgPath}, +searching @code{$PATH} if necessary. +@* +@code{$@} is replaced with the AutoGen package data installation directory +(aka @code{pkgdatadir}). +@* +@code{$NAME} is replaced by the contents of the @code{NAME} environment +variable. If not found, the search fails. + +Please note: both @code{$$} and @code{$NAME} must be at the start of the +@code{pzName} string and must either be the entire string or be followed +by the @code{\'/\'} (backslash on windows) character.'; + err = '@code{false} is returned if: +@* +@bullet{} The input name exceeds @code{bufSize} bytes. +@* +@bullet{} @code{$$}, @code{$@@} or @code{$NAME} is not the full string +and the next character is not \'/\'. +@* +@bullet{} libopts was built without PKGDATADIR defined and @code{$@@} +was specified. +@* +@bullet{} @code{NAME} is not a known environment variable +@* +@bullet{} @code{canonicalize_file_name} or @code{realpath} return +errors (cannot resolve the resulting path).'; + srcfile = 'load.c'; + linenum = '73'; +}; + + +#line 483 "enum.c" +export_func = { + name = 'optionMemberList'; + what = 'Get the list of members of a bit mask set'; + arg = { + arg_type = 'tOptDesc *'; + arg_name = 'od'; + arg_desc = 'the set membership option description'; + }; + ret_type = 'char *'; + ret_desc = 'the names of the set bits'; + doc = 'This converts the OPT_VALUE_name mask value to a allocated string. +It is the caller\'s responsibility to free the string.'; + srcfile = 'enum.c'; + linenum = '483'; +}; + + +#line 782 "nested.c" +export_func = { + name = 'optionNestedVal'; + private; + what = 'parse a hierarchical option argument'; + arg = { + arg_type = 'tOptions *'; + arg_name = 'opts'; + arg_desc = 'program options descriptor'; + }; + arg = { + arg_type = 'tOptDesc *'; + arg_name = 'od'; + arg_desc = 'the descriptor for this arg'; + }; + doc = +'Nested value was found on the command line'; + srcfile = 'nested.c'; + linenum = '782'; +}; + + +#line 303 "configfile.c" +export_func = { + name = 'optionNextValue'; + what = 'get the next value from a hierarchical list'; + arg = { + arg_type = 'const tOptionValue *'; + arg_name = 'pOptValue'; + arg_desc = 'a hierarchcal list value'; + }; + arg = { + arg_type = 'const tOptionValue *'; + arg_name = 'pOldValue'; + arg_desc = 'a value from this list'; + }; + ret_type = 'const tOptionValue *'; + ret_desc = 'a compound value structure'; + doc = +'This routine will return the next entry after the entry passed in. At the +end of the list, NULL will be returned. If the entry is not found on the +list, NULL will be returned and "@var{errno}" will be set to EINVAL. +The "@var{pOldValue}" must have been gotten from a prior call to this +routine or to "@code{opitonGetValue()}".'; + err = +'The returned result is NULL and errno is set: +@itemize @bullet +@item +@code{EINVAL} - the @code{pOptValue} does not point to a valid +hierarchical option value or @code{pOldValue} does not point to a +member of that option value. +@item +@code{ENOENT} - the supplied @code{pOldValue} pointed to the last entry. +@end itemize'; + srcfile = 'configfile.c'; + linenum = '303'; +}; + + +#line 96 "numeric.c" +export_func = { + name = 'optionNumericVal'; + private; + what = 'process an option with a numeric value.'; + arg = { + arg_type = 'tOptions *'; + arg_name = 'opts'; + arg_desc = 'program options descriptor'; + }; + arg = { + arg_type = 'tOptDesc *'; + arg_name = 'od'; + arg_desc = 'the descriptor for this arg'; + }; + doc = +'Decipher a numeric value.'; + srcfile = 'numeric.c'; + linenum = '96'; +}; + + +#line 189 "usage.c" +export_func = { + name = 'optionOnlyUsage'; + what = 'Print usage text for just the options'; + arg = { + arg_type = 'tOptions *'; + arg_name = 'pOpts'; + arg_desc = 'program options descriptor'; + }; + arg = { + arg_type = 'int'; + arg_name = 'ex_code'; + arg_desc = 'exit code for calling exit(3)'; + }; + doc = +'This routine will print only the usage for each option. +This function may be used when the emitted usage must incorporate +information not available to AutoOpts.'; + srcfile = 'usage.c'; + linenum = '189'; +}; + + +#line 97 "pgusage.c" +export_func = { + name = 'optionPagedUsage'; + private; + what = 'emit help text and pass through a pager program.'; + arg = { + arg_type = 'tOptions *'; + arg_name = 'opts'; + arg_desc = 'program options descriptor'; + }; + arg = { + arg_type = 'tOptDesc *'; + arg_name = 'od'; + arg_desc = 'the descriptor for this arg'; + }; + doc = +'Run the usage output through a pager. +This is very handy if it is very long. +This is disabled on platforms without a working fork() function.'; + srcfile = 'pgusage.c'; + linenum = '97'; +}; + + +#line 67 "makeshell.c" +export_func = { + name = 'optionParseShell'; + private; + what = 'Decipher a boolean value'; + arg = { + arg_type = 'tOptions *'; + arg_name = 'pOpts'; + arg_desc = 'program options descriptor'; + }; + doc = +'Emit a shell script that will parse the command line options.'; + srcfile = 'makeshell.c'; + linenum = '67'; +}; + + +#line 391 "usage.c" +export_func = { + name = 'optionPrintParagraphs'; + private; + what = 'Print a paragraph of usage text'; + arg = { + arg_type = 'char const *'; + arg_name = 'text'; + arg_desc = 'a block of text that has bee i18n-ed'; + }; + arg = { + arg_type = 'bool'; + arg_name = 'plain'; + arg_desc = 'false -> wrap text in fputs()'; + }; + arg = { + arg_type = 'FILE *'; + arg_name = 'fp'; + arg_desc = 'the stream file pointer for output'; + }; + doc = +'This procedure is called in two contexts: when a full or short usage text +has been provided for display, and when autogen is assembling a list of +translatable texts in the optmain.tlib template. In the former case, \\a +plain is set to \\a true, otherwise \\a false. + +Anything less than 256 characters in size is printed as a single unit. +Otherwise, paragraphs are detected. A paragraph break is defined as just +before a non-empty line preceded by two newlines or a line that starts +with at least one space character but fewer than 8 space characters. +Lines indented with tabs or more than 7 spaces are considered continuation +lines. + +If \'plain\' is true, we are emitting text for a user to see. So, if it is +true and NLS is not enabled, then just write the whole thing at once.'; + srcfile = 'usage.c'; + linenum = '391'; +}; + + +#line 184 "version.c" +export_func = { + name = 'optionPrintVersion'; + what = 'Print the program version'; + arg = { + arg_type = 'tOptions *'; + arg_name = 'opts'; + arg_desc = 'program options descriptor'; + }; + arg = { + arg_type = 'tOptDesc *'; + arg_name = 'od'; + arg_desc = 'the descriptor for this arg'; + }; + doc = +'This routine will print the version to stdout.'; + srcfile = 'version.c'; + linenum = '184'; +}; + + +#line 199 "version.c" +export_func = { + name = 'optionPrintVersionAndReturn'; + what = 'Print the program version'; + arg = { + arg_type = 'tOptions *'; + arg_name = 'opts'; + arg_desc = 'program options descriptor'; + }; + arg = { + arg_type = 'tOptDesc *'; + arg_name = 'od'; + arg_desc = 'the descriptor for this arg'; + }; + doc = +'This routine will print the version to stdout and return +instead of exiting. Please see the source for the +@code{print_ver} funtion for details on selecting how +verbose to be after this function returns.'; + srcfile = 'version.c'; + linenum = '199'; +}; + + +#line 292 "autoopts.c" +export_func = { + name = 'optionProcess'; + what = 'this is the main option processing routine'; + arg = { + arg_type = 'tOptions *'; + arg_name = 'opts'; + arg_desc = 'program options descriptor'; + }; + arg = { + arg_type = 'int'; + arg_name = 'a_ct'; + arg_desc = 'program arg count'; + }; + arg = { + arg_type = 'char **'; + arg_name = 'a_v'; + arg_desc = 'program arg vector'; + }; + ret_type = 'int'; + ret_desc = 'the count of the arguments processed'; + doc = +'This is the main entry point for processing options. It is intended +that this procedure be called once at the beginning of the execution of +a program. Depending on options selected earlier, it is sometimes +necessary to stop and restart option processing, or to select completely +different sets of options. This can be done easily, but you generally +do not want to do this. + +The number of arguments processed always includes the program name. +If one of the arguments is "--", then it is counted and the processing +stops. If an error was encountered and errors are to be tolerated, then +the returned value is the index of the argument causing the error. +A hyphen by itself ("-") will also cause processing to stop and will +@emph{not} be counted among the processed arguments. A hyphen by itself +is treated as an operand. Encountering an operand stops option +processing.'; + err = 'Errors will cause diagnostics to be printed. @code{exit(3)} may +or may not be called. It depends upon whether or not the options +were generated with the "allow-errors" attribute, or if the +ERRSKIP_OPTERR or ERRSTOP_OPTERR macros were invoked.'; + srcfile = 'autoopts.c'; + linenum = '292'; +}; + + +#line 347 "putshell.c" +export_func = { + name = 'optionPutShell'; + what = 'write a portable shell script to parse options'; + private; + arg = { + arg_type = 'tOptions *'; + arg_name = 'pOpts'; + arg_desc = 'the program options descriptor'; + }; + doc = 'This routine will emit portable shell script text for parsing +the options described in the option definitions.'; + srcfile = 'putshell.c'; + linenum = '347'; +}; + + +#line 88 "putshell.c" +export_func = { + name = 'optionQuoteString'; + private; + what = 'Print a string as quoted text suitable for a C compiler.'; + arg = { + arg_type = 'char const *'; + arg_name = 'text'; + arg_desc = 'a block of text to quote'; + }; + arg = { + arg_type = 'char const *'; + arg_name = 'nl'; + arg_desc = 'line splice text'; + }; + ret_type = 'char const *'; + ret_desc = 'the allocated input string as a quoted string'; + doc = +'This is for internal use by autogen and autoopts. +It takes an input string and produces text the C compiler can process +to produce an exact copy of the original string. +The caller must deallocate the result. Standard C strings and +K&R strings are distinguished by the "nl" string.'; + srcfile = 'putshell.c'; + linenum = '88'; +}; + + +#line 62 "reset.c" +export_func = { + name = 'optionResetOpt'; + private; + what = 'Reset the value of an option'; + arg = { + arg_type = 'tOptions *'; + arg_name = 'pOpts'; + arg_desc = 'program options descriptor'; + }; + arg = { + arg_type = 'tOptDesc *'; + arg_name = 'pOptDesc'; + arg_desc = 'the descriptor for this arg'; + }; + doc = +'This code will cause another option to be reset to its initial state. +For example, --reset=foo will cause the --foo option to be reset.'; + srcfile = 'reset.c'; + linenum = '62'; +}; + + +#line 116 "restore.c" +export_func = { + name = 'optionRestore'; + what = 'restore option state from memory copy'; + arg = { + arg_type = 'tOptions *'; + arg_name = 'pOpts'; + arg_desc = 'program options descriptor'; + }; + doc = 'Copy back the option state from saved memory. +The allocated memory is left intact, so this routine can be +called repeatedly without having to call optionSaveState again. +If you are restoring a state that was saved before the first call +to optionProcess(3AO), then you may change the contents of the +argc/argv parameters to optionProcess.'; + err = 'If you have not called @code{optionSaveState} before, a diagnostic is +printed to @code{stderr} and exit is called.'; + srcfile = 'restore.c'; + linenum = '116'; +}; + + +#line 768 "save.c" +export_func = { + name = 'optionSaveFile'; + what = 'saves the option state to a file'; + arg = { + arg_type = 'tOptions *'; + arg_name = 'opts'; + arg_desc = 'program options descriptor'; + }; + doc = +'This routine will save the state of option processing to a file. The name +of that file can be specified with the argument to the @code{--save-opts} +option, or by appending the @code{rcfile} attribute to the last +@code{homerc} attribute. If no @code{rcfile} attribute was specified, it +will default to @code{.@i{programname}rc}. If you wish to specify another +file, you should invoke the @code{SET_OPT_SAVE_OPTS(@i{filename})} macro. + +The recommend usage is as follows: +@example +optionProcess(&progOptions, argc, argv); +if (i_want_a_non_standard_place_for_this) +SET_OPT_SAVE_OPTS("myfilename"); +optionSaveFile(&progOptions); +@end example'; + err = +'If no @code{homerc} file was specified, this routine will silently return +and do nothing. If the output file cannot be created or updated, a message +will be printed to @code{stderr} and the routine will return.'; + srcfile = 'save.c'; + linenum = '768'; +}; + + +#line 73 "restore.c" +export_func = { + name = 'optionSaveState'; + what = 'saves the option state to memory'; + arg = { + arg_type = 'tOptions *'; + arg_name = 'pOpts'; + arg_desc = 'program options descriptor'; + }; + doc = +'This routine will allocate enough memory to save the current option +processing state. If this routine has been called before, that memory +will be reused. You may only save one copy of the option state. This +routine may be called before optionProcess(3AO). If you do call it +before the first call to optionProcess, then you may also change the +contents of argc/argv after you call optionRestore(3AO) + +In fact, more strongly put: it is safest to only use this function +before having processed any options. In particular, the saving and +restoring of stacked string arguments and hierarchical values is +disabled. The values are not saved.'; + err = 'If it fails to allocate the memory, +it will print a message to stderr and exit. +Otherwise, it will always succeed.'; + srcfile = 'restore.c'; + linenum = '73'; +}; + + +#line 505 "enum.c" +export_func = { + name = 'optionSetMembers'; + what = 'Convert between bit flag values and strings'; + private; + arg = { + arg_type = 'tOptions *'; + arg_name = 'opts'; + arg_desc = 'the program options descriptor'; + }; + arg = { + arg_type = 'tOptDesc *'; + arg_name = 'od'; + arg_desc = 'the set membership option description'; + }; + arg = { + arg_type = 'char const * const *'; + arg_name = 'nm_list'; + arg_desc = 'list of enumeration names'; + }; + arg = { + arg_type = 'unsigned int'; + arg_name = 'nm_ct'; + arg_desc = 'number of names in list'; + }; + doc = 'This converts the optArg.argString string from the option description +into the index corresponding to an entry in the name list. +This will match the generated enumeration value. +Full matches are always accepted. Partial matches are accepted +if there is only one partial match.'; + srcfile = 'enum.c'; + linenum = '505'; +}; + + +#line 32 "numeric.c" +export_func = { + name = 'optionShowRange'; + private; + what = 'Show info about range constraints'; + arg = { + arg_type = 'tOptions *'; + arg_name = 'pOpts'; + arg_desc = 'program options descriptor'; + }; + arg = { + arg_type = 'tOptDesc *'; + arg_name = 'pOptDesc'; + arg_desc = 'the descriptor for this arg'; + }; + arg = { + arg_type = 'void *'; + arg_name = 'rng_table'; + arg_desc = 'the value range tables'; + }; + arg = { + arg_type = 'int'; + arg_name = 'rng_count'; + arg_desc = 'the number of entries'; + }; + doc = +'Show information about a numeric option with range constraints.'; + srcfile = 'numeric.c'; + linenum = '32'; +}; + + +#line 223 "stack.c" +export_func = { + name = 'optionStackArg'; + private; + what = 'put option args on a stack'; + arg = { + arg_type = 'tOptions *'; + arg_name = 'opts'; + arg_desc = 'program options descriptor'; + }; + arg = { + arg_type = 'tOptDesc *'; + arg_name = 'od'; + arg_desc = 'the descriptor for this arg'; + }; + doc = +'Keep an entry-ordered list of option arguments.'; + srcfile = 'stack.c'; + linenum = '223'; +}; + + +#line 63 "time.c" +export_func = { + name = 'optionTimeDate'; + private; + what = 'process an option with a time and date.'; + arg = { + arg_type = 'tOptions *'; + arg_name = 'opts'; + arg_desc = 'program options descriptor'; + }; + arg = { + arg_type = 'tOptDesc *'; + arg_name = 'od'; + arg_desc = 'the descriptor for this arg'; + }; + doc = +'Decipher a time and date value.'; + srcfile = 'time.c'; + linenum = '63'; +}; + + +#line 30 "time.c" +export_func = { + name = 'optionTimeVal'; + private; + what = 'process an option with a time duration.'; + arg = { + arg_type = 'tOptions *'; + arg_name = 'opts'; + arg_desc = 'program options descriptor'; + }; + arg = { + arg_type = 'tOptDesc *'; + arg_name = 'od'; + arg_desc = 'the descriptor for this arg'; + }; + doc = +'Decipher a time duration value.'; + srcfile = 'time.c'; + linenum = '30'; +}; + + +#line 615 "nested.c" +export_func = { + name = 'optionUnloadNested'; + what = 'Deallocate the memory for a nested value'; + arg = { + arg_type = 'tOptionValue const *'; + arg_name = 'pOptVal'; + arg_desc = 'the hierarchical value'; + }; + doc = +'A nested value needs to be deallocated. The pointer passed in should +have been gotten from a call to @code{configFileLoad()} (See +@pxref{libopts-configFileLoad}).'; + srcfile = 'nested.c'; + linenum = '615'; +}; + + +#line 37 "stack.c" +export_func = { + name = 'optionUnstackArg'; + private; + what = 'Remove option args from a stack'; + arg = { + arg_type = 'tOptions *'; + arg_name = 'opts'; + arg_desc = 'program options descriptor'; + }; + arg = { + arg_type = 'tOptDesc *'; + arg_name = 'od'; + arg_desc = 'the descriptor for this arg'; + }; + doc = +'Invoked for options that are equivalenced to stacked options.'; + srcfile = 'stack.c'; + linenum = '37'; +}; + + +#line 501 "usage.c" +export_func = { + name = 'optionUsage'; + private; + what = 'Print usage text'; + arg = { + arg_type = 'tOptions *'; + arg_name = 'opts'; + arg_desc = 'program options descriptor'; + }; + arg = { + arg_type = 'int'; + arg_name = 'exitCode'; + arg_desc = 'exit code for calling exit(3)'; + }; + doc = +'This routine will print usage in both GNU-standard and AutoOpts-expanded +formats. The descriptor specifies the default, but AUTOOPTS_USAGE will +over-ride this, providing the value of it is set to either "gnu" or +"autoopts". This routine will @strong{not} return. + +If "exitCode" is "AO_EXIT_REQ_USAGE" (normally 64), then output will to +to stdout and the actual exit code will be "EXIT_SUCCESS".'; + srcfile = 'usage.c'; + linenum = '501'; +}; + + +#line 273 "find.c" +export_func = { + name = 'optionVendorOption'; + private; + what = 'Process a vendor option'; + arg = { + arg_type = 'tOptions *'; + arg_name = 'pOpts'; + arg_desc = 'program options descriptor'; + }; + arg = { + arg_type = 'tOptDesc *'; + arg_name = 'pOptDesc'; + arg_desc = 'the descriptor for this arg'; + }; + doc = +'For POSIX specified utilities, the options are constrained to the options, +@xref{config attributes, Program Configuration}. AutoOpts clients should +never specify this directly. It gets referenced when the option +definitions contain a "vendor-opt" attribute.'; + srcfile = 'find.c'; + linenum = '273'; +}; + + +#line 32 "version.c" +export_func = { + name = 'optionVersion'; + what = 'return the compiled AutoOpts version number'; + ret_type = 'char const *'; + ret_desc = 'the version string in constant memory'; + doc = +'Returns the full version string compiled into the library. +The returned string cannot be modified.'; + srcfile = 'version.c'; + linenum = '32'; +}; + + +#line 217 "version.c" +export_func = { + name = 'optionVersionStderr'; + private; + what = 'Print the program version to stderr'; + arg = { + arg_type = 'tOptions *'; + arg_name = 'opts'; + arg_desc = 'program options descriptor'; + }; + arg = { + arg_type = 'tOptDesc *'; + arg_name = 'od'; + arg_desc = 'the descriptor for this arg'; + }; + doc = +'This routine will print the version to stderr.'; + srcfile = 'version.c'; + linenum = '217'; +}; + + +#line 225 "streqvcmp.c" +export_func = { + name = 'strequate'; + what = 'map a list of characters to the same value'; + arg = { + arg_type = 'char const *'; + arg_name = 'ch_list'; + arg_desc = 'characters to equivalence'; + }; + doc = +'Each character in the input string get mapped to the first character +in the string. +This function name is mapped to option_strequate so as to not conflict +with the POSIX name space.'; + err = 'none.'; + srcfile = 'streqvcmp.c'; + linenum = '225'; +}; + + +#line 128 "streqvcmp.c" +export_func = { + name = 'streqvcmp'; + what = 'compare two strings with an equivalence mapping'; + arg = { + arg_type = 'char const *'; + arg_name = 'str1'; + arg_desc = 'first string'; + }; + arg = { + arg_type = 'char const *'; + arg_name = 'str2'; + arg_desc = 'second string'; + }; + ret_type = 'int'; + ret_desc = 'the difference between two differing characters'; + doc = +'Using a character mapping, two strings are compared for "equivalence". +Each input character is mapped to a comparison character and the +mapped-to characters are compared for the two NUL terminated input strings. +This function name is mapped to option_streqvcmp so as to not conflict +with the POSIX name space.'; + err = 'none checked. Caller responsible for seg faults.'; + srcfile = 'streqvcmp.c'; + linenum = '128'; +}; + + +#line 172 "streqvcmp.c" +export_func = { + name = 'streqvmap'; + what = 'Set the character mappings for the streqv functions'; + arg = { + arg_type = 'char'; + arg_name = 'from'; + arg_desc = 'Input character'; + }; + arg = { + arg_type = 'char'; + arg_name = 'to'; + arg_desc = 'Mapped-to character'; + }; + arg = { + arg_type = 'int'; + arg_name = 'ct'; + arg_desc = 'compare length'; + }; + doc = +'Set the character mapping. If the count (@code{ct}) is set to zero, then +the map is cleared by setting all entries in the map to their index +value. Otherwise, the "@code{From}" character is mapped to the "@code{To}" +character. If @code{ct} is greater than 1, then @code{From} and @code{To} +are incremented and the process repeated until @code{ct} entries have been +set. For example, +@example +streqvmap(\'a\', \'A\', 26); +@end example +@noindent +will alter the mapping so that all English lower case letters +will map to upper case. + +This function name is mapped to option_streqvmap so as to not conflict +with the POSIX name space.'; + err = 'none.'; + srcfile = 'streqvcmp.c'; + linenum = '172'; +}; + + +#line 80 "streqvcmp.c" +export_func = { + name = 'strneqvcmp'; + what = 'compare two strings with an equivalence mapping'; + arg = { + arg_type = 'char const *'; + arg_name = 'str1'; + arg_desc = 'first string'; + }; + arg = { + arg_type = 'char const *'; + arg_name = 'str2'; + arg_desc = 'second string'; + }; + arg = { + arg_type = 'int'; + arg_name = 'ct'; + arg_desc = 'compare length'; + }; + ret_type = 'int'; + ret_desc = 'the difference between two differing characters'; + doc = +'Using a character mapping, two strings are compared for "equivalence". +Each input character is mapped to a comparison character and the +mapped-to characters are compared for the two NUL terminated input strings. +The comparison is limited to @code{ct} bytes. +This function name is mapped to option_strneqvcmp so as to not conflict +with the POSIX name space.'; + err = 'none checked. Caller responsible for seg faults.'; + srcfile = 'streqvcmp.c'; + linenum = '80'; +}; + + +#line 251 "streqvcmp.c" +export_func = { + name = 'strtransform'; + what = 'convert a string into its mapped-to value'; + arg = { + arg_type = 'char *'; + arg_name = 'dest'; + arg_desc = 'output string'; + }; + arg = { + arg_type = 'char const *'; + arg_name = 'src'; + arg_desc = 'input string'; + }; + doc = +'Each character in the input string is mapped and the mapped-to +character is put into the output. +This function name is mapped to option_strtransform so as to not conflict +with the POSIX name space. + +The source and destination may be the same.'; + err = 'none.'; + srcfile = 'streqvcmp.c'; + linenum = '251'; +}; + + +#line 256 "text_mmap.c" +export_func = { + name = 'text_mmap'; + private; + what = 'map a text file with terminating NUL'; + arg = { + arg_type = 'char const *'; + arg_name = 'pzFile'; + arg_desc = 'name of the file to map'; + }; + arg = { + arg_type = 'int'; + arg_name = 'prot'; + arg_desc = 'mmap protections (see mmap(2))'; + }; + arg = { + arg_type = 'int'; + arg_name = 'flags'; + arg_desc = 'mmap flags (see mmap(2))'; + }; + arg = { + arg_type = 'tmap_info_t *'; + arg_name = 'mapinfo'; + arg_desc = 'returned info about the mapping'; + }; + ret-type = 'void *'; + ret-desc = 'The mmaped data address'; + doc = +'This routine will mmap a file into memory ensuring that there is at least +one @file{NUL} character following the file data. It will return the +address where the file contents have been mapped into memory. If there is a +problem, then it will return @code{MAP_FAILED} and set @code{errno} +appropriately. + +The named file does not exist, @code{stat(2)} will set @code{errno} as it +will. If the file is not a regular file, @code{errno} will be +@code{EINVAL}. At that point, @code{open(2)} is attempted with the access +bits set appropriately for the requested @code{mmap(2)} protections and flag +bits. On failure, @code{errno} will be set according to the documentation +for @code{open(2)}. If @code{mmap(2)} fails, @code{errno} will be set as +that routine sets it. If @code{text_mmap} works to this point, a valid +address will be returned, but there may still be ``issues\'\'. + +If the file size is not an even multiple of the system page size, then +@code{text_map} will return at this point and @code{errno} will be zero. +Otherwise, an anonymous map is attempted. If not available, then an attempt +is made to @code{mmap(2)} @file{/dev/zero}. If any of these fail, the +address of the file\'s data is returned, bug @code{no} @file{NUL} characters +are mapped after the end of the data.'; + see = 'mmap(2), open(2), stat(2)'; + err = 'Any error code issued by mmap(2), open(2), stat(2) is possible. +Additionally, if the specified file is not a regular file, then +errno will be set to @code{EINVAL}.'; + example = +'#include +tmap_info_t mi; +int no_nul; +void * data = text_mmap("file", PROT_WRITE, MAP_PRIVATE, &mi); +if (data == MAP_FAILED) return; +no_nul = (mi.txt_size == mi.txt_full_size); +<< use the data >> +text_munmap(&mi);'; + srcfile = 'text_mmap.c'; + linenum = '256'; +}; + + +#line 329 "text_mmap.c" +export_func = { + name = 'text_munmap'; + private; + what = 'unmap the data mapped in by text_mmap'; + arg = { + arg_type = 'tmap_info_t *'; + arg_name = 'mapinfo'; + arg_desc = 'info about the mapping'; + }; + ret-type = 'int'; + ret-desc = '-1 or 0. @code{errno} will have the error code.'; + doc = +'This routine will unmap the data mapped in with @code{text_mmap} and close +the associated file descriptors opened by that function.'; + see = 'munmap(2), close(2)'; + err = 'Any error code issued by munmap(2) or close(2) is possible.'; + srcfile = 'text_mmap.c'; + linenum = '329'; +}; +vers-curr = "172033"; +vers-min = "102400"; +vers-min-str = "25:0:0"; +vers-sovers = "42:1:17"; +display-ver = "42.1"; +library = opts; + +/* + * THIS FILE IS DISTRIBUTED + * + * This file is used to construct options.h + doc files. Because it is + * such a nuisance to get the build ordering correct, we distribute + * this. It should be constructed after all binaries are built. + */ diff --git a/autoopts/genshell.c b/autoopts/genshell.c new file mode 100644 index 0000000..05182a6 --- /dev/null +++ b/autoopts/genshell.c @@ -0,0 +1,848 @@ +/* -*- buffer-read-only: t -*- vi: set ro: + * + * DO NOT EDIT THIS FILE (genshell.c) + * + * It has been AutoGen-ed + * From the definitions genshell.def + * and the template file options + * + * Generated from AutoOpts 42:1:17 templates. + * + * AutoOpts is a copyrighted work. This source file is not encumbered + * by AutoOpts licensing, but is provided under the licensing terms chosen + * by the genshellopt author or copyright holder. AutoOpts is + * licensed under the terms of the LGPL. The redistributable library + * (``libopts'') is licensed under the terms of either the LGPL or, at the + * users discretion, the BSD license. See the AutoOpts and/or libopts sources + * for details. + * + * The genshellopt program is copyrighted and licensed + * under the following terms: + * + * Copyright (C) 1999-2018 Bruce Korb, all rights reserved. + * This is free software. It is licensed for use, modification and + * redistribution under the terms of the GNU Lesser General Public License, + * version 2 or later + * + * The genshellopt library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, see + * + */ + +#ifndef __doxygen__ +#define OPTION_CODE_COMPILE 1 +#include "genshell.h" +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif +extern FILE * option_usage_fp; +#define zCopyright (genshellopt_opt_strs+0) +#define zLicenseDescrip (genshellopt_opt_strs+285) + +extern tUsageProc genshelloptUsage; + +#ifndef NULL +# define NULL 0 +#endif + +/** + * static const strings for genshellopt options + */ +static char const genshellopt_opt_strs[1769] = +/* 0 */ "genshellopt 1\n" + "Copyright (C) 1999-2018 Bruce Korb, all rights reserved.\n" + "This is free software. It is licensed for use, modification and\n" + "redistribution under the terms of the GNU Lesser General Public License,\n" + "version 2 or later \n\0" +/* 285 */ "The genshellopt library is free software; you can redistribute it and/or\n" + "modify it under the terms of the GNU Library General Public License as\n" + "published by the Free Software Foundation; either version 2 of the License,\n" + "or (at your option) any later version.\n\n" + "This library is distributed in the hope that it will be useful, but WITHOUT\n" + "ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n" + "FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public\n" + "License for more details.\n\n" + "You should have received a copy of the GNU Library General Public License\n" + "along with this library; if not, see\n" + "\n\0" +/* 957 */ "Output Script File\0" +/* 976 */ "SCRIPT\0" +/* 983 */ "script\0" +/* 990 */ "Shell name (follows \"#!\" magic)\0" +/* 1022 */ "SHELL\0" +/* 1028 */ "no-shell\0" +/* 1037 */ "no\0" +/* 1040 */ "display extended usage information and exit\0" +/* 1084 */ "help\0" +/* 1089 */ "extended usage information passed thru pager\0" +/* 1134 */ "more-help\0" +/* 1144 */ "output version information and exit\0" +/* 1180 */ "version\0" +/* 1188 */ "GENSHELLOPT\0" +/* 1200 */ "genshellopt - Generate Shell Option Processing Script - Ver. 1\n" + "Usage: %s [ - [] | --[{=| }] ]...\n\0" +/* 1321 */ "autogen-users@lists.sourceforge.net\0" +/* 1357 */ "Note that 'shell' is only useful if the output file does not already exist.\n" + "If it does, then the shell name and optional first argument will be\n" + "extracted from the script file.\n\0" +/* 1534 */ "If the script file already exists and contains Automated Option Processing\n" + "text, the second line of the file through the ending tag will be replaced\n" + "by the newly generated text. The first '#!' line will be regenerated.\n\0" +/* 1755 */ "genshellopt 1"; + +/** + * script option description: + */ +/** Descriptive text for the script option */ +#define SCRIPT_DESC (genshellopt_opt_strs+957) +/** Upper-cased name for the script option */ +#define SCRIPT_NAME (genshellopt_opt_strs+976) +/** Name string for the script option */ +#define SCRIPT_name (genshellopt_opt_strs+983) +/** Compiled in flag settings for the script option */ +#define SCRIPT_FLAGS (OPTST_DISABLED \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING)) + +/** + * shell option description: + */ +/** Descriptive text for the shell option */ +#define SHELL_DESC (genshellopt_opt_strs+990) +/** Upper-cased name for the shell option */ +#define SHELL_NAME (genshellopt_opt_strs+1022) +/** disablement name for the shell option */ +#define NOT_SHELL_name (genshellopt_opt_strs+1028) +/** disablement prefix for the shell option */ +#define NOT_SHELL_PFX (genshellopt_opt_strs+1037) +/** Name string for the shell option */ +#define SHELL_name (NOT_SHELL_name + 3) +/** Compiled in flag settings for the shell option */ +#define SHELL_FLAGS (OPTST_INITENABLED \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING)) + +/* + * Help/More_Help/Version option descriptions: + */ +#define HELP_DESC (genshellopt_opt_strs+1040) +#define HELP_name (genshellopt_opt_strs+1084) +#ifdef HAVE_WORKING_FORK +#define MORE_HELP_DESC (genshellopt_opt_strs+1089) +#define MORE_HELP_name (genshellopt_opt_strs+1134) +#define MORE_HELP_FLAGS (OPTST_IMM | OPTST_NO_INIT) +#else +#define MORE_HELP_DESC HELP_DESC +#define MORE_HELP_name HELP_name +#define MORE_HELP_FLAGS (OPTST_OMITTED | OPTST_NO_INIT) +#endif +#ifdef NO_OPTIONAL_OPT_ARGS +# define VER_FLAGS (OPTST_IMM | OPTST_NO_INIT) +#else +# define VER_FLAGS (OPTST_SET_ARGTYPE(OPARG_TYPE_STRING) | \ + OPTST_ARG_OPTIONAL | OPTST_IMM | OPTST_NO_INIT) +#endif +#define VER_DESC (genshellopt_opt_strs+1144) +#define VER_name (genshellopt_opt_strs+1180) +/** + * Declare option callback procedures + */ +extern tOptProc + optionBooleanVal, optionNestedVal, optionNumericVal, + optionPagedUsage, optionPrintVersion, optionResetOpt, + optionStackArg, optionTimeDate, optionTimeVal, + optionUnstackArg, optionVendorOption; +static tOptProc + doUsageOpt; +#define VER_PROC optionPrintVersion + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/** + * Define the genshellopt Option Descriptions. + * This is an array of GENSHELL_OPTION_CT entries, one for each + * option that the genshellopt program responds to. + */ +static tOptDesc optDesc[GENSHELL_OPTION_CT] = { + { /* entry idx, value */ 0, VALUE_GENSHELL_OPT_SCRIPT, + /* equiv idx, value */ 0, VALUE_GENSHELL_OPT_SCRIPT, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ SCRIPT_FLAGS, 0, + /* last opt argumnt */ { NULL }, /* --script */ + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ NULL, + /* desc, NAME, name */ SCRIPT_DESC, SCRIPT_NAME, SCRIPT_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 1, VALUE_GENSHELL_OPT_SHELL, + /* equiv idx, value */ 1, VALUE_GENSHELL_OPT_SHELL, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ SHELL_FLAGS, 0, + /* last opt argumnt */ { NULL }, /* --shell */ + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ NULL, + /* desc, NAME, name */ SHELL_DESC, SHELL_NAME, SHELL_name, + /* disablement strs */ NOT_SHELL_name, NOT_SHELL_PFX }, + + { /* entry idx, value */ INDEX_GENSHELL_OPT_VERSION, VALUE_GENSHELL_OPT_VERSION, + /* equiv idx value */ NO_EQUIVALENT, VALUE_GENSHELL_OPT_VERSION, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ VER_FLAGS, AOUSE_VERSION, + /* last opt argumnt */ { NULL }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ VER_PROC, + /* desc, NAME, name */ VER_DESC, NULL, VER_name, + /* disablement strs */ NULL, NULL }, + + + + { /* entry idx, value */ INDEX_GENSHELL_OPT_HELP, VALUE_GENSHELL_OPT_HELP, + /* equiv idx value */ NO_EQUIVALENT, VALUE_GENSHELL_OPT_HELP, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ OPTST_IMM | OPTST_NO_INIT, AOUSE_HELP, + /* last opt argumnt */ { NULL }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ doUsageOpt, + /* desc, NAME, name */ HELP_DESC, NULL, HELP_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ INDEX_GENSHELL_OPT_MORE_HELP, VALUE_GENSHELL_OPT_MORE_HELP, + /* equiv idx value */ NO_EQUIVALENT, VALUE_GENSHELL_OPT_MORE_HELP, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ MORE_HELP_FLAGS, AOUSE_MORE_HELP, + /* last opt argumnt */ { NULL }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ optionPagedUsage, + /* desc, NAME, name */ MORE_HELP_DESC, NULL, MORE_HELP_name, + /* disablement strs */ NULL, NULL } +}; + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/** Reference to the upper cased version of genshellopt. */ +#define zPROGNAME (genshellopt_opt_strs+1188) +/** Reference to the title line for genshellopt usage. */ +#define zUsageTitle (genshellopt_opt_strs+1200) +/** There is no genshellopt configuration file. */ +#define zRcName NULL +/** There are no directories to search for genshellopt config files. */ +#define apzHomeList NULL +/** The genshellopt program bug email address. */ +#define zBugsAddr (genshellopt_opt_strs+1321) +/** Clarification/explanation of what genshellopt does. */ +#define zExplain (genshellopt_opt_strs+1357) +/** Extra detail explaining what genshellopt does. */ +#define zDetail (genshellopt_opt_strs+1534) +/** The full version string for genshellopt. */ +#define zFullVersion (genshellopt_opt_strs+1755) +/* extracted from optcode.tlib near line 342 */ + +#if defined(ENABLE_NLS) +# define OPTPROC_BASE OPTPROC_TRANSLATE + static tOptionXlateProc translate_option_strings; +#else +# define OPTPROC_BASE OPTPROC_NONE +# define translate_option_strings NULL +#endif /* ENABLE_NLS */ + +#define genshellopt_full_usage (NULL) +#define genshellopt_short_usage (NULL) + +#endif /* not defined __doxygen__ */ + +/* + * Create the static procedure(s) declared above. + */ +/** + * The callout function that invokes the genshelloptUsage function. + * + * @param[in] opts the AutoOpts option description structure + * @param[in] od the descriptor for the "help" (usage) option. + * @noreturn + */ +static void +doUsageOpt(tOptions * opts, tOptDesc * od) +{ + int ex_code; + ex_code = GENSHELLOPT_EXIT_SUCCESS; + genshelloptUsage(&genshelloptOptions, ex_code); + /* NOTREACHED */ + exit(GENSHELLOPT_EXIT_FAILURE); + (void)opts; + (void)od; +} +/* extracted from optmain.tlib near line 1250 */ + +/** + * The directory containing the data associated with genshellopt. + */ +#ifndef PKGDATADIR +# define PKGDATADIR "" +#endif + +/** + * Information about the person or institution that packaged genshellopt + * for the current distribution. + */ +#ifndef WITH_PACKAGER +# define genshellopt_packager_info NULL +#else +/** Packager information for genshellopt. */ +static char const genshellopt_packager_info[] = + "Packaged by " WITH_PACKAGER + +# ifdef WITH_PACKAGER_VERSION + " ("WITH_PACKAGER_VERSION")" +# endif + +# ifdef WITH_PACKAGER_BUG_REPORTS + "\nReport genshellopt bugs to " WITH_PACKAGER_BUG_REPORTS +# endif + "\n"; +#endif +#ifndef __doxygen__ + +#endif /* __doxygen__ */ +/** + * The option definitions for genshellopt. The one structure that + * binds them all. + */ +tOptions genshelloptOptions = { + OPTIONS_STRUCT_VERSION, + 0, NULL, /* original argc + argv */ + ( OPTPROC_BASE + + OPTPROC_ERRSTOP + + OPTPROC_SHORTOPT + + OPTPROC_LONGOPT + + OPTPROC_NO_REQ_OPT + + OPTPROC_NEGATIONS + + OPTPROC_NO_ARGS ), + 0, NULL, /* current option index, current option */ + NULL, NULL, zPROGNAME, + zRcName, zCopyright, zLicenseDescrip, + zFullVersion, apzHomeList, zUsageTitle, + zExplain, zDetail, optDesc, + zBugsAddr, /* address to send bugs to */ + NULL, NULL, /* extensions/saved state */ + genshelloptUsage, /* usage procedure */ + translate_option_strings, /* translation procedure */ + /* + * Indexes to special options + */ + { INDEX_GENSHELL_OPT_MORE_HELP, /* more-help option index */ + NO_EQUIVALENT, /* save option index */ + NO_EQUIVALENT, /* '-#' option index */ + NO_EQUIVALENT /* index of default opt */ + }, + 5 /* full option count */, 2 /* user option count */, + genshellopt_full_usage, genshellopt_short_usage, + NULL, NULL, + PKGDATADIR, genshellopt_packager_info +}; + +#if ENABLE_NLS +/** + * This code is designed to translate translatable option text for the + * genshellopt program. These translations happen upon entry + * to optionProcess(). + */ +#include +#include +#include +#include +#ifdef HAVE_DCGETTEXT +# include +#endif +#include + +static char * AO_gettext(char const * pz); +static void coerce_it(void ** s); + +/** + * AutoGen specific wrapper function for gettext. It relies on the macro _() + * to convert from English to the target language, then strdup-duplicates the + * result string. It tries the "libopts" domain first, then whatever has been + * set via the \a textdomain(3) call. + * + * @param[in] pz the input text used as a lookup key. + * @returns the translated text (if there is one), + * or the original text (if not). + */ +static char * +AO_gettext(char const * pz) +{ + char * res; + if (pz == NULL) + return NULL; +#ifdef HAVE_DCGETTEXT + /* + * While processing the option_xlateable_txt data, try to use the + * "libopts" domain. Once we switch to the option descriptor data, + * do *not* use that domain. + */ + if (option_xlateable_txt.field_ct != 0) { + res = dgettext("libopts", pz); + if (res == pz) + res = (char *)VOIDP(_(pz)); + } else + res = (char *)VOIDP(_(pz)); +#else + res = (char *)VOIDP(_(pz)); +#endif + if (res == pz) + return res; + res = strdup(res); + if (res == NULL) { + fputs(_("No memory for duping translated strings\n"), stderr); + exit(GENSHELLOPT_EXIT_FAILURE); + } + return res; +} + +/** + * All the pointers we use are marked "* const", but they are stored in + * writable memory. Coerce the mutability and set the pointer. + */ +static void coerce_it(void ** s) { *s = AO_gettext(*s); +} + +/** + * Translate all the translatable strings in the genshelloptOptions + * structure defined above. This is done only once. + */ +static void +translate_option_strings(void) +{ + tOptions * const opts = &genshelloptOptions; + + /* + * Guard against re-translation. It won't work. The strings will have + * been changed by the first pass through this code. One shot only. + */ + if (option_xlateable_txt.field_ct != 0) { + /* + * Do the translations. The first pointer follows the field count + * field. The field count field is the size of a pointer. + */ + char ** ppz = (char**)VOIDP(&(option_xlateable_txt)); + int ix = option_xlateable_txt.field_ct; + + do { + ppz++; /* skip over field_ct */ + *ppz = AO_gettext(*ppz); + } while (--ix > 0); + /* prevent re-translation and disable "libopts" domain lookup */ + option_xlateable_txt.field_ct = 0; + + coerce_it(VOIDP(&(opts->pzCopyright))); + coerce_it(VOIDP(&(opts->pzCopyNotice))); + coerce_it(VOIDP(&(opts->pzFullVersion))); + coerce_it(VOIDP(&(opts->pzUsageTitle))); + coerce_it(VOIDP(&(opts->pzExplain))); + coerce_it(VOIDP(&(opts->pzDetail))); + { + tOptDesc * od = opts->pOptDesc; + for (ix = opts->optCt; ix > 0; ix--, od++) + coerce_it(VOIDP(&(od->pzText))); + } + } +} +#endif /* ENABLE_NLS */ + +#ifdef DO_NOT_COMPILE_THIS_CODE_IT_IS_FOR_GETTEXT +/** I18N function strictly for xgettext. Do not compile. */ +static void bogus_function(void) { + /* TRANSLATORS: + + The following dummy function was crated solely so that xgettext can + extract the correct strings. These strings are actually referenced + by a field name in the genshelloptOptions structure noted in the + comments below. The literal text is defined in genshellopt_opt_strs. + + NOTE: the strings below are segmented with respect to the source string + genshellopt_opt_strs. The strings above are handed off for translation + at run time a paragraph at a time. Consequently, they are presented here + for translation a paragraph at a time. + + ALSO: often the description for an option will reference another option + by name. These are set off with apostrophe quotes (I hope). Do not + translate option names. + */ + /* referenced via genshelloptOptions.pzCopyright */ + puts(_("genshellopt 1\n\ +Copyright (C) 1999-2018 Bruce Korb, all rights reserved.\n\ +This is free software. It is licensed for use, modification and\n\ +redistribution under the terms of the GNU Lesser General Public License,\n\ +version 2 or later \n")); + + /* referenced via genshelloptOptions.pzCopyNotice */ + puts(_("The genshellopt library is free software; you can redistribute it and/or\n\ +modify it under the terms of the GNU Library General Public License as\n\ +published by the Free Software Foundation; either version 2 of the License,\n\ +or (at your option) any later version.\n\n")); + puts(_("This library is distributed in the hope that it will be useful, but WITHOUT\n\ +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n\ +FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public\n\ +License for more details.\n\n")); + puts(_("You should have received a copy of the GNU Library General Public License\n\ +along with this library; if not, see\n\ +\n")); + + /* referenced via genshelloptOptions.pOptDesc->pzText */ + puts(_("Output Script File")); + + /* referenced via genshelloptOptions.pOptDesc->pzText */ + puts(_("Shell name (follows \"#!\" magic)")); + + /* referenced via genshelloptOptions.pOptDesc->pzText */ + puts(_("display extended usage information and exit")); + + /* referenced via genshelloptOptions.pOptDesc->pzText */ + puts(_("extended usage information passed thru pager")); + + /* referenced via genshelloptOptions.pOptDesc->pzText */ + puts(_("output version information and exit")); + + /* referenced via genshelloptOptions.pzUsageTitle */ + puts(_("genshellopt - Generate Shell Option Processing Script - Ver. 1\n\ +Usage: %s [ - [] | --[{=| }] ]...\n")); + + /* referenced via genshelloptOptions.pzExplain */ + puts(_("Note that 'shell' is only useful if the output file does not already exist.\n\ +If it does, then the shell name and optional first argument will be\n\ +extracted from the script file.\n")); + + /* referenced via genshelloptOptions.pzDetail */ + puts(_("If the script file already exists and contains Automated Option Processing\n\ +text, the second line of the file through the ending tag will be replaced\n\ +by the newly generated text. The first '#!' line will be regenerated.\n")); + + /* referenced via genshelloptOptions.pzFullVersion */ + puts(_("genshellopt 1")); + + /* referenced via genshelloptOptions.pzFullUsage */ + puts(_("<<>>")); + + /* referenced via genshelloptOptions.pzShortUsage */ + puts(_("<<>>")); + /* LIBOPTS-MESSAGES: */ +#line 67 "../autoopts.c" + puts(_("allocation of %d bytes failed\n")); +#line 89 "../autoopts.c" + puts(_("allocation of %d bytes failed\n")); +#line 48 "../init.c" + puts(_("AutoOpts function called without option descriptor\n")); +#line 81 "../init.c" + puts(_("\tThis exceeds the compiled library version: ")); +#line 79 "../init.c" + puts(_("Automated Options Processing Error!\n" + "\t%s called AutoOpts function with structure version %d:%d:%d.\n")); +#line 78 "../autoopts.c" + puts(_("realloc of %d bytes at 0x%p failed\n")); +#line 83 "../init.c" + puts(_("\tThis is less than the minimum library version: ")); +#line 121 "../version.c" + puts(_("Automated Options version %s\n" + "\tCopyright (C) 1999-2017 by Bruce Korb - all rights reserved\n")); +#line 49 "../makeshell.c" + puts(_("(AutoOpts bug): %s.\n")); +#line 90 "../reset.c" + puts(_("optionResetOpt() called, but reset-option not configured")); +#line 241 "../usage.c" + puts(_("could not locate the 'help' option")); +#line 330 "../autoopts.c" + puts(_("optionProcess() was called with invalid data")); +#line 697 "../usage.c" + puts(_("invalid argument type specified")); +#line 568 "../find.c" + puts(_("defaulted to option with optional arg")); +#line 76 "../alias.c" + puts(_("aliasing option is out of range.")); +#line 210 "../enum.c" + puts(_("%s error: the keyword '%s' is ambiguous for %s\n")); +#line 78 "../find.c" + puts(_(" The following options match:\n")); +#line 263 "../find.c" + puts(_("%s: ambiguous option name: %s (matches %d options)\n")); +#line 161 "../check.c" + puts(_("%s: Command line arguments required\n")); +#line 43 "../alias.c" + puts(_("%d %s%s options allowed\n")); +#line 56 "../makeshell.c" + puts(_("%s error %d (%s) calling %s for '%s'\n")); +#line 268 "../makeshell.c" + puts(_("interprocess pipe")); +#line 171 "../version.c" + puts(_("error: version option argument '%c' invalid. Use:\n" + "\t'v' - version only\n" + "\t'c' - version and copyright\n" + "\t'n' - version and full copyright notice\n")); +#line 58 "../check.c" + puts(_("%s error: the '%s' and '%s' options conflict\n")); +#line 187 "../find.c" + puts(_("%s: The '%s' option has been disabled.")); +#line 400 "../find.c" + puts(_("%s: The '%s' option has been disabled.")); +#line 38 "../alias.c" + puts(_("-equivalence")); +#line 439 "../find.c" + puts(_("%s: illegal option -- %c\n")); +#line 110 "../reset.c" + puts(_("%s: illegal option -- %c\n")); +#line 241 "../find.c" + puts(_("%s: illegal option -- %s\n")); +#line 740 "../find.c" + puts(_("%s: illegal option -- %s\n")); +#line 118 "../reset.c" + puts(_("%s: illegal option -- %s\n")); +#line 305 "../find.c" + puts(_("%s: unknown vendor extension option -- %s\n")); +#line 135 "../enum.c" + puts(_(" or an integer from %d through %d\n")); +#line 145 "../enum.c" + puts(_(" or an integer from %d through %d\n")); +#line 696 "../usage.c" + puts(_("%s error: invalid option descriptor for %s\n")); +#line 1030 "../usage.c" + puts(_("%s error: invalid option descriptor for %s\n")); +#line 355 "../find.c" + puts(_("%s: invalid option name: %s\n")); +#line 497 "../find.c" + puts(_("%s: The '%s' option requires an argument.\n")); +#line 150 "../autoopts.c" + puts(_("(AutoOpts bug): Equivalenced option '%s' was equivalenced to both\n" + "\t'%s' and '%s'.")); +#line 94 "../check.c" + puts(_("%s error: The %s option is required\n")); +#line 602 "../find.c" + puts(_("%s: The '%s' option cannot have an argument.\n")); +#line 151 "../check.c" + puts(_("%s: Command line arguments are not allowed.\n")); +#line 568 "../save.c" + puts(_("error %d (%s) creating %s\n")); +#line 210 "../enum.c" + puts(_("%s error: '%s' does not match any %s keywords.\n")); +#line 93 "../reset.c" + puts(_("%s error: The '%s' option requires an argument.\n")); +#line 122 "../save.c" + puts(_("error %d (%s) stat-ing %s\n")); +#line 175 "../save.c" + puts(_("error %d (%s) stat-ing %s\n")); +#line 143 "../restore.c" + puts(_("%s error: no saved option state\n")); +#line 225 "../autoopts.c" + puts(_("'%s' is not a command line option.\n")); +#line 113 "../time.c" + puts(_("%s error: '%s' is not a recognizable date/time.\n")); +#line 50 "../time.c" + puts(_("%s error: '%s' is not a recognizable time duration.\n")); +#line 92 "../check.c" + puts(_("%s error: The %s option must appear %d times.\n")); +#line 165 "../numeric.c" + puts(_("%s error: '%s' is not a recognizable number.\n")); +#line 176 "../enum.c" + puts(_("%s error: %s exceeds %s keyword count\n")); +#line 279 "../usage.c" + puts(_("Try '%s %s' for more information.\n")); +#line 45 "../alias.c" + puts(_("one %s%s option allowed\n")); +#line 170 "../makeshell.c" + puts(_("standard output")); +#line 905 "../makeshell.c" + puts(_("standard output")); +#line 223 "../usage.c" + puts(_("standard output")); +#line 364 "../usage.c" + puts(_("standard output")); +#line 574 "../usage.c" + puts(_("standard output")); +#line 178 "../version.c" + puts(_("standard output")); +#line 223 "../usage.c" + puts(_("standard error")); +#line 364 "../usage.c" + puts(_("standard error")); +#line 574 "../usage.c" + puts(_("standard error")); +#line 178 "../version.c" + puts(_("standard error")); +#line 170 "../makeshell.c" + puts(_("write")); +#line 905 "../makeshell.c" + puts(_("write")); +#line 222 "../usage.c" + puts(_("write")); +#line 363 "../usage.c" + puts(_("write")); +#line 573 "../usage.c" + puts(_("write")); +#line 177 "../version.c" + puts(_("write")); +#line 60 "../numeric.c" + puts(_("%s error: %s option value %ld is out of range.\n")); +#line 44 "../check.c" + puts(_("%s error: %s option requires the %s option\n")); +#line 121 "../save.c" + puts(_("%s warning: cannot save options - %s not regular file\n")); +#line 174 "../save.c" + puts(_("%s warning: cannot save options - %s not regular file\n")); +#line 193 "../save.c" + puts(_("%s warning: cannot save options - %s not regular file\n")); +#line 567 "../save.c" + puts(_("%s warning: cannot save options - %s not regular file\n")); + /* END-LIBOPTS-MESSAGES */ + + /* USAGE-TEXT: */ +#line 822 "../usage.c" + puts(_("\t\t\t\t- an alternate for '%s'\n")); +#line 1097 "../usage.c" + puts(_("Version, usage and configuration options:")); +#line 873 "../usage.c" + puts(_("\t\t\t\t- default option for unnamed options\n")); +#line 786 "../usage.c" + puts(_("\t\t\t\t- disabled as '--%s'\n")); +#line 1066 "../usage.c" + puts(_(" --- %-14s %s\n")); +#line 1064 "../usage.c" + puts(_("This option has been disabled")); +#line 813 "../usage.c" + puts(_("\t\t\t\t- enabled by default\n")); +#line 40 "../alias.c" + puts(_("%s error: only ")); +#line 1143 "../usage.c" + puts(_(" - examining environment variables named %s_*\n")); +#line 168 "../file.c" + puts(_("\t\t\t\t- file must not pre-exist\n")); +#line 172 "../file.c" + puts(_("\t\t\t\t- file must pre-exist\n")); +#line 329 "../usage.c" + puts(_("Options are specified by doubled hyphens and their name or by a single\n" + "hyphen and the flag character.\n")); +#line 882 "../makeshell.c" + puts(_("\n" + "= = = = = = = =\n\n" + "This incarnation of genshell will produce\n" + "a shell script to parse the options for %s:\n\n")); +#line 142 "../enum.c" + puts(_(" or an integer mask with any of the lower %d bits set\n")); +#line 846 "../usage.c" + puts(_("\t\t\t\t- is a set membership option\n")); +#line 867 "../usage.c" + puts(_("\t\t\t\t- must appear between %d and %d times\n")); +#line 331 "../usage.c" + puts(_("Options are specified by single or double hyphens and their name.\n")); +#line 853 "../usage.c" + puts(_("\t\t\t\t- may appear multiple times\n")); +#line 840 "../usage.c" + puts(_("\t\t\t\t- may not be preset\n")); +#line 1258 "../usage.c" + puts(_(" Arg Option-Name Description\n")); +#line 1194 "../usage.c" + puts(_(" Flg Arg Option-Name Description\n")); +#line 1252 "../usage.c" + puts(_(" Flg Arg Option-Name Description\n")); +#line 1253 "../usage.c" + puts(_(" %3s %s")); +#line 1259 "../usage.c" + puts(_(" %3s %s")); +#line 336 "../usage.c" + puts(_("The '-#' option may omit the hash char\n")); +#line 332 "../usage.c" + puts(_("All arguments are named options.\n")); +#line 920 "../usage.c" + puts(_(" - reading file %s")); +#line 358 "../usage.c" + puts(_("\n" + "Please send bug reports to: <%s>\n")); +#line 100 "../version.c" + puts(_("\n" + "Please send bug reports to: <%s>\n")); +#line 129 "../version.c" + puts(_("\n" + "Please send bug reports to: <%s>\n")); +#line 852 "../usage.c" + puts(_("\t\t\t\t- may NOT appear - preset only\n")); +#line 893 "../usage.c" + puts(_("\n" + "The following option preset mechanisms are supported:\n")); +#line 1141 "../usage.c" + puts(_("\n" + "The following option preset mechanisms are supported:\n")); +#line 631 "../usage.c" + puts(_("prohibits these options:\n")); +#line 626 "../usage.c" + puts(_("prohibits the option '%s'\n")); +#line 81 "../numeric.c" + puts(_("%s%ld to %ld")); +#line 79 "../numeric.c" + puts(_("%sgreater than or equal to %ld")); +#line 75 "../numeric.c" + puts(_("%s%ld exactly")); +#line 68 "../numeric.c" + puts(_("%sit must lie in one of the ranges:\n")); +#line 68 "../numeric.c" + puts(_("%sit must be in the range:\n")); +#line 88 "../numeric.c" + puts(_(", or\n")); +#line 66 "../numeric.c" + puts(_("%sis scalable with a suffix: k/K/m/M/g/G/t/T\n")); +#line 77 "../numeric.c" + puts(_("%sless than or equal to %ld")); +#line 339 "../usage.c" + puts(_("Operands and options may be intermixed. They will be reordered.\n")); +#line 601 "../usage.c" + puts(_("requires the option '%s'\n")); +#line 604 "../usage.c" + puts(_("requires these options:\n")); +#line 1270 "../usage.c" + puts(_(" Arg Option-Name Req? Description\n")); +#line 1264 "../usage.c" + puts(_(" Flg Arg Option-Name Req? Description\n")); +#line 143 "../enum.c" + puts(_("or you may use a numeric representation. Preceding these with a '!'\n" + "will clear the bits, specifying 'none' will clear all bits, and 'all'\n" + "will set them all. Multiple entries may be passed as an option\n" + "argument list.\n")); +#line 859 "../usage.c" + puts(_("\t\t\t\t- may appear up to %d times\n")); +#line 52 "../enum.c" + puts(_("The valid \"%s\" option keywords are:\n")); +#line 1101 "../usage.c" + puts(_("The next option supports vendor supported extra options:")); +#line 722 "../usage.c" + puts(_("These additional options are:")); + /* END-USAGE-TEXT */ +} +#endif /* uncompilable code */ +#ifdef __cplusplus +} +#endif +/* genshell.c ends here */ diff --git a/autoopts/genshell.def b/autoopts/genshell.def new file mode 100644 index 0000000..8a4e2f0 --- /dev/null +++ b/autoopts/genshell.def @@ -0,0 +1,83 @@ + +autogen definitions options; + +/** + * \file genshell.def + * + * This module generates shell scripts with AutoOpts supported command line + * option processing. This program is licensed separately from the AutoOpts + * library and is _only_ available under the terms of the GNU General + * Public License. + * + * Genshell Copyright (C) 1999-2018 by Bruce Korb - all rights reserved + * Genshell is free software. + * This file is part of AutoGen. + * + * AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoGen 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. + * + * AutoGen is distributed in the hope that 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 . + */ + +copyright = { + date = "1999-2018"; + owner = "Bruce Korb"; + eaddr = "autogen-users@lists.sourceforge.net"; + type = lgplv2; +}; + +owner = "Bruce Korb"; +prog-name = "genshellopt"; +prog-title = "Generate Shell Option Processing Script"; +long-opts; +usage = genshelloptUsage; +prefix = genshell; + +version = 1; + +flag = { + name = script; + value = o; + arg-type = string; + descrip = "Output Script File"; +}; + +flag = { + name = shell; + disable = no; + enabled; + value = s; + arg-type = string; + descrip = 'Shell name (follows "#!" magic)'; +}; + +option-doc-format = texi; + +explain =<<- _EOF_ + Note that @code{shell} is only useful if the output file does not + already exist. If it does, then the shell name and optional first + argument will be extracted from the script file. + _EOF_; + +detail =<<- _EOF_ + If the script file already exists and contains Automated Option + Processing text, the second line of the file through the ending tag + will be replaced by the newly generated text. The first @code{#!} + line will be regenerated. + _EOF_; + +export = <<- EndOfText + #define ch_t unsigned char + #define cc_t const unsigned char + #define cch_t char const + EndOfText; diff --git a/autoopts/genshell.h b/autoopts/genshell.h new file mode 100644 index 0000000..994af16 --- /dev/null +++ b/autoopts/genshell.h @@ -0,0 +1,224 @@ +/* -*- buffer-read-only: t -*- vi: set ro: + * + * DO NOT EDIT THIS FILE (genshell.h) + * + * It has been AutoGen-ed + * From the definitions genshell.def + * and the template file options + * + * Generated from AutoOpts 42:1:17 templates. + * + * AutoOpts is a copyrighted work. This header file is not encumbered + * by AutoOpts licensing, but is provided under the licensing terms chosen + * by the genshellopt author or copyright holder. AutoOpts is + * licensed under the terms of the LGPL. The redistributable library + * (``libopts'') is licensed under the terms of either the LGPL or, at the + * users discretion, the BSD license. See the AutoOpts and/or libopts sources + * for details. + * + * The genshellopt program is copyrighted and licensed + * under the following terms: + * + * Copyright (C) 1999-2018 Bruce Korb, all rights reserved. + * This is free software. It is licensed for use, modification and + * redistribution under the terms of the GNU Lesser General Public License, + * version 2 or later + * + * The genshellopt library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, see + * + */ +/** + * This file contains the programmatic interface to the Automated + * Options generated for the genshellopt program. + * These macros are documented in the AutoGen info file in the + * "AutoOpts" chapter. Please refer to that doc for usage help. + */ +#ifndef AUTOOPTS_GENSHELL_H_GUARD +#define AUTOOPTS_GENSHELL_H_GUARD 1 +#include +#include +#include + +/** + * Ensure that the library used for compiling this generated header is at + * least as new as the version current when the header template was released + * (not counting patch version increments). Also ensure that the oldest + * tolerable version is at least as old as what was current when the header + * template was released. + */ +#define AO_TEMPLATE_VERSION 172033 +#if (AO_TEMPLATE_VERSION < OPTIONS_MINIMUM_VERSION) \ + || (AO_TEMPLATE_VERSION > OPTIONS_STRUCT_VERSION) +# error option template version mismatches autoopts/options.h header + Choke Me. +#endif + +#if GCC_VERSION > 40400 +#define NOT_REACHED __builtin_unreachable(); +#else +#define NOT_REACHED +#endif + +/** + * Enumeration of each option type for genshellopt + */ +typedef enum { + INDEX_GENSHELL_OPT_SCRIPT = 0, + INDEX_GENSHELL_OPT_SHELL = 1, + INDEX_GENSHELL_OPT_VERSION = 2, + INDEX_GENSHELL_OPT_HELP = 3, + INDEX_GENSHELL_OPT_MORE_HELP = 4 +} teGenshell_OptIndex; +/** count of all options for genshellopt */ +#define GENSHELL_OPTION_CT 5 +/** genshellopt version */ +#define GENSHELLOPT_VERSION "1" +/** Full genshellopt version text */ +#define GENSHELLOPT_FULL_VERSION "genshellopt 1" + +/** + * Interface defines for all options. Replace "n" with the UPPER_CASED + * option name (as in the teGenshell_OptIndex enumeration above). + * e.g. HAVE_GENSHELL_OPT(SCRIPT) + */ +#define GENSHELL_DESC(n) (genshelloptOptions.pOptDesc[INDEX_GENSHELL_OPT_## n]) +/** 'true' if an option has been specified in any way */ +#define HAVE_GENSHELL_OPT(n) (! UNUSED_OPT(& GENSHELL_DESC(n))) +/** The string argument to an option. The argument type must be \"string\". */ +#define GENSHELL_OPT_ARG(n) (GENSHELL_DESC(n).optArg.argString) +/** Mask the option state revealing how an option was specified. + * It will be one and only one of \a OPTST_SET, \a OPTST_PRESET, + * \a OPTST_DEFINED, \a OPTST_RESET or zero. + */ +#define STATE_GENSHELL_OPT(n) (GENSHELL_DESC(n).fOptState & OPTST_SET_MASK) +/** Count of option's occurrances *on the command line*. */ +#define COUNT_GENSHELL_OPT(n) (GENSHELL_DESC(n).optOccCt) +/** mask of \a OPTST_SET and \a OPTST_DEFINED. */ +#define ISSEL_GENSHELL_OPT(n) (SELECTED_OPT(&GENSHELL_DESC(n))) +/** 'true' if \a HAVE_OPT would yield 'false'. */ +#define ISUNUSED_GENSHELL_OPT(n) (UNUSED_OPT(& GENSHELL_DESC(n))) +/** 'true' if OPTST_DISABLED bit not set. */ +#define ENABLED_GENSHELL_OPT(n) (! DISABLED_OPT(& GENSHELL_DESC(n))) +/** number of stacked option arguments. + * Valid only for stacked option arguments. */ +#define STACKCT_GENSHELL_OPT(n) (((tArgList*)(GENSHELL_DESC(n).optCookie))->useCt) +/** stacked argument vector. + * Valid only for stacked option arguments. */ +#define STACKLST_GENSHELL_OPT(n) (((tArgList*)(GENSHELL_DESC(n).optCookie))->apzArgs) +/** Reset an option. */ +#define CLEAR_GENSHELL_OPT(n) STMTS( \ + GENSHELL_DESC(n).fOptState &= OPTST_PERSISTENT_MASK; \ + if ((GENSHELL_DESC(n).fOptState & OPTST_INITENABLED) == 0) \ + GENSHELL_DESC(n).fOptState |= OPTST_DISABLED; \ + GENSHELL_DESC(n).optCookie = NULL ) +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/** + * Enumeration of genshellopt exit codes + */ +typedef enum { + GENSHELLOPT_EXIT_SUCCESS = 0, + GENSHELLOPT_EXIT_FAILURE = 1, + GENSHELLOPT_EXIT_USAGE_ERROR = 64, + GENSHELLOPT_EXIT_LIBOPTS_FAILURE = 70 +} genshellopt_exit_code_t; +/** + * Interface defines for specific options. + * @{ + */ +#define VALUE_GENSHELL_OPT_SCRIPT 'o' +#define VALUE_GENSHELL_OPT_SHELL 's' +/** option flag (value) for help-value option */ +#define VALUE_GENSHELL_OPT_HELP '?' +/** option flag (value) for more-help-value option */ +#define VALUE_GENSHELL_OPT_MORE_HELP '!' +/** option flag (value) for version-value option */ +#define VALUE_GENSHELL_OPT_VERSION 'v' +/* + * Interface defines not associated with particular options + */ +#define ERRSKIP_GENSHELL_OPTERR STMTS(genshelloptOptions.fOptSet &= ~OPTPROC_ERRSTOP) +#define ERRSTOP_GENSHELL_OPTERR STMTS(genshelloptOptions.fOptSet |= OPTPROC_ERRSTOP) +#define RESTART_GENSHELL_OPT(n) STMTS( \ + genshelloptOptions.curOptIdx = (n); \ + genshelloptOptions.pzCurOpt = NULL ) +#define START_GENSHELL_OPT RESTART_GENSHELL_OPT(1) +#define GENSHELL_USAGE(c) (*genshelloptOptions.pUsageProc)(&genshelloptOptions, c) + +#ifdef __cplusplus +extern "C" { +#endif +/* + * global exported definitions + */ +#define ch_t unsigned char +#define cc_t const unsigned char +#define cch_t char const + + +/* * * * * * + * + * Declare the genshellopt option descriptor. + */ +extern tOptions genshelloptOptions; + +#if defined(ENABLE_NLS) +# ifndef _ +# include +# ifndef HAVE_GETTEXT + extern char * gettext(char const *); +# else +# include +# endif + +# ifndef ATTRIBUTE_FORMAT_ARG +# define ATTRIBUTE_FORMAT_ARG(_a) +# endif + +static inline char* aoGetsText(char const* pz) ATTRIBUTE_FORMAT_ARG(1); +static inline char* aoGetsText(char const* pz) { + if (pz == NULL) return NULL; + return (char*)gettext(pz); +} +# define _(s) aoGetsText(s) +# endif /* _() */ + +# define OPT_NO_XLAT_CFG_NAMES STMTS(genshelloptOptions.fOptSet |= \ + OPTPROC_NXLAT_OPT_CFG;) +# define OPT_NO_XLAT_OPT_NAMES STMTS(genshelloptOptions.fOptSet |= \ + OPTPROC_NXLAT_OPT|OPTPROC_NXLAT_OPT_CFG;) + +# define OPT_XLAT_CFG_NAMES STMTS(genshelloptOptions.fOptSet &= \ + ~(OPTPROC_NXLAT_OPT|OPTPROC_NXLAT_OPT_CFG);) +# define OPT_XLAT_OPT_NAMES STMTS(genshelloptOptions.fOptSet &= \ + ~OPTPROC_NXLAT_OPT;) + +#else /* ENABLE_NLS */ +# define OPT_NO_XLAT_CFG_NAMES +# define OPT_NO_XLAT_OPT_NAMES + +# define OPT_XLAT_CFG_NAMES +# define OPT_XLAT_OPT_NAMES + +# ifndef _ +# define _(_s) _s +# endif +#endif /* ENABLE_NLS */ + + +#ifdef __cplusplus +} +#endif +#endif /* AUTOOPTS_GENSHELL_H_GUARD */ + +/* genshell.h ends here */ diff --git a/autoopts/gettext.h b/autoopts/gettext.h new file mode 100644 index 0000000..87ec819 --- /dev/null +++ b/autoopts/gettext.h @@ -0,0 +1,294 @@ +/* Convenience header for conditional use of GNU . + Copyright (C) 1995-1998, 2000-2002, 2004-2006, 2009-2018 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.1, 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 _LIBGETTEXT_H +#define _LIBGETTEXT_H 1 + +/* NLS can be disabled through the configure --disable-nls option + or through "#define ENABLE NLS 0" before including this file. */ +#if defined ENABLE_NLS && ENABLE_NLS + +/* Get declarations of GNU message catalog functions. */ +# include + +/* You can set the DEFAULT_TEXT_DOMAIN macro to specify the domain used by + the gettext() and ngettext() macros. This is an alternative to calling + textdomain(), and is useful for libraries. */ +# ifdef DEFAULT_TEXT_DOMAIN +# undef gettext +# define gettext(Msgid) \ + dgettext (DEFAULT_TEXT_DOMAIN, Msgid) +# undef ngettext +# define ngettext(Msgid1, Msgid2, N) \ + dngettext (DEFAULT_TEXT_DOMAIN, Msgid1, Msgid2, N) +# endif + +#else + +/* Solaris /usr/include/locale.h includes /usr/include/libintl.h, which + chokes if dcgettext is defined as a macro. So include it now, to make + later inclusions of a NOP. We don't include + as well because people using "gettext.h" will not include , + and also including would fail on SunOS 4, whereas + is OK. */ +#if defined(__sun) +# include +#endif + +/* Many header files from the libstdc++ coming with g++ 3.3 or newer include + , which chokes if dcgettext is defined as a macro. So include + it now, to make later inclusions of a NOP. */ +#if defined(__cplusplus) && defined(__GNUG__) && (__GNUC__ >= 3) +# include +# if (__GLIBC__ >= 2 && !defined __UCLIBC__) || _GLIBCXX_HAVE_LIBINTL_H +# include +# endif +#endif + +/* Disabled NLS. + The casts to 'const char *' serve the purpose of producing warnings + for invalid uses of the value returned from these functions. + On pre-ANSI systems without 'const', the config.h file is supposed to + contain "#define const". */ +# undef gettext +# define gettext(Msgid) ((const char *) (Msgid)) +# undef dgettext +# define dgettext(Domainname, Msgid) ((void) (Domainname), gettext (Msgid)) +# undef dcgettext +# define dcgettext(Domainname, Msgid, Category) \ + ((void) (Category), dgettext (Domainname, Msgid)) +# undef ngettext +# define ngettext(Msgid1, Msgid2, N) \ + ((N) == 1 \ + ? ((void) (Msgid2), (const char *) (Msgid1)) \ + : ((void) (Msgid1), (const char *) (Msgid2))) +# undef dngettext +# define dngettext(Domainname, Msgid1, Msgid2, N) \ + ((void) (Domainname), ngettext (Msgid1, Msgid2, N)) +# undef dcngettext +# define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \ + ((void) (Category), dngettext (Domainname, Msgid1, Msgid2, N)) +# undef textdomain +# define textdomain(Domainname) ((const char *) (Domainname)) +# undef bindtextdomain +# define bindtextdomain(Domainname, Dirname) \ + ((void) (Domainname), (const char *) (Dirname)) +# undef bind_textdomain_codeset +# define bind_textdomain_codeset(Domainname, Codeset) \ + ((void) (Domainname), (const char *) (Codeset)) + +#endif + +/* Prefer gnulib's setlocale override over libintl's setlocale override. */ +#ifdef GNULIB_defined_setlocale +# undef setlocale +# define setlocale rpl_setlocale +#endif + +/* A pseudo function call that serves as a marker for the automated + extraction of messages, but does not call gettext(). The run-time + translation is done at a different place in the code. + The argument, String, should be a literal string. Concatenated strings + and other string expressions won't work. + The macro's expansion is not parenthesized, so that it is suitable as + initializer for static 'char[]' or 'const char[]' variables. */ +#define gettext_noop(String) String + +/* The separator between msgctxt and msgid in a .mo file. */ +#define GETTEXT_CONTEXT_GLUE "\004" + +/* Pseudo function calls, taking a MSGCTXT and a MSGID instead of just a + MSGID. MSGCTXT and MSGID must be string literals. MSGCTXT should be + short and rarely need to change. + The letter 'p' stands for 'particular' or 'special'. */ +#ifdef DEFAULT_TEXT_DOMAIN +# define pgettext(Msgctxt, Msgid) \ + pgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES) +#else +# define pgettext(Msgctxt, Msgid) \ + pgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES) +#endif +#define dpgettext(Domainname, Msgctxt, Msgid) \ + pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES) +#define dcpgettext(Domainname, Msgctxt, Msgid, Category) \ + pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, Category) +#ifdef DEFAULT_TEXT_DOMAIN +# define npgettext(Msgctxt, Msgid, MsgidPlural, N) \ + npgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES) +#else +# define npgettext(Msgctxt, Msgid, MsgidPlural, N) \ + npgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES) +#endif +#define dnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N) \ + npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES) +#define dcnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N, Category) \ + npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, Category) + +#ifdef __GNUC__ +__inline +#else +#ifdef __cplusplus +inline +#endif +#endif +static const char * +pgettext_aux (const char *domain, + const char *msg_ctxt_id, const char *msgid, + int category) +{ + const char *translation = dcgettext (domain, msg_ctxt_id, category); + if (translation == msg_ctxt_id) + return msgid; + else + return translation; +} + +#ifdef __GNUC__ +__inline +#else +#ifdef __cplusplus +inline +#endif +#endif +static const char * +npgettext_aux (const char *domain, + const char *msg_ctxt_id, const char *msgid, + const char *msgid_plural, unsigned long int n, + int category) +{ + const char *translation = + dcngettext (domain, msg_ctxt_id, msgid_plural, n, category); + if (translation == msg_ctxt_id || translation == msgid_plural) + return (n == 1 ? msgid : msgid_plural); + else + return translation; +} + +/* The same thing extended for non-constant arguments. Here MSGCTXT and MSGID + can be arbitrary expressions. But for string literals these macros are + less efficient than those above. */ + +#include + +#if (((__GNUC__ >= 3 || __GNUG__ >= 2) && !defined __STRICT_ANSI__) \ + /* || __STDC_VERSION__ == 199901L + || (__STDC_VERSION__ >= 201112L && !defined __STDC_NO_VLA__) */ ) +# define _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS 1 +#else +# define _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS 0 +#endif + +#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS +#include +#endif + +#define pgettext_expr(Msgctxt, Msgid) \ + dcpgettext_expr (NULL, Msgctxt, Msgid, LC_MESSAGES) +#define dpgettext_expr(Domainname, Msgctxt, Msgid) \ + dcpgettext_expr (Domainname, Msgctxt, Msgid, LC_MESSAGES) + +#ifdef __GNUC__ +__inline +#else +#ifdef __cplusplus +inline +#endif +#endif +static const char * +dcpgettext_expr (const char *domain, + const char *msgctxt, const char *msgid, + int category) +{ + size_t msgctxt_len = strlen (msgctxt) + 1; + size_t msgid_len = strlen (msgid) + 1; + const char *translation; +#if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS + char msg_ctxt_id[msgctxt_len + msgid_len]; +#else + char buf[1024]; + char *msg_ctxt_id = + (msgctxt_len + msgid_len <= sizeof (buf) + ? buf + : (char *) malloc (msgctxt_len + msgid_len)); + if (msg_ctxt_id != NULL) +#endif + { + int found_translation; + memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1); + msg_ctxt_id[msgctxt_len - 1] = '\004'; + memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len); + translation = dcgettext (domain, msg_ctxt_id, category); + found_translation = (translation != msg_ctxt_id); +#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS + if (msg_ctxt_id != buf) + free (msg_ctxt_id); +#endif + if (found_translation) + return translation; + } + return msgid; +} + +#define npgettext_expr(Msgctxt, Msgid, MsgidPlural, N) \ + dcnpgettext_expr (NULL, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES) +#define dnpgettext_expr(Domainname, Msgctxt, Msgid, MsgidPlural, N) \ + dcnpgettext_expr (Domainname, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES) + +#ifdef __GNUC__ +__inline +#else +#ifdef __cplusplus +inline +#endif +#endif +static const char * +dcnpgettext_expr (const char *domain, + const char *msgctxt, const char *msgid, + const char *msgid_plural, unsigned long int n, + int category) +{ + size_t msgctxt_len = strlen (msgctxt) + 1; + size_t msgid_len = strlen (msgid) + 1; + const char *translation; +#if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS + char msg_ctxt_id[msgctxt_len + msgid_len]; +#else + char buf[1024]; + char *msg_ctxt_id = + (msgctxt_len + msgid_len <= sizeof (buf) + ? buf + : (char *) malloc (msgctxt_len + msgid_len)); + if (msg_ctxt_id != NULL) +#endif + { + int found_translation; + memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1); + msg_ctxt_id[msgctxt_len - 1] = '\004'; + memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len); + translation = dcngettext (domain, msg_ctxt_id, msgid_plural, n, category); + found_translation = !(translation == msg_ctxt_id || translation == msgid_plural); +#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS + if (msg_ctxt_id != buf) + free (msg_ctxt_id); +#endif + if (found_translation) + return translation; + } + return (n == 1 ? msgid : msgid_plural); +} + +#endif /* _LIBGETTEXT_H */ diff --git a/autoopts/init.c b/autoopts/init.c new file mode 100644 index 0000000..b65e593 --- /dev/null +++ b/autoopts/init.c @@ -0,0 +1,289 @@ +/** + * \file initialize.c + * + * initialize the libopts data structures. + * + * @addtogroup autoopts + * @{ + */ +/* + * This file is part of AutoOpts, a companion to AutoGen. + * AutoOpts is free software. + * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoOpts is available under any one of two licenses. The license + * in use must be one of these two and the choice is under the control + * of the user of the license. + * + * The GNU Lesser General Public License, version 3 or later + * See the files "COPYING.lgplv3" and "COPYING.gplv3" + * + * The Modified Berkeley Software Distribution License + * See the file "COPYING.mbsd" + * + * These files have the following sha256 sums: + * + * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 + * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 + * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + */ + +/** + * Make sure the option descriptor is there and that we understand it. + * This should be called from any user entry point where one needs to + * worry about validity. (Some entry points are free to assume that + * the call is not the first to the library and, thus, that this has + * already been called.) + * + * Upon successful completion, pzProgName and pzProgPath are set. + * + * @param[in,out] opts program options descriptor + * @param[in] pname name of program, from argv[] + * @returns SUCCESS or FAILURE + */ +static tSuccess +validate_struct(tOptions * opts, char const * pname) +{ + if (opts == NULL) { + fputs(zno_opt_arg, stderr); + return FAILURE; + } + print_exit = ((opts->fOptSet & OPTPROC_SHELL_OUTPUT) != 0); + + /* + * IF the client has enabled translation and the translation procedure + * is available, then go do it. + */ + if ( ((opts->fOptSet & OPTPROC_TRANSLATE) != 0) + && (opts->pTransProc != NULL) + && (option_xlateable_txt.field_ct != 0) ) { + /* + * If option names are not to be translated at all, then do not do + * it for configuration parsing either. (That is the bit that really + * gets tested anyway.) + */ + if ((opts->fOptSet & OPTPROC_NO_XLAT_MASK) == OPTPROC_NXLAT_OPT) + opts->fOptSet |= OPTPROC_NXLAT_OPT_CFG; + opts->pTransProc(); + } + + /* + * IF the struct version is not the current, and also + * either too large (?!) or too small, + * THEN emit error message and fail-exit + */ + if ( ( opts->structVersion != OPTIONS_STRUCT_VERSION ) + && ( (opts->structVersion > OPTIONS_STRUCT_VERSION ) + || (opts->structVersion < OPTIONS_MINIMUM_VERSION ) + ) ) { + fprintf(stderr, zwrong_ver, pname, NUM_TO_VER(opts->structVersion)); + if (opts->structVersion > OPTIONS_STRUCT_VERSION ) + fputs(ztoo_new, stderr); + else + fputs(ztoo_old, stderr); + + fwrite(ao_ver_string, sizeof(ao_ver_string) - 1, 1, stderr); + return FAILURE; + } + + /* + * If the program name hasn't been set, then set the name and the path + * and the set of equivalent characters. + */ + if (opts->pzProgName == NULL) { + char const * pz = strrchr(pname, DIRCH); + char const ** pp = + (char const **)(void **)&(opts->pzProgName); + + if (pz != NULL) + *pp = pz+1; + else + *pp = pname; + + pz = pathfind(getenv("PATH"), (char *)pname, "rx"); + if (pz != NULL) + pname = VOIDP(pz); + + pp = (char const **)VOIDP(&(opts->pzProgPath)); + *pp = pname; + + /* + * when comparing long names, these are equivalent + */ + strequate(zSepChars); + } + + return SUCCESS; +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * DO PRESETS + * + * The next several routines do the immediate action pass on the command + * line options, then the environment variables, then the config files in + * reverse order. Once done with that, the order is reversed and all + * the config files and environment variables are processed again, this + * time only processing the non-immediate action options. do_presets() + * will then return for optionProcess() to do the final pass on the command + * line arguments. + */ + +/** + * scan the command line for immediate action options. + * This is only called the first time through. + * While this procedure is active, the OPTPROC_IMMEDIATE is true. + * + * @param pOpts program options descriptor + * @returns SUCCESS or FAILURE + */ +static tSuccess +immediate_opts(tOptions * opts) +{ + tSuccess res; + + opts->fOptSet |= OPTPROC_IMMEDIATE; + opts->curOptIdx = 1; /* start by skipping program name */ + opts->pzCurOpt = NULL; + + /* + * Examine all the options from the start. We process any options that + * are marked for immediate processing. + */ + for (;;) { + tOptState opt_st = OPTSTATE_INITIALIZER(PRESET); + + res = next_opt(opts, &opt_st); + switch (res) { + case FAILURE: goto failed_option; + case PROBLEM: res = SUCCESS; goto leave; + case SUCCESS: break; + } + + /* + * IF this is an immediate-attribute option, then do it. + */ + if (! DO_IMMEDIATELY(opt_st.flags)) + continue; + + if (! SUCCESSFUL(handle_opt(opts, &opt_st))) + break; + } failed_option:; + + if ((opts->fOptSet & OPTPROC_ERRSTOP) != 0) + (*opts->pUsageProc)(opts, EXIT_FAILURE); + + leave: + + opts->fOptSet &= ~OPTPROC_IMMEDIATE; + return res; +} + +/** + * check for preset values from a config files or envrionment variables + * + * @param[in,out] opts the structure with the option names to check + */ +static tSuccess +do_presets(tOptions * opts) +{ + tOptDesc * od = NULL; + + if (! SUCCESSFUL(immediate_opts(opts))) + return FAILURE; + + /* + * IF this option set has a --save-opts option, then it also + * has a --load-opts option. See if a command line option has disabled + * option presetting. + */ + if ( (opts->specOptIdx.save_opts != NO_EQUIVALENT) + && (opts->specOptIdx.save_opts != 0)) { + od = opts->pOptDesc + opts->specOptIdx.save_opts + 1; + if (DISABLED_OPT(od)) + return SUCCESS; + } + + /* + * Until we return from this procedure, disable non-presettable opts + */ + opts->fOptSet |= OPTPROC_PRESETTING; + /* + * IF there are no config files, + * THEN do any environment presets and leave. + */ + if (opts->papzHomeList == NULL) { + env_presets(opts, ENV_ALL); + } + else { + env_presets(opts, ENV_IMM); + + /* + * Check to see if environment variables have disabled presetting. + */ + if ((od != NULL) && ! DISABLED_OPT(od)) + intern_file_load(opts); + + /* + * ${PROGRAM_LOAD_OPTS} value of "no" cannot disable other environment + * variable options. Only the loading of .rc files. + */ + env_presets(opts, ENV_NON_IMM); + } + opts->fOptSet &= ~OPTPROC_PRESETTING; + + return SUCCESS; +} + +/** + * AutoOpts initialization + * + * @param[in,out] opts the structure to initialize + * @param[in] a_ct program argument count + * @param[in] a_v program argument vector + */ +static bool +ao_initialize(tOptions * opts, int a_ct, char ** a_v) +{ + if ((opts->fOptSet & OPTPROC_INITDONE) != 0) + return true; + + opts->origArgCt = (unsigned int)a_ct; + opts->origArgVect = a_v; + opts->fOptSet |= OPTPROC_INITDONE; + + if (HAS_pzPkgDataDir(opts)) + program_pkgdatadir = opts->pzPkgDataDir; + + if (! SUCCESSFUL(do_presets(opts))) + return false; + + /* + * IF option name conversion was suppressed but it is not suppressed + * for the command line, then it's time to translate option names. + * Usage text will not get retranslated. + */ + if ( ((opts->fOptSet & OPTPROC_TRANSLATE) != 0) + && (opts->pTransProc != NULL) + && ((opts->fOptSet & OPTPROC_NO_XLAT_MASK) == OPTPROC_NXLAT_OPT_CFG) + ) { + opts->fOptSet &= ~OPTPROC_NXLAT_OPT_CFG; + (*opts->pTransProc)(); + } + + if ((opts->fOptSet & OPTPROC_REORDER) != 0) + optionSort(opts); + + opts->curOptIdx = 1; + opts->pzCurOpt = NULL; + return true; +} + +/** @} + * + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of autoopts/initialize.c */ diff --git a/autoopts/install-hook.sh b/autoopts/install-hook.sh new file mode 100644 index 0000000..5aee2d9 --- /dev/null +++ b/autoopts/install-hook.sh @@ -0,0 +1,137 @@ +#! /bin/sh + +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under either of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + +egrep '#undef +AUTOOPTS_ENABLED' ${top_builddir}/config.h >/dev/null && \ + exit 0 + +srcdir=`dirname $0` +srcdir=`cd ${srcdir} ; pwd` + +. ${top_builddir}/config/shdefs + +rm -f ${DESTdestdir}/options.h ${DESTdestdir}/usage-txt.h +opthdrsrc=${srcdir}/autoopts/options.h +usehdrsrc=${srcdir}/autoopts/usage-txt.h +cfgf=${top_builddir}/config.h + +emit_options_h() { + sed '/^#include /dev/null + then echo '#include ' + else echo '#include ' ; fi + + if ${EGREP} 'define +HAVE_LIMITS_H' ${cfgf} >/dev/null + then echo '#include ' + else echo '#include ' ; fi + + if ${EGREP} 'define +HAVE_STDBOOL_H' ${cfgf} >/dev/null + then echo '#include ' + else cat <<- _EOF_ + typedef enum { false = 0, true = 1 } _Bool; + #define bool _Bool + #define true 1 + #define false 0 + _EOF_ + fi + + ${EGREP} 'define +NO_OPTIONAL_OPT_ARGS' ${cfgf} + + if ${EGREP} 'define +HAVE_INTPTR_T' ${cfgf} >/dev/null + then : + else + sizeof_charp=`${EGREP} 'define +SIZEOF_CHARP ' ${cfgf} | \ + sed 's/.*SIZEOF_CHARP *//'` + sizeof_long=` ${EGREP} 'define +SIZEOF_LONG ' ${cfgf} | \ + sed 's/.*SIZEOF_LONG *//'` + if test "X${sizeof_charp}" = "X${sizeof_long}" + then ptrtype=long + else ptrtype=int + fi + cat <<- _EOF_ + #ifndef HAVE_UINTPTR_T + #define HAVE_UINTPTR_T 1 + #define HAVE_INTPTR_T 1 + typedef $ptrtype intptr_t; + typedef unsigned $ptrtype uintptr_t; + #endif /* HAVE_UINTPTR_T */ + _EOF_ + fi + + sedcmd='1,/END-CONFIGURED-HEADERS/d' + + if ${EGREP} 'define +HAVE_PATHFIND' ${cfgf} >/dev/null + then nopathfind='/From:.*pathfind\.c/,/#endif.*HAVE_PATHFIND/d' + else nopathfind='/HAVE_PATHFIND/d' ; fi + + sed "${sedcmd};${nopathfind}" ${opthdrsrc} +} +emit_options_h > ${DESTdestdir}/options.h + +sed '/#if.*AUTOOPTS_INTERNAL/,/#endif.*AUTOOPTS_INTERNAL/d' \ + ${usehdrsrc} > ${DESTdestdir}/usage-txt.h + +test -d "${DESTpkgdatadir}" && { + rmbuild='/# *START-BUILDTREE-ISMS/,/# *END-BUILDTREE-ISMS/d + /# *END-INSTALL-ONLY-CODE/d + /^##/d' + + cd ${DESTpkgdatadir} + for f in * + do case "$f" in + agtexi-cmd.tpl | cmd-doc.tlib | def2pot.tpl | \ + getopt.tpl | options.tpl | str2init.tlib | usage.tlib) + sed "${rmbuild}" $f > $f.tmp + mv -f $f.tmp $f + ;; + + tpl-config.tlib ) + sed '/define top-[a-z]*-dir/d' $f > $f.tmp + mv -f $f.tmp $f + test -n "${DESTlibdatadir}" && { + test -d ${DESTlibdatadir} || \ + mkdir -p ${DESTlibdatadir} || \ + continue + + cp $f ${DESTlibdatadir}/. + } + ;; + + *.* ) : ;; + * ) + chmod a+x $f + ;; + esac + done +} + +## Local Variables: +## Mode: shell-script +## indent-tabs-mode: nil +## sh-basic-offset: 4 +## sh-indent-after-do: 4 +## sh-indentation: 4 +## sh-indent-for-case-label: 0 +## sh-indent-for-case-alt: 4 +## End: + +# end of install-hook.sh diff --git a/autoopts/intprops.h b/autoopts/intprops.h new file mode 100644 index 0000000..af456ff --- /dev/null +++ b/autoopts/intprops.h @@ -0,0 +1,453 @@ +/* intprops.h -- properties of integer types + + Copyright (C) 2001-2018 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.1 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. */ + +#ifndef _GL_INTPROPS_H +#define _GL_INTPROPS_H + +#include + +/* Return a value with the common real type of E and V and the value of V. */ +#define _GL_INT_CONVERT(e, v) (0 * (e) + (v)) + +/* Act like _GL_INT_CONVERT (E, -V) but work around a bug in IRIX 6.5 cc; see + . */ +#define _GL_INT_NEGATE_CONVERT(e, v) (0 * (e) - (v)) + +/* The extra casts in the following macros work around compiler bugs, + e.g., in Cray C 5.0.3.0. */ + +/* True if the arithmetic type T is an integer type. bool counts as + an integer. */ +#define TYPE_IS_INTEGER(t) ((t) 1.5 == 1) + +/* True if the real type T is signed. */ +#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1)) + +/* Return 1 if the real expression E, after promotion, has a + signed or floating type. */ +#define EXPR_SIGNED(e) (_GL_INT_NEGATE_CONVERT (e, 1) < 0) + + +/* Minimum and maximum values for integer types and expressions. */ + +/* The width in bits of the integer type or expression T. + Padding bits are not supported; this is checked at compile-time below. */ +#define TYPE_WIDTH(t) (sizeof (t) * CHAR_BIT) + +/* The maximum and minimum values for the integer type T. */ +#define TYPE_MINIMUM(t) ((t) ~ TYPE_MAXIMUM (t)) +#define TYPE_MAXIMUM(t) \ + ((t) (! TYPE_SIGNED (t) \ + ? (t) -1 \ + : ((((t) 1 << (TYPE_WIDTH (t) - 2)) - 1) * 2 + 1))) + +/* The maximum and minimum values for the type of the expression E, + after integer promotion. E should not have side effects. */ +#define _GL_INT_MINIMUM(e) \ + (EXPR_SIGNED (e) \ + ? ~ _GL_SIGNED_INT_MAXIMUM (e) \ + : _GL_INT_CONVERT (e, 0)) +#define _GL_INT_MAXIMUM(e) \ + (EXPR_SIGNED (e) \ + ? _GL_SIGNED_INT_MAXIMUM (e) \ + : _GL_INT_NEGATE_CONVERT (e, 1)) +#define _GL_SIGNED_INT_MAXIMUM(e) \ + (((_GL_INT_CONVERT (e, 1) << (TYPE_WIDTH ((e) + 0) - 2)) - 1) * 2 + 1) + +/* Work around OpenVMS incompatibility with C99. */ +#if !defined LLONG_MAX && defined __INT64_MAX +# define LLONG_MAX __INT64_MAX +# define LLONG_MIN __INT64_MIN +#endif + +/* This include file assumes that signed types are two's complement without + padding bits; the above macros have undefined behavior otherwise. + If this is a problem for you, please let us know how to fix it for your host. + This assumption is tested by the intprops-tests module. */ + +/* Does the __typeof__ keyword work? This could be done by + 'configure', but for now it's easier to do it by hand. */ +#if (2 <= __GNUC__ \ + || (1210 <= __IBMC__ && defined __IBM__TYPEOF__) \ + || (0x5110 <= __SUNPRO_C && !__STDC__)) +# define _GL_HAVE___TYPEOF__ 1 +#else +# define _GL_HAVE___TYPEOF__ 0 +#endif + +/* Return 1 if the integer type or expression T might be signed. Return 0 + if it is definitely unsigned. This macro does not evaluate its argument, + and expands to an integer constant expression. */ +#if _GL_HAVE___TYPEOF__ +# define _GL_SIGNED_TYPE_OR_EXPR(t) TYPE_SIGNED (__typeof__ (t)) +#else +# define _GL_SIGNED_TYPE_OR_EXPR(t) 1 +#endif + +/* Bound on length of the string representing an unsigned integer + value representable in B bits. log10 (2.0) < 146/485. The + smallest value of B where this bound is not tight is 2621. */ +#define INT_BITS_STRLEN_BOUND(b) (((b) * 146 + 484) / 485) + +/* Bound on length of the string representing an integer type or expression T. + Subtract 1 for the sign bit if T is signed, and then add 1 more for + a minus sign if needed. + + Because _GL_SIGNED_TYPE_OR_EXPR sometimes returns 0 when its argument is + signed, this macro may overestimate the true bound by one byte when + applied to unsigned types of size 2, 4, 16, ... bytes. */ +#define INT_STRLEN_BOUND(t) \ + (INT_BITS_STRLEN_BOUND (TYPE_WIDTH (t) - _GL_SIGNED_TYPE_OR_EXPR (t)) \ + + _GL_SIGNED_TYPE_OR_EXPR (t)) + +/* Bound on buffer size needed to represent an integer type or expression T, + including the terminating null. */ +#define INT_BUFSIZE_BOUND(t) (INT_STRLEN_BOUND (t) + 1) + + +/* Range overflow checks. + + The INT__RANGE_OVERFLOW macros return 1 if the corresponding C + operators might not yield numerically correct answers due to + arithmetic overflow. They do not rely on undefined or + implementation-defined behavior. Their implementations are simple + and straightforward, but they are a bit harder to use than the + INT__OVERFLOW macros described below. + + Example usage: + + long int i = ...; + long int j = ...; + if (INT_MULTIPLY_RANGE_OVERFLOW (i, j, LONG_MIN, LONG_MAX)) + printf ("multiply would overflow"); + else + printf ("product is %ld", i * j); + + Restrictions on *_RANGE_OVERFLOW macros: + + These macros do not check for all possible numerical problems or + undefined or unspecified behavior: they do not check for division + by zero, for bad shift counts, or for shifting negative numbers. + + These macros may evaluate their arguments zero or multiple times, + so the arguments should not have side effects. The arithmetic + arguments (including the MIN and MAX arguments) must be of the same + integer type after the usual arithmetic conversions, and the type + must have minimum value MIN and maximum MAX. Unsigned types should + use a zero MIN of the proper type. + + These macros are tuned for constant MIN and MAX. For commutative + operations such as A + B, they are also tuned for constant B. */ + +/* Return 1 if A + B would overflow in [MIN,MAX] arithmetic. + See above for restrictions. */ +#define INT_ADD_RANGE_OVERFLOW(a, b, min, max) \ + ((b) < 0 \ + ? (a) < (min) - (b) \ + : (max) - (b) < (a)) + +/* Return 1 if A - B would overflow in [MIN,MAX] arithmetic. + See above for restrictions. */ +#define INT_SUBTRACT_RANGE_OVERFLOW(a, b, min, max) \ + ((b) < 0 \ + ? (max) + (b) < (a) \ + : (a) < (min) + (b)) + +/* Return 1 if - A would overflow in [MIN,MAX] arithmetic. + See above for restrictions. */ +#define INT_NEGATE_RANGE_OVERFLOW(a, min, max) \ + ((min) < 0 \ + ? (a) < - (max) \ + : 0 < (a)) + +/* Return 1 if A * B would overflow in [MIN,MAX] arithmetic. + See above for restrictions. Avoid && and || as they tickle + bugs in Sun C 5.11 2010/08/13 and other compilers; see + . */ +#define INT_MULTIPLY_RANGE_OVERFLOW(a, b, min, max) \ + ((b) < 0 \ + ? ((a) < 0 \ + ? (a) < (max) / (b) \ + : (b) == -1 \ + ? 0 \ + : (min) / (b) < (a)) \ + : (b) == 0 \ + ? 0 \ + : ((a) < 0 \ + ? (a) < (min) / (b) \ + : (max) / (b) < (a))) + +/* Return 1 if A / B would overflow in [MIN,MAX] arithmetic. + See above for restrictions. Do not check for division by zero. */ +#define INT_DIVIDE_RANGE_OVERFLOW(a, b, min, max) \ + ((min) < 0 && (b) == -1 && (a) < - (max)) + +/* Return 1 if A % B would overflow in [MIN,MAX] arithmetic. + See above for restrictions. Do not check for division by zero. + Mathematically, % should never overflow, but on x86-like hosts + INT_MIN % -1 traps, and the C standard permits this, so treat this + as an overflow too. */ +#define INT_REMAINDER_RANGE_OVERFLOW(a, b, min, max) \ + INT_DIVIDE_RANGE_OVERFLOW (a, b, min, max) + +/* Return 1 if A << B would overflow in [MIN,MAX] arithmetic. + See above for restrictions. Here, MIN and MAX are for A only, and B need + not be of the same type as the other arguments. The C standard says that + behavior is undefined for shifts unless 0 <= B < wordwidth, and that when + A is negative then A << B has undefined behavior and A >> B has + implementation-defined behavior, but do not check these other + restrictions. */ +#define INT_LEFT_SHIFT_RANGE_OVERFLOW(a, b, min, max) \ + ((a) < 0 \ + ? (a) < (min) >> (b) \ + : (max) >> (b) < (a)) + +/* True if __builtin_add_overflow (A, B, P) works when P is non-null. */ +#if 5 <= __GNUC__ && !defined __ICC +# define _GL_HAS_BUILTIN_OVERFLOW 1 +#else +# define _GL_HAS_BUILTIN_OVERFLOW 0 +#endif + +/* True if __builtin_add_overflow_p (A, B, C) works. */ +#define _GL_HAS_BUILTIN_OVERFLOW_P (7 <= __GNUC__) + +/* The _GL*_OVERFLOW macros have the same restrictions as the + *_RANGE_OVERFLOW macros, except that they do not assume that operands + (e.g., A and B) have the same type as MIN and MAX. Instead, they assume + that the result (e.g., A + B) has that type. */ +#if _GL_HAS_BUILTIN_OVERFLOW_P +# define _GL_ADD_OVERFLOW(a, b, min, max) \ + __builtin_add_overflow_p (a, b, (__typeof__ ((a) + (b))) 0) +# define _GL_SUBTRACT_OVERFLOW(a, b, min, max) \ + __builtin_sub_overflow_p (a, b, (__typeof__ ((a) - (b))) 0) +# define _GL_MULTIPLY_OVERFLOW(a, b, min, max) \ + __builtin_mul_overflow_p (a, b, (__typeof__ ((a) * (b))) 0) +#else +# define _GL_ADD_OVERFLOW(a, b, min, max) \ + ((min) < 0 ? INT_ADD_RANGE_OVERFLOW (a, b, min, max) \ + : (a) < 0 ? (b) <= (a) + (b) \ + : (b) < 0 ? (a) <= (a) + (b) \ + : (a) + (b) < (b)) +# define _GL_SUBTRACT_OVERFLOW(a, b, min, max) \ + ((min) < 0 ? INT_SUBTRACT_RANGE_OVERFLOW (a, b, min, max) \ + : (a) < 0 ? 1 \ + : (b) < 0 ? (a) - (b) <= (a) \ + : (a) < (b)) +# define _GL_MULTIPLY_OVERFLOW(a, b, min, max) \ + (((min) == 0 && (((a) < 0 && 0 < (b)) || ((b) < 0 && 0 < (a)))) \ + || INT_MULTIPLY_RANGE_OVERFLOW (a, b, min, max)) +#endif +#define _GL_DIVIDE_OVERFLOW(a, b, min, max) \ + ((min) < 0 ? (b) == _GL_INT_NEGATE_CONVERT (min, 1) && (a) < - (max) \ + : (a) < 0 ? (b) <= (a) + (b) - 1 \ + : (b) < 0 && (a) + (b) <= (a)) +#define _GL_REMAINDER_OVERFLOW(a, b, min, max) \ + ((min) < 0 ? (b) == _GL_INT_NEGATE_CONVERT (min, 1) && (a) < - (max) \ + : (a) < 0 ? (a) % (b) != ((max) - (b) + 1) % (b) \ + : (b) < 0 && ! _GL_UNSIGNED_NEG_MULTIPLE (a, b, max)) + +/* Return a nonzero value if A is a mathematical multiple of B, where + A is unsigned, B is negative, and MAX is the maximum value of A's + type. A's type must be the same as (A % B)'s type. Normally (A % + -B == 0) suffices, but things get tricky if -B would overflow. */ +#define _GL_UNSIGNED_NEG_MULTIPLE(a, b, max) \ + (((b) < -_GL_SIGNED_INT_MAXIMUM (b) \ + ? (_GL_SIGNED_INT_MAXIMUM (b) == (max) \ + ? (a) \ + : (a) % (_GL_INT_CONVERT (a, _GL_SIGNED_INT_MAXIMUM (b)) + 1)) \ + : (a) % - (b)) \ + == 0) + +/* Check for integer overflow, and report low order bits of answer. + + The INT__OVERFLOW macros return 1 if the corresponding C operators + might not yield numerically correct answers due to arithmetic overflow. + The INT__WRAPV macros also store the low-order bits of the answer. + These macros work correctly on all known practical hosts, and do not rely + on undefined behavior due to signed arithmetic overflow. + + Example usage, assuming A and B are long int: + + if (INT_MULTIPLY_OVERFLOW (a, b)) + printf ("result would overflow\n"); + else + printf ("result is %ld (no overflow)\n", a * b); + + Example usage with WRAPV flavor: + + long int result; + bool overflow = INT_MULTIPLY_WRAPV (a, b, &result); + printf ("result is %ld (%s)\n", result, + overflow ? "after overflow" : "no overflow"); + + Restrictions on these macros: + + These macros do not check for all possible numerical problems or + undefined or unspecified behavior: they do not check for division + by zero, for bad shift counts, or for shifting negative numbers. + + These macros may evaluate their arguments zero or multiple times, so the + arguments should not have side effects. + + The WRAPV macros are not constant expressions. They support only + +, binary -, and *. The result type must be signed. + + These macros are tuned for their last argument being a constant. + + Return 1 if the integer expressions A * B, A - B, -A, A * B, A / B, + A % B, and A << B would overflow, respectively. */ + +#define INT_ADD_OVERFLOW(a, b) \ + _GL_BINARY_OP_OVERFLOW (a, b, _GL_ADD_OVERFLOW) +#define INT_SUBTRACT_OVERFLOW(a, b) \ + _GL_BINARY_OP_OVERFLOW (a, b, _GL_SUBTRACT_OVERFLOW) +#if _GL_HAS_BUILTIN_OVERFLOW_P +# define INT_NEGATE_OVERFLOW(a) INT_SUBTRACT_OVERFLOW (0, a) +#else +# define INT_NEGATE_OVERFLOW(a) \ + INT_NEGATE_RANGE_OVERFLOW (a, _GL_INT_MINIMUM (a), _GL_INT_MAXIMUM (a)) +#endif +#define INT_MULTIPLY_OVERFLOW(a, b) \ + _GL_BINARY_OP_OVERFLOW (a, b, _GL_MULTIPLY_OVERFLOW) +#define INT_DIVIDE_OVERFLOW(a, b) \ + _GL_BINARY_OP_OVERFLOW (a, b, _GL_DIVIDE_OVERFLOW) +#define INT_REMAINDER_OVERFLOW(a, b) \ + _GL_BINARY_OP_OVERFLOW (a, b, _GL_REMAINDER_OVERFLOW) +#define INT_LEFT_SHIFT_OVERFLOW(a, b) \ + INT_LEFT_SHIFT_RANGE_OVERFLOW (a, b, \ + _GL_INT_MINIMUM (a), _GL_INT_MAXIMUM (a)) + +/* Return 1 if the expression A B would overflow, + where OP_RESULT_OVERFLOW (A, B, MIN, MAX) does the actual test, + assuming MIN and MAX are the minimum and maximum for the result type. + Arguments should be free of side effects. */ +#define _GL_BINARY_OP_OVERFLOW(a, b, op_result_overflow) \ + op_result_overflow (a, b, \ + _GL_INT_MINIMUM (0 * (b) + (a)), \ + _GL_INT_MAXIMUM (0 * (b) + (a))) + +/* Store the low-order bits of A + B, A - B, A * B, respectively, into *R. + Return 1 if the result overflows. See above for restrictions. */ +#define INT_ADD_WRAPV(a, b, r) \ + _GL_INT_OP_WRAPV (a, b, r, +, __builtin_add_overflow, INT_ADD_OVERFLOW) +#define INT_SUBTRACT_WRAPV(a, b, r) \ + _GL_INT_OP_WRAPV (a, b, r, -, __builtin_sub_overflow, INT_SUBTRACT_OVERFLOW) +#define INT_MULTIPLY_WRAPV(a, b, r) \ + _GL_INT_OP_WRAPV (a, b, r, *, __builtin_mul_overflow, INT_MULTIPLY_OVERFLOW) + +/* Nonzero if this compiler has GCC bug 68193 or Clang bug 25390. See: + https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68193 + https://llvm.org/bugs/show_bug.cgi?id=25390 + For now, assume all versions of GCC-like compilers generate bogus + warnings for _Generic. This matters only for older compilers that + lack __builtin_add_overflow. */ +#if __GNUC__ +# define _GL__GENERIC_BOGUS 1 +#else +# define _GL__GENERIC_BOGUS 0 +#endif + +/* Store the low-order bits of A B into *R, where OP specifies + the operation. BUILTIN is the builtin operation, and OVERFLOW the + overflow predicate. Return 1 if the result overflows. See above + for restrictions. */ +#if _GL_HAS_BUILTIN_OVERFLOW +# define _GL_INT_OP_WRAPV(a, b, r, op, builtin, overflow) builtin (a, b, r) +#elif 201112 <= __STDC_VERSION__ && !_GL__GENERIC_BOGUS +# define _GL_INT_OP_WRAPV(a, b, r, op, builtin, overflow) \ + (_Generic \ + (*(r), \ + signed char: \ + _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \ + signed char, SCHAR_MIN, SCHAR_MAX), \ + short int: \ + _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \ + short int, SHRT_MIN, SHRT_MAX), \ + int: \ + _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \ + int, INT_MIN, INT_MAX), \ + long int: \ + _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long int, \ + long int, LONG_MIN, LONG_MAX), \ + long long int: \ + _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long long int, \ + long long int, LLONG_MIN, LLONG_MAX))) +#else +# define _GL_INT_OP_WRAPV(a, b, r, op, builtin, overflow) \ + (sizeof *(r) == sizeof (signed char) \ + ? _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \ + signed char, SCHAR_MIN, SCHAR_MAX) \ + : sizeof *(r) == sizeof (short int) \ + ? _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \ + short int, SHRT_MIN, SHRT_MAX) \ + : sizeof *(r) == sizeof (int) \ + ? _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \ + int, INT_MIN, INT_MAX) \ + : _GL_INT_OP_WRAPV_LONGISH(a, b, r, op, overflow)) +# ifdef LLONG_MAX +# define _GL_INT_OP_WRAPV_LONGISH(a, b, r, op, overflow) \ + (sizeof *(r) == sizeof (long int) \ + ? _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long int, \ + long int, LONG_MIN, LONG_MAX) \ + : _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long long int, \ + long long int, LLONG_MIN, LLONG_MAX)) +# else +# define _GL_INT_OP_WRAPV_LONGISH(a, b, r, op, overflow) \ + _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long int, \ + long int, LONG_MIN, LONG_MAX) +# endif +#endif + +/* Store the low-order bits of A B into *R, where the operation + is given by OP. Use the unsigned type UT for calculation to avoid + overflow problems. *R's type is T, with extrema TMIN and TMAX. + T must be a signed integer type. Return 1 if the result overflows. */ +#define _GL_INT_OP_CALC(a, b, r, op, overflow, ut, t, tmin, tmax) \ + (sizeof ((a) op (b)) < sizeof (t) \ + ? _GL_INT_OP_CALC1 ((t) (a), (t) (b), r, op, overflow, ut, t, tmin, tmax) \ + : _GL_INT_OP_CALC1 (a, b, r, op, overflow, ut, t, tmin, tmax)) +#define _GL_INT_OP_CALC1(a, b, r, op, overflow, ut, t, tmin, tmax) \ + ((overflow (a, b) \ + || (EXPR_SIGNED ((a) op (b)) && ((a) op (b)) < (tmin)) \ + || (tmax) < ((a) op (b))) \ + ? (*(r) = _GL_INT_OP_WRAPV_VIA_UNSIGNED (a, b, op, ut, t), 1) \ + : (*(r) = _GL_INT_OP_WRAPV_VIA_UNSIGNED (a, b, op, ut, t), 0)) + +/* Return the low-order bits of A B, where the operation is given + by OP. Use the unsigned type UT for calculation to avoid undefined + behavior on signed integer overflow, and convert the result to type T. + UT is at least as wide as T and is no narrower than unsigned int, + T is two's complement, and there is no padding or trap representations. + Assume that converting UT to T yields the low-order bits, as is + done in all known two's-complement C compilers. E.g., see: + https://gcc.gnu.org/onlinedocs/gcc/Integers-implementation.html + + According to the C standard, converting UT to T yields an + implementation-defined result or signal for values outside T's + range. However, code that works around this theoretical problem + runs afoul of a compiler bug in Oracle Studio 12.3 x86. See: + https://lists.gnu.org/r/bug-gnulib/2017-04/msg00049.html + As the compiler bug is real, don't try to work around the + theoretical problem. */ + +#define _GL_INT_OP_WRAPV_VIA_UNSIGNED(a, b, op, ut, t) \ + ((t) ((ut) (a) op (ut) (b))) + +#endif /* _GL_INTPROPS_H */ diff --git a/autoopts/load.c b/autoopts/load.c new file mode 100644 index 0000000..59d124e --- /dev/null +++ b/autoopts/load.c @@ -0,0 +1,578 @@ + +/** + * \file load.c + * + * This file contains the routines that deal with processing text strings + * for options, either from a NUL-terminated string passed in or from an + * rc/ini file. + * + * @addtogroup autoopts + * @{ + */ +/* + * This file is part of AutoOpts, a companion to AutoGen. + * AutoOpts is free software. + * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoOpts is available under any one of two licenses. The license + * in use must be one of these two and the choice is under the control + * of the user of the license. + * + * The GNU Lesser General Public License, version 3 or later + * See the files "COPYING.lgplv3" and "COPYING.gplv3" + * + * The Modified Berkeley Software Distribution License + * See the file "COPYING.mbsd" + * + * These files have the following sha256 sums: + * + * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 + * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 + * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + */ + +static bool +get_realpath(char * buf, size_t b_sz) +{ +#if defined(HAVE_CANONICALIZE_FILE_NAME) + { + size_t name_len; + + char * pz = canonicalize_file_name(buf); + if (pz == NULL) + return false; + + name_len = strlen(pz); + if (name_len >= (size_t)b_sz) { + free(pz); + return false; + } + + memcpy(buf, pz, name_len + 1); + free(pz); + } + +#elif defined(HAVE_REALPATH) + { + size_t name_len; + char z[PATH_MAX+1]; + + if (realpath(buf, z) == NULL) + return false; + + name_len = strlen(z); + if (name_len >= b_sz) + return false; + + memcpy(buf, z, name_len + 1); + } +#endif + return true; +} + +/*=export_func optionMakePath + * private: + * + * what: translate and construct a path + * arg: + char * + p_buf + The result buffer + + * arg: + int + b_sz + The size of this buffer + + * arg: + char const * + fname + The input name + + * arg: + char const * + prg_path + The full path of the current program + + * + * ret-type: bool + * ret-desc: true if the name was handled, otherwise false. + * If the name does not start with ``$'', then it is handled + * simply by copying the input name to the output buffer and + * resolving the name with either + * @code{canonicalize_file_name(3GLIBC)} or @code{realpath(3C)}. + * + * doc: + * + * This routine will copy the @code{pzName} input name into the + * @code{pzBuf} output buffer, not exceeding @code{bufSize} bytes. If the + * first character of the input name is a @code{'$'} character, then there + * is special handling: + * @* + * @code{$$} is replaced with the directory name of the @code{pzProgPath}, + * searching @code{$PATH} if necessary. + * @* + * @code{$@} is replaced with the AutoGen package data installation directory + * (aka @code{pkgdatadir}). + * @* + * @code{$NAME} is replaced by the contents of the @code{NAME} environment + * variable. If not found, the search fails. + * + * Please note: both @code{$$} and @code{$NAME} must be at the start of the + * @code{pzName} string and must either be the entire string or be followed + * by the @code{'/'} (backslash on windows) character. + * + * err: @code{false} is returned if: + * @* + * @bullet{} The input name exceeds @code{bufSize} bytes. + * @* + * @bullet{} @code{$$}, @code{$@@} or @code{$NAME} is not the full string + * and the next character is not '/'. + * @* + * @bullet{} libopts was built without PKGDATADIR defined and @code{$@@} + * was specified. + * @* + * @bullet{} @code{NAME} is not a known environment variable + * @* + * @bullet{} @code{canonicalize_file_name} or @code{realpath} return + * errors (cannot resolve the resulting path). +=*/ +bool +optionMakePath(char * p_buf, int b_sz, char const * fname, char const * prg_path) +{ + { + size_t len = strlen(fname); + + if (((size_t)b_sz <= len) || (len == 0)) + return false; + } + + /* + * IF not an environment variable, just copy the data + */ + if (*fname != '$') { + char const * src = fname; + char * dst = p_buf; + int ct = b_sz; + + for (;;) { + if ( (*(dst++) = *(src++)) == NUL) + break; + if (--ct <= 0) + return false; + } + } + + /* + * IF the name starts with "$$", then it must be "$$" or + * it must start with "$$/". In either event, replace the "$$" + * with the path to the executable and append a "/" character. + */ + else switch (fname[1]) { + case NUL: + return false; + + case '$': + if (! add_prog_path(p_buf, b_sz, fname, prg_path)) + return false; + break; + + case '@': + if (program_pkgdatadir[0] == NUL) + return false; + + if (snprintf(p_buf, (size_t)b_sz, "%s%s", + program_pkgdatadir, fname + 2) >= b_sz) + return false; + break; + + default: + if (! add_env_val(p_buf, b_sz, fname)) + return false; + } + + return get_realpath(p_buf, b_sz); +} + +/** + * convert a leading "$$" into a path to the executable. + */ +static bool +add_prog_path(char * buf, int b_sz, char const * fname, char const * prg_path) +{ + char const * path; + char const * pz; + int skip = 2; + size_t fname_len; + size_t dir_len; //!< length of the directory portion of the path to the exe + + switch (fname[2]) { + case DIRCH: + skip = 3; + case NUL: + break; + default: + return false; + } + + /* + * See if the path is included in the program name. + * If it is, we're done. Otherwise, we have to hunt + * for the program using "pathfind". + */ + if (strchr(prg_path, DIRCH) != NULL) + path = prg_path; + else { + path = pathfind(getenv("PATH"), (char *)prg_path, "rx"); + + if (path == NULL) + return false; + } + + pz = strrchr(path, DIRCH); + + /* + * IF we cannot find a directory name separator, + * THEN we do not have a path name to our executable file. + */ + if (pz == NULL) + return false; + + fname += skip; + fname_len = strlen(fname) + 1; // + NUL byte + dir_len = (pz - path) + 1; // + dir sep character + + /* + * Concatenate the file name to the end of the executable path. + * The result may be either a file or a directory. + */ + if (dir_len + fname_len > (unsigned)b_sz) + return false; + + memcpy(buf, path, dir_len); + memcpy(buf + dir_len, fname, fname_len); + + /* + * If the "path" path was gotten from "pathfind()", then it was + * allocated and we need to deallocate it. + */ + if (path != prg_path) + AGFREE(path); + return true; +} + +/** + * Add an environment variable value. + */ +static bool +add_env_val(char * buf, int buf_sz, char const * name) +{ + char * dir_part = buf; + + for (;;) { + int ch = (int)*++name; + if (! IS_VALUE_NAME_CHAR(ch)) + break; + *(dir_part++) = (char)ch; + } + + if (dir_part == buf) + return false; + + *dir_part = NUL; + + dir_part = getenv(buf); + + /* + * Environment value not found -- skip the home list entry + */ + if (dir_part == NULL) + return false; + + { + size_t dir_len = strlen(dir_part); + size_t nm_len = strlen(name) + 1; + + if (dir_len + nm_len >= (unsigned)buf_sz) + return false; + memcpy(buf, dir_part, dir_len); + memcpy(buf + dir_len, name, nm_len); + } + + return true; +} + +/** + * Trim leading and trailing white space. + * If we are cooking the text and the text is quoted, then "cook" + * the string. To cook, the string must be quoted. + * + * @param[in,out] txt the input and output string + * @param[in] mode the handling mode (cooking method) + */ +static void +munge_str(char * txt, tOptionLoadMode mode) +{ + char * end; + + if (mode == OPTION_LOAD_KEEP) + return; + + if (IS_WHITESPACE_CHAR(*txt)) { + char * src = SPN_WHITESPACE_CHARS(txt+1); + size_t l = strlen(src) + 1; + memmove(txt, src, l); + end = txt + l - 1; + + } else + end = txt + strlen(txt); + + end = SPN_WHITESPACE_BACK(txt, end); + *end = NUL; + + if (mode == OPTION_LOAD_UNCOOKED) + return; + + switch (*txt) { + default: return; + case '"': + case '\'': break; + } + + switch (end[-1]) { + default: return; + case '"': + case '\'': break; + } + + (void)ao_string_cook(txt, NULL); +} + +static char * +assemble_arg_val(char * txt, tOptionLoadMode mode) +{ + char * end = strpbrk(txt, ARG_BREAK_STR); + int space_break; + + /* + * Not having an argument to a configurable name is okay. + */ + if (end == NULL) + return txt + strlen(txt); + + /* + * If we are keeping all whitespace, then the modevalue starts with the + * character that follows the end of the configurable name, regardless + * of which character caused it. + */ + if (mode == OPTION_LOAD_KEEP) { + *(end++) = NUL; + return end; + } + + /* + * If the name ended on a white space character, remember that + * because we'll have to skip over an immediately following ':' or '=' + * (and the white space following *that*). + */ + space_break = IS_WHITESPACE_CHAR(*end); + *(end++) = NUL; + + end = SPN_WHITESPACE_CHARS(end); + if (space_break && ((*end == ':') || (*end == '='))) + end = SPN_WHITESPACE_CHARS(end+1); + + return end; +} + +static char * +trim_quotes(char * arg) +{ + switch (*arg) { + case '"': + case '\'': + ao_string_cook(arg, NULL); + } + return arg; +} + +/** + * See if the option is to be processed in the current scan direction + * (-1 or +1). + */ +static bool +direction_ok(opt_state_mask_t f, int dir) +{ + if (dir == 0) + return true; + + switch (f & (OPTST_IMM|OPTST_DISABLE_IMM)) { + case 0: + /* + * The selected option has no immediate action. + * THEREFORE, if the direction is PRESETTING + * THEN we skip this option. + */ + if (PRESETTING(dir)) + return false; + break; + + case OPTST_IMM: + if (PRESETTING(dir)) { + /* + * We are in the presetting direction with an option we handle + * immediately for enablement, but normally for disablement. + * Therefore, skip if disabled. + */ + if ((f & OPTST_DISABLED) == 0) + return false; + } else { + /* + * We are in the processing direction with an option we handle + * immediately for enablement, but normally for disablement. + * Therefore, skip if NOT disabled. + */ + if ((f & OPTST_DISABLED) != 0) + return false; + } + break; + + case OPTST_DISABLE_IMM: + if (PRESETTING(dir)) { + /* + * We are in the presetting direction with an option we handle + * immediately for disablement, but normally for handling. + * Therefore, skip if NOT disabled. + */ + if ((f & OPTST_DISABLED) != 0) + return false; + } else { + /* + * We are in the processing direction with an option we handle + * immediately for disablement, but normally for handling. + * Therefore, skip if disabled. + */ + if ((f & OPTST_DISABLED) == 0) + return false; + } + break; + + case OPTST_IMM|OPTST_DISABLE_IMM: + /* + * The selected option is always for immediate action. + * THEREFORE, if the direction is PROCESSING + * THEN we skip this option. + */ + if (PROCESSING(dir)) + return false; + break; + } + return true; +} + +/** + * Load an option from a block of text. The text must start with the + * configurable/option name and be followed by its associated value. + * That value may be processed in any of several ways. See "tOptionLoadMode" + * in autoopts.h. + * + * @param[in,out] opts program options descriptor + * @param[in,out] opt_state option processing state + * @param[in,out] line source line with long option name in it + * @param[in] direction current processing direction (preset or not) + * @param[in] load_mode option loading mode (OPTION_LOAD_*) + */ +static void +load_opt_line(tOptions * opts, tOptState * opt_state, char * line, + tDirection direction, tOptionLoadMode load_mode ) +{ + /* + * When parsing a stored line, we only look at the characters after + * a hyphen. Long names must always be at least two characters and + * short options are always exactly one character long. + */ + line = SPN_LOAD_LINE_SKIP_CHARS(line); + + { + char * arg = assemble_arg_val(line, load_mode); + + if (IS_OPTION_NAME_CHAR(line[1])) { + + if (! SUCCESSFUL(opt_find_long(opts, line, opt_state))) + return; + + } else if (! SUCCESSFUL(opt_find_short(opts, *line, opt_state))) + return; + + if ((! CALLED(direction)) && (opt_state->flags & OPTST_NO_INIT)) + return; + + opt_state->pzOptArg = trim_quotes(arg); + } + + if (! direction_ok(opt_state->flags, direction)) + return; + + /* + * Fix up the args. + */ + if (OPTST_GET_ARGTYPE(opt_state->pOD->fOptState) == OPARG_TYPE_NONE) { + if (*opt_state->pzOptArg != NUL) + return; + opt_state->pzOptArg = NULL; + + } else if (opt_state->pOD->fOptState & OPTST_ARG_OPTIONAL) { + if (*opt_state->pzOptArg == NUL) + opt_state->pzOptArg = NULL; + else { + AGDUPSTR(opt_state->pzOptArg, opt_state->pzOptArg, "opt arg"); + opt_state->flags |= OPTST_ALLOC_ARG; + } + + } else { + if (*opt_state->pzOptArg == NUL) + opt_state->pzOptArg = zNil; + else { + AGDUPSTR(opt_state->pzOptArg, opt_state->pzOptArg, "opt arg"); + opt_state->flags |= OPTST_ALLOC_ARG; + } + } + + { + tOptionLoadMode sv = option_load_mode; + option_load_mode = load_mode; + handle_opt(opts, opt_state); + option_load_mode = sv; + } +} + +/*=export_func optionLoadLine + * + * what: process a string for an option name and value + * + * arg: tOptions *, opts, program options descriptor + * arg: char const *, line, NUL-terminated text + * + * doc: + * + * This is a client program callable routine for setting options from, for + * example, the contents of a file that they read in. Only one option may + * appear in the text. It will be treated as a normal (non-preset) option. + * + * When passed a pointer to the option struct and a string, it will find + * the option named by the first token on the string and set the option + * argument to the remainder of the string. The caller must NUL terminate + * the string. The caller need not skip over any introductory hyphens. + * Any embedded new lines will be included in the option + * argument. If the input looks like one or more quoted strings, then the + * input will be "cooked". The "cooking" is identical to the string + * formation used in AutoGen definition files (@pxref{basic expression}), + * except that you may not use backquotes. + * + * err: Invalid options are silently ignored. Invalid option arguments + * will cause a warning to print, but the function should return. +=*/ +void +optionLoadLine(tOptions * opts, char const * line) +{ + tOptState st = OPTSTATE_INITIALIZER(SET); + char * pz; + proc_state_mask_t sv_flags = opts->fOptSet; + opts->fOptSet &= ~OPTPROC_ERRSTOP; + AGDUPSTR(pz, line, "opt line"); + load_opt_line(opts, &st, pz, DIRECTION_CALLED, OPTION_LOAD_COOKED); + AGFREE(pz); + opts->fOptSet = sv_flags; +} +/** @} + * + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of autoopts/load.c */ diff --git a/autoopts/makeshell.c b/autoopts/makeshell.c new file mode 100644 index 0000000..10ed120 --- /dev/null +++ b/autoopts/makeshell.c @@ -0,0 +1,918 @@ + +/** + * \file makeshell.c + * + * This module will interpret the options set in the tOptions + * structure and create a Bourne shell script capable of parsing them. + * + * @addtogroup autoopts + * @{ + */ +/* + * This file is part of AutoOpts, a companion to AutoGen. + * AutoOpts is free software. + * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoOpts is available under any one of two licenses. The license + * in use must be one of these two and the choice is under the control + * of the user of the license. + * + * The GNU Lesser General Public License, version 3 or later + * See the files "COPYING.lgplv3" and "COPYING.gplv3" + * + * The Modified Berkeley Software Distribution License + * See the file "COPYING.mbsd" + * + * These files have the following sha256 sums: + * + * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 + * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 + * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + */ + + static inline unsigned char to_uchar (char ch) { return ch; } + +#define UPPER(_c) (toupper(to_uchar(_c))) +#define LOWER(_c) (tolower(to_uchar(_c))) + +noreturn static void +option_exits(int exit_code) +{ + if (print_exit) + printf("\nexit %d\n", exit_code); + exit(exit_code); +} + +noreturn static void +ao_bug(char const * msg) +{ + fprintf(stderr, zao_bug_msg, msg); + option_exits(EX_SOFTWARE); +} + +static void +fserr_warn(char const * prog, char const * op, char const * fname) +{ + fprintf(stderr, zfserr_fmt, prog, errno, strerror(errno), + op, fname); +} + +noreturn static void +fserr_exit(char const * prog, char const * op, char const * fname) +{ + fserr_warn(prog, op, fname); + option_exits(EXIT_FAILURE); +} + +/*=export_func optionParseShell + * private: + * + * what: Decipher a boolean value + * arg: + tOptions * + pOpts + program options descriptor + + * + * doc: + * Emit a shell script that will parse the command line options. +=*/ +void +optionParseShell(tOptions * opts) +{ + /* + * Check for our SHELL option now. + * IF the output file contains the "#!" magic marker, + * it will override anything we do here. + */ + if (HAVE_GENSHELL_OPT(SHELL)) + shell_prog = GENSHELL_OPT_ARG(SHELL); + + else if (! ENABLED_GENSHELL_OPT(SHELL)) + shell_prog = NULL; + + else if ((shell_prog = getenv("SHELL")), + shell_prog == NULL) + + shell_prog = POSIX_SHELL; + + /* + * Check for a specified output file + */ + if (HAVE_GENSHELL_OPT(SCRIPT)) + open_out(GENSHELL_OPT_ARG(SCRIPT), opts->pzProgName); + + emit_usage(opts); + emit_setup(opts); + + /* + * There are four modes of option processing. + */ + switch (opts->fOptSet & (OPTPROC_LONGOPT|OPTPROC_SHORTOPT)) { + case OPTPROC_LONGOPT: + fputs(LOOP_STR, stdout); + + fputs(LONG_OPT_MARK, stdout); + fputs(INIT_LOPT_STR, stdout); + emit_long(opts); + printf(LOPT_ARG_FMT, opts->pzPROGNAME); + fputs(END_OPT_SEL_STR, stdout); + + fputs(NOT_FOUND_STR, stdout); + break; + + case 0: + fputs(ONLY_OPTS_LOOP, stdout); + fputs(INIT_LOPT_STR, stdout); + emit_long(opts); + printf(LOPT_ARG_FMT, opts->pzPROGNAME); + break; + + case OPTPROC_SHORTOPT: + fputs(LOOP_STR, stdout); + + fputs(FLAG_OPT_MARK, stdout); + fputs(INIT_OPT_STR, stdout); + emit_flag(opts); + printf(OPT_ARG_FMT, opts->pzPROGNAME); + fputs(END_OPT_SEL_STR, stdout); + + fputs(NOT_FOUND_STR, stdout); + break; + + case OPTPROC_LONGOPT|OPTPROC_SHORTOPT: + fputs(LOOP_STR, stdout); + + fputs(LONG_OPT_MARK, stdout); + fputs(INIT_LOPT_STR, stdout); + emit_long(opts); + printf(LOPT_ARG_FMT, opts->pzPROGNAME); + fputs(END_OPT_SEL_STR, stdout); + + fputs(FLAG_OPT_MARK, stdout); + fputs(INIT_OPT_STR, stdout); + emit_flag(opts); + printf(OPT_ARG_FMT, opts->pzPROGNAME); + fputs(END_OPT_SEL_STR, stdout); + + fputs(NOT_FOUND_STR, stdout); + break; + } + + emit_wrapup(opts); + if ((script_trailer != NULL) && (*script_trailer != NUL)) + fputs(script_trailer, stdout); + else if (ENABLED_GENSHELL_OPT(SHELL)) + printf(SHOW_PROG_ENV, opts->pzPROGNAME); + +#ifdef HAVE_FCHMOD + fchmod(STDOUT_FILENO, 0755); +#endif + fclose(stdout); + + if (ferror(stdout)) + fserr_exit(opts->pzProgName, zwriting, zstdout_name); + + AGFREE(script_text); + script_leader = NULL; + script_trailer = NULL; + script_text = NULL; +} + +#ifdef HAVE_WORKING_FORK +/** + * Print the value of "var" to a file descriptor. + * The "fdin" is the read end of a pipe to a forked process that + * is writing usage text to it. We read that text in and re-emit + * to standard out, formatting it so that it is assigned to a + * shell variable. + * + * @param[in] prog The capitalized, c-variable-formatted program name + * @param[in] var a similarly formatted type name + * (LONGUSAGE, USAGE or VERSION) + * @param[in] fdin the input end of a pipe + */ +static void +emit_var_text(char const * prog, char const * var, int fdin) +{ + FILE * fp = fdopen(fdin, "r" FOPEN_BINARY_FLAG); + int nlct = 0; /* defer newlines and skip trailing ones */ + + printf(SET_TEXT_FMT, prog, var); + if (fp == NULL) + goto skip_text; + + for (;;) { + int ch = fgetc(fp); + switch (ch) { + + case NL: + nlct++; + break; + + case '\'': + while (nlct > 0) { + fputc(NL, stdout); + nlct--; + } + fputs(apostrophe, stdout); + break; + + case EOF: + goto done; + + default: + while (nlct > 0) { + fputc(NL, stdout); + nlct--; + } + fputc(ch, stdout); + break; + } + } done:; + + fclose(fp); + + skip_text: + + fputs(END_SET_TEXT, stdout); +} +#endif + +/** + * The purpose of this function is to assign "long usage", short usage + * and version information to a shell variable. Rather than wind our + * way through all the logic necessary to emit the text directly, we + * fork(), have our child process emit the text the normal way and + * capture the output in the parent process. + * + * @param[in] opts the program options + * @param[in] which what to print: long usage, usage or version + * @param[in] od for TT_VERSION, it is the version option + */ +static void +text_to_var(tOptions * opts, teTextTo which, tOptDesc * od) +{ +# define _TT_(n) static char const z ## n [] = #n; + TEXTTO_TABLE +# undef _TT_ +# define _TT_(n) z ## n , + static char const * ttnames[] = { TEXTTO_TABLE }; +# undef _TT_ + +#if ! defined(HAVE_WORKING_FORK) + printf(SET_NO_TEXT_FMT, opts->pzPROGNAME, ttnames[which]); +#else + int fdpair[2]; + + fflush(stdout); + fflush(stderr); + + if (pipe(fdpair) != 0) + fserr_exit(opts->pzProgName, "pipe", zinter_proc_pipe); + + switch (fork()) { + case -1: + fserr_exit(opts->pzProgName, "fork", opts->pzProgName); + /* NOTREACHED */ + + case 0: + /* + * Send both stderr and stdout to the pipe. No matter which + * descriptor is used, we capture the output on the read end. + */ + dup2(fdpair[1], STDERR_FILENO); + dup2(fdpair[1], STDOUT_FILENO); + close(fdpair[0]); + + switch (which) { + case TT_LONGUSAGE: + (*(opts->pUsageProc))(opts, EXIT_SUCCESS); + /* FALLTHROUGH */ /* NOTREACHED */ + + case TT_USAGE: + (*(opts->pUsageProc))(opts, EXIT_FAILURE); + /* FALLTHROUGH */ /* NOTREACHED */ + + case TT_VERSION: + if (od->fOptState & OPTST_ALLOC_ARG) { + AGFREE(od->optArg.argString); + od->fOptState &= ~OPTST_ALLOC_ARG; + } + od->optArg.argString = "c"; + optionPrintVersion(opts, od); + /* FALLTHROUGH */ /* NOTREACHED */ + + default: + option_exits(EXIT_FAILURE); + /* FALLTHROUGH */ /* NOTREACHED */ + } + /* FALLTHROUGH */ /* NOTREACHED */ + + default: + close(fdpair[1]); + } + + emit_var_text(opts->pzPROGNAME, ttnames[which], fdpair[0]); +#endif +} + +/** + * capture usage text in shell variables. + * + */ +static void +emit_usage(tOptions * opts) +{ + char tm_nm_buf[AO_NAME_SIZE]; + + /* + * First, switch stdout to the output file name. + * Then, change the program name to the one defined + * by the definitions (rather than the current + * executable name). Down case the upper cased name. + */ + if (script_leader != NULL) + fputs(script_leader, stdout); + + { + char const * out_nm; + + { + time_t c_tim = time(NULL); + struct tm * ptm = localtime(&c_tim); + strftime(tm_nm_buf, AO_NAME_SIZE, TIME_FMT, ptm ); + } + + if (HAVE_GENSHELL_OPT(SCRIPT)) + out_nm = GENSHELL_OPT_ARG(SCRIPT); + else out_nm = STDOUT; + + if ((script_leader == NULL) && (shell_prog != NULL)) + printf(SHELL_MAGIC, shell_prog); + + printf(PREAMBLE_FMT, START_MARK, out_nm, tm_nm_buf); + } + + printf(END_PRE_FMT, opts->pzPROGNAME); + + /* + * Get a copy of the original program name in lower case and + * fill in an approximation of the program name from it. + */ + { + char * pzPN = tm_nm_buf; + char const * pz = opts->pzPROGNAME; + char ** pp; + + /* Copy the program name into the time/name buffer */ + for (;;) { + if ((*pzPN++ = (char)tolower(*pz++)) == NUL) + break; + } + + pp = VOIDP(&(opts->pzProgPath)); + *pp = tm_nm_buf; + pp = VOIDP(&(opts->pzProgName)); + *pp = tm_nm_buf; + } + + text_to_var(opts, TT_LONGUSAGE, NULL); + text_to_var(opts, TT_USAGE, NULL); + + { + tOptDesc * pOptDesc = opts->pOptDesc; + int optionCt = opts->optCt; + + for (;;) { + if (pOptDesc->pOptProc == optionPrintVersion) { + text_to_var(opts, TT_VERSION, pOptDesc); + break; + } + + if (--optionCt <= 0) + break; + pOptDesc++; + } + } +} + +static void +emit_wrapup(tOptions * opts) +{ + tOptDesc * od = opts->pOptDesc; + int opt_ct = opts->presetOptCt; + char const * fmt; + + printf(FINISH_LOOP, opts->pzPROGNAME); + for (;opt_ct > 0; od++, --opt_ct) { + /* + * Options that are either usage documentation or are compiled out + * are not to be processed. + */ + if (SKIP_OPT(od) || (od->pz_NAME == NULL)) + continue; + + /* + * do not presence check if there is no minimum/must-set + */ + if ((od->optMinCt == 0) && ((od->fOptState & OPTST_MUST_SET) == 0)) + continue; + + if (od->optMaxCt > 1) + fmt = CHK_MIN_COUNT; + else fmt = CHK_ONE_REQUIRED; + + { + int min = (od->optMinCt == 0) ? 1 : od->optMinCt; + printf(fmt, opts->pzPROGNAME, od->pz_NAME, min); + } + } + fputs(END_MARK, stdout); +} + +static void +emit_setup(tOptions * opts) +{ + tOptDesc * od = opts->pOptDesc; + int opt_ct = opts->presetOptCt; + char const * fmt; + char const * def_val; + + for (;opt_ct > 0; od++, --opt_ct) { + char int_val_buf[32]; + + /* + * Options that are either usage documentation or are compiled out + * are not to be processed. + */ + if (SKIP_OPT(od) || (od->pz_NAME == NULL)) + continue; + + if (od->optMaxCt > 1) + fmt = MULTI_DEF_FMT; + else fmt = SGL_DEF_FMT; + + /* + * IF this is an enumeration/bitmask option, then convert the value + * to a string before printing the default value. + */ + switch (OPTST_GET_ARGTYPE(od->fOptState)) { + case OPARG_TYPE_ENUMERATION: + (*(od->pOptProc))(OPTPROC_EMIT_SHELL, od ); + def_val = od->optArg.argString; + break; + + /* + * Numeric and membership bit options are just printed as a number. + */ + case OPARG_TYPE_NUMERIC: + snprintf(int_val_buf, sizeof(int_val_buf), "%d", + (int)od->optArg.argInt); + def_val = int_val_buf; + break; + + case OPARG_TYPE_MEMBERSHIP: + snprintf(int_val_buf, sizeof(int_val_buf), "%lu", + (unsigned long)od->optArg.argIntptr); + def_val = int_val_buf; + break; + + case OPARG_TYPE_BOOLEAN: + def_val = (od->optArg.argBool) ? TRUE_STR : FALSE_STR; + break; + + default: + if (od->optArg.argString == NULL) { + if (fmt == SGL_DEF_FMT) + fmt = SGL_NO_DEF_FMT; + def_val = NULL; + } + else + def_val = od->optArg.argString; + } + + printf(fmt, opts->pzPROGNAME, od->pz_NAME, def_val); + } +} + +static void +emit_action(tOptions * opts, tOptDesc * od) +{ + if (od->pOptProc == optionPrintVersion) + printf(ECHO_N_EXIT, opts->pzPROGNAME, VER_STR); + + else if (od->pOptProc == optionPagedUsage) + printf(PAGE_USAGE_TEXT, opts->pzPROGNAME); + + else if (od->pOptProc == optionLoadOpt) { + printf(LVL3_CMD, NO_LOAD_WARN); + printf(LVL3_CMD, YES_NEED_OPT_ARG); + + } else if (od->pz_NAME == NULL) { + + if (od->pOptProc == NULL) { + printf(LVL3_CMD, NO_SAVE_OPTS); + printf(LVL3_CMD, OK_NEED_OPT_ARG); + } else + printf(ECHO_N_EXIT, opts->pzPROGNAME, LONG_USE_STR); + + } else { + if (od->optMaxCt == 1) + printf(SGL_ARG_FMT, opts->pzPROGNAME, od->pz_NAME); + else { + if ((unsigned)od->optMaxCt < NOLIMIT) + printf(CHK_MAX_COUNT, opts->pzPROGNAME, + od->pz_NAME, od->optMaxCt); + + printf(MULTI_ARG_FMT, opts->pzPROGNAME, od->pz_NAME); + } + + /* + * Fix up the args. + */ + if (OPTST_GET_ARGTYPE(od->fOptState) == OPARG_TYPE_NONE) { + printf(SET_MULTI_ARG, opts->pzPROGNAME, od->pz_NAME); + printf(LVL3_CMD, NO_ARG_NEEDED); + + } else if (od->fOptState & OPTST_ARG_OPTIONAL) { + printf(SET_MULTI_ARG, opts->pzPROGNAME, od->pz_NAME); + printf(LVL3_CMD, OK_NEED_OPT_ARG); + + } else { + printf(LVL3_CMD, YES_NEED_OPT_ARG); + } + } + fputs(zOptionEndSelect, stdout); +} + +static void +emit_inaction(tOptions * opts, tOptDesc * od) +{ + if (od->pOptProc == optionLoadOpt) { + printf(LVL3_CMD, NO_SUPPRESS_LOAD); + + } else if (od->optMaxCt == 1) + printf(NO_SGL_ARG_FMT, opts->pzPROGNAME, + od->pz_NAME, od->pz_DisablePfx); + else + printf(NO_MULTI_ARG_FMT, opts->pzPROGNAME, + od->pz_NAME, od->pz_DisablePfx); + + printf(LVL3_CMD, NO_ARG_NEEDED); + fputs(zOptionEndSelect, stdout); +} + +/** + * recognize flag options. These go at the end. + * At the end, emit code to handle options we don't recognize. + * + * @param[in] opts the program options + */ +static void +emit_flag(tOptions * opts) +{ + tOptDesc * od = opts->pOptDesc; + int opt_ct = opts->optCt; + + fputs(zOptionCase, stdout); + + for (;opt_ct > 0; od++, --opt_ct) { + + if (SKIP_OPT(od) || ! IS_GRAPHIC_CHAR(od->optValue)) + continue; + + printf(zOptionFlag, od->optValue); + emit_action(opts, od); + } + printf(UNK_OPT_FMT, FLAG_STR, opts->pzPROGNAME); +} + +/** + * Emit the match text for a long option. The passed in \a name may be + * either the enablement name or the disablement name. + * + * @param[in] name The current name to check. + * @param[in] cod current option descriptor + * @param[in] opts the program options + */ +static void +emit_match_expr(char const * name, tOptDesc * cod, tOptions * opts) +{ + char name_bf[32]; + unsigned int min_match_ct = 2; + unsigned int max_match_ct = strlen(name) - 1; + + if (max_match_ct >= sizeof(name_bf) - 1) + goto leave; + + { + tOptDesc * od = opts->pOptDesc; + int ct = opts->optCt; + + for (; ct-- > 0; od++) { + unsigned int match_ct = 0; + + /* + * Omit the current option, Doc opts and compiled out opts. + */ + if ((od == cod) || SKIP_OPT(od)) + continue; + + /* + * Check each character of the name case insensitively. + * They must not be the same. They cannot be, because it would + * not compile correctly if they were. + */ + while (UPPER(od->pz_Name[match_ct]) == UPPER(name[match_ct])) + match_ct++; + + if (match_ct > min_match_ct) + min_match_ct = match_ct; + + /* + * Check the disablement name, too. + */ + if (od->pz_DisableName == NULL) + continue; + + match_ct = 0; + while ( toupper(od->pz_DisableName[match_ct]) + == toupper(name[match_ct])) + match_ct++; + if (match_ct > min_match_ct) + min_match_ct = match_ct; + } + } + + /* + * Don't bother emitting partial matches if there is only one possible + * partial match. + */ + if (min_match_ct < max_match_ct) { + char * pz = name_bf + min_match_ct; + int nm_ix = min_match_ct; + + memcpy(name_bf, name, min_match_ct); + + for (;;) { + *pz = NUL; + printf(zOptionPartName, name_bf); + *pz++ = name[nm_ix++]; + if (name[nm_ix] == NUL) { + *pz = NUL; + break; + } + } + } + +leave: + printf(zOptionFullName, name); +} + +/** + * Emit GNU-standard long option handling code. + * + * @param[in] opts the program options + */ +static void +emit_long(tOptions * opts) +{ + tOptDesc * od = opts->pOptDesc; + int ct = opts->optCt; + + fputs(zOptionCase, stdout); + + /* + * do each option, ... + */ + do { + /* + * Documentation & compiled-out options + */ + if (SKIP_OPT(od)) + continue; + + emit_match_expr(od->pz_Name, od, opts); + emit_action(opts, od); + + /* + * Now, do the same thing for the disablement version of the option. + */ + if (od->pz_DisableName != NULL) { + emit_match_expr(od->pz_DisableName, od, opts); + emit_inaction(opts, od); + } + } while (od++, --ct > 0); + + printf(UNK_OPT_FMT, OPTION_STR, opts->pzPROGNAME); +} + +/** + * Load the previous shell script output file. We need to preserve any + * hand-edited additions outside of the START_MARK and END_MARKs. + * + * @param[in] fname the output file name + */ +static char * +load_old_output(char const * fname, char const * pname) +{ + /* + * IF we cannot stat the file, + * THEN assume we are creating a new file. + * Skip the loading of the old data. + */ + FILE * fp = fopen(fname, "r" FOPEN_BINARY_FLAG); + struct stat stbf; + char * text; + char * scan; + + if (fp == NULL) + return NULL; + + /* + * If we opened it, we should be able to stat it and it needs + * to be a regular file + */ + if ((fstat(fileno(fp), &stbf) != 0) || (! S_ISREG(stbf.st_mode))) + fserr_exit(pname, "fstat", fname); + + scan = text = AGALOC(stbf.st_size + 1, "f data"); + + /* + * Read in all the data as fast as our OS will let us. + */ + for (;;) { + size_t inct = fread(VOIDP(scan), 1, (size_t)stbf.st_size, fp); + if (inct == 0) + break; + + stbf.st_size -= (ssize_t)inct; + + if (stbf.st_size == 0) + break; + + scan += inct; + } + + *scan = NUL; + fclose(fp); + + return text; +} + +/** + * Open the specified output file. If it already exists, load its + * contents and save the non-generated (hand edited) portions. + * If a "start mark" is found, everything before it is preserved leader. + * If not, the entire thing is a trailer. Assuming the start is found, + * then everything after the end marker is the trailer. If the end + * mark is not found, the file is actually corrupt, but we take the + * remainder to be the trailer. + * + * @param[in] fname the output file name + */ +static void +open_out(char const * fname, char const * pname) +{ + + do { + char * txt = script_text = load_old_output(fname, pname); + char * scn; + + if (txt == NULL) + break; + + scn = strstr(txt, START_MARK); + if (scn == NULL) { + script_trailer = txt; + break; + } + + *(scn++) = NUL; + scn = strstr(scn, END_MARK); + if (scn == NULL) { + /* + * The file is corrupt. Set the trailer to be everything + * after the start mark. The user will need to fix it up. + */ + script_trailer = txt + strlen(txt) + START_MARK_LEN + 1; + break; + } + + /* + * Check to see if the data contains our marker. + * If it does, then we will skip over it + */ + script_trailer = scn + END_MARK_LEN; + script_leader = txt; + } while (false); + + if (freopen(fname, "w" FOPEN_BINARY_FLAG, stdout) != stdout) + fserr_exit(pname, "freopen", fname); +} + +/*=export_func genshelloptUsage + * private: + * what: The usage function for the genshellopt generated program + * + * arg: + tOptions * + opts + program options descriptor + + * arg: + int + exit_cd + usage text type to produce + + * + * doc: + * This function is used to create the usage strings for the option + * processing shell script code. Two child processes are spawned + * each emitting the usage text in either the short (error exit) + * style or the long style. The generated program will capture this + * and create shell script variables containing the two types of text. +=*/ +void +genshelloptUsage(tOptions * opts, int exit_cd) +{ +#if ! defined(HAVE_WORKING_FORK) + optionUsage(opts, exit_cd); +#else + /* + * IF not EXIT_SUCCESS, + * THEN emit the short form of usage. + */ + if (exit_cd != EXIT_SUCCESS) + optionUsage(opts, exit_cd); + fflush(stderr); + fflush(stdout); + if (ferror(stdout) || ferror(stderr)) + option_exits(EXIT_FAILURE); + + option_usage_fp = stdout; + + /* + * First, print our usage + */ + switch (fork()) { + case -1: + optionUsage(opts, EXIT_FAILURE); + /* FALLTHROUGH */ /* NOTREACHED */ + + case 0: + pagerState = PAGER_STATE_CHILD; + optionUsage(opts, EXIT_SUCCESS); + /* FALLTHROUGH */ /* NOTREACHED */ + + default: + { + int sts; + wait(&sts); + } + } + + /* + * Generate the pzProgName, since optionProcess() normally + * gets it from the command line + */ + { + char * pz; + char ** pp = VOIDP(&(optionParseShellOptions->pzProgName)); + AGDUPSTR(pz, optionParseShellOptions->pzPROGNAME, "prog name"); + *pp = pz; + while (*pz != NUL) { + *pz = (char)LOWER(*pz); + pz++; + } + } + + /* + * Separate the makeshell usage from the client usage + */ + fprintf(option_usage_fp, zGenshell, optionParseShellOptions->pzProgName); + fflush(option_usage_fp); + + /* + * Now, print the client usage. + */ + switch (fork()) { + case 0: + pagerState = PAGER_STATE_CHILD; + /*FALLTHROUGH*/ + case -1: + optionUsage(optionParseShellOptions, EXIT_FAILURE); + /* FALLTHROUGH */ /* NOTREACHED */ + + default: + { + int sts; + wait(&sts); + } + } + + fflush(stdout); + if (ferror(stdout)) + fserr_exit(opts->pzProgName, zwriting, zstdout_name); + + option_exits(EXIT_SUCCESS); +#endif +} + +/** @} + * + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of autoopts/makeshell.c */ diff --git a/autoopts/mk-autoopts-pc.in b/autoopts/mk-autoopts-pc.in new file mode 100644 index 0000000..2038cfc --- /dev/null +++ b/autoopts/mk-autoopts-pc.in @@ -0,0 +1,77 @@ +#! @CONFIG_SHELL@ +## --------------------------------------------------------------------- +## mk-autoopts-pc.in -- Describe AutoOpts configuration +## +## Autoopts Copyright (C) 1992-2018 by Bruce Korb +## +## DO NOT EDIT THIS FILE (mk-autoopts-pc.in) +## +## It has been AutoGen-ed +## From the definitions aoconf.def +## and the template file aoconf.tpl +## + prefix="@prefix@" + datarootdir="@datarootdir@" + datadir="@datadir@" + package="@PACKAGE@" + includedir="@includedir@" + exec_prefix="@exec_prefix@" + bindir="@bindir@" + libdir="@libdir@" + ldopts="@AG_LDFLAGS@" + exeext="@EXEEXT@" + version="@AO_CURRENT@:@AO_REVISION@:@AO_AGE@" + dotver="@AO_CURRENT@.@AO_REVISION@.@AO_AGE@" + pkgdatadir="${datadir}/${package}" + autogen="${bindir}/autogen${exeext}" + ldflags="-L${libdir} -lopts" + libs="${ldflags}" + libsrc="${pkgdatadir}/libopts-${dotver}.tar.gz" + static_libs="${libdir}/libopts.a" + cflags="-I${includedir}" +test 'X@ENABLE_STATIC@' = Xno && static_libs='' +case "${libdir}" in +/lib | /lib64 | /usr/lib | /usr/lib64 | /usr/lib/* ) + ldopts='' + ldflags=-lopts + ;; + +* ) + ldflags="${ldopts} ${ldflags}" + ;; +esac +libs=${ldflags} +test "${includedir}" = "/usr/include" && cflags="" +PS4='+aoc=${FUNCNAME:-=}-$LINENO> ' +dirname=`dirname ${1}` +test -d ${dirname} || mkdir -p ${dirname} || exit 1 + +cat > ${1} <<- _EOF_ + # pkg-config information for AutoOpts ${dotver} + # + prefix="${prefix}" + datarootdir="${datarootdir}" + datadir="${datadir}" + package="${package}" + includedir="${includedir}" + exec_prefix="${exec_prefix}" + bindir="${bindir}" + libdir="${libdir}" + ldopts="${ldopts}" + exeext="${exeext}" + version="${version}" + dotver="${dotver}" + pkgdatadir="${pkgdatadir}" + autogen="${autogen}" + libs="${libs}" + libsrc="${libsrc}" + static_libs="${static_libs}" + + Name: AutoOpts + Description: A semi-automated generated/library option parser + URL: http://www.gnu.org/software/autogen + Version: ${dotver} + Libs: ${ldflags} + Cflags: ${cflags} + _EOF_ +## end of mk-autoopts-pc.in diff --git a/autoopts/mk-tpl-config.sh b/autoopts/mk-tpl-config.sh new file mode 100755 index 0000000..71f7de4 --- /dev/null +++ b/autoopts/mk-tpl-config.sh @@ -0,0 +1,256 @@ +#! /bin/sh + +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + +prog=`basename $0 .sh` + +die() { + echo "$prog failure: $*" + kill -TERM $progpid + sleep 1 + exit 1 +} + +init() { + PS4='+tpc-${FUNCNAME:-=}-$LINENO> ' + progpid=$$ + prog=`basename $0` + progdir=`\cd \`dirname $0\` >/dev/null ; pwd` + readonly progpid progdir prog + + for d in top_srcdir srcdir top_builddir builddir + do + eval v=\${$d} + test -d "$v" || die "$d does not reference a directory" + v=`cd $v >/dev/null && pwd` + eval ${d}=${v} + done + . ${top_builddir}/config/shdefs +} + +collect_src() { + exec 8>&1 1>&2 + cd ${builddir} + sentinel_file=${1} ; shift + cat 1>&8 <<- _EOF_ + #define AUTOOPTS_INTERNAL 1 + #include "autoopts/project.h" + + #include "ao-strs.h" + static char const ao_ver_string[] = + "${AO_CURRENT}:${AO_REVISION}:${AO_AGE}\n"; + _EOF_ + + for f in "$@" + do test "X$f" = "Xproject.h" || \ + printf '#include "%s"\n' $f + done 1>&8 +} + +extension_defines() { + cd ${builddir}/tpl + + test -f tpl-config.tlib || die "tpl-config.tlib not configured" + test -f ${top_builddir}/config.h || die "config.h missing" + ${GREP:-grep} 'extension-defines' tpl-config.tlib >/dev/null && return + + txt=`sed -n '/POSIX.*SOURCE/,/does not conform to ANSI C/{ + /^#/p + } + /does not conform to ANSI C/q' ${top_builddir}/config.h` + + { + sed '/define *top-build-dir/d;/^;;;/d' tpl-config.tlib + cat <<- _EOF_ + (define top-build-dir "`cd ${top_builddir} >/dev/null + pwd`") + (define top-src-dir "`cd ${top_srcdir} >/dev/null + pwd`") + (define extension-defines + "${txt}") \\=] + _EOF_ + } > tpl-config.$$ + mv -f tpl-config.$$ tpl-config.tlib +} + +fix_scripts() { + for f in ${srcdir}/tpl/*.sh ${srcdir}/tpl/*.pl + do + d=`basename $f | sed 's/\.[sp][hl]$//'` + st=`sed 1q $f` + + case "$st" in + *perl ) echo '#!' `which perl` + sed 1d $f + ;; + + */sh ) echo '#!' ${POSIX_SHELL} + sed 1d $f + ;; + + * ) die "Invalid script type: $st" + ;; + esac > $d + chmod 755 $d + done + + for f in ${srcdir}/tpl/*.pm + do + test -f ${f##*/} && continue + cp $f ${f##*/} + chmod 644 ${f##*/} + done +} + +find_shell_prog() { + case `uname -s` in + SunOS ) + while : ; do + POSIX_SHELL=`which bash` + test -x "${POSIX_SHELL}" && break + POSIX_SHELL=/usr/xpg4/bin/sh + test -x "${POSIX_SHELL}" && break + die "You are hosed. You are on Solaris and have no usable shell." + done + ;; + esac +} + +find_cat_prog() { + while : + do + \unalias -a + unset -f command cat which + POSIX_CAT=`which cat` + test -x "$POSIX_CAT" && break + POSIX_CAT=` + PATH=\`command -p getconf CS_PATH\` + command -v cat ` + test -x "${POSIX_CAT}" && break + die "cannot locate 'cat' command" + done + + formats='man mdoc texi' + for f in $formats + do + for g in $formats + do + test -f ${f}2${g} || { + printf "#! ${POSIX_SHELL}\nexec ${POSIX_CAT} "'${1+"$@"}\n' \ + > ${f}2${g} + chmod 755 ${f}2${g} + } + done + done +} + +scan_cflags() { + libguiledir= + while test $# -gt 0 + do + case "$1" in + -I ) + test -f "$2/libguile/__scm.h" && { + libguiledir=$2 + return 0 + } + ;; + -I* ) + f=${1#-I} + test -f "$f/libguile/__scm.h" && { + libguiledir=$f + return 0 + } + ;; + esac + shift + done + + libguiledir=/usr/include + test -f $libguiledir/libguile/__scm.h && return 0 + die "The Guile header __scm.h cannot be found" +} + +find_libguiledir() { + guile_scm_h= + libguiledir=`exec 2>/dev/null ; guile-config info includedir` + + if test -d "${libguiledir}" + then + test -f ${libguiledir}/libguile.h || { + set -- ${libguiledir}/*guile*/. + if test -d "${2}" + then libguiledir=${2%/.} + elif test -d "$1" + then libguiledir=${1%/.} + fi + } + + v=`guile-config --version 2>&1 | sed 's/.* version //'` + test -d ${libguiledir}/${v%.*} && v=${v%.*} + test -d ${libguiledir}/${v} && libguiledir=${libguiledir}/$v + + else + scan_cflags $* + fi + guile_scm_h=`find ${libguiledir} -type f -name __scm.h` +} + +fix_guile() { + cd ${builddir} + find_libguiledir ${LGCFLAGS} + + list=`exec 2>/dev/null + find ${libguiledir}/libguile* -type f | \ + xargs grep -l -E '\'` + + test -z "$list" && exit 0 + + test -d libguile || mkdir libguile || { + echo "cannot make libguile directory" + exit 1 + } 1>&2 + + noret='\([^a-zA-Z0-9_]\)noreturn\([^a-zA-Z0-9_]\)' + nores='\1__noreturn__\2' + sedex="s@${noret}@${nores}@" + + echo "Patching files to remove bare 'noreturn' keyword in" \ + $list >&2 + + for f in $list + do + g=libguile${f##*/libguile} + sed "${sedex}" $f > $g + diff -u $f $g >&2 || : + done + + test -f libguile.h || cp ${libguiledir}/libguile.h . +} + +init +collect_src "$@" > ${builddir}/libopts.c +extension_defines +fix_scripts +find_shell_prog +find_cat_prog +fix_guile +touch ${sentinel_file} diff --git a/autoopts/nested.c b/autoopts/nested.c new file mode 100644 index 0000000..e760450 --- /dev/null +++ b/autoopts/nested.c @@ -0,0 +1,905 @@ + +/** + * \file nested.c + * + * Handle options with arguments that contain nested values. + * + * @addtogroup autoopts + * @{ + */ +/* + * Automated Options Nested Values module. + * + * This file is part of AutoOpts, a companion to AutoGen. + * AutoOpts is free software. + * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoOpts is available under any one of two licenses. The license + * in use must be one of these two and the choice is under the control + * of the user of the license. + * + * The GNU Lesser General Public License, version 3 or later + * See the files "COPYING.lgplv3" and "COPYING.gplv3" + * + * The Modified Berkeley Software Distribution License + * See the file "COPYING.mbsd" + * + * These files have the following sha256 sums: + * + * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 + * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 + * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + */ + +typedef struct { + int xml_ch; + int xml_len; + char xml_txt[8]; +} xml_xlate_t; + + static xml_xlate_t const xml_xlate[] = { + { '&', 4, "amp;" }, + { '<', 3, "lt;" }, + { '>', 3, "gt;" }, + { '"', 5, "quot;" }, + { '\'',5, "apos;" } +}; + +#ifndef ENOMSG +#define ENOMSG ENOENT +#endif + +/** + * Backslashes are used for line continuations. We keep the newline + * characters, but trim out the backslash: + */ +static void +remove_continuation(char * src) +{ + char * pzD; + + do { + while (*src == NL) src++; + pzD = strchr(src, NL); + if (pzD == NULL) + return; + + /* + * pzD has skipped at least one non-newline character and now + * points to a newline character. It now becomes the source and + * pzD goes to the previous character. + */ + src = pzD--; + if (*pzD != '\\') + pzD++; + } while (pzD == src); + + /* + * Start shifting text. + */ + for (;;) { + char ch = ((*pzD++) = *(src++)); + switch (ch) { + case NUL: return; + case '\\': + if (*src == NL) + --pzD; /* rewrite on next iteration */ + } + } +} + +/** + * Find the end of a quoted string, skipping escaped quote characters. + */ +static char const * +scan_q_str(char const * pzTxt) +{ + char q = *(pzTxt++); /* remember the type of quote */ + + for (;;) { + char ch = *(pzTxt++); + if (ch == NUL) + return pzTxt-1; + + if (ch == q) + return pzTxt; + + if (ch == '\\') { + ch = *(pzTxt++); + /* + * IF the next character is NUL, drop the backslash, too. + */ + if (ch == NUL) + return pzTxt - 2; + + /* + * IF the quote character or the escape character were escaped, + * then skip both, as long as the string does not end. + */ + if ((ch == q) || (ch == '\\')) { + if (*(pzTxt++) == NUL) + return pzTxt-1; + } + } + } +} + + +/** + * Associate a name with either a string or no value. + * + * @param[in,out] pp argument list to add to + * @param[in] name the name of the "suboption" + * @param[in] nm_len the length of the name + * @param[in] val the string value for the suboption + * @param[in] d_len the length of the value + * + * @returns the new value structure + */ +static tOptionValue * +add_string(void ** pp, char const * name, size_t nm_len, + char const * val, size_t d_len) +{ + tOptionValue * pNV; + size_t sz = nm_len + d_len + sizeof(*pNV); + + pNV = AGALOC(sz, "option name/str value pair"); + + if (val == NULL) { + pNV->valType = OPARG_TYPE_NONE; + pNV->pzName = pNV->v.strVal; + + } else { + pNV->valType = OPARG_TYPE_STRING; + if (d_len > 0) { + char const * src = val; + char * pzDst = pNV->v.strVal; + int ct = (int)d_len; + do { + int ch = *(src++) & 0xFF; + if (ch == NUL) goto data_copy_done; + if (ch == '&') + ch = get_special_char(&src, &ct); + *(pzDst++) = (char)ch; + } while (--ct > 0); + data_copy_done: + *pzDst = NUL; + + } else { + pNV->v.strVal[0] = NUL; + } + + pNV->pzName = pNV->v.strVal + d_len + 1; + } + + memcpy(pNV->pzName, name, nm_len); + pNV->pzName[ nm_len ] = NUL; + addArgListEntry(pp, pNV); + return pNV; +} + +/** + * Associate a name with a boolean value + * + * @param[in,out] pp argument list to add to + * @param[in] name the name of the "suboption" + * @param[in] nm_len the length of the name + * @param[in] val the boolean value for the suboption + * @param[in] d_len the length of the value + * + * @returns the new value structure + */ +static tOptionValue * +add_bool(void ** pp, char const * name, size_t nm_len, + char const * val, size_t d_len) +{ + size_t sz = nm_len + sizeof(tOptionValue) + 1; + tOptionValue * new_val = AGALOC(sz, "bool val"); + + /* + * Scan over whitespace is constrained by "d_len" + */ + while (IS_WHITESPACE_CHAR(*val) && (d_len > 0)) { + d_len--; val++; + } + + if (d_len == 0) + new_val->v.boolVal = 0; + + else if (IS_DEC_DIGIT_CHAR(*val)) + new_val->v.boolVal = (unsigned)atoi(val); + + else new_val->v.boolVal = ! IS_FALSE_TYPE_CHAR(*val); + + new_val->valType = OPARG_TYPE_BOOLEAN; + new_val->pzName = (char *)(new_val + 1); + memcpy(new_val->pzName, name, nm_len); + new_val->pzName[ nm_len ] = NUL; + addArgListEntry(pp, new_val); + return new_val; +} + +/** + * Associate a name with strtol() value, defaulting to zero. + * + * @param[in,out] pp argument list to add to + * @param[in] name the name of the "suboption" + * @param[in] nm_len the length of the name + * @param[in] val the numeric value for the suboption + * @param[in] d_len the length of the value + * + * @returns the new value structure + */ +static tOptionValue * +add_number(void ** pp, char const * name, size_t nm_len, + char const * val, size_t d_len) +{ + size_t sz = nm_len + sizeof(tOptionValue) + 1; + tOptionValue * new_val = AGALOC(sz, "int val"); + + /* + * Scan over whitespace is constrained by "d_len" + */ + while (IS_WHITESPACE_CHAR(*val) && (d_len > 0)) { + d_len--; val++; + } + if (d_len == 0) + new_val->v.longVal = 0; + else + new_val->v.longVal = strtol(val, 0, 0); + + new_val->valType = OPARG_TYPE_NUMERIC; + new_val->pzName = (char *)(new_val + 1); + memcpy(new_val->pzName, name, nm_len); + new_val->pzName[ nm_len ] = NUL; + addArgListEntry(pp, new_val); + return new_val; +} + +/** + * Associate a name with a nested/hierarchical value. + * + * @param[in,out] pp argument list to add to + * @param[in] name the name of the "suboption" + * @param[in] nm_len the length of the name + * @param[in] val the nested values for the suboption + * @param[in] d_len the length of the value + * + * @returns the new value structure + */ +static tOptionValue * +add_nested(void ** pp, char const * name, size_t nm_len, + char * val, size_t d_len) +{ + tOptionValue * new_val; + + if (d_len == 0) { + size_t sz = nm_len + sizeof(*new_val) + 1; + new_val = AGALOC(sz, "empty nest"); + new_val->v.nestVal = NULL; + new_val->valType = OPARG_TYPE_HIERARCHY; + new_val->pzName = (char *)(new_val + 1); + memcpy(new_val->pzName, name, nm_len); + new_val->pzName[ nm_len ] = NUL; + + } else { + new_val = optionLoadNested(val, name, nm_len); + } + + if (new_val != NULL) + addArgListEntry(pp, new_val); + + return new_val; +} + +/** + * We have an entry that starts with a name. Find the end of it, cook it + * (if called for) and create the name/value association. + */ +static char const * +scan_name(char const * name, tOptionValue * res) +{ + tOptionValue * new_val; + char const * pzScan = name+1; /* we know first char is a name char */ + char const * pzVal; + size_t nm_len = 1; + size_t d_len = 0; + + /* + * Scan over characters that name a value. These names may not end + * with a colon, but they may contain colons. + */ + pzScan = SPN_VALUE_NAME_CHARS(name + 1); + if (pzScan[-1] == ':') + pzScan--; + nm_len = (size_t)(pzScan - name); + + pzScan = SPN_HORIZ_WHITE_CHARS(pzScan); + + re_switch: + + switch (*pzScan) { + case '=': + case ':': + pzScan = SPN_HORIZ_WHITE_CHARS(pzScan + 1); + if ((*pzScan == '=') || (*pzScan == ':')) + goto default_char; + goto re_switch; + + case NL: + case ',': + pzScan++; + /* FALLTHROUGH */ + + case NUL: + add_string(&(res->v.nestVal), name, nm_len, NULL, (size_t)0); + break; + + case '"': + case '\'': + pzVal = pzScan; + pzScan = scan_q_str(pzScan); + d_len = (size_t)(pzScan - pzVal); + new_val = add_string(&(res->v.nestVal), name, nm_len, pzVal, + d_len); + if ((new_val != NULL) && (option_load_mode == OPTION_LOAD_COOKED)) + ao_string_cook(new_val->v.strVal, NULL); + break; + + default: + default_char: + /* + * We have found some strange text value. It ends with a newline + * or a comma. + */ + pzVal = pzScan; + for (;;) { + char ch = *(pzScan++); + switch (ch) { + case NUL: + pzScan--; + d_len = (size_t)(pzScan - pzVal); + goto string_done; + /* FALLTHROUGH */ + + case NL: + if ( (pzScan > pzVal + 2) + && (pzScan[-2] == '\\') + && (pzScan[ 0] != NUL)) + continue; + /* FALLTHROUGH */ + + case ',': + d_len = (size_t)(pzScan - pzVal) - 1; + string_done: + new_val = add_string(&(res->v.nestVal), name, nm_len, + pzVal, d_len); + if (new_val != NULL) + remove_continuation(new_val->v.strVal); + goto leave_scan_name; + } + } + break; + } leave_scan_name:; + + return pzScan; +} + +/** + * Some xml element that does not start with a name. + * The next character must be either '!' (introducing a comment), + * or '?' (introducing an XML meta-marker of some sort). + * We ignore these and indicate an error (NULL result) otherwise. + * + * @param[in] txt the text within an xml bracket + * @returns the address of the character after the closing marker, or NULL. + */ +static char const * +unnamed_xml(char const * txt) +{ + switch (*txt) { + default: + txt = NULL; + break; + + case '!': + txt = strstr(txt, "-->"); + if (txt != NULL) + txt += 3; + break; + + case '?': + txt = strchr(txt, '>'); + if (txt != NULL) + txt++; + break; + } + return txt; +} + +/** + * Scan off the xml element name, and the rest of the header, too. + * Set the value type to NONE if it ends with "/>". + * + * @param[in] name the first name character (alphabetic) + * @param[out] nm_len the length of the name + * @param[out] val set valType field to STRING or NONE. + * + * @returns the scan resumption point, or NULL on error + */ +static char const * +scan_xml_name(char const * name, size_t * nm_len, tOptionValue * val) +{ + char const * scan = SPN_VALUE_NAME_CHARS(name + 1); + *nm_len = (size_t)(scan - name); + if (*nm_len > 64) + return NULL; + val->valType = OPARG_TYPE_STRING; + + if (IS_WHITESPACE_CHAR(*scan)) { + /* + * There are attributes following the name. Parse 'em. + */ + scan = SPN_WHITESPACE_CHARS(scan); + scan = parse_attrs(NULL, scan, &option_load_mode, val); + if (scan == NULL) + return NULL; /* oops */ + } + + if (! IS_END_XML_TOKEN_CHAR(*scan)) + return NULL; /* oops */ + + if (*scan == '/') { + /* + * Single element XML entries get inserted as an empty string. + */ + if (*++scan != '>') + return NULL; + val->valType = OPARG_TYPE_NONE; + } + return scan+1; +} + +/** + * We've found a closing '>' without a preceding '/', thus we must search + * the text for '' where "name" is the name of the XML element. + * + * @param[in] name the start of the name in the element header + * @param[in] nm_len the length of that name + * @param[out] len the length of the value (string between header and + * the trailer/tail. + * @returns the character after the trailer, or NULL if not found. + */ +static char const * +find_end_xml(char const * src, size_t nm_len, char const * val, size_t * len) +{ + char z[72] = " 0); /* nm_len is known to be 64 or less */ + *(dst++) = '>'; + *dst = NUL; + + { + char const * res = strstr(val, z); + + if (res != NULL) { + char const * end = (option_load_mode != OPTION_LOAD_KEEP) + ? SPN_WHITESPACE_BACK(val, res) + : res; + *len = (size_t)(end - val); /* includes trailing white space */ + res = SPN_WHITESPACE_CHARS(res + (dst - z)); + } + return res; + } +} + +/** + * We've found a '<' character. We ignore this if it is a comment or a + * directive. If it is something else, then whatever it is we are looking + * at is bogus. Returning NULL stops processing. + * + * @param[in] xml_name the name of an xml bracket (usually) + * @param[in,out] res_val the option data derived from the XML element + * + * @returns the place to resume scanning input + */ +static char const * +scan_xml(char const * xml_name, tOptionValue * res_val) +{ + size_t nm_len, v_len; + char const * scan; + char const * val_str; + tOptionValue valu; + tOptionLoadMode save_mode = option_load_mode; + + if (! IS_VAR_FIRST_CHAR(*++xml_name)) + return unnamed_xml(xml_name); + + /* + * "scan_xml_name()" may change "option_load_mode". + */ + val_str = scan_xml_name(xml_name, &nm_len, &valu); + if (val_str == NULL) + goto bail_scan_xml; + + if (valu.valType == OPARG_TYPE_NONE) + scan = val_str; + else { + if (option_load_mode != OPTION_LOAD_KEEP) + val_str = SPN_WHITESPACE_CHARS(val_str); + scan = find_end_xml(xml_name, nm_len, val_str, &v_len); + if (scan == NULL) + goto bail_scan_xml; + } + + /* + * "scan" now points to where the scan is to resume after returning. + * It either points after "/>" at the end of the XML element header, + * or it points after the "" tail based on the name in the header. + */ + + switch (valu.valType) { + case OPARG_TYPE_NONE: + add_string(&(res_val->v.nestVal), xml_name, nm_len, NULL, 0); + break; + + case OPARG_TYPE_STRING: + { + tOptionValue * new_val = add_string( + &(res_val->v.nestVal), xml_name, nm_len, val_str, v_len); + + if (option_load_mode != OPTION_LOAD_KEEP) + munge_str(new_val->v.strVal, option_load_mode); + + break; + } + + case OPARG_TYPE_BOOLEAN: + add_bool(&(res_val->v.nestVal), xml_name, nm_len, val_str, v_len); + break; + + case OPARG_TYPE_NUMERIC: + add_number(&(res_val->v.nestVal), xml_name, nm_len, val_str, v_len); + break; + + case OPARG_TYPE_HIERARCHY: + { + char * pz = AGALOC(v_len+1, "h scan"); + memcpy(pz, val_str, v_len); + pz[v_len] = NUL; + add_nested(&(res_val->v.nestVal), xml_name, nm_len, pz, v_len); + AGFREE(pz); + break; + } + + case OPARG_TYPE_ENUMERATION: + case OPARG_TYPE_MEMBERSHIP: + default: + break; + } + + option_load_mode = save_mode; + return scan; + +bail_scan_xml: + option_load_mode = save_mode; + return NULL; +} + + +/** + * Deallocate a list of option arguments. This must have been gotten from + * a hierarchical option argument, not a stacked list of strings. It is + * an internal call, so it is not validated. The caller is responsible for + * knowing what they are doing. + */ +static void +unload_arg_list(tArgList * arg_list) +{ + int ct = arg_list->useCt; + char const ** pnew_val = arg_list->apzArgs; + + while (ct-- > 0) { + tOptionValue * new_val = (tOptionValue *)VOIDP(*(pnew_val++)); + if (new_val->valType == OPARG_TYPE_HIERARCHY) + unload_arg_list(new_val->v.nestVal); + AGFREE(new_val); + } + + AGFREE(arg_list); +} + +/*=export_func optionUnloadNested + * + * what: Deallocate the memory for a nested value + * arg: + tOptionValue const * + pOptVal + the hierarchical value + + * + * doc: + * A nested value needs to be deallocated. The pointer passed in should + * have been gotten from a call to @code{configFileLoad()} (See + * @pxref{libopts-configFileLoad}). +=*/ +void +optionUnloadNested(tOptionValue const * opt_val) +{ + if (opt_val == NULL) return; + if (opt_val->valType != OPARG_TYPE_HIERARCHY) { + errno = EINVAL; + return; + } + + unload_arg_list(opt_val->v.nestVal); + + AGFREE(opt_val); +} + +/** + * This is a _stable_ sort. The entries are sorted alphabetically, + * but within entries of the same name the ordering is unchanged. + * Typically, we also hope the input is sorted. + */ +static void +sort_list(tArgList * arg_list) +{ + int ix; + int lm = arg_list->useCt; + + /* + * This loop iterates "useCt" - 1 times. + */ + for (ix = 0; ++ix < lm;) { + int iy = ix-1; + tOptionValue * new_v = C(tOptionValue *, arg_list->apzArgs[ix]); + tOptionValue * old_v = C(tOptionValue *, arg_list->apzArgs[iy]); + + /* + * For as long as the new entry precedes the "old" entry, + * move the old pointer. Stop before trying to extract the + * "-1" entry. + */ + while (strcmp(old_v->pzName, new_v->pzName) > 0) { + arg_list->apzArgs[iy+1] = VOIDP(old_v); + old_v = (tOptionValue *)VOIDP(arg_list->apzArgs[--iy]); + if (iy < 0) + break; + } + + /* + * Always store the pointer. Sometimes it is redundant, + * but the redundancy is cheaper than a test and branch sequence. + */ + arg_list->apzArgs[iy+1] = VOIDP(new_v); + } +} + +/*= + * private: + * + * what: parse a hierarchical option argument + * arg: + char const * + pzTxt + the text to scan + + * arg: + char const * + pzName + the name for the text + + * arg: + size_t + nm_len + the length of "name" + + * + * ret_type: tOptionValue * + * ret_desc: An allocated, compound value structure + * + * doc: + * A block of text represents a series of values. It may be an + * entire configuration file, or it may be an argument to an + * option that takes a hierarchical value. + * + * If NULL is returned, errno will be set: + * @itemize @bullet + * @item + * @code{EINVAL} the input text was NULL. + * @item + * @code{ENOMEM} the storage structures could not be allocated + * @item + * @code{ENOMSG} no configuration values were found + * @end itemize +=*/ +static tOptionValue * +optionLoadNested(char const * text, char const * name, size_t nm_len) +{ + tOptionValue * res_val; + + /* + * Make sure we have some data and we have space to put what we find. + */ + if (text == NULL) { + errno = EINVAL; + return NULL; + } + text = SPN_WHITESPACE_CHARS(text); + if (*text == NUL) { + errno = ENOMSG; + return NULL; + } + res_val = AGALOC(sizeof(*res_val) + nm_len + 1, "nest args"); + res_val->valType = OPARG_TYPE_HIERARCHY; + res_val->pzName = (char *)(res_val + 1); + memcpy(res_val->pzName, name, nm_len); + res_val->pzName[nm_len] = NUL; + + { + tArgList * arg_list = AGALOC(sizeof(*arg_list), "nest arg l"); + + res_val->v.nestVal = arg_list; + arg_list->useCt = 0; + arg_list->allocCt = MIN_ARG_ALLOC_CT; + } + + /* + * Scan until we hit a NUL. + */ + do { + text = SPN_WHITESPACE_CHARS(text); + if (IS_VAR_FIRST_CHAR(*text)) + text = scan_name(text, res_val); + + else switch (*text) { + case NUL: + goto scan_done; + + case '<': + text = scan_xml(text, res_val); + if (text == NULL) + goto woops; + if (*text == ',') + text++; + break; + + case '#': + text = strchr(text, NL); + break; + + default: + goto woops; + } + } while (text != NULL); scan_done:; + + { + tArgList * al = res_val->v.nestVal; + if (al->useCt == 0) { + errno = ENOMSG; + goto woops; + } + if (al->useCt > 1) + sort_list(al); + } + + return res_val; + + woops: + AGFREE(res_val->v.nestVal); + AGFREE(res_val); + return NULL; +} + +/*=export_func optionNestedVal + * private: + * + * what: parse a hierarchical option argument + * arg: + tOptions * + opts + program options descriptor + + * arg: + tOptDesc * + od + the descriptor for this arg + + * + * doc: + * Nested value was found on the command line +=*/ +void +optionNestedVal(tOptions * opts, tOptDesc * od) +{ + if (opts < OPTPROC_EMIT_LIMIT) + return; + + if (od->fOptState & OPTST_RESET) { + tArgList * arg_list = od->optCookie; + int ct; + char const ** av; + + if (arg_list == NULL) + return; + ct = arg_list->useCt; + av = arg_list->apzArgs; + + while (--ct >= 0) { + void * p = VOIDP(*(av++)); + optionUnloadNested((tOptionValue const *)p); + } + + AGFREE(od->optCookie); + + } else { + tOptionValue * opt_val = optionLoadNested( + od->optArg.argString, od->pz_Name, strlen(od->pz_Name)); + + if (opt_val != NULL) + addArgListEntry(&(od->optCookie), VOIDP(opt_val)); + } +} + +/** + * get_special_char + */ +static int +get_special_char(char const ** ppz, int * ct) +{ + char const * pz = *ppz; + + if (*ct < 3) + return '&'; + + if (*pz == '#') { + int base = 10; + int retch; + + pz++; + if (*pz == 'x') { + base = 16; + pz++; + } + retch = (int)strtoul(pz, (char **)&pz, base); + if (*pz != ';') + return '&'; + base = (int)(++pz - *ppz); + if (base > *ct) + return '&'; + + *ct -= base; + *ppz = pz; + return retch; + } + + { + int ctr = sizeof(xml_xlate) / sizeof(xml_xlate[0]); + xml_xlate_t const * xlatp = xml_xlate; + + for (;;) { + if ( (*ct >= xlatp->xml_len) + && (strncmp(pz, xlatp->xml_txt, (size_t)xlatp->xml_len) == 0)) { + *ppz += xlatp->xml_len; + *ct -= xlatp->xml_len; + return xlatp->xml_ch; + } + + if (--ctr <= 0) + break; + xlatp++; + } + } + return '&'; +} + +/** + * emit_special_char + */ +static void +emit_special_char(FILE * fp, int ch) +{ + int ctr = sizeof(xml_xlate) / sizeof(xml_xlate[0]); + xml_xlate_t const * xlatp = xml_xlate; + + putc('&', fp); + for (;;) { + if (ch == xlatp->xml_ch) { + fputs(xlatp->xml_txt, fp); + return; + } + if (--ctr <= 0) + break; + xlatp++; + } + fprintf(fp, XML_HEX_BYTE_FMT, (ch & 0xFF)); +} + +/** @} + * + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of autoopts/nested.c */ diff --git a/autoopts/numeric.c b/autoopts/numeric.c new file mode 100644 index 0000000..bbb43cc --- /dev/null +++ b/autoopts/numeric.c @@ -0,0 +1,180 @@ + +/** + * \file numeric.c + * + * Handle options with numeric (integer) arguments. + * + * @addtogroup autoopts + * @{ + */ +/* + * This file is part of AutoOpts, a companion to AutoGen. + * AutoOpts is free software. + * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoOpts is available under any one of two licenses. The license + * in use must be one of these two and the choice is under the control + * of the user of the license. + * + * The GNU Lesser General Public License, version 3 or later + * See the files "COPYING.lgplv3" and "COPYING.gplv3" + * + * The Modified Berkeley Software Distribution License + * See the file "COPYING.mbsd" + * + * These files have the following sha256 sums: + * + * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 + * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 + * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + */ + +/*=export_func optionShowRange + * private: + * + * what: Show info about range constraints + * arg: + tOptions * + pOpts + program options descriptor + + * arg: + tOptDesc * + pOptDesc + the descriptor for this arg + + * arg: + void * + rng_table + the value range tables + + * arg: + int + rng_count + the number of entries + + * + * doc: + * Show information about a numeric option with range constraints. +=*/ +void +optionShowRange(tOptions * pOpts, tOptDesc * pOD, void * rng_table, int rng_ct) +{ + const struct {long const rmin, rmax;} * rng = rng_table; + + char const * pz_indent = zTabHyp + tab_skip_ct; + + /* + * The range is shown only for full usage requests and an error + * in this particular option. + */ + if (pOpts != OPTPROC_EMIT_USAGE) { + if (pOpts <= OPTPROC_EMIT_LIMIT) + return; + pz_indent = ONE_TAB_STR; + + fprintf(option_usage_fp, zRangeErr, pOpts->pzProgName, + pOD->pz_Name, pOD->optArg.argInt); + pz_indent = ""; + } + + if (pOD->fOptState & OPTST_SCALED_NUM) + fprintf(option_usage_fp, zRangeScaled, pz_indent); + + fprintf(option_usage_fp, (rng_ct > 1) ? zRangeLie : zRangeOnly, pz_indent); + pz_indent = (pOpts != OPTPROC_EMIT_USAGE) + ? ONE_TAB_STR + : (zTabSpace + tab_skip_ct); + + for (;;) { + if (rng->rmax == LONG_MIN) + fprintf(option_usage_fp, zRangeExact, pz_indent, rng->rmin); + else if (rng->rmin == LONG_MIN) + fprintf(option_usage_fp, zRangeUpto, pz_indent, rng->rmax); + else if (rng->rmax == LONG_MAX) + fprintf(option_usage_fp, zRangeAbove, pz_indent, rng->rmin); + else + fprintf(option_usage_fp, zRange, pz_indent, rng->rmin, + rng->rmax); + + if (--rng_ct <= 0) { + fputc(NL, option_usage_fp); + break; + } + fputs(zRangeOr, option_usage_fp); + rng++; + } + + if (pOpts > OPTPROC_EMIT_LIMIT) + pOpts->pUsageProc(pOpts, EXIT_FAILURE); +} + +/*=export_func optionNumericVal + * private: + * + * what: process an option with a numeric value. + * arg: + tOptions * + opts + program options descriptor + + * arg: + tOptDesc * + od + the descriptor for this arg + + * + * doc: + * Decipher a numeric value. +=*/ +void +optionNumericVal(tOptions * opts, tOptDesc * od) +{ + char * pz; + long val; + + /* + * Guard against all the different ways this procedure might get invoked + * when there is no string argument provided. + */ + if (INQUERY_CALL(opts, od) || (od->optArg.argString == NULL)) + return; + + /* + * Numeric options may have a range associated with it. + * If it does, the usage procedure requests that it be + * emitted by passing a NULL od pointer. Also bail out + * if there is no option argument or if we are being reset. + */ + if ( (od == NULL) + || (od->optArg.argString == NULL) + || ((od->fOptState & OPTST_RESET) != 0) + || (opts <= OPTPROC_EMIT_LIMIT)) + return; + + errno = 0; + val = strtol(od->optArg.argString, &pz, 0); + if ((pz == od->optArg.argString) || (errno != 0)) + goto bad_number; + + if ((od->fOptState & OPTST_SCALED_NUM) != 0) + switch (*(pz++)) { + case NUL: pz--; break; + case 't': val *= 1000; /* FALLTHROUGH */ + case 'g': val *= 1000; /* FALLTHROUGH */ + case 'm': val *= 1000; /* FALLTHROUGH */ + case 'k': val *= 1000; break; + + case 'T': val *= 1024; /* FALLTHROUGH */ + case 'G': val *= 1024; /* FALLTHROUGH */ + case 'M': val *= 1024; /* FALLTHROUGH */ + case 'K': val *= 1024; break; + + default: goto bad_number; + } + + if (*pz != NUL) + goto bad_number; + + if (od->fOptState & OPTST_ALLOC_ARG) { + AGFREE(od->optArg.argString); + od->fOptState &= ~OPTST_ALLOC_ARG; + } + + od->optArg.argInt = val; + return; + + bad_number: + + fprintf( stderr, zNotNumber, opts->pzProgName, od->optArg.argString ); + if ((opts->fOptSet & OPTPROC_ERRSTOP) != 0) + (*(opts->pUsageProc))(opts, EXIT_FAILURE); + + errno = EINVAL; + od->optArg.argInt = ~0; +} + +/** @} + * + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of autoopts/numeric.c */ diff --git a/autoopts/option-value-type.c b/autoopts/option-value-type.c new file mode 100644 index 0000000..2bc8642 --- /dev/null +++ b/autoopts/option-value-type.c @@ -0,0 +1,156 @@ +/* -*- buffer-read-only: t -*- vi: set ro: + * + * DO NOT EDIT THIS FILE (stdin.c) + * + * It has been AutoGen-ed + * From the definitions stdin + * and the template file str2enum + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name ``Bruce Korb'' nor the name of any other + * contributor may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * str2enum IS PROVIDED BY Bruce Korb ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL Bruce Korb OR ANY OTHER CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "option-value-type.h" +/* ANSI-C code produced by gperf version 3.1 */ +/* Command-line: gperf option-value-type.gp */ +/* Computed positions: -k'1' */ + + + +# if 0 /* gperf build options: */ +// %struct-type +// %language=ANSI-C +// %includes +// %global-table +// %omit-struct-type +// %readonly-tables +// %compare-strncmp +// +// %define slot-name vtp_name +// %define hash-function-name option_value_type_hash +// %define lookup-function-name find_option_value_type_name +// %define word-array-name option_value_type_table +// %define initializer-suffix ,VTP_COUNT_CMD +// +# endif + +#include "option-value-type.h" +typedef struct { + char const * vtp_name; + option_value_type_enum_t vtp_id; +} option_value_type_map_t; +#include + +/* maximum key range = 15, duplicates = 0 */ + +static unsigned int +option_value_type_hash (register const char *str, register size_t len) +{ + static const unsigned char asso_values[] = + { + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 0, 18, + 18, 18, 18, 18, 0, 10, 18, 5, 18, 18, + 5, 18, 18, 18, 18, 0, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18 + }; + return len + asso_values[(unsigned char)str[0]]; +} + +static const option_value_type_map_t option_value_type_table[] = + { + {"",VTP_COUNT_CMD}, {"",VTP_COUNT_CMD}, + {"",VTP_COUNT_CMD}, + {"set", VTP_CMD_SET}, + {"bool", VTP_CMD_BOOL}, + {"",VTP_COUNT_CMD}, + {"string", VTP_CMD_STRING}, + {"boolean", VTP_CMD_BOOLEAN}, + {"",VTP_COUNT_CMD}, + {"hierarchy", VTP_CMD_HIERARCHY}, + {"",VTP_COUNT_CMD}, + {"nested", VTP_CMD_NESTED}, + {"keyword", VTP_CMD_KEYWORD}, + {"",VTP_COUNT_CMD}, + {"set-membership", VTP_CMD_SET_MEMBERSHIP}, + {"",VTP_COUNT_CMD}, {"",VTP_COUNT_CMD}, + {"integer", VTP_CMD_INTEGER} + }; + +static inline const option_value_type_map_t * +find_option_value_type_name (register const char *str, register size_t len) +{ + if (len <= 14 && len >= 3) + { + register unsigned int key = (int)option_value_type_hash (str, len); + + if (key <= 17) + { + register const char *s = option_value_type_table[key].vtp_name; + + if (*str == *s && !strncmp (str + 1, s + 1, len - 1) && s[len] == '\0') + return &option_value_type_table[key]; + } + } + return 0; +} + +/** + * Convert a command (keyword) to a option_value_type_enum_t enumeration value. + * + * @param[in] str a string that should start with a known key word. + * @param[in] len the provided length of the keyword at \a str. + * @returns the enumeration value. + * If not found, that value is VTP_INVALID_CMD. + */ +option_value_type_enum_t +find_option_value_type_cmd(char const * str, size_t len) +{ + option_value_type_map_t const * map; + + map = find_option_value_type_name(str, (unsigned int)len); + return (map == NULL) ? VTP_INVALID_CMD : map->vtp_id; +} + +/* end of option-value-type.c */ diff --git a/autoopts/option-value-type.h b/autoopts/option-value-type.h new file mode 100644 index 0000000..cf6dcaa --- /dev/null +++ b/autoopts/option-value-type.h @@ -0,0 +1,60 @@ +/* -*- buffer-read-only: t -*- vi: set ro: + * + * DO NOT EDIT THIS FILE (stdin.h) + * + * It has been AutoGen-ed + * From the definitions stdin + * and the template file str2enum + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name ``Bruce Korb'' nor the name of any other + * contributor may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * str2enum IS PROVIDED BY Bruce Korb ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL Bruce Korb OR ANY OTHER CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Command/Keyword Dispatcher + */ +#ifndef STR2ENUM_OPTION_VALUE_TYPE_H_GUARD +#define STR2ENUM_OPTION_VALUE_TYPE_H_GUARD 1 +#include +#ifndef MISSING_INTTYPES_H +# include +#endif + +typedef enum { + VTP_INVALID_CMD = 0, + VTP_CMD_STRING = 1, + VTP_CMD_INTEGER = 2, + VTP_CMD_BOOL = 3, + VTP_CMD_BOOLEAN = 4, + VTP_CMD_KEYWORD = 5, + VTP_CMD_SET = 6, + VTP_CMD_SET_MEMBERSHIP = 7, + VTP_CMD_NESTED = 8, + VTP_CMD_HIERARCHY = 9, + VTP_COUNT_CMD +} option_value_type_enum_t; + +extern option_value_type_enum_t +find_option_value_type_cmd(char const * str, size_t len); + +#endif /* STR2ENUM_OPTION_VALUE_TYPE_H_GUARD */ +/* end of option-value-type.h */ diff --git a/autoopts/option-xat-attribute.c b/autoopts/option-xat-attribute.c new file mode 100644 index 0000000..a34ab1b --- /dev/null +++ b/autoopts/option-xat-attribute.c @@ -0,0 +1,148 @@ +/* -*- buffer-read-only: t -*- vi: set ro: + * + * DO NOT EDIT THIS FILE (stdin.c) + * + * It has been AutoGen-ed + * From the definitions stdin + * and the template file str2enum + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name ``Bruce Korb'' nor the name of any other + * contributor may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * str2enum IS PROVIDED BY Bruce Korb ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL Bruce Korb OR ANY OTHER CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "option-xat-attribute.h" +/* ANSI-C code produced by gperf version 3.1 */ +/* Command-line: gperf option-xat-attribute.gp */ +/* Computed positions: -k'1' */ + + + +# if 0 /* gperf build options: */ +// %struct-type +// %language=ANSI-C +// %includes +// %global-table +// %omit-struct-type +// %readonly-tables +// %compare-strncmp +// +// %define slot-name xat_name +// %define hash-function-name option_xat_attribute_hash +// %define lookup-function-name find_option_xat_attribute_name +// %define word-array-name option_xat_attribute_table +// %define initializer-suffix ,XAT_COUNT_CMD +// +# endif + +#include "option-xat-attribute.h" +typedef struct { + char const * xat_name; + option_xat_attribute_enum_t xat_id; +} option_xat_attribute_map_t; +#include + +/* maximum key range = 6, duplicates = 0 */ + +static unsigned int +option_xat_attribute_hash (register const char *str, register size_t len) +{ + static const unsigned char asso_values[] = + { + 10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10, 0, + 10,10,10,10,10,10,10, 5,10, 0, + 10,10,10,10,10,10, 0, 0,10, 0, + 10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10 + }; + return len + asso_values[(unsigned char)str[0]]; +} + +static const option_xat_attribute_map_t option_xat_attribute_table[] = + { + {"",XAT_COUNT_CMD}, {"",XAT_COUNT_CMD}, + {"",XAT_COUNT_CMD}, {"",XAT_COUNT_CMD}, + {"type", XAT_CMD_TYPE}, + {"words", XAT_CMD_WORDS}, + {"cooked", XAT_CMD_COOKED}, + {"members", XAT_CMD_MEMBERS}, + {"uncooked", XAT_CMD_UNCOOKED}, + {"keep", XAT_CMD_KEEP} + }; + +static inline const option_xat_attribute_map_t * +find_option_xat_attribute_name (register const char *str, register size_t len) +{ + if (len <= 8 && len >= 4) + { + register unsigned int key = (int)option_xat_attribute_hash (str, len); + + if (key <= 9) + { + register const char *s = option_xat_attribute_table[key].xat_name; + + if (*str == *s && !strncmp (str + 1, s + 1, len - 1) && s[len] == '\0') + return &option_xat_attribute_table[key]; + } + } + return 0; +} + +/** + * Convert a command (keyword) to a option_xat_attribute_enum_t enumeration value. + * + * @param[in] str a string that should start with a known key word. + * @param[in] len the provided length of the keyword at \a str. + * @returns the enumeration value. + * If not found, that value is XAT_INVALID_CMD. + */ +option_xat_attribute_enum_t +find_option_xat_attribute_cmd(char const * str, size_t len) +{ + option_xat_attribute_map_t const * map; + + map = find_option_xat_attribute_name(str, (unsigned int)len); + return (map == NULL) ? XAT_INVALID_CMD : map->xat_id; +} + +/* end of option-xat-attribute.c */ diff --git a/autoopts/option-xat-attribute.h b/autoopts/option-xat-attribute.h new file mode 100644 index 0000000..dde1617 --- /dev/null +++ b/autoopts/option-xat-attribute.h @@ -0,0 +1,57 @@ +/* -*- buffer-read-only: t -*- vi: set ro: + * + * DO NOT EDIT THIS FILE (stdin.h) + * + * It has been AutoGen-ed + * From the definitions stdin + * and the template file str2enum + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name ``Bruce Korb'' nor the name of any other + * contributor may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * str2enum IS PROVIDED BY Bruce Korb ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL Bruce Korb OR ANY OTHER CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Command/Keyword Dispatcher + */ +#ifndef STR2ENUM_OPTION_XAT_ATTRIBUTE_H_GUARD +#define STR2ENUM_OPTION_XAT_ATTRIBUTE_H_GUARD 1 +#include +#ifndef MISSING_INTTYPES_H +# include +#endif + +typedef enum { + XAT_INVALID_CMD = 0, + XAT_CMD_TYPE = 1, + XAT_CMD_WORDS = 2, + XAT_CMD_MEMBERS = 3, + XAT_CMD_COOKED = 4, + XAT_CMD_UNCOOKED = 5, + XAT_CMD_KEEP = 6, + XAT_COUNT_CMD +} option_xat_attribute_enum_t; + +extern option_xat_attribute_enum_t +find_option_xat_attribute_cmd(char const * str, size_t len); + +#endif /* STR2ENUM_OPTION_XAT_ATTRIBUTE_H_GUARD */ +/* end of option-xat-attribute.h */ diff --git a/autoopts/optionFileLoad.3 b/autoopts/optionFileLoad.3 new file mode 100644 index 0000000..5256ea2 --- /dev/null +++ b/autoopts/optionFileLoad.3 @@ -0,0 +1,52 @@ +.TH optionFileLoad 3 2018-08-26 "" "Programmer's Manual" +.\" DO NOT EDIT THIS FILE (optionFileLoad.3) +.\" +.\" It has been AutoGen-ed +.\" From the definitions ./funcs.def +.\" and the template file agman3.tpl +.SH NAME +optionFileLoad - Load the locatable config files, in order +.sp 1 +.SH SYNOPSIS + +#include <\fIyour-opts.h\fP> +.br +cc [...] -o outfile infile.c -l\fBopts\fP [...] +.sp 1 +int \fBoptionFileLoad\fP(tOptions * \fIopts\fP, char const * \fIprog\fP); +.sp 1 +.SH DESCRIPTION +This function looks in all the specified directories for a configuration +file ("rc" file or "ini" file) and processes any found twice. The first +time through, they are processed in reverse order (last file first). At +that time, only "immediate action" configurables are processed. For +example, if the last named file specifies not processing any more +configuration files, then no more configuration files will be processed. +Such an option in the \fBfirst\fP named directory will have no effect. + +Once the immediate action configurables have been handled, then the +directories are handled in normal, forward order. In that way, later +config files can override the settings of earlier config files. + +See the AutoOpts documentation for a thorough discussion of the +config file format. + +Configuration files not found or not decipherable are simply ignored. +.TP +.IR opts +program options descriptor +.TP +.IR prog +program name +.sp 1 +.SH RETURN VALUE +0 \-> SUCCESS, \-1 \-> FAILURE +.sp 1 +.SH ERRORS +Returns the value, "-1" if the program options descriptor +is out of date or indecipherable. Otherwise, the value "0" will +always be returned. +.SH SEE ALSO +The \fIinfo\fP documentation for the -l\fIopts\fP library. +.br +ao_string_tokenize(3), configFileLoad(3), optionFindNextValue(3), optionFindValue(3), optionFree(3), optionGetValue(3), optionLoadLine(3), optionMemberList(3), optionNextValue(3), optionOnlyUsage(3), optionPrintVersion(3), optionPrintVersionAndReturn(3), optionProcess(3), optionRestore(3), optionSaveFile(3), optionSaveState(3), optionUnloadNested(3), optionVersion(3), strequate(3), streqvcmp(3), streqvmap(3), strneqvcmp(3), strtransform(3), diff --git a/autoopts/optionFindNextValue.3 b/autoopts/optionFindNextValue.3 new file mode 100644 index 0000000..af529ed --- /dev/null +++ b/autoopts/optionFindNextValue.3 @@ -0,0 +1,50 @@ +.TH optionFindNextValue 3 2018-08-26 "" "Programmer's Manual" +.\" DO NOT EDIT THIS FILE (optionFindNextValue.3) +.\" +.\" It has been AutoGen-ed +.\" From the definitions ./funcs.def +.\" and the template file agman3.tpl +.SH NAME +optionFindNextValue - find a hierarcicaly valued option instance +.sp 1 +.SH SYNOPSIS + +#include <\fIyour-opts.h\fP> +.br +cc [...] -o outfile infile.c -l\fBopts\fP [...] +.sp 1 +const tOptionValue * \fBoptionFindNextValue\fP(const tOptDesc * \fIodesc\fP, const tOptionValue * \fIpPrevVal\fP, char const * \fIname\fP, char const * \fIvalue\fP); +.sp 1 +.SH DESCRIPTION +This routine will find the next entry in a nested value option or +configurable. It will search through the list and return the next entry +that matches the criteria. +.TP +.IR odesc +an option with a nested arg type +.TP +.IR pPrevVal +the last entry +.TP +.IR name +name of value to find +.TP +.IR value +the matching value +.sp 1 +.SH RETURN VALUE +a compound value structure +.sp 1 +.SH ERRORS +The returned result is NULL and errno is set: +.sp 1ize @bullet +.sp 1 +\fBEINVAL\fP \- the \fBpOptValue\fP does not point to a valid +hierarchical option value. +.sp 1 +\fBENOENT\fP \- no entry matched the given name. +@end itemize +.SH SEE ALSO +The \fIinfo\fP documentation for the -l\fIopts\fP library. +.br +ao_string_tokenize(3), configFileLoad(3), optionFileLoad(3), optionFindValue(3), optionFree(3), optionGetValue(3), optionLoadLine(3), optionMemberList(3), optionNextValue(3), optionOnlyUsage(3), optionPrintVersion(3), optionPrintVersionAndReturn(3), optionProcess(3), optionRestore(3), optionSaveFile(3), optionSaveState(3), optionUnloadNested(3), optionVersion(3), strequate(3), streqvcmp(3), streqvmap(3), strneqvcmp(3), strtransform(3), diff --git a/autoopts/optionFindValue.3 b/autoopts/optionFindValue.3 new file mode 100644 index 0000000..57b57bf --- /dev/null +++ b/autoopts/optionFindValue.3 @@ -0,0 +1,46 @@ +.TH optionFindValue 3 2018-08-26 "" "Programmer's Manual" +.\" DO NOT EDIT THIS FILE (optionFindValue.3) +.\" +.\" It has been AutoGen-ed +.\" From the definitions ./funcs.def +.\" and the template file agman3.tpl +.SH NAME +optionFindValue - find a hierarcicaly valued option instance +.sp 1 +.SH SYNOPSIS + +#include <\fIyour-opts.h\fP> +.br +cc [...] -o outfile infile.c -l\fBopts\fP [...] +.sp 1 +const tOptionValue * \fBoptionFindValue\fP(const tOptDesc * \fIodesc\fP, char const * \fIname\fP, char const * \fIval\fP); +.sp 1 +.SH DESCRIPTION +This routine will find an entry in a nested value option or configurable. +It will search through the list and return a matching entry. +.TP +.IR odesc +an option with a nested arg type +.TP +.IR name +name of value to find +.TP +.IR val +the matching value +.sp 1 +.SH RETURN VALUE +a compound value structure +.sp 1 +.SH ERRORS +The returned result is NULL and errno is set: +.sp 1ize @bullet +.sp 1 +\fBEINVAL\fP \- the \fBpOptValue\fP does not point to a valid +hierarchical option value. +.sp 1 +\fBENOENT\fP \- no entry matched the given name. +@end itemize +.SH SEE ALSO +The \fIinfo\fP documentation for the -l\fIopts\fP library. +.br +ao_string_tokenize(3), configFileLoad(3), optionFileLoad(3), optionFindNextValue(3), optionFree(3), optionGetValue(3), optionLoadLine(3), optionMemberList(3), optionNextValue(3), optionOnlyUsage(3), optionPrintVersion(3), optionPrintVersionAndReturn(3), optionProcess(3), optionRestore(3), optionSaveFile(3), optionSaveState(3), optionUnloadNested(3), optionVersion(3), strequate(3), streqvcmp(3), streqvmap(3), strneqvcmp(3), strtransform(3), diff --git a/autoopts/optionFree.3 b/autoopts/optionFree.3 new file mode 100644 index 0000000..b8b0f04 --- /dev/null +++ b/autoopts/optionFree.3 @@ -0,0 +1,31 @@ +.TH optionFree 3 2018-08-26 "" "Programmer's Manual" +.\" DO NOT EDIT THIS FILE (optionFree.3) +.\" +.\" It has been AutoGen-ed +.\" From the definitions ./funcs.def +.\" and the template file agman3.tpl +.SH NAME +optionFree - free allocated option processing memory +.sp 1 +.SH SYNOPSIS + +#include <\fIyour-opts.h\fP> +.br +cc [...] -o outfile infile.c -l\fBopts\fP [...] +.sp 1 +void \fBoptionFree\fP(tOptions * \fIpOpts\fP); +.sp 1 +.SH DESCRIPTION +AutoOpts sometimes allocates memory and puts pointers to it in the +option state structures. This routine deallocates all such memory. +.TP +.IR pOpts +program options descriptor +.sp 1 +.SH ERRORS +As long as memory has not been corrupted, +this routine is always successful. +.SH SEE ALSO +The \fIinfo\fP documentation for the -l\fIopts\fP library. +.br +ao_string_tokenize(3), configFileLoad(3), optionFileLoad(3), optionFindNextValue(3), optionFindValue(3), optionGetValue(3), optionLoadLine(3), optionMemberList(3), optionNextValue(3), optionOnlyUsage(3), optionPrintVersion(3), optionPrintVersionAndReturn(3), optionProcess(3), optionRestore(3), optionSaveFile(3), optionSaveState(3), optionUnloadNested(3), optionVersion(3), strequate(3), streqvcmp(3), streqvmap(3), strneqvcmp(3), strtransform(3), diff --git a/autoopts/optionGetValue.3 b/autoopts/optionGetValue.3 new file mode 100644 index 0000000..01ce960 --- /dev/null +++ b/autoopts/optionGetValue.3 @@ -0,0 +1,47 @@ +.TH optionGetValue 3 2018-08-26 "" "Programmer's Manual" +.\" DO NOT EDIT THIS FILE (optionGetValue.3) +.\" +.\" It has been AutoGen-ed +.\" From the definitions ./funcs.def +.\" and the template file agman3.tpl +.SH NAME +optionGetValue - get a specific value from a hierarcical list +.sp 1 +.SH SYNOPSIS + +#include <\fIyour-opts.h\fP> +.br +cc [...] -o outfile infile.c -l\fBopts\fP [...] +.sp 1 +const tOptionValue * \fBoptionGetValue\fP(const tOptionValue * \fIpOptValue\fP, char const * \fIvalueName\fP); +.sp 1 +.SH DESCRIPTION +This routine will find an entry in a nested value option or configurable. +If "valueName" is NULL, then the first entry is returned. Otherwise, +the first entry with a name that exactly matches the argument will be +returned. If there is no matching value, NULL is returned and errno is +set to ENOENT. If the provided option value is not a hierarchical value, +NULL is also returned and errno is set to EINVAL. +.TP +.IR pOptValue +a hierarchcal value +.TP +.IR valueName +name of value to get +.sp 1 +.SH RETURN VALUE +a compound value structure +.sp 1 +.SH ERRORS +The returned result is NULL and errno is set: +.sp 1ize @bullet +.sp 1 +\fBEINVAL\fP \- the \fBpOptValue\fP does not point to a valid +hierarchical option value. +.sp 1 +\fBENOENT\fP \- no entry matched the given name. +@end itemize +.SH SEE ALSO +The \fIinfo\fP documentation for the -l\fIopts\fP library. +.br +ao_string_tokenize(3), configFileLoad(3), optionFileLoad(3), optionFindNextValue(3), optionFindValue(3), optionFree(3), optionLoadLine(3), optionMemberList(3), optionNextValue(3), optionOnlyUsage(3), optionPrintVersion(3), optionPrintVersionAndReturn(3), optionProcess(3), optionRestore(3), optionSaveFile(3), optionSaveState(3), optionUnloadNested(3), optionVersion(3), strequate(3), streqvcmp(3), streqvmap(3), strneqvcmp(3), strtransform(3), diff --git a/autoopts/optionLoadLine.3 b/autoopts/optionLoadLine.3 new file mode 100644 index 0000000..caac444 --- /dev/null +++ b/autoopts/optionLoadLine.3 @@ -0,0 +1,45 @@ +.TH optionLoadLine 3 2018-08-26 "" "Programmer's Manual" +.\" DO NOT EDIT THIS FILE (optionLoadLine.3) +.\" +.\" It has been AutoGen-ed +.\" From the definitions ./funcs.def +.\" and the template file agman3.tpl +.SH NAME +optionLoadLine - process a string for an option name and value +.sp 1 +.SH SYNOPSIS + +#include <\fIyour-opts.h\fP> +.br +cc [...] -o outfile infile.c -l\fBopts\fP [...] +.sp 1 +void \fBoptionLoadLine\fP(tOptions * \fIopts\fP, char const * \fIline\fP); +.sp 1 +.SH DESCRIPTION +This is a client program callable routine for setting options from, for +example, the contents of a file that they read in. Only one option may +appear in the text. It will be treated as a normal (non-preset) option. + +When passed a pointer to the option struct and a string, it will find +the option named by the first token on the string and set the option +argument to the remainder of the string. The caller must NUL terminate +the string. The caller need not skip over any introductory hyphens. +Any embedded new lines will be included in the option +argument. If the input looks like one or more quoted strings, then the +input will be "cooked". The "cooking" is identical to the string +formation used in AutoGen definition files (@pxref{basic expression}), +except that you may not use backquotes. +.TP +.IR opts +program options descriptor +.TP +.IR line +NUL-terminated text +.sp 1 +.SH ERRORS +Invalid options are silently ignored. Invalid option arguments +will cause a warning to print, but the function should return. +.SH SEE ALSO +The \fIinfo\fP documentation for the -l\fIopts\fP library. +.br +ao_string_tokenize(3), configFileLoad(3), optionFileLoad(3), optionFindNextValue(3), optionFindValue(3), optionFree(3), optionGetValue(3), optionMemberList(3), optionNextValue(3), optionOnlyUsage(3), optionPrintVersion(3), optionPrintVersionAndReturn(3), optionProcess(3), optionRestore(3), optionSaveFile(3), optionSaveState(3), optionUnloadNested(3), optionVersion(3), strequate(3), streqvcmp(3), streqvmap(3), strneqvcmp(3), strtransform(3), diff --git a/autoopts/optionMemberList.3 b/autoopts/optionMemberList.3 new file mode 100644 index 0000000..5edb666 --- /dev/null +++ b/autoopts/optionMemberList.3 @@ -0,0 +1,30 @@ +.TH optionMemberList 3 2018-08-26 "" "Programmer's Manual" +.\" DO NOT EDIT THIS FILE (optionMemberList.3) +.\" +.\" It has been AutoGen-ed +.\" From the definitions ./funcs.def +.\" and the template file agman3.tpl +.SH NAME +optionMemberList - Get the list of members of a bit mask set +.sp 1 +.SH SYNOPSIS + +#include <\fIyour-opts.h\fP> +.br +cc [...] -o outfile infile.c -l\fBopts\fP [...] +.sp 1 +char * \fBoptionMemberList\fP(tOptDesc * \fIod\fP); +.sp 1 +.SH DESCRIPTION +This converts the OPT_VALUE_name mask value to a allocated string. +It is the caller's responsibility to free the string. +.TP +.IR od +the set membership option description +.sp 1 +.SH RETURN VALUE +the names of the set bits +.SH SEE ALSO +The \fIinfo\fP documentation for the -l\fIopts\fP library. +.br +ao_string_tokenize(3), configFileLoad(3), optionFileLoad(3), optionFindNextValue(3), optionFindValue(3), optionFree(3), optionGetValue(3), optionLoadLine(3), optionNextValue(3), optionOnlyUsage(3), optionPrintVersion(3), optionPrintVersionAndReturn(3), optionProcess(3), optionRestore(3), optionSaveFile(3), optionSaveState(3), optionUnloadNested(3), optionVersion(3), strequate(3), streqvcmp(3), streqvmap(3), strneqvcmp(3), strtransform(3), diff --git a/autoopts/optionNextValue.3 b/autoopts/optionNextValue.3 new file mode 100644 index 0000000..29dcca5 --- /dev/null +++ b/autoopts/optionNextValue.3 @@ -0,0 +1,47 @@ +.TH optionNextValue 3 2018-08-26 "" "Programmer's Manual" +.\" DO NOT EDIT THIS FILE (optionNextValue.3) +.\" +.\" It has been AutoGen-ed +.\" From the definitions ./funcs.def +.\" and the template file agman3.tpl +.SH NAME +optionNextValue - get the next value from a hierarchical list +.sp 1 +.SH SYNOPSIS + +#include <\fIyour-opts.h\fP> +.br +cc [...] -o outfile infile.c -l\fBopts\fP [...] +.sp 1 +const tOptionValue * \fBoptionNextValue\fP(const tOptionValue * \fIpOptValue\fP, const tOptionValue * \fIpOldValue\fP); +.sp 1 +.SH DESCRIPTION +This routine will return the next entry after the entry passed in. At the +end of the list, NULL will be returned. If the entry is not found on the +list, NULL will be returned and "\fBerrno\fP" will be set to EINVAL. +The "\fBpOldValue\fP" must have been gotten from a prior call to this +routine or to "\fBopitonGetValue()\fP". +.TP +.IR pOptValue +a hierarchcal list value +.TP +.IR pOldValue +a value from this list +.sp 1 +.SH RETURN VALUE +a compound value structure +.sp 1 +.SH ERRORS +The returned result is NULL and errno is set: +.sp 1ize @bullet +.sp 1 +\fBEINVAL\fP \- the \fBpOptValue\fP does not point to a valid +hierarchical option value or \fBpOldValue\fP does not point to a +member of that option value. +.sp 1 +\fBENOENT\fP \- the supplied \fBpOldValue\fP pointed to the last entry. +@end itemize +.SH SEE ALSO +The \fIinfo\fP documentation for the -l\fIopts\fP library. +.br +ao_string_tokenize(3), configFileLoad(3), optionFileLoad(3), optionFindNextValue(3), optionFindValue(3), optionFree(3), optionGetValue(3), optionLoadLine(3), optionMemberList(3), optionOnlyUsage(3), optionPrintVersion(3), optionPrintVersionAndReturn(3), optionProcess(3), optionRestore(3), optionSaveFile(3), optionSaveState(3), optionUnloadNested(3), optionVersion(3), strequate(3), streqvcmp(3), streqvmap(3), strneqvcmp(3), strtransform(3), diff --git a/autoopts/optionOnlyUsage.3 b/autoopts/optionOnlyUsage.3 new file mode 100644 index 0000000..51307be --- /dev/null +++ b/autoopts/optionOnlyUsage.3 @@ -0,0 +1,31 @@ +.TH optionOnlyUsage 3 2018-08-26 "" "Programmer's Manual" +.\" DO NOT EDIT THIS FILE (optionOnlyUsage.3) +.\" +.\" It has been AutoGen-ed +.\" From the definitions ./funcs.def +.\" and the template file agman3.tpl +.SH NAME +optionOnlyUsage - Print usage text for just the options +.sp 1 +.SH SYNOPSIS + +#include <\fIyour-opts.h\fP> +.br +cc [...] -o outfile infile.c -l\fBopts\fP [...] +.sp 1 +void \fBoptionOnlyUsage\fP(tOptions * \fIpOpts\fP, int \fIex_code\fP); +.sp 1 +.SH DESCRIPTION +This routine will print only the usage for each option. +This function may be used when the emitted usage must incorporate +information not available to AutoOpts. +.TP +.IR pOpts +program options descriptor +.TP +.IR ex_code +exit code for calling exit(3) +.SH SEE ALSO +The \fIinfo\fP documentation for the -l\fIopts\fP library. +.br +ao_string_tokenize(3), configFileLoad(3), optionFileLoad(3), optionFindNextValue(3), optionFindValue(3), optionFree(3), optionGetValue(3), optionLoadLine(3), optionMemberList(3), optionNextValue(3), optionPrintVersion(3), optionPrintVersionAndReturn(3), optionProcess(3), optionRestore(3), optionSaveFile(3), optionSaveState(3), optionUnloadNested(3), optionVersion(3), strequate(3), streqvcmp(3), streqvmap(3), strneqvcmp(3), strtransform(3), diff --git a/autoopts/optionPrintVersion.3 b/autoopts/optionPrintVersion.3 new file mode 100644 index 0000000..99dffba --- /dev/null +++ b/autoopts/optionPrintVersion.3 @@ -0,0 +1,29 @@ +.TH optionPrintVersion 3 2018-08-26 "" "Programmer's Manual" +.\" DO NOT EDIT THIS FILE (optionPrintVersion.3) +.\" +.\" It has been AutoGen-ed +.\" From the definitions ./funcs.def +.\" and the template file agman3.tpl +.SH NAME +optionPrintVersion - Print the program version +.sp 1 +.SH SYNOPSIS + +#include <\fIyour-opts.h\fP> +.br +cc [...] -o outfile infile.c -l\fBopts\fP [...] +.sp 1 +void \fBoptionPrintVersion\fP(tOptions * \fIopts\fP, tOptDesc * \fIod\fP); +.sp 1 +.SH DESCRIPTION +This routine will print the version to stdout. +.TP +.IR opts +program options descriptor +.TP +.IR od +the descriptor for this arg +.SH SEE ALSO +The \fIinfo\fP documentation for the -l\fIopts\fP library. +.br +ao_string_tokenize(3), configFileLoad(3), optionFileLoad(3), optionFindNextValue(3), optionFindValue(3), optionFree(3), optionGetValue(3), optionLoadLine(3), optionMemberList(3), optionNextValue(3), optionOnlyUsage(3), optionPrintVersionAndReturn(3), optionProcess(3), optionRestore(3), optionSaveFile(3), optionSaveState(3), optionUnloadNested(3), optionVersion(3), strequate(3), streqvcmp(3), streqvmap(3), strneqvcmp(3), strtransform(3), diff --git a/autoopts/optionPrintVersionAndReturn.3 b/autoopts/optionPrintVersionAndReturn.3 new file mode 100644 index 0000000..d901af5 --- /dev/null +++ b/autoopts/optionPrintVersionAndReturn.3 @@ -0,0 +1,32 @@ +.TH optionPrintVersionAndReturn 3 2018-08-26 "" "Programmer's Manual" +.\" DO NOT EDIT THIS FILE (optionPrintVersionAndReturn.3) +.\" +.\" It has been AutoGen-ed +.\" From the definitions ./funcs.def +.\" and the template file agman3.tpl +.SH NAME +optionPrintVersionAndReturn - Print the program version +.sp 1 +.SH SYNOPSIS + +#include <\fIyour-opts.h\fP> +.br +cc [...] -o outfile infile.c -l\fBopts\fP [...] +.sp 1 +void \fBoptionPrintVersionAndReturn\fP(tOptions * \fIopts\fP, tOptDesc * \fIod\fP); +.sp 1 +.SH DESCRIPTION +This routine will print the version to stdout and return +instead of exiting. Please see the source for the +\fBprint_ver\fP funtion for details on selecting how +verbose to be after this function returns. +.TP +.IR opts +program options descriptor +.TP +.IR od +the descriptor for this arg +.SH SEE ALSO +The \fIinfo\fP documentation for the -l\fIopts\fP library. +.br +ao_string_tokenize(3), configFileLoad(3), optionFileLoad(3), optionFindNextValue(3), optionFindValue(3), optionFree(3), optionGetValue(3), optionLoadLine(3), optionMemberList(3), optionNextValue(3), optionOnlyUsage(3), optionPrintVersion(3), optionProcess(3), optionRestore(3), optionSaveFile(3), optionSaveState(3), optionUnloadNested(3), optionVersion(3), strequate(3), streqvcmp(3), streqvmap(3), strneqvcmp(3), strtransform(3), diff --git a/autoopts/optionProcess.3 b/autoopts/optionProcess.3 new file mode 100644 index 0000000..3bd7495 --- /dev/null +++ b/autoopts/optionProcess.3 @@ -0,0 +1,55 @@ +.TH optionProcess 3 2018-08-26 "" "Programmer's Manual" +.\" DO NOT EDIT THIS FILE (optionProcess.3) +.\" +.\" It has been AutoGen-ed +.\" From the definitions ./funcs.def +.\" and the template file agman3.tpl +.SH NAME +optionProcess - this is the main option processing routine +.sp 1 +.SH SYNOPSIS + +#include <\fIyour-opts.h\fP> +.br +cc [...] -o outfile infile.c -l\fBopts\fP [...] +.sp 1 +int \fBoptionProcess\fP(tOptions * \fIopts\fP, int \fIa_ct\fP, char ** \fIa_v\fP); +.sp 1 +.SH DESCRIPTION +This is the main entry point for processing options. It is intended +that this procedure be called once at the beginning of the execution of +a program. Depending on options selected earlier, it is sometimes +necessary to stop and restart option processing, or to select completely +different sets of options. This can be done easily, but you generally +do not want to do this. + +The number of arguments processed always includes the program name. +If one of the arguments is "--", then it is counted and the processing +stops. If an error was encountered and errors are to be tolerated, then +the returned value is the index of the argument causing the error. +A hyphen by itself ("-") will also cause processing to stop and will +\fInot\fP be counted among the processed arguments. A hyphen by itself +is treated as an operand. Encountering an operand stops option +processing. +.TP +.IR opts +program options descriptor +.TP +.IR a_ct +program arg count +.TP +.IR a_v +program arg vector +.sp 1 +.SH RETURN VALUE +the count of the arguments processed +.sp 1 +.SH ERRORS +Errors will cause diagnostics to be printed. \fBexit(3)\fP may +or may not be called. It depends upon whether or not the options +were generated with the "allow-errors" attribute, or if the +ERRSKIP_OPTERR or ERRSTOP_OPTERR macros were invoked. +.SH SEE ALSO +The \fIinfo\fP documentation for the -l\fIopts\fP library. +.br +ao_string_tokenize(3), configFileLoad(3), optionFileLoad(3), optionFindNextValue(3), optionFindValue(3), optionFree(3), optionGetValue(3), optionLoadLine(3), optionMemberList(3), optionNextValue(3), optionOnlyUsage(3), optionPrintVersion(3), optionPrintVersionAndReturn(3), optionRestore(3), optionSaveFile(3), optionSaveState(3), optionUnloadNested(3), optionVersion(3), strequate(3), streqvcmp(3), streqvmap(3), strneqvcmp(3), strtransform(3), diff --git a/autoopts/optionRestore.3 b/autoopts/optionRestore.3 new file mode 100644 index 0000000..3167d0a --- /dev/null +++ b/autoopts/optionRestore.3 @@ -0,0 +1,35 @@ +.TH optionRestore 3 2018-08-26 "" "Programmer's Manual" +.\" DO NOT EDIT THIS FILE (optionRestore.3) +.\" +.\" It has been AutoGen-ed +.\" From the definitions ./funcs.def +.\" and the template file agman3.tpl +.SH NAME +optionRestore - restore option state from memory copy +.sp 1 +.SH SYNOPSIS + +#include <\fIyour-opts.h\fP> +.br +cc [...] -o outfile infile.c -l\fBopts\fP [...] +.sp 1 +void \fBoptionRestore\fP(tOptions * \fIpOpts\fP); +.sp 1 +.SH DESCRIPTION +Copy back the option state from saved memory. +The allocated memory is left intact, so this routine can be +called repeatedly without having to call optionSaveState again. +If you are restoring a state that was saved before the first call +to optionProcess(3AO), then you may change the contents of the +argc/argv parameters to optionProcess. +.TP +.IR pOpts +program options descriptor +.sp 1 +.SH ERRORS +If you have not called \fBoptionSaveState\fP before, a diagnostic is +printed to \fBstderr\fP and exit is called. +.SH SEE ALSO +The \fIinfo\fP documentation for the -l\fIopts\fP library. +.br +ao_string_tokenize(3), configFileLoad(3), optionFileLoad(3), optionFindNextValue(3), optionFindValue(3), optionFree(3), optionGetValue(3), optionLoadLine(3), optionMemberList(3), optionNextValue(3), optionOnlyUsage(3), optionPrintVersion(3), optionPrintVersionAndReturn(3), optionProcess(3), optionSaveFile(3), optionSaveState(3), optionUnloadNested(3), optionVersion(3), strequate(3), streqvcmp(3), streqvmap(3), strneqvcmp(3), strtransform(3), diff --git a/autoopts/optionSaveFile.3 b/autoopts/optionSaveFile.3 new file mode 100644 index 0000000..32e0af5 --- /dev/null +++ b/autoopts/optionSaveFile.3 @@ -0,0 +1,44 @@ +.TH optionSaveFile 3 2018-08-26 "" "Programmer's Manual" +.\" DO NOT EDIT THIS FILE (optionSaveFile.3) +.\" +.\" It has been AutoGen-ed +.\" From the definitions ./funcs.def +.\" and the template file agman3.tpl +.SH NAME +optionSaveFile - saves the option state to a file +.sp 1 +.SH SYNOPSIS + +#include <\fIyour-opts.h\fP> +.br +cc [...] -o outfile infile.c -l\fBopts\fP [...] +.sp 1 +void \fBoptionSaveFile\fP(tOptions * \fIopts\fP); +.sp 1 +.SH DESCRIPTION +This routine will save the state of option processing to a file. The name +of that file can be specified with the argument to the \fB--save-opts\fP +option, or by appending the \fBrcfile\fP attribute to the last +\fBhomerc\fP attribute. If no \fBrcfile\fP attribute was specified, it +will default to \fB.\fIprogramname\fPrc\fP. If you wish to specify another +file, you should invoke the \fBSET_OPT_SAVE_OPTS(\fIfilename\fP)\fP macro. + +The recommend usage is as follows: +.nf + optionProcess(&progOptions, argc, argv); + if (i_want_a_non_standard_place_for_this) + SET_OPT_SAVE_OPTS("myfilename"); + optionSaveFile(&progOptions); +.fi +.TP +.IR opts +program options descriptor +.sp 1 +.SH ERRORS +If no \fBhomerc\fP file was specified, this routine will silently return +and do nothing. If the output file cannot be created or updated, a message +will be printed to \fBstderr\fP and the routine will return. +.SH SEE ALSO +The \fIinfo\fP documentation for the -l\fIopts\fP library. +.br +ao_string_tokenize(3), configFileLoad(3), optionFileLoad(3), optionFindNextValue(3), optionFindValue(3), optionFree(3), optionGetValue(3), optionLoadLine(3), optionMemberList(3), optionNextValue(3), optionOnlyUsage(3), optionPrintVersion(3), optionPrintVersionAndReturn(3), optionProcess(3), optionRestore(3), optionSaveState(3), optionUnloadNested(3), optionVersion(3), strequate(3), streqvcmp(3), streqvmap(3), strneqvcmp(3), strtransform(3), diff --git a/autoopts/optionSaveState.3 b/autoopts/optionSaveState.3 new file mode 100644 index 0000000..67ead60 --- /dev/null +++ b/autoopts/optionSaveState.3 @@ -0,0 +1,41 @@ +.TH optionSaveState 3 2018-08-26 "" "Programmer's Manual" +.\" DO NOT EDIT THIS FILE (optionSaveState.3) +.\" +.\" It has been AutoGen-ed +.\" From the definitions ./funcs.def +.\" and the template file agman3.tpl +.SH NAME +optionSaveState - saves the option state to memory +.sp 1 +.SH SYNOPSIS + +#include <\fIyour-opts.h\fP> +.br +cc [...] -o outfile infile.c -l\fBopts\fP [...] +.sp 1 +void \fBoptionSaveState\fP(tOptions * \fIpOpts\fP); +.sp 1 +.SH DESCRIPTION +This routine will allocate enough memory to save the current option +processing state. If this routine has been called before, that memory +will be reused. You may only save one copy of the option state. This +routine may be called before optionProcess(3AO). If you do call it +before the first call to optionProcess, then you may also change the +contents of argc/argv after you call optionRestore(3AO) + +In fact, more strongly put: it is safest to only use this function +before having processed any options. In particular, the saving and +restoring of stacked string arguments and hierarchical values is +disabled. The values are not saved. +.TP +.IR pOpts +program options descriptor +.sp 1 +.SH ERRORS +If it fails to allocate the memory, +it will print a message to stderr and exit. +Otherwise, it will always succeed. +.SH SEE ALSO +The \fIinfo\fP documentation for the -l\fIopts\fP library. +.br +ao_string_tokenize(3), configFileLoad(3), optionFileLoad(3), optionFindNextValue(3), optionFindValue(3), optionFree(3), optionGetValue(3), optionLoadLine(3), optionMemberList(3), optionNextValue(3), optionOnlyUsage(3), optionPrintVersion(3), optionPrintVersionAndReturn(3), optionProcess(3), optionRestore(3), optionSaveFile(3), optionUnloadNested(3), optionVersion(3), strequate(3), streqvcmp(3), streqvmap(3), strneqvcmp(3), strtransform(3), diff --git a/autoopts/optionUnloadNested.3 b/autoopts/optionUnloadNested.3 new file mode 100644 index 0000000..fc4dc2b --- /dev/null +++ b/autoopts/optionUnloadNested.3 @@ -0,0 +1,28 @@ +.TH optionUnloadNested 3 2018-08-26 "" "Programmer's Manual" +.\" DO NOT EDIT THIS FILE (optionUnloadNested.3) +.\" +.\" It has been AutoGen-ed +.\" From the definitions ./funcs.def +.\" and the template file agman3.tpl +.SH NAME +optionUnloadNested - Deallocate the memory for a nested value +.sp 1 +.SH SYNOPSIS + +#include <\fIyour-opts.h\fP> +.br +cc [...] -o outfile infile.c -l\fBopts\fP [...] +.sp 1 +void \fBoptionUnloadNested\fP(tOptionValue const * \fIpOptVal\fP); +.sp 1 +.SH DESCRIPTION +A nested value needs to be deallocated. The pointer passed in should +have been gotten from a call to \fBconfigFileLoad()\fP (See +@pxref{libopts-configFileLoad}). +.TP +.IR pOptVal +the hierarchical value +.SH SEE ALSO +The \fIinfo\fP documentation for the -l\fIopts\fP library. +.br +ao_string_tokenize(3), configFileLoad(3), optionFileLoad(3), optionFindNextValue(3), optionFindValue(3), optionFree(3), optionGetValue(3), optionLoadLine(3), optionMemberList(3), optionNextValue(3), optionOnlyUsage(3), optionPrintVersion(3), optionPrintVersionAndReturn(3), optionProcess(3), optionRestore(3), optionSaveFile(3), optionSaveState(3), optionVersion(3), strequate(3), streqvcmp(3), streqvmap(3), strneqvcmp(3), strtransform(3), diff --git a/autoopts/optionVersion.3 b/autoopts/optionVersion.3 new file mode 100644 index 0000000..3eaa195 --- /dev/null +++ b/autoopts/optionVersion.3 @@ -0,0 +1,27 @@ +.TH optionVersion 3 2018-08-26 "" "Programmer's Manual" +.\" DO NOT EDIT THIS FILE (optionVersion.3) +.\" +.\" It has been AutoGen-ed +.\" From the definitions ./funcs.def +.\" and the template file agman3.tpl +.SH NAME +optionVersion - return the compiled AutoOpts version number +.sp 1 +.SH SYNOPSIS + +#include <\fIyour-opts.h\fP> +.br +cc [...] -o outfile infile.c -l\fBopts\fP [...] +.sp 1 +char const * \fBoptionVersion\fP(void); +.sp 1 +.SH DESCRIPTION +Returns the full version string compiled into the library. +The returned string cannot be modified. +.sp 1 +.SH RETURN VALUE +the version string in constant memory +.SH SEE ALSO +The \fIinfo\fP documentation for the -l\fIopts\fP library. +.br +ao_string_tokenize(3), configFileLoad(3), optionFileLoad(3), optionFindNextValue(3), optionFindValue(3), optionFree(3), optionGetValue(3), optionLoadLine(3), optionMemberList(3), optionNextValue(3), optionOnlyUsage(3), optionPrintVersion(3), optionPrintVersionAndReturn(3), optionProcess(3), optionRestore(3), optionSaveFile(3), optionSaveState(3), optionUnloadNested(3), strequate(3), streqvcmp(3), streqvmap(3), strneqvcmp(3), strtransform(3), diff --git a/autoopts/parse-duration.c b/autoopts/parse-duration.c new file mode 100644 index 0000000..0f4a056 --- /dev/null +++ b/autoopts/parse-duration.c @@ -0,0 +1,604 @@ +/* Parse a time duration and return a seconds count + Copyright (C) 2008-2018 Free Software Foundation, Inc. + Written by Bruce Korb , 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 2.1 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 "parse-duration.h" + +#include +#include +#include +#include +#include +#include + +#include "intprops.h" + +#ifndef NUL +#define NUL '\0' +#endif + +#define cch_t char const + +typedef enum { + NOTHING_IS_DONE, + YEAR_IS_DONE, + MONTH_IS_DONE, + WEEK_IS_DONE, + DAY_IS_DONE, + HOUR_IS_DONE, + MINUTE_IS_DONE, + SECOND_IS_DONE +} whats_done_t; + +#define SEC_PER_MIN 60 +#define SEC_PER_HR (SEC_PER_MIN * 60) +#define SEC_PER_DAY (SEC_PER_HR * 24) +#define SEC_PER_WEEK (SEC_PER_DAY * 7) +#define SEC_PER_MONTH (SEC_PER_DAY * 30) +#define SEC_PER_YEAR (SEC_PER_DAY * 365) + +#undef MAX_DURATION +#define MAX_DURATION TYPE_MAXIMUM(time_t) + +/* Wrapper around strtoul that does not require a cast. */ +static unsigned long +str_const_to_ul (cch_t * str, cch_t ** ppz, int base) +{ + return strtoul (str, (char **)ppz, base); +} + +/* Wrapper around strtol that does not require a cast. */ +static long +str_const_to_l (cch_t * str, cch_t ** ppz, int base) +{ + return strtol (str, (char **)ppz, base); +} + +/* Returns BASE + VAL * SCALE, interpreting BASE = BAD_TIME + with errno set as an error situation, and returning BAD_TIME + with errno set in an error situation. */ +static time_t +scale_n_add (time_t base, time_t val, int scale) +{ + if (base == BAD_TIME) + { + if (errno == 0) + errno = EINVAL; + return BAD_TIME; + } + + if (val > MAX_DURATION / scale) + { + errno = ERANGE; + return BAD_TIME; + } + + val *= scale; + if (base > MAX_DURATION - val) + { + errno = ERANGE; + return BAD_TIME; + } + + return base + val; +} + +/* After a number HH has been parsed, parse subsequent :MM or :MM:SS. */ +static time_t +parse_hr_min_sec (time_t start, cch_t * pz) +{ + int lpct = 0; + + errno = 0; + + /* For as long as our scanner pointer points to a colon *AND* + we've not looped before, then keep looping. (two iterations max) */ + while ((*pz == ':') && (lpct++ <= 1)) + { + unsigned long v = str_const_to_ul (pz+1, &pz, 10); + + if (errno != 0) + return BAD_TIME; + + start = scale_n_add (v, start, 60); + + if (errno != 0) + return BAD_TIME; + } + + /* allow for trailing spaces */ + while (isspace ((unsigned char)*pz)) + pz++; + if (*pz != NUL) + { + errno = EINVAL; + return BAD_TIME; + } + + return start; +} + +/* Parses a value and returns BASE + value * SCALE, interpreting + BASE = BAD_TIME with errno set as an error situation, and returning + BAD_TIME with errno set in an error situation. */ +static time_t +parse_scaled_value (time_t base, cch_t ** ppz, cch_t * endp, int scale) +{ + cch_t * pz = *ppz; + time_t val; + + if (base == BAD_TIME) + return base; + + errno = 0; + val = str_const_to_ul (pz, &pz, 10); + if (errno != 0) + return BAD_TIME; + while (isspace ((unsigned char)*pz)) + pz++; + if (pz != endp) + { + errno = EINVAL; + return BAD_TIME; + } + + *ppz = pz; + return scale_n_add (base, val, scale); +} + +/* Parses the syntax YEAR-MONTH-DAY. + PS points into the string, after "YEAR", before "-MONTH-DAY". */ +static time_t +parse_year_month_day (cch_t * pz, cch_t * ps) +{ + time_t res = 0; + + res = parse_scaled_value (0, &pz, ps, SEC_PER_YEAR); + + pz++; /* over the first '-' */ + ps = strchr (pz, '-'); + if (ps == NULL) + { + errno = EINVAL; + return BAD_TIME; + } + res = parse_scaled_value (res, &pz, ps, SEC_PER_MONTH); + + pz++; /* over the second '-' */ + ps = pz + strlen (pz); + return parse_scaled_value (res, &pz, ps, SEC_PER_DAY); +} + +/* Parses the syntax YYYYMMDD. */ +static time_t +parse_yearmonthday (cch_t * in_pz) +{ + time_t res = 0; + char buf[8]; + cch_t * pz; + + if (strlen (in_pz) != 8) + { + errno = EINVAL; + return BAD_TIME; + } + + memcpy (buf, in_pz, 4); + buf[4] = NUL; + pz = buf; + res = parse_scaled_value (0, &pz, buf + 4, SEC_PER_YEAR); + + memcpy (buf, in_pz + 4, 2); + buf[2] = NUL; + pz = buf; + res = parse_scaled_value (res, &pz, buf + 2, SEC_PER_MONTH); + + memcpy (buf, in_pz + 6, 2); + buf[2] = NUL; + pz = buf; + return parse_scaled_value (res, &pz, buf + 2, SEC_PER_DAY); +} + +/* Parses the syntax yy Y mm M ww W dd D. */ +static time_t +parse_YMWD (cch_t * pz) +{ + time_t res = 0; + cch_t * ps = strchr (pz, 'Y'); + if (ps != NULL) + { + res = parse_scaled_value (0, &pz, ps, SEC_PER_YEAR); + pz++; + } + + ps = strchr (pz, 'M'); + if (ps != NULL) + { + res = parse_scaled_value (res, &pz, ps, SEC_PER_MONTH); + pz++; + } + + ps = strchr (pz, 'W'); + if (ps != NULL) + { + res = parse_scaled_value (res, &pz, ps, SEC_PER_WEEK); + pz++; + } + + ps = strchr (pz, 'D'); + if (ps != NULL) + { + res = parse_scaled_value (res, &pz, ps, SEC_PER_DAY); + pz++; + } + + while (isspace ((unsigned char)*pz)) + pz++; + if (*pz != NUL) + { + errno = EINVAL; + return BAD_TIME; + } + + return res; +} + +/* Parses the syntax HH:MM:SS. + PS points into the string, after "HH", before ":MM:SS". */ +static time_t +parse_hour_minute_second (cch_t * pz, cch_t * ps) +{ + time_t res = 0; + + res = parse_scaled_value (0, &pz, ps, SEC_PER_HR); + + pz++; + ps = strchr (pz, ':'); + if (ps == NULL) + { + errno = EINVAL; + return BAD_TIME; + } + + res = parse_scaled_value (res, &pz, ps, SEC_PER_MIN); + + pz++; + ps = pz + strlen (pz); + return parse_scaled_value (res, &pz, ps, 1); +} + +/* Parses the syntax HHMMSS. */ +static time_t +parse_hourminutesecond (cch_t * in_pz) +{ + time_t res = 0; + char buf[4]; + cch_t * pz; + + if (strlen (in_pz) != 6) + { + errno = EINVAL; + return BAD_TIME; + } + + memcpy (buf, in_pz, 2); + buf[2] = NUL; + pz = buf; + res = parse_scaled_value (0, &pz, buf + 2, SEC_PER_HR); + + memcpy (buf, in_pz + 2, 2); + buf[2] = NUL; + pz = buf; + res = parse_scaled_value (res, &pz, buf + 2, SEC_PER_MIN); + + memcpy (buf, in_pz + 4, 2); + buf[2] = NUL; + pz = buf; + return parse_scaled_value (res, &pz, buf + 2, 1); +} + +/* Parses the syntax hh H mm M ss S. */ +static time_t +parse_HMS (cch_t * pz) +{ + time_t res = 0; + cch_t * ps = strchr (pz, 'H'); + if (ps != NULL) + { + res = parse_scaled_value (0, &pz, ps, SEC_PER_HR); + pz++; + } + + ps = strchr (pz, 'M'); + if (ps != NULL) + { + res = parse_scaled_value (res, &pz, ps, SEC_PER_MIN); + pz++; + } + + ps = strchr (pz, 'S'); + if (ps != NULL) + { + res = parse_scaled_value (res, &pz, ps, 1); + pz++; + } + + while (isspace ((unsigned char)*pz)) + pz++; + if (*pz != NUL) + { + errno = EINVAL; + return BAD_TIME; + } + + return res; +} + +/* Parses a time (hours, minutes, seconds) specification in either syntax. */ +static time_t +parse_time (cch_t * pz) +{ + cch_t * ps; + time_t res = 0; + + /* + * Scan for a hyphen + */ + ps = strchr (pz, ':'); + if (ps != NULL) + { + res = parse_hour_minute_second (pz, ps); + } + + /* + * Try for a 'H', 'M' or 'S' suffix + */ + else if (ps = strpbrk (pz, "HMS"), + ps == NULL) + { + /* Its a YYYYMMDD format: */ + res = parse_hourminutesecond (pz); + } + + else + res = parse_HMS (pz); + + return res; +} + +/* Returns a substring of the given string, with spaces at the beginning and at + the end destructively removed, per SNOBOL. */ +static char * +trim (char * pz) +{ + /* trim leading white space */ + while (isspace ((unsigned char)*pz)) + pz++; + + /* trim trailing white space */ + { + char * pe = pz + strlen (pz); + while ((pe > pz) && isspace ((unsigned char)pe[-1])) + pe--; + *pe = NUL; + } + + return pz; +} + +/* + * Parse the year/months/days of a time period + */ +static time_t +parse_period (cch_t * in_pz) +{ + char * pT; + char * ps; + char * pz = strdup (in_pz); + void * fptr = pz; + time_t res = 0; + + if (pz == NULL) + { + errno = ENOMEM; + return BAD_TIME; + } + + pT = strchr (pz, 'T'); + if (pT != NULL) + { + *(pT++) = NUL; + pz = trim (pz); + pT = trim (pT); + } + + /* + * Scan for a hyphen + */ + ps = strchr (pz, '-'); + if (ps != NULL) + { + res = parse_year_month_day (pz, ps); + } + + /* + * Try for a 'Y', 'M' or 'D' suffix + */ + else if (ps = strpbrk (pz, "YMWD"), + ps == NULL) + { + /* Its a YYYYMMDD format: */ + res = parse_yearmonthday (pz); + } + + else + res = parse_YMWD (pz); + + if ((errno == 0) && (pT != NULL)) + { + time_t val = parse_time (pT); + res = scale_n_add (res, val, 1); + } + + free (fptr); + return res; +} + +static time_t +parse_non_iso8601 (cch_t * pz) +{ + whats_done_t whatd_we_do = NOTHING_IS_DONE; + + time_t res = 0; + + do { + time_t val; + + errno = 0; + val = str_const_to_l (pz, &pz, 10); + if (errno != 0) + goto bad_time; + + /* IF we find a colon, then we're going to have a seconds value. + We will not loop here any more. We cannot already have parsed + a minute value and if we've parsed an hour value, then the result + value has to be less than an hour. */ + if (*pz == ':') + { + if (whatd_we_do >= MINUTE_IS_DONE) + break; + + val = parse_hr_min_sec (val, pz); + + if ((whatd_we_do == HOUR_IS_DONE) && (val >= SEC_PER_HR)) + break; + + return scale_n_add (res, val, 1); + } + + { + unsigned int mult; + + /* Skip over white space following the number we just parsed. */ + while (isspace ((unsigned char)*pz)) + pz++; + + switch (*pz) + { + default: goto bad_time; + case NUL: + return scale_n_add (res, val, 1); + + case 'y': case 'Y': + if (whatd_we_do >= YEAR_IS_DONE) + goto bad_time; + mult = SEC_PER_YEAR; + whatd_we_do = YEAR_IS_DONE; + break; + + case 'M': + if (whatd_we_do >= MONTH_IS_DONE) + goto bad_time; + mult = SEC_PER_MONTH; + whatd_we_do = MONTH_IS_DONE; + break; + + case 'W': + if (whatd_we_do >= WEEK_IS_DONE) + goto bad_time; + mult = SEC_PER_WEEK; + whatd_we_do = WEEK_IS_DONE; + break; + + case 'd': case 'D': + if (whatd_we_do >= DAY_IS_DONE) + goto bad_time; + mult = SEC_PER_DAY; + whatd_we_do = DAY_IS_DONE; + break; + + case 'h': + if (whatd_we_do >= HOUR_IS_DONE) + goto bad_time; + mult = SEC_PER_HR; + whatd_we_do = HOUR_IS_DONE; + break; + + case 'm': + if (whatd_we_do >= MINUTE_IS_DONE) + goto bad_time; + mult = SEC_PER_MIN; + whatd_we_do = MINUTE_IS_DONE; + break; + + case 's': + mult = 1; + whatd_we_do = SECOND_IS_DONE; + break; + } + + res = scale_n_add (res, val, mult); + + pz++; + while (isspace ((unsigned char)*pz)) + pz++; + if (*pz == NUL) + return res; + + if (! isdigit ((unsigned char)*pz)) + break; + } + + } while (whatd_we_do < SECOND_IS_DONE); + + bad_time: + errno = EINVAL; + return BAD_TIME; +} + +time_t +parse_duration (char const * pz) +{ + while (isspace ((unsigned char)*pz)) + pz++; + + switch (*pz) + { + case 'P': + return parse_period (pz + 1); + + case 'T': + return parse_time (pz + 1); + + default: + if (isdigit ((unsigned char)*pz)) + return parse_non_iso8601 (pz); + + errno = EINVAL; + return BAD_TIME; + } +} + +/* + * Local Variables: + * mode: C + * c-file-style: "gnu" + * indent-tabs-mode: nil + * End: + * end of parse-duration.c */ diff --git a/autoopts/parse-duration.h b/autoopts/parse-duration.h new file mode 100644 index 0000000..9a7bcd5 --- /dev/null +++ b/autoopts/parse-duration.h @@ -0,0 +1,90 @@ +/* Parse a time duration and return a seconds count + Copyright (C) 2008-2018 Free Software Foundation, Inc. + Written by Bruce Korb , 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 2.1 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 . */ + +/* + + Readers and users of this function are referred to the ISO-8601 + specification, with particular attention to "Durations". + + At the time of writing, this worked: + + https://en.wikipedia.org/wiki/ISO_8601#Durations + + The string must start with a 'P', 'T' or a digit. + + ==== if it is a digit + + the string may contain: NNN Y NNN M NNN W NNN d NNN h NNN m NNN s + This represents NNN years, NNN months, NNN weeks, NNN days, NNN hours, + NNN minutes and NNN seconds. + The embedded white space is optional. + These terms must appear in this order. + Case is significant: 'M' is months and 'm' is minutes. + The final "s" is optional. + All of the terms ("NNN" plus designator) are optional. + Minutes and seconds may optionally be represented as NNN:NNN. + Also, hours, minute and seconds may be represented as NNN:NNN:NNN. + There is no limitation on the value of any of the terms, except + that the final result must fit in a time_t value. + + ==== if it is a 'P' or 'T', please see ISO-8601 for a rigorous definition. + + The 'P' term may be followed by any of three formats: + yyyymmdd + yy-mm-dd + yy Y mm M ww W dd D + + or it may be empty and followed by a 'T'. The "yyyymmdd" must be eight + digits long. + + NOTE! Months are always 30 days and years are always 365 days long. + 5 years is always 1825 days, not 1826 or 1827 depending on leap year + considerations. 3 months is always 90 days. There is no consideration + for how many days are in the current, next or previous months. + + For the final format: + * Embedded white space is allowed, but it is optional. + * All of the terms are optional. Any or all-but-one may be omitted. + * The meanings are yy years, mm months, ww weeks and dd days. + * The terms must appear in this order. + + ==== The 'T' term may be followed by any of these formats: + + hhmmss + hh:mm:ss + hh H mm M ss S + + For the final format: + * Embedded white space is allowed, but it is optional. + * All of the terms are optional. Any or all-but-one may be omitted. + * The terms must appear in this order. + + */ +#ifndef GNULIB_PARSE_DURATION_H +#define GNULIB_PARSE_DURATION_H + +#include + +/* Return value when a valid duration cannot be parsed. */ +#define BAD_TIME ((time_t)~0) + +/* Parses the given string. If it has the syntax of a valid duration, + this duration is returned. Otherwise, the return value is BAD_TIME, + and errno is set to either EINVAL (bad syntax) or ERANGE (out of range). */ +extern time_t parse_duration (char const * in_pz); + +#endif /* GNULIB_PARSE_DURATION_H */ diff --git a/autoopts/pgusage.c b/autoopts/pgusage.c new file mode 100644 index 0000000..f895b3b --- /dev/null +++ b/autoopts/pgusage.c @@ -0,0 +1,187 @@ + +/** + * \file pgusage.c + * + * Automated Options Paged Usage module. + * + * @addtogroup autoopts + * @{ + */ +/* + * This routine will run run-on options through a pager so the + * user may examine, print or edit them at their leisure. + * + * This file is part of AutoOpts, a companion to AutoGen. + * AutoOpts is free software. + * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoOpts is available under any one of two licenses. The license + * in use must be one of these two and the choice is under the control + * of the user of the license. + * + * The GNU Lesser General Public License, version 3 or later + * See the files "COPYING.lgplv3" and "COPYING.gplv3" + * + * The Modified Berkeley Software Distribution License + * See the file "COPYING.mbsd" + * + * These files have the following sha256 sums: + * + * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 + * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 + * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + */ + +#if defined(HAVE_WORKING_FORK) +static inline FILE * +open_tmp_usage(char ** buf) +{ + char * bf; + size_t bfsz; + + { + unsigned int my_pid = (unsigned int)getpid(); + char const * tmpdir = getenv(TMPDIR); + if (tmpdir == NULL) + tmpdir = tmp_dir; + bfsz = TMP_FILE_FMT_LEN + strlen(tmpdir) + 10; + bf = AGALOC(bfsz, "tmp fil"); + snprintf(bf, bfsz, TMP_FILE_FMT, tmpdir, my_pid); + } + + { + static mode_t const cmask = S_IRWXO | S_IRWXG; + mode_t svmsk = umask(cmask); + int fd = mkstemp(bf); + (void)umask(svmsk); + + if (fd < 0) { + AGFREE(bf); + return NULL; + } + *buf = bf; + return fdopen(fd, "w"); + } +} + +static inline char * +mk_pager_cmd(char const * fname) +{ + /* + * Page the file and remove it when done. For shell script processing, + * we must redirect the output to the current stderr, otherwise stdout. + */ + fclose(option_usage_fp); + option_usage_fp = NULL; + + { + char const * pager = (char const *)getenv(PAGER_NAME); + size_t bfsz; + char * res; + + /* + * Use the "more(1)" program if "PAGER" has not been defined + */ + if (pager == NULL) + pager = MORE_STR; + + bfsz = 2 * strlen(fname) + strlen(pager) + PAGE_USAGE_FMT_LEN; + res = AGALOC(bfsz, "more cmd"); + snprintf(res, bfsz, PAGE_USAGE_FMT, pager, fname); + AGFREE(fname); + return res; + } +} +#endif + +/*=export_func optionPagedUsage + * private: + * + * what: emit help text and pass through a pager program. + * arg: + tOptions * + opts + program options descriptor + + * arg: + tOptDesc * + od + the descriptor for this arg + + * + * doc: + * Run the usage output through a pager. + * This is very handy if it is very long. + * This is disabled on platforms without a working fork() function. +=*/ +void +optionPagedUsage(tOptions * opts, tOptDesc * od) +{ +#if ! defined(HAVE_WORKING_FORK) + if ((od->fOptState & OPTST_RESET) != 0) + return; + + (*opts->pUsageProc)(opts, EXIT_SUCCESS); +#else + static bool sv_print_exit = false; + static char * fil_name = NULL; + + /* + * IF we are being called after the usage proc is done + * (and thus has called "exit(2)") + * THEN invoke the pager to page through the usage file we created. + */ + switch (pagerState) { + case PAGER_STATE_INITIAL: + { + if ((od->fOptState & OPTST_RESET) != 0) + return; + option_usage_fp = open_tmp_usage(&fil_name); + if (option_usage_fp == NULL) + (*opts->pUsageProc)(opts, EXIT_SUCCESS); + + pagerState = PAGER_STATE_READY; + sv_print_exit = print_exit; + + /* + * Set up so this routine gets called during the exit logic + */ + atexit((void(*)(void))optionPagedUsage); + + /* + * The usage procedure will now put the usage information into + * the temporary file we created above. Keep any shell commands + * out of the result. + */ + print_exit = false; + (*opts->pUsageProc)(opts, EXIT_SUCCESS); + + /* NOTREACHED */ + _exit(EXIT_FAILURE); + } + + case PAGER_STATE_READY: + fil_name = mk_pager_cmd(fil_name); + + if (sv_print_exit) { + fputs("\nexit 0\n", stdout); + fclose(stdout); + dup2(STDERR_FILENO, STDOUT_FILENO); + + } else { + fclose(stderr); + dup2(STDOUT_FILENO, STDERR_FILENO); + } + + ignore_val( system( fil_name)); + AGFREE(fil_name); + + case PAGER_STATE_CHILD: + /* + * This is a child process used in creating shell script usage. + */ + break; + } +#endif +} + +/** @} + * + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of autoopts/pgusage.c */ diff --git a/autoopts/po/usage-txt.pot b/autoopts/po/usage-txt.pot new file mode 100644 index 0000000..009f9c7 --- /dev/null +++ b/autoopts/po/usage-txt.pot @@ -0,0 +1,353 @@ +# Automated Option parsing usage text. +# Copyright (C) 1999-2018 by Bruce Korb - all rights reserved +# This file is distributed under the same licenses as the AutoOpts package. +# Bruce Korb +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: autogen \n" +"Report-Msgid-Bugs-To: autogen-users@lists.sourceforge.net\n" +"POT-Creation-Date: 2018-08-26 10:44-0700\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../autoopts.c:67 ../autoopts.c:89 +msgid "allocation of %d bytes failed\n" + +#: ../init.c:48 +msgid "AutoOpts function called without option descriptor\n" + +#: ../init.c:81 +msgid "\tThis exceeds the compiled library version: " + +#: ../init.c:79 +msgid "Automated Options Processing Error!\n" + "\t%s called AutoOpts function with structure version %d:%d:%d.\n" + +#: ../autoopts.c:78 +msgid "realloc of %d bytes at 0x%p failed\n" + +#: ../init.c:83 +msgid "\tThis is less than the minimum library version: " + +#: ../version.c:121 +msgid "Automated Options version %s\n" + "\tCopyright (C) 1999-2017 by Bruce Korb - all rights reserved\n" + +#: ../makeshell.c:49 +msgid "(AutoOpts bug): %s.\n" + +#: ../reset.c:90 +msgid "optionResetOpt() called, but reset-option not configured" + +#: ../usage.c:241 +msgid "could not locate the 'help' option" + +#: ../autoopts.c:330 +msgid "optionProcess() was called with invalid data" + +#: ../usage.c:697 +msgid "invalid argument type specified" + +#: ../find.c:568 +msgid "defaulted to option with optional arg" + +#: ../alias.c:76 +msgid "aliasing option is out of range." + +#: ../enum.c:210 +msgid "%s error: the keyword '%s' is ambiguous for %s\n" + +#: ../find.c:78 +msgid " The following options match:\n" + +#: ../find.c:263 +msgid "%s: ambiguous option name: %s (matches %d options)\n" + +#: ../check.c:161 +msgid "%s: Command line arguments required\n" + +#: ../alias.c:43 +msgid "%d %s%s options allowed\n" + +#: ../makeshell.c:56 +msgid "%s error %d (%s) calling %s for '%s'\n" + +#: ../makeshell.c:268 +msgid "interprocess pipe" + +#: ../version.c:171 +msgid "error: version option argument '%c' invalid. Use:\n" + "\t'v' - version only\n" + "\t'c' - version and copyright\n" + "\t'n' - version and full copyright notice\n" + +#: ../check.c:58 +msgid "%s error: the '%s' and '%s' options conflict\n" + +#: ../find.c:187 ../find.c:400 +msgid "%s: The '%s' option has been disabled." + +#: ../alias.c:38 +msgid "-equivalence" + +#: ../usage.c:1203 ../usage.c:1217 +msgid "=T/F" + +#: ../usage.c:1199 ../usage.c:1217 +msgid "=KWd" + +#: ../usage.c:1198 ../usage.c:1217 +msgid "=num" + +#: ../usage.c:1196 ../usage.c:1217 +msgid "=str" + +#: ../find.c:439 ../reset.c:110 +msgid "%s: illegal option -- %c\n" + +#: ../find.c:241 ../find.c:740 ../reset.c:118 +msgid "%s: illegal option -- %s\n" + +#: ../find.c:305 +msgid "%s: unknown vendor extension option -- %s\n" + +#: ../enum.c:135 ../enum.c:145 +msgid " or an integer from %d through %d\n" + +#: ../usage.c:696 ../usage.c:1030 +msgid "%s error: invalid option descriptor for %s\n" + +#: ../find.c:355 +msgid "%s: invalid option name: %s\n" + +#: ../find.c:497 +msgid "%s: The '%s' option requires an argument.\n" + +#: ../autoopts.c:150 +msgid "(AutoOpts bug): Equivalenced option '%s' was equivalenced to both\n" + "\t'%s' and '%s'." + +#: ../check.c:94 +msgid "%s error: The %s option is required\n" + +#: ../find.c:602 +msgid "%s: The '%s' option cannot have an argument.\n" + +#: ../check.c:151 +msgid "%s: Command line arguments are not allowed.\n" + +#: ../save.c:568 +msgid "error %d (%s) creating %s\n" + +#: ../enum.c:210 +msgid "%s error: '%s' does not match any %s keywords.\n" + +#: ../reset.c:93 +msgid "%s error: The '%s' option requires an argument.\n" + +#: ../save.c:122 ../save.c:175 +msgid "error %d (%s) stat-ing %s\n" + +#: ../restore.c:143 +msgid "%s error: no saved option state\n" + +#: ../autoopts.c:225 +msgid "'%s' is not a command line option.\n" + +#: ../time.c:113 +msgid "%s error: '%s' is not a recognizable date/time.\n" + +#: ../time.c:50 +msgid "%s error: '%s' is not a recognizable time duration.\n" + +#: ../check.c:92 +msgid "%s error: The %s option must appear %d times.\n" + +#: ../numeric.c:165 +msgid "%s error: '%s' is not a recognizable number.\n" + +#: ../enum.c:176 +msgid "%s error: %s exceeds %s keyword count\n" + +#: ../usage.c:279 +msgid "Try '%s %s' for more information.\n" + +#: ../alias.c:45 +msgid "one %s%s option allowed\n" + +#: ../makeshell.c:170 ../makeshell.c:905 ../usage.c:223 ../usage.c:364 ../usage.c:574 ../version.c:178 +msgid "standard output" + +#: ../usage.c:223 ../usage.c:364 ../usage.c:574 ../version.c:178 +msgid "standard error" + +#: ../makeshell.c:170 ../makeshell.c:905 ../usage.c:222 ../usage.c:363 ../usage.c:573 ../version.c:177 +msgid "write" + +#: ../numeric.c:60 +msgid "%s error: %s option value %ld is out of range.\n" + +#: ../check.c:44 +msgid "%s error: %s option requires the %s option\n" + +#: ../save.c:121 ../save.c:174 ../save.c:193 ../save.c:567 +msgid "%s warning: cannot save options - %s not regular file\n" + +#: ../usage.c:822 +msgid "\t\t\t\t- an alternate for '%s'\n" + +#: ../usage.c:1097 +msgid "Version, usage and configuration options:" + +#: ../usage.c:873 +msgid "\t\t\t\t- default option for unnamed options\n" + +#: ../usage.c:786 +msgid "\t\t\t\t- disabled as '--%s'\n" + +#: ../usage.c:1066 +msgid " --- %-14s %s\n" + +#: ../usage.c:1064 +msgid "This option has been disabled" + +#: ../usage.c:813 +msgid "\t\t\t\t- enabled by default\n" + +#: ../alias.c:40 +msgid "%s error: only " + +#: ../usage.c:1143 +msgid " - examining environment variables named %s_*\n" + +#: ../file.c:168 +msgid "\t\t\t\t- file must not pre-exist\n" + +#: ../file.c:172 +msgid "\t\t\t\t- file must pre-exist\n" + +#: ../usage.c:329 +msgid "Options are specified by doubled hyphens and their name or by a single\n" + "hyphen and the flag character.\n" + +#: ../makeshell.c:882 +msgid "\n" + "= = = = = = = =\n\n" + "This incarnation of genshell will produce\n" + "a shell script to parse the options for %s:\n\n" + +#: ../enum.c:142 +msgid " or an integer mask with any of the lower %d bits set\n" + +#: ../usage.c:846 +msgid "\t\t\t\t- is a set membership option\n" + +#: ../usage.c:867 +msgid "\t\t\t\t- must appear between %d and %d times\n" + +#: ../usage.c:331 +msgid "Options are specified by single or double hyphens and their name.\n" + +#: ../usage.c:853 +msgid "\t\t\t\t- may appear multiple times\n" + +#: ../usage.c:840 +msgid "\t\t\t\t- may not be preset\n" + +#: ../usage.c:1258 +msgid " Arg Option-Name Description\n" + +#: ../usage.c:1194 ../usage.c:1252 +msgid " Flg Arg Option-Name Description\n" + +#: ../usage.c:1253 ../usage.c:1259 +msgid " %3s %s" + +#: ../usage.c:336 +msgid "The '-#' option may omit the hash char\n" + +#: ../usage.c:332 +msgid "All arguments are named options.\n" + +#: ../usage.c:920 +msgid " - reading file %s" + +#: ../usage.c:358 ../version.c:100 ../version.c:129 +msgid "\n" + "Please send bug reports to: <%s>\n" + +#: ../usage.c:852 +msgid "\t\t\t\t- may NOT appear - preset only\n" + +#: ../usage.c:893 ../usage.c:1141 +msgid "\n" + "The following option preset mechanisms are supported:\n" + +#: ../usage.c:631 +msgid "prohibits these options:\n" + +#: ../usage.c:626 +msgid "prohibits the option '%s'\n" + +#: ../numeric.c:81 +msgid "%s%ld to %ld" + +#: ../numeric.c:79 +msgid "%sgreater than or equal to %ld" + +#: ../numeric.c:75 +msgid "%s%ld exactly" + +#: ../numeric.c:68 +msgid "%sit must lie in one of the ranges:\n" + +#: ../numeric.c:68 +msgid "%sit must be in the range:\n" + +#: ../numeric.c:88 +msgid ", or\n" + +#: ../numeric.c:66 +msgid "%sis scalable with a suffix: k/K/m/M/g/G/t/T\n" + +#: ../numeric.c:77 +msgid "%sless than or equal to %ld" + +#: ../usage.c:339 +msgid "Operands and options may be intermixed. They will be reordered.\n" + +#: ../usage.c:601 +msgid "requires the option '%s'\n" + +#: ../usage.c:604 +msgid "requires these options:\n" + +#: ../usage.c:1270 +msgid " Arg Option-Name Req? Description\n" + +#: ../usage.c:1264 +msgid " Flg Arg Option-Name Req? Description\n" + +#: ../enum.c:143 +msgid "or you may use a numeric representation. Preceding these with a '!'\n" + "will clear the bits, specifying 'none' will clear all bits, and 'all'\n" + "will set them all. Multiple entries may be passed as an option\n" + "argument list.\n" + +#: ../usage.c:859 +msgid "\t\t\t\t- may appear up to %d times\n" + +#: ../enum.c:52 +msgid "The valid \"%s\" option keywords are:\n" + +#: ../usage.c:1101 +msgid "The next option supports vendor supported extra options:" + +#: ../usage.c:722 +msgid "These additional options are:" \ No newline at end of file diff --git a/autoopts/project.h b/autoopts/project.h new file mode 100644 index 0000000..1f196ef --- /dev/null +++ b/autoopts/project.h @@ -0,0 +1,81 @@ + +/** + * \file project.h + * + * This file is part of AutoOpts, a companion to AutoGen. + * AutoOpts is free software. + * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoOpts is available under any one of two licenses. The license + * in use must be one of these two and the choice is under the control + * of the user of the license. + * + * The GNU Lesser General Public License, version 3 or later + * See the files "COPYING.lgplv3" and "COPYING.gplv3" + * + * The Modified Berkeley Software Distribution License + * See the file "COPYING.mbsd" + * + * These files have the following sha256 sums: + * + * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 + * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 + * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + */ + +#ifndef AUTOGEN_PROJECT_H +#define AUTOGEN_PROJECT_H + +#include "config.h" +#include "compat/compat.h" +#include "ag-char-map.h" + +/* + * Procedure success codes + * + * USAGE: define procedures to return "tSuccess". Test their results + * with the SUCCEEDED, FAILED and HADGLITCH macros. + * + * Microsoft sticks its nose into user space here, so for Windows' sake, + * make sure all of these are undefined. + */ +#undef SUCCESS +#undef FAILURE +#undef PROBLEM +#undef SUCCEEDED +#undef SUCCESSFUL +#undef FAILED +#undef HADGLITCH + +#define SUCCESS ((tSuccess) 0) +#define FAILURE ((tSuccess)-1) +#define PROBLEM ((tSuccess) 1) + +typedef int tSuccess; + +#define SUCCEEDED(p) ((p) == SUCCESS) +#define SUCCESSFUL(p) SUCCEEDED(p) +#define FAILED(p) ((p) < SUCCESS) +#define HADGLITCH(p) ((p) > SUCCESS) + +#ifndef STR +# define __STR(s) #s +# define STR(s) __STR(s) +#endif + +#ifdef DEFINING +# define VALUE(s) = s +# define MODE +#else +# define VALUE(s) +# define MODE extern +#endif + +#undef NUL +#define NUL '\0' + +#define MOD_LOCAL static +#define parse_duration option_parse_duration + +#endif /* AUTOGEN_PROJECT_H */ +/* end of project.h */ diff --git a/autoopts/proto.h b/autoopts/proto.h new file mode 100644 index 0000000..437e81e --- /dev/null +++ b/autoopts/proto.h @@ -0,0 +1,620 @@ +/* -*- buffer-read-only: t -*- vi: set ro: + * + * Prototypes for autoopts + * Generated Sun Aug 26 10:44:39 PDT 2018 + */ +#ifndef AUTOOPTS_PROTO_H_GUARD +#define AUTOOPTS_PROTO_H_GUARD 1 + + +/* + * Static declarations from alias.c + */ +static tSuccess +too_many_occurrences(tOptions * opts, tOptDesc * od); + +/* + * Static declarations from autoopts.c + */ +static void * +ao_malloc(size_t sz); + +static void * +ao_realloc(void *p, size_t sz); + +static char * +ao_strdup(char const *str); + +static tSuccess +handle_opt(tOptions * opts, tOptState * o_st); + +static tSuccess +next_opt(tOptions * opts, tOptState * o_st); + +static tSuccess +regular_opts(tOptions * opts); + +/* + * Static declarations from check.c + */ +static bool +has_conflict(tOptions * pOpts, tOptDesc * od); + +static bool +occurs_enough(tOptions * pOpts, tOptDesc * pOD); + +static bool +is_consistent(tOptions * pOpts); + +/* + * Static declarations from configfile.c + */ +static void +file_preset(tOptions * opts, char const * fname, int dir); + +static char * +handle_comment(char * txt); + +static char * +handle_cfg(tOptions * opts, tOptState * ost, char * txt, int dir); + +static char * +handle_directive(tOptions * opts, char * txt); + +static char * +aoflags_directive(tOptions * opts, char * txt); + +static char * +program_directive(tOptions * opts, char * txt); + +static char * +handle_section(tOptions * opts, char * txt); + +static int +parse_xml_encoding(char ** ppz); + +static char * +trim_xml_text(char * intxt, char const * pznm, tOptionLoadMode mode); + +static void +cook_xml_text(char * pzData); + +static char * +handle_struct(tOptions * opts, tOptState * ost, char * txt, int dir); + +static void +intern_file_load(tOptions * opts); + +static char const * +parse_attrs(tOptions * opts, char const * txt, tOptionLoadMode * pMode, + tOptionValue * pType); + +static char const * +parse_keyword(tOptions * opts, char const * txt, tOptionValue * typ); + +static char const * +parse_set_mem(tOptions * opts, char const * txt, tOptionValue * typ); + +static char const * +parse_value(char const * txt, tOptionValue * typ); + +/* + * Static declarations from cook.c + */ +static char * +nl_count(char * start, char * end, int * lnct_p); + +static bool +contiguous_quote(char ** pps, char * pq, int * lnct_p); + +/* + * Static declarations from enum.c + */ +static void +enum_err(tOptions * pOpts, tOptDesc * pOD, + char const * const * paz_names, int name_ct); + +static uintptr_t +find_name(char const * name, tOptions * pOpts, tOptDesc * pOD, + char const * const * paz_names, unsigned int name_ct); + +static void +set_memb_shell(tOptions * pOpts, tOptDesc * pOD, char const * const * paz_names, + unsigned int name_ct); + +static void +set_memb_names(tOptions * opts, tOptDesc * od, char const * const * nm_list, + unsigned int nm_ct); + +static uintptr_t +check_membership_start(tOptDesc * od, char const ** argp, bool * invert); + +static uintptr_t +find_member_bit(tOptions * opts, tOptDesc * od, char const * pz, int len, + char const * const * nm_list, unsigned int nm_ct); + +/* + * Static declarations from env.c + */ +static void +doPrognameEnv(tOptions * pOpts, teEnvPresetType type); + +static void +do_env_opt(tOptState * os, char * env_name, + tOptions * pOpts, teEnvPresetType type); + +static void +env_presets(tOptions * pOpts, teEnvPresetType type); + +/* + * Static declarations from file.c + */ +static void +check_existence(teOptFileType ftype, tOptions * pOpts, tOptDesc * pOD); + +static void +open_file_fd(tOptions * pOpts, tOptDesc * pOD, tuFileMode mode); + +static void +fopen_file_fp(tOptions * pOpts, tOptDesc * pOD, tuFileMode mode); + +/* + * Static declarations from find.c + */ +static int +parse_opt(char const ** nm_pp, char ** arg_pp, char * buf, size_t bufsz); + +static void +opt_ambiguities(tOptions * opts, char const * name, int nm_len); + +static int +opt_match_ct(tOptions * opts, char const * name, int nm_len, + int * ixp, bool * disable); + +static tSuccess +opt_set(tOptions * opts, char * arg, int idx, bool disable, tOptState * st); + +static tSuccess +opt_unknown(tOptions * opts, char const * name, char * arg, tOptState * st); + +static tSuccess +opt_ambiguous(tOptions * opts, char const * name, int match_ct); + +static tSuccess +opt_find_long(tOptions * opts, char const * opt_name, tOptState * state); + +static tSuccess +opt_find_short(tOptions * pOpts, uint_t optValue, tOptState * pOptState); + +static tSuccess +get_opt_arg_must(tOptions * opts, tOptState * o_st); + +static tSuccess +get_opt_arg_may(tOptions * pOpts, tOptState * o_st); + +static tSuccess +get_opt_arg_none(tOptions * pOpts, tOptState * o_st); + +static tSuccess +get_opt_arg(tOptions * opts, tOptState * o_st); + +static tSuccess +find_opt(tOptions * opts, tOptState * o_st); + +/* + * Static declarations from init.c + */ +static tSuccess +validate_struct(tOptions * opts, char const * pname); + +static tSuccess +immediate_opts(tOptions * opts); + +static tSuccess +do_presets(tOptions * opts); + +static bool +ao_initialize(tOptions * opts, int a_ct, char ** a_v); + +/* + * Static declarations from load.c + */ +static bool +get_realpath(char * buf, size_t b_sz); + +static bool +add_prog_path(char * buf, int b_sz, char const * fname, char const * prg_path); + +static bool +add_env_val(char * buf, int buf_sz, char const * name); + +static void +munge_str(char * txt, tOptionLoadMode mode); + +static char * +assemble_arg_val(char * txt, tOptionLoadMode mode); + +static char * +trim_quotes(char * arg); + +static bool +direction_ok(opt_state_mask_t f, int dir); + +static void +load_opt_line(tOptions * opts, tOptState * opt_state, char * line, + tDirection direction, tOptionLoadMode load_mode ); + +/* + * Static declarations from makeshell.c + */ +noreturn static void +option_exits(int exit_code); + +noreturn static void +ao_bug(char const * msg); + +static void +fserr_warn(char const * prog, char const * op, char const * fname); + +noreturn static void +fserr_exit(char const * prog, char const * op, char const * fname); + +static void +emit_var_text(char const * prog, char const * var, int fdin); + +static void +text_to_var(tOptions * opts, teTextTo which, tOptDesc * od); + +static void +emit_usage(tOptions * opts); + +static void +emit_wrapup(tOptions * opts); + +static void +emit_setup(tOptions * opts); + +static void +emit_action(tOptions * opts, tOptDesc * od); + +static void +emit_inaction(tOptions * opts, tOptDesc * od); + +static void +emit_flag(tOptions * opts); + +static void +emit_match_expr(char const * name, tOptDesc * cod, tOptions * opts); + +static void +emit_long(tOptions * opts); + +static char * +load_old_output(char const * fname, char const * pname); + +static void +open_out(char const * fname, char const * pname); + +/* + * Static declarations from nested.c + */ +static void +remove_continuation(char * src); + +static char const * +scan_q_str(char const * pzTxt); + +static tOptionValue * +add_string(void ** pp, char const * name, size_t nm_len, + char const * val, size_t d_len); + +static tOptionValue * +add_bool(void ** pp, char const * name, size_t nm_len, + char const * val, size_t d_len); + +static tOptionValue * +add_number(void ** pp, char const * name, size_t nm_len, + char const * val, size_t d_len); + +static tOptionValue * +add_nested(void ** pp, char const * name, size_t nm_len, + char * val, size_t d_len); + +static char const * +scan_name(char const * name, tOptionValue * res); + +static char const * +unnamed_xml(char const * txt); + +static char const * +scan_xml_name(char const * name, size_t * nm_len, tOptionValue * val); + +static char const * +find_end_xml(char const * src, size_t nm_len, char const * val, size_t * len); + +static char const * +scan_xml(char const * xml_name, tOptionValue * res_val); + +static void +unload_arg_list(tArgList * arg_list); + +static void +sort_list(tArgList * arg_list); + +static tOptionValue * +optionLoadNested(char const * text, char const * name, size_t nm_len); + +static int +get_special_char(char const ** ppz, int * ct); + +static void +emit_special_char(FILE * fp, int ch); + +/* + * Static declarations from parse-duration.c + */ +static unsigned long +str_const_to_ul (cch_t * str, cch_t ** ppz, int base); + +static long +str_const_to_l (cch_t * str, cch_t ** ppz, int base); + +static time_t +scale_n_add (time_t base, time_t val, int scale); + +static time_t +parse_hr_min_sec (time_t start, cch_t * pz); + +static time_t +parse_scaled_value (time_t base, cch_t ** ppz, cch_t * endp, int scale); + +static time_t +parse_year_month_day (cch_t * pz, cch_t * ps); + +static time_t +parse_yearmonthday (cch_t * in_pz); + +static time_t +parse_YMWD (cch_t * pz); + +static time_t +parse_hour_minute_second (cch_t * pz, cch_t * ps); + +static time_t +parse_hourminutesecond (cch_t * in_pz); + +static time_t +parse_HMS (cch_t * pz); + +static time_t +parse_time (cch_t * pz); + +static char * +trim (char * pz); + +static time_t +parse_period (cch_t * in_pz); + +static time_t +parse_non_iso8601 (cch_t * pz); + +/* + * Static declarations from pgusage.c + */ +static inline FILE * +open_tmp_usage(char ** buf); + +static inline char * +mk_pager_cmd(char const * fname); + +/* + * Static declarations from putshell.c + */ +static size_t +string_size(char const * scan, size_t nl_len); + +static char const * +print_quoted_apostrophes(char const * str); + +static void +print_quot_str(char const * str); + +static void +print_enumeration(tOptions * pOpts, tOptDesc * pOD); + +static void +print_membership(tOptions * pOpts, tOptDesc * pOD); + +static void +print_stacked_arg(tOptions * pOpts, tOptDesc * pOD); + +static void +print_reordering(tOptions * opts); + +/* + * Static declarations from reset.c + */ +static void +optionReset(tOptions * pOpts, tOptDesc * pOD); + +static void +optionResetEverything(tOptions * pOpts); + +/* + * Static declarations from restore.c + */ +static void +fixupSavedOptionArgs(tOptions * pOpts); + +/* + * Static declarations from save.c + */ +static char const * +find_dir_name(tOptions * opts, int * p_free); + +static char const * +find_file_name(tOptions * opts, int * p_free_name); + +static void +prt_entry(FILE * fp, tOptDesc * od, char const * l_arg, save_flags_mask_t save_fl); + +static void +prt_value(FILE * fp, int depth, tOptDesc * od, tOptionValue const * ovp); + +static void +prt_string(FILE * fp, char const * name, char const * pz); + +static void +prt_val_list(FILE * fp, char const * name, tArgList * al); + +static void +prt_nested(FILE * fp, tOptDesc * od, save_flags_mask_t save_fl); + +static void +remove_settings(tOptions * opts, char const * fname); + +static FILE * +open_sv_file(tOptions * opts, save_flags_mask_t save_fl); + +static void +prt_no_arg_opt(FILE * fp, tOptDesc * vod, tOptDesc * pod, save_flags_mask_t save_fl); + +static void +prt_str_arg(FILE * fp, tOptDesc * od, save_flags_mask_t save_fl); + +static void +prt_enum_arg(FILE * fp, tOptDesc * od, save_flags_mask_t save_fl); + +static void +prt_set_arg(FILE * fp, tOptDesc * od, save_flags_mask_t save_fl); + +static void +prt_file_arg(FILE * fp, tOptDesc * od, tOptions * opts, save_flags_mask_t save_fl); + +/* + * Static declarations from sort.c + */ +static tSuccess +must_arg(tOptions * opts, char * arg_txt, tOptState * pOS, + char ** opt_txt, uint32_t * opt_idx); + +static tSuccess +maybe_arg(tOptions * opts, char * arg_txt, tOptState * pOS, + char ** opt_txt, uint32_t * opt_idx); + +static tSuccess +short_opt_ck(tOptions * opts, char * arg_txt, tOptState * pOS, + char ** opt_txt, uint32_t * opt_idx); + +static void +optionSort(tOptions * opts); + +/* + * Static declarations from stack.c + */ +static void +addArgListEntry(void ** ppAL, void * entry); + +/* + * Static declarations from text_mmap.c + */ +static void +load_text_file(tmap_info_t * mapinfo, char const * pzFile); + +static void +validate_mmap(char const * fname, int prot, int flags, tmap_info_t * mapinfo); + +static void +close_mmap_files(tmap_info_t * mi); + +/* + * Static declarations from tokenize.c + */ +static void +copy_cooked(ch_t ** ppDest, char const ** ppSrc); + +static void +copy_raw(ch_t ** ppDest, char const ** ppSrc); + +static token_list_t * +alloc_token_list(char const * str); + +/* + * Static declarations from usage.c + */ +static unsigned int +parse_usage_flags(ao_flag_names_t const * fnt, char const * txt); + +static void +set_usage_flags(tOptions * opts, char const * flg_txt); + +static inline bool +do_gnu_usage(tOptions * pOpts); + +static inline bool +skip_misuse_usage(tOptions * pOpts); + +static void +print_offer_usage(tOptions * opts); + +static void +print_usage_details(tOptions * opts, int exit_code); + +static void +print_one_paragraph(char const * text, bool plain, FILE * fp); + +static void +prt_conflicts(tOptions * opts, tOptDesc * od); + +static void +prt_one_vendor(tOptions * opts, tOptDesc * od, + arg_types_t * argtp, char const * usefmt); + +static void +prt_vendor_opts(tOptions * opts, char const * title); + +static void +prt_extd_usage(tOptions * opts, tOptDesc * od, char const * title); + +static void +prt_ini_list(char const * const * papz, char const * ini_file, + char const * path_nm); + +static void +prt_preamble(tOptions * opts, tOptDesc * od, arg_types_t * at); + +static void +prt_one_usage(tOptions * opts, tOptDesc * od, arg_types_t * at); + +static void +prt_opt_usage(tOptions * opts, int ex_code, char const * title); + +static void +prt_prog_detail(tOptions * opts); + +static int +setGnuOptFmts(tOptions * opts, char const ** ptxt); + +static int +setStdOptFmts(tOptions * opts, char const ** ptxt); + +/* + * Static declarations from version.c + */ +static void +emit_first_line( + FILE * fp, char const * alt1, char const * alt2, char const * alt3); + +static void +emit_simple_ver(tOptions * o, FILE * fp); + +static void +emit_copy_full(tOptions * o, FILE * fp); + +static void +emit_copy_note(tOptions * opts, FILE * fp); + +static void +print_ver(tOptions * opts, tOptDesc * od, FILE * fp, bool call_exit); + +#endif /* AUTOOPTS_PROTO_H_GUARD */ diff --git a/autoopts/putshell.c b/autoopts/putshell.c new file mode 100644 index 0000000..84463dd --- /dev/null +++ b/autoopts/putshell.c @@ -0,0 +1,495 @@ + +/** + * \file putshell.c + * + * This module will interpret the options set in the tOptions + * structure and print them to standard out in a fashion that + * will allow them to be interpreted by the Bourne or Korn shells. + * + * @addtogroup autoopts + * @{ + */ +/* + * This file is part of AutoOpts, a companion to AutoGen. + * AutoOpts is free software. + * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoOpts is available under any one of two licenses. The license + * in use must be one of these two and the choice is under the control + * of the user of the license. + * + * The GNU Lesser General Public License, version 3 or later + * See the files "COPYING.lgplv3" and "COPYING.gplv3" + * + * The Modified Berkeley Software Distribution License + * See the file "COPYING.mbsd" + * + * These files have the following sha256 sums: + * + * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 + * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 + * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + */ + +/** + * Count the number of bytes required to represent a string as a + * compilable string. + * + * @param[in] scan the text to be rewritten as a C program text string. + * @param[in] nl_len the number of bytes used for each embedded newline. + * + * @returns the count, including the terminating NUL byte. + */ +static size_t +string_size(char const * scan, size_t nl_len) +{ + /* + * Start by counting the start and end quotes, plus the NUL. + */ + size_t res_ln = 3; + + for (;;) { + char ch = *(scan++); + if ((ch >= ' ') && (ch <= '~')) { + + /* + * a backslash allowance for double quotes and baskslashes + */ + res_ln += ((ch == '"') || (ch == '\\')) ? 2 : 1; + } + + /* + * When not a normal character, then count the characters + * required to represent whatever it is. + */ + else switch (ch) { + case NUL: + return res_ln; + + case NL: + res_ln += nl_len; + break; + + case HT: + case BEL: + case BS: + case FF: + case CR: + case VT: + res_ln += 2; + break; + + default: + res_ln += 4; /* text len for \xNN */ + } + } +} + +/*=export_func optionQuoteString + * private: + * + * what: Print a string as quoted text suitable for a C compiler. + * arg: + char const * + text + a block of text to quote + + * arg: + char const * + nl + line splice text + + * + * ret_type: char const * + * ret_desc: the allocated input string as a quoted string + * + * doc: + * This is for internal use by autogen and autoopts. + * It takes an input string and produces text the C compiler can process + * to produce an exact copy of the original string. + * The caller must deallocate the result. Standard C strings and + * K&R strings are distinguished by the "nl" string. +=*/ +char const * +optionQuoteString(char const * text, char const * nl) +{ + size_t nl_len = strlen(nl); + size_t out_sz = string_size(text, nl_len); + char * out; + char * res = out = AGALOC(out_sz, "quot str"); + + *(out++) = '"'; + + for (;;) { + unsigned char ch = (unsigned char)*text; + if ((ch >= ' ') && (ch <= '~')) { + if ((ch == '"') || (ch == '\\')) + /* + * We must escape these characters in the output string + */ + *(out++) = '\\'; + *(out++) = (char)ch; + + } else switch (ch) { +# define add_esc_ch(_ch) { *(out++) = '\\'; *(out++) = (_ch); } + case BEL: add_esc_ch('a'); break; + case BS: add_esc_ch('b'); break; + case HT: add_esc_ch('t'); break; + case VT: add_esc_ch('v'); break; + case FF: add_esc_ch('f'); break; + case CR: add_esc_ch('r'); break; + + case LF: + /* + * Place contiguous new-lines on a single line. + * The current character is a NL, check the next one. + */ + while (*++text == NL) + add_esc_ch('n'); + + /* + * Insert a splice before starting next line + */ + if (*text != NUL) { + memcpy(out, nl, nl_len); + out += nl_len; + + continue; /* text is already at the next character */ + } + + add_esc_ch('n'); + /* FALLTHROUGH */ + + case NUL: + /* + * End of string. Terminate the quoted output. If necessary, + * deallocate the text string. Return the scan resumption point. + */ + *(out++) = '"'; + *(out++) = NUL; +#ifndef NDEBUG + if ((size_t)(out - res) > out_sz) { + fputs(misguess_len, stderr); + option_exits(EXIT_FAILURE); + } +#endif + return res; + + default: + /* + * sprintf is safe here, because we already computed + * the amount of space we will be using. Assertion is above. + */ + out += sprintf(out, MK_STR_OCT_FMT, ch); + } + + text++; +# undef add_esc_ch + } +} + +/** + * Print out escaped apostorophes. + * + * @param[in] str the apostrophies to print + */ +static char const * +print_quoted_apostrophes(char const * str) +{ + while (*str == APOSTROPHE) { + fputs(QUOT_APOS, stdout); + str++; + } + return str; +} + +/** + * Print a single quote (apostrophe quoted) string. + * Other than somersaults for apostrophes, nothing else needs quoting. + * + * @param[in] str the string to print + */ +static void +print_quot_str(char const * str) +{ + /* + * Handle empty strings to make the rest of the logic simpler. + */ + if ((str == NULL) || (*str == NUL)) { + fputs(EMPTY_ARG, stdout); + return; + } + + /* + * Emit any single quotes/apostrophes at the start of the string and + * bail if that is all we need to do. + */ + str = print_quoted_apostrophes(str); + if (*str == NUL) + return; + + /* + * Start the single quote string + */ + fputc(APOSTROPHE, stdout); + for (;;) { + char const * pz = strchr(str, APOSTROPHE); + if (pz == NULL) + break; + + /* + * Emit the string up to the single quote (apostrophe) we just found. + */ + (void)fwrite(str, (size_t)(pz - str), (size_t)1, stdout); + + /* + * Close the current string, emit the apostrophes and re-open the + * string (IFF there is more text to print). + */ + fputc(APOSTROPHE, stdout); + str = print_quoted_apostrophes(pz); + if (*str == NUL) + return; + + fputc(APOSTROPHE, stdout); + } + + /* + * If we broke out of the loop, we must still emit the remaining text + * and then close the single quote string. + */ + fputs(str, stdout); + fputc(APOSTROPHE, stdout); +} + +static void +print_enumeration(tOptions * pOpts, tOptDesc * pOD) +{ + uintptr_t e_val = pOD->optArg.argEnum; + printf(OPT_VAL_FMT, pOpts->pzPROGNAME, pOD->pz_NAME); + + /* + * Convert value to string, print that and restore numeric value. + */ + (*(pOD->pOptProc))(OPTPROC_RETURN_VALNAME, pOD); + printf(QUOT_ARG_FMT, pOD->optArg.argString); + if (pOD->fOptState & OPTST_ALLOC_ARG) + AGFREE(pOD->optArg.argString); + pOD->optArg.argEnum = e_val; + + printf(OPT_END_FMT, pOpts->pzPROGNAME, pOD->pz_NAME); +} + +static void +print_membership(tOptions * pOpts, tOptDesc * pOD) +{ + char const * svstr = pOD->optArg.argString; + char const * pz; + uintptr_t val = 1; + printf(zOptNumFmt, pOpts->pzPROGNAME, pOD->pz_NAME, + (int)(uintptr_t)(pOD->optCookie)); + pOD->optCookie = VOIDP(~0UL); + (*(pOD->pOptProc))(OPTPROC_RETURN_VALNAME, pOD); + + pz = pOD->optArg.argString; + while (*pz != NUL) { + printf("readonly %s_", pOD->pz_NAME); + pz = SPN_PLUS_N_SPACE_CHARS(pz); + + for (;;) { + int ch = *(pz++); + if (IS_LOWER_CASE_CHAR(ch)) fputc(toupper(ch), stdout); + else if (IS_UPPER_CASE_CHAR(ch)) fputc(ch, stdout); + else if (IS_PLUS_N_SPACE_CHAR(ch)) goto name_done; + else if (ch == NUL) { pz--; goto name_done; } + else fputc('_', stdout); + } name_done:; + printf(SHOW_VAL_FMT, (unsigned long)val); + val <<= 1; + } + + AGFREE(pOD->optArg.argString); + pOD->optArg.argString = svstr; +} + +static void +print_stacked_arg(tOptions * pOpts, tOptDesc * pOD) +{ + tArgList * pAL = (tArgList *)pOD->optCookie; + char const ** ppz = pAL->apzArgs; + int ct = pAL->useCt; + + printf(zOptCookieCt, pOpts->pzPROGNAME, pOD->pz_NAME, ct); + + while (--ct >= 0) { + printf(ARG_BY_NUM_FMT, pOpts->pzPROGNAME, pOD->pz_NAME, + pAL->useCt - ct); + print_quot_str(*(ppz++)); + printf(EXPORT_ARG_FMT, pOpts->pzPROGNAME, pOD->pz_NAME, + pAL->useCt - ct); + } +} + +/** + * emit the arguments as readily parsed text. + * The program options are set by emitting the shell "set" command. + * + * @param[in] opts the program options structure + */ +static void +print_reordering(tOptions * opts) +{ + unsigned int ix; + + fputs(set_dash, stdout); + + for (ix = opts->curOptIdx; + ix < opts->origArgCt; + ix++) { + fputc(' ', stdout); + print_quot_str(opts->origArgVect[ ix ]); + } + fputs(init_optct, stdout); +} + +/*=export_func optionPutShell + * what: write a portable shell script to parse options + * private: + * arg: tOptions *, pOpts, the program options descriptor + * doc: This routine will emit portable shell script text for parsing + * the options described in the option definitions. +=*/ +void +optionPutShell(tOptions * pOpts) +{ + int optIx = 0; + + printf(zOptCtFmt, pOpts->curOptIdx-1); + + do { + tOptDesc * pOD = pOpts->pOptDesc + optIx; + + if ((pOD->fOptState & OPTST_NO_OUTPUT_MASK) != 0) + continue; + + /* + * Equivalence classes are hard to deal with. Where the + * option data wind up kind of squishes around. For the purposes + * of emitting shell state, they are not recommended, but we'll + * do something. I guess we'll emit the equivalenced-to option + * at the point in time when the base option is found. + */ + if (pOD->optEquivIndex != NO_EQUIVALENT) + continue; /* equivalence to a different option */ + + /* + * Equivalenced to a different option. Process the current option + * as the equivalenced-to option. Keep the persistent state bits, + * but copy over the set-state bits. + */ + if (pOD->optActualIndex != optIx) { + tOptDesc * p = pOpts->pOptDesc + pOD->optActualIndex; + p->optArg = pOD->optArg; + p->fOptState &= OPTST_PERSISTENT_MASK; + p->fOptState |= pOD->fOptState & ~OPTST_PERSISTENT_MASK; + printf(zEquivMode, pOpts->pzPROGNAME, pOD->pz_NAME, p->pz_NAME); + pOD = p; + } + + /* + * If the argument type is a set membership bitmask, then we always + * emit the thing. We do this because it will always have some sort + * of bitmask value and we need to emit the bit values. + */ + if (OPTST_GET_ARGTYPE(pOD->fOptState) == OPARG_TYPE_MEMBERSHIP) { + print_membership(pOpts, pOD); + continue; + } + + /* + * IF the option was either specified or it wakes up enabled, + * then we will emit information. Otherwise, skip it. + * The idea is that if someone defines an option to initialize + * enabled, we should tell our shell script that it is enabled. + */ + if (UNUSED_OPT(pOD) && DISABLED_OPT(pOD)) + continue; + + /* + * Handle stacked arguments + */ + if ( (pOD->fOptState & OPTST_STACKED) + && (pOD->optCookie != NULL) ) { + print_stacked_arg(pOpts, pOD); + continue; + } + + /* + * If the argument has been disabled, + * Then set its value to the disablement string + */ + if ((pOD->fOptState & OPTST_DISABLED) != 0) { + printf(zOptDisabl, pOpts->pzPROGNAME, pOD->pz_NAME, + (pOD->pz_DisablePfx != NULL) + ? pOD->pz_DisablePfx : "false"); + continue; + } + + /* + * If the argument type is numeric, the last arg pointer + * is really the VALUE of the string that was pointed to. + */ + if (OPTST_GET_ARGTYPE(pOD->fOptState) == OPARG_TYPE_NUMERIC) { + printf(zOptNumFmt, pOpts->pzPROGNAME, pOD->pz_NAME, + (int)pOD->optArg.argInt); + continue; + } + + /* + * If the argument type is an enumeration, then it is much + * like a text value, except we call the callback function + * to emit the value corresponding to the "optArg" number. + */ + if (OPTST_GET_ARGTYPE(pOD->fOptState) == OPARG_TYPE_ENUMERATION) { + print_enumeration(pOpts, pOD); + continue; + } + + /* + * If the argument type is numeric, the last arg pointer + * is really the VALUE of the string that was pointed to. + */ + if (OPTST_GET_ARGTYPE(pOD->fOptState) == OPARG_TYPE_BOOLEAN) { + printf(zFullOptFmt, pOpts->pzPROGNAME, pOD->pz_NAME, + (pOD->optArg.argBool == 0) ? "false" : "true"); + continue; + } + + /* + * IF the option has an empty value, + * THEN we set the argument to the occurrence count. + */ + if ( (pOD->optArg.argString == NULL) + || (pOD->optArg.argString[0] == NUL) ) { + + printf(zOptNumFmt, pOpts->pzPROGNAME, pOD->pz_NAME, + pOD->optOccCt); + continue; + } + + /* + * This option has a text value + */ + printf(OPT_VAL_FMT, pOpts->pzPROGNAME, pOD->pz_NAME); + print_quot_str(pOD->optArg.argString); + printf(OPT_END_FMT, pOpts->pzPROGNAME, pOD->pz_NAME); + + } while (++optIx < pOpts->presetOptCt ); + + if ( ((pOpts->fOptSet & OPTPROC_REORDER) != 0) + && (pOpts->curOptIdx < pOpts->origArgCt)) + print_reordering(pOpts); + + fflush(stdout); +} + +/** @} + * + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of autoopts/putshell.c */ diff --git a/autoopts/reset.c b/autoopts/reset.c new file mode 100644 index 0000000..f7b58e8 --- /dev/null +++ b/autoopts/reset.c @@ -0,0 +1,141 @@ + +/** + * \file reset.c + * + * Reset the option state to the compiled state. + * + * @addtogroup autoopts + * @{ + */ +/* + * This file is part of AutoOpts, a companion to AutoGen. + * AutoOpts is free software. + * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoOpts is available under any one of two licenses. The license + * in use must be one of these two and the choice is under the control + * of the user of the license. + * + * The GNU Lesser General Public License, version 3 or later + * See the files "COPYING.lgplv3" and "COPYING.gplv3" + * + * The Modified Berkeley Software Distribution License + * See the file "COPYING.mbsd" + * + * These files have the following sha256 sums: + * + * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 + * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 + * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + */ + +static void +optionReset(tOptions * pOpts, tOptDesc * pOD) +{ + pOD->fOptState &= OPTST_PERSISTENT_MASK; + pOD->fOptState |= OPTST_RESET; + if (pOD->pOptProc != NULL) + pOD->pOptProc(pOpts, pOD); + pOD->optArg.argString = + pOpts->originalOptArgArray[ pOD->optIndex ].argString; + pOD->optCookie = pOpts->originalOptArgCookie[ pOD->optIndex ]; + pOD->fOptState &= OPTST_PERSISTENT_MASK; +} + + +static void +optionResetEverything(tOptions * pOpts) +{ + tOptDesc * pOD = pOpts->pOptDesc; + int ct = pOpts->presetOptCt; + + for (;;) { + optionReset(pOpts, pOD); + + if (--ct <= 0) + break; + pOD++; + } +} + + +/*=export_func optionResetOpt + * private: + * + * what: Reset the value of an option + * arg: + tOptions * + pOpts + program options descriptor + + * arg: + tOptDesc * + pOptDesc + the descriptor for this arg + + * + * doc: + * This code will cause another option to be reset to its initial state. + * For example, --reset=foo will cause the --foo option to be reset. +=*/ +void +optionResetOpt(tOptions * pOpts, tOptDesc * pOD) +{ + static bool reset_active = false; + + tOptState opt_state = OPTSTATE_INITIALIZER(DEFINED); + char const * pzArg = pOD->optArg.argString; + tSuccess succ; + + if (pOpts <= OPTPROC_EMIT_LIMIT) + return; + + if (reset_active) + return; + + if ( (! HAS_originalOptArgArray(pOpts)) + || (pOpts->originalOptArgCookie == NULL)) + ao_bug(zno_reset); + + if ((pzArg == NULL) || (*pzArg == NUL)) { + fprintf(stderr, zreset_arg, pOpts->pzProgName, pOD->pz_Name); + pOpts->pUsageProc(pOpts, EXIT_FAILURE); + /* NOTREACHED */ + assert(0 == 1); + } + + reset_active = true; + + if (pzArg[1] == NUL) { + if (*pzArg == '*') { + optionResetEverything(pOpts); + reset_active = false; + return; + } + + succ = opt_find_short(pOpts, (uint8_t)*pzArg, &opt_state); + if (! SUCCESSFUL(succ)) { + fprintf(stderr, zIllOptChr, pOpts->pzProgPath, *pzArg); + pOpts->pUsageProc(pOpts, EXIT_FAILURE); + /* NOTREACHED */ + assert(0 == 1); + } + } else { + succ = opt_find_long(pOpts, (char *)pzArg, &opt_state); + if (! SUCCESSFUL(succ)) { + fprintf(stderr, zIllOptStr, pOpts->pzProgPath, pzArg); + pOpts->pUsageProc(pOpts, EXIT_FAILURE); + /* NOTREACHED */ + assert(0 == 1); + } + } + + /* + * We've found the indicated option. Turn off all non-persistent + * flags because we're forcing the option back to its initialized state. + * Call any callout procedure to handle whatever it needs to. + * Finally, clear the reset flag, too. + */ + optionReset(pOpts, opt_state.pOD); + reset_active = false; +} +/** @} + * + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of autoopts/reset.c */ diff --git a/autoopts/restore.c b/autoopts/restore.c new file mode 100644 index 0000000..36ebbce --- /dev/null +++ b/autoopts/restore.c @@ -0,0 +1,223 @@ + +/* + * \file restore.c + * + * This module's routines will save the current option state to memory + * and restore it. If saved prior to the initial optionProcess call, + * then the initial state will be restored. + * + * @addtogroup autoopts + * @{ + */ +/* + * This file is part of AutoOpts, a companion to AutoGen. + * AutoOpts is free software. + * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoOpts is available under any one of two licenses. The license + * in use must be one of these two and the choice is under the control + * of the user of the license. + * + * The GNU Lesser General Public License, version 3 or later + * See the files "COPYING.lgplv3" and "COPYING.gplv3" + * + * The Modified Berkeley Software Distribution License + * See the file "COPYING.mbsd" + * + * These files have the following sha256 sums: + * + * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 + * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 + * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + */ + +/* + * optionFixupSavedOpts Really, it just wipes out option state for + * options that are troublesome to copy. viz., stacked strings and + * hierarcicaly valued option args. We do duplicate string args that + * have been marked as allocated though. + */ +static void +fixupSavedOptionArgs(tOptions * pOpts) +{ + tOptions * p = pOpts->pSavedState; + tOptDesc * pOD = pOpts->pOptDesc; + int ct = pOpts->optCt; + + /* + * Make sure that allocated stuff is only referenced in the + * archived copy of the data. + */ + for (; ct-- > 0; pOD++) { + switch (OPTST_GET_ARGTYPE(pOD->fOptState)) { + case OPARG_TYPE_STRING: + if (pOD->fOptState & OPTST_STACKED) { + tOptDesc * q = p->pOptDesc + (pOD - pOpts->pOptDesc); + q->optCookie = NULL; + } + if (pOD->fOptState & OPTST_ALLOC_ARG) { + tOptDesc * q = p->pOptDesc + (pOD - pOpts->pOptDesc); + AGDUPSTR(q->optArg.argString, pOD->optArg.argString, "arg"); + } + break; + + case OPARG_TYPE_HIERARCHY: + { + tOptDesc * q = p->pOptDesc + (pOD - pOpts->pOptDesc); + q->optCookie = NULL; + } + } + } +} + +/*=export_func optionSaveState + * + * what: saves the option state to memory + * arg: tOptions *, pOpts, program options descriptor + * + * doc: + * + * This routine will allocate enough memory to save the current option + * processing state. If this routine has been called before, that memory + * will be reused. You may only save one copy of the option state. This + * routine may be called before optionProcess(3AO). If you do call it + * before the first call to optionProcess, then you may also change the + * contents of argc/argv after you call optionRestore(3AO) + * + * In fact, more strongly put: it is safest to only use this function + * before having processed any options. In particular, the saving and + * restoring of stacked string arguments and hierarchical values is + * disabled. The values are not saved. + * + * err: If it fails to allocate the memory, + * it will print a message to stderr and exit. + * Otherwise, it will always succeed. +=*/ +void +optionSaveState(tOptions * pOpts) +{ + tOptions * p = (tOptions *)pOpts->pSavedState; + + if (p == NULL) { + size_t sz = sizeof(*pOpts) + + ((size_t)pOpts->optCt * sizeof(tOptDesc)); + p = AGALOC(sz, "saved option state"); + + pOpts->pSavedState = p; + } + + memcpy(p, pOpts, sizeof(*p)); + memcpy(p + 1, pOpts->pOptDesc, (size_t)p->optCt * sizeof(tOptDesc)); + + fixupSavedOptionArgs(pOpts); +} + + +/*=export_func optionRestore + * + * what: restore option state from memory copy + * arg: tOptions *, pOpts, program options descriptor + * + * doc: Copy back the option state from saved memory. + * The allocated memory is left intact, so this routine can be + * called repeatedly without having to call optionSaveState again. + * If you are restoring a state that was saved before the first call + * to optionProcess(3AO), then you may change the contents of the + * argc/argv parameters to optionProcess. + * + * err: If you have not called @code{optionSaveState} before, a diagnostic is + * printed to @code{stderr} and exit is called. +=*/ +void +optionRestore(tOptions * pOpts) +{ + tOptions * p = (tOptions *)pOpts->pSavedState; + + if (p == NULL) { + char const * pzName = pOpts->pzProgName; + if (pzName == NULL) { + pzName = pOpts->pzPROGNAME; + if (pzName == NULL) + pzName = zNil; + } + fprintf(stderr, zNoState, pzName); + option_exits(EXIT_FAILURE); + } + + pOpts->pSavedState = NULL; + optionFree(pOpts); + + memcpy(pOpts, p, sizeof(*p)); + memcpy(pOpts->pOptDesc, p+1, (size_t)p->optCt * sizeof(tOptDesc)); + pOpts->pSavedState = p; + + fixupSavedOptionArgs(pOpts); +} + +/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */ + +/*=export_func optionFree + * + * what: free allocated option processing memory + * arg: tOptions *, pOpts, program options descriptor + * + * doc: AutoOpts sometimes allocates memory and puts pointers to it in the + * option state structures. This routine deallocates all such memory. + * + * err: As long as memory has not been corrupted, + * this routine is always successful. +=*/ +void +optionFree(tOptions * pOpts) +{ + free_saved_state: + { + tOptDesc * p = pOpts->pOptDesc; + int ct = pOpts->optCt; + do { + if (p->fOptState & OPTST_ALLOC_ARG) { + AGFREE(p->optArg.argString); + p->optArg.argString = NULL; + p->fOptState &= ~OPTST_ALLOC_ARG; + } + + switch (OPTST_GET_ARGTYPE(p->fOptState)) { + case OPARG_TYPE_STRING: +#ifdef WITH_LIBREGEX + if ( (p->fOptState & OPTST_STACKED) + && (p->optCookie != NULL)) { + p->optArg.argString = ".*"; + optionUnstackArg(pOpts, p); + } +#else + /* leak memory */; +#endif + break; + + case OPARG_TYPE_HIERARCHY: + if (p->optCookie != NULL) + unload_arg_list(p->optCookie); + break; + } + + p->optCookie = NULL; + } while (p++, --ct > 0); + } + if (pOpts->pSavedState != NULL) { + tOptions * p = (tOptions *)pOpts->pSavedState; + memcpy(pOpts, p, sizeof(*p)); + memcpy(pOpts->pOptDesc, p+1, (size_t)p->optCt * sizeof(tOptDesc)); + AGFREE(pOpts->pSavedState); + pOpts->pSavedState = NULL; + goto free_saved_state; + } +} + +/** @} + * + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of autoopts/restore.c */ diff --git a/autoopts/save-flags.c b/autoopts/save-flags.c new file mode 100644 index 0000000..d295170 --- /dev/null +++ b/autoopts/save-flags.c @@ -0,0 +1,248 @@ +/* -*- buffer-read-only: t -*- vi: set ro: + * + * DO NOT EDIT THIS FILE (save-flags.c) + * + * It has been AutoGen-ed + * From the definitions /tmp/.ag-ufBbQe/save-flags.def + * and the template file str2enum + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name ``Bruce Korb'' nor the name of any other + * contributor may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * str2enum IS PROVIDED BY Bruce Korb ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL Bruce Korb OR ANY OTHER CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "save-flags.h" +#include +#ifndef MISSING_INTTYPES_H +# include +#endif + +typedef enum { + SVFL_BNM_DEFAULT = 0, + SVFL_BNM_USAGE = 1, + SVFL_BNM_UPDATE = 2, + SVFL_COUNT_BNM +} save_flags_enum_t; + +static save_flags_enum_t +find_save_flags_bnm(char const * str, size_t len); + + +#include +#include +#ifndef NUL +#define NUL '\0' +#endif + +/* ANSI-C code produced by gperf version 3.1 */ +/* Command-line: gperf save-flags.gp */ +/* Computed positions: -k'' */ + + +# if 0 /* gperf build options: */ +// %struct-type +// %language=ANSI-C +// %includes +// %global-table +// %omit-struct-type +// %readonly-tables +// %compare-strncmp +// +// %define slot-name svfl_name +// %define hash-function-name save_flags_hash +// %define lookup-function-name find_save_flags_name +// %define word-array-name save_flags_table +// %define initializer-suffix ,SVFL_COUNT_BNM +// +# endif + +#include "save-flags.h" +typedef struct { + char const * svfl_name; + save_flags_enum_t svfl_id; +} save_flags_map_t; +#include + +/* maximum key range = 3, duplicates = 0 */ + +static unsigned int +save_flags_hash (register const char *str, register size_t len) +{ + (void)str; + (void)len; + return len; +} + +static const save_flags_map_t save_flags_table[] = + { + {"",SVFL_COUNT_BNM}, {"",SVFL_COUNT_BNM}, + {"",SVFL_COUNT_BNM}, {"",SVFL_COUNT_BNM}, + {"",SVFL_COUNT_BNM}, + {"usage", SVFL_BNM_USAGE}, + {"update", SVFL_BNM_UPDATE}, + {"default", SVFL_BNM_DEFAULT} + }; + +static inline const save_flags_map_t * +find_save_flags_name (register const char *str, register size_t len) +{ + if (len <= 7 && len >= 5) + { + register unsigned int key = (int)save_flags_hash (str, len); + + if (key <= 7) + { + register const char *s = save_flags_table[key].svfl_name; + + if (*str == *s && !strncmp (str + 1, s + 1, len - 1) && s[len] == '\0') + return &save_flags_table[key]; + } + } + return 0; +} + +/** + * Convert a command (keyword) to a save_flags_enum_t enumeration value. + * + * @param[in] str a string that should start with a known key word. + * @param[in] len the provided length of the keyword at \a str. + * @returns the enumeration value. + * If not found, that value is SVFL_COUNT_BNM. + */ +static save_flags_enum_t +find_save_flags_bnm(char const * str, size_t len) +{ + save_flags_map_t const * map; + + map = find_save_flags_name(str, (unsigned int)len); + if (map != NULL) + return map->svfl_id; + /* Check for a partial match */ + { + /* + * Indexes of valid save_flags_table entries in sorted order: + */ + static unsigned int const ix_map[] = { + 7, 6, 5 }; + save_flags_enum_t res = SVFL_COUNT_BNM; + static int const HI = (sizeof(ix_map) / sizeof(ix_map[0])) - 1; + int lo = 0; + int hi = HI; + int av; + int cmp; + + for (;;) { + av = (hi + lo) / 2; + map = save_flags_table + ix_map[av]; + cmp = strncmp(map->svfl_name, str, len); + if (cmp == 0) break; + if (cmp > 0) + hi = av - 1; + else lo = av + 1; + if (lo > hi) + return SVFL_COUNT_BNM; + } + res = map->svfl_id; + /* + * If we have an exact match, accept it. + */ + if (map->svfl_name[len] == NUL) + return res; + /* + * Check for a duplicate partial match (a partial match + * with a higher or lower index than "av". + */ + if (av < HI) { + map = save_flags_table + ix_map[av + 1]; + if (strncmp(map->svfl_name, str, len) == 0) + return SVFL_COUNT_BNM; + } + if (av > 0) { + map = save_flags_table + ix_map[av - 1]; + if (strncmp(map->svfl_name, str, len) == 0) + return SVFL_COUNT_BNM; + } + return res; + } +} + +/** + * Convert a string to a save_flags_mask_t mask. + * Bit names prefixed with a hyphen have the bit removed from the mask. + * If the string starts with a '-', '+' or '|' character, then + * the old value is used as a base, otherwise the result mask + * is initialized to zero. Separating bit names with '+' or '|' + * characters is optional. By default, the bits are "or"-ed into the + * result. + * + * @param[in] str string with a list of bit names + * @param[in] old previous value, used if \a str starts with a '+' or '-'. + * + * @returns an unsigned integer with the bits set. + */ +save_flags_mask_t +save_flags_str2mask(char const * str, save_flags_mask_t old) +{ + static char const white[] = ", \t\f"; + static char const name_chars[] = + "adefglpstu" + "ADEFGLPSTU"; + + save_flags_mask_t res = 0; + int have_data = 0; + + for (;;) { + save_flags_enum_t val; + unsigned int val_len; + unsigned int invert = 0; + + str += strspn(str, white); + switch (*str) { + case NUL: return res; + case '-': case '~': + invert = 1; + /* FALLTHROUGH */ + + case '+': case '|': + if (have_data == 0) + res = old; + + str += 1 + strspn(str + 1, white); + if (*str == NUL) + return 0; + } + + val_len = strspn(str, name_chars); + if (val_len == 0) + return 0; + val = find_save_flags_bnm(str, val_len); + if (val == SVFL_COUNT_BNM) + return 0; + if (invert) + res &= ~((save_flags_mask_t)1 << val); + else + res |= (save_flags_mask_t)1 << val; + have_data = 1; + str += val_len; + } +} +/* end of save-flags.c */ diff --git a/autoopts/save-flags.h b/autoopts/save-flags.h new file mode 100644 index 0000000..dcfe0c9 --- /dev/null +++ b/autoopts/save-flags.h @@ -0,0 +1,68 @@ +/* -*- buffer-read-only: t -*- vi: set ro: + * + * DO NOT EDIT THIS FILE (save-flags.h) + * + * It has been AutoGen-ed + * From the definitions /tmp/.ag-ufBbQe/save-flags.def + * and the template file str2enum + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name ``Bruce Korb'' nor the name of any other + * contributor may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * str2enum IS PROVIDED BY Bruce Korb ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL Bruce Korb OR ANY OTHER CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Command/Keyword Dispatcher + */ +#ifndef STR2ENUM_SAVE_FLAGS_H_GUARD +#define STR2ENUM_SAVE_FLAGS_H_GUARD 1 +#include +#include + +/** integral type for holding save_flags masks */ +typedef uint32_t save_flags_mask_t; + +/** bits defined for save_flags_mask_t */ +/** include default values in commentary */ +#define SVFL_DEFAULT 0x0001U +/** include usage text in commentary */ +#define SVFL_USAGE 0x0002U +/** replace or append state */ +#define SVFL_UPDATE 0x0004U + +/** bits in USAGE_DEFAULT mask: + * usage default */ +#define SVFL_USAGE_DEFAULT_MASK 0x0003U + +/** all bits in save_flags_mask_t masks */ +#define SVFL_MASK_ALL 0x0007U + +/** no bits in save_flags_mask_t */ +#define SVFL_NONE 0x0000U + +/** buffer size needed to hold all bit names for save_flags_mask_t masks */ +#define MAX_SAVE_FLAGS_NAME_SIZE 21 + +extern save_flags_mask_t +save_flags_str2mask(char const * str, save_flags_mask_t old); + +#endif /* STR2ENUM_SAVE_FLAGS_H_GUARD */ +/* end of save-flags.h */ diff --git a/autoopts/save.c b/autoopts/save.c new file mode 100644 index 0000000..8b1fba9 --- /dev/null +++ b/autoopts/save.c @@ -0,0 +1,916 @@ + +/* + * \file save.c + * + * This module's routines will take the currently set options and + * store them into an ".rc" file for re-interpretation the next + * time the invoking program is run. + * + * @addtogroup autoopts + * @{ + */ +/* + * This file is part of AutoOpts, a companion to AutoGen. + * AutoOpts is free software. + * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoOpts is available under any one of two licenses. The license + * in use must be one of these two and the choice is under the control + * of the user of the license. + * + * The GNU Lesser General Public License, version 3 or later + * See the files "COPYING.lgplv3" and "COPYING.gplv3" + * + * The Modified Berkeley Software Distribution License + * See the file "COPYING.mbsd" + * + * These files have the following sha256 sums: + * + * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 + * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 + * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + */ +#include "save-flags.h" + +/** + * find the config file directory name + * + * @param opts the options descriptor + * @param p_free tell caller if name was allocated or not + */ +static char const * +find_dir_name(tOptions * opts, int * p_free) +{ + char const * dir; + + if ( (opts->specOptIdx.save_opts == NO_EQUIVALENT) + || (opts->specOptIdx.save_opts == 0)) + return NULL; + + dir = opts->pOptDesc[ opts->specOptIdx.save_opts ].optArg.argString; + if ((dir != NULL) && (*dir != NUL)) { + char const * pz = strchr(dir, '>'); + if (pz == NULL) + return dir; + while (*(++pz) == '>') ; + pz += strspn(pz, " \t"); + dir = pz; + if (*dir != NUL) + return dir; + } + + if (opts->papzHomeList == NULL) + return NULL; + + /* + * This function only works if there is a directory where + * we can stash the RC (INI) file. + */ + for (int idx = 0;; idx++) { + char f_name[ AG_PATH_MAX+1 ]; + + dir = opts->papzHomeList[idx]; + + switch (*dir) { + case '$': + break; + case NUL: + continue; + default: + return dir; + } + if (optionMakePath(f_name, (int)sizeof(f_name), dir, opts->pzProgPath)) { + *p_free = true; + AGDUPSTR(dir, f_name, "homerc"); + return dir; + } + } + return NULL; +} + +/** + * Find the name of the save-the-options file + * + * @param opts the options descriptor + * @param p_free_name tell caller if name was allocated or not + */ +static char const * +find_file_name(tOptions * opts, int * p_free_name) +{ + struct stat stBuf; + int free_dir_name = 0; + + char const * res = find_dir_name(opts, &free_dir_name); + if (res == NULL) + return res; + + /* + * See if we can find the specified directory. We use a once-only loop + * structure so we can bail out early. + */ + if (stat(res, &stBuf) != 0) do { + char z[AG_PATH_MAX]; + char * dirchp; + + /* + * IF we could not, check to see if we got a full + * path to a file name that has not been created yet. + */ + if (errno != ENOENT) { + bogus_name: + fprintf(stderr, zsave_warn, opts->pzProgName, res); + fprintf(stderr, zNoStat, errno, strerror(errno), res); + if (free_dir_name) + AGFREE(res); + return NULL; + } + + /* + * Strip off the last component, stat the remaining string and + * that string must name a directory + */ + dirchp = strrchr(res, DIRCH); + if (dirchp == NULL) { + stBuf.st_mode = S_IFREG; + break; /* found directory -- viz., "." */ + } + + if ((size_t)(dirchp - res) >= sizeof(z)) + goto bogus_name; + + memcpy(z, res, (size_t)(dirchp - res)); + z[dirchp - res] = NUL; + + if ((stat(z, &stBuf) != 0) || ! S_ISDIR(stBuf.st_mode)) + goto bogus_name; + stBuf.st_mode = S_IFREG; /* file within this directory */ + } while (false); + + /* + * IF what we found was a directory, + * THEN tack on the config file name + */ + if (S_ISDIR(stBuf.st_mode)) { + + { + size_t sz = strlen(res) + strlen(opts->pzRcName) + 2; + char * pzPath = (char *)AGALOC(sz, "file name"); + if ( snprintf(pzPath, sz, "%s/%s", res, opts->pzRcName) + >= (int)sz) + option_exits(EXIT_FAILURE); + + if (free_dir_name) + AGFREE(res); + res = pzPath; + free_dir_name = 1; + } + + /* + * IF we cannot stat the object for any reason other than + * it does not exist, then we bail out + */ + if (stat(res, &stBuf) != 0) { + if (errno != ENOENT) { + fprintf(stderr, zsave_warn, opts->pzProgName, res); + fprintf(stderr, zNoStat, errno, strerror(errno), + res); + AGFREE(res); + return NULL; + } + + /* + * It does not exist yet, but it will be a regular file + */ + stBuf.st_mode = S_IFREG; + } + } + + /* + * Make sure that whatever we ultimately found, that it either is + * or will soon be a file. + */ + if (! S_ISREG(stBuf.st_mode)) { + fprintf(stderr, zsave_warn, opts->pzProgName, res); + if (free_dir_name) + AGFREE(res); + return NULL; + } + + /* + * Get rid of the old file + */ + *p_free_name = free_dir_name; + return res; +} + +/** + * print one option entry to the save file. + * + * @param[in] fp the file pointer for the save file + * @param[in] od the option descriptor to print + * @param[in] l_arg the last argument for the option + * @param[in] save_fl include usage in comments + */ +static void +prt_entry(FILE * fp, tOptDesc * od, char const * l_arg, save_flags_mask_t save_fl) +{ + int space_ct; + + if (save_fl & SVFL_USAGE) + fprintf(fp, ao_name_use_fmt, od->pz_Name, od->pzText); + if (UNUSED_OPT(od) && (save_fl & SVFL_DEFAULT)) + fputs(ao_default_use, fp); + + /* + * There is an argument. Pad the name so values line up. + * Not disabled *OR* this got equivalenced to another opt, + * then use current option name. + * Otherwise, there must be a disablement name. + */ + { + char const * pz = + (od->pz_DisableName == NULL) + ? od->pz_Name + : (DISABLED_OPT(od) + ? od->pz_DisableName + : ((od->optEquivIndex == NO_EQUIVALENT) + ? od->pz_Name : od->pz_DisableName) + ); + + space_ct = 17 - strlen(pz); + fputs(pz, fp); + } + + if ( (l_arg == NULL) + && (OPTST_GET_ARGTYPE(od->fOptState) != OPARG_TYPE_NUMERIC)) + goto end_entry; + + fputs(" = ", fp); + while (space_ct-- > 0) fputc(' ', fp); + + /* + * IF the option is numeric only, + * THEN the char pointer is really the number + */ + if (OPTST_GET_ARGTYPE(od->fOptState) == OPARG_TYPE_NUMERIC) + fprintf(fp, "%d", (int)(intptr_t)l_arg); + + else { + for (;;) { + char const * eol = strchr(l_arg, NL); + + /* + * IF this is the last line + * THEN bail and print it + */ + if (eol == NULL) + break; + + /* + * Print the continuation and the text from the current line + */ + (void)fwrite(l_arg, (size_t)(eol - l_arg), (size_t)1, fp); + l_arg = eol+1; /* advance the Last Arg pointer */ + fputs("\\\n", fp); + } + + /* + * Terminate the entry + */ + fputs(l_arg, fp); + } + +end_entry: + fputc(NL, fp); +} + +/** + * print an option's value + * + * @param[in] fp the file pointer for the save file + * @param[in] od the option descriptor to print + */ +static void +prt_value(FILE * fp, int depth, tOptDesc * od, tOptionValue const * ovp) +{ + while (--depth >= 0) + putc(' ', fp), putc(' ', fp); + + switch (ovp->valType) { + default: + case OPARG_TYPE_NONE: + fprintf(fp, NULL_ATR_FMT, ovp->pzName); + break; + + case OPARG_TYPE_STRING: + prt_string(fp, ovp->pzName, ovp->v.strVal); + break; + + case OPARG_TYPE_ENUMERATION: + case OPARG_TYPE_MEMBERSHIP: + if (od != NULL) { + uint32_t opt_state = od->fOptState; + uintptr_t val = od->optArg.argEnum; + char const * typ = (ovp->valType == OPARG_TYPE_ENUMERATION) + ? "keyword" : "set-membership"; + + fprintf(fp, TYPE_ATR_FMT, ovp->pzName, typ); + + /* + * This is a magic incantation that will convert the + * bit flag values back into a string suitable for printing. + */ + (*(od->pOptProc))(OPTPROC_RETURN_VALNAME, od ); + if (od->optArg.argString != NULL) { + fputs(od->optArg.argString, fp); + + if (ovp->valType != OPARG_TYPE_ENUMERATION) { + /* + * set membership strings get allocated + */ + AGFREE(od->optArg.argString); + } + } + + od->optArg.argEnum = val; + od->fOptState = opt_state; + fprintf(fp, END_XML_FMT, ovp->pzName); + break; + } + /* FALLTHROUGH */ + + case OPARG_TYPE_NUMERIC: + fprintf(fp, NUMB_ATR_FMT, ovp->pzName, ovp->v.longVal); + break; + + case OPARG_TYPE_BOOLEAN: + fprintf(fp, BOOL_ATR_FMT, ovp->pzName, + ovp->v.boolVal ? "true" : "false"); + break; + + case OPARG_TYPE_HIERARCHY: + prt_val_list(fp, ovp->pzName, ovp->v.nestVal); + break; + } +} + +/** + * Print a string value in XML format + * + * @param[in] fp the file pointer for the save file + */ +static void +prt_string(FILE * fp, char const * name, char const * pz) +{ + fprintf(fp, OPEN_XML_FMT, name); + for (;;) { + int ch = ((int)*(pz++)) & 0xFF; + + switch (ch) { + case NUL: goto string_done; + + case '&': + case '<': + case '>': +#if __GNUC__ >= 4 + case 1 ... (' ' - 1): + case ('~' + 1) ... 0xFF: +#endif + emit_special_char(fp, ch); + break; + + default: +#if __GNUC__ < 4 + if ( ((ch >= 1) && (ch <= (' ' - 1))) + || ((ch >= ('~' + 1)) && (ch <= 0xFF)) ) { + emit_special_char(fp, ch); + break; + } +#endif + putc(ch, fp); + } + } string_done:; + fprintf(fp, END_XML_FMT, name); +} + +/** + * Print an option that can have multiple values in XML format + * + * @param[in] fp file pointer + */ +static void +prt_val_list(FILE * fp, char const * name, tArgList * al) +{ + static int depth = 1; + + int sp_ct; + int opt_ct; + void ** opt_list; + + if (al == NULL) + return; + opt_ct = al->useCt; + opt_list = (void **)al->apzArgs; + + if (opt_ct <= 0) { + fprintf(fp, OPEN_CLOSE_FMT, name); + return; + } + + fprintf(fp, NESTED_OPT_FMT, name); + + depth++; + while (--opt_ct >= 0) { + tOptionValue const * ovp = *(opt_list++); + + prt_value(fp, depth, NULL, ovp); + } + depth--; + + for (sp_ct = depth; --sp_ct >= 0;) + putc(' ', fp), putc(' ', fp); + fprintf(fp, "\n", name); +} + +/** + * printed a nested/hierarchical value + * + * @param[in] fp file pointer + * @param[in] od option descriptor + * @param[in] save_fl include usage in comments + */ +static void +prt_nested(FILE * fp, tOptDesc * od, save_flags_mask_t save_fl) +{ + int opt_ct; + tArgList * al = od->optCookie; + void ** opt_list; + + if (save_fl & SVFL_USAGE) + fprintf(fp, ao_name_use_fmt, od->pz_Name, od->pzText); + + /* + * Never show a default value if a hierarchical value is empty. + */ + if (UNUSED_OPT(od) || (al == NULL)) + return; + + opt_ct = al->useCt; + opt_list = (void **)al->apzArgs; + + if (opt_ct <= 0) + return; + + do { + tOptionValue const * base = *(opt_list++); + tOptionValue const * ovp = optionGetValue(base, NULL); + + if (ovp == NULL) + continue; + + fprintf(fp, NESTED_OPT_FMT, od->pz_Name); + + do { + prt_value(fp, 1, od, ovp); + + } while (ovp = optionNextValue(base, ovp), + ovp != NULL); + + fprintf(fp, "\n", od->pz_Name); + } while (--opt_ct > 0); +} + +/** + * remove the current program settings + * + * @param[in] opts the program options structure + * @param[in] fname the save file name + */ +static void +remove_settings(tOptions * opts, char const * fname) +{ + size_t const name_len = strlen(opts->pzProgName); + tmap_info_t map_info; + char * text = text_mmap(fname, PROT_READ|PROT_WRITE, MAP_PRIVATE, &map_info); + char * scan = text; + + for (;;) { + char * next = scan = strstr(scan, zCfgProg); + if (scan == NULL) + goto leave; + + scan = SPN_WHITESPACE_CHARS(scan + zCfgProg_LEN); + if ( (strneqvcmp(scan, opts->pzProgName, (int)name_len) == 0) + && (IS_END_XML_TOKEN_CHAR(scan[name_len])) ) { + + scan = next; + break; + } + } + + /* + * If not NULL, "scan" points to the "pzProgName, fname); + fprintf(stderr, zNoCreat, errno, strerror(errno), fname); + if (free_name) + AGFREE(fname); + return fp; + } + + if (free_name) + AGFREE(fname); + } + + do { + struct stat sbuf; + if (fstat(fileno(fp), &sbuf) < 0) + break; + + if (sbuf.st_size > zPresetFile_LEN) { + /* non-zero size implies save_fl is non-zero */ + fprintf(fp, zFmtProg, opts->pzProgName); + return fp; + } + } while (false); + + /* + * We have a new file. Insert a header + */ + fputs("# ", fp); + { + char const * e = strchr(opts->pzUsageTitle, NL); + if (e++ != NULL) + fwrite(opts->pzUsageTitle, 1, e - opts->pzUsageTitle, fp); + } + + { + time_t cur_time = time(NULL); + char * time_str = ctime(&cur_time); + + fprintf(fp, zPresetFile, time_str); +#ifdef HAVE_ALLOCATED_CTIME + /* + * The return values for ctime(), localtime(), and gmtime() + * normally point to static data that is overwritten by each call. + * The test to detect allocated ctime, so we leak the memory. + */ + AGFREE(time_str); +#endif + } + if (save_fl != 0) + fprintf(fp, zFmtProg, opts->pzProgName); + return fp; +} + +/** + * print option without an arg + * + * @param[in] fp file pointer + * @param[in] vod value option descriptor + * @param[in] pod primary option descriptor + * @param[in] save_fl include usage in comments + */ +static void +prt_no_arg_opt(FILE * fp, tOptDesc * vod, tOptDesc * pod, save_flags_mask_t save_fl) +{ + /* + * The aliased to argument indicates whether or not the option + * is "disabled". However, the original option has the name + * string, so we get that there, not with "vod". + */ + char const * pznm = + (DISABLED_OPT(vod)) ? pod->pz_DisableName : pod->pz_Name; + /* + * If the option was disabled and the disablement name is NULL, + * then the disablement was caused by aliasing. + * Use the name as the string to emit. + */ + if (pznm == NULL) + pznm = pod->pz_Name; + + if (save_fl & SVFL_USAGE) + fprintf(fp, ao_name_use_fmt, pod->pz_Name, pod->pzText); + if (UNUSED_OPT(pod) && (save_fl & SVFL_DEFAULT)) + fputs(ao_default_use, fp); + + fprintf(fp, "%s\n", pznm); +} + +/** + * print the string valued argument(s). + * + * @param[in] fp file pointer + * @param[in] od value option descriptor + * @param[in] save_fl include usage in comments + */ +static void +prt_str_arg(FILE * fp, tOptDesc * od, save_flags_mask_t save_fl) +{ + if (UNUSED_OPT(od) || ((od->fOptState & OPTST_STACKED) == 0)) { + char const * arg = od->optArg.argString; + if (arg == NULL) + arg = "''"; + prt_entry(fp, od, arg, save_fl); + + } else { + tArgList * pAL = (tArgList *)od->optCookie; + int uct = pAL->useCt; + char const ** ppz = pAL->apzArgs; + + /* + * un-disable multiple copies of disabled options. + */ + if (uct > 1) + od->fOptState &= ~OPTST_DISABLED; + + while (uct-- > 0) { + prt_entry(fp, od, *(ppz++), save_fl); + save_fl &= ~SVFL_USAGE; + } + } +} + +/** + * print the string value of an enumeration. + * + * @param[in] fp the file pointer to write to + * @param[in] od the option descriptor with the enumerated value + * @param[in] save_fl include usage in comments + */ +static void +prt_enum_arg(FILE * fp, tOptDesc * od, save_flags_mask_t save_fl) +{ + uintptr_t val = od->optArg.argEnum; + + /* + * This is a magic incantation that will convert the + * bit flag values back into a string suitable for printing. + */ + (*(od->pOptProc))(OPTPROC_RETURN_VALNAME, od); + prt_entry(fp, od, VOIDP(od->optArg.argString), save_fl); + + od->optArg.argEnum = val; +} + +/** + * Print the bits set in a bit mask option. + * + * We call the option handling function with a magic value for + * the options pointer and it allocates and fills in the string. + * We print that with a call to prt_entry(). + * + * @param[in] fp the file pointer to write to + * @param[in] od the option descriptor with a bit mask value type + * @param[in] save_fl include usage in comments + */ +static void +prt_set_arg(FILE * fp, tOptDesc * od, save_flags_mask_t save_fl) +{ + char * list = optionMemberList(od); + size_t len = strlen(list); + char * buf = (char *)AGALOC(len + 3, "dir name"); + *buf= '='; + memcpy(buf+1, list, len + 1); + prt_entry(fp, od, buf, save_fl); + AGFREE(buf); + AGFREE(list); +} + +/** + * figure out what the option file name argument is. + * If one can be found, call prt_entry() to emit it. + * + * @param[in] fp the file pointer to write to. + * @param[in] od the option descriptor with a bit mask value type + * @param[in] opts the program options descriptor + * @param[in] save_fl include usage in comments + */ +static void +prt_file_arg(FILE * fp, tOptDesc * od, tOptions * opts, save_flags_mask_t save_fl) +{ + /* + * If the cookie is not NULL, then it has the file name, period. + * Otherwise, if we have a non-NULL string argument, then.... + */ + if (od->optCookie != NULL) + prt_entry(fp, od, od->optCookie, save_fl); + + else if (HAS_originalOptArgArray(opts)) { + char const * orig = + opts->originalOptArgArray[od->optIndex].argString; + + if (od->optArg.argString == orig) { + if (save_fl) + fprintf(fp, ao_name_use_fmt, od->pz_Name, od->pzText); + return; + } + + prt_entry(fp, od, od->optArg.argString, save_fl); + + } else if (save_fl) + fprintf(fp, ao_name_use_fmt, od->pz_Name, od->pzText); +} + +/*=export_func optionSaveFile + * + * what: saves the option state to a file + * + * arg: tOptions *, opts, program options descriptor + * + * doc: + * + * This routine will save the state of option processing to a file. The name + * of that file can be specified with the argument to the @code{--save-opts} + * option, or by appending the @code{rcfile} attribute to the last + * @code{homerc} attribute. If no @code{rcfile} attribute was specified, it + * will default to @code{.@i{programname}rc}. If you wish to specify another + * file, you should invoke the @code{SET_OPT_SAVE_OPTS(@i{filename})} macro. + * + * The recommend usage is as follows: + * @example + * optionProcess(&progOptions, argc, argv); + * if (i_want_a_non_standard_place_for_this) + * SET_OPT_SAVE_OPTS("myfilename"); + * optionSaveFile(&progOptions); + * @end example + * + * err: + * + * If no @code{homerc} file was specified, this routine will silently return + * and do nothing. If the output file cannot be created or updated, a message + * will be printed to @code{stderr} and the routine will return. +=*/ +void +optionSaveFile(tOptions * opts) +{ + tOptDesc * od; + int ct; + FILE * fp; + save_flags_mask_t save_flags = SVFL_NONE; + + do { + char * temp_str; + char const * dir = opts->pOptDesc[ opts->specOptIdx.save_opts ].optArg.argString; + size_t flen; + + if (dir == NULL) + break; + temp_str = strchr(dir, '>'); + if (temp_str == NULL) + break; + if (temp_str[1] == '>') + save_flags = SVFL_UPDATE; + flen = (temp_str - dir); + if (flen == 0) + break; + temp_str = AGALOC(flen + 1, "flag search str"); + memcpy(temp_str, dir, flen); + temp_str[flen] = NUL; + save_flags |= save_flags_str2mask(temp_str, SVFL_NONE); + AGFREE(temp_str); + } while (false); + + fp = open_sv_file(opts, save_flags & SVFL_UPDATE); + if (fp == NULL) + return; + + /* + * FOR each of the defined options, ... + */ + ct = opts->presetOptCt; + od = opts->pOptDesc; + do { + tOptDesc * vod; + + /* + * Equivalenced options get picked up when the equivalenced-to + * option is processed. And do not save options with any state + * bits in the DO_NOT_SAVE collection + * + * ** option cannot be preset + * #define OPTST_NO_INIT 0x0000100U + * ** disable from cmd line + * #define OPTST_NO_COMMAND 0x2000000U + * ** alias for other option + * #define OPTST_ALIAS 0x8000000U + */ + if ((od->fOptState & OPTST_DO_NOT_SAVE_MASK) != 0) + continue; + + if ( (od->optEquivIndex != NO_EQUIVALENT) + && (od->optEquivIndex != od->optIndex)) + continue; + + if (UNUSED_OPT(od) && ((save_flags & SVFL_USAGE_DEFAULT_MASK) == SVFL_NONE)) + continue; + + /* + * The option argument data are found at the equivalenced-to option, + * but the actual option argument type comes from the original + * option descriptor. Be careful! + */ + vod = ((od->fOptState & OPTST_EQUIVALENCE) != 0) + ? (opts->pOptDesc + od->optActualIndex) : od; + + switch (OPTST_GET_ARGTYPE(od->fOptState)) { + case OPARG_TYPE_NONE: + prt_no_arg_opt(fp, vod, od, save_flags); + break; + + case OPARG_TYPE_NUMERIC: + prt_entry(fp, vod, VOIDP(vod->optArg.argInt), save_flags); + break; + + case OPARG_TYPE_STRING: + prt_str_arg(fp, vod, save_flags); + break; + + case OPARG_TYPE_ENUMERATION: + prt_enum_arg(fp, vod, save_flags); + break; + + case OPARG_TYPE_MEMBERSHIP: + prt_set_arg(fp, vod, save_flags); + break; + + case OPARG_TYPE_BOOLEAN: + prt_entry(fp, vod, vod->optArg.argBool ? "true" : "false", save_flags); + break; + + case OPARG_TYPE_HIERARCHY: + prt_nested(fp, vod, save_flags); + break; + + case OPARG_TYPE_FILE: + prt_file_arg(fp, vod, opts, save_flags); + break; + + default: + break; /* cannot handle - skip it */ + } + } while (od++, (--ct > 0)); + + fclose(fp); +} +/** @} + * + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of autoopts/save.c */ diff --git a/autoopts/sort.c b/autoopts/sort.c new file mode 100644 index 0000000..b4bd5cb --- /dev/null +++ b/autoopts/sort.c @@ -0,0 +1,326 @@ + +/* + * \file sort.c + * + * This module implements argument sorting. + * + * @addtogroup autoopts + * @{ + */ +/* + * This file is part of AutoOpts, a companion to AutoGen. + * AutoOpts is free software. + * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoOpts is available under any one of two licenses. The license + * in use must be one of these two and the choice is under the control + * of the user of the license. + * + * The GNU Lesser General Public License, version 3 or later + * See the files "COPYING.lgplv3" and "COPYING.gplv3" + * + * The Modified Berkeley Software Distribution License + * See the file "COPYING.mbsd" + * + * These files have the following sha256 sums: + * + * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 + * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 + * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + */ + +/* + * "must_arg" and "maybe_arg" are really similar. The biggest + * difference is that "may" will consume the next argument only if it + * does not start with a hyphen and "must" will consume it, hyphen or not. + */ +static tSuccess +must_arg(tOptions * opts, char * arg_txt, tOptState * pOS, + char ** opt_txt, uint32_t * opt_idx) +{ + /* + * An option argument is required. Long options can either have + * a separate command line argument, or an argument attached by + * the '=' character. Figure out which. + */ + switch (pOS->optType) { + case TOPT_SHORT: + /* + * See if an arg string follows the flag character. If not, + * the next arg must be the option argument. + */ + if (*arg_txt != NUL) + return SUCCESS; + break; + + case TOPT_LONG: + /* + * See if an arg string has already been assigned (glued on + * with an `=' character). If not, the next is the opt arg. + */ + if (pOS->pzOptArg != NULL) + return SUCCESS; + break; + + default: + return FAILURE; + } + if (opts->curOptIdx >= opts->origArgCt) + return FAILURE; + + opt_txt[ (*opt_idx)++ ] = opts->origArgVect[ (opts->curOptIdx)++ ]; + return SUCCESS; +} + +static tSuccess +maybe_arg(tOptions * opts, char * arg_txt, tOptState * pOS, + char ** opt_txt, uint32_t * opt_idx) +{ + /* + * An option argument is optional. + */ + switch (pOS->optType) { + case TOPT_SHORT: + /* + * IF nothing is glued on after the current flag character, + * THEN see if there is another argument. If so and if it + * does *NOT* start with a hyphen, then it is the option arg. + */ + if (*arg_txt != NUL) + return SUCCESS; + break; + + case TOPT_LONG: + /* + * Look for an argument if we don't already have one (glued on + * with a `=' character) + */ + if (pOS->pzOptArg != NULL) + return SUCCESS; + break; + + default: + return FAILURE; + } + if (opts->curOptIdx >= opts->origArgCt) + return PROBLEM; + + arg_txt = opts->origArgVect[ opts->curOptIdx ]; + if (*arg_txt != '-') + opt_txt[ (*opt_idx)++ ] = opts->origArgVect[ (opts->curOptIdx)++ ]; + return SUCCESS; +} + +/* + * Process a string of short options glued together. If the last one + * does or may take an argument, the do the argument processing and leave. + */ +static tSuccess +short_opt_ck(tOptions * opts, char * arg_txt, tOptState * pOS, + char ** opt_txt, uint32_t * opt_idx) +{ + while (*arg_txt != NUL) { + if (FAILED(opt_find_short(opts, (uint8_t)*arg_txt, pOS))) + return FAILURE; + + /* + * See if we can have an arg. + */ + if (OPTST_GET_ARGTYPE(pOS->pOD->fOptState) == OPARG_TYPE_NONE) { + arg_txt++; + + } else if (pOS->pOD->fOptState & OPTST_ARG_OPTIONAL) { + /* + * Take an argument if it is not attached and it does not + * start with a hyphen. + */ + if (arg_txt[1] != NUL) + return SUCCESS; + + arg_txt = opts->origArgVect[ opts->curOptIdx ]; + if (*arg_txt != '-') + opt_txt[ (*opt_idx)++ ] = + opts->origArgVect[ (opts->curOptIdx)++ ]; + return SUCCESS; + + } else { + /* + * IF we need another argument, be sure it is there and + * take it. + */ + if (arg_txt[1] == NUL) { + if (opts->curOptIdx >= opts->origArgCt) + return FAILURE; + opt_txt[ (*opt_idx)++ ] = + opts->origArgVect[ (opts->curOptIdx)++ ]; + } + return SUCCESS; + } + } + return SUCCESS; +} + +/* + * If the program wants sorted options (separated operands and options), + * then this routine will to the trick. + */ +static void +optionSort(tOptions * opts) +{ + char ** opt_txt; + char ** ppzOpds; + uint32_t optsIdx = 0; + uint32_t opdsIdx = 0; + + tOptState os = OPTSTATE_INITIALIZER(DEFINED); + + /* + * Disable for POSIX conformance, or if there are no operands. + */ + if ( (getenv("POSIXLY_CORRECT") != NULL) + || NAMED_OPTS(opts)) + return; + + /* + * Make sure we can allocate two full-sized arg vectors. + */ + opt_txt = malloc(opts->origArgCt * sizeof(char *)); + if (opt_txt == NULL) + goto exit_no_mem; + + ppzOpds = malloc(opts->origArgCt * sizeof(char *)); + if (ppzOpds == NULL) { + free(opt_txt); + goto exit_no_mem; + } + + opts->curOptIdx = 1; + opts->pzCurOpt = NULL; + + /* + * Now, process all the options from our current position onward. + * (This allows interspersed options and arguments for the few + * non-standard programs that require it.) + */ + for (;;) { + char * arg_txt; + tSuccess res; + + /* + * If we're out of arguments, we're done. Join the option and + * operand lists into the original argument vector. + */ + if (opts->curOptIdx >= opts->origArgCt) { + errno = 0; + goto joinLists; + } + + arg_txt = opts->origArgVect[ opts->curOptIdx ]; + if (*arg_txt != '-') { + ppzOpds[ opdsIdx++ ] = opts->origArgVect[ (opts->curOptIdx)++ ]; + continue; + } + + switch (arg_txt[1]) { + case NUL: + /* + * A single hyphen is an operand. + */ + ppzOpds[ opdsIdx++ ] = opts->origArgVect[ (opts->curOptIdx)++ ]; + continue; + + case '-': + /* + * Two consecutive hypens. Put them on the options list and then + * _always_ force the remainder of the arguments to be operands. + */ + if (arg_txt[2] == NUL) { + opt_txt[ optsIdx++ ] = + opts->origArgVect[ (opts->curOptIdx)++ ]; + goto restOperands; + } + res = opt_find_long(opts, arg_txt+2, &os); + break; + + default: + /* + * If short options are not allowed, then do long + * option processing. Otherwise the character must be a + * short (i.e. single character) option. + */ + if ((opts->fOptSet & OPTPROC_SHORTOPT) == 0) { + res = opt_find_long(opts, arg_txt+1, &os); + } else { + res = opt_find_short(opts, (uint8_t)arg_txt[1], &os); + } + break; + } + if (FAILED(res)) { + errno = EINVAL; + goto freeTemps; + } + + /* + * We've found an option. Add the argument to the option list. + * Next, we have to see if we need to pull another argument to be + * used as the option argument. + */ + opt_txt[ optsIdx++ ] = opts->origArgVect[ (opts->curOptIdx)++ ]; + + if (OPTST_GET_ARGTYPE(os.pOD->fOptState) == OPARG_TYPE_NONE) { + /* + * No option argument. If we have a short option here, + * then scan for short options until we get to the end + * of the argument string. + */ + if ( (os.optType == TOPT_SHORT) + && FAILED(short_opt_ck(opts, arg_txt+2, &os, opt_txt, + &optsIdx)) ) { + errno = EINVAL; + goto freeTemps; + } + + } else if (os.pOD->fOptState & OPTST_ARG_OPTIONAL) { + switch (maybe_arg(opts, arg_txt+2, &os, opt_txt, &optsIdx)) { + case FAILURE: errno = EIO; goto freeTemps; + case PROBLEM: errno = 0; goto joinLists; + } + + } else { + switch (must_arg(opts, arg_txt+2, &os, opt_txt, &optsIdx)) { + case PROBLEM: + case FAILURE: errno = EIO; goto freeTemps; + } + } + } /* for (;;) */ + + restOperands: + while (opts->curOptIdx < opts->origArgCt) + ppzOpds[ opdsIdx++ ] = opts->origArgVect[ (opts->curOptIdx)++ ]; + + joinLists: + if (optsIdx > 0) + memcpy(opts->origArgVect + 1, opt_txt, + (size_t)optsIdx * sizeof(char *)); + if (opdsIdx > 0) + memcpy(opts->origArgVect + 1 + optsIdx, ppzOpds, + (size_t)opdsIdx * sizeof(char *)); + + freeTemps: + free(opt_txt); + free(ppzOpds); + return; + + exit_no_mem: + errno = ENOMEM; + return; +} + +/** @} + * + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of autoopts/sort.c */ diff --git a/autoopts/stack.c b/autoopts/stack.c new file mode 100644 index 0000000..39a328a --- /dev/null +++ b/autoopts/stack.c @@ -0,0 +1,267 @@ + +/** + * \file stack.c + * + * This is a special option processing routine that will save the + * argument to an option in a FIFO queue. + * + * @addtogroup autoopts + * @{ + */ +/* + * This file is part of AutoOpts, a companion to AutoGen. + * AutoOpts is free software. + * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoOpts is available under any one of two licenses. The license + * in use must be one of these two and the choice is under the control + * of the user of the license. + * + * The GNU Lesser General Public License, version 3 or later + * See the files "COPYING.lgplv3" and "COPYING.gplv3" + * + * The Modified Berkeley Software Distribution License + * See the file "COPYING.mbsd" + * + * These files have the following sha256 sums: + * + * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 + * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 + * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + */ + +#ifdef WITH_LIBREGEX +# include REGEX_HEADER +#endif + +/*=export_func optionUnstackArg + * private: + * + * what: Remove option args from a stack + * arg: + tOptions * + opts + program options descriptor + + * arg: + tOptDesc * + od + the descriptor for this arg + + * + * doc: + * Invoked for options that are equivalenced to stacked options. +=*/ +void +optionUnstackArg(tOptions * opts, tOptDesc * od) +{ + tArgList * arg_list; + + if (INQUERY_CALL(opts, od)) + return; + + arg_list = (tArgList *)od->optCookie; + + /* + * IF we don't have any stacked options, + * THEN indicate that we don't have any of these options + */ + if (arg_list == NULL) { + od->fOptState &= OPTST_PERSISTENT_MASK; + if ((od->fOptState & OPTST_INITENABLED) == 0) + od->fOptState |= OPTST_DISABLED; + return; + } + +#ifdef WITH_LIBREGEX + { + regex_t re; + int i, ct, dIdx; + + if (regcomp(&re, od->optArg.argString, REG_NOSUB) != 0) + return; + + /* + * search the list for the entry(s) to remove. Entries that + * are removed are *not* copied into the result. The source + * index is incremented every time. The destination only when + * we are keeping a define. + */ + for (i = 0, dIdx = 0, ct = arg_list->useCt; --ct >= 0; i++) { + char const * pzSrc = arg_list->apzArgs[ i ]; + char * pzEq = strchr(pzSrc, '='); + int res; + + + if (pzEq != NULL) + *pzEq = NUL; + + res = regexec(&re, pzSrc, (size_t)0, NULL, 0); + switch (res) { + case 0: + /* + * Remove this entry by reducing the in-use count + * and *not* putting the string pointer back into + * the list. + */ + AGFREE(pzSrc); + arg_list->useCt--; + break; + + default: + case REG_NOMATCH: + if (pzEq != NULL) + *pzEq = '='; + + /* + * IF we have dropped an entry + * THEN we have to move the current one. + */ + if (dIdx != i) + arg_list->apzArgs[ dIdx ] = pzSrc; + dIdx++; + } + } + + regfree(&re); + } +#else /* not WITH_LIBREGEX */ + { + int i, ct, dIdx; + + /* + * search the list for the entry(s) to remove. Entries that + * are removed are *not* copied into the result. The source + * index is incremented every time. The destination only when + * we are keeping a define. + */ + for (i = 0, dIdx = 0, ct = arg_list->useCt; --ct >= 0; i++) { + const char * pzSrc = arg_list->apzArgs[ i ]; + char * pzEq = strchr(pzSrc, '='); + + if (pzEq != NULL) + *pzEq = NUL; + + if (strcmp(pzSrc, od->optArg.argString) == 0) { + /* + * Remove this entry by reducing the in-use count + * and *not* putting the string pointer back into + * the list. + */ + AGFREE(pzSrc); + arg_list->useCt--; + } else { + if (pzEq != NULL) + *pzEq = '='; + + /* + * IF we have dropped an entry + * THEN we have to move the current one. + */ + if (dIdx != i) + arg_list->apzArgs[ dIdx ] = pzSrc; + dIdx++; + } + } + } +#endif /* WITH_LIBREGEX */ + /* + * IF we have unstacked everything, + * THEN indicate that we don't have any of these options + */ + if (arg_list->useCt == 0) { + od->fOptState &= OPTST_PERSISTENT_MASK; + if ((od->fOptState & OPTST_INITENABLED) == 0) + od->fOptState |= OPTST_DISABLED; + AGFREE(arg_list); + od->optCookie = NULL; + } +} + + +/* + * Put an entry into an argument list. The first argument points to + * a pointer to the argument list structure. It gets passed around + * as an opaque address. + */ +static void +addArgListEntry(void ** ppAL, void * entry) +{ + tArgList * pAL = *(void **)ppAL; + + /* + * IF we have never allocated one of these, + * THEN allocate one now + */ + if (pAL == NULL) { + pAL = (tArgList *)AGALOC(sizeof(*pAL), "new option arg stack"); + if (pAL == NULL) + return; + pAL->useCt = 0; + pAL->allocCt = MIN_ARG_ALLOC_CT; + *ppAL = VOIDP(pAL); + } + + /* + * ELSE if we are out of room + * THEN make it bigger + */ + else if (pAL->useCt >= pAL->allocCt) { + size_t sz = sizeof(*pAL); + pAL->allocCt += INCR_ARG_ALLOC_CT; + + /* + * The base structure contains space for MIN_ARG_ALLOC_CT + * pointers. We subtract it off to find our augment size. + */ + sz += sizeof(char *) * ((size_t)pAL->allocCt - MIN_ARG_ALLOC_CT); + pAL = (tArgList *)AGREALOC(VOIDP(pAL), sz, "expanded opt arg stack"); + if (pAL == NULL) + return; + *ppAL = VOIDP(pAL); + } + + /* + * Insert the new argument into the list + */ + pAL->apzArgs[ (pAL->useCt)++ ] = entry; +} + + +/*=export_func optionStackArg + * private: + * + * what: put option args on a stack + * arg: + tOptions * + opts + program options descriptor + + * arg: + tOptDesc * + od + the descriptor for this arg + + * + * doc: + * Keep an entry-ordered list of option arguments. +=*/ +void +optionStackArg(tOptions * opts, tOptDesc * od) +{ + char * pz; + + if (INQUERY_CALL(opts, od)) + return; + + if ((od->fOptState & OPTST_RESET) != 0) { + tArgList * arg_list = od->optCookie; + int ix; + if (arg_list == NULL) + return; + + ix = arg_list->useCt; + while (--ix >= 0) + AGFREE(arg_list->apzArgs[ix]); + AGFREE(arg_list); + + } else { + if (od->optArg.argString == NULL) + return; + + AGDUPSTR(pz, od->optArg.argString, "stack arg"); + addArgListEntry(&(od->optCookie), VOIDP(pz)); + } +} +/** @} + * + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of autoopts/stack.c */ diff --git a/autoopts/stdnoreturn.in.h b/autoopts/stdnoreturn.in.h new file mode 100644 index 0000000..bf46c08 --- /dev/null +++ b/autoopts/stdnoreturn.in.h @@ -0,0 +1,60 @@ +/* A substitute for ISO C11 . + + Copyright 2012-2018 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.1, 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. */ + +#ifndef noreturn + +/* ISO C11 for platforms that lack it. + + References: + ISO C11 (latest free draft + ) + section 7.23 */ + +/* The definition of _Noreturn is copied here. */ + +#if 1200 <= _MSC_VER || defined __CYGWIN__ +/* On MSVC, standard include files contain declarations like + __declspec (noreturn) void abort (void); + "#define noreturn _Noreturn" would cause this declaration to be rewritten + to the invalid + __declspec (__declspec (noreturn)) void abort (void); + + Similarly, on Cygwin, standard include files contain declarations like + void __cdecl abort (void) __attribute__ ((noreturn)); + "#define noreturn _Noreturn" would cause this declaration to be rewritten + to the invalid + void __cdecl abort (void) __attribute__ ((__attribute__ ((__noreturn__)))); + + Instead, define noreturn to empty, so that such declarations are rewritten to + __declspec () void abort (void); + or + void __cdecl abort (void) __attribute__ (()); + respectively. This gives up on noreturn's advice to the compiler but at + least it is valid code. */ +# define noreturn /*empty*/ +#else +# define noreturn _Noreturn +#endif + +/* Did he ever return? + No he never returned + And his fate is still unlearn'd ... + -- Steiner J, Hawes BL. M.T.A. (1949) */ + +#endif /* noreturn */ diff --git a/autoopts/strequate.3 b/autoopts/strequate.3 new file mode 100644 index 0000000..362c439 --- /dev/null +++ b/autoopts/strequate.3 @@ -0,0 +1,32 @@ +.TH strequate 3 2018-08-26 "" "Programmer's Manual" +.\" DO NOT EDIT THIS FILE (strequate.3) +.\" +.\" It has been AutoGen-ed +.\" From the definitions ./funcs.def +.\" and the template file agman3.tpl +.SH NAME +strequate - map a list of characters to the same value +.sp 1 +.SH SYNOPSIS + +#include <\fIyour-opts.h\fP> +.br +cc [...] -o outfile infile.c -l\fBopts\fP [...] +.sp 1 +void \fBstrequate\fP(char const * \fIch_list\fP); +.sp 1 +.SH DESCRIPTION +Each character in the input string get mapped to the first character +in the string. +This function name is mapped to option_strequate so as to not conflict +with the POSIX name space. +.TP +.IR ch_list +characters to equivalence +.sp 1 +.SH ERRORS +none. +.SH SEE ALSO +The \fIinfo\fP documentation for the -l\fIopts\fP library. +.br +ao_string_tokenize(3), configFileLoad(3), optionFileLoad(3), optionFindNextValue(3), optionFindValue(3), optionFree(3), optionGetValue(3), optionLoadLine(3), optionMemberList(3), optionNextValue(3), optionOnlyUsage(3), optionPrintVersion(3), optionPrintVersionAndReturn(3), optionProcess(3), optionRestore(3), optionSaveFile(3), optionSaveState(3), optionUnloadNested(3), optionVersion(3), streqvcmp(3), streqvmap(3), strneqvcmp(3), strtransform(3), diff --git a/autoopts/streqvcmp.3 b/autoopts/streqvcmp.3 new file mode 100644 index 0000000..87b7ea2 --- /dev/null +++ b/autoopts/streqvcmp.3 @@ -0,0 +1,39 @@ +.TH streqvcmp 3 2018-08-26 "" "Programmer's Manual" +.\" DO NOT EDIT THIS FILE (streqvcmp.3) +.\" +.\" It has been AutoGen-ed +.\" From the definitions ./funcs.def +.\" and the template file agman3.tpl +.SH NAME +streqvcmp - compare two strings with an equivalence mapping +.sp 1 +.SH SYNOPSIS + +#include <\fIyour-opts.h\fP> +.br +cc [...] -o outfile infile.c -l\fBopts\fP [...] +.sp 1 +int \fBstreqvcmp\fP(char const * \fIstr1\fP, char const * \fIstr2\fP); +.sp 1 +.SH DESCRIPTION +Using a character mapping, two strings are compared for "equivalence". +Each input character is mapped to a comparison character and the +mapped-to characters are compared for the two NUL terminated input strings. +This function name is mapped to option_streqvcmp so as to not conflict +with the POSIX name space. +.TP +.IR str1 +first string +.TP +.IR str2 +second string +.sp 1 +.SH RETURN VALUE +the difference between two differing characters +.sp 1 +.SH ERRORS +none checked. Caller responsible for seg faults. +.SH SEE ALSO +The \fIinfo\fP documentation for the -l\fIopts\fP library. +.br +ao_string_tokenize(3), configFileLoad(3), optionFileLoad(3), optionFindNextValue(3), optionFindValue(3), optionFree(3), optionGetValue(3), optionLoadLine(3), optionMemberList(3), optionNextValue(3), optionOnlyUsage(3), optionPrintVersion(3), optionPrintVersionAndReturn(3), optionProcess(3), optionRestore(3), optionSaveFile(3), optionSaveState(3), optionUnloadNested(3), optionVersion(3), strequate(3), streqvmap(3), strneqvcmp(3), strtransform(3), diff --git a/autoopts/streqvcmp.c b/autoopts/streqvcmp.c new file mode 100644 index 0000000..53477d6 --- /dev/null +++ b/autoopts/streqvcmp.c @@ -0,0 +1,284 @@ + +/** + * \file streqvcmp.c + * + * String Equivalence Comparison + * + * These routines allow any character to be mapped to any other + * character before comparison. In processing long option names, + * the characters "-", "_" and "^" all need to be equivalent + * (because they are treated so by different development environments). + * + * @addtogroup autoopts + * @{ + */ +/* + * This file is part of AutoOpts, a companion to AutoGen. + * AutoOpts is free software. + * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoOpts is available under any one of two licenses. The license + * in use must be one of these two and the choice is under the control + * of the user of the license. + * + * The GNU Lesser General Public License, version 3 or later + * See the files "COPYING.lgplv3" and "COPYING.gplv3" + * + * The Modified Berkeley Software Distribution License + * See the file "COPYING.mbsd" + * + * These files have the following sha256 sums: + * + * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 + * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 + * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + * + * This array is designed for mapping upper and lower case letter + * together for a case independent comparison. The mappings are + * based upon ascii character sequences. + */ + static unsigned char charmap[] = { + NUL, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, '\a', + '\b', '\t', NL, '\v', '\f', '\r', 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, + + ' ', '!', '"', '#', '$', '%', '&', '\'', + '(', ')', '*', '+', ',', '-', '.', '/', + '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', ':', ';', '<', '=', '>', '?', + + '@', 'a', 'b', 'c', 'd', 'e', 'f', 'g', + 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', + 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', + 'x', 'y', 'z', '[', '\\', ']', '^', '_', + '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', + 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', + 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', + 'x', 'y', 'z', '{', '|', '}', '~', 0x7f, + + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, + 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, + 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, + 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, + 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, + 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, + + 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, + 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, + 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, + 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, + 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, + 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, + 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, + 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, +}; + + +/*=export_func strneqvcmp + * + * what: compare two strings with an equivalence mapping + * + * arg: + char const * + str1 + first string + + * arg: + char const * + str2 + second string + + * arg: + int + ct + compare length + + * + * ret_type: int + * ret_desc: the difference between two differing characters + * + * doc: + * + * Using a character mapping, two strings are compared for "equivalence". + * Each input character is mapped to a comparison character and the + * mapped-to characters are compared for the two NUL terminated input strings. + * The comparison is limited to @code{ct} bytes. + * This function name is mapped to option_strneqvcmp so as to not conflict + * with the POSIX name space. + * + * err: none checked. Caller responsible for seg faults. +=*/ +int +strneqvcmp(char const * s1, char const * s2, int ct) +{ + for (; ct > 0; --ct) { + unsigned char u1 = (unsigned char) *s1++; + unsigned char u2 = (unsigned char) *s2++; + int dif; + if (u1 == u2) { + if (u1 == NUL) + return 0; + continue; + } + + dif = charmap[ u1 ] - charmap[ u2 ]; + + if (dif != 0) + return dif; + + if (u1 == NUL) + return 0; + } + + return 0; +} + + +/*=export_func streqvcmp + * + * what: compare two strings with an equivalence mapping + * + * arg: + char const * + str1 + first string + + * arg: + char const * + str2 + second string + + * + * ret_type: int + * ret_desc: the difference between two differing characters + * + * doc: + * + * Using a character mapping, two strings are compared for "equivalence". + * Each input character is mapped to a comparison character and the + * mapped-to characters are compared for the two NUL terminated input strings. + * This function name is mapped to option_streqvcmp so as to not conflict + * with the POSIX name space. + * + * err: none checked. Caller responsible for seg faults. +=*/ +int +streqvcmp(char const * s1, char const * s2) +{ + for (;;) { + unsigned char u1 = (unsigned char) *s1++; + unsigned char u2 = (unsigned char) *s2++; + int dif; + if (u1 == u2) { + if (u1 == NUL) + return 0; + continue; + } + + dif = charmap[ u1 ] - charmap[ u2 ]; + + if (dif != 0) + return dif; + + if (u1 == NUL) + return 0; + } +} + + +/*=export_func streqvmap + * + * what: Set the character mappings for the streqv functions + * + * arg: + char + from + Input character + + * arg: + char + to + Mapped-to character + + * arg: + int + ct + compare length + + * + * doc: + * + * Set the character mapping. If the count (@code{ct}) is set to zero, then + * the map is cleared by setting all entries in the map to their index + * value. Otherwise, the "@code{From}" character is mapped to the "@code{To}" + * character. If @code{ct} is greater than 1, then @code{From} and @code{To} + * are incremented and the process repeated until @code{ct} entries have been + * set. For example, + * @example + * streqvmap('a', 'A', 26); + * @end example + * @noindent + * will alter the mapping so that all English lower case letters + * will map to upper case. + * + * This function name is mapped to option_streqvmap so as to not conflict + * with the POSIX name space. + * + * err: none. +=*/ +void +streqvmap(char from, char to, int ct) +{ + if (ct == 0) { + ct = sizeof(charmap) - 1; + do { + charmap[ct] = (unsigned char)ct; + } while (--ct >= 0); + } + + else { + unsigned int i_to = (int)to & 0xFF; + unsigned int i_from = (int)from & 0xFF; + + do { + charmap[i_from] = (unsigned char)i_to; + i_from++; + i_to++; + if ((i_from >= sizeof(charmap)) || (i_to >= sizeof(charmap))) + break; + } while (--ct > 0); + } +} + + +/*=export_func strequate + * + * what: map a list of characters to the same value + * + * arg: + char const * + ch_list + characters to equivalence + + * + * doc: + * + * Each character in the input string get mapped to the first character + * in the string. + * This function name is mapped to option_strequate so as to not conflict + * with the POSIX name space. + * + * err: none. +=*/ +void +strequate(char const * s) +{ + if ((s != NULL) && (*s != NUL)) { + unsigned char equiv = (unsigned char)*s; + while (*s != NUL) + charmap[(unsigned char)*(s++)] = equiv; + } +} + + +/*=export_func strtransform + * + * what: convert a string into its mapped-to value + * + * arg: + char * + dest + output string + + * arg: + char const * + src + input string + + * + * doc: + * + * Each character in the input string is mapped and the mapped-to + * character is put into the output. + * This function name is mapped to option_strtransform so as to not conflict + * with the POSIX name space. + * + * The source and destination may be the same. + * + * err: none. +=*/ +void +strtransform(char * d, char const * s) +{ + do { + *(d++) = (char)charmap[(unsigned char)*s]; + } while (*(s++) != NUL); +} + +/** @} + * + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of autoopts/streqvcmp.c */ diff --git a/autoopts/streqvmap.3 b/autoopts/streqvmap.3 new file mode 100644 index 0000000..a4aad67 --- /dev/null +++ b/autoopts/streqvmap.3 @@ -0,0 +1,48 @@ +.TH streqvmap 3 2018-08-26 "" "Programmer's Manual" +.\" DO NOT EDIT THIS FILE (streqvmap.3) +.\" +.\" It has been AutoGen-ed +.\" From the definitions ./funcs.def +.\" and the template file agman3.tpl +.SH NAME +streqvmap - Set the character mappings for the streqv functions +.sp 1 +.SH SYNOPSIS + +#include <\fIyour-opts.h\fP> +.br +cc [...] -o outfile infile.c -l\fBopts\fP [...] +.sp 1 +void \fBstreqvmap\fP(char \fIfrom\fP, char \fIto\fP, int \fIct\fP); +.sp 1 +.SH DESCRIPTION +Set the character mapping. If the count (\fBct\fP) is set to zero, then +the map is cleared by setting all entries in the map to their index +value. Otherwise, the "\fBFrom\fP" character is mapped to the "\fBTo\fP" +character. If \fBct\fP is greater than 1, then \fBFrom\fP and \fBTo\fP +are incremented and the process repeated until \fBct\fP entries have been +set. For example, +.nf + streqvmap('a', 'A', 26); +.fi +will alter the mapping so that all English lower case letters +will map to upper case. + +This function name is mapped to option_streqvmap so as to not conflict +with the POSIX name space. +.TP +.IR from +Input character +.TP +.IR to +Mapped-to character +.TP +.IR ct +compare length +.sp 1 +.SH ERRORS +none. +.SH SEE ALSO +The \fIinfo\fP documentation for the -l\fIopts\fP library. +.br +ao_string_tokenize(3), configFileLoad(3), optionFileLoad(3), optionFindNextValue(3), optionFindValue(3), optionFree(3), optionGetValue(3), optionLoadLine(3), optionMemberList(3), optionNextValue(3), optionOnlyUsage(3), optionPrintVersion(3), optionPrintVersionAndReturn(3), optionProcess(3), optionRestore(3), optionSaveFile(3), optionSaveState(3), optionUnloadNested(3), optionVersion(3), strequate(3), streqvcmp(3), strneqvcmp(3), strtransform(3), diff --git a/autoopts/strneqvcmp.3 b/autoopts/strneqvcmp.3 new file mode 100644 index 0000000..c123db9 --- /dev/null +++ b/autoopts/strneqvcmp.3 @@ -0,0 +1,43 @@ +.TH strneqvcmp 3 2018-08-26 "" "Programmer's Manual" +.\" DO NOT EDIT THIS FILE (strneqvcmp.3) +.\" +.\" It has been AutoGen-ed +.\" From the definitions ./funcs.def +.\" and the template file agman3.tpl +.SH NAME +strneqvcmp - compare two strings with an equivalence mapping +.sp 1 +.SH SYNOPSIS + +#include <\fIyour-opts.h\fP> +.br +cc [...] -o outfile infile.c -l\fBopts\fP [...] +.sp 1 +int \fBstrneqvcmp\fP(char const * \fIstr1\fP, char const * \fIstr2\fP, int \fIct\fP); +.sp 1 +.SH DESCRIPTION +Using a character mapping, two strings are compared for "equivalence". +Each input character is mapped to a comparison character and the +mapped-to characters are compared for the two NUL terminated input strings. +The comparison is limited to \fBct\fP bytes. +This function name is mapped to option_strneqvcmp so as to not conflict +with the POSIX name space. +.TP +.IR str1 +first string +.TP +.IR str2 +second string +.TP +.IR ct +compare length +.sp 1 +.SH RETURN VALUE +the difference between two differing characters +.sp 1 +.SH ERRORS +none checked. Caller responsible for seg faults. +.SH SEE ALSO +The \fIinfo\fP documentation for the -l\fIopts\fP library. +.br +ao_string_tokenize(3), configFileLoad(3), optionFileLoad(3), optionFindNextValue(3), optionFindValue(3), optionFree(3), optionGetValue(3), optionLoadLine(3), optionMemberList(3), optionNextValue(3), optionOnlyUsage(3), optionPrintVersion(3), optionPrintVersionAndReturn(3), optionProcess(3), optionRestore(3), optionSaveFile(3), optionSaveState(3), optionUnloadNested(3), optionVersion(3), strequate(3), streqvcmp(3), streqvmap(3), strtransform(3), diff --git a/autoopts/strtransform.3 b/autoopts/strtransform.3 new file mode 100644 index 0000000..01f6104 --- /dev/null +++ b/autoopts/strtransform.3 @@ -0,0 +1,37 @@ +.TH strtransform 3 2018-08-26 "" "Programmer's Manual" +.\" DO NOT EDIT THIS FILE (strtransform.3) +.\" +.\" It has been AutoGen-ed +.\" From the definitions ./funcs.def +.\" and the template file agman3.tpl +.SH NAME +strtransform - convert a string into its mapped-to value +.sp 1 +.SH SYNOPSIS + +#include <\fIyour-opts.h\fP> +.br +cc [...] -o outfile infile.c -l\fBopts\fP [...] +.sp 1 +void \fBstrtransform\fP(char * \fIdest\fP, char const * \fIsrc\fP); +.sp 1 +.SH DESCRIPTION +Each character in the input string is mapped and the mapped-to +character is put into the output. +This function name is mapped to option_strtransform so as to not conflict +with the POSIX name space. + +The source and destination may be the same. +.TP +.IR dest +output string +.TP +.IR src +input string +.sp 1 +.SH ERRORS +none. +.SH SEE ALSO +The \fIinfo\fP documentation for the -l\fIopts\fP library. +.br +ao_string_tokenize(3), configFileLoad(3), optionFileLoad(3), optionFindNextValue(3), optionFindValue(3), optionFree(3), optionGetValue(3), optionLoadLine(3), optionMemberList(3), optionNextValue(3), optionOnlyUsage(3), optionPrintVersion(3), optionPrintVersionAndReturn(3), optionProcess(3), optionRestore(3), optionSaveFile(3), optionSaveState(3), optionUnloadNested(3), optionVersion(3), strequate(3), streqvcmp(3), streqvmap(3), strneqvcmp(3), diff --git a/autoopts/test/Makefile.am b/autoopts/test/Makefile.am new file mode 100644 index 0000000..33633e4 --- /dev/null +++ b/autoopts/test/Makefile.am @@ -0,0 +1,55 @@ +## -*- Mode: Makefile -*- +## +## Makefile.am +## +## Author: Bruce Korb +## +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + +libsrc = libopts-@AO_CURRENT@.@AO_REVISION@.@AO_AGE@.tar.gz +EXTRA_DIST = defs.in stdopts.def $(TESTS) +TESTS = \ + alias.test argument.test cfg-edit.test cond.test \ + config.test doc.test enums.test equiv.test \ + errors.test getopt.test handler.test immediate.test \ + keyword.test library.test main.test nested.test \ + nls.test rc.test shell.test stdopts.test \ + time.test usage.test vendor.test vers.test + +getopt.test : ../$(libsrc) +../$(libsrc): + cd .. ; echo $(MAKE) $(libsrc) ; $(MAKE) $(libsrc) >/dev/null 2>&1 + +distclean-local: + @-rm -rf *-testd FAILURES + +check : perm-stamp + +perm-stamp : + @-cd $(srcdir) ; chmod +x *.test 2>/dev/null + +verbose : distclean-local + VERBOSE=true ; export VERBOSE ; \ + $(MAKE) check TESTS="$(TESTS)" + +.PHONY : distclean-local verbose perm-stamp + +# Makefile.am ends here diff --git a/autoopts/test/Makefile.in b/autoopts/test/Makefile.in new file mode 100644 index 0000000..9c45047 --- /dev/null +++ b/autoopts/test/Makefile.in @@ -0,0 +1,901 @@ +# Makefile.in generated by automake 1.16.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2018 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +subdir = autoopts/test +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/config/ag_macros.m4 \ + $(top_srcdir)/config/asm-underscore.m4 \ + $(top_srcdir)/config/extensions.m4 \ + $(top_srcdir)/config/guile.m4 \ + $(top_srcdir)/config/host-cpu-c-abi.m4 \ + $(top_srcdir)/config/lib-ld.m4 \ + $(top_srcdir)/config/lib-link.m4 \ + $(top_srcdir)/config/lib-prefix.m4 \ + $(top_srcdir)/config/libopts.m4 \ + $(top_srcdir)/config/libtool.m4 \ + $(top_srcdir)/config/ltoptions.m4 \ + $(top_srcdir)/config/ltsugar.m4 \ + $(top_srcdir)/config/ltversion.m4 \ + $(top_srcdir)/config/lt~obsolete.m4 \ + $(top_srcdir)/config/onceonly.m4 $(top_srcdir)/config/pkg.m4 \ + $(top_srcdir)/config/snprintfv.m4 \ + $(top_srcdir)/config/stdnoreturn.m4 \ + $(top_srcdir)/config/unlocked-io.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = defs +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +am__tty_colors_dummy = \ + mgn= red= grn= lgn= blu= brg= std=; \ + am__color_tests=no +am__tty_colors = { \ + $(am__tty_colors_dummy); \ + if test "X$(AM_COLOR_TESTS)" = Xno; then \ + am__color_tests=no; \ + elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ + am__color_tests=yes; \ + elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ + am__color_tests=yes; \ + fi; \ + if test $$am__color_tests = yes; then \ + red=''; \ + grn=''; \ + lgn=''; \ + blu=''; \ + mgn=''; \ + brg=''; \ + std=''; \ + fi; \ +} +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__recheck_rx = ^[ ]*:recheck:[ ]* +am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* +am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* +# A command that, given a newline-separated list of test names on the +# standard input, print the name of the tests that are to be re-run +# upon "make recheck". +am__list_recheck_tests = $(AWK) '{ \ + recheck = 1; \ + while ((rc = (getline line < ($$0 ".trs"))) != 0) \ + { \ + if (rc < 0) \ + { \ + if ((getline line2 < ($$0 ".log")) < 0) \ + recheck = 0; \ + break; \ + } \ + else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \ + { \ + recheck = 0; \ + break; \ + } \ + else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \ + { \ + break; \ + } \ + }; \ + if (recheck) \ + print $$0; \ + close ($$0 ".trs"); \ + close ($$0 ".log"); \ +}' +# A command that, given a newline-separated list of test names on the +# standard input, create the global log from their .trs and .log files. +am__create_global_log = $(AWK) ' \ +function fatal(msg) \ +{ \ + print "fatal: making $@: " msg | "cat >&2"; \ + exit 1; \ +} \ +function rst_section(header) \ +{ \ + print header; \ + len = length(header); \ + for (i = 1; i <= len; i = i + 1) \ + printf "="; \ + printf "\n\n"; \ +} \ +{ \ + copy_in_global_log = 1; \ + global_test_result = "RUN"; \ + while ((rc = (getline line < ($$0 ".trs"))) != 0) \ + { \ + if (rc < 0) \ + fatal("failed to read from " $$0 ".trs"); \ + if (line ~ /$(am__global_test_result_rx)/) \ + { \ + sub("$(am__global_test_result_rx)", "", line); \ + sub("[ ]*$$", "", line); \ + global_test_result = line; \ + } \ + else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \ + copy_in_global_log = 0; \ + }; \ + if (copy_in_global_log) \ + { \ + rst_section(global_test_result ": " $$0); \ + while ((rc = (getline line < ($$0 ".log"))) != 0) \ + { \ + if (rc < 0) \ + fatal("failed to read from " $$0 ".log"); \ + print line; \ + }; \ + printf "\n"; \ + }; \ + close ($$0 ".trs"); \ + close ($$0 ".log"); \ +}' +# Restructured Text title. +am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; } +# Solaris 10 'make', and several other traditional 'make' implementations, +# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it +# by disabling -e (using the XSI extension "set +e") if it's set. +am__sh_e_setup = case $$- in *e*) set +e;; esac +# Default flags passed to test drivers. +am__common_driver_flags = \ + --color-tests "$$am__color_tests" \ + --enable-hard-errors "$$am__enable_hard_errors" \ + --expect-failure "$$am__expect_failure" +# To be inserted before the command running the test. Creates the +# directory for the log if needed. Stores in $dir the directory +# containing $f, in $tst the test, in $log the log. Executes the +# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and +# passes TESTS_ENVIRONMENT. Set up options for the wrapper that +# will run the test scripts (or their associated LOG_COMPILER, if +# thy have one). +am__check_pre = \ +$(am__sh_e_setup); \ +$(am__vpath_adj_setup) $(am__vpath_adj) \ +$(am__tty_colors); \ +srcdir=$(srcdir); export srcdir; \ +case "$@" in \ + */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \ + *) am__odir=.;; \ +esac; \ +test "x$$am__odir" = x"." || test -d "$$am__odir" \ + || $(MKDIR_P) "$$am__odir" || exit $$?; \ +if test -f "./$$f"; then dir=./; \ +elif test -f "$$f"; then dir=; \ +else dir="$(srcdir)/"; fi; \ +tst=$$dir$$f; log='$@'; \ +if test -n '$(DISABLE_HARD_ERRORS)'; then \ + am__enable_hard_errors=no; \ +else \ + am__enable_hard_errors=yes; \ +fi; \ +case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ + am__expect_failure=yes;; \ + *) \ + am__expect_failure=no;; \ +esac; \ +$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT) +# A shell command to get the names of the tests scripts with any registered +# extension removed (i.e., equivalently, the names of the test logs, with +# the '.log' extension removed). The result is saved in the shell variable +# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly, +# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)", +# since that might cause problem with VPATH rewrites for suffix-less tests. +# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'. +am__set_TESTS_bases = \ + bases='$(TEST_LOGS)'; \ + bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ + bases=`echo $$bases` +RECHECK_LOGS = $(TEST_LOGS) +AM_RECURSIVE_TARGETS = check recheck +TEST_SUITE_LOG = test-suite.log +TEST_EXTENSIONS = @EXEEXT@ .test +am__test_logs1 = $(TESTS:=.log) +am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) +TEST_LOGS = $(am__test_logs2:.test.log=.log) +TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/config/test-driver +TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ + $(TEST_LOG_FLAGS) +am__set_b = \ + case '$@' in \ + */*) \ + case '$*' in \ + */*) b='$*';; \ + *) b=`echo '$@' | sed 's/\.log$$//'`; \ + esac;; \ + *) \ + b='$*';; \ + esac +am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/defs.in \ + $(top_srcdir)/config/test-driver +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AGEN5_TESTS = @AGEN5_TESTS@ +AG_LDFLAGS = @AG_LDFLAGS@ +AG_MAJOR_VERSION = @AG_MAJOR_VERSION@ +AG_MINOR_VERSION = @AG_MINOR_VERSION@ +AG_STATIC_AUTOGEN = @AG_STATIC_AUTOGEN@ +AG_TIMEOUT = @AG_TIMEOUT@ +AG_VERSION = @AG_VERSION@ +AG_XML2 = @AG_XML2@ +AGexe = @AGexe@ +AGnam = @AGnam@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AO_AGE = @AO_AGE@ +AO_CURRENT = @AO_CURRENT@ +AO_REVISION = @AO_REVISION@ +AO_TEMPLATE_VERSION = @AO_TEMPLATE_VERSION@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CLexe = @CLexe@ +CLnam = @CLnam@ +CONFIG_SHELL = @CONFIG_SHELL@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEBUG_ENABLED = @DEBUG_ENABLED@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +DYNAMIC_AG = @DYNAMIC_AG@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ENABLE_STATIC = @ENABLE_STATIC@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GDexe = @GDexe@ +GDnam = @GDnam@ +GO_AGE = @GO_AGE@ +GO_CURRENT = @GO_CURRENT@ +GO_REVISION = @GO_REVISION@ +GREP = @GREP@ +GUILE_CFLAGS = @GUILE_CFLAGS@ +GUILE_EFFECTIVE_VERSION = @GUILE_EFFECTIVE_VERSION@ +GUILE_LDFLAGS = @GUILE_LDFLAGS@ +GUILE_LIBS = @GUILE_LIBS@ +GUILE_LTLIBS = @GUILE_LTLIBS@ +HOST_CPU = @HOST_CPU@ +HOST_CPU_C_ABI = @HOST_CPU_C_ABI@ +INCLIST = @INCLIST@ +INCSNPRINTFV = @INCSNPRINTFV@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSNPRINTFV = @LIBSNPRINTFV@ +LIBTOOL = @LIBTOOL@ +LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ +LIBXML2_LIBS = @LIBXML2_LIBS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +M4_SRC = @M4_SRC@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPTS_TESTDIR = @OPTS_TESTDIR@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POSIX_SHELL = @POSIX_SHELL@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STDNORETURN_H = @STDNORETURN_H@ +STRIP = @STRIP@ +TEXI2HTML = @TEXI2HTML@ +VERSION = @VERSION@ +WARN_CFLAGS = @WARN_CFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_aux_dir = @ac_aux_dir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +libsrc = libopts-@AO_CURRENT@.@AO_REVISION@.@AO_AGE@.tar.gz +EXTRA_DIST = defs.in stdopts.def $(TESTS) +TESTS = \ + alias.test argument.test cfg-edit.test cond.test \ + config.test doc.test enums.test equiv.test \ + errors.test getopt.test handler.test immediate.test \ + keyword.test library.test main.test nested.test \ + nls.test rc.test shell.test stdopts.test \ + time.test usage.test vendor.test vers.test + +all: all-am + +.SUFFIXES: +.SUFFIXES: .log .test .test$(EXEEXT) .trs +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu autoopts/test/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu autoopts/test/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +defs: $(top_builddir)/config.status $(srcdir)/defs.in + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +tags TAGS: + +ctags CTAGS: + +cscope cscopelist: + + +# Recover from deleted '.trs' file; this should ensure that +# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create +# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells +# to avoid problems with "make -n". +.log.trs: + rm -f $< $@ + $(MAKE) $(AM_MAKEFLAGS) $< + +# Leading 'am--fnord' is there to ensure the list of targets does not +# expand to empty, as could happen e.g. with make check TESTS=''. +am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) +am--force-recheck: + @: + +$(TEST_SUITE_LOG): $(TEST_LOGS) + @$(am__set_TESTS_bases); \ + am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ + redo_bases=`for i in $$bases; do \ + am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \ + done`; \ + if test -n "$$redo_bases"; then \ + redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \ + redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \ + if $(am__make_dryrun); then :; else \ + rm -f $$redo_logs && rm -f $$redo_results || exit 1; \ + fi; \ + fi; \ + if test -n "$$am__remaking_logs"; then \ + echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ + "recursion detected" >&2; \ + elif test -n "$$redo_logs"; then \ + am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ + fi; \ + if $(am__make_dryrun); then :; else \ + st=0; \ + errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \ + for i in $$redo_bases; do \ + test -f $$i.trs && test -r $$i.trs \ + || { echo "$$errmsg $$i.trs" >&2; st=1; }; \ + test -f $$i.log && test -r $$i.log \ + || { echo "$$errmsg $$i.log" >&2; st=1; }; \ + done; \ + test $$st -eq 0 || exit 1; \ + fi + @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \ + ws='[ ]'; \ + results=`for b in $$bases; do echo $$b.trs; done`; \ + test -n "$$results" || results=/dev/null; \ + all=` grep "^$$ws*:test-result:" $$results | wc -l`; \ + pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \ + fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \ + skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \ + xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \ + xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \ + error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \ + if test `expr $$fail + $$xpass + $$error` -eq 0; then \ + success=true; \ + else \ + success=false; \ + fi; \ + br='==================='; br=$$br$$br$$br$$br; \ + result_count () \ + { \ + if test x"$$1" = x"--maybe-color"; then \ + maybe_colorize=yes; \ + elif test x"$$1" = x"--no-color"; then \ + maybe_colorize=no; \ + else \ + echo "$@: invalid 'result_count' usage" >&2; exit 4; \ + fi; \ + shift; \ + desc=$$1 count=$$2; \ + if test $$maybe_colorize = yes && test $$count -gt 0; then \ + color_start=$$3 color_end=$$std; \ + else \ + color_start= color_end=; \ + fi; \ + echo "$${color_start}# $$desc $$count$${color_end}"; \ + }; \ + create_testsuite_report () \ + { \ + result_count $$1 "TOTAL:" $$all "$$brg"; \ + result_count $$1 "PASS: " $$pass "$$grn"; \ + result_count $$1 "SKIP: " $$skip "$$blu"; \ + result_count $$1 "XFAIL:" $$xfail "$$lgn"; \ + result_count $$1 "FAIL: " $$fail "$$red"; \ + result_count $$1 "XPASS:" $$xpass "$$red"; \ + result_count $$1 "ERROR:" $$error "$$mgn"; \ + }; \ + { \ + echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ + $(am__rst_title); \ + create_testsuite_report --no-color; \ + echo; \ + echo ".. contents:: :depth: 2"; \ + echo; \ + for b in $$bases; do echo $$b; done \ + | $(am__create_global_log); \ + } >$(TEST_SUITE_LOG).tmp || exit 1; \ + mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ + if $$success; then \ + col="$$grn"; \ + else \ + col="$$red"; \ + test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ + fi; \ + echo "$${col}$$br$${std}"; \ + echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}"; \ + echo "$${col}$$br$${std}"; \ + create_testsuite_report --maybe-color; \ + echo "$$col$$br$$std"; \ + if $$success; then :; else \ + echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \ + if test -n "$(PACKAGE_BUGREPORT)"; then \ + echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ + fi; \ + echo "$$col$$br$$std"; \ + fi; \ + $$success || exit 1 + +check-TESTS: + @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list + @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list + @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + @set +e; $(am__set_TESTS_bases); \ + log_list=`for i in $$bases; do echo $$i.log; done`; \ + trs_list=`for i in $$bases; do echo $$i.trs; done`; \ + log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ + $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ + exit $$?; +recheck: all + @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + @set +e; $(am__set_TESTS_bases); \ + bases=`for i in $$bases; do echo $$i; done \ + | $(am__list_recheck_tests)` || exit 1; \ + log_list=`for i in $$bases; do echo $$i.log; done`; \ + log_list=`echo $$log_list`; \ + $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \ + am__force_recheck=am--force-recheck \ + TEST_LOGS="$$log_list"; \ + exit $$? +.test.log: + @p='$<'; \ + $(am__set_b); \ + $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +@am__EXEEXT_TRUE@.test$(EXEEXT).log: +@am__EXEEXT_TRUE@ @p='$<'; \ +@am__EXEEXT_TRUE@ $(am__set_b); \ +@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ +@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ +@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ +@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) check-TESTS +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) + -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) + -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-local + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: check-am install-am install-strip + +.PHONY: all all-am check check-TESTS check-am clean clean-generic \ + clean-libtool cscopelist-am ctags-am distclean \ + distclean-generic distclean-libtool distclean-local distdir \ + dvi dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am recheck tags-am \ + uninstall uninstall-am + +.PRECIOUS: Makefile + + +getopt.test : ../$(libsrc) +../$(libsrc): + cd .. ; echo $(MAKE) $(libsrc) ; $(MAKE) $(libsrc) >/dev/null 2>&1 + +distclean-local: + @-rm -rf *-testd FAILURES + +check : perm-stamp + +perm-stamp : + @-cd $(srcdir) ; chmod +x *.test 2>/dev/null + +verbose : distclean-local + VERBOSE=true ; export VERBOSE ; \ + $(MAKE) check TESTS="$(TESTS)" + +.PHONY : distclean-local verbose perm-stamp + +# Makefile.am ends here + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/autoopts/test/alias.test b/autoopts/test/alias.test new file mode 100755 index 0000000..b7195e6 --- /dev/null +++ b/autoopts/test/alias.test @@ -0,0 +1,119 @@ +#! /bin/sh +# +# alias.test --- test option aliasing +# +# Author: Bruce Korb +## +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + +. ./defs + +# # # # # # # # # # DEFINITIONS FILE # # # # # # # # # + +echo "creating ${testname}.def in `pwd`" +testname="${testname}" test_main="YES" \ +argument="arg [...]" long_opts="YES" use_flags=true \ +${SHELLX} ${stdopts} option:'opt init' second=020 || \ + failure "Could not run stdopts.def" +: add defs +cat >> ${testname}.def <<- \_EOF_ + + flag = { + name = a-opt; + value = a; + aliases = option; + }; + + flag = { + name = b-second; + value = b; + aliases = second; + }; + _EOF_ + +echo ${AG_L} ${testname}.def +${AG_L} ${testname}.def || \ + failure AutoGen could not process + +compile "-?" + +# # # # # # # # # # FIRST TEST # # # # # # # # # + +echo creating ${testname}-1.help +clean_help > ${testname}-1.help <<'_EOF_' +test_alias - Test AutoOpts for alias +Usage: alias [ - [] | --[{=| }] ]... arg [...] + Flg Arg Option-Name Description + -o Str option The option option descrip + -s Num second The second option descrip + -a Str a-opt an alias for the 'option' option + -b Num b-second an alias for the 'second' option + -? no help display extended usage information and exit + -! no more-help extended usage information passed thru pager + +Options are specified by doubled hyphens and their name or by a single +hyphen and the flag character. +_EOF_ + +cmp -s ${testname}-1.help ${testname}.help || \ + failure "`diff ${testname}-1.help ${testname}.help`" + +./${testname} -o foo -a bar && \ + failure "both -o and -a were accepted" + +./${testname} -a bar fumble > ${testname}.out +cat > ${testname}.base <<- \_EOF_ + OPTION_CT=2 + export OPTION_CT + TEST_ALIAS_OPTION='bar' + export TEST_ALIAS_OPTION + _EOF_ + +cmp -s ${testname}.out ${testname}.base || \ + failure "`diff ${testname}.out ${testname}.base`" + +run_ag als -T agtexi-cmd.tpl ${testname}.def +test -f invoke-test_${testname}.menu || \ + failure "no menu entry output" +rm -f invoke-test_${testname}.menu +test -f invoke-test_${testname}.texi || \ + failure "no texi output" +mv -f invoke-test_${testname}.texi ${testname}.texi + +run_ag als -T agmdoc-cmd.tpl ${testname}.def +test -f test_${testname}.1 || failure "no man page output" +mv test_${testname}.1 ${testname}.1 +lnct=` + ${EGREP} 'an alias for the .*(option|second).* option' \ + ${testname}.texi ${testname}.1 | \ + wc -l` +test $lnct -eq 4 || \ + failure "bad documentation output" + +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## End: + +# end of cond.test diff --git a/autoopts/test/argument.test b/autoopts/test/argument.test new file mode 100755 index 0000000..f3b0058 --- /dev/null +++ b/autoopts/test/argument.test @@ -0,0 +1,237 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# ---------------------------------------------------------------------- +# argument.test --- test argument program attribute +# make sure that when it is not specified +# then option processing consumes all args. +# +# Author: Bruce Korb +## +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd +# +# ---------------------------------------------------------------------- + +. ./defs + +# # # # # # # # # # DEFINITIONS FILE # # # # # # # # # + +echo "creating ${testname}.def in `pwd`" +export testname test_main argument long_opts +${SHELLX} ${stdopts} option:'opt init' second=020 || \ + failure "Could not run stdopts.def" + +${AG_L} ${testname}.def || \ + failure AutoGen could not process + +compile "-?" + +# # # # # # # # # # HELP OUTPUT FILE # # # # # # # # # + +basehlp=${testname}.hlp +echo creating ${basehlp} +clean_help > ${basehlp} <<'_EOF_' +test_argument - Test AutoOpts for argument +Usage: argument [ - [] ]... + Flg Arg Option-Name Description + -o Str option The option option descrip + -s Num second The second option descrip + -? no help display extended usage information and exit + -! no more-help extended usage information passed thru pager + +_EOF_ + +cmp -s ${testname}.h*lp || \ + failure "`diff ${basehlp} ${testname}.help`" + +./${testname} mumble 2> /dev/null && \ + failure ${testname} should not accept non-options + +./${testname} -s mumble 2> /dev/null && \ + failure ${testname} should not accept bad options + +./${testname} -o string -s 99 > /dev/null || \ + failure ${testname} did not handle its options + +# # # # # # # # # # T E S T 2 # # # # # # # # # # # + +exec 3> ${testname}2.def +${SED} '/arg-type = number/q' ${testname}.def >&3 +cat >&3 <<- _EOF_ + arg-range = "-1"; + arg-range = "3->021"; + arg-range = "040->0x1FFF"; + scaled; + flag-code[1] = ' /* no-op one */;'; + flag-code[0] = ' /* no-op zero */;'; + }; + include = '#include '; + _EOF_ +exec 3>&- + +${AG_L} ${testname}2.def || \ + failure AutoGen could not process +{ + ${SED} '/#if.*TEST-MAIN-PROCEDURE:/,/#endif.*END-TEST-MAIN/d + /^#/s/_ARGUMENT_/_ARGUMENT2_/' \ + ${testname}2.c + cat < XX +mv ${testname}2.c ${testname}2.c.save +mv -f XX ${testname}2.c + +Csrc=${testname}2 +compile "-?" + +clean_help > ${testname}2.hlp <<'_EOF_' +test_argument - Test AutoOpts for argument +Usage: argument2 [ - [] ]... + Flg Arg Option-Name Description + -o Str option The option option descrip + -s Num second The second option descrip + - is scalable with a suffix: k/K/m/M/g/G/t/T + - it must lie in one of the ranges: + -1 exactly, or + 3 to 17, or + 32 to 8191 + -? no help display extended usage information and exit + -! no more-help extended usage information passed thru pager + +_EOF_ + +cmp -s ${testname}2.hlp ${testname}2.help || \ + failure "`diff ${testname}2.hlp ${testname}2.help`" + +./${testname}2 -o string -s 037 > /dev/null && \ + failure ${testname} handled wrong sized option + +./${testname}2 -o string -s 0x37 > /dev/null || \ + failure ${testname} did not handle its options + +./${testname}2 -o string -s 8k > /dev/null || \ + failure ${testname} could not handle 8k + +./${testname}2 -o string -s 8K > ${testname}2-bad.out 2>&1 && \ + failure ${testname} did handle 8K + +${GREP} 'error:.* value .* is out of range\.$' ${testname}2-bad.out || \ + failure "missing 'is out of range' message" + +# # # # # # # # # # T E S T 3 # # # # # # # # # # # + +exec 3> ${testname}3.def +${SED} '/value = .s.;/q' ${testname}.def >&3 +cat >&3 <<- _EOF_ + arg-type = file; + file-exists = yes; + open-file = fopen; + file-mode = "r"; + }; + _EOF_ +exec 3>&- + +${AG_L} ${testname}3.def || \ + failure AutoGen could not process +{ + ${SED} '/^#if.*TEST MAIN PROCEDURE:/,/#endif.*defined TEST_/d + /^#/s/_ARGUMENT_/_ARGUMENT3_/' \ + ${testname}3.c + cat < XX +mv ${testname}3.c ${testname}3.c.save +mv -f XX ${testname}3.c + +Csrc=${testname}3 +compile "-?" + +clean_help > ${testname}3.hlp <<'_EOF_' +test_argument - Test AutoOpts for argument +Usage: argument3 [ - [] ]... + Flg Arg Option-Name Description + -o Str option The option option descrip + -s Fil second The second option descrip + - file must pre-exist + -? no help display extended usage information and exit + -! no more-help extended usage information passed thru pager + +_EOF_ + +cmp -s ${testname}3.hlp ${testname}3.help || \ + failure "`diff ${testname}3.hlp ${testname}3.help`" + +./${testname}3 -o string -s `pwd`/bogusfilename.c > /dev/null && \ + failure ${testname} handled non-existent file + +./${testname}3 -o string -s `pwd`/${testname}3.hlp > ${testname}3-a.hlp || \ + failure ${testname} could not handle existing file + +cmp -s ${testname}3.hlp ${testname}3-a.hlp || \ + failure "`diff ${testname}3.hlp ${testname}3-a.hlp`" +# # # # # # # # # # T E S T 4 # # # # # # # # # # # + +${SED} /arg-range/d ${testname}2.def > ${testname}4.def + +${AG_L} ${testname}4.def || \ + failure AutoGen could not process +${SED} -n '/^doOptSecond/,/^}/p' ${testname}4.c > ${testname}4.res +Csrc=${testname}4 +compile '-?' + +cat > ${testname}4.base <<- _EOF_ + doOptSecond(tOptions* pOptions, tOptDesc* pOptDesc) + { + /* + * Be sure the flag-code[0] handles special values for the options pointer + * viz. (poptions <= OPTPROC_EMIT_LIMIT) *and also* the special flag bit + * ((poptdesc->fOptState & OPTST_RESET) != 0) telling the option to + * reset its state. + */ + /* extracted from argument4.def, line 22 */ + /* no-op zero */; + optionNumericVal(pOptions, pOptDesc); + /* no-op one */; + } + _EOF_ + +cmp -s ${testname}4.base ${testname}4.res || \ + failure "`diff ${testname}4.base ${testname}4.res`" + +# # # # # # # # # # T E S T E N D # # # # # # # # # # + +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## End: + +# end of argument.test diff --git a/autoopts/test/cfg-edit.test b/autoopts/test/cfg-edit.test new file mode 100755 index 0000000..f0d7ffc --- /dev/null +++ b/autoopts/test/cfg-edit.test @@ -0,0 +1,330 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# +# cfg-edit.test --- test changing the configuration for a daemon process +# +# Author: Bruce Korb +## +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + +. ./defs + +# # # # # # # # # # DEFINITIONS FILE # # # # # # # # # + +cfg_file=`basename ${TMPDIR}`/${testname}.cfg + +exec 5> ${testname}.def +cat >&5 <<- _EOF_ + + AutoGen definitions options; + + config-header = 'config.h'; + prog-name = "test_${testname}"; + prog-title = "Test AutoOpts for ${testname}"; + homerc = ${cfg_file}; + resettable; + argument = '[ ]'; + + flag = { + name = struct; + value = s; + max = NOLIMIT; + descrip = 'structured argument val'; + arg-type = nested; + }; + + flag = { + name = members; + value = m; + descrip = 'membership set'; + keyword = one, two, three, four, five, six, seven, eight, nine, ten; + arg-default = five; + arg-type = set; + }; + + flag = { + name = enumerate; + value = e; + descrip = 'a test enumeration'; + keyword = uno, dos, tres, quatro, cinco, seis, siete, ocho; + arg-default = cinco; + arg-type = keyword; + }; + + flag = { + name = stacking; + value = k; + descrip = 'stack up a list'; + arg-default = initialized; + arg-type = string; + stack-arg; max = NOLIMIT; + }; + + flag = { + name = number; + value = n; + descrip = 'a range constrained int'; + arg-default = 32; + arg-type = number; + arg-range = '->-1', '1->31', '33', '64->'; + }; + + flag = { + name = boolean; + value = b; + descrip = 'a boolean value'; + arg-default = true; + arg-type = boolean; + }; + + flag = { + name = in-file; + value = I; + descrip = 'an input file'; + arg-type = file; + open-file = descriptor; + file-mode = O_RDONLY; + file-exists = yes; + }; + + flag = { + name = out-file; + value = O; + descrip = 'an output file'; + arg-type = file; + open-file = fopen; + file-mode = w; + file-exists = no; + }; + + flag = { + name = test-file; + value = T; + descrip = 'a test file'; + arg-type = file; + }; + + main = { + main-type = main; + _EOF_ + +asl='<''<' +cat >&5 <<- _EOF_ + main-text = ${asl}- _EOCode_ + { + tOptions * const pOpts = &test_${test_name}Options; + int svix = pOpts->specOptIdx.save_opts; + char const * pzFile = "${cfg_file}-default"; + + if (argc > 0) + pzFile = *argv; + if (svix == 0) exit(1); + SET_OPT_SAVE_OPTS(pzFile); + optionSaveFile(pOpts); + } + _EOF_ + +echo "_EOCode_; };" >&5 + +exec 5>&- + +# # # # # # # # # # CREATE PROGRAM # # # # # # # # # + +echo ${AG_L} ${testname}.def +${AG_L} ${testname}.def || \ + failure AutoGen could not process + +compile "-?" + +# # # # # # # # # # HELP OUTPUT FILE # # # # # # # # # + +basehelp=${testname}-base.help +echo creating ${basehelp} +clean_help > ${basehelp} <<_EOF_ +test_${testname} - Test AutoOpts for ${testname} +Usage: ${testname} [ - [] ]... [ ] + Flg Arg Option-Name Description + -s Cpx struct structured argument val + - may appear multiple times + -m Mbr members membership set + - is a set membership option + -e KWd enumerate a test enumeration + -k Str stacking stack up a list + - may appear multiple times + -n Num number a range constrained int + - it must lie in one of the ranges: + less than or equal to -1, or + 1 to 31, or + 33 exactly, or + greater than or equal to 64 + -b T/F boolean a boolean value + -I Fil in-file an input file + - file must pre-exist + -O Fil out-file an output file + - file must not pre-exist + -T Fil test-file a test file + -R Str reset-option reset an option's state + -? no help display extended usage information and exit + -! no more-help extended usage information passed thru pager + -> opt save-opts save the option state to a config file + -< Str load-opts load options from a config file + - disabled as '--no-load-opts' + - may appear multiple times + + +The following option preset mechanisms are supported: + - reading file ${testname}.cfg + +The valid "members" option keywords are: + one two three four five six seven eight nine ten + or an integer mask with any of the lower 10 bits set +or you may use a numeric representation. Preceding these with a '!' +will clear the bits, specifying 'none' will clear all bits, and 'all' +will set them all. Multiple entries may be passed as an option +argument list. +The valid "enumerate" option keywords are: + uno dos tres quatro cinco seis siete ocho + or an integer from 0 through 7 +_EOF_ + +${SED} "/ - reading file/s/ file .*/ file ${testname}.cfg/" \ + ${testname}.help > X$$ +mv -f X$$ ${testname}.help +pair="${basehelp} ${testname}.help" +cmp -s ${pair} || \ + failure "$testname help mismatch$nl`diff ${pair}`" + +rm -f ${testname}.cfg +./${testname} -m '+ one + three + seven' '->' +members=`${SED} -n 's/^members *= *=//p' ${cfg_file}` +case "${members}" in +'one + three + five + seven' ) : ;; +* ) failure "members not set to one, three, five and seven" ;; +esac + +./${testname} -R '*' '->' +members=`${SED} -n 's/^members *//p' ${cfg_file}` 2>/dev/null +case "${members}" in +'' ) : ;; +* ) failure "members entry not removed" +esac + +arg1="stumble, foo${ht}lish, 1234, able" +arg2='foo, 4321 one, two=2, three' +dir=`echo ${TMPDIR} | ${SED} "s@^\`pwd\`//*@@"` +out_file=${dir}/${testname}-out-file +rm -f ${out_file} +./${testname} -m 'one + three' -b true -m 'seven' \ + -s "${arg1}" -n -200 -s "${arg2}" -e ocho \ + -I ${srcdir}/${testname}.test \ + -O ${out_file} \ + -T ${dir}/${testname}-test-file \ + '->' +${SED} '/^#/d' ${cfg_file} > ${testname}-X +mv -f ${testname}-X ${cfg_file} +cat > ${testname}.sample-cfg <<- \_EOF_ + + + 0x4D2 + foo lish + + + + 0x10E1 + + + + + 2 + + + members = =one + three + five + seven + enumerate = ocho + number = -200 + boolean = true + _EOF_ + +cat >> ${testname}.sample-cfg <<- _EOF_ + in-file = ${srcdir}/${testname}.test + out-file = ${out_file} + test-file = ${dir}/${testname}-test-file + _EOF_ +pair=${testname}.sample-cfg\ ${cfg_file} +cmp ${pair} || \ + failure "improperly saved state:${nl}`diff ${pair}`" + +rm -f ${out_file} +./${testname} ${cfg_file}-2 +${SED} '/^#/d' ${cfg_file}-2 > ${testname}-X +mv -f ${testname}-X ${cfg_file}-2 +cmp ${cfg_file} ${cfg_file}-2 || \ + failure "mismatched: re-saved config${nl}`diff ${cfg_file} ${cfg_file}-2`" + +rm -f ${cfg_file}-2 +rm -f ${out_file} +./${testname} -R struct ${cfg_file}-2 +test "X`egrep -v '^#' ${cfg_file}-2`" = "X`egrep '^[a-z]' ${cfg_file}`" || \ + failure "structure not erased${nl}`cat ${cfg_file}-2`" + +opt_ct=7 +mv -f ${cfg_file}-2 ${cfg_file} +ct=`egrep '^[a-z]' ${cfg_file} | wc -l` +test ${ct} -eq ${opt_ct} || failure "wrong line count${nl}`cat ${cfg_file}`" + +rm -f ${out_file} + +remove_opt() { + opt_ct=`expr $opt_ct - 1` + ./${testname} -R ${1} '->' + ct=`egrep '^[a-z]' ${cfg_file} | wc -l` + test ${ct} -eq ${opt_ct} || \ + failure "${1} is still there${nl}`cat ${cfg_file}`" +} + +for f in out-file in-file test-file boolean members enumerate number +do + remove_opt $f +done + +./${testname} -k alpha -k beta -k omega ${cfg_file}-XX +${SED} '/^#/d' ${cfg_file}-XX > ${cfg_file}-2 +cat > ${cfg_file}-3 <<- _EOF_ + stacking = alpha + stacking = beta + stacking = omega + _EOF_ +cmp ${cfg_file}-[23] || \ + failure "missing stacking args:${nl}`diff -c ${cfg_file}-[23]`" +./${testname} -R k ${cfg_file}-2 +ct=`egrep '^[a-z]' ${cfg_file}-2 | wc -l` +test ${ct} -eq 0 || failure "arg values still stacked" + +# # # # # # # # # # TEST OPERATION # # # # # # # # # # + +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## End: + +# end of cfg-edit.test diff --git a/autoopts/test/cond.test b/autoopts/test/cond.test new file mode 100755 index 0000000..2324211 --- /dev/null +++ b/autoopts/test/cond.test @@ -0,0 +1,193 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# ---------------------------------------------------------------------- +# cond.test --- test conditionally compiled option +# +# Author: Bruce Korb +## +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd +# +# ---------------------------------------------------------------------- + +. ./defs + +# # # # # # # # # # DEFINITIONS FILE # # # # # # # # # + +echo "creating ${testname}.def in `pwd`" +testname="${testname}" test_main="${test_main}" \ +argument="${argument}" long_opts="${long_opts}" \ +${SHELLX} ${stdopts} option:'opt init' second=020 || \ + failure "Could not run stdopts.def" +cat >> ${testname}.def < ${testname}-1.help <<'_EOF_' +test_cond - Test AutoOpts for cond +Usage: cond [ - [] ]... + Flg Arg Option-Name Description + -o Str option The option option descrip + -s Num second The second option descrip + -I Num interfere cond interference test + -? no help display extended usage information and exit + -! no more-help extended usage information passed thru pager + +_EOF_ + +cmp -s ${testname}-1.help ${testname}.help || \ + failure "TEST 1 FAILED${nl}`diff ${testname}-1.help ${testname}.help`" + +./${testname}-1 -c 123 2>/dev/null && \ + failure "*DID* process -c option" + +# # # # # # # # # # SECOND TEST # # # # # # # # # + +INC="${INC} -DCOND=1" +compile "-?" +mv ${testname} ${testname}-2 +clean_help > ${testname}-2.help <<'_EOF_' +test_cond - Test AutoOpts for cond +Usage: cond [ - [] ]... + Flg Arg Option-Name Description + -o Str option The option option descrip + -s Num second The second option descrip + -c Num condition cond test + -I Num interfere cond interference test + -? no help display extended usage information and exit + -! no more-help extended usage information passed thru pager + +_EOF_ + +cmp -s ${testname}-2.help ${testname}.help || \ + failure "TEST 2 FAILED${nl}`diff ${testname}-2.help ${testname}.help`" + +# # # # # # # # # # THIRD TEST # # # # # # # # # + +echo guard-option-names\; >> ${testname}.def +echo ${AG_L} ${testname}.def +${AG_L} ${testname}.def || failure AutoGen could not process + +( cc_cmd=`echo ${cc_cmd} | \ + ${SED} "s/-DTEST_TEST/-DSECOND -DTEST_TEST/" ` + eval "$cc_cmd" 2>&1 ) \ + | ${SED} -n '/undefining SECOND due to option name conflict/p' \ + > ${testname}-cc.log + +test -s ${testname}-cc.log || \ + failure "warning diffs: 'undefining SECOND' not found" + +# # # # # # # # # # FOURTH TEST # # # # # # # # # + +${SED} '/value = c/s/$/ deprecated;/' ${testname}.def > ${testname}.def4 + +echo ${AG_L} ${testname}.def4 +${AG_L} ${testname}.def4 || \ + failure AutoGen could not process ${testname}.def4 + +compile "-?" +mv ${testname} ${testname}-4 +cmp -s ${testname}-1.help ${testname}.help || \ + failure "TEST 4 FAILED${nl}`diff ${testname}-1.help ${testname}.help`" + +./${testname}-4 -c 123 || \ + failure "could not process -c option" + +# # # # # # # # # # FIFTH TEST # # # # # # # # # + +${SED} '/deprecated/s/deprecated.*/arg-range = "0->1000";/' \ + ${testname}.def4 > ${testname}.def5 + +echo ${AG_L} ${testname}.def5 +${AG_L} ${testname}.def5 || \ + failure AutoGen could not process ${testname}.def5 + +compile "-?" +mv ${testname} ${testname}-5 +clean_help > ${testname}-5.help <<'_EOF_' +test_cond - Test AutoOpts for cond +Usage: cond [ - [] ]... + Flg Arg Option-Name Description + -o Str option The option option descrip + -s Num second The second option descrip + -c Num condition cond test + - it must be in the range: + 0 to 1000 + -I Num interfere cond interference test + -? no help display extended usage information and exit + -! no more-help extended usage information passed thru pager + +_EOF_ + +cmp -s ${testname}-5.help ${testname}.help || \ + failure "TEST 5 FAILED${nl}`diff -u ${testname}-5.help ${testname}.help`" + +# # # # # # # # # # SIXTH TEST # # # # # # # # # + +INC=`echo ${INC} | sed 's/ -DCOND=1//'` +compile "-?" +mv ${testname} ${testname}-6 +clean_help > ${testname}-6.help <<'_EOF_' +test_cond - Test AutoOpts for cond +Usage: cond [ - [] ]... + Flg Arg Option-Name Description + -o Str option The option option descrip + -s Num second The second option descrip + -I Num interfere cond interference test + -? no help display extended usage information and exit + -! no more-help extended usage information passed thru pager + +_EOF_ + +cmp -s ${testname}-6.help ${testname}.help || \ + failure "TEST 6 FAILED${nl}`diff -u ${testname}-6.help ${testname}.help`" + +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## End: + +# end of cond.test diff --git a/autoopts/test/config.test b/autoopts/test/config.test new file mode 100755 index 0000000..0b2b273 --- /dev/null +++ b/autoopts/test/config.test @@ -0,0 +1,200 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# ---------------------------------------------------------------------- +# rc.test --- test loading and saving of rc files +# +# Author: Bruce Korb +## +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd +# +# ---------------------------------------------------------------------- +. ./defs + +# # # # # # # # # # PROGRAM FILE # # # # # # # # # + +cat > ${testname}.c <<- _EOTest_ + #include + #include "config.h" + #include + + int print_entry( const tOptionValue* pGV ); + int print_entry( const tOptionValue* pGV ) { + if (pGV == NULL) { + fprintf( stderr, "ENTRY NOT FOUND\n" ); + return 1; + } + printf( "%-8s -- ", pGV->pzName ); + switch (pGV->valType) { + case OPARG_TYPE_NONE: + fputs( "no value\n", stdout ); break; + + case OPARG_TYPE_STRING: + printf( "string: %s\n", pGV->v.strVal ); break; + + case OPARG_TYPE_ENUMERATION: + printf( "enum: %d\n", pGV->v.enumVal ); break; + + case OPARG_TYPE_BOOLEAN: + printf( "bool: %s\n", + pGV->v.boolVal ? "TRUE" : "false" ); break; + + case OPARG_TYPE_MEMBERSHIP: + printf( "members: 0x%08lX\n", (unsigned long)pGV->v.setVal ); break; + + case OPARG_TYPE_NUMERIC: + printf( "integer: %ld\n", pGV->v.longVal ); break; + + case OPARG_TYPE_HIERARCHY: + printf( "nested: 0x%08lX\n", (unsigned long)pGV->v.nestVal ); break; + + default: + printf( "bad type: %d\n", pGV->valType ); + return 1; + } + return 0; + } + + int main( int argc, char** argv ) { + int res = 0; + const tOptionValue* pOV; + if ((argc < 3) || (argv[1][0] == '-')) { + fputs( "help\n", stdout ); + return 0; + } + pOV = configFileLoad( *++argv ); + if (pOV == NULL) { + fprintf( stderr, "Could not load: %s\n", *argv ); + return 1; + } + argc -= 2; + while (argc-- > 0) { + const tOptionValue* pGV = optionGetValue( pOV, *++argv ); + res |= print_entry( pGV ); + } + + { + const tOptionValue* pGV = optionGetValue( pOV, "n4_ty" ); + pGV = optionGetValue( pGV, "b4r" ); + if (pGV->valType != OPARG_TYPE_BOOLEAN) { + res = 1; + } else if (pGV->v.boolVal) { + fputs( "YES!!\n", stdout ); + } else { + fputs( "oops!!\n", stdout ); + res = 1; + } + } + + { + const tOptionValue* pGV = optionGetValue( pOV, NULL ); + while (pGV != NULL) { + res |= print_entry( pGV ); + pGV = optionNextValue( pOV, pGV ); + } + } + + print_entry( pOV ); + optionUnloadNested( pOV ); + return res; + } + _EOTest_ + +compile --help + +# # # # # # # # # # RUN TESTS # # # # # # # # # + +echo Constructing test ${testname} files +cat > ${testname}.cfg <<- \_EOConfig_ + mumble = grumble + grumble : rumble + + stumble "The\tquick\ + brown fox\tjumped\n\ + over everything." + + stumble2 The\ + quick\ + brown\ + \ + fix. + + + foo : foolish + YES!! + + alpha, beta ', gamma' + "Carol\tTine\n" + + 42 + _EOConfig_ + +cat > ${testname}.res <<- \_EOResult_ + mumble -- string: grumble + grumble -- string: rumble + stumble -- string: The quickbrown fox jumped + over everything. + alpha -- no value + beta -- string: , gamma + zzyzx -- integer: 42 + YES!! + alpha -- no value + beta -- string: , gamma + beta -- string: Carol Tine + + grumble -- string: rumble + mumble -- string: grumble + n4_ty -- nested: 0xXXXXXXXX + stumble -- string: The quickbrown fox jumped + over everything. + stumble2 -- string: The + quick + brown + + fix. + zzyzx -- integer: 42 + ./config.cfg -- nested: 0xXXXXXXXX + _EOResult_ + +./${testname} ./${testname}.cfg mumble grumble stumble alpha beta zzyzx \ + > ${testname}.tmp-out || { + failure "Cannot run ${testname}" +} + +${SED} '/ -- nested:/s/0x.*/0xXXXXXXXX/' \ + ${testname}.tmp-out > ${testname}.out +cmp ${testname}.out ${testname}.res || { + failure "`diff -c ${testname}.out ${testname}.res`" +} + +./${testname} ${testname}.cfg gamma >/dev/null && \ + failure "found non-existent value" + +# # # # # # # # # # CLEANUP # # # # # # # # # + +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## End: + +# end of config.test diff --git a/autoopts/test/defs.in b/autoopts/test/defs.in new file mode 100644 index 0000000..a026d89 --- /dev/null +++ b/autoopts/test/defs.in @@ -0,0 +1,392 @@ +#! /bin/echo this_file_should_be_sourced,_not_executed +# -*- Mode: Shell-script -*- +# +# defs --- define the environment for autogen tests. +# +# Author: Bruce Korb +# +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# +# C O N F I G U R E D V A L U E S +# +# Make sure srcdir is an absolute path. Supply the variable +# if it does not exist. We want to be able to run the tests +# stand-alone!! +# +cfg_vals() +{ + case `uname -s` in + SunOS ) + if test "X$BASH_VERSION" = X + then + # On Solaris, make certain we do not use /bin/sh + sh=`which bash` + test "X$sh" = X && sh=/usr/xpg4/bin/sh + BASH_VERSION=not-good-enough + export BASH_VERSION + exec $sh "$0" "$@" + fi + ;; + esac + + set -a + TESTS='' + builddir=`pwd` + progpid=$$ + : ${top_builddir=@top_builddir@} + top_builddir=`cd ${top_builddir} >/dev/null ; pwd` + : ${top_srcdir=@top_srcdir@} + top_srcdir=`cd ${top_srcdir} >/dev/null ; pwd` + : ${srcdir=@srcdir@} + srcdir=`cd $srcdir >/dev/null && pwd` + . ${top_builddir}/config/shdefs "${builddir}/` + echo $0|${SED:-sed} 's@.*/@@'`" + progname=`echo "$1" | ${SED} 's,^.*/,,'` + testname=`echo "$progname" | ${SED} 's,\..*$,,'` + testsubdir=${testname}-testd + tstdir=${builddir}/${testsubdir} + PS4=">${testname}-\${FUNCNAME}> " + test_name=`echo ${testname} | ${SED} 's/-/_/g'` + ( exec 2>/dev/null; ulimit -c unlimited ) && \ + ulimit -c unlimited + + CFLAGS="${CFLAGS} ${DEFS}" + : ${PAGER=more} + + stdopts=${top_srcdir}/autoopts/test/stdopts.def + test_main=yes + use_flags=true + sed_omit_license="/-\*- buffer-read-only:/,/^ \*\//d" + TERM='' + set +a + + ( + test_local() { + local local_works=yes + } + test_local + ) || eval 'local() { : ; }' + + vars=`set | ${SED} -n '/^\(LANG\|LC_[A-Z_]*\)=/s/=.*//p'` 2>/dev/null + unset AUTOOPTS_USAGE $vars CONTENT_LENGTH REQUEST_METHOD QUERY_STRING +} + +# If only the "rm(1)" command could be relied upon.... +# +purge() +{ + rm -rf ${*} 2>/dev/null + bad='' + for f + do test -f ${f} -o -d ${f} && bad="${bad} ${f}" + done + test -z "$bad" && return 0 + + # NFS "busy" files and MS-DOS fs sometimes fail. + # + set -- $bad + test "x${RANDOM}" = "x${RANDOM}" && RANDOM=`expr 0${RANDOM} + 1 2>/dev/null` + + f=zzPURGE-${1}-${RANDOM}-${progpid} + if test $# -gt 1 + then mkdir "${f}" + mv $* "${f}/." + else mv $1 "${f}" + fi +} + +init_tests() +{ + exec 8>&2 + BASH_XTRACEFD=8 + + TMPDIR="${tstdir}/${testname}-tmpd" + mkdir -p ${TMPDIR} + CFLAGS=`echo ${CFLAGS} | \ + ${SED} "s/-Werror[^ ${ht}]*//g;s/-Wextra//g"` + + lo_dir=${top_builddir}/autoopts + lo_lib=`find ${lo_dir} -type f -name "*libopts.${OBJEXT}" | head -n1` + test -f "$lo_lib" || { + lo_lib=`find ${lo_dir} -type f -name "*libopts.lo" | head -n1` + test -f "$lo_lib" || die "no libopts lib" + } + lo_dir=${lo_lib%/*} + test "X${LD_LIBRARY_PATH}" = X || \ + LD_LIBRARY_PATH=:${LD_LIBRARY_PATH} + LD_LIBRARY_PATH=${lo_dir}:${LIBGUILE_PATH}${LD_LIBRARY_PATH} + + case ${AG_VERSION} in + *pre* ) GUILE_WARN_DEPRECATED=detailed ;; + * ) GUILE_WARN_DEPRECATED=no ;; + esac + + case "$LIB" in + *-lgen* ) : ;; + * ) + for f in /usr/lib*/libgen.so /lib*/libgen.so + do + test -f $f && { + LIB="${LIB} -lgen" + break + } + done + ;; + esac + LIB="${lo_lib} ${LIB}" + + AG_L=run_ag\ ao + agl_opts="-L${top_builddir}/autoopts/tpl" + test "L${top_builddir}" = "L${top_srcdir}" || \ + agl_opts="$agl_opts -L${top_srcdir}/autoopts/tpl" + export TMPDIR PATH LD_LIBRARY_PATH \ + GUILE_WARN_DEPRECATED LIB AG_L agl_opts \ + CC LIBGUILE AG_VERSION +} + +be_silent() +{ + setx=: + msg=echo + VERBOSE=false + purge ${testsubdir} + + run_ag() + { + local opts= + opts='' + shift + + case " $* " in + *' -L'* ) : ;; + * ) opts="${agl_opts}" ;; + esac + + ${AGexe} ${opts} "$@" + } + + init_tests +} + +be_verbose() +{ + set -x + setx='set -x' + msg=: + VERBOSE=true + test -d ${testsubdir} || mkdir ${testsubdir} || exit 1 + + run_ag() + { + local opts= tfile=${testname}-aglog-${1}-${progpid}.log + ${verb_ok:-true} && { + case " $* " in + *' --trace'* ) : ;; + * ) + opts="--trace=every --trace-out=>>${tfile}" + ;; + esac + AUTOGEN_TRACE=every + AUTOGEN_TRACE_OUT=">>`pwd`/${tfile}" + export AUTOGEN_TRACE_OUT AUTOGEN_TRACE + } + shift + + case " $* " in + *' -L'* ) : ;; + * ) opts="${opts} ${agl_opts}" ;; + esac + + MALLOC_CHECK_=3 ${AGexe} ${opts} "$@" + } + + init_tests +} + +cfg_inc() +{ + test_src=$srcdir/${testname}.test + cd ${testsubdir} || { + echo "Cannot make or change into ${testsubdir}" + exit 1 + } + + dirs=` + for f in ${top_builddir} ${top_srcdir} + do + for d in . autoopts agen5 + do + cd $f/$d + pwd >&9 + cd - + done 9>&1 1>/dev/null + done | sort -u | ${SED} 's/^/-I/'` + + INC=`echo ${dirs} ${CPPFLAGS}` + + : "=== Running $progname for ${testname} using ${SHELL} ===" + chmod +w * > /dev/null 2>&1 || : + ${VERBOSE} && SHELLX="${SHELL} -x" || SHELLX="${SHELL}" +} + +# # # # +# +# "clean_help" -- remove variable parts so results can be compared +# +nl=' +' +ht=' ' +basic_help_clean="/^Packaged by/d +/^Report .* bugs to/d +/[Pp]lease send bug reports/d +/^exit [0-9]/d +/^[ ${ht}]*\$/d" +TR=`command -v tr` +test -x "$TR" || die "cannot run tests without 'tr' program" + +export nl ht basic_help_clean TR +readonly nl ht basic_help_clean TR + +clean_help() { + test -z "$sedcmd" && \ + s=${basic_help_clean} || \ + s="${sedcmd}${nl}${basic_help_clean}" + + ${SED} "${s}" ${1+"$@"} +} + +compile() +{ + ${setx} + test "X${Csrc}" = "X" && Csrc="${testname}" + test "X${Cexe}" = "X" && Cexe="${Csrc}" + test "X${Dnam}" = "X" && Dnam="${testname}" + + d=`echo TEST_TEST_${Dnam}_OPTS | ${TR} '[a-z]-' '[A-Z]_'` + cc_cmd="${CC} ${CFLAGS} -D$d ${INC} -o ${Cexe} ${Csrc}.c ${LIB}" + eval ${cc_cmd} || \ + failure cannot compile ${Csrc}.c + if test $# -gt 0 + then + ( set +xe + exec 2>&1 + ./${Cexe} ${*} ${dosed} + ) || failure cannot obtain help output for ${Csrc} + fi > ${Cexe}.RAW-HELP + clean_help ${Cexe}.RAW-HELP > ${Csrc}.help + Csrc='' Cexe='' Dnam='' +} + +cleanup() +{ + kill -9 $THUMPER_PID + trap '' 15 + ${setx} + ${VERBOSE} || { + cd ${builddir} + purge ${testsubdir} + } + ${msg} ${testname} done + exit 0 +} + +# A standard failure function +# +failure() +{ + kill -9 $THUMPER_PID + trap '' 15 + set -x + cd ${tstdir}/.. + if test -d FAILURES + then test -d "FAILURES/${testsubdir}" && \ + purge "FAILURES/${testsubdir}" + else mkdir FAILURES + fi + + mv "${testsubdir}" "FAILURES/${testsubdir}" + test -f "${testname}.log" && { + mv "${testname}.log" "FAILURES/${testsubdir}/amtest-${testname}.log" + ln -s "FAILURES/${testsubdir}/amtest-${testname}.log" "${testname}.log" + } + echo FAILURE: "$*" + exit 1 +} + +thumper() +{ + exec > /dev/null 2>&1 /dev/null ; pwd` + cd / + rpid=${progpid} + test -z "${kill_delay}" && kill_delay=3 + kill_delay=`expr $kill_delay '*' $AG_TIMEOUT` + while test ${kill_delay} -gt 0 + do sleep 1 + ps -p ${rpid} || exit 0 + kill_delay=`expr $kill_delay - 1` + done + kill -15 ${rpid} + sleep 1 + ps -p ${rpid} || exit + test -d "$bdir" && { + test -d ${bdir}/FAILURES || \ + mkdir ${bdir}/FAILURES + mv -f "${tstdir}" "${bdir}/FAILURES/." + } + kill -9 ${rpid} +} + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + +cfg_vals $0 + +case "${VERBOSE}" in +'' | [Nn]* | 0 | [Ff]* ) + be_silent ;; + +[Yy]* | [0-9] | [Tt]* ) + be_verbose ;; + +* ) + case "$-" in + *x* ) be_verbose ;; + * ) be_silent ;; + esac +esac + +thumper & +THUMPER_PID=$! +cfg_inc + +trap "failure 'test ${testname} killed on timeout'" 15 + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## sh-basic-offset: 2 +## End: + +# defs.in ends here diff --git a/autoopts/test/doc.test b/autoopts/test/doc.test new file mode 100755 index 0000000..ff522c4 --- /dev/null +++ b/autoopts/test/doc.test @@ -0,0 +1,854 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# +# doc.test --- test doc templates +# +# Author: Bruce Korb +# +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + +. ./defs + +# # # # # # # # # # DEFINITIONS FILE # # # # # # # # # +echo make defs from test file +${SED} "1,/^##* *BEGIN-DEFS/d + /^prog-name/s/=.*/= ${testname};/ + \\@^// *END-DEFS@q" \ + ${test_src} > ${testname}.def + +# # # # # # # # # # TEXI DOC CHECK # # # # # # # # # +run_ag tc -Tagtexi-cmd ${testname}.def +test -f invoke-${testname}.menu -a -f invoke-${testname}.texi || \ + failure "invoke-${testname}.{menu,texi} not built" +${SED} '/^@ignore/,/^@end ignore/d' \ + invoke-${testname}.texi > ${testname}-res.texi +rm -f invoke-${testname}.menu invoke-${testname}.texi + +${SED} -n '1,/^##* *BEGIN-TEXI/d + /^## END-TEXI/q + /^/p' \ + ${test_src} > ${testname}-base.texi + +outfiles="${testname}-res.texi ${testname}-base.texi" +cmp -s ${outfiles} || \ + failure "Differences: ${outfiles}${nl}`diff ${outfiles}`" + +# # # # # # # # # # MAN DOC CHECK # # # # # # # # # +run_ag mn -Tagman-cmd ${testname}.def +test -f ${testname}.1 || \ + failure "${testname}.1 not built" + +{ + ${SED} '/^\.\\"/d;/^$/d;/^\.TH/s/ *".*//' ${testname}.1 + rm -f ${testname}.1 + echo +} > ${testname}-res.1 + +${SED} "1,/^##* *BEGIN-MAN/d + /^## END-MAN/{;s/.*//;q;}" ${test_src} > ${testname}-base.1 + +outfiles="${testname}-base.1 ${testname}-res.1" +cmp -s ${outfiles} || \ + failure "Differences: ${outfiles}${nl}`diff -u ${outfiles}`" + +# # # # # # # # # # MDOC DOC CHECK # # # # # # # # # +run_ag md -Tagmdoc-cmd ${testname}.def +test -f ${testname}.1 || \ + failure "${testname}.1 not built" + +{ + ${EGREP} -v '^\.(Dd |Os |\\")|^$' ${testname}.1 + echo +} > ${testname}-mdoc-res.1 + +${SED} "1,/^##* *BEGIN-MDOC/d + /^## END-MDOC/{;s/.*//;q;}" ${test_src} > ${testname}-mdoc-base.1 + +outfiles="${testname}-mdoc-base.1 ${testname}-mdoc-res.1" +cmp -s ${outfiles} || \ + failure "Differences: ${outfiles}${nl}`diff -u ${outfiles}`" + +# # # # # # # # # # POT CHECK # # # # # # # # # +run_ag pt -Tdef2pot ${testname}.def +test -s ${testname}.pot || \ + failure "${testname}.pot not built" + +{ + ${SED} -e '/^# *Copyright/s/).*/)/' \ + -e '/^$/d' \ + -e 's/>, 20[0-9][0-9]\./>./' \ + -e '/POT-Creation-Date:/s/ 2[0-9].*/\\n"/' \ + ${testname}.pot + echo +} > ${testname}-res.pot + +${SED} "1,/^##* *BEGIN-POT/d + /^$/d + /^## END-POT/{;s/.*//;q;}" ${test_src} > ${testname}-base.pot + +outfiles="${testname}-base.pot ${testname}-res.pot" +cmp -s ${outfiles} || \ + failure "Differences: ${outfiles}${nl}`diff -u ${outfiles}`" + +# # # # # # # # # # # FINISH # # # # # # # # # # # + +cleanup + +exit 0 + +# # # # # # # # # # # OPTION DEFS + +cat <<_End_Of_Definitions_ +## BEGIN-DEFS +AutoGen Definitions options; +prog-name = gnutls-cli; +prog-title = "GnuTLS client"; +prog-desc = "Simple client program to set up a TLS connection."; +short-usage = <<- _EOUsage_ + Usage: gnutls-cli [options] hostname + gnutls-cli --help for usage instructions. + _EOUsage_; +prog-group = "GnuTLS"; +detail = <<- _EODetail_ + Simple client program to set up a TLS connection to some other computer. + It sets up a TLS connection and forwards data from the standard input + to the secured socket and vice versa. + _EODetail_; + +gnu-usage; +no-misuse-usage; +disable-save; +reorder-args; +no-xlate = opt; +argument = "[hostname]"; +long-opts; + +copyright = { + date = "2000-2018"; + owner = "Free Software Foundation"; + author = "Nikos Mavrogiannopoulos, Simon Josefsson and others; " + "see /usr/share/doc/gnutls-bin/AUTHORS for a complete list."; + eaddr = "bug-gnutls@gnu.org"; + type = gpl; +}; +version = "3.0.12"; +help-value = h; +more-help-value = M; +option-format = texi; + +flag = { + name = debug; + value = d; + arg-type = number; + arg-range = "0->9999"; + descrip = "Enable @code{debugging}"; + doc = 'really enable debugging'; +}; + +flag = { + name = mtu; + arg-type = number; + arg-range = "0->17000"; + descrip = "Set MTU for datagram TLS"; + doc = "Really set MTU for datagram TLS"; +}; + +flag = { + name = group-2; + descrip = "second group of options"; + documentation; +}; + +flag = { + name = crlf; + descrip = "Send CR LF instead of LF"; + doc = "Really send CR LF instead of LF"; +}; + +flag = { + name = x509fmtder; + descrip = "Use DER format for certificates to read from"; + doc = "Really use DER format for certificates to read from"; +}; + +flag = { + name = group-3; + descrip = "third group of options"; + documentation; +}; + +flag = { + name = recordsize; + arg-type = number; + arg-range = "0->4096"; + descrip = "The maximum record size to advertize"; + doc = "Really the maximum record size to advertize"; +}; + +flag = { + name = priority; + arg-type = string; + descrip = "Priorities string"; + doc = <<- _EODoc_ + TLS algorithms and protocols to enable. You can + use predefined sets of ciphersuites such as PERFORMANCE, + NORMAL, SECURE128, SECURE256. + + Check the GnuTLS manual on section ``Priority strings'' for more + information on allowed keywords + _EODoc_; +}; + + +doc-section = { + ds-type = 'SEE ALSO'; + ds-format = texi; + omit-texi; + ds-text = 'gnutls-cli-debug(1), gnutls-serv(1)'; +}; + +doc-section = { + ds-type = EXAMPLES; + ds-format = texi; + ds-text = <<- _EOT_ + To connect to a server using PSK authentication, you need to enable + the choice of PSK by using a cipher priority parameter such as in the + example below. + @example + $ ./gnutls-cli -p 5556 localhost --pskusername psk_identity \\ + --pskkey 88f3824b3e5659f52d00e959bacab954b6540344 \\ + --priority NORMAL:-KX-ALL:+ECDHE-PSK:+DHE-PSK:+PSK + Resolving 'localhost'... + Connecting to '127.0.0.1:5556'... + - PSK authentication. + - Version: TLS1.1 + - Key Exchange: PSK + - Cipher: AES-128-CBC + - MAC: SHA1 + - Compression: NULL + - Handshake was completed + + - Simple Client Mode: + @end example + By keeping the --pskusername parameter and removing the --pskkey + parameter, it will query only for the password during the handshake. + + To list the ciphersuites in a priority string: + @example + $ ./gnutls-cli --priority SECURE192 -l + Cipher suites for SECURE192 + TLS_ECDHE_ECDSA_AES_256_CBC_SHA384 0xc0, 0x24 TLS1.2 + TLS_ECDHE_ECDSA_AES_256_GCM_SHA384 0xc0, 0x2e TLS1.2 + TLS_ECDHE_RSA_AES_256_GCM_SHA384 0xc0, 0x30 TLS1.2 + TLS_DHE_RSA_AES_256_CBC_SHA256 0x00, 0x6b TLS1.2 + TLS_DHE_DSS_AES_256_CBC_SHA256 0x00, 0x6a TLS1.2 + TLS_RSA_AES_256_CBC_SHA256 0x00, 0x3d TLS1.2 + @end example + _EOT_; +}; +// END-DEFS +_End_Of_Definitions_ + +# # # # # # # # # # # TEXI TEXT + +cat <<_End_Of_TexInfo_ +## BEGIN-TEXI +@node doc Invocation +@section Invoking doc +@pindex doc +@cindex GnuTLS client +Simple client program to set up a TLS connection to some other computer. +It sets up a TLS connection and forwards data from the standard input +to the secured socket and vice versa. + +This section was generated by @strong{AutoGen}, +using the @code{agtexi-cmd} template and the option descriptions for the @code{doc} program. +This software is released under the GNU General Public License, version 3 or later. + +@menu +* doc usage:: doc help/usage (@option{--help}) +* doc base-options:: Base options +* doc group-2:: group-2 options +* doc group-3:: group-3 options +* doc exit status:: exit status +* doc Examples:: Examples +@end menu + +@node doc usage +@subsection doc help/usage (@option{--help}) +@cindex doc help + +This is the automatically generated usage text for doc. + +The text printed is the same whether selected with the @code{help} option +(@option{--help}) or the @code{more-help} option (@option{--more-help}). @code{more-help} will print +the usage text by passing it through a pager program. +@code{more-help} is disabled on platforms without a working +@code{fork(2)} function. The @code{PAGER} environment variable is +used to select the program, defaulting to @file{more}. Both will exit +with a status code of 0. + +@exampleindent 0 +@example +doc is unavailable - no --help +@end example +@exampleindent 4 + +@node doc +@subsection Base options +@subsubheading debug option (-d). +@anchor{doc debug} +@cindex doc-debug + +This is the ``enable @code{debugging}'' option. +This option takes a number argument. +really enable debugging +@subsubheading mtu option. +@anchor{doc mtu} +@cindex doc-mtu + +This is the ``set mtu for datagram tls'' option. +This option takes a number argument. +Really set MTU for datagram TLS +@node doc group-2 +@subsection group-2 options +second group of options. +@subsubheading crlf option. +@anchor{doc crlf} +@cindex doc-crlf + +This is the ``send cr lf instead of lf'' option. +Really send CR LF instead of LF +@subsubheading x509fmtder option. +@anchor{doc x509fmtder} +@cindex doc-x509fmtder + +This is the ``use der format for certificates to read from'' option. +Really use DER format for certificates to read from +@node doc group-3 +@subsection group-3 options +third group of options. +@subsubheading recordsize option. +@anchor{doc recordsize} +@cindex doc-recordsize + +This is the ``the maximum record size to advertize'' option. +This option takes a number argument. +Really the maximum record size to advertize +@subsubheading priority option. +@anchor{doc priority} +@cindex doc-priority + +This is the ``priorities string'' option. +This option takes a string argument. +TLS algorithms and protocols to enable. You can +use predefined sets of ciphersuites such as PERFORMANCE, +NORMAL, SECURE128, SECURE256. + +Check the GnuTLS manual on section ``Priority strings'' for more +information on allowed keywords +@node doc exit status +@subsection doc exit status + +One of the following exit values will be returned: +@table @samp +@item 0 (EXIT_SUCCESS) +Successful program execution. +@item 1 (EXIT_FAILURE) +The operation failed or the command syntax was not valid. +@end table +@node doc Examples +@subsection doc Examples +To connect to a server using PSK authentication, you need to enable +the choice of PSK by using a cipher priority parameter such as in the +example below. +@example +$ ./gnutls-cli -p 5556 localhost --pskusername psk_identity \\ + --pskkey 88f3824b3e5659f52d00e959bacab954b6540344 \\ + --priority NORMAL:-KX-ALL:+ECDHE-PSK:+DHE-PSK:+PSK +Resolving 'localhost'... +Connecting to '127.0.0.1:5556'... +- PSK authentication. +- Version: TLS1.1 +- Key Exchange: PSK +- Cipher: AES-128-CBC +- MAC: SHA1 +- Compression: NULL +- Handshake was completed + +- Simple Client Mode: +@end example +By keeping the --pskusername parameter and removing the --pskkey +parameter, it will query only for the password during the handshake. + +To list the ciphersuites in a priority string: +@example +$ ./gnutls-cli --priority SECURE192 -l +Cipher suites for SECURE192 +TLS_ECDHE_ECDSA_AES_256_CBC_SHA384 0xc0, 0x24 TLS1.2 +TLS_ECDHE_ECDSA_AES_256_GCM_SHA384 0xc0, 0x2e TLS1.2 +TLS_ECDHE_RSA_AES_256_GCM_SHA384 0xc0, 0x30 TLS1.2 +TLS_DHE_RSA_AES_256_CBC_SHA256 0x00, 0x6b TLS1.2 +TLS_DHE_DSS_AES_256_CBC_SHA256 0x00, 0x6a TLS1.2 +TLS_RSA_AES_256_CBC_SHA256 0x00, 0x3d TLS1.2 +@end example +## END-TEXI +_End_Of_TexInfo_ + +# # # # # # # # # # # MAN PAGE + +cat <<_End_Of_ManPage_ +## BEGIN-MAN +.de1 NOP +. it 1 an-trap +. if \\n[.$] \,\\$*\/ +.. +.ie t \ +.ds B-Font [CB] +.ds I-Font [CI] +.ds R-Font [CR] +.el \ +.ds B-Font B +.ds I-Font I +.ds R-Font R +.TH doc 1 +.SH NAME +\f\*[B-Font]doc\fP +\- GnuTLS client +.SH SYNOPSIS +\f\*[B-Font]doc\fP +[\f\*[B-Font]\-flags\f[]] +[\f\*[B-Font]\-flag\f[] [\f\*[I-Font]value\f[]]] +[\f\*[B-Font]\-\-option-name\f[][[=| ]\f\*[I-Font]value\f[]]] +[hostname] +.sp \n(Ppu +.ne 2 +Operands and options may be intermixed. They will be reordered. +.sp \n(Ppu +.ne 2 +.SH "DESCRIPTION" +Simple client program to set up a TLS connection to some other computer. +It sets up a TLS connection and forwards data from the standard input +to the secured socket and vice versa. +.SH "OPTIONS" +.TP +.NOP \f\*[B-Font]\-d\f[] \f\*[I-Font]number\f[], \f\*[B-Font]\-\-debug\f[]=\f\*[I-Font]number\f[] +Enable \fBdebugging\fP. +This option takes an integer number as its argument. +The value of +\f\*[I-Font]number\f[] +is constrained to being: +.in +4 +.nf +.na +in the range 0 through 9999 +.fi +.in -4 +.sp +really enable debugging +.TP +.NOP \f\*[B-Font]\-\-mtu\f[]=\f\*[I-Font]number\f[] +Set MTU for datagram TLS. +This option takes an integer number as its argument. +The value of +\f\*[I-Font]number\f[] +is constrained to being: +.in +4 +.nf +.na +in the range 0 through 17000 +.fi +.in -4 +.sp +Really set MTU for datagram TLS +.SS "second group of options" +.TP +.NOP \f\*[B-Font]\-\-crlf\f[] +Send CR LF instead of LF. +.sp +Really send CR LF instead of LF +.TP +.NOP \f\*[B-Font]\-\-x509fmtder\f[] +Use DER format for certificates to read from. +.sp +Really use DER format for certificates to read from +.SS "third group of options" +.TP +.NOP \f\*[B-Font]\-\-recordsize\f[]=\f\*[I-Font]number\f[] +The maximum record size to advertize. +This option takes an integer number as its argument. +The value of +\f\*[I-Font]number\f[] +is constrained to being: +.in +4 +.nf +.na +in the range 0 through 4096 +.fi +.in -4 +.sp +Really the maximum record size to advertize +.TP +.NOP \f\*[B-Font]\-\-priority\f[]=\f\*[I-Font]string\f[] +Priorities string. +.sp +TLS algorithms and protocols to enable. You can +use predefined sets of ciphersuites such as PERFORMANCE, +NORMAL, SECURE128, SECURE256. +.sp +Check the GnuTLS manual on section \(lqPriority strings\(rq for more +information on allowed keywords +.TP +.NOP \f\*[B-Font]\-h\f[], \f\*[B-Font]\-\-help\f[] +Display usage information and exit. +.TP +.NOP \f\*[B-Font]\-M\f[], \f\*[B-Font]\-\-more\-help\f[] +Pass the extended usage information through a pager. +.TP +.NOP \f\*[B-Font]\-v\f[] [{\f\*[I-Font]v|c|n\f[] \f\*[B-Font]\-\-version\f[] [{\f\*[I-Font]v|c|n\f[]}]}] +Output version of program and exit. The default mode is `v', a simple +version. The `c' mode will print copyright information and `n' will +print the full copyright notice. +.PP +.sp +.SH EXAMPLES +To connect to a server using PSK authentication, you need to enable +the choice of PSK by using a cipher priority parameter such as in the +example below. +.br +.in +4 +.nf +$ ./gnutls\-cli \-p 5556 localhost \-\-pskusername psk_identity \\ + \-\-pskkey 88f3824b3e5659f52d00e959bacab954b6540344 \\ + \-\-priority NORMAL:\-KX\-ALL:+ECDHE\-PSK:+DHE\-PSK:+PSK +Resolving 'localhost'... +Connecting to '127.0.0.1:5556'... +- PSK authentication. +- Version: TLS1.1 +- Key Exchange: PSK +- Cipher: AES\-128\-CBC +- MAC: SHA1 +- Compression: NULL +- Handshake was completed +.sp +- Simple Client Mode: +.in -4 +.fi +By keeping the \-\-pskusername parameter and removing the \-\-pskkey +parameter, it will query only for the password during the handshake. +.sp +To list the ciphersuites in a priority string: +.br +.in +4 +.nf +$ ./gnutls\-cli \-\-priority SECURE192 \-l +Cipher suites for SECURE192 +TLS_ECDHE_ECDSA_AES_256_CBC_SHA384 0xc0, 0x24 TLS1.2 +TLS_ECDHE_ECDSA_AES_256_GCM_SHA384 0xc0, 0x2e TLS1.2 +TLS_ECDHE_RSA_AES_256_GCM_SHA384 0xc0, 0x30 TLS1.2 +TLS_DHE_RSA_AES_256_CBC_SHA256 0x00, 0x6b TLS1.2 +TLS_DHE_DSS_AES_256_CBC_SHA256 0x00, 0x6a TLS1.2 +TLS_RSA_AES_256_CBC_SHA256 0x00, 0x3d TLS1.2 +.in -4 +.fi +.SH "EXIT STATUS" +One of the following exit values will be returned: +.TP +.NOP 0 " (EXIT_SUCCESS)" +Successful program execution. +.TP +.NOP 1 " (EXIT_FAILURE)" +The operation failed or the command syntax was not valid. +.TP +.NOP 70 " (EX_SOFTWARE)" +libopts had an internal operational error. Please report +it to autogen-users@lists.sourceforge.net. Thank you. +.PP +.SH "SEE ALSO" +gnutls\-cli\-debug(1), gnutls\-serv(1) +.SH "AUTHORS" +Nikos Mavrogiannopoulos, Simon Josefsson and others; see /usr/share/doc/gnutls-bin/AUTHORS for a complete list. +.SH "COPYRIGHT" +Copyright (C) 2000-2018 Free Software Foundation all rights reserved. +This program is released under the terms of the GNU General Public License, version 3 or later. +.SH "BUGS" +Please send bug reports to: bug-gnutls@gnu.org +.SH "NOTES" +This manual page was \fIAutoGen\fP-erated from the \fBdoc\fP +option definitions. +## END-MAN +_End_Of_ManPage_ + +# # # # # # # # # # # MDOC PAGE + +cat <<_End_Of_MdocPage_ +## BEGIN-MDOC +.Dt DOC 1 User Commands +.Os +.Sh NAME +.Nm doc +.Nd GnuTLS client +.Sh SYNOPSIS +.Nm +.Op Fl flags +.Op Fl flag Op Ar value +.Op Fl \-option\-name Ns Oo Oo Ns "=| " Oc Ns Ar value Oc +[hostname] +.Pp +Operands and options may be intermixed. They will be reordered. +.Pp +.Sh "DESCRIPTION" +Simple client program to set up a TLS connection to some other computer. +It sets up a TLS connection and forwards data from the standard input +to the secured socket and vice versa. +.Sh "OPTIONS" +.Bl -tag +.It Fl d Ar number , Fl \-debug Ns = Ns Ar number +Enable \fBdebugging\fP. +This option takes an integer number as its argument. +The value of +.Ar number +is constrained to being: +.in +4 +.nf +.na +in the range 0 through 9999 +.fi +.in -4 +.sp +really enable debugging +.It Fl \-mtu Ns = Ns Ar number +Set MTU for datagram TLS. +This option takes an integer number as its argument. +The value of +.Ar number +is constrained to being: +.in +4 +.nf +.na +in the range 0 through 17000 +.fi +.in -4 +.sp +Really set MTU for datagram TLS +.Ss "second group of options" +.It Fl \-crlf +Send CR LF instead of LF. +.sp +Really send CR LF instead of LF +.It Fl \-x509fmtder +Use DER format for certificates to read from. +.sp +Really use DER format for certificates to read from +.Ss "third group of options" +.It Fl \-recordsize Ns = Ns Ar number +The maximum record size to advertize. +This option takes an integer number as its argument. +The value of +.Ar number +is constrained to being: +.in +4 +.nf +.na +in the range 0 through 4096 +.fi +.in -4 +.sp +Really the maximum record size to advertize +.It Fl \-priority Ns = Ns Ar string +Priorities string. +.sp +TLS algorithms and protocols to enable. You can +use predefined sets of ciphersuites such as PERFORMANCE, +NORMAL, SECURE128, SECURE256. +.sp +Check the GnuTLS manual on section \(lqPriority strings\(rq for more +information on allowed keywords +.It Fl h , Fl \-help +Display usage information and exit. +.It Fl M , Fl \-more\-help +Pass the extended usage information through a pager. +.It Fl v Op Brq Ar v|c|n Fl \-version Op Brq Ar v|c|n +Output version of program and exit. The default mode is `v', a simple +version. The `c' mode will print copyright information and `n' will +print the full copyright notice. +.El +.sp +.Sh EXAMPLES +To connect to a server using PSK authentication, you need to enable +the choice of PSK by using a cipher priority parameter such as in the +example below. +.Bd -literal -offset indent +$ ./gnutls\-cli \-p 5556 localhost \-\-pskusername psk_identity \\ + \-\-pskkey 88f3824b3e5659f52d00e959bacab954b6540344 \\ + \-\-priority NORMAL:\-KX\-ALL:+ECDHE\-PSK:+DHE\-PSK:+PSK +Resolving 'localhost'... +Connecting to '127.0.0.1:5556'... +- PSK authentication. +- Version: TLS1.1 +- Key Exchange: PSK +- Cipher: AES\-128\-CBC +- MAC: SHA1 +- Compression: NULL +- Handshake was completed +.sp +- Simple Client Mode: +.Ed +By keeping the \-\-pskusername parameter and removing the \-\-pskkey +parameter, it will query only for the password during the handshake. +.sp +To list the ciphersuites in a priority string: +.Bd -literal -offset indent +$ ./gnutls\-cli \-\-priority SECURE192 \-l +Cipher suites for SECURE192 +TLS_ECDHE_ECDSA_AES_256_CBC_SHA384 0xc0, 0x24 TLS1.2 +TLS_ECDHE_ECDSA_AES_256_GCM_SHA384 0xc0, 0x2e TLS1.2 +TLS_ECDHE_RSA_AES_256_GCM_SHA384 0xc0, 0x30 TLS1.2 +TLS_DHE_RSA_AES_256_CBC_SHA256 0x00, 0x6b TLS1.2 +TLS_DHE_DSS_AES_256_CBC_SHA256 0x00, 0x6a TLS1.2 +TLS_RSA_AES_256_CBC_SHA256 0x00, 0x3d TLS1.2 +.Ed +.Sh "EXIT STATUS" +One of the following exit values will be returned: +.Bl -tag +.It 0 " (EXIT_SUCCESS)" +Successful program execution. +.It 1 " (EXIT_FAILURE)" +The operation failed or the command syntax was not valid. +.It 70 " (EX_SOFTWARE)" +libopts had an internal operational error. Please report +it to autogen\-users@lists.sourceforge.net. Thank you. +.El +.Sh "SEE ALSO" +gnutls\-cli\-debug(1), gnutls\-serv(1) +.Sh "AUTHORS" +Nikos Mavrogiannopoulos, Simon Josefsson and others; see /usr/share/doc/gnutls\-bin/AUTHORS for a complete list. +.Sh "COPYRIGHT" +Copyright (C) 2000\-2018 Free Software Foundation all rights reserved. +This program is released under the terms of the GNU General Public License, version 3 or later. +.Sh "BUGS" +Please send bug reports to: bug\-gnutls@gnu.org +.Sh "NOTES" +This manual page was \fIAutoGen\fP\-erated from the \fBdoc\fP +option definitions. +## END-MDOC +_End_Of_MdocPage_ + +# # # # # # # # # # # POT PAGE + +cat <<_End_Of_PotPage_ +## BEGIN-POT +# localization template (.pot) for doc.def of doc, +# this file is used to generate localized manual for doc. +# Copyright (C) +# This file is distributed under the terms of the +# the GNU General Public License, version 3 or later +# The program owners may be reached via: +# Free Software Foundation . +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: doc 3.0.12\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date:\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" +#: doc.def:3 +msgid "GnuTLS client" +msgstr "" +#: doc.def:42 +msgid "Enable debugging" +msgstr "" +#: doc.def:43 +msgid "really enable debugging" +msgstr "" +#: doc.def:50 +msgid "Set MTU for datagram TLS" +msgstr "" +#: doc.def:51 +msgid "Really set MTU for datagram TLS" +msgstr "" +#: doc.def:56 +msgid "second group of options" +msgstr "" +#: doc.def:62 +msgid "Send CR LF instead of LF" +msgstr "" +#: doc.def:63 +msgid "Really send CR LF instead of LF" +msgstr "" +#: doc.def:68 +msgid "Use DER format for certificates to read from" +msgstr "" +#: doc.def:69 +msgid "Really use DER format for certificates to read from" +msgstr "" +#: doc.def:74 +msgid "third group of options" +msgstr "" +#: doc.def:82 +msgid "The maximum record size to advertize" +msgstr "" +#: doc.def:83 +msgid "Really the maximum record size to advertize" +msgstr "" +#: doc.def:89 +msgid "Priorities string" +msgstr "" +#: doc.def:91 +msgid "TLS algorithms and protocols to enable. You can use predefined sets of\n" + "ciphersuites such as PERFORMANCE, NORMAL, SECURE128, SECURE256.\n\n" + "Check the GnuTLS manual on section ``Priority strings'' for more\n" + "information on allowed keywords" +msgstr "" +#: doc.def:6 +msgid "Usage: gnutls-cli [options] hostname gnutls-cli --help for usage\n" + "instructions." +msgstr "" +#: doc.def:11 +msgid "Simple client program to set up a TLS connection to some other computer.\n" + "It sets up a TLS connection and forwards data from the standard input to\n" + "the secured socket and vice versa." +msgstr "" + +#: +msgid "This program is released under the terms of the GNU General Public License, version 3 or later." +msgstr "" + +#: doc.def:21 +msgid "[hostname]" +msgstr "" +## END-POT +_End_Of_PotPage_ + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## End: + +# end of doc.test diff --git a/autoopts/test/enums.test b/autoopts/test/enums.test new file mode 100755 index 0000000..c909a96 --- /dev/null +++ b/autoopts/test/enums.test @@ -0,0 +1,309 @@ +#! /bin/sh +# -*- Mode: shell-script -*- +# ---------------------------------------------------------------------- +# enums.test --- test enums program attribute +# make sure that when it is not specified +# then option processing consumes all args. +# +# Author: Bruce Korb +## +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd +# +# ---------------------------------------------------------------------- + +. ./defs + +# # # # # # # # # # DEFINITIONS FILE # # # # # # # # # + +cat > ${testname}.def <<- _EOF_ + autogen definitions options; + + prog-name = ${testname}-test; + prog-title = 'test complex main procedure'; + config-header = config.h; + + argument = '[ ]'; + long-opts; + + flag = { + name = print; + value = p; + descrip = 'Print operational info'; + arg-type = keyword; + arg-name = type; + min = 1; + equivalence = print; + keyword = one, two, three, four, five, six, seven, eight, nine, ten; + }; + + flag = { + name = dump-log; + value = D; + descrip = 'Dump the program log'; + equivalence = print; + }; + + flag = { + name = all-dump; + value = A; + equivalence = print; + descrip = 'Dump everything we\'ve got'; + }; + + flag = { + name = set; + value = s; + descrip = 'set options'; + arg-type = set; + arg-name = 'opt[, ...]'; + arg-default = first,fifth,ninth,thirteenth; + equivalence = print; + keyword = first, second, third, fourth, fifth, sixth, seventh, + eighth, ninth, tenth, eleventh, twelfth, thirteenth, + fourteenth, fifteenth, sixteenth; + }; + + flag = { + name = unset; + value = u; + descrip = 'unset debug options'; + arg-type = string; + arg-name = 'opt[, ...]'; + equivalence = print; + flag-proc = set; + }; + + flag = { + name = msg-num; + value = m; + descrip = 'message number'; + no-preset; + arg-type = string; + arg-name = id; + max = NOLIMIT; + + flag-code = <<- _EndOfFlagCode_ + /* + * 'set' and 'unset' must be acted upon immediately + * -- we may get more of them. + */ + switch (WHICH_IDX_PRINT) { + case NO_EQUIVALENT: + case INDEX_OPT_PRINT: + case INDEX_OPT_DUMP_LOG: + case INDEX_OPT_ALL_DUMP: + if (COUNT_OPT( MSG_NUM ) > 1) { + fputs("Except for 'set' and 'unset' functions, " + "only one 'msg-num' is allowed\n", stderr); + USAGE(EXIT_FAILURE); + } + break; + case INDEX_OPT_SET: + set_options(1, pOptDesc->pzLastArg); + break; + case INDEX_OPT_UNSET: + set_options(0, pOptDesc->pzLastArg); + break; + }; + _EndOfFlagCode_; + }; + /* + cat <<_EOF_ + * for emacs */ + + export = "#include \n" + "#include \n" + "#include \n" + "#include \n" + "#include \n" + "#include \"config.h\"\n" + "#include \"compat/compat.h\""; + + include = 'void set_options(int mode, char const* pzArg);'; + + main = { + main-type = include; + tpl = ${testname}.tpl; + }; + _EOF_ + +# # # # # # # # # # TEMPLATE FILE # # # # # # # # # +# +# In one case we must not use built in echo. +# +cat > ${testname}.tpl <<- \__EOF + [= AutoGen5 Template -*- Mode: C -*- =] + [=(define proc-list "")=] + typedef int (do_proc_t)(void); + extern do_proc_t + [= (set! proc-list (string-append "do_print_undefined,\ndo_print_" + (join ",\ndo_print_" (stack "flag[0].keyword")) )) + (set! proc-list + (shell (string-append "${CLexe} -I4 --spread=1 <<_EOF_\n" + proc-list "\n_EOF_")) ) + proc-list =]; + do_proc_t* do_proc[] = { + [= (. proc-list) =] }; + + [=(shellf "procs='%s' ; ix=0 ; for p in ${procs} + do + p=`echo $p | sed s/,//` + echo int ${p}'(void) {' + printf ' fputs(\"'${p}'\\\\n\", stdout);\n' + echo \" return ${ix}; }\" + ix=`expr $ix + 1` + done" proc-list) =] + + int + do_dump_log(void) + { + return WHICH_IDX_PRINT != INDEX_OPT_DUMP_LOG; + } + + int + do_all_dump(void) + { + return WHICH_IDX_PRINT != INDEX_OPT_ALL_DUMP; + } + + int + do_set(int which_way) + { + printf("PRINT = 0x%lX\n", (unsigned long)DESC(PRINT).optCookie); + printf("SET = 0x%lX\n", (unsigned long)DESC(SET).optCookie); + if (which_way) + printf("0x%lX\n", OPT_VALUE_SET); + else + printf("0x%lX\n", (~ OPT_VALUE_SET) & SET_MEMBERSHIP_MASK); + return 0; + } + + void + set_options(int mode, char const* pzArg) + { + exit(atoi(pzArg)); + } + __EOF + +cat >> ${testname}.tpl <<- __EOF + int + main( int argc, char** argv ) + { + { + int ct = optionProcess(&${testname}_testOptions, argc, argv); + argc -= ct; + argv += ct; + } + + if (argc > 1) + return EXIT_FAILURE; + + /* + * Invoke the proper operational procedure. + */ + { + int res = 0; + switch (WHICH_IDX_PRINT) { + case INDEX_OPT_PRINT: res = do_proc[OPT_VALUE_PRINT](); break; + case INDEX_OPT_DUMP_LOG: res = do_dump_log(); break; + case INDEX_OPT_ALL_DUMP: res = do_all_dump(); break; + case INDEX_OPT_SET: res = do_set(1); break; + case INDEX_OPT_UNSET: res = do_set(0); break; + } + return res; + } + } + __EOF + +# # # # # # # # # # CREATE PROGRAM # # # # # # # # # + +echo ${AG_L} ${testname}.def +${AG_L} ${testname}.def || \ + failure AutoGen could not process + +compile "-?" + +# # # # # # # # # # HELP OUTPUT FILE # # # # # # # # # + +basehlp=${testname}.hlp +echo creating ${basehlp} +clean_help > ${basehlp} <<_EOF_ +${testname}-test - test complex main procedure +Usage: ${testname} { - [] | --[{=| }] }... [ ] + Flg Arg Option-Name Req? Description + -p KWd print YES Print operational info + -D no dump-log opt Dump the program log + - an alternate for 'print' + -A no all-dump opt Dump everything we've got + - an alternate for 'print' + -s Mbr set opt set options + - an alternate for 'print' + -u Str unset opt unset debug options + - an alternate for 'print' + -m Str msg-num opt message number + - may not be preset + - may appear multiple times + -? no help opt display extended usage information and exit + -! no more-help opt extended usage information passed thru pager + +Options are specified by doubled hyphens and their name or by a single +hyphen and the flag character. + +The valid "print" option keywords are: + one two three four five six seven eight nine ten + or an integer from 1 through 10 +The valid "set" option keywords are: + first second third fourth fifth sixth seventh + eighth ninth tenth eleventh twelfth thirteenth fourteenth + fifteenth sixteenth + or an integer mask with any of the lower 16 bits set +or you may use a numeric representation. Preceding these with a '!' +will clear the bits, specifying 'none' will clear all bits, and 'all' +will set them all. Multiple entries may be passed as an option +argument list. +_EOF_ + +cmp -s ${testname}.h*lp || \ + failure "`diff ${basehlp} ${testname}.help`" + +# # # # # # # # # # TEST OPERATION # # # # # # # # # # + +ix=0 +for f in one two three four five six seven eight nine ten +do + ix=`expr $ix + 1` + txt=`./${testname} -p $f` + test $? -eq $ix || \ + failure "'./${testname} -p $f' did not yield $ix" + test "${txt}" = "do_print_${f}" || \ + failure "'./${testname} -p $f' did not print 'do_print_${f}'" +done + +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## sh-basic-offset: 2 +## End: + +# end of enums.test diff --git a/autoopts/test/equiv.test b/autoopts/test/equiv.test new file mode 100755 index 0000000..4759b7c --- /dev/null +++ b/autoopts/test/equiv.test @@ -0,0 +1,273 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# +# equiv.test --- test option equivivalence classes +# +# Author: Bruce Korb +## +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + +. ./defs + +# # # # # # # # # # DEFINITIONS FILE # # # # # # # # # + +echo "creating ${testname}.def in `pwd`" +CFLAGS="-g -static" \ +testname="${testname}" test_main="${test_main}" \ +argument="${argument}" long_opts="${long_opts}" \ +${SHELLX} ${stdopts} option:'opt init' second=020 || \ + failure "Could not run stdopts.def" +cat >> ${testname}.def <<'_EOF_' +long-opts; + +flag = { + name = alpha; + descrip = "alpha opt"; + equivalence = alpha; + doc = 'alpha mumbling'; + arg-type = str; + arg-optional; +}; + +flag = { + name = beta; + descrip = "beta opt"; + equivalence = alpha; + doc = 'beta mumbling'; + arg-type = num; +}; + +flag = { + name = gamma; + descrip = "gamma opt"; + equivalence = alpha; + doc = 'gamma mumbling'; + arg-type = bool; +}; + +flag = { + name = omega; + descrip = "omega opt"; + equivalence = alpha; + doc = 'omega mumbling'; + arg-type = key; + keyword = uno, dos, tres, mucho; + arg-optional; + arg-default = mucho; +}; +_EOF_ +echo ${AG_L} ${testname}.def +${AG_L} ${testname}.def || \ + failure "AutoGen could not process - exited $?" + +compile "-?" + +# # # # # # # # # # HELP OUTPUT FILE # # # # # # # # # + +echo creating ${testname}-base.help +clean_help > ${testname}-base.help <<_EOF_ +test_${testname} - Test AutoOpts for ${testname} +Usage: equiv [ - [] | --[{=| }] ]... + Flg Arg Option-Name Description + -o Str option The option option descrip + -s Num second The second option descrip + opt alpha alpha opt + Num beta beta opt + - an alternate for 'alpha' + T/F gamma gamma opt + - an alternate for 'alpha' + opt omega omega opt + - an alternate for 'alpha' + -? no help display extended usage information and exit + -! no more-help extended usage information passed thru pager + +Options are specified by doubled hyphens and their name or by a single +hyphen and the flag character. + +The valid "omega" option keywords are: + uno dos tres mucho + or an integer from 0 through 3 +_EOF_ + +cmp -s ${testname}*.help || \ + failure "`diff ${testname}-base.help ${testname}.help`" + +cat > ${testname}-base.out <<_EOF_ +OPTION_CT=3 +export OPTION_CT +TEST_EQUIV_SECOND=2 # 0x2 +export TEST_EQUIV_SECOND +TEST_EQUIV_ALPHA=1 # 0x1 +export TEST_EQUIV_ALPHA +=== --beta 5 -o opt === +OPTION_CT=4 +export OPTION_CT +TEST_EQUIV_OPTION='opt' +export TEST_EQUIV_OPTION +TEST_EQUIV_ALPHA_MODE='BETA' +export TEST_EQUIV_ALPHA_MODE +TEST_EQUIV_BETA=5 # 0x5 +export TEST_EQUIV_BETA +=== --gamma Yes! === +OPTION_CT=2 +export OPTION_CT +TEST_EQUIV_ALPHA_MODE='GAMMA' +export TEST_EQUIV_ALPHA_MODE +TEST_EQUIV_GAMMA='true' +export TEST_EQUIV_GAMMA +=== --gamma false === +OPTION_CT=2 +export OPTION_CT +TEST_EQUIV_ALPHA_MODE='GAMMA' +export TEST_EQUIV_ALPHA_MODE +TEST_EQUIV_GAMMA='false' +export TEST_EQUIV_GAMMA +=== --omega tres === +OPTION_CT=2 +export OPTION_CT +TEST_EQUIV_ALPHA_MODE='OMEGA' +export TEST_EQUIV_ALPHA_MODE +TEST_EQUIV_OMEGA='tres' +export TEST_EQUIV_OMEGA +_EOF_ + +( set -e +x + ./${testname} --alpha -s 2 + echo === --beta 5 -o opt === + ./${testname} --beta 5 -o opt + echo === --gamma Yes! === + ./${testname} --gamma Yes! + echo === --gamma false === + ./${testname} --gamma false + echo === --omega tres === + ./${testname} --omega tres ) > ${testname}.out + +cmp -s ${testname}-base.out ${testname}.out || \ + failure "` + diff -c ${testname}-base.out ${testname}.out`" + +# # # # # # # # # # HELP OUTPUT FILE # # # # # # # # # + +echo creating ${testname}-base2.help +clean_help > ${testname}-base2.help <<_EOF_ +test_${testname} - Test AutoOpts for ${testname} +Usage: equiv [ - [] | --[{=| }] ]... + Flg Arg Option-Name Description + -o Str option The option option descrip + -s Num second The second option descrip + opt alpha alpha opt + Num beta beta opt + - an alternate for 'alpha' + T/F gamma gamma opt + - an alternate for 'alpha' + opt omega omega opt + - an alternate for 'alpha' + -? no help display extended usage information and exit + -! no more-help extended usage information passed thru pager + -> opt save-opts save the option state to a config file + -< Str load-opts load options from a config file + - disabled as '--no-load-opts' + - may appear multiple times + +Options are specified by doubled hyphens and their name or by a single +hyphen and the flag character. + +The following option preset mechanisms are supported: + - reading file ..../TD/.test_equivrc + +The valid "omega" option keywords are: + uno dos tres mucho + or an integer from 0 through 3 +_EOF_ + +echo 'homerc = "$$";' >> ${testname}.def + +echo ${AG_L} ${testname}.def +${AG_L} ${testname}.def || \ + failure AutoGen could not process + +compile "-?" +${SED} '/^ - reading file/s, file .*-testd/, file ..../TD/,' \ + ${testname}.help > ${testname}-test2.help +cmp -s ${testname}-base2.help ${testname}-test2.help || \ + failure "`diff ${testname}-base2.help ${testname}-test2.help`" + +echo 'gamma Yes' > .test_equivrc + +cat > ${testname}-base.out2 <<_EOF_ +=== -o opt === +OPTION_CT=2 +export OPTION_CT +TEST_EQUIV_OPTION='opt' +export TEST_EQUIV_OPTION +TEST_EQUIV_ALPHA_MODE='GAMMA' +export TEST_EQUIV_ALPHA_MODE +TEST_EQUIV_GAMMA='true' +export TEST_EQUIV_GAMMA +=== --gamma Yes! === +OPTION_CT=2 +export OPTION_CT +TEST_EQUIV_ALPHA_MODE='GAMMA' +export TEST_EQUIV_ALPHA_MODE +TEST_EQUIV_GAMMA='true' +export TEST_EQUIV_GAMMA +=== --gamma false === +OPTION_CT=2 +export OPTION_CT +TEST_EQUIV_ALPHA_MODE='GAMMA' +export TEST_EQUIV_ALPHA_MODE +TEST_EQUIV_GAMMA='false' +export TEST_EQUIV_GAMMA +=== --omega tres === +OPTION_CT=2 +export OPTION_CT +TEST_EQUIV_ALPHA_MODE='OMEGA' +export TEST_EQUIV_ALPHA_MODE +TEST_EQUIV_OMEGA='tres' +export TEST_EQUIV_OMEGA +_EOF_ + +( set -e + echo === -o opt === + ./${testname} -o opt + echo === --gamma Yes! === + ./${testname} --gamma Yes! + echo === --gamma false === + ./${testname} --gamma false + echo === --omega tres === + ./${testname} --omega tres ) > ${testname}.out2 + +cmp -s ${testname}-base.out2 ${testname}.out2 || \ + failure "` + diff -c ${testname}-base.out2 ${testname}.out2`" + +./${testname} --omega tres --beta 12 2>/dev/null && \ + failure "${testname}-2 ERROR: conflicting options accepted" + +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## End: + +# end of equiv.test diff --git a/autoopts/test/errors.test b/autoopts/test/errors.test new file mode 100755 index 0000000..527df26 --- /dev/null +++ b/autoopts/test/errors.test @@ -0,0 +1,231 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# ---------------------------------------------------------------------- +# errors.test --- test argument program attribute +# make sure that when it is not specified +# then option processing consumes all args. +# +# Author: Bruce Korb +## +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd +${VERBOSE} && kill_delay=10 || kill_delay=5 +. ./defs + +# # # # # # # # # # DEFINITIONS FILE # # # # # # # # # + +echo "creating ${testname}.def in `pwd`" + +testname="${testname}" \ +test_main="${test_main}" \ +argument="arg ..." \ +long_opts="yes" \ +${SHELLX} ${stdopts} option second:fumble ignored || \ + failure "Could not run stdopts.def" + +echo 'reorder-args;' >> ${testname}.def +${SED} -e '/"second"/a\ + must-set;' \ + -e '/"ignored"/a\ + omitted-usage = "we have dumped this"; ifdef = IGNORE_THIS;' \ + ${testname}.def > ${testname}.tmp +mv -f ${testname}.tmp ${testname}.def +echo "homerc = ${testname}RC;" >> ${testname}.def + +echo ${AG_L} ${testname}.def +${AG_L} ${testname}.def || \ + failure AutoGen could not process + +mkdir ${testname}RC +compile "--help" + +# # # # # # # # # # HELP OUTPUT FILE # # # # # # # # # + +echo creating ${testname}.res-help +clean_help > ${testname}.res-help <<'_EOF_' +test_errors - Test AutoOpts for errors +Usage: errors [ - [] | --[{=| }] ]... arg ... + Flg Arg Option-Name Description + -o no option The option option descrip + -s Str second The second option descrip + -i --- ignored we have dumped this + -? no help display extended usage information and exit + -! no more-help extended usage information passed thru pager + -> opt save-opts save the option state to a config file + -< Str load-opts load options from a config file + - disabled as '--no-load-opts' + - may appear multiple times + +Options are specified by doubled hyphens and their name or by a single +hyphen and the flag character. +Operands and options may be intermixed. They will be reordered. + +The following option preset mechanisms are supported: + - reading file errorsRC/.test_errorsrc +_EOF_ + +clean_help > ${testname}.ignored-expected <<\_EOF_ +errors: The 'ignored' option has been disabled. -- we have dumped this +test_errors - Test AutoOpts for errors +Usage: errors [ - [] | --[{=| }] ]... arg ... + Flg Arg Option-Name Description + -o no option The option option descrip + -s Str second The second option descrip + -? no help display extended usage information and exit + -! no more-help extended usage information passed thru pager + -> opt save-opts save the option state to a config file + -< Str load-opts load options from a config file + +Options are specified by doubled hyphens and their name or by a single +hyphen and the flag character. +Operands and options may be intermixed. They will be reordered. +_EOF_ + +dir=`pwd -P` || dir=`pwd` +${SED} "s#${dir}/##" ${testname}.help > ${testname}.bas-help +cmp -s ${testname}.*-help || \ + failure "help output: `diff ${testname}.*-help`" + +./${testname} -s foo -o -s bar 2> /dev/null && \ + failure ${testname} should not accept multiple options + +./${testname} -o -s foo > /dev/null 2>&1 && \ + failure ${testname} must have arguments + +./${testname} -o -s foo mumble > /dev/null || \ + failure ${testname} stumbled somehow + +./${testname} -o > /dev/null 2>&1 && \ + failure ${testname} "'option'" must have argument + +./${testname} -o mumble > /dev/null 2>&1 && \ + failure ${testname} must have second argument + +echo "second bumble" > ${testname}RC/.test_errorsrc +./${testname} -o mumble > /dev/null || \ + failure ${testname} did not see errorsRC/.test_errorsrc + +./${testname} --ignored > ${testname}.ignored 2>&1 && \ + failure "${testname} accepted --ignored" + +clean_help < ${testname}.ignored > ${testname}.ignored-result +cmp -s ${testname}.ignored-* || \ + failure "${testname}.ignored error: `diff ${testname}.ignored-*`" + +mv ${testname}RC/.test_errorsrc ${testname}RC/test_errors.rc +./${testname} --load=${testname}RC/test_errors.rc -o mumble > /dev/null || \ + failure ${testname} did not see errorsRC/test_errors.rc + +# # # # # # # # # # DEFINITIONS FILE # # # # # # # # # + +echo "allow_errors;" >> ${testname}.def + +echo ${AG_L} ${testname}.def +${AG_L} ${testname}.def || \ + failure AutoGen could not process allow-errors + +compile "--help" + +${SED} "s#${dir}/##" ${testname}.help > ${testname}.bas-help +cmp -s ${testname}.*-help || \ + failure "help output: `diff ${testname}.*-help`" + +# This time, having a duplicate should be ignored... +# +./${testname} -s foo -o -s bar mumble 2> /dev/null 1>&2 || \ + failure ${testname} should not object to multiple options + +# # # # # # # # # # DEFINITIONS FILE # # # # # # # # # + +${SED} '/second option/a\ + max = "10";' ${testname}.def > XX +mv -f XX ${testname}.def +cat >> ${testname}.def << '_EOF_' +flag = { + name = "another"; + max = '5'; + descrip = "Another option descrip"; + value = 'X'; +}; + +_EOF_ + +echo ${AG_L} ${testname}.def +${AG_L} ${testname}.def || \ + failure AutoGen could not process gnu-usage + +compile "--help" + +# # # # # # # # # # SORTED ARGS OUTPUT FILE # # # # # # # # # +test -n "${POSIXLY_CORRECT}" && { + POSIXLY_CORRECT='' + unset POSIXLY_CORRECT +} + +echo creating ${testname}-sh.samp +cat > ${testname}-sh.samp <<'_EOF_' +OPTION_CT=4 +export OPTION_CT +TEST_ERRORS_OPTION=1 # 0x1 +export TEST_ERRORS_OPTION +TEST_ERRORS_SECOND='foo' +export TEST_ERRORS_SECOND +TEST_ERRORS_ANOTHER=1 # 0x1 +export TEST_ERRORS_ANOTHER +set -- 'mum'\''ble' '-X' 'stumble' +OPTION_CT=0 +_EOF_ + +./${testname} "mum'ble" -os foo -X -- -X stumble > ${testname}-sh.out + +cmp -s ${testname}-sh.out ${testname}-sh.samp || \ + failure "`diff ${testname}-sh.samp ${testname}-sh.out`" + +cat >> ${testname}.def << '_EOF_' +flag = { + name = "still-another"; + ifdef = true ; ifndef = false; + descrip = "Another option descrip"; + value = 'Y'; +}; +_EOF_ + +case "${BASH_VERSION}" in +not-good-enough ) + echo "You are running Solaris without bash available." + echo "duplicate option flags cannot be tested." + ;; + +* ) + ${SED} '/ value /s/Y/X/;s/ ifndef =.*//' ${testname}.def > ${testname}-2.def + ${AG_L} ${testname}-2.def && \ + failure AutoGen processed conflicting flag values + ;; +esac + +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## End: + +# end of errors.test diff --git a/autoopts/test/getopt.test b/autoopts/test/getopt.test new file mode 100755 index 0000000..7fa56d8 --- /dev/null +++ b/autoopts/test/getopt.test @@ -0,0 +1,674 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# +# getopt.test --- test getopt_long argument processing +# +# Author: Bruce Korb +# +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + +. ./defs + +compile_getopt() { + run_ag opts -b${testname}-bn ${testname}.def || \ + failure "AutoGen could not process ${testname}.def #${1}" + + # Remove the variable comments so we can test against the expected result + # + ${SED} '/Last template edit:/d' getopt-test_${testname}.c \ + > ${testname}${1}-getopt.c + + # Finally, compile this thing: + # + ${CC} ${CFLAGS} -c ${testname}${1}-getopt.c || \ + failure "could not compile ${testname}1-getopt.c" + + ${SED} "${sed_omit_license}"' + /Packaged by /d + s@^Report .* bugs to.*"@\\n"@ + s@^Please send bug.*"@\\n"@ + s@\\n\\n\\n\\$@\\n\\n\\@ + s@\(and the flag character\.\\n.\)n\\$@\1@' ${testname}${1}-getopt.c \ + > ${testname}${1}-res.c + cmp -s ${testname}${1}-base.c ${testname}${1}-res.c || { set +x ; \ + failure "`diff -c ${testname}${1}-base.c ${testname}${1}-res.c`" ; } +} + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# +# Fix up a test-specific include directory: +# +# The getopt template presumes that everything has been installed. +# However, we have to work with the local stuff. So, remove the +# "autoopts-config" probing and replace with local stuff: +# +go_init() +{ + mkdir -p ${TMPDIR}/autoopts + test -d ${TMPDIR}/autoopts || exit 1 + CC="${CC} ${CFLAGS} ${INC}" + INC='' + AUTOGEN_TEMPL_DIRS=${TMPDIR} + CFLAGS="-I${TMPDIR}" + LDFLAGS="${LDFLAGS} ${LIB}" + export CFLAGS LDFLAGS TMPDIR AUTOGEN_TEMPL_DIRS INC CC + aolib=`find ${top_builddir}/autoopts -type f -name libopts.a` + case " ${LDFLAGS} " in + *' -lgen '* ) aolib=${aolib}\ -lgen ;; + esac + + cp ${top_srcdir}/autoopts/tpl/* ${TMPDIR}/. + test "X${top_srcdir}" = "X${top_builddir}" || \ + cp ${top_builddir}/autoopts/tpl/* ${TMPDIR}/. + chmod u+w ${TMPDIR}/* + + ${SED} -e "/^cflags=/s@=.*@='-I${TMPDIR}/autoopts -I${top_builddir}'@" \ + -e "/^ldflags=/s@=.*@='${aolib}'@" \ + ${TMPDIR}/usage.tlib > ${TMPDIR}/usage.tlib-XX + mv -f ${TMPDIR}/usage.tlib-XX ${TMPDIR}/usage.tlib + + # In order to compile correctly, we have to temporarily install the options.h + # header in our TMPDIR. We also must find that header first. Tweak CFLAGS: + # + DESTdestdir=${TMPDIR}/autoopts \ + top_builddir=${top_builddir} \ + CONFIG_SHELL="${SHELL}" \ + POSIX_SHELL="${SHELL}" \ + PS4='>ih-$FUNCNAME> ' \ + ${SHELLX} ${top_srcdir}/autoopts/install-hook.sh + + export AUTOGEN_TEMPL_DIRS=${TMPDIR} +} 1>&8 + +# # # # # # # # # # DEFINITIONS FILE # # # # # # # # # +go_samples() { + + echo "creating ${testname}.def in `pwd`" + ${SED} -e '1,/^## *START-DEFS/d' \ + -e '/^## *END-DEFS/{;s/.*//;q;}' \ + ${srcdir}/getopt.test > ${testname}.def + + # # # # # # # # # # BASE-1 OUTPUT FILE # # # # # # # # # + + echo creating ${testname}1-base.c + ${SED} -e '1,/^## *START-SOURCE1/d' \ + -e '/## *[E]ND-SOURCE1/{;s/ *#* *END-SOURCE1.*//;q;}' \ + ${srcdir}/getopt.test > ${testname}1-base.c + + # # # # # # # # # # BASE-2 OUTPUT FILE # # # # # # # # # + + echo creating ${testname}2-base.c + ${SED} -e '1,/^## *START-SOURCE2/d' \ + -e '/## *[E]ND-SOURCE2/{;s/ *#* *END-SOURCE2.*//;q;}' \ + ${srcdir}/getopt.test > ${testname}2-base.c +} + +# # # # # # # # # # RESULTS TESTING # # # # # # # # # + +go_init +go_samples +compile_getopt 1 + +${GREP} 'getopt_long' /usr/include/getopt.h >/dev/null && { + CFLAGS="${CFLAGS} -D_GNU_SOURCE=1" + ${SED} '/REMOVE/d;$a\ +long-opts;\ +version-value; +' ${testname}.def > ${testname}2.def + mv -f ${testname}.def ${testname}1.def + mv -f ${testname}2.def ${testname}.def + + compile_getopt 2 +} + +cleanup +exit 0 + +# # # # # # # # # # ==== DATA ==== # # # # # # # # # + +cat <<- _EODefs_ +## START-DEFS +AutoGen definitions getopt; + +prog-name = "test_getopt"; +prog-title = "Test AutoOpts for getopt"; +main = { main-type = shell-process; main-text = "";}; +config-header = 'config.h'; + +settable; +version = '1.2.3'; +help-value = 'h'; +gnu-usage; +no-libopts; + +copyright = { + date = "2003-2018"; + owner = "Odyssey Computing Concepts, Inc."; + author= "Bruce Korb"; + eaddr = "bkorb@gnu.org"; + type = lgpl; +}; + +flag = { + name = "option"; + descrip = "The option option descrip"; + value = 'o'; + arg_type = string; arg_default = 'opt init'; +}; + +flag = { + name = "second"; + descrip = "The second option descrip"; + value = 's'; + arg_type = string; arg_default = '020'; +}; + +flag = { + name = no_val; + descrip = 'option with no flag'; + value = 'F'; /* REMOVE */ + flags-must = max_val; +}; + +flag = { + name = max_val; + descrip = 'option with max ct'; + value = 'X'; /* REMOVE */ + max = '5'; +}; + +flag = { + name = min2_val; + descrip = 'option with min ct'; + value = 'M'; /* REMOVE */ + max = '50'; + flags-cant = max_val; + min = '5'; +}; + +flag = { + name = min_val; + descrip = 'option with min ct'; + value = '2'; /* REMOVE */ + max = '50'; + min = '5'; +}; +## END-DEFS +_EODefs_ + +# # # # # # # # # + +cat <<- _EOSource1_ +## START-SOURCE1 +#include "getopt-test_getopt.h" + +#include + +#include +#include +#include +#include +#include "getopt-bn.h" + +#ifndef DIRCH +# if defined(_WIN32) && !defined(__CYGWIN__) +# define DIRCH '\\' +# else +# define DIRCH '/' +# endif +#endif +/* + * Option flag character list + */ +static char z_opts[] = "o:s:FXM2hv"; + +/* + * AutoOpts library replacement routines: + */ +noreturn void +optionUsage (tOptions * pOptions, int status) +{ + if (status != 0) + fprintf (stderr, _("Try `%s -h' for more information.\n"), + test_getoptOptions.pzProgName); + else + { + fputs (_("test_getopt - Test AutoOpts for getopt\n\ +Usage: test_getopt { - [] }...\n\n\ + -o str The option option descrip\n\ + -s str The second option descrip\n\ + -F option with no flag\n\ + -X option with max ct\n\ + -M option with min ct\n\ + -2 option with min ct\n\ + -v output version information and exit\n\ + -h display extended usage information and exit\n\n\ +\n"), stdout); + } + + exit (status); +} + +noreturn void +optionPrintVersion (tOptions * pOptions, tOptDesc * pOptDesc) +{ + char const * pz_by = + _("test_getopt 1.2.3\n\ +Written by Bruce Korb.\n\n\ +Copyright (C) 2003-2018 Odyssey Computing Concepts, Inc.\n\ +This is free software; see the source for copying conditions. There is NO\n\ +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"); + + fputs (pz_by, stdout); + exit (EXIT_SUCCESS); +} + +/* + * If an option appears more often than is allowed, ... + */ +static void +usage_too_many (tOptDesc* pOptDesc) +{ + char const * pz = + _("test_getopt error: the '%s' option appears more than %d times\n"); + fprintf (stderr, pz, pOptDesc->pz_Name, pOptDesc->optMaxCt); + USAGE(EXIT_FAILURE); +} + +/* + * There is at least one option that must appear. + */ +static void +usage_too_few (tOptDesc* pOptDesc) +{ + char const * pz = + _("test_getopt error: the '%s' option must appear %d times\n"); + fprintf (stderr, pz, pOptDesc->pz_Name, pOptDesc->optMinCt); + USAGE(EXIT_FAILURE); +} + +/* + * There is at least one pair of options that may not appear together + * on the command line. + */ +static void +usage_cannot (char const* pz_what, char const* pz_cant) +{ + char const * pz = + _("test_getopt error: the `%s' option conflicts with the `%s' option.\n"); + fprintf (stderr, pz, pz_what, pz_cant); + USAGE(EXIT_FAILURE); +} + +/* + * There is at least one pair of options that are required to appear + * together on the command line. + */ +static void +usage_must (char const* pz_what, char const* pz_must) +{ + char const * pz = + _("test_getopt error: the `%s' option requires the `%s' option.\n"); + fprintf (stderr, pz, pz_what, pz_must); + USAGE(EXIT_FAILURE); +} + +/* + * Process the options for the "test_getopt" program. + * This function was generated to use the getopt(3posix) function. + * There are 8 options for this program, + * including "help (usage)" and "version". + */ +int +process_test_getopt_opts (int argc, char** argv) +{ + { + char * pz_prog = strrchr (argv[0], DIRCH); + /* + * This violates the const-ness of the pzProgName field. + * The const-ness is to prevent accidents. This is not accidental. + */ + char ** pp = VOIDP(&(test_getoptOptions.pzProgName)); + + if (pz_prog != NULL) + pz_prog++; + else + pz_prog = argv[0]; + *pp = pz_prog; + } + + for (;;) { + switch (getopt (argc, argv, z_opts)) { + case -1: goto leave_processing; + case 0: break; + + case VALUE_OPT_OPTION: + if (HAVE_OPT(OPTION)) + usage_too_many (&DESC(OPTION)); + SET_OPT_OPTION(optarg); + break; + + case VALUE_OPT_SECOND: + if (HAVE_OPT(SECOND)) + usage_too_many (&DESC(SECOND)); + SET_OPT_SECOND(optarg); + break; + + case VALUE_OPT_NO_VAL: + if (HAVE_OPT(NO_VAL)) + usage_too_many (&DESC(NO_VAL)); + SET_OPT_NO_VAL; + break; + + case VALUE_OPT_MAX_VAL: + if (DESC(MAX_VAL).optOccCt++ >= DESC(MAX_VAL).optMaxCt) + usage_too_many (&DESC(MAX_VAL)); + SET_OPT_MAX_VAL; + break; + + case VALUE_OPT_MIN2_VAL: + if (DESC(MIN2_VAL).optOccCt++ >= DESC(MIN2_VAL).optMaxCt) + usage_too_many (&DESC(MIN2_VAL)); + SET_OPT_MIN2_VAL; + break; + + case VALUE_OPT_MIN_VAL: + if (DESC(MIN_VAL).optOccCt++ >= DESC(MIN_VAL).optMaxCt) + usage_too_many (&DESC(MIN_VAL)); + SET_OPT_MIN_VAL; + break; + + case VALUE_OPT_HELP: + USAGE(EXIT_SUCCESS); + /* NOTREACHED */ + + case VALUE_OPT_VERSION: + optionPrintVersion (&test_getoptOptions, &DESC(VERSION)); + /* NOTREACHED */ + + default: + USAGE(EXIT_FAILURE); + } + } leave_processing:; + + if (HAVE_OPT(NO_VAL)) { + if (! HAVE_OPT(MAX_VAL)) + usage_must (DESC(NO_VAL).pz_Name, DESC(MAX_VAL).pz_Name); + } + + if (HAVE_OPT(MIN2_VAL)) { + if (HAVE_OPT(MAX_VAL)) + usage_cannot (DESC(MIN2_VAL).pz_Name, DESC(MAX_VAL).pz_Name); + if (DESC(MIN2_VAL).optOccCt < DESC(MIN2_VAL).optMinCt) + usage_too_few (&DESC(MIN2_VAL)); + } + else + usage_too_few (&DESC(MIN2_VAL)); + + if (DESC(MIN_VAL).optOccCt < DESC(MIN_VAL).optMinCt) + usage_too_few (&DESC(MIN_VAL)); + + return 0; +} ## END-SOURCE1 +_EOSource1_ + +# # # # # # # # # + +cat <<- _EOSource2_ +## START-SOURCE2 +#include "getopt-test_getopt.h" + +#include + +#include +#include +#include +#include +#include "getopt-bn.h" + +#ifndef DIRCH +# if defined(_WIN32) && !defined(__CYGWIN__) +# define DIRCH '\\' +# else +# define DIRCH '/' +# endif +#endif + +/* + * getopt_long option descriptor + */ +static struct option a_long_opts[] = { + { "option", 1, NULL, VALUE_OPT_OPTION }, + { "second", 1, NULL, VALUE_OPT_SECOND }, + { "no_val", 0, NULL, VALUE_OPT_NO_VAL }, + { "max_val", 0, NULL, VALUE_OPT_MAX_VAL }, + { "min2_val", 0, NULL, VALUE_OPT_MIN2_VAL }, + { "min_val", 0, NULL, VALUE_OPT_MIN_VAL }, + { "help", 0, NULL, VALUE_OPT_HELP }, + { "version", 0, NULL, VALUE_OPT_VERSION }, + { NULL, 0, NULL, 0 } +}; + +/* + * Option flag character list + */ +static char z_opts[] = "o:s:h"; + +/* + * AutoOpts library replacement routines: + */ +noreturn void +optionUsage (tOptions * pOptions, int status) +{ + if (status != 0) + fprintf (stderr, _("Try `%s --help' for more information.\n"), + test_getoptOptions.pzProgName); + else + { + fputs (_("test_getopt - Test AutoOpts for getopt\n\ +Usage: test_getopt { - [] | --[{=| }] }...\n\n\ + -o, --option=str The option option descrip\n\ + -s, --second=str The second option descrip\n\ + --no-val option with no flag\n\ + --max-val option with max ct\n\ + --min2-val option with min ct\n\ + --min-val option with min ct\n\ + --version output version information and exit\n\ + -h, --help display extended usage information and exit\n\n\ +Options are specified by doubled hyphens and their name or by a single\n\ +hyphen and the flag character.\n\ +\n"), stdout); + } + + exit (status); +} + +noreturn void +optionPrintVersion (tOptions * pOptions, tOptDesc * pOptDesc) +{ + char const * pz_by = + _("test_getopt 1.2.3\n\ +Written by Bruce Korb.\n\n\ +Copyright (C) 2003-2018 Odyssey Computing Concepts, Inc.\n\ +This is free software; see the source for copying conditions. There is NO\n\ +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"); + + fputs (pz_by, stdout); + exit (EXIT_SUCCESS); +} + +/* + * If an option appears more often than is allowed, ... + */ +static void +usage_too_many (tOptDesc* pOptDesc) +{ + char const * pz = + _("test_getopt error: the '%s' option appears more than %d times\n"); + fprintf (stderr, pz, pOptDesc->pz_Name, pOptDesc->optMaxCt); + USAGE(EXIT_FAILURE); +} + +/* + * There is at least one option that must appear. + */ +static void +usage_too_few (tOptDesc* pOptDesc) +{ + char const * pz = + _("test_getopt error: the '%s' option must appear %d times\n"); + fprintf (stderr, pz, pOptDesc->pz_Name, pOptDesc->optMinCt); + USAGE(EXIT_FAILURE); +} + +/* + * There is at least one pair of options that may not appear together + * on the command line. + */ +static void +usage_cannot (char const* pz_what, char const* pz_cant) +{ + char const * pz = + _("test_getopt error: the `%s' option conflicts with the `%s' option.\n"); + fprintf (stderr, pz, pz_what, pz_cant); + USAGE(EXIT_FAILURE); +} + +/* + * There is at least one pair of options that are required to appear + * together on the command line. + */ +static void +usage_must (char const* pz_what, char const* pz_must) +{ + char const * pz = + _("test_getopt error: the `%s' option requires the `%s' option.\n"); + fprintf (stderr, pz, pz_what, pz_must); + USAGE(EXIT_FAILURE); +} + +/* + * Process the options for the "test_getopt" program. + * This function was generated to use the getopt_long(3GNU) function. + * There are 8 options for this program, + * including "help (usage)" and "version". + */ +int +process_test_getopt_opts (int argc, char** argv) +{ + { + char * pz_prog = strrchr (argv[0], DIRCH); + /* + * This violates the const-ness of the pzProgName field. + * The const-ness is to prevent accidents. This is not accidental. + */ + char ** pp = VOIDP(&(test_getoptOptions.pzProgName)); + + if (pz_prog != NULL) + pz_prog++; + else + pz_prog = argv[0]; + *pp = pz_prog; + } + + for (;;) { + switch (getopt_long (argc, argv, z_opts, a_long_opts, NULL)) { + case -1: goto leave_processing; + case 0: break; + + case VALUE_OPT_OPTION: + if (HAVE_OPT(OPTION)) + usage_too_many (&DESC(OPTION)); + SET_OPT_OPTION(optarg); + break; + + case VALUE_OPT_SECOND: + if (HAVE_OPT(SECOND)) + usage_too_many (&DESC(SECOND)); + SET_OPT_SECOND(optarg); + break; + + case VALUE_OPT_NO_VAL: + if (HAVE_OPT(NO_VAL)) + usage_too_many (&DESC(NO_VAL)); + SET_OPT_NO_VAL; + break; + + case VALUE_OPT_MAX_VAL: + if (DESC(MAX_VAL).optOccCt++ >= DESC(MAX_VAL).optMaxCt) + usage_too_many (&DESC(MAX_VAL)); + SET_OPT_MAX_VAL; + break; + + case VALUE_OPT_MIN2_VAL: + if (DESC(MIN2_VAL).optOccCt++ >= DESC(MIN2_VAL).optMaxCt) + usage_too_many (&DESC(MIN2_VAL)); + SET_OPT_MIN2_VAL; + break; + + case VALUE_OPT_MIN_VAL: + if (DESC(MIN_VAL).optOccCt++ >= DESC(MIN_VAL).optMaxCt) + usage_too_many (&DESC(MIN_VAL)); + SET_OPT_MIN_VAL; + break; + + case VALUE_OPT_HELP: + USAGE(EXIT_SUCCESS); + /* NOTREACHED */ + + case VALUE_OPT_VERSION: + optionPrintVersion (&test_getoptOptions, &DESC(VERSION)); + /* NOTREACHED */ + + default: + USAGE(EXIT_FAILURE); + } + } leave_processing:; + + if (HAVE_OPT(NO_VAL)) { + if (! HAVE_OPT(MAX_VAL)) + usage_must (DESC(NO_VAL).pz_Name, DESC(MAX_VAL).pz_Name); + } + + if (HAVE_OPT(MIN2_VAL)) { + if (HAVE_OPT(MAX_VAL)) + usage_cannot (DESC(MIN2_VAL).pz_Name, DESC(MAX_VAL).pz_Name); + if (DESC(MIN2_VAL).optOccCt < DESC(MIN2_VAL).optMinCt) + usage_too_few (&DESC(MIN2_VAL)); + } + else + usage_too_few (&DESC(MIN2_VAL)); + + if (DESC(MIN_VAL).optOccCt < DESC(MIN_VAL).optMinCt) + usage_too_few (&DESC(MIN_VAL)); + + return 0; +} ## END-SOURCE2 +_EOSource2_ + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## sh-basic-offset: 2 +## End: + +# end of getopt.test diff --git a/autoopts/test/handler.test b/autoopts/test/handler.test new file mode 100755 index 0000000..01cfccc --- /dev/null +++ b/autoopts/test/handler.test @@ -0,0 +1,261 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# ---------------------------------------------------------------------- +# handler.test --- test option handling +# make sure that when it is not specified +# then option processing consumes all args. +# +# Author: Bruce Korb +## +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd +# +# ---------------------------------------------------------------------- + +. ./defs + +# # # # # # # # # # DEFINITIONS FILE # # # # # # # # # + +echo "creating ${testname}.def in `pwd`" +cat > ${testname}.def <<_EOF_ +AutoGen Definitions options; +prog-name = ${testname}; +prog-title = "Testing ${testname}"; + +flag = { + name = first; + descrip = "first description"; + extract_code; +}; + +flag = { + name = second; + descrip = "second description"; + arg-type = keyword; + keyword = alpha, beta, gamma, omega; +}; + +flag = { + name = third; + descrip = "third description"; + flag_code = " SomeCodeOrOther();"; +}; + +flag = { + name = fourth; + descrip = "fourth description"; + arg-type = keyword; + keyword = alpha, beta, gamma, omega; + arg-default = gamma; + arg-optional; +}; + +flag = { + name = fifth; + descrip = "fifth description"; + flag_proc = first; +}; + +flag = { + name = sixth; + descrip = "sixth description"; + arg-type = set-member; + keyword = alpha, beta, gamma, omega; + arg-default = gamma, beta; +}; +_EOF_ + +echo ${AG_L} ${testname}.def +${AG_L} ${testname}.def || \ + failure AutoGen could not process + +${SED} '/START =/a\ +SampleCode();\ +XXX-REMOVE-XXX' ${testname}.c > ${testname}.tmp +chmod 644 ${testname}.c +${SED} -e '/^XXX-REMOVE-XXX$/d;s/XXX-REMOVE-XXX//' \ + ${testname}.tmp > ${testname}.c + +${AG_L} ${testname}.def || \ + failure AutoGen could not process + +# We are testing to ensure the procedures are created correctly. +# The template line numbers and time stamps and all that cruft +# vary too much, so sed them away. +# +${SED} -e '1,/Create the static procedure(s) declared above/d' \ + -e '/extracted from.*near line/d' \ + -e '/^#line/d' \ + -e 's@handler_opt_strs+[0-9]*@handler_opt_strs+NNN@g' \ + -e 's@+NNN, *@+NNN, @g' \ + -e '/^#ifndef *PKGDATADIR/,$d' \ + ${testname}.c > ${testname}.test + +# # # # # # # # # # SAMPLE OUTPUT FILE # # # # # # # # # + +echo creating ${testname}.sample +cat > ${testname}.sample <<\_EOF_ + */ +/** + * The callout function that invokes the optionUsage function. + * + * @param[in] opts the AutoOpts option description structure + * @param[in] od the descriptor for the "help" (usage) option. + * @noreturn + */ +static void +doUsageOpt(tOptions * opts, tOptDesc * od) +{ + int ex_code; + ex_code = HANDLER_EXIT_SUCCESS; + optionUsage(&handlerOptions, ex_code); + /* NOTREACHED */ + exit(HANDLER_EXIT_FAILURE); + (void)opts; + (void)od; +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/** + * Code to handle the first option. + * + * @param[in] pOptions the handler options data structure + * @param[in,out] pOptDesc the option descriptor for this option. + */ +static void +doOptFirst(tOptions* pOptions, tOptDesc* pOptDesc) +{ +/* START =-= First Opt Code =-= DO NOT CHANGE THIS COMMENT */ +SampleCode(); +/* END =-= First Opt Code =-= DO NOT CHANGE THIS COMMENT */ + (void)pOptDesc; + (void)pOptions; +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/** + * Code to handle the second option. + * + * @param[in] pOptions the handler options data structure + * @param[in,out] pOptDesc the option descriptor for this option. + */ +static void +doOptSecond(tOptions* pOptions, tOptDesc* pOptDesc) +{ + + static char const zDef[2] = { 0x7F, 0 }; + static char const * const names[5] = { zDef, + handler_opt_strs+NNN, handler_opt_strs+NNN, handler_opt_strs+NNN, + handler_opt_strs+NNN }; + + if (pOptions <= OPTPROC_EMIT_LIMIT) { + (void) optionEnumerationVal(pOptions, pOptDesc, names, 5); + return; /* protect AutoOpts client code from internal callbacks */ + } + + pOptDesc->optArg.argEnum = + optionEnumerationVal(pOptions, pOptDesc, names, 5); +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/** + * Code to handle the third option. + * + * @param[in] pOptions the handler options data structure + * @param[in,out] pOptDesc the option descriptor for this option. + */ +static void +doOptThird(tOptions* pOptions, tOptDesc* pOptDesc) +{ + /* + * Be sure the flag-code[0] handles special values for the options pointer + * viz. (poptions <= OPTPROC_EMIT_LIMIT) *and also* the special flag bit + * ((poptdesc->fOptState & OPTST_RESET) != 0) telling the option to + * reset its state. + */ + /* extracted from handler.def, line 21 */ + SomeCodeOrOther(); + (void)pOptDesc; + (void)pOptions; +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/** + * Code to handle the fourth option. + * + * @param[in] pOptions the handler options data structure + * @param[in,out] pOptDesc the option descriptor for this option. + */ +static void +doOptFourth(tOptions* pOptions, tOptDesc* pOptDesc) +{ + + static char const * const names[4] = { + handler_opt_strs+NNN, handler_opt_strs+NNN, handler_opt_strs+NNN, + handler_opt_strs+NNN }; + + if (pOptions <= OPTPROC_EMIT_LIMIT) { + (void) optionEnumerationVal(pOptions, pOptDesc, names, 4); + return; /* protect AutoOpts client code from internal callbacks */ + } + + if (pOptDesc->optArg.argString == NULL) + pOptDesc->optArg.argEnum = FOURTH_GAMMA; + else + pOptDesc->optArg.argEnum = + optionEnumerationVal(pOptions, pOptDesc, names, 4); +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/** + * Code to handle the sixth option. + * + * @param[in] pOptions the handler options data structure + * @param[in,out] pOptDesc the option descriptor for this option. + */ +static void +doOptSixth(tOptions* pOptions, tOptDesc* pOptDesc) +{ + + static char const * const names[4] = { + "alpha", "beta", "gamma", "omega" + }; + /* + * This function handles special invalid values for "pOptions" + */ + optionSetMembers(pOptions, pOptDesc, names, 4); +} + +/** + * The directory containing the data associated with handler. + */ +_EOF_ +pair="${testname}.test ${testname}.sample" +cmp -s ${pair} || failure "`diff -c ${pair}`" + +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## End: + +# end of handler.test diff --git a/autoopts/test/immediate.test b/autoopts/test/immediate.test new file mode 100755 index 0000000..8967fd5 --- /dev/null +++ b/autoopts/test/immediate.test @@ -0,0 +1,122 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# ---------------------------------------------------------------------- +# immediate.test --- test immediate option handling +# +# Author: Bruce Korb +## +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2017 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd +#--copyright-mark "(copyright \\(c\\)[ \t]+|" \ +# "date[ \t]*=[ \t]*\")([12][90][0-9][0-9])" +# ---------------------------------------------------------------------- + +. ./defs + +# # # # # # # # # # DEFINITIONS FILE # # # # # # # # # + +echo "creating ${testname}.def in `pwd`" + +cat > ${testname}.def << _EOF_ +AutoGen definitions options; + +prog-name = "test_${testname}"; +prog-title = "Test AutoOpts for ${testname}"; +include = "#include \nint invocation_ct = 0;"; +config-header = 'config.h'; +version = '1.0'; +omit-nls-code; +copyright = { + date = "1992-2017"; + owner = "Bruce Korb"; + eaddr = "autogen-users@lists.sourceforge.net"; + type = gpl; +}; + +flag = { + name = "second"; + descrip = "The second option descrip"; + immediate = also; + immed-disable = also; + disable = not; + arg-type = string; + flag-code = " invocation_ct++;"; +}; + +main = { + main-type = main; + main-text = ' printf( "invocation_ct = %d\\n", invocation_ct );'; +}; + +_EOF_ + +INC=`echo ${INC} | ${SED} 's/-lguile//;s/-lqthreads//'` +CFLAGS="-g`echo ' '${CFLAGS}' ' | \ + ${SED} 's, -O2 , -O0 ,;s/ -g[^ ]* / /'`" + +echo ${AG_L} ${testname}.def +${AG_L} ${testname}.def || \ + failure AutoGen could not process + +sedcmd="/All arguments are named options./q" +compile "help" + +# # # # # # # # # # HELP OUTPUT FILE # # # # # # # # # + +echo creating ${testname}.hlp +clean_help > ${testname}.hlp << '_EOF_' +test_immediate - Test AutoOpts for immediate - Ver. 1.0 +Usage: immediate [ [{=| }] ]... + Arg Option-Name Description + Str second The second option descrip + - disabled as '--not-second' + opt version output version information and exit + no help display extended usage information and exit + no more-help extended usage information passed thru pager + +All arguments are named options. +_EOF_ + +cmp -s ${testname}.help ${testname}.hlp || { set +x ; \ + failure "`diff -c ${testname}.hlp ${testname}.help`" ; } + +f=`./${testname} second=hand` +test "$f" = "invocation_ct = 2" || \ + failure "enabled option not processed twice" + +f=`./${testname} not-second` +test "$f" = "invocation_ct = 2" || \ + failure "DIS-abled option not processed twice" + +f=`./${testname} help version=c | ${FGREP} 'Usage:'` +test -z "${f}" && failure "no Usage: in help text" + +f=`./${testname} version=c help | ${FGREP} -i 'Copyright (C)'` +test -z "${f}" && failure "no 'Copyright (C)' in version text" + +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## End: + +# end of immediate.test diff --git a/autoopts/test/keyword.test b/autoopts/test/keyword.test new file mode 100755 index 0000000..1a3f459 --- /dev/null +++ b/autoopts/test/keyword.test @@ -0,0 +1,506 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# ---------------------------------------------------------------------- +# keyword.test --- keyword option processing +# +# Author: Bruce Korb +## +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd +# +# ---------------------------------------------------------------------- + +. ./defs + +# # # # # # # # # # DEFINITIONS FILE # # # # # # # # # + +echo "creating ${testname}.def in `pwd`" +testname="${testname}" test_main="" \ +argument="${argument}" long_opts="yes" \ +${SHELLX} ${stdopts} option:'opt init' || failure "Could not run stdopts.def" +cat >> ${testname}.def <<- _EndOfDef_ + help_value = X; + homerc = '.'; + rcfile = ${testname}.cfg; + + flag = { + name = trace; + arg-type = keyword; + arg-default = nothing; + arg-name = level; + descrip = "tracing level of detail"; + keyword = nothing, templates, block-macros, expressions, + explanations; + }; + + flag = { + name = sets; + arg-type = set-members; + arg-default = second, fourth; + arg-name = member-list; + descrip = "set membership testing"; + keyword = first, second, third, fourth, fifth, + sixth, seventh, eighth, ninth, tenth, + eleventh, twelfth, thirteenth, fourteenth, fifteenth, + sixteenth, seventeenth, eighteenth; + }; + main = { main-type = shell-process; }; + _EndOfDef_ + +echo ${AG_L} ${testname}.def +${AG_L} ${testname}.def || \ + failure AutoGen could not process + +compile "-X" + +# # # # # # # # # # HELP OUTPUT FILE # # # # # # # # # + +echo creating ${testname}.bas-help +clean_help > ${testname}.bas-help <<\_EOF_ +test_keyword - Test AutoOpts for keyword +Usage: keyword [ - [] | --[{=| }] ]... + Flg Arg Option-Name Description + -o Str option The option option descrip + KWd trace tracing level of detail + Mbr sets set membership testing + - is a set membership option + -X no help display extended usage information and exit + -! no more-help extended usage information passed thru pager + -> opt save-opts save the option state to a config file + -< Str load-opts load options from a config file + - disabled as '--no-load-opts' + - may appear multiple times + +Options are specified by doubled hyphens and their name or by a single +hyphen and the flag character. + +The following option preset mechanisms are supported: + - reading file ./keyword.cfg + +The valid "trace" option keywords are: + nothing templates block-macros expressions explanations + or an integer from 0 through 4 +The valid "sets" option keywords are: + first second third fourth fifth sixth + seventh eighth ninth tenth eleventh twelfth + thirteenth fourteenth fifteenth sixteenth seventeenth eighteenth + or an integer mask with any of the lower 18 bits set +or you may use a numeric representation. Preceding these with a '!' +will clear the bits, specifying 'none' will clear all bits, and 'all' +will set them all. Multiple entries may be passed as an option +argument list. +_EOF_ + +dir=`pwd -P` || dir=`pwd` +${SED} "s#${dir}/##" ${testname}.help > ${testname}.res-help +pair="${testname}.bas-help ${testname}.res-help" +cmp -s ${pair} || \ + failure "help output:$nl`diff -u ${pair}`" + +./${testname} --trace=exp > /dev/null 2>&1 && \ + failure "${testname} accepted ambiguous keyword" + +./${testname} --trace=999 > /dev/null 2>&1 && \ + failure "${testname} accepted too much tracing" + +./${testname} --trace=~0 > /dev/null 2>&1 || \ + failure "${testname} would not accept max tracing" + +./${testname} --trace=expr --set=thirteen,ninth,third > ${testname}.t1-s || \ + failure "${testname} did not handle its options" + +cat > ${testname}.t1-b <<- \_EndTst_ + OPTION_CT=2 + export OPTION_CT + TEST_KEYWORD_TRACE='expressions' + export TEST_KEYWORD_TRACE + TEST_KEYWORD_SETS=4366 # 0x110E + export TEST_KEYWORD_SETS + readonly SETS_FIRST=1 # 0x1 + readonly SETS_SECOND=2 # 0x2 + readonly SETS_THIRD=4 # 0x4 + readonly SETS_FOURTH=8 # 0x8 + readonly SETS_FIFTH=16 # 0x10 + readonly SETS_SIXTH=32 # 0x20 + readonly SETS_SEVENTH=64 # 0x40 + readonly SETS_EIGHTH=128 # 0x80 + readonly SETS_NINTH=256 # 0x100 + readonly SETS_TENTH=512 # 0x200 + readonly SETS_ELEVENTH=1024 # 0x400 + readonly SETS_TWELFTH=2048 # 0x800 + readonly SETS_THIRTEENTH=4096 # 0x1000 + readonly SETS_FOURTEENTH=8192 # 0x2000 + readonly SETS_FIFTEENTH=16384 # 0x4000 + readonly SETS_SIXTEENTH=32768 # 0x8000 + readonly SETS_SEVENTEENTH=65536 # 0x10000 + readonly SETS_EIGHTEENTH=131072 # 0x20000 + _EndTst_ + +pair="${testname}.t1-b ${testname}.t1-s" +cmp -s ${pair} || \ + failure "miscompare${nl}`diff -u ${pair}`" + +rm -f ${testname}.cfg +./${testname} --trace=expr --set=+thirteen,ninth,third --save=${testname}.cfg || \ + failure "${testname} could not save its options" + +${EGREP} -v '^#' ${testname}.cfg > ${testname}res.cfg || \ + failure "${testname} could not create ${testname}.cfg" + +cat > ${testname}base.cfg <<- \_EndIni_ + trace = expressions + sets = =second + third + fourth + ninth + thirteenth + _EndIni_ + +pair="${testname}base.cfg ${testname}res.cfg" +cmp -s $pair || \ + failure "miscompare${nl}`diff -u $pair`" + +${AG_L} -T agman-cmd.tpl ${testname}.def +test -f test_${testname}.1 || \ + failure "'test_${testname}.1' was not produced" +mv test_${testname}.1 ${testname}.1 + +${SED} '1,/^## BEGIN-MAN/d + /^## *END-MAN/,$d' ${test_src} > ${testname}-base.1 + +${SED} '1,/^\.SH NAME/d' ${testname}.1 > ${testname}-res.1 +pair="${testname}-base.1 ${testname}-res.1" +cmp -s $pair || \ + failure "mismatched:${nl}`diff -u $pair`" + +# # # # # # # # # # CHECK OUT MDOC # # # # # # # # # # # + +${AG_L} -T agmdoc-cmd.tpl ${testname}.def +test -f test_${testname}.1 || \ + failure "'test_${testname}.1' was not produced" +mv test_${testname}.1 ${testname}.mdoc + +${SED} '1,/^## *BEGIN-MDOC/d + /^## *END-MDOC/,$d' ${test_src} > ${testname}-base.mdoc + +${SED} '/DO NOT EDIT/,/and the template file/d + /^\.Os /d + /^\.Dd /d + /^$/d' \ + ${testname}.mdoc > ${testname}-res.mdoc +cmp -s ${testname}-base.mdoc ${testname}-res.mdoc || \ + failure "`diff -u ${testname}-base.mdoc ${testname}-res.mdoc`" + +# # # # # # # # # # CHECK OUT VAL2STR # # # # # # # # # # # + +exec 3> ${testname}_2.def +${SED} '/^prog-name/s/";/_2";/;/^main *=/,$d' ${testname}.def >&3 +cat >&3 <<- \_EOF_ + include = '#include '; + main = { + main-type = main; + main-text = + ' printf( "%s\n", OPT_TRACE_VAL2STR( OPT_VALUE_TRACE ));'; + }; + _EOF_ +exec 3>&- + +echo ${AG_L} ${testname}_2.def +${AG_L} ${testname}_2.def || \ + failure AutoGen could not process + +Csrc=${testname}_2 +Dnam=${Csrc} +compile "-X" || failure "cannot compile ${testname}_2" + +val=`./${testname}_2 --trace=expr 2>&1` || \ + failure "cannot run ${testname}_2" + +case "${val}" in +expressions) : ;; +* ) failure "${testname}_2 returned '${val}', not 'expressions': + ${testname}_2 --trace=expr" ;; +esac + +cleanup + +exit 0 + +# # # # # # # # # # # MAN PAGE + +cat <<_End_Of_ManPage_ +## BEGIN-MAN +\f\*[B-Font]test_keyword\fP +\- Test AutoOpts for keyword +.SH SYNOPSIS +\f\*[B-Font]test_keyword\fP +.\" Mixture of short (flag) options and long options +[\f\*[B-Font]\-flags\f[]] +[\f\*[B-Font]\-flag\f[] [\f\*[I-Font]value\f[]]] +[\f\*[B-Font]\-\-option-name\f[][[=| ]\f\*[I-Font]value\f[]]] +.sp \n(Ppu +.ne 2 + +All arguments must be options. +.sp \n(Ppu +.ne 2 + +This program will emit text that is expected to be evaluated by +a Bourne-compatible shell, thus digesting the options for the script. +.sp \n(Ppu +.ne 2 + +.SH "DESCRIPTION" +There is no description for this command. +.SH "OPTIONS" +.TP +.NOP \f\*[B-Font]\-o\f[] \f\*[I-Font]string\f[], \f\*[B-Font]\-\-option\f[]=\f\*[I-Font]string\f[] +The option option descrip. +The default +\f\*[I-Font]string\f[] +for this option is: +.ti +4 + opt init +.sp +This option has not been fully documented. +.TP +.NOP \f\*[B-Font]\-\-trace\f[]=\f\*[I-Font]level\f[] +tracing level of detail. +This option takes a keyword as its argument. The argument sets an enumeration value that can +be tested by comparing them against the option value macro. +The available keywords are: +.in +4 +.nf +.na +nothing templates block-macros +expressions explanations +.fi +or their numeric equivalent. +.in -4 +.sp +The default +\f\*[I-Font]level\f[] +for this option is: +.ti +4 + nothing +.sp +This option has not been fully documented. +.TP +.NOP \f\*[B-Font]\-\-sets\f[]=\f\*[I-Font]member\-list\f[] +set membership testing. +This option takes a keyword as its argument list. Each entry turns on or off +membership bits. The bits are set by name or numeric value and cleared +by preceding the name or number with an exclamation character ('!'). +They can all be cleared with the magic name \fInone\fR and they can all be set +with +.IR all . +A single option will process a list of these values. +The available keywords are: +.in +4 +.nf +.na +first second third fourth +fifth sixth seventh eighth +ninth tenth eleventh twelfth +thirteenth fourteenth fifteenth sixteenth +seventeenth eighteenth +.fi +or their numeric equivalent. +.in -4 +.sp +The default +\f\*[I-Font]member\-list\f[] +for this option is: +.ti +4 + second + fourth +.sp +This option has not been fully documented. +.TP +.NOP \f\*[B-Font]\-X\f[], \f\*[B-Font]\-\-help\f[] +Display usage information and exit. +.TP +.NOP \f\*[B-Font]\-\&!\f[], \f\*[B-Font]\-\-more-help\f[] +Pass the extended usage information through a pager. +.TP +.NOP \f\*[B-Font]\->\f[] [\f\*[I-Font]cfgfile\f[]], \f\*[B-Font]\-\-save-opts\f[] [=\f\*[I-Font]cfgfile\f[]] +Save the option state to \fIcfgfile\fP. The default is the \fIlast\fP +configuration file listed in the \fBOPTION PRESETS\fP section, below. +The command will exit after updating the config file. +.TP +.NOP \f\*[B-Font]\-<\f[] \f\*[I-Font]cfgfile\f[], \f\*[B-Font]\-\-load-opts\f[]=\f\*[I-Font]cfgfile\f[], \f\*[B-Font]\-\-no-load-opts\f[] +Load options from \fIcfgfile\fP. +The \fIno-load-opts\fP form will disable the loading +of earlier config/rc/ini files. \fI\-\-no-load-opts\fP is handled early, +out of order. +.PP +.SH "OPTION PRESETS" +Any option that is not marked as \fInot presettable\fP may be preset +by loading values from configuration ("RC" or ".INI") file(s). +The file "\fI./keyword.cfg\fP" will be used, if present. +.SH "FILES" +See \fBOPTION PRESETS\fP for configuration files. +.SH "EXIT STATUS" +One of the following exit values will be returned: +.TP +.NOP 0 " (EXIT_SUCCESS)" +Successful program execution. +.TP +.NOP 1 " (EXIT_FAILURE)" +The operation failed or the command syntax was not valid. +.TP +.NOP 66 " (EX_NOINPUT)" +A specified configuration file could not be loaded. +.TP +.NOP 70 " (EX_SOFTWARE)" +libopts had an internal operational error. Please report +it to autogen-users@lists.sourceforge.net. Thank you. +.PP +.SH "NOTES" +This manual page was \fIAutoGen\fP-erated from the \fBtest_keyword\fP +option definitions. +## END-MAN +_End_Of_ManPage_ + +# # # # # # # # # # # MDOC PAGE + +cat <<_End_Of_MdocPage_ +## BEGIN-MDOC +.Dt TEST_KEYWORD 1 User Commands +.Os +.Sh NAME +.Nm test_keyword +.Nd Test AutoOpts for keyword +.Sh SYNOPSIS +.Nm +.\" Mixture of short (flag) options and long options +.Op Fl flags +.Op Fl flag Op Ar value +.Op Fl \-option\-name Ns Oo Oo Ns "=| " Oc Ns Ar value Oc +.Pp +All arguments must be options. +.Pp +This program will emit text that is expected to be evaluated by +a Bourne\-compatible shell, thus digesting the options for the script. +.Pp +.Sh "DESCRIPTION" +There is no description for this command. +.Sh "OPTIONS" +.Bl -tag +.It Fl o Ar string , Fl \-option Ns = Ns Ar string +The option option descrip. +The default +.Ar string +for this option is: +.ti +4 + opt init +.sp +This option has not been fully documented. +.It Fl \-trace Ns = Ns Ar level +tracing level of detail. +This option takes a keyword as its argument. The argument sets an enumeration value that can +be tested by comparing them against the option value macro. +The available keywords are: +.in +4 +.nf +.na +nothing templates block\-macros +expressions explanations +.fi +or their numeric equivalent. +.in -4 +.sp +The default +.Ar level +for this option is: +.ti +4 + nothing +.sp +This option has not been fully documented. +.It Fl \-sets Ns = Ns Ar member\-list +set membership testing. +This option takes a keyword as its argument list. Each entry turns on or off +membership bits. The bits are set by name or numeric value and cleared +by preceding the name or number with an exclamation character ('!'). +They can all be cleared with the magic name \fInone\fR and they can all be set +with +.IR all . +A single option will process a list of these values. +The available keywords are: +.in +4 +.nf +.na +first second third fourth +fifth sixth seventh eighth +ninth tenth eleventh twelfth +thirteenth fourteenth fifteenth sixteenth +seventeenth eighteenth +.fi +or their numeric equivalent. +.in -4 +.sp +The default +.Ar member\-list +for this option is: +.ti +4 + second + fourth +.sp +This option has not been fully documented. +.It Fl X , Fl \-help +Display usage information and exit. +.It Fl \&! , Fl \-more\-help +Pass the extended usage information through a pager. +.It Fl > Oo Ar cfgfile Oc , Fl \-save\-opts Oo Ns = Ns Ar cfgfile Oc +Save the option state to \fIcfgfile\fP. The default is the \fIlast\fP +configuration file listed in the \fBOPTION PRESETS\fP section, below. +The command will exit after updating the config file. +.It Fl < Ar cfgfile , Fl \-load\-opts Ns = Ns Ar cfgfile , Fl \-no\-load\-opts +Load options from \fIcfgfile\fP. +The \fIno\-load\-opts\fP form will disable the loading +of earlier config/rc/ini files. \fI\-\-no\-load\-opts\fP is handled early, +out of order. +.El +.Sh "OPTION PRESETS" +Any option that is not marked as \fInot presettable\fP may be preset +by loading values from configuration ("RC" or ".INI") file(s). +The file "\fI./keyword.cfg\fP" will be used, if present. +.Sh "FILES" +See \fBOPTION PRESETS\fP for configuration files. +.Sh "EXIT STATUS" +One of the following exit values will be returned: +.Bl -tag +.It 0 " (EXIT_SUCCESS)" +Successful program execution. +.It 1 " (EXIT_FAILURE)" +The operation failed or the command syntax was not valid. +.It 66 " (EX_NOINPUT)" +A specified configuration file could not be loaded. +.It 70 " (EX_SOFTWARE)" +libopts had an internal operational error. Please report +it to autogen\-users@lists.sourceforge.net. Thank you. +.El +.Sh "NOTES" +This manual page was \fIAutoGen\fP\-erated from the \fBtest_keyword\fP +option definitions. +## END-MDOC +_End_Of_MdocPage_ + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## End: + +# end of keyword.test diff --git a/autoopts/test/library.test b/autoopts/test/library.test new file mode 100755 index 0000000..0514721 --- /dev/null +++ b/autoopts/test/library.test @@ -0,0 +1,169 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# ---------------------------------------------------------------------- +# library.test --- test library options +# +# Author: Bruce Korb +## +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd +# +# ---------------------------------------------------------------------- + +. ./defs + +# # # # # # # # # # DEFINITIONS FILE # # # # # # # # # + +DEND=\<\<'- _DESC_END_' + +cat > ${testname}-libopts.def <<- _EODefs_ + flag = { name = zzyzx-opts; + documentation; + lib-name = zzyzx; + descrip = ${DEND} + This option introduces the options for the + zzyzx library + _DESC_END_; + }; + flag = { + name = library; + value = c; + ifdef = LIBOPTS; + descrip = "library test"; + doc = mumble; + }; + _EODefs_ + +cat > ${testname}-lib.def <<- _EODefs_ + + AutoGen definitions options; + + prog-name = ${testname}; + prog-title = lib-${testname}; + config-header = 'config.h'; + + library; + #include ${testname}-libopts.def + _EODefs_ + +cat > ${testname}-prog.def <<- _EOF_ + + AutoGen definitions options; + + prog-name = test-lib-prog; + prog-title = 'Test ${testname} Program'; + config-header = 'config.h'; + + flag = { + name = program; + value = p; + descrip = "${testname} program test"; + doc = stumble; + }; + + #include ${testname}-libopts.def + _EOF_ + +echo ${AG_L} ${testname}-lib.def +${AG_L} ${testname}-lib.def || \ + failure AutoGen could not process ${testname}-lib.def + +echo ${AG_L} ${testname}-prog.def +${AG_L} ${testname}-prog.def || \ + failure AutoGen could not process ${testname}-prog.def + +for f in lib prog +do + ${SED} -e '1,/include /d' \ + -e '/endif .* AUTOOPTS_.*_H_GUARD/,$d' \ + -e 's/near line [0-9]*/near line XXX/' \ + ${testname}-${f}.h > ${testname}-${f}.h-res || \ + failure could not sed ${testname}-${f}.h +done + +# # # # # # # # # # TEST PROGRAM # # # # # # # # # # + +cat > ${testname}-lib.c <<- _EOCode_ + #include + #define LIBOPTS + #include "${testname}-lib.h" + void check_library_opt( void ); + void check_library_opt( void ) { + if (HAVE_OPT(LIBRARY)) return; + exit( EXIT_FAILURE ); } + _EOCode_ +test $? -eq 0 || failure cannot create ${testname}-lib.c + +${CC} ${CFLAGS} ${INC} -o ${testname}-lib.o -c ${testname}-lib.c +test $? -eq 0 || failure cannot compile ${testname}-lib.c + +cat > ${testname}-main.c <<- _EOCode_ + #include + #include + #define LIBOPTS + #include "${testname}-prog.c" + extern void check_library_opt( void ); + int main( int argc, char** argv ) { + (void)optionProcess( &test_lib_progOptions, argc, argv ); + check_library_opt(); + return EXIT_SUCCESS; } + _EOCode_ + +${CC} ${CFLAGS} ${INC} -o ${testname} ${testname}-main.c ${testname}-lib.o ${LIB} +test $? -eq 0 || failure cannot compile ${testname}-main.c + +./${testname} -c || failure library option not detected + +# # # # # # # # # # HELP OUTPUT # # # # # # # # # # + +./${testname} -? | clean_help > ${testname}.help-sample + +clean_help > ${testname}.help-base <<- _EOHelp_ +test-lib-prog - Test library Program +Usage: library [ - ]... + Flg Arg Option-Name Description + -p no program library program test + +This option introduces the options for the zzyzx library: + + Flg Arg Option-Name Description + -c no library library test + +Version, usage and configuration options: + + Flg Arg Option-Name Description + -? no help display extended usage information and exit + -! no more-help extended usage information passed thru pager + + _EOHelp_ + +cmp ${testname}.help-* || \ + failure "help output mismatch: +`diff ${testname}.help-*`" + +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## End: + +# end of library.test diff --git a/autoopts/test/main.test b/autoopts/test/main.test new file mode 100755 index 0000000..63659ff --- /dev/null +++ b/autoopts/test/main.test @@ -0,0 +1,123 @@ +#! /bin/sh +# -*- Mode: Shell-Script -*- +# ---------------------------------------------------------------------- +# main.test --- test main program attribute +# make sure that when it is not specified +# then option processing consumes all args. +# +# Author: Bruce Korb +## +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd +# +# ---------------------------------------------------------------------- + +. ./defs + +# # # # # # # # # # DEFINITIONS FILE # # # # # # # # # + +echo "creating ${testname}.def in `pwd`" +testname="${testname}" \ +argument="${argument}" long_opts="${long_opts}" \ +${SHELLX} ${stdopts} option:'opt init' second=020 || \ + failure "Could not run stdopts.def" + +exec 4> ${testname}.def2 +${SED} '/test_main=/d' ${testname}.def >&4 +unset test_main +cat >&4 <<- _EOF_ + explain = 'This is some explanatory text.'; + argument = '[ ... ]'; + main = { + handler-proc = fumble; + fumble-code = ' printf("%s\n", pz_entry);'; + main-type = for-each; + interleaved; + }; + _EOF_ +exec 4>&- +mv -f ${testname}.def2 ${testname}.def + +echo ${AG_L} ${testname}.def +${AG_L} ${testname}.def || \ + failure AutoGen could not process + +compile "-?" + +# # # # # # # # # # HELP OUTPUT FILE # # # # # # # # # + +basehlp=${testname}.hlp +echo creating ${basehlp} +clean_help > ${basehlp} <<'_EOF_' +test_main - Test AutoOpts for main +Usage: main [ - [] ]... [ ... ] + Flg Arg Option-Name Description + -o Str option The option option descrip + -s Num second The second option descrip + -? no help display extended usage information and exit + -! no more-help extended usage information passed thru pager + +This is some explanatory text. + +If no arguments are provided, input arguments are read from stdin, +one per line; blank and '#'-prefixed lines are comments. +Options may appear in the input interspersed with the 'normal' input. +'stdin' may not be a terminal (tty). +_EOF_ + +pair=`echo ${testname}.h*lp` +cmp -s $pair || \ + failure "DIFFER: $pair +`diff $pair`" + +# # # # # # # # # # TEST OPERATION # # # # # # # # # # +sedcmd='/illegal option /d' +echo '--help' | ./${testname} 2>&1 | clean_help > ${testname}.out + +pair="${testname}.hlp ${testname}.out" +cmp -s $pair || \ + failure "DIFFER: $pair +`diff ${testname}.hlp ${testname}.out`" + +./${testname} > ${testname}.out2 < ${testname}.base2 <<\_EOF_ +the +quick +brown fox +_EOF_ + +cmp -s ${testname}.base2 ${testname}.out2 || \ + failure "`diff ${testname}.base2 ${testname}.out2`" + +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## End: + +# end of main.test diff --git a/autoopts/test/nested.test b/autoopts/test/nested.test new file mode 100755 index 0000000..a4d4755 --- /dev/null +++ b/autoopts/test/nested.test @@ -0,0 +1,265 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# ---------------------------------------------------------------------- +# nested.test --- test nested option values +# +# Author: Bruce Korb +## +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd +# +# ---------------------------------------------------------------------- + +. ./defs + +# # # # # # # # # # DEFINITIONS FILE # # # # # # # # # + +exec 5> ${testname}.def +cat >&5 <<- _EOF_ + + AutoGen definitions options; + + config-header = 'config.h'; + prog-name = "test_${testname}"; + prog-title = "Test AutoOpts for ${testname}"; + homerc = ${testname}.d/${testname}.cfg; + + flag = { + name = struct; + value = s; + max = NOLIMIT; + descrip = 'structured argument val'; + arg-type = nested; + }; + main = { + main-type = main; + _EOF_ + +test -d ${testname}.d || mkdir -p ${testname}.d + +echo ' main-text = <''<- _EOCode_' >&5 +cat >&5 <<- _EOF_ + { + int ix = 0; + const tOptionValue* pOV = + optionFindValue(&DESC(STRUCT), NULL, NULL); + do { + printf("\nstruct opt #%d:\n", ++ix); + res |= print_entry( pOV ); + pOV = optionFindNextValue(&DESC(STRUCT), pOV, NULL, NULL); + } while (pOV != NULL); + } + _EOF_ + +echo "_EOCode_; };" >&5 + +echo 'include = <''<- _EOSubr_' >&5 +cat >&5 <<- _EOF_ + #include + + int print_nested( const tOptionValue* pGV ); + int print_entry( const tOptionValue* pGV ); + int print_entry( const tOptionValue* pGV ) { + if (pGV == NULL) { + fprintf( stderr, "ENTRY NOT FOUND\n" ); + return 1; + } + printf( "%-8s -- ", pGV->pzName ); + switch (pGV->valType) { + case OPARG_TYPE_NONE: + fputs( "no value\n", stdout ); break; + + case OPARG_TYPE_STRING: + printf( "string: %s\n", pGV->v.strVal ); break; + + case OPARG_TYPE_ENUMERATION: + printf( "enum: %d\n", pGV->v.enumVal ); break; + + case OPARG_TYPE_BOOLEAN: + printf( "bool: %s\n", + pGV->v.boolVal ? "TRUE" : "false" ); break; + + case OPARG_TYPE_MEMBERSHIP: + printf("members: 0x%08lX\n", (unsigned long)pGV->v.setVal); break; + + case OPARG_TYPE_NUMERIC: + printf( "integer: %ld\n", pGV->v.longVal ); break; + + case OPARG_TYPE_HIERARCHY: + printf( "nested: 0x%08lX\n", (unsigned long)pGV->v.nestVal ); + return print_nested( pGV ); + break; + + default: + printf( "bad type: %d\n", pGV->valType ); + return 1; + } + return 0; + } + + int print_nested( const tOptionValue* pGV ) { + int res = 0; + const tOptionValue* pOV = optionGetValue( pGV, NULL ); + while (pOV != NULL) { + res |= print_entry( pOV ); + pOV = optionNextValue( pGV, pOV ); + } + return res; + } + _EOF_ +echo "_EOSubr_;" >&5 + +exec 5>&- + +# # # # # # # # # # CREATE PROGRAM # # # # # # # # # + +echo ${AG_L} ${testname}.def +${AG_L} ${testname}.def || \ + failure AutoGen could not process + +compile "-?" + +# # # # # # # # # # HELP OUTPUT FILE # # # # # # # # # + +basehelp=${testname}-base.help +echo creating ${basehelp} +clean_help > ${basehelp} <<_EOF_ +test_${testname} - Test AutoOpts for ${testname} +Usage: ${testname} [ - [] ]... + Flg Arg Option-Name Description + -s Cpx struct structured argument val + - may appear multiple times + -? no help display extended usage information and exit + -! no more-help extended usage information passed thru pager + -> opt save-opts save the option state to a config file + -< Str load-opts load options from a config file + - disabled as '--no-load-opts' + - may appear multiple times + + +The following option preset mechanisms are supported: + - reading file ${testname}.cfg +_EOF_ + +${SED} "/ - reading file/s/ file .*/ file ${testname}.cfg/" \ + ${testname}.help > X$$ +mv -f X$$ ${testname}.help + +cmp -s ${basehelp} ${testname}.help || \ + failure "`diff ${basehelp} ${testname}.help`" + +# # # # # # # # # # SINGLE ARG TEST # # # # # # # # # + +cat > ${testname}-res1.base <<- _EOF_ + + struct opt #1: + struct -- nested: 0xXXXXXXXX + able -- no value + bar -- integer: 1234 + foo -- no value + stumble -- no value + _EOF_ + +./${testname} -s 'stumble, foo, 1234 able' | \ +${SED} '/ nested:/s/ 0x.*/ 0xXXXXXXXX/' > ${testname}-res1.out || \ + failure "FAILED: \ +./${testname} -s 'stumble, foo, 1234 baz'" + +cmp -s ${testname}-res1.* || \ + failure "`diff ${testname}-res1.*`" + +# # # # # # # # # # DOUBLE ARG TEST # # # # # # # # # + +arg1="stumble, foo${ht}lish, 1234, able" +arg2='foo, 4321 one, two=2, three' +(./${testname} -s "${arg1}" -s "${arg2}" \ + | ${SED} '/ nested:/s/ 0x.*/ 0xXXXXXXXX/' ) > ${testname}-res2.out || \ + failure "FAILED: ./${testname} ${arg1} ${arg2}" + +cat > ${testname}-res2.base <<- _EOF_ + + struct opt #1: + struct -- nested: 0xXXXXXXXX + able -- no value + bar -- integer: 1234 + foo -- string: foo lish + stumble -- no value + + struct opt #2: + struct -- nested: 0xXXXXXXXX + bar -- integer: 4321 + foo -- no value + gr -- nested: 0xXXXXXXXX + one -- no value + three -- no value + two -- string: 2 + _EOF_ + +cmp -s ${testname}-res2.* || \ + failure "`diff ${testname}-res2.*`" + +./${testname} -s "${arg1}" -s "${arg2}" '->' +${SED} -e '3s/.*/# ***DATE***/' ${testname}.d/${testname}.cfg > ${testname}.XX +mv -f ${testname}.XX ${testname}.d/${testname}.cfg +cat > ${testname}-res3.base <<- _EOF_ + # test_nested - Test AutoOpts for nested + # preset/initialization file + # ***DATE*** + # + + + 0x4D2 + foo lish + + + + 0x10E1 + + + + + 2 + + + _EOF_ +files=${testname}-res3.base\ ${testname}.d/${testname}.cfg +cmp -s ${files} || \ + failure "saved config${nl}`diff ${files}`" + +# Copy the config file and verify that the contents are the same. +# +./${testname} "->${testname}.d/${testname}.cfg2" +${SED} -e '3s/.*/# ***DATE***/' ${testname}.d/${testname}.cfg2 > ${testname}.XX +mv -f ${testname}.XX ${testname}.d/${testname}.cfg2 +files=${testname}.d/${testname}.cfg\ ${testname}.d/${testname}.cfg2 +cmp -s ${files} || \ + failure "re-saved config${nl}`diff ${files}`" + +# # # # # # # # # # TEST OPERATION # # # # # # # # # # + +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## End: + +# end of nested.test diff --git a/autoopts/test/nls.test b/autoopts/test/nls.test new file mode 100755 index 0000000..681ad5e --- /dev/null +++ b/autoopts/test/nls.test @@ -0,0 +1,164 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# ---------------------------------------------------------------------- +# nls.test --- test NLS, sort-of +# +# Author: Bruce Korb +## +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd +# +# ---------------------------------------------------------------------- + +. ./defs +for f in HAVE_LIBINTL_H DEBUG_ENABLED +do + grep "#define.*$f" ${top_builddir}/config.h >/dev/null || { + echo "$f is not defined -- skiping $0" + exit 0 + } +done +AUTOGEN_TEMPL_DIRS=`cd ${srcdir}/..;pwd` +export AUTOGEN_TEMPL_DIRS + +# # # # # # # # # # DEFINITIONS FILE # # # # # # # # # + +echo "creating ${testname}.def in `pwd`" +testname="${testname}" test_main="YES" \ +argument="${argument}" long_opts="YES" \ +${SHELLX} ${stdopts} option:'opt init' second=020 || \ + failure "Could not run stdopts.def" + +echo 'export = "extern char* gettext( char const* );";' >> ${testname}.def +CC="${CC} ${CFLAGS} -DENABLE_NLS=1 ${INC}" +CFLAGS='' +INC='' + +compile_with_nls() { + + echo ${AG_L} ${testname}.def + ${AG_L} ${testname}.def || \ + failure AutoGen could not process + + chmod u+w ${testname}.[ch] + # a "gettext" that reverses the text lines and characters. + # Leading white space is stripped from each line so that + # output lines do not have trailing white space. + # + cat >> ${testname}.c <<'_EOF_' +#include +char* +gettext(char const* pzS) +{ + static char z[4096]; + char* pzD = z + sizeof(z) - 1; + int ct = 0; + int found_nl = 0; + if (pzS == NULL) + return NULL; + if (strchr(pzS, '%') != NULL) + return VOIDP(pzS); + *--pzD = '\0'; + while ((*pzS == ' ') || (*pzS == '\t')) pzS++; + for (;;) { + char ch = *(pzS++); + if (ch == '\0') + break; + *(--pzD) = ch; + ct++; + if (ch != '\n') + continue; + found_nl = 1; + while ((*pzS == ' ') || (*pzS == '\t')) pzS++; + } + if (found_nl) + strcpy(z + sizeof(z) - 2, "\n"); + while (*pzD == '\n') + pzD++; + return pzD; +} +_EOF_ + + sedcmd='/ot sgub .* tropeR$/d;/ yb degakcaP/d' + compile "--help" + mv ${testname}.help ${testname}-${1}.help + cmp -s ${testname}-${1}.help ${testname}-${1}.hlp || { set +x ; \ + failure "`diff -c ${testname}-${1}.hlp ${testname}-${1}.help`" ; } +} + +# # # # # # # # # # HELP OUTPUT FILE # # # # # # # # # + +echo creating ${testname}.hlp +clean_help > ${testname}-1.hlp <<'_EOF_' +test_nls - Test AutoOpts for nls +Usage: nls [ - [] | --[{=| }] ]... +noitpircseD emaN-noitpO grA glF + -o Str option pircsed noitpo noitpo ehT + -s Num second pircsed noitpo dnoces ehT + -? no help tixe dna noitamrofni egasu dednetxe yalpsid + -! no more-help regap urht dessap noitamrofni egasu dednetxe +.retcarahc galf eht dna nehpyh +elgnis a yb ro eman rieht dna snehpyh delbuod yb deificeps era snoitpO +_EOF_ + +compile_with_nls 1 + +mv ${testname}.def ${testname}-1.def + +exec 3> ${testname}.def +cat ${testname}-1.def >&3 +echo 'full-usage = <''<''- _EOF_' >&3 +clean_help >&3 <<'_EOF_' +test_nls - Test AutoOpts for nls +Usage: nls [ - [] | --[{=| }] ]... + Flg Arg Option-Name Description + -o Str option The option descrip + -s Num second The second descrip + -? no help display extended usage information and exit + -! no more-help extended usage information passed thru pager + +Options are specified by doubled hyphens and their name or by a single +hyphen and the flag character. +_EOF_ +echo '_EOF_;' >&3 +exec 3>&- + +clean_help > ${testname}-2.hlp <<'_EOF_' +...] ]>lav<} |={[>eman<-- | ]>lav<[ >galf<- [ sln :egasU +sln rof stpOotuA tseT - sln_tset +pircsed noitpo ehT noitpo rtS o- +noitpircseD emaN-noitpO grA glF +pircsed dnoces ehT dnoces muN s- +.retcarahc galf eht dna nehpyh +elgnis a yb ro eman rieht dna snehpyh delbuod yb deificeps era snoitpO +regap urht dessap noitamrofni egasu dednetxe pleh-erom on !- +tixe dna noitamrofni egasu dednetxe yalpsid pleh on ?- +_EOF_ + +compile_with_nls 2 +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## End: + +# end of nls.test diff --git a/autoopts/test/rc.test b/autoopts/test/rc.test new file mode 100755 index 0000000..3c5ec54 --- /dev/null +++ b/autoopts/test/rc.test @@ -0,0 +1,261 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- + +# rc.test --- test loading and saving of rc files +# +# Author: Bruce Korb +## +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + +. ./defs + +AUTOOPTS_TRACE=every +AUTOOPTS_TRACE_OUT=">>`pwd`/${testname}-ag-trace.txt" +export AUTOOPTS_TRACE AUTOOPTS_TRACE_OUT + +# # # # # # # # # # DEFINITIONS FILE # # # # # # # # # +startdir=`pwd` +: "creating ${testname}.def in $startdir" + +TESTNAME=RC +export TESTNAME + +test_main="yes" \ +argument="mumble" long_opts="yes" \ +${SHELLX} ${stdopts} option second:init third: || \ + failure "Could not run stdopts.def" + +cat >> ${testname}.def <<_EOF_ +homerc = "\$\$/${testname}.rc"; +rcfile = ${testname}.file; +environrc; +_EOF_ + +${AG_L} ${testname}.def || \ + failure AutoGen could not process A + +# # # # # # # # # # VALIDATE HELP # # # # # # # # # + +clean_help > ${testname}-base1.help <<_EOF_ +test_rc - Test AutoOpts for rc +Usage: rc [ - [] | --[{=| }] ]... mumble + Flg Arg Option-Name Description + -o no option The option option descrip + -s Str second The second option descrip + -t Str third The third option descrip + -? no help display extended usage information and exit + -! no more-help extended usage information passed thru pager + -> opt save-opts save the option state to a config file + -< Str load-opts load options from a config file + - disabled as '--no-load-opts' + - may appear multiple times + +Options are specified by doubled hyphens and their name or by a single +hyphen and the flag character. + +The following option preset mechanisms are supported: + - reading file ..../${testname}.rc/rc.file + - examining environment variables named TEST_RC_* +_EOF_ + +mkdir ${testname}.rc ${testname}.run +compile "--help" +${SED} 's@\( - reading file \).*\(/'${testname}.rc/rc.file'\)@\1....\2@' \ + ${testname}.help > ${testname}-res1.help +cmp ${testname}-*1.help || \ + failure "`diff ${testname}-*.help`" + +# # # # # # # # # # DO THE REAL TEST # # # # # # # # # + +# Install an initialization for the "second" option. +# That goes into the ${testname}.rc directory. +# We change into the ${testname}.run directory and run the program. +# It should pick up the value saved into the ${testname}.rc dir. +# +./${testname} --second=third '->'${testname}.rc/${testname}.file + +cd ${testname}.run +../${testname} -t xxx MUMBLE > ${testname}.cmds + +# This is what the output should be: +# +cat > ${testname}.test <<'_EOF_' +OPTION_CT=2 +export OPTION_CT +TEST_RC_SECOND='third' +export TEST_RC_SECOND +TEST_RC_THIRD='xxx' +export TEST_RC_THIRD +_EOF_ + + +cmp ${testname}.cmds ${testname}.test || { + df="`diff -c ${testname}.test ${testname}.cmds`" + cd .. + failure "${df}" +} + +# # # # # + +TEST_RC=--no-load ../${testname} -t xxx MUMBLE > ${testname}-2.cmds + +# This is what the output should be: +# +cat > ${testname}-2.test <<'_EOF_' +OPTION_CT=2 +export OPTION_CT +TEST_RC_THIRD='xxx' +export TEST_RC_THIRD +_EOF_ + +cmp ${testname}-2.cmds ${testname}-2.test || { + df="`diff -c ${testname}-2.test ${testname}-2.cmds`" + cd .. + failure "${df}" +} + +# # # # # # # # # # SECOND TEST OUTPUT FILE # # # # # # # # # + +cat >> ../${testname}.rc/${testname}.file <<_EOF_ +[TEST_MUMBLE] +second fourth + +[TEST_${TESTNAME}] +second = fifth + +# this is another comment +# +[TEST_STUMBLE] +second : sixth +_EOF_ + +../${testname} -t yyy MUMBLE > ${testname}.cmds + +# This is what the output should be: +# +cat > ${testname}.test <<'_EOF_' +OPTION_CT=2 +export OPTION_CT +TEST_RC_SECOND='fifth' +export TEST_RC_SECOND +TEST_RC_THIRD='yyy' +export TEST_RC_THIRD +_EOF_ + +cmp ${testname}.cmds ${testname}.test || { + df="`diff -c ${testname}.test ${testname}.cmds`" + cd .. + failure "${df}" +} + +mv ../${testname}.rc/${testname}.file ../${testname}.rc/${testname}.save +( ${SED} '/^[TEST_MUMBLE]/,$d' ../${testname}.rc/${testname}.save + cat <<- _EOF_ + + second fourth + + + + fifth + + # this is another comment + # + + second : sixth + _EOF_ +) > ../${testname}.rc/${testname}.file + +../${testname} -t yyy MUMBLE > ${testname}.cmds + +cmp ${testname}.cmds ${testname}.test || { + df="USING : `diff -c ${testname}.test ${testname}.cmds`" + cd .. + failure "${df}" +} + +# # # # # # # # # # SECOND TEST, pt 2 UPDATE FILE # # # # # + +cp ../${testname}.rc/${testname}.file ../${testname}.rc/${testname}.more-save +../${testname} -t yyy '->>>' + +pair="../${testname}.rc/${testname}.file ../${testname}.rc/${testname}.more-save" +cmp $pair && { + df="USING : `diff -c $pair`" + cd .. + failure "UNCHANGED: $pair`echo;cat ../${testname}.rc/${testname}.file`" +} +{ + ${SED} "/^/,/^#\$/d" \ + ../${testname}.rc/${testname}.more-save + cat <<- _EOF + + second = fifth + third = yyy + _EOF +} > ../${testname}.rc/${testname}.expect +pair="../${testname}.rc/${testname}.file ../${testname}.rc/${testname}.expect" +cmp $pair || failure "BAD UPDATE: $pair`echo;cat ../${testname}.rc/${testname}.file`" + +# # # # # # # # # # THIRD TEST OUTPUT FILE # # # # # # # # # + +cd ${startdir} + +echo 'disable-save;' >> ${testname}.def + +${AG_L} ${testname}.def || \ + failure AutoGen could not process B + +compile "--help" +${SED} 's@\( - reading file \).*\(/'${testname}.rc/rc.file'\)@\1....\2@' \ + ${testname}.help > ${testname}-res2.help +egrep -v ' save-opts +save ' ${testname}-base1.help > ${testname}-base2.help + +cmp ${testname}-*2.help || \ + failure "`diff ${testname}-*2.help`" + +echo 'disable-load;' >> ${testname}.def + +${AG_L} ${testname}.def || \ + failure AutoGen could not process B + +compile "--help" +${SED} 's@\( - reading file \).*\(/'${testname}.rc/rc.file'\)@\1....\2@' \ + ${testname}.help > ${testname}-res3.help + +${SED} -e '/ load-opts *load /,/multiple times$/d' \ + ${testname}-base2.help > ${testname}-base3.help + +cmp ${testname}-*3.help || \ + failure "`diff ${testname}-*3.help`" + +# # # # # # # # # # HELP OUTPUT FILE # # # # # # # # # + +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## End: + +# end of rc.test diff --git a/autoopts/test/shell.test b/autoopts/test/shell.test new file mode 100755 index 0000000..527c7f7 --- /dev/null +++ b/autoopts/test/shell.test @@ -0,0 +1,502 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# ---------------------------------------------------------------------- +# shell.test --- test shell program attribute +# make sure that when it is not specified +# then option processing consumes all args. +# +# Author: Bruce Korb +## +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd +# +# ---------------------------------------------------------------------- + +. ./defs + +# # # # # # # # # # DEFINITIONS FILE # # # # # # # # # + +echo "creating ${testname}.def in `pwd`" + + testname="${testname}" \ +test_main="${test_main}" \ + argument="reg-arg [ ... ]" \ +long_opts=true \ +${SHELLX} ${stdopts} option: second || failure "Could not run stdopts.def" +mv ${testname}.def ${testname}.def-ori +{ + ${SED} '/^test-main/d;/value = .s/i\ + min = 1; max = 2; + ' ${testname}.def-ori + cat <<- _EOF_ + detail = "exit 99 ; oops."; + no-xlate = anything; + main = { main-type = shell-process; }; + _EOF_ +} > ${testname}.def + +${AG_L} ${testname}.def || \ + failure AutoGen could not process + +compile "-?" 2> ${testname}.hlp + +# # # # # # # # # # HELP OUTPUT FILE # # # # # # # # # + +echo creating ${testname}.hlp +cat > ${testname}.hlp <<'_EOF_' +test_shell - Test AutoOpts for shell +Usage: shell { - [] | --[{=| }] }... \ + reg-arg [ ... ] + Flg Arg Option-Name Req? Description + -o Str option opt The option option descrip + -s no second YES The second option descrip + - may appear up to 2 times + -? no help opt display extended usage information and exit + -! no more-help opt extended usage information passed thru pager +Options are specified by doubled hyphens and their name or by a single +hyphen and the flag character. +_EOF_ + +pair="${testname}.hlp ${testname}.help" +cmp -s ${pair} || \ + failure "HELP mismatch +`diff $pair`" + +./${testname} -X 2> /dev/null && \ + failure ${testname} should not accept bogus options + +./${testname} -o 2> /dev/null && \ + failure ${testname} should not accept missing options argument + +./${testname} 2> /dev/null && \ + failure ${testname} must have an argument + +( + PS4='>st> ' + set -- --help + eval "`exec 2>/dev/null ; ./${testname} \"$@\"`" + exit 1 +) || failure "improper --help exit" + +# # # # # # # # # # SHELL OUTPUT FILE # # # # # # # # # + +echo creating ${testname}.out +cat > ${testname}.out <<_EOF_ +OPTION_CT=3 +export OPTION_CT +TEST_SHELL_OPTION='opt-arg' +export TEST_SHELL_OPTION +TEST_SHELL_SECOND=1 # 0x1 +export TEST_SHELL_SECOND +_EOF_ + +./${testname} -o opt-arg -s a1 a2 > ${testname}.test || \ + failure ${testname} did not handle its options + +pair="${testname}.out ${testname}.test" +cmp -s $pair || \ + failure "SHELL PARSE OUTPUT CHANGED +`diff ${pair}`" + +${SED} '/main-type/s/process/parser/' ${testname}.def > XX +mv -f XX ${testname}.def + +echo ${AG_L} ${testname}.def +${AG_L} ${testname}.def || \ + failure 'AutoGen could not process' + +sedcmd='/Note that.*is only useful/,/will be regenerated/d' +compile "-?" + +# # # # # # # # # # HELP OUTPUT FILE # # # # # # # # # + +echo creating second ${testname}.hlp +clean_help > ${testname}.hlp <<'_EOF_' +genshellopt - Generate Shell Option Processing Script - Ver. 1 +Usage: shell [ - [] | --[{=| }] ]... + Flg Arg Option-Name Description + -o Str script Output Script File + -s Str shell Shell name (follows "#!" magic) + - disabled as '--no-shell' + - enabled by default + -v opt version output version information and exit + -? no help display extended usage information and exit + -! no more-help extended usage information passed thru pager + +Options are specified by doubled hyphens and their name or by a single +hyphen and the flag character. + +Note that ``shell'' is only useful if the output file does not already +exist. If it does, then the shell name and optional first argument will +be extracted from the script file. + +If the script file already exists and contains Automated Option Processing +text, the second line of the file through the ending tag will be replaced +by the newly generated text. The first ``#!'' line will be regenerated. + += = = = = = = = + +This incarnation of genshell will produce +a shell script to parse the options for test_shell: + +test_shell - Test AutoOpts for shell +Usage: test_shell { - [] | --[{=| }] }... \ + reg-arg [ ... ] + Flg Arg Option-Name Req? Description + -o Str option opt The option option descrip + -s no second YES The second option descrip + -? no help opt display extended usage information and exit + -! no more-help opt extended usage information passed thru pager + +Options are specified by doubled hyphens and their name or by a single +hyphen and the flag character. +_EOF_ + +pair=${testname}.hlp\ ${testname}.help +cmp -s ${pair} || \ + failure "script generator help output mismatch: +`diff -c ${pair}`" + +# # # # # # # # # # SCRIPT OUTPUT FILE # # # # # # # # # + +echo creating ${testname}.sht +exec 3> ${testname}.sht +echo "#! ${SHELL}" >&3 +cat >&3 <<'_EOF_' +# +TEST_SHELL_LONGUSAGE_TEXT='test_shell - Test AutoOpts for shell +Usage: test_shell { - [] | --[{=| }] }... \ + reg-arg [ ... ] + Flg Arg Option-Name Req? Description + -o Str option opt The option option descrip + -s no second YES The second option descrip + - may appear up to 2 times + -? no help opt display extended usage information and exit + -! no more-help opt extended usage information passed thru pager + +Options are specified by doubled hyphens and their name or by a single +hyphen and the flag character.' + +TEST_SHELL_USAGE_TEXT='test_shell - Test AutoOpts for shell +Usage: test_shell { - [] | --[{=| }] }... \ + reg-arg [ ... ] + Flg Arg Option-Name Req? Description + -o Str option opt The option option descrip + -s no second YES The second option descrip + -? no help opt display extended usage information and exit + -! no more-help opt extended usage information passed thru pager + +Options are specified by doubled hyphens and their name or by a single +hyphen and the flag character.' + + +TEST_SHELL_OPTION=${TEST_SHELL_OPTION} +TEST_SHELL_OPTION_set=false +export TEST_SHELL_OPTION + +if test -z "${TEST_SHELL_SECOND}" +then + TEST_SHELL_SECOND_CT=0 + export TEST_SHELL_SECOND_CT +else + TEST_SHELL_SECOND_CT=1 + TEST_SHELL_SECOND_1=${TEST_SHELL_SECOND} + export TEST_SHELL_SECOND_CT TEST_SHELL_SECOND_1 +fi + +ARG_COUNT=$# +OPT_PROCESS=true +OPT_ARG=$1 +while ${OPT_PROCESS} && [ $# -gt 0 ] +do + OPT_ELEMENT='' + OPT_ARG_VAL='' + + case "${OPT_ARG}" in + -- ) + OPT_PROCESS=false + shift + ;; + --* ) + OPT_CODE=`echo "X${OPT_ARG}"|sed 's/^X-*//'` + shift + OPT_ARG=$1 + case "${OPT_CODE}" in *=* ) + OPT_ARG_VAL=`echo "${OPT_CODE}"|sed 's/^[^=]*=//'` + OPT_CODE=`echo "${OPT_CODE}"|sed 's/=.*$//'` ;; esac + case "${OPT_CODE}" in + 'op' | \ + 'opt' | \ + 'opti' | \ + 'optio' | \ + 'option' ) + if [ -n "${TEST_SHELL_OPTION}" ] && ${TEST_SHELL_OPTION_set} ; then + echo 'Error: duplicate OPTION option' + echo "$TEST_SHELL_USAGE_TEXT" + exit 1 + fi >&2 + TEST_SHELL_OPTION_set=true + OPT_NAME='OPTION' + OPT_ARG_NEEDED=YES + ;; + + 'se' | \ + 'sec' | \ + 'seco' | \ + 'secon' | \ + 'second' ) + if [ $TEST_SHELL_SECOND_CT -gt 2 ] ; then + echo 'Error: more than 2 SECOND options' + echo "$TEST_SHELL_USAGE_TEXT" + exit 1 + fi >&2 + TEST_SHELL_SECOND_CT=`expr ${TEST_SHELL_SECOND_CT} + 1` + OPT_ELEMENT="_${TEST_SHELL_SECOND_CT}" + OPT_NAME='SECOND' + eval TEST_SHELL_SECOND${OPT_ELEMENT}=true + export TEST_SHELL_SECOND${OPT_ELEMENT} + OPT_ARG_NEEDED=NO + ;; + + 'he' | \ + 'hel' | \ + 'help' ) + echo "$TEST_SHELL_LONGUSAGE_TEXT" + exit 0 + ;; + + 'mo' | \ + 'mor' | \ + 'more' | \ + 'more-' | \ + 'more-h' | \ + 'more-he' | \ + 'more-hel' | \ + 'more-help' ) + echo "$TEST_SHELL_LONGUSAGE_TEXT" | ${PAGER-more} + exit 0 + ;; + + * ) + echo Unknown option: "${OPT_CODE}" >&2 + echo "$TEST_SHELL_USAGE_TEXT" >&2 + exit 1 + ;; + esac + case "${OPT_ARG_NEEDED}" in + NO ) + OPT_ARG_VAL='' + ;; + YES ) + if [ -z "${OPT_ARG_VAL}" ] + then + if [ $# -eq 0 ] + then + echo No argument provided for ${OPT_NAME} option + echo "$TEST_SHELL_USAGE_TEXT" + exit 1 + fi >&2 + OPT_ARG_VAL=${OPT_ARG} + shift + OPT_ARG=$1 + fi + ;; + OK ) + if [ -z "${OPT_ARG_VAL}" ] && [ $# -gt 0 ] + then + case "${OPT_ARG}" in -* ) ;; * ) + OPT_ARG_VAL=${OPT_ARG} + shift + OPT_ARG=$1 ;; esac + fi + ;; + esac + ;; + + -* ) + OPT_CODE=`echo "X${OPT_ARG}" | sed 's/X-\(.\).*/\1/'` + OPT_ARG=` echo "X${OPT_ARG}" | sed 's/X-.//'` + case "${OPT_CODE}" in + 'o' ) + if [ -n "${TEST_SHELL_OPTION}" ] && ${TEST_SHELL_OPTION_set} ; then + echo 'Error: duplicate OPTION option' + echo "$TEST_SHELL_USAGE_TEXT" + exit 1 + fi >&2 + TEST_SHELL_OPTION_set=true + OPT_NAME='OPTION' + OPT_ARG_NEEDED=YES + ;; + + 's' ) + if [ $TEST_SHELL_SECOND_CT -gt 2 ] ; then + echo 'Error: more than 2 SECOND options' + echo "$TEST_SHELL_USAGE_TEXT" + exit 1 + fi >&2 + TEST_SHELL_SECOND_CT=`expr ${TEST_SHELL_SECOND_CT} + 1` + OPT_ELEMENT="_${TEST_SHELL_SECOND_CT}" + OPT_NAME='SECOND' + eval TEST_SHELL_SECOND${OPT_ELEMENT}=true + export TEST_SHELL_SECOND${OPT_ELEMENT} + OPT_ARG_NEEDED=NO + ;; + + '?' ) + echo "$TEST_SHELL_LONGUSAGE_TEXT" + exit 0 + ;; + + '!' ) + echo "$TEST_SHELL_LONGUSAGE_TEXT" | ${PAGER-more} + exit 0 + ;; + + * ) + echo Unknown flag: "${OPT_CODE}" >&2 + echo "$TEST_SHELL_USAGE_TEXT" >&2 + exit 1 + ;; + esac + case "${OPT_ARG_NEEDED}" in + NO ) + if [ -n "${OPT_ARG}" ] + then + OPT_ARG=-${OPT_ARG} + else + shift + OPT_ARG=$1 + fi + ;; + YES ) + if [ -n "${OPT_ARG}" ] + then + OPT_ARG_VAL=${OPT_ARG} + else + if [ $# -eq 0 ] + then + echo No argument provided for ${OPT_NAME} option + echo "$TEST_SHELL_USAGE_TEXT" + exit 1 + fi >&2 + shift + OPT_ARG_VAL=$1 + fi + shift + OPT_ARG=$1 + ;; + OK ) + if [ -n "${OPT_ARG}" ] + then + OPT_ARG_VAL=${OPT_ARG} + shift + OPT_ARG=$1 + else + shift + if [ $# -gt 0 ] + then + case "$1" in -* ) ;; * ) + OPT_ARG_VAL=$1 + shift ;; esac + OPT_ARG=$1 + fi + fi + ;; + esac + ;; + + * ) + OPT_PROCESS=false + ;; + esac + if [ -n "${OPT_ARG_VAL}" ] + then + eval TEST_SHELL_${OPT_NAME}${OPT_ELEMENT}="'${OPT_ARG_VAL}'" + export TEST_SHELL_${OPT_NAME}${OPT_ELEMENT} + fi +done +OPTION_COUNT=`expr $ARG_COUNT - $#` +OPERAND_COUNT=$# +unset OPT_PROCESS || : +unset OPT_ELEMENT || : +unset OPT_ARG || : +unset OPT_ARG_NEEDED || : +unset OPT_NAME || : +unset OPT_CODE || : +unset OPT_ARG_VAL || : +test ${TEST_SHELL_SECOND_CT-0} -ge 1 || { + echo TEST_SHELL_SECOND has not been set + exit 1 +} 1>&2 + +# # # # # # # # # # +# +# END OF AUTOMATED OPTION PROCESSING +# +# # # # # # # # # # -- do not modify this marker -- + +env | grep '^TEST_SHELL_' +_EOF_ +exec 3>&- + +# # # # # # # # # # SCRIPT OUTPUT TESTING # # # # # # # # # + +rm -f ${testname}.sh +./${testname} -o ${testname}.sh + +sedcmd='2,/From the.*option def/d;/^exit 99/d' +${FGREP} 'Packaged by ' ${testname}.sh >/dev/null && { + sedcmd=${sedcmd}${nl}'/^Packaged by /d + /^Report .* bugs to /d' +} +sedcmd=${sedcmd}${nl}'/and the flag character\.$/s/$/'"'/" + +${SED} "$sedcmd" ${testname}.sh > ${testname}.shx + +pair="${testname}.sht ${testname}.shx" +cmp -s ${pair} || \ + failure "PARSING SCRIPT CHANGE +`diff ${pair}`" + +# # # # # # # # # # SCRIPT PROCESSING TEST # # # # # # # # # + +./${testname}.sh --opt opt-arg -s a1 a2 | sort > ${testname}.test || \ + failure ${testname} did not handle its options + +sort > ${testname}.out <<_EOF_ +TEST_SHELL_OPTION=opt-arg +TEST_SHELL_SECOND_1=true +TEST_SHELL_SECOND_CT=1 +_EOF_ + +pair="${testname}.out ${testname}.test" +cmp -s $pair || \ + failure "Misprocessed options +`diff $pair`" + +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## End: + +# end of shell.test diff --git a/autoopts/test/stdopts.def b/autoopts/test/stdopts.def new file mode 100644 index 0000000..59f3d8d --- /dev/null +++ b/autoopts/test/stdopts.def @@ -0,0 +1,107 @@ +#! /bin/sh + +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + +# This is the standard set of options for testing option processing +# It is expected to be dot + +exec 5> $testname.def +cat >&5 <<- _EOF_ + + AutoGen definitions options; + + config-header = 'config.h'; + prog-name = "test_${testname}"; + prog-title = "Test AutoOpts for ${testname}"; + _EOF_ + +echo test_main $test_main +echo argument $argument +echo long_opts $long_opts + +{ + test -n "${test_main}" && echo "test-main = '${test_main}';" + test -n "${argument}" && echo "argument = '${argument}';" + test -n "${long_opts}" && echo "long-opts;" +} >&5 + +for flag +do + fname=`echo "${flag}" | ${SED} 's/[^a-zA-Z0-9_-].*//'` + flag=`echo "${flag}" | ${SED} "s/^${fname}//"` + + case "${flag}" in + :* ) + aval=`echo $flag | ${SED} 's/^://'` + arg=" arg-type = string;" + test -n "${aval}" && arg="${arg} arg_default = '${aval}';" + ;; + + =* ) + aval=`echo $flag | ${SED} 's/=//'` + arg=" arg-type = number;" + test -n "${aval}" && arg="${arg} arg_default = '${aval}';" + ;; + + @* ) + arg=`echo $flag | ${SED} 's/@//'` + case "${arg}" in + *=* ) default=`echo $flag | ${SED} 's/.*=//'` + arg=`echo $arg | ${SED} 's/=.*//'` + arg=" arg-type = '${arg}'; arg-default='${default}';" + ;; + + * ) + arg=" arg-type = '${arg}';" + ;; + esac + ;; + + * ) + unset arg + ;; + esac + + cat <<-_EOF_ + flag = { + name = "${fname}"; + descrip = "The ${fname} option descrip"; + _EOF_ + + ${use_flags} && { + fname=`echo ${fname} | ${SED} 's/\(.\).*/\1/'` + echo " value = '${fname}';" + } + test -n "${arg}" && echo "${arg}" + echo "};" + echo +done >&5 + +exec 5>&- +ls -l ${testname}.def + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## End: + +# end of stdopts.def diff --git a/autoopts/test/stdopts.test b/autoopts/test/stdopts.test new file mode 100755 index 0000000..c4b667e --- /dev/null +++ b/autoopts/test/stdopts.test @@ -0,0 +1,169 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# ---------------------------------------------------------------------- +# stdopts.test --- test standard options +# +# Author: Bruce Korb +## +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd +# +# ---------------------------------------------------------------------- + +. ./defs + +# # # # # # # # # # DEFINITIONS FILE # # # # # # # # # + +echo "creating ${testname}.def in `pwd`" +cat > ${testname}.def <<- _EOF_ + + AutoGen Definitions options; + + prog-name = test_${testname}; + prog-title = "${testname} test"; + config-header = 'config.h'; + no-xlate = anything; + main = { + main-type = main; + main-text = <<- _EndMain_ + \ (void)optionProcess(&test_${testname}Options, argc, argv); + \ optionPutShell(&test_${testname}Options); + \ return ferror(stdout) ? 1 : 0; + _EndMain_; + }; + long-opts; + + #define VERBOSE_ENUM + #define VERBOSE_FLAG + + #include stdoptions + _EOF_ + +${AG_L} ${testname}.def || \ + failure AutoGen could not process + +compile "-?" + +# # # # # # # # # # HELP OUTPUT FILE # # # # # # # # # + +echo creating ${testname}.hlp +clean_help > ${testname}.hbase <<- _EOF_ + test_stdopts - stdopts test + Usage: stdopts [ - [] | --[{=| }] ]... + + The following options are commonly used and are provided and supported + by AutoOpts: + + Flg Arg Option-Name Description + -V KWd verbose run program with progress info + + Version, usage and configuration options: + + Flg Arg Option-Name Description + -? no help display extended usage information and exit + -! no more-help extended usage information passed thru pager + + Options are specified by doubled hyphens and their name or by a single + hyphen and the flag character. + + The valid "verbose" option keywords are: + silent quiet brief informative verbose + or an integer from 0 through 4 + _EOF_ + +# When building with DEBUG set, we get an unanticipated option: +# +${GREP} -v 'run program with debugging info' ${testname}.help > ${testname}.hres + +cmp -s ${testname}.h[br]* || \ + failure "MISCOMPARE: `diff ${testname}.h[br]*`" + +./${testname} --verbose=exp > /dev/null 2>&1 && \ + failure ${testname} accepted ambiguous keyword + +./${testname} --verbose=inf > ${testname}.out || \ + failure ${testname} did not handle its options + +cat > ${testname}.oex <<_EOF_ +OPTION_CT=1 +export OPTION_CT +TEST_STDOPTS_VERBOSE='informative' +export TEST_STDOPTS_VERBOSE +_EOF_ + +cmp -s ${testname}.o* || \ + failure "`diff ${testname}.o??`" + +# # # # # # # # # # USAGE OPTION # # # # # # # # # # # + +( ${SED} "s/${testname}/${testname}-2/g + s/-2Options/_2Options/g" ${testname}.def + echo 'usage-opt;' +) > ${testname}-2.def + +testname=${testname}-2 + +${AG_L} ${testname}.def || { + testname=${testname%-2} + failure AutoGen could not process +} + +compile "--usage" + +clean_help > ${testname}.hbase <<- _EOF_ + test_stdopts-2 - stdopts-2 test + Usage: stdopts-2 [ - [] | --[{=| }] ]... + Flg Arg Option-Name Description + -V KWd verbose run program with progress info + -? no help display extended usage information and exit + -! no more-help extended usage information passed thru pager + -u no usage abbreviated usage to stdout + + Options are specified by doubled hyphens and their name or by a single + hyphen and the flag character. + _EOF_ + +# When building with DEBUG set, we get an unanticipated option: +# +${GREP} -v 'run program with debugging info' ${testname}.help > ${testname}.hres + +cmp -s ${testname}.h[br]* || { + testname=${testname%-2} + failure "MISCOMPARE: `diff ${testname}-2.h[br]*`" +} + +use=` + set +x + exec 2>&1 + exec 1>/dev/null + ./${testname} --usage` +test $? -eq 0 || failure usage failure +test "X${use}" = X || failure misdirected usage + +testname=${testname%-2} +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## End: + +# end of stdopts.test diff --git a/autoopts/test/time.test b/autoopts/test/time.test new file mode 100755 index 0000000..4e85713 --- /dev/null +++ b/autoopts/test/time.test @@ -0,0 +1,100 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# ---------------------------------------------------------------------- +# time.test --- test time duration argument +# +# Author: Bruce Korb +## +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd +# +# ---------------------------------------------------------------------- + +. ./defs + +# # # # # # # # # # DEFINITIONS FILE # # # # # # # # # + +echo "creating ${testname}.def in `pwd`" +unset test_main +export testname argument long_opts + +${SHELLX} ${stdopts} ${testname}@time='1d 2 h 15:10' +here='<<' +cat >> ${testname}.def <<- _EOF_ + main = { + main-type = main; + main-text = ${here}- CodeEnd + printf("arg %s represents %d seconds", argv[-1], + OPT_VALUE_TIME); + return 0; + CodeEnd; + }; + _EOF_ + +echo ${AG_L} ${testname}.def +${AG_L} ${testname}.def || \ + failure AutoGen could not process + +compile "-?" + +# # # # # # # # # # HELP OUTPUT FILE # # # # # # # # # + +basehlp=${testname}.hlp +echo creating ${basehlp} +clean_help > ${basehlp} <<'_EOF_' +test_time - Test AutoOpts for time +Usage: time [ - [] ]... + Flg Arg Option-Name Description + -t Tim time The time option descrip + -? no help display extended usage information and exit + -! no more-help extended usage information passed thru pager + +_EOF_ + +cmp -s ${testname}.h*lp || \ + failure "`diff ${basehlp} ${testname}.help`" + +time_val=213791 + +ck() { + tim=`./${testname} -t "$*" | \ + ${SED} -n 's/.* represents \([0-9]*\) seconds/\1/p'` + test -z "${tim}" && failure ${testname} could not parse "$*" + test ${tim} -eq ${time_val} || \ + failure ${testname} misevaluated "$*" +} + +ck 2 d 11h 23:11 +ck 2 d 11h 23m 11s + +tim=`./${testname} -t '2 d 10h 83:11'` && \ + failure ${testname} handled bad options + +# # # # # # # # # # T E S T E N D # # # # # # # # # # + +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## End: + +# end of argument.test diff --git a/autoopts/test/usage.test b/autoopts/test/usage.test new file mode 100755 index 0000000..5b88a89 --- /dev/null +++ b/autoopts/test/usage.test @@ -0,0 +1,655 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# ---------------------------------------------------------------------- +# usage.test --- test all the ways usage text can be printed. +# +# Author: Bruce Korb +## +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd +# +# ---------------------------------------------------------------------- + +${VERBOSE} && kill_delay=15 || kill_delay=8 +. ./defs + +# # # # # # # # # # HELP OUTPUT FILE # # # # # # # # # + +# ============= usage_LGFRA.hlp ============== +${SED} 's/^X//;/^[ ]*$/d' << 'SHAR_EOF' > 'usage_LGFRA.hlp' +test_usage_LGFRA - Checkout usage_LGFRA Options +Usage: usage_LGFRA { - [] | --[{=| }] }... \ + cmd-arg ... +X +X -L, --check-dirs=str Checkout directory list +X --show-defs[=arg] Show the definition tree +X -?, --help display extended usage information and exit +X -!, --more-help extended usage information passed thru pager +SHAR_EOF + +# ============= usage_LGFRp.hlp ============== +${SED} 's/^X//;/^[ ]*$/d' << 'SHAR_EOF' > 'usage_LGFRp.hlp' +test_usage_LGFRp - Checkout usage_LGFRp Options +Usage: usage_LGFRp { - | -- }... cmd-arg ... +X +X -L, --check-dirs Checkout directory list +X --show-defs Show the definition tree +X -?, --help display extended usage information and exit +X -!, --more-help extended usage information passed thru pager +SHAR_EOF + +# ============= usage_LGFoA.hlp ============== +${SED} 's/^X//;/^[ ]*$/d' << 'SHAR_EOF' > 'usage_LGFoA.hlp' +test_usage_LGFoA - Checkout usage_LGFoA Options +Usage: usage_LGFoA [ - [] | --[{=| }] ]... \ + cmd-arg ... +X +X -L, --check-dirs=str Checkout directory list +X --show-defs[=arg] Show the definition tree +X -?, --help display extended usage information and exit +X -!, --more-help extended usage information passed thru pager +SHAR_EOF + +# ============= usage_LGFop.hlp ============== +${SED} 's/^X//;/^[ ]*$/d' << 'SHAR_EOF' > 'usage_LGFop.hlp' +test_usage_LGFop - Checkout usage_LGFop Options +Usage: usage_LGFop [ - | -- ]... cmd-arg ... +X +X -L, --check-dirs Checkout directory list +X --show-defs Show the definition tree +X -?, --help display extended usage information and exit +X -!, --more-help extended usage information passed thru pager +SHAR_EOF + +# ============= usage_LGsRA.hlp ============== +${SED} 's/^X//;/^[ ]*$/d' << 'SHAR_EOF' > 'usage_LGsRA.hlp' +test_usage_LGsRA - Checkout usage_LGsRA Options +Usage: usage_LGsRA { --[{=| }] }... cmd-arg ... +X +X --check-dirs=str Checkout directory list +X --show-defs[=arg] Show the definition tree +X --help display extended usage information and exit +X --more-help extended usage information passed thru pager +SHAR_EOF + +# ============= usage_LGsRp.hlp ============== +${SED} 's/^X//;/^[ ]*$/d' << 'SHAR_EOF' > 'usage_LGsRp.hlp' +test_usage_LGsRp - Checkout usage_LGsRp Options +Usage: usage_LGsRp { -- }... cmd-arg ... +X +X --check-dirs Checkout directory list +X --show-defs Show the definition tree +X --help display extended usage information and exit +X --more-help extended usage information passed thru pager +SHAR_EOF + +# ============= usage_LGsoA.hlp ============== +${SED} 's/^X//;/^[ ]*$/d' << 'SHAR_EOF' > 'usage_LGsoA.hlp' +test_usage_LGsoA - Checkout usage_LGsoA Options +Usage: usage_LGsoA [ --[{=| }] ]... cmd-arg ... +X +X --check-dirs=str Checkout directory list +X --show-defs[=arg] Show the definition tree +X --help display extended usage information and exit +X --more-help extended usage information passed thru pager +SHAR_EOF + +# ============= usage_LGsop.hlp ============== +${SED} 's/^X//;/^[ ]*$/d' << 'SHAR_EOF' > 'usage_LGsop.hlp' +test_usage_LGsop - Checkout usage_LGsop Options +Usage: usage_LGsop [ -- ]... cmd-arg ... +X +X --check-dirs Checkout directory list +X --show-defs Show the definition tree +X --help display extended usage information and exit +X --more-help extended usage information passed thru pager +SHAR_EOF + +# ============= usage_LaFRA.hlp ============== +${SED} 's/^X//;/^[ ]*$/d' << 'SHAR_EOF' > 'usage_LaFRA.hlp' +test_usage_LaFRA - Checkout usage_LaFRA Options +Usage: usage_LaFRA { - [] | --[{=| }] }... \ + cmd-arg ... +X Flg Arg Option-Name Req? Description +X -L Str check-dirs YES Checkout directory list +X opt show-defs opt Show the definition tree +X -? no help opt display extended usage information and exit +X -! no more-help opt extended usage information passed thru pager +SHAR_EOF + +# ============= usage_LaFRp.hlp ============== +${SED} 's/^X//;/^[ ]*$/d' << 'SHAR_EOF' > 'usage_LaFRp.hlp' +test_usage_LaFRp - Checkout usage_LaFRp Options +Usage: usage_LaFRp { - | -- }... cmd-arg ... +X Flg Arg Option-Name Req? Description +X -L no check-dirs YES Checkout directory list +X no show-defs opt Show the definition tree +X -? no help opt display extended usage information and exit +X -! no more-help opt extended usage information passed thru pager +SHAR_EOF + +# ============= usage_LaFoA.hlp ============== +${SED} 's/^X//;/^[ ]*$/d' << 'SHAR_EOF' > 'usage_LaFoA.hlp' +test_usage_LaFoA - Checkout usage_LaFoA Options +Usage: usage_LaFoA [ - [] | --[{=| }] ]... \ + cmd-arg ... +X Flg Arg Option-Name Description +X -L Str check-dirs Checkout directory list +X opt show-defs Show the definition tree +X -? no help display extended usage information and exit +X -! no more-help extended usage information passed thru pager +SHAR_EOF + +# ============= usage_LaFop.hlp ============== +${SED} 's/^X//;/^[ ]*$/d' << 'SHAR_EOF' > 'usage_LaFop.hlp' +test_usage_LaFop - Checkout usage_LaFop Options +Usage: usage_LaFop [ - | -- ]... cmd-arg ... +X Flg Arg Option-Name Description +X -L no check-dirs Checkout directory list +X no show-defs Show the definition tree +X -? no help display extended usage information and exit +X -! no more-help extended usage information passed thru pager +SHAR_EOF + +# ============= usage_LasRA.hlp ============== +${SED} 's/^X//;/^[ ]*$/d' << 'SHAR_EOF' > 'usage_LasRA.hlp' +test_usage_LasRA - Checkout usage_LasRA Options +Usage: usage_LasRA { --[{=| }] }... cmd-arg ... +X Arg Option-Name Req? Description +X Str check-dirs YES Checkout directory list +X opt show-defs opt Show the definition tree +X no help opt display extended usage information and exit +X no more-help opt extended usage information passed thru pager +SHAR_EOF + +# ============= usage_LasRp.hlp ============== +${SED} 's/^X//;/^[ ]*$/d' << 'SHAR_EOF' > 'usage_LasRp.hlp' +test_usage_LasRp - Checkout usage_LasRp Options +Usage: usage_LasRp { -- }... cmd-arg ... +X Arg Option-Name Req? Description +X no check-dirs YES Checkout directory list +X no show-defs opt Show the definition tree +X no help opt display extended usage information and exit +X no more-help opt extended usage information passed thru pager +SHAR_EOF + +# ============= usage_LasoA.hlp ============== +${SED} 's/^X//;/^[ ]*$/d' << 'SHAR_EOF' > 'usage_LasoA.hlp' +test_usage_LasoA - Checkout usage_LasoA Options +Usage: usage_LasoA [ --[{=| }] ]... cmd-arg ... +X Arg Option-Name Description +X Str check-dirs Checkout directory list +X opt show-defs Show the definition tree +X no help display extended usage information and exit +X no more-help extended usage information passed thru pager +SHAR_EOF + +# ============= usage_Lasop.hlp ============== +${SED} 's/^X//;/^[ ]*$/d' << 'SHAR_EOF' > 'usage_Lasop.hlp' +test_usage_Lasop - Checkout usage_Lasop Options +Usage: usage_Lasop [ -- ]... cmd-arg ... +X Arg Option-Name Description +X no check-dirs Checkout directory list +X no show-defs Show the definition tree +X no help display extended usage information and exit +X no more-help extended usage information passed thru pager +SHAR_EOF + +# ============= usage_sGFRA.hlp ============== +${SED} 's/^X//;/^[ ]*$/d' << 'SHAR_EOF' > 'usage_sGFRA.hlp' +test_usage_sGFRA - Checkout usage_sGFRA Options +Usage: usage_sGFRA { - [] }... cmd-arg ... +X +X -L str Checkout directory list +X -s [arg] Show the definition tree +X -? display extended usage information and exit +X -! extended usage information passed thru pager +SHAR_EOF + +# ============= usage_sGFRp.hlp ============== +${SED} 's/^X//;/^[ ]*$/d' << 'SHAR_EOF' > 'usage_sGFRp.hlp' +test_usage_sGFRp - Checkout usage_sGFRp Options +Usage: usage_sGFRp { - }... cmd-arg ... +X +X -L Checkout directory list +X -s Show the definition tree +X -? display extended usage information and exit +X -! extended usage information passed thru pager +SHAR_EOF + +# ============= usage_sGFoA.hlp ============== +${SED} 's/^X//;/^[ ]*$/d' << 'SHAR_EOF' > 'usage_sGFoA.hlp' +test_usage_sGFoA - Checkout usage_sGFoA Options +Usage: usage_sGFoA [ - [] ]... cmd-arg ... +X +X -L str Checkout directory list +X -s [arg] Show the definition tree +X -? display extended usage information and exit +X -! extended usage information passed thru pager +SHAR_EOF + +# ============= usage_sGFop.hlp ============== +${SED} 's/^X//;/^[ ]*$/d' << 'SHAR_EOF' > 'usage_sGFop.hlp' +test_usage_sGFop - Checkout usage_sGFop Options +Usage: usage_sGFop [ - ]... cmd-arg ... +X +X -L Checkout directory list +X -s Show the definition tree +X -? display extended usage information and exit +X -! extended usage information passed thru pager +SHAR_EOF + +# ============= usage_sGsRA.hlp ============== +${SED} 's/^X//;/^[ ]*$/d' << 'SHAR_EOF' > 'usage_sGsRA.hlp' +test_usage_sGsRA - Checkout usage_sGsRA Options +Usage: usage_sGsRA { [{=| }] }... +X +X check-dirs=str Checkout directory list +X show-defs[=arg] Show the definition tree +X help display extended usage information and exit +X more-help extended usage information passed thru pager +SHAR_EOF + +# ============= usage_sGsRp.hlp ============== +${SED} 's/^X//;/^[ ]*$/d' << 'SHAR_EOF' > 'usage_sGsRp.hlp' +test_usage_sGsRp - Checkout usage_sGsRp Options +Usage: usage_sGsRp { }... +X +X check-dirs Checkout directory list +X show-defs Show the definition tree +X help display extended usage information and exit +X more-help extended usage information passed thru pager +SHAR_EOF + +# ============= usage_sGsoA.hlp ============== +${SED} 's/^X//;/^[ ]*$/d' << 'SHAR_EOF' > 'usage_sGsoA.hlp' +test_usage_sGsoA - Checkout usage_sGsoA Options +Usage: usage_sGsoA [ [{=| }] ]... +X +X check-dirs=str Checkout directory list +X show-defs[=arg] Show the definition tree +X help display extended usage information and exit +X more-help extended usage information passed thru pager +SHAR_EOF + +# ============= usage_sGsop.hlp ============== +${SED} 's/^X//;/^[ ]*$/d' << 'SHAR_EOF' > 'usage_sGsop.hlp' +test_usage_sGsop - Checkout usage_sGsop Options +Usage: usage_sGsop [ ]... +X +X check-dirs Checkout directory list +X show-defs Show the definition tree +X help display extended usage information and exit +X more-help extended usage information passed thru pager +SHAR_EOF + +# ============= usage_saFRA.hlp ============== +${SED} 's/^X//;/^[ ]*$/d' << 'SHAR_EOF' > 'usage_saFRA.hlp' +test_usage_saFRA - Checkout usage_saFRA Options +Usage: usage_saFRA { - [] }... cmd-arg ... +X Flg Arg Option-Name Req? Description +X -L Str check-dirs YES Checkout directory list +X -s opt show-defs opt Show the definition tree +X -? no help opt display extended usage information and exit +X -! no more-help opt extended usage information passed thru pager +SHAR_EOF + +# ============= usage_saFRp.hlp ============== +${SED} 's/^X//;/^[ ]*$/d' << 'SHAR_EOF' > 'usage_saFRp.hlp' +test_usage_saFRp - Checkout usage_saFRp Options +Usage: usage_saFRp { - }... cmd-arg ... +X Flg Arg Option-Name Req? Description +X -L no check-dirs YES Checkout directory list +X -s no show-defs opt Show the definition tree +X -? no help opt display extended usage information and exit +X -! no more-help opt extended usage information passed thru pager +SHAR_EOF + +# ============= usage_saFoA.hlp ============== +${SED} 's/^X//;/^[ ]*$/d' << 'SHAR_EOF' > 'usage_saFoA.hlp' +test_usage_saFoA - Checkout usage_saFoA Options +Usage: usage_saFoA [ - [] ]... cmd-arg ... +X Flg Arg Option-Name Description +X -L Str check-dirs Checkout directory list +X -s opt show-defs Show the definition tree +X -? no help display extended usage information and exit +X -! no more-help extended usage information passed thru pager +SHAR_EOF + +# ============= usage_saFop.hlp ============== +${SED} 's/^X//;/^[ ]*$/d' << 'SHAR_EOF' > 'usage_saFop.hlp' +test_usage_saFop - Checkout usage_saFop Options +Usage: usage_saFop [ - ]... cmd-arg ... +X Flg Arg Option-Name Description +X -L no check-dirs Checkout directory list +X -s no show-defs Show the definition tree +X -? no help display extended usage information and exit +X -! no more-help extended usage information passed thru pager +SHAR_EOF + +# ============= usage_sasRA.hlp ============== +${SED} 's/^X//;/^[ ]*$/d' << 'SHAR_EOF' > 'usage_sasRA.hlp' +test_usage_sasRA - Checkout usage_sasRA Options +Usage: usage_sasRA { [{=| }] }... +X Arg Option-Name Req? Description +X Str check-dirs YES Checkout directory list +X opt show-defs opt Show the definition tree +X no help opt display extended usage information and exit +X no more-help opt extended usage information passed thru pager +SHAR_EOF + +# ============= usage_sasRp.hlp ============== +${SED} 's/^X//;/^[ ]*$/d' << 'SHAR_EOF' > 'usage_sasRp.hlp' +test_usage_sasRp - Checkout usage_sasRp Options +Usage: usage_sasRp { }... +X Arg Option-Name Req? Description +X no check-dirs YES Checkout directory list +X no show-defs opt Show the definition tree +X no help opt display extended usage information and exit +X no more-help opt extended usage information passed thru pager +SHAR_EOF + +# ============= usage_sasoA.hlp ============== +${SED} 's/^X//;/^[ ]*$/d' << 'SHAR_EOF' > 'usage_sasoA.hlp' +test_usage_sasoA - Checkout usage_sasoA Options +Usage: usage_sasoA [ [{=| }] ]... +X Arg Option-Name Description +X Str check-dirs Checkout directory list +X opt show-defs Show the definition tree +X no help display extended usage information and exit +X no more-help extended usage information passed thru pager +SHAR_EOF + +# ============= usage_sasop.hlp ============== +${SED} 's/^X//;/^[ ]*$/d' << 'SHAR_EOF' > 'usage_sasop.hlp' +test_usage_sasop - Checkout usage_sasop Options +Usage: usage_sasop [ ]... +X Arg Option-Name Description +X no check-dirs Checkout directory list +X no show-defs Show the definition tree +X no help display extended usage information and exit +X no more-help extended usage information passed thru pager +SHAR_EOF + +# # # # # # # # # # DEFINITIONS FILES # # # # # # # # # + +emit_defs() +{ + exec 4> $1.def + cat >&4 <<- _EOF_ + AutoGen Definitions options; + prog-name = test_$1; + prog-title = "Checkout $1 Options"; + config-header = 'config.h'; + test-main; + _EOF_ + + cmd_arg="argument = 'cmd-arg ...';" + if ${long_opts} + then + echo "long-opts;" >&4 + if ${flag_opts} + then detail="Long and short (flag) options are accepted." + else detail="Only long options are accepted." ; fi + else + if ${flag_opts} + then detail="Only short (flag) options are accepted." + else detail="All command line arguments must be named options." + cmd_arg='' + fi + fi + + if ${gnu_usage} + then + echo "gnu-usage;" >&4 + detail="${detail}${nl}Usage should be in GNU style." + else + detail="${detail}${nl}Usage is in AutoOpts traditional style." + fi + + cat >&4 <<- _EOF_ + ${cmd_arg} + flag = { + name = check_dirs; + descrip = "Checkout directory list"; + _EOF_ + + if ${flag_opts} + then + echo " value = L;" >&4 + fi + + if ${req_opts} + then + echo " min = '1';" >&4 + detail="${detail}${nl}The check-dirs option is required." + else + detail="${detail}${nl}There are no required options." + fi + + if ${arg_opts} + then + echo " arg-type = string;" >&4 + echo " arg-name = dir;" >&4 + detail="${detail}${nl}Some options require arguments." + else + detail="${detail}${nl}No options require arguments." + fi + + cat >&4 <<- _EOF_ + }; + + flag = { + name = show_defs; + descrip = "Show the definition tree"; + _EOF_ + + if ${flag_opts} + then + ${long_opts} || echo " value = s;" >&4 + fi + + if ${arg_opts} + then + echo " arg-type = number;" >&4 + echo " arg-name = depth;" >&4 + echo " arg-optional;" >&4 + fi + + echo "};" >&4 + echo "detail = '${detail}';" >&4 + + exec 4>&- +} + +run_usage_test() { + ${arg_opts} && name="${rname}A" || name="${rname}p" + testname=${tname}_${name} + emit_defs ${testname} + test_list="${test_list} ${testname}" + echo firstline >> ${defnames_raw} + ${AG_L} ${testname}.def >> ${defnames_raw} || { + cat ${defnames_raw} + failure "AutoGen could not process $testname" + } + + ${SED} \ + -e '1,/definition names looked up/d' \ + -e '/end of looked up def/,$d' ${defnames_raw} \ + ${defnames_raw} >> ${defnames_file} + compile ${helpstr} + ${SED} -e '/extended usage information passed thru pager/q' \ + ${testname}.help > XXX + mv XXX ${testname}.help + cmp -s ${testname}.help ${testname}.hlp || \ + failure "FAILED ${testname} hlp -> help +`diff ${testname}.hlp ${testname}.help`" +} + +test_list="" +tname=${testname} +defnames_raw=${TMPDIR}/defnames.raw +defnames_file=${TMPDIR}/defnames.uniq +AG_L=${AG_L}\ --used-defines + +case "$-" in +*x* ) setx='set -x' ;; +* ) setx='' ;; +esac + +stime=$(date +%s) + +for long_opts in true false +do + ${long_opts} && lname=L || lname=s + + for gnu_usage in true false + do + ${gnu_usage} && uname="${lname}G" || uname="${lname}a" + + for flag_opts in true false + do + ${flag_opts} && fname="${uname}F" || fname="${uname}s" + + if ${long_opts} + then helpstr=--help + + elif ${flag_opts} + then helpstr='-?' + + else helpstr=help + fi + + for req_opts in true false + do + ${req_opts} && rname="${fname}R" || rname="${fname}o" + + for arg_opts in true false + do + run_usage_test + done + done + done + done +done + +test -z "${DEBUG_USAGE}" && cleanup && exit 0 + +sort -u -o ${defnames_file} ${defnames_file} +cat > ${defnames_raw} <<- _EOF_ + aliases + allow_errors + arg_default + arg_optional + arg_range + arg_type + argument + call_proc + code + config_header + copyright + default + deprecated + descrip + detail + disable + documentation + eaddr + enable + enabled + environrc + equivalence + exit_name + explain + export + extract_code + field + file_fail_code + flag + flag_code + flag_proc + flags_cant + flags_must + full_usage + gnu_usage + guard_option_names + help_value + homerc + ifdef + ifndef + immed_disable + immediate + include + lib_name + library + long_opts + main + main_text + main_type + max + min + more_help_value + must_set + name + no_command + no_libopts + no_misuse_usage + no_preset + no_xlate + nomem_fail_code + omitted_usage + package + prefix + prefix_enum + preserve_case + prog_name + prog_title + reorder_args + resettable + scaled + settable + short_usage + stack_arg + std_value + test_main + translators + unstack_arg + usage + usage_message + usage_opt + usage_type + val_name + val_upname + value + version + _EOF_ + +cmp ${defnames_raw} ${defnames_file} || \ + failure "${defnames_raw} and ${defnames_file} do not compare${nl}` + diff ${defnames_raw} ${defnames_file}`" +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## End: + +# end of usage.test diff --git a/autoopts/test/vendor.test b/autoopts/test/vendor.test new file mode 100755 index 0000000..9047e3f --- /dev/null +++ b/autoopts/test/vendor.test @@ -0,0 +1,170 @@ +#! /bin/sh +# -*- Mode: shell-script -*- +# ---------------------------------------------------------------------- +# vendor.test --- test the vendor-opt option +# +# Author: Bruce Korb +## +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd +# +# ---------------------------------------------------------------------- + +. ./defs + +# # # # # # # # # # DEFINITIONS FILE # # # # # # # # # + +{ + sedcmd=' +s/long-opts;/vendor-opt;/ +/#include "autogen.h"/d +/^prog-name/s/=.*/= '${testname}';/ +s/AutoGen/'${testname}'/g +/^include /s/= '${testname}'5 Temp/= AutoGen5 Temp/ +/^config-header/s/=.*/= '${testname}'-config.h;/ +/call-proc *=/d +/#ifndef XML/,/^#endif/ { + /^#else/,/^#endif/d + /^#/d +} +/flag-code =.*_EOCode_/,/_EOCode_;/d +/flag-code *=/d +' + + ${SED} "$sedcmd" ${top_srcdir}/agen5/opts.def + cat <<- _EOF_ + config-header = ${testname}-config.h; + help-value = h; + save-opts-value = S; + load-opts-value = P; + gnu-usage; + main = { main-type = shell-process; }; + include = '#undef DEBUG_ENABLED'; + _EOF_ +} > ${testname}.def + +{ + sed '/^#endif.*_CONFIG_H/d' ${top_builddir}/config.h + sed '1,/#define *COMPAT_H_GUARD/d + /^#endif .* COMPAT_H_GUARD/{ + s/COMPAT_H_GUARD/AUTOGEN_CONFIG_H/ + q + }' ${top_srcdir}/compat/compat.h +} > ./${testname}-config.h + +echo ${AG_L} ${testname}.def +${AG_L} ${testname}.def || \ + failure AutoGen could not process + +sedcmd='' +HOME=${TMPDIR} compile "-h" +${SED} 1d ${testname}.help > ${testname}.$$ +mv -f ${testname}.$$ ${testname}.help + +clean_help > ${testname}.hlp <<_EOF_ +Usage: ${testname} [ - [] ]... [ ] +The following options select definitions, templates and scheme functions +to use: + -L str Search for templates in DIR + - may appear multiple times + -T str Use TPL-FILE for the template + - may not be preset + -m Do not use in-mem streams +The following options modify how output is handled: + -b str Specify NAME as the base name for output + - may not be preset +The following options are often useful while debugging new templates: + -t num Limit server shell operations to SECONDS + - it must be in the range: + 0 to 3600 + --- show-defs This option has been disabled + -C Leave a core dump on a failure exit +These options can be used to control what gets processed in the +definitions files and template files: + -s str Skip the file with this SUFFIX + - prohibits the option 'select-suffix' + - may not be preset + - may appear multiple times + -o str specify this output suffix + - may not be preset + - may appear multiple times + -D str name to add to definition list + - may appear multiple times + -U str definition list removal pattern + - an alternate for 'define' +This option is used to automate dependency tracking: + -M [arg] emit make dependency file + - may not be preset + - may appear multiple times +help, version, option and error handling: +Version, usage and configuration options: + -R str reset an option's state + -v [arg] output version information and exit + -h display extended usage information and exit + -! extended usage information passed thru pager + -u abbreviated usage to stdout + -S [arg] save the option state to a config file + -P str load options from a config file + - disabled as '--no-load-opts' + - may appear multiple times +The next option supports vendor supported extra options: + -W str vendor supported additional options + These additional options are: + definitions=str Read definitions from FILE + - disabled as '--no-definitions' + - enabled by default + - may not be preset + shell=str name or path name of shell to use + equate=str characters considered equivalent + source-time set mod times to latest source + - disabled as '--no-source-time' + writable Allow output files to be writable + - disabled as '--not-writable' + loop-limit=num Limit on increment loops + - is scalable with a suffix: k/K/m/M/g/G/t/T + - it must lie in one of the ranges: + -1 exactly, or + 1 to 16777216 + trace=KWd tracing level of detail + trace-out=str tracing output file or filter + used-defines Show the definitions used + - may not be preset + no-abort Do not abort on errors +${testname} creates text files from templates using external definitions. + +The following option preset mechanisms are supported: + - reading file \$HOME/.${testname}rc + - reading file ./.${testname}rc + - examining environment variables named VENDOR_* + +The valid "trace" option keywords are: + nothing debug-message server-shell templates block-macros + expressions everything + or an integer from 0 through 6 + +${testname} is a tool designed for generating program files that contain +repetitive text with varied substitutions. +_EOF_ + +pair="${testname}.hlp ${testname}.help" +cmp -s ${pair} || \ + failure "vendor help mismatch$nl`diff $pair`" + +cleanup diff --git a/autoopts/test/vers.test b/autoopts/test/vers.test new file mode 100755 index 0000000..d498de8 --- /dev/null +++ b/autoopts/test/vers.test @@ -0,0 +1,106 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# ---------------------------------------------------------------------- +# vers.test --- test vers program attribute +# make sure that when it is not specified +# then option processing consumes all args. +# +# Author: Bruce Korb +## +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd +## +# ---------------------------------------------------------------------- + +. ./defs + +# # # # # # # # # # DEFINITIONS FILE # # # # # # # # # + +echo "creating $testname.def in `pwd`" +testname="$testname" test_main="${test_main}" \ +argument="${argument}" long_opts="${long_opts}" \ +${SHELLX} ${stdopts} option second || failure "Could not construct stdopts" +echo 'help-value = h;' >> $testname.def +echo 'version-value = V;' >> $testname.def + +echo ${AG_L} $testname.def +${AG_L} $testname.def || \ + failure AutoGen could not process + +compile "-h" + + +# # # # # # # # # # HELP OUTPUT FILE # # # # # # # # # + +echo creating $testname.hlp +clean_help > $testname.hlp <<'_EOF_' +test_vers - Test AutoOpts for vers +Usage: vers [ - ]... + Flg Arg Option-Name Description + -o no option The option option descrip + -s no second The second option descrip + -h no help display extended usage information and exit + -! no more-help extended usage information passed thru pager + +_EOF_ + +cmp -s $testname.h*lp || \ + failure help output mismatch + +./$testname -v 2> /dev/null && \ + failure $testname should not accept version option + +ver="`echo '$Revision: 4.8 $'|${SED} 's/.*: *\([0-9.a-z]*\).*/\1/'`" +echo "version = '$ver';" >> $testname.def + +echo ${AG_L} $testname.def +${AG_L} $testname.def || \ + failure AutoGen could not process + +compile "-h" + +./$testname -V 2> /dev/null || \ + failure "$testname '*SHOULD*' accept version option" + +echo recreating $testname.hlp +clean_help > $testname.hlp <<_EOF_ +test_vers - Test AutoOpts for vers - Ver. ${ver} +Usage: vers [ - ]... + Flg Arg Option-Name Description + -o no option The option option descrip + -s no second The second option descrip + -V opt version output version information and exit + -h no help display extended usage information and exit + -! no more-help extended usage information passed thru pager + +_EOF_ + +cmp -s $testname.h*lp || \ + failure versioned help output mismatch + +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## End: + +# end of vers.test diff --git a/autoopts/text_mmap.c b/autoopts/text_mmap.c new file mode 100644 index 0000000..1109308 --- /dev/null +++ b/autoopts/text_mmap.c @@ -0,0 +1,382 @@ +/** + * @file text_mmap.c + * + * Map a text file, ensuring the text always has an ending NUL byte. + * + * @addtogroup autoopts + * @{ + */ +/* + * This file is part of AutoOpts, a companion to AutoGen. + * AutoOpts is free software. + * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoOpts is available under any one of two licenses. The license + * in use must be one of these two and the choice is under the control + * of the user of the license. + * + * The GNU Lesser General Public License, version 3 or later + * See the files "COPYING.lgplv3" and "COPYING.gplv3" + * + * The Modified Berkeley Software Distribution License + * See the file "COPYING.mbsd" + * + * These files have the following sha256 sums: + * + * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 + * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 + * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + */ +#if defined(HAVE_MMAP) +# ifndef MAP_ANONYMOUS +# ifdef MAP_ANON +# define MAP_ANONYMOUS MAP_ANON +# endif +# endif + +# if ! defined(MAP_ANONYMOUS) && ! defined(HAVE_DEV_ZERO) + /* + * We must have either /dev/zero or anonymous mapping for + * this to work. + */ +# undef HAVE_MMAP + +# else +# ifdef _SC_PAGESIZE +# define GETPAGESIZE() sysconf(_SC_PAGESIZE) +# else +# define GETPAGESIZE() getpagesize() +# endif +# endif +#endif + +/* + * Some weird systems require that a specifically invalid FD number + * get passed in as an argument value. Which value is that? Well, + * as everybody knows, if open(2) fails, it returns -1, so that must + * be the value. :) + */ +#define AO_INVALID_FD -1 + +#define FILE_WRITABLE(_prt,_flg) \ + ( (_prt & PROT_WRITE) \ + && ((_flg & (MAP_SHARED|MAP_PRIVATE)) == MAP_SHARED)) +#define MAP_FAILED_PTR (VOIDP(MAP_FAILED)) + +/** + * Load the contents of a text file. There are two separate implementations, + * depending up on whether mmap(3) is available. + * + * If not available, malloc the file length plus one byte. Read it in + * and NUL terminate. + * + * If available, first check to see if the text file size is a multiple of a + * page size. If it is, map the file size plus an extra page from either + * anonymous memory or from /dev/zero. Then map the file text on top of the + * first pages of the anonymous/zero pages. Otherwise, just map the file + * because there will be NUL bytes provided at the end. + * + * @param mapinfo a structure holding everything we need to know + * about the mapping. + * + * @param pzFile name of the file, for error reporting. + */ +static void +load_text_file(tmap_info_t * mapinfo, char const * pzFile) +{ +#if ! defined(HAVE_MMAP) + mapinfo->txt_data = AGALOC(mapinfo->txt_size+1, "file text"); + if (mapinfo->txt_data == NULL) { + mapinfo->txt_errno = ENOMEM; + return; + } + + { + size_t sz = mapinfo->txt_size; + char * pz = mapinfo->txt_data; + + while (sz > 0) { + ssize_t rdct = read(mapinfo->txt_fd, pz, sz); + if (rdct <= 0) { + mapinfo->txt_errno = errno; + fserr_warn("libopts", "read", pzFile); + free(mapinfo->txt_data); + return; + } + + pz += rdct; + sz -= rdct; + } + + *pz = NUL; + } + + mapinfo->txt_errno = 0; + +#else /* HAVE mmap */ + size_t const pgsz = (size_t)GETPAGESIZE(); + void * map_addr = NULL; + + (void)pzFile; + + mapinfo->txt_full_size = (mapinfo->txt_size + pgsz) & ~(pgsz - 1); + if (mapinfo->txt_full_size == (mapinfo->txt_size + pgsz)) { + /* + * The text is a multiple of a page boundary. We must map an + * extra page so the text ends with a NUL. + */ +#if defined(MAP_ANONYMOUS) + map_addr = mmap(NULL, mapinfo->txt_full_size, PROT_READ|PROT_WRITE, + MAP_ANONYMOUS|MAP_PRIVATE, AO_INVALID_FD, 0); +#else + mapinfo->txt_zero_fd = open("/dev/zero", O_RDONLY); + + if (mapinfo->txt_zero_fd == AO_INVALID_FD) { + mapinfo->txt_errno = errno; + return; + } + map_addr = mmap(NULL, mapinfo->txt_full_size, PROT_READ|PROT_WRITE, + MAP_PRIVATE, mapinfo->txt_zero_fd, 0); +#endif + if (map_addr == MAP_FAILED_PTR) { + mapinfo->txt_errno = errno; + return; + } + mapinfo->txt_flags |= MAP_FIXED; + } + + mapinfo->txt_data = + mmap(map_addr, mapinfo->txt_size, mapinfo->txt_prot, + mapinfo->txt_flags, mapinfo->txt_fd, 0); + + if (mapinfo->txt_data == MAP_FAILED_PTR) + mapinfo->txt_errno = errno; +#endif /* HAVE_MMAP */ +} + +/** + * Make sure all the parameters are correct: we have a file name that + * is a text file that we can read. + * + * @param fname the text file to map + * @param prot the memory protections requested (read/write/etc.) + * @param flags mmap flags + * @param mapinfo a structure holding everything we need to know + * about the mapping. + */ +static void +validate_mmap(char const * fname, int prot, int flags, tmap_info_t * mapinfo) +{ + memset(mapinfo, 0, sizeof(*mapinfo)); +#if defined(HAVE_MMAP) && ! defined(MAP_ANONYMOUS) + mapinfo->txt_zero_fd = AO_INVALID_FD; +#endif + mapinfo->txt_fd = AO_INVALID_FD; + mapinfo->txt_prot = prot; + mapinfo->txt_flags = flags; + + /* + * Map mmap flags and protections into open flags and do the open. + */ + { + /* + * See if we will be updating the file. If we can alter the memory + * and if we share the data and we are *not* copy-on-writing the data, + * then our updates will show in the file, so we must open with + * write access. + */ + int o_flag = +#ifdef _WIN32 + O_BINARY | +#endif + FILE_WRITABLE(prot, flags) ? O_RDWR : O_RDONLY; + + /* + * If you're not sharing the file and you are writing to it, + * then don't let anyone else have access to the file. + */ + if (((flags & MAP_SHARED) == 0) && (prot & PROT_WRITE)) + o_flag |= O_EXCL; + + mapinfo->txt_fd = open(fname, o_flag); + if (mapinfo->txt_fd < 0) { + mapinfo->txt_errno = errno; + mapinfo->txt_fd = AO_INVALID_FD; + return; + } + } + + /* + * Make sure we can stat the regular file. Save the file size. + */ + { + struct stat sb; + if (fstat(mapinfo->txt_fd, &sb) != 0) { + mapinfo->txt_errno = errno; + close(mapinfo->txt_fd); + return; + } + + if (! S_ISREG(sb.st_mode)) { + mapinfo->txt_errno = errno = EINVAL; + close(mapinfo->txt_fd); + return; + } + + mapinfo->txt_size = (size_t)sb.st_size; + } + + if (mapinfo->txt_fd == AO_INVALID_FD) + mapinfo->txt_errno = errno; +} + +/** + * Close any files opened by the mapping. + * + * @param mi a structure holding everything we need to know about the map. + */ +static void +close_mmap_files(tmap_info_t * mi) +{ + if (mi->txt_fd == AO_INVALID_FD) + return; + + close(mi->txt_fd); + mi->txt_fd = AO_INVALID_FD; + +#if defined(HAVE_MMAP) && ! defined(MAP_ANONYMOUS) + if (mi->txt_zero_fd == AO_INVALID_FD) + return; + + close(mi->txt_zero_fd); + mi->txt_zero_fd = AO_INVALID_FD; +#endif +} + +/*=export_func text_mmap + * private: + * + * what: map a text file with terminating NUL + * + * arg: char const *, pzFile, name of the file to map + * arg: int, prot, mmap protections (see mmap(2)) + * arg: int, flags, mmap flags (see mmap(2)) + * arg: tmap_info_t *, mapinfo, returned info about the mapping + * + * ret-type: void * + * ret-desc: The mmaped data address + * + * doc: + * + * This routine will mmap a file into memory ensuring that there is at least + * one @file{NUL} character following the file data. It will return the + * address where the file contents have been mapped into memory. If there is a + * problem, then it will return @code{MAP_FAILED} and set @code{errno} + * appropriately. + * + * The named file does not exist, @code{stat(2)} will set @code{errno} as it + * will. If the file is not a regular file, @code{errno} will be + * @code{EINVAL}. At that point, @code{open(2)} is attempted with the access + * bits set appropriately for the requested @code{mmap(2)} protections and flag + * bits. On failure, @code{errno} will be set according to the documentation + * for @code{open(2)}. If @code{mmap(2)} fails, @code{errno} will be set as + * that routine sets it. If @code{text_mmap} works to this point, a valid + * address will be returned, but there may still be ``issues''. + * + * If the file size is not an even multiple of the system page size, then + * @code{text_map} will return at this point and @code{errno} will be zero. + * Otherwise, an anonymous map is attempted. If not available, then an attempt + * is made to @code{mmap(2)} @file{/dev/zero}. If any of these fail, the + * address of the file's data is returned, bug @code{no} @file{NUL} characters + * are mapped after the end of the data. + * + * see: mmap(2), open(2), stat(2) + * + * err: Any error code issued by mmap(2), open(2), stat(2) is possible. + * Additionally, if the specified file is not a regular file, then + * errno will be set to @code{EINVAL}. + * + * example: + * #include + * tmap_info_t mi; + * int no_nul; + * void * data = text_mmap("file", PROT_WRITE, MAP_PRIVATE, &mi); + * if (data == MAP_FAILED) return; + * no_nul = (mi.txt_size == mi.txt_full_size); + * << use the data >> + * text_munmap(&mi); +=*/ +void * +text_mmap(char const * pzFile, int prot, int flags, tmap_info_t * mi) +{ + validate_mmap(pzFile, prot, flags, mi); + if (mi->txt_errno != 0) + return MAP_FAILED_PTR; + + load_text_file(mi, pzFile); + + if (mi->txt_errno == 0) + return mi->txt_data; + + close_mmap_files(mi); + + errno = mi->txt_errno; + mi->txt_data = MAP_FAILED_PTR; + return mi->txt_data; +} + + +/*=export_func text_munmap + * private: + * + * what: unmap the data mapped in by text_mmap + * + * arg: tmap_info_t *, mapinfo, info about the mapping + * + * ret-type: int + * ret-desc: -1 or 0. @code{errno} will have the error code. + * + * doc: + * + * This routine will unmap the data mapped in with @code{text_mmap} and close + * the associated file descriptors opened by that function. + * + * see: munmap(2), close(2) + * + * err: Any error code issued by munmap(2) or close(2) is possible. +=*/ +int +text_munmap(tmap_info_t * mi) +{ + errno = 0; + +#ifdef HAVE_MMAP + (void)munmap(mi->txt_data, mi->txt_full_size); + +#else // don't HAVE_MMAP + /* + * IF the memory is writable *AND* it is not private (copy-on-write) + * *AND* the memory is "sharable" (seen by other processes) + * THEN rewrite the data. Emulate mmap visibility. + */ + if ( FILE_WRITABLE(mi->txt_prot, mi->txt_flags) + && (lseek(mi->txt_fd, 0, SEEK_SET) >= 0) ) + write(mi->txt_fd, mi->txt_data, mi->txt_size); + + free(mi->txt_data); +#endif /* HAVE_MMAP */ + + mi->txt_errno = errno; + close_mmap_files(mi); + + return mi->txt_errno; +} + +/** @} + * + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of autoopts/text_mmap.c */ diff --git a/autoopts/time.c b/autoopts/time.c new file mode 100644 index 0000000..debaa7a --- /dev/null +++ b/autoopts/time.c @@ -0,0 +1,145 @@ + +/** + * \file time.c + * + * @addtogroup autoopts + * @{ + */ +/* + * This file is part of AutoOpts, a companion to AutoGen. + * AutoOpts is free software. + * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoOpts is available under any one of two licenses. The license + * in use must be one of these two and the choice is under the control + * of the user of the license. + * + * The GNU Lesser General Public License, version 3 or later + * See the files "COPYING.lgplv3" and "COPYING.gplv3" + * + * The Modified Berkeley Software Distribution License + * See the file "COPYING.mbsd" + * + * These files have the following sha256 sums: + * + * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 + * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 + * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + */ + +/*=export_func optionTimeVal + * private: + * + * what: process an option with a time duration. + * arg: + tOptions * + opts + program options descriptor + + * arg: + tOptDesc * + od + the descriptor for this arg + + * + * doc: + * Decipher a time duration value. +=*/ +void +optionTimeVal(tOptions * opts, tOptDesc * od) +{ + time_t val; + + if (INQUERY_CALL(opts, od)) + return; + + val = parse_duration(od->optArg.argString); + if (val == BAD_TIME) { + fprintf(stderr, zNotDuration, opts->pzProgName, od->optArg.argString); + if ((opts->fOptSet & OPTPROC_ERRSTOP) != 0) + (*(opts->pUsageProc))(opts, EXIT_FAILURE); + } + + if (od->fOptState & OPTST_ALLOC_ARG) { + AGFREE(od->optArg.argString); + od->fOptState &= ~OPTST_ALLOC_ARG; + } + + od->optArg.argInt = (long)val; +} + +/*=export_func optionTimeDate + * private: + * + * what: process an option with a time and date. + * arg: + tOptions * + opts + program options descriptor + + * arg: + tOptDesc * + od + the descriptor for this arg + + * + * doc: + * Decipher a time and date value. +=*/ +void +optionTimeDate(tOptions * opts, tOptDesc * od) +{ +#if defined(HAVE_GETDATE_R) && defined(HAVE_PUTENV) + if (INQUERY_CALL(opts, od)) + return; + + if ((! HAS_pzPkgDataDir(opts)) || (opts->pzPkgDataDir == NULL)) + goto default_action; + + /* + * Export the DATEMSK environment variable. getdate_r() uses it to + * find the file with the strptime formats. If we cannot find the file + * we need ($PKGDATADIR/datemsk), then fall back to just a time duration. + */ + { + static char * envptr = NULL; + + if (envptr == NULL) { + static char const fmt[] = "DATEMSK=%s/datemsk"; + size_t sz = sizeof(fmt) + strlen(opts->pzPkgDataDir); + envptr = AGALOC(sz, fmt); + if (snprintf(envptr, sz, fmt, opts->pzPkgDataDir) >= (int)sz) + option_exits(EXIT_FAILURE); + + putenv(envptr); + } + + if (access(envptr+8, R_OK) != 0) + goto default_action; + } + + /* + * Convert the date to a time since the epoch and stash it in a long int. + */ + { + struct tm stm; + time_t tm; + + if (getdate_r(od->optArg.argString, &stm) != 0) { + fprintf(stderr, zNotDate, opts->pzProgName, + od->optArg.argString); + if ((opts->fOptSet & OPTPROC_ERRSTOP) != 0) + (*(opts->pUsageProc))(opts, EXIT_FAILURE); + return; + } + + tm = mktime(&stm); + + if (od->fOptState & OPTST_ALLOC_ARG) { + AGFREE(od->optArg.argString); + od->fOptState &= ~OPTST_ALLOC_ARG; + } + + od->optArg.argInt = tm; + } + return; + + default_action: + +#endif + optionTimeVal(opts, od); + if (od->optArg.argInt != BAD_TIME) + od->optArg.argInt += (long)time(NULL); +} +/** @} + * + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of autoopts/time.c */ diff --git a/autoopts/tokenize.c b/autoopts/tokenize.c new file mode 100644 index 0000000..7489e3d --- /dev/null +++ b/autoopts/tokenize.c @@ -0,0 +1,322 @@ +/** \file tokenize.c + * + * Tokenize a string, accommodating quoted strings. + * + * @addtogroup autoopts + * @{ + */ +/* + * This file defines the string_tokenize interface + * This file is part of AutoOpts, a companion to AutoGen. + * AutoOpts is free software. + * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoOpts is available under any one of two licenses. The license + * in use must be one of these two and the choice is under the control + * of the user of the license. + * + * The GNU Lesser General Public License, version 3 or later + * See the files "COPYING.lgplv3" and "COPYING.gplv3" + * + * The Modified Berkeley Software Distribution License + * See the file "COPYING.mbsd" + * + * These files have the following sha256 sums: + * + * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 + * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 + * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + */ + +static void +copy_cooked(ch_t ** ppDest, char const ** ppSrc) +{ + ch_t * pDest = (ch_t *)*ppDest; + const ch_t * pSrc = (const ch_t *)(*ppSrc + 1); + + for (;;) { + ch_t ch = *(pSrc++); + switch (ch) { + case NUL: *ppSrc = NULL; return; + case '"': goto done; + case '\\': + pSrc += ao_string_cook_escape_char((char *)pSrc, (char *)&ch, 0x7F); + if (ch == 0x7F) + break; + /* FALLTHROUGH */ + + default: + *(pDest++) = ch; + } + } + + done: + *ppDest = (ch_t *)pDest; /* next spot for storing character */ + *ppSrc = (char const *)pSrc; /* char following closing quote */ +} + + +static void +copy_raw(ch_t ** ppDest, char const ** ppSrc) +{ + ch_t * pDest = *ppDest; + cc_t * pSrc = (cc_t *) (*ppSrc + 1); + + for (;;) { + ch_t ch = *(pSrc++); + switch (ch) { + case NUL: *ppSrc = NULL; return; + case '\'': goto done; + case '\\': + /* + * *Four* escapes are handled: newline removal, escape char + * quoting and apostrophe quoting + */ + switch (*pSrc) { + case NUL: *ppSrc = NULL; return; + case '\r': + if (*(++pSrc) == NL) + ++pSrc; + continue; + + case NL: + ++pSrc; + continue; + + case '\'': + ch = '\''; + /* FALLTHROUGH */ + + case '\\': + ++pSrc; + break; + } + /* FALLTHROUGH */ + + default: + *(pDest++) = ch; + } + } + + done: + *ppDest = pDest; /* next spot for storing character */ + *ppSrc = (char const *) pSrc; /* char following closing quote */ +} + +static token_list_t * +alloc_token_list(char const * str) +{ + token_list_t * res; + + int max_token_ct = 2; /* allow for trailing NULL pointer & NUL on string */ + + if (str == NULL) goto enoent_res; + + /* + * Trim leading white space. Use "ENOENT" and a NULL return to indicate + * an empty string was passed. + */ + str = SPN_WHITESPACE_CHARS(str); + if (*str == NUL) goto enoent_res; + + /* + * Take an approximate count of tokens. If no quoted strings are used, + * it will be accurate. If quoted strings are used, it will be a little + * high and we'll squander the space for a few extra pointers. + */ + { + char const * pz = str; + + do { + max_token_ct++; + pz = BRK_WHITESPACE_CHARS(pz+1); + pz = SPN_WHITESPACE_CHARS(pz); + } while (*pz != NUL); + + res = malloc(sizeof(*res) + (size_t)(pz - str) + + ((size_t)max_token_ct * sizeof(ch_t *))); + } + + if (res == NULL) + errno = ENOMEM; + else res->tkn_list[0] = (ch_t *)(res->tkn_list + (max_token_ct - 1)); + + return res; + + enoent_res: + + errno = ENOENT; + return NULL; +} + +/*=export_func ao_string_tokenize + * + * what: tokenize an input string + * + * arg: + char const * + string + string to be tokenized + + * + * ret_type: token_list_t * + * ret_desc: pointer to a structure that lists each token + * + * doc: + * + * This function will convert one input string into a list of strings. + * The list of strings is derived by separating the input based on + * white space separation. However, if the input contains either single + * or double quote characters, then the text after that character up to + * a matching quote will become the string in the list. + * + * The returned pointer should be deallocated with @code{free(3C)} when + * are done using the data. The data are placed in a single block of + * allocated memory. Do not deallocate individual token/strings. + * + * The structure pointed to will contain at least these two fields: + * @table @samp + * @item tkn_ct + * The number of tokens found in the input string. + * @item tok_list + * An array of @code{tkn_ct + 1} pointers to substring tokens, with + * the last pointer set to NULL. + * @end table + * + * There are two types of quoted strings: single quoted (@code{'}) and + * double quoted (@code{"}). Singly quoted strings are fairly raw in that + * escape characters (@code{\\}) are simply another character, except when + * preceding the following characters: + * @example + * @code{\\} double backslashes reduce to one + * @code{'} incorporates the single quote into the string + * @code{\n} suppresses both the backslash and newline character + * @end example + * + * Double quote strings are formed according to the rules of string + * constants in ANSI-C programs. + * + * example: + * @example + * #include + * int ix; + * token_list_t * ptl = ao_string_tokenize(some_string) + * for (ix = 0; ix < ptl->tkn_ct; ix++) + * do_something_with_tkn(ptl->tkn_list[ix]); + * free(ptl); + * @end example + * Note that everything is freed with the one call to @code{free(3C)}. + * + * err: + * NULL is returned and @code{errno} will be set to indicate the problem: + * @itemize @bullet + * @item + * @code{EINVAL} - There was an unterminated quoted string. + * @item + * @code{ENOENT} - The input string was empty. + * @item + * @code{ENOMEM} - There is not enough memory. + * @end itemize +=*/ +token_list_t * +ao_string_tokenize(char const * str) +{ + token_list_t * res = alloc_token_list(str); + ch_t * pzDest; + + /* + * Now copy each token into the output buffer. + */ + if (res == NULL) + return res; + + pzDest = (ch_t *)(res->tkn_list[0]); + res->tkn_ct = 0; + + do { + res->tkn_list[ res->tkn_ct++ ] = pzDest; + for (;;) { + int ch = (ch_t)*str; + if (IS_WHITESPACE_CHAR(ch)) { + found_white_space: + str = SPN_WHITESPACE_CHARS(str+1); + break; + } + + switch (ch) { + case '"': + copy_cooked(&pzDest, &str); + if (str == NULL) { + free(res); + errno = EINVAL; + return NULL; + } + if (IS_WHITESPACE_CHAR(*str)) + goto found_white_space; + break; + + case '\'': + copy_raw(&pzDest, &str); + if (str == NULL) { + free(res); + errno = EINVAL; + return NULL; + } + if (IS_WHITESPACE_CHAR(*str)) + goto found_white_space; + break; + + case NUL: + goto copy_done; + + default: + str++; + *(pzDest++) = (unsigned char)ch; + } + } copy_done:; + + /* + * NUL terminate the last token and see if we have any more tokens. + */ + *(pzDest++) = NUL; + } while (*str != NUL); + + res->tkn_list[ res->tkn_ct ] = NULL; + + return res; +} + +#ifdef TEST +#include +#include + +int +main(int argc, char ** argv) +{ + if (argc == 1) { + printf("USAGE: %s arg [ ... ]\n", *argv); + return 1; + } + while (--argc > 0) { + char * arg = *(++argv); + token_list_t * p = ao_string_tokenize(arg); + if (p == NULL) { + printf("Parsing string ``%s'' failed:\n\terrno %d (%s)\n", + arg, errno, strerror(errno)); + } else { + int ix = 0; + printf("Parsed string ``%s''\ninto %d tokens:\n", arg, p->tkn_ct); + do { + printf(" %3d: ``%s''\n", ix+1, p->tkn_list[ix]); + } while (++ix < p->tkn_ct); + free(p); + } + } + return 0; +} +#endif + +/** @} + * + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of autoopts/tokenize.c */ diff --git a/autoopts/tpl/Mdoc.pm b/autoopts/tpl/Mdoc.pm new file mode 100644 index 0000000..4638526 --- /dev/null +++ b/autoopts/tpl/Mdoc.pm @@ -0,0 +1,542 @@ +=begin comment + +## Mdoc.pm -- Perl functions for mdoc processing +## +## Author: Oliver Kindernay (GSoC project for NTP.org) +## +## +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd +=end comment +=head1 NAME + +Mdoc - perl module to parse Mdoc macros + +=head1 SYNOPSIS + + use Mdoc qw(ns pp soff son stoggle mapwords); + +See mdoc2man and mdoc2texi for code examples. + +=head1 FUNCTIONS + +=over 4 + +=item def_macro( NAME, CODE, [ raw => 1, greedy => 1, concat_until => '.Xx' ] ) + +Define new macro. The CODE reference will be called by call_macro(). You can +have two distinct definitions for and inline macro and for a standalone macro +(i. e. 'Pa' and '.Pa'). + +The CODE reference is passed a list of arguments and is expected to return list +of strings and control characters (see C). + +By default the surrouding "" from arguments to macros are removed, use C +to disable this. + +Normaly CODE reference is passed all arguments up to next nested macro. Set +C to to pass everything up to the end of the line. + +If the concat_until is present, the line is concated until the .Xx macro is +found. For example the following macro definition + + def_macro('.Oo', gen_encloser(qw([ ]), concat_until => '.Oc' } + def_macro('.Cm', sub { mapwords {'($_)'} @_ } } + +and the following input + + .Oo + .Cm foo | + .Cm bar | + .Oc + +results in [(foo) | (bar)] + +=item get_macro( NAME ) + +Returns a hash reference like: + + { run => CODE, raw => [1|0], greedy => [1|0] } + +Where C is the CODE reference used to define macro called C + +=item parse_line( INPUT, OUTPUT_CODE, PREPROCESS_CODE ) + +Parse a line from the C filehandle. If a macro was detected it returns a +list (MACRO_NAME, @MACRO_ARGS), otherwise it calls the C, giving +caller a chance to modify line before printing it. If C is +defined it calls it prior to passing argument to a macro, giving caller a +chance to alter them. if EOF was reached undef is returned. + +=item call_macro( MACRO, ARGS, ... ) + +Call macro C with C. The CODE reference for macro C is +called and for all the nested macros. Every called macro returns a list which +is appended to return value and returned when all nested macros are processed. +Use to_string() to produce a printable string from the list. + +=item to_string ( LIST ) + +Processes C returned from call_macro() and returns formatted string. + +=item mapwords BLOCK ARRAY + +This is like perl's map only it calls BLOCK only on elements which are not +punctuation or control characters. + +=item space ( ['on'|'off] ) + +Turn spacing on or off. If called without argument it returns the current state. + +=item gen_encloser ( START, END ) + +Helper function for generating macros that enclose their arguments. + gen_encloser(qw({ })); +returns + sub { '{', ns, @_, ns, pp('}')} + +=item set_Bl_callback( CODE , DEFS ) + +This module implements the Bl/El macros for you. Using set_Bl_callback you can +provide a macro definition that should be executed on a .Bl call. + +=item set_El_callback( CODE , DEFS ) + +This module implements the Bl/El macros for you. Using set_El_callback you can +provide a macro definition that should be executed on a .El call. + +=item set_Re_callback( CODE ) + +The C is called after a Rs/Re block is done. With a hash reference as a +parameter, describing the reference. + +=back + +=head1 CONSTANTS + +=over 4 + +=item ns + +Indicate 'no space' between to members of the list. + +=item pp ( STRING ) + +The string is 'punctuation point'. It means that every punctuation +preceeding that element is put behind it. + +=item soff + +Turn spacing off. + +=item son + +Turn spacing on. + +=item stoggle + +Toogle spacing. + +=item hs + +Print space no matter spacing mode. + +=back + +=head1 TODO + +* The concat_until only works with standalone macros. This means that + .Po blah Pc +will hang until .Pc in encountered. + +* Provide default macros for Bd/Ed + +* The reference implementation is uncomplete + +=cut + +package Mdoc; +use strict; +use warnings; +use List::Util qw(reduce); +use Text::ParseWords qw(quotewords); +use Carp; +use Exporter qw(import); +our @EXPORT_OK = qw(ns pp soff son stoggle hs mapwords gen_encloser nl); + +use constant { + ns => ['nospace'], + soff => ['spaceoff'], + son => ['spaceon'], + stoggle => ['spacetoggle'], + hs => ['hardspace'], +}; + +sub pp { + my $c = shift; + return ['pp', $c ]; +} +sub gen_encloser { + my ($o, $c) = @_; + return sub { ($o, ns, @_, ns, pp($c)) }; +} + +sub mapwords(&@) { + my ($f, @l) = @_; + my @res; + for my $el (@l) { + local $_ = $el; + push @res, $el =~ /^(?:[,\.\{\}\(\):;\[\]\|])$/ || ref $el eq 'ARRAY' ? + $el : $f->(); + } + return @res; +} + +my %macros; + +############################################################################### + +# Default macro definitions start + +############################################################################### + +def_macro('Xo', sub { @_ }, concat_until => '.Xc'); + +def_macro('.Ns', sub {ns, @_}); +def_macro('Ns', sub {ns, @_}); + +{ + my %reference; + def_macro('.Rs', sub { () } ); + def_macro('.%A', sub { + if ($reference{authors}) { + $reference{authors} .= " and @_" + } + else { + $reference{authors} = "@_"; + } + return (); + }); + def_macro('.%T', sub { $reference{title} = "@_"; () } ); + def_macro('.%O', sub { $reference{optional} = "@_"; () } ); + + sub set_Re_callback { + my ($sub) = @_; + croak 'Not a CODE reference' if not ref $sub eq 'CODE'; + def_macro('.Re', sub { + my @ret = $sub->(\%reference); + %reference = (); @ret + }); + return; + } +} + +def_macro('.Bl', sub { die '.Bl - no list callback set' }); +def_macro('.It', sub { die ".It called outside of list context - maybe near line $." }); +def_macro('.El', sub { die '.El requires .Bl first' }); + + +{ + my $elcb = sub { () }; + + sub set_El_callback { + my ($sub) = @_; + croak 'Not a CODE reference' if ref $sub ne 'CODE'; + $elcb = $sub; + return; + } + + sub set_Bl_callback { + my ($blcb, %defs) = @_; + croak 'Not a CODE reference' if ref $blcb ne 'CODE'; + def_macro('.Bl', sub { + + my $orig_it = get_macro('.It'); + my $orig_el = get_macro('.El'); + my $orig_bl = get_macro('.Bl'); + my $orig_elcb = $elcb; + + # Restore previous .It and .El on each .El + def_macro('.El', sub { + def_macro('.El', delete $orig_el->{run}, %$orig_el); + def_macro('.It', delete $orig_it->{run}, %$orig_it); + def_macro('.Bl', delete $orig_bl->{run}, %$orig_bl); + my @ret = $elcb->(@_); + $elcb = $orig_elcb; + @ret + }); + $blcb->(@_) + }, %defs); + return; + } +} + +def_macro('.Sm', sub { + my ($arg) = @_; + if (defined $arg) { + space($arg); + } else { + space() eq 'off' ? + space('on') : + space('off'); + } + () +} ); +def_macro('Sm', do { my $off; sub { + my ($arg) = @_; + if (defined $arg && $arg =~ /^(on|off)$/) { + shift; + if ($arg eq 'off') { soff, @_; } + elsif ($arg eq 'on') { son, @_; } + } + else { + stoggle, @_; + } +}} ); + +############################################################################### + +# Default macro definitions end + +############################################################################### + +sub def_macro { + croak 'Odd number of elements for hash argument <'.(scalar @_).'>' if @_%2; + my ($macro, $sub, %def) = @_; + croak 'Not a CODE reference' if ref $sub ne 'CODE'; + + $macros{ $macro } = { + run => $sub, + greedy => delete $def{greedy} || 0, + raw => delete $def{raw} || 0, + concat_until => delete $def{concat_until}, + }; + if ($macros{ $macro }{concat_until}) { + $macros{ $macros{ $macro }{concat_until} } = { run => sub { @_ } }; + $macros{ $macro }{greedy} = 1; + } + return; +} + +sub get_macro { + my ($macro) = @_; + croak "Macro <$macro> not defined" if not exists $macros{ $macro }; + +{ %{ $macros{ $macro } } } +} + +#TODO: document this +sub parse_opts { + my %args; + my $last; + for (@_) { + if ($_ =~ /^\\?-/) { + s/^\\?-//; + $args{$_} = 1; + $last = _unquote($_); + } + else { + $args{$last} = _unquote($_) if $last; + undef $last; + } + } + return %args; +} + +sub _is_control { + my ($el, $expected) = @_; + if (defined $expected) { + ref $el eq 'ARRAY' and $el->[0] eq $expected; + } + else { + ref $el eq 'ARRAY'; + } +} + +{ + my $sep = ' '; + + sub to_string { + if (@_ > 0) { + # Handle punctunation + my ($in_brace, @punct) = ''; + my @new = map { + if (/^([\[\(])$/) { + ($in_brace = $1) =~ tr/([/)]/; + $_, ns + } + elsif (/^([\)\]])$/ && $in_brace eq $1) { + $in_brace = ''; + ns, $_ + } + elsif ($_ =~ /^[,\.;:\?\!\)\]]$/) { + push @punct, ns, $_; + (); + } + elsif (_is_control($_, 'pp')) { + $_->[1] + } + elsif (_is_control($_)) { + $_ + } + else { + splice (@punct), $_; + } + } @_; + push @new, @punct; + + # Produce string out of an array dealing with the special control characters + # space('off') must but one character delayed + my ($no_space, $space_off) = 1; + my $res = ''; + while (defined(my $el = shift @new)) { + if (_is_control($el, 'hardspace')) { $no_space = 1; $res .= ' ' } + elsif (_is_control($el, 'nospace')) { $no_space = 1; } + elsif (_is_control($el, 'spaceoff')) { $space_off = 1; } + elsif (_is_control($el, 'spaceon')) { space('on'); } + elsif (_is_control($el, 'spacetoggle')) { space() eq 'on' ? + $space_off = 1 : + space('on') } + else { + if ($no_space) { + $no_space = 0; + $res .= "$el" + } + else { + $res .= "$sep$el" + } + + if ($space_off) { space('off'); $space_off = 0; } + } + } + $res + } + else { + ''; + } + } + + sub space { + my ($arg) = @_; + if (defined $arg && $arg =~ /^(on|off)$/) { + $sep = ' ' if $arg eq 'on'; + $sep = '' if $arg eq 'off'; + return; + } + else { + return $sep eq '' ? 'off' : 'on'; + } + } +} + +sub _unquote { + my @args = @_; + $_ =~ s/^"([^"]+)"$/$1/g for @args; + wantarray ? @args : $args[0]; +} + +sub call_macro { + my ($macro, @args) = @_; + my @ret; + + my @newargs; + my $i = 0; + + @args = _unquote(@args) if (!$macros{ $macro }{raw}); + + # Call any callable macros in the argument list + for (@args) { + if ($_ =~ /^[A-Z][a-z]+$/ && exists $macros{ $_ }) { + push @ret, call_macro($_, @args[$i+1 .. $#args]); + last; + } else { + if ($macros{ $macro }{greedy}) { + push @ret, $_; + } + else { + push @newargs, $_; + } + } + $i++; + } + + if ($macros{ $macro }{concat_until}) { + my ($n_macro, @n_args) = (''); + while (1) { + die "EOF was reached and no $macros{ $macro }{concat_until} found" + if not defined $n_macro; + ($n_macro, @n_args) = parse_line(undef, sub { push @ret, shift }); + if ($n_macro eq $macros{ $macro }{concat_until}) { + push @ret, call_macro($n_macro, @n_args); + last; + } + else { + $n_macro =~ s/^\.//; + push @ret, call_macro($n_macro, @n_args) if exists $macros{ $n_macro }; + } + } + } + + if ($macros{ $macro }{greedy}) { + #print "MACROG $macro (", (join ', ', @ret), ")\n"; + return $macros{ $macro }{run}->(@ret); + } + else { + #print "MACRO $macro (", (join ', ', @newargs), ")".(join ', ', @ret)."\n"; + return $macros{ $macro }{run}->(@newargs), @ret; + } +} + +{ + my ($in_fh, $out_sub, $preprocess_sub); + sub parse_line { + $in_fh = $_[0] if defined $_[0] || !defined $in_fh; + $out_sub = $_[1] if defined $_[1] || !defined $out_sub; + $preprocess_sub = $_[2] if defined $_[2] || !defined $preprocess_sub; + + croak 'out_sub not a CODE reference' + if not ref $out_sub eq 'CODE'; + croak 'preprocess_sub not a CODE reference' + if defined $preprocess_sub && not ref $preprocess_sub eq 'CODE'; + + while (my $line = <$in_fh>) { + chomp $line; + if ($line =~ /^\.[A-z][a-z0-9]+/ || $line =~ /^\.%[A-Z]/ || + $line =~ /^\.\\"/) + { + $line =~ s/ +/ /g; + my ($macro, @args) = quotewords(' ', 1, $line); + @args = grep { defined $_ } @args; + $preprocess_sub->(@args) if defined $preprocess_sub; + if ($macro && exists $macros{ $macro }) { + return ($macro, @args); + } else { + $out_sub->($line); + } + } + else { + $out_sub->($line); + } + } + return; + } +} + +1; +__END__ diff --git a/autoopts/tpl/aginfo.tpl b/autoopts/tpl/aginfo.tpl new file mode 100644 index 0000000..3c9d478 --- /dev/null +++ b/autoopts/tpl/aginfo.tpl @@ -0,0 +1,12 @@ +[= AutoGen5 template + +texi + +## Copyright (C) 2006-2018 Bruce Korb, all rights reserved. + +=] +[= `echo please note that this is obsolete >&2` =][= + +INCLUDE "agtexi-cmd.tpl" + +\=] diff --git a/autoopts/tpl/aginfo3.tpl b/autoopts/tpl/aginfo3.tpl new file mode 100644 index 0000000..efccb1a --- /dev/null +++ b/autoopts/tpl/aginfo3.tpl @@ -0,0 +1,126 @@ +{+ AutoGen5 template -*- nroff -*- + +texi + +## aginfo3.tpl -- Template for function texi doc +## +## Author: Bruce Korb +## +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + ++}{+ + +(out-push-new (sprintf "%s.menu" (base-name))) +(define lib-name (get "library")) +(if (< (string-length lib-name) 1) + (set! lib-name (base-name)) ) +(define node-name (sprintf "lib%s procedures" lib-name)) +(define sec-name (sprintf "lib%s External Procedures" lib-name)) + +(define doc-level (getenv "LEVEL")) +(if (not (string? doc-level)) + (set! doc-level "section")) +(sprintf "* %-28s %s\n" (string-append node-name "::") sec-name) +}{+ +(out-pop) ++}@node {+ (. node-name) +} +@{+ (. doc-level) +} {+ (. sec-name) +} + +{+ + +IF (not (exist? "lib-description")) + ++}These are the publicly exported procedures from the lib@i{{+(. lib-name)+}} +library. Any other functions mentioned in the @i{header} file are +for the private use of the library.{+ + +ELSE +}{+ lib-description +}{+ +ENDIF +} + +@menu{+ + +FOR export-func +}{+ + IF (not (exist? "private")) +} +* lib{+(sprintf "%-24s" (string-append + lib-name "-" (get "name") "::")) + +} {+name +}{+ + + ENDIF private +}{+ + +ENDFOR export-func +} +@end menu + +This {+(. doc-level)+} was automatically generated by AutoGen +using extracted information and the {+(tpl-file)+} template.{+ + +FOR export-func +}{+ + IF (not (exist? "private")) + ++} + +@node lib{+library+}-{+name+} +@{+CASE (. doc-level)+}{+ + = chapter +}{+ + = section +}sub{+ + = subsection +}subsub{+ + ESAC +}section {+name+} +@findex {+name+} + +{+what+} + +@noindent +Usage: +@example +{+ % ret-type "%s res = " ++}{+name+}({+ + IF (exist? "arg") +} {+ + FOR arg ", " +}{+arg-name+}{+ + ENDFOR +} {+ + ENDIF +}); +@end example{+ + IF (or (exist? "arg") (exist? "ret-type")) +} +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab -------------{+ + FOR arg "\n" +} +@item @tab {+arg-name+} @tab @code{{+arg-type+}} +@tab {+arg-desc+}{+ + ENDFOR+}{+ + IF (exist? "ret-type") +} +@item @tab returns @tab {+ret-type+} +@tab {+ ret-desc +}{+ + + ENDIF +} +@end multitable{+ + + ENDIF ++} + +{+doc+} +{+ % err "\n%s\n" +}{+ + + ENDIF private +}{+ + +ENDFOR export-func + + ++} diff --git a/autoopts/tpl/agman-cmd.tpl b/autoopts/tpl/agman-cmd.tpl new file mode 100644 index 0000000..9a1777b --- /dev/null +++ b/autoopts/tpl/agman-cmd.tpl @@ -0,0 +1,63 @@ +[+: -*- Mode: nroff -*- + + AutoGen5 template man + +## agman-cmd.tpl -- Template for command line man pages +## +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## Copyright (C) 1992-2018 Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + +# Produce a man page for section 1, 5 or 8 commands. +# Which is selected via: -DMAN_SECTION=n +# passed to the autogen invocation. "n" may have a suffix, if desired. +# +:+][+: +(out-push-new) :+] +if test -z "${MAN_PAGE_DATE}" +then LC_ALL=C date '+%d %b %Y' | sed 's/ */ /g' +else echo "${MAN_PAGE_DATE}" +fi +[+: +(define mpage-date (shell (out-pop #t))) + +(define head-line (lambda() + (sprintf ".TH %s %s \"%s\" \"%s\" \"%s\"\n.\\\"\n" + (get "prog-name") man-sect + mpage-date package-text section-name) )) + +(define man-page #t) +(out-push-new) :+][+: + +INCLUDE "cmd-doc.tlib" :+][+: +INVOKE build-doc :+][+: + + (shell (string-append + "fn='" (find-file "mdoc2man") "'\n" + "test -f ${fn} || die mdoc2man not found from $PWD\n" + "${fn} <<\\_EndOfMdoc_ || die ${fn} failed in $PWD\n" + (out-pop #t) + "\n_EndOfMdoc_" )) + +:+][+: + +(out-move (string-append (get "prog-name") "." + man-sect)) :+][+: + +agman-cmd.tpl ends here :+] diff --git a/autoopts/tpl/agman-file.tpl b/autoopts/tpl/agman-file.tpl new file mode 100644 index 0000000..8b6430a --- /dev/null +++ b/autoopts/tpl/agman-file.tpl @@ -0,0 +1,90 @@ +[+: -*- Mode: nroff -*- + + AutoGen5 template man + +## agman-file.tpl -- Template for file man pages +## +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## Copyright (C) 1992-2018 Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + +# Produce a man page for section 5 - configuration file formats. +# +:+][+: +(out-push-new) :+] +if test -z "${MAN_PAGE_DATE}" +then LC_ALL=C date '+%d %b %Y' | sed 's/ */ /g' +else echo "${MAN_PAGE_DATE}" +fi +[+: +(define mpage-date (shell (out-pop #t))) + +(define head-line (lambda() + (sprintf ".TH %s %s \"%s\" \"%s\" \"%s\"\n.\\\"\n" + (get "prog-name") man-sect + mpage-date package-text section-name) )) + +(define man-page #t) + +:+][+: + +INCLUDE "cmd-doc.tlib" + +:+] +.\" +.SH NAME +[+: prog-name :+] \- [+: prog-title :+] configuration file +[+: + +(define command-doc #f) +(out-push-new) :+][+: + +INVOKE build-doc :+][+: + + (shell (string-append + "fn='" (find-file "mdoc2man") "'\n" + "test -f ${fn} || die mdoc2man not found from $PWD\n" + "${fn} <<\\_EndOfMdoc_ || die ${fn} failed in $PWD\n" + (out-pop #t) + "\n_EndOfMdoc_" )) + +:+][+: + +(out-move (string-append (get "prog-name") "." + man-sect)) :+][+: # + +.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +.\" S Y N O P S I S +.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = :+][+: + +DEFINE mk-synopsis :+][+: + (out-push-new file-name) \:+] +.SH SYNOPSIS +.B [+: file-path :+] +.PP [+: + +(if (exist? "explain") + (string-append "\n.PP\n" + (join "\n.PP\n" (stack "explain"))) ) :+][+: + +(out-pop) :+][+: + +ENDDEF mk-synopsis + +agman-file.tpl ends here :+] diff --git a/autoopts/tpl/agman.tlib b/autoopts/tpl/agman.tlib new file mode 100644 index 0000000..bef8e2a --- /dev/null +++ b/autoopts/tpl/agman.tlib @@ -0,0 +1,98 @@ +[+: AutoGen5 template -*- shell-script -*- + +null + +:+][+: + +## agman-lib.tpl -- Template for command line man pages +## +## Author: Jim Van Zandt +## +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + +## This "library" converts texi-isms into man-isms. It gets included +## by the man page template at the point where texi-isms might start appearing +## and then "emit-man-text" is invoked when all the text has been assembled. +## +## Display the command line prototype, +## based only on the argument processing type. +## +## And run the entire output through "sed" to convert texi-isms + +:+][+: + +(define sed-script (string-append (base-name) ".post-proc-sed")) +(out-push-new sed-script) + +\:+] +s;@code{\([^}]*\)};\\fB\1\\fP;g +s;@var{\([^}]*\)};\\fB\1\\fP;g +s;@samp{\([^}]*\)};\\fB\1\\fP;g +s;@i{\([^}]*\)};\\fI\1\\fP;g +s;@file{\([^}]*\)};\\fI\1\\fP;g +s;@emph{\([^}]*\)};\\fI\1\\fP;g +s;@strong{\([^}]*\)};\\fB\1\\fP;g +s/@\([{}]\)/\1/g +s,^\$\*$,.br, +/@ *example/,/@ *end *example/s/^/ / +s/^ *@ *example/.nf/ +s/^ *@ *end *example/.fi/ +/^ *@ *noindent/d +/^ *@ *enumerate/d +s/^ *@ *end *enumerate/.br/ +/^ *@ *table/d +s/^ *@ *end *table/.br/ +s/^@item \(.*\)/.sp\ +.IR "\1"/ +s/^@item/.sp 1/ +s/\*\([a-zA-Z0-9:~=_ -]*\)\*/\\fB\1\\fP/g +s/``\([a-zA-Z0-9:~+=_ -]*\)''/\\(lq\1\\(rq/g +s/^'/\\'/ +s/^@\*/.br/ +s/ -/ \\-/g +s/^\.in \\-/.in -/ +[+: + +(out-suspend "sed-script") +(define raw-text (string-append (base-name) ".raw")) +(out-push-new raw-text) + +:+][+: + +DEFINE emit-man-text :+][+: + (out-pop) + (out-resume "sed-script") :+][+: + + FOR doc-sub :+][+: + + (define field-name (get "sub-name")) + (define rep-string (string-append "<<" field-name ">>")) + (string-substitute (get "sub-expr") rep-string (get field-name)) + :+][+: + ENDFOR doc-sub :+][+: + + (out-pop) + (shellf "sed -f %1$s %2$s ; rm -f %1$s %2$s" + sed-script raw-text) :+][+: + +ENDDEF emit-man-text :+][+: # + +agman-lib.tpl ends here :+] diff --git a/autoopts/tpl/agman1.tpl b/autoopts/tpl/agman1.tpl new file mode 100644 index 0000000..0b931a2 --- /dev/null +++ b/autoopts/tpl/agman1.tpl @@ -0,0 +1,12 @@ +[+: -*- Mode: nroff -*- + +AutoGen5 template man=%s.1 + +## Copyright (C) 2001-2018 Bruce Korb, all rights reserved. + +:+] +[+: `echo please note that this is obsolete >&2` :+][+: + +INCLUDE "agman-cmd.tpl" + +\:+] diff --git a/autoopts/tpl/agman3.tpl b/autoopts/tpl/agman3.tpl new file mode 100644 index 0000000..6e53191 --- /dev/null +++ b/autoopts/tpl/agman3.tpl @@ -0,0 +1,145 @@ +{+ AutoGen5 template -*- nroff -*- + +null + +## agman3.tpl -- Template for command line man pages +## +## Author: Bruce Korb +## +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + ++}{+ + +(define see-also "") +(if (exist? "see-also") + (set! see-also (string-append (get "see-also") " ")) ) + ++}{+ + +FOR export-func +}{+ + (if (not (exist? "private")) + (set! see-also (string-append see-also + (get "name") "(3) " )) ) + +}{+ + +ENDFOR export-func +}{+ + + +FOR export-func +}{+ + IF (not (exist? "private")) +}{+ + + (out-push-new (string-append + (get "name") ".3" )) + ++}.TH {+name+} 3 {+ ` + if test -z "${MAN_PAGE_DATE}" + then date +%Y-%m-%d + else echo "${MAN_PAGE_DATE}"; fi +` +} "" "Programmer's Manual" +{+ + +;; The following "dne" argument is a string of 5 characters: +;; '.' '\\' '"' and two spaces. It _is_ hard to read. " +;; +(dne ".\\\" ") + ++} +.SH NAME +{+name+} - {+what+} +.sp 1 +.SH SYNOPSIS +{+IF (exist? "header") +} +#include <\fI{+header+}\fP> +.br{+ + ENDIF+} +cc [...] -o outfile infile.c -l\fB{+library+}\fP [...] +.sp 1 +{+ ?% ret-type "%s" void ++} \fB{+name+}\fP({+ + IF (not (exist? "arg")) +}void{+ + ELSE +}{+ + FOR arg ", " +}{+arg-type+} \fI{+arg-name+}\fP{+ + ENDFOR arg +}{+ + ENDIF +}); +.sp 1 +.SH DESCRIPTION +{+ + INCLUDE "agman.tlib" ++}{+ +(get "doc") +}{+ + IF (exist? "arg") +}{+ + FOR arg +} +.TP +.IR {+ arg-name +} +{+ arg-desc +}{+ + + ENDFOR arg +}{+ + ENDIF arg exists +}{+ + + IF (exist? "ret-type") +} +.sp 1 +.SH RETURN VALUE +{+ret-desc+}{+ + + ENDIF +}{+ + + IF (exist? "err") +} +.sp 1 +.SH ERRORS +{+ err +}{+ + + ENDIF +}{+ + + IF (exist? "example") +} +.sp 1 +.SH EXAMPLES +.nf +.in +5 +{+ example +} +.in -5 +.fi{+ + + ENDIF +}{+ + +emit-man-text + ++} +.SH SEE ALSO +The \fIinfo\fP documentation for the -l\fI{+library+}\fP library. +.br +{+ +(define tmp-txt (get "see")) +(if (> (string-length see-also) 0) + (set! tmp-txt (string-append see-also ", " tmp-txt)) ) + +(shellf "echo '%s' | \ +sed 's@%s(3) @@;s/3) $/3)/;s/(3) /(3), /g;s/, *,/,/g;s/^, *//'" + tmp-txt (get "name")) +} +{+ + + (out-pop) +}{+ + + ENDIF private +}{+ + +ENDFOR export-func + + ++} diff --git a/autoopts/tpl/agmdoc-cmd.tpl b/autoopts/tpl/agmdoc-cmd.tpl new file mode 100644 index 0000000..084830b --- /dev/null +++ b/autoopts/tpl/agmdoc-cmd.tpl @@ -0,0 +1,52 @@ +[+: -*- Mode: nroff -*- + + AutoGen5 template mdoc + +## agman-cmd.tpl -- Template for command line mdoc pages +## +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + +# Produce a man page for section 1, 5 or 8 commands. +# Which is selected via: -DMAN_SECTION=n +# passed to the autogen invocation. "n" may have a suffix, if desired. +# +:+][+: +(out-push-new) :+] +if test -z "${MAN_PAGE_DATE}" +then LC_ALL=C date '+%B %e %Y' | sed 's/ */ /g' +else echo "${MAN_PAGE_DATE}" +fi +[+: +(define mpage-date (shell (out-pop #t))) + +(define head-line (lambda() (string-append + ".Dd " mpage-date + "\n.Dt " UP-PROG-NAME " " man-sect " " section-name + "\n.Os\n") )) + +(define man-page #f) :+][+: + +INCLUDE "cmd-doc.tlib" :+][+: +INVOKE build-doc :+][+: + +(out-move (string-append + (get "prog-name") "." man-sect)) :+][+: +agmdoc-cmd.tpl ends here :+] diff --git a/autoopts/tpl/agmdoc-file.tpl b/autoopts/tpl/agmdoc-file.tpl new file mode 100644 index 0000000..ed8c8ed --- /dev/null +++ b/autoopts/tpl/agmdoc-file.tpl @@ -0,0 +1,76 @@ +[+: -*- Mode: nroff -*- + + AutoGen5 template mdoc + +## agman-file.tpl -- Template for file mdoc pages +## +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + +# Produce an mdoc page for section 5 - configuration file formats. +# +:+][+: +(out-push-new) :+] +if test -z "${MAN_PAGE_DATE}" +then LC_ALL=C date '+%B %e %Y' | sed 's/ */ /g' +else echo "${MAN_PAGE_DATE}" +fi +[+: +(define mpage-date (shell (out-pop #t))) + +(define head-line (lambda() (string-append + ".Dd " mpage-date + "\n.Dt " UP-PROG-NAME " " man-sect " " section-name + "\n.Os " (shell "uname -sr") "\n") )) + +(define man-page #f) + +:+][+: + +INCLUDE "cmd-doc.tlib" + +:+] +.Sh NAME +.Nm [+: prog-name :+] +.Nd [+: prog-title :+] +[+: INVOKE build-doc :+][+: + +(out-move (string-append (get "prog-name") "." + man-sect)) :+][+:# + +.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +.\" S Y N O P S I S +.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = :+][+: + +DEFINE mk-synopsis :+][+: + (out-push-new file-name) \:+] +.Sh SYNOPSIS +.Sy [+: file-path :+] +.Pp [+: + +FOR explain "\n.Pp\n" :+][+: + explain :+][+: +ENDFOR :+][+: + +(out-pop) :+][+: + +ENDDEF mk-synopsis + +agmdoc-file.tpl ends here :+] diff --git a/autoopts/tpl/agpl.lic b/autoopts/tpl/agpl.lic new file mode 100644 index 0000000..bff4469 --- /dev/null +++ b/autoopts/tpl/agpl.lic @@ -0,0 +1,19 @@ +Copyright (C) , all rights reserved. +This is free software. It is licensed for use, modification and +redistribution under the terms of the GNU Affero GPL, version 3 +or later + + 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. + + is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . + +GNU Affero GPL, version 3 or later diff --git a/autoopts/tpl/agtexi-cmd.tpl b/autoopts/tpl/agtexi-cmd.tpl new file mode 100644 index 0000000..a6d080c --- /dev/null +++ b/autoopts/tpl/agtexi-cmd.tpl @@ -0,0 +1,970 @@ +[= AutoGen5 template -*- Mode: texinfo -*- + +texi=invoke_PROGRAMNAME.texi + +# Documentation template +# +# This file is part of AutoOpts, a companion to AutoGen. +# AutoOpts is free software. +# AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +# +# AutoOpts is available under any one of two licenses. The license +# in use must be one of these two and the choice is under the control +# of the user of the license. +# +# The GNU Lesser General Public License, version 3 or later +# See the files "COPYING.lgplv3" and "COPYING.gplv3" +# +# The Modified Berkeley Software Distribution License +# See the file "COPYING.mbsd" +# +# These files have the following sha256 sums: +# +# 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +# 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +# 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + +=][= + +INVOKE initialization =][= +INVOKE emit-description =] + +This [=(string-downcase doc-level)=] was generated by @strong{AutoGen}, +using the @code{agtexi-cmd} template and the option descriptions for the [=(. +coded-prog-name)=] program.[= (name-copyright) =] + +@menu +[= + (out-push-new) (out-suspend "menu") + (out-push-new) =][= + +INVOKE emit-usage-opt =][= + +;; FOR all options, ... +;; +(define opt-name "") +(define extra-text "") +(define optname-from "A-Z_^") +(define optname-to "a-z--") +(define invalid-doc "* INVALID *") +(if (exist? "preserve-case") (begin + (set! optname-from "_^") + (set! optname-to "--") )) +(if (and have-doc-options (not (exist? "flag[].documentation"))) (begin + (ag-fprintf "menu" menu-entry-fmt + "base-options:: " "Base options") + (print-node opt-name "Base options") +) ) + +=][=# + +@c = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =][= + +FOR flag =][= + IF (and (last-for?) (exist? "documentation")) =][= BREAK =][= ENDIF =][= + + (set! opt-name (string-tr! (get "name") optname-from optname-to)) + (if (exist? "documentation") + (begin + (set! label-str (string-append opt-name " options")) + (ag-fprintf "menu" menu-entry-fmt + (string-append opt-name ":: ") label-str) + (print-node opt-name label-str) + (ag-fprintf 0 "\n%s." (get "descrip")) + (set! tmp-str (get "documentation")) + (if (> (string-length tmp-str) 1) + (ag-fprintf 0 "\n%s" tmp-str)) + ) + (begin + (set! tmp-str (get "doc" invalid-doc)) + (if (< 0 (string-length tmp-str)) (begin + (set! label-str (string-append opt-name " option" + (if (exist? "value") + (string-append " (-" (get "value") ")") + "" ) )) + (if have-doc-options + (ag-fprintf 0 opt-node-fmt opt-name label-str) + (begin + (ag-fprintf "menu" menu-entry-fmt + (string-append opt-name ":: ") label-str) + (print-node opt-name label-str) + ) + ) + (ag-fprintf 0 "\n@cindex %s-%s" down-prog-name opt-name) + ) ) + ) + ) =][= + + IF (and (not (exist? "documentation")) + (< 0 (string-length tmp-str)) ) + =][= + IF (exist? "aliases") =][= + INVOKE emit-aliases =][= + ELSE =][= + INVOKE emit-opt-text =][= + ENDIF =][= + ENDIF =][= + +ENDFOR flag =][= + +IF + (define home-rc-files (> (count "homerc") 0)) + (if (and (not home-rc-files) (exist? "homerc")) + (set! home-rc-files (> (string-length (get "homerc")) 0)) ) + (define environ-init (exist? "environrc")) + (or home-rc-files environ-init) + =][= + + INVOKE emit-presets =][= + +ENDIF =][= + +INVOKE emit-exit-status =][= +INVOKE emit-doc-sections =][= + +(out-suspend "opt-desc") +(out-resume "menu") +(emit (out-pop #t)) +(emit "@end menu\n") +(out-resume "opt-desc") +(emit (out-pop #t)) +(define post-proc-cmd (get "doc-sub-cmd" "sed -f %s %s")) + +(if do-post-proc (begin + (out-pop) + (shellf post-proc-cmd post-proc-file raw-doc-file) +) ) + +=][=# + +@c = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =][= + +DEFINE emit-doc-sections =][= + +FOR doc-section =][= + + IF (define opt-name (string-capitalize! (get "ds-type"))) + (or (== opt-name "Exit Status") + (== opt-name "Description") + (exist? "omit-texi")) =][= + CONTINUE =][= + ENDIF =][= + + (define section-file (string-append tmp-dir "/" + (string-substitute opt-name " " "-"))) + (if (not (access? section-file R_OK)) (begin + (ag-fprintf "menu" menu-entry-fmt (string-append opt-name "::") opt-name) + (set! label-str (string-append + down-prog-name " " (string-capitalize opt-name))) + (out-push-new section-file) + (print-node opt-name label-str) + ) (begin + (out-push-add section-file) + (emit "\n") + ) ) + + (define cvt-fn (get "ds-format" "texi")) + (if (not (== cvt-fn "texi")) + (divert-convert cvt-fn) ) =][= + (emit (string-append "\n" (get "ds-text") "\n")) + (convert-divert) + (out-pop) + +=][= +ENDFOR doc-section =][= + +FOR doc-section =][= + IF (define opt-name (string-capitalize! (get "ds-type"))) + (define section-file (string-append tmp-dir "/" + (string-substitute opt-name " " "-"))) + (access? section-file R_OK) + =][= + (shellf "cat %1$s ; rm -f %1$s" section-file) + =][= + ENDIF accessible section file =][= +ENDFOR doc-section =][= + +ENDDEF emit-doc-sections + +@c = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =][= + +DEFINE emit-description =][= + +(if (exist? "explain") + (emit (string-append "\n" (get "explain") "\n")) ) +(set! tmp-str (get "option-format" "texi")) +(divert-convert tmp-str) + +=][= + +IF (match-value? == "doc-section.ds-type" "DESCRIPTION") =][= + + FOR doc-section =][= + IF (== (get "ds-type") "DESCRIPTION") =][= + (define cvt-fn (get "ds-format" "texi")) + (if (not (== cvt-fn "texi")) + (divert-convert cvt-fn) ) + (emit (string-append "\n" (get "ds-text") "\n")) + =][= + BREAK =][= + + ENDIF =][= + ENDFOR =][= + +ELSE =][= + +(join "\n\n" + (if (exist? "prog-info-descrip") + (stack "prog-info-descrip") + (if (exist? "prog-man-descrip") + (stack "prog-man-descrip") + (if (exist? "prog-descrip") + (stack "prog-descrip") + (stack "detail") +) ) ) ) =][= + +ENDIF =][= + +(convert-divert) =][= + +ENDDEF emit-description + +@c = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =][= + +DEFINE emit-exit-status =][= + (ag-fprintf "menu" menu-entry-fmt "exit status::" "exit status") + (print-node "exit status" (string-append program-name " exit status")) =] + +One of the following exit values will be returned: +@table @samp +@item 0 (EXIT_[= + (set! tmp-str (get "exit-name[0]" "SUCCESS")) + (string-upcase (string->c-name! tmp-str)) + =]) +[= + (define need-ex-noinput (exist? "homerc")) + (define need-ex-software #t) + (get "exit-desc[0]" "Successful program execution.")=] +@item 1 (EXIT_[= + + (set! tmp-str (get "exit-name[1]" "FAILURE")) + (string-upcase (string->c-name! tmp-str))=]) +[= (get "exit-desc[1]" + "The operation failed or the command syntax was not valid.") =][= + +FOR exit-desc (for-from 2) =][= + (if (= (for-index) 66) + (set! need-ex-noinput #f) + (if (= (for-index) 70) + (set! need-ex-software #f) )) + (set! tmp-str (get (sprintf "exit-name[%d]" (for-index)) "* unnamed *")) + (sprintf "\n@item %d (EXIT_%s)\n%s" (for-index) + (string-upcase (string->c-name! tmp-str)) + (get (sprintf "exit-desc[%d]" (for-index)))) + =][= +ENDFOR exit-desc =][= + +(if need-ex-noinput + (emit "\n@item 66 (EX_NOINPUT) +A specified configuration file could not be loaded.")) + +(if need-ex-noinput + (emit "\n@item 70 (EX_SOFTWARE) +libopts had an internal operational error. Please report +it to autogen-users@@lists.sourceforge.net. Thank you.")) +=] +@end table[= + +ENDDEF emit-exit-status + +@c = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =][= + +DEFINE emit-aliases =] + +This is an alias for the @code{[= aliases =]} option, +[= (sprintf "@pxref{%1$s %2$s, the %2$s option documentation}.\n" + down-prog-name (get "aliases")) =][= + +ENDDEF emit-aliases + +@c = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =][= + +DEFINE emit-opt-text =] + +This is the ``[=(string-downcase! (get "descrip"))=]'' option.[= + IF (exist? "arg-type") =] +This option takes a[= (if (exist? "arg-optional") "n optional" "") + =] [= arg-type =] argument[= +(if (exist? "arg-name") (string-append " @file{" + (string-substitute (get "arg-name") "@" "@@") "}")) + =].[= + ENDIF =][= + + IF (out-push-new) + + (exist? "min") =]@item +is required to appear on the command line. +[= + ENDIF=][= + + IF (exist? "max") =]@item +may appear [= + IF % max (== "%s" "NOLIMIT") + =]an unlimited number of times[= + ELSE + =]up to [=max=] times[= + ENDIF=]. +[= + ENDIF=][= + + IF (exist? "disable") =]@item +can be disabled with --[=disable=]-[=(. opt-name)=][= + (if (exist? "enable") (emit + "\nand enabled with --" (get "enable") "-" opt-name)) =]. +[= + ENDIF=][= + + IF (exist? "enabled") =]@item +It is enabled by default. +[= + ENDIF=][= + + IF (exist? "ifdef") =]@item +must be compiled in by defining @code{[=(get "ifdef") + =]} during the compilation. +[= + ENDIF =][= + + IF (exist? "ifndef") =]@item +must be compiled in by @strong{un}-defining @code{[=(get "ifndef") + =]} during the compilation. +[= + ENDIF=][= + + IF (exist? "no_preset") =]@item +may not be preset with environment variables or configuration (rc/ini) files. +[= + ENDIF=][= + + IF (exist? "equivalence") =]@item +is a member of the [=equivalence=] class of options. +[= + ENDIF=][= + + IF (exist? "flags_must") =]@item +must appear in combination with the following options: +[= FOR flags_must ", " =][=flags_must=][= + ENDFOR=]. +[= + ENDIF=][= + + IF (exist? "flags_cant") =]@item +must not appear in combination with any of the following options: +[= FOR flags_cant ", " =][=flags_cant=][= + ENDFOR=]. +[= + ENDIF=][= + + IF (~* (get "arg-type") "key|set") =]@item +This option takes a keyword as its argument[= + + CASE arg-type =][= + =* key =]. +The argument sets an enumeration value that can be tested by comparing[= + + =* set =] list. +Each entry turns on or off membership bits. These bits can be tested +with bit tests against[= + ESAC arg-type =] the option value macro ([= +(string-upcase (string-append +(if (exist? "prefix") (string-append (get "prefix") "_") "") +"OPT_VALUE_" (get "name") )) =]). +The available keywords are: +@example +[= (shell (string-append + "${CLexe:-columns} -I4 --spread=1 -W50 <<\\" heredoc-marker + (join "\n" (stack "keyword") "\n") + heredoc-marker + ) ) =] +@end example +[= + + IF (=* (get "arg-type") "key") =] +or their numeric equivalent. +[= ENDIF =][= + + ENDIF key/set arg =][= + + IF (set! extra-text (out-pop #t)) + (> (string-length extra-text) 2) + =] + +@noindent +This option has some usage constraints. It: +@itemize @bullet +[= (. extra-text) =]@end itemize +[= ENDIF =][= + +?% doc "\n%s" "\nThis option has no @samp{doc} documentation." =][= + IF (exist? "deprecated") =] + +@strong{NOTE}@strong{: THIS OPTION IS DEPRECATED}[= + + ENDIF =][= + +ENDDEF emit-opt-text + +@c = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =][= + +DEFINE set-home-rc-vars =][= + CASE homerc =][= + ==* '$@' =][= + (set! explain-pkgdatadir #t) + (set! cfg-file-name (string-substitute (get "homerc") + "$@" "$(pkgdatadir)")) =][= + + == '.' =][= + (set! cfg-file-name "$PWD") + (set! env-var-list (string-append env-var-list "PWD, ")) + =][= + + ==* './' =][= + (set! explain-pkgdatadir #t) + (set! env-var-list (string-append env-var-list "PWD, ")) + (set! cfg-file-name (string-append "$PWD" (substring (get "homerc") 1))) + =][= + + ~~* '\$[A-Za-z]' =][= + (set! cfg-file-name (get "homerc")) + (set! env-var-list (string-append env-var-list + (shellf "echo '%s' | sed 's/^.//;s#/.*##'" cfg-file-name) + ", " )) + =][= + + == "" =][= (set! cfg-file-name "") =][= + + * =][= + (set! cfg-file-name (get "homerc")) =][= + ESAC =][= + +ENDDEF set-home-rc-vars + +@c = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =][= + +DEFINE emit-multiple-rc =] +@noindent +@code{libopts} will search in [= + + (define explain-pkgdatadir #f) + (define env-var-list "") + rc-count =] places for configuration files: +@itemize @bullet[= +FOR homerc =][= + INVOKE set-home-rc-vars =][= + (if (> (string-length cfg-file-name) 0) + (sprintf "\n@item\n%s" cfg-file-name )) + =][= + +ENDFOR homerc =] +@end itemize[= + (if explain-pkgdatadir (ag-fprintf 0 +"\nThe value for @code{$(pkgdatadir)} is recorded at package configure time +and replaced by @file{libopts} when @file{%s} runs." program-name)) + +(if (> (string-length env-var-list) 1) + (shell (string-append +"list='@code{'`echo '" env-var-list "' | \ + sed -e 's#, $##' \ + -e 's#, #}, @code{#g' \ + -e 's#, \\([^ ][^ ]*\\)$#, and \\1#'`\\} +echo +echo 'The environment variables' ${list} +echo 'are expanded and replaced when @file{" program-name "} runs.'" +)) ) =] +For any of these that are plain files, they are simply processed. +For any that are directories, then a file named @file{[= + (if (exist? "rcfile") (get "rcfile") + (string-append "." program-name "rc"))=]} is searched for +within that directory and processed. +[= + +ENDDEF emit-multiple-rc + +@c = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =][= + +DEFINE emit-one-rc-dir =] +@noindent +@code{libopts} will search in [= + (define env-var-list "") + (define explain-pkgdatadir #f)=][= + INVOKE set-home-rc-vars + +=]@file{[=(. cfg-file-name) =]} for configuration (option) data.[= + IF (. explain-pkgdatadir) =] +The value for @code{$(pkgdatadir)} is recorded at package configure time +and replaced by @file{libopts} when @file{[=prog-name=]} runs. +[=ENDIF=][= +(if (> (string-length env-var-list) 1) + (sprintf +"\nThe environment variable @code{%s} is expanded and replaced when +the program runs" env-var-list)) =] +If this is a plain file, it is simply processed. +If it is a directory, then a file named @file{[= +(if (exist? "rcfile") (get "rcfile") + (string-append "." program-name "rc")) +=]} is searched for within that directory. +[= + +ENDDEF emit-one-rc-dir + +@c = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =][= + +DEFINE emit-rc-file-info =] +[= + + IF (define rc-count (count "homerc")) + (define cfg-file-name "") + (> rc-count 1) =][= + + INVOKE emit-multiple-rc =][= + + ELIF (> (string-length (get "homerc")) 1) + =][= + INVOKE emit-one-rc-dir =][= + ENDIF (> rc-count 1) + +=] +Configuration files may be in a wide variety of formats. +The basic format is an option name followed by a value (argument) on the +same line. Values may be separated from the option name with a colon, +equal sign or simply white space. Values may be continued across multiple +lines by escaping the newline with a backslash. + +Multiple programs may also share the same initialization file. +Common options are collected at the top, followed by program specific +segments. The segments are separated by lines like: +@example +[[=(. UP-PROG-NAME)=]] +@end example +@noindent +or by +@example + +@end example +@noindent +Do not mix these styles within one configuration file. + +Compound values and carefully constructed string values may also be +specified using XML syntax: +@example + + ...<...>... + +@end example +@noindent +yielding an @code{option-name.sub-opt} string value of +@example +"...<...>..." +@end example +@code{AutoOpts} does not track suboptions. You simply note that it is a +hierarchicly valued option. @code{AutoOpts} does provide a means for searching +the associated name/value pair list (see: optionFindValue).[= + +ENDDEF emit-rc-file-info + +@c = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =][= + +DEFINE emit-presets =] + +[= + (ag-fprintf "menu" menu-entry-fmt "config::" + (string-append "presetting/configuring " down-prog-name) ) + + (print-node "config" + (string-append "presetting/configuring " program-name) ) =] + +Any option that is not marked as @i{not presettable} may be preset by +loading values from [= + +IF + + (if home-rc-files (emit + "configuration (\"rc\" or \"ini\") files")) + + environ-init + + =][= + (if home-rc-files (emit ", and values from ")) + =]environment variables named @code{[=(. UP-PROG-NAME)=]} and @code{[= +(. UP-PROG-NAME)=]_}. @code{} must be one of +the options listed above in upper case and segmented with underscores. +The @code{[=(. UP-PROG-NAME)=]} variable will be tokenized and parsed like +the command line. The remaining variables are tested for existence and their +values are treated like option arguments[= + ENDIF have environment inits =]. +[= + + IF (. home-rc-files) =][= + INVOKE emit-rc-file-info =][= + ENDIF home-rc-files =] + +The command line options relating to configuration and/or usage help are: +[= + +IF (exist? "version") =] +@[= (. head-level) =] version[= (flag-string "version-value" "v") =] + +Print the program version to standard out, optionally with licensing +information, then exit 0. The optional argument specifies how much licensing +detail to provide. The default is to print [= +(if (exist? "gnu-usage") + "the license name with the version" + "just the version") +=]. The licensing information may be selected with an option argument. +Only the first letter of the argument is examined: + +@table @samp +@item version +Only print the version.[= +(if (not (exist? "gnu-usage")) " This is the default.")=] +@item copyright +Name the copyright usage licensing terms.[= +(if (exist? "gnu-usage") " This is the default.")=] +@item verbose +Print the full copyright usage licensing terms. +@end table +[= +ENDIF version =][= + +IF (exist? "usage-opt") =] +@[= (. head-level) =] usage[= (flag-string "usage-value" "u") =] + +Print abbreviated usage to standard out, then exit 0. +[= +ENDIF usage-opt =][= + +IF (exist? "vendor-opt") =] +@[= (. head-level) =] vendor-option (-W) + +Options that do not have flag values specified must be specified with +@code{-W} and the long option name. That long name is the argument to +this option. Any options so named that require an argument must have +that argument attached to the option name either with quoting or an +equal sign. +[= +ENDIF vendor-opt =][= + +IF (exist? "resettable") =] +@[= (. head-level) =] reset-option[= (flag-string "reset-value" "R") =] + +Resets the specified option to the compiled-in initial state. +This will undo anything that may have been set by configuration files. +The option argument may be either the option flag character or its long name. +[= +ENDIF resettable =][= + +IF (exist? "home-rc") =][= + IF (not (exist? "disable-save")) =] +@[= (. head-level) =] save-opts[= (flag-string "save-opts-value" ">") =] + +Saves the final, configured option state to the specified file (the optional +option argument). If no file is specified, then it will be saved to the +highest priority (last named) @file{rc-file} in the search list. +The command will exit after updating this file. +[= + ENDIF disable-save =][= + + IF (not (exist? "disable-load")) =] +@[= (. head-level) =] load-opts[= (flag-string "load-opts-value" "<") =] + +Loads the named configuration file. +[= + ENDIF disable-load =][= +ENDIF home-rc =][= + +ENDDEF emit-presets + +@c = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =][= + +DEFINE header \=] +\input texinfo +@c -*-texinfo-*- +@c %**start of header +@setfilename [= (string-append down-prog-name ".info") =] +@settitle [= (sprintf (if (exist? "package") "%2$s - %1$s" "%s") + (get "package") (get "prog-title")) =] +@c %**end of header +@setchapternewpage off +@titlepage +@sp 10 +@comment The title is printed in a large font. +@center @titlefont{Sample Title} + +@c The following two commands start the copyright page. +@page +@vskip 0pt plus 1filll +[= (name-copyright) =][= +IF (exist? "copyright.type") =] +[= (license-full (get "copyright.type") program-name "" + (get "copyright.owner" (get "copyright.author" "")) + (get "copyright.date") ) =][= +ENDIF =] +@end titlepage +@node Top, [= prog-name =] usage, , (dir) +@top [= prog-title =] +[= + +ENDDEF header + +@c = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =][= + +DEFINE emit-usage-opt =][= + + (define label-str (string-append + program-name " help/usage (@option{" help-opt "})")) + (ag-fprintf "menu" menu-entry-fmt "usage::" label-str) + (sprintf node-fmt "usage" label-str) =] +@cindex [=(. down-prog-name)=] help + +This is the automatically generated usage text for [= prog-name =]. + +The text printed is the same whether selected with the @code{help} option +(@option{[= (. help-opt) =]}) or the @code{more-help} option (@option{[= +(. more-help-opt) =]}). @code{more-help} will print +the usage text by passing it through a pager program. +@code{more-help} is disabled on platforms without a working +@code{fork(2)} function. The @code{PAGER} environment variable is +used to select the program, defaulting to @file{more}. Both will exit +with a status code of 0. + +@exampleindent 0 +@example +[= (out-push-new) =] +prog_name=[= (. program-name) =] +PROG=./${prog_name} +test -f ${PROG} || { + PROG=`echo $PROG | tr '[A-Z]' '[a-z]'` + test -f ${PROG} || PROG=`echo $PROG | tr x_ x-` +} +if [ ! -f ${PROG} ] +then + if [= (string-append program-name " " help-opt) =] > /dev/null 2>&1 + then PROG=`command -v ${prog_name}` + else PROG="echo ${prog_name} is unavailable - no " + fi +fi +${PROG} [=(. help-opt)=] 2>&1 | \ + sed -e "s/Usage: lt-${prog_name} /Usage: ${prog_name} /" \ + -e 's/@/@@/g;s/{/@{/g;s/}/@}/g' \ + -e 's/ / /g' +[= (shell (out-pop #t)) =] +@end example +@exampleindent 4 +[= + +ENDDEF emit-usage-opt + +@c = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =][= + +DEFINE initialization =][= + + ;;# START-BUILDTREE-ISMS + ;; + (shell "CLexe=${AGexe%/agen5/*}/columns/columns + test -x \"${CLexe}\" || { + CLexe=${AGexe%/autogen}/columns + test -x \"${CLexe}\" || die 'columns program is not findable' + }") + +=][= # END-BUILDTREE-ISMS + +(shell "CLexe=`echo ${AGexe} | sed 's@/autogen@/columns@'` + test -x \"${CLexe}\" || CLexe=`which columns`") + +# END-INSTALL-ONLY-CODE =][= + + ;; divert-convert divert text for conversion to .texi format + ;; convert-divert convert the diversion done with divert-convert + ;; + (define divert-convert (lambda (diversion-type) (begin + (set! was-diverted + (not (or (== diversion-type "texi") (== diversion-type "")))) + (if was-diverted (begin + (set! cvt-script + (find-file (string-append diversion-type "2texi"))) + (if (not (defined? 'cvt-script)) + (error (sprintf "unknown source format type: %s" + diversion-type)) ) + (out-push-new) )) ))) + + (define heredoc-marker "_Unlikely_Here_Doc_Marker_\n") + (define convert-divert (lambda () + (if was-diverted (shell (string-append + cvt-script "<<\\" heredoc-marker (out-pop #t) "\n" heredoc-marker + )) ))) + + (define was-diverted #f) + (define diversion-type "") + (define cvt-script "") + (define tmp-str "") + + (define name-copyright (lambda () + (if (exist? "copyright") + (string-append "\nThis software is released under " + (license-name (get "copyright.type" "an unknown copyright")) + "." ) ) )) + + (make-tmp-dir) + (define program-name (get "prog-name")) + (define down-prog-name (string-downcase program-name)) + (define UP-PROG-NAME (string-upcase program-name)) + (shellf "export AG_DEF_PROG_NAME=%s" program-name) + (define doc-level (getenv "LEVEL")) + (if (not (string? doc-level)) + (set! doc-level "section")) + (define file-name (string-append down-prog-name ".texi")) + (define coded-prog-name (string-append "@code{" down-prog-name "}")) + + (define replace-prog-name (lambda (nm) + (string-substitute (get nm) down-prog-name coded-prog-name ) )) + + (define have-doc-options (exist? "flag.documentation")) + (define print-menu #t) + (define do-doc-nodes #f) + (define menu-entry-fmt (string-append + "* " down-prog-name " %-24s %s\n")) + (define emit-menu-entry (lambda (is-doc) (not is-doc))) + (if have-doc-options + (set! emit-menu-entry (lambda (is-doc) is-doc)) ) + (define chk-flag-val (exist? "flag.value")) + (define flag-string (lambda (v-nm v-df) (if (not chk-flag-val) "" + (string-append " (-" + (if (exist? v-nm) (get v-nm) v-df) + ")") ))) + + (define help-opt "") + (if (exist? "long-opts") + (set! help-opt "--help") + (if (not (exist? "flag.value")) + (set! help-opt "help") + (if (not (exist? "help-value")) + (set! help-opt "-?") + (begin + (set! tmp-str (get "help-value")) + (if (> (string-length tmp-str) 0) + (set! help-opt (string-append "-" tmp-str)) + (set! help-opt "--help") + ) ) + ))) + + (define more-help-opt "") + (if (exist? "long-opts") + (set! more-help-opt "--more-help") + (if (not (exist? "flag.value")) + (set! more-help-opt "more-help") + (if (not (exist? "more-help-value")) + (set! more-help-opt "-!") + (begin + (set! tmp-str (get "more-help-value")) + (if (> (string-length tmp-str) 0) + (set! more-help-opt (string-append "-" tmp-str)) + (set! more-help-opt "--more-help") + ) ) + ))) + + =][= + + CASE (. doc-level) =][= + == document =][= INVOKE header =][= + (define sub-level "chapter") + (define head-level "heading") =][= + == chapter =][= + (define sub-level "section") + (define head-level "subheading") =][= + == section =][= + (define sub-level "subsection") + (define head-level "subsubheading") =][= + == subsection =][= + (define sub-level "subsubsection") + (define head-level "subsubheading") =][= + + * =][=(error (sprintf "invalid doc level: %s\n" doc-level)) =][= + + ESAC doc level =][= + + (define node-fmt (string-append + "\n@node " down-prog-name " %s\n@" sub-level " %s")) + (define print-node (lambda (a b) (ag-fprintf 0 node-fmt a b) )) + + (define opt-node-fmt (if have-doc-options + (string-append "\n@" head-level + " %2$s.\n@anchor{" down-prog-name " %1$s}") + node-fmt + )) + + (define exit-sts-fmt "\n\n@node %1$s %2$s\n@%3$s %1$s %2$s\n") + (if (not (== doc-level "document")) + (set! file-name (string-append "invoke-" file-name)) ) + + (out-move file-name) + + (out-push-new (string-substitute (out-name) ".texi" ".menu")) + + (ag-fprintf 0 "* %-32s Invoking %s\n" + (string-append program-name " Invocation::") + program-name ) + + (out-pop) + +\=] +@node [= prog-name =] Invocation +@[=(. doc-level) =] Invoking [= prog-name =] +@pindex [= prog-name =] +@cindex [= prog-title =][= + + FOR concept =] +@cindex [= concept =][= + ENDFOR + +=] +@ignore +[= + +(dne "# " "# ") + +=] +@end ignore +[= +(define rep-string "") +(define do-post-proc #f) +(define post-proc-file "") +(define raw-doc-file "") +(define post-proc-commands "") =][= + +FOR doc-sub =][= + (define field-name (get "sub-type" "texi")) + (if (~~ "texi" field-name) (begin + (set! do-post-proc #t) + (set! field-name (get "sub-name")) + (set! rep-string (string-append "<<" field-name ">>")) + (set! post-proc-commands (string-append post-proc-commands + (string-substitute (get "sub-text") rep-string (get field-name)) + "\n" )) + ) ) =][= + +ENDFOR doc-sub =][= + +(if (> (string-length post-proc-commands) 1) (begin + (set! post-proc-file (string-append tmp-dir "/post-proc-cmds")) + (out-push-new post-proc-file) + (emit post-proc-commands) + (out-pop) + (set! raw-doc-file (string-append tmp-dir "/raw-doc")) + (out-push-new raw-doc-file) +) ) + +=][= + +ENDDEF initialization + +@c agtexi-cmd.tpl ends here =] diff --git a/autoopts/tpl/agtexi-file.tpl b/autoopts/tpl/agtexi-file.tpl new file mode 100644 index 0000000..eeaaf37 --- /dev/null +++ b/autoopts/tpl/agtexi-file.tpl @@ -0,0 +1,327 @@ +[= AutoGen5 template -*- Mode: texinfo -*- + +texi + +# Documentation template +# +# This file is part of AutoOpts, a companion to AutoGen. +# AutoOpts is free software. +# AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +# +# AutoOpts is available under any one of two licenses. The license +# in use must be one of these two and the choice is under the control +# of the user of the license. +# +# The GNU Lesser General Public License, version 3 or later +# See the files "COPYING.lgplv3" and "COPYING.gplv3" +# +# The Modified Berkeley Software Distribution License +# See the file "COPYING.mbsd" +# +# These files have the following sha256 sums: +# +# 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +# 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +# 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + +=][= + +INVOKE initialization =][= + +(out-push-new (string-substitute (out-name) ".texi" ".menu")) + +(ag-fprintf 0 "* %-32s Notes about %s\n" + (string-append program-name " Notes::") + program-name ) + +(out-pop) +(if (exist? "explain") + (emit (string-append "\n" (get "explain") "\n")) ) +(set! tmp-str (get "option-doc-format" "texi")) +(divert-convert tmp-str) + +=][= + +IF (match-value? == "doc-section.ds-type" "DESCRIPTION") =][= + + FOR doc-section =][= + IF (== (get "ds-type") "DESCRIPTION") =][= + (define cvt-fn (get "ds-format" "texi")) + (if (not (== cvt-fn "texi")) + (divert-convert cvt-fn) ) =][= + (emit (string-append "\n" (get "ds-text") "\n")) + =][= + BREAK =][= + + ENDIF =][= + ENDFOR =][= + +ELSE =][= + +(join "\n\n" + (if (exist? "prog-info-descrip") + (stack "prog-info-descrip") + (if (exist? "prog-man-descrip") + (stack "prog-man-descrip") + (if (exist? "prog-descrip") + (stack "prog-descrip") + (stack "detail") +) ) ) ) =][= + +ENDIF =][= + +(convert-divert) =] + +This [=(string-downcase doc-level)=] was generated by @strong{AutoGen}, +using the @code{agtexi-cmd} template and the option descriptions for the [=(. +coded-prog-name)=] program.[= (name-copyright) =] + +@menu +[= + (out-push-new) (out-suspend "menu") + (out-push-new) + (define label-str (string-append + program-name " help/usage Something")) + =][=# + +@c = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =][= + +FOR flag =][= + + (set! opt-name (string-tr! (get "name") optname-from optname-to)) + (if (exist? "documentation") + (begin + (set! label-str (string-append opt-name " options")) + (ag-fprintf "menu" menu-entry-fmt + (string-append opt-name ":: ") label-str) + (print-node opt-name label-str) + (ag-fprintf 0 "\n%s." (get "descrip")) + (set! tmp-str (get "documentation")) + (if (> (string-length tmp-str) 1) + (ag-fprintf 0 "\n%s" tmp-str)) + ) + (begin + (set! tmp-str (get "doc" invalid-doc)) + (if (< 0 (string-length tmp-str)) (begin + (set! label-str (string-append opt-name " option" + (if (exist? "value") + (string-append " (-" (get "value") ")") + "" ) )) + (if have-doc-options + (ag-fprintf 0 opt-node-fmt opt-name label-str) + (begin + (ag-fprintf "menu" menu-entry-fmt + (string-append opt-name ":: ") label-str) + (print-node opt-name label-str) + ) + ) + (ag-fprintf 0 "\n@cindex %s-%s" down-prog-name opt-name) + ) ) + ) + ) =][= + + IF (and (not (exist? "documentation")) + (< 0 (string-length tmp-str)) ) + =][= + ENDIF =][= + +ENDFOR flag =][= + +INVOKE emit-doc-sections =][= + +(out-suspend "opt-desc") +(out-resume "menu") +(emit (out-pop #t)) +(emit "@end menu\n") +(out-resume "opt-desc") +(out-pop #t) =][=# + +@c = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =][= + +DEFINE emit-doc-sections =][= + +FOR doc-section =][= + + IF (define opt-name (string-capitalize! (get "ds-type"))) + (or (== opt-name "Exit Status") + (== opt-name "Description") + (exist? "omit-texi")) =][= + CONTINUE =][= + ENDIF =][= + + (ag-fprintf "menu" menu-entry-fmt (string-append opt-name "::") opt-name) + =][= + (set! label-str (string-append + down-prog-name " " (string-capitalize opt-name))) + =][= + (print-node opt-name label-str) + =][= + (define cvt-fn (get "ds-format" "texi")) + =][= + (if (not (== cvt-fn "texi")) + (divert-convert cvt-fn) ) =][= + (emit (string-append "\n" (get "ds-text") "\n")) + (convert-divert) =][= + +ENDFOR doc-section =][= + +ENDDEF emit-doc-sections + +@c = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =][= + +DEFINE header \=] +\input texinfo +@c -*-texinfo-*- +@c %**start of header +@setfilename [= (string-append down-prog-name ".info") =] +@settitle [= (sprintf (if (exist? "package") "%2$s - %1$s" "%s") + (get "package") (get "prog-title")) =] +@c %**end of header +@setchapternewpage off +@titlepage +@sp 10 +@comment The title is printed in a large font. +@center @titlefont{Sample Title} + +@c The following two commands start the copyright page. +@page +@vskip 0pt plus 1filll +[= (name-copyright) =][= +IF (exist? "copyright.type") =] +[= (license-full (get "copyright.type") program-name "" + (get "copyright.owner" (get "copyright.author" "")) + (get "copyright.date") ) =][= +ENDIF =] +@end titlepage +@node Top, [= prog-name =] usage, , (dir) +@top [= prog-title =] +[= + +ENDDEF header + +@c = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =][= + +DEFINE initialization =][= + + ;; divert-convert divert text for conversion to .texi format + ;; convert-divert convert the diversion done with divert-convert + ;; + (define divert-convert (lambda (diversion-type) (begin + (set! was-diverted + (not (or (== diversion-type "texi") (== diversion-type "")))) + (if was-diverted (begin + (set! cvt-script + (find-file (string-append diversion-type "2texi"))) + (if (not (defined? 'cvt-script)) + (error (sprintf "unknown source format type: %s" + diversion-type)) ) + (out-push-new) )) ))) + + (define heredoc-marker "_Unlikely_Here_Doc_Marker_\n") + (define convert-divert (lambda () + (if was-diverted (shell (string-append + cvt-script "<<\\" heredoc-marker (out-pop #t) "\n" heredoc-marker + )) ))) + + (define was-diverted #f) + (define diversion-type "") + (define cvt-script "") + (define tmp-str "") + + (define name-copyright (lambda () + (if (exist? "copyright") + (string-append "\nThis software is released under " + (license-name (get "copyright.type" "an unknown copyright")) + "." ) ) )) + + (make-tmp-dir) + (define program-name (get "prog-name")) + (define down-prog-name (string-downcase program-name)) + (define UP-PROG-NAME (string-upcase program-name)) + (shell "export AG_DEF_PROG_NAME=" program-name + "\nCLexe=`echo ${AGexe} | sed 's@/autogen@/columns@'`") + + (define doc-level (getenv "LEVEL")) + (if (not (string? doc-level)) + (set! doc-level "section")) + (define file-name (string-append down-prog-name ".texi")) + (define coded-prog-name (string-append "@code{" down-prog-name "}")) + + (define replace-prog-name (lambda (nm) + (string-substitute (get nm) down-prog-name coded-prog-name ) )) + + (define have-doc-options (exist? "flag.documentation")) + (define print-menu #t) + (define do-doc-nodes #f) + (define menu-entry-fmt (string-append + "* " down-prog-name " %-24s %s\n")) + (define emit-menu-entry (lambda (is-doc) (not is-doc))) + (if have-doc-options + (set! emit-menu-entry (lambda (is-doc) is-doc)) ) + (define chk-flag-val (exist? "flag.value")) + (define flag-string (lambda (v-nm v-df) (if (not chk-flag-val) "" + (string-append " (-" + (if (exist? v-nm) (get v-nm) v-df) + ")") ))) + + =][= + + CASE (. doc-level) =][= + == document =][= INVOKE header =][= + (define sub-level "chapter") + (define head-level "heading") =][= + == chapter =][= + (define sub-level "section") + (define head-level "subheading") =][= + == section =][= + (define sub-level "subsection") + (define head-level "subsubheading") =][= + == subsection =][= + (define sub-level "subsubsection") + (define head-level "subsubheading") =][= + + * =][=(error (sprintf "invalid doc level: %s\n" doc-level)) =][= + + ESAC doc level =][= + + (define node-fmt (string-append + "\n@node " down-prog-name " %s\n@" sub-level " %s")) + (define print-node (lambda (a b) (ag-fprintf 0 node-fmt a b) )) + + (define opt-node-fmt (if have-doc-options + (string-append "\n@" head-level + " %2$s.\n@anchor{" down-prog-name " %1$s}") + node-fmt + )) + + (define exit-sts-fmt "\n\n@node %1$s %2$s\n@%3$s %1$s %2$s\n") + =][= + + IF (not (== doc-level "document")) =][= + (set! file-name (string-append "invoke-" file-name)) + \=] +@node [= prog-name =] Notes +@[=(. doc-level) =] Notes about [= prog-name =] +@pindex [= prog-name =] +@cindex [= prog-title =][= + +FOR concept =] +@cindex [= concept =][= +ENDFOR =][= + + ENDIF document component + +=] +@ignore +[= + +(out-move file-name) +(dne "# " "# ") + +=] +@end ignore +[= + +ENDDEF initialization + +@c agtexi-cmd.tpl ends here =] diff --git a/autoopts/tpl/bits.tpl b/autoopts/tpl/bits.tpl new file mode 100644 index 0000000..a272423 --- /dev/null +++ b/autoopts/tpl/bits.tpl @@ -0,0 +1,717 @@ +[= AutoGen5 Template -*- Mode: C -*- + +h c + +## Author: Bruce Korb +## +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + + (define base-name "") + (define BASE-NAME "") + (define element-type "") + (define init-done #f) + (define is-64-bit #f) + (define is-array #f) + (define name-width 0) + (define desc-width 0) + (define bit-list "") + (define bit-name "") + (define tmp-name "") + + (define id-name (lambda (sfx) + (string-append + prefix "_" (string-upcase! (string->c-name! (get "b-name"))) sfx + ) )) + + (define mask-name (lambda (sfx) + (string-append + prefix "_" (string-upcase! (string->c-name! (get "m-name"))) sfx + ) )) + +=][= + +INVOKE preamble + +=][= + +CASE (suffix) =][= + +# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =][= + +== h + +=] +[= + (shell "sedcmd='s/$/_val} +/;s/^/${/'") + (make-header-guard "bit_mask") =] +#include [= (if (exist? "stdint-hdr") + (string-append "\"" (get "stdint-hdr") "\"") + "" ) =] + +typedef [= + + (define type-name (string-append base-name "_bits_t")) + (define tmp + (if (< (high-lim "bit") 32) (begin + (set! element-type "uint32_t") + "uint32_t %s_bits_t") + (if (< (high-lim "bit") 64) (begin + (set! element-type "uint64_t") + (set! is-64-bit #t) + "uint64_t %s_bits_t" ) + (begin + (set! element-type "uint32_t") + (set! is-array #t) + (sprintf "uint32_t %%s_bits_t[%s]" + (shellf "mask_ct=`calc '( %d + 32 ) / 32'` ; echo $mask_ct" + (high-lim "bit")) ) )) )) + + (sprintf tmp base-name) + +=]; +typedef enum {[= + +FOR bit =][= + + (set! bit-name (string->c-name! (get "b-name"))) + (shellf + "%1$s_val=`calc '2 ^ %2$d'`\nmask_val=`calc \"${mask_val} + ${%1$s_val}\"`" + bit-name (for-index)) + + (set! tmp (string-length bit-name)) + (if (> tmp name-width) + (set! name-width tmp)) + (set! tmp (string-length (get "b-what"))) + (if (> tmp desc-width) + (set! desc-width tmp)) =][= + +ENDFOR bit =][= + + (define define-width (+ name-width 6 (string-length prefix))) + (define enum-fmt (sprintf "\n %%-%ds =%%4d%%s /* %%-%ds */" + define-width desc-width)) + +=][= + +FOR bit =][= + + (sprintf enum-fmt (id-name "_ID") (for-index) + (if (last-for?) " " ",") (get "b-what")) =][= +ENDFOR bit + += = = = = = = = = = = = = = = = =][= + +IF (ag-fprintf 0 "\n} %s_enum_t;\n" base-name) + (define def-fmt (sprintf "\n#define %%-%ds " define-width)) + + (< (high-lim "bit") 32) =][= + + INVOKE emit-word-macro one = 'U' mask-fmt = "%08XU" =][= + +ELIF (< (high-lim "bit") 64) =][= + + INVOKE emit-word-macro one = 'ULL' mask-fmt = "%016XULL" =][= + +ELSE more than 64 bits =][= + + INVOKE emit-multi-macros =][= + +ENDIF how many bits =][= + +IF (if (exist? "extra-defs") + (emit (string-append "\n\n" (get "extra-defs") "\n"))) + + (not (exist? "no-code")) =] +/* + * Return a string containing the names of the bits set. + */ +extern char * +[= (. base-name) =]_names([= (. type-name) =] bits); + +#define INV_[= (. BASE-NAME) =] -1 +#define DUP_[= (. BASE-NAME) =] -2 + +/* + * Set the bits in "bits" as specified by the input string "str". + * If any names are untranslatable (not in the name list or are + * ambiguous in that they match the initial portion of more than + * one entry), it will return -1 or -2, respectively. + * Otherwise, it returns the number of bits set in "bits". + */ +extern int +[= (. base-name) =]_bits( + [= (. type-name) =] * const bits, + char const * str); +[= ENDIF =] +#endif /* [= (. header-guard) =] */[= + +# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =][= + +== c + + +=] +#include +#include +#include +#include +[= + + (if (exist? "no-code") (out-delete)) + (ag-fprintf 0 "#include \"%s\"\n" header-file) + (string-table-new "nm") + (string-table-add "nm" "* INVALID *") + (define ix 0) + (define offset-list "") + (define sorted-off "") =][= + +FOR bit (for-from 0) (for-by 1) =][= + + (if (exist? "b-name") + (begin + (set! tmp (string-downcase! (string->c-name! (get "b-name")))) + (set! ix (string-table-add "nm" tmp)) + (set! offset-list (string-append offset-list (sprintf "%d\n" ix))) + (set! sorted-off (string-append sorted-off + (sprintf "%-40s { %3d, %3d }\n" tmp ix (for-index)))) + ) + + (set! offset-list (string-append offset-list "0\n" )) + ) =][= + +ENDFOR bit =][= + + (emit-string-table "nm") + (sprintf "\nchar *\n%1$s_names(%1$s_bits_t bits)\n{" base-name) +=] + static int const nm_ixa[ [= (+ 1 (high-lim "bit")) =] ] = { +[= + + (define string-table-size (lambda (st-name) + (hash-ref (hash-ref stt-table st-name) "current-index") )) + + (emit (shellf "columns -I8 -S, --spread=1 <<_EOF_\n%s_EOF_" offset-list)) +=] }; + + static char buf[ [= (+ (string-table-size "nm") (count "bit")) =] ]; + char * buf_p = buf; + int ix = 0; +[= + +IF (< (high-lim "bit") 64) + +=] + while (bits != 0) { + if ((bits & 1) != 0) { + char const * p = nm + nm_ixa[ix]; + + if (buf_p > buf) { + *(buf_p++) = ','; + *(buf_p++) = ' '; + } + + if (p == nm) { + Oops: + strncpy(buf_p, nm, sizeof (buf) - (buf_p - buf)); + break; + } + + while ((*(buf_p++) = *(p++)) != '\0') ; + buf_p--; + } + bits >>= 1; + if (++ix > [= (high-lim "bit") =]) { + if (bits != 0) + goto Oops; + break; + } + }[= + +ELSE more than 64: + +=] + int bix = 0; + int bit_lim = 32; + do { + uint32_t bit_word = bits[bix]; + int ix = bix * 32; + + while (bit_word != 0) { + if ((bit_word & 1) != 0) { + char const * p = nm + nm_ixa[ix]; + + if (buf_p > buf) { + *(buf_p++) = ','; + *(buf_p++) = ' '; + } + + if (p == nm) { + Oops: + strncpy(buf_p, nm, sizeof (buf) - (buf_p - buf)); + break; + } + + while ((*(buf_p++) = *(p++)) != '\0') ; + buf_p--; + } + bit_word >>= 1; + if (++ix > [= (high-lim "bit") =]) { + if (bit_word != 0) + goto Oops; + return buf; + } + } + } while (++bix < [= `echo $mask_ct` =]);[= + +ENDIF + +=] + + return buf; +} + +static int +str_to_id(char const * str, char const ** p_str) +{ + static char nm_buf[ [= (+ 1 name-width) =] ]; + int res = -1; + int part = 1; + size_t len = 0; + + /* + * Extract the lower cased name with '-' replaced with '_' + */ + { + char * p = nm_buf; + + for (;;) { + char ch = *(str++); + switch (ch) { + case '-': + ch = '_'; + /* FALLTHROUGH */ + + case '_': + break; + + default: + if (isupper(ch)) + ch = _tolower(ch); + else if (! isalnum(ch)) { + str--; + goto have_name; + } + } + + if (++len > [= (. name-width) =]) + return -1; + + *(p++) = ch; + } have_name :; + + *p = '\0'; + len = p - nm_buf; + if (len == 0) + return INV_[= (. BASE-NAME) =]; + } + + /* + * Search the alphabetized table + */ + do { + static struct { + unsigned short const nm_off, val; + } nm_ixa[ [= (count "bit") =] ] = { +[= + (shellf (string-append + "(sort | sed 's/.*{/{/' | columns -I8 -S, --spread=1)<<_EOF_\n" + sorted-off "_EOF_" + )) +=] }; + + int av; + int lo = 0; + int hi = [= (- (count "bit") 1) =]; + + /* + * Binary search for first match + */ + do { + char const * p; + int df; + + av = (lo + hi) / 2; + p = nm + nm_ixa[av].nm_off; + df = strncmp(p, nm_buf, len); + + if (df == 0) { + res = nm_ixa[av].val; + if (p[len] == '\0') + part = 0; + + break; + } + + if (df > 0) + hi = av - 1; + else lo = av + 1; + + } while (lo <= hi); + + if (res < 0) + return INV_[= (. BASE-NAME) =]; + + if (part == 0) + break; + + /* + * Partial match. Look for an earlier match. One may be a full match. + */ + lo = av; + while (lo > 0) { + char const * p = nm + nm_ixa[--lo].nm_off; + int df = strncmp(p, nm_buf, len); + if (df != 0) + break; + if (p[len] == '\0') { + part = 0; + res = nm_ixa[lo].val; + break; + } + part++; + } + + if (part > 1) { + *p_str = nm_buf; + return DUP_[= (. BASE-NAME) =]; + } + + if ((part == 0) || (av == [= (- (count "bit") 1) =])) + break; + + /* + * Look for a successor match. No full match possible. + */ + { + char const * p = nm + nm_ixa[av+1].nm_off; + int df = strncmp(p, nm_buf, len); + if (df == 0) { + *p_str = nm_buf; + return DUP_[= (. BASE-NAME) =]; + } + } + } while (0); + + while (isspace(*str)) str++; + *p_str = str; + return res; +} + +int +[= + +# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =][= + +(. base-name) =]_bits( + [= (. type-name) =] * const bits[= (if is-array "_p")=], + char const * str) +{[= + IF (. is-array) =] + [= (. element-type) =] * const bits = VOIDP(bits_p);[= + ENDIF =] + int ct = 0; + int res = 0; + + memset(bits, '\0', sizeof([= (. type-name) =])); + + another_bit: + + while (isspace(*str) || (*str == ',')) str++; + + for (;;) { + if (isdigit(*str)) { + [=(. element-type) =] num = + ([=(. element-type) =])strtoull(str, &str, 0); + *bits |= num; + ct += (num != 0); + + } else if (isalpha(*str)) { + res = str_to_id(str, &str); + if (res < 0) { + if (res == DUP_[= (. BASE-NAME) =]) + fprintf(stderr, "duplicate matches for '%s'\n", str); + goto fail_exit; + } + ct++; +[= + + IF (. is-array) =] + bits[res/32] |= 1 << (res & 0x1F);[= + ELIF (. is-64-bit) =] + *bits |= 1ULL << res;[= + ELSE =] + *bits |= 1 << res;[= + ENDIF + +=] + } else switch (*str) { + case ',': + goto another_bit; + + case '\0': + return ct; + + default: + res = INV_[= (. BASE-NAME) =]; + goto fail_exit; + } + } + + fail_exit: + memset(bits, '\0', sizeof(*bits)); + return res; +} + +#ifdef TEST_BITS + +static char const bit_names[] = +[= +(kr-string (string-append "The known " base-name " bit names are:\n" + (shellf (string-append + "(sort | columns -I2 --spread=1\n) <<_EOF_\n" + (string-downcase! (join "\n" (stack "bit.b-name"))) + "\n_EOF_")) + "\n" )) + =]; + +int +main(int argc, char** argv) +{ + static char const fmt_z[] = "'%s' yields: %s\n"; + [= (. type-name) =] bts; + if (argc != 2) { + fputs(bit_names, stderr); + return 1; + } + { + int ct = [= (. base-name) =]_bits(&bts, argv[1]); + if (ct <= 0) { + char const * pz; + switch (ct) { + case 0: pz = "no results"; break; + case INV_[= (. BASE-NAME) =]: pz = "invalid name"; break; + case DUP_[= (. BASE-NAME) =]: pz = "multiple match"; break; + } + fprintf(stderr, fmt_z, argv[1], pz); + fputs(bit_names, stderr); + return 1; + } + } + { + char * pz = [= (. base-name) =]_names(bts); + printf(fmt_z, argv[1], pz); + } + return 0; +} +#endif +[= + +ESAC =] +/* end of [= (out-name) =] */ +[=# + += = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =][= + +DEFINE preamble =][= + + (if (not init-done) (begin + + (if (not (exist? "mask-name")) + (error "no defined bit mask name")) + + (shell "calc() { bc <<_EOF_ +$* +_EOF_ +} + mask_val=0") + (set! init-done #t) + (set! base-name (string-downcase! (string->c-name! (get "mask-name")))) + (set! BASE-NAME (string-upcase base-name)) + (set! prefix (string-upcase (string->c-name! + (if (exist? "prefix") (get "prefix") base-name) ))) + ) ) + + (dne " * " "/* ") =] + */ +[= + +ENDDEF preamble + += = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =][= + +DEFINE emit-bit-list =][= + + (if (exist? "b-name") + (set! bit-list (string-append (join "\n" (stack "b-name")) "\n")) + (set! bit-list "") + ) =][= + + FOR m-inc =][= + (set! tmp (string->c-name! (get "m-inc"))) + (set! bit-list (string-append bit-list + (shellf "echo \"${%s}\"" tmp) "\n")) + =][= + ENDFOR m-inc=][= + + (set! bit-list (string->c-name! bit-list)) + (shellf "%s='%s'" (string->c-name! (get "m-name")) bit-list) + + (emit (shell (string-append + + "(sort -u | columns -I8 --spread=1 -S' |' --format=" prefix "_%s_BIT " + "--line=' \\'\n) <<\\_EOF_\n" + (string-upcase bit-list) + "_EOF_" + + ))) + + (shell (string-append + "sum=`(sort -u | \ + sed -e \"${sedcmd}\"\n) <<\\_EOF_\n" + bit-list + "_EOF_\n`\n" + "sum=`eval calc ${sum} 0`\n" + "printf " + (if (>= (high-lim "bit") 32) + "' \\\\\\n /* 0x%016XULL */\\n'" + (if (>= (high-lim "bit") 16) + "' \\\\\\n /* 0x%08XU */\\n'" + "' \\\\\\n /* 0x%04XU */\\n'" )) + " ${sum}" + )) +=][= + +ENDDEF emit-bit-list + += = = = = = = = = = = = = = = = = = = = =][= + +DEFINE emit-word-macro =][= + + (set! tmp-name (string-upcase! (string-append prefix "_" + (if (exist? "zero-name") (get "zero-name") "NO_BITS") ))) + (sprintf def-fmt tmp-name) =]0[= one =][= + + FOR bit =][= + + (sprintf def-fmt (id-name "_BIT")) =](1[=one=] << [= (id-name "_ID") =])[= + + ENDFOR =][= + + (ag-fprintf 0 def-fmt (string-append BASE-NAME "_MASK")) + (shellf "printf 0x%s ${mask_val}" (get "mask-fmt")) + + =][= + + FOR mask + + =] +[= (sprintf def-fmt (mask-name "_MASK")) =]( \ +[= INVOKE emit-bit-list =] )[= + + ENDFOR mask =][= + + FOR un-mask + + =] +[= (sprintf def-fmt (mask-name "_MASK")) =]([= + (string-append BASE-NAME "_MASK") =] & ~( \ +[= INVOKE emit-bit-list =]))[= + + ENDFOR un-mask=][= + + (if (exist? "defined") (string-append "\n\n" (get "defined"))) + +=][= IF (not (exist? "omit-test-n-set")) =] + +#define SET_[= (. BASE-NAME) =](_m, _b) \ + do { (_m) |= 1[= one =] << _b; } while (0) +#define CLEAR_[= (. BASE-NAME) =](_m, _b) \ + do { (_m) &= ~(1[= one =] << _b); } while (0) +#define TEST_[= (. BASE-NAME) =](_m, _b) (((_m) & (1[= one =] << _b)) != 0) +#define AND_[= (. BASE-NAME) =](_d, _s1, _s2) \ + do { (_d) = (_s1) & (_s2); } while (0) +#define OR_[= (. BASE-NAME) =](_d, _s1, _s2) \ + do { (_d) = (_s1) | (_s2); } while (0) +#define XOR_[= (. BASE-NAME) =](_d, _s1, _s2) \ + do { (_d) = (_s1) ^ (_s2); } while (0) +#define NOT_[= (. BASE-NAME) =](_d, _s) \ + do { (_d) = ~(_s); } while (0) +[= ENDIF omit-test-n-set =][= +ENDDEF emit-word-macro + += = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =][= + +DEFINE emit-loop-macro + +=][= + + (sprintf "#define %5s_%s" (get "mac-name") BASE-NAME) =][= + + CASE op-code =][= + == "~" =](_d, _s)[= (set! tmp one-arg-op)=][= + * =](_d, _s1, _s2)[= (set! tmp two-arg-op)=][= + ESAC op-code =] \ + [= (. iterate) =] \ + [= (sprintf tmp (get "op-code")) =][= + +ENDDEF emit-loop-macro + += = = = = = = = = = = = = = = = = = = =][= + +DEFINE emit-multi-macros + +=][= + +defined + +=][= IF (not (exist? "omit-test-n-set")) =] + +#define SET_[= +(define iterate (sprintf "do { int _ix_ = 0; for (;_ix_ < %s; _ix_++) {" + (shell "echo $mask_ct") )) +(define two-arg-op "(_d)[_ix_] = (_s1)[_ix_] %s (_s2)[_ix_]; } } while (0)") +(define one-arg-op "(_d)[_ix_] = %s(_s)[_ix_]; } } while (0)") + + BASE-NAME =](_m, _b) \ + do { (_m)[(_b)/32] |= 1U << ((_b) % 32); } while (0) +#define CLEAR_[= (. BASE-NAME) =](_m, _b) \ + do { (_m)[(_b)/32] &= ~(1U << ((_b) % 32)); } while (0) +#define TEST_[= (. BASE-NAME) =](_m, _b) \ + (((_m)[(_b)/32] & (1U << ((_b) % 32))) != 0) +[= INVOKE emit-loop-macro op-code = "&" mac-name = AND =] +[= INVOKE emit-loop-macro op-code = "|" mac-name = OR =] +[= INVOKE emit-loop-macro op-code = "^" mac-name = XOR =] +[= INVOKE emit-loop-macro op-code = "~" mac-name = NOT =] +[= ENDIF omit-test-n-set =][= + +ENDDEF emit-multi-macros =][= + +# End of bits.tpl \=] diff --git a/autoopts/tpl/cmd-doc.tlib b/autoopts/tpl/cmd-doc.tlib new file mode 100644 index 0000000..87e17fd --- /dev/null +++ b/autoopts/tpl/cmd-doc.tlib @@ -0,0 +1,1182 @@ +[+: -*- Mode: nroff -*- + + AutoGen5 template man + +# cmd-doc.tlib -- Template for command line man/mdoc pages +# +# This file is part of AutoOpts, a companion to AutoGen. +# AutoOpts is free software. +# Copyright (C) 1992-2018 Bruce Korb - all rights reserved +# +# AutoOpts is available under any one of two licenses. The license +# in use must be one of these two and the choice is under the control +# of the user of the license. +# +# The GNU Lesser General Public License, version 3 or later +# See the files "COPYING.lgplv3" and "COPYING.gplv3" +# +# The Modified Berkeley Software Distribution License +# See the file "COPYING.mbsd" +# +# These files have the following sha256 sums: +# +# 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +# 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +# 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + +# Produce a man page for section 1, 5, 6 or 8 commands. Which is +# selected via: -DMAN_SECTION=n. "n" may have a suffix, if desired. +# These sections have default section names that may be overridden +# with -DSECTIN_NAME=XX, also passed to the autogen invocation. +# +:+][+: + + ;;# START-BUILDTREE-ISMS + ;; + (shell "CLexe=${AGexe%/agen5/*}/columns/columns + test -x \"${CLexe}\" || { + CLexe=${AGexe%/autogen}/columns + test -x \"${CLexe}\" || die 'columns program is not findable' + }") + +:+][+: # END-BUILDTREE-ISMS + +(shell "CLexe=`echo ${AGexe} | sed 's@/autogen@/columns@'` + test -x \"${CLexe}\" || CLexe=`which columns`") + +# END-INSTALL-ONLY-CODE :+][+: + +(define down-prog-name (string-downcase! (get "prog-name"))) +(define UP-PROG-NAME (get-up-name "prog-name")) + +(define command-doc #t) +(define tmp-val (getenv "MAN_SECTION")) +(define man-sect (if (exist? "cmd-section") (get "cmd-section") "1")) +(define file-name "") +(define sect-name "") +(define macro-name "") +(define tmp-str "") +(define fname-line "") +(define use-flags (exist? "flag.value")) +(define named-mode (not (or use-flags (exist? "long-opts") ))) + +(if (defined? 'tmp-val) + (if (string? tmp-val) + (set! man-sect tmp-val))) + +(define section-name + (if (=* man-sect "1") "User Commands" + (if (=* man-sect "5") "File Formats" + (if (=* man-sect "6") "Games" + (if (=* man-sect "8") "System Management" + (error + "the agman-cmd template only produces section 1, 5, 6 and 8 man pages") +))))) +(set! tmp-val (getenv "SECTION_NAME")) +(if (defined? 'tmp-val) (if (string? tmp-val) + (set! section-name tmp-val) )) + +(define package-text "") +(define package+version (and (exist? "package") (exist? "version"))) + +(if (or (exist? "package") (exist? "version")) (begin + (set! package-text (string-append + (get "package") + (if package+version " (" "") + (get "version") + (if package+version ")" "") )) +) ) + +(define name-to-fname (lambda (nm) + (string-tr (string-downcase nm) " " "-") )) + +(define sect-line-fname (lambda () (begin + (out-push-new file-name) + (emit (string-append ".Sh \"" sect-name "\"\n")) + (string-append "mk-" macro-name) ))) + +(make-tmp-dir) +(shell "mkdir $tmp_dir/SEC") +(define home-rc-files (exist? "homerc")) +(define home-rc-text + "\nSee \\fBOPTION PRESETS\\fP for configuration files.") + +(define environ-init (exist? "environrc")) +(define environ-text + "\nSee \\fBOPTION PRESETS\\fP for configuration environment variables.") + +(emit (head-line)) +(dne ".\\\" ") :+] +.Sh NAME +.Nm [+: prog-name :+] +.Nd [+: prog-title :+] +[+: INCLUDE "tpl-config.tlib" :+][+:# + +.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +.\" B U I L D D O C +.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = :+][+: + +DEFINE build-doc :+][+: + +(if (not command-doc) (begin + (set! home-rc-files #f) + (set! home-rc-text "") +) ) :+][+: + +INVOKE doc-sections :+][+: +INVOKE ao-sections :+][+: +INVOKE assemble-sections :+][+: + +ENDDEF build-doc + +.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +.\" A S S E M B L E S E C T I O N S +.\" +.\" Emit the files for each section that was provided, and do conversions +.\" +.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = :+][+: + +DEFINE assemble-sections :+][+: + +(out-push-new) + +:+][+: +#.\" Insert the sections in the prescribed order +#.\" Ensure a newline between them all. We strip blank lines, +#.\" so extra blank lines get removed. +#:+] +{ + cvt_prog='[+: + + (define target-form (if man-page "man" "mdoc")) + (define source-form (get "option-format" "texi")) + (define converter (string-append source-form "2" target-form )) + (set! tmp-str (find-file converter)) + + (if (not (defined? 'tmp-str)) + (error (string-append "cannot locate " converter))) + tmp-str :+]' + cvt_prog=`cd \`dirname "$cvt_prog"\` >/dev/null && pwd + `/`basename "$cvt_prog"` + cd $tmp_dir/SEC + test -x "$cvt_prog" || die "'$cvt_prog' is not executable" + + list='synopsis description options option-presets' + for f in $list + do test -f $f && { + cat $f ; echo + } + done > ../raw-doc + rm -f $list name + + list='implementation-notes environment files examples exit-status errors + compatibility see-also conforming-to history authors copyright bugs + notes' + for f in $list + do test -f $f && { + cat $f ; echo + } + done > ../end-doc + rm -f $list + + cat * ../end-doc >> ../raw-doc +} 2>/dev/null +cd .. +[+: +IF (exist? "doc-sub") :+][+: + (out-push-new (string-append tmp-dir "/doc-secs")) :+][+: + FOR doc-sub :+][+: + + IF (define field-name (get "sub-type" target-form)) + (~~ target-form field-name) :+][+: + + (set! field-name (get "sub-name")) + (define rep-string (string-append "<<" field-name ">>")) + (emit (string-substitute (get "sub-text") rep-string (get field-name))) + "\n" + + :+][+: ENDIF :+][+: + + ENDFOR doc-sub :+][+: + + (out-pop) + (define post-proc-cmd (string-append + (get "doc-sub-cmd" "sed -f %s %s") " | " + egrep-prog " -v '^[ ]*$'")) + (sprintf post-proc-cmd "doc-secs" "raw-doc") + :+][+: +ELSE \:+] +[+:(. egrep-prog):+] -v '^[ ]*$' raw-doc[+: +ENDIF doc-sub exists :+] | $cvt_prog[+: + +(shell (out-pop #t)) + +:+][+: + +ENDDEF assemble-sections + +.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +.\" D O C S E C T I O N S +.\" +.\" Emit the files for each section that was provided. +.\" If multiple sections exist, they get glued together with ".Pp" +.\" between them. +.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = :+][+: + +DEFINE doc-sections :+][+: + +FOR doc-section :+][+: + IF + (define sec-type (string-upcase (get "ds-type"))) + (define sec-name (name-to-fname sec-type)) + (define cvt-fn (find-file (string-append + (get "ds-format" "man") "2mdoc"))) + (if (not (defined? 'cvt-fn)) + (error (sprintf "Cannot locate converter for %s" + (get "ds-format" "man")))) + + (define sec-file (string-append tmp-dir "/SEC/" sec-name)) + (access? sec-file R_OK) :+][+: + (out-push-add sec-file) + (emit ".Pp\n") :+][+: + + ELSE :+][+: CASE + (out-push-new sec-file) + sec-type :+][+: + + == "" :+][+: (error "unnamed doc-section") :+][+: + *==* " " :+].Sh "[+: (. sec-type) :+]"[+: + * :+].Sh [+: (. sec-type) :+][+: + ESAC :+][+: + ENDIF :+] +[+: + + (shell (string-append + "fn='" cvt-fn "'\n" + "test -f ${fn} || die ${fn} not found from $PWD\n" + "export PERL5LIB=`dirname \"$fn\"`\n" + "${fn} <<\\_EndOfDocSection_ || die ${fn} failed in $PWD\n" + (get "ds-text") + "\n_EndOfDocSection_" + )) :+][+: + + CASE (emit "\n") sec-type :+][+: + == FILES :+][+: + (if home-rc-files (emit home-rc-text)) + (set! home-rc-files #f) :+][+: + + == ENVIRONMENT :+][+: + (if environ-init (emit environ-text)) + (set! environ-init #f) :+][+: + ESAC :+][+: + + (out-pop) + :+][+: + +ENDFOR doc-section :+][+: + +ENDDEF doc-sections + +.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +.\" A O S E C T I O N S +.\" +.\" Emit the files for the sections that these templates augment, +.\" replace or conditionally replace +.\" +.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = :+][+: + +DEFINE ao-sections :+][+: + IF (. command-doc) :+][+: + INVOKE cond-section sec = "OPTIONS" mode = "replace" :+][+: + INVOKE cond-section sec = "EXIT STATUS" mode = "insert" :+][+: + + IF (or home-rc-files environ-init) :+][+: + INVOKE cond-section sec = "OPTION PRESETS" mode = "replace" :+][+: + + IF (. home-rc-files) :+][+: + INVOKE cond-section sec = "FILES" mode = "append" :+][+: + ENDIF :+][+: + + IF (. environ-init) :+][+: + INVOKE cond-section sec = "ENVIRONMENT" mode = "append" :+][+: + ENDIF :+][+: + ENDIF :+][+: + + ELSE section 5, not command :+][+: + INVOKE cond-section sec = "FILES" mode = "append" :+][+: + ENDIF section 5/not :+][+: + + INVOKE cond-section sec = "SYNOPSIS" mode = "alt" :+][+: + INVOKE cond-section sec = "DESCRIPTION" mode = "append" :+][+: + INVOKE cond-section sec = "AUTHORS" mode = "alt" :+][+: + INVOKE cond-section sec = "BUGS" mode = "append" :+][+: + INVOKE cond-section sec = "NOTES" mode = "append" :+][+: + +IF (exist? "copyright") :+][+: + INVOKE cond-section sec = "COPYRIGHT" mode = "alt" :+][+: +ENDIF :+][+: + +ENDDEF ao-sections + +.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +.\" C O N D I T I O N A L S E C T I O N +.\" +.\" Figure out what to do for AutoOpts required sections, depending on "mode" +.\" In all cases, if the file does not exist, invoke the "mk" macro to create +.\" a new file. If it does exist, then: +.\" +.\" alt Alternate -- emit no text +.\" replace throw away any pre-existing file. +.\" append invoke the "append" macro to emit additional text +.\" insert save the current contents, replacing the .Sh line with .Pp. +.\" invoke the "mk" macro then emit the saved text +.\" +.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = :+][+: + +DEFINE cond-section :+][+: + + IF + (set! sect-name (string-upcase! (string-substitute + (get "sec") "-" " " ))) + (set! macro-name (string-downcase! (string-substitute + sect-name " " "-" ))) + (set! file-name (string-append tmp-dir "/SEC/" macro-name)) + + (not (access? file-name R_OK)) :+][+: + + INVOKE (sect-line-fname) :+][+: + + ELSE file exists :+][+: + + CASE (get "mode") :+][+: + + == replace :+][+: + INVOKE (sect-line-fname) :+][+: + + == append :+][+: + (out-push-add file-name) :+][+: + INVOKE (string-append "append-" macro-name) :+][+: + + == insert :+][+: + (set! fname-line (shellf + "sed '1s/.Sh .*/.Pp/' %1$s ; rm -f %1$s" file-name)) :+][+: + INVOKE (sect-line-fname) :+][+: + + == alt :+][+: + (out-push-new) :+][+: + + * :+][+: + (error (sprintf "invalid section type: %s" (get "mode"))) + + :+][+: + ESAC :+][+: + + ENDIF file existence/non-existence :+][+: + (out-pop) :+][+: # All paths open out :+][+: +ENDDEF cond-section + +.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +.\" M K - D E S C R I P T I O N +.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = :+][+: + +DEFINE mk-description :+][+: + + (out-push-new) + (emit + (if (exist? "prog-man-descrip") + (stack-join "\n.Pp\n" "prog-man-descrip") + (if (exist? "detail") + (stack-join "\n.Pp\n" "detail") + "There is no description for this command." + ) ) ) + (shell "sed 's/^$/.sp/' <<\\_EODesc_\n" (out-pop #t) "\n_EODesc_") + + :+][+: + INVOKE append-description :+][+: + +ENDDEF mk-description + +.\" = = = = = = = = = = = = = = = = = = +.\" A P P E N D - D E S C R I P T I O N +.\" = = = = = = = = = = = = = = = = = = :+][+: + +DEFINE append-description :+][+: + +IF (= (get "main.main-type") "for-each"):+][+: + + CASE main.handler-type :+][+: + ~* ^(name|file)|.*text :+] +.Pp +This program will perform its function for every file named on the command +line or every file named in a list read from stdin. The arguments or input +names must be pre\-existing files. The input list may contain comments, +which[+: + + !E :+] +.Pp +This program will perform its function for every command line argument +or every non\-comment line in a list read from stdin. +The input list comments[+: + + * :+][+: + (error "the 'for-each' main has in invalid handler-type.") :+][+: + ESAC \:+] + are blank lines or lines beginning with a '[+: + ?% comment-char "%s" "#" :+]' character. +[+: + +ENDIF - "main" is of "for-each" type :+][+: + +ENDDEF append-description + +.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +.\" M K - O P T I O N S +.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = :+][+: + +DEFINE mk-options + +:+][+: + +(define opt-arg "") +(define dis-name "") +(define opt-name "") +(define optname-from "A-Z_^") +(define optname-to "a-z--") +(define cvt-cmd "") +(define formatted-doc (exist? "option-format")) + +(if formatted-doc (begin + (out-push-new) + (set! cvt-cmd (string-append (get "option-format") "2mdoc")) +) ) + +(if (exist? "preserve-case") + (begin + (set! optname-from "_^") + (set! optname-to "--") +) ) + +(define fix-optname (lambda (o_nm) (begin + (set! o_nm (string-tr o_nm optname-from optname-to)) + (set! o_nm (string-substitute o_nm "-" "\\-" )) + o_nm ))) + +(if (exist? "option-info") + (string-append ".Pp\n" (get "option-info") "\n") ) +\:+] +.Bl -tag[+: + +FOR flag :+][+: + IF (not (exist? "documentation")) :+][+: + IF (exist? "aliases") :+][+: + INVOKE emit-alias-opt :+][+: + ELSE :+][+: + INVOKE emit-flag-text :+][+: + ENDIF :+][+: + + ELSE :+] +.Ss "[+: (get "descrip" "") :+]"[+: +(set! tmp-str (get "documentation" "")) +(if (> (string-length tmp-str) 3) (string-append + "\n" tmp-str "\n" )) :+][+: + + ENDIF :+][+: +ENDFOR flag + +.\" = = = = = = = = = = = = = = = = = +.\" help option +.\" = = = = = = = = = = = = = = = = = + +:+] +.It [+: + (define tmp-val (get "help-value" "\\&?")) + (if (and use-flags (> (string-length tmp-val) 0)) + (string-append "Fl " tmp-val + (if (exist? "long-opts") " , Fl -help" "") ) + (string-append (if (exist? "long-opts") "Fl -" "") "help" ) + ) \:+] + +Display usage information and exit.[+:# + +.\" = = = = = = = = = = = = = = = = = +.\" more-help option +.\" = = = = = = = = = = = = = = = = = :+][+: + + IF (not (exist? "no-libopts")) :+] +.It [+: + (define tmp-val (get "more-help-value" "\\&!")) + (if (and use-flags (> (string-length tmp-val) 0)) + (string-append "Fl " tmp-val + (if (exist? "long-opts") " , Fl -more-help" "") ) + (string-append (if (exist? "long-opts") "Fl -" "") "more-help" ) + ) \:+] + +Pass the extended usage information through a pager.[+: + +ENDIF no no-libopts + +.\" = = = = = = = = = = = = = = = = = +.\" save and load configuration +.\" = = = = = = = = = = = = = = = = = :+][+: + +IF (exist? "homerc") :+] +.It [+: + + IF (not (exist? "disable-save")) :+][+: + + (define tmp-val (get "save-opts-value" ">")) + (if (and use-flags (> (string-length tmp-val) 0)) + (string-append "Fl " tmp-val " Oo Ar cfgfile Oc" + (if (exist? "long-opts") + " , Fl -save-opts Oo Ns = Ns Ar cfgfile Oc" ) "") + (string-append (if (exist? "long-opts") "Fl -" "") + "save-opts Oo Ns = Ns Ar cfgfile Oc" ) + ) \:+] + +Save the option state to \fIcfgfile\fP. The default is the \fIlast\fP +configuration file listed in the \fBOPTION PRESETS\fP section, below. +The command will exit after updating the config file. +.It [+: + ENDIF saving not disabled :+][+: + + (define tmp-val (get "load-opts-value" "<")) + (define tmp-str (if (exist? "long-opts") "Fl -" "")) + + (if (and use-flags (> (string-length tmp-val) 0)) + (string-append "Fl " tmp-val " Ar cfgfile" + (if (exist? "long-opts") + (string-append " , " tmp-str "load-opts Ns = Ns Ar cfgfile" + " , " tmp-str "no-load-opts" ) + "") ) + (string-append tmp-str "load-opts Ns = Ns Ar cfgfile , " + tmp-str "no-load-opts" ) + ) \:+] + +Load options from \fIcfgfile\fP. +The \fIno-load-opts\fP form will disable the loading +of earlier config/rc/ini files. \fI\-\-no-load-opts\fP is handled early, +out of order.[+: + +ENDIF (exist? "homerc") + +.\" = = = = = = = = = = = = = = = = = +.\" version +.\" = = = = = = = = = = = = = = = = = :+][+: + +IF (exist? "version") :+] +.It [+: + + (define tmp-val (get "version-value" "v")) + (if (and use-flags (> (string-length tmp-val) 0)) + (string-append "Fl " tmp-val " Op Brq Ar v|c|n" + (if (exist? "long-opts") + " Fl -version Op Brq Ar v|c|n" ) "") + (string-append (if (exist? "long-opts") "Fl -" "") + "version Op Brq Ar v|c|n" ) + ) \:+] + +Output version of program and exit. The default mode is `v', a simple +version. The `c' mode will print copyright information and `n' will +print the full copyright notice.[+: +ENDIF :+] +.El +[+: + +(if formatted-doc + (shell (string-append + "fn='" (find-file cvt-cmd) + "'\ntest -f ${fn} || die '" cvt-cmd " not found'\n" + "${fn} <<\\_EndOfMdoc_ || die ${fn} failed in $PWD\n" + (out-pop #t) + "\n_EndOfMdoc_" )) ) :+][+: + +ENDDEF mk-options + +.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +.\" M K - O P T I O N - P R E S E T S +.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = :+][+: + +DEFINE mk-option-presets \:+] +Any option that is not marked as \fInot presettable\fP may be preset +by loading values from [+: + IF (. home-rc-files) + :+]configuration ("RC" or ".INI") file(s)[+: + IF (. environ-init) :+] and values from +[+: + ENDIF :+][+: + ENDIF :+][+: + IF (. environ-init) :+]environment variables named: +.nf + \fB[+:(. UP-PROG-NAME):+]_\fP or \fB[+:(. UP-PROG-NAME):+]\fP +.fi +.ad[+: + IF (. home-rc-files) :+] +The environmental presets take precedence (are processed later than) +the configuration files.[+: + ENDIF :+][+: + ELSE :+].[+: + ENDIF :+][+: + + CASE + (define rc-file + (get "rcfile" (string-append "." (get "prog-name") "rc")) ) + (count "homerc") :+][+: + + == "0" :+][+: + == "1" :+][+: + + CASE homerc :+][+: + ~~ '\.|\$HOME' :+] +The file "\fI[+: (string-append (get "homerc") "/" rc-file) +:+]\fP" will be used, if present.[+: + + == "" :+][+: + + * :+] +The \fIhomerc\fP file is "\fI[+:homerc:+]\fP", unless that is a directory. +In that case, the file "\fI[+: (. rc-file) :+]\fP" +is searched for within that directory.[+: + ESAC :+][+: + + * :+] +The \fIhomerc\fP files are [+: + FOR homerc ", " :+][+: + IF (last-for?) :+]and [+: + ENDIF :+]"\fI[+: homerc :+]\fP"[+: ENDFOR :+]. +If any of these are directories, then the file \fI[+: (. rc-file) :+]\fP +is searched for within those directories.[+: + ESAC :+][+: + +ENDDEF mk-option-presets + +.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +.\" M K - E X I T - S T A T U S +.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = :+][+: + +DEFINE mk-exit-status \:+] +One of the following exit values will be returned: +.Bl -tag +[+: +(ag-fprintf 0 ".It 0 \" (EXIT_%s)\"\n%s\n" + (string->c-name! (string-upcase (get "exit-name[0]" "SUCCESS"))) + (get "exit-desc[0]" "Successful program execution.") ) + +(define need-ex-noinput (exist? "homerc")) +(define need-ex-software #t) + +(ag-fprintf 0 ".It 1 \" (EXIT_%s)\"\n%s\n" + (string->c-name! (string-upcase (get "exit-name[1]" "FAILURE"))) + (get "exit-desc[1]" + "The operation failed or the command syntax was not valid.")) :+][+: + +FOR exit-desc (for-from 2) :+][+: + (if (= (for-index) 66) + (set! need-ex-noinput #f) + (if (= (for-index) 70) + (set! need-ex-software #f) )) + + (set! tmp-str (get (sprintf "exit-name[%d]" (for-index)) "* unnamed *")) + (sprintf ".It %d \" (EXIT_%s)\"\n%s\n" + (for-index) + (string-upcase (string->c-name! tmp-str)) + (get "exit-desc" "")) :+][+: +ENDFOR exit-desc :+][+: +(if need-ex-noinput + (emit ".It 66 \" (EX_NOINPUT)\" +A specified configuration file could not be loaded.\n")) + +(if need-ex-software + (emit ".It 70 \" (EX_SOFTWARE)\" +libopts had an internal operational error. Please report +it to autogen-users@lists.sourceforge.net. Thank you.\n")) + +(if (> (string-length fname-line) 1) + (emit fname-line)) :+] +.El +[+: + +ENDDEF mk-exit-status + +.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +.\" M K - A U T H O R S +.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = :+][+: + +DEFINE mk-authors :+][+: + + (define remove-authors #t) + + (set! tmp-val + (if (exist? "copyright.author") + (stack-join ",\n" "copyright.author") + (stack-join ",\n" "copyright.owner") )) + + (if (> (string-length tmp-val) 1) + (string-append tmp-val "\n") + (delete-file file-name)) + + :+][+: + +ENDDEF mk-authors + +.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +.\" M K - B U G S +.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = :+][+: + +DEFINE mk-bugs :+][+: + + (set! tmp-val (get "copyright.eaddr" (get "eaddr"))) + (if (> (string-length tmp-val) 1) + (string-append "Please send bug reports to: " tmp-val "\n") + (delete-file file-name) ) + :+][+: + +ENDDEF mk-bugs :+][+: + +DEFINE append-bugs :+][+: + + (set! tmp-val (get "copyright.eaddr" (get "eaddr"))) + (if (> (string-length tmp-val) 1) + (string-append "\n.Pp\nPlease send bug reports to: " tmp-val "\n") ) + :+][+: + +ENDDEF append-bugs + +.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +.\" M K - C O P Y R I G H T (+ licensing) +.\" +.\" This section is guaranteed to be the last section in the man page +.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = :+][+: + +DEFINE mk-copyright \:+] +Copyright (C) [+: copyright.date :+] [+: + (get "copyright.owner" (get "copyright.author" (get "copyright.eaddr"))) + :+] all rights reserved. +[+: CASE (get "copyright.type") :+][+: + = note :+][+: (get "copyright.text") :+][+: + == '' :+]This program has an unspecified license.[+: + + * :+][+: + (string-append "This program is released under the terms of " + (license-name (get "copyright.type")) ".") :+][+: + + ESAC :+] +[+: +ENDDEF mk-copyright + +.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +.\" M K - N O T E S +.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = :+][+: + +DEFINE mk-notes \:+] +This manual page was \fIAutoGen\fP-erated from the \fB[+: prog-name :+]\fP +option definitions. +[+: + +ENDDEF mk-notes + +.\" = = = = = APPEND TO IT: :+][+: + +DEFINE append-notes :+] +.Pp +This manual page was \fIAutoGen\fP-erated from the \fB[+: prog-name :+]\fP +option definitions.[+: + +ENDDEF append-notes + +.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +.\" M K - E N V I R O N M E N T +.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = :+][+: + +DEFINE mk-environment :+][+: + INVOKE append-environment :+][+: +ENDDEF mk-environment + +.\" = = = = = APPEND TO IT: :+][+: + +DEFINE append-environment :+] +[+:(. environ-text) :+][+: +ENDDEF append-environment + +.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +.\" M K - F I L E S +.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = :+][+: + +DEFINE mk-files :+][+: + INVOKE append-files :+][+: +ENDDEF mk-files + +.\" = = = = = APPEND TO IT: :+][+: + +DEFINE append-files :+] +[+:(. home-rc-text) :+][+: +ENDDEF append-files + +.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +.\" E M I T A L I A S O P T +.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = :+][+: + +DEFINE emit-alias-opt :+] +.It [+: + IF (exist? "value") :+][+: + IF (exist? "long-opts") \:+] + Fl [+:value:+] , Fl \-[+: name :+][+: + ELSE \:+] + Fl [+:value:+][+: + ENDIF (exist? "long-opts") :+][+: + + ELSE value does not exist -- named option only :+][+: + + IF (not (exist? "long-opts")) \:+] + [+: name :+][+: + ELSE \:+] + Fl \-[+: (get "name") :+][+: + ENDIF :+][+: + ENDIF :+] +This is an alias for the \fI--[+: aliases :+]\fR option.[+: + IF (exist? "deprecated") :+] +.sp +.B +NOTE: THIS OPTION IS DEPRECATED +[+: + ENDIF :+][+: +ENDDEF emit-alias-opt + +.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +.\" E M I T F L A G T E X T +.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = :+][+: + +DEFINE emit-flag-text :+][+: + + (if (exist? "enable") + (set! opt-name (string-append (get "enable") "-" (get "name"))) + (set! opt-name (get "name")) ) + (if (exist? "disable") + (set! dis-name (string-append (get "disable") "-" (get "name"))) + (set! dis-name "") ) + + (set! opt-name (fix-optname opt-name)) + (if (> (string-length dis-name) 0) + (set! dis-name (fix-optname dis-name)) ) + + (if (not (exist? "arg-type")) + (set! opt-arg "") + (set! opt-arg (string-append "Ar " + (fix-optname (if (exist? "arg-name") + (get "arg-name") + (string-downcase! (get "arg-type")) )) + )) + ) + +:+] +.It [+: + IF (exist? "value") :+][+: + IF (exist? "long-opts") :+][+: + + # * * * * * * * * * * * * * * * * * * * * + * + * The option has a flag value (character) AND + * the program uses long options + * + \:+] + Fl [+:value:+][+: + IF (not (exist? "arg-type")) :+] , Fl -[+: + ELSE :+] [+:(. opt-arg):+] , Fl -[+: + ENDIF :+][+: (. opt-name) :+] [+: + IF (exist? "arg-type") :+][+: + ? arg-optional Oo Ns = Ns + :+] [+: (. opt-arg) :+] [+: + arg-optional Oc :+][+: + ENDIF :+][+: + IF (exist? "disable") :+] , Fl -[+:(. dis-name):+][+: + ENDIF :+][+: + + ELSE :+][+: + + # * * * * * * * * * * * * * * * * * * * * + * + * The option has a flag value (character) BUT + * the program does _NOT_ use long options + * + \:+] + Fl [+:value:+] [+: + IF (exist? "arg-type") :+][+: + arg-optional Oo :+] [+:(. opt-arg):+] [+: + arg-optional Oc :+] [+: + ENDIF " :+][+: + ENDIF (exist? "long-opts") :+][+: + + + ELSE value does not exist -- named option only :+][+: + + IF (not (exist? "long-opts")) :+][+: + + # * * * * * * * * * * * * * * * * * * * * + * + * The option does not have a flag value (character). + * The program does _NOT_ use long options either. + * Special magic: All arguments are named options. + * + \:+] + [+: (. opt-name) :+] [+: + IF (exist? "arg-type") :+] [+: + ? arg-optional ' Oo = Ns' ' Ns = Ns ' + :+] [+:(. opt-arg) :+] [+: + arg-optional Oc :+] [+: + ENDIF:+][+: + IF (exist? "disable") :+] , Fl -[+:(. dis-name):+][+: + ENDIF :+][+: + + + ELSE :+][+: + # * * * * * * * * * * * * * * * * * * * * + * + * The option does not have a flag value (character). + * The program, instead, only accepts long options. + * + \:+] + Fl -[+: (. opt-name) :+] [+: + + IF (exist? "arg-type") :+][+: + arg-optional Oo :+] Ns = Ns [+:(. opt-arg):+] [+: + arg-optional Oc :+][+: + ENDIF :+][+: + + (if (exist? "disable") + (string-append ", Fl \\-" dis-name) + "") :+][+: + ENDIF :+][+: + ENDIF :+] +[+: (get "descrip" "") :+].[+: + + IF (exist? "min") :+] +This option is required to appear.[+: + ENDIF :+][+: + + IF (exist? "max") :+] +This option may appear [+: + IF % max (= "%s" "NOLIMIT") + :+]an unlimited number of times[+:ELSE + :+]up to [+: max :+] times[+: + ENDIF:+].[+: + ENDIF:+][+: + + IF (exist? "disable") :+] +The \fI[+:(. dis-name):+]\fP form will [+: + IF (exist? "stack-arg") + :+]clear the list of option arguments[+: + ELSE :+]disable the option[+: + ENDIF :+].[+: + ENDIF:+][+: + + IF (exist? "enabled") :+] +This option is enabled by default.[+: + ENDIF :+][+: + + IF (exist? "no-preset") :+] +This option may not be preset with environment variables +or in initialization (rc) files.[+: + ENDIF :+][+: + + IF (and (exist? "default") named-mode) :+] +This option is the default option.[+: + ENDIF :+][+: + + IF (exist? "equivalence") :+] +This option is a member of the [+:equivalence:+] class of options.[+: + ENDIF :+][+: + + IF (exist? "flags-must") :+] +This option must appear in combination with the following options: +[+: FOR flags-must ", " :+][+:flags-must:+][+:ENDFOR:+].[+: + ENDIF :+][+: + + IF (exist? "flags-cant") :+] +This option must not appear in combination with any of the following options: +[+: FOR flags-cant ", " :+][+:flags-cant:+][+:ENDFOR:+].[+: + ENDIF :+][+: + + + IF (~* (get "arg-type") "key|set") :+] +This option takes a keyword as its argument[+: + + IF (=* (get "arg-type") "set") + +:+] list. Each entry turns on or off +membership bits. The bits are set by name or numeric value and cleared +by preceding the name or number with an exclamation character ('!'). +They can all be cleared with the magic name \fInone\fR and they can all be set +with +.IR all . +A single option will process a list of these values.[+: + + ELSE + +:+]. The argument sets an enumeration value that can +be tested by comparing them against the option value macro.[+: + + ENDIF + +:+] +The available keywords are: +.in +4 +.nf +.na +[+: (shellf "${CLexe} --indent='' --spread=1 -W50 <<_EOF_\n%s\n_EOF_" + (join "\n" (stack "keyword")) ) :+] +.fi +or their numeric equivalent. +.in -4[+: (if (exist? "arg-default") "\n.sp" ) :+][+: + + ELIF (=* (get "arg-type") "num") :+] +This option takes an integer number as its argument.[+: + + IF (exist? "arg-range") :+] +The value of +.[+:(. opt-arg):+] +is constrained to being: +.in +4 +.nf +.na[+:FOR arg_range ", or" :+] +[+: (shell " +range='" (get "arg-range") "' + +case \"X${range}\" in +X'->'?* ) + echo \"less than or equal to\" ` + echo $range | sed 's/->//' ` ;; + +X?*'->' ) + echo \"greater than or equal to\" ` + echo $range | sed 's/->.*//' ` ;; + +X?*'->'?* ) + echo \"in the range \" ` + echo $range | sed 's/->/ through /' ` ;; + +X?* ) + echo exactly $range ;; + +X* ) echo $range is indeterminate +esac" ) :+][+: + ENDFOR arg-range " :+] +.fi +.in -4[+: + + ENDIF arg-range exists :+][+: + + ENDIF arg-type key/set/num :+][+: + + IF (exist? "arg-default") :+] +The default +.[+: (. opt-arg) :+] +for this option is: +.ti +4 + [+: (join " + " (stack "arg-default" )) :+][+: + ENDIF :+] +.sp +[+: + (if (exist? "doc") (string-substitute (get "doc" "") "\n\n" "\n.sp\n") + "This option has not been fully documented." ) :+][+: + IF (exist? "deprecated") :+] +.sp +.B +NOTE: THIS OPTION IS DEPRECATED +[+: + ENDIF :+][+: + +ENDDEF emit-flag-text :+][+: + +DEFINE mk-synopsis :+][+: + (out-push-new file-name) \:+] +.Sh SYNOPSIS +.Nm[+: + + IF (. use-flags) :+][+: + IF (exist? "long-opts") :+] +.\" Mixture of short (flag) options and long options +.Op Fl flags +.Op Fl flag Op Ar value +.Op Fl \-option-name Ns Oo Oo Ns "=| " Oc Ns Ar value Oc +[+: ELSE no long options: :+] +.Op Fl flags +.Op Fl flag Op Ar value +[+: ENDIF + :+][+: + ELIF (exist? "long-opts") + :+] +.Op Fl \-option-name +.Op Fl \-option-name Ar value +[+: + + ELIF (not (exist? "argument")) :+] +.Op Ar option\-name Ar value +.Pp +All arguments are named options. +[+: + ENDIF :+][+: + + IF (exist? "argument") :+][+: + argument :+][+: + + IF (exist? "reorder-args") :+] +.Pp +Operands and options may be intermixed. They will be reordered. +[+: ENDIF :+][+: + + ELIF (or (exist? "long-opts") use-flags) + +:+] +.Pp +All arguments must be options. +[+: + + ENDIF :+][+: + + IF (exist? "main") :+][+: + CASE main.main-type :+][+: + == shell-process :+] +.Pp +This program will emit text that is expected to be evaluated by +a Bourne-compatible shell, thus digesting the options for the script.[+: + + == shell-parser :+] +.Pp +This program is designed to produce output suitable for inclusion +into a shell script that will parse the options described.[+: + + == for-each :+] +.Pp +The operands that this program operates on may be specified either +on the command line or read from standard input, one per line. +In that input, leading and trailing white space is stripped, +blank lines are ignored[+: + + IF (define comment-char (get "comment-char" "#")) + (> (string-length comment-char) 1) \:+] + and lines beginning with the character +.I [+: (substring comment-char 1 0):+] +are treated as comments[+: + ENDIF :+].[+: + + IF (exist? "interleaved") :+] +Options may be interleaved with operands both on the command +line and when operands are read from standard input.[+: + ENDIF interleaved + +:+] +Standard input may not be a terminal.[+: + + ESAC main-type :+][+: + ENDIF main exists :+] +.Pp +[+: + +FOR explain "\n.Pp\n" :+][+: + (get "explain" "") :+][+: +ENDFOR :+][+: + +(out-pop) :+][+: + +ENDDEF mk-synopsis + +.\" cmd-doc.tlib ends here \:+] diff --git a/autoopts/tpl/def2pot.tpl b/autoopts/tpl/def2pot.tpl new file mode 100644 index 0000000..29f7acb --- /dev/null +++ b/autoopts/tpl/def2pot.tpl @@ -0,0 +1,144 @@ +[= AutoGen5 template pot =][= +# +# this template can be used to generate .pot file for the +# option definition files for these templates: +# aginfo.tpl, agman-cmd.tpl, agmdoc-cmd.tpl +# + +# This file is part of AutoOpts, a companion to AutoGen. +# AutoOpts is free software. +# AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +# +# AutoOpts is available under any one of two licenses. The license +# in use must be one of these two and the choice is under the control +# of the user of the license. +# +# The GNU Lesser General Public License, version 3 or later +# See the files "COPYING.lgplv3" and "COPYING.gplv3" +# +# The Modified Berkeley Software Distribution License +# See the file "COPYING.mbsd" +# +# These files have the following sha256 sums: +# +# 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +# 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +# 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + +====================== FUNCTIONS BEGIN =======================][= +DEFINE genmsg =][= + + IF (set! msg-id (get "msgid")) + (set! msg-text (get-text msg-id)) + (< 0 (string-length msg-text)) =] +#: [=(def-file-line msg-id "%s:%d") =] +msgid [= (c-string msg-text) =] +msgstr "" +[=ENDIF =][= +ENDDEF =][= + +DEFINE genmsg2 =][= + IF (set! msg-text (get "msgid")) + (string-length msg-text) =] +#: [=(def-file-line msg-text "%s:%d") =] +msgid [= (c-string msg-text) =] +msgstr "" +[=ENDIF =][= +ENDDEF =][= + +(define get-text (lambda (nm) (shell (string-append + + "{ sed 's/@[a-z]*{\\([^}]*\\)}/\\1/g' | " + "${CLexe} --fill -I0 -W72\n" + "} <<\\_EODesc_\n" + (get nm) + "\n_EODesc_" +)))) +(define msg-text "") +(define msg-id "") + + ;;# START-BUILDTREE-ISMS + ;; + (shell "CLexe=${AGexe%/agen5/*}/columns/columns + test -x \"${CLexe}\" || { + CLexe=${AGexe%/autogen}/columns + test -x \"${CLexe}\" || die 'columns program is not findable' + }") + +=][= # END-BUILDTREE-ISMS + +(shell "CLexe=`echo ${AGexe} | sed 's@/autogen@/columns@'` + test -x \"${CLexe}\" || CLexe=`which columns`") + +# END-INSTALL-ONLY-CODE =][= # + +;; ==================== FUNCTIONS END =========================== + +;; pot file header and comment info \=] +# localization template (.pot) for [= (def-file) =] of [= prog-name =], +# this file is used to generate localized manual for [= prog-name =]. +# Copyright (C) [= (shell "date +%Y") =][= + + IF (exist? "copyright") =] +# This file is distributed under the terms of the +# [= (license-name (get "copyright.type")) \=] + +# The program owners may be reached via: +# [=(shellf + "author='%s' email='%s' date=`date +%%Y` + printf '%%s <%%s>, %%s.' \"$author\" \"$email\" \"${date}\"" + (get "copyright.owner" "FIRST AUTHOR") + (get "copyright.eaddr" "EMAIL@ADDRESS") +)=][= ENDIF =] +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: [= prog-name =] [= version =]\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: [= (shell "date +\"%F %R%z\"") =]\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" +[= +genmsg msgid=prog-title =][= + +IF (exist? "full-usage") =][= + genmsg msgid=full-usage =][= +ELSE =][= + FOR flag =][= + genmsg msgid=descrip =][= + genmsg msgid=doc =][= + ENDFOR =][= +ENDIF =][= + +IF (exist? "short-usage") =][= + genmsg msgid=short-usage =][= +ENDIF =][= + +FOR explain =][= + genmsg msgid=explain =][= +ENDFOR =][= + +FOR detail =][= + genmsg msgid=detail =][= +ENDFOR =][= + +CASE (get "copyright.type") =][= + = note =][= + == '' =][= + * =][= + genmsg2 msgid=(string-append + "This program is released under the terms of " + (license-name (get "copyright.type")) ".") + =][= +ESAC =][= + +genmsg msgid=option-info =][= +genmsg msgid=argument =][= +genmsg msgid=man-doc =][= +genmsg msgid=copyright.text =] diff --git a/autoopts/tpl/getopt.tpl b/autoopts/tpl/getopt.tpl new file mode 100644 index 0000000..880583b --- /dev/null +++ b/autoopts/tpl/getopt.tpl @@ -0,0 +1,510 @@ +[+ AutoGen5 Template -*- Mode: C -*- + + h=%s-temp.h + c=%s-temp.c +][+ + +`stamp=\`sed 's,.*stamp: *",,;s,".*,,' <<\_EOF_ + Time-stamp: "2018-08-08 17:59:09 bkorb" +_EOF_ +\` ` +][+ + +;; This file is part of AutoOpts, a companion to AutoGen. +;; AutoOpts is free software. +;; AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +;; +;; AutoOpts is available under any one of two licenses. The license +;; in use must be one of these two and the choice is under the control +;; of the user of the license. +;; +;; The GNU Lesser General Public License, version 3 or later +;; See the files "COPYING.lgplv3" and "COPYING.gplv3" +;; +;; The Modified Berkeley Software Distribution License +;; See the file "COPYING.mbsd" +;; +;; These files have the following sha256 sums: +;; +;; 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +;; 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +;; 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + + (if (not (exist? "settable")) + (error "'settable' must be specified globally for getopt_long\n")) + (if (not (exist? "no-libopts")) + (error "'no-libopts' must be specified globally to use getopt\n")) + (define prog-name (string->c-name! (get "prog-name"))) + (define PROG-NAME (string-upcase prog-name)) + (out-move (string-append "getopt-" prog-name "." (suffix))) + (dne " * " "/* " ) +] + *[+ + + IF (exist? "copyright") +] + * +[+ + CASE copyright.type +][+ + == "" +] * licensing type not specified.[+ + = note +][+ (prefix " * " (get "copyright.text")) +][+ + * +][+ + (license-description (get "copyright.type") prog-name " * " + (get "copyright.owner")) +][+ + ESAC +][+ + ENDIF +] + * + * Last template edit: [+ `echo $stamp` +] + */[+ +CASE (suffix) +][+ +== h +][+ + (define header-file (out-name)) + (out-push-new) \+] +{ +[+ # START-BUILDTREE-ISMS: + +# The following code is sedded away in install-hook.sh. +# The goal is to ensure we use build tree templates in testing mode, and +# remove them when installing this file. + +\+] + aobdir=`echo ${AGexe} | sed 's@/agen5/.*$@@'`/autoopts + agopts=-L`dirname [+ (tpl-file #t) +]`' ' + test "X-L$aobdir/tpl " = "X$agopts" || \ + agopts="-L${aobdir}/tpl $agopts" + tarfile=`set -- ${aobdir}/libopts*.tar.* + test -f $1 || { + cd ${aobdir} + ${MAKE:-make} libsrc || exit 1 + cd - + set -- ${aobdir}/libopts*.tar.* + test -f $1 || die 'libopts tarball not built' + } >&2 + echo $1`[+ + +# END-BUILDTREE-ISMS the following code is for installed version: + agopts= + aocfg=`echo ${AGexe} | sed 's@/[^/]*$@@'`/autoopts-config + test -x "${aocfg}" || aocfg=`which autoopts-config` + tarfile=`${aocfg} libsrc` + +# END-INSTALL-ONLY-CODE +] + if test -n "${AG_Tracing}" + then + AG_Dep_File=`dirname "${AG_Tracing}"`/ao-[+ (base-name) +].dep + agopts="${agopts}-MF${AG_Dep_File} -MT${AG_Dep_File%.dep}.targ" + fi + cmd="${AGexe} -b[+(base-name)+] ${agopts} -Toptions.tpl [+(def-file)+]" + $cmd || die "COMMAND FAIL: $cmd" + def_hdr=[+ (base-name) +].h + sed 's@@"[+ (. header-file) + +]"@' $def_hdr > XXX-$$ + mv -f XXX-$$ $def_hdr + hdrfile=`gunzip -c $tarfile | tar tf - | fgrep /autoopts/options.h` + gunzip -c $tarfile | tar xf - $hdrfile + exec 3< $hdrfile + untardir=`echo $hdrfile | sed 's@/.*@@'` +} >&2 + +while : +do + IFS= read -r -u3 line || die "no header guard in $hdrfile" + case "$line" in + *AUTOOPTS_OPTIONS_H_GUARD ) break ;; + esac +done +echo + +echo "$line" +IFS= read -r -u3 line || die "short $hdrfile" +case "$line" in +'#define AUTOOPTS_OPTIONS_H_GUARD'* ) : ;; +*) die "invalid header guard in $hdrfile" ;; +esac +echo "$line" +echo '#include "[+ +(if (exist? "config-header") + (get "config-header") + (error "getopt template requires a \"config-header\" attribute") +) +]"' + +while : +do + IFS= read -r -u3 line || die "no CPLUSPLUS_CLOSER in $hdrfile" + case "$line" in + *'Versions where in various fields first appear'* ) break ;; + esac + echo "$line" +done + +cat <<- _EOF_ + * option loop function + */ + #ifdef __cplusplus + #define CPLUSPLUS_OPENER extern "C" { + CPLUSPLUS_OPENER + #define CPLUSPLUS_CLOSER } + #else + #define CPLUSPLUS_CLOSER + #endif + + extern int process_[+(. prog-name)+]_opts(int argc, char ** argv); + extern void optionPrintVersion(tOptions * opts, tOptDesc * od); + extern void optionUsage(tOptions * opts, int exit_code); + + CPLUSPLUS_CLOSER + _EOF_ + +sed '1,/^CPLUSPLUS_CLOSER/d' <&3 +exec 3<&- +rm -rf $untardir +[+ (shell (out-pop #t)) +] +[+ == c +] +#include "[+ (. header-file) +]" + +#include + +#include +#include +#include +#include <[+ (if (exist? "long-opts") "getopt" "unistd") +].h> +#include "[+ (base-name) +].h" + +#ifndef DIRCH +# if defined(_WIN32) && !defined(__CYGWIN__) +# define DIRCH '\\' +# else +# define DIRCH '/' +# endif +#endif[+ + +IF (exist? "long-opts") +] + +/* + * getopt_long option descriptor + */ +static struct option a_long_opts[] = {[+ + + FOR flag +][+ + (sprintf + + "\n { %-20s %d, NULL, VALUE_OPT_%s }," + (string-append (c-string (get "name")) ",") + (if (exist? "arg-type") 1 0) + (string-upcase (string->c-name! (get "name"))) + ) +][+ + + ENDFOR flag + ++] + { "help", 0, NULL, VALUE_OPT_HELP },[+ +IF (exist? "version") +] + { "version", 0, NULL, VALUE_OPT_VERSION },[+ +ENDIF +] + { NULL, 0, NULL, 0 } +}; +[+ ENDIF +] +/* + * Option flag character list + */ +static char z_opts[] = "[+ # close quote for emacs " +][+ + FOR flag +][+ + CASE value +][+ + ~ [!-~] +][+ value +][+ + + CASE arg-type +][+ + =* str +]:[+ + == "" +][+ + * +][+ (error (sprintf + "error in %s opt: The only allowed arg type is 'string'\n" + (get "name") )) +][+ + ESAC +][+ + + ESAC +][+ + + ENDFOR flag +][+ + + IF (not (exist? "help-value")) +]?[+ + ELSE +][+ + CASE help-value +][+ + == "" +][+ + == '"' +]\"[+ + * +][+ help-value +][+ + ESAC +][+ + ENDIF +][+ + + IF (exist? "version") +][+ + IF (not (exist? "version-value")) +]v[+ + ELSE +][+ + CASE version-value +][+ + == "" +][+ + == '"' +]\"[+ + * +][+ version-value +][+ + ESAC +][+ + ENDIF +][+ + ENDIF +][+ + + (define help-opt + (if (exist? "long-opts") "--help" + (if (not (exist? "flag.value")) "help" + (if (exist? "help-value") (string-append "-" (get "help-value")) + "-?" ))) ) + ;; open quote for emacs " +]"; + +/* + * AutoOpts library replacement routines: + */ +noreturn void +optionUsage (tOptions * pOptions, int status) +{ + if (status != 0) + fprintf (stderr, _("Try `%s [+(. help-opt)+]' for more information.\n"), + [+ (. prog-name) +]Options.pzProgName); + else + { + fputs (_([+ + INVOKE emit-usage-string usage-type = short +]), stdout); + } + + exit (status); +} + +noreturn void +optionPrintVersion (tOptions * pOptions, tOptDesc * pOptDesc) +{ + char const * pz_by = + _("[+ # " +][+ + + (sprintf "%s%s %s" prog-name + (if (exist? "prog-group") + (sprintf " (%s)" (get "prog-group")) + "" ) + (get "version") ) +]\n\ +Written by [+(join ", " (stack "copyright.author"))+].\n\n\ +Copyright (C) [+ copyright.date +] [+ copyright.owner +]\n[+ + +CASE copyright.type +][+ +*~ [l]*gpl +]\ +This is free software; see the source for copying conditions. There is NO\n\ +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.[+ + +ESAC +][+ # " +]\n"); + + fputs (pz_by, stdout); + exit (EXIT_SUCCESS); +} + +/* + * If an option appears more often than is allowed, ... + */ +static void +usage_too_many (tOptDesc* pOptDesc) +{ + char const * pz = + _("[+(. prog-name) + +] error: the '%s' option appears more than %d times\n"); + fprintf (stderr, pz, pOptDesc->pz_Name, pOptDesc->optMaxCt); + USAGE(EXIT_FAILURE); +} +[+ + IF (exist? "flag.min") ++] +/* + * There is at least one option that must appear. + */ +static void +usage_too_few (tOptDesc* pOptDesc) +{ + char const * pz = + _("[+(. prog-name) + +] error: the '%s' option must appear %d times\n"); + fprintf (stderr, pz, pOptDesc->pz_Name, pOptDesc->optMinCt); + USAGE(EXIT_FAILURE); +} +[+ + ENDIF ++][+ + IF (exist? "flag.flags-cant") ++] +/* + * There is at least one pair of options that may not appear together + * on the command line. + */ +static void +usage_cannot (char const* pz_what, char const* pz_cant) +{ + char const * pz = + _("[+(. prog-name) + +] error: the `%s' option conflicts with the `%s' option.\n"); + fprintf (stderr, pz, pz_what, pz_cant); + USAGE(EXIT_FAILURE); +} +[+ + ENDIF ++][+ + IF (exist? "flag.flags-must") ++] +/* + * There is at least one pair of options that are required to appear + * together on the command line. + */ +static void +usage_must (char const* pz_what, char const* pz_must) +{ + char const * pz = + _("[+(. prog-name) + +] error: the `%s' option requires the `%s' option.\n"); + fprintf (stderr, pz, pz_what, pz_must); + USAGE(EXIT_FAILURE); +} +[+ + ENDIF ++] +/* + * Process the options for the "[+(. prog-name)+]" program. + * This function was generated to use the getopt[+ + (if (exist? "long-opts") "_long(3GNU)" "(3posix)") +] function. + * There are [+ (+ (count "flag") (if (exist? "version") 2 1)) + +] options for this program, + * including "help (usage)"[+ + IF (exist? "version") +] and "version"[+ ENDIF +]. + */ +int +process_[+(. prog-name)+]_opts (int argc, char** argv) +{ + { + char * pz_prog = strrchr (argv[0], DIRCH); + /* + * This violates the const-ness of the pzProgName field. + * The const-ness is to prevent accidents. This is not accidental. + */ + char ** pp = VOIDP(&([+ (. prog-name) +]Options.pzProgName)); + + if (pz_prog != NULL) + pz_prog++; + else + pz_prog = argv[0]; + *pp = pz_prog; + } + + for (;;) { + switch ([+ + +IF (exist? "long-opts") + +]getopt_long (argc, argv, z_opts, a_long_opts, NULL)[+ +ELSE +]getopt (argc, argv, z_opts)[+ +ENDIF +]) { + case -1: goto leave_processing; + case 0: break;[+ + FOR flag +][+ + (define OPT-NAME (string-upcase! (string->c-name! (get "name")))) ++] + + case VALUE_OPT_[+ (. OPT-NAME) +]:[+ + + IF (not (exist? "max")) +] + if (HAVE_OPT([+(. OPT-NAME)+])) + usage_too_many (&DESC([+(. OPT-NAME) +]));[+ + + ELIF (not (= (get "max") "nolimit")) +] + if (DESC([+(. OPT-NAME)+]).optOccCt++ >= DESC([+(. OPT-NAME)+]).optMaxCt) + usage_too_many (&DESC([+(. OPT-NAME) +]));[+ + ENDIF ++] + SET_OPT_[+(. OPT-NAME)+][+ (if (exist? "arg-type") "(optarg)") +]; + break;[+ + + ENDFOR +] + + case VALUE_OPT_HELP: + USAGE(EXIT_SUCCESS); + /* NOTREACHED */ +[+ IF (exist? "version") +] + case VALUE_OPT_VERSION: + optionPrintVersion (&[+ (. prog-name) +]Options, &DESC(VERSION)); + /* NOTREACHED */ +[+ ENDIF +] + default: + USAGE(EXIT_FAILURE); + } + } leave_processing:; +[+ +FOR flag +][+ + IF + (set! OPT-NAME (string-upcase! (string->c-name! (get "name")))) + (define check-have-opt (or (exist? "flags-cant") (exist? "flags-must"))) + check-have-opt ++] + if (HAVE_OPT([+ (. OPT-NAME) +])) {[+ + + FOR flags-cant +] + if (HAVE_OPT([+ (string-upcase! (string->c-name! (get "flags-cant"))) +])) + usage_cannot (DESC([+ (. OPT-NAME) +]).pz_Name, DESC([+ + (string-upcase! (string->c-name! (get "flags-cant"))) +]).pz_Name);[+ + ENDFOR cant +][+ + + FOR flags-must +] + if (! HAVE_OPT([+(string-upcase! (string->c-name! (get "flags-must")))+])) + usage_must (DESC([+ (. OPT-NAME) +]).pz_Name, DESC([+ + (string-upcase! (string->c-name! (get "flags-must"))) +]).pz_Name);[+ + ENDFOR must +][+ + + IF (exist? "min") +][+ + IF (> (string->number (get "min" "0")) 1) +] + if (DESC([+(. OPT-NAME)+]).optOccCt < DESC([+(. OPT-NAME)+]).optMinCt) + usage_too_few (&DESC([+(. OPT-NAME) +]));[+ + + ENDIF +][+ + ENDIF +] + } +[+ + + ENDIF + ++][+ + + IF (exist? "min") +][+ + IF (. check-have-opt) ++] else[+ + + ELSE ++] + if ([+ # + We have a minimum count, but we have not checked for option existence + yet because there are no option interdependencies. We must therefore + now check to see if the option has appeared the required number of + times. In the absence of a max count, our limit must be one and we + only check for presence. If a max count exists, then we will also + have kept the occurrence count. Check that against the limit. +][+ + + IF (not (exist? "max")) + +]! HAVE_OPT([+ (. OPT-NAME) +])[+ + ELSE max ct exists + +]DESC([+(. OPT-NAME)+]).optOccCt < DESC([+(. OPT-NAME)+]).optMinCt[+ + ENDIF +])[+ + + ENDIF +] + usage_too_few (&DESC([+(. OPT-NAME) +])); +[+ + ENDIF +][+ +ENDFOR +] + return 0; +} +[+ ESAC +][+ + +DEFINE emit-usage-string +][+ + + (out-push-new) +][+ + INCLUDE "usage.tlib" +][+ + (out-suspend "use-text") + (out-push-new) \+] +sed -e '/version information/s/ -v \[arg\]/ -v /' \ + -e '/: illegal option --/d' \ + -e 's/ --version\[=arg\]/ --version /' <<_EOF_ +[+ (out-resume "use-text") (out-pop #t) +] +_EOF_[+ + + (kr-string (string-append (shell (out-pop #t)) "\n" ) + ) + ++][+ + +ENDDEF + +# end of getopt.tpl \+] diff --git a/autoopts/tpl/gpl.lic b/autoopts/tpl/gpl.lic new file mode 100644 index 0000000..f728389 --- /dev/null +++ b/autoopts/tpl/gpl.lic @@ -0,0 +1,19 @@ +Copyright (C) , all rights reserved. +This is free software. It is licensed for use, modification and +redistribution under the terms of the GNU General Public License, +version 3 or later + + 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. + + is distributed in the hope that 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 . + +the GNU General Public License, version 3 or later diff --git a/autoopts/tpl/gplv2.lic b/autoopts/tpl/gplv2.lic new file mode 100644 index 0000000..7c6ed85 --- /dev/null +++ b/autoopts/tpl/gplv2.lic @@ -0,0 +1,19 @@ +Copyright (C) , all rights reserved. +This is free software. It is licensed for use, modification and +redistribution under the terms of the GNU General Public License, +version 2 + + is free software: you can redistribute it and/or modify it +under the terms of version 2 of the GNU General Public License, +as published by the Free Software Foundation. + + is distributed in the hope that 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, +version 2, along with this program. +If not, see . + +the GNU General Public License, version 2 diff --git a/autoopts/tpl/lgpl.lic b/autoopts/tpl/lgpl.lic new file mode 100644 index 0000000..92373ab --- /dev/null +++ b/autoopts/tpl/lgpl.lic @@ -0,0 +1,19 @@ +Copyright (C) , all rights reserved. +This is free software. It is licensed for use, modification and +redistribution under the terms of the GNU Lesser General Public License, +version 3 or later + + is free software: you can redistribute 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. + + is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the 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 ."; + +the GNU Lesser General Public License, version 3 or later diff --git a/autoopts/tpl/lgplv2.lic b/autoopts/tpl/lgplv2.lic new file mode 100644 index 0000000..70233f3 --- /dev/null +++ b/autoopts/tpl/lgplv2.lic @@ -0,0 +1,20 @@ +Copyright (C) , all rights reserved. +This is free software. It is licensed for use, modification and +redistribution under the terms of the GNU Lesser General Public License, +version 2 or later + +The library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; if not, see + + +the GNU Lesser General Public License, version 2.0 or later diff --git a/autoopts/tpl/man2mdoc.pl b/autoopts/tpl/man2mdoc.pl new file mode 100755 index 0000000..0816c21 --- /dev/null +++ b/autoopts/tpl/man2mdoc.pl @@ -0,0 +1,304 @@ +#!/usr/bin/perl + +## man2mdoc.pl -- Convert man tags to mdoc tags +## +## Author: Harlan Stenn +## +## +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + +use strict; + +my ($taglist , $optlistold, $paraold, $parafirstval,$List, + $indentation,$isindentated); + +my ($line); + +$isindentated = 0; #this variable is used check the indentation +$indentation = 0; #this variable is used to set the indentation if given +$List = 0; +$parafirstval = 0; +$paraold = 0; +$taglist = 0; ### 1 = taglist, 0 = other list types except taglist +$optlistold = 0; ## 1 = previous list entry was there, 0 = not + +while ($line = ) +{ + if ($line !~ /^\./ ) { + if ($line =~ /[\\fB|\\fI]/) { + MakeMacro($line); + print "\n"; + next; + } + + print $line; + next; + } + + $line =~ s/^\.//; + + next + if ($line =~ /\\"/); + + $line = ParseMacro($line); + + print($line) + if (defined $line); +} + +sub ParseMacro +{ + my ($line) = @_; + + my (@words,$retval); + $retval = ''; + @words = split(/\s+/,$line); + + while($_ = shift (@words)) { + if (/^sp$/ || /^ne$/ || /^na$/|| /^rt$/|| /^mk$/|| /^ad$/) { + last; + } + + if (/^RS$/) { + $List = 1; + # this is to check whether that indentation value is given, + # if it is not given tha means we have to use default indentation, + # if it is given we need to check for that value + # + $isindentated = scalar(@words); + + if ($isindentated) { + if ($_ = shift (@words)) + { + $indentation = 1; + last; + } + $indentation = 0; + last; + } + $indentation = 1; + last; + } + + if (/^IP$/ && $List) { + if (!$optlistold) { + $optlistold = 1; + $taglist = 1; + + if ($indentation) { + $retval .= ".Bl -tag -offset indent -compact\n"; + } else { + $retval .= ".Bl -tab -offset 0n -compact\n"; + } + print $retval; + $words[0] =~ s/\\fB/ Nm /; + $words[0] =~ s/\\fI/ Ar /; + $words[0] =~ s/\\fR/ /g; + + print ".It ".$words[0]."\n"; + last; + + } + + if ($optlistold) { + $words[0] =~ s/\\fB/ Nm /; + $words[0] =~ s/\\fI/ Ar /; + $words[0] =~ s/\\fR/ /g; + print ".It ".$words[0]."\n"; + last; + } + } + + if (/^TP$/ && $List) { + if (!$optlistold) + { + $optlistold = 1; + $taglist = 1; + + if ($indentation) { + $retval .= ".Bl -tag -offset indent -compact\n"; + } else { + $retval .= ".Bl -tab -offset 0n -compact\n"; + } + print $retval; + $retval = ; + + $retval =~ s/\\fB/ Nm /; + $retval =~ s/\\fI/ Ar /; + $retval =~ s/\\fR/ /g; + + print ".It ".$retval."\n"; + last; + } + + if ($optlistold) { + $retval = ; + $retval =~ s/\\fB/ Nm /; + $retval =~ s/\\fI/ Ar /; + $retval =~ s/\\fR/ /g; + print ".It ".$retval."\n"; + last; + } + } + + if (/^RE$/) { + $indentation = 0; + $optlistold = 0; + $isindentated = 0; + + $optlistold = 0; + + } + + if (/^IP$/ && !$List) + { + if (!$optlistold && $words[0] =~ /^\\\(bu$/) { + $optlistold = 1; + $retval .= ".Bl -bullet"."\n"; + print $retval; + print ".It \n"; + last; + } + + + if (!$optlistold && $words[0] =~ /^-$/) { + $optlistold = 1; + $retval .= ".Bl -dash \n"; + print $retval; + print ".It \n"; + last; + } + + + if (!$optlistold && $words[0] =~ /^[1-9]\.$/) { + $optlistold = 1; + $retval .= ".Bl -enum \n"; + print $retval; + print ".It \n"; + last; + + } + + if (!$optlistold && $words[0] !~ /[0-9|-|(br]/) { + $optlistold = 1; + $taglist = 1; + $retval .= ".Bl -tag \n"; + print $retval; + print ".It ".$words[0]."\n"; + last; + } + + if (!$optlistold) { + $optlistold = 1; + $retval .= ".Bl -item \n"; + print $retval; + print ".It \n"; + last; + + } + + if ($optlistold) { + print ".It \n"; + last + } + } + + if ($optlistold && ! /^IP$/ ) { + $optlistold = 0; + print ".El \n"; + } + + if (/^TP$/) { + $parafirstval = 1; + + if (!$paraold) { + $retval .= ".Bl -tag \n"; + print $retval; + print ".It "; + $paraold = 1; + last; + } + + if ($paraold) { + print ".It "; + $paraold = 1; + last; + } + } + + #text bolding (mdoc : .Nm ntpq) (man : .B ntpq ) + if (/^RS$/) { + $List = 1; + } + + if (/^B$/) { + $retval .= ".Nm ".join(' ',@words)."\n"; + print $retval; + } + + #text bolding () + if (/\\fB/) { + $retval = $_; + $retval =~ s/[\\fB|\\fP]//g; + print ".Nm ".$retval."\n"; + } + + if (/\\fI/) { + $retval = $_; + $retval =~ s/[\\fI|\\fP]//g; + print ".Em ".$retval."\n"; + } + + if (/^I$/) { + $retval .= ".Em ".join(' ',@words)."\n"; + print $retval; + } + + if (/^PP$/) { + print "\n"; + } + + if (/^LP$/) { + print "\n"; + } + } +} + +sub MakeMacro +{ + my (@words); + @words = split(/\s+/,$line); + while($_ = shift (@words)) + { + if (/\\fB/ or /\\fI/) { + print "\n"; + $_ =~ s/\\fB/\.Nm /; + $_ =~ s/\\fI/\.Ar /; + $_ =~ s/\\fR//g; + + print $_; + print"\n"; + next; + } + + print $_." "; + } +} diff --git a/autoopts/tpl/man2texi.sh b/autoopts/tpl/man2texi.sh new file mode 100755 index 0000000..023e05b --- /dev/null +++ b/autoopts/tpl/man2texi.sh @@ -0,0 +1,27 @@ +#! /bin/sh + +## man2texi.sh -- script to convert man page isms to texi-isms +## +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + +sed \ + -e 's;\\fB\([^\\]*\)\\fP;@var{\1};' \ + -e 's;\\fI\([^\\]*\)\\fP;@i{\1};' diff --git a/autoopts/tpl/mbsd.lic b/autoopts/tpl/mbsd.lic new file mode 100644 index 0000000..408eb43 --- /dev/null +++ b/autoopts/tpl/mbsd.lic @@ -0,0 +1,31 @@ +Copyright (C) , all rights reserved. +This is free software. It is licensed for use, modification and +redistribution under the terms of the +Modified (3 clause) Berkeley Software Distribution License + + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. Neither the name ``'' nor the name of any other + contributor may be used to endorse or promote products derived + from this software without specific prior written permission. + + IS PROVIDED BY ``AS IS'' AND ANY EXPRESS +OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL OR ANY OTHER CONTRIBUTORS +BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +the Modified Berkeley Software Distribution License diff --git a/autoopts/tpl/mdoc2man.pl b/autoopts/tpl/mdoc2man.pl new file mode 100644 index 0000000..2168d0c --- /dev/null +++ b/autoopts/tpl/mdoc2man.pl @@ -0,0 +1,219 @@ +#!/usr/bin/perl + +## mdoc2man.pl -- Convert mdoc tags to man tags +## +## Author: Harlan Stenn +## +## +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + +### ToDo +# Properly implement -columns in the "my %lists" definition... +# +# .Xr requires at least 1 arg, the code here expects at least 2 +# +### + +package mdoc2man; +use strict; +use warnings; +use File::Basename; +use lib dirname(__FILE__); +use Mdoc qw(hs ns pp mapwords son soff stoggle gen_encloser); + +######## +## Basic +######## + +Mdoc::def_macro( '.Sh', sub { '.SH', hs, @_ }, raw => 1); +Mdoc::def_macro( '.Ss', sub { '.SS', hs, @_ }, raw => 1); +Mdoc::def_macro( '.Pp', sub { ".sp \\n(Ppu\n.ne 2\n" } ); +Mdoc::def_macro( '.Nd', sub { "\\- @_" } ); + +# Macros that enclose things +Mdoc::def_macro( '.Brq', gen_encloser(qw({ })) , greedy => 1 ); +Mdoc::def_macro( '.Op' , gen_encloser(qw([ ])) , greedy => 1 ); +Mdoc::def_macro( '.Qq' , gen_encloser(qw(" ")) , greedy => 1 ); +Mdoc::def_macro( '.Dq' , gen_encloser(qw(\*[Lq] \*[Rq])), greedy => 1 ); +Mdoc::def_macro( '.Ql' , gen_encloser(qw(\[oq] \[cq])) , greedy => 1 ); +Mdoc::def_macro( '.Sq' , gen_encloser(qw(\[oq] \[cq])) , greedy => 1 ); +Mdoc::def_macro( '.Pq' , gen_encloser(qw/( )/) , greedy => 1 ); +Mdoc::def_macro( '.D1' , sub { ".in +4\n", ns, @_ , ns , "\n.in -4" } , greedy => 1); + +Mdoc::def_macro( 'Oo', sub { '[', @_ } ); +Mdoc::def_macro( 'Oc', sub { ']', @_ } ); + +Mdoc::def_macro( 'Po', sub { '(', @_} ); +Mdoc::def_macro( 'Pc', sub { ')', @_ } ); + +Mdoc::def_macro( 'Bro', sub { '{', ns, @_ } ); +Mdoc::def_macro( 'Brc', sub { '}', @_ } ); + +Mdoc::def_macro( '.Oo', gen_encloser(qw([ ])), concat_until => '.Oc' ); +Mdoc::def_macro( '.Bro', gen_encloser(qw({ })), concat_until => '.Brc' ); +Mdoc::def_macro( '.Po', gen_encloser(qw/( )/), concat_until => '.Pc' ); + +Mdoc::def_macro( '.Ev', sub { @_ } ); +Mdoc::def_macro( '.An', sub { ".NOP ", @_, "\n.br" }, raw => 1 ); +Mdoc::def_macro( '.Li', sub { mapwords {"\\f[C]$_\\f[]"} @_ } ); +Mdoc::def_macro( '.Cm', sub { mapwords {"\\f\\*[B-Font]$_\\f[]"} @_ } ); +Mdoc::def_macro( '.Ic', sub { mapwords {"\\f\\*[B-Font]$_\\f[]"} @_ } ); +Mdoc::def_macro( '.Fl', sub { mapwords {"\\f\\*[B-Font]\\-$_\\f[]"} @_ } ); +Mdoc::def_macro( '.Ar', sub { mapwords {"\\f\\*[I-Font]$_\\f[]"} @_ } ); +Mdoc::def_macro( '.Em', sub { mapwords {"\\fI$_\\f[]"} @_ } ); +Mdoc::def_macro( '.Va', sub { mapwords {"\\fI$_\\f[]"} @_ } ); +Mdoc::def_macro( '.Sx', sub { mapwords {"\\fI$_\\f[]"} @_ } ); +Mdoc::def_macro( '.Xr', sub { "\\fC".(shift)."\\f[]\\fR(".(shift).")\\f[]", @_ } ); +Mdoc::def_macro( '.Fn', sub { "\\f\\*[B-Font]".(shift)."\\f[]\\fR()\\f[]" } ); +Mdoc::def_macro( '.Fn', sub { "\\fB".(shift)."\\f[]\\fR()\\f[]" } ); +Mdoc::def_macro( '.Fx', sub { "FreeBSD", @_ } ); +Mdoc::def_macro( '.Ux', sub { "UNIX", @_ } ); + +Mdoc::def_macro( '.No', sub { ".NOP", map { ($_, ns) } @_ } ); +Mdoc::def_macro( '.Pa', sub { mapwords {"\\fI$_\\f[]"} @_; } ); +{ + my $name; + Mdoc::def_macro('.Nm', sub { + $name = shift if (!$name); + "\\f\\*[B-Font]$name\\fP", @_ + } ); +} + +######## +## lists +######## + +my %lists = ( + bullet => sub { + Mdoc::def_macro('.It', sub { '.IP \fB\(bu\fP 2' }); + }, + + column => sub { + Mdoc::def_macro('.It', sub { '.IP \fB\(bu\fP 2' }); + }, + + tag => sub { + my (%opts) = @_; + + my $width = ''; + + if (exists $opts{width}) { + $width = ' '.((length $opts{width})+1); + } + + if (exists $opts{compact}) { + my $dobrns = 0; + Mdoc::def_macro('.It', sub { + my @ret = (".TP$width\n.NOP", hs); + if ($dobrns) { + ".br\n.ns\n", ns, @ret, @_; + } + else { + $dobrns = 1; + @ret, @_; + } + }, raw => 1); + } + else { + Mdoc::def_macro('.It', sub { + ".TP$width\n.NOP", hs, @_ + }, raw => 1); + } + }, +); + +Mdoc::set_Bl_callback(do { my $nested = 0; sub { + my $type = shift; + my %opts = Mdoc::parse_opts(@_); + if (defined $type && $type =~ /-(\w+)/ && exists $lists{$1}) { + + # Wrap nested lists with .RS and .RE + Mdoc::set_El_callback(sub { + return '.RE' if $nested-- > 1; + return '.PP'; + }); + + $lists{$1}->(%opts); + + if ($nested++) { + return ".RS"; + } + else { + return (); + } + } + else { + die "Invalid list type <$type>"; + } +}}, raw => 1); + +# don't bother with arguments for now and do what mdoc2man'.sh' did + +Mdoc::def_macro('.Bd', sub { ".br\n.in +4\n.nf" } ); +Mdoc::def_macro('.Ed', sub { ".in -4\n.fi" } ); + +Mdoc::set_Re_callback(sub { + my ($reference) = @_; + <<"REF"; +$reference->{authors}, +\\fI$reference->{title}\\fR, +$reference->{optional}\n.PP +REF +}); + +# Define all macros which have the same sub for inline and standalone macro +for (qw(Xr Em Ar Fl Ic Cm Qq Op Nm Pa Sq Li Va Brq Pq Fx Ux)) { + my $m = Mdoc::get_macro(".$_"); + Mdoc::def_macro($_, delete $m->{run}, %$m); +} + +sub print_line { + print shift; + print "\n"; +} + +sub run { + print <<'DEFS'; +.de1 NOP +. it 1 an-trap +. if \\n[.$] \,\\$*\/ +.. +.ie t \ +.ds B-Font [CB] +.ds I-Font [CI] +.ds R-Font [CR] +.el \ +.ds B-Font B +.ds I-Font I +.ds R-Font R +DEFS + + while (my ($macro, @args) = Mdoc::parse_line(\*STDIN, \&print_line)) { + my @ret = Mdoc::call_macro($macro, @args); + print_line(Mdoc::to_string(@ret)) if @ret; + } + return 0; +} + +exit run(@ARGV) unless caller; + +1; +__END__ diff --git a/autoopts/tpl/mdoc2texi.pl b/autoopts/tpl/mdoc2texi.pl new file mode 100644 index 0000000..570d18b --- /dev/null +++ b/autoopts/tpl/mdoc2texi.pl @@ -0,0 +1,185 @@ +#! /usr/bin/perl + +## mdoc2texi.pl -- Convert mdoc tags to texi tags +## +## Author: Harlan Stenn +## +## +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + +### To Do: + +# the Bl -column command needs work: +# - support for "-offset" +# - support for the header widths + +### + +package mdoc2texi; +use strict; +use warnings; +use File::Basename qw(dirname); +use lib dirname(__FILE__); +use Mdoc qw(ns pp hs mapwords gen_encloser nl); + +# Ignore commments +Mdoc::def_macro( '.\"', sub { () } ); + +# Enclosers +Mdoc::def_macro( '.An', sub { @_, ns, '@*' } ); +Mdoc::def_macro( '.Aq', gen_encloser(qw(< >)), greedy => 1); +Mdoc::def_macro( '.Bq', gen_encloser(qw([ ])), greedy => 1); +Mdoc::def_macro( '.Brq', gen_encloser(qw(@{ @})), greedy => 1); +Mdoc::def_macro( '.Pq', gen_encloser(qw/( )/), greedy => 1); +Mdoc::def_macro( '.Qq', gen_encloser(qw(" ")), greedy => 1); +Mdoc::def_macro( '.Op', gen_encloser(qw(@code{[ ]})), greedy => 1); +Mdoc::def_macro( '.Ql', gen_encloser(qw(@quoteleft{} @quoteright{})), + greedy => 1); +Mdoc::def_macro( '.Sq', gen_encloser(qw(@quoteleft{} @quoteright{})), + greedy => 1); +Mdoc::def_macro( '.Dq', gen_encloser(qw(@quotedblleft{} @quotedblright{})), + greedy => 1); +Mdoc::def_macro( '.Eq', sub { + my ($o, $c) = (shift, pop); + gen_encloser($o, $c)->(@_) +}, greedy => 1); +Mdoc::def_macro( '.D1', sub { "\@example\n", ns, @_, ns, "\n\@end example" }, + greedy => 1); +Mdoc::def_macro( '.Dl', sub { "\@example\n", ns, @_, ns, "\n\@end example" }, + greedy => 1); + +Mdoc::def_macro( '.Oo', gen_encloser(qw(@code{[ ]})), concat_until => '.Oc'); +Mdoc::def_macro( 'Oo', sub { '@code{[', ns, @_ } ); +Mdoc::def_macro( 'Oc', sub { @_, ns, pp(']}') } ); + +Mdoc::def_macro( '.Bro', gen_encloser(qw(@code{@{ @}})), concat_until => '.Brc'); +Mdoc::def_macro( 'Bro', sub { '@code{@{', ns, @_ } ); +Mdoc::def_macro( 'Brc', sub { @_, ns, pp('@}}') } ); + +Mdoc::def_macro( '.Po', gen_encloser(qw/( )/), concat_until => '.Pc'); +Mdoc::def_macro( 'Po', sub { '(', @_ } ); +Mdoc::def_macro( 'Pc', sub { @_, ')' } ); + +Mdoc::def_macro( '.Ar', sub { mapwords {"\@kbd{$_}"} @_ } ); +Mdoc::def_macro( '.Fl', sub { mapwords {"\@code{-$_}"} @_ } ); +Mdoc::def_macro( '.Cm', sub { mapwords {"\@code{-$_}"} @_ } ); +Mdoc::def_macro( '.Ic', sub { mapwords {"\@code{$_}"} @_ } ); +Mdoc::def_macro( '.Cm', sub { mapwords {"\@code{$_}"} @_ } ); +Mdoc::def_macro( '.Li', sub { mapwords {"\@code{$_}"} @_ } ); +Mdoc::def_macro( '.Va', sub { mapwords {"\@code{$_}"} @_ } ); +Mdoc::def_macro( '.Em', sub { mapwords {"\@emph{$_}"} @_ } ); +Mdoc::def_macro( '.Fn', sub { '@code{'.(shift).'()}' } ); +Mdoc::def_macro( '.Ss', sub { "\@subsubsection", hs, @_ }); +Mdoc::def_macro( '.Sh', sub { + my $name = "@_"; + "\@node", hs, "$name\n", ns, "\@subsection", hs, $name + }); +Mdoc::def_macro( '.Ss', sub { "\@subsubsection", hs, @_ }); +Mdoc::def_macro( '.Xr', sub { '@code{'.(shift).'('.(shift).')}', @_ } ); +Mdoc::def_macro( '.Sx', gen_encloser(qw(@ref{ })) ); +Mdoc::def_macro( '.Ux', sub { '@sc{unix}', @_ } ); +Mdoc::def_macro( '.Fx', sub { '@sc{freebsd}', @_ } ); +{ + my $name; + Mdoc::def_macro('.Nm', sub { + $name = shift || $ENV{AG_DEF_PROG_NAME} || 'XXX' if (!$name); + "\@code{$name}" + } ); +} +Mdoc::def_macro( '.Pa', sub { mapwords {"\@file{$_}"} @_ } ); +Mdoc::def_macro( '.Pp', sub { '' } ); + +# Setup references + +Mdoc::def_macro( '.Rs', sub { "\@*\n", @_ } ); +Mdoc::set_Re_callback(sub { + my ($reference) = @_; + "@*\n", ns, $reference->{authors}, ',', "\@emph{$reference->{title}}", + ',', $reference->{optional} + }); + +# Set up Bd/Ed + +my %displays = ( + literal => [ '@verbatim', '@end verbatim' ], +); + +Mdoc::def_macro( '.Bd', sub { + (my $type = shift) =~ s/^-//; + die "Not supported display type <$type>" + if not exists $displays{ $type }; + + my $orig_ed = Mdoc::get_macro('.Ed'); + Mdoc::def_macro('.Ed', sub { + Mdoc::def_macro('.Ed', delete $orig_ed->{run}, %$orig_ed); + $displays{ $type }[1]; + }); + $displays{ $type }[0] + }); +Mdoc::def_macro('.Ed', sub { die '.Ed used but .Bd was not seen' }); + +# Set up Bl/El + +my %lists = ( + bullet => [ '@itemize @bullet', '@end itemize' ], + tag => [ '@table @asis', '@end table' ], + column => [ '@table @asis', '@end table' ], +); + +Mdoc::set_Bl_callback(sub { + my $type = shift; + die "Specify a list type" if not defined $type; + $type =~ s/^-//; + die "Not supported list type <$type>" if not exists $lists{ $type }; + Mdoc::set_El_callback(sub { $lists{ $type }[1] }); + $lists{ $type }[0] + }); +Mdoc::def_macro('.It', sub { '@item', hs, @_ }); + +for (qw(Aq Bq Brq Pq Qq Ql Sq Dq Eq Ar Fl Ic Pa Op Cm Li Fx Ux Va)) { + my $m = Mdoc::get_macro(".$_"); + Mdoc::def_macro($_, delete $m->{run}, %$m); +} + +sub print_line { + my $s = shift; + $s =~ s/\\&//g; + print "$s\n"; +} + +sub preprocess_args { + $_ =~ s/([{}])/\@$1/g for @_; +} + +sub run { + while (my ($macro, @args) = Mdoc::parse_line(\*STDIN, \&print_line, + \&preprocess_args) + ) { + my @ret = Mdoc::call_macro($macro, @args); + if (@ret) { + my $s = Mdoc::to_string(@ret); + print_line($s); + } + } + return 0; +} + +exit run(@ARGV) unless caller; diff --git a/autoopts/tpl/optcode.tlib b/autoopts/tpl/optcode.tlib new file mode 100644 index 0000000..f6b4dc6 --- /dev/null +++ b/autoopts/tpl/optcode.tlib @@ -0,0 +1,869 @@ +[= autogen5 template + +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + +=][= + +;;; +;;; Compute the usage line. It is complex because we are trying to +;;; encode as much information as we can and still be comprehensible. +;;; +;;; The rules are: If any options have a "value" attribute, then +;;; there are flags allowed, so include "-" on the usage line. +;;; If the program has the "long-opts" attribute set, then we must +;;; have "" or "--" on the line, depending on +;;; whether or not there are flag options. If any options take +;;; arguments, then append "[]" to the flag description and +;;; "[{=| }]" to the option-name/name descriptions. We will not +;;; worry about being correct if every option has a required argument. +;;; Finally, if there are no minimum occurrence counts (i.e. all +;;; options are optional), then we put square brackets around the +;;; syntax. +;;; +;;; Compute the option arguments +;;; +(define tmp-val "") +(if (exist? "flag.arg-type") + (set! tmp-val "[{=| }]")) + +(define usage-line (string-append "Usage: %s " + + ;; If at least one option has a minimum occurrence count + ;; we use curly brackets around the option syntax. + ;; + (if (not (exist? "flag.min")) "[ " "{ ") + + (if (exist? "flag.value") + (string-append "-" + (if (exist? "flag.arg-type") " []" "") + (if (exist? "long-opts") " | " "") ) + (if (not (exist? "long-opts")) + (string-append "" tmp-val) "" ) ) + + (if (exist? "long-opts") + (string-append "--" tmp-val) "" ) + + (if (not (exist? "flag.min")) " ]..." " }...") +) ) + +(if (exist? "argument") + (set! usage-line (string-append usage-line + + ;; the USAGE line plus the program name plus the argument goes + ;; past 80 columns, then break the line, else separate with space + ;; + (if (< 80 (+ (string-length usage-line) + (len "argument") + (string-length prog-name) )) + " \\\n\t\t" + " " + ) + + (get "argument") + )) +) + +(define usage-text (string-append prog-name + (if (exist? "package") + (string-append " (" (get "package") ")") + "" ) + " - " (get "prog-title") + (if (and (exist? "version") (not (exist? "gnu-usage"))) + (string-append " - Ver. " (get "version")) + "" ) + "\n" usage-line "\n" +)) =][= # + +// # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= + +INCLUDE "optmain.tlib" + +=] +#ifndef __doxygen__ +#define OPTION_CODE_COMPILE 1 +#include "[= (define lib-externs "") header-file=]" +#include +#include +[= + + (if (== (get "main.main-type" "") "for-each") + (emit "\n#include ") ) + +=] +#include +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif +extern FILE * option_usage_fp;[= + +IF (not (exist? "copyright")) + +=] +#define zCopyright NULL +#define zLicenseDescrip NULL[= +ELSE =][= + CASE (define cright-owner (get "copyright.owner" (get "copyright.author"))) + (get "copyright.type") =][= + + = note =][= + (set! tmp-text (get "copyright.text")) + (define ext-text tmp-text) =][= + + ~~* . =][= + (define ext-text + (license-description (get "copyright.type") + prog-name "" cright-owner ) ) + + (set! tmp-text + (license-info (get "copyright.type") + prog-name "" cright-owner (get "copyright.date") ) ) + =][= + + * =][= + (set! tmp-text (sprintf + "Copyright (C) %s %s, all rights reserved" + (get "copyright.date") cright-owner )) + (define ext-text tmp-text) =][= + + ESAC =][= + +(set! tmp-text (string-append version-text "\n" tmp-text)) +(if (not omit-nls-code) + (put-xget "pzCopyright" tmp-text)) + +(string-append "\n#define zCopyright (" + (string-table-add-ref opt-strs tmp-text) + ")\n#define zLicenseDescrip (" + + (if (= tmp-text ext-text) + "zCopyright" + (begin + (set! ext-text (string-append (shell (string-append + "${CLexe} --fill -I0 -W75 <<_EOF_\n" ext-text "\n_EOF_" )) "\n" )) + + (if (not omit-nls-code) + (put-xget "pzCopyNotice" ext-text)) + (string-table-add-ref opt-strs ext-text) + ) ) + ")\n" ) =][= + +ENDIF "copyright" =][= + + (define usage-proc (get "usage")) + (if (< 1 (string-length usage-proc)) + (emit (string-append "\nextern tUsageProc " usage-proc ";")) + (set! usage-proc "optionUsage") + ) + +=] +[= INVOKE join-or-expand join-type = "include" =] +#ifndef NULL +# define NULL 0 +#endif + +/** + * static const strings for [= prog-name =] options + */[= + (out-resume "home-list") \=][= + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= + +FOR flag "\n" =][= + (define flag-index (for-index)) =][= + INVOKE emit-opt-strs =][= + + (if (exist? "lib-name") (begin + (set! lib-opt-ptr (string->c-name! (string-append + (get "lib-name") "_" (get "name") "_optDesc_p"))) + (set! lib-externs (string-append lib-externs + (sprintf "tOptDesc * const %-16s = optDesc + %d;\n" + lib-opt-ptr (for-index) ) )) + ) ) =][= + +ENDFOR flag =][= + +INVOKE help-strs =][= +INVOKE decl-callbacks =][= + +IF (exist? "version") =][= + + IF (exist? "version-proc") =] +#define VER_PROC [= (get "version-proc") =][= + ELIF (. guarded-test-main) =] +#ifdef [=(. main-guard) =] +# define VER_PROC optionVersionStderr +#else +# define VER_PROC optionPrintVersion +#endif /* [=(. main-guard)=] */[= + ELSE =] +#define VER_PROC optionPrintVersion[= + ENDIF guarded-test-main =][= + +ENDIF there is a version + +=] +[= INVOKE emit-option-desc-table =] +[= (. lib-externs) =] +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/** Reference to the upper cased version of [= prog-name =]. */ +#define zPROGNAME ([= (string-table-add-ref opt-strs pname-up) =]) +/** Reference to the title line for [= prog-name =] usage. */ +#define zUsageTitle ([= + (define homerc-ct 0) + (define homerc-txt "") + (if (not omit-nls-code) + (put-xget "pzUsageTitle" usage-text)) + + (string-table-add-ref opt-strs usage-text) =]) +[= +FOR homerc =][= + (set! tmp-text (get "homerc")) + (if (> (string-length tmp-text) 0) (begin + (set! homerc-ct (+ 1 homerc-ct)) + (set! homerc-txt (string-append homerc-txt + "\n " (string-table-add-ref opt-strs tmp-text) "," )) + ) ) =][= +ENDFOR homerc =][= +IF (> homerc-ct 0) \=] +/** [= prog-name =] configuration file name. */ +#define zRcName ([= + (set! tmp-text (get "rcfile" + (string-append "." pname-down "rc") )) + (string-table-add-ref opt-strs tmp-text) =]) +/** Directories to search for [= prog-name =] config files. */ +static char const * const apzHomeList[= + (sprintf "[%u] = {%s\n NULL };" (+ 1 homerc-ct) homerc-txt) =][= + +ELSE \=] +/** There is no [= prog-name =] configuration file. */ +#define zRcName NULL +/** There are no directories to search for [= prog-name =] config files. */ +#define apzHomeList NULL[= +ENDIF =] +/** The [= prog-name =] program bug email address. */ +#define zBugsAddr ([= +(out-push-new) \=] +s/@[a-z]*{\([^{@}]*\)}/'\1'/g +s=@@=[= prog-name =]=g +/^@\(end *\)*example/d +s/^@item *$/\ +/[= + +(define patch-text-sed + (sprintf "sed %s <<\\_EODetail_ | ${CLexe} --fill -I0 -W75\n" + (raw-shell-str (out-pop #t)) ) ) + +(define patch-text (lambda (t-name) + (set! tmp-text (string-append + + (shell (string-append + patch-text-sed + (get t-name) + "\n_EODetail_" )) + "\n" )) )) + +(if (exist? "copyright.eaddr") + (string-table-add-ref opt-strs (get "copyright.eaddr")) + (if (exist? "eaddr") + (string-table-add-ref opt-strs (get "eaddr")) + "NULL" +) ) =]) +/** Clarification/explanation of what [= prog-name =] does. */ +#define zExplain ([= + +(if (or (exist? "explain") (== (get "main.main-type") "for-each")) + (begin + (if (exist? "explain") + (patch-text "explain") + (set! tmp-text "") ) + + (if (== (get "main.main-type") "for-each") + (set! tmp-text (string-append tmp-text +"\nIf no arguments are provided, input arguments are read from stdin, +one per line; blank and '" +(if (exist? "main.comment-char") (get "main.comment-char") "#") +"'-prefixed lines are comments.\n" +(if (exist? "main.interleaved") + "Options may appear in the input interspersed with the 'normal' input.\n" + "") +"'stdin' may not be a terminal (tty).\n" )) ) + + (if (not omit-nls-code) + (put-xget "pzExplain" tmp-text)) + (string-table-add-ref opt-strs tmp-text) + ) + "NULL" +) =]) +/** Extra detail explaining what [= prog-name =] does. */ +#define zDetail ([= + +(if (exist? "detail") + (begin + (patch-text "detail") + (if (not omit-nls-code) + (put-xget "pzDetail" tmp-text)) + (string-table-add-ref opt-strs tmp-text) + ) + "NULL" +) =]) +/** The full version string for [= prog-name =]. */ +#define zFullVersion ([= + +(if (exist? "version") (begin + (if (not omit-nls-code) + (put-xget "pzFullVersion" version-text)) + (string-table-add-ref opt-strs version-text) ) + "NULL") =])[= +(tpl-file-line extract-fmt) +=][= + + IF (. omit-nls-code) =] +#define OPTPROC_BASE OPTPROC_NONE +#define translate_option_strings NULL +[= ELSE =] +#if defined(ENABLE_NLS) +# define OPTPROC_BASE OPTPROC_TRANSLATE[= +CASE no-xlate =][= +!E =][= += opt-cfg =] | OPTPROC_NXLAT_OPT_CFG[= += opt =] | OPTPROC_NXLAT_OPT[= +* =][= (error "invalid value for 'no-xlate'") =][= +ESAC no-xlate =] + static tOptionXlateProc translate_option_strings; +#else +# define OPTPROC_BASE OPTPROC_NONE +# define translate_option_strings NULL +#endif /* ENABLE_NLS */ +[= ENDIF no-nls =][= + IF (exist? "resettable") =] +#ifndef optArgBucket_t +#define opt_arg_union_t optArgBucket_t +#endif +/** Compiled-in initial values for [= prog-name =] options. */ +static opt_arg_union_t const original_[=(. pname-down)=]_defaults[ [= +(. UP-prefix) =]OPTION_CT ] = { +[= (shell (string-append + "sed '$s@},@} @' <<\\_EOF_" default-text "\n_EOF_\n")) =] +}; +/** Compiled-in initial values for [= prog-name =] option cookies. */ +static void * const original_[=(. pname-down)=]_cookies[ [= +(. UP-prefix) =]OPTION_CT ] = { +[= + (shell (string-append "${CLexe} -I4 -S, <<\\_EOF_\n" default-cookie "_EOF_")) +=] +}; +[= ENDIF resettable=] +[= INVOKE emit-help-text help-type = full \=] +[= INVOKE emit-help-text help-type = short =] +#endif /* not defined __doxygen__ */ +[= INVOKE emit-option-callbacks =] +/** + * The directory containing the data associated with [= prog-name =]. + */ +#ifndef PKGDATADIR +# define PKGDATADIR "" +#endif + +/** + * Information about the person or institution that packaged [= prog-name =] + * for the current distribution. + */ +#ifndef WITH_PACKAGER +# define [=(. pname)=]_packager_info NULL +#else +/** Packager information for [= prog-name =]. */ +static char const [=(. pname)=]_packager_info[] = + "Packaged by " WITH_PACKAGER + +# ifdef WITH_PACKAGER_VERSION + " ("WITH_PACKAGER_VERSION")" +# endif + +# ifdef WITH_PACKAGER_BUG_REPORTS + "\nReport [=(. pname)=] bugs to " WITH_PACKAGER_BUG_REPORTS +# endif + "\n"; +#endif +#ifndef __doxygen__ +[= + (out-suspend "home-list") + (emit-string-table opt-strs) + (out-resume "home-list") + (define put-shell-main (== (get "main.main-type") "shell-process")) + (out-pop #t) +=] +#endif /* __doxygen__ */ +/** + * The option definitions for [= prog-name =]. The one structure that + * binds them all. + */ +tOptions [=(. pname)=]Options = { + OPTIONS_STRUCT_VERSION, + 0, NULL, /* original argc + argv */ + ( OPTPROC_BASE[= + (define tmp-val "\n + OPTPROC_") + (if (not (exist? "allow-errors")) (emit tmp-val "ERRSTOP")) + (if (exist? "flag.value") (emit tmp-val "SHORTOPT")) + (if (exist? "long-opts") (emit tmp-val "LONGOPT")) + (if (not (exist? "flag.min")) (emit tmp-val "NO_REQ_OPT")) + (if (exist? "flag.disable") (emit tmp-val "NEGATIONS")) + (if (>= number-opt-index 0) (emit tmp-val "NUM_OPT")) + (if (exist? "environrc") (emit tmp-val "ENVIRON")) + (if (not (exist? "argument")) (emit tmp-val "NO_ARGS") + (if (not (==* (get "argument") "[")) (emit tmp-val "ARGS_REQ"))) + (if (exist? "reorder-args") (emit tmp-val "REORDER")) + (if (exist? "gnu-usage") (emit tmp-val "GNUUSAGE")) + (if (exist? "no-misuse-usage") (emit tmp-val "MISUSE")) + (if (exist? "vendor-opt") (emit tmp-val "VENDOR_OPT")) + (if put-shell-main (emit tmp-val "SHELL_OUTPUT")) + =] ), + 0, NULL, /* current option index, current option */ + NULL, NULL, zPROGNAME, + zRcName, zCopyright, zLicenseDescrip, + zFullVersion, apzHomeList, zUsageTitle, + zExplain, zDetail, optDesc, + zBugsAddr, /* address to send bugs to */ + NULL, NULL, /* extensions/saved state */ + [= (. usage-proc) =], /* usage procedure */ + translate_option_strings, /* translation procedure */ + /* + * Indexes to special options + */ + { [= (if (exist? "no-libopts") "NO_EQUIVALENT" + (string-append INDEX-pfx "MORE_HELP")) + =], /* more-help option index */ + [=IF (and (exist? "homerc") (not (exist? "disable-save"))) + =][= (. INDEX-pfx) =]SAVE_OPTS[= + ELSE =]NO_EQUIVALENT[= + ENDIF=], /* save option index */ + [= (if (>= number-opt-index 0) number-opt-index "NO_EQUIVALENT") + =], /* '-#' option index */ + [= (if (>= default-opt-index 0) default-opt-index "NO_EQUIVALENT") + =] /* index of default opt */ + }, + [= (. option-ct) =] /* full option count */, [= + (count "flag")=] /* user option count */, + [= (. pname) =]_full_usage, [= (. pname) =]_short_usage, +[= IF (exist? "resettable") \=] + original_[=(. pname-down)=]_defaults, original_[=(. pname-down)=]_cookies, +[= ELSE \=] + NULL, NULL, +[= ENDIF \=] + PKGDATADIR, [=(. pname)=]_packager_info +}; +[= + +FOR lib-name + +=] +tOptDesc* [= (string->c-name! (get "lib-name")) =]_optDesc_p = NULL;[= + +ENDFOR =][= + +IF (not omit-nls-code) =][= + INVOKE emit-nls-code =][= +ENDIF + +=] +#ifdef __cplusplus +} +#endif[= # + +// # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= + +DEFINE emit-nls-code + +=] +#if ENABLE_NLS +/** + * This code is designed to translate translatable option text for the + * [= prog-name =] program. These translations happen upon entry + * to optionProcess(). + */ +#include +#include +#include +#include +#ifdef HAVE_DCGETTEXT +# include +#endif +#include + +static char * AO_gettext(char const * pz); +static void coerce_it(void ** s); + +/** + * AutoGen specific wrapper function for gettext. It relies on the macro _() + * to convert from English to the target language, then strdup-duplicates the + * result string. It tries the "libopts" domain first, then whatever has been + * set via the \a textdomain(3) call. + * + * @param[in] pz the input text used as a lookup key. + * @returns the translated text (if there is one), + * or the original text (if not). + */ +static char * +AO_gettext(char const * pz) +{ + char * res; + if (pz == NULL) + return NULL; +#ifdef HAVE_DCGETTEXT + /* + * While processing the option_xlateable_txt data, try to use the + * "libopts" domain. Once we switch to the option descriptor data, + * do *not* use that domain. + */ + if (option_xlateable_txt.field_ct != 0) { + res = dgettext("libopts", pz); + if (res == pz) + res = (char *)VOIDP(_(pz)); + } else + res = (char *)VOIDP(_(pz)); +#else + res = (char *)VOIDP(_(pz)); +#endif + if (res == pz) + return res; + res = strdup(res); + if (res == NULL) { + fputs(_("No memory for duping translated strings\n"), stderr); + exit([=(. nomem-exit-code)=]); + } + return res; +} + +/** + * All the pointers we use are marked "* const", but they are stored in + * writable memory. Coerce the mutability and set the pointer. + */ +static void coerce_it(void ** s) { *s = AO_gettext(*s); +} + +/** + * Translate all the translatable strings in the [=(. pname)=]Options + * structure defined above. This is done only once. + */ +static void +translate_option_strings(void) +{ + tOptions * const opts = &[=(. pname)=]Options; + + /* + * Guard against re-translation. It won't work. The strings will have + * been changed by the first pass through this code. One shot only. + */ + if (option_xlateable_txt.field_ct != 0) { + /* + * Do the translations. The first pointer follows the field count + * field. The field count field is the size of a pointer. + */ + char ** ppz = (char**)VOIDP(&(option_xlateable_txt)); + int ix = option_xlateable_txt.field_ct; + + do { + ppz++; /* skip over field_ct */ + *ppz = AO_gettext(*ppz); + } while (--ix > 0); + /* prevent re-translation and disable "libopts" domain lookup */ + option_xlateable_txt.field_ct = 0; +[= + FOR field IN pzCopyright pzCopyNotice pzFullVersion =] + coerce_it(VOIDP(&(opts->[= field =])));[= + ENDFOR =][= + + IF (not (exist? "full-usage"))=][= + FOR field IN pzUsageTitle pzExplain pzDetail =] + coerce_it(VOIDP(&(opts->[= field =])));[= + ENDFOR =] + { + tOptDesc * od = opts->pOptDesc; + for (ix = opts->optCt; ix > 0; ix--, od++) + coerce_it(VOIDP(&(od->pzText))); + }[= + ENDIF =] + } +} +#endif /* ENABLE_NLS */ + +#ifdef DO_NOT_COMPILE_THIS_CODE_IT_IS_FOR_GETTEXT +/** I18N function strictly for xgettext. Do not compile. */ +static void bogus_function(void) { + /* TRANSLATORS: + + The following dummy function was crated solely so that xgettext can + extract the correct strings. These strings are actually referenced + by a field name in the [=(. pname)=]Options structure noted in the + comments below. The literal text is defined in [=(. pname)=]_opt_strs. + + NOTE: the strings below are segmented with respect to the source string + [=(. pname)=]_opt_strs. The strings above are handed off for translation + at run time a paragraph at a time. Consequently, they are presented here + for translation a paragraph at a time. + + ALSO: often the description for an option will reference another option + by name. These are set off with apostrophe quotes (I hope). Do not + translate option names. + */[= + +(out-resume "xget") +(emit (out-pop #t)) + +(out-push-new) \=] +test "X${CDPATH}" = X || CDPATH='' +incdir=[= (if (defined? 'inc-dir) inc-dir "") ;;' 4emacs =] +test -d "$incdir" || incdir=`dirname [=(tpl-file #t)=]`/.. +incdir=`cd $incdir/autoopts && pwd` +test -f ${incdir}/usage-txt.h && { + sedcmd='/LIBOPTS-MESSAGES:/,/END-[= + + (if (and (exist? "full-usage") (exist? "short-usage")) + "LIBOPTS-MESSAGES" + "USAGE-TEXT" ) =]/p' + sed -n "$sedcmd" ${incdir}/usage-txt.h +} +[= (shell (out-pop #t)) =] +} +#endif /* uncompilable code */[= + +ENDDEF emit-nls-code + +=][= + +DEFINE emit-option-desc-table + +=] +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/** + * Define the [= prog-name =] Option Descriptions. + * This is an array of [=(. UP-prefix)=]OPTION_CT entries, one for each + * option that the [= prog-name =] program responds to. + */ +static tOptDesc optDesc[[= +(define default-text "") +(define default-cookie "") +UP-prefix +=]OPTION_CT] = {[= + +FOR flag "\n" =][= + (define flag-index (for-index)) =][= + + INVOKE emit-opt-desc =][= + +ENDFOR flag + +=][= + +IF (exist? "resettable") + +=] + + { /* entry idx, value */ [= + (set! default-text (string-append default-text + "\n { NULL }, /* resettable */" )) + (set! default-cookie (string-append default-cookie "NULL\n" )) + INDEX-pfx =]RESET_OPTION, [= (. VALUE-pfx) =]RESET_OPTION, + /* equiv idx value */ NO_EQUIVALENT, [= (. VALUE-pfx) =]RESET_OPTION, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ RESET_FLAGS, AOUSE_RESET_OPTION, + /* last opt argumnt */ { NULL }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ optionResetOpt, + /* desc, NAME, name */ RESET_DESC, NULL, RESET_name, + /* disablement strs */ NULL, NULL },[= + +ENDIF + +=][= + +IF (exist? "version") =] + + { /* entry idx, value */ [= + (set! default-text (string-append default-text + "\n { NULL }, /* version */" )) + (set! default-cookie (string-append default-cookie "NULL\n" )) + INDEX-pfx =]VERSION, [= (. VALUE-pfx) =]VERSION, + /* equiv idx value */ NO_EQUIVALENT, [= (. VALUE-pfx) =]VERSION, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ VER_FLAGS, AOUSE_VERSION, + /* last opt argumnt */ { [=(if (exist? "version-type") + (string-append "(char const*)\"" (get "version-type") "\"") + "NULL")=] }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ VER_PROC, + /* desc, NAME, name */ VER_DESC, NULL, VER_name, + /* disablement strs */ NULL, NULL }, + +[= + +ENDIF =] + + { /* entry idx, value */ [= + (set! default-text (string-append default-text + "\n { NULL }, /* help */" )) + (set! default-cookie (string-append default-cookie "NULL\n" )) + INDEX-pfx =]HELP, [= (. VALUE-pfx) =]HELP, + /* equiv idx value */ NO_EQUIVALENT, [= (. VALUE-pfx) =]HELP, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ OPTST_IMM | OPTST_NO_INIT, AOUSE_HELP, + /* last opt argumnt */ { NULL }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ doUsageOpt, + /* desc, NAME, name */ HELP_DESC, NULL, HELP_name, + /* disablement strs */ NULL, NULL }[= + +IF (not (exist? "no-libopts")) =], + + { /* entry idx, value */ [= + (set! default-text (string-append default-text + "\n { NULL }, /* more-help */" )) + (set! default-cookie (string-append default-cookie "NULL\n" )) + INDEX-pfx =]MORE_HELP, [= (. VALUE-pfx) =]MORE_HELP, + /* equiv idx value */ NO_EQUIVALENT, [= (. VALUE-pfx) =]MORE_HELP, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ MORE_HELP_FLAGS, AOUSE_MORE_HELP, + /* last opt argumnt */ { NULL }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ optionPagedUsage, + /* desc, NAME, name */ MORE_HELP_DESC, NULL, MORE_HELP_name, + /* disablement strs */ NULL, NULL }[= + +ENDIF not have no-libopts =][= + +IF (exist? "usage-opt") =], + + { /* entry idx, value */ [= + (set! default-text (string-append default-text + "\n { NULL }, /* usage-opt */" )) + (set! default-cookie (string-append default-cookie "NULL\n" )) + INDEX-pfx =]USAGE, [= (. VALUE-pfx) =]USAGE, + /* equiv idx value */ NO_EQUIVALENT, [= (. VALUE-pfx) =]USAGE, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ OPTST_IMM | OPTST_NO_INIT, AOUSE_USAGE, + /* last opt argumnt */ { NULL }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ doUsageOpt, + /* desc, NAME, name */ USAGE_DESC, NULL, USAGE_name, + /* disablement strs */ NULL, NULL }[= + +ENDIF have usage-opt =][= + +IF (exist? "homerc") =][= + IF (not (exist? "disable-save")) =], + + { /* entry idx, value */ [= + (set! default-text (string-append default-text + "\n { NULL }, /* save-opts */" )) + (set! default-cookie (string-append default-cookie "NULL\n" )) + INDEX-pfx =]SAVE_OPTS, [= + (if (not (exist? "disable-save")) + (string-append VALUE-pfx "SAVE_OPTS") + "0") =], + /* equiv idx value */ NO_EQUIVALENT, [= (. VALUE-pfx) =]SAVE_OPTS, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ OPTST_SET_ARGTYPE(OPARG_TYPE_STRING) + | OPTST_ARG_OPTIONAL | OPTST_NO_INIT, AOUSE_SAVE_OPTS, + /* last opt argumnt */ { NULL }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ NULL, + /* desc, NAME, name */ SAVE_OPTS_DESC, NULL, SAVE_OPTS_name, + /* disablement strs */ NULL, NULL }[= + + ENDIF disable-save does not exist =], + + { /* entry idx, value */ [= + (set! default-text (string-append default-text + "\n { NULL }, /* load-opts */" )) + (set! default-cookie (string-append default-cookie "NULL\n" )) + INDEX-pfx =]LOAD_OPTS, [= + (if (not (exist? "disable-load")) + (string-append VALUE-pfx "LOAD_OPTS") + "0") =], + /* equiv idx value */ NO_EQUIVALENT, [= (. VALUE-pfx) =]LOAD_OPTS, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, NOLIMIT, 0, + /* opt state flags */ OPTST_SET_ARGTYPE(OPARG_TYPE_STRING) + | OPTST_DISABLE_IMM[= + (if (exist? "disable-load") "| OPTST_NO_COMMAND") =], AOUSE_LOAD_OPTS, + /* last opt argumnt */ { NULL }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ optionLoadOpt, + /* desc, NAME, name */ [= + (if (exist? "disable-load") "NULL, NULL, NULL" + "LOAD_OPTS_DESC, LOAD_OPTS_NAME, LOAD_OPTS_name")=], + /* disablement strs */ [= + (if (exist? "disable-load") "NULL, NULL" + "NO_LOAD_OPTS_name, LOAD_OPTS_pfx")=] }[= + +ENDIF have homerc =][= + +IF (exist? "vendor-opt") =], + + { /* entry idx, value */ [= + (set! default-text (string-append default-text + "\n { NULL }, /* vendor-opt */" )) + (set! default-cookie (string-append default-cookie "NULL\n" )) + INDEX-pfx =]VENDOR_OPT, [= (. VALUE-pfx) =]VENDOR_OPT, + /* equiv idx value */ NO_EQUIVALENT, [= (. VALUE-pfx) =]VENDOR_OPT, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, NOLIMIT, 0, + /* opt state flags */ OPTST_SET_ARGTYPE(OPARG_TYPE_STRING) + | OPTST_IMM | OPTST_TWICE, AOUSE_VENDOR_OPT, + /* last opt argumnt */ { NULL }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ optionVendorOption, + /* desc, NAME, name */ VEND_DESC, NULL, VEND_name, + /* disablement strs */ NULL, NULL }[= + +ENDIF have vendor-opt =] +}; +[= + +ENDDEF emit-option-desc-table + +/* + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * opthead.tpl ends here */ \=] diff --git a/autoopts/tpl/opthead.tlib b/autoopts/tpl/opthead.tlib new file mode 100644 index 0000000..5b024b4 --- /dev/null +++ b/autoopts/tpl/opthead.tlib @@ -0,0 +1,709 @@ +[= autogen5 template -*- Mode: C -*- + +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + +=] +/** + * This file contains the programmatic interface to the Automated + * Options generated for the [=prog-name=] program. + * These macros are documented in the AutoGen info file in the + * "AutoOpts" chapter. Please refer to that doc for usage help. + */ +[= + (emit (make-header-guard "autoopts")) + (if (exist? "config-header") + (ag-fprintf 0 "\n#include \"%s\"" (get "config-header")) ) + + (emit "\n#include \n" + "#include \n" + "#include \n") + + (define option-ct 0) + (define index-sep-str "") + + (set! max-name-len (+ max-name-len 2)) + (define index-fmt (sprintf "%%s\n %s%%-%ds=%%3d" INDEX-pfx max-name-len)) + + (define add-opt-index (lambda (opt-nm) (begin + (ag-fprintf 0 index-fmt index-sep-str opt-nm option-ct) + (set! option-ct (+ option-ct 1)) + (set! index-sep-str ",") + ) ) ) =][= + +IF (not (exist? "library")) =] +/** + * Ensure that the library used for compiling this generated header is at + * least as new as the version current when the header template was released + * (not counting patch version increments). Also ensure that the oldest + * tolerable version is at least as old as what was current when the header + * template was released. + */ +#define AO_TEMPLATE_VERSION [=(. ao-template-ver)=] +#if (AO_TEMPLATE_VERSION < OPTIONS_MINIMUM_VERSION) \ + || (AO_TEMPLATE_VERSION > OPTIONS_STRUCT_VERSION) +# error option template version mismatches autoopts/options.h header + Choke Me. +#endif +[= ENDIF not a library =] +#if GCC_VERSION > 40400 +#define NOT_REACHED __builtin_unreachable(); +#else +#define NOT_REACHED +#endif + +/** + * Enumeration of each option type for [= prog-name =] + */ +typedef enum {[= +FOR flag =][= + (if (exist? "documentation") + (set! option-ct (+ option-ct 1)) + (add-opt-index (get-up-name "name")) + ) + =][= +ENDFOR flag =][= + +IF (exist? "library") =], + LIBRARY_OPTION_COUNT[= + +ELSE not exists library =][= + + (if (exist? "resettable") (add-opt-index "RESET_OPTION")) + (if (exist? "version") (add-opt-index "VERSION")) + (add-opt-index "HELP") + (if (not (exist? "no-libopts")) (add-opt-index "MORE_HELP")) + (if (exist? "usage-opt") (add-opt-index "USAGE")) + (if (exist? "vendor-opt") (add-opt-index "VENDOR_OPT")) + + (if (exist? "homerc") (begin + (if (not (exist? "disable-save")) (add-opt-index "SAVE_OPTS")) + (add-opt-index "LOAD_OPTS") + ) ) =][= +ENDIF not exist library =] +} te[=(. Cap-prefix)=]OptIndex; +/** count of all options for [= prog-name =] */ +#define [=(. UP-prefix)=]OPTION_CT [= (. option-ct) =][= +IF (exist? "version") =] +/** [= prog-name =] version */ +#define [=(. pname-up)=]_VERSION [=(c-string (get "version"))=] +/** Full [= prog-name =] version text */ +#define [=(. pname-up)=]_FULL_VERSION [=(c-string version-text) =][= +ENDIF (exist? version) =] + +/** + * Interface defines for all options. Replace "n" with the UPPER_CASED + * option name (as in the te[=(. Cap-prefix)=]OptIndex enumeration above). + * e.g. HAVE_[=(. UP-prefix)=]OPT([= (get-up-name "flag[].name") =]) + */[= + +IF (exist? "library") + +=] +/** pointer to the library handling procedure. */ +extern tOptDesc * const [= (. lib-opt-ptr) =];[= + +ENDIF is a library =][= + +CASE guard-option-names =][= +!E =][= + (set! tmp-val (string-append "[" INDEX-pfx "## n]")) + =][= + += full-enum =][= + (set! tmp-val "[n]") =][= + +=* no-warn =][= + (set! tmp-val (string-append "[" INDEX-pfx "## n]")) + =][= + +* =][= + (set! tmp-val (string-append "[" INDEX-pfx "## n]")) + =][= + +ESAC =][= + +(if (exist? "library") + (set! tmp-val (string-append "(" lib-opt-ptr tmp-val ")")) + (set! tmp-val (string-append "(" pname "Options.pOptDesc" tmp-val ")")) ) + +(ag-fprintf 0 "\n#define %8sDESC(n) " UP-prefix) +(emit tmp-val) +(out-push-new) + +=] +/** 'true' if an option has been specified in any way */ +#define HAVE_

OPT(n) (! UNUSED_OPT(&

DESC(n))) +/** The string argument to an option. The argument type must be \"string\". */ +#define

OPT_ARG(n) (

DESC(n).optArg.argString) +/** Mask the option state revealing how an option was specified. + * It will be one and only one of \a OPTST_SET, \a OPTST_PRESET, + * \a OPTST_DEFINED, \a OPTST_RESET or zero. + */ +#define STATE_

OPT(n) (

DESC(n).fOptState & OPTST_SET_MASK) +/** Count of option's occurrances *on the command line*. */ +#define COUNT_

OPT(n) (

DESC(n).optOccCt) +/** mask of \a OPTST_SET and \a OPTST_DEFINED. */ +#define ISSEL_

OPT(n) (SELECTED_OPT(&

DESC(n))) +/** 'true' if \a HAVE_OPT would yield 'false'. */ +#define ISUNUSED_

OPT(n) (UNUSED_OPT(&

DESC(n))) +/** 'true' if OPTST_DISABLED bit not set. */ +#define ENABLED_

OPT(n) (! DISABLED_OPT(&

DESC(n))) +/** number of stacked option arguments. + * Valid only for stacked option arguments. */ +#define STACKCT_

OPT(n) (((tArgList*)(

DESC(n).optCookie))->useCt) +/** stacked argument vector. + * Valid only for stacked option arguments. */ +#define STACKLST_

OPT(n) (((tArgList*)(

DESC(n).optCookie))->apzArgs) +/** Reset an option. */ +#define CLEAR_

OPT(n) STMTS( \ +

DESC(n).fOptState &= OPTST_PERSISTENT_MASK; \ + if ((

DESC(n).fOptState & OPTST_INITENABLED) == 0) \ +

DESC(n).fOptState |= OPTST_DISABLED; \ +

DESC(n).optCookie = NULL )[= + +(set! tmp-val (if (> (string-length UP-prefix) 1) UP-prefix "")) +(string-substitute (out-pop #t) "

" tmp-val) + +=][= + +INVOKE emit-exit-codes =][= +INVOKE emit-option-guards + +=] +/** + * Interface defines for specific options. + * @{ + */[= + +FOR flag =][= + (define flag-index (for-index)) =][= + + INVOKE save-name-morphs =][= + + IF (set! opt-name (string-append OPT-pfx UP-name)) + (set! descriptor (string-append UP-prefix "DESC(" UP-name ")" )) + + (exist? "documentation") + + =][= + IF (hash-ref have-cb-procs flg-name) +=] +/** call the handler procedure for setting the [= name =] option. */ +#define SET_[= (string-append OPT-pfx UP-name) =] STMTS( \ + (*([=(. descriptor)=].pOptProc))(&[=(. pname)=]Options, \ + [=(. pname)=]Options.pOptDesc + [=(for-index)=])[= + + ENDIF =][= + ELSE =][= + INVOKE option-defines =][= + ENDIF =][= +ENDFOR flag =][= +INVOKE emit-opt-values =][= + +IF (and (exist? "homerc") (not (exist? "disable-save"))) + +=] +#define SET_[=(. OPT-pfx)=]SAVE_OPTS(a) STMTS( \ + [=(. UP-prefix)=]DESC(SAVE_OPTS).fOptState &= OPTST_PERSISTENT_MASK; \ + [=(. UP-prefix)=]DESC(SAVE_OPTS).fOptState |= OPTST_SET; \ + [=(. UP-prefix)=]DESC(SAVE_OPTS).optArg.argString = (char const*)(a))[= +ENDIF + +// # # # # # # # # # # # # # # # # # # # # # # =][= + +IF (not (exist? "library")) =][= + INVOKE emit-program-externs =][= +ENDIF + +=] +#endif /* [=(. header-guard)=] */ +[= # +// # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= + +DEFINE emit-program-externs + +=][= +(tpl-file-line extract-fmt) +(out-push-new) +=] +/* + * Interface defines not associated with particular options + */ +#define ERRSKIP_OPTERR STMTS(Options.fOptSet &= ~OPTPROC_ERRSTOP) +#define ERRSTOP_OPTERR STMTS(Options.fOptSet |= OPTPROC_ERRSTOP) +#define RESTART_OPT(n) STMTS( \ + Options.curOptIdx = (n); \ + Options.pzCurOpt = NULL ) +#define START_OPT RESTART_OPT(1) +#define USAGE(c) (*Options.pUsageProc)(&Options, c) +[= + +(set! tmp-val (if (> (string-length UP-prefix) 1) UP-prefix "")) +(string-substitute (out-pop #t) + (list "" "") + (list tmp-val pname) ) + +=] +#ifdef __cplusplus +extern "C" { +#endif +[= +INVOKE join-or-expand join-type = "export" =][= +INVOKE nls-header-code =] +[= + + IF + (define no-return-str (string-append + "noreturn extern void" "\n" lc-prefix)) + + (exist? "usage-message") + +=] +[=(. no-return-str)=]vusage_message(char const * fmt, va_list ap); +[=(. no-return-str)=]usage_message(char const * fmt, ...);[= + ENDIF have usage-message =][= + + IF (exist? "die-code") =] +[=(. no-return-str)=]vdie( int exit_code, char const * fmt, va_list); +[=(. no-return-str)=]die( int exit_code, char const * fmt, ...); +[=(. no-return-str)=]fserr(int exit_code, char const * op, char const * fn);[= + + IF (. no-mem-func) =] + +/** + * Print a [=(. nomem-exit-code)=] fatal error message and die. + * + * @param[in] sz the object size that was not allocated + * @param[in] what what that object was going to be + * @noreturn + */ +noreturn static inline void nomem_err(size_t sz, char const * what) +{ + char const * fmt = _("could not allocate %zu bytes for %s\n"); + die([=(. nomem-exit-code)=], fmt, sz, what); +}[= + + ENDIF no-memory failure =][= + + ENDIF die-code exists =][= + + IF (exist? "warn-code") =] +extern void [=(. lc-prefix)=]vwarning_msg( char const * fmt, va_list); +extern void [=(. lc-prefix)=]warning_msg( char const * fmt, ...);[= + ENDIF have warn-code =] +#ifdef __cplusplus +} +#endif[= + +ENDDEF emit-program-externs + +// # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= + +DEFINE emit-exit-codes + +=] +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/** + * Enumeration of [= prog-name =] exit codes + */ +typedef enum {[= + + (define exit-name-len 15) =][= + + FOR exit-name =][= + + (set! tmp-val (string-length (get "exit-name"))) + (if (> tmp-val exit-name-len) + (set! exit-name-len tmp-val)) =][= + + ENDFOR exit-name =][= + #/* + ;; Assume no definitions for exit-name[0] and [1]. If not true, + ;; then change the strings associated with the ones defined to the + ;; specified name. If the assumption is correct, we'll need to + ;; emit the a default value into the enumeration.. + =][= ;; */ + (set! tmp-val "") + (define no-mem-func #f) + (define need-ex-noinput (exist? "homerc")) + (define noinput-err-name "") + (define need-ex-software #t) + (define need-ex-usage #t) + (define usage-err-name "") + (define exit-code-fmt (sprintf + "\n %s_EXIT_%%-%us = %%d" pname-up exit-name-len )) + + (define succ-exit-code (string-append pname-up "_EXIT_SUCCESS")) + (if (exist? "exit-name[0]") + (set! succ-exit-code (string-append + pname-up "_EXIT_" (get-up-name "exit-name[0]") )) + + (set! tmp-val (sprintf exit-code-fmt "SUCCESS" 0)) + ) + + (define fail-exit-code (string-append pname-up "_EXIT_FAILURE")) + (if (exist? "exit-name[1]") + (set! fail-exit-code (string-append + pname-up "_EXIT_" (get-up-name "exit-name[1]") )) + + (set! tmp-val (string-append tmp-val + (if (> (string-length tmp-val) 1) "," "") + (sprintf exit-code-fmt "FAILURE" 1) )) + ) + + (define nomem-exit-code fail-exit-code) + (set! exit-code-fmt (string-append "," exit-code-fmt)) + + tmp-val =][= + + FOR exit-name =][= + (define err-name (get-up-name "exit-name")) + (if (~~ err-name "(NO_MEM|NOMEM)") (begin + (set! no-mem-func #t) + (set! nomem-exit-code (string-append + pname-up "_EXIT_" err-name)) )) + (sprintf exit-code-fmt err-name (for-index)) + =][= + + CASE (for-index) =][= + == 64 =][= (set! need-ex-usage #f) + (set! usage-err-name err-name) =][= + == 66 =][= (set! need-ex-noinput #f) + (set! noinput-err-name err-name) =][= + == 70 =][= (set! need-ex-software #f) =][= + ESAC (for-index) =][= + ENDFOR =][= + + (if need-ex-usage (begin + (set! usage-err-name (string-append pname-up "_EXIT_USAGE_ERROR")) + (ag-fprintf 0 exit-code-fmt "USAGE_ERROR" 64) )) + + (if need-ex-noinput (begin + (set! tmp-val (string-append pname-up "_EXIT_NO_CONFIG_INPUT")) + (ag-fprintf 0 exit-code-fmt "NO_CONFIG_INPUT" 66))) + + (define file-fail-exit-code + (if (exist? "file-fail-code") + (string-append pname-up "_EXIT_" (get-up-name "file-fail-code")) + (if need-ex-noinput + (string-append pname-up "_EXIT_NO_CONFIG_INPUT") + fail-exit-code ))) + + (if need-ex-software (begin + (set! need-ex-software (string-append pname-up "_EXIT_LIBOPTS_FAILURE")) + (ag-fprintf 0 exit-code-fmt "LIBOPTS_FAILURE" 70))) +=] +} [= (. pname-down) =]_exit_code_t;[= + +ENDDEF emit-exit-codes + +// # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= + +DEFINE emit-opt-values + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +Autoopts maintained option values. + +If *any* option flag value is specified, +then we provide flag characters for our options. +Otherwise, we will use the INDEX_* values for the option value. + +There are no documentation strings because these defines +are used identically to the user-generated VALUE defines. + +*/ =][= + +IF (exist? "flag.value") =][= + + INVOKE set-std-value + val-name = "help-value" + val-UPNAME = "HELP" + std-value = "?" =][= + + IF (not (exist? "no-libopts")) =][= + INVOKE set-std-value + val-name = "more-help-value" + val-UPNAME = "MORE_HELP" + std-value = "!" =][= + ENDIF don't have no-libopts ' =][= + + IF (exist? "resettable") =][= + INVOKE set-std-value + val-name = "reset-value" + val-UPNAME = "RESET_OPTION" + std-value = "R" =][= + ENDIF have "reset" =][= + + IF (exist? "version") =][= + INVOKE set-std-value + val-name = "version-value" + val-UPNAME = "VERSION" + std-value = "v" =][= + ENDIF have "version" =][= + + IF (exist? "usage-opt") =][= + INVOKE set-std-value + val-name = "usage-value" + val-UPNAME = "USAGE" + std-value = "u" =][= + ENDIF have "usage-opt" =][= + + IF (exist? "vendor-opt") =][= + INVOKE set-std-value + val-name = "vendor-value" + val-UPNAME = "VENDOR_OPT" + std-value = "W" =][= + ENDIF have "vendor-opt" =][= + + IF (exist? "homerc") =][= + + IF (not (exist? "disable-save")) =][= + INVOKE set-std-value + val-name = "save-opts-value" + val-UPNAME = "SAVE_OPTS" + std-value = ">" =][= + ELSE =] +#define [= (sprintf "%-23s 0" (string-append VALUE-pfx "SAVE_OPTS")) + =][= + ENDIF =][= + IF (not (exist? "disable-load")) =][= + INVOKE set-std-value + val-name = "load-opts-value" + val-UPNAME = "LOAD_OPTS" + std-value = "<" =][= + ELSE =] +#define [= (sprintf "%-23s 0" (string-append VALUE-pfx "LOAD_OPTS")) + =][= + ENDIF =][= + ENDIF have "homerc" =][= + +ELSE NO "flag.value" =] +[= +(set! index-fmt (string-append + "\n/** option value for %s option */" + "\n#define " VALUE-pfx "%-16s %s")) + (define std-vals (lambda (std-nm) + (ag-fprintf 0 index-fmt (string-downcase std-nm) std-nm (get-value-idx)) + ) ) + +(if (exist? "resettable") (std-vals "RESET_OPTION")) +(if (exist? "version") (std-vals "VERSION")) +(std-vals "HELP") +(if (not (exist? "no-libopts")) (std-vals "MORE_HELP")) +(if (exist? "usage-opt") (std-vals "USAGE")) +(if (exist? "homerc") (begin + (if (not (exist? "disable-save")) + (std-vals "SAVE_OPTS")) + (if (not (exist? "disable-load")) + (std-vals "LOAD_OPTS")) +) ) =][= + +ENDIF have flag.value/not =][= + +ENDDEF emit-opt-values + +// # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= + +DEFINE emit-option-guards + +=][= + +CASE guard-option-names =][= +!E =][= += full-enum =][= + + +=* no-warn =] +/** + * Make sure there are no #define name conflicts with the option names + * @{ + */[= + FOR flag =] +#undef [= (get-up-name "name") =][= + ENDFOR flag + +// # # # # # # # # # # # # # # # # # =][= + +* =][= + + (define undef-list "\n#else /* NO_OPTION_NAME_WARNINGS */") + (define conf-warn-fmt (string-append + "\n# ifdef %1$s" + "\n# warning undefining %1$s due to option name conflict" + "\n# undef %1$s" + "\n# endif" )) + +=] +/** @} */ +/** + * Make sure there are no #define name conflicts with the option names + */ +#ifndef NO_OPTION_NAME_WARNINGS[= + + FOR flag =][= + + (set! opt-name (get-up-name "name")) + (set! undef-list (string-append undef-list "\n# undef " opt-name)) + (sprintf conf-warn-fmt opt-name) + =][= + + ENDFOR flag =][= + + (. undef-list)=] +#endif /* NO_OPTION_NAME_WARNINGS */ +[= + +ESAC =][= + +ENDDEF emit-option-guards + +// # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= + +DEFINE set-std-value + +=] +/** option flag (value) for [= (get "val-name") =] option */ +#define [= (sprintf "%-23s " (string-append VALUE-pfx (get "val-UPNAME"))) =][= + CASE (define tmp-val (get "val-name")) + (get tmp-val) =][= + + == "" =][= + (if (exist? tmp-val) + (if (not (exist? "long-opts")) + (error (sprintf "'%s' may not be empty" tmp-val)) + (get-value-idx) + ) + + (sprintf "'%s'" (get "std-value")) + ) =][= + + == "'" =]'\''[= + ~~ . =]'[=(get tmp-val)=]'[= + * =][= (error (sprintf "option %s has multiple character flag value" + (get "val-name"))) =][= + ESAC =][= + +ENDDEF set-std-value + +// # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= + +DEFINE join-or-expand + +=][= + IF (define join-type (get "join-type")) + (exist? join-type) \=] +/* + * global [=(string-append join-type (if (==* join-type "inc") "d" "ed")) + =] definitions + */ +[= + IF + (set! tmp-text (join "\n\n" (stack join-type))) + (~* (get join-type) "^[^a-z0-9_]{2,}[ \t]+autogen5[ \t]+template") + =][= + INCLUDE (begin + (set! tmp-val (string-append tmp-dir "/" join-type "-text")) + (out-push-new tmp-val) + (emit tmp-text) + (out-pop) + tmp-val + ) =][= + ELSE text is not template =][= + (. tmp-text) =][= + ENDIF text is template =] +[=ENDIF join-type =][= +ENDDEF join-or-expand + +// # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= + +DEFINE nls-header-code + +=] + +/* * * * * * + * + * Declare the [=prog-name=] option descriptor. + */ +extern tOptions [=(. pname)=]Options;[= + + (if (> (string-length added-hdr) 0) + (begin + (emit "\n") + (shellf "sort -u <<_EOF_\n%s_EOF_" added-hdr) + ) ) =][= + + IF (not omit-nls-code) =] + +#if defined(ENABLE_NLS) +# ifndef _ +# include +# ifndef HAVE_GETTEXT + extern char * gettext(char const *); +# else +# include +# endif + +# ifndef ATTRIBUTE_FORMAT_ARG +# define ATTRIBUTE_FORMAT_ARG(_a) +# endif + +static inline char* aoGetsText(char const* pz) ATTRIBUTE_FORMAT_ARG(1); +static inline char* aoGetsText(char const* pz) { + if (pz == NULL) return NULL; + return (char*)gettext(pz); +} +# define _(s) aoGetsText(s) +# endif /* _() */ + +# define OPT_NO_XLAT_CFG_NAMES STMTS([=(. pname)=]Options.fOptSet |= \ + OPTPROC_NXLAT_OPT_CFG;) +# define OPT_NO_XLAT_OPT_NAMES STMTS([=(. pname)=]Options.fOptSet |= \ + OPTPROC_NXLAT_OPT|OPTPROC_NXLAT_OPT_CFG;) + +# define OPT_XLAT_CFG_NAMES STMTS([=(. pname)=]Options.fOptSet &= \ + ~(OPTPROC_NXLAT_OPT|OPTPROC_NXLAT_OPT_CFG);) +# define OPT_XLAT_OPT_NAMES STMTS([=(. pname)=]Options.fOptSet &= \ + ~OPTPROC_NXLAT_OPT;) + +#else /* ENABLE_NLS */[= + ENDIF no-nls-support =] +# define OPT_NO_XLAT_CFG_NAMES +# define OPT_NO_XLAT_OPT_NAMES + +# define OPT_XLAT_CFG_NAMES +# define OPT_XLAT_OPT_NAMES + +# ifndef _ +# define _(_s) _s +# endif[= + +(if (not omit-nls-code) (emit "\n#endif /* ENABLE_NLS */")) =] +[= +ENDDEF nls-header-code + +/* + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * opthead.tpl ends here */ \=] diff --git a/autoopts/tpl/options.tpl b/autoopts/tpl/options.tpl new file mode 100644 index 0000000..a02acab --- /dev/null +++ b/autoopts/tpl/options.tpl @@ -0,0 +1,73 @@ +[= Autogen5 Template -*- Mode: scheme -*- + +h +c + +=][= +# This file contains the templates used to generate the +# option descriptions for client programs, and it declares +# the macros used in the templates. + +# This file is part of AutoOpts, a companion to AutoGen. +# AutoOpts is free software. +# AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +# +# AutoOpts is available under any one of two licenses. The license +# in use must be one of these two and the choice is under the control +# of the user of the license. +# +# The GNU Lesser General Public License, version 3 or later +# See the files "COPYING.lgplv3" and "COPYING.gplv3" +# +# The Modified Berkeley Software Distribution License +# See the file "COPYING.mbsd" +# +# These files have the following sha256 sums: +# +# 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +# 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +# 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd +=][= +;;# START-BUILDTREE-ISMS +;; +(shell "CLexe=${AGexe%/agen5/*}/columns/columns + test -x \"${CLexe}\" || { + CLexe=${AGexe%/autogen}/columns + test -x \"${CLexe}\" || die 'columns program is not findable' + }" +) +=][= # END-BUILDTREE-ISMS + +(shell "CLexe=`echo ${AGexe} | sed 's@/autogen@/columns@'` + test -x \"${CLexe}\" || CLexe=`which columns`") + +# END-INSTALL-ONLY-CODE =][= + + (dne " * " "/* ") =][= + +CASE (suffix) =][= + +== h =][= + + INCLUDE "optlib.tlib" =][= + INVOKE init-and-validate =][= + INVOKE option-copyright =][= + INCLUDE "opthead.tlib" =][= + +== c =][= + + (if (exist? "library") + (out-delete)) =][= + + INVOKE option-copyright =][= + INCLUDE "optcode.tlib" =][= + + (if (exist? "flag.extract-code") + (shellf "test -f %1$s.c && rm -f %1$s.c.save" (base-name))) =][= + +ESAC =][= +IF (exist? "addtogroup") =] +/** @} */[= ENDIF =] +/* [= (out-name) =] ends here */[= + +# options.tpl ends here =] diff --git a/autoopts/tpl/optlib.tlib b/autoopts/tpl/optlib.tlib new file mode 100644 index 0000000..8bbea3b --- /dev/null +++ b/autoopts/tpl/optlib.tlib @@ -0,0 +1,1344 @@ +[= AutoGen5 Template Library -*- Mode: scheme -*- + +# This file is part of AutoOpts, a companion to AutoGen. +# AutoOpts is free software. +# AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +# +# AutoOpts is available under any one of two licenses. The license +# in use must be one of these two and the choice is under the control +# of the user of the license. +# +# The GNU Lesser General Public License, version 3 or later +# See the files "COPYING.lgplv3" and "COPYING.gplv3" +# +# The Modified Berkeley Software Distribution License +# See the file "COPYING.mbsd" +# +# These files have the following sha256 sums: +# +# 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +# 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +# 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + +=][= + +INCLUDE "tpl-config.tlib" =][= + +DEFINE init-and-validate =][= + +(if (not (exist? "flag.name")) + (error "No options have been defined" )) + +(if (> (count "flag") 100) + (error (sprintf "%d options are too many - limit of 100" + (count "flag")) )) + +(if (not (and (exist? "prog-name") (exist? "prog-title"))) + (error "prog-name and prog-title are required")) +(define prog-name (get "prog-name")) +(if (> (string-length prog-name) 16) + (error (sprintf "prog-name limited to 16 characters: %s" + prog-name)) ) + +(make-tmp-dir) +(define have-proc #f) +(define proc-name "") +(define test-name "") +(define tmp-text "") +(define is-extern #t) +(define is-lib-cb #f) +(define have-cb-procs (make-hash-table 31)) +(define is-ext-cb-proc (make-hash-table 31)) +(define is-lib-cb-proc (make-hash-table 31)) +(define cb-proc-name (make-hash-table 31)) +(define test-proc-name (make-hash-table 31)) +(define disable-name (make-hash-table 31)) +(define disable-prefix (make-hash-table 31)) +(define ifdef-ed (make-hash-table 31)) +(define tmp-ct 0) +(define extract-fmt "\n/* extracted from %s near line %d */\n") +(define make-callback-procs #f) +(define omit-nls-code (~ (get "no-xlate") "(any|no)thing")) +(define xlate-desc-p (and (not omit-nls-code) (not (exist? "full-usage")))) +(define alt-value-idx 4096) +(define get-value-idx (lambda() (begin + (set! alt-value-idx (+ 1 alt-value-idx)) + (sprintf "0x%X" alt-value-idx )))) + +(define have-noret-funcs + (or (exist? "usage-message") (exist? "die-code")) ) + +(define need-stacking (lambda() + (if (not (exist? "max")) + #f + (> (string->number (get "max")) 1) +) ) ) + +(define get-text (lambda (nm) (shell + "{ sed 's/@[a-z]*{\\([^}]*\\)}/\\1/g' | " + "${CLexe} --fill -I0 -W72\n}<<\\_EODesc_\n" + (get nm) "\n_EODesc_" ))) + +(define do-ifdefs (or (exist? "flag.ifdef") (exist? "flag.ifndef"))) + +;; IF long options are disallowed +;; AND at least one flag character (value) is supplied +;; THEN every option must have a 'value' attribute +;; +(define flag-options-only + (and (not (exist? "long-opts")) (exist? "flag.value"))) + +(if (exist? "vendor-opt") (begin + ;; except the 'vendor-opt' attribute allows long options that do + ;; not have flag values, but it conflicts with 'long-opts' and requires + ;; at least one 'flag.value' + ;; + (if (or (exist? "long-opts") (not (exist? "flag.value"))) + (error "'vendor-opt' and 'long-opts' conflict. flag values required") + (set! flag-options-only #f)) + (if (exist? "library") + (error "'vendor-opt' conflicts with 'library'")) +) ) + +(if (and (exist? "reorder-args") (not (exist? "argument")) ) + (error + "Reordering arguments requires operands (the 'argument' attribute)")) + +(if (and flag-options-only (exist? "flag.disable")) + (error "options can be disabled only with a long option name")) + +(if (exist? "flag.extract-code") + (shellf "f=%s.c ; test -s $f && mv -f $f $f.save" + (base-name))) + +(if (and (exist? "usage") (exist? "gnu-usage")) + (error "'usage' and 'gnu-usage' conflict." )) + +(if (> (count "flag.default") 1) + (error "Too many default options")) + +(if (exist? "library") (begin + (if (not (exist? "flag[0].documentation")) (error + "The first option of a library must be a documentation option")) + (if (not (exist? "flag[0].lib-name")) + (error "The first option of a library must specify 'lib-name'")) + (if (< 1 (count "flag.lib-name")) + (error "a library must only have one 'flag.lib-name'")) +) ) + +(if (exist? "main") (begin + (if (> (count "main") 1) + (error "too many main procedures")) + (if (not (exist? "main.main-type")) + (error "main procedure does not have a type") ) )) + +;; Establish a number of variations on the spelling of the +;; program name. Use these Scheme defined values throughout. +;; +(define pname (get-c-name "prog-name")) +(define pname-cap (string-capitalize pname)) +(define pname-up (string-upcase pname)) +(define pname-down (string-downcase pname)) +(define number-opt-index -1) +(define default-opt-index -1) + +(define guarded-test-main (or (exist? "test-main") + (string? (getenv "TEST_MAIN")))) +(if guarded-test-main + (warn "'test-main' is obsolete and should not be used any more. Use 'main'.")) + +(define main-guard (string-append "TEST_" pname-up "_OPTS" )) +(define make-main-proc + (if (exist? "main") + (~~ (get "main[].main-type" "") "shell-process|shell-parser|main") + guarded-test-main ) ) +(if (not make-main-proc) (set! guarded-test-main #f)) + +(define descriptor "") +(define opt-name "") +(define tmp-val "") +(define added-hdr "") + +(define flg-name "") +(define UP-name "") +(define cap-name "") +(define low-name "") +(define enum-pfx "") + +(define set-flag-names (lambda () (begin + (set! flg-name (get "name")) + (set! UP-name (get-up-name "name")) + (set! cap-name (string-capitalize UP-name )) + (set! low-name (string-downcase UP-name )) + (set! enum-pfx (if (exist? ".prefix-enum") + (string-append (get-up-name "prefix-enum") "_") + (string-append UP-prefix UP-name "_") )) +) ) ) + +(define UP-prefix "") +(define lc-prefix "") +(define Cap-prefix "") +(define OPT-pfx "OPT_") +(define INDEX-pfx "INDEX_OPT_") +(define VALUE-pfx "VALUE_OPT_") + +(if (exist? "prefix") + (begin + (set! UP-prefix (string-append (get-up-name "prefix") "_")) + (set! lc-prefix (string-downcase UP-prefix)) + (set! Cap-prefix (string-capitalize UP-prefix)) + (set! OPT-pfx (string-append UP-prefix "OPT_")) + (set! INDEX-pfx (string-append "INDEX_" OPT-pfx)) + (set! VALUE-pfx (string-append "VALUE_" OPT-pfx)) + ) ) + +(define cap-c-name (lambda (ag-name) + (string-capitalize! (get-c-name ag-name)) )) + +(define index-name (lambda (i-name) + (string-append INDEX-pfx (get-up-name i-name)) )) + +(define optname-from "A-Z_^") +(define optname-to "a-z--") +(if (exist? "preserve-case") + (begin + (set! optname-from "_^") + (set! optname-to "--") +) ) + +(define version-text (string-append prog-name + (if (exist? "package") + (string-append " (" (get "package") ")") + "" ) + (if (exist? "version") + (string-append " " (get "version")) + "" ) )) + +(if (exist? "flag.value") + (shellf " + + list=`echo '%s' | sort` + ulst=`echo \"${list}\" | sort -u` + test `echo \"${ulst}\" | wc -l` -ne %d && { + echo \"${list}\" > ${tmp_dir}/sort + echo \"${ulst}\" > ${tmp_dir}/uniq + df=`diff ${tmp_dir}/sort ${tmp_dir}/uniq | sed -n 's/< *//p'` + die 'duplicate option value characters:' ${df} + }" + + (join "\n" (stack "flag.value")) + (count "flag.value") ) ) + +(define temp-idx 0) +(define no-flag-ct 0) +(define lib-opt-ptr "") +(define max-name-len 10) =][= + + +FOR flag =][= + + (set! tmp-ct (len "name")) + (if (> tmp-ct 32) + (error (sprintf "Option %d name exceeds 32 characters: %s" + (for-index) (get "name")) )) + (if (> tmp-ct max-name-len) + (set! max-name-len tmp-ct)) + + (if (exist? "value") + (if (< 1 (count "value")) + (error (sprintf "Option %s has too many `value's" (get "name")))) + (set! no-flag-ct (+ 1 no-flag-ct)) + ) + + (if (and flag-options-only + (not (exist? "documentation")) + (not (exist? "value"))) + (error (sprintf "Option %s needs a `value' attribute" (get "name")))) + + (set! tmp-val + (+ (if (exist? "call-proc") 1 0) + (if (exist? "extract-code") 1 0) + (if (exist? "flag-proc") 1 0) + (if (exist? "unstack-arg") 1 0) + (if (exist? "stack-arg") 1 0) )) + + ;; IF there is one of the above callback proc types AND there is an + ;; option argument of type non-string, THEN oops. Conflict. + ;; + (if (and (> tmp-val 0) (exist? "arg-type") + (not (=* (get "arg-type") "str")) ) + (error (sprintf + "Option %s has a %s argument and a callback procedure" + (get "name") (get "arg-type") ) + ) ) + + ;; Count up the ways a callback procedure was specified. Must be 0 or 1 + ;; + (if (< 1 (+ (if (exist? "arg-range") 1 0) + (if (~* (get "arg-type") "key|set") 1 0) tmp-val)) + (error (sprintf "Option %s has multiple callback specifications" + (get "name")) )) + + (if (< 1 (+ (count "ifdef") (count "ifndef") )) + (error (sprintf "Option %s has multiple 'ifdef-es'" (get "name") )) ) + + (if (and (exist? "stack-arg") (not (exist? "arg-type"))) + (error (sprintf "Option %s has stacked args, but no arg-type" + (get "name")))) + + (if (and (exist? "min") (exist? "must-set")) + (error (sprintf "Option %s has both 'min' and 'must-set' attributes" + (get "name")))) + + (if (and (exist? "omitted-usage") + (not (exist? "ifdef")) + (not (exist? "ifndef")) ) + (error (string-append "Option " (get "name") " has 'omitted-usage' " + "but neither 'ifdef' nor 'ifndef'" )) ) + + (if (and (exist? "equivalence") + (exist? "aliases")) + (error (string-append "Option " (get "name") " has both " + "'equivalence' and 'aliases'" )) ) + + (if (exist? "lib-name") + (set! lib-opt-ptr (string->c-name! (string-append + (get "lib-name") "_" (get "name") "_optDesc_p"))) ) +=][= + +ENDFOR flag + +=][= +(if (and (exist? "vendor-opt") (= no-flag-ct 0)) + (error "'vendor-opt' requires that there be options without flag values")) + +(define opt-strs (string-append pname "_opt_strs")) +(string-table-new opt-strs) +(out-push-new) (out-suspend "home-list") +(if (not omit-nls-code) (begin + (out-push-new) + (out-suspend "xget") +) ) +(define field-name-fmt (string-append + "\n /* referenced via " pname "Options.%s */\n")) +(define put-xget (lambda (nm st) (begin + (out-resume "xget") + (ag-fprintf 0 field-name-fmt nm) + (mk-gettextable st) + (out-suspend "xget") +) ) ) +=][= + +ENDDEF init-and-validate + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= + +DEFINE save-name-morphs + + Save the various flag name morphs into hash tables + + Every option descriptor has a pointer to a handler procedure. That + pointer may be NULL. We generate a procedure for keyword, + set-membership and range checked options. "optionStackArg" is called + if "stack-arg" is specified. The specified procedure is called if + "call-proc" is specified. Finally, we insert the specified code for + options with "flag-code" or "extract-code" attributes. + + =][= + + IF + + (set-flag-names) + (hash-create-handle! ifdef-ed flg-name + (and do-ifdefs (or (exist? "ifdef") (exist? "ifndef"))) ) + (set! proc-name (string-append "doOpt" cap-name)) + (set! is-lib-cb #f) + + (exist? "call-proc") + + =][= # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= + + (set! have-proc #t) + (set! is-extern #t) + (set! proc-name (get "call-proc")) + (set! test-name (if need-stacking "optionStackArg" "NULL")) + =][= + + ELIF (or (exist? "extract-code") + (exist? "flag-code") + (exist? "aliases") + (exist? "arg-range")) + =][= + + (set! have-proc #t) + (set! is-extern #f) + (set! test-name (if (or (exist? "arg-range") (exist? "aliases")) + proc-name + (if need-stacking "optionStackArg" "NULL") )) + =][= + + ELIF (exist? "flag-proc") =][= + + (set! have-proc #t) + (set! proc-name (string-append "doOpt" (cap-c-name "flag-proc"))) + (set! test-name (if need-stacking "optionStackArg" "NULL")) + (set! is-extern #f) + =][= + + ELIF (exist? "stack-arg") =][= + + (if (not (exist? "max")) + (error (string-append flg-name + " has a stacked arg, but can only appear once")) ) + + (set! have-proc #t) + (set! proc-name "optionStackArg") + (set! is-lib-cb #t) + (set! test-name (if need-stacking proc-name "NULL")) + (set! is-extern #t) + =][= + + ELIF (exist? "unstack-arg") =][= + + (set! have-proc #t) + (set! proc-name "optionUnstackArg") + (set! is-lib-cb #t) + (set! test-name (if need-stacking proc-name "NULL")) + (set! is-extern #t) + =][= + + ELSE =][= + + CASE arg-type =][= + =* bool =][= + (set! proc-name "optionBooleanVal") + (set! is-lib-cb #t) + (set! test-name proc-name) + (set! is-extern #t) + (set! have-proc #t) =][= + + =* num =][= + (set! proc-name "optionNumericVal") + (set! is-lib-cb #t) + (set! test-name proc-name) + (set! is-extern #t) + (set! have-proc #t) =][= + + = time-date =][= + (set! proc-name "optionTimeDate") + (set! is-lib-cb #t) + (set! test-name proc-name) + (set! is-extern #t) + (set! have-proc #t) =][= + + =* time =][= + (set! proc-name "optionTimeVal") + (set! is-lib-cb #t) + (set! test-name proc-name) + (set! is-extern #t) + (set! have-proc #t) =][= + + ~* key|set|fil =][= + (set! test-name proc-name) + (set! is-extern #f) + (set! have-proc #t) =][= + + ~* hier|nest =][= + (set! proc-name "optionNestedVal") + (set! is-lib-cb #t) + (set! test-name proc-name) + (set! is-extern #t) + (set! have-proc #t) =][= + + * =][= + (set! have-proc #f) =][= + ESAC =][= + + ENDIF =][= + + ;; If these are different, then a #define name is inserted into the + ;; option descriptor table. Never a need to mess with it if we are + ;; not building a "test main" procedure. + ;; + (if (not guarded-test-main) + (set! test-name proc-name)) + + (if have-proc + (begin + (hash-create-handle! have-cb-procs flg-name #t) + (hash-create-handle! cb-proc-name flg-name proc-name) + (hash-create-handle! test-proc-name flg-name test-name) + (hash-create-handle! is-ext-cb-proc flg-name is-extern) + (hash-create-handle! is-lib-cb-proc flg-name is-lib-cb) + (set! make-callback-procs #t) + ) + (begin + (hash-create-handle! have-cb-procs flg-name #f) + (hash-create-handle! cb-proc-name flg-name "NULL") + (hash-create-handle! test-proc-name flg-name "NULL") + ) + ) + + (if (exist? "default") + (set! default-opt-index (. flag-index)) ) + +=][= + +ENDDEF save-name-morphs + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + +Emit the "#define SET_OPT_NAME ..." and "#define DISABLE_OPT_NAME ..." =][= + +DEFINE set-defines + +=] +#define SET_[=(. opt-name)=][= (if (exist? "arg-type") "(a)") + =] STMTS( \ + [=set-desc=].optActualIndex = [=(. flag-index)=]; \ + [=set-desc=].optActualValue = VALUE_[=(. opt-name)=]; \ + [=set-desc=].fOptState &= OPTST_PERSISTENT_MASK; \ + [=set-desc=].fOptState |= [=opt-state=][= + CASE arg-type =][= + ~* str|fil =]; \ + [=set-desc=].optArg.argString = (a)[= + =* num =]; \ + [=set-desc=].optArg.argInt = (a)[= + =* time =]; \ + [=set-desc=].optArg.argInt = (a)[= + =* bool =]; \ + [=set-desc=].optArg.argBool = (a)[= + =* key =]; \ + [=set-desc=].optArg.argEnum = (a)[= + =* set =]; \ + [=set-desc=].optArg.argIntptr = (a)[= + ~* hier|nest =]; \ + [=set-desc=].optArg.argString = (a)[= + + ESAC arg-type =][= + + IF (hash-ref have-cb-procs flg-name) =]; \ + (*([=(. descriptor)=].pOptProc))(&[=(. pname)=]Options, \ + [=(. pname)=]Options.pOptDesc + [=set-index=]);[= + ENDIF "callout procedure exists" =] )[= + + IF (exist? "disable") =][= + IF (~* (get "arg-type") "hier|nest") =] +#define DISABLE_[=(. opt-name)=](a) STMTS( \ + [=set-desc=].fOptState &= OPTST_PERSISTENT_MASK; \ + [=set-desc=].fOptState |= OPTST_SET | OPTST_DISABLED; \ + [=set-desc=].optArg.argString = (a); \ + optionNestedVal(&[=(. pname)=]Options, \ + [=(. pname)=]Options.pOptDesc + [=set-index=]);)[= + + ELSE =] +#define DISABLE_[=(. opt-name)=] STMTS( \ + [=set-desc=].fOptState &= OPTST_PERSISTENT_MASK; \ + [=set-desc=].fOptState |= OPTST_SET | OPTST_DISABLED; \ + [=set-desc=].optArg.argString = NULL[= + IF (hash-ref have-cb-procs flg-name) =]; \ + (*([=(. descriptor)=].pOptProc))(&[=(. pname)=]Options, \ + [=(. pname)=]Options.pOptDesc + [=set-index=]);[= + ENDIF "callout procedure exists" =] )[= + ENDIF =][= + ENDIF disable exists =][= + +ENDDEF set-defines + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + +Emit the copyright comment =][= + +DEFINE option-copyright =] + * + * Generated from AutoOpts [=(. ao-version)=] templates. + * + * AutoOpts is a copyrighted work. This [= + (if (= "h" (suffix)) "header" "source") =] file is not encumbered + * by AutoOpts licensing, but is provided under the licensing terms chosen + * by the [= prog-name =] author or copyright holder. AutoOpts is + * licensed under the terms of the LGPL. The redistributable library + * (``libopts'') is licensed under the terms of either the LGPL or, at the + * users discretion, the BSD license. See the AutoOpts and/or libopts sources + * for details.[= + +IF (exist? "copyright") =] + * + * The [= prog-name =] program is copyrighted and licensed + * under the following terms: + * +[= + CASE copyright.type =][= + == "" =][= + (sprintf " * %s Copyright (C) %s %s - all rights reserved\n * %s" + prog-name (get "copyright.date") (get "copyright.owner") + "licensing type not specified" ) =][= + + = note =][= (prefix " * " (get "copyright.text")) =][= + + * =][= (license-full (get "copyright.type") prog-name " * " + (get "copyright.owner") (get "copyright.date")) =][= + ESAC =][= +ENDIF "copyright exists" =] + */ +[= + +IF (exist? "addtogroup") \=] +/** \file [= (out-name) =] + * \addtogroup [= addtogroup =] + * @{ + */ +[= +ENDIF =][= + +ENDDEF option-copyright + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + +Emit usage text =][= + +DEFINE emit-help-text \=] +#define [= + (set! tmp-val (string-append (get "help-type") "-usage")) + (string->c-name! (string-append pname "_" tmp-val)) =] ([= + + CASE (set! tmp-val (get tmp-val "<<>>")) + tmp-val =][= + + == "<<>>" =]NULL[= + + == "" =][= + + (out-push-new) =][= + INCLUDE "usage.tlib" =][= + (define tmp-val (out-pop #t)) =][= + (string-table-add-ref opt-strs tmp-val) =][= + + ~ "[a-z][a-z0-9_]*" =][= (. tmp-val) =][= + + * anything else must be plain text =][= + (string-table-add-ref opt-strs tmp-val) =][= + ESAC flavor of usage text. =]) +[= +(if (not omit-nls-code) (begin + (set! tmp-text (string-append + "pz" (string-capitalize (get "help-type")) "Usage")) + (put-xget tmp-text tmp-val) )) =][= + +ENDDEF emit-help-text + +;; # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= + +DEFINE emit-keyword-enum =] +typedef enum {[= + (if (not (exist? "arg-default")) + (string-append " " enum-pfx "UNDEFINED = 0,")) =] +[=(shellf +"for f in %s ; do echo %s${f} ; done | \ + ${CLexe} -I4 --spread=3 --sep=, +test $? -eq 0 || die ${CLexe} failed" + (string-upcase! (string->c-name! (join " " (stack "keyword")))) + enum-pfx )=] +} te_[=(string-append Cap-prefix cap-name)=]; +#define [= (sprintf "%-24s" (string-append OPT-pfx UP-name "_VAL2STR(_v)")) + =] optionKeywordName(&[=(. value-desc)=], (_v)) +#define [=(. OPT-pfx)=]VALUE_[=(sprintf "%-14s" UP-name) + =] ([=(. value-desc)=].optArg.argEnum)[= + +ENDDEF emit-keyword-enum + +;; # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= + +DEFINE emit-member-mask =][= + + (define setmember-fmt (string-append "\n#define %-24s 0x%0" + (shellf "expr '(' %d + 4 ')' / 4" (count "keyword")) "XUL" + (if (> (count "keyword") 32) "L" "") )) + (define full-prefix (string-append UP-prefix UP-name) ) =][= + + FOR keyword =][= + + (sprintf setmember-fmt + (string->c-name! (string-append + full-prefix "_" (string-upcase! (get "keyword")) )) + (ash 1 (for-index)) ) =][= + + ENDFOR keyword =][= + + (ag-fprintf 0 setmember-fmt (string->c-name! (string-append + full-prefix "_MEMBERSHIP_MASK")) + (- (ash 1 (count "keyword")) 1) ) =] +#define [=(sprintf "%sVALUE_%-14s ((uintptr_t)%s.optCookie)" + OPT-pfx UP-name value-desc) + =] +#define [=(sprintf "%1$sMEMLST_%2$-13s optionMemberList(&%3$s)" + OPT-pfx UP-name value-desc) + =][= + +ENDDEF emit-member-mask + +;; # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= + +DEFINE emit-value-defines =][= + + CASE arg-type =][= + + =* num =] +#define [=(. OPT-pfx)=]VALUE_[=(sprintf "%-14s" UP-name) + =] ([=(. value-desc)=].optArg.argInt)[= + + =* time =] +#define [=(. OPT-pfx)=]VALUE_[=(sprintf "%-14s" UP-name) + =] ([=(. value-desc)=].optArg.argInt)[= + + =* key =][= + INVOKE emit-keyword-enum =][= + + =* set =][= + INVOKE emit-member-mask =][= + + =* bool =] +#define [=(. OPT-pfx)=]VALUE_[=(sprintf "%-14s" UP-name) + =] ([=(. value-desc)=].optArg.argBool)[= + + =* fil =][= + CASE open-file =][= + == "" =][= + =* desc =] +#define [=(. OPT-pfx)=]VALUE_[=(sprintf "%-14s" UP-name) + =] ([=(. value-desc)=].optArg.argFd)[= + * =] +#define [=(. OPT-pfx)=]VALUE_[=(sprintf "%-14s" UP-name) + =] ([=(. value-desc)=].optArg.argFp)[= + ESAC =][= + + ESAC =][= + +ENDDEF emit-value-defines + +;; # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= + +DEFINE set-option-define =][= + + IF (exist? "unstack-arg") =][= + + set-defines + set-desc = (string-append UP-prefix "DESC(" + (get-up-name "unstack-arg") ")" ) + set-index = (index-name "unstack-arg") + opt-state = "OPTST_SET | OPTST_EQUIVALENCE" =][= + + ELIF (and (exist? "equivalence") + (not (== (get-up-name "equivalence") UP-name))) =][= + + set-defines + set-desc = (string-append UP-prefix "DESC(" + (get-up-name "equivalence") ")" ) + set-index = (index-name "equivalence") + opt-state = "OPTST_SET | OPTST_EQUIVALENCE" =][= + + ELSE "is equivalenced" =][= + + set-defines + set-desc = (string-append UP-prefix "DESC(" UP-name ")" ) + set-index = (. flag-index) + opt-state = OPTST_SET =][= + + ENDIF is/not equivalenced =][= + +ENDDEF set-option-define + +;; # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +;; +;; #define's for a single option +;; +;; First, emit defines that are always required. Then start collecting +;; defines in a diverted output. If there is any output, there will +;; be well more than 2 bytes of it. If so, actually emit it, but first +;; see if it needs to be enclused in a #ifdef/#endif pair. +;; =][= +DEFINE option-defines =] +#define VALUE_[= + (define value-desc (string-append UP-prefix "DESC(" + (if (exist? "equivalence") + (get-up-name "equivalence") + UP-name) ")" )) + (sprintf "%-18s" opt-name)=] [= + + CASE value =][= + !E =][= (get-value-idx) =][= + == "'" =]'\''[= + == "\\" =]'\\'[= + ~~ "[ -~]" =]'[=value=]'[= + + =* num =][= + (if (>= number-opt-index 0) + (error "only one number option is allowed") ) + (set! number-opt-index flag-index) + (get-value-idx) =][= + + * =][=(error (sprintf + "Error: value for opt %s is `%s'\nmust be single char or 'NUMBER'" + (get "name") (get "value")))=][= + + ESAC =][= + (out-push-new) =][= + INVOKE emit-value-defines =][= + + IF (== (get-up-name "equivalence") UP-name) =] +/** Define the option value [= name =] is equivalenced to */ +#define WHICH_[=(sprintf "%-18s" opt-name) + =] ([=(. descriptor)=].optActualValue) +/** Define the index of the option [= name =] is equivalenced to */ +#define WHICH_[=(. UP-prefix)=]IDX_[=(sprintf "%-14s" UP-name) + =] ([=(. descriptor)=].optActualIndex)[= + ENDIF =][= + + IF (exist? "settable") =][= + INVOKE set-option-define =][= + ENDIF settable =][= + + IF (define tmp-val (out-pop #t)) + (if (defined? 'tmp-val) + (> (string-length tmp-val) 2) + #f ) =][= + + IF (hash-ref ifdef-ed flg-name) =] +#if[=ifndef "n"=]def [= ifdef =][= ifndef \=] +[= (. tmp-val) =] +#endif /* [= ifdef =][= ifndef =] */[= + + ELSE =] +[= (. tmp-val) =][= + ENDIF =][= + ENDIF =][= + +ENDDEF Option_Defines + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= + +DEFINE emit-alias-option + +=] +/** Descriptive text for the [= name =] option */ +#define [= (. UP-name) =]_DESC ([= + (set! tmp-val (string-append + "an alias for the '" (get "aliases") "' option")) + (if (exist? "deprecated") + (set! tmp-val (string-append tmp-val " (deprecated)")) ) + (if xlate-desc-p + (put-xget "pOptDesc->pzText" tmp-val) ) + (string-table-add-ref opt-strs tmp-val) =]) +#define [= (. UP-name) =]_NAME NULL +/** Unmodified name string for the [= name =] option */ +#define [= (. UP-name) =]_name ([= + (string-table-add-ref opt-strs (get "name")) =]) +/** Compiled in flag settings for the [= name =] option */ +#define [=(. UP-name)=]_FLAGS ([= + (get-up-name "aliases") =]_FLAGS | OPTST_ALIAS[= + (if (exist? "deprecated") " | OPTST_DEPRECATED") =])[= + +ENDDEF emit-alias-option " + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + +Define the arrays of values associated with an option (strings, etc.) =][= + +DEFINE emit-nondoc-option =][= + (if (exist? "translators") + (string-append "\n" (shell + "${CLexe} -I16 --fill --first='/* TRANSLATORS:' <<\\_EOF_\n" + (get "translators") "\n_EOF_") + " */" ) ) =] +/** Descriptive text for the [= name =] option */ +#define [= (. UP-name) =]_DESC ([= + (define tmp-val (get-text "descrip")) + (if (exist? "deprecated") + (set! tmp-val (string-append tmp-val " (deprecated)")) ) + (if xlate-desc-p + (put-xget "pOptDesc->pzText" tmp-val) ) + (string-table-add-ref opt-strs tmp-val) =]) +/** Upper-cased name for the [= name =] option */ +#define [= (. UP-name) =]_NAME ([= + (string-table-add-ref opt-strs UP-name) =])[= + + # IF this option can be disabled, + # THEN we must create the string for the disabled version + # =][= + IF (> (len "disable") 0) =] +/** disablement name for the [= name =] option */ +#define NOT_[= (. UP-name) =]_name ([= + (hash-create-handle! disable-name flg-name (string-append + "NOT_" UP-name "_name" )) + (hash-create-handle! disable-prefix flg-name (string-append + "NOT_" UP-name "_PFX" )) + (string-table-add-ref opt-strs + (string-tr! (string-append (get "disable") "-" flg-name) + optname-from optname-to)) =]) +/** disablement prefix for the [= name =] option */ +#define NOT_[= (. UP-name) =]_PFX ([= + (string-table-add-ref opt-strs (string-downcase! (get "disable"))) =]) +/** Name string for the [= name =] option */ +#define [= (. UP-name) =]_name ([= + (if (> (len "enable") 0) + (string-table-add-ref opt-strs + (string-tr! (string-append (get "enable") "-" flg-name) + optname-from optname-to) ) + (sprintf "NOT_%s_name + %d" + UP-name (+ (string-length (get "disable")) 1 )) + ) =])[= + + ELSE No disablement of this option: =][= + + (hash-create-handle! disable-name flg-name "NULL") + (hash-create-handle! disable-prefix flg-name "NULL") "" + =] +/** Name string for the [= name =] option */ +#define [= (. UP-name) =]_name ([= + (string-table-add-ref opt-strs + (string-tr! (string-append + (if (exist? "enable") (string-append (get "enable") "-") "") + (get "name")) + optname-from optname-to)) =])[= + + ENDIF (> (len "disable") 0) + + # Check for special attributes: a default value + # and conflicting or required options + =][= + IF (define def-arg-name (sprintf "%-28s " + (string-append UP-name "_DFT_ARG" ))) + (exist? "arg-default") =] +/** The compiled in default value for the [= name =] option argument */ +#define [= (. UP-name) =]_DFT_ARG ([= + CASE arg-type =][= + =* num =](char const*)[= arg-default =][= + + =* time =](char const*)[= + (time-string->number (get "arg-default")) =][= + + =* bool =][= + CASE arg-default =][= + ~ n.*|f.*|0 =](char const*)false[= + * =](char const*)true[= + ESAC =][= + + =* key =](char const*)[= + (emit (if (=* (get "arg-default") enum-pfx) "" enum-pfx)) + (get-up-name "arg-default") =][= + + =* set =]NULL) +#define [=(sprintf "%-28s " (string-append cap-name "CookieBits"))=]VOIDP([= + IF (not (exist? "arg-default")) =]0[= + ELSE =][= + FOR arg-default | =][= + (string->c-name! (string-append UP-prefix UP-name "_" + (get-up-name "arg-default") )) =][= + ENDFOR arg-default =][= + ENDIF =][= + + =* str =][= + (string-table-add-ref opt-strs (get "arg-default")) =][= + + =* file =][= + (string-table-add-ref opt-strs (get "arg-default")) =][= + + * =][= + (error (string-append cap-name + " has arg-default, but no valid arg-type")) =][= + ESAC =])[= + ENDIF =][= + + + IF (exist? "flags-must") =] +/** Other options that are required by the [= name =] option */ +static int const a[=(. cap-name)=]MustList[] = {[= + FOR flags-must =] + [= (index-name "flags-must") =],[= + ENDFOR flags_must =] NO_EQUIVALENT };[= + ENDIF =][= + + + IF (exist? "flags-cant") =] +/** Other options that appear in conjunction with the [= name =] option */ +static int const a[=(. cap-name)=]CantList[] = {[= + FOR flags-cant =] + [= (index-name "flags-cant") =],[= + ENDFOR flags-cant =] NO_EQUIVALENT };[= + ENDIF =] +/** Compiled in flag settings for the [= name =] option */ +#define [= (. UP-name) =]_FLAGS ([= + ? enabled "OPTST_INITENABLED" + "OPTST_DISABLED" =][= + stack-arg " | OPTST_STACKED" =][= + must-set " | OPTST_MUST_SET" =][= + no-preset " | OPTST_NO_INIT" =][= + no-command " | OPTST_NO_COMMAND" =][= + deprecated " | OPTST_DEPRECATED" =][= + + CASE immediate =][= + = also =] | OPTST_IMM | OPTST_TWICE[= + +E =] | OPTST_IMM[= + ESAC immediate =][= + + CASE immed-disable =][= + = also =] | OPTST_DISABLE_IMM | OPTST_DISABLE_TWICE[= + +E =] | OPTST_DISABLE_IMM[= + ESAC immed-disable =][= + + IF (exist? "arg-type") =][= + CASE arg-type =][= + + =* num =] \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_NUMERIC)[= + IF (exist? "scaled") =] \ + | OPTST_SCALED_NUM[= ENDIF =][= + + =* time =] \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_TIME)[= + + =* bool =] \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_BOOLEAN)[= + + =* key =] \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_ENUMERATION)[= + + =* set =] \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_MEMBERSHIP)[= + + ~* hier|nest =] \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_HIERARCHY)[= + + =* str =] \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING)[= + + =* fil =] \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_FILE)[= + + * =][= + (error (string-append "unknown arg type '" + (get "arg-type") "' for " flg-name)) =][= + ESAC arg-type =][= + (if (exist? "arg-optional") " | OPTST_ARG_OPTIONAL") =][= + ENDIF arg-type exists =])[= + +ENDDEF emit-nondoc-option + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + +Define the arrays of values associated with an option (strings, etc.) =][= + +DEFINE emit-opt-strs + +=] +/** + * [= (set-flag-names) flg-name =] option description[= + IF (or (exist? "flags_must") (exist? "flags_cant")) =] with + * "Must also have options" and "Incompatible options"[= + ENDIF =]: + */[= + IF (hash-ref ifdef-ed flg-name) =] +#if[=ifndef "n"=]def [= (define if-def-name (get "ifdef" (get "ifndef"))) + if-def-name =][= + ENDIF ifdef-ed =][= + + IF (exist? "documentation") =] +/** [= name =] option separation text */ +#define [= (. UP-name) =]_DESC ([= + (define tmp-val (string-append (get-text "descrip") ":")) + (if xlate-desc-p + (put-xget "pOptDesc->pzText" tmp-val) ) + (string-table-add-ref opt-strs tmp-val) =]) +#define [= (. UP-name) =]_FLAGS (OPTST_DOCUMENT | OPTST_NO_INIT)[= + ELIF (exist? "aliases") =][= + INVOKE emit-alias-option =][= + ELSE =][= + INVOKE emit-nondoc-option =][= + ENDIF (exist? "documentation") =][= + + IF (hash-ref ifdef-ed flg-name) =] + +#else /* disable [= (. flg-name)=] */ +#define [= (. UP-name) =]_FLAGS (OPTST_OMITTED | OPTST_NO_INIT)[= + + IF (exist? "arg-default") =] +#define [= (. UP-name) =]_DFT_ARG NULL[= + ENDIF =][= + + IF (exist? "flags-must") =] +#define a[=(. cap-name)=]MustList NULL[= + ENDIF =][= + + IF (exist? "flags-cant") =] +#define a[=(. cap-name)=]CantList NULL[= + ENDIF =] +#define [= (. UP-name) =]_NAME NULL[= + + IF (exist? "omitted-usage") =] +/** Descriptive text for the [= name =] option */ +#define [= (. UP-name) =]_DESC ([= + (set! tmp-text (get "omitted-usage")) + (if (> (string-length tmp-text) 1) (begin + (if xlate-desc-p + (put-xget "pOptDesc->pzText" tmp-text) ) + (string-table-add-ref opt-strs tmp-text) ) + "NULL") =]) +#define [= (. UP-name) =]_name ([= + (string-table-add-ref opt-strs (get "name")) =])[= + + ELSE =] +#define [= (. UP-name) =]_DESC NULL +#define [= (. UP-name) =]_name NULL[= + ENDIF =][= + + IF (> (len "disable") 0) =] +#define NOT_[= (. UP-name) =]_name NULL +#define NOT_[= (. UP-name) =]_PFX NULL[= + ENDIF =] +#endif /* [= (. if-def-name) =] */[= + ENDIF ifdef-ed =][= + +ENDDEF opt-strs + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + +Define the arrays of values associated with help/version/etc. =][= + +DEFINE help-strs + +=] + +/* + * Help[= (string-append + (if (exist? "no-libopts") "" "/More_Help") + (if (exist? "version") "/Version" "")) =] option descriptions: + */ +#define HELP_DESC ([= + (define tmp-text "display extended usage information and exit") + (if xlate-desc-p + (put-xget "pOptDesc->pzText" tmp-text) ) + (string-table-add-ref opt-strs tmp-text)=]) +#define HELP_name ([= + (string-table-add-ref opt-strs "help")=])[= + + IF (not (exist? "no-libopts")) + +=] +#ifdef HAVE_WORKING_FORK +#define MORE_HELP_DESC ([= + (define tmp-text "extended usage information passed thru pager") + (if xlate-desc-p + (put-xget "pOptDesc->pzText" tmp-text) ) + (string-table-add-ref opt-strs tmp-text)=]) +#define MORE_HELP_name ([= + (string-table-add-ref opt-strs "more-help")=]) +#define MORE_HELP_FLAGS (OPTST_IMM | OPTST_NO_INIT) +#else +#define MORE_HELP_DESC HELP_DESC +#define MORE_HELP_name HELP_name +#define MORE_HELP_FLAGS (OPTST_OMITTED | OPTST_NO_INIT) +#endif[= + + ENDIF (not (exist? "no-libopts")) =][= + + IF (exist? "version") + +=][= + CASE version-type =][= + ~* [vcn] =] +#define VER_FLAGS (OPTST_SET_ARGTYPE(OPARG_TYPE_STATIC) | \ + OPTST_IMM | OPTST_NO_INIT)[= + * =] +#ifdef NO_OPTIONAL_OPT_ARGS +# define VER_FLAGS (OPTST_IMM | OPTST_NO_INIT) +#else +# define VER_FLAGS (OPTST_SET_ARGTYPE(OPARG_TYPE_STRING) | \ + OPTST_ARG_OPTIONAL | OPTST_IMM | OPTST_NO_INIT) +#endif[= + ESAC =] +#define VER_DESC ([= + (define tmp-text "output version information and exit") + (if xlate-desc-p + (put-xget "pOptDesc->pzText" tmp-text) ) + (string-table-add-ref opt-strs tmp-text)=]) +#define VER_name ([= + (string-table-add-ref opt-strs "version")=])[= + + ENDIF (exist? "version") =][= + + IF (exist? "resettable") + +=] +#define RESET_DESC ([= + (define tmp-text "reset an option's state") + (if xlate-desc-p + (put-xget "pOptDesc->pzText" tmp-text) ) + (string-table-add-ref opt-strs tmp-text)=]) +#define RESET_name ([= + (string-table-add-ref opt-strs "reset-option")=]) +#define RESET_FLAGS (OPTST_SET_ARGTYPE(OPARG_TYPE_STRING)|OPTST_NO_INIT)[= + + ENDIF (exist? "resettable") =][= + + IF (exist? "usage-opt") + +=] +#define USAGE_DESC ([= + (define tmp-text "abbreviated usage to stdout") + (if xlate-desc-p + (put-xget "pOptDesc->pzText" tmp-text) ) + (string-table-add-ref opt-strs tmp-text)=]) +#define USAGE_name ([= + (string-table-add-ref opt-strs "usage")=])[= + + ENDIF (exist? "usage-opt") =][= + + IF (exist? "vendor-opt") + +=] +#define VEND_DESC ([= + (define tmp-text "vendor supported additional options") + (if xlate-desc-p + (put-xget "pOptDesc->pzText" tmp-text) ) + (string-table-add-ref opt-strs tmp-text)=]) +#define VEND_name ([= + (string-table-add-ref opt-strs "vendor-option")=])[= + + ENDIF (exist? "vendor-opt") =][= + + IF (exist? "homerc") =][= + + IF (not (exist? "disable-save")) =] +#define SAVE_OPTS_DESC ([= + (define tmp-text "save the option state to a config file") + (if xlate-desc-p + (put-xget "pOptDesc->pzText" tmp-text) ) + (string-table-add-ref opt-strs tmp-text)=]) +#define SAVE_OPTS_name ([= + (string-table-add-ref opt-strs "save-opts")=])[= + + ENDIF no disable-save =][= + + IF (not (exist? "disable-load")) =] +#define LOAD_OPTS_DESC ([= + (define tmp-text "load options from a config file") + (if xlate-desc-p + (put-xget "pOptDesc->pzText" tmp-text) ) + (string-table-add-ref opt-strs tmp-text)=]) +#define LOAD_OPTS_NAME ([= + (string-table-add-ref opt-strs "LOAD_OPTS")=]) +#define NO_LOAD_OPTS_name ([= + (string-table-add-ref opt-strs "no-load-opts")=]) +#define LOAD_OPTS_pfx ([= + (string-table-add-ref opt-strs "no")=]) +#define LOAD_OPTS_name (NO_LOAD_OPTS_name + 3)[= + + ENDIF no disable-load =][= + + ENDIF (exist? "homerc") =][= + +ENDDEF help-strs + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + +Define the values for an option descriptor =][= + +DEFINE emit-opt-desc =][= + IF + (set-flag-names) + + (exist? "documentation") + +=] + { /* entry idx, value */ 0, 0, + /* equiv idx, value */ 0, 0, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 0, 0, + /* opt state flags */ [=(. UP-name)=]_FLAGS, 0, + /* last opt argumnt */ { NULL }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ [= + IF (exist? "call-proc") =][=call-proc=][= + ELIF (or (exist? "extract-code") + (exist? "flag-code")) =]doOpt[=(. cap-name)=][= + ELSE =]NULL[= + ENDIF =], + /* desc, NAME, name */ [= + (set! default-text (string-append default-text + "\n { NULL }, /* doc opt */" )) + (set! default-cookie (string-append default-cookie "NULL\n" )) + UP-name =]_DESC, NULL, NULL, + /* disablement strs */ NULL, NULL },[= + + ELSE + +=] + { /* entry idx, value */ [=(. flag-index)=], [= + (string-append VALUE-pfx UP-name)=], + /* equiv idx, value */ [= + IF (== (get-up-name "equivalence") UP-name) + =]NO_EQUIVALENT, 0[= + ELIF (or (exist? "equivalence") (exist? "unstack-arg")) + =]NOLIMIT, NOLIMIT[= + ELSE + =][=(. flag-index)=], [=(string-append VALUE-pfx UP-name)=][= + ENDIF=], + /* equivalenced to */ [= + (if (exist? "unstack-arg") + (index-name "unstack-arg") + (if (and (exist? "equivalence") + (not (== (get-up-name "equivalence") UP-name)) ) + (index-name "equivalence") + "NO_EQUIVALENT" + ) ) =], + /* min, max, act ct */ [= + (if (exist? "min") (get "min") + (if (exist? "must-set") "1" "0" )) =], [= + (if (=* (get "arg-type") "set") "NOLIMIT" + (if (exist? "max") (get "max") "1") ) =], 0, + /* opt state flags */ [=(. UP-name)=]_FLAGS, 0, + /* last opt argumnt */ [= + (set! tmp-val (if (exist? "arg-default") + (string-append "{ " UP-name "_DFT_ARG },") + (string-append "{ NULL }, /* --" flg-name " */" ) )) + (set! default-text (string-append default-text "\n " tmp-val)) + tmp-val =] + /* arg list/cookie */ [= + (set! tmp-val (if (and (=* (get "arg-type") "set") (exist? "arg-default")) + (string-append cap-name "CookieBits") "NULL")) + (set! default-cookie (string-append default-cookie tmp-val "\n" )) + tmp-val =], + /* must/cannot opts */ [= + (if (exist? "flags-must") + (string-append "a" cap-name "MustList, ") + "NULL, " ) =][= + (if (exist? "flags-cant") + (string-append "a" cap-name "CantList") + "NULL" ) =], + /* option proc */ [= + + ;; If there is a difference between what gets invoked under test and + ;; what gets invoked "normally", then there must be a #define name + ;; for the procedure. There will only be such a difference if + ;; guarded-test-main is #t + ;; + (if (= (hash-ref cb-proc-name flg-name) + (hash-ref test-proc-name flg-name)) + + (hash-ref test-proc-name flg-name) + (string-append UP-name "_OPT_PROC") ) =], + /* desc, NAME, name */ [= + (sprintf "%1$s_DESC, %1$s_NAME, %1$s_name," UP-name) =] + /* disablement strs */ [=(hash-ref disable-name flg-name)=], [= + (hash-ref disable-prefix flg-name)=] },[= + ENDIF =][= + +ENDDEF opt-desc + +## Local Variables: +## mode: text +## indent-tabs-mode: nil +## End: + +optlib.tlib ends here \=] diff --git a/autoopts/tpl/optmain.tlib b/autoopts/tpl/optmain.tlib new file mode 100644 index 0000000..729fca5 --- /dev/null +++ b/autoopts/tpl/optmain.tlib @@ -0,0 +1,1441 @@ +[= AutoGen5 Template -*- Mode: C -*- + +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + +=][= + +(out-push-new) =] +ck_flag_code() { + addon_txt='' + txt1=`[=(. grep-prog)=] -w pOptDesc ${tmp_dir}/flag-code` + test -z "$txt1" && addon_txt=' (void)pOptDesc;\n' + txt2=`[=(. grep-prog)=] -w pOptions ${tmp_dir}/flag-code` + test -z "$txt2" && addon_txt=${addon_txt}' (void)pOptions;\n' + cat ${tmp_dir}/flag-code + test -z "$addon_txt" || printf "\n$addon_txt" + rm -f ${tmp_dir}/flag-code +}[= +(shell (out-pop #t)) =][= + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + + BUILD TEST MAIN + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= + +DEFINE build-test-main =][= + + IF (emit (tpl-file-line extract-fmt)) + (define end-test-main-guard "") + guarded-test-main +=] +#if defined([=(set! end-test-main-guard (string-append + "\n#endif /* " main-guard " END-TEST-MAIN-PROCEDURE */")) + main-guard=]) /* TEST-MAIN-PROCEDURE: */[= + + ENDIF guarded-test-main =][= + + IF (= (get "test-main") "optionParseShell") + +=] + +extern tOptions genshelloptOptions; +extern void optionParseShell(tOptions*); +extern tOptions* optionParseShellOptions;[= + + ELIF (not (exist? "main-text")) =][= + + (define option-emitter-proc (get "test-main")) + (if (<= (string-length option-emitter-proc) 3) + (set! option-emitter-proc "optionPutShell")) +=] + +extern void [= (. option-emitter-proc) =](tOptions*);[= + + ENDIF + +=] + +/** + * Generated main procedure. This will emit text that a Bourne shell can + * process to handle its command line arguments. + * + * @param[in] argc argument count + * @param[in] argv argument vector + * @returns program exit code + */ +int +main(int argc, char ** argv) +{ + int res = [=(. succ-exit-code)=];[= + + IF (= (get "test-main") "optionParseShell") =] + /* + * Stash a pointer to the options we are generating. + * `genshellUsage()' will use it. + */ + optionParseShellOptions = &[=(. pname)=]Options; + (void)optionProcess(&genshelloptOptions, argc, argv); + optionParseShell(&[=(. pname)=]Options);[= + + ELSE =][= + INVOKE emit-option-code =][= + INVOKE emit-main-text =][= + ENDIF =] + return res; +}[=(. end-test-main-guard) =][= + +ENDDEF build-test-main + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + + BUILD FOR-EACH MAIN + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= + +DEFINE for-each-main =][= + + (if (not (==* (get "argument") "[" )) + (error "command line arguments must be optional for a 'for-each' main")) + + (if (not (exist? "handler-proc")) + (error "'for-each' mains require a handler proc") ) + + (define handler-arg-type "") + (tpl-file-line extract-fmt) =][= + +INVOKE emit-handler-proc =][= + +IF (exist? "handler-type") =][= + INVOKE emit-file-dispatcher =][= +ENDIF handler-type exists =][= + +(tpl-file-line extract-fmt) + +=][= + +IF (not (exist? "stdin-input")) =][= + INVOKE emit-trim-input =][= +ENDIF + +=] +/** + * Generated main procedure. This will call the [=(. handler-proc)=] procedure + * for every operand on the command line. If there are no operands, then stdin + * is read for a list of file names to process. stdin must not be a terminal. + * It must be a pipe or a file. + * + * @param[in] argc argument count + * @param[in] argv argument vector + * @returns program exit code + */ +int +main(int argc, char ** argv) +{ + int res = 0; + int proc_ct = 0; + int arg_ix = optionProcess(&[=(. pname)=]Options, argc, argv);[= + + (if (exist? "main-init") (string-append + "\n " (def-file-line "main-init" extract-fmt) "\n" (get "main-init"))) + + =][= (tpl-file-line extract-fmt) =] + /* + * IF the input list is from the command line... + */ + if (arg_ix < argc) { + for (; arg_ix < argc; arg_ix++) { + char * arg = argv[arg_ix];[= + IF (exist? "interleaved") =] + if (*arg == '-') { + RESTART_OPT(arg_ix); + arg_ix = optionProcess(&[=(. pname)=]Options, argc, argv) - 1; + continue; + }[= + ENDIF interleaved =] + res |= [= (. handler-proc) =](arg); + proc_ct++; + }[= + IF (exist? "interleaved") =] + + if (proc_ct == 0) + fputs(_("[=(. prog-name) + =] Warning: no command operands were processed\n"), stderr);[= + ENDIF interleaved =] + }[= + +IF (exist? "stdin-input") =][= + INVOKE stdin-as-input =][= +ELSE =][= + INVOKE files-from-stdin =][= +ENDIF =][= + + (if (exist? "main-fini") (string-append + "\n " (def-file-line "main-fini" extract-fmt) "\n" (get "main-fini"))) + + =] + return res; +}[= + +ENDDEF for-each-main + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= + +DEFINE emit-file-dispatcher =][= + +(tpl-file-line extract-fmt) =] +/** + * validate file name and dispach callout procedure. + * This procedure is generated by AutoOpts. + * It will make sure that the input file name refers to a file[= + + CASE handler-type =][= +=* name =] + * that exists.[= +=* file =] + * that exists and has been opened for [= + CASE + (define open-mode (shellf "echo '%s' | sed 's/.*-//'" + (get "handler-type"))) + open-mode =][= + *~~* '[rwa]\+' =]reading and writing[= + *~~* [wa] =]writing[= + *~~* r =]reading[= + ESAC =].[= + +*=* text =] + * that has been read into memory as text.[= + ESAC =] + * + * @param fname the name of the file to process + * @returns program exit code flag + */ +static [= + +(define emit-failing-printf (not (= (get "file-fail-code") "success"))) + + pname-down =]_exit_code_t +validate_fname(char const * fname) +{ + static char const * err_str = NULL;[= + + IF (*=* (get "handler-type") "text") =] + char* file_text; + size_t text_size; + int res;[= + ENDIF =] + + if (err_str == NULL) + err_str = _("fs error %d (%s) %s-ing %s\n");[= + + IF (== (get "handler-type") "file-r") =] + if ((fname[0] == '-') && (fname[1] == '\0')) + return [= handler-proc =](_("standard input"), stdin);[= + ENDIF file-r handler type =] + { + struct stat sb; + if (stat(fname, &sb) < 0) {[= + IF (. emit-failing-printf) =] + fprintf(stderr, err_str, errno, strerror(errno), "stat", + fname);[= + ENDIF =] + return [= (. file-fail-exit-code) =]; + }[= + + IF (*=* (get "handler-type") "text") =] + + if (! S_ISREG(sb.st_mode)) {[= + IF (. emit-failing-printf) =] + fprintf(stderr, err_str, EINVAL, strerror(EINVAL), + _("not regular file:"), fname);[= + ENDIF =] + return [= (. file-fail-exit-code) =]; + }[= + + IF (=* (get "handler-type") "some-text") =] + + if (sb.st_size == 0) {[= + IF (. emit-failing-printf) =] + fprintf(stderr, err_str, EINVAL, strerror(EINVAL), + _("empty file:"), fname);[= + ENDIF =] + return [= (. file-fail-exit-code) =]; + }[= + + ENDIF =] + + text_size = sb.st_size;[= + + ENDIF =] + }[= + +CASE handler-type =][= +=* name =][= (tpl-file-line extract-fmt) =] + + return [= handler-proc =](fname);[= + +=* file =][= (tpl-file-line extract-fmt) =] + { + int res; + FILE* fp = fopen(fname, "[= + (shellf "echo '%s' | sed 's/.*-//'" + (get "handler-type")) =]"); + if (fp == NULL) { + fprintf(stderr, err_str, errno, strerror(errno), "fopen", + fname); + return [= (. file-fail-exit-code) =]; + } + res = [= handler-proc =](fname, fp); + fclose(fp); + return res; + }[= + +*=* text =][= (tpl-file-line extract-fmt) =] + file_text = malloc(text_size + 1); + if (file_text == NULL) { + fprintf(stderr, _("cannot allocate %u bytes for %s file text\n"), + (unsigned int)text_size+1, fname); + exit([=(. nomem-exit-code)=]); + } + + { + char* pz = file_text; + size_t sz = text_size; + int fd = open(fname, O_RDONLY); + int try_ct = 0; + + if (fd < 0) { + fprintf(stderr, err_str, errno, strerror(errno), "open", fname); + free(file_text); + return [= (. file-fail-exit-code) =]; + } + + while (sz > 0) { + ssize_t rd_ct = read(fd, pz, sz); + /* + * a read count of zero is theoretically okay, but we've already + * checked the file size, so we shoud be reading more. + * For us, a count of zero is an error. + */ + if (rd_ct <= 0) { + /* + * Try retriable errors up to 10 times. Then bomb out. + */ + if ( ((errno == EAGAIN) || (errno == EINTR)) + && (++try_ct < 10) ) + continue; + + fprintf(stderr, err_str, errno, strerror(errno), "read", fname); + exit([=(. file-fail-exit-code)=]); + } + pz += rd_ct; + sz -= rd_ct; + } + close(fd); + } + + /* + * Just in case it is a text file, we have an extra byte to NUL + * terminate the thing. + */ + file_text[ text_size ] = '\0'; + res = [= handler-proc =](fname, file_text, text_size);[= + IF (not (exist? "handler-frees")) =] + free(file_text);[= + ENDIF =] + return res;[= +ESAC =] +}[= +ENDDEF emit-file-dispatcher + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= + +DEFINE stdin-as-input =][= + IF (=* (get "handler-type") "file-") =] + else + /* + * process standard input as input file + */ + res = [= handler-proc =](_("standard input"), stdin);[= + ELSE =][= + (error "'stdin-input' specified for non-file handler type") =][= + ENDIF =][= +ENDDEF stdin-as-input + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= + +DEFINE emit-handler-proc =][= + +CASE handler-type =][= +=* name =][= (set! handler-arg-type "char const * fname") + (define handler-proc "validate_fname") =][= +=* file =][= + (set! handler-arg-type "char const * fname, FILE * entry_fp") + (define handler-proc "validate_fname") =][= +*=* text =][= + (set! handler-arg-type + "char const * fname, char * file_text, size_t text_size") + (define handler-proc "validate_fname") =][= +!E =][= (set! handler-arg-type "char const* pz_entry") + (define handler-proc (get "handler-proc")) =][= +* =][= (error) =][= +ESAC =] + +[= + +IF (set! tmp-text (string-append (get "handler-proc") "-code")) + (exist? tmp-text) + +\=] +static int +[= handler-proc =]([=(. handler-arg-type)=]) +{ + int res = 0;[= + (string-append + (def-file-line tmp-text extract-fmt) + (get tmp-text) ) =] + return res; +}[= + +ELSE + +\=] +extern int [= handler-proc =]([=(. handler-arg-type)=]);[= + +ENDIF + +=][= + +ENDDEF emit-handler-proc + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= + +DEFINE emit-trim-input =] +/** + * strip (destructively) the leading and trailing white space. + * Trailing white space is trimmed with a NUL byte. + * The returned address is that of the first character after the + * leading white space. Characters are not moved. + * + * @param[in,out] pz_s source text pointer + * @returns pointer to the same text buffer, but after skipping over the + * leading white space characters. + */ +static char * +trim_input_line(char * src_str) +{ + while ((unsigned int)isspace(*src_str)) + src_str++; + + { + char * end = src_str + strlen(src_str); + while ((end > src_str) && isspace((unsigned int)end[-1])) + end--; + *end = '\0'; + } + + switch (*src_str) { + case '\0':[= + (define comment-char (substring (get "comment-char" "#") 0 1)) + (if (> (string-length comment-char) 0) (begin + (if (or (== comment-char "\\") (== comment-char "'")) + (set! comment-char (string-append "\\" comment-char)) ) + (string-append "\n case '" comment-char "':") + ) ) =] + return NULL; + default: + return src_str; + } +} +[= +ENDDEF emit-trim-input + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= + +DEFINE files-from-stdin =] + /* + * Input list from tty input + */ + else if (isatty(STDIN_FILENO)) { + fputs(_("[=(. prog-name)=] ERROR: input list is a tty\n"), stderr); + [= (. UP-prefix) =]USAGE([=(. file-fail-exit-code)=]); + /* NOTREACHED */ + } + + /* + * Input list from a pipe or file or some such + */ + else { + long pg_size = sysconf(_SC_PAGESIZE); + char * buf = malloc((size_t)pg_size); + if (buf == NULL) { + fputs(_("[=(. prog-name) + =] ERROR: no memory for input list\n"), stderr); + return [=(. nomem-exit-code)=]; + } + + for (;;) { + char * pz = fgets(buf, (ssize_t)pg_size, stdin); + if (pz == NULL) + break; + + pz = trim_input_line(pz); + if (pz == NULL) + continue;[= + IF (= (get "handler-type") "file-r") =] + if ((pz[0] == '-') && (pz[1] == '\0')) + continue; /* disallowed when reading operands from stdin */[= + ENDIF file-r handler type =][= + IF (exist? "interleaved") =] + if (*pz == '-') { + optionLoadLine(&[=(. pname)=]Options, pz); + continue; + }[= + ENDIF interleaved =] + res |= [= (. handler-proc) =](pz); + proc_ct++; + } + + if (proc_ct == 0) + fputs(_("[=(. prog-name) + =] Warning: no input lines were read\n"), stderr); + free(buf); + } +[= + +ENDDEF files-from-stdin + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + + BUILD MAIN + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= + +DEFINE build-main =][= FOR main[] =][= + + CASE main-type =][= + == shell-process =][= + INVOKE build-test-main test-main = "optionPutShell" =][= + + == shell-parser =][= + INVOKE build-test-main test-main = "optionParseShell" =][= + + == main =][= + INVOKE build-test-main =][= + + == include =] +[= INCLUDE tpl =][= + + == invoke =][= + INVOKE (get "func") =][= + + == for-each =][= + INVOKE for-each-main =][= + + * =][= + (error (sprintf "unknown/invalid main-type: '%s'" (get "main-type"))) =][= + + ESAC =][= ENDFOR first-main =][= + +ENDDEF build-main + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + + DECLARE OPTION CALLBACK PROCEDURES + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= + +DEFINE decl-callbacks + + This is the test for whether or not to emit callback handling code: + +=] +/** + * Declare option callback procedures + */[= + (define undef-proc-names "") + (define decl-type "") + (define extern-proc-list (string-append + (if (exist? "version-proc") + (get "version-proc") + "optionPrintVersion") "\n" + "optionBooleanVal\n" + "optionNestedVal\n" + "optionNumericVal\n" + "optionResetOpt\n" + "optionStackArg\n" + "optionTimeDate\n" + "optionTimeVal\n" + "optionUnstackArg\n" + "optionVendorOption\n" + + ) ) + + (define extern-test-list "") + + (define emit-decl-list (lambda(txt-var is-extern) + (if (> (string-length txt-var) 1) (begin + + (emit (if is-extern "\nextern tOptProc\n" "\nstatic tOptProc\n")) + (set! txt-var (shellf " + (%s -v '^%s$' | sed '/^$/d' | sort -u | \ + sed 's@$@,@;$s@,$@;@' ) <<_EOProcs_\n%s_EOProcs_" + egrep-prog + (if is-extern "NULL" "(NULL|optionStackArg|optionUnstackArg)") + txt-var )) + + (emit (shellf (if (< (string-length txt-var) 72) + "f='%s' ; echo \" \" $f" + "${CLexe} --spread=1 -I4 <<_EOProcs_\n%s\n_EOProcs_" ) + txt-var )) + )) + )) + + (define static-proc-list "doUsageOpt\n") + (define static-test-list static-proc-list) + (define ifdef-fmt (string-append + "\n#if%1$sdef %2$s" + "\n %3$s tOptProc %4$s;" + "\n#else /* not %2$s */" + "\n# define %4$s NULL" + "\n#endif /* def/not %2$s */")) + + (define make-proc-decl #t) + + (define set-ifdef (lambda(n-or-def ifdef-cb ifdef-name) (begin + (set! decl-type (if (hash-ref is-ext-cb-proc flg-name) "extern" "static")) + (set! make-proc-decl #f) + (ag-fprintf 0 ifdef-fmt n-or-def ifdef-name decl-type ifdef-cb ) + ))) + + (define set-cb-decl (lambda() (begin + + (set! make-proc-decl #t) + (set! tmp-val (hash-ref cb-proc-name flg-name)) + + (if (exist? "ifdef") + (set-ifdef "" tmp-val (get "ifdef")) + + (if (exist? "ifndef") + (set-ifdef "n" tmp-val (get "ifndef")) + + (if (hash-ref is-ext-cb-proc flg-name) + (set! extern-proc-list (string-append + extern-proc-list tmp-val "\n" )) + + (set! static-proc-list (string-append + static-proc-list tmp-val "\n" )) + ) ) ) + + (if guarded-test-main (begin + (set! tmp-val (hash-ref test-proc-name flg-name)) + (if (hash-ref is-ext-cb-proc flg-name) + (set! extern-test-list (string-append extern-test-list + tmp-val "\n" )) + + (if make-proc-decl + (set! static-test-list + (string-append static-test-list tmp-val "\n") ) ) ) + ) ) + + ))) + =][= + + FOR flag =][= + + ;; Fill in four strings with names of callout procedures: + ;; extern-test-list - external callouts done IFF test main is built + ;; static-test-list - static callouts done IFF test main is built + ;; extern-proc-list - external callouts for normal compilation + ;; static-proc-list - static callouts for normal compilation + ;; + ;; Anything under the control of "if[n]def" has the declaration or + ;; #define to NULL emitted immediately. + ;; + (set! flg-name (get "name")) + + (if (and (hash-ref have-cb-procs flg-name) + (not (hash-ref is-lib-cb-proc flg-name)) ) + (set-cb-decl) + ) =][= + + ENDFOR flag =][= + + IF (. guarded-test-main) =][= + INVOKE emit-testing-defines =][= + ENDIF guarded-test-main =][= + + (if (not (exist? "no-libopts")) + (set! extern-proc-list (string-append extern-proc-list + "optionPagedUsage\n")) ) + + (emit-decl-list extern-proc-list #t) + (emit-decl-list static-proc-list #f) + (set! static-proc-list "") =][= + + FOR flag =][= + + (set! flg-name (get "name")) + (if (not (= (hash-ref cb-proc-name flg-name) + (hash-ref test-proc-name flg-name))) + (set! static-proc-list (string-append static-proc-list + "#define " (get-up-name "name") "_OPT_PROC " + (hash-ref cb-proc-name flg-name) "\n")) ) + =][= + ENDFOR flag =][= + + IF (> (string-length static-proc-list) 0) =] + +/** + * #define map the "normal" callout procs + */ +[= (. static-proc-list) =][= + + ENDIF have some #define mappings + +=][= + + (if guarded-test-main + (emit "\n#endif /* " main-guard " */") ) + + undef-proc-names =][= + +ENDDEF decl-callbacks + +// # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= + +DEFINE emit-testing-defines + +=][= + (set! extern-proc-list (string-append extern-proc-list + "optionVersionStderr\n")) + (tpl-file-line extract-fmt) =] +#if defined([=(. main-guard)=]) +/* + * Under test, omit argument processing, or call optionStackArg, + * if multiple copies are allowed. + */[= + + (emit-decl-list extern-test-list #t) + (emit-decl-list static-test-list #f) + (set! static-test-list "") =][= + + FOR flag =][= + + (set! flg-name (get "name")) + (if (not (= (hash-ref cb-proc-name flg-name) + (hash-ref test-proc-name flg-name))) + (set! static-test-list (string-append static-test-list + "#define " (get-up-name "name") "_OPT_PROC " + (hash-ref test-proc-name flg-name) "\n")) ) + =][= + ENDFOR flag =][= + + IF (> (string-length static-test-list) 0) =] + +/* + * #define map the "normal" callout procs to the test ones... + */ +[= (. static-test-list) =][= + + ENDIF have some #define mappings + +=] + +#else /* NOT defined [=(. main-guard)=] */ +/* + * When not under test, there are different procs to use + */[= + +ENDDEF emit-testing-defines + +// # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + + DEFINE OPTION CALLBACKS + +// # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= + +DEFINE callback-proc-header =] + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/** + * Code to handle the [=name=] option[= # */ =][= + + IF (exist? "ifdef") + +=], when [= ifdef =] is #define-d[= + (define ifdef-text (string-append "\n#ifdef " (get "ifdef"))) + (set! endif-test-main (string-append + (sprintf "\n#endif /* defined %s */" (get "ifdef")) + endif-test-main + )) =][= + + ELIF (exist? "ifndef") + +=], when [= ifndef =] is *not* #define-d[= + (define ifdef-text (string-append "\n#ifndef " (get "ifndef"))) + (set! endif-test-main (string-append + (sprintf "\n#endif /* ! defined %s */" (get "ifndef")) + endif-test-main + )) =][= + + ELSE unconditional code: + +=][= (define ifdef-text "") =][= + + ENDIF ifdef / ifndef + +=]. +[= (prefix " * " (get "doc")) =] + * @param[in] pOptions the [=(. prog-name)=] options data structure + * @param[in,out] pOptDesc the option descriptor for this option. + */[= (. ifdef-text) =] +static void +doOpt[= (set! endif-test-main (string-append "\n}" endif-test-main)) + cap-name =](tOptions* pOptions, tOptDesc* pOptDesc) +{ +[= + +ENDDEF callback-proc-header + +// # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= + +DEFINE reset-clause =][= + + (if (exist? "flag-code[0]") + (emit (string-append "\n" (get "flag-code[0]")))) + + (if (exist? "resettable") (emit (string-append + "\n if ((pOptDesc->fOptState & OPTST_RESET) != 0)" + "\n return;" )) ) + + =][= + +ENDDEF reset-clause + +// # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= + +DEFINE range-option-code + +=][= + +(define option-arg-type (get "arg-type")) +(define range-count (count "arg-range")) + +\=] + static struct {long rmin, rmax;} const rng[[= + (. range-count) =]] = { +[=(out-push-new) =][= + FOR arg-range ",\n" =]{ [= + + CASE arg-range =][= + *== "->" =][= + (string-substitute (get "arg-range") "->" "") =], LONG_MAX[= + + ==* "->" =]LONG_MIN, [= + (string-substitute (get "arg-range") "->" "") =][= + + *==* "->" =][= + (string-substitute (get "arg-range") "->" ", ") =][= + + ~~ -{0,1}[0-9]+ =][=arg-range=], LONG_MIN[= + + * =][= (error (string-append "Invalid range spec: ``" + (get "arg-range") "''" )) =][= + + ESAC arg-range =] }[= + ENDFOR =][= + + (shellf "${CLexe} -I8 --spread=2 <<_EOF_\n%s\n_EOF_" + (out-pop #t)) =] }; + int ix; + + if (pOptions <= OPTPROC_EMIT_LIMIT) + goto emit_ranges;[= + + INVOKE reset-clause =][= + + CASE (define leave-ok-code "") (define ok-return-code "") + (if (exist? "flag-code[1]") + (begin + (set! leave-ok-code "goto return_okay") + (set! ok-return-code (string-append + "\n return;\n\nreturn_okay:\n" + (get "flag-code[1]") )) + ) + (begin + (set! leave-ok-code "return") + (set! ok-return-code "") + ) ) + + option-arg-type =][= + + =* num =] + optionNumericVal(pOptions, pOptDesc);[= + + = time-date =][= + (error (string-append "time/date option " low-name + " may not be range limited.")) ) + =][= + + =* time =] + optionTimeVal(pOptions, pOptDesc); + if (pOptDesc->optArg.argInt == (long)BAD_TIME) + return;[= + + * =][= + (error (string-append option-arg-type " option " low-name + " may not be range limited.")) ) + =][= + + ESAC =] + + for (ix = 0; ix < [=(. range-count)=]; ix++) { + if (pOptDesc->optArg.argInt < rng[ix].rmin) + continue; /* ranges need not be ordered. */ + if (pOptDesc->optArg.argInt == rng[ix].rmin) + [= (. leave-ok-code) =]; + if (rng[ix].rmax == LONG_MIN) + continue; + if (pOptDesc->optArg.argInt <= rng[ix].rmax) + [= (. leave-ok-code) =]; + } + + option_usage_fp = stderr; + + emit_ranges: +optionShowRange(pOptions, pOptDesc, VOIDP(rng), [= (. range-count) =]);[= + +(. ok-return-code) =][= + +ENDDEF range-option-code + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= + +DEFINE alias-option-code \=] + int res = optionAlias(pOptions, pOptDesc, [= + (string-append INDEX-pfx (get-up-name "aliases")) =]); + if ((res != 0) && ((pOptions->fOptSet & OPTPROC_ERRSTOP) != 0)) + [= (. UP-prefix) =]USAGE([=(. usage-err-name)=]); +[= + +ENDDEF alias-option-code + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= + +DEFINE keyword-code =][= + (emit (tpl-file-line extract-fmt)) + + (set! tmp-ct (count "keyword")) + (if (not (exist? "arg-default")) + (begin + (set! tmp-ct (+ 1 tmp-ct)) + (emit " static char const zDef[2] = { 0x7F, 0 };\n") + ) ) \=] + static char const * const names[[= (. tmp-ct) =]] = {[= + (emit (if (not (exist? "arg-default")) " zDef,\n" "\n")) + (out-push-new) =][= + FOR keyword =][= + (string-table-add-ref opt-strs (get "keyword")) =] +[= ENDFOR =][= + (shell (string-append + "${CLexe} -S, -I8 --spread=1 <<-\\_EOF_\n" (out-pop #t) "_EOF_\nset +x" )) +=] }; + + if (pOptions <= OPTPROC_EMIT_LIMIT) { + (void) optionEnumerationVal(pOptions, pOptDesc, names, [= + (. tmp-ct)=]); + return; /* protect AutoOpts client code from internal callbacks */ + }[= + + INVOKE reset-clause =][= + + IF (exist? "arg-optional") + +=] + + if (pOptDesc->optArg.argString == NULL) + pOptDesc->optArg.argEnum = [= + (string-append UP-name "_" (if (> (len "arg-optional") 0) + (get-up-name "arg-optional") (if (exist? "arg-default") + (get-up-name "arg-default") + "UNDEFINED" ))) =]; + else + pOptDesc->optArg.argEnum = + optionEnumerationVal(pOptions, pOptDesc, names, [=(. tmp-ct)=]);[= + + ELSE + +=] + + pOptDesc->optArg.argEnum = + optionEnumerationVal(pOptions, pOptDesc, names, [=(. tmp-ct)=]);[= + + ENDIF =][= + + (if (exist? "flag-code[1]") + (emit (string-append "\n" (get "flag-code[1]")))) + + =][= + +ENDDEF keyword-code + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= + +DEFINE set-membership-code + +=][= + +(if (not (exist? "keyword")) + (error "set membership requires keywords")) +(set! tmp-ct (count "keyword")) +(emit (tpl-file-line extract-fmt)) +(ag-fprintf 0 " static char const * const names[%d] = {\n" tmp-ct) + +(shell (string-append + + "${CLexe} -I8 --spread=2 --sep=',' -f'\"%s\"' <<_EOF_\n" + (join "\n" (stack "keyword")) + "\n_EOF_\n" )) =] + };[= + + INVOKE reset-clause =] + /* + * This function handles special invalid values for "pOptions" + */ + optionSetMembers(pOptions, pOptDesc, names, [= (. tmp-ct) =]);[= + + (if (exist? "flag-code[1]") + (emit (string-append "\n" (get "flag-code[1]")))) + + =][= + +ENDDEF set-membership-code + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= + +DEFINE file-name-code + +\=] + static teOptFileType const type = + [= (set! tmp-val (get "open-file")) =][= + CASE file-exists =][= + == "" =]FTYPE_MODE_MAY_EXIST[= + =* "no" =]FTYPE_MODE_MUST_NOT_EXIST[= + * =]FTYPE_MODE_MUST_EXIST[= + ESAC =] + [= CASE open-file =][= + + == "" =]FTYPE_MODE_NO_OPEN[= + =* "desc" =]FTYPE_MODE_OPEN_FD[= + * =]FTYPE_MODE_FOPEN_FP[= + + ESAC =]; + static tuFileMode mode; +[= IF (or (=* tmp-val "desc") (== tmp-val "")) \=] +[= IF (not (exist? "file-mode")) \=] +#ifndef O_CLOEXEC +# define O_CLOEXEC 0 +#endif +[= (define file-mode "O_CLOEXEC") =][= + ELSE =][= + (define file-mode (get "file-mode")) \=] +[= ENDIF \=] + mode.file_flags = [= (. file-mode) =]; +[= ELSE \=] +#ifndef FOPEN_BINARY_FLAG +# define FOPEN_BINARY_FLAG +#endif + mode.file_mode = [= (c-string (get "file-mode")) =] FOPEN_BINARY_FLAG; +[= ENDIF =][= + + INVOKE reset-clause =] + /* + * This function handles special invalid values for "pOptions" + */ + optionFileCheck(pOptions, pOptDesc, type, mode);[= + + (if (exist? "flag-code[1]") + (emit (string-append "\n" (get "flag-code[1]")))) + + =][= + +ENDDEF file-name-code + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= + +DEFINE requested-code =][= + +IF (not (or (exist? "extract-code") (exist? "flag-code"))) + =][= RETURN =][= +ENDIF =][= + +(if guarded-test-main + (begin + (set! endif-test-main + (sprintf "\n#endif /* defined(%s) */" main-guard)) + (emit "\n\n#if ! defined(" main-guard ")") +) ) =][= + +INVOKE callback-proc-header =][= + +IF (out-push-new (string-append tmp-dir "/flag-code")) + (exist? "flag-code") =][= + + IF (exist? "flag-code[0]") \=] + /* + * Be sure the flag-code[0] handles special values for the options pointer + * viz. (poptions <= OPTPROC_EMIT_LIMIT) *and also* the special flag bit + * ((poptdesc->fOptState & OPTST_RESET) != 0) telling the option to + * reset its state. + */[= + (def-file-line "flag-code[0]" "\n /* extracted from %s, line %d */\n") + =][= flag-code[0] =][= + ENDIF =][= + + CASE arg-type =][= + =* bool =] + optionBooleanVal(pOptions, pOptDesc);[= + =* num =] + optionNumericVal(pOptions, pOptDesc);[= + = time-date =] + optionTimeDate(pOptions, pOptDesc);[= + =* time =] + optionTimeVal(pOptions, pOptDesc);[= + ~* hier|nest =] + optionNestedVal(pOptions, pOptDesc);[= + ESAC =][= + + IF (exist? "flag-code[1]") =] +[= flag-code[1] =][= + ENDIF =][= + +ELSE =][= + + (extract (string-append (base-name) ".c.save") (string-append + "/* %s =-= " cap-name " Opt Code =-= %s */")) + =][= +ENDIF =][= +(out-pop) +(shell "ck_flag_code") =][= + +ENDDEF requested-code + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= + +DEFINE define-option-callbacks =][= + + FOR flag =][= + (define flag-index (for-index)) + (set-flag-names) + (define endif-test-main "") =][= + +# # # # # # # # # # # # # # # # # # =][= + + IF (exist? "arg-range") =][= + + INVOKE callback-proc-header =][= + INVOKE range-option-code =][= + +# # # # # # # # # # # # # # # # # # =][= + + ELIF (exist? "aliases") =][= + + INVOKE callback-proc-header =][= + INVOKE alias-option-code =][= + +# # # # # # # # # # # # # # # # # # =][= + + ELSE =][= CASE arg-type =][= + + =* key =][= + INVOKE callback-proc-header =][= + INVOKE keyword-code =][= + +# # # # # # # # # # # # # # # # # # =][= + + =* set =][= + + INVOKE callback-proc-header =][= + INVOKE set-membership-code =][= + +# # # # # # # # # # # # # # # # # # =][= + + =* fil =][= + INVOKE callback-proc-header =][= + INVOKE file-name-code =][= + +# # # # # # # # # # # # # # # # # # =][= + + * =][= + INVOKE requested-code =][= + + ESAC =][= + ENDIF =][= + + (. endif-test-main) =][= + + ENDFOR flag =][= + +ENDDEF define-option-callbacks + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= + +DEFINE emit-option-callbacks =] +/* + * Create the static procedure(s) declared above. + */ +/** + * The callout function that invokes the [= (. usage-proc) + =] function. + * + * @param[in] opts the AutoOpts option description structure + * @param[in] od the descriptor for the "help" (usage) option. + * @noreturn + */ +static void +doUsageOpt(tOptions * opts, tOptDesc * od) +{ + int ex_code;[= + + IF (define od-used #f) + (exist? "resettable") =] + if ((od->fOptState & OPTST_RESET) != 0) + return;[= (set! od-used #t) =][= + + ENDIF =][= + + IF (exist? "usage-opt") =] + ex_code = (od->optIndex == [= (set! od-used #t) INDEX-pfx =]HELP) + ? [=(. succ-exit-code)=] : AO_EXIT_REQ_USAGE;[= + + ELSE =] + ex_code = [=(. succ-exit-code)=];[= + ENDIF =][= + (string-append "\n " usage-proc "(&" pname "Options, ex_code);") =] + /* NOTREACHED */ + exit([=(. fail-exit-code)=]); + (void)opts;[= + (if od-used "" "\n (void)od;") =] +}[= + +INVOKE define-option-callbacks =][= + +IF (exist? "main") =][= + INVOKE build-main =][= + +ELIF (. guarded-test-main) =][= + INVOKE build-test-main =][= + +ENDIF + +=][= +(tpl-file-line extract-fmt) +=][= + +IF (exist? "usage-message") =] +/** + * Print a usage message with a format and va_list argument. + * The [= (. usage-proc) =] function is then invoked to print + * the error usage text (somewhat abbreviated) and then exit. + * + * @param[in] fmt the message format string + * @param[in] ap the var-arg list. + * @noreturn + */ +[=(. no-return-str)=]vusage_message(char const * fmt, va_list ap) +{ + char const * er_leader = _("[= prog-name =] usage error:\n"); + fputs(er_leader, stderr); + vfprintf(stderr, fmt, ap); + [= (string-append usage-proc "(&" pname "Options, " usage-err-name ")") =]; + /* NOTREACHED, but C11 compilers cannot tell. */ + abort(); +} + +/** + * Print a usage message with a format and a variable argument list. + * [=(. lc-prefix)=]vusage_message() is called to do the work. + * + * @param[in] fmt the message format string + * @param[in] ... the argument list for the message + * @noreturn + */ +[=(. no-return-str)=]usage_message(char const * fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + [=(. lc-prefix)=]vusage_message(fmt, ap); +} +[= + +ENDIF have usage-message =][= + +IF (exist? "die-code") + +=] +/** + * Print a fatal error message and die, \a va_list style. + * + * @param[in] exit_code the value to call exit(3) with + * @param[in] fmt the death rattle message + * @param[in] ap the argument list for the message + * @noreturn + */ +[=(. no-return-str)=]vdie(int exit_code, char const * fmt, va_list ap) +{ + char const * die_leader = _("[= prog-name =] fatal error:\n");[= + (set! tmp-text (get "die-code")) + (if (> (string-length tmp-text) 1) + (string-append "\n\n" tmp-text "\n")) + =] + fputs(die_leader, stderr); + vfprintf(stderr, fmt, ap); + fflush(stderr); + exit(exit_code); +} + +/** + * Print a fatal error message and die, var-arg style. + * + * @param[in] exit_code the value to call exit(3) with + * @param[in] fmt the death rattle message + * @param[in] ... the list of arguments for the message + * @noreturn + */ +[=(. no-return-str)=]die(int exit_code, char const * fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + vdie(exit_code, fmt, ap); +} + +/** + * Print a file system error fatal error message and die. + * + * @param[in] exit_code the value to call exit(3) with. + * @param[in] op the operation that failed. + * @param[in] fname the file name the operation was on. + * @noreturn + */ +[=(. no-return-str)=]fserr(int exit_code, char const * op, char const * fname) +{ + char const * fserr_fmt = _("fserr %d (%s) performing '%s' on %s\n"); + die(exit_code, fserr_fmt, errno, strerror(errno), op, fname); +} +[= +ENDIF die-code =][= + +IF (exist? "warn-code") + +=] +/** + * Print a warning message, \a va_list style. + * + * @param[in] fmt the "something awry" message + * @param[in] ap the argument list for the message + */ +void +[=(. lc-prefix)=]vwarning_msg(char const * fmt, va_list ap) +{ + char const * warn_leader = _("[= prog-name =] WARNING:\n");[= + (set! tmp-text (get "warn-code")) + (if (> (string-length tmp-text) 1) + (string-append "\n\n" tmp-text "\n")) + =] + fputs(warn_leader, stderr); + vfprintf(stderr, fmt, ap); + fflush(stderr); +} + +/** + * Print a warning message, var-arg style. + * + * @param[in] fmt the "something awry" message + * @param[in] ... the list of arguments for the message + */ +void +[=(. lc-prefix)=]warning_msg(char const * fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + vwarning_msg(fmt, ap); + va_end(ap); +} +[= + +ENDIF have warn-code =][= + +ENDDEF emit-option-callbacks + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= + +DEFINE emit-option-code =][= + + IF (exist? "option-code") =][= + (def-file-line "option-code" extract-fmt) =][= + option-code =][= + + ELSE =][= + + IF (and (exist? "no-libopts") (not (exist? "autoopts-usage-tlib"))) =] + (void)process_[=(. pname)=]_opts(argc, argv);[= + ELIF (exist? "main-text") =] + { + int ct = optionProcess(&[=(. pname)=]Options, argc, argv); + argc -= ct; + argv += ct; + }[= + ELSE =] + (void)optionProcess(&[=(. pname)=]Options, argc, argv);[= + ENDIF =][= + + ENDIF =][= + +ENDDEF emit-option-code + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= + +DEFINE emit-main-text =][= + + IF (exist? "main-text") =][= + + (def-file-line "main-text" extract-fmt) =][= + main-text =][= + + ELSE =][= + + IF (and (exist? "no-libopts") (not (exist? "autoopts-usage-tlib"))) =] + /* When using AutoOpts with getopt(3C) or getopt_long(3GNU) + the main-text attribute of main _must_ be defined. */ +#error autoopts_with_getopt_must_define_main_text_attribute[= + ELSE test-main is not optionParseShell and main-text not exist + Above, we figure out which emitter procedure is to be used. + The default is optionPutShell. +=] + [= (. option-emitter-proc) =](&[=(. pname)=]Options); + res = ferror(stdout); + if (res != 0) + fputs("output error writing to stdout\n", stderr);[= + ENDIF =][= + + ENDIF =][= + +ENDDEF emit-main-text =] diff --git a/autoopts/tpl/perlopt.tpl b/autoopts/tpl/perlopt.tpl new file mode 100644 index 0000000..a5d4599 --- /dev/null +++ b/autoopts/tpl/perlopt.tpl @@ -0,0 +1,188 @@ +[= AutoGen5 template foo=(base-name) -*- Mode: scheme -*-=] +[= + +(emit (dne "# ")) + +(if (not (and (exist? "prog-name") (exist? "prog-title") (exist? "version"))) + (error "prog-name and prog-title are required")) +(define prog-name (get "prog-name")) + +(if (> (string-length prog-name) 16) + (error (sprintf "prog-name limited to 16 characters: %s" + prog-name)) ) +(if (not (exist? "long-opts")) + (error "long-opts is required")) + +;; perl list containing string to initialize the option hash +(define perl_opts "") +;; perl list containing option definitions for Getopt::Long +(define perl_defs " ") +;; usage string +(define perl_usage "") + +(define optname-from "A-Z_^") +(define optname-to "a-z--") +(define counter 0) + +(define q (lambda (s) (string-append "'" s "'"))) +(define qp (lambda (s) (string-append "q{" s "}"))) + +=][= + +FOR flag =][= + +(define optarg "") ;; the option argument for Getopt::Long +(define opttarget "''") ;; the value of a hash key that represents option +(define optargname "") +(define optisarray #f) +(define optname (string-tr! (get "name") optname-from optname-to)) + +=][= # +;; since autoopts doesn't support float we take the combination arg-name = +;; float and arg-type = string as float +=][= + IF arg-type =][= + CASE arg-type =][= + + =* num =][= (set! optarg "=i") =][= + + =* str =][= + (if (and (exist? "arg-name") (== (get "arg-name") "float")) + (set! optarg "=f") + (set! optarg "=s") + ) =][= + + * =][= + (error (string-append "unknown arg type '" + (get "arg-type") "' for " (get "name"))) =][= + ESAC arg-type =][= + ENDIF =][= + +(if (exist? "stack-arg") + ;; set optarget to array reference if can take more than one value + ;; FIXME: if "max" exists, then just presume it is greater than 1 + ;; + (if (and (exist? "max") (== (get "max") "NOLIMIT")) + (begin + (set! opttarget (string-append + "[" + (if (exist? "arg-default") (q (get "arg-default")) "") + "]" + ) + ) + (set! optisarray #t) + ) + (error "If stack-arg then max has to be NOLIMIT") + ) + ;; just scalar otherwise + (if (exist? "arg-default") (set! opttarget (q (get "arg-default")))) +) + +(set! perl_opts (string-append perl_opts + "'" (get "name") "' => " opttarget ",\n ")) + +(define def_add (string-append "'" optname (if (exist? "value") + (string-append "|" (get "value")) "") optarg "',")) + +(define add_len (+ (string-length def_add) counter)) +(if (> add_len 80) + (begin + (set! perl_defs (string-append perl_defs "\n " def_add)) + (set! counter 8) + ) + (begin + (set! perl_defs (string-append perl_defs " " def_add)) + (set! counter (+ counter add_len)) + ) +) + +(if (exist? "arg-type") + (if (and (exist? "arg-name") (== (get "arg-name") "float")) + (set! optargname "=float") + (set! optargname (string-append "=" (substring (get "arg-type") 0 3))) + ) + (set! optargname " ") +) + +(if (not (exist? "deprecated")) + (set! perl_usage (string-append perl_usage + (sprintf "\n %-28s %s" (string-append + (if (exist? "value") (string-append "-" (get "value") ",") " ") + " --" + (get "name") + optargname) + (get "descrip")) +) ) ) +(if optisarray + (set! perl_usage (string-append perl_usage + "\n - may appear multiple times")) +) + +=][= + +ENDFOR each "flag" =] + +use Getopt::Long qw(GetOptionsFromArray); +Getopt::Long::Configure(qw(no_auto_abbrev no_ignore_case_always)); + +my $usage; + +sub usage { + my ($ret) = @_; + print STDERR $usage; + exit $ret; +} + +sub paged_usage { + my ($ret) = @_; + my $pager = $ENV{PAGER} || '(less || more)'; + + open STDOUT, "| $pager" or die "Can't fork a pager: $!"; + print $usage; + + exit $ret; +} + +sub processOptions { + my $args = shift; + + my $opts = { + [= (. perl_opts) =]'help' => '', 'more-help' => '' + }; + my $argument = '[= argument =]'; + my $ret = GetOptionsFromArray($args, $opts, ( +[= (. perl_defs) =] + 'help|?', 'more-help')); + + $usage = <<'USAGE'; +[= prog-name =] - [= prog-title =] - Ver. [= version =] +USAGE: [= prog-name =] [ - [] | --[{=| }] ]... [= argument =] +[= (. perl_usage) =] + -?, --help Display usage information and exit + --more-help Pass the extended usage text through a pager + +Options are specified by doubled hyphens and their name or by a single +hyphen and the flag character. +USAGE + + usage(0) if $opts->{'help'}; + paged_usage(0) if $opts->{'more-help'};[= + +CASE argument =][= +!E =][= +==* "[" =][= +* =] + + if ($argument && $argument =~ /^[^\[]/ && !@$args) { + print STDERR "Not enough arguments supplied (See --help/-?)\n"; + exit 1; + }[= + +ESAC + +=] + $_[0] = $opts; + return $ret; +} + +END { close STDOUT }; diff --git a/autoopts/tpl/rc-sample.tpl b/autoopts/tpl/rc-sample.tpl new file mode 100644 index 0000000..58ba840 --- /dev/null +++ b/autoopts/tpl/rc-sample.tpl @@ -0,0 +1,125 @@ +[= AutoGen5 Template rc + +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + +=] +# [= (define prog-name (get "prog-name")) + prog-name =] sample configuration file +#[= + +IF (if (not (exist? "homerc")) + (error "RC file samples only work for rc-optioned programs") ) + + (out-move (string-append "sample-" + (if (exist? "rcfile") (get "rcfile") + (string-append (get "prog-name") "rc") ) + ) ) + + (set-writable) + + (exist? "copyright") +\=] +# This source file is copyrighted and licensed under the following terms: +# +[= + CASE copyright.type =][= + == "" =][= + (sprintf "# %s Copyright (C) %s %s - all rights reserved\n# %s" + prog-name (get "copyright.date") (get "copyright.owner") + "licensing type not specified" ) =][= + + = note =][= (prefix "# " (get "copyright.text")) =][= + + * =][= (license-full (get "copyright.type") prog-name "# " + (get "copyright.owner") (get "copyright.date")) =][= + ESAC =][= + +ENDIF "copyright exists" =][= + +FOR flag =][= + + IF (not (or (exist? "documentation") (exist? "no-preset"))) =] + +# [= name =] -- [= descrip =] +# +[= INVOKE emit-description =] +# Example: +# +#[= name =][= + IF (exist? "arg-type") + =] [= (if (exist? "arg-default") (get "arg-default") + (if (exist? "arg-name") (get "arg-name") + (get "arg-type") )) =][= + ENDIF (exist? "arg-type") =][= + + ENDIF (not (exist? "documentation")) =][= + +ENDFOR flag + += = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =][= + +DEFINE emit-description =][= +(out-push-new) =][= + + IF (~* (get "arg-type") "key|set") +=]This configuration value takes a keyword as its argument[= + + IF (=* (get "arg-type") "set") + +=] list. Each entry turns on or off membership bits. The bits are set by [=# +=]name or numeric value and cleared by preceding the name or number with an [=# +=]exclamation character ('!'). [= + + ELSE + +=]. [= + + ENDIF + +=]The available keywords are: [= + (join ", " (stack "keyword")) =]. [= + + ELIF (=* (get "arg-type") "num") + =]This configuration value takes an integer number as its argument. [= + IF (exist? "scaled") =]That number may be scaled with a single letter [=# +=]suffix: k/K/m/M/g/G/t/T These will multiply the value by powers of [=# +=]1000 (lower case) or 1024 (upper case). [= + ENDIF =][= + + ENDIF =][= + + (define fill-txt (out-pop #t)) + (if (defined? 'fill-txt) + (string-append + + (shell (string-append "while read line + do echo ${line} | fold -s -w76 | sed 's/^/# /' + echo '#' + done <<'__EndOfText__'\n" fill-txt "\n__EndOfText__" )) + + "\n#\n" + ) ) =][= + + (if (exist? "doc") (prefix "# " (get "doc"))) =][= + +ENDDEF emit-description + +=] diff --git a/autoopts/tpl/stdoptions.def b/autoopts/tpl/stdoptions.def new file mode 100644 index 0000000..6934fa0 --- /dev/null +++ b/autoopts/tpl/stdoptions.def @@ -0,0 +1,427 @@ + +/* -*- Mode: Text -*- + * + * This file is part of AutoOpts, a companion to AutoGen. + * AutoOpts is free software. + * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoOpts is available under any one of two licenses. The license + * in use must be one of these two and the choice is under the control + * of the user of the license. + * + * The GNU Lesser General Public License, version 3 or later + * See the files "COPYING.lgplv3" and "COPYING.gplv3" + * + * The Modified Berkeley Software Distribution License + * See the file "COPYING.mbsd" + * + * These files have the following sha256 sums: + * + * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 + * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 + * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + */ + +#ifndef NO_STD_OPT_DOC +# ifndef HAVE_STD_OPT_DOC +# define HAVE_STD_OPT_DOC 1 +flag = { + name = autoopts_std_options; + documentation; + descrip = <<- _EOF_ + The following options are commonly used and are + provided and supported by AutoOpts + _EOF_; +}; +# endif +#endif + +#ifdef ALL_STD_OPTS +#define BRIEF +#define DEBUG +#define DIRECTORY +#define DRY_RUN +#define INPUT +#define INTERACTIVE +#define OUTPUT +#define QUIET +#define SILENT +#define VERBOSE +#define WARN +#endif + +#ifdef ALL_FLAG_OPTS +#define BRIEF_FLAG +#define DEBUG_FLAG +#define DIRECTORY_FLAG +#define DRY_RUN_FLAG +#define INPUT_FLAG +#define INTERACTIVE_FLAG +#define OUTPUT_FLAG +#define QUIET_FLAG +#define SILENT_FLAG +#define VERBOSE_FLAG +#define WARN_FLAG +#endif + +#ifdef STD_EXITS +exit-name[64] = usage; +exit-desc[64] =<<- _EOExit_ + The command was used incorrectly, e.g., with the wrong number of + arguments, a bad flag, a bad syntax in a parameter. + _EOExit_; + +exit-name[65] = dataerr; +exit-desc[65] =<<- _EOExit_ + The input data was incorrect in some way. + _EOExit_; + +exit-name[66] = noinput; +exit-desc[66] =<<- _EOExit_ + An input file (not a system file) did not exist or was not readable. + _EOExit_; + +exit-name[67] = nouser; +exit-desc[67] =<<- _EOExit_ + The user specified did not exist. + _EOExit_; + +exit-name[68] = nohost; +exit-desc[68] =<<- _EOExit_ + The host specified did not exist. + _EOExit_; + +exit-name[69] = unavailable; +exit-desc[69] =<<- _EOExit_ + A service is unavailable. This can occur if a support program or + file does not exist. This can also be a catchall message when + something doesn't work, and the cause cannot be determined. + _EOExit_; + +exit-name[70] = software; +exit-desc[70] =<<- _EOExit_ + An internal software error has been detected. + _EOExit_; + +exit-name[71] = oserr; +exit-desc[71] =<<- _EOExit_ + An operating system error has been detected. This is used for such + things as "cannot fork", "cannot create pipe", or the similar. + _EOExit_; + +exit-name[72] = osfile; +exit-desc[72] =<<- _EOExit_ + Some system file (e.g., /etc/passwd, /etc/utmp, etc.) does not + exist, cannot be opened, or has some sort of error. + _EOExit_; + +exit-name[73] = cantcreat; +exit-desc[73] =<<- _EOExit_ + A (user specified) output file cannot be created. + _EOExit_; + +exit-name[74] = ioerr; +exit-desc[74] =<<- _EOExit_ + An error occurred while doing I/O on somefile. + _EOExit_; + +exit-name[75] = tempfail; +exit-desc[75] =<<- _EOExit_ + A temporary failure, indicating something that is not really an + error. The request should be reattempted later. + _EOExit_; + +exit-name[76] = protocol; +exit-desc[76] =<<- _EOExit_ + the remote system returned something that was "not possible" during + a protocol exchange. + _EOExit_; + +exit-name[77] = noperm; +exit-desc[77] =<<- _EOExit_ + You did not have sufficient permission to perform the operation. + This is not intended for file system problems, which should use + NOINPUT or CANTCREAT, but rather for higher level permissions. + _EOExit_; + +exit-name[78] = config; +exit-desc[78] = 'configuration error'; +#endif + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * Levels of user entertainment + * + * DEBUG output + */ +#ifdef DEBUG_FLAG +#define DEBUG +#endif + +#ifdef DEBUG +flag = { + name = DEBUG; +#ifdef DEBUG_FLAG + value = D; +#endif +#ifdef DEBUG_LEVEL + arg-type = number; +#endif + descrip = 'run program with debugging info'; + doc = + "Specifying this option will cause the program to display debugging\n" + "information. The information should be helpful to a developer in\n" + "debugging this program."; +}; +#endif + +/* * * * * * * * + * + * VERBOSE output + */ +#ifdef VERBOSE_FLAG +#define VERBOSE 1 +#endif + +#ifdef VERBOSE +flag = { + name = verbose; +#ifdef VERBOSE_FLAG + value = V; +#endif +#ifdef VERBOSE_LEVEL + arg-type = number; +#endif +#ifdef VERBOSE_ENUM + arg-type = keyword; + keyword = silent, quiet, brief, informative, verbose; + arg-default = brief; +#endif + descrip = 'run program with progress info'; + doc = + "Specifying this option will cause the program to display lots of\n" + "progress information. You will be able to see that the program\n" + "is working and it may help you debug your use of the tool."; +}; +#endif + +/* * * * * * * * + * + * WARNING output + */ +#ifdef WARN_LEVEL +#define WARN +#endif +#ifdef WARN_FLAG +#define WARN +#endif + +#ifdef WARN +flag = { + name = warn; +#ifdef WARN_FLAG + value = w; +#endif +#ifdef WARN_LEVEL + arg-type = number; + descrip = 'specify a warning-level threshhold'; + disable = no; + doc = + "Specifying this option will allow you to specify the warning level\n" + "for the messages you want to see. `--no-warn' will disable\n" + "warnings entirely."; +#else + descrip = 'disable warning output'; + doc = + "Specifying this option will cause the program to disable\n" + "warning messages."; +#endif +}; +#endif + +/* * * * * * * * + * + * BRIEF output + */ +#ifdef BRIEF_FLAG +#define BRIEF +#endif + +#ifdef BRIEF +flag = { + name = brief; +#ifdef BRIEF_FLAG + value = b; +#endif + descrip = 'run with minimal info output'; + doc = + "Specifying this option will cause the program to disable most progress\n" + "information."; +}; +#endif + +/* * * * * * * * + * + * QUIET/SILENT output + */ +#ifdef QUIET_FLAG +#define QUIET +#endif +#ifdef SILENT_FLAG +#define SILENT +#endif + +#ifdef QUIET_SILENT +#define QUIET +#define SILENT +#else + +#ifdef QUIET +#ifdef SILENT +#define QUIET_SILENT +#endif +#endif +#endif + +#ifdef QUIET +flag = { + name = quiet; +#ifdef QUIET_FLAG + value = q; +#endif +#ifdef QUIET_SILENT + equivalence = quiet; +#endif +#ifdef QUIET_LEVEL + arg-type = number; +#endif + descrip = 'run without unnecessary output'; + doc = + "Specifying this option will cause the program to disable progress\n" + "information."; +}; +#endif + +#ifdef SILENT +flag = { + name = silent; +#ifdef SILENT_FLAG + value = s; +#endif +#ifdef QUIET_SILENT + equivalence = quiet; +#endif +#ifdef SILENT_LEVEL + arg-type = number; +#endif + descrip = 'run without unnecessary output'; + doc = + "Specifying this option will cause the program to disable progress\n" + "information."; +}; +#endif + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * Operational mode + * + * DRY_RUN + */ +#ifdef DRY_RUN_FLAG +#define DRY_RUN +#endif + +#ifdef DRY_RUN +flag = { + name = DRY_RUN; +#ifdef DRY_RUN_FLAG + value = R; +#endif + descrip = 'program will make no changes'; + doc = + "Specifying this option will cause the program to run without\n" + "altering any of the normal output files. Instead, it will\n" + "display what it would otherwise have done."; +}; +#endif + +/* * * * * * * * + * + * INTERACTIVE OPERATION + */ +#ifdef INTERACTIVE_FLAG +#define INTERACTIVE +#endif + +#ifdef INTERACTIVE +flag = { + name = interactive; + arg-type = string; +#ifdef INTERACTIVE_FLAG + value = I; /* flag style option character */ +#endif + descrip = "prompt for confirmation"; + doc = + "Specifying this option will cause the program to query you for\n" + "confirmation before doing anything destructive."; +}; +#endif + +/* * * * * * * * + * + * INPUT/OUTPUT files + */ +#ifdef INPUT_FLAG +#define INPUT +#endif + +#ifdef INPUT +flag = { + name = input; + arg-type = string; +#ifdef INPUT_FLAG + value = i; /* flag style option character */ +#endif + descrip = "redirect input from file"; + doc = + "This option specifies the file to use for program input."; +}; +#endif + +#ifdef OUTPUT_FLAG +#define OUTPUT +#endif + +#ifdef OUTPUT +flag = { + name = output; + arg-type = string; +#ifdef OUTPUT_FLAG + value = o; /* flag style option character */ +#endif + descrip = "redirect output to file"; + doc = + "This option specifies the file to use for program output."; +}; +#endif + +/* * * * * * * * + * + * INPUT/OUTPUT directory + */ +#ifdef DIRECTORY_FLAG +#define DIRECTORY +#endif + +#ifdef DIRECTORY +flag = { + name = directory; + arg-type = string; +#ifdef DIRECTORY_FLAG + value = d; /* flag style option character */ +#endif + descrip = "use specified dir for I/O"; + doc = + "This option specifies the directory to use for program input and output."; +}; +#endif diff --git a/autoopts/tpl/str2enum.tpl b/autoopts/tpl/str2enum.tpl new file mode 100644 index 0000000..759b1c6 --- /dev/null +++ b/autoopts/tpl/str2enum.tpl @@ -0,0 +1,856 @@ +[= AutoGen5 Template h c -*- Mode: Scheme -*- + +# This file contains the templates used to generate +# keyword parsing code + +## This file is part of AutoGen. +## AutoGen is free software. +## AutoGen is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen 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. +## +## AutoGen is distributed in the hope that 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 file has the following md5sum: +## +## 43b91e8ca915626ed3818ffb1b71248b COPYING.gplv3 + +=][= + +(emit + (dne " * " "/* ") + "\n *\n" + (if (exist? "copyright") + (license-description + (get "copyright.type" "unknown") + (get "package" (shell "basename `pwd`")) + " * " + (get "copyright.owner" (get "copyright.author" "unknown")) ) + (license-description "mbsd" "str2enum" " * " "Bruce Korb") + ) +) + +=][= + +CASE (suffix) =][= # + +;;; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +;;; +;;; H CODE +;;; +;;;=][= +== h =][= +INVOKE init-header =][= + IF (exist? "addtogroup") =] +/** \file [= (out-name) =] + * Header for string to enumeration values and back again. + * @addtogroup [= addtogroup =] + * @{ + */[= + ENDIF addtogroup =] +#include +#ifndef MISSING_INTTYPES_H +# include +#endif + +typedef enum {[= + (if (> enum-val-offset 0) + (string-append "\n " invalid-cmd " = 0,") ) =][= + (shellf "mk_enum_list %d" enum-val-offset) =] + [= (. cmd-count) =][= + (if (= (get "invalid-val") "~0") + (string-append ",\n " invalid-cmd " = ~0") ) =] +} [= (. enum-name) =]; +[= + + FOR add-on-text =][= + IF (= (get "ao-file") "enum-header") =] +[= ao-text =] +[= ENDIF =][= + ENDFOR add-on-text =][= + + IF (if (exist? "no-code") + (if (exist? "dispatch") + (error "dispatch does not work without code") + #f) + #t) +=] +extern [= +(define find-arg-list (string-append "char const * str" len-arg)) +(string-append enum-name "\n" +find-func-name "(" find-arg-list ");\n") +=][= + +IF (not (exist? "no-name")) + +=] +extern char const * +[=(. base-type-name)=]_name([= (. enum-name) =] id); +[= + +ENDIF no-name + +=][= + + IF (define disp-text "") + (exist? "dispatch") =][= + + (out-push-new) + (out-suspend "disp-text") =][= + + FOR dispatch "\n" =] +[= INVOKE mk-dispatch =][= + ENDFOR dispatch =][= + + (out-resume "disp-text") + (set! disp-text (out-pop #t)) + =][= + + ENDIF dispatch exists + +=] +[=ENDIF exist/not "no-code" =][= +(if (exist? "addtogroup") "\n/** @} */") \=] +#endif /* [=(. header-guard) =] */[= # + +;;; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +;;; +;;; C CODE +;;; +;;;=][= +== c + +=] + */ +#include "[= ;;" + (if (exist? "no-code") (out-delete)) + (if move-output-file + (out-move (string-append base-file-name ".c"))) + header-file =]"[=#"=][= + (. extra-c-incl) =][= + IF (exist? "addtogroup") =] +/** \file [= (out-name) =] + * Code for string to enumeration values and back again. + * @addtogroup [= addtogroup =] + * @{ + */ +[=ENDIF addtogroup =][= + + INVOKE run-gperf =][= + INVOKE mk-finder =][= + + IF (not (exist? "no-name")) =][= + INVOKE mk-enum2name =][= + ENDIF dispatch =][= + + (. disp-text) =][= + + FOR add-on-text =][= + IF (= (get "ao-file") "enum-code") =] +[= ao-text =][= + ENDIF correct type =][= + ENDFOR add-on-text =][= +(if (exist? "addtogroup") "\n/** @} */") \=][= + +ESAC suffix c/h + +;;; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +;; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +;;; +;;; Create the function that converts the name into an enum value. +;;; +;;;=][= + +DEFINE init-header =][= + +(define computed-length #f) +(define return-length #f) +(define tmp-str "") +(define extra-c-incl "") +(define len-arg ", size_t len") +(define len-descrip +"\n * @param[in] len the provided length of the keyword at \\a str.") +(define enum-type "cmd") =][= + +INCLUDE "str2init.tlib" =][= + + CASE length =][= + !E =][= + (if (or (exist? "no-case") (exist? "alias")) + (set! extra-c-incl "\n#include ")) =][= + + = provided =][= + (if (or (exist? "no-case") (exist? "alias")) + (set! extra-c-incl "\n#include ")) =][= + + = returned =][= + (set! extra-c-incl "\n#include \n#include ") + (set! len-arg ", size_t * len") + (define len-descrip + "\n * @param[out] len address to store the keyword length from \\a str.") + (set! computed-length #t) + (set! return-length #t) =][= + + * =][= + (set! extra-c-incl "\n#include \n#include ") + (set! computed-length #t) + (set! len-descrip "") + (set! len-arg "") =][= + ESAC =][= + +(define equate-from "") +(define equate-to "") +(out-push-new) + +=] +mk_char_list() { + echo "$1" | sed 's/\(.\)/\1\ +/g' | sort -u | tr -d '\n\t ' +} + +readonly max_cmd_width=[=(. max-cmd-width)=] +readonly max_enm_width=[=(+ max-cmd-width (string-length enum-prefix) 1)=] +readonly min_cmd_width=[=(. min-cmd-width)=] +[= IF (exist? "equate") =] +equate_from='[=(define equate-from (get "equate")) equate-from=]' +equate_to=`echo "$equate_from" | sed "s#.#[=(substring equate-from 0 1)=]#g"` +[= ENDIF =] +mk_enum_list() { + tr '[a-z]' '[A-Z]' < ${tmp_dir}/commands | sort > ${tmp_dir}/commands-UC + exec 3< ${tmp_dir}/commands-UC + declare n c + declare fmt="\n [=(. enum-prefix)=]_%-${max_cmd_width}s = %s," + while read -u3 n c + do + printf "$fmt" $c `expr $n + $1` + done + exec 3<&- +} +[= + +(shell (out-pop #t)) +(if (exist? "equate") + (set! equate-to (shell "echo \"${equate_to}\"")) ) +(define cmd-chars (join "" (stack "cmd"))) + +(if (exist? "no-case") + (set! cmd-chars (string-append + (string-downcase cmd-chars) (string-upcase cmd-chars) )) ) + +(if (exist? "equate") + (set! cmd-chars (string-append cmd-chars (get "equate"))) +) + +(set! cmd-chars (shell "mk_char_list '" cmd-chars "'" )) +(emit "\n *\n * Command/Keyword Dispatcher\n */\n") +(make-header-guard "str2enum") + +=][= + +ENDDEF init-header + +;;; = = = = = = = = = = = = = = = = = = = +;;; +;;; Create the function that converts the name into an enum value. +;;; +;;;=][= + +DEFINE mk-finder =] + +/** + * Convert a command (keyword) to a [= (. enum-name) =] enumeration value.[= + IF (. computed-length) =] + * The length of the command is computed by calling \a strspn() + * on the input argument.[= + ENDIF =][= + IF (exist? "equate") =] + * Within the keyword, the following characters are considered equivalent: + * \a [=(. cmd-chars) =][= + ENDIF =] + * + * @param[in] str a string that should start with a known key word.[= + (. len-descrip) =] + * @returns the enumeration value. + * If not found, that value is [=(. invalid-cmd)=]. + */ +[= (string-append enum-name "\n" find-func-name) +=](char const * str[=(. len-arg)=]) +{[= + IF (exist? "alias") =] + switch (*str) {[= + FOR alias =] + case '[= (define cmd (get "alias")) + (substring cmd 0 1)=]': return [= + (set! cmd (shellf "echo %s" (substring cmd 1))) + (string-append enum-prefix "_" + (string->c-name! (string-upcase! cmd))) =];[= + ENDFOR alias =] + default: + if (! isalpha((unsigned char)*str)) + return [=(. invalid-cmd)=]; + break; + } + + {[= + ENDIF alias =] + [= (. base-type-name) =]_map_t const * map;[= + + IF (define len-param-name (if computed-length "clen" "len")) + (define check-length (if return-length + "\n if (len != NULL)\n\t*len = clen;" "\n")) + computed-length =] + static char const accept[] = + [= (set! check-length (string-append + check-length + "\n if (isalnum((unsigned char)str[clen]))" + "\n return " invalid-cmd ";" )) + + (kr-string cmd-chars) + =]; + unsigned int clen = strspn(str, accept);[= + ENDIF computed-length + +=][= + IF (or (exist? "no-case") (exist? "equate")) =][= + INVOKE cvt-chars =][= + ELSE =][= (. check-length) =][= + ENDIF \=] + + map = find_[=(. base-type-name)=]_name(str, (unsigned int)[= + (. len-param-name) =]);[= + + IF (not (exist? "partial")) =] + return (map == NULL) ? [=(. invalid-cmd)=] : map->[=(. enum-field)=];[= + ELSE =][= + INVOKE find-part-match =][= + ENDIF =][= + (if (exist? "alias") "\n }") =] +} +[= + +ENDDEF mk-finder + +;;; = = = = = = = = = = = = = = = = = = = +;;; +;;; Convert one character to canonical form. If there are equated characters +;;; or case mappings to do, do it here. +;;; +;;;=][= + +DEFINE cvt-chars =][= + +(define min-len (if (and (exist? "partial") (> min-cmd-width 2)) + 2 min-cmd-width)) + +=] + char name_buf[[=(+ 1 max-cmd-width)=]]; + unsigned int ix; + + /* too short, too long or followed immediately by a name char... */ + if ( ([=(sprintf "%s < %u" len-param-name min-len)=]) + || ([=(sprintf "%s > %u" len-param-name max-cmd-width)=]) + || isalnum((unsigned char)str[[=(. len-param-name)=]]) ) + return [=(. invalid-cmd)=]; + + for (ix = 0; ix < [=(. len-param-name)=]; ix++) { + int ch = (unsigned char)str[ix];[= + IF (exist? "equate") =] + switch (ch) { + [= (shell "echo '" (get "equate") "' | " + "sed \"s/\\(.\\)/case '\\1': /g\"") =] + name_buf[ix] = '[= (substring (get "equate") 0 1) =]'; + break; + default:[= + + IF (exist? "no-case") =] + name_buf[ix] = tolower(ch);[= + ELSE =] + name_buf[ix] = ch;[= + ENDIF =] + break; + }[= + + ELSE =] + name_buf[ix] = tolower(ch);[= + ENDIF no-case/equate =] + } + str = name_buf;[= + (if return-length (string-append + "\n if (len != NULL)\n\t*len = clen;")) + =][= + +ENDDEF cvt-chars + +;;; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +;; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +;;; +;;;=][= + +DEFINE mk-dispatch =][= + +(if (not (exist? "d-nam")) + (error "dispatch needs callout procedure name format ('d-nam')")) + +(define disp-type-name (shell + "echo " (get "d-nam") " | sed 's/%s//;s/__*/_/g;s/^_//;s/_$//'" )) +(define handler-type (string-append disp-type-name "_hdl_t")) + +(define disp-proc-name + (string-append disp-type-name "_" base-type-name "_disp" )) + +(define hdlr-arg-list (string-append enum-name " id, char const * str")) +(define disp-arg-list find-arg-list) +(define extra-args "") + +(if (exist? "d-arg") (begin + (set! extra-args (shell "echo '" (get "d-arg") "' | tr '\\n' ' '")) + (set! disp-arg-list (string-append disp-arg-list ",\n\t" extra-args)) + (set! hdlr-arg-list (string-append hdlr-arg-list ",\n\t" extra-args)) +) ) + +(emit (string-append "extern " (get "d-ret") "\n" +disp-proc-name "(" disp-arg-list ");" +"\n\ntypedef " (get "d-ret") " (" handler-type ")(\n\t" + hdlr-arg-list ");\n\n" handler-type "\n")) + +(out-push-new) =][= + +IF (exist? "d-only") =][= + +(out-push-new (string-append tmp-dir "/disp-list")) +(emit (string-downcase (string->c-name! (join "\n" (stack "d-only")))) + "\n" +) +(out-pop) =][= + +ELSE + +=] +rm -f ${tmp_dir}/disp-list +awk '{ print $2 }' ${tmp_dir}/commands[= + + IF (exist? "d-omit") =] | \ + grep -E -v '^([= + (string-downcase (string->c-name! (join " " (stack "d-only")))) +=])$' \ + sed 's/ /|/g'[= + + ENDIF d-omit =] > ${tmp_dir}/disp-list[= + +ENDIF d-only + +=] +{ + echo [=(. invalid-name)=] + cat ${tmp_dir}/disp-list +} | $CLexe -f '[= d-nam =]' -I4 --spread=1 -S, --end ';'[= + +(shell (out-pop #t)) =][= +(out-resume "disp-text") =][= +INVOKE mk-disp-code =][= +(out-suspend "disp-text") =][= + +ENDDEF mk-dispatch + +;;; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +;;; +;;;=][= + +DEFINE mk-disp-code =][= + +(out-push-new) + +=]mk_proc_dispatch() { + declare fmt="\n [[=(. enum-prefix)=]_%-${max_cmd_width}s] = [= + d-nam =]," + exec 3< ${tmp_dir}/disp-list + while read -u3 c + do + C=$(echo $c | tr '[a-z]' '[A-Z]') + printf "$fmt" $C $c + done + exec 3<&- + + printf "\n [%-${max_enm_width}s] = [= d-nam =] };\n" \ + [=(. invalid-cmd)=] [=(. invalid-name)=] +} +mk_lengths() { + exec 3< ${tmp_dir}/commands-UC + declare n=`expr ${max_cmd_width} + 1` + declare c + declare fmt="\n [[=(. enum-prefix)=]_%-${max_cmd_width}s] =" + while read -u3 n c + do + printf "$fmt ${#c}," "$c" + done | sed '$s/,$//' + + exec 3<&- +} +[= +(shell (out-pop #t)) +=] + +/** + * Dispatch a [=(. base-type-name)=] function, based on the keyword. + * + * @param[in] str a string that should start with a known key word.[= + (. len-descrip) =] + * @returns [= d-ret =], returned by the dispatched function. + */ +[= d-ret =] +[=(string-append disp-proc-name "(" disp-arg-list ")")=] +{ + static [=(. handler-type)=] * const dispatch[[= + (+ 2 bit-count)=]] = {[= + (shell "mk_proc_dispatch") =][= + +IF (. return-length) + +=] + [= (define length-value "*len") + enum-name =] id = [=(. find-func-name)=](str, len);[= + +ELIF (> (string-length len-arg) 0) + +=] + [= (define length-value "len") + enum-name =] id = [=(. find-func-name)=](str, len);[= + +ELSE + +=] + static unsigned int keywd_len[] = {[= + (shell "mk_lengths") =] }; + [= (define length-value "klen") + enum-name =] id = [=(. find-func-name)=](str); + unsigned int klen = [= + IF (exist? "alias") =](! isalnum((unsigned char)*str)) ? 1 : [= + ENDIF =]keywd_len[id];[= + +ENDIF + +=] + [=(. handler-type)=] * disp = dispatch[id]; + if (disp == NULL) + disp = dispatch[[=(. invalid-cmd)=]]; + [= + (if (= (get "d-ret") "void") "" "return ") + =]disp(id, str + [= + + IF (emit length-value) + (exist? "d-arg") =], [= + + (out-push-new) \=] + set -- `echo '[=(. extra-args)=]' | tr '*' ' '` + for f in $* + do case "$f" in + ( *, ) printf '%s ' "$f" ;; + esac + done + eval echo "\${$#}"[= + (shell (out-pop #t)) =][= + + ENDIF d-arg =]); +} +[= + +ENDDEF mk-disp-code + +;;; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +;;; +;;; Search through the alphabetized indexes for a unique partial match. +;;; +;;;=][= + +DEFINE find-part-match =] + if (map != NULL) + return map->[=(. enum-field)=]; + /* Check for a partial match */ + { + /* + * Indexes of valid [=(. base-type-name) +=]_table entries in sorted order: + */ + static unsigned int const ix_map[] = { +[= + +(out-push-new) + +=] +for f in `sed 's/:.*//' ${tmp_dir}/table` +do + echo `expr $f - 1` +done | $CLexe --spread=1 -S, -I12 --end ' };'[= + +(shell (out-pop #t)) + +=][= (define cmp-call (string-append + "strncmp(map->" name-field ", str, " len-param-name ")" )) =] + [= (. enum-name) =] res = [=(. invalid-cmd)=]; + static int const HI = (sizeof(ix_map) / sizeof(ix_map[0])) - 1; + int lo = 0; + int hi = HI; + int av; + int cmp; + + for (;;) { + av = (hi + lo) / 2; + map = [=(. base-type-name)=]_table + ix_map[av]; + cmp = [=(. cmp-call)=]; + if (cmp == 0) break; + if (cmp > 0) + hi = av - 1; + else lo = av + 1; + if (lo > hi) + return [=(. invalid-cmd)=]; + } + res = map->[=(. enum-field)=]; + /* + * If we have an exact match, accept it. + */ + if (map->[= (. name-field) =][[= (. len-param-name) =]] == NUL) + return res; + /* + * Check for a duplicate partial match (a partial match + * with a higher or lower index than "av". + */ + if (av < HI) { + map = [=(. base-type-name)=]_table + ix_map[av + 1]; + if ([=(. cmp-call)=] == 0) + return [=(. invalid-cmd)=]; + } + if (av > 0) { + map = [=(. base-type-name)=]_table + ix_map[av - 1]; + if ([=(. cmp-call)=] == 0) + return [=(. invalid-cmd)=]; + } + return res; + }[= + +ENDDEF find-part-match + +;;; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +;;; +;;; Make an enum to name converter. If the input id is valid, we *must* +;;; find an associated name. The table is compact and starts with 0. +;;; +;;;=][= + +DEFINE mk-enum2name + +=] +/** + * Convert an [= (. enum-name) =] value into a string. + * + * @param[in] id the enumeration value + * @returns the associated string, or "[=(. undef-str)=]" if \a id + * is out of range. + */ +char const * +[=(. base-type-name)=]_name([= (. enum-name) =] id) +{ + static char const undef[] = "[= + (if insert-undef "* UNDEFINED *" undef-str) =]"; + static char const * const nm_table[] = { +[= + +(out-push-new) + +=] +exec 4< ${tmp_dir}/table +while IFS='' read -u4 line +do + str=${line%\"*} + line=${line%'}'*} + printf " [%-${max_enm_width}s] = \"%s\",\n" ${line##*,} ${str#*\"} +done | sed '$s/,$/ };/'[= + +(shell (out-pop #t)) + +=] + char const * res = undef; + if (id < [=(. cmd-count)=]) { + res = nm_table[id]; + if (res == NULL) + res = undef; + } + return res; +} +[= + +ENDDEF mk-enum2name + +;;; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +;;; +;;;=][= +DEFINE run-gperf =] +[= +(define table-fmt (string-append + "%-" (number->string (+ max-cmd-width 1)) + "s " enum-prefix "_%s\n" )) +(out-push-new) + +=][= # + +;;; = = = = = = = = = = = = = = = = = = = +;;; +;;; GPERF OPTIONS +;;; +;;;\=] +%struct-type +%language=ANSI-C +%includes +%global-table +%omit-struct-type +%readonly-tables +%compare-strncmp + +%define slot-name [= +(define name-field (string-append pfx-str "_name")) name-field =] +%define hash-function-name [=(. base-type-name)=]_hash +%define lookup-function-name find_[=(. base-type-name)=]_name +%define word-array-name [=(. base-type-name)=]_table +%define initializer-suffix ,[=(. cmd-count)=] +[= + +(define gperf-opts (out-pop #t)) +(out-push-new (string-append tmp-dir "/" base-file-name ".gp")) + +\=][= # + +;;; = = = = = = = = = = = = = = = = = = = +;;; +;;; GPERF DEFINITIONS +;;; +;;;\=] +%{ +# if 0 /* gperf build options: */ +[= (prefix "// " gperf-opts) =] +# endif + +#include "[=(. header-file)=]" +typedef struct { + char const * [=(. name-field)=]; + [= (. enum-name) =] [= (define enum-field (string-append pfx-str "_id")) + enum-field =]; +} [=(. base-type-name)=]_map_t; +%} + +[= (. gperf-opts) =] + +[=(. base-type-name)=]_map_t; +%% +[= +FOR cmd =][= + (define cmd (get "cmd")) + (if (exist? "no-case") + (set! cmd (string-downcase cmd)) ) + (if (exist? "equate") + (set! cmd (string-tr! cmd equate-from equate-to)) ) + + (define tmp-val (string-append + (if (exist? "no-case") (string-downcase cmd) cmd) "," )) + + (sprintf table-fmt tmp-val (string-upcase! (string->c-name! cmd))) =][= +ENDFOR \=] +%% +[= + +(out-pop) +(out-push-new) + +=][= # + +;;; = = = = = = = = = = = = = = = = = = = RUN GPERF +;;; +;;; After running gperf, delete all the "inline" lines, the soure line +;;; numbers, GNUC INLINE hints, attribute inlines, the ASCII text tests and +;;; all the conditional code. These all check for stuff that is not relevant +;;; here. Replace all the #define-s with their defined-to values and strip +;;; out the #define-s themselves. Since we are appending to the output code, +;;; these #define-s interfere with what we need to do. Finally, we also force +;;; the generated find procedure to be static. We don't export it. +;;; +\=] +outdir=$PWD +cd ${tmp_dir} +use_args() { + while IFS='' read line + do + case "$line" in + *ARGSUSED* ) break ;; + * ) echo "$line" ;; + esac + done + + while IFS='' read line + do + case "$line" in + *' return '* ) + printf $' (void)str;\n (void)len;\n%s\n' "$line" + cat + return 0 + ;; + * ) echo "$line" + ;; + esac + done +} + +gperf [= (. base-file-name) =].gp | \ + sed -e '/^_*inline$/d' \ + -e '/^#line /d' \ + -e '/GNUC_.*_INLINE/d' \ + -e '/__attribute__.*inline/d' \ + -e '/^#if.*== *32/,/^#endif/d' \ + -e '/^#ifdef/d' \ + -e '/^#else/d' \ + -e '/^#endif$/d' \ + -e '/key = [=(. base-type-name)=]_hash/s/key = /key = (int)/' \ + -e 's/^\(const [=(. base-type-name)=]_map_t\)/static inline \1/' \ + > baseline + +sed -n -e '1,/_table\[\] =/d' \ + -e '/^ *{$/d' \ + -e '/^ *};/q' \ + -e 's/^ *//' \ + -e 's/}, {/},\ +{/g' \ + -e p baseline | \ + grep -n -v '""' | \ + sort -t: -k2 > table + +sedcmd=` + egrep '^#define ' baseline | \ + while read _ nm val _ + do + echo "/^#define *${nm}/d;s@${nm}@${val}@g" + done` + +grep -q -F '/*ARGSUSED*/' baseline && useargs=true || useargs=false +if $useargs +then + sed "${sedcmd}" baseline | use_args +else + sed "${sedcmd}" baseline +fi +[= +(shell (out-pop #t)) =][= + +ENDDEF run-gperf =] +/* end of [= (out-name) =] */[= + + # + * Local Variables: + * mode: text + * indent-tabs-mode: nil + * End: + * end of str2mask.tpl =] diff --git a/autoopts/tpl/str2init.tlib b/autoopts/tpl/str2init.tlib new file mode 100644 index 0000000..91b2826 --- /dev/null +++ b/autoopts/tpl/str2init.tlib @@ -0,0 +1,149 @@ +[= AutoGen5 Template null -*- Mode: Scheme -*- + +# This file contains the templates used to generate +# keyword parsing and bit map management code + +# This file is part of AutoGen. +# AutoGen is free software. +# AutoGen is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +# +# AutoGen 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. +# +# AutoGen is distributed in the hope that 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 file has the following md5sum: +# +# 43b91e8ca915626ed3818ffb1b71248b COPYING.gplv3 + +=][= +(define move-output-file (exist? "base-name")) +(define base-file-name (if move-output-file (get "base-name") (base-name))) +(define base-type-name (string->c-name! (string-downcase base-file-name))) +(define pfx-str "") +(define tmp-str "") +(define idx 0) + +(if move-output-file + (out-move (string-append base-file-name "." (suffix))) ) + +(if (exist? "prefix") + (set! pfx-str (string->c-name! (get "prefix"))) + (begin + (set! idx (string-index base-type-name (string->char-set "_-^"))) + (if (number? idx) + (set! pfx-str (substring/copy base-type-name 0 idx)) + (set! pfx-str base-type-name) +) ) ) +(define PFX-STR (string-upcase pfx-str)) +(define mask-name (string-append base-type-name "_mask_t")) +(define enum-name (string-append base-type-name "_enum_t")) +(define BASE-TYPE (string-upcase base-type-name)) + +(if (exist? "type") (set! enum-type (string->c-name! (get "type")))) +(define ENUM-TYPE (string-upcase (string-append "_" enum-type))) +(define find-func-name "") + +(if (<= (string-length enum-type) 0) (begin + (set! ENUM-TYPE "") + (set! find-func-name (string-append "find_" base-type-name)) + ) + (set! find-func-name (string-append + "find_" base-type-name "_" enum-type )) +) + +(define enum-prefix (string-append PFX-STR ENUM-TYPE)) +(define cmd-count (string-append PFX-STR "_COUNT" ENUM-TYPE)) +(define enum-val-offset (if (exist? "cmd[0]") 1 0)) +(define insert-undef #t) +(define invalid-name (if (exist? "invalid-name") + (string->c-name! (get "invalid-name")) + "invalid")) +(define INVALID-NAME (string-upcase invalid-name)) +(define max-cmd-width 0) +(define min-cmd-width 99999) +(define bit-count (+ 1 (high-lim "cmd"))) +(define undef-str (if (exist? "undef-str") (get "undef-str") "* UNDEFINED *")) + +(make-tmp-dir) +(out-push-new (string-append tmp-dir "/commands")) +(define finish-commands "chmod a+w ${tmp_dir}/commands") + +;;# START-BUILDTREE-ISMS + +(shell "CLexe=${AGexe%/agen5/*}/columns/columns +test -x \"${CLexe}\" || { + CLexe=${AGexe%/autogen}/columns + test -x \"${CLexe}\" || die 'columns program is not findable' +}") + +=][= # END-BUILDTREE-ISMS + +(shell + "gperf=`command -v gperf` 2>/dev/null\n" + "test -x \"$gperf\" || die 'gperf not installed'\n" + "CLexe=`echo ${AGexe} | sed 's@/autogen@/columns@'` + test -x \"${CLexe}\" || CLexe=`command -v columns`") + +# END-INSTALL-ONLY-CODE + +=][= + +FOR cmd =][= + (set! tmp-str (sprintf "what[%d]" (for-index))) + (if (exist? tmp-str) + (set! finish-commands (string-append finish-commands + "\ndesc_" tmp-str "=" (raw-shell-str (get tmp-str)) )) ) + (set! tmp-str (string-downcase! (string->c-name! (get "cmd")))) + (if (= tmp-str invalid-name) + (error (string-append "You cannot specify a cmd of " invalid-name)) ) + (set! idx (string-length tmp-str)) + (if (> idx max-cmd-width) (set! max-cmd-width idx)) + (if (< idx min-cmd-width) (set! min-cmd-width idx)) + (sprintf "%5u %s\n" (for-index) tmp-str) =][= + +ENDFOR cmd =][= + +(out-pop) +(shell finish-commands) +(if (< max-cmd-width 8) (set! max-cmd-width 8)) + + =][= +CASE invalid-val =][= +!E =][= + (define invalid-cmd (string-append PFX-STR "_" INVALID-NAME ENUM-TYPE)) + =][= + +== "~0" =][= + (set! enum-val-offset 0) + (set! insert-undef #f) + (define invalid-cmd (string-append PFX-STR "_" INVALID-NAME ENUM-TYPE)) + =][= + +== "" =][= + (set! enum-val-offset 0) + (set! insert-undef #f) + (define invalid-cmd cmd-count) + =][= + +* =][= + (error "if invalid-val exists, it is constrained to: + '' (empty) or '~0'.") + =][= + +ESAC + + * Local Variables: + * mode: scheme + * indent-tabs-mode: nil + * End: + * end of str2mask.tpl + +\=] diff --git a/autoopts/tpl/str2mask.tpl b/autoopts/tpl/str2mask.tpl new file mode 100644 index 0000000..87571e3 --- /dev/null +++ b/autoopts/tpl/str2mask.tpl @@ -0,0 +1,458 @@ +[= AutoGen5 Template h c -*- Mode: Scheme -*- + +# This file contains the templates used to generate +# bit map handling code + +## This file is part of AutoGen. +## AutoGen is free software. +## AutoGen is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen 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. +## +## AutoGen is distributed in the hope that 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 file has the following md5sum: +## +## 43b91e8ca915626ed3818ffb1b71248b COPYING.gplv3 + +=][= + +CASE (suffix) =][= # + +;;; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +;;; +;;; H CODE +;;; +;;;=][= +== h =][= + +INVOKE init-header =][= + +INVOKE sizes-n-formats =][= + +(out-push-new) + +=] +hdr_file=[=(string-append tmp-dir "/" base-file-name)=].h +mask_name=[= (. mask-name) =] + +sed '/^#define .*_GUARD/q' ${hdr_file} +cat <<- _EOF_ + #include + #include + + /** integral type for holding [=(. base-type-name)=] masks */ + typedef $mask_type ${mask_name}; +[= +FOR add-on-text =][= + IF (= (get "ao-file") "mask-header") =] +[= ao-text =][= + ENDIF correct type =][= +ENDFOR add-on-text =] + _EOF_ + +echo "/** bits defined for ${mask_name} */" +ix=0 + +declare C +exec 4< ${tmp_dir}/commands +all_mask=0 +while read -u4 n C +do + C=$(echo $C | tr '[a-z]' '[A-Z]') + v=$(( 1 << n )) + desc=${desc_what[$n]} + test -z "$desc" || { + test ${#desc} -gt 72 && \ + desc=$(echo "$desc" | fmt | sed '2,$s/^/ * /') + printf '/** %s */\n' "$desc" + } + printf "$def_fmt" $C $v + (( all_mask += v )) +done +exec 4<&- + +emit_mask_def() { + declare v=0 + declare mname=${1} + shift + declare which_bits='in' + $INVERT && which_bits='omitted from' + if test $# -eq 0 + then + printf "\n/** There are no bits in ${mname}. */\n" + else + printf "\n/** bits $which_bits ${mname%_MASK} mask:\n" + echo $* | tr ' ' '\n' | $CLexe --spread=1 -I' * ' --end=' */' + fi + + for f in $* + do eval f=\${val_$f} + (( v |= f )) + done + $INVERT && (( v ^= all_mask )) + printf "$def_fmt" ${mname} $v + eval $(echo val_${mname}=$v | tr '[A-Z]' '[a-z]') +} +[= + +FOR mask =][= + (set! tmp-str (string-append + (string-upcase! (string->c-name! (get "m-name"))) "_MASK")) + (string-append "INVERT=" (if (exist? "m-invert") "true" "false") + " emit_mask_def " tmp-str " " + (string->c-name! (join " " (stack "m-bit"))) "\n") =][= + +ENDFOR mask + +\=] +printf "\n/** all bits in ${mask_name} masks */\n" +printf "$def_fmt" MASK_ALL $all_mask[= +(define zero-mask-name (string-append "MASK_" )) =][= +IF (define zero-name (get "zero-name" "EMPTY")) + (> (string-length zero-name) 0) =] +printf "\n/** no bits in ${mask_name} */\n" +printf "$def_fmt" [=(string-upcase! (string->c-name! zero-name))=] 0[= +ENDIF have zero-name =][= + +IF (not (exist? "no-code")) =] +cat <<- _EOF_ + + /** buffer size needed to hold all bit names for ${mask_name} masks */ + #define MAX_[=(. BASE-TYPE)=]_NAME_SIZE [= + (+ 1 (string-length (join " " (stack "cmd")))) =] + + extern ${mask_name} + [=(. base-type-name) =]_str2mask(char const * str, ${mask_name} old); +[= + +IF (not (exist? "no-name")) =] + extern size_t + [=(. base-type-name)=]_mask2str([=(. mask-name) + =] mask, char * buf, size_t len); +[= + +ENDIF no name + +=] + _EOF_[= + +ENDIF not exist no-code =] +grep -E '^#endif .*_GUARD ' ${hdr_file} +[= +(emit (shell (out-pop #t))) +=][= + +;;; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +;;; +;;; C CODE +;;; +;;;=][= +== c + +=][= +(if (exist? "no-code") (out-delete)) +(out-move (string-append base-file-name ".c")) +(out-push-new) \=] +exec 4< ${tmp_dir}/[=(. base-file-name)=].c +while IFS='' read -u4 line +do + echo "$line" + case "$line" in + '#include '* ) break ;; + esac +done + +sed '1,/^#define.*_GUARD/d;s/^extern /static /;/^#endif.*_GUARD/,$d' \ + ${tmp_dir}/[=(. base-file-name)=].h + +cat <<\_EOF_ + +#include +#include +#ifndef NUL +#define NUL '\0' +#endif + +_EOF_ + +sed 's/^[=(. enum-name)=]$/static [=(. enum-name)=]/ + s/^char const \*$/static char const */ + /end of .*\.c/d' <&4 +exec 4<&- + +[= +(shell (out-pop #t)) +=] + +/** + * Convert a string to a [= (. mask-name) =] mask. + * Bit names prefixed with a hyphen have the bit removed from the mask. + * If the string starts with a '-', '+' or '|' character, then + * the old value is used as a base, otherwise the result mask + * is initialized to zero. Separating bit names with '+' or '|' + * characters is optional. By default, the bits are "or"-ed into the + * result. + * + * @param[in] str string with a list of bit names + * @param[in] old previous value, used if \a str starts with a '+' or '-'. + * + * @returns an unsigned integer with the bits set. + */ +[= (string-append mask-name "\n" base-type-name) +=]_str2mask(char const * str, [=(. mask-name)=] old) +{ + static char const white[] = ", \t\f"; + static char const name_chars[] = +[= (shell +"name_chars=`echo '" + (string->c-name! (join "" (stack "cmd"))) + "' | sed 's/\\(.\\)/\\1\\\\\n/g' | tr '[A-Z]' '[a-z]' | sort -u` + +alpha=`echo \"$name_chars\" | grep -E '^[a-z]$' | tr -d ' \\n'` +digit=`echo \"$name_chars\" | grep -Ev '^[a-z]$' | tr -d ' \\n'` +fmt=' \"%s\"\\n' +printf \"$fmt\" $alpha +printf \"$fmt\" `echo $alpha | tr '[a-z]' '[A-Z]'` +test -z \"${digit}\" || \ + printf \"$fmt\" ${digit} +") =]; + + [=(. mask-name)=] res = 0; + int have_data = 0; + + for (;;) { + [=(. enum-name)=] val; + unsigned int val_len; + unsigned int invert = 0; + + str += strspn(str, white); + switch (*str) { + case NUL: return res; + case '-': case '~': + invert = 1; + /* FALLTHROUGH */ + + case '+': case '|': + if (have_data == 0) + res = old; + + str += 1 + strspn(str + 1, white); + if (*str == NUL) + return 0; + } + + val_len = strspn(str, name_chars); + if (val_len == 0) + return 0; + val = [=(. find-func-name)=](str, val_len); + if (val == [=(. enum-count)=]) + return 0; + if (invert) + res &= ~(([=(. mask-name)=])1 << val); + else + res |= ([=(. mask-name)=])1 << val; + have_data = 1; + str += val_len; + } +}[= + +IF (not (exist? "no-name")) =] + +/** + * Convert a [=(. mask-name)=] mask to a string. + * + * @param[in] mask the mask with the bits to be named + * @param[out] buf where to store the result. This may be NULL. + * @param[in] len size of the output buffer + * @results The full length of the space needed for the result, + * including the terminating NUL byte. The actual result will not + * overwrite \a len bytes at \a buf. This value will also never + * exceed MAX_[=(. BASE-TYPE)=]_NAME_SIZE. + */ +size_t +[=(. base-type-name)=]_mask2str([=(. mask-name)=] mask, char * buf, size_t len) +{ + [=(. enum-name)=] val = ([=(. enum-name)=])0; + size_t res = 0; + if (buf == NULL) len = 0; + + for (; mask != 0; val++, mask >>= 1) { + char const * p; + size_t l; + + if (val >= [=(. enum-count)=]) + break; + + if ((mask & 1) == 0) + continue; + + p = [=(. base-type-name)=]_name(val); + if (*p == '*') + continue; /* ignore invalid bits */ + + l = strlen(p) + 1; /* includes NUL byte or spacer byte */ + if (l <= len) { + if (res > 0) + *(buf++) = ' '; + memcpy(buf, p, l); + buf += l - 1; + len -= l; + } + res += l; + } + return (res == 0) ? 1 : res; +}[= +ENDIF dispatch=][= + + FOR add-on-text =][= + IF (= (get "ao-file") "mask-code") =] +[= ao-text =][= + ENDIF correct type =][= + ENDFOR add-on-text =][= + +ESAC suffix c/h + +;;; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +;; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +;;; +;;; Create the function that converts the name into an mask value. +;;; +;;;=] +/* end of [= (out-name) =] */ +[= + +DEFINE sizes-n-formats =][= +(out-push-new) =][= + +FOR mask =][= + (set! tmp-str (string-append (get "m-name") "_MASK")) + (set! idx (string-length tmp-str)) + (if (> idx max-cmd-width) (set! max-cmd-width idx)) + =][= +ENDFOR mask + +=] +sfx=U +bits=[=(. bit-count)=] +hex_width=$(( (bits + 3) / 4 )) +(( hex_width < 4 )) && hex_width=4 +[= + +IF (exist? "mask-type") + +=] +mask_type=[= mask-type =] +(( bits > 32 )) && { + (( bits > 64 )) && die "cannot handle a $bits bit mask" + sfx=UL +} +[= + +ELSE mask type not provided + +=] +if (( bits <= 8 )) +then mask_type='uint8_t' +elif (( bits <= 16 )) +then mask_type='uint16_t' +elif (( bits <= 32 )) +then mask_type='uint32_t' +elif (( bits <= 64 )) +then mask_type='uint64_t' + sfx=UL +else + die "cannot handle a $bits bit mask" +fi +[= + +ENDIF mask type provided/not + +=] +hex_fmt=0x%0${hex_width}X${sfx} +def_fmt="#define [=(string-append PFX-STR ENUM-TYPE "_") +=]%-[=(. max-cmd-width)=]s ${hex_fmt}\\n" +[= + +(shell (out-pop #t)) =][= + +ENDDEF sizes-n-formats + +;;; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +;;; +;;; Initialize for the header +;;; +;;;=][= + +DEFINE init-header =][= + +(if (exist? "dispatch") + (error "bit masks do not have dispatching available")) + +(if (exist? "alias") + (error "bit name aliases are not allowed")) + +(define enum-type (if (exist? "prefix") "" "bit")) + +=][= + +INCLUDE "str2init.tlib" + +=][= + +(out-move ".Str2Mask-Set-Aside") +(define bit-enum-type + (string-append (if (== enum-type "bit") "" enum-type) "bnm")) +(define enum-count (string-append PFX-STR "_COUNT_" + (string-upcase bit-enum-type))) +(define assign-vals "") +(define find-func-name (string-append + "find_" base-type-name "_" bit-enum-type )) +(out-push-new (string-append tmp-dir "/" base-file-name ".def")) +=] +AutoGen Definitions str2enum; +prefix = '[=(. pfx-str)=]'; +type = '[=(string-downcase bit-enum-type)=]'; +invalid-name = '[=(. invalid-name)=]'; +invalid-val = ''; +[= + +FOR cmd =][= + (set! tmp-str (get "cmd")) + (set! idx (for-index)) + (ag-fprintf 0 "cmd[%u] = '%s';\n" idx tmp-str) + (set! tmp-str (string-downcase! (string->c-name! tmp-str))) + (set! idx (ash 1 idx)) + (set! assign-vals (string-append assign-vals + "val_" tmp-str "=" (number->string idx) "\n")) + =][= +ENDFOR =][= +(if (exist? "no-code") (emit "no-code;\n")) +(if (exist? "partial") (emit "partial;\n")) +(if (exist? "no-name") (emit "no-name;\n")) +(out-pop) +(shell assign-vals +"{ ${AGexe} -L" (dirname (tpl-file #t)) " ${tmp_dir}/" base-file-name ".def" +" || die 'Could not build enumeration\n'" + "\"`cat ${tmp_dir}/" base-file-name ".def`\"\n" +"cp " base-file-name ".[ch] ${tmp_dir}/.\n" +"rm -f " base-file-name ".[ch]\n} 1>&2") +(out-move (string-append base-file-name ".h")) + +=][= + +ENDDEF init-header + + * Local Variables: + * mode: text + * indent-tabs-mode: nil + * End: + * end of str2mask.tpl \=] diff --git a/autoopts/tpl/strings.tpl b/autoopts/tpl/strings.tpl new file mode 100644 index 0000000..fc6a039 --- /dev/null +++ b/autoopts/tpl/strings.tpl @@ -0,0 +1,171 @@ +[= AutoGen5 Template c -*- Mode: scheme -*- + +## Author: Bruce Korb +## +## Copyright (C) 2011-2018 Bruce Korb, all rights reserved. +## This is free software. It is licensed for use, modification and +## redistribution under the terms of the +## Modified (3 clause) Berkeley Software Distribution License +## +## +## Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions +## are met: +## 1. Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## 2. Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in the +## documentation and/or other materials provided with the distribution. +## 3. Neither the name ``Bruce Korb'' nor the name of any other +## contributor may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## strings IS PROVIDED BY Bruce Korb ``AS IS'' AND ANY EXPRESS +## OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +## WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +## ARE DISCLAIMED. IN NO EVENT SHALL Bruce Korb OR ANY OTHER CONTRIBUTORS +## BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +## BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=] +[= INCLUDE "tpl-config.tlib" =][= + +(define copy-years (shell + "sed -n '/Copyright (C)/ { + s/.*(C) *// + s/ *Bruce.*// + p + q + }' " (tpl-file #t) )) \=] +[= INVOKE leader guard = false \=] +[= (out-push-new (string-append (base-name) ".h")) \=] +[= INVOKE leader guard = true =] +[= (out-suspend "header") ;; resume defines + (define string-name (string->c-name! (string-append + (base-name) "-strtable"))) + (string-table-new string-name) + (define max-name-len 0) + (define tmp-str "") + (define tmp-len 0) \=] +#include "[= (. header-file) =]" +[= + +(define str-nm "") +(define str-val "") +(define str-ct 0) +(define name-ln 0) +(define find-ln "") +(define def-fmt "#define %%-%us (%%s)\n#define %%-%us %%d\n") +(out-push-new) ;; temp file for #defines +=][= +FOR string =][= + (set! find-ln (string-length (get "nm" ""))) + (if (> find-ln name-ln) + (set! name-ln find-ln)) =][= +ENDFOR string =][= + +(if (exist? "file-name-string") (begin + (set! str-nm (string-upcase (string-append string-name "_file"))) + (set! find-ln (string-length str-nm)) + (if (> find-ln name-ln) + (set! name-ln find-ln)) + (set! def-fmt (sprintf def-fmt (+ 1 name-ln) (+ 5 name-ln))) + (set! str-ct 1) + (set! str-val (string-append (base-name) ".c")) + (set! tmp-str (string-table-add-ref string-name str-val)) + (ag-fprintf 0 def-fmt str-nm tmp-str + (string-append str-nm "_LEN") (string-length str-val)) + ) + + (set! def-fmt (sprintf def-fmt (+ 1 name-ln) (+ 5 name-ln))) +) + +(set! find-ln "") =][= + +FOR string =][= + (set! str-nm (get "nm")) + (set! str-ct (+ str-ct 1)) + (set! str-val (get "str" str-nm)) + (set! tmp-str (string-table-add-ref string-name str-val)) + (if (exist? "define-line-no") + (set! find-ln (string-append find-ln str-nm " " tmp-str "\n")) ) + (sprintf def-fmt str-nm tmp-str + (string-append str-nm "_LEN") (string-length str-val)) =][= +ENDFOR string =][= + +(out-suspend "defines") +(out-resume "header") ;; real header file +(ag-fprintf 0 + "/*\n * %d strings in %s string table\n */\n" str-ct string-name) +(out-resume "defines") +(emit (shell (string-append "sort <<\\_EOF_\n" + (out-pop #t) "_EOF_"))) ;; #defines now in real header file +(emit "\n") +(out-push-new) +(emit-string-table string-name) +(define str-table (out-pop #t)) +(emit (shell (string-append + "sed -n '/static char const/ { + s/static char/extern char/ + s/ *=.*/;/ + p + q + }' <<\\_EOF_\n" + str-table + "\n_EOF_" +))) +(out-suspend "header") ;; resuming text output +(shell (string-append + "sed 's/^static char const/char const/' <<\\_EOF_\n" + str-table + "\n_EOF_" +)) =][= + +IF (out-resume "header") ;; real header file + (> (string-length find-ln) 0)=] + +[= (out-push-new) =] +while read nm ln +do + test -z "$nm" && break + ln='/\* *'${ln#*+}' \*/' + ln=`[=(. egrep-prog)=] -n "$ln" [= (base-name) =].c` + nm=`echo $nm | tr '[a-z]' '[A-Z]'`_LINENO + printf '#define %-31s %s\n' ${nm} ${ln%%:*} +done <<\_EOF_ +[= (. find-ln) =]_EOF_[= + +(shell (out-pop #t)) =][= +ENDIF find-ln not empty =][= +(if (exist? "header-trailer") + (emit (join "\n\n" "header-trailer")) ) \=] + + +#endif /* [= (. header-guard) =] */ +[= (out-pop) =][= + +DEFINE leader \=][= + (emit (dne " * " "/* ")) + (emit "\n *\n") + (emit (license-full "mbsd" "strings" " * " "Bruce Korb" copy-years)) + (emit "\n */\n") + (if (= (get "guard") "true") + (emit (string-append + (make-header-guard "strings") + (if (exist? "header-leader") (string-append "\n\n" + (join "\n\n" "header-leader") ) "" ) )) + (if (exist? "code-leader") + (emit (string-append "\n\n" (join "\n\n" "code-leader"))) ) + ) +=][= + +ENDDEF leader =][= +(if (exist? "code-trailer") + (emit (join "\n\n" "code-trailer")) ) =] + +/* end of [= (out-name) =] */ diff --git a/autoopts/tpl/texi2man.sh b/autoopts/tpl/texi2man.sh new file mode 100755 index 0000000..7889f05 --- /dev/null +++ b/autoopts/tpl/texi2man.sh @@ -0,0 +1,75 @@ +#! /bin/sh + +## texi2man.sh -- script to convert texi-isms to man page isms +## +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + +## This "library" converts texi-isms into man-isms. It gets included +## by the man page template at the point where texi-isms might start appearing +## and then "emit-man-text" is invoked when all the text has been assembled. +## +## Display the command line prototype, +## based only on the argument processing type. +## +## And run the entire output through "sed" to convert texi-isms + +nl=' +' +sedcmd= +bracket='{\([^}]*\)}' +replB='%BACKSLASH%fB\1%BACKSLASH%fP' +replI='%BACKSLASH%fI\1%BACKSLASH%fP' + +for f in code command var env dvn samp option strong +do + sedcmd="${sedcmd}s;@${f}${bracket};${replB};g${nl}" +done + +for f in i file emph kbd key abbr acronym email indicateurl +do + sedcmd="${sedcmd}s;@${f}${bracket};${replI};g${nl}" +done + +sed \ + -e "${sedcmd}" \ + -e 's;@pxref{\([^}]*\)};see: \1;g' \ + -e 's;@xref{\([^}]*\)};see: \1;g' \ + -e 's/@\([{}]\)/\1/g' \ + -e 's,^\$\*$,.br,' \ + -e '/@ *example/,/@ *end *example/s/^/ /' \ + -e 's/^ *@ *example/.nf/' \ + -e 's/^ *@ *end *example/.fi/' \ + -e '/^ *@ *noindent/d' \ + -e '/^ *@ *enumerate/d' \ + -e 's/^ *@ *end *enumerate/.br/' \ + -e '/^ *@ *table/d' \ + -e 's/^ *@ *end *table/.br/' \ + -e 's/^@item \(.*\)/.sp\ +.IR "\1"/' \ + -e 's/^@item/.sp 1/' \ + -e 's/\*\([a-zA-Z0-9:~=_ -]*\)\*/%BACKSLASH%fB\1%BACKSLASH%fP/g' \ + -e 's/``\([a-zA-Z0-9:~+=_ -]*\)'"''"'/\\(lq\1\\(rq/g' \ + -e "s/^'/\\'/" \ + -e 's/^@\*/.br/' \ + -e 's/^@sp/.sp/' \ + -e 's/ -/ \\-/g' \ + -e 's@^\.in \\-@.in -@' \ + -e 's#%BACKSLASH%#\\#g' diff --git a/autoopts/tpl/texi2mdoc.sh b/autoopts/tpl/texi2mdoc.sh new file mode 100755 index 0000000..b60aafa --- /dev/null +++ b/autoopts/tpl/texi2mdoc.sh @@ -0,0 +1,195 @@ +#! /bin/sh + +## texi2mdoc.sh -- script to convert texi-isms to mdoc-isms +## +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + +## This "library" converts texi-isms into man-isms. It gets included +## by the man page template at the point where texi-isms might start appearing +## and then "emit-man-text" is invoked when all the text has been assembled. +## +## Display the command line prototype, +## based only on the argument processing type. +## +## And run the entire output through "sed" to convert texi-isms + +# /bin/sh on Solaris is too horrible for words +# +case "$0" in +/bin/sh ) test -x /usr/xpg4/bin/sh && exec /usr/xpg4/bin/sh ${1+"$@"} ;; +esac + +parent_pid=$$ +prog=`basename $0 .sh` + +die() { + echo "$prog error: $*" >&2 + kill -TERM $parent_pid + sleep 1 + kill -9 $parent_pid + sleep 1 + exit 1 +} + +do_example() { + echo '.Bd -literal -offset indent' + res=0 + + while : + do + IFS='' read -r line || die "incomplete example" + case "$line" in + '@end '*example ) break ;; + esac + + do_line + done + echo '.Ed' + return $res +} + +do_noindent() { + return 0 +} + +do_enumerate() { + echo '.Bl -enum -compact' + + while : + do + IFS='' read -r line || die "incomplete enumerate" + case "$line" in + '@end '*enumerate ) break ;; + esac + + do_line + done + echo '.El' + + return $res +} + +do_end() { + die "Improper ending: $line" +} + +do_table() { + echo '.Bl -tag -width 8n' + + while : + do + IFS='' read -r line || die "incomplete table" + case "$line" in + '@end '*table ) break ;; + esac + + do_line + done + echo '.El' + + return $res +} + +do_itemize() { + echo '.Bl -bullet -compact' + + while : + do + IFS='' read -r line || die "incomplete itemize" + case "$line" in + '@end '*itemize ) break ;; + esac + + do_line + done + echo '.El' + + return $res +} + +do_item() { + printf '%s\n' "$line" | sed 's/@item/.It/' +} + +do_line() { + case "${line}" in + '@subheading'* ) printf '%s\n' "$line" | sed 's/@subheading/.SS /' ;; + '@*' ) echo .br ;; + '@sp') echo echo "${line}" | sed 's/@sp/.sp/' ;; + '' ) echo .sp ;; + '@'[{}]* ) printf '%s\n' "${line}" | sed 's/@\([{}]\)/\1/g' ;; + '@'* ) + typ=`printf '%s\n' "$line" | egrep '@[a-z]*\{'` + test ${#typ} -gt 0 && printf '%s\n' "$line" && return 0 + typ=`printf '%s\n' "$line" | sed 's/@ *//;s/[^a-z].*//'` + eval do_${typ} || die "do_${typ} failed" + ;; + + * ) + printf '%s\n' "$line" + ;; + esac + return 0 +} + + +nl=' +' +sedcmd= +bracket='{\([^}]*\)}' +replB='%BACKSLASH%fB\1%BACKSLASH%fP' +replI='%BACKSLASH%fI\1%BACKSLASH%fP' + +for f in code command var env dvn samp option strong +do + sedcmd="${sedcmd}s;@${f}${bracket};${replB};g${nl}" +done + +for f in i file emph kbd key abbr acronym email indicateurl +do + sedcmd="${sedcmd}s;@${f}${bracket};${replI};g${nl}" +done + +fixfont="${sedcmd}"' + s;@pxref{\([^}]*\)};see: \1;g + s;@xref{\([^}]*\)};see: \1;g + s/@\([{@}]\)/\1/g + s,^[@$]\*$,.br, + s/\*\([a-zA-Z0-9:~=_ -]*\)\*/\\fB\1\\fP/g + s/``\([a-zA-Z0-9:~+=_ -]*\)'\'\''/\\(lq\1\\(rq/g + s/\([^\\]\)-/\1\\-/g + s/\([^\\]\)-/\1\\-/g + /^\.Bl /s/ \\-/ -/g + /^\.Bd /s/ \\-/ -/g + /^\.in /s/ \\-/ -/g + s#%BACKSLASH%#\\#g'" + s/^'/\\\\'/ + /^\$/d" +readonly fixfont + +{ + while IFS='' read -r line + do + do_line + done +} | sed "${fixfont}" + +exit 0 diff --git a/autoopts/tpl/tpl-config-tlib.in b/autoopts/tpl/tpl-config-tlib.in new file mode 100644 index 0000000..e1c6b52 --- /dev/null +++ b/autoopts/tpl/tpl-config-tlib.in @@ -0,0 +1,82 @@ +[= Autogen5 Template configuration -*- Mode: scheme -*- =] +[= + +# This file contains configure stuff used by various templates. + +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + +=][= + +(define ao-version "@AO_CURRENT@:@AO_REVISION@:@AO_AGE@") +(define ao-template-ver "@AO_TEMPLATE_VERSION@") + +(define inst-prefix + (shell "prefix=\"@prefix@\" + echo \"${prefix}\"")) + +(define exec-prefix + (shell "exec_prefix=\"@exec_prefix@\" + echo \"${exec_prefix}\"")) + +(define inst-bin-dir + (shell "bindir=\"@bindir@\" + echo \"${bindir}\"")) + +(define libs + (shell "LIBS=\"@LIBS@\" + echo \"${LIBS}\"")) + +(define inc-dir + (shell "includedir=\"@includedir@\" + echo \"${includedir}\"")) + +(define lib-dir + (shell "libdir=\"@libdir@\" + echo \"${libdir}\"")) + +(define package + (shell "PACKAGE_TARNAME=\"@PACKAGE_TARNAME@\" + echo \"${PACKAGE_TARNAME}\"")) + +(define data-root-dir + (shell "datarootdir=\"@datarootdir@\" + echo \"${datarootdir}\"")) + +(define data-dir + (shell "datadir=\"@datadir@\" + echo \"${datadir}\"")) + +(define grep-prog + (shell "GREP=\"@GREP@\" + echo \"${GREP}\"")) + +(define egrep-prog + (shell "EGREP=\"@EGREP@\" + echo \"${EGREP}\"")) + +(define fgrep-prog + (shell "FGREP=\"@FGREP@\" + echo \"${FGREP}\"")) + +(define top-build-dir (shell "\\cd .. >/dev/null ; pwd")) +(define pkgdatadir (shell "echo \"${datadir}/${package}\"")) +(setenv "SHELL" "@POSIX_SHELL@") +;;; \=] diff --git a/autoopts/tpl/usage.tlib b/autoopts/tpl/usage.tlib new file mode 100644 index 0000000..eefc6e6 --- /dev/null +++ b/autoopts/tpl/usage.tlib @@ -0,0 +1,245 @@ +[= AutoGen5 Template -*- Mode: shell-script -*- + + help-text + +# This file is part of AutoGen. +# AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +# +# AutoGen 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. +# +# AutoGen is distributed in the hope that 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 . + +=][= INCLUDE "tpl-config.tlib" =][= + + ;; This template is designed to emit help text from the current set + ;; of option definitions. + ;; + ;;# START-BUILDTREE-ISMS + ;; + (shell "CLexe=${AGexe%/agen5/*}/columns/columns + test -x \"${CLexe}\" || { + CLexe=${AGexe%/autogen}/columns + test -x \"${CLexe}\" || die 'columns program is not findable' + }") + +=][= # END-BUILDTREE-ISMS + +(shell "CLexe=`echo ${AGexe} | sed 's@/autogen@/columns@'` + test -x \"${CLexe}\" || CLexe=`which columns`") + +# END-INSTALL-ONLY-CODE =][= + + (make-tmp-dir) + (out-push-new (shellf "echo ${tmp_dir}/%s.def" (get "prog-name"))) + (define emit-def (lambda (vname) + (if (exist? vname) + (sprintf "\n%s = %s;" vname (kr-string (get vname))) ) )) +=] +AutoGen Definitions options.tpl; +no-libopts; +no-xlate = anything; +autoopts-usage-tlib; +[= + +FOR var IN prog-name prog-title argument + environrc export homerc include + long-opts rcfile version detail + explain package preserve-case prog-desc + opts-ptr gnu-usage reorder-args usage-opt + + version-value help-value more-help-value + save-opts-value usage-value load-opts-value + =][= + (emit-def (get "var")) =][= +ENDFOR var IN .... =][= + +IF (exist? "config-header") =] +config-header = '[= prog-name =]-config.h';[= +ENDIF =][= + +FOR copyright =] +copyright = {[= + + FOR var IN date owner type text author eaddr + =][= + (emit-def (get "var")) =][= + ENDFOR var IN .... =] +};[= +ENDFOR copyright =] + +main = { main-type = main; }; +[= + +FOR flag + +=] +flag = {[= + + FOR var IN name descrip value max min must-set enable disable enabled + ifdef ifndef no-preset settable equivalence documentation + immediate immed-disable also + arg-type arg-optional arg-default default arg-range + stack-arg unstack-arg + =][= + (emit-def (get "var")) =][= + ENDFOR var IN .... =][= + + IF (exist? "keyword") =] + keyword = '[= (join "', '" (stack "keyword")) =]';[= + ENDIF keyword exists =][= + + IF (exist? "flags-must") =] + flags-must = '[= (join "', '" (stack "flags-must")) =]';[= + ENDIF flags-must exists =][= + + IF (exist? "flags-cant") =] + flags-cant = '[= (join "', '" (stack "flags-cant")) =]';[= + ENDIF flags-cant exists =] +};[= + +ENDFOR flag =][= + +(out-pop) +(out-push-new) +(out-push-new) =][= + +# We are creating a shell script that needs to obtain values from the current +# execution envronment for an execution environment that happens later. +# \=] +export tmp_dir="${tmp_dir}" \ + top_builddir="${top_builddir}" \ + CFLAGS="${CFLAGS}" \ + CLexe="${CLexe}"[= + +(shell (out-pop #t)) =] +save_dir=`pwd` +# redirect stdout. We see this IFF there is a problem +# +redirect_log=${tmp_dir}/redirected.log +exec 7>&1 9>&2 1> ${redirect_log} 2>&1 || \ + die "Redirection failure: 7>&1 9>&2 1> ${redirect_log} 2>&1" +redirect_die() { + exec 2>&9 1>&9 9>&- 7>&- + sed 's/^/## /' ${redirect_log} + die "$*" +} + +inc_list="-I${PWD} -I[=(. inc-dir)=]" +cfg_ldflags="[=(. libs)=]" +cfg_cflags="${CFLAGS}" +exe=${tmp_dir}/[= prog-name =] +[= # START-BUILDTREE-ISMS: + +# The following code is sedded away in install-hook.sh. +# The goal is to remove build tree-isms when installing this file. + +\=] +test -z "${top_builddir}" && ldflags='' || \ + ldflags=`exec 2>/dev/null + find ${top_builddir}/autoopts -name "libopts*.${OBJEXT}" | head -1` + +test -f "${ldflags}" || { + ldflags='[=(. lib-dir)=]/libopts.a' + test -f "${ldflags}" || redirect_die "Cannot locate libopts.a" +} +ldflags="$ldflags ${cfg_ldflags}" +test -d "${top_builddir}" && \ + inc_list="-I${top_builddir} -I${top_builddir}/autoopts ${inc_list}" +test -d "${top_srcdir}" && \ + inc_list="-I${top_srcdir}/autoopts ${inc_list}" + +[= # END-BUILDTREE-ISMS the following code is for installed version: + +aocfg=`dirname ${AGexe}`/autoopts-config +test -x "$aocfg" || redirect_die "missing $ag" +ldflags="${cfg_ldflags} `${aocfg} ldflags`" +cfg_cflags="${cfg_cflags} `${aocfg} cflags`" + +# END-INSTALL-ONLY-CODE \=] +[= IF (exist? "config-header") \=] +inc_list="-I${tmp_dir} ${inc_list}" +while : +do + h='[= config-header =]' + test -f "$h" && break + hdr=$h + h=`basename "${hdr}"` + test -f "$h" && break + g=$h + d=`pwd` + + while : + do + d=`dirname $d` + test "X$d" = X/ && \ + redirect_die "cannot locate $h" + h="$d/$g" + test -f "$h" && break + h="$d/$hdr" + test -f "$h" && break + done + break +done +cp "${h}" ${exe}-config.h +[= ENDIF \=] +flags="-DTEST_[= (string-upcase! (string->c-name! (get "prog-name"))) + =]_OPTS=1 ${inc_list} ${cfg_cflags}" +tpldir=`dirname [= (tpl-file)=]` +tpldir=`cd $tpldir >/dev/null && pwd` +cd ${tmp_dir} +mkdir ag-tmp +TMPDIR=${tmp_dir}/ag-tmp \ + ${AGexe} -L $tpldir [= prog-name =].def || \ + redirect_die "Cannot gen [= prog-name =]" +cd - +${CC:-cc} ${flags} -g -o TMPexe$$ ${exe}.c ${ldflags} || \ + redirect_die cannot compile ${exe}.c +mv -f TMPexe$$ ${exe} +xtr_set=`set -o | awk '/^xtrace/{ print $2 }'` +set +x +exec 2>/dev/null 1>&7 +${exe} [= + + (if (== (get "usage-type") "short") + (if (exist? "usage-opt") + (if (exist? "long-opts") + "--usage" + (string-append "-" (get "usage-value" "u")) + ) + "--give-me-short-usage 2>&1 | sed -e '/: illegal option /d'" + ) + (if (exist? "long-opts") + "--help" + (string-append "-" (get "help-value" "?")) + ) ) =] || \ + redirect_die "cannot obtain ${exe} help in ${tmp_dir}" +test "X${VERBOSE:-false}" = Xtrue && \ + cp -frp ${tmp_dir}/. ${save_dir}/TEMP-DIR +exec 1>&7 2>&9 7>&- 9>&- +test X$xtr_set = Xon && set -x +[= + +(shell (out-pop #t)) + +=][= +## +## Local Variables: +## Mode: shell-script +## indent-tabs-mode: nil +## sh-basic-offset: 4 +## sh-indent-after-do: 4 +## sh-indentation: 4 +## sh-indent-for-case-label: 0 +## sh-indent-for-case-alt: 4 +## End: +## +# end of usage.tlib =] diff --git a/autoopts/usage.c b/autoopts/usage.c new file mode 100644 index 0000000..8df3591 --- /dev/null +++ b/autoopts/usage.c @@ -0,0 +1,1285 @@ + +/* + * \file usage.c + * + * This module implements the default usage procedure for + * Automated Options. It may be overridden, of course. + * + * @addtogroup autoopts + * @{ + */ +/* + * Sort options: + --start=END-[S]TATIC-FORWARD --patt='^/\*($|[^:])' \ + --out=xx.c key='^[a-zA-Z0-9_]+\(' --trail='^/\*:' \ + --spac=2 --input=usage.c + */ + +/* + * This file is part of AutoOpts, a companion to AutoGen. + * AutoOpts is free software. + * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoOpts is available under any one of two licenses. The license + * in use must be one of these two and the choice is under the control + * of the user of the license. + * + * The GNU Lesser General Public License, version 3 or later + * See the files "COPYING.lgplv3" and "COPYING.gplv3" + * + * The Modified Berkeley Software Distribution License + * See the file "COPYING.mbsd" + * + * These files have the following sha256 sums: + * + * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 + * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 + * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + */ + +#define GRAPH_CH(_ch) \ + ((((unsigned)_ch) <= 0x7E) && (((unsigned)_ch) > ' ')) + +/** + * Parse the option usage flags string. Any parsing problems yield + * a zero (no flags set) result. This function is internal to + * set_usage_flags(). + * + * @param[in] fnt Flag Name Table - maps a name to a mask + * @param[in] txt the text to process. If NULL, then + * getenv("AUTOOPTS_USAGE") is used. + * @returns a bit mask indicating which \a fnt entries were found. + */ +static unsigned int +parse_usage_flags(ao_flag_names_t const * fnt, char const * txt) +{ + unsigned int res = 0; + + /* + * The text may be passed in. If not, use the environment variable. + */ + if (txt == NULL) { + txt = getenv("AUTOOPTS_USAGE"); + if (txt == NULL) + return 0; + } + + txt = SPN_WHITESPACE_CHARS(txt); + if (*txt == NUL) + return 0; + + /* + * search the string for table entries. We must understand everything + * we see in the string, or we give up on it. + */ + for (;;) { + int ix = 0; + + for (;;) { + if (strneqvcmp(txt, fnt[ix].fnm_name, (int)fnt[ix].fnm_len) == 0) + break; + if (++ix >= AOUF_COUNT) + return 0; + } + + /* + * Make sure we have a full match. Look for whitespace, + * a comma, or a NUL byte. + */ + if (! IS_END_LIST_ENTRY_CHAR(txt[fnt[ix].fnm_len])) + return 0; + + res |= 1U << ix; + txt = SPN_WHITESPACE_CHARS(txt + fnt[ix].fnm_len); + + switch (*txt) { + case NUL: + return res; + + case ',': + txt = SPN_WHITESPACE_CHARS(txt + 1); + /* Something must follow the comma */ + /* FALLTHROUGH */ + + default: + continue; + } + } +} + +/** + * Set option usage flags. Any parsing problems yield no changes to options. + * Three different bits may be fiddled: \a OPTPROC_GNUUSAGE, \a OPTPROC_MISUSE + * and \a OPTPROC_COMPUTE. + * + * @param[in] flg_txt text to parse. If NULL, then the AUTOOPTS_USAGE + * environment variable is parsed. + * @param[in,out] opts the program option descriptor + */ +static void +set_usage_flags(tOptions * opts, char const * flg_txt) +{ +# define _aof_(_n, _f) { sizeof(#_n)-1, _f, #_n }, + static ao_flag_names_t const fn_table[AOUF_COUNT] = { + AOFLAG_TABLE + }; +# undef _aof_ + + /* + * the flag word holds a bit for each selected table entry. + */ + unsigned int flg = parse_usage_flags(fn_table, flg_txt); + if (flg == 0) return; + + /* + * Ensure we do not have conflicting selections + */ + { + static unsigned int const form_mask = + AOUF_gnu | AOUF_autoopts; + static unsigned int const misuse_mask = + AOUF_no_misuse_usage | AOUF_misuse_usage; + if ( ((flg & form_mask) == form_mask) + || ((flg & misuse_mask) == misuse_mask) ) + return; + } + + /* + * Now fiddle the fOptSet bits, based on settings. + * The OPTPROC_LONGOPT bit is immutable, thus if it is set, + * then fnm points to a mask off mask. + */ + { + ao_flag_names_t const * fnm = fn_table; + for (;;) { + if ((flg & 1) != 0) { + if ((fnm->fnm_mask & OPTPROC_LONGOPT) != 0) + opts->fOptSet &= fnm->fnm_mask; + else opts->fOptSet |= fnm->fnm_mask; + } + flg >>= 1; + if (flg == 0) + break; + fnm++; + } + } +} + +/* + * Figure out if we should try to format usage text sort-of like + * the way many GNU programs do. + */ +static inline bool +do_gnu_usage(tOptions * pOpts) +{ + return (pOpts->fOptSet & OPTPROC_GNUUSAGE) ? true : false; +} + +/* + * Figure out if we should try to format usage text sort-of like + * the way many GNU programs do. + */ +static inline bool +skip_misuse_usage(tOptions * pOpts) +{ + return (pOpts->fOptSet & OPTPROC_MISUSE) ? true : false; +} + + +/*=export_func optionOnlyUsage + * + * what: Print usage text for just the options + * arg: + tOptions * + pOpts + program options descriptor + + * arg: + int + ex_code + exit code for calling exit(3) + + * + * doc: + * This routine will print only the usage for each option. + * This function may be used when the emitted usage must incorporate + * information not available to AutoOpts. +=*/ +void +optionOnlyUsage(tOptions * pOpts, int ex_code) +{ + char const * pOptTitle = NULL; + + set_usage_flags(pOpts, NULL); + if ((ex_code != EXIT_SUCCESS) && + skip_misuse_usage(pOpts)) + return; + + /* + * Determine which header and which option formatting strings to use + */ + if (do_gnu_usage(pOpts)) + (void)setGnuOptFmts(pOpts, &pOptTitle); + else + (void)setStdOptFmts(pOpts, &pOptTitle); + + prt_opt_usage(pOpts, ex_code, pOptTitle); + + fflush(option_usage_fp); + if (ferror(option_usage_fp) != 0) + fserr_exit(pOpts->pzProgName, zwriting, (option_usage_fp == stderr) + ? zstderr_name : zstdout_name); +} + +/** + * Print a message suggesting how to get help. + * + * @param[in] opts the program options + */ +static void +print_offer_usage(tOptions * opts) +{ + char help[24]; + + if (HAS_opt_usage_t(opts)) { + int ix = opts->presetOptCt; + tOptDesc * od = opts->pOptDesc + ix; + while (od->optUsage != AOUSE_HELP) { + if (++ix >= opts->optCt) + ao_bug(zmissing_help_msg); + od++; + } + switch (opts->fOptSet & (OPTPROC_LONGOPT | OPTPROC_SHORTOPT)) { + case OPTPROC_SHORTOPT: + help[0] = '-'; + help[1] = od->optValue; + help[2] = NUL; + break; + + case OPTPROC_LONGOPT: + case (OPTPROC_LONGOPT | OPTPROC_SHORTOPT): + help[0] = help[1] = '-'; + strncpy(help + 2, od->pz_Name, 20); + break; + + case 0: + strncpy(help, od->pz_Name, 20); + break; + } + + } else { + switch (opts->fOptSet & (OPTPROC_LONGOPT | OPTPROC_SHORTOPT)) { + case OPTPROC_SHORTOPT: + strcpy(help, "-h"); + break; + + case OPTPROC_LONGOPT: + case (OPTPROC_LONGOPT | OPTPROC_SHORTOPT): + strcpy(help, "--help"); + break; + + case 0: + strcpy(help, "help"); + break; + } + } + + fprintf(option_usage_fp, zoffer_usage_fmt, opts->pzProgName, help); +} + +/** + * Print information about each option. + * + * @param[in] opts the program options + * @param[in] exit_code whether or not there was a usage error reported. + * used to select full usage versus abbreviated. + */ +static void +print_usage_details(tOptions * opts, int exit_code) +{ + { + char const * pOptTitle = NULL; + int flen; + + /* + * Determine which header and which option formatting strings to use + */ + if (do_gnu_usage(opts)) { + flen = setGnuOptFmts(opts, &pOptTitle); + sprintf(line_fmt_buf, zFmtFmt, flen); + fputc(NL, option_usage_fp); + + } else { + flen = setStdOptFmts(opts, &pOptTitle); + sprintf(line_fmt_buf, zFmtFmt, flen); + + /* + * When we exit with EXIT_SUCCESS and the first option is a doc + * option, we do *NOT* want to emit the column headers. + * Otherwise, we do. + */ + if ( (exit_code != EXIT_SUCCESS) + || ((opts->pOptDesc->fOptState & OPTST_DOCUMENT) == 0) ) + + fputs(pOptTitle, option_usage_fp); + } + + flen = 4 - ((flen + 15) / 8); + if (flen > 0) + tab_skip_ct = flen; + prt_opt_usage(opts, exit_code, pOptTitle); + } + + /* + * Describe the mechanics of denoting the options + */ + switch (opts->fOptSet & OPTPROC_L_N_S) { + case OPTPROC_L_N_S: fputs(zFlagOkay, option_usage_fp); break; + case OPTPROC_SHORTOPT: break; + case OPTPROC_LONGOPT: fputs(zNoFlags, option_usage_fp); break; + case 0: fputs(zOptsOnly, option_usage_fp); break; + } + + if ((opts->fOptSet & OPTPROC_NUM_OPT) != 0) + fputs(zNumberOpt, option_usage_fp); + + if ((opts->fOptSet & OPTPROC_REORDER) != 0) + fputs(zReorder, option_usage_fp); + + if (opts->pzExplain != NULL) + fputs(opts->pzExplain, option_usage_fp); + + /* + * IF the user is asking for help (thus exiting with SUCCESS), + * THEN see what additional information we can provide. + */ + if (exit_code == EXIT_SUCCESS) + prt_prog_detail(opts); + + /* + * Give bug notification preference to the packager information + */ + if (HAS_pzPkgDataDir(opts) && (opts->pzPackager != NULL)) + fputs(opts->pzPackager, option_usage_fp); + + else if (opts->pzBugAddr != NULL) + fprintf(option_usage_fp, zPlsSendBugs, opts->pzBugAddr); + + fflush(option_usage_fp); + + if (ferror(option_usage_fp) != 0) + fserr_exit(opts->pzProgName, zwriting, (option_usage_fp == stderr) + ? zstderr_name : zstdout_name); +} + +static void +print_one_paragraph(char const * text, bool plain, FILE * fp) +{ + if (plain) { +#ifdef ENABLE_NLS +#ifdef HAVE_LIBINTL_H +#ifdef DEBUG_ENABLED +#undef gettext +#endif + char * buf = dgettext("libopts", text); + if (buf == text) + text = gettext(text); +#endif /* HAVE_LIBINTL_H */ +#endif /* ENABLE_NLS */ + fputs(text, fp); + } + + else { + char const * t = optionQuoteString(text, LINE_SPLICE); + fprintf(fp, PUTS_FMT, t); + AGFREE(t); + } +} + +/*=export_func optionPrintParagraphs + * private: + * + * what: Print a paragraph of usage text + * arg: + char const * + text + a block of text that has bee i18n-ed + + * arg: + bool + plain + false -> wrap text in fputs() + + * arg: + FILE * + fp + the stream file pointer for output + + * + * doc: + * This procedure is called in two contexts: when a full or short usage text + * has been provided for display, and when autogen is assembling a list of + * translatable texts in the optmain.tlib template. In the former case, \a + * plain is set to \a true, otherwise \a false. + * + * Anything less than 256 characters in size is printed as a single unit. + * Otherwise, paragraphs are detected. A paragraph break is defined as just + * before a non-empty line preceded by two newlines or a line that starts + * with at least one space character but fewer than 8 space characters. + * Lines indented with tabs or more than 7 spaces are considered continuation + * lines. + * + * If 'plain' is true, we are emitting text for a user to see. So, if it is + * true and NLS is not enabled, then just write the whole thing at once. +=*/ +void +optionPrintParagraphs(char const * text, bool plain, FILE * fp) +{ + size_t len = strlen(text); + char * buf; +#ifndef ENABLE_NLS + if (plain || (len < 256)) +#else + if (len < 256) +#endif + { + print_one_paragraph(text, plain, fp); + return; + } + + AGDUPSTR(buf, text, "ppara"); + text = buf; + + for (;;) { + char * scan; + + if (len < 256) { + done: + print_one_paragraph(buf, plain, fp); + break; + } + scan = buf; + + try_longer: + scan = strchr(scan, NL); + if (scan == NULL) + goto done; + + if ((scan - buf) < 40) { + scan++; + goto try_longer; + } + + scan++; + if ((! isspace((int)*scan)) || (*scan == HT)) + /* + * line starts with tab or non-whitespace --> continuation + */ + goto try_longer; + + if (*scan == NL) { + /* + * Double newline -> paragraph break + * Include all newlines in current paragraph. + */ + while (*++scan == NL) /*continue*/; + + } else { + char * p = scan; + int sp_ct = 0; + + while (*p == ' ') { + if (++sp_ct >= 8) { + /* + * Too many spaces --> continuation line + */ + scan = p; + goto try_longer; + } + p++; + } + } + + /* + * "scan" points to the first character of a paragraph or the + * terminating NUL byte. + */ + { + char svch = *scan; + *scan = NUL; + print_one_paragraph(buf, plain, fp); + len -= scan - buf; + if (len <= 0) + break; + *scan = svch; + buf = scan; + } + } + AGFREE(text); +} + +/*=export_func optionUsage + * private: + * + * what: Print usage text + * arg: + tOptions * + opts + program options descriptor + + * arg: + int + exitCode + exit code for calling exit(3) + + * + * doc: + * This routine will print usage in both GNU-standard and AutoOpts-expanded + * formats. The descriptor specifies the default, but AUTOOPTS_USAGE will + * over-ride this, providing the value of it is set to either "gnu" or + * "autoopts". This routine will @strong{not} return. + * + * If "exitCode" is "AO_EXIT_REQ_USAGE" (normally 64), then output will to + * to stdout and the actual exit code will be "EXIT_SUCCESS". +=*/ +noreturn void +optionUsage(tOptions * opts, int usage_exit_code) +{ + int exit_code = (usage_exit_code == AO_EXIT_REQ_USAGE) + ? EXIT_SUCCESS : usage_exit_code; + + displayEnum = false; + set_usage_flags(opts, NULL); + + /* + * Paged usage will preset option_usage_fp to an output file. + * If it hasn't already been set, then set it to standard output + * on successful exit (help was requested), otherwise error out. + * + * Test the version before obtaining pzFullUsage or pzShortUsage. + * These fields do not exist before revision 30. + */ + { + char const * pz; + + if (exit_code == EXIT_SUCCESS) { + pz = (opts->structVersion >= 30 * 4096) + ? opts->pzFullUsage : NULL; + + if (option_usage_fp == NULL) + option_usage_fp = print_exit ? stderr : stdout; + + } else { + pz = (opts->structVersion >= 30 * 4096) + ? opts->pzShortUsage : NULL; + + if (option_usage_fp == NULL) + option_usage_fp = stderr; + } + + if (((opts->fOptSet & OPTPROC_COMPUTE) == 0) && (pz != NULL)) { + if ((opts->fOptSet & OPTPROC_TRANSLATE) != 0) + optionPrintParagraphs(pz, true, option_usage_fp); + else + fputs(pz, option_usage_fp); + goto flush_and_exit; + } + } + + fprintf(option_usage_fp, opts->pzUsageTitle, opts->pzProgName); + + if ((exit_code == EXIT_SUCCESS) || + (! skip_misuse_usage(opts))) + + print_usage_details(opts, usage_exit_code); + else + print_offer_usage(opts); + + flush_and_exit: + fflush(option_usage_fp); + if (ferror(option_usage_fp) != 0) + fserr_exit(opts->pzProgName, zwriting, (option_usage_fp == stdout) + ? zstdout_name : zstderr_name); + + option_exits(exit_code); +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * PER OPTION TYPE USAGE INFORMATION + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/** + * print option conflicts. + * + * @param opts the program option descriptor + * @param od the option descriptor + */ +static void +prt_conflicts(tOptions * opts, tOptDesc * od) +{ + const int * opt_no; + fputs(zTabHyp + tab_skip_ct, option_usage_fp); + + /* + * REQUIRED: + */ + if (od->pOptMust != NULL) { + opt_no = od->pOptMust; + + if (opt_no[1] == NO_EQUIVALENT) { + fprintf(option_usage_fp, zReqOne, + opts->pOptDesc[*opt_no].pz_Name); + } else { + fputs(zReqThese, option_usage_fp); + for (;;) { + fprintf(option_usage_fp, zTabout + tab_skip_ct, + opts->pOptDesc[*opt_no].pz_Name); + if (*++opt_no == NO_EQUIVALENT) + break; + } + } + + if (od->pOptCant != NULL) + fputs(zTabHypAnd + tab_skip_ct, option_usage_fp); + } + + /* + * CONFLICTS: + */ + if (od->pOptCant == NULL) + return; + + opt_no = od->pOptCant; + + if (opt_no[1] == NO_EQUIVALENT) { + fprintf(option_usage_fp, zProhibOne, + opts->pOptDesc[*opt_no].pz_Name); + return; + } + + fputs(zProhib, option_usage_fp); + for (;;) { + fprintf(option_usage_fp, zTabout + tab_skip_ct, + opts->pOptDesc[*opt_no].pz_Name); + if (*++opt_no == NO_EQUIVALENT) + break; + } +} + +/** + * Print the usage information for a single vendor option. + * + * @param[in] opts the program option descriptor + * @param[in] od the option descriptor + * @param[in] argtp names of the option argument types + * @param[in] usefmt format for primary usage line + */ +static void +prt_one_vendor(tOptions * opts, tOptDesc * od, + arg_types_t * argtp, char const * usefmt) +{ + prt_preamble(opts, od, argtp); + + { + char z[ 80 ]; + char const * pzArgType; + + /* + * Determine the argument type string first on its usage, then, + * when the option argument is required, base the type string on the + * argument type. + */ + if (od->fOptState & OPTST_ARG_OPTIONAL) { + pzArgType = argtp->pzOpt; + + } else switch (OPTST_GET_ARGTYPE(od->fOptState)) { + case OPARG_TYPE_NONE: pzArgType = argtp->pzNo; break; + case OPARG_TYPE_ENUMERATION: pzArgType = argtp->pzKey; break; + case OPARG_TYPE_FILE: pzArgType = argtp->pzFile; break; + case OPARG_TYPE_MEMBERSHIP: pzArgType = argtp->pzKeyL; break; + case OPARG_TYPE_BOOLEAN: pzArgType = argtp->pzBool; break; + case OPARG_TYPE_NUMERIC: pzArgType = argtp->pzNum; break; + case OPARG_TYPE_HIERARCHY: pzArgType = argtp->pzNest; break; + case OPARG_TYPE_STRING: pzArgType = argtp->pzStr; break; + case OPARG_TYPE_TIME: pzArgType = argtp->pzTime; break; + default: goto bogus_desc; + } + + pzArgType = SPN_WHITESPACE_CHARS(pzArgType); + if (*pzArgType == NUL) + snprintf(z, sizeof(z), "%s", od->pz_Name); + else + snprintf(z, sizeof(z), "%s=%s", od->pz_Name, pzArgType); + fprintf(option_usage_fp, usefmt, z, od->pzText); + + switch (OPTST_GET_ARGTYPE(od->fOptState)) { + case OPARG_TYPE_ENUMERATION: + case OPARG_TYPE_MEMBERSHIP: + displayEnum = (od->pOptProc != NULL) ? true : displayEnum; + } + } + + return; + + bogus_desc: + fprintf(stderr, zbad_od, opts->pzProgName, od->pz_Name); + ao_bug(zbad_arg_type_msg); +} + +/** + * Print the long options processed with "-W". These options will be the + * ones that do *not* have flag characters. + * + * @param opts the program option descriptor + * @param title the title for the options + */ +static void +prt_vendor_opts(tOptions * opts, char const * title) +{ + static unsigned int const not_vended_mask = + OPTST_NO_USAGE_MASK | OPTST_DOCUMENT; + + static char const vfmtfmt[] = "%%-%us %%s\n"; + char vfmt[sizeof(vfmtfmt)]; + + /* + * Only handle client specified options. The "vendor option" follows + * "presetOptCt", so we won't loop/recurse indefinitely. + */ + int ct = opts->presetOptCt; + tOptDesc * od = opts->pOptDesc; + fprintf(option_usage_fp, zTabout + tab_skip_ct, zVendOptsAre); + + { + size_t nmlen = 0; + do { + size_t l; + if ( ((od->fOptState & not_vended_mask) != 0) + || GRAPH_CH(od->optValue)) + continue; + + l = strlen(od->pz_Name); + if (l > nmlen) nmlen = l; + } while (od++, (--ct > 0)); + + snprintf(vfmt, sizeof(vfmt), vfmtfmt, (unsigned int)nmlen + 4); + } + + if (tab_skip_ct > 0) + tab_skip_ct--; + + ct = opts->presetOptCt; + od = opts->pOptDesc; + + do { + if ( ((od->fOptState & not_vended_mask) != 0) + || GRAPH_CH(od->optValue)) + continue; + + prt_one_vendor(opts, od, &argTypes, vfmt); + prt_extd_usage(opts, od, title); + + } while (od++, (--ct > 0)); + + /* no need to restore "tab_skip_ct" - options are done now */ +} + +/** + * Print extended usage. Usage/help was requested. + * + * @param opts the program option descriptor + * @param od the option descriptor + * @param title the title for the options + */ +static void +prt_extd_usage(tOptions * opts, tOptDesc * od, char const * title) +{ + if ( ((opts->fOptSet & OPTPROC_VENDOR_OPT) != 0) + && (od->optActualValue == VENDOR_OPTION_VALUE)) { + prt_vendor_opts(opts, title); + return; + } + + /* + * IF there are option conflicts or dependencies, + * THEN print them here. + */ + if ((od->pOptMust != NULL) || (od->pOptCant != NULL)) + prt_conflicts(opts, od); + + /* + * IF there is a disablement string + * THEN print the disablement info + */ + if (od->pz_DisableName != NULL ) + fprintf(option_usage_fp, zDis + tab_skip_ct, od->pz_DisableName); + + /* + * Check for argument types that have callbacks with magical properties + */ + switch (OPTST_GET_ARGTYPE(od->fOptState)) { + case OPARG_TYPE_NUMERIC: + /* + * IF the numeric option has a special callback, + * THEN call it, requesting the range or other special info + */ + if ( (od->pOptProc != NULL) + && (od->pOptProc != optionNumericVal) ) { + (*(od->pOptProc))(OPTPROC_EMIT_USAGE, od); + } + break; + + case OPARG_TYPE_FILE: + (*(od->pOptProc))(OPTPROC_EMIT_USAGE, od); + break; + } + + /* + * IF the option defaults to being enabled, + * THEN print that out + */ + if (od->fOptState & OPTST_INITENABLED) + fputs(zEnab + tab_skip_ct, option_usage_fp); + + /* + * IF the option is in an equivalence class + * AND not the designated lead + * THEN print equivalence and leave it at that. + */ + if ( (od->optEquivIndex != NO_EQUIVALENT) + && (od->optEquivIndex != od->optActualIndex ) ) { + fprintf(option_usage_fp, zalt_opt + tab_skip_ct, + opts->pOptDesc[ od->optEquivIndex ].pz_Name); + return; + } + + /* + * IF this particular option can NOT be preset + * AND some form of presetting IS allowed, + * AND it is not an auto-managed option (e.g. --help, et al.) + * THEN advise that this option may not be preset. + */ + if ( ((od->fOptState & OPTST_NO_INIT) != 0) + && ( (opts->papzHomeList != NULL) + || (opts->pzPROGNAME != NULL) + ) + && (od->optIndex < opts->presetOptCt) + ) + + fputs(zNoPreset + tab_skip_ct, option_usage_fp); + + /* + * Print the appearance requirements. + */ + if (OPTST_GET_ARGTYPE(od->fOptState) == OPARG_TYPE_MEMBERSHIP) + fputs(zMembers + tab_skip_ct, option_usage_fp); + + else switch (od->optMinCt) { + case 1: + case 0: + switch (od->optMaxCt) { + case 0: fputs(zPreset + tab_skip_ct, option_usage_fp); break; + case NOLIMIT: fputs(zNoLim + tab_skip_ct, option_usage_fp); break; + case 1: break; + /* + * IF the max is more than one but limited, print "UP TO" message + */ + default: + fprintf(option_usage_fp, zUpTo + tab_skip_ct, od->optMaxCt); break; + } + break; + + default: + /* + * More than one is required. Print the range. + */ + fprintf(option_usage_fp, zMust + tab_skip_ct, + od->optMinCt, od->optMaxCt); + } + + if ( NAMED_OPTS(opts) + && (opts->specOptIdx.default_opt == od->optIndex)) + fputs(zDefaultOpt + tab_skip_ct, option_usage_fp); +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/** + * Figure out where all the initialization files might live. This requires + * translating some environment variables and testing to see if a name is a + * directory or a file. It's squishy, but important to tell users how to + * find these files. + * + * @param[in] papz search path + * @param[out] ini_file an output buffer of AG_PATH_MAX+1 bytes + * @param[in] path_nm the name of the file we're hunting for + */ +static void +prt_ini_list(char const * const * papz, char const * ini_file, + char const * path_nm) +{ + char pth_buf[AG_PATH_MAX+1]; + + fputs(zPresetIntro, option_usage_fp); + + for (;;) { + char const * path = *(papz++); + char const * nm_buf = pth_buf; + + if (path == NULL) + break; + + /* + * Ignore any invalid paths + */ + if (! optionMakePath(pth_buf, (int)sizeof(pth_buf), path, path_nm)) + nm_buf = path; + + /* + * Expand paths that are relative to the executable or installation + * directories. Leave alone paths that use environment variables. + */ + else if ((*path == '$') + && ((path[1] == '$') || (path[1] == '@'))) + path = nm_buf; + + /* + * Print the name of the "homerc" file. If the "rcfile" name is + * not empty, we may or may not print that, too... + */ + fprintf(option_usage_fp, zPathFmt, path); + if (*ini_file != NUL) { + struct stat sb; + + /* + * IF the "homerc" file is a directory, + * then append the "rcfile" name. + */ + if ((stat(nm_buf, &sb) == 0) && S_ISDIR(sb.st_mode)) { + fputc(DIRCH, option_usage_fp); + fputs(ini_file, option_usage_fp); + } + } + + fputc(NL, option_usage_fp); + } +} + +/** + * Print the usage line preamble text + * + * @param opts the program option descriptor + * @param od the option descriptor + * @param at names of the option argument types + */ +static void +prt_preamble(tOptions * opts, tOptDesc * od, arg_types_t * at) +{ + /* + * Flag prefix: IF no flags at all, then omit it. If not printable + * (not allowed for this option), then blank, else print it. + * Follow it with a comma if we are doing GNU usage and long + * opts are to be printed too. + */ + if ((opts->fOptSet & OPTPROC_SHORTOPT) == 0) + fputs(at->pzSpc, option_usage_fp); + + else if (! GRAPH_CH(od->optValue)) { + if ( (opts->fOptSet & (OPTPROC_GNUUSAGE|OPTPROC_LONGOPT)) + == (OPTPROC_GNUUSAGE|OPTPROC_LONGOPT)) + fputc(' ', option_usage_fp); + fputs(at->pzNoF, option_usage_fp); + + } else { + fprintf(option_usage_fp, " -%c", od->optValue); + if ( (opts->fOptSet & (OPTPROC_GNUUSAGE|OPTPROC_LONGOPT)) + == (OPTPROC_GNUUSAGE|OPTPROC_LONGOPT)) + fputs(", ", option_usage_fp); + } +} + +/** + * Print the usage information for a single option. + * + * @param opts the program option descriptor + * @param od the option descriptor + * @param at names of the option argument types + */ +static void +prt_one_usage(tOptions * opts, tOptDesc * od, arg_types_t * at) +{ + prt_preamble(opts, od, at); + + { + char z[80]; + char const * atyp; + + /* + * Determine the argument type string first on its usage, then, + * when the option argument is required, base the type string on the + * argument type. + */ + if (od->fOptState & OPTST_ARG_OPTIONAL) { + atyp = at->pzOpt; + + } else switch (OPTST_GET_ARGTYPE(od->fOptState)) { + case OPARG_TYPE_NONE: atyp = at->pzNo; break; + case OPARG_TYPE_ENUMERATION: atyp = at->pzKey; break; + case OPARG_TYPE_FILE: atyp = at->pzFile; break; + case OPARG_TYPE_MEMBERSHIP: atyp = at->pzKeyL; break; + case OPARG_TYPE_BOOLEAN: atyp = at->pzBool; break; + case OPARG_TYPE_NUMERIC: atyp = at->pzNum; break; + case OPARG_TYPE_HIERARCHY: atyp = at->pzNest; break; + case OPARG_TYPE_STRING: atyp = at->pzStr; break; + case OPARG_TYPE_TIME: atyp = at->pzTime; break; + default: goto bogus_desc; + } + +#ifdef _WIN32 + if (at->pzOptFmt == zGnuOptFmt) + snprintf(z, sizeof(z), "--%s%s", od->pz_Name, atyp); + else if (at->pzOptFmt == zGnuOptFmt + 2) + snprintf(z, sizeof(z), "%s%s", od->pz_Name, atyp); + else +#endif + snprintf(z, sizeof(z), at->pzOptFmt, atyp, od->pz_Name, + (od->optMinCt != 0) ? at->pzReq : at->pzOpt); + + fprintf(option_usage_fp, line_fmt_buf, z, od->pzText); + + switch (OPTST_GET_ARGTYPE(od->fOptState)) { + case OPARG_TYPE_ENUMERATION: + case OPARG_TYPE_MEMBERSHIP: + displayEnum = (od->pOptProc != NULL) ? true : displayEnum; + } + } + + return; + + bogus_desc: + fprintf(stderr, zbad_od, opts->pzProgName, od->pz_Name); + option_exits(EX_SOFTWARE); +} + +/** + * Print out the usage information for just the options. + */ +static void +prt_opt_usage(tOptions * opts, int ex_code, char const * title) +{ + int ct = opts->optCt; + int optNo = 0; + tOptDesc * od = opts->pOptDesc; + int docCt = 0; + + do { + /* + * no usage --> disallowed on command line (OPTST_NO_COMMAND), or + * deprecated -- strongly discouraged (OPTST_DEPRECATED), or + * compiled out of current object code (OPTST_OMITTED) + */ + if ((od->fOptState & OPTST_NO_USAGE_MASK) != 0) { + + /* + * IF this is a compiled-out option + * *AND* usage was requested with "omitted-usage" + * *AND* this is NOT abbreviated usage + * THEN display this option. + */ + if ( (od->fOptState == (OPTST_OMITTED | OPTST_NO_INIT)) + && (od->pz_Name != NULL) + && (ex_code == EXIT_SUCCESS)) { + + char const * why_pz = + (od->pzText == NULL) ? zDisabledWhy : od->pzText; + prt_preamble(opts, od, &argTypes); + fprintf(option_usage_fp, zDisabledOpt, od->pz_Name, why_pz); + } + + continue; + } + + if ((od->fOptState & OPTST_DOCUMENT) != 0) { + if (ex_code == EXIT_SUCCESS) { + fprintf(option_usage_fp, argTypes.pzBrk, od->pzText, + title); + docCt++; + } + + continue; + } + + /* Skip name only options when we have a vendor option */ + if ( ((opts->fOptSet & OPTPROC_VENDOR_OPT) != 0) + && (! GRAPH_CH(od->optValue))) + continue; + + /* + * IF this is the first auto-opt maintained option + * *AND* we are doing a full help + * *AND* there are documentation options + * *AND* the last one was not a doc option, + * THEN document that the remaining options are not user opts + */ + if ((docCt > 0) && (ex_code == EXIT_SUCCESS)) { + if (opts->presetOptCt == optNo) { + if ((od[-1].fOptState & OPTST_DOCUMENT) == 0) + fprintf(option_usage_fp, argTypes.pzBrk, zAuto, title); + + } else if ((ct == 1) && + (opts->fOptSet & OPTPROC_VENDOR_OPT)) + fprintf(option_usage_fp, argTypes.pzBrk, zVendIntro, title); + } + + prt_one_usage(opts, od, &argTypes); + + /* + * IF we were invoked because of the --help option, + * THEN print all the extra info + */ + if (ex_code == EXIT_SUCCESS) + prt_extd_usage(opts, od, title); + + } while (od++, optNo++, (--ct > 0)); + + fputc(NL, option_usage_fp); +} + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/** + * Print program details. + * @param[in] opts the program option descriptor + */ +static void +prt_prog_detail(tOptions * opts) +{ + bool need_intro = (opts->papzHomeList == NULL); + + /* + * Display all the places we look for config files, if we have + * a list of directories to search. + */ + if (! need_intro) + prt_ini_list(opts->papzHomeList, opts->pzRcName, opts->pzProgPath); + + /* + * Let the user know about environment variable settings + */ + if ((opts->fOptSet & OPTPROC_ENVIRON) != 0) { + if (need_intro) + fputs(zPresetIntro, option_usage_fp); + + fprintf(option_usage_fp, zExamineFmt, opts->pzPROGNAME); + } + + /* + * IF we found an enumeration, + * THEN hunt for it again. Call the handler proc with a NULL + * option struct pointer. That tells it to display the keywords. + */ + if (displayEnum) { + int ct = opts->optCt; + int optNo = 0; + tOptDesc * od = opts->pOptDesc; + + fputc(NL, option_usage_fp); + fflush(option_usage_fp); + do { + switch (OPTST_GET_ARGTYPE(od->fOptState)) { + case OPARG_TYPE_ENUMERATION: + case OPARG_TYPE_MEMBERSHIP: + (*(od->pOptProc))(OPTPROC_EMIT_USAGE, od); + } + } while (od++, optNo++, (--ct > 0)); + } + + /* + * If there is a detail string, now is the time for that. + */ + if (opts->pzDetail != NULL) + fputs(opts->pzDetail, option_usage_fp); +} + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * OPTION LINE FORMATTING SETUP + * + * The "OptFmt" formats receive three arguments: + * 1. the type of the option's argument + * 2. the long name of the option + * 3. "YES" or "no ", depending on whether or not the option must appear + * on the command line. + * These formats are used immediately after the option flag (if used) has + * been printed. + * + * Set up the formatting for GNU-style output + */ +static int +setGnuOptFmts(tOptions * opts, char const ** ptxt) +{ + static char const zOneSpace[] = " "; + int flen = 22; + *ptxt = zNoRq_ShrtTtl; + + argTypes.pzStr = zGnuStrArg; + argTypes.pzReq = zOneSpace; + argTypes.pzNum = zGnuNumArg; + argTypes.pzKey = zGnuKeyArg; + argTypes.pzKeyL = zGnuKeyLArg; + argTypes.pzTime = zGnuTimeArg; + argTypes.pzFile = zGnuFileArg; + argTypes.pzBool = zGnuBoolArg; + argTypes.pzNest = zGnuNestArg; + argTypes.pzOpt = zGnuOptArg; + argTypes.pzNo = zOneSpace; + argTypes.pzBrk = zGnuBreak; + argTypes.pzNoF = zSixSpaces; + argTypes.pzSpc = zThreeSpaces; + + switch (opts->fOptSet & OPTPROC_L_N_S) { + case OPTPROC_L_N_S: argTypes.pzOptFmt = zGnuOptFmt; break; + case OPTPROC_LONGOPT: argTypes.pzOptFmt = zGnuOptFmt; break; + case 0: argTypes.pzOptFmt = zGnuOptFmt + 2; break; + case OPTPROC_SHORTOPT: + argTypes.pzOptFmt = zShrtGnuOptFmt; + zGnuStrArg[0] = zGnuNumArg[0] = zGnuKeyArg[0] = zGnuBoolArg[0] = ' '; + argTypes.pzOpt = " [arg]"; + flen = 8; + break; + } + + return flen; +} + + +/* + * Standard (AutoOpts normal) option line formatting + */ +static int +setStdOptFmts(tOptions * opts, char const ** ptxt) +{ + int flen = 0; + + argTypes.pzStr = zStdStrArg; + argTypes.pzReq = zStdReqArg; + argTypes.pzNum = zStdNumArg; + argTypes.pzKey = zStdKeyArg; + argTypes.pzKeyL = zStdKeyLArg; + argTypes.pzTime = zStdTimeArg; + argTypes.pzFile = zStdFileArg; + argTypes.pzBool = zStdBoolArg; + argTypes.pzNest = zStdNestArg; + argTypes.pzOpt = zStdOptArg; + argTypes.pzNo = zStdNoArg; + argTypes.pzBrk = zStdBreak; + argTypes.pzNoF = zFiveSpaces; + argTypes.pzSpc = zTwoSpaces; + + switch (opts->fOptSet & (OPTPROC_NO_REQ_OPT | OPTPROC_SHORTOPT)) { + case (OPTPROC_NO_REQ_OPT | OPTPROC_SHORTOPT): + *ptxt = zNoRq_ShrtTtl; + argTypes.pzOptFmt = zNrmOptFmt; + flen = 19; + break; + + case OPTPROC_NO_REQ_OPT: + *ptxt = zNoRq_NoShrtTtl; + argTypes.pzOptFmt = zNrmOptFmt; + flen = 19; + break; + + case OPTPROC_SHORTOPT: + *ptxt = zReq_ShrtTtl; + argTypes.pzOptFmt = zReqOptFmt; + flen = 24; + break; + + case 0: + *ptxt = zReq_NoShrtTtl; + argTypes.pzOptFmt = zReqOptFmt; + flen = 24; + } + + return flen; +} + +/** @} + * + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of autoopts/usage.c */ diff --git a/autoopts/version.c b/autoopts/version.c new file mode 100644 index 0000000..cd46be3 --- /dev/null +++ b/autoopts/version.c @@ -0,0 +1,240 @@ + +/** \file version.c + * + * This module implements the default usage procedure for + * Automated Options. It may be overridden, of course. + * + * @addtogroup autoopts + * @{ + */ +/* + * This file is part of AutoOpts, a companion to AutoGen. + * AutoOpts is free software. + * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoOpts is available under any one of two licenses. The license + * in use must be one of these two and the choice is under the control + * of the user of the license. + * + * The GNU Lesser General Public License, version 3 or later + * See the files "COPYING.lgplv3" and "COPYING.gplv3" + * + * The Modified Berkeley Software Distribution License + * See the file "COPYING.mbsd" + * + * These files have the following sha256 sums: + * + * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 + * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 + * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + */ + +/*=export_func optionVersion + * + * what: return the compiled AutoOpts version number + * ret_type: char const * + * ret_desc: the version string in constant memory + * doc: + * Returns the full version string compiled into the library. + * The returned string cannot be modified. +=*/ +char const * +optionVersion(void) +{ + static char const ver[] = OPTIONS_DOTTED_VERSION; + return ver; +} + +static void +emit_first_line( + FILE * fp, char const * alt1, char const * alt2, char const * alt3) +{ + char const * p = (alt1 != NULL) ? alt1 : ((alt2 != NULL) ? alt2 : alt3); + char const * e; + if (p == NULL) + return; + e = strchr(p, NL); + if (e == NULL) + fputs(p, fp); + else + fwrite(p, 1, (e - p), fp); + fputc(NL, fp); +} + +/** + * Select among various ways to emit version information. + * + * @param[in] o the option descriptor + * @param[in] fp the output stream + */ +static void +emit_simple_ver(tOptions * o, FILE * fp) +{ + emit_first_line(fp, o->pzFullVersion, o->pzCopyright, o->pzUsageTitle); +} + +/** + * print the version with a copyright notice. + * + * @param[in] o the option descriptor + * @param[in] fp the output stream + */ +static void +emit_copy_full(tOptions * o, FILE * fp) +{ + if (o->pzCopyright != NULL) + fputs(o->pzCopyright, fp); + + else if (o->pzFullVersion != NULL) + fputs(o->pzFullVersion, fp); + + else + emit_first_line(fp, o->pzUsageTitle, NULL, NULL); + + if (HAS_pzPkgDataDir(o) && (o->pzPackager != NULL)) { + fputc(NL, fp); + fputs(o->pzPackager, fp); + + } else if (o->pzBugAddr != NULL) { + fputc(NL, fp); + fprintf(fp, zPlsSendBugs, o->pzBugAddr); + } +} + +/** + * print the version and any copyright notice. + * The version with a full copyright and additional notes. + * + * @param[in] opts the option descriptor + * @param[in] fp the output stream + */ +static void +emit_copy_note(tOptions * opts, FILE * fp) +{ + if (opts->pzCopyright != NULL) + fputs(opts->pzCopyright, fp); + + if (opts->pzCopyNotice != NULL) + fputs(opts->pzCopyNotice, fp); + + fputc(NL, fp); + fprintf(fp, zao_ver_fmt, optionVersion()); + + if (HAS_pzPkgDataDir(opts) && (opts->pzPackager != NULL)) { + fputc(NL, fp); + fputs(opts->pzPackager, fp); + + } else if (opts->pzBugAddr != NULL) { + fputc(NL, fp); + fprintf(fp, zPlsSendBugs, opts->pzBugAddr); + } +} + +/** + * Handle the version printing. We must see how much information + * is being requested and select the correct printing routine. + */ +static void +print_ver(tOptions * opts, tOptDesc * od, FILE * fp, bool call_exit) +{ + char ch; + + if (opts <= OPTPROC_EMIT_LIMIT) + return; + + /* + * IF we have an argument for this option, use it + * Otherwise, default to version only or copyright note, + * depending on whether the layout is GNU standard form or not. + */ + if ( (od->fOptState & OPTST_ARG_OPTIONAL) + && (od->optArg.argString != NULL) + && (od->optArg.argString[0] != NUL)) + + ch = od->optArg.argString[0]; + + else if (OPTST_GET_ARGTYPE(od->fOptState) == OPARG_TYPE_STATIC) { + ch = od->optArg.argString[0]; + + } else { + set_usage_flags(opts, NULL); + ch = (opts->fOptSet & OPTPROC_GNUUSAGE) ? 'c' : 'v'; + } + + switch (ch) { + case NUL: /* arg provided, but empty */ + case 'v': case 'V': emit_simple_ver(opts, fp); break; + case 'c': case 'C': emit_copy_full( opts, fp); break; + case 'n': case 'N': emit_copy_note( opts, fp); break; + + default: + fprintf(stderr, zBadVerArg, ch); + option_exits(EXIT_FAILURE); + } + + fflush(fp); + if (ferror(fp)) + fserr_exit(opts->pzProgName, zwriting, + (fp == stdout) ? zstdout_name : zstderr_name); + + if (call_exit) + option_exits(EXIT_SUCCESS); +} + +/*=export_func optionPrintVersion + * + * what: Print the program version + * arg: + tOptions * + opts + program options descriptor + + * arg: + tOptDesc * + od + the descriptor for this arg + + * + * doc: + * This routine will print the version to stdout. +=*/ +void +optionPrintVersion(tOptions * opts, tOptDesc * od) +{ + print_ver(opts, od, print_exit ? stderr : stdout, true); +} + +/*=export_func optionPrintVersionAndReturn + * + * what: Print the program version + * arg: + tOptions * + opts + program options descriptor + + * arg: + tOptDesc * + od + the descriptor for this arg + + * + * doc: + * This routine will print the version to stdout and return + * instead of exiting. Please see the source for the + * @code{print_ver} funtion for details on selecting how + * verbose to be after this function returns. +=*/ +void +optionPrintVersionAndReturn(tOptions * opts, tOptDesc * od) +{ + print_ver(opts, od, print_exit ? stderr : stdout, false); +} + +/*=export_func optionVersionStderr + * private: + * + * what: Print the program version to stderr + * arg: + tOptions * + opts + program options descriptor + + * arg: + tOptDesc * + od + the descriptor for this arg + + * + * doc: + * This routine will print the version to stderr. +=*/ +void +optionVersionStderr(tOptions * opts, tOptDesc * od) +{ + print_ver(opts, od, stderr, true); +} + +/** @} + * + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of autoopts/version.c */ diff --git a/build-aux/run-ag.sh b/build-aux/run-ag.sh new file mode 100644 index 0000000..6ee7b85 --- /dev/null +++ b/build-aux/run-ag.sh @@ -0,0 +1,89 @@ +#! /bin/bash +## run-ag.sh -- shell script for running autogen within autogen build +## +## Author: Bruce Korb +## +## This file is part of AutoGen. +## AutoGen Copyright (C) 2018 by Bruce Korb - all rights reserved +## +## AutoGen 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. +## +## AutoGen is distributed in the hope that 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 . +## --------------------------------------------------------------------- +# +# If the first argument ends with *-dep.mk, then it is expected that this +# script has been called in the Makefile building phase and the target and +# any containing directory must be created. The target is created with a +# very old time stamp. +# +AGexe=/u/bkorb/tools/ag/autogen-bld/agen5/.libs/autogen +find_exe() { + eval local exe=\${$1} + test -x "$exe" && return 0 + case "$2" in + autogen ) exe=`cd ../agen5 > /dev/null ; pwd`/$2 ;; + columns ) exe=`cd ../columns > /dev/null ; pwd`/$2 ;; + + * ) echo "wrong executable: '$2'" >&2 + exit 1 ;; + esac + test -x "$exe" || exe=`command -v $2` + test -x "$exe" || { + echo "cannot locate $2" + return 1 + } 1>&2 + eval $1=$exe + return 0 +} + +STAMP_TEMP_DIR=$(mktemp --suffix=.tdir -d /tmp/run-ag-XXXXXXXX) +exec 9>&2 2>> ${STAMP_TEMP_DIR}/mk-stamps.log +VERBOSE=1 + +test "X$VERBOSE" = X1 && { + PS4='+run-ag-$LINENO> ' + set -x + : in $PWD +} + +stamp_file='' +case "$1" in + -MF*-dep.mk ) : ;; + + *-dep.mk ) + dir=`dirname "$1"` + test -d "$dir" || mkdir -p "$dir" || exit 1 + touch -t 197001020000 "$1" + exit $? + ;; + + '' ) exit 1 ;; +esac + +test -x "$AGexe" || find_exe AGexe autogen +test -x "CLexe" || find_exe CLexe columns +PATH=`dirname "$CLexe"`:"$PATH" +L_opt="-L'${top_srcdir}/autoopts/tpl'" +test "X${top_srcdir}" = "X${top_builddir}" || \ + L_opt="$L_opt -L'${top_builddir}/autoopts/tpl'" + +eval "${AGexe}" $L_opt '"$@"' +exit $? + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## sh-basic-offset: 2 +## End: + +# END OF add-on/build-aux/mk-ag-dep.sh diff --git a/columns/Makefile.am b/columns/Makefile.am new file mode 100644 index 0000000..f6e77cc --- /dev/null +++ b/columns/Makefile.am @@ -0,0 +1,74 @@ +## -*- Mode: Makefile -*- +## +## Makefile.am -- process this file with automake to produce Makefile.in +## +## Copyright (C) 1992-2018 by Bruce Korb +## +## This file is part of AutoGen. +## +## AutoGen 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. +## +## AutoGen is distributed in the hope that 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 . + +bin_PROGRAMS = columns +columns_LDFLAGS = -no-install +csrc = opts.h columns.c opts.c +nodist_columns_SOURCES = cols.c + +LO_LIB = $(top_builddir)/autoopts/libopts.la +columns_LDADD = $(LO_LIB) $(GUILE_LIBS) + +BUILT_SOURCES = columns.menu columns.texi columns.1 +EXTRA_DIST = opts.def $(csrc) + +RUNAG = $(AGexe) -L$(top_srcdir)/autoopts/tpl \ + -L$(top_builddir)/autoopts/tpl -MF$@ +man_MANS = columns.1 + +AM_CPPFLAGS = @INCLIST@ + +CONFIG_CLEAN_FILES = $(BUILT_SOURCES) stamp-* +MAINTAINERCLEANFILES = $(CONFIG_CLEAN_FILES) +DISTCLEANFILES = cols.c +DOC_TIMEOUT = -DLEVEL=section --timeout=`expr $(AG_TIMEOUT) '*' 3` + +gen : $(BUILT_SOURCES) + +all : gen + +## opts.h cannot be built until columns is built, so no rules for it. + +columns.menu columns.texi : stamp-agtexi +columns.1 : stamp-agman + +cols.c : Makefile + exec > $@ ; \ + echo '#undef PKGDATADIR' ; \ + echo '#define PKGDATADIR "$(pkgdatadir)"' ; \ + echo ; echo '#define DEFINING 1' ; \ + echo '#include "autoopts/project.h"' ; \ + for f in $(csrc) ; do echo "#include \"$$f\"" ; done + +$(LO_LIB) : + ( cd $(top_builddir)/autoopts ; $(MAKE) libopts.la ) + +stamp-agtexi : opts.def columns$(EXEEXT) + top_builddir=$(top_builddir) \ + $(RUNAG) -Tagtexi-cmd.tpl $(DOC_TIMEOUT) $(srcdir)/opts.def + +stamp-agman : opts.def columns$(EXEEXT) + top_builddir=$(top_builddir) \ + $(RUNAG) -Tagman-cmd.tpl $(srcdir)/opts.def + +.NOTPARALLEL: + +# end of Makefile.am diff --git a/columns/Makefile.in b/columns/Makefile.in new file mode 100644 index 0000000..8da74c6 --- /dev/null +++ b/columns/Makefile.in @@ -0,0 +1,831 @@ +# Makefile.in generated by automake 1.16.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2018 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +bin_PROGRAMS = columns$(EXEEXT) +subdir = columns +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/config/ag_macros.m4 \ + $(top_srcdir)/config/asm-underscore.m4 \ + $(top_srcdir)/config/extensions.m4 \ + $(top_srcdir)/config/guile.m4 \ + $(top_srcdir)/config/host-cpu-c-abi.m4 \ + $(top_srcdir)/config/lib-ld.m4 \ + $(top_srcdir)/config/lib-link.m4 \ + $(top_srcdir)/config/lib-prefix.m4 \ + $(top_srcdir)/config/libopts.m4 \ + $(top_srcdir)/config/libtool.m4 \ + $(top_srcdir)/config/ltoptions.m4 \ + $(top_srcdir)/config/ltsugar.m4 \ + $(top_srcdir)/config/ltversion.m4 \ + $(top_srcdir)/config/lt~obsolete.m4 \ + $(top_srcdir)/config/onceonly.m4 $(top_srcdir)/config/pkg.m4 \ + $(top_srcdir)/config/snprintfv.m4 \ + $(top_srcdir)/config/stdnoreturn.m4 \ + $(top_srcdir)/config/unlocked-io.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_VPATH_FILES = +am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" +PROGRAMS = $(bin_PROGRAMS) +nodist_columns_OBJECTS = cols.$(OBJEXT) +columns_OBJECTS = $(nodist_columns_OBJECTS) +am__DEPENDENCIES_1 = +columns_DEPENDENCIES = $(LO_LIB) $(am__DEPENDENCIES_1) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +columns_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(columns_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/config/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/cols.Po +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(nodist_columns_SOURCES) +DIST_SOURCES = +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +man1dir = $(mandir)/man1 +NROFF = nroff +MANS = $(man_MANS) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/config/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AGEN5_TESTS = @AGEN5_TESTS@ +AG_LDFLAGS = @AG_LDFLAGS@ +AG_MAJOR_VERSION = @AG_MAJOR_VERSION@ +AG_MINOR_VERSION = @AG_MINOR_VERSION@ +AG_STATIC_AUTOGEN = @AG_STATIC_AUTOGEN@ +AG_TIMEOUT = @AG_TIMEOUT@ +AG_VERSION = @AG_VERSION@ +AG_XML2 = @AG_XML2@ +AGexe = @AGexe@ +AGnam = @AGnam@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AO_AGE = @AO_AGE@ +AO_CURRENT = @AO_CURRENT@ +AO_REVISION = @AO_REVISION@ +AO_TEMPLATE_VERSION = @AO_TEMPLATE_VERSION@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CLexe = @CLexe@ +CLnam = @CLnam@ +CONFIG_SHELL = @CONFIG_SHELL@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEBUG_ENABLED = @DEBUG_ENABLED@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +DYNAMIC_AG = @DYNAMIC_AG@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ENABLE_STATIC = @ENABLE_STATIC@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GDexe = @GDexe@ +GDnam = @GDnam@ +GO_AGE = @GO_AGE@ +GO_CURRENT = @GO_CURRENT@ +GO_REVISION = @GO_REVISION@ +GREP = @GREP@ +GUILE_CFLAGS = @GUILE_CFLAGS@ +GUILE_EFFECTIVE_VERSION = @GUILE_EFFECTIVE_VERSION@ +GUILE_LDFLAGS = @GUILE_LDFLAGS@ +GUILE_LIBS = @GUILE_LIBS@ +GUILE_LTLIBS = @GUILE_LTLIBS@ +HOST_CPU = @HOST_CPU@ +HOST_CPU_C_ABI = @HOST_CPU_C_ABI@ +INCLIST = @INCLIST@ +INCSNPRINTFV = @INCSNPRINTFV@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSNPRINTFV = @LIBSNPRINTFV@ +LIBTOOL = @LIBTOOL@ +LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ +LIBXML2_LIBS = @LIBXML2_LIBS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +M4_SRC = @M4_SRC@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPTS_TESTDIR = @OPTS_TESTDIR@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POSIX_SHELL = @POSIX_SHELL@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STDNORETURN_H = @STDNORETURN_H@ +STRIP = @STRIP@ +TEXI2HTML = @TEXI2HTML@ +VERSION = @VERSION@ +WARN_CFLAGS = @WARN_CFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_aux_dir = @ac_aux_dir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +columns_LDFLAGS = -no-install +csrc = opts.h columns.c opts.c +nodist_columns_SOURCES = cols.c +LO_LIB = $(top_builddir)/autoopts/libopts.la +columns_LDADD = $(LO_LIB) $(GUILE_LIBS) +BUILT_SOURCES = columns.menu columns.texi columns.1 +EXTRA_DIST = opts.def $(csrc) +RUNAG = $(AGexe) -L$(top_srcdir)/autoopts/tpl \ + -L$(top_builddir)/autoopts/tpl -MF$@ + +man_MANS = columns.1 +AM_CPPFLAGS = @INCLIST@ +CONFIG_CLEAN_FILES = $(BUILT_SOURCES) stamp-* +MAINTAINERCLEANFILES = $(CONFIG_CLEAN_FILES) +DISTCLEANFILES = cols.c +DOC_TIMEOUT = -DLEVEL=section --timeout=`expr $(AG_TIMEOUT) '*' 3` +all: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu columns/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu columns/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ + fi; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p \ + || test -f $$p1 \ + ; then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' \ + -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' \ + `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(bindir)" && rm -f $$files + +clean-binPROGRAMS: + @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list + +columns$(EXEEXT): $(columns_OBJECTS) $(columns_DEPENDENCIES) $(EXTRA_columns_DEPENDENCIES) + @rm -f columns$(EXEEXT) + $(AM_V_CCLD)$(columns_LINK) $(columns_OBJECTS) $(columns_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cols.Po@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-man1: $(man_MANS) + @$(NORMAL_INSTALL) + @list1=''; \ + list2='$(man_MANS)'; \ + test -n "$(man1dir)" \ + && test -n "`echo $$list1$$list2`" \ + || exit 0; \ + echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \ + { for i in $$list1; do echo "$$i"; done; \ + if test -n "$$list2"; then \ + for i in $$list2; do echo "$$i"; done \ + | sed -n '/\.1[a-z]*$$/p'; \ + fi; \ + } | while read p; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; echo "$$p"; \ + done | \ + sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ + sed 'N;N;s,\n, ,g' | { \ + list=; while read file base inst; do \ + if test "$$base" = "$$inst"; then list="$$list $$file"; else \ + echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ + $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ + fi; \ + done; \ + for i in $$list; do echo "$$i"; done | $(am__base_list) | \ + while read files; do \ + test -z "$$files" || { \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ + done; } + +uninstall-man1: + @$(NORMAL_UNINSTALL) + @list=''; test -n "$(man1dir)" || exit 0; \ + files=`{ for i in $$list; do echo "$$i"; done; \ + l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ + sed -n '/\.1[a-z]*$$/p'; \ + } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ + dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir) + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) check-am +all-am: Makefile $(PROGRAMS) $(MANS) +installdirs: + for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) +clean: clean-am + +clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/cols.Po + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-man + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-binPROGRAMS + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: install-man1 + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/cols.Po + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-binPROGRAMS uninstall-man + +uninstall-man: uninstall-man1 + +.MAKE: all check install install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-binPROGRAMS clean-generic clean-libtool cscopelist-am \ + ctags ctags-am distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-binPROGRAMS \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-man1 \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags tags-am uninstall uninstall-am \ + uninstall-binPROGRAMS uninstall-man uninstall-man1 + +.PRECIOUS: Makefile + + +gen : $(BUILT_SOURCES) + +all : gen + +columns.menu columns.texi : stamp-agtexi +columns.1 : stamp-agman + +cols.c : Makefile + exec > $@ ; \ + echo '#undef PKGDATADIR' ; \ + echo '#define PKGDATADIR "$(pkgdatadir)"' ; \ + echo ; echo '#define DEFINING 1' ; \ + echo '#include "autoopts/project.h"' ; \ + for f in $(csrc) ; do echo "#include \"$$f\"" ; done + +$(LO_LIB) : + ( cd $(top_builddir)/autoopts ; $(MAKE) libopts.la ) + +stamp-agtexi : opts.def columns$(EXEEXT) + top_builddir=$(top_builddir) \ + $(RUNAG) -Tagtexi-cmd.tpl $(DOC_TIMEOUT) $(srcdir)/opts.def + +stamp-agman : opts.def columns$(EXEEXT) + top_builddir=$(top_builddir) \ + $(RUNAG) -Tagman-cmd.tpl $(srcdir)/opts.def + +.NOTPARALLEL: + +# end of Makefile.am + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/columns/columns.c b/columns/columns.c new file mode 100644 index 0000000..e1a4725 --- /dev/null +++ b/columns/columns.c @@ -0,0 +1,741 @@ + +/** + * @file columns.c + * @group columns + * @{ + */ +/* + * Columns Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * Columns is free software. + * This file is part of AutoGen. + * + * AutoGen Copyright (C) 1992-2017 by Bruce Korb - all rights reserved + * + * AutoGen 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. + * + * AutoGen is distributed in the hope that 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 . + */ +#ifndef NUL +# define NUL '\0' +#endif + +struct print_list { + char ** papz; + int index; +}; + +typedef struct print_list tPrintList, *tpPrintList; + +int maxEntryWidth = 0; +int fillColumnCt = 0; + +#define LINE_LIMIT 4096 +char zLine[ LINE_LIMIT ]; +char zFmtLine[ LINE_LIMIT ]; + +char ** papzLines = (char **)NULL; +char const * pzLinePfx = ""; +char const * pzFirstPfx = NULL; +size_t allocCt = 0; +size_t usedCt = 0; +size_t columnCt = 0; +size_t columnSz = 0; +size_t indentSize = 0; + +MOD_LOCAL inline void * +malloc_or_die(size_t sz); +MOD_LOCAL char const * +construct_first_pfx(char const * f_indent); +MOD_LOCAL uint32_t +pad_indentation(char const * pzIndentArg, char const ** pfx); +MOD_LOCAL void +readLines(void); +MOD_LOCAL void +writeColumns(void); +MOD_LOCAL void +trim_last_separation(void); +MOD_LOCAL void +writeRows(void); +MOD_LOCAL int +emitWord(char const * word, size_t len, int col); +MOD_LOCAL void +writeFill(void); +MOD_LOCAL int +compProc(const void * p1, const void * p2); + +int +main(int argc, char ** argv) +{ + (void)optionProcess( &columnsOptions, argc, argv ); + + if (HAVE_OPT( INDENT )) { + indentSize = pad_indentation( OPT_ARG(INDENT), &pzLinePfx); + OPT_VALUE_WIDTH -= (long)indentSize; + + pzFirstPfx = HAVE_OPT(FIRST_INDENT) + ? construct_first_pfx( OPT_ARG(FIRST_INDENT)) + : pzLinePfx; + } + + if (HAVE_OPT( LINE_SEPARATION )) + OPT_VALUE_WIDTH -= (long int)strlen( OPT_ARG( LINE_SEPARATION)); + + if (HAVE_OPT( COL_WIDTH )) + columnSz = (size_t)OPT_VALUE_COL_WIDTH; + + if (HAVE_OPT( COLUMNS )) + columnCt = (size_t)OPT_VALUE_COLUMNS; + + if (OPT_VALUE_WIDTH <= 16) + OPT_VALUE_WIDTH = 16; + + readLines(); + + if (HAVE_OPT( SORT )) + qsort(VOIDP(papzLines), usedCt, sizeof(char *), &compProc); + + if (HAVE_OPT( BY_COLUMNS )) + writeColumns(); + else if (HAVE_OPT(FILL)) + writeFill(); + else + writeRows(); + + return EXIT_SUCCESS; +} + +MOD_LOCAL inline void * +malloc_or_die(size_t sz) +{ + void * res = malloc(sz); + if (res == NULL) + die(COLUMNS_EXIT_FAILURE, "could not allocate %d bytes", sz); + + return res; +} + +MOD_LOCAL char const * +construct_first_pfx(char const * f_indent) +{ + static char const pad_fmt[] = "%%-%ds"; + // 24 > log10(0xFFFFFFFFFFFFFFFFULL) + char pfx_buf[24 + sizeof(pad_fmt)]; + size_t firstSize = pad_indentation(f_indent, &pzFirstPfx); + size_t len; + char * res; + + /* + * If this first line exceeds the indentation size, then we + * need to append a newline and any indentation. + */ + if (firstSize > indentSize) { + size_t sep_len = HAVE_OPT(LINE_SEPARATION) + ? strlen( OPT_ARG(LINE_SEPARATION)) : 0; + len = firstSize + sep_len + indentSize + 3; + sprintf(pfx_buf, pad_fmt, (int)firstSize); + } else { + len = indentSize + 3; + sprintf(pfx_buf, pad_fmt, (int)indentSize); + } + + res = malloc_or_die(len); + snprintf(res, len, pfx_buf, pzFirstPfx); + pzFirstPfx = res; + + if (firstSize > indentSize) { + char * p = res + firstSize; + + if (HAVE_OPT( LINE_SEPARATION )) { + len = strlen(OPT_ARG(LINE_SEPARATION)); + memcpy(p, OPT_ARG(LINE_SEPARATION), len); + p += len; + } + + sprintf(p, "\n%s", pzLinePfx); + } + + return res; +} + +MOD_LOCAL uint32_t +pad_indentation(char const * pzIndentArg, char const ** pfx) +{ + char * pz; + unsigned int cct; + + errno = 0; + cct = (unsigned int)strtoul(pzIndentArg, &pz, 0); + + /* + * IF the indent argument is a number + */ + if ((*pz == NUL) && (errno == 0) && (cct < OPT_VALUE_WIDTH)) { + char * p; + + /* + * Allocate a string to hold the line prefix + */ + *pfx = p = malloc_or_die( (size_t)cct + 1 ); + + /* + * Set it to a NUL terminated string of spaces + */ + if (cct > 0) + memset(p, ' ', (size_t)cct); + p[cct] = NUL; + + } else { + /* + * Otherwise, set the line prefix to whatever the string is. + * It will not be the empty string because that is handled + * as an indent count of zero and is ignored. + */ + char const * p = pzIndentArg; + *pfx = pzIndentArg; + cct = 0; + + for (;;) { + /* + * Compute the length of the last line of the prefix. + */ + switch (*p++) { + case NUL: + goto colsCounted; + + case '\t': + cct += (unsigned)OPT_VALUE_TAB_WIDTH; + cct -= (unsigned)(cct % OPT_VALUE_TAB_WIDTH); + break; + + case '\n': + case '\f': + case '\r': + cct = 0; + break; + + default: + cct++; + break; + + case '\a': + break; + } + } colsCounted:; + } + + return cct; +} + +MOD_LOCAL void +readLines(void) +{ + int sepLen = HAVE_OPT(SEPARATION) + ? (int)strlen(OPT_ARG(SEPARATION)) : 0; + + /* + * Read the input text, stripping trailing white space + */ + for (;;) { + char * pzL; + char * pzText = fgets(zLine, (int)sizeof(zLine), stdin); + size_t len; + + if (pzText == NULL) + break; + + /* + * Trim off trailing white space. + */ + len = strlen( pzText ); + pzText += len; + while (isspace(pzText[-1])) { + if (--pzText == zLine) { + if (HAVE_OPT(FILL)) + break; + goto next_line; + } + len--; + } + + *pzText = NUL; + + /* + * IF the input lines are to be reformatted, + * THEN the length is the result of the sprintf + * Else, compute the length. + */ + if (HAVE_OPT(FORMAT)) { + pzText = zFmtLine; + len = (size_t)snprintf( + zFmtLine, sizeof(zFmtLine), OPT_ARG(FORMAT), zLine); + } else { + pzText = zLine; + } + + /* + * Allocate a string and space in the pointer array. + */ + len += (size_t)sepLen + 1; + pzL = (char *)malloc_or_die( len ); + if (++usedCt > allocCt) { + allocCt += 128; + papzLines = (char **)realloc(VOIDP(papzLines), + sizeof(char *) * allocCt ); + } + papzLines[ usedCt-1 ] = pzL; + + /* + * Copy the text and append the separation character + */ + strcpy( pzL, pzText ); + + /* + * Initially, all strings have the separator, + * the entries may get reordered. + */ + if (sepLen > 0) + strcat(pzL, OPT_ARG(SEPARATION)); + + if ((int)len > maxEntryWidth) + maxEntryWidth = (int)len; + next_line:; + } + + if (maxEntryWidth == 0) { + fputs( "columns warning: no input text was read\n", stderr ); + exit( EXIT_SUCCESS ); + } + + /* + * Set the line width to the amount of space we have to play with. + */ + if ((OPT_VALUE_WIDTH < maxEntryWidth) && (! HAVE_OPT(FILL))) + OPT_VALUE_WIDTH = maxEntryWidth; + + /* + * If we do not have a column size set, + * then figure out what it must be. + */ + if (columnSz == 0) { + /* + * IF the column count has not been set, + * THEN compute it. + */ + if (columnCt == 0) + columnCt = (size_t)(OPT_VALUE_WIDTH / maxEntryWidth); + + /* + * IF there are to be multiple columns, ... + */ + if (columnCt > 1) { + size_t spreadwidth = (size_t)(OPT_VALUE_WIDTH - maxEntryWidth); + int sz = (int)(spreadwidth / (size_t)(columnCt-1)); + + /* + * Either there is room for added space, + * or we must (possibly) reduce the number of columns + */ + if (sz >= maxEntryWidth) + columnSz = (size_t)sz; + else { + columnCt = ((size_t)spreadwidth / (size_t)maxEntryWidth) + 1; + if (columnCt > 1) + columnSz = (size_t)spreadwidth / (size_t)(columnCt - 1); + else columnSz = (size_t)OPT_VALUE_WIDTH; + } + } + } + + /* + * Otherwise, the column size has been set. Ensure it is sane. + */ + else { + bool compute_val = (columnCt == 0); + + /* + * Increase the column size to the width of the widest entry + */ + if (maxEntryWidth > (int)columnSz) + columnSz = (size_t)maxEntryWidth; + + /* + * IF we have not been provided a column count + * *OR* we are set to overfill the output line, + * THEN compute the number of columns. + */ + if (! compute_val) { + long width = (long)maxEntryWidth + (long)(columnSz * (columnCt-1)); + compute_val = width > (unsigned)OPT_VALUE_WIDTH; + } + if (compute_val) + columnCt = (size_t)( + (((long)OPT_VALUE_WIDTH - (long)maxEntryWidth) / + (long)columnSz) + 1); + } + + /* + * Ensure that any "spread" we added to the column size + * does not exceed the parameterized limit. + */ + if ( HAVE_OPT( SPREAD ) + && ((maxEntryWidth + OPT_VALUE_SPREAD - 1) < (int)columnSz)) + columnSz = (size_t)(maxEntryWidth + OPT_VALUE_SPREAD - 1); +} + +MOD_LOCAL void +writeColumns(void) +{ + char zFmt[ 12 ]; + int colCt, rowCt, col, row; + tpPrintList pPL; + + colCt = (int)columnCt; + snprintf(zFmt, sizeof(zFmt), "%%-%ds", (int)columnSz); + + if (colCt == 1) { + writeRows(); + return; + } + + pPL = (tpPrintList)malloc_or_die((unsigned long)colCt * sizeof(tPrintList)); + + /* + * This "loop" is normally executed half way through and exited. + * IF, however, we would produce an empty final column, + * we will reduce our column count and line width and then + * try the top-of-column pointer computation again. + * + * The problem solved here is that sometimes, when the + * number of entries in a row is greater than the number of rows, + * it is possible that all the entries that would have been + * in the last column are, instead, essentially put on the + * last row. That will leave the final column empty. + * We could regroup at that point and spread the columns some more, + * but, if done, is an exercise for later. + */ + for (;;) { + int rem; + int fsz; + + rowCt = ((int)usedCt/colCt) + (((int)usedCt % colCt) ? 1 : 0); + + /* + * FOR each column, compute the address of the pointer to + * the string at the top of the column, and the index of + * that entry. + */ + for (col = 0; col < colCt ; col++) { + pPL[col].papz = papzLines + (col * rowCt); + pPL[col].index = col * rowCt; + } + + /* + * IF the final column is not empty, + * THEN break out and start printing. + */ + if (pPL[colCt-1].index < (int)usedCt) + break; + + /* + * The last column is blank, so we reduce our column count, + * even if the user specified a count!! + */ + colCt--; + rem = (int)OPT_VALUE_WIDTH - (int)(colCt * maxEntryWidth); + + if ((rem == 0) || (colCt < 2) || (columnSz > 0)) + fsz = maxEntryWidth; + else + fsz = maxEntryWidth + (rem / (colCt-1)); + snprintf( zFmt, sizeof(zFmt), "%%-%ds", fsz ); + } + + /* + * Now, actually print each row... + */ + for ( row = 0 ;; ) { + char * pzL; + char * pzE; + + if (pzLinePfx != NULL) + fputs( pzLinePfx, stdout ); + + /* + * Increment the index of the current entry in the last column. + * IF it goes beyond the end of the entries in use, + * THEN reduce our column count. + */ + if ((pPL[colCt-1].index)++ >= (int)usedCt) + colCt--; + + /* + * Get the address of the string in the last column. + */ + pzE = *(pPL[colCt-1].papz++); + + col = 0; + + /* + * FOR every column except the last, + * print the entry with the width format + * + * No need to worry about referring to a non-existent entry. Only + * the last column might have that problem, and we addressed it above + * where the column count got decremented. + */ + while (++col < colCt) { + pzL = *(pPL[col-1].papz++); + fprintf( stdout, zFmt, pzL ); + free( VOIDP(pzL) ); + } + + /* + * See if we are on the last row. If so, then this is the last entry. + * Strip any separation characters, emit the entry and break out. + */ + if (++row == rowCt) { + /* + * IF we have a separator, + * THEN remove it from the last entry. + */ + if (HAVE_OPT( SEPARATION )) { + char * pz = pzE + strlen( pzE ) + - strlen( OPT_ARG(SEPARATION)); + *pz = NUL; + } + + fputs(pzE, stdout); + if (HAVE_OPT(ENDING)) + fputs(OPT_ARG(ENDING), stdout); + + putc( '\n', stdout ); + break; + } + + /* + * Print the last entry on the line, without the width format. + * If we have line separation (which does not apply to the last + * line), then emit those characters, too. + */ + fputs( pzE, stdout ); + if (HAVE_OPT( LINE_SEPARATION )) + fputs( OPT_ARG( LINE_SEPARATION ), stdout ); + + putc( '\n', stdout ); + free( VOIDP(pzE) ); + } + + free(pPL); +} + +MOD_LOCAL void +trim_last_separation(void) +{ + char * pz = papzLines[ usedCt-1 ]; + pz += strlen(pz) - strlen( OPT_ARG(SEPARATION)); + *pz = NUL; +} + +MOD_LOCAL void +writeRows(void) +{ + char zFmt[32]; + int colCt; + + colCt = (int)columnCt; + snprintf(zFmt, sizeof(zFmt), "%%-%ds", (int)columnSz); + + if (HAVE_OPT( SEPARATION )) + trim_last_separation(); + + if (pzFirstPfx != NULL) { + fputs( pzFirstPfx, stdout ); + pzFirstPfx = pzLinePfx; + } + + { + char ** ppzLL = papzLines; + size_t left = usedCt; + int lnNo = 0; + + /* + * FOR every entry we are to emit, ... + */ + for (;;) { + char * pzL = *ppzLL++; + + /* + * IF this is the last entry, + * THEN emit it and a new line and break out + */ + if (--left <= 0) { + fputs(pzL, stdout); + if (HAVE_OPT(ENDING)) + fputs(OPT_ARG(ENDING), stdout); + + putc('\n', stdout); + free(VOIDP(pzL)); + break; + } + + /* + * IF the count of entries on this line is still less + * than the number of columns, + * THEN emit the padded entry + * ELSE ... + */ + if (++lnNo < colCt) + fprintf( stdout, zFmt, pzL ); + + else { + lnNo = 0; + /* + * Last entry on the line. Emit the string without padding. + * IF we have a line separation string, emit that too. + */ + fputs( pzL, stdout ); + if (HAVE_OPT( LINE_SEPARATION )) + fputs( OPT_ARG( LINE_SEPARATION ), stdout ); + + putc( '\n', stdout ); + + /* + * Start the next line with any required indentation + */ + if (pzFirstPfx != NULL) { + fputs( pzFirstPfx, stdout ); + pzFirstPfx = pzLinePfx; + } + } + + free( VOIDP(pzL) ); + } + } +} + +MOD_LOCAL int +emitWord(char const * word, size_t len, int col) +{ + static int ended_with_period = 0; + + if (col > 0) { + if ((int)len >= (OPT_VALUE_WIDTH - col)) { + putc('\n', stdout); + if (pzLinePfx != NULL) + fputs(pzLinePfx, stdout); + col = 0; + + } else { + if (ended_with_period) { + putc(' ', stdout); + col++; + } + putc(' ', stdout); + col++; + } + } + + fwrite(word, len, 1, stdout); + col += (int)len; + ended_with_period = (word[len - 1] == '.'); + + return col; +} + +/* + * writeFill -- fill the output. Pack together as much as will fit + * on each line. + */ +MOD_LOCAL void +writeFill(void) +{ + char ** ppzLL = papzLines; + size_t left = usedCt; + int colNo = 0; + + if (HAVE_OPT( SEPARATION )) + trim_last_separation(); + + if (pzFirstPfx != NULL) + fputs(pzFirstPfx, stdout); + + /* + * FOR every entry we are to emit, ... + */ + while (left-- > 0) { + char * pzL = *ppzLL; + + while (isspace(*pzL)) pzL++; + + /* + * Blank lines are magical and trigger a blank line in output. + */ + if (*pzL == NUL) { + if (! HAVE_OPT(SORT)) { + if (colNo > 0) /* guard against multiple blank lines */ + putc('\n', stdout); + putc('\n', stdout); + colNo = -2; + } + + free(*(ppzLL++)); + continue; + } + + /* + * We are going to emit some output. Make sure we're indented. + */ + if (colNo < 0) { + if (pzLinePfx != NULL) + fputs(pzLinePfx, stdout); + colNo = 0; + } + + do { + size_t tknlen; + + for (tknlen = 0; pzL[tknlen] != NUL; tknlen++) + if (isspace(pzL[tknlen])) + break; + colNo = emitWord(pzL, tknlen, colNo); + pzL += tknlen; + while (isspace(*pzL)) pzL++; + } while (*pzL != NUL); + + free(*(ppzLL++)); + } + + if (HAVE_OPT(ENDING) && (left == 0)) + fputs(OPT_ARG(ENDING), stdout); + + putc('\n', stdout); +} + + +/* + * Line comparison procedure + */ +MOD_LOCAL int +compProc(const void * p1, const void * p2) +{ + char const * pz1 = *(char * const *)p1; + char const * pz2 = *(char * const *)p2; + return strcmp(pz1, pz2); +} +/** @} + * + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of columns/columns.c */ diff --git a/columns/opts.c b/columns/opts.c new file mode 100644 index 0000000..1f81d8f --- /dev/null +++ b/columns/opts.c @@ -0,0 +1,1106 @@ +/* -*- buffer-read-only: t -*- vi: set ro: + * + * DO NOT EDIT THIS FILE (opts.c) + * + * It has been AutoGen-ed + * From the definitions opts.def + * and the template file options + * + * Generated from AutoOpts 42:1:17 templates. + * + * AutoOpts is a copyrighted work. This source file is not encumbered + * by AutoOpts licensing, but is provided under the licensing terms chosen + * by the columns author or copyright holder. AutoOpts is + * licensed under the terms of the LGPL. The redistributable library + * (``libopts'') is licensed under the terms of either the LGPL or, at the + * users discretion, the BSD license. See the AutoOpts and/or libopts sources + * for details. + * + * The columns program is copyrighted and licensed + * under the following terms: + * + * Copyright (C) 1999-2017 Bruce Korb, all rights reserved. + * This is free software. It is licensed for use, modification and + * redistribution under the terms of the GNU General Public License, + * version 3 or later + * + * columns 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. + * + * columns is distributed in the hope that 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 . + */ +/** \file opts.c + * \addtogroup columns + * @{ + */ + +#ifndef __doxygen__ +#define OPTION_CODE_COMPILE 1 +#include "opts.h" +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif +extern FILE * option_usage_fp; +#define zCopyright (columns_opt_strs+0) +#define zLicenseDescrip (columns_opt_strs+268) + +/* + * global included definitions + */ + +#include + +#define OPEN_ERROR_FMT (columns_opt_strs+871) + +#ifndef NULL +# define NULL 0 +#endif + +/** + * static const strings for columns options + */ +static char const columns_opt_strs[2139] = +/* 0 */ "columns (GNU AutoGen) 1.2\n" + "Copyright (C) 1999-2017 Bruce Korb, all rights reserved.\n" + "This is free software. It is licensed for use, modification and\n" + "redistribution under the terms of the GNU General Public License,\n" + "version 3 or later \n\0" +/* 268 */ "columns is free software: you can redistribute it and/or modify it under\n" + "the terms of the GNU General Public License as published by the Free\n" + "Software Foundation, either version 3 of the License, or (at your option)\n" + "any later version.\n\n" + "columns is distributed in the hope that it will be useful, but WITHOUT ANY\n" + "WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\n" + "FOR A PARTICULAR PURPOSE. See the GNU General Public License for more\n" + "details.\n\n" + "You should have received a copy of the GNU General Public License along\n" + "with this program. If not, see .\n\0" +/* 871 */ "Error %d (%s) opening %s\n\0" +/* 897 */ "Specify the output dimensions:\0" +/* 928 */ "Maximum Line Width\0" +/* 947 */ "WIDTH\0" +/* 953 */ "width\0" +/* 959 */ "Desired number of columns\0" +/* 985 */ "COLUMNS\0" +/* 993 */ "columns\0" +/* 1001 */ "Set width of each column\0" +/* 1026 */ "COL_WIDTH\0" +/* 1036 */ "col-width\0" +/* 1046 */ "tab width\0" +/* 1056 */ "TAB_WIDTH\0" +/* 1066 */ "tab-width\0" +/* 1076 */ "Specify how to lay out the text:\0" +/* 1109 */ "maximum spread added to column width\0" +/* 1146 */ "SPREAD\0" +/* 1153 */ "spread\0" +/* 1160 */ "Fill lines with input\0" +/* 1182 */ "FILL\0" +/* 1187 */ "fill\0" +/* 1192 */ "Line prefix or indentation\0" +/* 1219 */ "INDENT\0" +/* 1226 */ "indent\0" +/* 1233 */ "First line prefix\0" +/* 1251 */ "FIRST_INDENT\0" +/* 1264 */ "first-indent\0" +/* 1277 */ "Formatting string for each input\0" +/* 1310 */ "FORMAT\0" +/* 1317 */ "format\0" +/* 1324 */ "Separation string - follows all but last\0" +/* 1365 */ "SEPARATION\0" +/* 1376 */ "separation\0" +/* 1387 */ "string at end of all lines but last\0" +/* 1423 */ "LINE_SEPARATION\0" +/* 1439 */ "line-separation\0" +/* 1455 */ "string at end of last line\0" +/* 1482 */ "ENDING\0" +/* 1489 */ "ending\0" +/* 1496 */ "Specify the ordering of the entries:\0" +/* 1533 */ "Print entries in column order\0" +/* 1563 */ "BY_COLUMNS\0" +/* 1574 */ "by-columns\0" +/* 1585 */ "Sort input text\0" +/* 1601 */ "SORT\0" +/* 1606 */ "sort\0" +/* 1611 */ "Redirecting stdin to an alternate file:\0" +/* 1651 */ "Input file (if not stdin)\0" +/* 1677 */ "INPUT\0" +/* 1683 */ "input\0" +/* 1689 */ "display extended usage information and exit\0" +/* 1733 */ "help\0" +/* 1738 */ "extended usage information passed thru pager\0" +/* 1783 */ "more-help\0" +/* 1793 */ "output version information and exit\0" +/* 1829 */ "version\0" +/* 1837 */ "save the option state to a config file\0" +/* 1876 */ "save-opts\0" +/* 1886 */ "load options from a config file\0" +/* 1918 */ "LOAD_OPTS\0" +/* 1928 */ "no-load-opts\0" +/* 1941 */ "no\0" +/* 1944 */ "columns (GNU AutoGen) - Columnize Input Text - Ver. 1.2\n" + "Usage: %s [ - [] | --[{=| }] ]...\n\0" +/* 2058 */ ".\0" +/* 2060 */ "$HOME\0" +/* 2066 */ ".columnsrc\0" +/* 2077 */ "autogen-users@lists.sourceforge.net\0" +/* 2113 */ "columns (GNU AutoGen) 1.2"; + +/** + * dimensions option description: + */ +/** dimensions option separation text */ +#define DIMENSIONS_DESC (columns_opt_strs+897) +#define DIMENSIONS_FLAGS (OPTST_DOCUMENT | OPTST_NO_INIT) + +/** + * width option description: + */ +/** Descriptive text for the width option */ +#define WIDTH_DESC (columns_opt_strs+928) +/** Upper-cased name for the width option */ +#define WIDTH_NAME (columns_opt_strs+947) +/** Name string for the width option */ +#define WIDTH_name (columns_opt_strs+953) +/** The compiled in default value for the width option argument */ +#define WIDTH_DFT_ARG ((char const*)79) +/** Compiled in flag settings for the width option */ +#define WIDTH_FLAGS (OPTST_DISABLED \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_NUMERIC)) + +/** + * columns option description: + */ +/** Descriptive text for the columns option */ +#define COLUMNS_DESC (columns_opt_strs+959) +/** Upper-cased name for the columns option */ +#define COLUMNS_NAME (columns_opt_strs+985) +/** Name string for the columns option */ +#define COLUMNS_name (columns_opt_strs+993) +/** The compiled in default value for the columns option argument */ +#define COLUMNS_DFT_ARG ((char const*)0) +/** Compiled in flag settings for the columns option */ +#define COLUMNS_FLAGS (OPTST_DISABLED \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_NUMERIC)) + +/** + * col_width option description: + */ +/** Descriptive text for the col_width option */ +#define COL_WIDTH_DESC (columns_opt_strs+1001) +/** Upper-cased name for the col_width option */ +#define COL_WIDTH_NAME (columns_opt_strs+1026) +/** Name string for the col_width option */ +#define COL_WIDTH_name (columns_opt_strs+1036) +/** The compiled in default value for the col_width option argument */ +#define COL_WIDTH_DFT_ARG ((char const*)0) +/** Compiled in flag settings for the col_width option */ +#define COL_WIDTH_FLAGS (OPTST_DISABLED \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_NUMERIC)) + +/** + * tab_width option description: + */ +/** Descriptive text for the tab_width option */ +#define TAB_WIDTH_DESC (columns_opt_strs+1046) +/** Upper-cased name for the tab_width option */ +#define TAB_WIDTH_NAME (columns_opt_strs+1056) +/** Name string for the tab_width option */ +#define TAB_WIDTH_name (columns_opt_strs+1066) +/** The compiled in default value for the tab_width option argument */ +#define TAB_WIDTH_DFT_ARG ((char const*)8) +/** Compiled in flag settings for the tab_width option */ +#define TAB_WIDTH_FLAGS (OPTST_DISABLED \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_NUMERIC)) + +/** + * treatment option description: + */ +/** treatment option separation text */ +#define TREATMENT_DESC (columns_opt_strs+1076) +#define TREATMENT_FLAGS (OPTST_DOCUMENT | OPTST_NO_INIT) + +/** + * spread option description: + */ +/** Descriptive text for the spread option */ +#define SPREAD_DESC (columns_opt_strs+1109) +/** Upper-cased name for the spread option */ +#define SPREAD_NAME (columns_opt_strs+1146) +/** Name string for the spread option */ +#define SPREAD_name (columns_opt_strs+1153) +/** The compiled in default value for the spread option argument */ +#define SPREAD_DFT_ARG ((char const*)0) +/** Compiled in flag settings for the spread option */ +#define SPREAD_FLAGS (OPTST_DISABLED \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_NUMERIC)) + +/** + * fill option description with + * "Must also have options" and "Incompatible options": + */ +/** Descriptive text for the fill option */ +#define FILL_DESC (columns_opt_strs+1160) +/** Upper-cased name for the fill option */ +#define FILL_NAME (columns_opt_strs+1182) +/** Name string for the fill option */ +#define FILL_name (columns_opt_strs+1187) +/** Other options that appear in conjunction with the fill option */ +static int const aFillCantList[] = { + INDEX_OPT_SPREAD, + INDEX_OPT_COL_WIDTH, + INDEX_OPT_BY_COLUMNS, NO_EQUIVALENT }; +/** Compiled in flag settings for the fill option */ +#define FILL_FLAGS (OPTST_DISABLED) + +/** + * indent option description: + */ +/** Descriptive text for the indent option */ +#define INDENT_DESC (columns_opt_strs+1192) +/** Upper-cased name for the indent option */ +#define INDENT_NAME (columns_opt_strs+1219) +/** Name string for the indent option */ +#define INDENT_name (columns_opt_strs+1226) +/** Compiled in flag settings for the indent option */ +#define INDENT_FLAGS (OPTST_DISABLED \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING)) + +/** + * first_indent option description with + * "Must also have options" and "Incompatible options": + */ +/** Descriptive text for the first_indent option */ +#define FIRST_INDENT_DESC (columns_opt_strs+1233) +/** Upper-cased name for the first_indent option */ +#define FIRST_INDENT_NAME (columns_opt_strs+1251) +/** Name string for the first_indent option */ +#define FIRST_INDENT_name (columns_opt_strs+1264) +/** Other options that are required by the first_indent option */ +static int const aFirst_IndentMustList[] = { + INDEX_OPT_INDENT, NO_EQUIVALENT }; +/** Compiled in flag settings for the first_indent option */ +#define FIRST_INDENT_FLAGS (OPTST_DISABLED \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING)) + +/** + * format option description: + */ +/** Descriptive text for the format option */ +#define FORMAT_DESC (columns_opt_strs+1277) +/** Upper-cased name for the format option */ +#define FORMAT_NAME (columns_opt_strs+1310) +/** Name string for the format option */ +#define FORMAT_name (columns_opt_strs+1317) +/** Compiled in flag settings for the format option */ +#define FORMAT_FLAGS (OPTST_DISABLED \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING)) + +/** + * separation option description: + */ +/** Descriptive text for the separation option */ +#define SEPARATION_DESC (columns_opt_strs+1324) +/** Upper-cased name for the separation option */ +#define SEPARATION_NAME (columns_opt_strs+1365) +/** Name string for the separation option */ +#define SEPARATION_name (columns_opt_strs+1376) +/** Compiled in flag settings for the separation option */ +#define SEPARATION_FLAGS (OPTST_DISABLED \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING)) + +/** + * line_separation option description: + */ +/** Descriptive text for the line_separation option */ +#define LINE_SEPARATION_DESC (columns_opt_strs+1387) +/** Upper-cased name for the line_separation option */ +#define LINE_SEPARATION_NAME (columns_opt_strs+1423) +/** Name string for the line_separation option */ +#define LINE_SEPARATION_name (columns_opt_strs+1439) +/** Compiled in flag settings for the line_separation option */ +#define LINE_SEPARATION_FLAGS (OPTST_DISABLED \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING)) + +/** + * ending option description: + */ +/** Descriptive text for the ending option */ +#define ENDING_DESC (columns_opt_strs+1455) +/** Upper-cased name for the ending option */ +#define ENDING_NAME (columns_opt_strs+1482) +/** Name string for the ending option */ +#define ENDING_name (columns_opt_strs+1489) +/** Compiled in flag settings for the ending option */ +#define ENDING_FLAGS (OPTST_DISABLED \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING)) + +/** + * ordering option description: + */ +/** ordering option separation text */ +#define ORDERING_DESC (columns_opt_strs+1496) +#define ORDERING_FLAGS (OPTST_DOCUMENT | OPTST_NO_INIT) + +/** + * by_columns option description: + */ +/** Descriptive text for the by_columns option */ +#define BY_COLUMNS_DESC (columns_opt_strs+1533) +/** Upper-cased name for the by_columns option */ +#define BY_COLUMNS_NAME (columns_opt_strs+1563) +/** Name string for the by_columns option */ +#define BY_COLUMNS_name (columns_opt_strs+1574) +/** Compiled in flag settings for the by_columns option */ +#define BY_COLUMNS_FLAGS (OPTST_DISABLED) + +/** + * sort option description: + */ +/** Descriptive text for the sort option */ +#define SORT_DESC (columns_opt_strs+1585) +/** Upper-cased name for the sort option */ +#define SORT_NAME (columns_opt_strs+1601) +/** Name string for the sort option */ +#define SORT_name (columns_opt_strs+1606) +/** Compiled in flag settings for the sort option */ +#define SORT_FLAGS (OPTST_DISABLED \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING) | OPTST_ARG_OPTIONAL) + +/** + * input-text option description: + */ +/** input-text option separation text */ +#define INPUT_TEXT_DESC (columns_opt_strs+1611) +#define INPUT_TEXT_FLAGS (OPTST_DOCUMENT | OPTST_NO_INIT) + +/** + * input option description: + */ +/** Descriptive text for the input option */ +#define INPUT_DESC (columns_opt_strs+1651) +/** Upper-cased name for the input option */ +#define INPUT_NAME (columns_opt_strs+1677) +/** Name string for the input option */ +#define INPUT_name (columns_opt_strs+1683) +/** Compiled in flag settings for the input option */ +#define INPUT_FLAGS (OPTST_DISABLED \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING)) + +/* + * Help/More_Help/Version option descriptions: + */ +#define HELP_DESC (columns_opt_strs+1689) +#define HELP_name (columns_opt_strs+1733) +#ifdef HAVE_WORKING_FORK +#define MORE_HELP_DESC (columns_opt_strs+1738) +#define MORE_HELP_name (columns_opt_strs+1783) +#define MORE_HELP_FLAGS (OPTST_IMM | OPTST_NO_INIT) +#else +#define MORE_HELP_DESC HELP_DESC +#define MORE_HELP_name HELP_name +#define MORE_HELP_FLAGS (OPTST_OMITTED | OPTST_NO_INIT) +#endif +#ifdef NO_OPTIONAL_OPT_ARGS +# define VER_FLAGS (OPTST_IMM | OPTST_NO_INIT) +#else +# define VER_FLAGS (OPTST_SET_ARGTYPE(OPARG_TYPE_STRING) | \ + OPTST_ARG_OPTIONAL | OPTST_IMM | OPTST_NO_INIT) +#endif +#define VER_DESC (columns_opt_strs+1793) +#define VER_name (columns_opt_strs+1829) +#define SAVE_OPTS_DESC (columns_opt_strs+1837) +#define SAVE_OPTS_name (columns_opt_strs+1876) +#define LOAD_OPTS_DESC (columns_opt_strs+1886) +#define LOAD_OPTS_NAME (columns_opt_strs+1918) +#define NO_LOAD_OPTS_name (columns_opt_strs+1928) +#define LOAD_OPTS_pfx (columns_opt_strs+1941) +#define LOAD_OPTS_name (NO_LOAD_OPTS_name + 3) +/** + * Declare option callback procedures + */ +extern tOptProc + optionBooleanVal, optionNestedVal, optionNumericVal, + optionPagedUsage, optionPrintVersion, optionResetOpt, + optionStackArg, optionTimeDate, optionTimeVal, + optionUnstackArg, optionVendorOption; +static tOptProc + doOptCol_Width, doOptColumns, doOptInput, doOptSpread, + doOptWidth, doUsageOpt; +#define VER_PROC optionPrintVersion + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/** + * Define the columns Option Descriptions. + * This is an array of OPTION_CT entries, one for each + * option that the columns program responds to. + */ +static tOptDesc optDesc[OPTION_CT] = { + { /* entry idx, value */ 0, 0, + /* equiv idx, value */ 0, 0, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 0, 0, + /* opt state flags */ DIMENSIONS_FLAGS, 0, + /* last opt argumnt */ { NULL }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ NULL, + /* desc, NAME, name */ DIMENSIONS_DESC, NULL, NULL, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 1, VALUE_OPT_WIDTH, + /* equiv idx, value */ 1, VALUE_OPT_WIDTH, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ WIDTH_FLAGS, 0, + /* last opt argumnt */ { WIDTH_DFT_ARG }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ doOptWidth, + /* desc, NAME, name */ WIDTH_DESC, WIDTH_NAME, WIDTH_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 2, VALUE_OPT_COLUMNS, + /* equiv idx, value */ 2, VALUE_OPT_COLUMNS, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ COLUMNS_FLAGS, 0, + /* last opt argumnt */ { COLUMNS_DFT_ARG }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ doOptColumns, + /* desc, NAME, name */ COLUMNS_DESC, COLUMNS_NAME, COLUMNS_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 3, VALUE_OPT_COL_WIDTH, + /* equiv idx, value */ 3, VALUE_OPT_COL_WIDTH, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ COL_WIDTH_FLAGS, 0, + /* last opt argumnt */ { COL_WIDTH_DFT_ARG }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ doOptCol_Width, + /* desc, NAME, name */ COL_WIDTH_DESC, COL_WIDTH_NAME, COL_WIDTH_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 4, VALUE_OPT_TAB_WIDTH, + /* equiv idx, value */ 4, VALUE_OPT_TAB_WIDTH, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ TAB_WIDTH_FLAGS, 0, + /* last opt argumnt */ { TAB_WIDTH_DFT_ARG }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ optionNumericVal, + /* desc, NAME, name */ TAB_WIDTH_DESC, TAB_WIDTH_NAME, TAB_WIDTH_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 0, 0, + /* equiv idx, value */ 0, 0, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 0, 0, + /* opt state flags */ TREATMENT_FLAGS, 0, + /* last opt argumnt */ { NULL }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ NULL, + /* desc, NAME, name */ TREATMENT_DESC, NULL, NULL, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 6, VALUE_OPT_SPREAD, + /* equiv idx, value */ 6, VALUE_OPT_SPREAD, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ SPREAD_FLAGS, 0, + /* last opt argumnt */ { SPREAD_DFT_ARG }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ doOptSpread, + /* desc, NAME, name */ SPREAD_DESC, SPREAD_NAME, SPREAD_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 7, VALUE_OPT_FILL, + /* equiv idx, value */ 7, VALUE_OPT_FILL, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ FILL_FLAGS, 0, + /* last opt argumnt */ { NULL }, /* --fill */ + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, aFillCantList, + /* option proc */ NULL, + /* desc, NAME, name */ FILL_DESC, FILL_NAME, FILL_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 8, VALUE_OPT_INDENT, + /* equiv idx, value */ 8, VALUE_OPT_INDENT, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ INDENT_FLAGS, 0, + /* last opt argumnt */ { NULL }, /* --indent */ + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ NULL, + /* desc, NAME, name */ INDENT_DESC, INDENT_NAME, INDENT_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 9, VALUE_OPT_FIRST_INDENT, + /* equiv idx, value */ 9, VALUE_OPT_FIRST_INDENT, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ FIRST_INDENT_FLAGS, 0, + /* last opt argumnt */ { NULL }, /* --first_indent */ + /* arg list/cookie */ NULL, + /* must/cannot opts */ aFirst_IndentMustList, NULL, + /* option proc */ NULL, + /* desc, NAME, name */ FIRST_INDENT_DESC, FIRST_INDENT_NAME, FIRST_INDENT_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 10, VALUE_OPT_FORMAT, + /* equiv idx, value */ 10, VALUE_OPT_FORMAT, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ FORMAT_FLAGS, 0, + /* last opt argumnt */ { NULL }, /* --format */ + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ NULL, + /* desc, NAME, name */ FORMAT_DESC, FORMAT_NAME, FORMAT_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 11, VALUE_OPT_SEPARATION, + /* equiv idx, value */ 11, VALUE_OPT_SEPARATION, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ SEPARATION_FLAGS, 0, + /* last opt argumnt */ { NULL }, /* --separation */ + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ NULL, + /* desc, NAME, name */ SEPARATION_DESC, SEPARATION_NAME, SEPARATION_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 12, VALUE_OPT_LINE_SEPARATION, + /* equiv idx, value */ 12, VALUE_OPT_LINE_SEPARATION, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ LINE_SEPARATION_FLAGS, 0, + /* last opt argumnt */ { NULL }, /* --line_separation */ + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ NULL, + /* desc, NAME, name */ LINE_SEPARATION_DESC, LINE_SEPARATION_NAME, LINE_SEPARATION_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 13, VALUE_OPT_ENDING, + /* equiv idx, value */ 13, VALUE_OPT_ENDING, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ ENDING_FLAGS, 0, + /* last opt argumnt */ { NULL }, /* --ending */ + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ NULL, + /* desc, NAME, name */ ENDING_DESC, ENDING_NAME, ENDING_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 0, 0, + /* equiv idx, value */ 0, 0, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 0, 0, + /* opt state flags */ ORDERING_FLAGS, 0, + /* last opt argumnt */ { NULL }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ NULL, + /* desc, NAME, name */ ORDERING_DESC, NULL, NULL, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 15, VALUE_OPT_BY_COLUMNS, + /* equiv idx, value */ 15, VALUE_OPT_BY_COLUMNS, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ BY_COLUMNS_FLAGS, 0, + /* last opt argumnt */ { NULL }, /* --by_columns */ + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ NULL, + /* desc, NAME, name */ BY_COLUMNS_DESC, BY_COLUMNS_NAME, BY_COLUMNS_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 16, VALUE_OPT_SORT, + /* equiv idx, value */ 16, VALUE_OPT_SORT, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ SORT_FLAGS, 0, + /* last opt argumnt */ { NULL }, /* --sort */ + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ NULL, + /* desc, NAME, name */ SORT_DESC, SORT_NAME, SORT_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 0, 0, + /* equiv idx, value */ 0, 0, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 0, 0, + /* opt state flags */ INPUT_TEXT_FLAGS, 0, + /* last opt argumnt */ { NULL }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ NULL, + /* desc, NAME, name */ INPUT_TEXT_DESC, NULL, NULL, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 18, VALUE_OPT_INPUT, + /* equiv idx, value */ 18, VALUE_OPT_INPUT, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ INPUT_FLAGS, 0, + /* last opt argumnt */ { NULL }, /* --input */ + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ doOptInput, + /* desc, NAME, name */ INPUT_DESC, INPUT_NAME, INPUT_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ INDEX_OPT_VERSION, VALUE_OPT_VERSION, + /* equiv idx value */ NO_EQUIVALENT, VALUE_OPT_VERSION, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ VER_FLAGS, AOUSE_VERSION, + /* last opt argumnt */ { NULL }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ VER_PROC, + /* desc, NAME, name */ VER_DESC, NULL, VER_name, + /* disablement strs */ NULL, NULL }, + + + + { /* entry idx, value */ INDEX_OPT_HELP, VALUE_OPT_HELP, + /* equiv idx value */ NO_EQUIVALENT, VALUE_OPT_HELP, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ OPTST_IMM | OPTST_NO_INIT, AOUSE_HELP, + /* last opt argumnt */ { NULL }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ doUsageOpt, + /* desc, NAME, name */ HELP_DESC, NULL, HELP_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ INDEX_OPT_MORE_HELP, VALUE_OPT_MORE_HELP, + /* equiv idx value */ NO_EQUIVALENT, VALUE_OPT_MORE_HELP, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ MORE_HELP_FLAGS, AOUSE_MORE_HELP, + /* last opt argumnt */ { NULL }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ optionPagedUsage, + /* desc, NAME, name */ MORE_HELP_DESC, NULL, MORE_HELP_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ INDEX_OPT_SAVE_OPTS, VALUE_OPT_SAVE_OPTS, + /* equiv idx value */ NO_EQUIVALENT, VALUE_OPT_SAVE_OPTS, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ OPTST_SET_ARGTYPE(OPARG_TYPE_STRING) + | OPTST_ARG_OPTIONAL | OPTST_NO_INIT, AOUSE_SAVE_OPTS, + /* last opt argumnt */ { NULL }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ NULL, + /* desc, NAME, name */ SAVE_OPTS_DESC, NULL, SAVE_OPTS_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ INDEX_OPT_LOAD_OPTS, VALUE_OPT_LOAD_OPTS, + /* equiv idx value */ NO_EQUIVALENT, VALUE_OPT_LOAD_OPTS, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, NOLIMIT, 0, + /* opt state flags */ OPTST_SET_ARGTYPE(OPARG_TYPE_STRING) + | OPTST_DISABLE_IMM, AOUSE_LOAD_OPTS, + /* last opt argumnt */ { NULL }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ optionLoadOpt, + /* desc, NAME, name */ LOAD_OPTS_DESC, LOAD_OPTS_NAME, LOAD_OPTS_name, + /* disablement strs */ NO_LOAD_OPTS_name, LOAD_OPTS_pfx } +}; + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/** Reference to the upper cased version of columns. */ +#define zPROGNAME (columns_opt_strs+985) +/** Reference to the title line for columns usage. */ +#define zUsageTitle (columns_opt_strs+1944) +/** columns configuration file name. */ +#define zRcName (columns_opt_strs+2066) +/** Directories to search for columns config files. */ +static char const * const apzHomeList[3] = { + columns_opt_strs+2058, + columns_opt_strs+2060, + NULL }; +/** The columns program bug email address. */ +#define zBugsAddr (columns_opt_strs+2077) +/** Clarification/explanation of what columns does. */ +#define zExplain (NULL) +/** Extra detail explaining what columns does. */ +#define zDetail (NULL) +/** The full version string for columns. */ +#define zFullVersion (columns_opt_strs+2113) +/* extracted from optcode.tlib near line 342 */ + +#define OPTPROC_BASE OPTPROC_NONE +#define translate_option_strings NULL + +#define columns_full_usage (NULL) +#define columns_short_usage (NULL) + +#endif /* not defined __doxygen__ */ + +/* + * Create the static procedure(s) declared above. + */ +/** + * The callout function that invokes the optionUsage function. + * + * @param[in] opts the AutoOpts option description structure + * @param[in] od the descriptor for the "help" (usage) option. + * @noreturn + */ +static void +doUsageOpt(tOptions * opts, tOptDesc * od) +{ + int ex_code; + ex_code = COLUMNS_EXIT_SUCCESS; + optionUsage(&columnsOptions, ex_code); + /* NOTREACHED */ + exit(COLUMNS_EXIT_FAILURE); + (void)opts; + (void)od; +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/** + * Code to handle the width option. + * This option specifies the full width of the output line, + * including any start-of-line indentation. The output will fill + * each line as completely as possible, unless the column width has + * been explicitly specified. If the maximum width is less than + * the length of the widest input, you will get a single column + * of output. + * @param[in] pOptions the columns options data structure + * @param[in,out] pOptDesc the option descriptor for this option. + */ +static void +doOptWidth(tOptions* pOptions, tOptDesc* pOptDesc) +{ + static struct {long rmin, rmax;} const rng[1] = { + { 16, 4095 } }; + int ix; + + if (pOptions <= OPTPROC_EMIT_LIMIT) + goto emit_ranges; + optionNumericVal(pOptions, pOptDesc); + + for (ix = 0; ix < 1; ix++) { + if (pOptDesc->optArg.argInt < rng[ix].rmin) + continue; /* ranges need not be ordered. */ + if (pOptDesc->optArg.argInt == rng[ix].rmin) + return; + if (rng[ix].rmax == LONG_MIN) + continue; + if (pOptDesc->optArg.argInt <= rng[ix].rmax) + return; + } + + option_usage_fp = stderr; + + emit_ranges: +optionShowRange(pOptions, pOptDesc, VOIDP(rng), 1); +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/** + * Code to handle the columns option. + * Use this option to specify exactly how many columns to produce. + * If that many columns will not fit within @var{line_width}, then + * the count will be reduced to the number that fit. + * @param[in] pOptions the columns options data structure + * @param[in,out] pOptDesc the option descriptor for this option. + */ +static void +doOptColumns(tOptions* pOptions, tOptDesc* pOptDesc) +{ + static struct {long rmin, rmax;} const rng[1] = { + { 1, 2048 } }; + int ix; + + if (pOptions <= OPTPROC_EMIT_LIMIT) + goto emit_ranges; + optionNumericVal(pOptions, pOptDesc); + + for (ix = 0; ix < 1; ix++) { + if (pOptDesc->optArg.argInt < rng[ix].rmin) + continue; /* ranges need not be ordered. */ + if (pOptDesc->optArg.argInt == rng[ix].rmin) + return; + if (rng[ix].rmax == LONG_MIN) + continue; + if (pOptDesc->optArg.argInt <= rng[ix].rmax) + return; + } + + option_usage_fp = stderr; + + emit_ranges: +optionShowRange(pOptions, pOptDesc, VOIDP(rng), 1); +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/** + * Code to handle the col_width option. + * Use this option to specify exactly how many characters are to be + * allocated for each column. If it is narrower than the widest entry, + * it will be over-ridden with the required width. + * @param[in] pOptions the columns options data structure + * @param[in,out] pOptDesc the option descriptor for this option. + */ +static void +doOptCol_Width(tOptions* pOptions, tOptDesc* pOptDesc) +{ + static struct {long rmin, rmax;} const rng[1] = { + { 1, 2048 } }; + int ix; + + if (pOptions <= OPTPROC_EMIT_LIMIT) + goto emit_ranges; + optionNumericVal(pOptions, pOptDesc); + + for (ix = 0; ix < 1; ix++) { + if (pOptDesc->optArg.argInt < rng[ix].rmin) + continue; /* ranges need not be ordered. */ + if (pOptDesc->optArg.argInt == rng[ix].rmin) + return; + if (rng[ix].rmax == LONG_MIN) + continue; + if (pOptDesc->optArg.argInt <= rng[ix].rmax) + return; + } + + option_usage_fp = stderr; + + emit_ranges: +optionShowRange(pOptions, pOptDesc, VOIDP(rng), 1); +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/** + * Code to handle the spread option. + * Use this option to specify exactly how many characters may be + * added to each column. It allows you to prevent columns from + * becoming too far apart. Without this option, @file{columns} + * will attempt to widen columns to fill the full width. + * @param[in] pOptions the columns options data structure + * @param[in,out] pOptDesc the option descriptor for this option. + */ +static void +doOptSpread(tOptions* pOptions, tOptDesc* pOptDesc) +{ + static struct {long rmin, rmax;} const rng[1] = { + { 1, 1024 } }; + int ix; + + if (pOptions <= OPTPROC_EMIT_LIMIT) + goto emit_ranges; + optionNumericVal(pOptions, pOptDesc); + + for (ix = 0; ix < 1; ix++) { + if (pOptDesc->optArg.argInt < rng[ix].rmin) + continue; /* ranges need not be ordered. */ + if (pOptDesc->optArg.argInt == rng[ix].rmin) + return; + if (rng[ix].rmax == LONG_MIN) + continue; + if (pOptDesc->optArg.argInt <= rng[ix].rmax) + return; + } + + option_usage_fp = stderr; + + emit_ranges: +optionShowRange(pOptions, pOptDesc, VOIDP(rng), 1); +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/** + * Code to handle the input option. + * This program normally runs as a @code{filter}, reading from standard + * input, columnizing and writing to standard out. This option redirects + * input to a file. + * @param[in] pOptions the columns options data structure + * @param[in,out] pOptDesc the option descriptor for this option. + */ +static void +doOptInput(tOptions* pOptions, tOptDesc* pOptDesc) +{ + /* + * Be sure the flag-code[0] handles special values for the options pointer + * viz. (poptions <= OPTPROC_EMIT_LIMIT) *and also* the special flag bit + * ((poptdesc->fOptState & OPTST_RESET) != 0) telling the option to + * reset its state. + */ + /* extracted from opts.def, line 305 */ + FILE * fp = freopen( + pOptDesc->optArg.argString, "r" FOPEN_BINARY_FLAG, stdin); + + if (fp == (FILE *)NULL) { + fprintf(stderr, OPEN_ERROR_FMT, errno, strerror(errno), + pOptDesc->optArg.argString); + USAGE(EXIT_FAILURE); + } + (void)pOptions; +} +/* extracted from optmain.tlib near line 1250 */ + +/** + * Print a fatal error message and die, \a va_list style. + * + * @param[in] exit_code the value to call exit(3) with + * @param[in] fmt the death rattle message + * @param[in] ap the argument list for the message + * @noreturn + */ +noreturn extern void +vdie(int exit_code, char const * fmt, va_list ap) +{ + char const * die_leader = _("columns fatal error:\n"); + fputs(die_leader, stderr); + vfprintf(stderr, fmt, ap); + fflush(stderr); + exit(exit_code); +} + +/** + * Print a fatal error message and die, var-arg style. + * + * @param[in] exit_code the value to call exit(3) with + * @param[in] fmt the death rattle message + * @param[in] ... the list of arguments for the message + * @noreturn + */ +noreturn extern void +die(int exit_code, char const * fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + vdie(exit_code, fmt, ap); +} + +/** + * Print a file system error fatal error message and die. + * + * @param[in] exit_code the value to call exit(3) with. + * @param[in] op the operation that failed. + * @param[in] fname the file name the operation was on. + * @noreturn + */ +noreturn extern void +fserr(int exit_code, char const * op, char const * fname) +{ + char const * fserr_fmt = _("fserr %d (%s) performing '%s' on %s\n"); + die(exit_code, fserr_fmt, errno, strerror(errno), op, fname); +} + +/** + * The directory containing the data associated with columns. + */ +#ifndef PKGDATADIR +# define PKGDATADIR "" +#endif + +/** + * Information about the person or institution that packaged columns + * for the current distribution. + */ +#ifndef WITH_PACKAGER +# define columns_packager_info NULL +#else +/** Packager information for columns. */ +static char const columns_packager_info[] = + "Packaged by " WITH_PACKAGER + +# ifdef WITH_PACKAGER_VERSION + " ("WITH_PACKAGER_VERSION")" +# endif + +# ifdef WITH_PACKAGER_BUG_REPORTS + "\nReport columns bugs to " WITH_PACKAGER_BUG_REPORTS +# endif + "\n"; +#endif +#ifndef __doxygen__ + +#endif /* __doxygen__ */ +/** + * The option definitions for columns. The one structure that + * binds them all. + */ +tOptions columnsOptions = { + OPTIONS_STRUCT_VERSION, + 0, NULL, /* original argc + argv */ + ( OPTPROC_BASE + + OPTPROC_ERRSTOP + + OPTPROC_SHORTOPT + + OPTPROC_LONGOPT + + OPTPROC_NO_REQ_OPT + + OPTPROC_ENVIRON + + OPTPROC_NO_ARGS ), + 0, NULL, /* current option index, current option */ + NULL, NULL, zPROGNAME, + zRcName, zCopyright, zLicenseDescrip, + zFullVersion, apzHomeList, zUsageTitle, + zExplain, zDetail, optDesc, + zBugsAddr, /* address to send bugs to */ + NULL, NULL, /* extensions/saved state */ + optionUsage, /* usage procedure */ + translate_option_strings, /* translation procedure */ + /* + * Indexes to special options + */ + { INDEX_OPT_MORE_HELP, /* more-help option index */ + INDEX_OPT_SAVE_OPTS, /* save option index */ + NO_EQUIVALENT, /* '-#' option index */ + NO_EQUIVALENT /* index of default opt */ + }, + 24 /* full option count */, 19 /* user option count */, + columns_full_usage, columns_short_usage, + NULL, NULL, + PKGDATADIR, columns_packager_info +}; + +#ifdef __cplusplus +} +#endif +/** @} */ +/* opts.c ends here */ diff --git a/columns/opts.def b/columns/opts.def new file mode 100644 index 0000000..dbe975f --- /dev/null +++ b/columns/opts.def @@ -0,0 +1,362 @@ +/* -*- Mode: conf -*- */ + +autogen definitions options; +addtogroup = columns; + +/* opts.def: option definitons for columns + * + * AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoGen 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. + * + * AutoGen is distributed in the hope that 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 . + */ + +copyright = { + date = "1999-2017"; + type = gpl; + owner = "Bruce Korb"; + eaddr = 'autogen-users@lists.sourceforge.net'; +}; + +prog-name = "columns"; +prog-title = "Columnize Input Text"; +package = 'GNU AutoGen'; +homerc = '.', '$HOME'; +environrc; +long-opts; +no-xlate = anything; +omit-nls-code; +die-code; + +version = "1.2"; + +export = <<- EOExport + #include "config.h" + #include + #include + #include + #include + #include + #include + EOExport; + +include = "[= AutoGen5 Template =]"; +include = "#include "; + +flag = { + name = dimensions; + documentation; + + descrip = 'Specify the output dimensions'; +}; + +flag = { + name = width; + value = W; + arg-type = number; + arg-default = 79; + arg-name = num; + arg-range = '16->4095'; + descrip = "Maximum Line Width"; + doc = <<- _EODoc_ + This option specifies the full width of the output line, + including any start-of-line indentation. The output will fill + each line as completely as possible, unless the column width has + been explicitly specified. If the maximum width is less than + the length of the widest input, you will get a single column + of output. + _EODoc_; +}; + +flag = { + name = columns; + value = c; + arg-type = number; + arg-default = 0; + arg-name = count; + arg-range = '1->2048'; + descrip = "Desired number of columns"; + doc = <<- _EODoc_ + Use this option to specify exactly how many columns to produce. + If that many columns will not fit within @var{line_width}, then + the count will be reduced to the number that fit. + _EODoc_; +}; + +flag = { + name = col_width; + value = w; + arg-type = number; + arg-default = 0; + arg-name = num; + arg-range = '1->2048'; + descrip = "Set width of each column"; + doc = <<- _EODoc_ + Use this option to specify exactly how many characters are to be + allocated for each column. If it is narrower than the widest entry, + it will be over-ridden with the required width. + _EODoc_; +}; + +flag = { + name = tab_width; + arg-type = number; + arg-default = 8; + arg-name = num; + descrip = "tab width"; + doc = <<- _EODoc_ + If an indentation string contains tabs, then this value is used to + compute the ending column of the prefix string. + _EODoc_; +}; + +#ifdef LATER +flag = { + name = page_len; + arg-type = number; + arg-name = num; + descrip = "Page Length"; + doc = <<- _EODoc_ + This many lines will be printed before a form feed is emitted. + The 'by_columns' ordering will wrap columns within a page. + _EODoc_; +}; +#endif + +flag = { + name = treatment; + documentation; + descrip = 'Specify how to lay out the text'; +}; + +flag = { + name = spread; + arg-type = number; + arg-default = 0; + arg-name = num; + arg-range = '1->1024'; + descrip = "maximum spread added to column width"; + doc = <<- _EODoc_ + Use this option to specify exactly how many characters may be + added to each column. It allows you to prevent columns from + becoming too far apart. Without this option, @file{columns} + will attempt to widen columns to fill the full width. + _EODoc_; +}; + +flag = { + name = fill; + descrip = "Fill lines with input"; + flags-cant = spread, col_width, by_columns; + doc = <<- _EODoc_ + Instead of columnizing the input text, fill the output lines + with the input lines. Blank lines on input will cause a + blank line in the output, unless the output is sorted. + With sorted output, blank lines are ignored. + _EODoc_; +}; + +flag = { + name = indent; + value = I; + arg-type = string; + arg-name = l-pfx; + descrip = "Line prefix or indentation"; + doc = <<- _EODoc_ + If a number, then this many spaces will be inserted at the start of + every line. Otherwise, it is a line prefix that will be inserted + at the start of every line. + _EODoc_; +}; + +flag = { + name = first_indent; + arg-type = string; + flags_must = indent; + arg-name = l-pfx; + descrip = "First line prefix"; + doc = <<- _EODoc_ + If a number, then this many spaces will be inserted at the start of + the first line. Otherwise, it is a line prefix that will be inserted + at the start of that line. If its length exceeds "indent", then it + will be emitted on a line by itself, suffixed by any line separation + string. For example: + + @example + $ columns --first='#define TABLE' -c 2 -I4 --line=' \' <<_EOF_ + one + two + three + four + _EOF_ + #define TABLE \ + one two \ + three four + @end example + _EODoc_; // ' +}; + +flag = { + name = format; + value = f; + arg-type = string; + arg-name = fmt-str; + descrip = "Formatting string for each input"; + doc = <<- _EODoc_ + If you need to reformat each input text, the argument to this + option is interpreted as an @code{sprintf(3)} format that is used + to produce each output entry. + _EODoc_; +}; + +flag = { + name = separation; + value = S; + arg-type = string; + arg-name = sep-str; + descrip = "Separation string - follows all but last"; + doc = <<- _EODoc_ + Use this option if, for example, you wish a comma to appear after + each entry except the last. + _EODoc_; +}; + +flag = { + name = line_separation; + arg-type = string; + arg-name = sep-str; + descrip = "string at end of all lines but last"; + doc = <<- _EODoc_ + Use this option if, for example, you wish a backslash to appear at + the end of every line, except the last. + _EODoc_; +}; + +flag = { + name = ending; + arg-type = string; + arg-name = end-str; + descrip = "string at end of last line"; + doc = <<- _EODoc_ + This option puts the specified string at the end of the output. + _EODoc_; +}; + +flag = { + name = ordering; + documentation; + descrip = 'Specify the ordering of the entries'; +}; + +flag = { + name = by_columns; + descrip = "Print entries in column order"; + doc = <<- _EODoc_ + Normally, the entries are printed out in order by rows and then columns. + This option will cause the entries to be ordered within columns. + The final column, instead of the final row, may be shorter than the + others. + _EODoc_; +}; + +flag = { + name = sort; + value = s; + arg-type = string; + arg-optional; + arg-name = key-pat; + descrip = "Sort input text"; + doc = <<- _EODoc_ + Causes the input text to be sorted. If an argument is supplied, + it is presumed to be a pattern and the sort is based upon the + matched text. If the pattern starts with or consists of + an asterisk (@code{*}), then the sort is case insensitive. + _EODoc_; +}; + +flag = { + name = input-text; + documentation; + descrip = 'Redirecting stdin to an alternate file'; +}; + +include = + '#define OPEN_ERROR_FMT ([= + (string-table-add-ref opt-strs + "Error %d (%s) opening %s\n")=])'; + +flag = { + name = input; + value = i; + arg-type = string; + arg-name = file; + descrip = "Input file (if not stdin)"; + flag-code = <<- _EODoc_ + FILE * fp = freopen( + pOptDesc->optArg.argString, "r" FOPEN_BINARY_FLAG, stdin); + + if (fp == (FILE *)NULL) { + fprintf(stderr, OPEN_ERROR_FMT, errno, strerror(errno), + pOptDesc->optArg.argString); + USAGE(EXIT_FAILURE); + } + _EODoc_; + doc = <<- _EODoc_ + This program normally runs as a @code{filter}, reading from standard + input, columnizing and writing to standard out. This option redirects + input to a file. + _EODoc_; +}; + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * Program Documentation + */ +option-doc-format = texi; + +/* prog_man_descrip = -- unchanged; */ + +doc-section = { + ds-type = "SEE ALSO"; + ds-format = texi; + ds-text = <<- _EndOfMan_ + This program is documented more fully in the Columns section + of the Add-On chapter in the @code{AutoGen} Info system documentation. + _EndOfMan_; +}; + +prog_descrip = <<- _EndOfMan_ + This program was designed for the purpose of generating compact, + columnized tables. It will read a list of text items from standard + in or a specified input file and produce a columnized listing of + all the non-blank lines. Leading white space on each line is + preserved, but trailing white space is stripped. Methods of + applying per-entry and per-line embellishments are provided. + See the formatting and separation arguments below. + + This program is used by AutoGen to help clean up and organize + its output. + + See @file{autogen/agen5/fsm.tpl} and the generated output + @file{pseudo-fsm.h}. + + This function was not implemented as an expression function because + either it would have to be many expression functions, or a provision + would have to be added to provide options to expression functions. + Maybe not a bad idea, but it is not being implemented at the moment. + + A side benefit is that you can use it outside of @code{autogen} to + columnize input, a la the @code{ls} command. + _EndOfMan_; + +/* end of opts.def */ diff --git a/columns/opts.h b/columns/opts.h new file mode 100644 index 0000000..a41aed0 --- /dev/null +++ b/columns/opts.h @@ -0,0 +1,251 @@ +/* -*- buffer-read-only: t -*- vi: set ro: + * + * DO NOT EDIT THIS FILE (opts.h) + * + * It has been AutoGen-ed + * From the definitions opts.def + * and the template file options + * + * Generated from AutoOpts 42:1:17 templates. + * + * AutoOpts is a copyrighted work. This header file is not encumbered + * by AutoOpts licensing, but is provided under the licensing terms chosen + * by the columns author or copyright holder. AutoOpts is + * licensed under the terms of the LGPL. The redistributable library + * (``libopts'') is licensed under the terms of either the LGPL or, at the + * users discretion, the BSD license. See the AutoOpts and/or libopts sources + * for details. + * + * The columns program is copyrighted and licensed + * under the following terms: + * + * Copyright (C) 1999-2017 Bruce Korb, all rights reserved. + * This is free software. It is licensed for use, modification and + * redistribution under the terms of the GNU General Public License, + * version 3 or later + * + * columns 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. + * + * columns is distributed in the hope that 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 . + */ +/** \file opts.h + * \addtogroup columns + * @{ + */ +/** + * This file contains the programmatic interface to the Automated + * Options generated for the columns program. + * These macros are documented in the AutoGen info file in the + * "AutoOpts" chapter. Please refer to that doc for usage help. + */ +#ifndef AUTOOPTS_OPTS_H_GUARD +#define AUTOOPTS_OPTS_H_GUARD 1 +#include +#include +#include + +/** + * Ensure that the library used for compiling this generated header is at + * least as new as the version current when the header template was released + * (not counting patch version increments). Also ensure that the oldest + * tolerable version is at least as old as what was current when the header + * template was released. + */ +#define AO_TEMPLATE_VERSION 172033 +#if (AO_TEMPLATE_VERSION < OPTIONS_MINIMUM_VERSION) \ + || (AO_TEMPLATE_VERSION > OPTIONS_STRUCT_VERSION) +# error option template version mismatches autoopts/options.h header + Choke Me. +#endif + +#if GCC_VERSION > 40400 +#define NOT_REACHED __builtin_unreachable(); +#else +#define NOT_REACHED +#endif + +/** + * Enumeration of each option type for columns + */ +typedef enum { + INDEX_OPT_WIDTH = 1, + INDEX_OPT_COLUMNS = 2, + INDEX_OPT_COL_WIDTH = 3, + INDEX_OPT_TAB_WIDTH = 4, + INDEX_OPT_SPREAD = 6, + INDEX_OPT_FILL = 7, + INDEX_OPT_INDENT = 8, + INDEX_OPT_FIRST_INDENT = 9, + INDEX_OPT_FORMAT = 10, + INDEX_OPT_SEPARATION = 11, + INDEX_OPT_LINE_SEPARATION = 12, + INDEX_OPT_ENDING = 13, + INDEX_OPT_BY_COLUMNS = 15, + INDEX_OPT_SORT = 16, + INDEX_OPT_INPUT = 18, + INDEX_OPT_VERSION = 19, + INDEX_OPT_HELP = 20, + INDEX_OPT_MORE_HELP = 21, + INDEX_OPT_SAVE_OPTS = 22, + INDEX_OPT_LOAD_OPTS = 23 +} teOptIndex; +/** count of all options for columns */ +#define OPTION_CT 24 +/** columns version */ +#define COLUMNS_VERSION "1.2" +/** Full columns version text */ +#define COLUMNS_FULL_VERSION "columns (GNU AutoGen) 1.2" + +/** + * Interface defines for all options. Replace "n" with the UPPER_CASED + * option name (as in the teOptIndex enumeration above). + * e.g. HAVE_OPT(DIMENSIONS) + */ +#define DESC(n) (columnsOptions.pOptDesc[INDEX_OPT_## n]) +/** 'true' if an option has been specified in any way */ +#define HAVE_OPT(n) (! UNUSED_OPT(& DESC(n))) +/** The string argument to an option. The argument type must be \"string\". */ +#define OPT_ARG(n) (DESC(n).optArg.argString) +/** Mask the option state revealing how an option was specified. + * It will be one and only one of \a OPTST_SET, \a OPTST_PRESET, + * \a OPTST_DEFINED, \a OPTST_RESET or zero. + */ +#define STATE_OPT(n) (DESC(n).fOptState & OPTST_SET_MASK) +/** Count of option's occurrances *on the command line*. */ +#define COUNT_OPT(n) (DESC(n).optOccCt) +/** mask of \a OPTST_SET and \a OPTST_DEFINED. */ +#define ISSEL_OPT(n) (SELECTED_OPT(&DESC(n))) +/** 'true' if \a HAVE_OPT would yield 'false'. */ +#define ISUNUSED_OPT(n) (UNUSED_OPT(& DESC(n))) +/** 'true' if OPTST_DISABLED bit not set. */ +#define ENABLED_OPT(n) (! DISABLED_OPT(& DESC(n))) +/** number of stacked option arguments. + * Valid only for stacked option arguments. */ +#define STACKCT_OPT(n) (((tArgList*)(DESC(n).optCookie))->useCt) +/** stacked argument vector. + * Valid only for stacked option arguments. */ +#define STACKLST_OPT(n) (((tArgList*)(DESC(n).optCookie))->apzArgs) +/** Reset an option. */ +#define CLEAR_OPT(n) STMTS( \ + DESC(n).fOptState &= OPTST_PERSISTENT_MASK; \ + if ((DESC(n).fOptState & OPTST_INITENABLED) == 0) \ + DESC(n).fOptState |= OPTST_DISABLED; \ + DESC(n).optCookie = NULL ) +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/** + * Enumeration of columns exit codes + */ +typedef enum { + COLUMNS_EXIT_SUCCESS = 0, + COLUMNS_EXIT_FAILURE = 1, + COLUMNS_EXIT_USAGE_ERROR = 64, + COLUMNS_EXIT_NO_CONFIG_INPUT = 66, + COLUMNS_EXIT_LIBOPTS_FAILURE = 70 +} columns_exit_code_t; +/** + * Interface defines for specific options. + * @{ + */ +#define VALUE_OPT_WIDTH 'W' + +#define OPT_VALUE_WIDTH (DESC(WIDTH).optArg.argInt) +#define VALUE_OPT_COLUMNS 'c' + +#define OPT_VALUE_COLUMNS (DESC(COLUMNS).optArg.argInt) +#define VALUE_OPT_COL_WIDTH 'w' + +#define OPT_VALUE_COL_WIDTH (DESC(COL_WIDTH).optArg.argInt) +#define VALUE_OPT_TAB_WIDTH 0x1001 + +#define OPT_VALUE_TAB_WIDTH (DESC(TAB_WIDTH).optArg.argInt) +#define VALUE_OPT_SPREAD 0x1002 + +#define OPT_VALUE_SPREAD (DESC(SPREAD).optArg.argInt) +#define VALUE_OPT_FILL 0x1003 +#define VALUE_OPT_INDENT 'I' +#define VALUE_OPT_FIRST_INDENT 0x1004 +#define VALUE_OPT_FORMAT 'f' +#define VALUE_OPT_SEPARATION 'S' +#define VALUE_OPT_LINE_SEPARATION 0x1005 +#define VALUE_OPT_ENDING 0x1006 +#define VALUE_OPT_BY_COLUMNS 0x1007 +#define VALUE_OPT_SORT 's' +#define VALUE_OPT_INPUT 'i' +/** option flag (value) for help-value option */ +#define VALUE_OPT_HELP '?' +/** option flag (value) for more-help-value option */ +#define VALUE_OPT_MORE_HELP '!' +/** option flag (value) for version-value option */ +#define VALUE_OPT_VERSION 'v' +/** option flag (value) for save-opts-value option */ +#define VALUE_OPT_SAVE_OPTS '>' +/** option flag (value) for load-opts-value option */ +#define VALUE_OPT_LOAD_OPTS '<' +#define SET_OPT_SAVE_OPTS(a) STMTS( \ + DESC(SAVE_OPTS).fOptState &= OPTST_PERSISTENT_MASK; \ + DESC(SAVE_OPTS).fOptState |= OPTST_SET; \ + DESC(SAVE_OPTS).optArg.argString = (char const*)(a)) +/* + * Interface defines not associated with particular options + */ +#define ERRSKIP_OPTERR STMTS(columnsOptions.fOptSet &= ~OPTPROC_ERRSTOP) +#define ERRSTOP_OPTERR STMTS(columnsOptions.fOptSet |= OPTPROC_ERRSTOP) +#define RESTART_OPT(n) STMTS( \ + columnsOptions.curOptIdx = (n); \ + columnsOptions.pzCurOpt = NULL ) +#define START_OPT RESTART_OPT(1) +#define USAGE(c) (*columnsOptions.pUsageProc)(&columnsOptions, c) + +#ifdef __cplusplus +extern "C" { +#endif +/* + * global exported definitions + */ +#include "config.h" +#include +#include +#include +#include +#include +#include + + +/* * * * * * + * + * Declare the columns option descriptor. + */ +extern tOptions columnsOptions; +# define OPT_NO_XLAT_CFG_NAMES +# define OPT_NO_XLAT_OPT_NAMES + +# define OPT_XLAT_CFG_NAMES +# define OPT_XLAT_OPT_NAMES + +# ifndef _ +# define _(_s) _s +# endif + + +noreturn extern void +vdie( int exit_code, char const * fmt, va_list); +noreturn extern void +die( int exit_code, char const * fmt, ...); +noreturn extern void +fserr(int exit_code, char const * op, char const * fn); +#ifdef __cplusplus +} +#endif +#endif /* AUTOOPTS_OPTS_H_GUARD */ + +/** @} */ +/* opts.h ends here */ diff --git a/compat/Makefile.am b/compat/Makefile.am new file mode 100644 index 0000000..b745a1e --- /dev/null +++ b/compat/Makefile.am @@ -0,0 +1,51 @@ +## -*- Mode: Makefile -*- +## +## Makefile.am -- process this file with automake to produce Makefile.in +## +## Copyright (C) 1997-2018 by Bruce Korb +## Author: Bruce Korb +## +## This file is part of AutoGen. +## +## AutoGen 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. +## +## AutoGen is distributed in the hope that 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 . + +COMPAT_CSRC = chmod.c pathfind.c snprintf.c strchr.c strdup.c strftime.c \ + strsignal.c +COMPAT_HDRS = compat.h strsignal.h windows-config.h unlocked-io.h +COMPAT_GEN = bootstrap.dir strsignal.def strsignal.tpl +EXTRA_DIST = $(COMPAT_CSRC) $(COMPAT_HDRS) $(COMPAT_GEN) + +MAINTAINERCLEANFILES = strsignal.h + +all: + : + +strsignal.h : strsignal.def strsignal.tpl + @if $(AGexe) --version >&- 2>&- ; then \ + echo $(AGexe) -L $(srcdir) $(srcdir)/strsignal.def ; \ + top_srcdir=$(top_srcdir) top_builddir=$(top_builddir) \ + $(AGexe) -L $(srcdir) $(srcdir)/strsignal.def ; \ + elif $(AGnam) --version >&- 2>&- ; then \ + echo $(AGnam) -L $(srcdir) $(srcdir)/strsignal.def ; \ + top_srcdir=$(top_srcdir) top_builddir=$(top_builddir) \ + $(AGnam) -L $(srcdir) $(srcdir)/strsignal.def ; \ + elif test -s $(srcdir)/$@; then \ + echo "WARNING: $(AGnam) not available, current $(srcdir)/$@ used"; \ + else \ + echo "ERROR: $(srcdir)/$@ has been corrupted"; exit 1;\ + fi + +.NOTPARALLEL: + +# compat/Makefile.am ends here diff --git a/compat/Makefile.in b/compat/Makefile.in new file mode 100644 index 0000000..d315571 --- /dev/null +++ b/compat/Makefile.in @@ -0,0 +1,534 @@ +# Makefile.in generated by automake 1.16.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2018 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +subdir = compat +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/config/ag_macros.m4 \ + $(top_srcdir)/config/asm-underscore.m4 \ + $(top_srcdir)/config/extensions.m4 \ + $(top_srcdir)/config/guile.m4 \ + $(top_srcdir)/config/host-cpu-c-abi.m4 \ + $(top_srcdir)/config/lib-ld.m4 \ + $(top_srcdir)/config/lib-link.m4 \ + $(top_srcdir)/config/lib-prefix.m4 \ + $(top_srcdir)/config/libopts.m4 \ + $(top_srcdir)/config/libtool.m4 \ + $(top_srcdir)/config/ltoptions.m4 \ + $(top_srcdir)/config/ltsugar.m4 \ + $(top_srcdir)/config/ltversion.m4 \ + $(top_srcdir)/config/lt~obsolete.m4 \ + $(top_srcdir)/config/onceonly.m4 $(top_srcdir)/config/pkg.m4 \ + $(top_srcdir)/config/snprintfv.m4 \ + $(top_srcdir)/config/stdnoreturn.m4 \ + $(top_srcdir)/config/unlocked-io.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +am__DIST_COMMON = $(srcdir)/Makefile.in +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AGEN5_TESTS = @AGEN5_TESTS@ +AG_LDFLAGS = @AG_LDFLAGS@ +AG_MAJOR_VERSION = @AG_MAJOR_VERSION@ +AG_MINOR_VERSION = @AG_MINOR_VERSION@ +AG_STATIC_AUTOGEN = @AG_STATIC_AUTOGEN@ +AG_TIMEOUT = @AG_TIMEOUT@ +AG_VERSION = @AG_VERSION@ +AG_XML2 = @AG_XML2@ +AGexe = @AGexe@ +AGnam = @AGnam@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AO_AGE = @AO_AGE@ +AO_CURRENT = @AO_CURRENT@ +AO_REVISION = @AO_REVISION@ +AO_TEMPLATE_VERSION = @AO_TEMPLATE_VERSION@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CLexe = @CLexe@ +CLnam = @CLnam@ +CONFIG_SHELL = @CONFIG_SHELL@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEBUG_ENABLED = @DEBUG_ENABLED@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +DYNAMIC_AG = @DYNAMIC_AG@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ENABLE_STATIC = @ENABLE_STATIC@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GDexe = @GDexe@ +GDnam = @GDnam@ +GO_AGE = @GO_AGE@ +GO_CURRENT = @GO_CURRENT@ +GO_REVISION = @GO_REVISION@ +GREP = @GREP@ +GUILE_CFLAGS = @GUILE_CFLAGS@ +GUILE_EFFECTIVE_VERSION = @GUILE_EFFECTIVE_VERSION@ +GUILE_LDFLAGS = @GUILE_LDFLAGS@ +GUILE_LIBS = @GUILE_LIBS@ +GUILE_LTLIBS = @GUILE_LTLIBS@ +HOST_CPU = @HOST_CPU@ +HOST_CPU_C_ABI = @HOST_CPU_C_ABI@ +INCLIST = @INCLIST@ +INCSNPRINTFV = @INCSNPRINTFV@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSNPRINTFV = @LIBSNPRINTFV@ +LIBTOOL = @LIBTOOL@ +LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ +LIBXML2_LIBS = @LIBXML2_LIBS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +M4_SRC = @M4_SRC@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPTS_TESTDIR = @OPTS_TESTDIR@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POSIX_SHELL = @POSIX_SHELL@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STDNORETURN_H = @STDNORETURN_H@ +STRIP = @STRIP@ +TEXI2HTML = @TEXI2HTML@ +VERSION = @VERSION@ +WARN_CFLAGS = @WARN_CFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_aux_dir = @ac_aux_dir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +COMPAT_CSRC = chmod.c pathfind.c snprintf.c strchr.c strdup.c strftime.c \ + strsignal.c + +COMPAT_HDRS = compat.h strsignal.h windows-config.h unlocked-io.h +COMPAT_GEN = bootstrap.dir strsignal.def strsignal.tpl +EXTRA_DIST = $(COMPAT_CSRC) $(COMPAT_HDRS) $(COMPAT_GEN) +MAINTAINERCLEANFILES = strsignal.h +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu compat/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu compat/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +tags TAGS: + +ctags CTAGS: + +cscope cscopelist: + + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: all all-am check check-am clean clean-generic clean-libtool \ + cscopelist-am ctags-am distclean distclean-generic \ + distclean-libtool distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + + +all: + : + +strsignal.h : strsignal.def strsignal.tpl + @if $(AGexe) --version >&- 2>&- ; then \ + echo $(AGexe) -L $(srcdir) $(srcdir)/strsignal.def ; \ + top_srcdir=$(top_srcdir) top_builddir=$(top_builddir) \ + $(AGexe) -L $(srcdir) $(srcdir)/strsignal.def ; \ + elif $(AGnam) --version >&- 2>&- ; then \ + echo $(AGnam) -L $(srcdir) $(srcdir)/strsignal.def ; \ + top_srcdir=$(top_srcdir) top_builddir=$(top_builddir) \ + $(AGnam) -L $(srcdir) $(srcdir)/strsignal.def ; \ + elif test -s $(srcdir)/$@; then \ + echo "WARNING: $(AGnam) not available, current $(srcdir)/$@ used"; \ + else \ + echo "ERROR: $(srcdir)/$@ has been corrupted"; exit 1;\ + fi + +.NOTPARALLEL: + +# compat/Makefile.am ends here + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/compat/bootstrap.dir b/compat/bootstrap.dir new file mode 100644 index 0000000..79611db --- /dev/null +++ b/compat/bootstrap.dir @@ -0,0 +1,32 @@ +#! /bin/echo This_file_must_be_sourced,_not_executed +## +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen 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. +## +## AutoGen is distributed in the hope that 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 . + +if ${skip_gen} +then + gunzip < strsignal.h.gz > strsignal.h +else + ${AGexe} strsignal.def +fi + +# Local Variables: +# mode:shell-script +# sh-indentation:4 +# sh-basic-offset:4 +# indent-tabs-mode: nil +# End: + +# compat/bootstrap.dir ends here diff --git a/compat/chmod.c b/compat/chmod.c new file mode 100644 index 0000000..01a1be0 --- /dev/null +++ b/compat/chmod.c @@ -0,0 +1,4 @@ + +inline int chmod(char const * path, mode_t mode) { + return 0; +} diff --git a/compat/compat.h b/compat/compat.h new file mode 100644 index 0000000..70a5652 --- /dev/null +++ b/compat/compat.h @@ -0,0 +1,383 @@ +/* -*- Mode: C -*- + * + * compat.h is free software. + * This file is part of AutoGen and AutoOpts. + * + * AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoOpts is available under any one of two licenses. The license + * in use must be one of these two and the choice is under the control + * of the user of the license. + * + * The GNU Lesser General Public License, version 3 or later + * See the files "COPYING.lgplv3" and "COPYING.gplv3" + * + * The Modified Berkeley Software Distribution License + * See the file "COPYING.mbsd" + * + * These files have the following sha256 sums: + * + * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 + * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 + * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + */ + +/** + * \file compat.h + * fake the preprocessor into handlng stuff portability + */ +#ifndef COMPAT_H_GUARD +#define COMPAT_H_GUARD 1 + +#if defined(HAVE_CONFIG_H) +# include + +#elif defined(_WIN32) && !defined(__CYGWIN__) +# include "windows-config.h" + +#else +# error "compat.h" requires "config.h" + choke me. +#endif + + +#ifndef HAVE_STRSIGNAL +# ifndef HAVE_RAW_DECL_STRSIGNAL + char * strsignal(int signo); +# endif +#endif + +#define _GNU_SOURCE 1 /* for strsignal in GNU's libc */ +#define __USE_GNU 1 /* exact same thing as above */ +#define __EXTENSIONS__ 1 /* and another way to call for it */ + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * SYSTEM HEADERS: + */ +#include +#ifdef HAVE_SYS_MMAN_H +# include +#endif +#include +#if HAVE_SYS_PROCSET_H +# include +#endif +#include +#ifdef HAVE_SYS_WAIT_H +# include +#endif + +#if defined( HAVE_SOLARIS_SYSINFO ) +# include +#elif defined( HAVE_UNAME_SYSCALL ) +# include +#endif + +#ifdef DAEMON_ENABLED +# if HAVE_SYS_STROPTS_H +# include +# endif + +# if HAVE_SYS_SOCKET_H +# include +# endif + +# if ! defined(HAVE_SYS_POLL_H) && ! defined(HAVE_SYS_SELECT_H) +# error This system cannot support daemon processing + Choke Me. +# endif + +# if HAVE_SYS_POLL_H +# include +# endif + +# if HAVE_SYS_SELECT_H +# include +# endif + +# if HAVE_NETINET_IN_H +# include +# endif + +# if HAVE_SYS_UN_H +# include +# endif +#endif + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * USER HEADERS: + */ +#include +#include +#include + +/* + * Directory opening stuff: + */ +# if defined (_POSIX_SOURCE) +/* Posix does not require that the d_ino field be present, and some + systems do not provide it. */ +# define REAL_DIR_ENTRY(dp) 1 +# else /* !_POSIX_SOURCE */ +# define REAL_DIR_ENTRY(dp) (dp->d_ino != 0) +# endif /* !_POSIX_SOURCE */ + +# if defined (HAVE_DIRENT_H) +# include +# define D_NAMLEN(dirent) strlen((dirent)->d_name) +# else /* !HAVE_DIRENT_H */ +# define dirent direct +# define D_NAMLEN(dirent) (dirent)->d_namlen +# if defined (HAVE_SYS_NDIR_H) +# include +# endif /* HAVE_SYS_NDIR_H */ +# if defined (HAVE_SYS_DIR_H) +# include +# endif /* HAVE_SYS_DIR_H */ +# if defined (HAVE_NDIR_H) +# include +# endif /* HAVE_NDIR_H */ +# endif /* !HAVE_DIRENT_H */ + +#include +#ifdef HAVE_FCNTL_H +# include +#endif +#ifndef O_NONBLOCK +# define O_NONBLOCK FNDELAY +#endif + +#if defined(HAVE_LIBGEN) && defined(HAVE_LIBGEN_H) +# include +#endif + +#if defined(HAVE_LIMITS_H) /* this is also in options.h */ +# include +#elif defined(HAVE_SYS_LIMITS_H) +# include +#endif /* HAVE_LIMITS/SYS_LIMITS_H */ + +#include +#include +#include + +#if defined(HAVE_STDINT_H) +# include + +#elif defined(HAVE_INTTYPES_H) +# include +#endif + +#include +#include +#include + +#ifdef HAVE_UTIME_H +# include +#endif + +#ifdef HAVE_UNISTD_H +# include +#endif + +#if defined(HAVE_STDBOOL_H) +# include +#elif ! defined(bool) + typedef enum { false = 0, true = 1 } _Bool; +# define bool _Bool + + /* The other macros must be usable in preprocessor directives. */ +# define false 0 +# define true 1 +#endif + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * FIXUPS and CONVIENCE STUFF: + */ +#ifdef __cplusplus +# define EXTERN extern "C" +#else +# define EXTERN extern +#endif + +/* some systems #def errno! and others do not declare it!! */ +#ifndef errno + extern int errno; +#endif + +/* Some machines forget this! */ + +# ifndef EXIT_FAILURE +# define EXIT_SUCCESS 0 +# define EXIT_FAILURE 1 +# endif + +#ifndef NUL +# define NUL '\0' +#endif + +#ifndef NULL +# define NULL 0 +#endif + +#if !defined (MAXPATHLEN) && defined (HAVE_SYS_PARAM_H) +# include +#endif /* !MAXPATHLEN && HAVE_SYS_PARAM_H */ + +#if !defined (MAXPATHLEN) && defined (PATH_MAX) +# define MAXPATHLEN PATH_MAX +#endif /* !MAXPATHLEN && PATH_MAX */ + +#if !defined (MAXPATHLEN) && defined(_MAX_PATH) +# define PATH_MAX _MAX_PATH +# define MAXPATHLEN _MAX_PATH +#endif + +#if !defined (MAXPATHLEN) +# define MAXPATHLEN 4096 +#endif /* MAXPATHLEN */ + +#define AG_PATH_MAX ((size_t)MAXPATHLEN) + +#ifndef LONG_MAX +# define LONG_MAX ~(1L << (8*sizeof(long) -1)) +# define INT_MAX ~(1 << (8*sizeof(int) -1)) +#endif + +#ifndef ULONG_MAX +# define ULONG_MAX ~(OUL) +# define UINT_MAX ~(OU) +#endif + +#ifndef SHORT_MAX +# define SHORT_MAX ~(1 << (8*sizeof(short) - 1)) +#else +# define USHORT_MAX ~(OUS) +#endif + +#ifndef HAVE_INT8_T + typedef signed char int8_t; +# define HAVE_INT8_T 1 +#endif +#ifndef HAVE_UINT8_T + typedef unsigned char uint8_t; +# define HAVE_UINT8_T 1 +#endif +#ifndef HAVE_INT16_T + typedef signed short int16_t; +# define HAVE_INT16_T 1 +#endif +#ifndef HAVE_UINT16_T + typedef unsigned short uint16_t; +# define HAVE_UINT16_T 1 +#endif + +#ifndef HAVE_INT32_T +# if SIZEOF_INT == 4 + typedef signed int int32_t; +# elif SIZEOF_LONG == 4 + typedef signed long int32_t; +# endif +# define HAVE_INT32_T 1 +#endif + +#ifndef HAVE_UINT32_T +# if SIZEOF_INT == 4 + typedef unsigned int uint32_t; +# elif SIZEOF_LONG == 4 + typedef unsigned long uint32_t; +# else +# error Cannot create a uint32_t type. + Choke Me. +# endif +# define HAVE_UINT32_T 1 +#endif + +#ifndef HAVE_INTPTR_T +# if SIZEOF_CHARP == SIZEOF_LONG + typedef signed long intptr_t; +# else + typedef signed int intptr_t; +# endif +# define HAVE_INTPTR_T 1 +#endif + +#ifndef HAVE_UINTPTR_T +# if SIZEOF_CHARP == SIZEOF_LONG + typedef unsigned long intptr_t; +# else + typedef unsigned int intptr_t; +# endif +# define HAVE_INTPTR_T 1 +#endif + +#ifndef HAVE_UINT_T + typedef unsigned int uint_t; +# define HAVE_UINT_T 1 +#endif + +#ifndef HAVE_SIZE_T + typedef unsigned int size_t; +# define HAVE_SIZE_T 1 +#endif +#ifndef HAVE_WINT_T + typedef unsigned int wint_t; +# define HAVE_WINT_T 1 +#endif +#ifndef HAVE_PID_T + typedef signed int pid_t; +# define HAVE_PID_T 1 +#endif + +/* redefine these for BSD style string libraries */ +#ifndef HAVE_STRCHR +# define strchr index +# define strrchr rindex +#endif + +#ifdef USE_FOPEN_BINARY +# ifndef FOPEN_BINARY_FLAG +# define FOPEN_BINARY_FLAG "b" +# endif +# ifndef FOPEN_TEXT_FLAG +# define FOPEN_TEXT_FLAG "t" +# endif +#else +# ifndef FOPEN_BINARY_FLAG +# define FOPEN_BINARY_FLAG +# endif +# ifndef FOPEN_TEXT_FLAG +# define FOPEN_TEXT_FLAG +# endif +#endif + +#ifndef STR +# define _STR(s) #s +# define STR(s) _STR(s) +#endif + +/* ##### Pointer sized word ##### */ + +/* FIXME: the MAX stuff in here is broken! */ +#if SIZEOF_CHARP > SIZEOF_INT + typedef long t_word; + #define WORD_MAX LONG_MAX + #define WORD_MIN LONG_MIN +#else /* SIZEOF_CHARP <= SIZEOF_INT */ + typedef int t_word; + #define WORD_MAX INT_MAX + #define WORD_MIN INT_MIN +#endif + +#endif /* COMPAT_H_GUARD */ + +/* + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of compat/compat.h */ diff --git a/compat/pathfind.c b/compat/pathfind.c new file mode 100644 index 0000000..5c477ca --- /dev/null +++ b/compat/pathfind.c @@ -0,0 +1,283 @@ +/* -*- Mode: C -*- */ + +/* pathfind.c --- find a FILE MODE along PATH */ + +/* Author: Gary V Vaughan */ + +/* Code: */ + +static char * +pathfind( char const * path, + char const * fname, + char const * mode ); + +#include "compat.h" +#ifndef HAVE_PATHFIND +#if defined(__windows__) && !defined(__CYGWIN__) +static char * +pathfind( char const * path, + char const * fname, + char const * mode ) +{ + return strdup(fname); +} +#else + +static char * make_absolute(char const * string, char const * dot_path); +static char * canonicalize_pathname(char * path); +static char * extract_colon_unit(char * dir, char const * string, int * p_index); + +/** + * local implementation of pathfind. + * @param[in] path colon separated list of directories + * @param[in] fname the name we are hunting for + * @param[in] mode the required file mode + * @returns an allocated string with the full path, or NULL + */ +static char * +pathfind( char const * path, + char const * fname, + char const * mode ) +{ + int p_index = 0; + int mode_bits = 0; + char * res_path = NULL; + char zPath[ AG_PATH_MAX + 1 ]; + + if (strchr( mode, 'r' )) mode_bits |= R_OK; + if (strchr( mode, 'w' )) mode_bits |= W_OK; + if (strchr( mode, 'x' )) mode_bits |= X_OK; + + /* + * FOR each non-null entry in the colon-separated path, DO ... + */ + for (;;) { + DIR * dirP; + char * colon_unit = extract_colon_unit( zPath, path, &p_index ); + + if (colon_unit == NULL) + break; + + dirP = opendir( colon_unit ); + + /* + * IF the directory is inaccessable, THEN next directory + */ + if (dirP == NULL) + continue; + + for (;;) { + struct dirent *entP = readdir( dirP ); + + if (entP == (struct dirent *)NULL) + break; + + /* + * IF the file name matches the one we are looking for, ... + */ + if (strcmp(entP->d_name, fname) == 0) { + char * abs_name = make_absolute(fname, colon_unit); + + /* + * Make sure we can access it in the way we want + */ + if (access(abs_name, mode_bits) >= 0) { + /* + * We can, so normalize the name and return it below + */ + res_path = canonicalize_pathname(abs_name); + } + + free(abs_name); + break; + } + } + + closedir( dirP ); + + if (res_path != NULL) + break; + } + + return res_path; +} + +/* + * Turn STRING (a pathname) into an absolute pathname, assuming that + * DOT_PATH contains the symbolic location of `.'. This always returns + * a new string, even if STRING was an absolute pathname to begin with. + */ +static char * +make_absolute( char const * string, char const * dot_path ) +{ + char * result; + int result_len; + + if (!dot_path || *string == '/') { + result = strdup( string ); + } else { + if (dot_path && dot_path[0]) { + result = malloc( 2 + strlen( dot_path ) + strlen( string ) ); + strcpy( result, dot_path ); + result_len = (int)strlen(result); + if (result[result_len - 1] != '/') { + result[result_len++] = '/'; + result[result_len] = '\0'; + } + } else { + result = malloc( 3 + strlen( string ) ); + result[0] = '.'; result[1] = '/'; result[2] = '\0'; + result_len = 2; + } + + strcpy( result + result_len, string ); + } + + return result; +} + +/* + * Canonicalize PATH, and return a new path. The new path differs from + * PATH in that: + * + * Multiple `/'s are collapsed to a single `/'. + * Leading `./'s are removed. + * Trailing `/.'s are removed. + * Trailing `/'s are removed. + * Non-leading `../'s and trailing `..'s are handled by removing + * portions of the path. + */ +static char * +canonicalize_pathname( char *path ) +{ + int i, start; + char stub_char, *result; + + /* The result cannot be larger than the input PATH. */ + result = strdup( path ); + + stub_char = (*path == '/') ? '/' : '.'; + + /* Walk along RESULT looking for things to compact. */ + i = 0; + while (result[i]) { + while (result[i] != '\0' && result[i] != '/') + i++; + + start = i++; + + /* If we didn't find any slashes, then there is nothing left to + * do. + */ + if (!result[start]) + break; + + /* Handle multiple `/'s in a row. */ + while (result[i] == '/') + i++; + +#if !defined (apollo) + if ((start + 1) != i) +#else + if ((start + 1) != i && (start != 0 || i != 2)) +#endif /* apollo */ + { + strcpy( result + start + 1, result + i ); + i = start + 1; + } + + /* Handle backquoted `/'. */ + if (start > 0 && result[start - 1] == '\\') + continue; + + /* Check for trailing `/', and `.' by itself. */ + if ((start && !result[i]) + || (result[i] == '.' && !result[i+1])) { + result[--i] = '\0'; + break; + } + + /* Check for `../', `./' or trailing `.' by itself. */ + if (result[i] == '.') { + /* Handle `./'. */ + if (result[i + 1] == '/') { + strcpy( result + i, result + i + 1 ); + i = (start < 0) ? 0 : start; + continue; + } + + /* Handle `../' or trailing `..' by itself. */ + if (result[i + 1] == '.' && + (result[i + 2] == '/' || !result[i + 2])) { + while (--start > -1 && result[start] != '/') + ; + strcpy( result + start + 1, result + i + 2 ); + i = (start < 0) ? 0 : start; + continue; + } + } + } + + if (!*result) { + *result = stub_char; + result[1] = '\0'; + } + + return result; +} + +/* + * Given a string containing units of information separated by colons, + * return the next one pointed to by (P_INDEX), or NULL if there are no + * more. Advance (P_INDEX) to the character after the colon. + */ +static char * +extract_colon_unit(char * pzDir, char const * string, int * p_index) +{ + char * pzDest = pzDir; + int ix = *p_index; + + if (string == NULL) + return NULL; + + if ((unsigned)ix >= strlen( string )) + return NULL; + + { + char const * pzSrc = string + ix; + + while (*pzSrc == ':') pzSrc++; + + for (;;) { + char ch = (*(pzDest++) = *(pzSrc++)); + switch (ch) { + case ':': + pzDest[-1] = NUL; + /* FALLTHROUGH */ + case NUL: + goto copy_done; + } + + if ((unsigned long)(pzDest - pzDir) >= AG_PATH_MAX) + break; + } copy_done:; + + ix = (int)(pzSrc - string); + } + + if (*pzDir == NUL) + return NULL; + + *p_index = ix; + return pzDir; +} +#endif /* __windows__ / __CYGWIN__ */ +#endif /* HAVE_PATHFIND */ + +/* + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of compat/pathfind.c */ diff --git a/compat/snprintf.c b/compat/snprintf.c new file mode 100644 index 0000000..eccea1f --- /dev/null +++ b/compat/snprintf.c @@ -0,0 +1,62 @@ + +#ifndef HAVE_VPRINTF +#include "choke-me: no vprintf and no snprintf" + choke me. +#endif + +#if defined(HAVE_STDARG_H) +# include +# ifndef VA_START +# define VA_START(a, f) va_start(a, f) +# define VA_END(a) va_end(a) +# endif /* VA_START */ +# define SNV_USING_STDARG_H + +#elif defined(HAVE_VARARGS_H) +# include +# ifndef VA_START +# define VA_START(a, f) va_start(a) +# define VA_END(a) va_end(a) +# endif /* VA_START */ +# undef SNV_USING_STDARG_H + +#else +# include "must-have-stdarg-or-varargs" + choke me. +#endif + +static int +snprintf(char *str, size_t n, char const *fmt, ...) +{ + va_list ap; + int rval; + +#ifdef VSPRINTF_CHARSTAR + char *rp; + VA_START(ap, fmt); + rp = vsprintf(str, fmt, ap); + VA_END(ap); + rval = strlen(rp); + +#else + VA_START(ap, fmt); + rval = vsprintf(str, fmt, ap); + VA_END(ap); +#endif + + if (rval > n) { + fprintf(stderr, "snprintf buffer overrun %d > %d\n", rval, (int)n); + abort(); + } + return rval; +} + +static int +vsnprintf( char *str, size_t n, char const *fmt, va_list ap ) +{ +#ifdef VSPRINTF_CHARSTAR + return (strlen(vsprintf(str, fmt, ap))); +#else + return (vsprintf(str, fmt, ap)); +#endif +} diff --git a/compat/strchr.c b/compat/strchr.c new file mode 100644 index 0000000..f409387 --- /dev/null +++ b/compat/strchr.c @@ -0,0 +1,66 @@ +/* + SYNOPSIS + #include + + char *strchr(char const *s, int c); + + char *strrchr(char const *s, int c); + + DESCRIPTION + The strchr() function returns a pointer to the first occurrence of the + character c in the string s. + + The strrchr() function returns a pointer to the last occurrence of the + character c in the string s. + + Here "character" means "byte" - these functions do not work with wide + or multi-byte characters. + + RETURN VALUE + The strchr() and strrchr() functions return a pointer to the matched + character or NULL if the character is not found. + + CONFORMING TO + SVID 3, POSIX, BSD 4.3, ISO 9899 +*/ + +static char * +strchr(char const *s, int c); + +static char * +strrchr(char const *s, int c); + +static char * +strchr(char const *s, int c) +{ + do { + if ((unsigned char)*s == (unsigned char)c) + return s; + + } while (*(++s) != NUL); + + return NULL; +} + +static char * +strrchr(char const *s, int c) +{ + char const *e = s + strlen(s); + + for (;;) { + if (--e < s) + break; + + if ((unsigned char)*e == (unsigned char)c) + return e; + } + return NULL; +} + +/* + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of compat/strsignal.c */ diff --git a/compat/strdup.c b/compat/strdup.c new file mode 100644 index 0000000..f3a4077 --- /dev/null +++ b/compat/strdup.c @@ -0,0 +1,22 @@ +/* + * Platforms without strdup ?!?!?! + */ + +static char * +strdup( char const *s ); + +static char * +strdup( char const *s ) +{ + char *cp; + + if (s == NULL) + return NULL; + + cp = (char *) AGALOC((unsigned) (strlen(s)+1), "strdup"); + + if (cp != NULL) + (void) strcpy(cp, s); + + return cp; +} diff --git a/compat/strftime.c b/compat/strftime.c new file mode 100644 index 0000000..400ad52 --- /dev/null +++ b/compat/strftime.c @@ -0,0 +1,1049 @@ +/* + 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 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. If not, see . + + */ + +#if HAVE_CONFIG_H +# include +#endif + +#ifdef _LIBC +# define HAVE_LIMITS_H 1 +# 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 +# define STDC_HEADERS 1 +# include +# include "../locale/localeinfo.h" +#endif + +#include +#include /* Some systems define `time_t' here. */ + +#ifdef TIME_WITH_SYS_TIME +# include +# include +#else +# ifdef HAVE_SYS_TIME_H +# include +# else +# include +# endif +#endif +#if HAVE_TZNAME +extern char *tzname[]; +#endif + +/* 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) + +#if DO_MULTIBYTE +# if HAVE_MBRLEN +# include +# else + /* Simulate mbrlen with mblen as best we can. */ +# define mbstate_t int +# define mbrlen(s, n, ps) mblen (s, n) +# define mbsinit(ps) (*(ps) == 0) +# endif + static const mbstate_t mbstate_zero; +#endif + +#if HAVE_LIMITS_H +# include +#endif + +#if STDC_HEADERS +# include +# include +# include +#else +# define memcpy(d, s, n) bcopy ((s), (d), (n)) +#endif + +#ifndef __P +# if defined (__GNUC__) || (defined (__STDC__) && __STDC__) +# define __P(args) args +# else +# define __P(args) () +# endif /* GCC. */ +#endif /* Not __P. */ + +#ifndef PTR +# ifdef __STDC__ +# define PTR void * +# else +# define PTR char * +# endif +#endif + +#ifndef CHAR_BIT +# define CHAR_BIT 8 +#endif + +#ifndef NULL +# define NULL 0 +#endif + +#define TYPE_SIGNED(t) ((t) -1 < 0) + +/* Bound on length of the string representing an integer value of type t. + Subtract one for the sign bit if t is signed; + 302 / 1000 is log10 (2) rounded up; + add one for integer division truncation; + add one more for a minus sign if t is signed. */ +#define INT_STRLEN_BOUND(t) \ + ((sizeof (t) * CHAR_BIT - TYPE_SIGNED (t)) * 302 / 100 + 1 + TYPE_SIGNED (t)) + +#define TM_YEAR_BASE 1900 + +#ifndef __isleap +/* Nonzero if YEAR is a leap year (every 4 years, + except every 100th isn't, and every 400th is). */ +# define __isleap(year) \ + ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0)) +#endif + + +#ifdef _LIBC +# define gmtime_r __gmtime_r +# define localtime_r __localtime_r +extern int __tz_compute __P ((time_t timer, const struct tm *tm)); +# define tzname __tzname +# define tzset __tzset +#else +# if ! HAVE_LOCALTIME_R +# if ! HAVE_TM_GMTOFF +/* Approximate gmtime_r as best we can in its absence. */ +# define gmtime_r my_gmtime_r +static struct tm *gmtime_r __P ((const time_t *, struct tm *)); +static struct tm * +gmtime_r (const time_t *t, struct tm *tp) +{ + struct tm *l = gmtime (t); + if (! l) + return 0; + *tp = *l; + return tp; +} +# endif /* ! HAVE_TM_GMTOFF */ + +/* Approximate localtime_r as best we can in its absence. */ +# define localtime_r my_localtime_r +static struct tm *localtime_r __P ((const time_t *, struct tm *)); +static struct tm * +localtime_r (const time_t *t, struct tm *tp) +{ + struct tm *l = localtime (t); + if (! l) + return 0; + *tp = *l; + return tp; +} +# endif /* ! HAVE_LOCALTIME_R */ +#endif /* ! defined (_LIBC) */ + + +#if !defined (memset) && !HAVE_MEMSET && !_LIBC +/* Some systems lack the `memset' function and we don't want to + introduce additional dependencies. */ +static char const spaces[16] = " "; + +# define memset_space(P, Len) \ + do { \ + int _len = (Len); \ + \ + do \ + { \ + int _this = _len > 16 ? 16 : _len; \ + memcpy ((P), spaces, (size_t) _this); \ + (P) += _this; \ + _len -= _this; \ + } \ + while (_len > 0); \ + } while (false) +#else +# define memset_space(P, Len) memset ((P), ' ', (size_t) (Len)) +#endif + +#define add(n, f) \ + do \ + { \ + int _n = (n); \ + int _delta = width - _n; \ + int _incr = _n + (_delta > 0 ? _delta : 0); \ + if (i + _incr >= maxsize) \ + return 0; \ + if (p) \ + { \ + if (_delta > 0) \ + memset_space (p, _delta); \ + f; \ + p += _n; \ + } \ + i += _incr; \ + } while (false) + +#define cpy(n, s) \ + add ((n), \ + if (to_lowcase) \ + memcpy_lowcase (p, (s), (size_t) _n); \ + else if (to_uppcase) \ + memcpy_uppcase (p, (s), (size_t) _n); \ + else \ + memcpy ((PTR) p, (PTR) (s), (size_t) _n)) + + + +#ifdef _LIBC +# define TOUPPER(Ch) toupper (Ch) +# define TOLOWER(Ch) tolower (Ch) +#else +# define TOUPPER(Ch) (islower (Ch) ? toupper (Ch) : (Ch)) +# define TOLOWER(Ch) (isupper (Ch) ? tolower (Ch) : (Ch)) +#endif +/* We don't use `isdigit' here since the locale dependent + interpretation is not what we want here. We only need to accept + the arabic digits in the ASCII range. One day there is perhaps a + more reliable way to accept other sets of digits. */ +#define ISDIGIT(Ch) ((unsigned int) (Ch) - '0' <= 9) + +static char *memcpy_lowcase __P ((char *dest, char const *src, size_t len)); + +static char * +memcpy_lowcase (char *dest, char const *src, size_t len) +{ + while (len-- > 0) + dest[len] = TOLOWER (src[len]); + return dest; +} + +static char *memcpy_uppcase __P ((char *dest, char const *src, size_t len)); + +static char * +memcpy_uppcase (char *dest, char const *src, size_t len) +{ + while (len-- > 0) + dest[len] = TOUPPER (src[len]); + return dest; +} + +#if ! HAVE_TM_GMTOFF +/* Yield the difference between *A and *B, + measured in seconds, ignoring leap seconds. */ +static int tm_diff __P ((const struct tm *, const struct tm *)); +static int +tm_diff (const struct tm *a, const struct tm *b) +{ + /* Compute intervening leap days correctly even if year is negative. + Take care to avoid int overflow in leap day calculations, + but it's OK to assume that A and B are close to each other. */ + int a4 = (a->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (a->tm_year & 3); + int b4 = (b->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (b->tm_year & 3); + int a100 = a4 / 25 - (a4 % 25 < 0); + int b100 = b4 / 25 - (b4 % 25 < 0); + int a400 = a100 >> 2; + int b400 = b100 >> 2; + int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400); + int years = a->tm_year - b->tm_year; + int days = (365 * years + intervening_leap_days + + (a->tm_yday - b->tm_yday)); + return (60 * (60 * (24 * days + (a->tm_hour - b->tm_hour)) + + (a->tm_min - b->tm_min)) + + (a->tm_sec - b->tm_sec)); +} +#endif /* ! HAVE_TM_GMTOFF */ + + + +/* The number of days from the first day of the first ISO week of this + year to the year day YDAY with week day WDAY. ISO weeks start on + Monday; the first ISO week has the year's first Thursday. YDAY may + be as small as YDAY_MINIMUM. */ +#define ISO_WEEK_START_WDAY 1 /* Monday */ +#define ISO_WEEK1_WDAY 4 /* Thursday */ +#define YDAY_MINIMUM (-366) +static int iso_week_days __P ((int, int)); +#ifdef __GNUC__ +inline +#endif +static int +iso_week_days (int yday, int wday) +{ + /* Add enough to the first operand of % to make it nonnegative. */ + int big_enough_multiple_of_7 = (-YDAY_MINIMUM / 7 + 2) * 7; + return (yday + - (yday - wday + ISO_WEEK1_WDAY + big_enough_multiple_of_7) % 7 + + ISO_WEEK1_WDAY - ISO_WEEK_START_WDAY); +} + + +#ifndef _NL_CURRENT +static char const weekday_name[][10] = + { + "Sunday", "Monday", "Tuesday", "Wednesday", + "Thursday", "Friday", "Saturday" + }; +static char const month_name[][10] = + { + "January", "February", "March", "April", "May", "June", + "July", "August", "September", "October", "November", "December" + }; +#endif + + +#if !defined _LIBC && HAVE_TZNAME && HAVE_TZSET + /* Solaris 2.5 tzset sometimes modifies the storage returned by localtime. + Work around this bug by copying *tp before it might be munged. */ + size_t _strftime_copytm __P ((char *, size_t, char const *, + const struct tm *)); + size_t + strftime (s, maxsize, format, tp) + char *s; + size_t maxsize; + char const *format; + const struct tm *tp; + { + struct tm tmcopy; + tmcopy = *tp; + return _strftime_copytm (s, maxsize, format, &tmcopy); +} +# ifdef strftime +# undef strftime +# endif +# define strftime _strftime_copytm +#endif + + + +/* Write information from TP into S according to the format + string FORMAT, writing no more that MAXSIZE characters + (including the terminating '\0') and returning number of + characters written. If S is NULL, nothing will be written + anywhere, so to determine how many characters would be + written, use NULL for S and (size_t) UINT_MAX for MAXSIZE. */ +size_t +strftime (char *s, size_t maxsize, char const *format, const struct tm *tp) +{ + int hour12 = tp->tm_hour; +#ifdef _NL_CURRENT + char const *const a_wkday = _NL_CURRENT (LC_TIME, ABDAY_1 + tp->tm_wday); + char const *const f_wkday = _NL_CURRENT (LC_TIME, DAY_1 + tp->tm_wday); + char const *const a_month = _NL_CURRENT (LC_TIME, ABMON_1 + tp->tm_mon); + char const *const f_month = _NL_CURRENT (LC_TIME, MON_1 + tp->tm_mon); + char const *const ampm = _NL_CURRENT (LC_TIME, + hour12 > 11 ? PM_STR : AM_STR); + size_t aw_len = strlen (a_wkday); + size_t am_len = strlen (a_month); + size_t ap_len = strlen (ampm); +#else + char const *const f_wkday = weekday_name[tp->tm_wday]; + char const *const f_month = month_name[tp->tm_mon]; + char const *const a_wkday = f_wkday; + char const *const a_month = f_month; + char const *const ampm = "AMPM" + 2 * (hour12 > 11); + size_t aw_len = 3; + size_t am_len = 3; + size_t ap_len = 2; +#endif + size_t wkday_len = strlen (f_wkday); + size_t month_len = strlen (f_month); + char const *zone; + size_t zonelen; + size_t i = 0; + char *p = s; + char const *f; + + zone = NULL; +#if !defined _LIBC && HAVE_TM_ZONE + /* XXX We have some problems here. First, the string pointed to by + tm_zone is dynamically allocated while loading the zone data. But + when another zone is loaded since the information in TP were + computed this would be a stale pointer. + The second problem is the POSIX test suite which assumes setting + the environment variable TZ to a new value before calling strftime() + will influence the result (the %Z format) even if the information in + TP is computed with a totally different time zone. --drepper@gnu */ + zone = (char const *) tp->tm_zone; +#endif +#if HAVE_TZNAME + /* POSIX.1 8.1.1 requires that whenever strftime() is called, the + time zone names contained in the external variable `tzname' shall + be set as if the tzset() function had been called. */ +# if HAVE_TZSET + tzset (); +# endif + + if (!(zone && *zone) && tp->tm_isdst >= 0) + zone = tzname[tp->tm_isdst]; +#endif + if (! zone) + zone = ""; /* POSIX.2 requires the empty string here. */ + + zonelen = strlen (zone); + + if (hour12 > 12) + hour12 -= 12; + else + if (hour12 == 0) hour12 = 12; + + for (f = format; *f != '\0'; ++f) + { + int pad; /* Padding for number ('-', '_', or 0). */ + int modifier; /* Field modifier ('E', 'O', or 0). */ + int digits; /* Max digits for numeric format. */ + int number_value; /* Numeric value to be printed. */ + int negative_number; /* 1 if the number is negative. */ + char const *subfmt; + char *bufp; + char buf[1 + (sizeof (int) < sizeof (time_t) + ? INT_STRLEN_BOUND (time_t) + : INT_STRLEN_BOUND (int))]; + int width = -1; + int to_lowcase = 0; + int to_uppcase = 0; + +#if DO_MULTIBYTE + + switch (*f) + { + case '%': + break; + +#if __STDC__ + case '\a': +#else + case 7: /* '\a' is ASCII decimal value 7. */ +#endif + case '\b': case '\t': case '\n': + case '\v': case '\f': case '\r': + 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 '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 '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 '~': + /* The C Standard requires these 98 characters (plus '%') to + be in the basic execution character set. None of these + characters can start a multibyte sequence, so they need + not be analyzed further. */ + add (1, *p = *f); + continue; + + default: + /* Copy this multibyte sequence until we reach its end, find + an error, or come back to the initial shift state. */ + { + mbstate_t mbstate = mbstate_zero; + size_t len = 0; + + do + { + size_t bytes = mbrlen (f + len, (size_t) -1, &mbstate); + + if (bytes == 0) + break; + + if (bytes == (size_t) -2 || bytes == (size_t) -1) + { + len++; + break; + } + + len += bytes; + } + while (! mbsinit (&mbstate)); + + cpy (len, f); + continue; + } + } + +#else /* ! DO_MULTIBYTE */ + + /* Either multibyte encodings are not supported, or they are + safe for formats, so any non-'%' byte can be copied through. */ + if (*f != '%') + { + add (1, *p = *f); + continue; + } + +#endif /* ! DO_MULTIBYTE */ + + /* Check for flags that can modify a format. */ + pad = 0; + while (1) + { + switch (*++f) + { + /* This influences the number formats. */ + case '_': + case '-': + case '0': + pad = *f; + continue; + + /* This changes textual output. */ + case '^': + to_uppcase = 1; + continue; + + default: + break; + } + break; + } + + /* As a GNU extension we allow to specify the field width. */ + if (ISDIGIT (*f)) + { + width = 0; + do + { + width *= 10; + width += *f - '0'; + ++f; + } + while (ISDIGIT (*f)); + } + + /* Check for modifiers. */ + switch (*f) + { + case 'E': + case 'O': + modifier = *f++; + break; + + default: + modifier = 0; + break; + } + + /* Now do the specified format. */ + switch (*f) + { +#define DO_NUMBER(d, v) \ + digits = d; number_value = v; goto do_number +#define DO_NUMBER_SPACEPAD(d, v) \ + digits = d; number_value = v; goto do_number_spacepad + + case '%': + if (modifier != 0) + goto bad_format; + add (1, *p = *f); + break; + + case 'a': + if (modifier != 0) + goto bad_format; + cpy (aw_len, a_wkday); + break; + + case 'A': + if (modifier != 0) + goto bad_format; + cpy (wkday_len, f_wkday); + break; + + case 'b': + case 'h': /* POSIX.2 extension. */ + if (modifier != 0) + goto bad_format; + cpy (am_len, a_month); + break; + + case 'B': + if (modifier != 0) + goto bad_format; + cpy (month_len, f_month); + break; + + case 'c': + if (modifier == 'O') + goto bad_format; +#ifdef _NL_CURRENT + if (! (modifier == 'E' + && *(subfmt = _NL_CURRENT (LC_TIME, ERA_D_T_FMT)) != '\0')) + subfmt = _NL_CURRENT (LC_TIME, D_T_FMT); +#else + subfmt = "%a %b %e %H:%M:%S %Y"; +#endif + + subformat: + { + char *old_start = p; + size_t len = strftime (NULL, maxsize - i, subfmt, tp); + if (len == 0 && *subfmt) + return 0; + add (len, strftime (p, maxsize - i, subfmt, tp)); + + if (to_uppcase) + while (old_start < p) + { + *old_start = TOUPPER (*old_start); + ++old_start; + } + } + break; + + case 'C': /* POSIX.2 extension. */ + if (modifier == 'O') + goto bad_format; +#if HAVE_STRUCT_ERA_ENTRY + if (modifier == 'E') + { + struct era_entry *era = _nl_get_era_entry (tp); + if (era) + { + size_t len = strlen (era->name_fmt); + cpy (len, era->name_fmt); + break; + } + } +#endif + { + int year = tp->tm_year + TM_YEAR_BASE; + DO_NUMBER (1, year / 100 - (year % 100 < 0)); + } + + case 'x': + if (modifier == 'O') + goto bad_format; +#ifdef _NL_CURRENT + if (! (modifier == 'E' + && *(subfmt = _NL_CURRENT (LC_TIME, ERA_D_FMT)) != '\0')) + subfmt = _NL_CURRENT (LC_TIME, D_FMT); + goto subformat; +#endif + /* Fall through. */ + case 'D': /* POSIX.2 extension. */ + if (modifier != 0) + goto bad_format; + subfmt = "%m/%d/%y"; + goto subformat; + + case 'd': + if (modifier == 'E') + goto bad_format; + + DO_NUMBER (2, tp->tm_mday); + + case 'e': /* POSIX.2 extension. */ + if (modifier == 'E') + goto bad_format; + + DO_NUMBER_SPACEPAD (2, tp->tm_mday); + + /* All numeric formats set DIGITS and NUMBER_VALUE and then + jump to one of these two labels. */ + + do_number_spacepad: + /* Force `_' flag unless overwritten by `0' flag. */ + if (pad != '0') + pad = '_'; + + do_number: + /* Format the number according to the MODIFIER flag. */ + +#ifdef _NL_CURRENT + if (modifier == 'O' && 0 <= number_value) + { + /* Get the locale specific alternate representation of + the number NUMBER_VALUE. If none exist NULL is returned. */ + char const *cp = _nl_get_alt_digit (number_value); + + if (cp != NULL) + { + size_t digitlen = strlen (cp); + if (digitlen != 0) + { + cpy (digitlen, cp); + break; + } + } + } +#endif + { + unsigned int u = number_value; + + bufp = buf + sizeof (buf); + negative_number = number_value < 0; + + if (negative_number) + u = -u; + + do + *--bufp = u % 10 + '0'; + while ((u /= 10) != 0); + } + + do_number_sign_and_padding: + if (negative_number) + *--bufp = '-'; + + if (pad != '-') + { + int padding = digits - (buf + sizeof (buf) - bufp); + + if (pad == '_') + { + while (0 < padding--) + *--bufp = ' '; + } + else + { + bufp += negative_number; + while (0 < padding--) + *--bufp = '0'; + if (negative_number) + *--bufp = '-'; + } + } + + cpy (buf + sizeof (buf) - bufp, bufp); + break; + + + case 'H': + if (modifier == 'E') + goto bad_format; + + DO_NUMBER (2, tp->tm_hour); + + case 'I': + if (modifier == 'E') + goto bad_format; + + DO_NUMBER (2, hour12); + + case 'k': /* GNU extension. */ + if (modifier == 'E') + goto bad_format; + + DO_NUMBER_SPACEPAD (2, tp->tm_hour); + + case 'l': /* GNU extension. */ + if (modifier == 'E') + goto bad_format; + + DO_NUMBER_SPACEPAD (2, hour12); + + case 'j': + if (modifier == 'E') + goto bad_format; + + DO_NUMBER (3, 1 + tp->tm_yday); + + case 'M': + if (modifier == 'E') + goto bad_format; + + DO_NUMBER (2, tp->tm_min); + + case 'm': + if (modifier == 'E') + goto bad_format; + + DO_NUMBER (2, tp->tm_mon + 1); + + case 'n': /* POSIX.2 extension. */ + add (1, *p = '\n'); + break; + + case 'P': + to_lowcase = 1; + /* FALLTHROUGH */ + + case 'p': + cpy (ap_len, ampm); + break; + + case 'R': /* GNU extension. */ + subfmt = "%H:%M"; + goto subformat; + + case 'r': /* POSIX.2 extension. */ +#ifdef _NL_CURRENT + if (*(subfmt = _NL_CURRENT (LC_TIME, T_FMT_AMPM)) == '\0') +#endif + subfmt = "%I:%M:%S %p"; + goto subformat; + + case 'S': + if (modifier == 'E') + goto bad_format; + + DO_NUMBER (2, tp->tm_sec); + + case 's': /* GNU extension. */ + { + struct tm ltm; + time_t t; + + ltm = *tp; + t = mktime (<m); + + /* Generate string value for T using time_t arithmetic; + this works even if sizeof (long) < sizeof (time_t). */ + + bufp = buf + sizeof (buf); + negative_number = t < 0; + + do + { + int d = t % 10; + t /= 10; + + if (negative_number) + { + d = -d; + + /* Adjust if division truncates to minus infinity. */ + if (0 < -1 % 10 && d < 0) + { + t++; + d += 10; + } + } + + *--bufp = d + '0'; + } + while (t != 0); + + digits = 1; + goto do_number_sign_and_padding; + } + + case 'X': + if (modifier == 'O') + goto bad_format; +#ifdef _NL_CURRENT + if (! (modifier == 'E' + && *(subfmt = _NL_CURRENT (LC_TIME, ERA_T_FMT)) != '\0')) + subfmt = _NL_CURRENT (LC_TIME, T_FMT); + goto subformat; +#endif + /* Fall through. */ + case 'T': /* POSIX.2 extension. */ + subfmt = "%H:%M:%S"; + goto subformat; + + case 't': /* POSIX.2 extension. */ + add (1, *p = '\t'); + break; + + case 'u': /* POSIX.2 extension. */ + DO_NUMBER (1, (tp->tm_wday - 1 + 7) % 7 + 1); + + case 'U': + if (modifier == 'E') + goto bad_format; + + DO_NUMBER (2, (tp->tm_yday - tp->tm_wday + 7) / 7); + + case 'V': + case 'g': /* GNU extension. */ + case 'G': /* GNU extension. */ + if (modifier == 'E') + goto bad_format; + { + int year = tp->tm_year + TM_YEAR_BASE; + int days = iso_week_days (tp->tm_yday, tp->tm_wday); + + if (days < 0) + { + /* This ISO week belongs to the previous year. */ + year--; + days = iso_week_days (tp->tm_yday + (365 + __isleap (year)), + tp->tm_wday); + } + else + { + int d = iso_week_days (tp->tm_yday - (365 + __isleap (year)), + tp->tm_wday); + if (0 <= d) + { + /* This ISO week belongs to the next year. */ + year++; + days = d; + } + } + + switch (*f) + { + case 'g': + DO_NUMBER (2, (year % 100 + 100) % 100); + + case 'G': + DO_NUMBER (1, year); + + default: + DO_NUMBER (2, days / 7 + 1); + } + } + + case 'W': + if (modifier == 'E') + goto bad_format; + + DO_NUMBER (2, (tp->tm_yday - (tp->tm_wday - 1 + 7) % 7 + 7) / 7); + + case 'w': + if (modifier == 'E') + goto bad_format; + + DO_NUMBER (1, tp->tm_wday); + + case 'Y': +#if HAVE_STRUCT_ERA_ENTRY + if (modifier == 'E') + { + struct era_entry *era = _nl_get_era_entry (tp); + if (era) + { + subfmt = strchr (era->name_fmt, '\0') + 1; + goto subformat; + } + } +#endif + if (modifier == 'O') + goto bad_format; + else + DO_NUMBER (1, tp->tm_year + TM_YEAR_BASE); + + case 'y': +#if HAVE_STRUCT_ERA_ENTRY + if (modifier == 'E') + { + struct era_entry *era = _nl_get_era_entry (tp); + if (era) + { + int delta = tp->tm_year - era->start_date[0]; + DO_NUMBER (1, (era->offset + + (era->direction == '-' ? -delta : delta))); + } + } +#endif + DO_NUMBER (2, (tp->tm_year % 100 + 100) % 100); + + case 'Z': + cpy (zonelen, zone); + break; + + case 'z': /* GNU extension. */ + if (tp->tm_isdst < 0) + break; + + { + int diff; +#if HAVE_TM_GMTOFF + diff = tp->tm_gmtoff; +#else + struct tm gtm; + struct tm ltm; + time_t lt; + + ltm = *tp; + lt = mktime (<m); + + if (lt == (time_t) -1) + { + /* mktime returns -1 for errors, but -1 is also a + valid time_t value. Check whether an error really + occurred. */ + struct tm tm; + localtime_r (<, &tm); + + if ((ltm.tm_sec ^ tm.tm_sec) + | (ltm.tm_min ^ tm.tm_min) + | (ltm.tm_hour ^ tm.tm_hour) + | (ltm.tm_mday ^ tm.tm_mday) + | (ltm.tm_mon ^ tm.tm_mon) + | (ltm.tm_year ^ tm.tm_year)) + break; + } + + if (! gmtime_r (<, >m)) + break; + + diff = tm_diff (<m, >m); +#endif + + if (diff < 0) + { + add (1, *p = '-'); + diff = -diff; + } + else + add (1, *p = '+'); + + diff /= 60; + DO_NUMBER (4, (diff / 60) * 100 + diff % 60); + } + + case '\0': /* GNU extension: % at end of format. */ + --f; + /* Fall through. */ + default: + /* Unknown format; output the format, including the '%', + since this is most likely the right thing to do if a + multibyte string has been misparsed. */ + bad_format: + { + int flen; + for (flen = 1; f[1 - flen] != '%'; flen++) + continue; + cpy (flen, &f[1 - flen]); + } + break; + } + } + + if (p) + *p = '\0'; + return i; +} + +/* + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of compat/strftime.c */ diff --git a/compat/strsignal.c b/compat/strsignal.c new file mode 100644 index 0000000..7d785ee --- /dev/null +++ b/compat/strsignal.c @@ -0,0 +1,119 @@ + +/** + * \file strsignal.c + * + * This file is part of AutoGen. + * + * AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoGen 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. + * + * AutoGen is distributed in the hope that 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 . + * + * As a special exception, Bruce Korb gives permission for additional + * uses of the text contained in the release of strsignal. + * + * The exception is that, if you link the strsignal 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 strsignal 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 Bruce Korb under + * the name strsignal. If you copy code from other sources under the + * General Public License into a copy of strsignal, 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 strsignal, it is your choice + * whether to permit this exception to apply to your modifications. + * If you do not wish that, delete this exception notice. + */ + +#include "compat.h" + +/* Routines imported from standard C runtime libraries. */ + +#if ! defined(HAVE_STRSIGNAL) + +#ifdef __STDC__ +# include +#else /* !__STDC__ */ +# ifndef const +# define const +# endif +#endif /* __STDC__ */ + +#ifdef HAVE_SYS_SIGLIST +# include +#endif + +/* + * Import the generated tables + */ +#include "strsignal.h" +#endif + +#ifndef HAVE_STRSIGNAL + +/* + +NAME + + strsignal -- map a signal number to a signal message string + +SYNOPSIS + + char *strsignal (int signo) + +DESCRIPTION + + Maps an signal number to an signal message string, the contents of + which are implementation defined. On systems which have the external + variable sys_siglist, these strings will be the same as the ones used + by psignal(). + + If the supplied signal number is within the valid range of indices + for the sys_siglist, but no message is available for the particular + signal number, then returns the string "Signal NUM", where NUM is the + signal number. + + If the supplied signal number is not a valid index into sys_siglist, + returns NULL. + + The returned string is only guaranteed to be valid only until the + next call to strsignal. + + Also, though not declared "const", it is. +*/ + +char * +strsignal( int signo ) +{ + if (SIGNAL_IN_RANGE( signo )) + return (char *)SIGNAL_INFO( signo ); + + return NULL; +} +#endif /* HAVE_STRSIGNAL */ + +/* + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of compat/strsignal.c */ diff --git a/compat/strsignal.def b/compat/strsignal.def new file mode 100644 index 0000000..19f2f0e --- /dev/null +++ b/compat/strsignal.def @@ -0,0 +1,151 @@ +autogen definitions strsignal; + +/* + * Dynamic definitions for creating the strsignal.h header file + * + * This file is part of AutoGen. + * + * AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoGen 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. + * + * AutoGen is distributed in the hope that 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 . + */ + +#shell + +RE_sigfind=$'[A-Z12]+[ \t]+[1-9][0-9]*' +RE_sigdef=$'^#[ \t]*define[ \t][ \t]*_*SIG' +RE_inc=$'^#[ \t]*include[ \t][ \t]*<' + +threshold=5 # minimum number of signals to accept +num=0 # number of signals defined in this file +seen="" # include files already searched +files="sys/signal.h" # initial files to search + +cd /usr/include +while test -n "$files" +do + for file in $files; do + # look for $threshold or more matches in one of the search files + test -f $file || continue + sigs=`egrep "$RE_sigdef$RE_sigfind" $file|sed "s,$RE_sigdef,,"` + test -z "$sigs" || num=`echo "$sigs" | wc -l` + test $num -lt $threshold || break + seen="$file $seen" + done + test $num -lt $threshold || break + + # IF no file has $threshold or better SIG matches; + # generate a new search list from all files #included from the old list + newfiles="" + for file in $files; do + test -f $file || continue + new=`egrep "$RE_inc" $file|sed "s,$RE_inc,,"';s,>.*$,,'` + newfiles=" $new $newfiles" + done + + # remove any files that have been searched previously + for file in $seen; do + newfiles=`echo "$newfiles"|sed "s, $file , ,g"` + done + + # set the search list for the next iteration + files="$newfiles" + num=0 +done + +if test $num -lt $threshold +then + echo "WARNING: cannot find signal definitions in $seen" >&2 + echo "using POSIX + ANSI signal definitions" >&2 + cat <<- _EOF_ + signal[ 1 ] = { signame = SIGHUP; + sigtext = "Hangup (POSIX)."; }; + signal[ 2 ] = { signame = SIGINT; + sigtext = "Interrupt (ANSI)."; }; + signal[ 3 ] = { signame = SIGQUIT; + sigtext = "Quit (POSIX)."; }; + signal[ 4 ] = { signame = SIGILL; + sigtext = "Illegal instruction (ANSI)."; }; + signal[ 5 ] = { signame = SIGTRAP; + sigtext = "Trace trap (POSIX)."; }; + signal[ 6 ] = { signame = SIGABRT; + sigtext = "Abort (ANSI)."; }; + signal[ 8 ] = { signame = SIGFPE; + sigtext = "Floating-point exception (ANSI)."; }; + signal[ 9 ] = { signame = SIGKILL; + sigtext = "Kill, unblockable (POSIX)."; }; + signal[ 10 ] = { signame = SIGUSR1; + sigtext = "User-defined signal 1 (POSIX)."; }; + signal[ 11 ] = { signame = SIGSEGV; + sigtext = "Segmentation violation (ANSI)."; }; + signal[ 12 ] = { signame = SIGUSR2; + sigtext = "User-defined signal 2 (POSIX)."; }; + signal[ 13 ] = { signame = SIGPIPE; + sigtext = "Broken pipe (POSIX)."; }; + signal[ 14 ] = { signame = SIGALRM; + sigtext = "Alarm clock (POSIX)."; }; + signal[ 15 ] = { signame = SIGTERM; + sigtext = "Termination (ANSI)."; }; + signal[ 17 ] = { signame = SIGCHLD; + sigtext = "Child status has changed (POSIX)."; }; + signal[ 18 ] = { signame = SIGCONT; + sigtext = "Continue (POSIX)."; }; + signal[ 19 ] = { signame = SIGSTOP; + sigtext = "Stop, unblockable (POSIX)."; }; + signal[ 20 ] = { signame = SIGTSTP; + sigtext = "Keyboard stop (POSIX)."; }; + signal[ 21 ] = { signame = SIGTTIN; + sigtext = "Background read from tty (POSIX)."; }; + signal[ 22 ] = { signame = SIGTTOU; + sigtext = "Background write to tty (POSIX)."; }; +_EOF_ + +else + echo "$sigs" | + while read SIG NUM f + do + # IF the "signal number" is octal or hex or non-numeric, + # THEN we know it is a value we are not interested in + # + case ${NUM} in + *[A-Za-z_]* ) + continue ;; + esac + + # Sometimes, there are aliases. Accept only the first. + # + if eval test ! -z \"\$HAVE_${NUM}\" + then continue ; fi + + # We also know we are not interested in super large numbers + # (e.g. SIGSTKSZ 8192) + # + if test ${NUM} -gt 127 + then continue ; fi + + eval HAVE_${NUM}=1 + f=`echo "$f" | sed -e 's;/\*[ ]*;;' -e 's;[ ]*\*/;;'` + if test -z "$f" + then f="Undescribed: SIG${SIG} (${NUM})" ; fi + + cat <<- _EOF_ + signal[ ${NUM} ] = { + signame = ${SIG}; + sigtext = "$f"; + }; + + _EOF_ + done +fi +#endshell diff --git a/compat/strsignal.h b/compat/strsignal.h new file mode 100644 index 0000000..466bf15 --- /dev/null +++ b/compat/strsignal.h @@ -0,0 +1,96 @@ +/* -*- buffer-read-only: t -*- vi: set ro: + * + * DO NOT EDIT THIS FILE (strsignal.h) + * + * It has been AutoGen-ed + * From the definitions strsignal.def + * and the template file strsignal + * + * Generated for a 4.15.0-20-generic Linux platform + * + * strsignal Copyright (C) 1992-2017 by Bruce Korb - all rights reserved + * + * AutoGen 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. + * + * AutoGen is distributed in the hope that 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 . + */ +#ifndef MAX_SIGNAL_NUMBER +#define MAX_SIGNAL_NUMBER 22 +#define SIGNAL_IN_RANGE(s) (((unsigned)s) <= MAX_SIGNAL_NUMBER) +#define SIGNAL_NAME(s) (zSigNames + sigNameOffset[s]) +#define SIGNAL_INFO(s) (zSigInfo + sigInfoOffset[s]) + +static char const zSigNames[] = + "INVALID\0" "SIGSIGHUP\0" "SIGSIGINT\0" "SIGSIGQUIT\0" "SIGSIGILL\0" + "SIGSIGTRAP\0" "SIGSIGABRT\0" "SIGSIGFPE\0" "SIGSIGKILL\0" "SIGSIGUSR1\0" + "SIGSIGSEGV\0" "SIGSIGUSR2\0" "SIGSIGPIPE\0" "SIGSIGALRM\0" "SIGSIGTERM\0" + "SIGSIGCHLD\0" "SIGSIGCONT\0" "SIGSIGSTOP\0" "SIGSIGTSTP\0" "SIGSIGTTIN\0" + "SIGSIGTTOU\0"; + +static const unsigned int sigNameOffset[] = { + 0, 8, 18, 28, 39, 49, 60, 0, 71, 81, 92, 103, 114, 125, 136, + 147, 0, 158, 169, 180, 191, 202, 213 }; + +#ifndef HAVE_SYS_SIGLIST +static char const zSigInfo[] = + /* 0 */ "Signal 0 invalid\0" + /* 1 */ "Hangup (POSIX).\0" + /* 2 */ "Interrupt (ANSI).\0" + /* 3 */ "Quit (POSIX).\0" + /* 4 */ "Illegal instruction (ANSI).\0" + /* 5 */ "Trace trap (POSIX).\0" + /* 6 */ "Abort (ANSI).\0" + /* 7 */ "Signal 7 invalid\0" + /* 8 */ "Floating-point exception (ANSI).\0" + /* 9 */ "Kill, unblockable (POSIX).\0" + /* 10 */ "User-defined signal 1 (POSIX).\0" + /* 11 */ "Segmentation violation (ANSI).\0" + /* 12 */ "User-defined signal 2 (POSIX).\0" + /* 13 */ "Broken pipe (POSIX).\0" + /* 14 */ "Alarm clock (POSIX).\0" + /* 15 */ "Termination (ANSI).\0" + /* 16 */ "Signal 16 invalid\0" + /* 17 */ "Child status has changed (POSIX).\0" + /* 18 */ "Continue (POSIX).\0" + /* 19 */ "Stop, unblockable (POSIX).\0" + /* 20 */ "Keyboard stop (POSIX).\0" + /* 21 */ "Background read from tty (POSIX).\0" + /* 22 */ "Background write to tty (POSIX).\0"; + +static const unsigned int sigInfoOffset[] = { + 0, 17, 33, 51, 65, 93, 113, 127, 144, 177, 204, 235, 266, 297, 318, + 339, 359, 377, 411, 429, 456, 479, 513 }; + +#endif /* MAX_SIGNAL_NUMBER */ + +#ifndef HAVE_STRSIGNAL +extern char * strsignal( int signo ); +#endif + +#ifdef DEBUG_STRSIGNAL +#include + +int +main(int argc, char ** argv) +{ + int sig = 0; + fputs( "Sig Sig-Name Description\n" + "=== ======== ===========\n", stdout ); + do { + printf( "%3d %-10s %s\n", sig, SIGNAL_NAME(sig), + SIGNAL_INFO(sig) ); + ++sig; + } while (SIGNAL_IN_RANGE(sig)); + return 0; +} +#endif /* DEBUG */ +#endif /* MAX_SIGNAL_NUMBER */ diff --git a/compat/strsignal.tpl b/compat/strsignal.tpl new file mode 100644 index 0000000..87e6243 --- /dev/null +++ b/compat/strsignal.tpl @@ -0,0 +1,126 @@ +[= AutoGen5 template -*- Mode: html -*- + +h + +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen 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. +## +## AutoGen is distributed in the hope that 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 . + +(setenv "SHELL" "/bin/sh") + +=] +[=(dne " * " "/* ")=] + * + * Generated for a [=`uname -r`=] [=`uname`=] platform + * + * strsignal Copyright (C) 1992-2017 by Bruce Korb - all rights reserved + * +[=(gpl "AutoGen" " * ")=] + */ +#ifndef MAX_SIGNAL_NUMBER +#define MAX_SIGNAL_NUMBER [= (high-lim "signal") =] +#define SIGNAL_IN_RANGE(s) (((unsigned)s) <= MAX_SIGNAL_NUMBER) +#define SIGNAL_NAME(s) (zSigNames + sigNameOffset[s]) +#define SIGNAL_INFO(s) (zSigInfo + sigInfoOffset[s])[= + +(define sig-names "\"INVALID\\0\"\n") +(define name-refs "") +(define name-ix (- (string-length sig-names) 4)) +(define tmp-text "") + +(define sig-info "") +(define info-refs "") +(define info-ix 0) + +(define add-string (lambda() + (if (exist? "signame") + (begin + (set! tmp-text (string-append "\"SIG" (get "signame") "\\0\"\n")) + (set! sig-names (string-append sig-names tmp-text)) + (set! name-refs (string-append name-refs + (sprintf "%d\n" name-ix) )) + (set! name-ix (+ name-ix (string-length tmp-text) -4)) + + (set! tmp-text (sprintf "/* %3d */ \"%s\\0\"\n" + (for-index) (get "sigtext"))) + ) + + (begin + (set! name-refs (string-append name-refs "0\n")) + (set! tmp-text (sprintf "/* %1$3d */ \"Signal %1$d invalid\\0\"\n" + (for-index))) + ) ) + + (set! sig-info (string-append sig-info tmp-text)) + (set! info-refs (string-append info-refs + (sprintf "%d\n" info-ix) )) + (set! info-ix (+ info-ix (string-length tmp-text) -14)) +)) =][= + +FOR signal (for-from 0) (for-by 1) =][= + + (add-string) =][= + +ENDFOR signal =] + +static char const zSigNames[] = +[=(shell (string-append + "columns -I4 --spread=1 <<'_EOF_'\n" + sig-names + "_EOF_" )) =]; + +static const unsigned int sigNameOffset[] = { +[=(shell (string-append + "columns -I4 -S, --spread=1 <<'_EOF_'\n" + name-refs + "_EOF_" )) =] }; + +#ifndef HAVE_SYS_SIGLIST +static char const zSigInfo[] = +[=(shell (string-append + "columns -I4 --spread=1 <<'_EOF_'\n" + sig-info + "_EOF_" )) =]; + +static const unsigned int sigInfoOffset[] = { +[=(shell (string-append + "columns -I4 -S, --spread=1 <<'_EOF_'\n" + info-refs + "_EOF_" )) =] }; + +#endif /* MAX_SIGNAL_NUMBER */ + +#ifndef HAVE_STRSIGNAL +extern char * strsignal( int signo ); +#endif + +#ifdef DEBUG_STRSIGNAL +#include + +int +main(int argc, char ** argv) +{ + int sig = 0; + fputs( "Sig Sig-Name Description\n" + "=== ======== ===========\n", stdout ); + do { + printf( "%3d %-10s %s\n", sig, SIGNAL_NAME(sig), + SIGNAL_INFO(sig) ); + ++sig; + } while (SIGNAL_IN_RANGE(sig)); + return 0; +} +#endif /* DEBUG */ +#endif /* MAX_SIGNAL_NUMBER */ diff --git a/compat/unlocked-io.h b/compat/unlocked-io.h new file mode 100644 index 0000000..1fc1097 --- /dev/null +++ b/compat/unlocked-io.h @@ -0,0 +1,137 @@ +/* Prefer faster, non-thread-safe stdio functions if available. + + Copyright (C) 2001-2004, 2009-2012, 2014-2015, 2018 + 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. */ + +#ifndef UNLOCKED_IO_H +# define UNLOCKED_IO_H 1 + +/* These are wrappers for functions/macros from the GNU C library, and + from other C libraries supporting POSIX's optional thread-safe functions. + + The standard I/O functions are thread-safe. These *_unlocked ones are + more efficient but not thread-safe. That they're not thread-safe is + fine since all of the applications in this package are single threaded. + + Also, some code that is shared with the GNU C library may invoke + the *_unlocked functions directly. On hosts that lack those + functions, invoke the non-thread-safe versions instead. */ + +# include + +# if HAVE_DECL_CLEARERR_UNLOCKED +# undef clearerr +# define clearerr(x) clearerr_unlocked (x) +# else +# define clearerr_unlocked(x) clearerr (x) +# endif + +# if HAVE_DECL_FEOF_UNLOCKED +# undef feof +# define feof(x) feof_unlocked (x) +# else +# define feof_unlocked(x) feof (x) +# endif + +# if HAVE_DECL_FERROR_UNLOCKED +# undef ferror +# define ferror(x) ferror_unlocked (x) +# else +# define ferror_unlocked(x) ferror (x) +# endif + +# if HAVE_DECL_FFLUSH_UNLOCKED +# undef fflush +# define fflush(x) fflush_unlocked (x) +# else +# define fflush_unlocked(x) fflush (x) +# endif + +# if HAVE_DECL_FGETS_UNLOCKED +# undef fgets +# define fgets(x,y,z) fgets_unlocked (x,y,z) +# else +# define fgets_unlocked(x,y,z) fgets (x,y,z) +# endif + +# if HAVE_DECL_FPUTC_UNLOCKED +# undef fputc +# define fputc(x,y) fputc_unlocked (x,y) +# else +# define fputc_unlocked(x,y) fputc (x,y) +# endif + +# if HAVE_DECL_FPUTS_UNLOCKED +# undef fputs +# define fputs(x,y) fputs_unlocked (x,y) +# else +# define fputs_unlocked(x,y) fputs (x,y) +# endif + +# if HAVE_DECL_FREAD_UNLOCKED +# undef fread +# define fread(w,x,y,z) fread_unlocked (w,x,y,z) +# else +# define fread_unlocked(w,x,y,z) fread (w,x,y,z) +# endif + +# if HAVE_DECL_FWRITE_UNLOCKED +# undef fwrite +# define fwrite(w,x,y,z) fwrite_unlocked (w,x,y,z) +# else +# define fwrite_unlocked(w,x,y,z) fwrite (w,x,y,z) +# endif + +# if HAVE_DECL_GETC_UNLOCKED +# undef getc +# define getc(x) getc_unlocked (x) +# else +# define getc_unlocked(x) getc (x) +# endif + +# if HAVE_DECL_GETCHAR_UNLOCKED +# undef getchar +# define getchar() getchar_unlocked () +# else +# define getchar_unlocked() getchar () +# endif + +# if HAVE_DECL_PUTC_UNLOCKED +# undef putc +# define putc(x,y) putc_unlocked (x,y) +# else +# define putc_unlocked(x,y) putc (x,y) +# endif + +# if HAVE_DECL_PUTCHAR_UNLOCKED +# undef putchar +# define putchar(x) putchar_unlocked (x) +# else +# define putchar_unlocked(x) putchar (x) +# endif + +# undef flockfile +# define flockfile(x) ((void) 0) + +# undef ftrylockfile +# define ftrylockfile(x) 0 + +# undef funlockfile +# define funlockfile(x) ((void) 0) + +#endif /* UNLOCKED_IO_H */ diff --git a/compat/windows-config.h b/compat/windows-config.h new file mode 100644 index 0000000..7ce1636 --- /dev/null +++ b/compat/windows-config.h @@ -0,0 +1,144 @@ + +/** + * \file windows-config.h + * + * This file contains all of the routines that must be linked into + * an executable to use the generated option processing. The optional + * routines are in separately compiled modules so that they will not + * necessarily be linked in. + * + * This file is part of AutoOpts, a companion to AutoGen. + * AutoOpts is free software. + * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoOpts is available under any one of two licenses. The license + * in use must be one of these two and the choice is under the control + * of the user of the license. + * + * The GNU Lesser General Public License, version 3 or later + * See the files "COPYING.lgplv3" and "COPYING.gplv3" + * + * The Modified Berkeley Software Distribution License + * See the file "COPYING.mbsd" + * + * These files have the following sha256 sums: + * + * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 + * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 + * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + */ + +#ifndef WINDOWS_CONFIG_HACKERY +#define WINDOWS_CONFIG_HACKERY 1 + +/* + * The definitions below have been stolen from NTP's config.h for Windows. + * However, they may be kept here in order to keep libopts independent from + * the NTP project. + */ +#ifndef __windows__ +# define __windows__ 4 +#endif + +/* + * Miscellaneous functions that Microsoft maps to other names + */ +#define snprintf _snprintf + +#define SIZEOF_INT 4 +#define SIZEOF_CHARP 4 +#define SIZEOF_LONG 4 +#define SIZEOF_SHORT 2 + +#define HAVE_LIMITS_H 1 +#define HAVE_STRDUP 1 +#define HAVE_STRCHR 1 +#define HAVE_FCNTL_H 1 + +/* + * VS.NET's version of wspiapi.h has a bug in it where it assigns a value + * to a variable inside an if statement. It should be comparing them. + * We prevent inclusion since we are not using this code so we don't have + * to see the warning messages + */ +#ifndef _WSPIAPI_H_ +#define _WSPIAPI_H_ +#endif + +/* Prevent inclusion of winsock.h in windows.h */ +#ifndef _WINSOCKAPI_ +#define _WINSOCKAPI_ +#endif + +#ifndef __RPCASYNC_H__ +#define __RPCASYNC_H__ +#endif + +/* Include Windows headers */ +#include +#include +#include + +/* + * Compatibility declarations for Windows, assuming SYS_WINNT + * has been defined. + */ +#define strdup _strdup +#define stat _stat /* struct stat from */ +#define unlink _unlink +#define fchmod( _x, _y ) +#define ssize_t SSIZE_T + +#include +#define open _open +#define close _close +#define read _read +#define write _write +#define lseek _lseek +#define pipe _pipe +#define dup2 _dup2 + +#define O_RDWR _O_RDWR +#define O_RDONLY _O_RDONLY +#define O_EXCL _O_EXCL + +#ifndef S_ISREG +# define S_IFREG _S_IFREG +# define S_ISREG(mode) (((mode) & S_IFREG) == S_IFREG) +#endif + +#ifndef S_ISDIR +# define S_IFDIR _S_IFDIR +# define S_ISDIR(mode) (((mode) & S_IFDIR) == S_IFDIR) +#endif + +/* C99 exact size integer support. */ +#if defined(HAVE_INTTYPES_H) +# include + +#elif defined(HAVE_STDINT_H) +# include +# define MISSING_INTTYPES_H 1 + +#elif ! defined(ADDED_EXACT_SIZE_INTEGERS) +# define ADDED_EXACT_SIZE_INTEGERS 1 +# define MISSING_INTTYPES_H 1 + + typedef __int8 int8_t; + typedef unsigned __int8 uint8_t; + + typedef __int16 int16_t; + typedef unsigned __int16 uint16_t; + + typedef __int32 int32_t; + typedef unsigned __int32 uint32_t; + + typedef __int64 int64_t; + typedef unsigned __int64 uint64_t; + + typedef unsigned long uintptr_t; + typedef long intptr_t; +#endif + +#endif /* WINDOWS_CONFIG_HACKERY */ +/* windows-config.h ends here */ diff --git a/config-h.in b/config-h.in new file mode 100644 index 0000000..afd32d0 --- /dev/null +++ b/config-h.in @@ -0,0 +1,759 @@ +/* config-h.in. Generated from configure.ac by autoheader. */ + +/* CPU and C ABI indicator */ +#ifndef __i386__ +#undef __i386__ +#endif +#ifndef __x86_64_x32__ +#undef __x86_64_x32__ +#endif +#ifndef __x86_64__ +#undef __x86_64__ +#endif +#ifndef __alpha__ +#undef __alpha__ +#endif +#ifndef __arm__ +#undef __arm__ +#endif +#ifndef __armhf__ +#undef __armhf__ +#endif +#ifndef __arm64_ilp32__ +#undef __arm64_ilp32__ +#endif +#ifndef __arm64__ +#undef __arm64__ +#endif +#ifndef __hppa__ +#undef __hppa__ +#endif +#ifndef __hppa64__ +#undef __hppa64__ +#endif +#ifndef __ia64_ilp32__ +#undef __ia64_ilp32__ +#endif +#ifndef __ia64__ +#undef __ia64__ +#endif +#ifndef __m68k__ +#undef __m68k__ +#endif +#ifndef __mips__ +#undef __mips__ +#endif +#ifndef __mipsn32__ +#undef __mipsn32__ +#endif +#ifndef __mips64__ +#undef __mips64__ +#endif +#ifndef __powerpc__ +#undef __powerpc__ +#endif +#ifndef __powerpc64__ +#undef __powerpc64__ +#endif +#ifndef __powerpc64_elfv2__ +#undef __powerpc64_elfv2__ +#endif +#ifndef __riscv32__ +#undef __riscv32__ +#endif +#ifndef __riscv64__ +#undef __riscv64__ +#endif +#ifndef __riscv32_ilp32__ +#undef __riscv32_ilp32__ +#endif +#ifndef __riscv32_ilp32f__ +#undef __riscv32_ilp32f__ +#endif +#ifndef __riscv32_ilp32d__ +#undef __riscv32_ilp32d__ +#endif +#ifndef __riscv64_ilp32__ +#undef __riscv64_ilp32__ +#endif +#ifndef __riscv64_ilp32f__ +#undef __riscv64_ilp32f__ +#endif +#ifndef __riscv64_ilp32d__ +#undef __riscv64_ilp32d__ +#endif +#ifndef __riscv64_lp64__ +#undef __riscv64_lp64__ +#endif +#ifndef __riscv64_lp64f__ +#undef __riscv64_lp64f__ +#endif +#ifndef __riscv64_lp64d__ +#undef __riscv64_lp64d__ +#endif +#ifndef __s390__ +#undef __s390__ +#endif +#ifndef __s390x__ +#undef __s390x__ +#endif +#ifndef __sh__ +#undef __sh__ +#endif +#ifndef __sparc__ +#undef __sparc__ +#endif +#ifndef __sparc64__ +#undef __sparc64__ +#endif + + +#ifndef AUTOGEN_CONFIG_H + +#define AUTOGEN_CONFIG_H 1 + +/* define to suitable timeout limit for shell command */ +#undef AG_DEFAULT_TIMEOUT + +/* Define this to the autoopts interface age number */ +#undef AO_AGE + +/* Define this to the autoopts current interface number */ +#undef AO_CURRENT + +/* Define this to the autoopts interface revision number */ +#undef AO_REVISION + +/* format_arg attribute wrapper */ +#undef ATTRIBUTE_FORMAT_ARG + +/* Define this to a working Bourne shell */ +#undef CONFIG_SHELL + +/* Define this if debugging is enabled */ +#undef DEBUG_ENABLED + +/* "Define if we can use it" */ +#undef ENABLE_FMEMOPEN + +/* nls support in libopts */ +#undef ENABLE_NLS + +/* fopen(3) accepts a 'b' in the mode flag */ +#undef FOPEN_BINARY_FLAG + +/* fopen(3) accepts a 't' in the mode flag */ +#undef FOPEN_TEXT_FLAG + +/* define to a single number for Guile version */ +#undef GUILE_VERSION + +/* Define to 1 if you have the header file. */ +#undef HAVE_ASSERT_H + +/* Define to 1 if you have the `canonicalize_file_name' function. */ +#undef HAVE_CANONICALIZE_FILE_NAME + +/* Define to 1 if you have the `chmod' function. */ +#undef HAVE_CHMOD + +/* Define to 1 if you have the `clock_gettime' function. */ +#undef HAVE_CLOCK_GETTIME + +/* Define to 1 if you have the `copysign' function. */ +#undef HAVE_COPYSIGN + +/* Define to 1 if you have the `copysignl' function. */ +#undef HAVE_COPYSIGNL + +/* Define to 1 if you have the header file. */ +#undef HAVE_CTYPE_H + +/* Define to 1 if you have the declaration of `clearerr_unlocked', and to 0 if + you don't. */ +#undef HAVE_DECL_CLEARERR_UNLOCKED + +/* Define to 1 if you have the declaration of `feof_unlocked', and to 0 if you + don't. */ +#undef HAVE_DECL_FEOF_UNLOCKED + +/* Define to 1 if you have the declaration of `ferror_unlocked', and to 0 if + you don't. */ +#undef HAVE_DECL_FERROR_UNLOCKED + +/* Define to 1 if you have the declaration of `fflush_unlocked', and to 0 if + you don't. */ +#undef HAVE_DECL_FFLUSH_UNLOCKED + +/* Define to 1 if you have the declaration of `fgets_unlocked', and to 0 if + you don't. */ +#undef HAVE_DECL_FGETS_UNLOCKED + +/* Define to 1 if you have the declaration of `fputc_unlocked', and to 0 if + you don't. */ +#undef HAVE_DECL_FPUTC_UNLOCKED + +/* Define to 1 if you have the declaration of `fputs_unlocked', and to 0 if + you don't. */ +#undef HAVE_DECL_FPUTS_UNLOCKED + +/* Define to 1 if you have the declaration of `fread_unlocked', and to 0 if + you don't. */ +#undef HAVE_DECL_FREAD_UNLOCKED + +/* Define to 1 if you have the declaration of `fwrite_unlocked', and to 0 if + you don't. */ +#undef HAVE_DECL_FWRITE_UNLOCKED + +/* Define to 1 if you have the declaration of `getchar_unlocked', and to 0 if + you don't. */ +#undef HAVE_DECL_GETCHAR_UNLOCKED + +/* Define to 1 if you have the declaration of `getc_unlocked', and to 0 if you + don't. */ +#undef HAVE_DECL_GETC_UNLOCKED + +/* Define to 1 if you have the declaration of `putchar_unlocked', and to 0 if + you don't. */ +#undef HAVE_DECL_PUTCHAR_UNLOCKED + +/* Define to 1 if you have the declaration of `putc_unlocked', and to 0 if you + don't. */ +#undef HAVE_DECL_PUTC_UNLOCKED + +/* Define to 1 if you have the declaration of `sigsetjmp', and to 0 if you + don't. */ +#undef HAVE_DECL_SIGSETJMP + +/* Define to 1 if you have the declaration of `sys_siglist', and to 0 if you + don't. */ +#undef HAVE_DECL_SYS_SIGLIST + +/* Define this if /dev/zero is readable device */ +#undef HAVE_DEV_ZERO + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +#undef HAVE_DIRENT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_DLFCN_H + +/* Define to 1 if you have the `dlopen' function. */ +#undef HAVE_DLOPEN + +/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */ +#undef HAVE_DOPRNT + +/* Define to 1 if you have the header file. */ +#undef HAVE_ERRNO_H + +/* Define to 1 if you have the `fchmod' function. */ +#undef HAVE_FCHMOD + +/* Define to 1 if you have the header file. */ +#undef HAVE_FCNTL_H + +/* Define to 1 if you have the `fopencookie' function. */ +#undef HAVE_FOPENCOOKIE + +/* Define to 1 if you have the `fork' function. */ +#undef HAVE_FORK + +/* Define to 1 if you have the `frexpl' function. */ +#undef HAVE_FREXPL + +/* Define to 1 if you have the `fstat' function. */ +#undef HAVE_FSTAT + +/* Define to 1 if you have the `funopen' function. */ +#undef HAVE_FUNOPEN + +/* Define to 1 if you have the `futimes' function. */ +#undef HAVE_FUTIMES + +/* Define to 1 if you have the `getdate_r' function. */ +#undef HAVE_GETDATE_R + +/* Define to 1 if the system has the type `int16_t'. */ +#undef HAVE_INT16_T + +/* Define to 1 if the system has the type `int32_t'. */ +#undef HAVE_INT32_T + +/* Define to 1 if the system has the type `int8_t'. */ +#undef HAVE_INT8_T + +/* Define to 1 if the system has the type `intptr_t'. */ +#undef HAVE_INTPTR_T + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the `ldexpl' function. */ +#undef HAVE_LDEXPL + +/* Define to 1 if you have the `dl' library (-ldl). */ +#undef HAVE_LIBDL + +/* Define to 1 if you have the `gen' library (-lgen). */ +#undef HAVE_LIBGEN + +/* Define to 1 if you have the header file. */ +#undef HAVE_LIBGEN_H + +/* Define to 1 if you have the `intl' library (-lintl). */ +#undef HAVE_LIBINTL + +/* Define to 1 if you have the header file. */ +#undef HAVE_LIBINTL_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_LIBIO_H + +/* Define to 1 if you have the `m' library (-lm). */ +#undef HAVE_LIBM + +/* Define to 1 if you have the header file. */ +#undef HAVE_LIMITS_H + +/* Define to 1 if the system has the type `long double'. */ +#undef HAVE_LONG_DOUBLE + +/* Define to 1 if the type `long double' works and has more range or precision + than `double'. */ +#undef HAVE_LONG_DOUBLE_WIDER + +/* Define to 1 if the system has the type `long long'. */ +#undef HAVE_LONG_LONG + +/* Define to 1 if the system has the type 'long long int'. */ +#undef HAVE_LONG_LONG_INT + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the `mmap' function. */ +#undef HAVE_MMAP + +/* Define to 1 if you have the `modfl' function. */ +#undef HAVE_MODFL + +/* Define to 1 if you have the header file, and it defines `DIR'. */ +#undef HAVE_NDIR_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_NETINET_IN_H + +/* Define this if pathfind(3) works */ +#undef HAVE_PATHFIND + +/* Define to 1 if the system has the type `pid_t'. */ +#undef HAVE_PID_T + +/* Define to 1 if the system has the type `ptrdiff_t'. */ +#undef HAVE_PTRDIFF_T + +/* Define to 1 if you have the `putenv' function. */ +#undef HAVE_PUTENV + +/* Define this if we have a functional realpath(3C) */ +#undef HAVE_REALPATH + +/* Define to 1 if you have the header file. */ +#undef HAVE_RUNETYPE_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SETJMP_H + +/* Define to 1 if the system has the type `size_t'. */ +#undef HAVE_SIZE_T + +/* Define to 1 if you have the `snprintf' function. */ +#undef HAVE_SNPRINTF + +/* Define this if sysinfo(2) is Solaris */ +#undef HAVE_SOLARIS_SYSINFO + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDARG_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDBOOL_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the `strchr' function. */ +#undef HAVE_STRCHR + +/* Define this if strcspn matches prototype and works */ +#undef HAVE_STRCSPN + +/* Define to 1 if you have the `strdup' function. */ +#undef HAVE_STRDUP + +/* Define this if strftime() works */ +#undef HAVE_STRFTIME + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the `strlcpy' function. */ +#undef HAVE_STRLCPY + +/* Define to 1 if you have the `strrchr' function. */ +#undef HAVE_STRRCHR + +/* Define to 1 if you have the `strsignal' function. */ +#undef HAVE_STRSIGNAL + +/* Define to 1 if you have the `strtoul' function. */ +#undef HAVE_STRTOUL + +/* Define to 1 if `st_mtim' is a member of `struct stat'. */ +#undef HAVE_STRUCT_STAT_ST_MTIM + +/* Define to 1 if `st_mtimensec' is a member of `struct stat'. */ +#undef HAVE_STRUCT_STAT_ST_MTIMENSEC + +/* Define to 1 if `st_mtimespec' is a member of `struct stat'. */ +#undef HAVE_STRUCT_STAT_ST_MTIMESPEC + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYSEXITS_H + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +#undef HAVE_SYS_DIR_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_LIMITS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_MMAN_H + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +#undef HAVE_SYS_NDIR_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_PARAM_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_POLL_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_PROCSET_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_RESOURCE_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SELECT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SOCKET_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STROPTS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TIME_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_UN_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_WAIT_H + +/* Define to 1 if the system has the type `uint16_t'. */ +#undef HAVE_UINT16_T + +/* Define to 1 if the system has the type `uint32_t'. */ +#undef HAVE_UINT32_T + +/* Define to 1 if the system has the type `uint8_t'. */ +#undef HAVE_UINT8_T + +/* Define to 1 if the system has the type `uintmax_t'. */ +#undef HAVE_UINTMAX_T + +/* Define to 1 if the system has the type `uintptr_t'. */ +#undef HAVE_UINTPTR_T + +/* Define to 1 if the system has the type `uint_t'. */ +#undef HAVE_UINT_T + +/* Define this if uname(2) is POSIX */ +#undef HAVE_UNAME_SYSCALL + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define to 1 if the system has the type 'unsigned long long int'. */ +#undef HAVE_UNSIGNED_LONG_LONG_INT + +/* Define to 1 if you have the `utimensat' function. */ +#undef HAVE_UTIMENSAT + +/* Define to 1 if you have the `utimes' function. */ +#undef HAVE_UTIMES + +/* Define to 1 if you have the header file. */ +#undef HAVE_UTIME_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_VALUES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_VARARGS_H + +/* Define to 1 if you have the `vfork' function. */ +#undef HAVE_VFORK + +/* Define to 1 if you have the header file. */ +#undef HAVE_VFORK_H + +/* Define to 1 if you have the `vprintf' function. */ +#undef HAVE_VPRINTF + +/* Define to 1 if you have the header file. */ +#undef HAVE_WCHAR_H + +/* Define to 1 if the system has the type `wchar_t'. */ +#undef HAVE_WCHAR_T + +/* Define to 1 if the system has the type `wint_t'. */ +#undef HAVE_WINT_T + +/* Define to 1 if `fork' works. */ +#undef HAVE_WORKING_FORK + +/* [setjmp links okay] */ +#undef HAVE_WORKING_SETJMP + +/* [sigsetjmp links okay] */ +#undef HAVE_WORKING_SIGSETJMP + +/* Define to 1 if `vfork' works. */ +#undef HAVE_WORKING_VFORK + +/* Define to the sub-directory where libtool stores uninstalled libraries. */ +#undef LT_OBJDIR + +/* Define if typedefs for the funopen function pointers are required. */ +#undef NEED_COOKIE_FUNCTION_TYPEDEFS + +/* Define this if optional arguments are disallowed */ +#undef NO_OPTIONAL_OPT_ARGS + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the home page for this package. */ +#undef PACKAGE_URL + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* define to a working POSIX compliant shell */ +#undef POSIX_SHELL + +/* name of regex header file */ +#undef REGEX_HEADER + +/* Define if shell scripts are enabled */ +#undef SHELL_ENABLED + +/* The size of `char*', as computed by sizeof. */ +#undef SIZEOF_CHARP + +/* The size of `char *', as computed by sizeof. */ +#undef SIZEOF_CHAR_P + +/* The size of `int', as computed by sizeof. */ +#undef SIZEOF_INT + +/* The size of `long', as computed by sizeof. */ +#undef SIZEOF_LONG + +/* The size of `short', as computed by sizeof. */ +#undef SIZEOF_SHORT + +/* define to static or static inline */ +#undef SNV_INLINE + +/* Define this to the long+double type */ +#undef SNV_LONG_DOUBLE + +/* Define this if statically link autogen to libopts */ +#undef STATIC_AUTOGEN_ENABLED + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Define this if specify an autogen timeout */ +#undef TIMEOUT_ENABLED + +/* Enable extensions on AIX 3, Interix. */ +#ifndef _ALL_SOURCE +# undef _ALL_SOURCE +#endif +/* Enable general extensions on macOS. */ +#ifndef _DARWIN_C_SOURCE +# undef _DARWIN_C_SOURCE +#endif +/* Enable GNU extensions on systems that have them. */ +#ifndef _GNU_SOURCE +# undef _GNU_SOURCE +#endif +/* Enable NetBSD extensions on NetBSD. */ +#ifndef _NETBSD_SOURCE +# undef _NETBSD_SOURCE +#endif +/* Enable OpenBSD extensions on NetBSD. */ +#ifndef _OPENBSD_SOURCE +# undef _OPENBSD_SOURCE +#endif +/* Enable threading extensions on Solaris. */ +#ifndef _POSIX_PTHREAD_SEMANTICS +# undef _POSIX_PTHREAD_SEMANTICS +#endif +/* Enable extensions specified by ISO/IEC TS 18661-5:2014. */ +#ifndef __STDC_WANT_IEC_60559_ATTRIBS_EXT__ +# undef __STDC_WANT_IEC_60559_ATTRIBS_EXT__ +#endif +/* Enable extensions specified by ISO/IEC TS 18661-1:2014. */ +#ifndef __STDC_WANT_IEC_60559_BFP_EXT__ +# undef __STDC_WANT_IEC_60559_BFP_EXT__ +#endif +/* Enable extensions specified by ISO/IEC TS 18661-2:2015. */ +#ifndef __STDC_WANT_IEC_60559_DFP_EXT__ +# undef __STDC_WANT_IEC_60559_DFP_EXT__ +#endif +/* Enable extensions specified by ISO/IEC TS 18661-4:2015. */ +#ifndef __STDC_WANT_IEC_60559_FUNCS_EXT__ +# undef __STDC_WANT_IEC_60559_FUNCS_EXT__ +#endif +/* Enable extensions specified by ISO/IEC TS 18661-3:2015. */ +#ifndef __STDC_WANT_IEC_60559_TYPES_EXT__ +# undef __STDC_WANT_IEC_60559_TYPES_EXT__ +#endif +/* Enable extensions specified by ISO/IEC TR 24731-2:2010. */ +#ifndef __STDC_WANT_LIB_EXT2__ +# undef __STDC_WANT_LIB_EXT2__ +#endif +/* Enable extensions specified by ISO/IEC 24747:2009. */ +#ifndef __STDC_WANT_MATH_SPEC_FUNCS__ +# undef __STDC_WANT_MATH_SPEC_FUNCS__ +#endif +/* Enable extensions on HP NonStop. */ +#ifndef _TANDEM_SOURCE +# undef _TANDEM_SOURCE +#endif +/* Enable X/Open extensions if necessary. HP-UX 11.11 defines + mbstate_t only if _XOPEN_SOURCE is defined to 500, regardless of + whether compiling with -Ae or -D_HPUX_SOURCE=1. */ +#ifndef _XOPEN_SOURCE +# undef _XOPEN_SOURCE +#endif +/* Enable X/Open compliant socket functions that do not require linking + with -lxnet on HP-UX 11.11. */ +#ifndef _HPUX_ALT_XOPEN_SOCKET_API +# undef _HPUX_ALT_XOPEN_SOCKET_API +#endif +/* Enable general extensions on Solaris. */ +#ifndef __EXTENSIONS__ +# undef __EXTENSIONS__ +#endif + + +/* Define to 1 if you want getc etc. to use unlocked I/O if available. + Unlocked I/O can improve performance in unithreaded apps, but it is not + safe for multithreaded apps. */ +#undef USE_UNLOCKED_IO + +/* Version number of package */ +#undef VERSION + +/* Define if using the dmalloc debugging malloc package */ +#undef WITH_DMALLOC + +/* Define this if a working libregex can be found */ +#undef WITH_LIBREGEX + +/* Define this if name of the packager of this software is supplied */ +#undef WITH_PACKAGER + +/* Define this if bug reporting URI/e-mail/etc. is supplied */ +#undef WITH_PACKAGER_BUG_REPORTS + +/* Define this if packager-specific version information is supplied */ +#undef WITH_PACKAGER_VERSION + +/* Define to 1 if on MINIX. */ +#undef _MINIX + +/* Define to 1 to make NetBSD features available. MINIX 3 needs this. */ +#undef _NETBSD_SOURCE + +/* Define to 2 if the system does not provide POSIX.1 features except with + this defined. */ +#undef _POSIX_1_SOURCE + +/* Define to 1 if you need to in order for 'stat' and other things to work. */ +#undef _POSIX_SOURCE + +/* Define to empty if `const' does not conform to ANSI C. */ +#undef const + +/* Define to `int' if doesn't define. */ +#undef gid_t + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef __cplusplus +#undef inline +#endif + +/* Define to `int' if does not define. */ +#undef mode_t + +/* Define to `int' if does not define. */ +#undef pid_t + +/* Define to `unsigned int' if does not define. */ +#undef size_t + +/* Define to `int' if doesn't define. */ +#undef uid_t + +/* Define as `fork' if `vfork' does not work. */ +#undef vfork + +#endif /* AUTOGEN_CONFIG_H */ diff --git a/config/ag_macros.m4 b/config/ag_macros.m4 new file mode 100644 index 0000000..ccce347 --- /dev/null +++ b/config/ag_macros.m4 @@ -0,0 +1,605 @@ + +dnl do always before generated macros: +dnl +AC_DEFUN([INVOKE_AG_MACROS_FIRST],[ + stat_nsec_found=no + AC_CHECK_MEMBERS( + [struct stat.st_mtim, struct stat.st_mtimensec, struct stat.st_mtimespec], + [stat_nsec_found=yes], [], [[#include ]]) + AC_CHECK_FUNCS(strchr strlcpy snprintf dlopen utimensat clock_gettime) + AC_SEARCH_LIBS(copysign, [m], + [AC_DEFINE(HAVE_COPYSIGN, 1, + [Define to 1 if you have the `copysign' function.])]) + AC_SEARCH_LIBS(copysignl, [m], + [AC_DEFINE(HAVE_COPYSIGNL, 1, + [Define to 1 if you have the `copysignl' function.])]) + AC_SEARCH_LIBS(modfl, [m], + [AC_DEFINE(HAVE_MODFL, 1, + [Define to 1 if you have the `modfl' function.])]) + + # ---------------------------------------------------------------------- + # Check for the functions needed from libgen and libdl + # ---------------------------------------------------------------------- + + AM_CONDITIONAL([NEED_PATHFIND], [test X$ac_cv_func_pathfind = Xyes]) + [if test X$ac_cv_func_dlopen = Xyes + then DYNAMIC_AG=-export-dynamic + else DYNAMIC_AG="" + fi] + AC_SUBST(DYNAMIC_AG) + + AC_CHECK_HEADERS([libio.h ctype.h assert.h sys/resource.h]) + AC_CHECK_DECLS([sigsetjmp],,, [#include ]) + AC_DECL_SYS_SIGLIST + AC_CHECK_FUNCS([putenv getdate_r utimes futimes]) + + AC_C_INLINE + AC_TYPE_LONG_LONG_INT + + AC_PROG_GREP + AC_PROG_EGREP + AC_PROG_FGREP +]) + + + +dnl +dnl do always after generated macros: +dnl +AC_DEFUN([INVOKE_AG_MACROS_LAST],[ +[if test X${INVOKE_AG_MACROS_LAST_done} != Xyes ; then] + GUILE_FLAGS + [test -x "${PKG_CONFIG}" || { + test -z "${PKG_CONFIG}" && PKG_CONFIG=pkg-config + f=`command -v ${PKG_CONFIG}` + test -x "${f}" && PKG_CONFIG="$f" + } + # Grab the first "-I" option that works + # + ag_gv=`gdir=\`${PKG_CONFIG} --cflags-only-I \ + guile-${GUILE_EFFECTIVE_VERSION} | \ + sed 's/ *-I/ /g'\` + test ${#gdir} -gt 1 || gdir=/usr/include + for d in $gdir + do test -f "$d/libguile/version.h" && gdir=$d && break + done + gdir=\`awk '/SCM_MICRO_VERSION/{ print @S|@3 }' \ + "${gdir}/libguile/version.h"\` + test -n "$gdir" || exit 1 + IFS=' .' + set -- ${GUILE_EFFECTIVE_VERSION} + printf '%u%02u%03u' ${1} ${2} ${gdir} + ` + + test -n "$ag_gv" || ]AC_MSG_FAILURE([cannot determine Guile version], 1) + test ${ag_gv} -ge 200000 || AC_MSG_FAILURE([cannot use pre-2.0 Guile]) + AC_DEFINE_UNQUOTED(GUILE_VERSION, ${ag_gv}, + [define to a single number for Guile version]) + INVOKE_LIBOPTS_MACROS + + [test "X${ac_cv_header_sys_wait_h}" = Xyes || \ + ]AC_MSG_ERROR([you must have sys/wait.h on your system]) + + AC_CHECK_FUNCS([fopencookie funopen], [break]) + case "${ac_cv_func_fopencookie}${ac_cv_func_funopen}" in + *yes* ) + AC_DEFINE([ENABLE_FMEMOPEN], 1, "Define if we can use it") + ;; + esac + + # Note that BSD does not typedef these in its headers, but instead + # calls for them to be identical in signature to read(2), write(2), + # lseek(2), and close(2). Newlib however does include typedefs + # in its stdio.h for these, and they do not match the signatures + # of the BSD implementation. So this test relies on the fact + # that any typedef will succeed for BSD, while only one that + # matches the existing definitions in stdio.h will succeed for + # a newlib system. + + if test "X${ac_cv_func_funopen}" = Xyes; then + AC_CACHE_CHECK([for cookie_function_t type], + [ag_cv_cookie_function_t], + [AC_TRY_COMPILE([#include + typedef int cookie_read_function_t (void *, char *, int); + ], [], ag_cv_cookie_function_t="bsd", + AC_TRY_COMPILE([#include + typedef ssize_t cookie_read_function_t (void *, char *, size_t); + ], [], ag_cv_cookie_function_t="newlib", + AC_MSG_ERROR([Unknown flavor of cookie_XXX_t types])))]) + fi + if test "X${ag_cv_cookie_function_t}" = Xbsd; then + AC_DEFINE([NEED_COOKIE_FUNCTION_TYPEDEFS], [1], + [Define if typedefs for the funopen function pointers are required.]) + fi + + AC_CACHE_CHECK([for static inline], [snv_cv_static_inline], [ + AC_TRY_COMPILE([static inline foo(bar) int bar; { return bar; }], + [return foo(0);], + [snv_cv_static_inline='static inline'], + [snv_cv_static_inline='static']) + ]) + AC_DEFINE_UNQUOTED(SNV_INLINE, ${snv_cv_static_inline}, + [define to static or static inline]) + [if test "X${libopts_cv_with_libregex}" = Xno + then + echo "A POSIX compliant regcomp/regexec routine is required. + These are required for AutoGen to work correctly. If you have + such a library present on your system, you must specify it by + setting the LIBS environment variable, e.g., \"LIBS='-lregex'\". + If you do not have such a library on your system, then you should + download and install, for example, the one from: + ftp://ftp.gnu.org/gnu/rx/" >&2] + AC_MSG_ERROR([Cannot find working POSIX regex library]) + [fi] +[ INVOKE_AG_MACROS_LAST_done=yes +fi]]) + +dnl +dnl @synopsis INVOKE_AG_MACROS +dnl +dnl This macro will invoke the AutoConf macros specified in misc.def +dnl that have not been disabled with "omit-invocation". +dnl +AC_DEFUN([AG_DISABLE_SHELL],[ + AC_ARG_ENABLE([shell], + AS_HELP_STRING([--disable-shell], [shell scripts are desired]), + [ag_cv_enable_shell=${enable_shell}], + AC_CACHE_CHECK([whether shell scripts are desired], ag_cv_enable_shell, + ag_cv_enable_shell=yes) + ) # end of AC_ARG_ENABLE + if test "X${ag_cv_enable_shell}" != Xno + then + AC_FUNC_FORK + fi + +]) # end of AC_DEFUN of AG_DISABLE_SHELL + + +AC_DEFUN([AG_TEST_DO_SHELL],[ + AC_MSG_CHECKING([whether using shell scripts]) + AC_CACHE_VAL([ag_cv_test_do_shell],[ + ag_cv_test_do_shell=`exec 2> /dev/null +test "x$ac_cv_func_fork_works" != xyes && \\ + test "x$ac_cv_func_vfork_works" != xyes && exit 1 +test "x$ag_cv_enable_shell" = xyes || exit 1 +echo yes` + if test $? -ne 0 || test -z "$ag_cv_test_do_shell" + then ag_cv_test_do_shell=no + fi + ]) # end of CACHE_VAL of ag_cv_test_do_shell + AC_MSG_RESULT([${ag_cv_test_do_shell}]) + if test "X${ag_cv_test_do_shell}" != Xno + then + AC_SUBST(OPTS_TESTDIR) +AC_SUBST(AGEN5_TESTS) +AC_DEFINE([SHELL_ENABLED], [1], [Define if shell scripts are enabled]) +OPTS_TESTDIR=test +AGEN5_TESTS='$(SHELL_TESTS) $(NOSHELL_TESTS)' + else + OPTS_TESTDIR= +AGEN5_TESTS='$(NOSHELL_TESTS)' + fi + AM_CONDITIONAL([DO_SHELL_CMDS],[test "X${ag_cv_test_do_shell}" != Xno]) + +]) # end of AC_DEFUN of AG_TEST_DO_SHELL + + +AC_DEFUN([AG_ENABLE_STATIC_AUTOGEN],[ + AC_ARG_ENABLE([static-autogen], + AS_HELP_STRING([--enable-static-autogen], [statically link autogen to libopts]), + [ag_cv_enable_static_autogen=${enable_static_autogen}], + AC_CACHE_CHECK([whether statically link autogen to libopts], ag_cv_enable_static_autogen, + ag_cv_enable_static_autogen=no) + ) # end of AC_ARG_ENABLE + if test "X${ag_cv_enable_static_autogen}" != Xno + then + AC_DEFINE([STATIC_AUTOGEN_ENABLED],[1], + [Define this if statically link autogen to libopts]) + AG_STATIC_AUTOGEN="-static" + else + AG_STATIC_AUTOGEN='' + fi + AC_SUBST([AG_STATIC_AUTOGEN]) + +]) # end of AC_DEFUN of AG_ENABLE_STATIC_AUTOGEN + + +AC_DEFUN([AG_LINK_SETJMP],[ + AC_MSG_CHECKING([whether setjmp() links okay]) + AC_CACHE_VAL([ag_cv_link_setjmp],[ + AC_LINK_IFELSE( + AC_LANG_PROGRAM([@%:@include ], + [jmp_buf bf; +if (setjmp(bf)) + return 0; +return 0;]), + [ag_cv_link_setjmp=yes], + [ag_cv_link_setjmp=no] + ) # end of AC_LINK_IFELSE + ]) # end of AC_CACHE_VAL for ag_cv_link_setjmp + AC_MSG_RESULT([${ag_cv_link_setjmp}]) + if test "X${ag_cv_link_setjmp}" != Xno + then + AC_DEFINE(HAVE_WORKING_SETJMP, 1, @<:@setjmp links okay@:>@) + fi + +]) # end of AC_DEFUN of AG_LINK_SETJMP + + +AC_DEFUN([AG_COMPILE_FORMAT_ARG],[ + AC_MSG_CHECKING([whether __attribute__((format_arg(n))) works]) + AC_CACHE_VAL([ag_cv_compile_format_arg],[ + AC_COMPILE_IFELSE( + AC_LANG_PROGRAM([@%:@include +char const * foo(char const * fmt, int v) __attribute__((format_arg(1)));], + [ int i = 0; + printf(foo("argc is %d\n", i), i);]), + [ag_cv_compile_format_arg=yes], + [ag_cv_compile_format_arg=no] + ) # end of AC_COMPILE_IFELSE + ]) # end of AC_CACHE_VAL for ag_cv_compile_format_arg + AC_MSG_RESULT([${ag_cv_compile_format_arg}]) + if test "X${ag_cv_compile_format_arg}" != Xno + then + format_arg_expansion="__attribute__((format_arg(_a)))" + else + format_arg_expansion="" + fi + AC_DEFINE_UNQUOTED([ATTRIBUTE_FORMAT_ARG(_a)], + [${format_arg_expansion}], + [format_arg attribute wrapper]) + +]) # end of AC_DEFUN of AG_COMPILE_FORMAT_ARG + + +AC_DEFUN([AG_LINK_SIGSETJMP],[ + AC_MSG_CHECKING([whether sigsetjmp() links okay]) + AC_CACHE_VAL([ag_cv_link_sigsetjmp],[ + AC_LINK_IFELSE( + AC_LANG_PROGRAM([@%:@include ], + [sigjmp_buf bf; +if (sigsetjmp(bf,0)) + return 0; +return 0;]), + [ag_cv_link_sigsetjmp=yes], + [ag_cv_link_sigsetjmp=no] + ) # end of AC_LINK_IFELSE + ]) # end of AC_CACHE_VAL for ag_cv_link_sigsetjmp + AC_MSG_RESULT([${ag_cv_link_sigsetjmp}]) + if test "X${ag_cv_link_sigsetjmp}" != Xno + then + AC_DEFINE(HAVE_WORKING_SIGSETJMP, 1, @<:@sigsetjmp links okay@:>@) + fi + +]) # end of AC_DEFUN of AG_LINK_SIGSETJMP + + +AC_DEFUN([AG_WITHLIB_XML2],[ + AC_ARG_WITH([libxml2], + AS_HELP_STRING([--with-libxml2], [libxml2 installation prefix]), + [ag_cv_with_libxml2_root=${with_libxml2}], + AC_CACHE_CHECK([whether with-libxml2 was specified], ag_cv_with_libxml2_root, + ag_cv_with_libxml2_root=no) + ) # end of AC_ARG_WITH libxml2 + + if test "${with_libxml2+set}" = set && \ + test "X${withval}" = Xno + then ## disabled by request + ag_cv_with_libxml2_root=no + ag_cv_with_libxml2_cflags=no + ag_cv_with_libxml2_libs=no + else + + AC_ARG_WITH([libxml2-cflags], + AS_HELP_STRING([--with-libxml2-cflags], [libxml2 compile flags]), + [ag_cv_with_libxml2_cflags=${with_libxml2_cflags}], + AC_CACHE_CHECK([whether with-libxml2-cflags was specified], ag_cv_with_libxml2_cflags, + ag_cv_with_libxml2_cflags=no) + ) # end of AC_ARG_WITH libxml2-cflags + + AC_ARG_WITH([libxml2-libs], + AS_HELP_STRING([--with-libxml2-libs], [libxml2 link command arguments]), + [ag_cv_with_libxml2_libs=${with_libxml2_libs}], + AC_CACHE_CHECK([whether with-libxml2-libs was specified], ag_cv_with_libxml2_libs, + ag_cv_with_libxml2_libs=no) + ) # end of AC_ARG_WITH libxml2-libs + + case "X${ag_cv_with_libxml2_cflags}" in + Xyes|Xno|X ) + case "X${ag_cv_with_libxml2_root}" in + Xyes|Xno|X ) ag_cv_with_libxml2_cflags=no ;; + * ) ag_cv_with_libxml2_cflags=-I${ag_cv_with_libxml2_root}/include ;; + esac + esac + case "X${ag_cv_with_libxml2_libs}" in + Xyes|Xno|X ) + case "X${ag_cv_with_libxml2_root}" in + Xyes|Xno|X ) ag_cv_with_libxml2_libs=no ;; + * ) ag_cv_with_libxml2_libs="-L${ag_cv_with_libxml2_root}/lib -lxml2" ;; + esac + esac + ag_save_CPPFLAGS="${CPPFLAGS}" + ag_save_LIBS="${LIBS}" + case "X${ag_cv_with_libxml2_cflags}" in + Xyes|Xno|X ) + f=`xml2-config --cflags 2>/dev/null` || f='' + test -n "${f}" && ag_cv_with_libxml2_cflags="${f}" && \ + AC_MSG_NOTICE([xml2-config used for CFLAGS: $f]) ;; + esac + case "X${ag_cv_with_libxml2_libs}" in + Xyes|Xno|X ) + f=`xml2-config --libs 2>/dev/null` || f='' + test -n "${f}" && ag_cv_with_libxml2_libs="${f}" && \ + AC_MSG_NOTICE([xml2-config used for LIBS: $f]) ;; + esac + case "X${ag_cv_with_libxml2_cflags}" in + Xyes|Xno|X ) + ag_cv_with_libxml2_cflags="" ;; + * ) CPPFLAGS="${CPPFLAGS} ${ag_cv_with_libxml2_cflags}" ;; + esac + case "X${ag_cv_with_libxml2_libs}" in + Xyes|Xno|X ) + LIBS="${LIBS} -lxml2" + ag_cv_with_libxml2_libs="-lxml2" ;; + * ) + LIBS="${LIBS} ${ag_cv_with_libxml2_libs}" ;; + esac + LIBXML2_CFLAGS="" + LIBXML2_LIBS="" + AC_MSG_CHECKING([whether libxml2 can be linked with]) + AC_CACHE_VAL([ag_cv_with_libxml2],[ + AC_LINK_IFELSE( + [AC_LANG_SOURCE([[@%:@include +@%:@include + +int main () { +xmlDocPtr p = xmlParseFile( "mumble.xml" ); }]])], + [ag_cv_with_libxml2=yes], + [ag_cv_with_libxml2=no]) # end of AC_LINK_IFELSE + ]) # end of AC_CACHE_VAL for ag_cv_with_libxml2 + fi ## disabled by request + AC_MSG_RESULT([${ag_cv_with_libxml2}]) + AC_SUBST([LIBXML2_CFLAGS]) + AC_SUBST([LIBXML2_LIBS]) + if test "X${ag_cv_with_libxml2}" != Xno + then[ + LIBXML2_CFLAGS="${ag_cv_with_libxml2_cflags}" + LIBXML2_LIBS="${ag_cv_with_libxml2_libs}"] + CPPFLAGS="@S|@{ag_save_CPPFLAGS}" + LIBS="@S|@{ag_save_LIBS}" + + else + CPPFLAGS="${ag_save_CPPFLAGS}" + LIBS="${ag_save_LIBS}" + LIBXML2_CFLAGS='' + LIBXML2_LIBS='' + fi + AC_SUBST([AG_XML2]) + AM_CONDITIONAL([HAVE_XML_LIB],[test "X${ag_cv_with_libxml2}" != Xno]) + +]) # end of AC_DEFUN of AG_WITHLIB_XML2 + + +AC_DEFUN([AG_RUN_SOLARIS_SYSINFO],[ + AC_MSG_CHECKING([whether sysinfo(2) is Solaris]) + AC_CACHE_VAL([ag_cv_run_solaris_sysinfo],[ + AC_RUN_IFELSE([AC_LANG_SOURCE([@%:@include +int main() { char z@<:@ 256 @:>@; +long sz = sysinfo(SI_SYSNAME, z, sizeof(z)); +return (sz > 0) ? 0 : 1; }] )], + [ag_cv_run_solaris_sysinfo=yes],[ag_cv_run_solaris_sysinfo=no],[ag_cv_run_solaris_sysinfo=no] + ) # end of RUN_IFELSE + ]) # end of AC_CACHE_VAL for ag_cv_run_solaris_sysinfo + AC_MSG_RESULT([${ag_cv_run_solaris_sysinfo}]) + if test "X${ag_cv_run_solaris_sysinfo}" != Xno + then + AC_DEFINE([HAVE_SOLARIS_SYSINFO],[1], + [Define this if sysinfo(2) is Solaris]) + fi + +]) # end of AC_DEFUN of AG_RUN_SOLARIS_SYSINFO + + +AC_DEFUN([AG_ENABLE_TIMEOUT],[ + AC_ARG_ENABLE([timeout], + AS_HELP_STRING([--enable-timeout], [specify an autogen timeout]), + [ag_cv_enable_timeout=${enable_timeout}], + AC_CACHE_CHECK([whether specify an autogen timeout], ag_cv_enable_timeout, + ag_cv_enable_timeout=no) + ) # end of AC_ARG_ENABLE + if test "X${ag_cv_enable_timeout}" != Xno + then + AC_DEFINE([TIMEOUT_ENABLED],[1], + [Define this if specify an autogen timeout]) + AG_TIMEOUT="@S|@{ag_cv_enable_timeout}" + else + AG_TIMEOUT='' + fi + AC_SUBST([AG_TIMEOUT]) + +]) # end of AC_DEFUN of AG_ENABLE_TIMEOUT + + +AC_DEFUN([AG_RUN_STRCSPN],[ + AC_MSG_CHECKING([whether strcspn matches prototype and works]) + AC_CACHE_VAL([ag_cv_run_strcspn],[ + AC_RUN_IFELSE([AC_LANG_SOURCE([@%:@include +int main (int argc, char ** argv) { + char zRej@<:@@:>@ = reject; + char zAcc@<:@@:>@ = "a-ok-eject"; + return strcspn( zAcc, zRej ) - 5; +}] )] + [ag_cv_run_strcspn=yes],[ag_cv_run_strcspn=no],[ag_cv_run_strcspn=no] + ) # end of RUN_IFELSE + ]) # end of AC_CACHE_VAL for ag_cv_run_strcspn + AC_MSG_RESULT([${ag_cv_run_strcspn}]) + if test "X${ag_cv_run_strcspn}" != Xno + then + AC_DEFINE([HAVE_STRCSPN],[1], + [Define this if strcspn matches prototype and works]) + else + COMPATOBJ="@S|@COMPATOBJ strcspn.lo" + fi + +]) # end of AC_DEFUN of AG_RUN_STRCSPN + + +AC_DEFUN([AG_RUN_UNAME_SYSCALL],[ + AC_MSG_CHECKING([whether uname(2) is POSIX]) + AC_CACHE_VAL([ag_cv_run_uname_syscall],[ + AC_RUN_IFELSE([AC_LANG_SOURCE([@%:@include +int main() { struct utsname unm; +return uname( &unm ); }] )], + [ag_cv_run_uname_syscall=yes],[ag_cv_run_uname_syscall=no],[ag_cv_run_uname_syscall=no] + ) # end of RUN_IFELSE + ]) # end of AC_CACHE_VAL for ag_cv_run_uname_syscall + AC_MSG_RESULT([${ag_cv_run_uname_syscall}]) + if test "X${ag_cv_run_uname_syscall}" != Xno + then + AC_DEFINE([HAVE_UNAME_SYSCALL],[1], + [Define this if uname(2) is POSIX]) + fi + +]) # end of AC_DEFUN of AG_RUN_UNAME_SYSCALL + + +AC_DEFUN([AG_TEST_LDFLAGS],[ + AC_MSG_CHECKING([whether runtime library dirs can be specified]) + AC_CACHE_VAL([ag_cv_test_ldflags],[ + ag_cv_test_ldflags=`exec 2> /dev/null +echo 'int main() { return 0; }' > conftest.$ac_ext +libs="${LIBS}" +LIBS="${LIBS} -Wl,-R/tmp" +if (eval $ac_link) > /dev/null 2>&1 +then echo '-Wl,-R${libdir}' ; rm -f conftest* ; exit 0 ; fi +LIBS="${libs} -R/tmp" +if (eval $ac_link) > /dev/null 2>&1 +then echo '-R${libdir}' ; rm -f conftest* ; exit 0 ; fi +rm -f conftest* ; exit 1` + if test $? -ne 0 || test -z "$ag_cv_test_ldflags" + then ag_cv_test_ldflags=no + fi + ]) # end of CACHE_VAL of ag_cv_test_ldflags + AC_MSG_RESULT([${ag_cv_test_ldflags}]) + if test "X${ag_cv_test_ldflags}" != Xno + then + AG_LDFLAGS="@S|@{ag_cv_test_ldflags}" + else + AG_LDFLAGS='' + fi + AC_SUBST([AG_LDFLAGS]) + +]) # end of AC_DEFUN of AG_TEST_LDFLAGS + + +AC_DEFUN([AG_ENABLE_DEBUG],[ + AC_ARG_ENABLE([debug], + AS_HELP_STRING([--enable-debug], [wanting autogen debugging]), + [ag_cv_enable_debug=${enable_debug}], + AC_CACHE_CHECK([whether wanting autogen debugging], ag_cv_enable_debug, + ag_cv_enable_debug=no) + ) # end of AC_ARG_ENABLE + if test "X${ag_cv_enable_debug}" != Xno + then + AC_DEFINE([DEBUG_ENABLED],[1], + [Define this if wanting autogen debugging]) + AC_DEFINE([DEBUG_ENABLED], [1], + [Define this if debugging is enabled]) + [f=`which dmalloc 2>/dev/null` + test -n "$f" && LIBS="${LIBS} -ldmalloc"] + fi + +]) # end of AC_DEFUN of AG_ENABLE_DEBUG + + +AC_DEFUN([AG_WITH_GROUP_PACKAGER],[ + AC_ARG_WITH([packager], + AS_HELP_STRING([--with-packager], [name of the packager of this software is supplied]), + [ag_cv_with_group_packager=${with_packager}], + AC_CACHE_CHECK([whether name of the packager of this software is supplied], ag_cv_with_group_packager, + ag_cv_with_group_packager=no) + ) # end of AC_ARG_WITH + if test "X${ag_cv_with_group_packager}" != Xno + then + AC_DEFINE_UNQUOTED([WITH_PACKAGER],["${withval}"], + [Define this if name of the packager of this software is supplied]) + fi + AC_ARG_WITH([packager-version], + AS_HELP_STRING([--with-packager-version], [packager-specific version information is supplied]), + [ag_cv_with_group_packager_version=${with_packager_version}], + AC_CACHE_CHECK([whether packager-specific version information is supplied], ag_cv_with_group_packager_version, + ag_cv_with_group_packager_version=no) + ) # end of AC_ARG_WITH + if test "X${ag_cv_with_group_packager_version}" != Xno + then + AC_DEFINE_UNQUOTED([WITH_PACKAGER_VERSION],["${withval}"], + [Define this if packager-specific version information is supplied]) + fi + AC_ARG_WITH([packager-bug-reports], + AS_HELP_STRING([--with-packager-bug-reports], [bug reporting URI/e-mail/etc. is supplied]), + [ag_cv_with_group_packager_bug_reports=${with_packager_bug_reports}], + AC_CACHE_CHECK([whether bug reporting URI/e-mail/etc. is supplied], ag_cv_with_group_packager_bug_reports, + ag_cv_with_group_packager_bug_reports=no) + ) # end of AC_ARG_WITH + if test "X${ag_cv_with_group_packager_bug_reports}" != Xno + then + AC_DEFINE_UNQUOTED([WITH_PACKAGER_BUG_REPORTS],["${withval}"], + [Define this if bug reporting URI/e-mail/etc. is supplied]) + fi + if test "X$with_packager" != "X" || \ + test "X$with_packager_version$with_packager_bug_reports" = "X" + then : + else + + AC_MSG_ERROR([--with-packager-{bug-reports,version} require --with-packager]) + fi + +]) # end of AC_DEFUN of AG_WITH_GROUP_PACKAGER + + +AC_DEFUN([INVOKE_AG_MACROS],[ + AC_REQUIRE([INVOKE_AG_MACROS_FIRST]) + # Check to see if shell scripts are desired. + AG_DISABLE_SHELL + + # Check to see if using shell scripts. + AG_TEST_DO_SHELL + + # Check to see if statically link autogen to libopts. + AG_ENABLE_STATIC_AUTOGEN + + # Check to see if setjmp() links okay. + AG_LINK_SETJMP + + # Check to see if __attribute__((format_arg(n))) works. + AG_COMPILE_FORMAT_ARG + + # Check to see if sigsetjmp() links okay. + AG_LINK_SIGSETJMP + + # Check to see if a working libxml2 can be found. + AG_WITHLIB_XML2 + + # Check to see if sysinfo(2) is Solaris. + AG_RUN_SOLARIS_SYSINFO + + # Check to see if specify an autogen timeout. + AG_ENABLE_TIMEOUT + + # Check to see if strcspn matches prototype and works. + AG_RUN_STRCSPN + + # Check to see if uname(2) is POSIX. + AG_RUN_UNAME_SYSCALL + + # Check to see if runtime library dirs can be specified. + AG_TEST_LDFLAGS + + # Check to see if wanting autogen debugging. + AG_ENABLE_DEBUG + + # Check to see if name of the packager of this software is supplied. + AG_WITH_GROUP_PACKAGER + + INVOKE_AG_MACROS_LAST +]) # end AC_DEFUN of INVOKE_AG_MACROS diff --git a/config/asm-underscore.m4 b/config/asm-underscore.m4 new file mode 100644 index 0000000..58a5299 --- /dev/null +++ b/config/asm-underscore.m4 @@ -0,0 +1,72 @@ +# asm-underscore.m4 serial 4 +dnl Copyright (C) 2010-2018 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. Based on as-underscore.m4 in GNU clisp. + +# gl_ASM_SYMBOL_PREFIX +# Tests for the prefix of C symbols at the assembly language level and the +# linker level. This prefix is either an underscore or empty. Defines the +# C macro USER_LABEL_PREFIX to this prefix, and sets ASM_SYMBOL_PREFIX to +# a stringified variant of this prefix. + +AC_DEFUN([gl_ASM_SYMBOL_PREFIX], +[ + AC_REQUIRE([AC_PROG_EGREP]) + dnl We don't use GCC's __USER_LABEL_PREFIX__ here, because + dnl 1. It works only for GCC. + dnl 2. It is incorrectly defined on some platforms, in some GCC versions. + AC_REQUIRE([gl_C_ASM]) + AC_CACHE_CHECK( + [whether C symbols are prefixed with underscore at the linker level], + [gl_cv_prog_as_underscore], + [cat > conftest.c </dev/null 2>&1 + if LC_ALL=C $EGREP '(^|[[^a-zA-Z0-9_]])_foo([[^a-zA-Z0-9_]]|$)' conftest.$gl_asmext >/dev/null; then + gl_cv_prog_as_underscore=yes + else + gl_cv_prog_as_underscore=no + fi + rm -f conftest* + ]) + if test $gl_cv_prog_as_underscore = yes; then + USER_LABEL_PREFIX=_ + else + USER_LABEL_PREFIX= + fi + AC_DEFINE_UNQUOTED([USER_LABEL_PREFIX], [$USER_LABEL_PREFIX], + [Define to the prefix of C symbols at the assembler and linker level, + either an underscore or empty.]) + ASM_SYMBOL_PREFIX='"'${USER_LABEL_PREFIX}'"' + AC_SUBST([ASM_SYMBOL_PREFIX]) +]) + +# gl_C_ASM +# Determines how to produce an assembly language file from C source code. +# Sets the variables: +# gl_asmext - the extension of assembly language output, +# gl_c_asm_opt - the C compiler option that produces assembly language output. + +AC_DEFUN([gl_C_ASM], +[ + AC_EGREP_CPP([MicrosoftCompiler], + [ +#ifdef _MSC_VER +MicrosoftCompiler +#endif + ], + [gl_asmext='asm' + gl_c_asm_opt='-c -Fa' + ], + [gl_asmext='s' + gl_c_asm_opt='-S' + ]) +]) diff --git a/config/bootstrap b/config/bootstrap new file mode 100755 index 0000000..793579a --- /dev/null +++ b/config/bootstrap @@ -0,0 +1,209 @@ +#! /bin/bash +# -*- Mode: Shell-script -*- +# +# bootstrap --- maintainer's bootstrap script +# +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen 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. +## +## AutoGen is distributed in the hope that 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 script is designed to find any directories which contain a +# configure.ac in script, and to run the autotools programs from each +# of those directories to make sure they are in a state ready to +# 'configure; make; make install' +# +# Often this process involves more than `libtoolize; automake; autoconf', +# so supplementary actions can be placed in a bootstrap.local script +# in the same directory as this script, and anywhere in the source tree +# in bootstrap.dir files. The bootstrap.local script will be sourced +# twice; first with BOOTSTRAP=pre before the main part is run, and then +# again with BOOTSTRAP=post after the main part has finished. This makes +# it possible to set up any links or temporary files required for this +# script to work before it has executed, and then remove them when it +# has finished. The bootstrap.dir files are also sourced, in a random +# order, as they are found in the tree just before the BOOTSTRAP=post +# phase. This allows a developer to put any peculiar bootstrap actions +# required by individual directories where they can be seen (and not +# forgotten!). +# +# In an ideal world, running this bootstrap script (including any extra +# scripts it executes) should leave a freshly checked out repository tree +# in the same state as a freshly unrolled tarball. In this way, one +# no longer has to maintain generated files under source control, they +# can be generated after checkout using this bootstrap procedure. + +PS4='+BS=${FUNCNAME:-=}-$LINENO> ' + +top_srcdir=$( + cd $(dirname $0)/.. >/dev/null || kill -9 $$ + pwd ) +top_builddir=${top_srcdir} + +PS4='+shlib=${FUNCNAME:-=}-$LINENO> ' \ + source config/bootstrap.shlib + +config_tools() +{ + config_file=configure.ac + conf_dir=${top_srcdir}/config + test -f "${top_srcdir}/${config_file}.pre" || \ + die "${config_file}.pre not in ${top_srcdir}" + + # This missing function is used in many places + # + export config_file top_srcdir top_builddir + + # ------------------------------------------------------------------ + # Make sure all of the maintainer tools required for bootstrap are + # available on the host machine. + # ------------------------------------------------------------------ + # + tools="autoconf autoheader aclocal automake libtoolize" + for f in $tools + do + tool=$(command -v ${f}) > /dev/null || die "No $f found" + eval ${f}_reqver=$( + set -- $(${tool} --version | sed 1q) + eval echo \${$#}) + eval $(echo $f | tr '[a-z]' '[A-Z]')=${tool} + done + + char_mapper=$(command -v char-mapper) 2>/dev/null + test -x "${char_mapper}" || { + char_mapper=$( + cd add-on/char-mapper >&2 + make char-mapper >&2 || die "cannot make char-mapper" + echo ${PWD}/char-mapper) + } + export char_mapper + + echo bootstrapping in ${PWD} + if test -d "${TEMP_DIR}" + then + i_made_temp_dir=false + + else + TEMP_DIR=`mktemp -d ${TMPDIR:-/tmp}/bs-XXXXXX` + i_made_temp_dir=true + export TEMP_DIR + fi + test -d "$TEMP_DIR" || { + temp_dir=${TMP:-/tmp}/bs-$$ + rm -rf ${TEMP_DIR} + mkdir ${TEMP_DIR} + chmod 700 ${TEMP_DIR} + } + + trap "rm -rf ${TEMP_DIR}" 0 + set +e +} + +# Source any local scripts which add to the bootstrap procedure. +# The bootstrap.local script should test the value of the BOOTSTRAP +# environment variable to see whether it should run the sections +# to be called before the main script, or afterwards. +# +source_bs() { + local file=${2} + cd ${file%/*} + file=${file##*/} + test -f $file && ( + PS4="+${1#./}=\${FUNCNAME:-=}-\$LINENO> " + shift 2 + : IN $PWD sourcing $file + source ${PWD}/${file} ${1+"$@"} || die ${file} failed + ) + file=${PWD##*/} + cd - >/dev/null +} + +pre_local() +{ + BOOTSTRAP=pre REQUEST_METHOD= + export BOOTSTRAP + unset REQUEST_METHOD + source_bs pbs ${conf_dir}/bootstrap.local pre + source_bs aobs autoopts/bootstrap.dir aoconf +} + +post_local() +{ + bslist=`find . -name bootstrap.dir` + for f in ${bslist} + do + source_bs ${f%/bootstrap.dir} $f recursive + done + + source_bs Abs ${conf_dir}/bootstrap.local post +} + +filter_chaff() { + cat > ${TEMP_DIR}/config-log.txt + if test -f configure + then + sedcmd='/configure.ac:.*no .* detected/,/configure.ac:.*top level/d' + sed "$sedcmd" ${TEMP_DIR}/config-log.txt + else + cat ${TEMP_DIR}/config-log.txt + fi +} + +run_autotools() +{ + cd ${top_builddir} + # remove any stale config.cache + doit rm -f config.cache + + test -n "$auxdir" || auxdir=${top_srcdir} + test -d $auxdir || auxdir=. + + doit $LIBTOOLIZE --force + doit $ACLOCAL -I config + doit $AUTOHEADER + doit $AUTOMAKE --gnu --add-missing + test -f libtool || cp -fp $(command -v libtool) . + doit $AUTOCONF + sedcmd='s/^PS4=/## PS4=/' + shopt -qo xtrace && { + sedcmd+=$';/SHELL.*CONFIG_STATUS/{\n' + sedcmd+='s/^/ PS4="+csts=\\${FUNCNAME:-=}-\\$LINENO> " /' + sedcmd+=$'\ns/SHELL /SHELL -x /\n}' + } + sed -i "$sedcmd" configure +} + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# +# M A I N +# +{ + config_tools + pre_local + ( run_autotools 2>&1 ) | filter_chaff + post_local + + trap '' 0 + echo 'bootstrap complete' + ${i_made_temp_dir} && rm -rf ${TEMP_DIR} + : ; exit +} +# Local Variables: +# mode:shell-script +# sh-indentation:4 +# sh-basic-offset:4 +# indent-tabs-mode: nil +# End: + +# bootstrap ends here diff --git a/config/bootstrap.local b/config/bootstrap.local new file mode 100644 index 0000000..fd50f3a --- /dev/null +++ b/config/bootstrap.local @@ -0,0 +1,277 @@ +#! /bin/echo This_file_must_be_sourced,_not_executed +# +# config/bootstrap.local --- maintainer's bootstrap script +# +# Author: Bruce Korb +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen 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. +## +## AutoGen is distributed in the hope that 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 . + +locate_exe() +{ + if [ -x "$1" ] + then + echo "$1" + return 0 + fi + + case "${1}" in + */* ) + echo "Cannot find ${1}" >&2 + return 1 + ;; + "" ) + echo "USAGE: locate_exe " >&2 + exit 1 + ;; + * ) + name="${1}" + ;; + esac + + SV="${IFS}" + IFS=" :" + set -- ${PATH} + for f + do + if [ -x ${f}/${name} ] + then + echo ${f}/${name} + return 0 + fi + done + return 1 +} + +install_m4() { + local d= m4=$1 ; shift + set -- ${1+"$@"} /usr/local/share /usr/share + for d + do + test -f "$d/aclocal/$m4" || continue + echo "Installing $m4" + cp "$d/aclocal/$m4" config/. + return 0 + done + return 1 +} + +one_year_limit() { + ( + set +x + year_ago=$(( $(date +%s) - (60 * 60 * 24 * 365) )) + limit=$(date --date=@${year_ago} +%Y-%M-%d) + while IFS= read -r line + do + if [[ "$line" =~ ^[12].* ]] + then + set -- $line + [[ "$1" < "$limit" ]] && exit 0 + fi + + echo "$line" + done + ) +} + +find_gnulib() { + test -z "$GNULIBDIR" && { + local gld=$(command -v gnulib-tool) + test "X$gld" = "X" || gld=$(dirname "$gld") + for d in $HOME/tools/gnulib ~gnu/proj/gnulib /usr/share/gnulib \ + ${gld:+"$gld"} + do + test -d "$d" && GNULIBDIR=$d && break + done + test -z "$GNULIBDIR" && die "cannot find GNULIBDIR" + } + unset LANG || LANG='' + for f in gnulib-tool m4/lib-link.m4 build-aux/config.rpath \ + build-aux/git-version-gen + do test -s ${GNULIBDIR}/$f || die "not found: ${GNULIBDIR}/$f" + g=${f##*/} ; g=${g%%.*} ; g=${g//-/_} + eval export GL_${g^^}=${GNULIBDIR}/$f + done +} + +set_ag_ver() { + local cmt= ver=$( + \cd ${SOURCE_DIR} + ${GL_GIT_VERSION_GEN} ZZJUNK) + + export AG_MAJOR_VERSION=${ver%%.*} + ver=${ver#${AG_MAJOR_VERSION}.} + local scmd="s/^AG_MAJOR_VERSION=.*/AG_MAJOR_VERSION=${AG_MAJOR_VERSION}/" + + export AG_MINOR_VERSION=${ver%%.*} + ver=${ver#${AG_MINOR_VERSION}} + scmd+=";s/^AG_MINOR_VERSION=.*/AG_MINOR_VERSION=${AG_MINOR_VERSION}/" + + ver=${ver#.} + export AG_PATCHLEVEL= + if test ${#ver} -eq 0 + then + export AG_PATCHLEVEL= + else + export AG_PATCHLEVEL=.${ver%%.*} + ver=${ver#${AG_PATCHLEVEL#.}} + test ${#ver} -gt 0 && { + ver=${ver#.} + AG_PATCHLEVEL+=.$(printf %03u ${ver%%-*}) + } + fi + scmd+=";s/^AG_PATCHLEVEL=.*/AG_PATCHLEVEL=${AG_PATCHLEVEL}/" + sed "$scmd" VERSION.pre > VERSION + eval "$(egrep '^[A-Z][A-Z0-9_]+=' VERSION | sed 's/^/export /')" + test ${#AGexe} -eq 0 && AGexe=autogen + f=$(command -v ${AGexe}) + if test -x "$f" + then AGexe="$f" + else AGexe=$(command -v autogen) + fi +} + +config_versions() { + find_gnulib + set_ag_ver + unset LANG || LANG='' + + sedcmd="s/^AC_INIT(.*/AC_INIT([${PACKAGE}],[${AG_VERSION}],[${EADDR}])/" + + sed "$sedcmd" ${config_file}.pre > ${config_file} + sedcmd="/eaddr *=/s/= .*/= '${EADDR}';/" + for f in $(egrep -l 'eaddr +=' */*opts.def) + do sed "$sedcmd" $f > X ; mv -f X $f + done + + sed "1s/__CURRENT_VERSION__.*/${AG_VERSION} - $(date '+%B %Y')/" NEWS.pre > NEWS + + cd ${top_srcdir} + + cp snprintfv/snprintfv.m4 config/. + f=$(exec 2>/dev/null ; command -v guile) + test ${#f} -gt 0 && f=${f%/guile} && f=${f%/bin} + install_m4 guile.m4 $f + install_m4 pkg.m4 + + marker='=== Component Todo:' + sedcmd="/${marker}/,\$d" + rm -f TODO + { + sed "$sedcmd" TODO-top + for f in */TODO + do + test -s $f || continue + echo ; echo ${marker} ${f} '===' + cat ${f} + done + } > TODO + cd ${top_srcdir} + + glopts=' + --import + --lgpl=2 + --lib=do_not_make_me + --libtool + --local-dir=tmp + --m4-base=config + --makefile-name=gnulib.mk + --no-changelog + --source-base=autoopts + --symlink' + glmods=' + extensions + gendocs + gettext-h + havelib + parse-duration + snippet/_Noreturn + stdnoreturn' + cmd=$(echo ${GL_GNULIB_TOOL} $glopts $glmods) + echo GNULIB-TOOL: $cmd + ${cmd} + sed -i 's/do_not_make_me_.*_SOURCES/EXTRA_DIST/;/do_not_make_me/d' \ + autoopts/gnulib.mk + sedcmd=$(cat <<- \_EndOfSed + s@/config/snippet/@/compat/@ + \@begin .*snippet/_Noreturn@,\@end .*snippet/_Noreturn@ { + /^##/d + p + } + \@begin .* module stdnoreturn@,\@end .* module stdnoreturn@ { + /^##/d + p + } + _EndOfSed + ) + sedcmd='s@/config/snippet/@/compat/@' + sedcmd+=$'\n\@begin .*snippet/_Noreturn@,\@end .*snippet/_Noreturn@ p' + sedcmd+=$'\n\@begin .* module stdnoreturn@,\@end .* module stdnoreturn@ p' + sed -n "$sedcmd" autoopts/gnulib.mk | \ + grep -v '^##' > pkg/libopts/stdnoreturn.mk + cp autoopts/gnulib.mk /tmp + cp ${GNULIBDIR}/build-aux/config.rpath ${GNULIBDIR}/m4/lib-link.m4 config/. + + ${GNULIBDIR}/build-aux/gitlog-to-changelog | \ + one_year_limit > ${top_srcdir}/ChangeLog + echo GNULIB-TOOL-DONE +} + +tweak_Makefile_am() +{ + # IF the source dir is not known, + # THEN it is the directory above the directory of this file. + # + test -z "${top_srcdir}" && \ + top_srcdir=$({ \cd $(dirname $0) ; \cd .. ; } >/dev/null ; pwd) + cd ${top_srcdir}/pkg + { + sed '/^LIBOPTS_FILES *=/{ + s/=.*/= \\/ + q + }' Makefile.am.pre + + find libopts -type f -name '[a-zA-Z]*' | \ + columns --spread=1 -I4 --line=' \' + echo + + sed '1,/LIBOPTS_FILES *=/d' Makefile.am.pre + } > Makefile.am + cd ${top_srcdir} + cp agen5/Makefile.am.pre agen5/Makefile.am +} + +cd ${top_srcdir} + +case "${1}" in +( pre ) + echo '@setfilename autogen.info' > doc/autogen.texi + test -f ${top_srcdir}/configure && rm -f ${top_srcdir}/configure + config_versions + tweak_Makefile_am + ;; + +( post ) + rm -f doc/autogen.texi + ;; +esac + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# indent-tabs-mode: nil +# End: + +# config/bootstrap.local ends here diff --git a/config/bootstrap.shlib b/config/bootstrap.shlib new file mode 100644 index 0000000..26aeb04 --- /dev/null +++ b/config/bootstrap.shlib @@ -0,0 +1,256 @@ +#! /bin/echo This_file_must_be_sourced,_not_executed +# config/bootstrap.local --- maintainer's bootstrap script +# +# Author: Bruce Korb +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen 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. +## +## AutoGen is distributed in the hope that 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 file contains various utility functions for the "bootstrap" scripts +# that are scattered about. + +mainpid=$$ + +die() { + echo "bootstrap failure: $*" >&2 + kill -9 ${mainpid} + exit 1 +} + +doit () +{ + if test "x$1" != x: + then + echo "RUN: $*" + eval "$@" || die "FAILURE $?: $*" + fi +} + +case `set -o` in +*posix*) set -o posix ;; +*) exec bash $0 ${1+"$@"} ;; +esac + +case "${SHELL}" in +*[akz]sh) : ;; +*) + while : ; do + SHELL=`which bash 2>/dev/null` + test -x "${SHELL}" && break + + SHELL=`which ksh 2>/dev/null` + test -x "${SHELL}" && break + + SHELL=/usr/xpg4/bin/sh + test -x "${SHELL}" && break + + SHELL=`which sh 2>/dev/null` + test -x "${SHELL}" && break + + die "unable to determine which shell to use" + done + ;; +esac + +case "${VERBOSE}" in +[tTyY1]* ) VERBOSE=true ;; +[fFnN0]* ) VERBOSE=false ;; +* ) + case "$-" in + *x* ) VERBOSE=true ;; + * ) VERBOSE=false ;; + esac +esac + +if ${VERBOSE} +then setx=set\ -x dashx=-x ; set -x +else setx=: dashx= ; set +x +fi + +test -z "${BASH_VERSION}" && \ + local() { "$@" ; } + +# Setup run_ag +test ${#top_srcdir} -eq 0 && { + echo "NO TOP DIRECTORY in $PWD" + exit 1 +} 1>&2 +f=$(\cd ${top_srcdir}/autoopts/tpl >/dev/null && pwd) +test ${#top_builddir} -eq 0 && { + echo "NO BUILD DIRECTORY in $PWD" + exit 1 +} 1>&2 +g=$(\cd ${top_builddir}/autoopts/tpl >/dev/null && pwd) +tpl_dir='-L'$f +test "X$f" = "X$g" || tpl_dir=$tpl_dir' -L'$g +readonly tpl_dir + +if ${VERBOSE} +then + # vgopts='--suppressions=/old-home/bkorb/ag/valgrind.conf --leak-check=yes' + # valgrind ${vgopts} --log-file=${vgfile} \ + + run_ag() + { + local tag=${1} ; shift + # local vgfile=/tmp/vglog/${tag}-%p.txt + local tfile='>>'ag-${tag}-$$.log + if test -n "$DEPFILE" + then tag="-MTstamp-${tag} -MF${DEPFILE} -MP" + else tag="-MFstamp-${tag} -MP" + fi + tag="${tag} --trace=every --trace-out=${tfile}" + + MALLOC_CHECK_=2 \ + ${AGexe} ${tpl_dir} ${tag} "$@" || die "FAILED: ${AGexe} $*" + } +else + run_ag() + { + # local vgfile=/tmp/vglog/${1}-%p.txt + if test -n "$DEPFILE" + then tag="-MTstamp-${1} -MF${DEPFILE} -MP" + else tag="-MFstamp-${1} -MP" + fi + shift + + echo ${AGexe} ${tpl_dir} ${tag} "$@" + ${AGexe} ${tpl_dir} ${tag} "$@" || die "FAILED: ${AGexe} $*" + } +fi + +trap 'die "trapped exit signal"' 0 + +test "X${CDPATH}" = X || { + ( unset CDPATH ) > /dev/null 2>&1 && unset CDPATH || CDPATH='' +} + +nl=$'\n' +ht=$'\t' +GREP=$(command -v grep) +EGREP=${GREP}\ -E +FGREP=${GREP}\ -F + +# Check for AutoGen version 5. +# +skip_gen=false +test -x "${AGexe}" || { + AGexe=${AGexe:-$(command -v autogen)} + test -x "$AGexe" || { + skip_gen=true + AGexe='die "AutoGen requires autogen to bootstrap"' + GDexe=${AGexe} + CLexe=${AGexe} + } +} + +${skip_gen} || { + v="$($AGexe --version || :)" + v=$(echo "$v" | sed 's/.* //;1q') + case "$v" in + 5.* ) : ;; + * ) die "OUT OF DATE AutoGen: $v" ;; + esac + + GDexe=${AGexe%/*}/getdefs + CLexe=${AGexe%/*}/columns + test -x "${GDexe}" -a -x "${CLexe}" || \ + die "autogen support programs are missing" +} + +export AGexe GDexe CLexe setx dashx VERBOSE nl ht + +untar_touch() { + list=`tar -xzvf "$@"` + touch $list +} + +# # # # # # # # # # # # # # # # # # # +# +# Make the option processing files: +# +make_opts() +{ + # Make the option processing files: + # + if ${skip_gen} + then untar_touch ${PWD##*/}-opts.tgz + else run_ag opts ${DEBUG_OPTS} *opts.def + fi +} + +# # # # # # # # # # # # # # # # # # # +# +# Extract all the static procedure declarations into a "proto.h" header. +# These functions are shared throughout the autoopts code. +# +make_proto() +{ + local temp_proto=proto-h$$ proto_h=proto.h + + exec 5> $temp_proto + + local files=`ls -1 *.c | grep -v 'fsm\.c$'` + local base_dir=`basename \`pwd\`` + local marker=`echo ${base_dir} | tr '[a-z]' '[A-Z]'`_PROTO_H_GUARD + + cat >&5 <<- _EOF_ + /* -*- buffer-read-only: t -*- vi: set ro: + * + * Prototypes for ${base_dir} + * Generated `date` + */ + #ifndef ${marker} + #define ${marker} 1 + + _EOF_ + + deplist= + local sed_static='\@^\(noreturn \)\?static @, \@^{@ p' + local sed_trim='s/)$/);/;s/^{.*//' + + for f in ${files} + do + grep -q 'buffer-read-only:' $f && continue + + txt=$(sed -n "$sed_static" $f | sed "$sed_trim") + test ${#txt} -gt 4 && { + printf '\n/*\n * Static declarations from %s\n */\n' $f + echo "$txt" + } >&5 + done + cat >&5 <<- _EOF + + #endif /* ${marker} */ + _EOF + exec 5>&- + + if test -f ${proto_h} && cmp -s ${temp_proto} ${proto_h} + then + rm -f ${temp_proto} + touch ${proto_h} + else + mv -f ${temp_proto} ${proto_h} + fi +} + +# Local Variables: +# mode:shell-script +# sh-indentation:4 +# sh-basic-offset:4 +# indent-tabs-mode: nil +# End: + +# bootstrap.shlib ends here diff --git a/config/compile b/config/compile new file mode 100755 index 0000000..99e5052 --- /dev/null +++ b/config/compile @@ -0,0 +1,348 @@ +#! /bin/sh +# Wrapper for compilers which do not understand '-c -o'. + +scriptversion=2018-03-07.03; # UTC + +# Copyright (C) 1999-2018 Free Software Foundation, Inc. +# Written by Tom Tromey . +# +# 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. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# This file is maintained in Automake, please report +# bugs to or send patches to +# . + +nl=' +' + +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent tools from complaining about whitespace usage. +IFS=" "" $nl" + +file_conv= + +# func_file_conv build_file lazy +# Convert a $build file to $host form and store it in $file +# Currently only supports Windows hosts. If the determined conversion +# type is listed in (the comma separated) LAZY, no conversion will +# take place. +func_file_conv () +{ + file=$1 + case $file in + / | /[!/]*) # absolute file, and not a UNC file + if test -z "$file_conv"; then + # lazily determine how to convert abs files + case `uname -s` in + MINGW*) + file_conv=mingw + ;; + CYGWIN*) + file_conv=cygwin + ;; + *) + file_conv=wine + ;; + esac + fi + case $file_conv/,$2, in + *,$file_conv,*) + ;; + mingw/*) + file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` + ;; + cygwin/*) + file=`cygpath -m "$file" || echo "$file"` + ;; + wine/*) + file=`winepath -w "$file" || echo "$file"` + ;; + esac + ;; + esac +} + +# func_cl_dashL linkdir +# Make cl look for libraries in LINKDIR +func_cl_dashL () +{ + func_file_conv "$1" + if test -z "$lib_path"; then + lib_path=$file + else + lib_path="$lib_path;$file" + fi + linker_opts="$linker_opts -LIBPATH:$file" +} + +# func_cl_dashl library +# Do a library search-path lookup for cl +func_cl_dashl () +{ + lib=$1 + found=no + save_IFS=$IFS + IFS=';' + for dir in $lib_path $LIB + do + IFS=$save_IFS + if $shared && test -f "$dir/$lib.dll.lib"; then + found=yes + lib=$dir/$lib.dll.lib + break + fi + if test -f "$dir/$lib.lib"; then + found=yes + lib=$dir/$lib.lib + break + fi + if test -f "$dir/lib$lib.a"; then + found=yes + lib=$dir/lib$lib.a + break + fi + done + IFS=$save_IFS + + if test "$found" != yes; then + lib=$lib.lib + fi +} + +# func_cl_wrapper cl arg... +# Adjust compile command to suit cl +func_cl_wrapper () +{ + # Assume a capable shell + lib_path= + shared=: + linker_opts= + for arg + do + if test -n "$eat"; then + eat= + else + case $1 in + -o) + # configure might choose to run compile as 'compile cc -o foo foo.c'. + eat=1 + case $2 in + *.o | *.[oO][bB][jJ]) + func_file_conv "$2" + set x "$@" -Fo"$file" + shift + ;; + *) + func_file_conv "$2" + set x "$@" -Fe"$file" + shift + ;; + esac + ;; + -I) + eat=1 + func_file_conv "$2" mingw + set x "$@" -I"$file" + shift + ;; + -I*) + func_file_conv "${1#-I}" mingw + set x "$@" -I"$file" + shift + ;; + -l) + eat=1 + func_cl_dashl "$2" + set x "$@" "$lib" + shift + ;; + -l*) + func_cl_dashl "${1#-l}" + set x "$@" "$lib" + shift + ;; + -L) + eat=1 + func_cl_dashL "$2" + ;; + -L*) + func_cl_dashL "${1#-L}" + ;; + -static) + shared=false + ;; + -Wl,*) + arg=${1#-Wl,} + save_ifs="$IFS"; IFS=',' + for flag in $arg; do + IFS="$save_ifs" + linker_opts="$linker_opts $flag" + done + IFS="$save_ifs" + ;; + -Xlinker) + eat=1 + linker_opts="$linker_opts $2" + ;; + -*) + set x "$@" "$1" + shift + ;; + *.cc | *.CC | *.cxx | *.CXX | *.[cC]++) + func_file_conv "$1" + set x "$@" -Tp"$file" + shift + ;; + *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO]) + func_file_conv "$1" mingw + set x "$@" "$file" + shift + ;; + *) + set x "$@" "$1" + shift + ;; + esac + fi + shift + done + if test -n "$linker_opts"; then + linker_opts="-link$linker_opts" + fi + exec "$@" $linker_opts + exit 1 +} + +eat= + +case $1 in + '') + echo "$0: No command. Try '$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: compile [--help] [--version] PROGRAM [ARGS] + +Wrapper for compilers which do not understand '-c -o'. +Remove '-o dest.o' from ARGS, run PROGRAM with the remaining +arguments, and rename the output as expected. + +If you are trying to build a whole package this is not the +right script to run: please start by reading the file 'INSTALL'. + +Report bugs to . +EOF + exit $? + ;; + -v | --v*) + echo "compile $scriptversion" + exit $? + ;; + cl | *[/\\]cl | cl.exe | *[/\\]cl.exe | \ + icl | *[/\\]icl | icl.exe | *[/\\]icl.exe ) + func_cl_wrapper "$@" # Doesn't return... + ;; +esac + +ofile= +cfile= + +for arg +do + if test -n "$eat"; then + eat= + else + case $1 in + -o) + # configure might choose to run compile as 'compile cc -o foo foo.c'. + # So we strip '-o arg' only if arg is an object. + eat=1 + case $2 in + *.o | *.obj) + ofile=$2 + ;; + *) + set x "$@" -o "$2" + shift + ;; + esac + ;; + *.c) + cfile=$1 + set x "$@" "$1" + shift + ;; + *) + set x "$@" "$1" + shift + ;; + esac + fi + shift +done + +if test -z "$ofile" || test -z "$cfile"; then + # If no '-o' option was seen then we might have been invoked from a + # pattern rule where we don't need one. That is ok -- this is a + # normal compilation that the losing compiler can handle. If no + # '.c' file was seen then we are probably linking. That is also + # ok. + exec "$@" +fi + +# Name of file we expect compiler to create. +cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` + +# Create the lock directory. +# Note: use '[/\\:.-]' here to ensure that we don't use the same name +# that we are using for the .o file. Also, base the name on the expected +# object file name, since that is what matters with a parallel build. +lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d +while true; do + if mkdir "$lockdir" >/dev/null 2>&1; then + break + fi + sleep 1 +done +# FIXME: race condition here if user kills between mkdir and trap. +trap "rmdir '$lockdir'; exit 1" 1 2 15 + +# Run the compile. +"$@" +ret=$? + +if test -f "$cofile"; then + test "$cofile" = "$ofile" || mv "$cofile" "$ofile" +elif test -f "${cofile}bj"; then + test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile" +fi + +rmdir "$lockdir" +exit $ret + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC0" +# time-stamp-end: "; # UTC" +# End: diff --git a/config/config.guess b/config/config.guess new file mode 100755 index 0000000..256083a --- /dev/null +++ b/config/config.guess @@ -0,0 +1,1476 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright 1992-2018 Free Software Foundation, Inc. + +timestamp='2018-03-08' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that +# program. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). +# +# Originally written by Per Bothner; maintained since 2000 by Ben Elliston. +# +# You can get the latest version of this script from: +# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess +# +# Please send patches to . + + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Options: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright 1992-2018 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > "$dummy.c" ; + for c in cc gcc c89 c99 ; do + if ($c -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ; set_cc_for_build= ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +case "$UNAME_SYSTEM" in +Linux|GNU|GNU/*) + # If the system lacks a compiler, then just pick glibc. + # We could probably try harder. + LIBC=gnu + + eval "$set_cc_for_build" + cat <<-EOF > "$dummy.c" + #include + #if defined(__UCLIBC__) + LIBC=uclibc + #elif defined(__dietlibc__) + LIBC=dietlibc + #else + LIBC=gnu + #endif + EOF + eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`" + + # If ldd exists, use it to detect musl libc. + if command -v ldd >/dev/null && \ + ldd --version 2>&1 | grep -q ^musl + then + LIBC=musl + fi + ;; +esac + +# Note: order is significant - the case branches are not exclusive. + +case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \ + "/sbin/$sysctl" 2>/dev/null || \ + "/usr/sbin/$sysctl" 2>/dev/null || \ + echo unknown)` + case "$UNAME_MACHINE_ARCH" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + sh5el) machine=sh5le-unknown ;; + earmv*) + arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,'` + endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'` + machine="${arch}${endian}"-unknown + ;; + *) machine="$UNAME_MACHINE_ARCH"-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently (or will in the future) and ABI. + case "$UNAME_MACHINE_ARCH" in + earm*) + os=netbsdelf + ;; + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval "$set_cc_for_build" + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ELF__ + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # Determine ABI tags. + case "$UNAME_MACHINE_ARCH" in + earm*) + expr='s/^earmv[0-9]/-eabi/;s/eb$//' + abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"` + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "$UNAME_VERSION" in + Debian*) + release='-gnu' + ;; + *) + release=`echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "$machine-${os}${release}${abi}" + exit ;; + *:Bitrig:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` + echo "$UNAME_MACHINE_ARCH"-unknown-bitrig"$UNAME_RELEASE" + exit ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + echo "$UNAME_MACHINE_ARCH"-unknown-openbsd"$UNAME_RELEASE" + exit ;; + *:LibertyBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'` + echo "$UNAME_MACHINE_ARCH"-unknown-libertybsd"$UNAME_RELEASE" + exit ;; + *:MidnightBSD:*:*) + echo "$UNAME_MACHINE"-unknown-midnightbsd"$UNAME_RELEASE" + exit ;; + *:ekkoBSD:*:*) + echo "$UNAME_MACHINE"-unknown-ekkobsd"$UNAME_RELEASE" + exit ;; + *:SolidBSD:*:*) + echo "$UNAME_MACHINE"-unknown-solidbsd"$UNAME_RELEASE" + exit ;; + macppc:MirBSD:*:*) + echo powerpc-unknown-mirbsd"$UNAME_RELEASE" + exit ;; + *:MirBSD:*:*) + echo "$UNAME_MACHINE"-unknown-mirbsd"$UNAME_RELEASE" + exit ;; + *:Sortix:*:*) + echo "$UNAME_MACHINE"-unknown-sortix + exit ;; + *:Redox:*:*) + echo "$UNAME_MACHINE"-unknown-redox + exit ;; + mips:OSF1:*.*) + echo mips-dec-osf1 + exit ;; + alpha:OSF1:*:*) + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE=alpha ;; + "EV4.5 (21064)") + UNAME_MACHINE=alpha ;; + "LCA4 (21066/21068)") + UNAME_MACHINE=alpha ;; + "EV5 (21164)") + UNAME_MACHINE=alphaev5 ;; + "EV5.6 (21164A)") + UNAME_MACHINE=alphaev56 ;; + "EV5.6 (21164PC)") + UNAME_MACHINE=alphapca56 ;; + "EV5.7 (21164PC)") + UNAME_MACHINE=alphapca57 ;; + "EV6 (21264)") + UNAME_MACHINE=alphaev6 ;; + "EV6.7 (21264A)") + UNAME_MACHINE=alphaev67 ;; + "EV6.8CB (21264C)") + UNAME_MACHINE=alphaev68 ;; + "EV6.8AL (21264B)") + UNAME_MACHINE=alphaev68 ;; + "EV6.8CX (21264D)") + UNAME_MACHINE=alphaev68 ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE=alphaev69 ;; + "EV7 (21364)") + UNAME_MACHINE=alphaev7 ;; + "EV7.9 (21364A)") + UNAME_MACHINE=alphaev79 ;; + esac + # A Pn.n version is a patched version. + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + echo "$UNAME_MACHINE"-dec-osf"`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`" + # Reset EXIT trap before exiting to avoid spurious non-zero exit code. + exitcode=$? + trap '' 0 + exit $exitcode ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo "$UNAME_MACHINE"-unknown-amigaos + exit ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo "$UNAME_MACHINE"-unknown-morphos + exit ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit ;; + *:z/VM:*:*) + echo s390-ibm-zvmoe + exit ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix"$UNAME_RELEASE" + exit ;; + arm*:riscos:*:*|arm*:RISCOS:*:*) + echo arm-unknown-riscos + exit ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit ;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7; exit ;; + esac ;; + s390x:SunOS:*:*) + echo "$UNAME_MACHINE"-ibm-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`" + exit ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" + exit ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`" + exit ;; + i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) + echo i386-pc-auroraux"$UNAME_RELEASE" + exit ;; + i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) + eval "$set_cc_for_build" + SUN_ARCH=i386 + # If there is a compiler, see if it is configured for 64-bit objects. + # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. + # This test works for both compilers. + if [ "$CC_FOR_BUILD" != no_compiler_found ]; then + if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + SUN_ARCH=x86_64 + fi + fi + echo "$SUN_ARCH"-pc-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" + exit ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" + exit ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos"`echo "$UNAME_RELEASE"|sed -e 's/-/_/'`" + exit ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos"$UNAME_RELEASE" + exit ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos"$UNAME_RELEASE" + ;; + sun4) + echo sparc-sun-sunos"$UNAME_RELEASE" + ;; + esac + exit ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos"$UNAME_RELEASE" + exit ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint"$UNAME_RELEASE" + exit ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint"$UNAME_RELEASE" + exit ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint"$UNAME_RELEASE" + exit ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint"$UNAME_RELEASE" + exit ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint"$UNAME_RELEASE" + exit ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint"$UNAME_RELEASE" + exit ;; + m68k:machten:*:*) + echo m68k-apple-machten"$UNAME_RELEASE" + exit ;; + powerpc:machten:*:*) + echo powerpc-apple-machten"$UNAME_RELEASE" + exit ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix"$UNAME_RELEASE" + exit ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix"$UNAME_RELEASE" + exit ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix"$UNAME_RELEASE" + exit ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval "$set_cc_for_build" + sed 's/^ //' << EOF > "$dummy.c" +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o "$dummy" "$dummy.c" && + dummyarg=`echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`"$dummy" "$dummyarg"` && + { echo "$SYSTEM_NAME"; exit; } + echo mips-mips-riscos"$UNAME_RELEASE" + exit ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ "$UNAME_PROCESSOR" = mc88100 ] || [ "$UNAME_PROCESSOR" = mc88110 ] + then + if [ "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx ] || \ + [ "$TARGET_BINARY_INTERFACE"x = x ] + then + echo m88k-dg-dgux"$UNAME_RELEASE" + else + echo m88k-dg-dguxbcs"$UNAME_RELEASE" + fi + else + echo i586-dg-dgux"$UNAME_RELEASE" + fi + exit ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit ;; + *:IRIX*:*:*) + echo mips-sgi-irix"`echo "$UNAME_RELEASE"|sed -e 's/-/_/g'`" + exit ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV="$UNAME_VERSION.$UNAME_RELEASE" + fi + echo "$UNAME_MACHINE"-ibm-aix"$IBM_REV" + exit ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval "$set_cc_for_build" + sed 's/^ //' << EOF > "$dummy.c" + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` + then + echo "$SYSTEM_NAME" + else + echo rs6000-ibm-aix3.2.5 + fi + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit ;; + *:AIX:*:[4567]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/lslpp ] ; then + IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | + awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` + else + IBM_REV="$UNAME_VERSION.$UNAME_RELEASE" + fi + echo "$IBM_ARCH"-ibm-aix"$IBM_REV" + exit ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit ;; + ibmrt:4.4BSD:*|romp-ibm:4.4BSD:*) + echo romp-ibm-bsd4.4 + exit ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd"$UNAME_RELEASE" # 4.3 with uname added to + exit ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'` + case "$UNAME_MACHINE" in + 9000/31?) HP_ARCH=m68000 ;; + 9000/[34]??) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "$sc_cpu_version" in + 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0 + 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "$sc_kernel_bits" in + 32) HP_ARCH=hppa2.0n ;; + 64) HP_ARCH=hppa2.0w ;; + '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "$HP_ARCH" = "" ]; then + eval "$set_cc_for_build" + sed 's/^ //' << EOF > "$dummy.c" + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=`"$dummy"` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ "$HP_ARCH" = hppa2.0w ] + then + eval "$set_cc_for_build" + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | + grep -q __LP64__ + then + HP_ARCH=hppa2.0w + else + HP_ARCH=hppa64 + fi + fi + echo "$HP_ARCH"-hp-hpux"$HPUX_REV" + exit ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux"$HPUX_REV" + exit ;; + 3050*:HI-UX:*:*) + eval "$set_cc_for_build" + sed 's/^ //' << EOF > "$dummy.c" + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` && + { echo "$SYSTEM_NAME"; exit; } + echo unknown-hitachi-hiuxwe2 + exit ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:*) + echo hppa1.1-hp-bsd + exit ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*) + echo hppa1.1-hp-osf + exit ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo "$UNAME_MACHINE"-unknown-osf1mk + else + echo "$UNAME_MACHINE"-unknown-osf1 + fi + exit ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*[A-Z]90:*:*:*) + echo "$UNAME_MACHINE"-cray-unicos"$UNAME_RELEASE" \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' + exit ;; + *:UNICOS/mp:*:*) + echo craynv-cray-unicosmp"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' + exit ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` + FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` + FUJITSU_REL=`echo "$UNAME_RELEASE" | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` + FUJITSU_REL=`echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo "$UNAME_MACHINE"-pc-bsdi"$UNAME_RELEASE" + exit ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi"$UNAME_RELEASE" + exit ;; + *:BSD/OS:*:*) + echo "$UNAME_MACHINE"-unknown-bsdi"$UNAME_RELEASE" + exit ;; + *:FreeBSD:*:*) + UNAME_PROCESSOR=`/usr/bin/uname -p` + case "$UNAME_PROCESSOR" in + amd64) + UNAME_PROCESSOR=x86_64 ;; + i386) + UNAME_PROCESSOR=i586 ;; + esac + echo "$UNAME_PROCESSOR"-unknown-freebsd"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`" + exit ;; + i*:CYGWIN*:*) + echo "$UNAME_MACHINE"-pc-cygwin + exit ;; + *:MINGW64*:*) + echo "$UNAME_MACHINE"-pc-mingw64 + exit ;; + *:MINGW*:*) + echo "$UNAME_MACHINE"-pc-mingw32 + exit ;; + *:MSYS*:*) + echo "$UNAME_MACHINE"-pc-msys + exit ;; + i*:PW*:*) + echo "$UNAME_MACHINE"-pc-pw32 + exit ;; + *:Interix*:*) + case "$UNAME_MACHINE" in + x86) + echo i586-pc-interix"$UNAME_RELEASE" + exit ;; + authenticamd | genuineintel | EM64T) + echo x86_64-unknown-interix"$UNAME_RELEASE" + exit ;; + IA64) + echo ia64-unknown-interix"$UNAME_RELEASE" + exit ;; + esac ;; + i*:UWIN*:*) + echo "$UNAME_MACHINE"-pc-uwin + exit ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + echo x86_64-unknown-cygwin + exit ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" + exit ;; + *:GNU:*:*) + # the GNU system + echo "`echo "$UNAME_MACHINE"|sed -e 's,[-/].*$,,'`-unknown-$LIBC`echo "$UNAME_RELEASE"|sed -e 's,/.*$,,'`" + exit ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo "$UNAME_MACHINE-unknown-`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`-$LIBC" + exit ;; + i*86:Minix:*:*) + echo "$UNAME_MACHINE"-pc-minix + exit ;; + aarch64:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + aarch64_be:Linux:*:*) + UNAME_MACHINE=aarch64_be + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep -q ld.so.1 + if test "$?" = 0 ; then LIBC=gnulibc1 ; fi + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + arc:Linux:*:* | arceb:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + arm*:Linux:*:*) + eval "$set_cc_for_build" + if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_EABI__ + then + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + else + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabi + else + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabihf + fi + fi + exit ;; + avr32*:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + cris:Linux:*:*) + echo "$UNAME_MACHINE"-axis-linux-"$LIBC" + exit ;; + crisv32:Linux:*:*) + echo "$UNAME_MACHINE"-axis-linux-"$LIBC" + exit ;; + e2k:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + frv:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + hexagon:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + i*86:Linux:*:*) + echo "$UNAME_MACHINE"-pc-linux-"$LIBC" + exit ;; + ia64:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + k1om:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + m32r*:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + m68*:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + mips:Linux:*:* | mips64:Linux:*:*) + eval "$set_cc_for_build" + sed 's/^ //' << EOF > "$dummy.c" + #undef CPU + #undef ${UNAME_MACHINE} + #undef ${UNAME_MACHINE}el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=${UNAME_MACHINE}el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=${UNAME_MACHINE} + #else + CPU= + #endif + #endif +EOF + eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU'`" + test "x$CPU" != x && { echo "$CPU-unknown-linux-$LIBC"; exit; } + ;; + mips64el:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + openrisc*:Linux:*:*) + echo or1k-unknown-linux-"$LIBC" + exit ;; + or32:Linux:*:* | or1k*:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + padre:Linux:*:*) + echo sparc-unknown-linux-"$LIBC" + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-"$LIBC" + exit ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-"$LIBC" ;; + PA8*) echo hppa2.0-unknown-linux-"$LIBC" ;; + *) echo hppa-unknown-linux-"$LIBC" ;; + esac + exit ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-"$LIBC" + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-"$LIBC" + exit ;; + ppc64le:Linux:*:*) + echo powerpc64le-unknown-linux-"$LIBC" + exit ;; + ppcle:Linux:*:*) + echo powerpcle-unknown-linux-"$LIBC" + exit ;; + riscv32:Linux:*:* | riscv64:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo "$UNAME_MACHINE"-ibm-linux-"$LIBC" + exit ;; + sh64*:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + sh*:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + tile*:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + vax:Linux:*:*) + echo "$UNAME_MACHINE"-dec-linux-"$LIBC" + exit ;; + x86_64:Linux:*:*) + echo "$UNAME_MACHINE"-pc-linux-"$LIBC" + exit ;; + xtensa*:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo "$UNAME_MACHINE"-pc-sysv4.2uw"$UNAME_VERSION" + exit ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo "$UNAME_MACHINE"-pc-os2-emx + exit ;; + i*86:XTS-300:*:STOP) + echo "$UNAME_MACHINE"-unknown-stop + exit ;; + i*86:atheos:*:*) + echo "$UNAME_MACHINE"-unknown-atheos + exit ;; + i*86:syllable:*:*) + echo "$UNAME_MACHINE"-pc-syllable + exit ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) + echo i386-unknown-lynxos"$UNAME_RELEASE" + exit ;; + i*86:*DOS:*:*) + echo "$UNAME_MACHINE"-pc-msdosdjgpp + exit ;; + i*86:*:4.*:*) + UNAME_REL=`echo "$UNAME_RELEASE" | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo "$UNAME_MACHINE"-univel-sysv"$UNAME_REL" + else + echo "$UNAME_MACHINE"-pc-sysv"$UNAME_REL" + fi + exit ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo "$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}{$UNAME_VERSION}" + exit ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo "$UNAME_MACHINE"-pc-sco"$UNAME_REL" + else + echo "$UNAME_MACHINE"-pc-sysv32 + fi + exit ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i586. + # Note: whatever this is, it MUST be the same as what config.sub + # prints for the "djgpp" host, or else GDB configure will decide that + # this is a cross-build. + echo i586-pc-msdosdjgpp + exit ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv"$UNAME_RELEASE" # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv"$UNAME_RELEASE" # Unknown i860-SVR4 + fi + exit ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + NCR*:*:4.2:* | MPRAS*:*:4.2:*) + OS_REL='.3' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } + /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos"$UNAME_RELEASE" + exit ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos"$UNAME_RELEASE" + exit ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos"$UNAME_RELEASE" + exit ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) + echo powerpc-unknown-lynxos"$UNAME_RELEASE" + exit ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv"$UNAME_RELEASE" + exit ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo "$UNAME_MACHINE"-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + echo "$UNAME_MACHINE"-stratus-vos + exit ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux"$UNAME_RELEASE" + exit ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv"$UNAME_RELEASE" + else + echo mips-unknown-sysv"$UNAME_RELEASE" + fi + exit ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit ;; + BePC:Haiku:*:*) # Haiku running on Intel PC compatible. + echo i586-pc-haiku + exit ;; + x86_64:Haiku:*:*) + echo x86_64-unknown-haiku + exit ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux"$UNAME_RELEASE" + exit ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux"$UNAME_RELEASE" + exit ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux"$UNAME_RELEASE" + exit ;; + SX-7:SUPER-UX:*:*) + echo sx7-nec-superux"$UNAME_RELEASE" + exit ;; + SX-8:SUPER-UX:*:*) + echo sx8-nec-superux"$UNAME_RELEASE" + exit ;; + SX-8R:SUPER-UX:*:*) + echo sx8r-nec-superux"$UNAME_RELEASE" + exit ;; + SX-ACE:SUPER-UX:*:*) + echo sxace-nec-superux"$UNAME_RELEASE" + exit ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody"$UNAME_RELEASE" + exit ;; + *:Rhapsody:*:*) + echo "$UNAME_MACHINE"-apple-rhapsody"$UNAME_RELEASE" + exit ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown + eval "$set_cc_for_build" + if test "$UNAME_PROCESSOR" = unknown ; then + UNAME_PROCESSOR=powerpc + fi + if test "`echo "$UNAME_RELEASE" | sed -e 's/\..*//'`" -le 10 ; then + if [ "$CC_FOR_BUILD" != no_compiler_found ]; then + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + case $UNAME_PROCESSOR in + i386) UNAME_PROCESSOR=x86_64 ;; + powerpc) UNAME_PROCESSOR=powerpc64 ;; + esac + fi + # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc + if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_PPC >/dev/null + then + UNAME_PROCESSOR=powerpc + fi + fi + elif test "$UNAME_PROCESSOR" = i386 ; then + # Avoid executing cc on OS X 10.9, as it ships with a stub + # that puts up a graphical alert prompting to install + # developer tools. Any system running Mac OS X 10.7 or + # later (Darwin 11 and later) is required to have a 64-bit + # processor. This is not true of the ARM version of Darwin + # that Apple uses in portable devices. + UNAME_PROCESSOR=x86_64 + fi + echo "$UNAME_PROCESSOR"-apple-darwin"$UNAME_RELEASE" + exit ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = x86; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo "$UNAME_PROCESSOR"-"$UNAME_MACHINE"-nto-qnx"$UNAME_RELEASE" + exit ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit ;; + NEO-*:NONSTOP_KERNEL:*:*) + echo neo-tandem-nsk"$UNAME_RELEASE" + exit ;; + NSE-*:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk"$UNAME_RELEASE" + exit ;; + NSR-*:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk"$UNAME_RELEASE" + exit ;; + NSV-*:NONSTOP_KERNEL:*:*) + echo nsv-tandem-nsk"$UNAME_RELEASE" + exit ;; + NSX-*:NONSTOP_KERNEL:*:*) + echo nsx-tandem-nsk"$UNAME_RELEASE" + exit ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit ;; + DS/*:UNIX_System_V:*:*) + echo "$UNAME_MACHINE"-"$UNAME_SYSTEM"-"$UNAME_RELEASE" + exit ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = 386; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo "$UNAME_MACHINE"-unknown-plan9 + exit ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux"$UNAME_RELEASE" + exit ;; + *:DragonFly:*:*) + echo "$UNAME_MACHINE"-unknown-dragonfly"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`" + exit ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case "$UNAME_MACHINE" in + A*) echo alpha-dec-vms ; exit ;; + I*) echo ia64-dec-vms ; exit ;; + V*) echo vax-dec-vms ; exit ;; + esac ;; + *:XENIX:*:SysV) + echo i386-pc-xenix + exit ;; + i*86:skyos:*:*) + echo "$UNAME_MACHINE"-pc-skyos"`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'`" + exit ;; + i*86:rdos:*:*) + echo "$UNAME_MACHINE"-pc-rdos + exit ;; + i*86:AROS:*:*) + echo "$UNAME_MACHINE"-pc-aros + exit ;; + x86_64:VMkernel:*:*) + echo "$UNAME_MACHINE"-unknown-esx + exit ;; + amd64:Isilon\ OneFS:*:*) + echo x86_64-unknown-onefs + exit ;; +esac + +echo "$0: unable to guess system type" >&2 + +case "$UNAME_MACHINE:$UNAME_SYSTEM" in + mips:Linux | mips64:Linux) + # If we got here on MIPS GNU/Linux, output extra information. + cat >&2 <&2 </dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = "$UNAME_MACHINE" +UNAME_RELEASE = "$UNAME_RELEASE" +UNAME_SYSTEM = "$UNAME_SYSTEM" +UNAME_VERSION = "$UNAME_VERSION" +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/config/config.rpath b/config/config.rpath new file mode 100755 index 0000000..fc5913d --- /dev/null +++ b/config/config.rpath @@ -0,0 +1,684 @@ +#! /bin/sh +# Output a system dependent set of variables, describing how to set the +# run time search path of shared libraries in an executable. +# +# Copyright 1996-2018 Free Software Foundation, Inc. +# Taken from GNU libtool, 2001 +# Originally by Gordon Matzigkeit , 1996 +# +# 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. +# +# The first argument passed to this file is the canonical host specification, +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# The environment variables CC, GCC, LDFLAGS, LD, with_gnu_ld +# should be set by the caller. +# +# The set of defined variables is at the end of this script. + +# Known limitations: +# - On IRIX 6.5 with CC="cc", the run time search patch must not be longer +# than 256 bytes, otherwise the compiler driver will dump core. The only +# known workaround is to choose shorter directory names for the build +# directory and/or the installation directory. + +# All known linkers require a '.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a +shrext=.so + +host="$1" +host_cpu=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +host_vendor=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +host_os=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` + +# Code taken from libtool.m4's _LT_CC_BASENAME. + +for cc_temp in $CC""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`echo "$cc_temp" | sed -e 's%^.*/%%'` + +# Code taken from libtool.m4's _LT_COMPILER_PIC. + +wl= +if test "$GCC" = yes; then + wl='-Wl,' +else + case "$host_os" in + aix*) + wl='-Wl,' + ;; + mingw* | cygwin* | pw32* | os2* | cegcc*) + ;; + hpux9* | hpux10* | hpux11*) + wl='-Wl,' + ;; + irix5* | irix6* | nonstopux*) + wl='-Wl,' + ;; + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + ecc*) + wl='-Wl,' + ;; + icc* | ifort*) + wl='-Wl,' + ;; + lf95*) + wl='-Wl,' + ;; + nagfor*) + wl='-Wl,-Wl,,' + ;; + pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) + wl='-Wl,' + ;; + ccc*) + wl='-Wl,' + ;; + xl* | bgxl* | bgf* | mpixl*) + wl='-Wl,' + ;; + como) + wl='-lopt=' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ F* | *Sun*Fortran*) + wl= + ;; + *Sun\ C*) + wl='-Wl,' + ;; + esac + ;; + esac + ;; + newsos6) + ;; + *nto* | *qnx*) + ;; + osf3* | osf4* | osf5*) + wl='-Wl,' + ;; + rdos*) + ;; + solaris*) + case $cc_basename in + f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) + wl='-Qoption ld ' + ;; + *) + wl='-Wl,' + ;; + esac + ;; + sunos4*) + wl='-Qoption ld ' + ;; + sysv4 | sysv4.2uw2* | sysv4.3*) + wl='-Wl,' + ;; + sysv4*MP*) + ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + wl='-Wl,' + ;; + unicos*) + wl='-Wl,' + ;; + uts4*) + ;; + esac +fi + +# Code taken from libtool.m4's _LT_LINKER_SHLIBS. + +hardcode_libdir_flag_spec= +hardcode_libdir_separator= +hardcode_direct=no +hardcode_minus_L=no + +case "$host_os" in + cygwin* | mingw* | pw32* | cegcc*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd*) + with_gnu_ld=no + ;; +esac + +ld_shlibs=yes +if test "$with_gnu_ld" = yes; then + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + # Unlike libtool, we use -rpath here, not --rpath, since the documented + # option of GNU ld is called -rpath, not --rpath. + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + case "$host_os" in + aix[3-9]*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + ld_shlibs=no + fi + ;; + amigaos*) + case "$host_cpu" in + powerpc) + ;; + m68k) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + beos*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + : + else + ld_shlibs=no + fi + ;; + 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' + if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then + : + else + ld_shlibs=no + fi + ;; + haiku*) + ;; + interix[3-9]*) + hardcode_direct=no + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + ;; + gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + : + else + ld_shlibs=no + fi + ;; + netbsd*) + ;; + solaris*) + if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then + ld_shlibs=no + elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + : + else + ld_shlibs=no + fi + ;; + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) + ld_shlibs=no + ;; + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`' + else + ld_shlibs=no + fi + ;; + esac + ;; + sunos4*) + hardcode_direct=yes + ;; + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + : + else + ld_shlibs=no + fi + ;; + esac + if test "$ld_shlibs" = no; then + hardcode_libdir_flag_spec= + fi +else + case "$host_os" in + aix3*) + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L=yes + if test "$GCC" = yes; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct=unsupported + fi + ;; + aix[4-9]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + else + aix_use_runtimelinking=no + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + ;; + esac + fi + hardcode_direct=yes + hardcode_libdir_separator=':' + if test "$GCC" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && \ + strings "$collect2name" | grep resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + hardcode_direct=unsupported + hardcode_minus_L=yes + hardcode_libdir_flag_spec='-L$libdir' + hardcode_libdir_separator= + fi + ;; + esac + fi + # Begin _LT_AC_SYS_LIBPATH_AIX. + echo 'int main () { return 0; }' > conftest.c + ${CC} ${LDFLAGS} conftest.c -o conftest + aix_libpath=`dump -H conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'` + if test -z "$aix_libpath"; then + aix_libpath=`dump -HX64 conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'` + fi + if test -z "$aix_libpath"; then + aix_libpath="/usr/lib:/lib" + fi + rm -f conftest.c conftest + # End _LT_AC_SYS_LIBPATH_AIX. + if test "$aix_use_runtimelinking" = yes; then + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' + else + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + fi + fi + ;; + amigaos*) + case "$host_cpu" in + powerpc) + ;; + m68k) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + bsdi[45]*) + ;; + cygwin* | mingw* | pw32* | cegcc*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec=' ' + libext=lib + ;; + darwin* | rhapsody*) + hardcode_direct=no + if { case $cc_basename in ifort*) true;; *) test "$GCC" = yes;; esac; }; then + : + else + ld_shlibs=no + fi + ;; + dgux*) + hardcode_libdir_flag_spec='-L$libdir' + ;; + freebsd2.[01]*) + hardcode_direct=yes + hardcode_minus_L=yes + ;; + freebsd* | dragonfly*) + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + ;; + hpux9*) + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + ;; + hpux10*) + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + fi + ;; + hpux11*) + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + case $host_cpu in + hppa*64*|ia64*) + hardcode_direct=no + ;; + *) + hardcode_direct=yes + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + ;; + esac + fi + ;; + irix5* | irix6* | nonstopux*) + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + netbsd*) + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + ;; + newsos6) + hardcode_direct=yes + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + *nto* | *qnx*) + ;; + openbsd*) + if test -f /usr/libexec/ld.so; then + hardcode_direct=yes + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + else + case "$host_os" in + openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) + hardcode_libdir_flag_spec='-R$libdir' + ;; + *) + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + ;; + esac + fi + else + ld_shlibs=no + fi + ;; + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + osf3*) + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + osf4* | osf5*) + if test "$GCC" = yes; then + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + else + # Both cc and cxx compiler support -rpath directly + hardcode_libdir_flag_spec='-rpath $libdir' + fi + hardcode_libdir_separator=: + ;; + solaris*) + hardcode_libdir_flag_spec='-R$libdir' + ;; + sunos4*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_direct=yes + hardcode_minus_L=yes + ;; + sysv4) + case $host_vendor in + sni) + hardcode_direct=yes # is this really true??? + ;; + siemens) + hardcode_direct=no + ;; + motorola) + hardcode_direct=no #Motorola manual says yes, but my tests say they lie + ;; + esac + ;; + sysv4.3*) + ;; + sysv4*MP*) + if test -d /usr/nec; then + ld_shlibs=yes + fi + ;; + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + ;; + sysv5* | sco3.2v5* | sco5v6*) + hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' + hardcode_libdir_separator=':' + ;; + uts4*) + hardcode_libdir_flag_spec='-L$libdir' + ;; + *) + ld_shlibs=no + ;; + esac +fi + +# Check dynamic linker characteristics +# 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 +# linker has special search rules. +library_names_spec= # the last element of library_names_spec in libtool.m4 +libname_spec='lib$name' +case "$host_os" in + aix3*) + library_names_spec='$libname.a' + ;; + aix[4-9]*) + library_names_spec='$libname$shrext' + ;; + amigaos*) + case "$host_cpu" in + powerpc*) + library_names_spec='$libname$shrext' ;; + m68k) + library_names_spec='$libname.a' ;; + esac + ;; + beos*) + library_names_spec='$libname$shrext' + ;; + bsdi[45]*) + library_names_spec='$libname$shrext' + ;; + cygwin* | mingw* | pw32* | cegcc*) + shrext=.dll + library_names_spec='$libname.dll.a $libname.lib' + ;; + darwin* | rhapsody*) + shrext=.dylib + library_names_spec='$libname$shrext' + ;; + dgux*) + library_names_spec='$libname$shrext' + ;; + freebsd[23].*) + library_names_spec='$libname$shrext$versuffix' + ;; + freebsd* | dragonfly*) + library_names_spec='$libname$shrext' + ;; + gnu*) + library_names_spec='$libname$shrext' + ;; + haiku*) + library_names_spec='$libname$shrext' + ;; + hpux9* | hpux10* | hpux11*) + case $host_cpu in + ia64*) + shrext=.so + ;; + hppa*64*) + shrext=.sl + ;; + *) + shrext=.sl + ;; + esac + library_names_spec='$libname$shrext' + ;; + interix[3-9]*) + library_names_spec='$libname$shrext' + ;; + irix5* | irix6* | nonstopux*) + library_names_spec='$libname$shrext' + case "$host_os" in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= ;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 ;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 ;; + *) libsuff= shlibsuff= ;; + esac + ;; + esac + ;; + linux*oldld* | linux*aout* | linux*coff*) + ;; + linux* | k*bsd*-gnu | kopensolaris*-gnu) + library_names_spec='$libname$shrext' + ;; + knetbsd*-gnu) + library_names_spec='$libname$shrext' + ;; + netbsd*) + library_names_spec='$libname$shrext' + ;; + newsos6) + library_names_spec='$libname$shrext' + ;; + *nto* | *qnx*) + library_names_spec='$libname$shrext' + ;; + openbsd*) + library_names_spec='$libname$shrext$versuffix' + ;; + os2*) + libname_spec='$name' + shrext=.dll + library_names_spec='$libname.a' + ;; + osf3* | osf4* | osf5*) + library_names_spec='$libname$shrext' + ;; + rdos*) + ;; + solaris*) + library_names_spec='$libname$shrext' + ;; + sunos4*) + library_names_spec='$libname$shrext$versuffix' + ;; + sysv4 | sysv4.3*) + library_names_spec='$libname$shrext' + ;; + sysv4*MP*) + library_names_spec='$libname$shrext' + ;; + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + library_names_spec='$libname$shrext' + ;; + tpf*) + library_names_spec='$libname$shrext' + ;; + uts4*) + library_names_spec='$libname$shrext' + ;; +esac + +sed_quote_subst='s/\(["`$\\]\)/\\\1/g' +escaped_wl=`echo "X$wl" | sed -e 's/^X//' -e "$sed_quote_subst"` +shlibext=`echo "$shrext" | sed -e 's,^\.,,'` +escaped_libname_spec=`echo "X$libname_spec" | sed -e 's/^X//' -e "$sed_quote_subst"` +escaped_library_names_spec=`echo "X$library_names_spec" | sed -e 's/^X//' -e "$sed_quote_subst"` +escaped_hardcode_libdir_flag_spec=`echo "X$hardcode_libdir_flag_spec" | sed -e 's/^X//' -e "$sed_quote_subst"` + +LC_ALL=C sed -e 's/^\([a-zA-Z0-9_]*\)=/acl_cv_\1=/' <. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that +# program. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). + + +# Please send patches to . +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# You can get the latest version of this script from: +# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS + +Canonicalize a configuration name. + +Options: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright 1992-2018 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo "$1" + exit ;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ + linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ + knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \ + kopensolaris*-gnu* | cloudabi*-eabi* | \ + storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + android-linux) + os=-linux-android + basic_machine=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown + ;; + *) + basic_machine=`echo "$1" | sed 's/-[^-]*$//'` + if [ "$basic_machine" != "$1" ] + then os=`echo "$1" | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis | -knuth | -cray | -microblaze*) + os= + basic_machine=$1 + ;; + -bluegene*) + os=-cnk + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco6) + os=-sco5v6 + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` + ;; + -sco5v6*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*178) + os=-lynxos178 + ;; + -lynx*5) + os=-lynxos5 + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo "$1" | sed -e 's/86-.*/86-sequent/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | aarch64 | aarch64_be \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ + | arc | arceb \ + | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ + | avr | avr32 \ + | ba \ + | be32 | be64 \ + | bfin \ + | c4x | c8051 | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | e2k | epiphany \ + | fido | fr30 | frv | ft32 \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | hexagon \ + | i370 | i860 | i960 | ia16 | ia64 \ + | ip2k | iq2000 \ + | k1om \ + | le32 | le64 \ + | lm32 \ + | m32c | m32r | m32rle | m68000 | m68k | m88k \ + | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64octeon | mips64octeonel \ + | mips64orion | mips64orionel \ + | mips64r5900 | mips64r5900el \ + | mips64vr | mips64vrel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa32r6 | mipsisa32r6el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64r6 | mipsisa64r6el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipsr5900 | mipsr5900el \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | moxie \ + | mt \ + | msp430 \ + | nds32 | nds32le | nds32be \ + | nios | nios2 | nios2eb | nios2el \ + | ns16k | ns32k \ + | open8 | or1k | or1knd | or32 \ + | pdp10 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle \ + | pru \ + | pyramid \ + | riscv32 | riscv64 \ + | rl78 | rx \ + | score \ + | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[234]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ + | spu \ + | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ + | ubicom32 \ + | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ + | visium \ + | wasm32 \ + | x86 | xc16x | xstormy16 | xtensa \ + | z8k | z80) + basic_machine=$basic_machine-unknown + ;; + c54x) + basic_machine=tic54x-unknown + ;; + c55x) + basic_machine=tic55x-unknown + ;; + c6x) + basic_machine=tic6x-unknown + ;; + leon|leon[3-9]) + basic_machine=sparc-$basic_machine + ;; + m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip) + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65) + ;; + ms1) + basic_machine=mt-unknown + ;; + + strongarm | thumb | xscale) + basic_machine=arm-unknown + ;; + xgate) + basic_machine=$basic_machine-unknown + os=-none + ;; + xscaleeb) + basic_machine=armeb-unknown + ;; + + xscaleel) + basic_machine=armel-unknown + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`"$1"\': machine \`"$basic_machine"\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | aarch64-* | aarch64_be-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* | avr32-* \ + | ba-* \ + | be32-* | be64-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* \ + | c8051-* | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | e2k-* | elxsi-* \ + | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | hexagon-* \ + | i*86-* | i860-* | i960-* | ia16-* | ia64-* \ + | ip2k-* | iq2000-* \ + | k1om-* \ + | le32-* | le64-* \ + | lm32-* \ + | m32c-* | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ + | microblaze-* | microblazeel-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64octeon-* | mips64octeonel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64r5900-* | mips64r5900el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mips64vr5900-* | mips64vr5900el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa32r6-* | mipsisa32r6el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64r6-* | mipsisa64r6el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipsr5900-* | mipsr5900el-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | mt-* \ + | msp430-* \ + | nds32-* | nds32le-* | nds32be-* \ + | nios-* | nios2-* | nios2eb-* | nios2el-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | open8-* \ + | or1k*-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ + | pru-* \ + | pyramid-* \ + | riscv32-* | riscv64-* \ + | rl78-* | romp-* | rs6000-* | rx-* \ + | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ + | sparclite-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx*-* \ + | tahoe-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tile*-* \ + | tron-* \ + | ubicom32-* \ + | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ + | vax-* \ + | visium-* \ + | wasm32-* \ + | we32k-* \ + | x86-* | x86_64-* | xc16x-* | xps100-* \ + | xstormy16-* | xtensa*-* \ + | ymp-* \ + | z8k-* | z80-*) + ;; + # Recognize the basic CPU types without company name, with glob match. + xtensa*) + basic_machine=$basic_machine-unknown + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-pc + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + abacus) + basic_machine=abacus-unknown + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amd64) + basic_machine=x86_64-pc + ;; + amd64-*) + basic_machine=x86_64-`echo "$basic_machine" | sed 's/^[^-]*-//'` + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aros) + basic_machine=i386-pc + os=-aros + ;; + asmjs) + basic_machine=asmjs-unknown + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + blackfin) + basic_machine=bfin-unknown + os=-linux + ;; + blackfin-*) + basic_machine=bfin-`echo "$basic_machine" | sed 's/^[^-]*-//'` + os=-linux + ;; + bluegene*) + basic_machine=powerpc-ibm + os=-cnk + ;; + c54x-*) + basic_machine=tic54x-`echo "$basic_machine" | sed 's/^[^-]*-//'` + ;; + c55x-*) + basic_machine=tic55x-`echo "$basic_machine" | sed 's/^[^-]*-//'` + ;; + c6x-*) + basic_machine=tic6x-`echo "$basic_machine" | sed 's/^[^-]*-//'` + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + cegcc) + basic_machine=arm-unknown + os=-cegcc + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + craynv) + basic_machine=craynv-cray + os=-unicosmp + ;; + cr16 | cr16-*) + basic_machine=cr16-unknown + os=-elf + ;; + crds | unos) + basic_machine=m68k-crds + ;; + crisv32 | crisv32-* | etraxfs*) + basic_machine=crisv32-axis + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + crx) + basic_machine=crx-unknown + os=-elf + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dicos) + basic_machine=i686-pc + os=-dicos + ;; + djgpp) + basic_machine=i586-pc + os=-msdosdjgpp + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2*) + basic_machine=m68k-bull + os=-sysv3 + ;; + e500v[12]) + basic_machine=powerpc-unknown + os=$os"spe" + ;; + e500v[12]-*) + basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'` + os=$os"spe" + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; + i*86v32) + basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + leon-*|leon[3-9]-*) + basic_machine=sparc-`echo "$basic_machine" | sed 's/-.*//'` + ;; + m68knommu) + basic_machine=m68k-unknown + os=-linux + ;; + m68knommu-*) + basic_machine=m68k-`echo "$basic_machine" | sed 's/^[^-]*-//'` + os=-linux + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + microblaze*) + basic_machine=microblaze-xilinx + ;; + mingw64) + basic_machine=x86_64-pc + os=-mingw64 + ;; + mingw32) + basic_machine=i686-pc + os=-mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + os=-mingw32ce + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'`-unknown + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + moxiebox) + basic_machine=moxie-unknown + os=-moxiebox + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + ms1-*) + basic_machine=`echo "$basic_machine" | sed -e 's/ms1-/mt-/'` + ;; + msys) + basic_machine=i686-pc + os=-msys + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + nacl) + basic_machine=le32-unknown + os=-nacl + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + neo-tandem) + basic_machine=neo-tandem + ;; + nse-tandem) + basic_machine=nse-tandem + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + nsv-tandem) + basic_machine=nsv-tandem + ;; + nsx-tandem) + basic_machine=nsx-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + openrisc | openrisc-*) + basic_machine=or32-unknown + ;; + os400) + basic_machine=powerpc-ibm + os=-os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + parisc) + basic_machine=hppa-unknown + os=-linux + ;; + parisc-*) + basic_machine=hppa-`echo "$basic_machine" | sed 's/^[^-]*-//'` + os=-linux + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pc98) + basic_machine=i386-pc + ;; + pc98-*) + basic_machine=i386-`echo "$basic_machine" | sed 's/^[^-]*-//'` + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo "$basic_machine" | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo "$basic_machine" | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc | ppcbe) basic_machine=powerpc-unknown + ;; + ppc-* | ppcbe-*) + basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo "$basic_machine" | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo "$basic_machine" | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo "$basic_machine" | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rdos | rdos64) + basic_machine=x86_64-pc + os=-rdos + ;; + rdos32) + basic_machine=i386-pc + os=-rdos + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sde) + basic_machine=mipsisa32-sde + os=-elf + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh5el) + basic_machine=sh5le-unknown + ;; + simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + strongarm-* | thumb-*) + basic_machine=arm-`echo "$basic_machine" | sed 's/^[^-]*-//'` + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tile*) + basic_machine=$basic_machine-unknown + os=-linux-gnu + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + tpf) + basic_machine=s390x-ibm + os=-tpf + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + x64) + basic_machine=x86_64-pc + ;; + xbox) + basic_machine=i686-pc + os=-mingw32 + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + xscale-* | xscalee[bl]-*) + basic_machine=`echo "$basic_machine" | sed 's/^xscale/arm/'` + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + mmix) + basic_machine=mmix-knuth + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`"$1"\': machine \`"$basic_machine"\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo "$basic_machine" | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo "$basic_machine" | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases that might get confused + # with valid system types. + # -solaris* is a basic system type, with this one exception. + -auroraux) + os=-auroraux + ;; + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # es1800 is here to avoid being matched by es* (a different OS) + -es1800*) + os=-ose + ;; + # Now accept the basic system types. + # The portable systems comes first. + # Each alternative MUST end in a * to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ + | -sym* | -kopensolaris* | -plan9* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* | -aros* | -cloudabi* | -sortix* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -knetbsd* | -mirbsd* | -netbsd* \ + | -bitrig* | -openbsd* | -solidbsd* | -libertybsd* \ + | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ + | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* | -hcos* \ + | -chorusos* | -chorusrdb* | -cegcc* | -glidix* \ + | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -midipix* | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ + | -linux-newlib* | -linux-musl* | -linux-uclibc* \ + | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ + | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \ + | -onefs* | -tirtos* | -phoenix* | -fuchsia* | -redox* | -bme* \ + | -midnightbsd*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -xray | -os68k* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo "$os" | sed -e 's|mac|macos|'` + ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo "$os" | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo "$os" | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -os400*) + os=-os400 + ;; + -wince*) + os=-wince + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -syllable*) + os=-syllable + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -tpf*) + os=-tpf + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4*) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -zvmoe) + os=-zvmoe + ;; + -dicos*) + os=-dicos + ;; + -pikeos*) + # Until real need of OS specific support for + # particular features comes up, bare metal + # configurations are quite functional. + case $basic_machine in + arm*) + os=-eabi + ;; + *) + os=-elf + ;; + esac + ;; + -nacl*) + ;; + -ios) + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`"$1"\': system \`"$os"\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + score-*) + os=-elf + ;; + spu-*) + os=-elf + ;; + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + c8051-*) + os=-elf + ;; + hexagon-*) + os=-elf + ;; + tic54x-*) + os=-coff + ;; + tic55x-*) + os=-coff + ;; + tic6x-*) + os=-coff + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + ;; + m68*-cisco) + os=-aout + ;; + mep-*) + os=-elf + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + pru-*) + os=-elf + ;; + *-be) + os=-beos + ;; + *-ibm) + os=-aix + ;; + *-knuth) + os=-mmixware + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -cnk*|-aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -os400*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -tpf*) + vendor=ibm + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo "$basic_machine" | sed "s/unknown/$vendor/"` + ;; +esac + +echo "$basic_machine$os" +exit + +# Local variables: +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/config/depcomp b/config/depcomp new file mode 100755 index 0000000..65cbf70 --- /dev/null +++ b/config/depcomp @@ -0,0 +1,791 @@ +#! /bin/sh +# depcomp - compile a program generating dependencies as side-effects + +scriptversion=2018-03-07.03; # UTC + +# Copyright (C) 1999-2018 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. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Originally written by Alexandre Oliva . + +case $1 in + '') + echo "$0: No command. Try '$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: depcomp [--help] [--version] PROGRAM [ARGS] + +Run PROGRAMS ARGS to compile a file, generating dependencies +as side-effects. + +Environment variables: + depmode Dependency tracking mode. + source Source file read by 'PROGRAMS ARGS'. + object Object file output by 'PROGRAMS ARGS'. + DEPDIR directory where to store dependencies. + depfile Dependency file to output. + tmpdepfile Temporary file to use when outputting dependencies. + libtool Whether libtool is used (yes/no). + +Report bugs to . +EOF + exit $? + ;; + -v | --v*) + echo "depcomp $scriptversion" + exit $? + ;; +esac + +# Get the directory component of the given path, and save it in the +# global variables '$dir'. Note that this directory component will +# be either empty or ending with a '/' character. This is deliberate. +set_dir_from () +{ + case $1 in + */*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;; + *) dir=;; + esac +} + +# Get the suffix-stripped basename of the given path, and save it the +# global variable '$base'. +set_base_from () +{ + base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'` +} + +# If no dependency file was actually created by the compiler invocation, +# we still have to create a dummy depfile, to avoid errors with the +# Makefile "include basename.Plo" scheme. +make_dummy_depfile () +{ + echo "#dummy" > "$depfile" +} + +# Factor out some common post-processing of the generated depfile. +# Requires the auxiliary global variable '$tmpdepfile' to be set. +aix_post_process_depfile () +{ + # If the compiler actually managed to produce a dependency file, + # post-process it. + if test -f "$tmpdepfile"; then + # Each line is of the form 'foo.o: dependency.h'. + # Do two passes, one to just change these to + # $object: dependency.h + # and one to simply output + # dependency.h: + # which is needed to avoid the deleted-header problem. + { sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile" + sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile" + } > "$depfile" + rm -f "$tmpdepfile" + else + make_dummy_depfile + fi +} + +# A tabulation character. +tab=' ' +# A newline character. +nl=' +' +# Character ranges might be problematic outside the C locale. +# These definitions help. +upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ +lower=abcdefghijklmnopqrstuvwxyz +digits=0123456789 +alpha=${upper}${lower} + +if test -z "$depmode" || test -z "$source" || test -z "$object"; then + echo "depcomp: Variables source, object and depmode must be set" 1>&2 + exit 1 +fi + +# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. +depfile=${depfile-`echo "$object" | + sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} +tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} + +rm -f "$tmpdepfile" + +# Avoid interferences from the environment. +gccflag= dashmflag= + +# Some modes work just like other modes, but use different flags. We +# parameterize here, but still list the modes in the big case below, +# to make depend.m4 easier to write. Note that we *cannot* use a case +# here, because this file can only contain one case statement. +if test "$depmode" = hp; then + # HP compiler uses -M and no extra arg. + gccflag=-M + depmode=gcc +fi + +if test "$depmode" = dashXmstdout; then + # This is just like dashmstdout with a different argument. + dashmflag=-xM + depmode=dashmstdout +fi + +cygpath_u="cygpath -u -f -" +if test "$depmode" = msvcmsys; then + # This is just like msvisualcpp but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u='sed s,\\\\,/,g' + depmode=msvisualcpp +fi + +if test "$depmode" = msvc7msys; then + # This is just like msvc7 but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u='sed s,\\\\,/,g' + depmode=msvc7 +fi + +if test "$depmode" = xlc; then + # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information. + gccflag=-qmakedep=gcc,-MF + depmode=gcc +fi + +case "$depmode" in +gcc3) +## gcc 3 implements dependency tracking that does exactly what +## we want. Yay! Note: for some reason libtool 1.4 doesn't like +## it if -MD -MP comes after the -MF stuff. Hmm. +## Unfortunately, FreeBSD c89 acceptance of flags depends upon +## the command line argument order; so add the flags where they +## appear in depend2.am. Note that the slowdown incurred here +## affects only configure: in makefiles, %FASTDEP% shortcuts this. + for arg + do + case $arg in + -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; + *) set fnord "$@" "$arg" ;; + esac + shift # fnord + shift # $arg + done + "$@" + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + mv "$tmpdepfile" "$depfile" + ;; + +gcc) +## Note that this doesn't just cater to obsosete pre-3.x GCC compilers. +## but also to in-use compilers like IMB xlc/xlC and the HP C compiler. +## (see the conditional assignment to $gccflag above). +## There are various ways to get dependency output from gcc. Here's +## why we pick this rather obscure method: +## - Don't want to use -MD because we'd like the dependencies to end +## up in a subdir. Having to rename by hand is ugly. +## (We might end up doing this anyway to support other compilers.) +## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like +## -MM, not -M (despite what the docs say). Also, it might not be +## supported by the other compilers which use the 'gcc' depmode. +## - Using -M directly means running the compiler twice (even worse +## than renaming). + if test -z "$gccflag"; then + gccflag=-MD, + fi + "$@" -Wp,"$gccflag$tmpdepfile" + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + # The second -e expression handles DOS-style file names with drive + # letters. + sed -e 's/^[^:]*: / /' \ + -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" +## This next piece of magic avoids the "deleted header file" problem. +## The problem is that when a header file which appears in a .P file +## is deleted, the dependency causes make to die (because there is +## typically no way to rebuild the header). We avoid this by adding +## dummy dependencies for each header file. Too bad gcc doesn't do +## this for us directly. +## Some versions of gcc put a space before the ':'. On the theory +## that the space means something, we add a space to the output as +## well. hp depmode also adds that space, but also prefixes the VPATH +## to the object. Take care to not repeat it in the output. +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +sgi) + if test "$libtool" = yes; then + "$@" "-Wp,-MDupdate,$tmpdepfile" + else + "$@" -MDupdate "$tmpdepfile" + fi + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + + if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files + echo "$object : \\" > "$depfile" + # Clip off the initial element (the dependent). Don't try to be + # clever and replace this with sed code, as IRIX sed won't handle + # lines with more than a fixed number of characters (4096 in + # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; + # the IRIX cc adds comments like '#:fec' to the end of the + # dependency line. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \ + | tr "$nl" ' ' >> "$depfile" + echo >> "$depfile" + # The second pass generates a dummy entry for each header file. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ + >> "$depfile" + else + make_dummy_depfile + fi + rm -f "$tmpdepfile" + ;; + +xlc) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +aix) + # The C for AIX Compiler uses -M and outputs the dependencies + # in a .u file. In older versions, this file always lives in the + # current directory. Also, the AIX compiler puts '$object:' at the + # start of each line; $object doesn't have directory information. + # Version 6 uses the directory in both cases. + set_dir_from "$object" + set_base_from "$object" + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.u + tmpdepfile2=$base.u + tmpdepfile3=$dir.libs/$base.u + "$@" -Wc,-M + else + tmpdepfile1=$dir$base.u + tmpdepfile2=$dir$base.u + tmpdepfile3=$dir$base.u + "$@" -M + fi + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + do + test -f "$tmpdepfile" && break + done + aix_post_process_depfile + ;; + +tcc) + # tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26 + # FIXME: That version still under development at the moment of writing. + # Make that this statement remains true also for stable, released + # versions. + # It will wrap lines (doesn't matter whether long or short) with a + # trailing '\', as in: + # + # foo.o : \ + # foo.c \ + # foo.h \ + # + # It will put a trailing '\' even on the last line, and will use leading + # spaces rather than leading tabs (at least since its commit 0394caf7 + # "Emit spaces for -MD"). + "$@" -MD -MF "$tmpdepfile" + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each non-empty line is of the form 'foo.o : \' or ' dep.h \'. + # We have to change lines of the first kind to '$object: \'. + sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile" + # And for each line of the second kind, we have to emit a 'dep.h:' + # dummy dependency, to avoid the deleted-header problem. + sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile" + rm -f "$tmpdepfile" + ;; + +## The order of this option in the case statement is important, since the +## shell code in configure will try each of these formats in the order +## listed in this file. A plain '-MD' option would be understood by many +## compilers, so we must ensure this comes after the gcc and icc options. +pgcc) + # Portland's C compiler understands '-MD'. + # Will always output deps to 'file.d' where file is the root name of the + # source file under compilation, even if file resides in a subdirectory. + # The object file name does not affect the name of the '.d' file. + # pgcc 10.2 will output + # foo.o: sub/foo.c sub/foo.h + # and will wrap long lines using '\' : + # foo.o: sub/foo.c ... \ + # sub/foo.h ... \ + # ... + set_dir_from "$object" + # Use the source, not the object, to determine the base name, since + # that's sadly what pgcc will do too. + set_base_from "$source" + tmpdepfile=$base.d + + # For projects that build the same source file twice into different object + # files, the pgcc approach of using the *source* file root name can cause + # problems in parallel builds. Use a locking strategy to avoid stomping on + # the same $tmpdepfile. + lockdir=$base.d-lock + trap " + echo '$0: caught signal, cleaning up...' >&2 + rmdir '$lockdir' + exit 1 + " 1 2 13 15 + numtries=100 + i=$numtries + while test $i -gt 0; do + # mkdir is a portable test-and-set. + if mkdir "$lockdir" 2>/dev/null; then + # This process acquired the lock. + "$@" -MD + stat=$? + # Release the lock. + rmdir "$lockdir" + break + else + # If the lock is being held by a different process, wait + # until the winning process is done or we timeout. + while test -d "$lockdir" && test $i -gt 0; do + sleep 1 + i=`expr $i - 1` + done + fi + i=`expr $i - 1` + done + trap - 1 2 13 15 + if test $i -le 0; then + echo "$0: failed to acquire lock after $numtries attempts" >&2 + echo "$0: check lockdir '$lockdir'" >&2 + exit 1 + fi + + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each line is of the form `foo.o: dependent.h', + # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process this invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp2) + # The "hp" stanza above does not work with aCC (C++) and HP's ia64 + # compilers, which have integrated preprocessors. The correct option + # to use with these is +Maked; it writes dependencies to a file named + # 'foo.d', which lands next to the object file, wherever that + # happens to be. + # Much of this is similar to the tru64 case; see comments there. + set_dir_from "$object" + set_base_from "$object" + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir.libs/$base.d + "$@" -Wc,+Maked + else + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir$base.d + "$@" +Maked + fi + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile1" "$tmpdepfile2" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile" + # Add 'dependent.h:' lines. + sed -ne '2,${ + s/^ *// + s/ \\*$// + s/$/:/ + p + }' "$tmpdepfile" >> "$depfile" + else + make_dummy_depfile + fi + rm -f "$tmpdepfile" "$tmpdepfile2" + ;; + +tru64) + # The Tru64 compiler uses -MD to generate dependencies as a side + # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'. + # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put + # dependencies in 'foo.d' instead, so we check for that too. + # Subdirectories are respected. + set_dir_from "$object" + set_base_from "$object" + + if test "$libtool" = yes; then + # Libtool generates 2 separate objects for the 2 libraries. These + # two compilations output dependencies in $dir.libs/$base.o.d and + # in $dir$base.o.d. We have to check for both files, because + # one of the two compilations can be disabled. We should prefer + # $dir$base.o.d over $dir.libs/$base.o.d because the latter is + # automatically cleaned when .libs/ is deleted, while ignoring + # the former would cause a distcleancheck panic. + tmpdepfile1=$dir$base.o.d # libtool 1.5 + tmpdepfile2=$dir.libs/$base.o.d # Likewise. + tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504 + "$@" -Wc,-MD + else + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir$base.d + tmpdepfile3=$dir$base.d + "$@" -MD + fi + + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + do + test -f "$tmpdepfile" && break + done + # Same post-processing that is required for AIX mode. + aix_post_process_depfile + ;; + +msvc7) + if test "$libtool" = yes; then + showIncludes=-Wc,-showIncludes + else + showIncludes=-showIncludes + fi + "$@" $showIncludes > "$tmpdepfile" + stat=$? + grep -v '^Note: including file: ' "$tmpdepfile" + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + # The first sed program below extracts the file names and escapes + # backslashes for cygpath. The second sed program outputs the file + # name when reading, but also accumulates all include files in the + # hold buffer in order to output them again at the end. This only + # works with sed implementations that can handle large buffers. + sed < "$tmpdepfile" -n ' +/^Note: including file: *\(.*\)/ { + s//\1/ + s/\\/\\\\/g + p +}' | $cygpath_u | sort -u | sed -n ' +s/ /\\ /g +s/\(.*\)/'"$tab"'\1 \\/p +s/.\(.*\) \\/\1:/ +H +$ { + s/.*/'"$tab"'/ + G + p +}' >> "$depfile" + echo >> "$depfile" # make sure the fragment doesn't end with a backslash + rm -f "$tmpdepfile" + ;; + +msvc7msys) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +#nosideeffect) + # This comment above is used by automake to tell side-effect + # dependency tracking mechanisms from slower ones. + +dashmstdout) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout, regardless of -o. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove '-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + test -z "$dashmflag" && dashmflag=-M + # Require at least two characters before searching for ':' + # in the target name. This is to cope with DOS-style filenames: + # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise. + "$@" $dashmflag | + sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process this sed invocation + # correctly. Breaking it into two sed invocations is a workaround. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +dashXmstdout) + # This case only exists to satisfy depend.m4. It is never actually + # run, as this mode is specially recognized in the preamble. + exit 1 + ;; + +makedepend) + "$@" || exit $? + # Remove any Libtool call + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + # X makedepend + shift + cleared=no eat=no + for arg + do + case $cleared in + no) + set ""; shift + cleared=yes ;; + esac + if test $eat = yes; then + eat=no + continue + fi + case "$arg" in + -D*|-I*) + set fnord "$@" "$arg"; shift ;; + # Strip any option that makedepend may not understand. Remove + # the object too, otherwise makedepend will parse it as a source file. + -arch) + eat=yes ;; + -*|$object) + ;; + *) + set fnord "$@" "$arg"; shift ;; + esac + done + obj_suffix=`echo "$object" | sed 's/^.*\././'` + touch "$tmpdepfile" + ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" + rm -f "$depfile" + # makedepend may prepend the VPATH from the source file name to the object. + # No need to regex-escape $object, excess matching of '.' is harmless. + sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process the last invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed '1,2d' "$tmpdepfile" \ + | tr ' ' "$nl" \ + | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" "$tmpdepfile".bak + ;; + +cpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove '-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + "$@" -E \ + | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + | sed '$ s: \\$::' > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + cat < "$tmpdepfile" >> "$depfile" + sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvisualcpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + IFS=" " + for arg + do + case "$arg" in + -o) + shift + ;; + $object) + shift + ;; + "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") + set fnord "$@" + shift + shift + ;; + *) + set fnord "$@" "$arg" + shift + shift + ;; + esac + done + "$@" -E 2>/dev/null | + sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile" + echo "$tab" >> "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvcmsys) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +none) + exec "$@" + ;; + +*) + echo "Unknown depmode $depmode" 1>&2 + exit 1 + ;; +esac + +exit 0 + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC0" +# time-stamp-end: "; # UTC" +# End: diff --git a/config/extensions.m4 b/config/extensions.m4 new file mode 100644 index 0000000..71a854f --- /dev/null +++ b/config/extensions.m4 @@ -0,0 +1,189 @@ +# serial 18 -*- Autoconf -*- +# Enable extensions on systems that normally disable them. + +# Copyright (C) 2003, 2006-2018 Free Software Foundation, Inc. +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This definition of AC_USE_SYSTEM_EXTENSIONS is stolen from git +# Autoconf. Perhaps we can remove this once we can assume Autoconf +# 2.70 or later everywhere, but since Autoconf mutates rapidly +# enough in this area it's likely we'll need to redefine +# AC_USE_SYSTEM_EXTENSIONS for quite some time. + +# If autoconf reports a warning +# warning: AC_COMPILE_IFELSE was called before AC_USE_SYSTEM_EXTENSIONS +# or warning: AC_RUN_IFELSE was called before AC_USE_SYSTEM_EXTENSIONS +# the fix is +# 1) to ensure that AC_USE_SYSTEM_EXTENSIONS is never directly invoked +# but always AC_REQUIREd, +# 2) to ensure that for each occurrence of +# AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) +# or +# AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) +# the corresponding gnulib module description has 'extensions' among +# its dependencies. This will ensure that the gl_USE_SYSTEM_EXTENSIONS +# invocation occurs in gl_EARLY, not in gl_INIT. + +# AC_USE_SYSTEM_EXTENSIONS +# ------------------------ +# Enable extensions on systems that normally disable them, +# typically due to standards-conformance issues. +# +# Remember that #undef in AH_VERBATIM gets replaced with #define by +# 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_ONCE([AC_USE_SYSTEM_EXTENSIONS], +[AC_BEFORE([$0], [AC_COMPILE_IFELSE])dnl +AC_BEFORE([$0], [AC_RUN_IFELSE])dnl + + AC_CHECK_HEADER([minix/config.h], [MINIX=yes], [MINIX=]) + if test "$MINIX" = yes; then + AC_DEFINE([_POSIX_SOURCE], [1], + [Define to 1 if you need to in order for 'stat' and other + things to work.]) + AC_DEFINE([_POSIX_1_SOURCE], [2], + [Define to 2 if the system does not provide POSIX.1 features + except with this defined.]) + AC_DEFINE([_MINIX], [1], + [Define to 1 if on MINIX.]) + AC_DEFINE([_NETBSD_SOURCE], [1], + [Define to 1 to make NetBSD features available. MINIX 3 needs this.]) + fi + +dnl Use a different key than __EXTENSIONS__, as that name broke existing +dnl configure.ac when using autoheader 2.62. + AH_VERBATIM([USE_SYSTEM_EXTENSIONS], +[/* Enable extensions on AIX 3, Interix. */ +#ifndef _ALL_SOURCE +# undef _ALL_SOURCE +#endif +/* Enable general extensions on macOS. */ +#ifndef _DARWIN_C_SOURCE +# undef _DARWIN_C_SOURCE +#endif +/* Enable GNU extensions on systems that have them. */ +#ifndef _GNU_SOURCE +# undef _GNU_SOURCE +#endif +/* Enable NetBSD extensions on NetBSD. */ +#ifndef _NETBSD_SOURCE +# undef _NETBSD_SOURCE +#endif +/* Enable OpenBSD extensions on NetBSD. */ +#ifndef _OPENBSD_SOURCE +# undef _OPENBSD_SOURCE +#endif +/* Enable threading extensions on Solaris. */ +#ifndef _POSIX_PTHREAD_SEMANTICS +# undef _POSIX_PTHREAD_SEMANTICS +#endif +/* Enable extensions specified by ISO/IEC TS 18661-5:2014. */ +#ifndef __STDC_WANT_IEC_60559_ATTRIBS_EXT__ +# undef __STDC_WANT_IEC_60559_ATTRIBS_EXT__ +#endif +/* Enable extensions specified by ISO/IEC TS 18661-1:2014. */ +#ifndef __STDC_WANT_IEC_60559_BFP_EXT__ +# undef __STDC_WANT_IEC_60559_BFP_EXT__ +#endif +/* Enable extensions specified by ISO/IEC TS 18661-2:2015. */ +#ifndef __STDC_WANT_IEC_60559_DFP_EXT__ +# undef __STDC_WANT_IEC_60559_DFP_EXT__ +#endif +/* Enable extensions specified by ISO/IEC TS 18661-4:2015. */ +#ifndef __STDC_WANT_IEC_60559_FUNCS_EXT__ +# undef __STDC_WANT_IEC_60559_FUNCS_EXT__ +#endif +/* Enable extensions specified by ISO/IEC TS 18661-3:2015. */ +#ifndef __STDC_WANT_IEC_60559_TYPES_EXT__ +# undef __STDC_WANT_IEC_60559_TYPES_EXT__ +#endif +/* Enable extensions specified by ISO/IEC TR 24731-2:2010. */ +#ifndef __STDC_WANT_LIB_EXT2__ +# undef __STDC_WANT_LIB_EXT2__ +#endif +/* Enable extensions specified by ISO/IEC 24747:2009. */ +#ifndef __STDC_WANT_MATH_SPEC_FUNCS__ +# undef __STDC_WANT_MATH_SPEC_FUNCS__ +#endif +/* Enable extensions on HP NonStop. */ +#ifndef _TANDEM_SOURCE +# undef _TANDEM_SOURCE +#endif +/* Enable X/Open extensions if necessary. HP-UX 11.11 defines + mbstate_t only if _XOPEN_SOURCE is defined to 500, regardless of + whether compiling with -Ae or -D_HPUX_SOURCE=1. */ +#ifndef _XOPEN_SOURCE +# undef _XOPEN_SOURCE +#endif +/* Enable X/Open compliant socket functions that do not require linking + with -lxnet on HP-UX 11.11. */ +#ifndef _HPUX_ALT_XOPEN_SOCKET_API +# undef _HPUX_ALT_XOPEN_SOCKET_API +#endif +/* Enable general extensions on Solaris. */ +#ifndef __EXTENSIONS__ +# undef __EXTENSIONS__ +#endif +]) + AC_CACHE_CHECK([whether it is safe to define __EXTENSIONS__], + [ac_cv_safe_to_define___extensions__], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([[ +# define __EXTENSIONS__ 1 + ]AC_INCLUDES_DEFAULT])], + [ac_cv_safe_to_define___extensions__=yes], + [ac_cv_safe_to_define___extensions__=no])]) + test $ac_cv_safe_to_define___extensions__ = yes && + AC_DEFINE([__EXTENSIONS__]) + AC_DEFINE([_ALL_SOURCE]) + AC_DEFINE([_DARWIN_C_SOURCE]) + AC_DEFINE([_GNU_SOURCE]) + AC_DEFINE([_NETBSD_SOURCE]) + AC_DEFINE([_OPENBSD_SOURCE]) + AC_DEFINE([_POSIX_PTHREAD_SEMANTICS]) + AC_DEFINE([__STDC_WANT_IEC_60559_ATTRIBS_EXT__]) + AC_DEFINE([__STDC_WANT_IEC_60559_BFP_EXT__]) + AC_DEFINE([__STDC_WANT_IEC_60559_DFP_EXT__]) + AC_DEFINE([__STDC_WANT_IEC_60559_FUNCS_EXT__]) + AC_DEFINE([__STDC_WANT_IEC_60559_TYPES_EXT__]) + AC_DEFINE([__STDC_WANT_LIB_EXT2__]) + AC_DEFINE([__STDC_WANT_MATH_SPEC_FUNCS__]) + AC_DEFINE([_TANDEM_SOURCE]) + AC_CACHE_CHECK([whether _XOPEN_SOURCE should be defined], + [ac_cv_should_define__xopen_source], + [ac_cv_should_define__xopen_source=no + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([[ + #include + mbstate_t x;]])], + [], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([[ + #define _XOPEN_SOURCE 500 + #include + mbstate_t x;]])], + [ac_cv_should_define__xopen_source=yes])])]) + test $ac_cv_should_define__xopen_source = yes && + AC_DEFINE([_XOPEN_SOURCE], [500]) + AC_DEFINE([_HPUX_ALT_XOPEN_SOCKET_API]) +])# AC_USE_SYSTEM_EXTENSIONS + +# gl_USE_SYSTEM_EXTENSIONS +# ------------------------ +# Enable extensions on systems that normally disable them, +# typically due to standards-conformance issues. +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/config/gendocs.sh b/config/gendocs.sh new file mode 100755 index 0000000..91c058d --- /dev/null +++ b/config/gendocs.sh @@ -0,0 +1,510 @@ +#!/bin/sh -e +# gendocs.sh -- generate a GNU manual in many formats. This script is +# mentioned in maintain.texi. See the help message below for usage details. + +scriptversion=2018-03-06.19 + +# Copyright 2003-2018 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 . +# +# Original author: Mohit Agarwal. +# Send bug reports and any other correspondence to bug-gnulib@gnu.org. +# +# The latest version of this script, and the companion template, is +# available from the Gnulib repository: +# +# https://git.savannah.gnu.org/cgit/gnulib.git/tree/build-aux/gendocs.sh +# https://git.savannah.gnu.org/cgit/gnulib.git/tree/doc/gendocs_template + +# TODO: +# - image importing was only implemented for HTML generated by +# makeinfo. But it should be simple enough to adjust. +# - images are not imported in the source tarball. All the needed +# formats (PDF, PNG, etc.) should be included. + +prog=`basename "$0"` +srcdir=`pwd` + +scripturl="https://git.savannah.gnu.org/cgit/gnulib.git/plain/build-aux/gendocs.sh" +templateurl="https://git.savannah.gnu.org/cgit/gnulib.git/plain/doc/gendocs_template" + +: ${SETLANG="env LANG= LC_MESSAGES= LC_ALL= LANGUAGE="} +: ${MAKEINFO="makeinfo"} +: ${TEXI2DVI="texi2dvi"} +: ${DOCBOOK2HTML="docbook2html"} +: ${DOCBOOK2PDF="docbook2pdf"} +: ${DOCBOOK2TXT="docbook2txt"} +: ${GENDOCS_TEMPLATE_DIR="."} +: ${PERL='perl'} +: ${TEXI2HTML="texi2html"} +unset CDPATH +unset use_texi2html + +MANUAL_TITLE= +PACKAGE= +EMAIL=webmasters@gnu.org # please override with --email +commonarg= # passed to all makeinfo/texi2html invcations. +dirargs= # passed to all tools (-I dir). +dirs= # -I directories. +htmlarg="--css-ref=/software/gnulib/manual.css -c TOP_NODE_UP_URL=/manual" +default_htmlarg=true +infoarg=--no-split +generate_ascii=true +generate_html=true +generate_info=true +generate_tex=true +outdir=manual +source_extra= +split=node +srcfile= +texarg="-t @finalout" + +version="gendocs.sh $scriptversion + +Copyright 2018 Free Software Foundation, Inc. +There is NO warranty. You may redistribute this software +under the terms of the GNU General Public License. +For more information about these matters, see the files named COPYING." + +usage="Usage: $prog [OPTION]... PACKAGE MANUAL-TITLE + +Generate output in various formats from PACKAGE.texinfo (or .texi or +.txi) source. See the GNU Maintainers document for a more extensive +discussion: + https://www.gnu.org/prep/maintain_toc.html + +Options: + --email ADR use ADR as contact in generated web pages; always give this. + + -s SRCFILE read Texinfo from SRCFILE, instead of PACKAGE.{texinfo|texi|txi} + -o OUTDIR write files into OUTDIR, instead of manual/. + -I DIR append DIR to the Texinfo search path. + --common ARG pass ARG in all invocations. + --html ARG pass ARG to makeinfo or texi2html for HTML targets, + instead of '$htmlarg'. + --info ARG pass ARG to makeinfo for Info, instead of --no-split. + --no-ascii skip generating the plain text output. + --no-html skip generating the html output. + --no-info skip generating the info output. + --no-tex skip generating the dvi and pdf output. + --source ARG include ARG in tar archive of sources. + --split HOW make split HTML by node, section, chapter; default node. + --tex ARG pass ARG to texi2dvi for DVI and PDF, instead of -t @finalout. + + --texi2html use texi2html to make HTML target, with all split versions. + --docbook convert through DocBook too (xml, txt, html, pdf). + + --help display this help and exit successfully. + --version display version information and exit successfully. + +Simple example: $prog --email bug-gnu-emacs@gnu.org emacs \"GNU Emacs Manual\" + +Typical sequence: + cd PACKAGESOURCE/doc + wget \"$scripturl\" + wget \"$templateurl\" + $prog --email BUGLIST MANUAL \"GNU MANUAL - One-line description\" + +Output will be in a new subdirectory \"manual\" (by default; +use -o OUTDIR to override). Move all the new files into your web CVS +tree, as explained in the Web Pages node of maintain.texi. + +Please use the --email ADDRESS option so your own bug-reporting +address will be used in the generated HTML pages. + +MANUAL-TITLE is included as part of the HTML of the overall +manual/index.html file. It should include the name of the package being +documented. manual/index.html is created by substitution from the file +$GENDOCS_TEMPLATE_DIR/gendocs_template. (Feel free to modify the +generic template for your own purposes.) + +If you have several manuals, you'll need to run this script several +times with different MANUAL values, specifying a different output +directory with -o each time. Then write (by hand) an overall index.html +with links to them all. + +If a manual's Texinfo sources are spread across several directories, +first copy or symlink all Texinfo sources into a single directory. +(Part of the script's work is to make a tar.gz of the sources.) + +As implied above, by default monolithic Info files are generated. +If you want split Info, or other Info options, use --info to override. + +You can set the environment variables MAKEINFO, TEXI2DVI, TEXI2HTML, +and PERL to control the programs that get executed, and +GENDOCS_TEMPLATE_DIR to control where the gendocs_template file is +looked for. With --docbook, the environment variables DOCBOOK2HTML, +DOCBOOK2PDF, and DOCBOOK2TXT are also consulted. + +By default, makeinfo and texi2dvi are run in the default (English) +locale, since that's the language of most Texinfo manuals. If you +happen to have a non-English manual and non-English web site, see the +SETLANG setting in the source. + +Email bug reports or enhancement requests to bug-gnulib@gnu.org. +" + +while test $# -gt 0; do + case $1 in + -s) shift; srcfile=$1;; + -o) shift; outdir=$1;; + -I) shift; dirargs="$dirargs -I '$1'"; dirs="$dirs $1";; + --common) shift; commonarg=$1;; + --docbook) docbook=yes;; + --email) shift; EMAIL=$1;; + --html) shift; default_htmlarg=false; htmlarg=$1;; + --info) shift; infoarg=$1;; + --no-ascii) generate_ascii=false;; + --no-html) generate_ascii=false;; + --no-info) generate_info=false;; + --no-tex) generate_tex=false;; + --source) shift; source_extra=$1;; + --split) shift; split=$1;; + --tex) shift; texarg=$1;; + --texi2html) use_texi2html=1;; + + --help) echo "$usage"; exit 0;; + --version) echo "$version"; exit 0;; + -*) + echo "$0: Unknown option \`$1'." >&2 + echo "$0: Try \`--help' for more information." >&2 + exit 1;; + *) + if test -z "$PACKAGE"; then + PACKAGE=$1 + elif test -z "$MANUAL_TITLE"; then + MANUAL_TITLE=$1 + else + echo "$0: extra non-option argument \`$1'." >&2 + exit 1 + fi;; + esac + shift +done + +# makeinfo uses the dirargs, but texi2dvi doesn't. +commonarg=" $dirargs $commonarg" + +# For most of the following, the base name is just $PACKAGE +base=$PACKAGE + +if $default_htmlarg && test -n "$use_texi2html"; then + # The legacy texi2html doesn't support TOP_NODE_UP_URL + htmlarg="--css-ref=/software/gnulib/manual.css" +fi + +if test -n "$srcfile"; then + # but here, we use the basename of $srcfile + base=`basename "$srcfile"` + case $base in + *.txi|*.texi|*.texinfo) base=`echo "$base"|sed 's/\.[texinfo]*$//'`;; + esac + PACKAGE=$base +elif test -s "$srcdir/$PACKAGE.texinfo"; then + srcfile=$srcdir/$PACKAGE.texinfo +elif test -s "$srcdir/$PACKAGE.texi"; then + srcfile=$srcdir/$PACKAGE.texi +elif test -s "$srcdir/$PACKAGE.txi"; then + srcfile=$srcdir/$PACKAGE.txi +else + echo "$0: cannot find .texinfo or .texi or .txi for $PACKAGE in $srcdir." >&2 + exit 1 +fi + +if test ! -r $GENDOCS_TEMPLATE_DIR/gendocs_template; then + echo "$0: cannot read $GENDOCS_TEMPLATE_DIR/gendocs_template." >&2 + echo "$0: it is available from $templateurl." >&2 + exit 1 +fi + +# Function to return size of $1 in something resembling kilobytes. +calcsize() +{ + size=`ls -ksl $1 | awk '{print $1}'` + echo $size +} + +# copy_images OUTDIR HTML-FILE... +# ------------------------------- +# Copy all the images needed by the HTML-FILEs into OUTDIR. +# Look for them in . and the -I directories; this is simpler than what +# makeinfo supports with -I, but hopefully it will suffice. +copy_images() +{ + local odir + odir=$1 + shift + $PERL -n -e " +BEGIN { + \$me = '$prog'; + \$odir = '$odir'; + @dirs = qw(. $dirs); +} +" -e ' +/<img src="(.*?)"/g && ++$need{$1}; + +END { + #print "$me: @{[keys %need]}\n"; # for debugging, show images found. + FILE: for my $f (keys %need) { + for my $d (@dirs) { + if (-f "$d/$f") { + use File::Basename; + my $dest = dirname ("$odir/$f"); + # + use File::Path; + -d $dest || mkpath ($dest) + || die "$me: cannot mkdir $dest: $!\n"; + # + use File::Copy; + copy ("$d/$f", $dest) + || die "$me: cannot copy $d/$f to $dest: $!\n"; + next FILE; + } + } + die "$me: $ARGV: cannot find image $f\n"; + } +} +' -- "$@" || exit 1 +} + +case $outdir in + /*) abs_outdir=$outdir;; + *) abs_outdir=$srcdir/$outdir;; +esac + +echo "Making output for $srcfile" +echo " in `pwd`" +mkdir -p "$outdir/" + +# +if $generate_info; then + cmd="$SETLANG $MAKEINFO -o $PACKAGE.info $commonarg $infoarg \"$srcfile\"" + echo "Generating info... ($cmd)" + rm -f $PACKAGE.info* # get rid of any strays + eval "$cmd" + tar czf "$outdir/$PACKAGE.info.tar.gz" $PACKAGE.info* + ls -l "$outdir/$PACKAGE.info.tar.gz" + info_tgz_size=`calcsize "$outdir/$PACKAGE.info.tar.gz"` + # do not mv the info files, there's no point in having them available + # separately on the web. +fi # end info + +# +if $generate_tex; then + cmd="$SETLANG $TEXI2DVI $dirargs $texarg \"$srcfile\"" + printf "\nGenerating dvi... ($cmd)\n" + eval "$cmd" + # compress/finish dvi: + gzip -f -9 $PACKAGE.dvi + dvi_gz_size=`calcsize $PACKAGE.dvi.gz` + mv $PACKAGE.dvi.gz "$outdir/" + ls -l "$outdir/$PACKAGE.dvi.gz" + + cmd="$SETLANG $TEXI2DVI --pdf $dirargs $texarg \"$srcfile\"" + printf "\nGenerating pdf... ($cmd)\n" + eval "$cmd" + pdf_size=`calcsize $PACKAGE.pdf` + mv $PACKAGE.pdf "$outdir/" + ls -l "$outdir/$PACKAGE.pdf" +fi # end tex (dvi + pdf) + +# +if $generate_ascii; then + opt="-o $PACKAGE.txt --no-split --no-headers $commonarg" + cmd="$SETLANG $MAKEINFO $opt \"$srcfile\"" + printf "\nGenerating ascii... ($cmd)\n" + eval "$cmd" + ascii_size=`calcsize $PACKAGE.txt` + gzip -f -9 -c $PACKAGE.txt >"$outdir/$PACKAGE.txt.gz" + ascii_gz_size=`calcsize "$outdir/$PACKAGE.txt.gz"` + mv $PACKAGE.txt "$outdir/" + ls -l "$outdir/$PACKAGE.txt" "$outdir/$PACKAGE.txt.gz" +fi + +# + +if $generate_html; then +# Split HTML at level $1. Used for texi2html. +html_split() +{ + opt="--split=$1 --node-files $commonarg $htmlarg" + cmd="$SETLANG $TEXI2HTML --output $PACKAGE.html $opt \"$srcfile\"" + printf "\nGenerating html by $1... ($cmd)\n" + eval "$cmd" + split_html_dir=$PACKAGE.html + ( + cd ${split_html_dir} || exit 1 + ln -sf ${PACKAGE}.html index.html + tar -czf "$abs_outdir/${PACKAGE}.html_$1.tar.gz" -- *.html + ) + eval html_$1_tgz_size=`calcsize "$outdir/${PACKAGE}.html_$1.tar.gz"` + rm -f "$outdir"/html_$1/*.html + mkdir -p "$outdir/html_$1/" + mv ${split_html_dir}/*.html "$outdir/html_$1/" + rmdir ${split_html_dir} +} + +if test -z "$use_texi2html"; then + opt="--no-split --html -o $PACKAGE.html $commonarg $htmlarg" + cmd="$SETLANG $MAKEINFO $opt \"$srcfile\"" + printf "\nGenerating monolithic html... ($cmd)\n" + rm -rf $PACKAGE.html # in case a directory is left over + eval "$cmd" + html_mono_size=`calcsize $PACKAGE.html` + gzip -f -9 -c $PACKAGE.html >"$outdir/$PACKAGE.html.gz" + html_mono_gz_size=`calcsize "$outdir/$PACKAGE.html.gz"` + copy_images "$outdir/" $PACKAGE.html + mv $PACKAGE.html "$outdir/" + ls -l "$outdir/$PACKAGE.html" "$outdir/$PACKAGE.html.gz" + + # Before Texinfo 5.0, makeinfo did not accept a --split=HOW option, + # it just always split by node. So if we're splitting by node anyway, + # leave it out. + if test "x$split" = xnode; then + split_arg= + else + split_arg=--split=$split + fi + # + opt="--html -o $PACKAGE.html $split_arg $commonarg $htmlarg" + cmd="$SETLANG $MAKEINFO $opt \"$srcfile\"" + printf "\nGenerating html by $split... ($cmd)\n" + eval "$cmd" + split_html_dir=$PACKAGE.html + copy_images $split_html_dir/ $split_html_dir/*.html + ( + cd $split_html_dir || exit 1 + tar -czf "$abs_outdir/$PACKAGE.html_$split.tar.gz" -- * + ) + eval \ + html_${split}_tgz_size=`calcsize "$outdir/$PACKAGE.html_$split.tar.gz"` + rm -rf "$outdir/html_$split/" + mv $split_html_dir "$outdir/html_$split/" + du -s "$outdir/html_$split/" + ls -l "$outdir/$PACKAGE.html_$split.tar.gz" + +else # use texi2html: + opt="--output $PACKAGE.html $commonarg $htmlarg" + cmd="$SETLANG $TEXI2HTML $opt \"$srcfile\"" + printf "\nGenerating monolithic html with texi2html... ($cmd)\n" + rm -rf $PACKAGE.html # in case a directory is left over + eval "$cmd" + html_mono_size=`calcsize $PACKAGE.html` + gzip -f -9 -c $PACKAGE.html >"$outdir/$PACKAGE.html.gz" + html_mono_gz_size=`calcsize "$outdir/$PACKAGE.html.gz"` + mv $PACKAGE.html "$outdir/" + + html_split node + html_split chapter + html_split section +fi +fi # end html + +# +printf "\nMaking .tar.gz for sources...\n" +d=`dirname $srcfile` +( + cd "$d" + srcfiles=`ls -d *.texinfo *.texi *.txi *.eps $source_extra 2>/dev/null` || true + tar czfh "$abs_outdir/$PACKAGE.texi.tar.gz" $srcfiles + ls -l "$abs_outdir/$PACKAGE.texi.tar.gz" +) +texi_tgz_size=`calcsize "$outdir/$PACKAGE.texi.tar.gz"` + +# +# Do everything again through docbook. +if test -n "$docbook"; then + opt="-o - --docbook $commonarg" + cmd="$SETLANG $MAKEINFO $opt \"$srcfile\" >${srcdir}/$PACKAGE-db.xml" + printf "\nGenerating docbook XML... ($cmd)\n" + eval "$cmd" + docbook_xml_size=`calcsize $PACKAGE-db.xml` + gzip -f -9 -c $PACKAGE-db.xml >"$outdir/$PACKAGE-db.xml.gz" + docbook_xml_gz_size=`calcsize "$outdir/$PACKAGE-db.xml.gz"` + mv $PACKAGE-db.xml "$outdir/" + + split_html_db_dir=html_node_db + opt="$commonarg -o $split_html_db_dir" + cmd="$DOCBOOK2HTML $opt \"${outdir}/$PACKAGE-db.xml\"" + printf "\nGenerating docbook HTML... ($cmd)\n" + eval "$cmd" + ( + cd ${split_html_db_dir} || exit 1 + tar -czf "$abs_outdir/${PACKAGE}.html_node_db.tar.gz" -- *.html + ) + html_node_db_tgz_size=`calcsize "$outdir/${PACKAGE}.html_node_db.tar.gz"` + rm -f "$outdir"/html_node_db/*.html + mkdir -p "$outdir/html_node_db" + mv ${split_html_db_dir}/*.html "$outdir/html_node_db/" + rmdir ${split_html_db_dir} + + cmd="$DOCBOOK2TXT \"${outdir}/$PACKAGE-db.xml\"" + printf "\nGenerating docbook ASCII... ($cmd)\n" + eval "$cmd" + docbook_ascii_size=`calcsize $PACKAGE-db.txt` + mv $PACKAGE-db.txt "$outdir/" + + cmd="$DOCBOOK2PDF \"${outdir}/$PACKAGE-db.xml\"" + printf "\nGenerating docbook PDF... ($cmd)\n" + eval "$cmd" + docbook_pdf_size=`calcsize $PACKAGE-db.pdf` + mv $PACKAGE-db.pdf "$outdir/" +fi + +# +printf "\nMaking index.html for $PACKAGE...\n" +if test -z "$use_texi2html"; then + CONDS="/%%IF *HTML_SECTION%%/,/%%ENDIF *HTML_SECTION%%/d;\ + /%%IF *HTML_CHAPTER%%/,/%%ENDIF *HTML_CHAPTER%%/d" +else + # should take account of --split here. + CONDS="/%%ENDIF.*%%/d;/%%IF *HTML_SECTION%%/d;/%%IF *HTML_CHAPTER%%/d" +fi + +curdate=`$SETLANG date '+%B %d, %Y'` +sed \ + -e "s!%%TITLE%%!$MANUAL_TITLE!g" \ + -e "s!%%EMAIL%%!$EMAIL!g" \ + -e "s!%%PACKAGE%%!$PACKAGE!g" \ + -e "s!%%DATE%%!$curdate!g" \ + -e "s!%%HTML_MONO_SIZE%%!$html_mono_size!g" \ + -e "s!%%HTML_MONO_GZ_SIZE%%!$html_mono_gz_size!g" \ + -e "s!%%HTML_NODE_TGZ_SIZE%%!$html_node_tgz_size!g" \ + -e "s!%%HTML_SECTION_TGZ_SIZE%%!$html_section_tgz_size!g" \ + -e "s!%%HTML_CHAPTER_TGZ_SIZE%%!$html_chapter_tgz_size!g" \ + -e "s!%%INFO_TGZ_SIZE%%!$info_tgz_size!g" \ + -e "s!%%DVI_GZ_SIZE%%!$dvi_gz_size!g" \ + -e "s!%%PDF_SIZE%%!$pdf_size!g" \ + -e "s!%%ASCII_SIZE%%!$ascii_size!g" \ + -e "s!%%ASCII_GZ_SIZE%%!$ascii_gz_size!g" \ + -e "s!%%TEXI_TGZ_SIZE%%!$texi_tgz_size!g" \ + -e "s!%%DOCBOOK_HTML_NODE_TGZ_SIZE%%!$html_node_db_tgz_size!g" \ + -e "s!%%DOCBOOK_ASCII_SIZE%%!$docbook_ascii_size!g" \ + -e "s!%%DOCBOOK_PDF_SIZE%%!$docbook_pdf_size!g" \ + -e "s!%%DOCBOOK_XML_SIZE%%!$docbook_xml_size!g" \ + -e "s!%%DOCBOOK_XML_GZ_SIZE%%!$docbook_xml_gz_size!g" \ + -e "s,%%SCRIPTURL%%,$scripturl,g" \ + -e "s!%%SCRIPTNAME%%!$prog!g" \ + -e "$CONDS" \ +$GENDOCS_TEMPLATE_DIR/gendocs_template >"$outdir/index.html" + +echo "Done, see $outdir/ subdirectory for new files." + +# Local variables: +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/config/gnulib-cache.m4 b/config/gnulib-cache.m4 new file mode 100644 index 0000000..2ec4643 --- /dev/null +++ b/config/gnulib-cache.m4 @@ -0,0 +1,73 @@ +# Copyright (C) 2002-2018 Free Software Foundation, Inc. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This file is distributed in the hope that 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 file. If not, see <https://www.gnu.org/licenses/>. +# +# As a special exception to the GNU General Public License, +# this file may be distributed as part of a program that +# contains a configuration script generated by Autoconf, under +# the same distribution terms as the rest of that program. +# +# Generated by gnulib-tool. +# +# This file represents the specification of how gnulib-tool is used. +# It acts as a cache: It is written and read by gnulib-tool. +# In projects that use version control, this file is meant to be put under +# version control, like the configure.ac and various Makefile.am files. + + +# Specification in the form of a command-line invocation: +# gnulib-tool --import --local-dir=tmp \ +# --lib=do_not_make_me \ +# --source-base=autoopts \ +# --m4-base=config \ +# --doc-base=doc \ +# --tests-base=tests \ +# --aux-dir=config \ +# --lgpl=2 \ +# --makefile-name=gnulib.mk \ +# --no-conditional-dependencies \ +# --libtool \ +# --macro-prefix=gl \ +# extensions \ +# gendocs \ +# gettext-h \ +# havelib \ +# parse-duration \ +# snippet/_Noreturn \ +# stdnoreturn + +# Specification in the form of a few gnulib-tool.m4 macro invocations: +gl_LOCAL_DIR([tmp]) +gl_MODULES([ + extensions + gendocs + gettext-h + havelib + parse-duration + snippet/_Noreturn + stdnoreturn +]) +gl_AVOID([]) +gl_SOURCE_BASE([autoopts]) +gl_M4_BASE([config]) +gl_PO_BASE([]) +gl_DOC_BASE([doc]) +gl_TESTS_BASE([tests]) +gl_LIB([do_not_make_me]) +gl_LGPL([2]) +gl_MAKEFILE_NAME([gnulib.mk]) +gl_LIBTOOL +gl_MACRO_PREFIX([gl]) +gl_PO_DOMAIN([]) +gl_WITNESS_C_MACRO([]) diff --git a/config/gnulib-comp.m4 b/config/gnulib-comp.m4 new file mode 100644 index 0000000..399e98e --- /dev/null +++ b/config/gnulib-comp.m4 @@ -0,0 +1,230 @@ +# DO NOT EDIT! GENERATED AUTOMATICALLY! +# Copyright (C) 2002-2018 Free Software Foundation, Inc. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This file is distributed in the hope that 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 file. If not, see <https://www.gnu.org/licenses/>. +# +# As a special exception to the GNU General Public License, +# this file may be distributed as part of a program that +# contains a configuration script generated by Autoconf, under +# the same distribution terms as the rest of that program. +# +# Generated by gnulib-tool. +# +# This file represents the compiled summary of the specification in +# gnulib-cache.m4. It lists the computed macro invocations that need +# to be invoked from configure.ac. +# In projects that use version control, this file can be treated like +# other built files. + + +# 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], +[ + m4_pattern_forbid([^gl_[A-Z]])dnl the gnulib macro namespace + m4_pattern_allow([^gl_ES$])dnl a valid locale name + m4_pattern_allow([^gl_LIBOBJS$])dnl a variable + m4_pattern_allow([^gl_LTLIBOBJS$])dnl a variable + + # Pre-early section. + AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) + AC_REQUIRE([gl_PROG_AR_RANLIB]) + + # Code from module extensions: + # Code from module gendocs: + # Code from module gettext-h: + # Code from module havelib: + # Code from module host-cpu-c-abi: + # Code from module intprops: + # Code from module parse-duration: + # Code from module snippet/_Noreturn: + # Code from module stdnoreturn: +]) + +# This macro should be invoked from ./configure.ac, in the section +# "Check for header files, types and library functions". +AC_DEFUN([gl_INIT], +[ + AM_CONDITIONAL([GL_COND_LIBTOOL], [true]) + gl_cond_libtool=true + gl_m4_base='config' + m4_pushdef([AC_LIBOBJ], m4_defn([gl_LIBOBJ])) + m4_pushdef([AC_REPLACE_FUNCS], m4_defn([gl_REPLACE_FUNCS])) + m4_pushdef([AC_LIBSOURCES], m4_defn([gl_LIBSOURCES])) + m4_pushdef([gl_LIBSOURCES_LIST], []) + m4_pushdef([gl_LIBSOURCES_DIR], []) + gl_COMMON + gl_source_base='autoopts' + AC_SUBST([LIBINTL]) + AC_SUBST([LTLIBINTL]) + AC_REQUIRE([gl_HOST_CPU_C_ABI]) + gl_STDNORETURN_H + # End of code from modules + m4_ifval(gl_LIBSOURCES_LIST, [ + m4_syscmd([test ! -d ]m4_defn([gl_LIBSOURCES_DIR])[ || + for gl_file in ]gl_LIBSOURCES_LIST[ ; do + if test ! -r ]m4_defn([gl_LIBSOURCES_DIR])[/$gl_file ; then + echo "missing file ]m4_defn([gl_LIBSOURCES_DIR])[/$gl_file" >&2 + exit 1 + fi + done])dnl + m4_if(m4_sysval, [0], [], + [AC_FATAL([expected source file, required through AC_LIBSOURCES, not found])]) + ]) + m4_popdef([gl_LIBSOURCES_DIR]) + m4_popdef([gl_LIBSOURCES_LIST]) + m4_popdef([AC_LIBSOURCES]) + m4_popdef([AC_REPLACE_FUNCS]) + m4_popdef([AC_LIBOBJ]) + AC_CONFIG_COMMANDS_PRE([ + gl_libobjs= + gl_ltlibobjs= + if test -n "$gl_LIBOBJS"; then + # Remove the extension. + sed_drop_objext='s/\.o$//;s/\.obj$//' + for i in `for i in $gl_LIBOBJS; do echo "$i"; done | sed -e "$sed_drop_objext" | sort | uniq`; do + gl_libobjs="$gl_libobjs $i.$ac_objext" + gl_ltlibobjs="$gl_ltlibobjs $i.lo" + done + fi + AC_SUBST([gl_LIBOBJS], [$gl_libobjs]) + AC_SUBST([gl_LTLIBOBJS], [$gl_ltlibobjs]) + ]) + gltests_libdeps= + gltests_ltlibdeps= + m4_pushdef([AC_LIBOBJ], m4_defn([gltests_LIBOBJ])) + m4_pushdef([AC_REPLACE_FUNCS], m4_defn([gltests_REPLACE_FUNCS])) + m4_pushdef([AC_LIBSOURCES], m4_defn([gltests_LIBSOURCES])) + m4_pushdef([gltests_LIBSOURCES_LIST], []) + m4_pushdef([gltests_LIBSOURCES_DIR], []) + gl_COMMON + gl_source_base='tests' +changequote(,)dnl + gltests_WITNESS=IN_`echo "${PACKAGE-$PACKAGE_TARNAME}" | LC_ALL=C tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ | LC_ALL=C sed -e 's/[^A-Z0-9_]/_/g'`_GNULIB_TESTS +changequote([, ])dnl + AC_SUBST([gltests_WITNESS]) + gl_module_indicator_condition=$gltests_WITNESS + m4_pushdef([gl_MODULE_INDICATOR_CONDITION], [$gl_module_indicator_condition]) + m4_popdef([gl_MODULE_INDICATOR_CONDITION]) + m4_ifval(gltests_LIBSOURCES_LIST, [ + m4_syscmd([test ! -d ]m4_defn([gltests_LIBSOURCES_DIR])[ || + for gl_file in ]gltests_LIBSOURCES_LIST[ ; do + if test ! -r ]m4_defn([gltests_LIBSOURCES_DIR])[/$gl_file ; then + echo "missing file ]m4_defn([gltests_LIBSOURCES_DIR])[/$gl_file" >&2 + exit 1 + fi + done])dnl + m4_if(m4_sysval, [0], [], + [AC_FATAL([expected source file, required through AC_LIBSOURCES, not found])]) + ]) + m4_popdef([gltests_LIBSOURCES_DIR]) + m4_popdef([gltests_LIBSOURCES_LIST]) + m4_popdef([AC_LIBSOURCES]) + m4_popdef([AC_REPLACE_FUNCS]) + m4_popdef([AC_LIBOBJ]) + AC_CONFIG_COMMANDS_PRE([ + gltests_libobjs= + gltests_ltlibobjs= + if test -n "$gltests_LIBOBJS"; then + # Remove the extension. + sed_drop_objext='s/\.o$//;s/\.obj$//' + for i in `for i in $gltests_LIBOBJS; do echo "$i"; done | sed -e "$sed_drop_objext" | sort | uniq`; do + gltests_libobjs="$gltests_libobjs $i.$ac_objext" + gltests_ltlibobjs="$gltests_ltlibobjs $i.lo" + done + fi + AC_SUBST([gltests_LIBOBJS], [$gltests_libobjs]) + AC_SUBST([gltests_LTLIBOBJS], [$gltests_ltlibobjs]) + ]) +]) + +# Like AC_LIBOBJ, except that the module name goes +# into gl_LIBOBJS instead of into LIBOBJS. +AC_DEFUN([gl_LIBOBJ], [ + AS_LITERAL_IF([$1], [gl_LIBSOURCES([$1.c])])dnl + gl_LIBOBJS="$gl_LIBOBJS $1.$ac_objext" +]) + +# Like AC_REPLACE_FUNCS, except that the module name goes +# into gl_LIBOBJS instead of into LIBOBJS. +AC_DEFUN([gl_REPLACE_FUNCS], [ + m4_foreach_w([gl_NAME], [$1], [AC_LIBSOURCES(gl_NAME[.c])])dnl + AC_CHECK_FUNCS([$1], , [gl_LIBOBJ($ac_func)]) +]) + +# Like AC_LIBSOURCES, except the directory where the source file is +# expected is derived from the gnulib-tool parameterization, +# and alloca is special cased (for the alloca-opt module). +# We could also entirely rely on EXTRA_lib..._SOURCES. +AC_DEFUN([gl_LIBSOURCES], [ + m4_foreach([_gl_NAME], [$1], [ + m4_if(_gl_NAME, [alloca.c], [], [ + m4_define([gl_LIBSOURCES_DIR], [autoopts]) + m4_append([gl_LIBSOURCES_LIST], _gl_NAME, [ ]) + ]) + ]) +]) + +# Like AC_LIBOBJ, except that the module name goes +# into gltests_LIBOBJS instead of into LIBOBJS. +AC_DEFUN([gltests_LIBOBJ], [ + AS_LITERAL_IF([$1], [gltests_LIBSOURCES([$1.c])])dnl + gltests_LIBOBJS="$gltests_LIBOBJS $1.$ac_objext" +]) + +# Like AC_REPLACE_FUNCS, except that the module name goes +# into gltests_LIBOBJS instead of into LIBOBJS. +AC_DEFUN([gltests_REPLACE_FUNCS], [ + m4_foreach_w([gl_NAME], [$1], [AC_LIBSOURCES(gl_NAME[.c])])dnl + AC_CHECK_FUNCS([$1], , [gltests_LIBOBJ($ac_func)]) +]) + +# Like AC_LIBSOURCES, except the directory where the source file is +# expected is derived from the gnulib-tool parameterization, +# and alloca is special cased (for the alloca-opt module). +# We could also entirely rely on EXTRA_lib..._SOURCES. +AC_DEFUN([gltests_LIBSOURCES], [ + m4_foreach([_gl_NAME], [$1], [ + m4_if(_gl_NAME, [alloca.c], [], [ + m4_define([gltests_LIBSOURCES_DIR], [tests]) + m4_append([gltests_LIBSOURCES_LIST], _gl_NAME, [ ]) + ]) + ]) +]) + +# 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/gendocs.sh + doc/gendocs_template + doc/gendocs_template_min + lib/_Noreturn.h + lib/gettext.h + lib/intprops.h + lib/parse-duration.c + lib/parse-duration.h + lib/stdnoreturn.in.h + m4/00gnulib.m4 + m4/asm-underscore.m4 + m4/extensions.m4 + m4/gnulib-common.m4 + m4/host-cpu-c-abi.m4 + m4/lib-ld.m4 + m4/lib-link.m4 + m4/lib-prefix.m4 + m4/onceonly.m4 + m4/stdnoreturn.m4 +]) diff --git a/config/guile.m4 b/config/guile.m4 new file mode 100644 index 0000000..89823e9 --- /dev/null +++ b/config/guile.m4 @@ -0,0 +1,394 @@ +## Autoconf macros for working with Guile. +## +## Copyright (C) 1998,2001, 2006, 2010, 2012, 2013, 2014 Free Software Foundation, Inc. +## +## This library is free software; you can redistribute 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 + +# serial 10 + +## Index +## ----- +## +## GUILE_PKG -- find Guile development files +## GUILE_PROGS -- set paths to Guile interpreter, config and tool programs +## GUILE_FLAGS -- set flags for compiling and linking with Guile +## GUILE_SITE_DIR -- find path to Guile "site" directories +## GUILE_CHECK -- evaluate Guile Scheme code and capture the return value +## GUILE_MODULE_CHECK -- check feature of a Guile Scheme module +## GUILE_MODULE_AVAILABLE -- check availability of a Guile Scheme module +## GUILE_MODULE_REQUIRED -- fail if a Guile Scheme module is unavailable +## GUILE_MODULE_EXPORTS -- check if a module exports a variable +## GUILE_MODULE_REQUIRED_EXPORT -- fail if a module doesn't export a variable + +## Code +## ---- + +## NOTE: Comments preceding an AC_DEFUN (starting from "Usage:") are massaged +## into doc/ref/autoconf-macros.texi (see Makefile.am in that directory). + +# GUILE_PKG -- find Guile development files +# +# Usage: GUILE_PKG([VERSIONS]) +# +# This macro runs the @code{pkg-config} tool to find development files +# for an available version of Guile. +# +# By default, this macro will search for the latest stable version of +# Guile (e.g. 2.2), falling back to the previous stable version +# (e.g. 2.0) if it is available. If no guile-@var{VERSION}.pc file is +# found, an error is signalled. The found version is stored in +# @var{GUILE_EFFECTIVE_VERSION}. +# +# If @code{GUILE_PROGS} was already invoked, this macro ensures that the +# development files have the same effective version as the Guile +# program. +# +# @var{GUILE_EFFECTIVE_VERSION} is marked for substitution, as by +# @code{AC_SUBST}. +# +AC_DEFUN([GUILE_PKG], + [PKG_PROG_PKG_CONFIG + _guile_versions_to_search="m4_default([$1], [2.2 2.0 1.8])" + if test -n "$GUILE_EFFECTIVE_VERSION"; then + _guile_tmp="" + for v in $_guile_versions_to_search; do + if test "$v" = "$GUILE_EFFECTIVE_VERSION"; then + _guile_tmp=$v + fi + done + if test -z "$_guile_tmp"; then + AC_MSG_FAILURE([searching for guile development files for versions $_guile_versions_to_search, but previously found $GUILE version $GUILE_EFFECTIVE_VERSION]) + fi + _guile_versions_to_search=$GUILE_EFFECTIVE_VERSION + fi + GUILE_EFFECTIVE_VERSION="" + _guile_errors="" + for v in $_guile_versions_to_search; do + if test -z "$GUILE_EFFECTIVE_VERSION"; then + AC_MSG_NOTICE([checking for guile $v]) + PKG_CHECK_EXISTS([guile-$v], [GUILE_EFFECTIVE_VERSION=$v], []) + fi + done + + if test -z "$GUILE_EFFECTIVE_VERSION"; then + AC_MSG_ERROR([ +No Guile development packages were found. + +Please verify that you have Guile installed. If you installed Guile +from a binary distribution, please verify that you have also installed +the development packages. If you installed it yourself, you might need +to adjust your PKG_CONFIG_PATH; see the pkg-config man page for more. +]) + fi + AC_MSG_NOTICE([found guile $GUILE_EFFECTIVE_VERSION]) + AC_SUBST([GUILE_EFFECTIVE_VERSION]) + ]) + +# GUILE_FLAGS -- set flags for compiling and linking with Guile +# +# Usage: GUILE_FLAGS +# +# This macro runs the @code{pkg-config} tool to find out how to compile +# and link programs against Guile. It sets four variables: +# @var{GUILE_CFLAGS}, @var{GUILE_LDFLAGS}, @var{GUILE_LIBS}, and +# @var{GUILE_LTLIBS}. +# +# @var{GUILE_CFLAGS}: flags to pass to a C or C++ compiler to build code that +# uses Guile header files. This is almost always just one or more @code{-I} +# flags. +# +# @var{GUILE_LDFLAGS}: flags to pass to the compiler to link a program +# against Guile. This includes @code{-lguile-@var{VERSION}} for the +# Guile library itself, and may also include one or more @code{-L} flag +# to tell the compiler where to find the libraries. But it does not +# include flags that influence the program's runtime search path for +# libraries, and will therefore lead to a program that fails to start, +# unless all necessary libraries are installed in a standard location +# such as @file{/usr/lib}. +# +# @var{GUILE_LIBS} and @var{GUILE_LTLIBS}: flags to pass to the compiler or to +# libtool, respectively, to link a program against Guile. It includes flags +# that augment the program's runtime search path for libraries, so that shared +# libraries will be found at the location where they were during linking, even +# in non-standard locations. @var{GUILE_LIBS} is to be used when linking the +# program directly with the compiler, whereas @var{GUILE_LTLIBS} is to be used +# when linking the program is done through libtool. +# +# The variables are marked for substitution, as by @code{AC_SUBST}. +# +AC_DEFUN([GUILE_FLAGS], + [AC_REQUIRE([GUILE_PKG]) + PKG_CHECK_MODULES(GUILE, [guile-$GUILE_EFFECTIVE_VERSION]) + + dnl GUILE_CFLAGS and GUILE_LIBS are already defined and AC_SUBST'd by + dnl PKG_CHECK_MODULES. But GUILE_LIBS to pkg-config is GUILE_LDFLAGS + dnl to us. + + GUILE_LDFLAGS=$GUILE_LIBS + + dnl Determine the platform dependent parameters needed to use rpath. + dnl AC_LIB_LINKFLAGS_FROM_LIBS is defined in gnulib/m4/lib-link.m4 and needs + dnl the file gnulib/build-aux/config.rpath. + AC_LIB_LINKFLAGS_FROM_LIBS([GUILE_LIBS], [$GUILE_LDFLAGS], []) + GUILE_LIBS="$GUILE_LDFLAGS $GUILE_LIBS" + AC_LIB_LINKFLAGS_FROM_LIBS([GUILE_LTLIBS], [$GUILE_LDFLAGS], [yes]) + GUILE_LTLIBS="$GUILE_LDFLAGS $GUILE_LTLIBS" + + AC_SUBST([GUILE_EFFECTIVE_VERSION]) + AC_SUBST([GUILE_CFLAGS]) + AC_SUBST([GUILE_LDFLAGS]) + AC_SUBST([GUILE_LIBS]) + AC_SUBST([GUILE_LTLIBS]) + ]) + +# GUILE_SITE_DIR -- find path to Guile site directories +# +# Usage: GUILE_SITE_DIR +# +# This looks for Guile's "site" directories. The variable @var{GUILE_SITE} will +# be set to Guile's "site" directory for Scheme source files (usually something +# like PREFIX/share/guile/site). @var{GUILE_SITE_CCACHE} will be set to the +# directory for compiled Scheme files also known as @code{.go} files +# (usually something like +# PREFIX/lib/guile/@var{GUILE_EFFECTIVE_VERSION}/site-ccache). +# @var{GUILE_EXTENSION} will be set to the directory for compiled C extensions +# (usually something like +# PREFIX/lib/guile/@var{GUILE_EFFECTIVE_VERSION}/extensions). The latter two +# are set to blank if the particular version of Guile does not support +# them. Note that this macro will run the macros @code{GUILE_PKG} and +# @code{GUILE_PROGS} if they have not already been run. +# +# The variables are marked for substitution, as by @code{AC_SUBST}. +# +AC_DEFUN([GUILE_SITE_DIR], + [AC_REQUIRE([GUILE_PKG]) + AC_REQUIRE([GUILE_PROGS]) + AC_MSG_CHECKING(for Guile site directory) + GUILE_SITE=`$PKG_CONFIG --print-errors --variable=sitedir guile-$GUILE_EFFECTIVE_VERSION` + AC_MSG_RESULT($GUILE_SITE) + if test "$GUILE_SITE" = ""; then + AC_MSG_FAILURE(sitedir not found) + fi + AC_SUBST(GUILE_SITE) + AC_MSG_CHECKING([for Guile site-ccache directory using pkgconfig]) + GUILE_SITE_CCACHE=`$PKG_CONFIG --variable=siteccachedir guile-$GUILE_EFFECTIVE_VERSION` + if test "$GUILE_SITE_CCACHE" = ""; then + AC_MSG_RESULT(no) + AC_MSG_CHECKING([for Guile site-ccache directory using interpreter]) + GUILE_SITE_CCACHE=`$GUILE -c "(display (if (defined? '%site-ccache-dir) (%site-ccache-dir) \"\"))"` + if test $? != "0" -o "$GUILE_SITE_CCACHE" = ""; then + AC_MSG_RESULT(no) + GUILE_SITE_CCACHE="" + AC_MSG_WARN([siteccachedir not found]) + fi + fi + AC_MSG_RESULT($GUILE_SITE_CCACHE) + AC_SUBST([GUILE_SITE_CCACHE]) + AC_MSG_CHECKING(for Guile extensions directory) + GUILE_EXTENSION=`$PKG_CONFIG --print-errors --variable=extensiondir guile-$GUILE_EFFECTIVE_VERSION` + AC_MSG_RESULT($GUILE_EXTENSION) + if test "$GUILE_EXTENSION" = ""; then + GUILE_EXTENSION="" + AC_MSG_WARN(extensiondir not found) + fi + AC_SUBST(GUILE_EXTENSION) + ]) + +# GUILE_PROGS -- set paths to Guile interpreter, config and tool programs +# +# Usage: GUILE_PROGS([VERSION]) +# +# This macro looks for programs @code{guile} and @code{guild}, setting +# variables @var{GUILE} and @var{GUILD} to their paths, respectively. +# The macro will attempt to find @code{guile} with the suffix of +# @code{-X.Y}, followed by looking for it with the suffix @code{X.Y}, and +# then fall back to looking for @code{guile} with no suffix. If +# @code{guile} is still not found, signal an error. The suffix, if any, +# that was required to find @code{guile} will be used for @code{guild} +# as well. +# +# By default, this macro will search for the latest stable version of +# Guile (e.g. 2.2). x.y or x.y.z versions can be specified. If an older +# version is found, the macro will signal an error. +# +# The effective version of the found @code{guile} is set to +# @var{GUILE_EFFECTIVE_VERSION}. This macro ensures that the effective +# version is compatible with the result of a previous invocation of +# @code{GUILE_FLAGS}, if any. +# +# As a legacy interface, it also looks for @code{guile-config} and +# @code{guile-tools}, setting @var{GUILE_CONFIG} and @var{GUILE_TOOLS}. +# +# The variables are marked for substitution, as by @code{AC_SUBST}. +# +AC_DEFUN([GUILE_PROGS], + [_guile_required_version="m4_default([$1], [$GUILE_EFFECTIVE_VERSION])" + if test -z "$_guile_required_version"; then + _guile_required_version=2.2 + fi + + _guile_candidates=guile + _tmp= + for v in `echo "$_guile_required_version" | tr . ' '`; do + if test -n "$_tmp"; then _tmp=$_tmp.; fi + _tmp=$_tmp$v + _guile_candidates="guile-$_tmp guile$_tmp $_guile_candidates" + done + + AC_PATH_PROGS(GUILE,[$_guile_candidates]) + if test -z "$GUILE"; then + AC_MSG_ERROR([guile required but not found]) + fi + + _guile_suffix=`echo "$GUILE" | sed -e 's,^.*/guile\(.*\)$,\1,'` + _guile_effective_version=`$GUILE -c "(display (effective-version))"` + if test -z "$GUILE_EFFECTIVE_VERSION"; then + GUILE_EFFECTIVE_VERSION=$_guile_effective_version + elif test "$GUILE_EFFECTIVE_VERSION" != "$_guile_effective_version"; then + AC_MSG_ERROR([found development files for Guile $GUILE_EFFECTIVE_VERSION, but $GUILE has effective version $_guile_effective_version]) + fi + + _guile_major_version=`$GUILE -c "(display (major-version))"` + _guile_minor_version=`$GUILE -c "(display (minor-version))"` + _guile_micro_version=`$GUILE -c "(display (micro-version))"` + _guile_prog_version="$_guile_major_version.$_guile_minor_version.$_guile_micro_version" + + AC_MSG_CHECKING([for Guile version >= $_guile_required_version]) + _major_version=`echo $_guile_required_version | cut -d . -f 1` + _minor_version=`echo $_guile_required_version | cut -d . -f 2` + _micro_version=`echo $_guile_required_version | cut -d . -f 3` + if test "$_guile_major_version" -gt "$_major_version"; then + true + elif test "$_guile_major_version" -eq "$_major_version"; then + if test "$_guile_minor_version" -gt "$_minor_version"; then + true + elif test "$_guile_minor_version" -eq "$_minor_version"; then + if test -n "$_micro_version"; then + if test "$_guile_micro_version" -lt "$_micro_version"; then + AC_MSG_ERROR([Guile $_guile_required_version required, but $_guile_prog_version found]) + fi + fi + elif test "$GUILE_EFFECTIVE_VERSION" = "$_major_version.$_minor_version" -a -z "$_micro_version"; then + # Allow prereleases that have the right effective version. + true + else + as_fn_error $? "Guile $_guile_required_version required, but $_guile_prog_version found" "$LINENO" 5 + fi + elif test "$GUILE_EFFECTIVE_VERSION" = "$_major_version.$_minor_version" -a -z "$_micro_version"; then + # Allow prereleases that have the right effective version. + true + else + AC_MSG_ERROR([Guile $_guile_required_version required, but $_guile_prog_version found]) + fi + AC_MSG_RESULT([$_guile_prog_version]) + + AC_PATH_PROG(GUILD,[guild$_guile_suffix]) + AC_SUBST(GUILD) + + AC_PATH_PROG(GUILE_CONFIG,[guile-config$_guile_suffix]) + AC_SUBST(GUILE_CONFIG) + if test -n "$GUILD"; then + GUILE_TOOLS=$GUILD + else + AC_PATH_PROG(GUILE_TOOLS,[guile-tools$_guile_suffix]) + fi + AC_SUBST(GUILE_TOOLS) + ]) + +# GUILE_CHECK -- evaluate Guile Scheme code and capture the return value +# +# Usage: GUILE_CHECK_RETVAL(var,check) +# +# @var{var} is a shell variable name to be set to the return value. +# @var{check} is a Guile Scheme expression, evaluated with "$GUILE -c", and +# returning either 0 or non-#f to indicate the check passed. +# Non-0 number or #f indicates failure. +# Avoid using the character "#" since that confuses autoconf. +# +AC_DEFUN([GUILE_CHECK], + [AC_REQUIRE([GUILE_PROGS]) + $GUILE -c "$2" > /dev/null 2>&1 + $1=$? + ]) + +# GUILE_MODULE_CHECK -- check feature of a Guile Scheme module +# +# Usage: GUILE_MODULE_CHECK(var,module,featuretest,description) +# +# @var{var} is a shell variable name to be set to "yes" or "no". +# @var{module} is a list of symbols, like: (ice-9 common-list). +# @var{featuretest} is an expression acceptable to GUILE_CHECK, q.v. +# @var{description} is a present-tense verb phrase (passed to AC_MSG_CHECKING). +# +AC_DEFUN([GUILE_MODULE_CHECK], + [AC_MSG_CHECKING([if $2 $4]) + GUILE_CHECK($1,(use-modules $2) (exit ((lambda () $3)))) + if test "$$1" = "0" ; then $1=yes ; else $1=no ; fi + AC_MSG_RESULT($$1) + ]) + +# GUILE_MODULE_AVAILABLE -- check availability of a Guile Scheme module +# +# Usage: GUILE_MODULE_AVAILABLE(var,module) +# +# @var{var} is a shell variable name to be set to "yes" or "no". +# @var{module} is a list of symbols, like: (ice-9 common-list). +# +AC_DEFUN([GUILE_MODULE_AVAILABLE], + [GUILE_MODULE_CHECK($1,$2,0,is available) + ]) + +# GUILE_MODULE_REQUIRED -- fail if a Guile Scheme module is unavailable +# +# Usage: GUILE_MODULE_REQUIRED(symlist) +# +# @var{symlist} is a list of symbols, WITHOUT surrounding parens, +# like: ice-9 common-list. +# +AC_DEFUN([GUILE_MODULE_REQUIRED], + [GUILE_MODULE_AVAILABLE(ac_guile_module_required, ($1)) + if test "$ac_guile_module_required" = "no" ; then + AC_MSG_ERROR([required guile module not found: ($1)]) + fi + ]) + +# GUILE_MODULE_EXPORTS -- check if a module exports a variable +# +# Usage: GUILE_MODULE_EXPORTS(var,module,modvar) +# +# @var{var} is a shell variable to be set to "yes" or "no". +# @var{module} is a list of symbols, like: (ice-9 common-list). +# @var{modvar} is the Guile Scheme variable to check. +# +AC_DEFUN([GUILE_MODULE_EXPORTS], + [GUILE_MODULE_CHECK($1,$2,$3,exports `$3') + ]) + +# GUILE_MODULE_REQUIRED_EXPORT -- fail if a module doesn't export a variable +# +# Usage: GUILE_MODULE_REQUIRED_EXPORT(module,modvar) +# +# @var{module} is a list of symbols, like: (ice-9 common-list). +# @var{modvar} is the Guile Scheme variable to check. +# +AC_DEFUN([GUILE_MODULE_REQUIRED_EXPORT], + [GUILE_MODULE_EXPORTS(guile_module_required_export,$1,$2) + if test "$guile_module_required_export" = "no" ; then + AC_MSG_ERROR([module $1 does not export $2; required]) + fi + ]) + +## guile.m4 ends here diff --git a/config/host-cpu-c-abi.m4 b/config/host-cpu-c-abi.m4 new file mode 100644 index 0000000..3fac6f7 --- /dev/null +++ b/config/host-cpu-c-abi.m4 @@ -0,0 +1,456 @@ +# host-cpu-c-abi.m4 serial 10 +dnl Copyright (C) 2002-2018 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 and Sam Steingold. + +dnl Sets the HOST_CPU variable to the canonical name of the CPU. +dnl Sets the HOST_CPU_C_ABI variable to the canonical name of the CPU with its +dnl C language ABI (application binary interface). +dnl Also defines __${HOST_CPU}__ and __${HOST_CPU_C_ABI}__ as C macros in +dnl config.h. +dnl +dnl This canonical name can be used to select a particular assembly language +dnl source file that will interoperate with C code on the given host. +dnl +dnl For example: +dnl * 'i386' and 'sparc' are different canonical names, because code for i386 +dnl will not run on SPARC CPUs and vice versa. They have different +dnl instruction sets. +dnl * 'sparc' and 'sparc64' are different canonical names, because code for +dnl 'sparc' and code for 'sparc64' cannot be linked together: 'sparc' code +dnl contains 32-bit instructions, whereas 'sparc64' code contains 64-bit +dnl instructions. A process on a SPARC CPU can be in 32-bit mode or in 64-bit +dnl mode, but not both. +dnl * 'mips' and 'mipsn32' are different canonical names, because they use +dnl different argument passing and return conventions for C functions, and +dnl although the instruction set of 'mips' is a large subset of the +dnl instruction set of 'mipsn32'. +dnl * 'mipsn32' and 'mips64' are different canonical names, because they use +dnl different sizes for the C types like 'int' and 'void *', and although +dnl the instruction sets of 'mipsn32' and 'mips64' are the same. +dnl * The same canonical name is used for different endiannesses. You can +dnl determine the endianness through preprocessor symbols: +dnl - 'arm': test __ARMEL__. +dnl - 'mips', 'mipsn32', 'mips64': test _MIPSEB vs. _MIPSEL. +dnl - 'powerpc64': test _BIG_ENDIAN vs. _LITTLE_ENDIAN. +dnl * The same name 'i386' is used for CPUs of type i386, i486, i586 +dnl (Pentium), AMD K7, Pentium II, Pentium IV, etc., because +dnl - Instructions that do not exist on all of these CPUs (cmpxchg, +dnl MMX, SSE, SSE2, 3DNow! etc.) are not frequently used. If your +dnl assembly language source files use such instructions, you will +dnl need to make the distinction. +dnl - Speed of execution of the common instruction set is reasonable across +dnl the entire family of CPUs. If you have assembly language source files +dnl that are optimized for particular CPU types (like GNU gmp has), you +dnl will need to make the distinction. +dnl See <https://en.wikipedia.org/wiki/X86_instruction_listings>. +AC_DEFUN([gl_HOST_CPU_C_ABI], +[ + AC_REQUIRE([AC_CANONICAL_HOST]) + AC_REQUIRE([gl_C_ASM]) + AC_CACHE_CHECK([host CPU and C ABI], [gl_cv_host_cpu_c_abi], + [case "$host_cpu" in + +changequote(,)dnl + i[4567]86 ) +changequote([,])dnl + gl_cv_host_cpu_c_abi=i386 + ;; + + x86_64 ) + # On x86_64 systems, the C compiler may be generating code in one of + # these ABIs: + # - 64-bit instruction set, 64-bit pointers, 64-bit 'long': x86_64. + # - 64-bit instruction set, 64-bit pointers, 32-bit 'long': x86_64 + # with native Windows (mingw, MSVC). + # - 64-bit instruction set, 32-bit pointers, 32-bit 'long': x86_64-x32. + # - 32-bit instruction set, 32-bit pointers, 32-bit 'long': i386. + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if (defined __x86_64__ || defined __amd64__ \ + || defined _M_X64 || defined _M_AMD64) + int ok; + #else + error fail + #endif + ]])], + [AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if defined __ILP32__ || defined _ILP32 + int ok; + #else + error fail + #endif + ]])], + [gl_cv_host_cpu_c_abi=x86_64-x32], + [gl_cv_host_cpu_c_abi=x86_64])], + [gl_cv_host_cpu_c_abi=i386]) + ;; + +changequote(,)dnl + alphaev[4-8] | alphaev56 | alphapca5[67] | alphaev6[78] ) +changequote([,])dnl + gl_cv_host_cpu_c_abi=alpha + ;; + + arm* | aarch64 ) + # Assume arm with EABI. + # On arm64 systems, the C compiler may be generating code in one of + # these ABIs: + # - aarch64 instruction set, 64-bit pointers, 64-bit 'long': arm64. + # - aarch64 instruction set, 32-bit pointers, 32-bit 'long': arm64-ilp32. + # - 32-bit instruction set, 32-bit pointers, 32-bit 'long': arm or armhf. + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#ifdef __aarch64__ + int ok; + #else + error fail + #endif + ]])], + [AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if defined __ILP32__ || defined _ILP32 + int ok; + #else + error fail + #endif + ]])], + [gl_cv_host_cpu_c_abi=arm64-ilp32], + [gl_cv_host_cpu_c_abi=arm64])], + [# Don't distinguish little-endian and big-endian arm, since they + # don't require different machine code for simple operations and + # since the user can distinguish them through the preprocessor + # defines __ARMEL__ vs. __ARMEB__. + # But distinguish arm which passes floating-point arguments and + # return values in integer registers (r0, r1, ...) - this is + # gcc -mfloat-abi=soft or gcc -mfloat-abi=softfp - from arm which + # passes them in float registers (s0, s1, ...) and double registers + # (d0, d1, ...) - this is gcc -mfloat-abi=hard. GCC 4.6 or newer + # sets the preprocessor defines __ARM_PCS (for the first case) and + # __ARM_PCS_VFP (for the second case), but older GCC does not. + echo 'double ddd; void func (double dd) { ddd = dd; }' > conftest.c + # Look for a reference to the register d0 in the .s file. + AC_TRY_COMMAND(${CC-cc} $CFLAGS $CPPFLAGS $gl_c_asm_opt conftest.c) >/dev/null 2>&1 + if LC_ALL=C grep 'd0,' conftest.$gl_asmext >/dev/null; then + gl_cv_host_cpu_c_abi=armhf + else + gl_cv_host_cpu_c_abi=arm + fi + rm -f conftest* + ]) + ;; + + hppa1.0 | hppa1.1 | hppa2.0* | hppa64 ) + # On hppa, the C compiler may be generating 32-bit code or 64-bit + # code. In the latter case, it defines _LP64 and __LP64__. + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#ifdef __LP64__ + int ok; + #else + error fail + #endif + ]])], + [gl_cv_host_cpu_c_abi=hppa64], + [gl_cv_host_cpu_c_abi=hppa]) + ;; + + ia64* ) + # On ia64 on HP-UX, the C compiler may be generating 64-bit code or + # 32-bit code. In the latter case, it defines _ILP32. + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#ifdef _ILP32 + int ok; + #else + error fail + #endif + ]])], + [gl_cv_host_cpu_c_abi=ia64-ilp32], + [gl_cv_host_cpu_c_abi=ia64]) + ;; + + mips* ) + # We should also check for (_MIPS_SZPTR == 64), but gcc keeps this + # at 32. + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if defined _MIPS_SZLONG && (_MIPS_SZLONG == 64) + int ok; + #else + error fail + #endif + ]])], + [gl_cv_host_cpu_c_abi=mips64], + [# In the n32 ABI, _ABIN32 is defined, _ABIO32 is not defined (but + # may later get defined by <sgidefs.h>), and _MIPS_SIM == _ABIN32. + # In the 32 ABI, _ABIO32 is defined, _ABIN32 is not defined (but + # may later get defined by <sgidefs.h>), and _MIPS_SIM == _ABIO32. + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if (_MIPS_SIM == _ABIN32) + int ok; + #else + error fail + #endif + ]])], + [gl_cv_host_cpu_c_abi=mipsn32], + [gl_cv_host_cpu_c_abi=mips])]) + ;; + + powerpc* ) + # Different ABIs are in use on AIX vs. Mac OS X vs. Linux,*BSD. + # No need to distinguish them here; the caller may distinguish + # them based on the OS. + # On powerpc64 systems, the C compiler may still be generating + # 32-bit code. And on powerpc-ibm-aix systems, the C compiler may + # be generating 64-bit code. + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if defined __powerpc64__ || defined _ARCH_PPC64 + int ok; + #else + error fail + #endif + ]])], + [# On powerpc64, there are two ABIs on Linux: The AIX compatible + # one and the ELFv2 one. The latter defines _CALL_ELF=2. + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if defined _CALL_ELF && _CALL_ELF == 2 + int ok; + #else + error fail + #endif + ]])], + [gl_cv_host_cpu_c_abi=powerpc64-elfv2], + [gl_cv_host_cpu_c_abi=powerpc64]) + ], + [gl_cv_host_cpu_c_abi=powerpc]) + ;; + + rs6000 ) + gl_cv_host_cpu_c_abi=powerpc + ;; + + riscv32 | riscv64 ) + # There are 2 architectures (with variants): rv32* and rv64*. + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if __riscv_xlen == 64 + int ok; + #else + error fail + #endif + ]])], + [cpu=riscv64], + [cpu=riscv32]) + # There are 6 ABIs: ilp32, ilp32f, ilp32d, lp64, lp64f, lp64d. + # Size of 'long' and 'void *': + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if defined __LP64__ + int ok; + #else + error fail + #endif + ]])], + [main_abi=lp64], + [main_abi=ilp32]) + # Float ABIs: + # __riscv_float_abi_double: + # 'float' and 'double' are passed in floating-point registers. + # __riscv_float_abi_single: + # 'float' are passed in floating-point registers. + # __riscv_float_abi_soft: + # No values are passed in floating-point registers. + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if defined __riscv_float_abi_double + int ok; + #else + error fail + #endif + ]])], + [float_abi=d], + [AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if defined __riscv_float_abi_single + int ok; + #else + error fail + #endif + ]])], + [float_abi=f], + [float_abi='']) + ]) + gl_cv_host_cpu_c_abi="${cpu}-${main_abi}${float_abi}" + ;; + + s390* ) + # On s390x, the C compiler may be generating 64-bit (= s390x) code + # or 31-bit (= s390) code. + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if defined __LP64__ || defined __s390x__ + int ok; + #else + error fail + #endif + ]])], + [gl_cv_host_cpu_c_abi=s390x], + [gl_cv_host_cpu_c_abi=s390]) + ;; + + sparc | sparc64 ) + # UltraSPARCs running Linux have `uname -m` = "sparc64", but the + # C compiler still generates 32-bit code. + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if defined __sparcv9 || defined __arch64__ + int ok; + #else + error fail + #endif + ]])], + [gl_cv_host_cpu_c_abi=sparc64], + [gl_cv_host_cpu_c_abi=sparc]) + ;; + + *) + gl_cv_host_cpu_c_abi="$host_cpu" + ;; + esac + ]) + + dnl In most cases, $HOST_CPU and $HOST_CPU_C_ABI are the same. + HOST_CPU=`echo "$gl_cv_host_cpu_c_abi" | sed -e 's/-.*//'` + HOST_CPU_C_ABI="$gl_cv_host_cpu_c_abi" + AC_SUBST([HOST_CPU]) + AC_SUBST([HOST_CPU_C_ABI]) + + # This was + # AC_DEFINE_UNQUOTED([__${HOST_CPU}__]) + # AC_DEFINE_UNQUOTED([__${HOST_CPU_C_ABI}__]) + # earlier, but KAI C++ 3.2d doesn't like this. + sed -e 's/-/_/g' >> confdefs.h <<EOF +#ifndef __${HOST_CPU}__ +#define __${HOST_CPU}__ 1 +#endif +#ifndef __${HOST_CPU_C_ABI}__ +#define __${HOST_CPU_C_ABI}__ 1 +#endif +EOF + AH_TOP([/* CPU and C ABI indicator */ +#ifndef __i386__ +#undef __i386__ +#endif +#ifndef __x86_64_x32__ +#undef __x86_64_x32__ +#endif +#ifndef __x86_64__ +#undef __x86_64__ +#endif +#ifndef __alpha__ +#undef __alpha__ +#endif +#ifndef __arm__ +#undef __arm__ +#endif +#ifndef __armhf__ +#undef __armhf__ +#endif +#ifndef __arm64_ilp32__ +#undef __arm64_ilp32__ +#endif +#ifndef __arm64__ +#undef __arm64__ +#endif +#ifndef __hppa__ +#undef __hppa__ +#endif +#ifndef __hppa64__ +#undef __hppa64__ +#endif +#ifndef __ia64_ilp32__ +#undef __ia64_ilp32__ +#endif +#ifndef __ia64__ +#undef __ia64__ +#endif +#ifndef __m68k__ +#undef __m68k__ +#endif +#ifndef __mips__ +#undef __mips__ +#endif +#ifndef __mipsn32__ +#undef __mipsn32__ +#endif +#ifndef __mips64__ +#undef __mips64__ +#endif +#ifndef __powerpc__ +#undef __powerpc__ +#endif +#ifndef __powerpc64__ +#undef __powerpc64__ +#endif +#ifndef __powerpc64_elfv2__ +#undef __powerpc64_elfv2__ +#endif +#ifndef __riscv32__ +#undef __riscv32__ +#endif +#ifndef __riscv64__ +#undef __riscv64__ +#endif +#ifndef __riscv32_ilp32__ +#undef __riscv32_ilp32__ +#endif +#ifndef __riscv32_ilp32f__ +#undef __riscv32_ilp32f__ +#endif +#ifndef __riscv32_ilp32d__ +#undef __riscv32_ilp32d__ +#endif +#ifndef __riscv64_ilp32__ +#undef __riscv64_ilp32__ +#endif +#ifndef __riscv64_ilp32f__ +#undef __riscv64_ilp32f__ +#endif +#ifndef __riscv64_ilp32d__ +#undef __riscv64_ilp32d__ +#endif +#ifndef __riscv64_lp64__ +#undef __riscv64_lp64__ +#endif +#ifndef __riscv64_lp64f__ +#undef __riscv64_lp64f__ +#endif +#ifndef __riscv64_lp64d__ +#undef __riscv64_lp64d__ +#endif +#ifndef __s390__ +#undef __s390__ +#endif +#ifndef __s390x__ +#undef __s390x__ +#endif +#ifndef __sh__ +#undef __sh__ +#endif +#ifndef __sparc__ +#undef __sparc__ +#endif +#ifndef __sparc64__ +#undef __sparc64__ +#endif +]) + +]) diff --git a/config/install-defs.sh b/config/install-defs.sh new file mode 100644 index 0000000..f61f924 --- /dev/null +++ b/config/install-defs.sh @@ -0,0 +1,17 @@ +#! /bin/sh +# AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +sedcmd= +nl=' +' +eval `egrep '^SED=' ${top_builddir}/config/shdefs` + +for v in srcdir top_srcdir top_builddir +do + eval val=\"\${$v}\" + val=`cd ${val} >/dev/null && pwd` + sedcmd="${sedcmd}/: .{$v=/s@=[^}]*}@=$val}@$nl" +done + +${SED} "$sedcmd" $1 > ./.defs$$ +mv .defs$$ defs +chmod +x ${srcdir}/*.test >/dev/null 2>&1 diff --git a/config/install-sh b/config/install-sh new file mode 100755 index 0000000..8175c64 --- /dev/null +++ b/config/install-sh @@ -0,0 +1,518 @@ +#!/bin/sh +# install - install a program, script, or datafile + +scriptversion=2018-03-11.20; # UTC + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. +# +# Copyright (C) 1994 X Consortium +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# 'make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. + +tab=' ' +nl=' +' +IFS=" $tab$nl" + +# Set DOITPROG to "echo" to test this script. + +doit=${DOITPROG-} +doit_exec=${doit:-exec} + +# Put in absolute file names if you don't have them in your path; +# or use environment vars. + +chgrpprog=${CHGRPPROG-chgrp} +chmodprog=${CHMODPROG-chmod} +chownprog=${CHOWNPROG-chown} +cmpprog=${CMPPROG-cmp} +cpprog=${CPPROG-cp} +mkdirprog=${MKDIRPROG-mkdir} +mvprog=${MVPROG-mv} +rmprog=${RMPROG-rm} +stripprog=${STRIPPROG-strip} + +posix_mkdir= + +# Desired mode of installed file. +mode=0755 + +chgrpcmd= +chmodcmd=$chmodprog +chowncmd= +mvcmd=$mvprog +rmcmd="$rmprog -f" +stripcmd= + +src= +dst= +dir_arg= +dst_arg= + +copy_on_change=false +is_target_a_directory=possibly + +usage="\ +Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 [OPTION]... -t DIRECTORY SRCFILES... + or: $0 [OPTION]... -d DIRECTORIES... + +In the 1st form, copy SRCFILE to DSTFILE. +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +In the 4th, create DIRECTORIES. + +Options: + --help display this help and exit. + --version display version info and exit. + + -c (ignored) + -C install only if different (preserve the last data modification time) + -d create directories instead of installing files. + -g GROUP $chgrpprog installed files to GROUP. + -m MODE $chmodprog installed files to MODE. + -o USER $chownprog installed files to USER. + -s $stripprog installed files. + -t DIRECTORY install into DIRECTORY. + -T report an error if DSTFILE is a directory. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG + RMPROG STRIPPROG +" + +while test $# -ne 0; do + case $1 in + -c) ;; + + -C) copy_on_change=true;; + + -d) dir_arg=true;; + + -g) chgrpcmd="$chgrpprog $2" + shift;; + + --help) echo "$usage"; exit $?;; + + -m) mode=$2 + case $mode in + *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) + echo "$0: invalid mode: $mode" >&2 + exit 1;; + esac + shift;; + + -o) chowncmd="$chownprog $2" + shift;; + + -s) stripcmd=$stripprog;; + + -t) + is_target_a_directory=always + dst_arg=$2 + # Protect names problematic for 'test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + shift;; + + -T) is_target_a_directory=never;; + + --version) echo "$0 $scriptversion"; exit $?;; + + --) shift + break;; + + -*) echo "$0: invalid option: $1" >&2 + exit 1;; + + *) break;; + esac + shift +done + +# We allow the use of options -d and -T together, by making -d +# take the precedence; this is for compatibility with GNU install. + +if test -n "$dir_arg"; then + if test -n "$dst_arg"; then + echo "$0: target directory not allowed when installing a directory." >&2 + exit 1 + fi +fi + +if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then + # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dst_arg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dst_arg" + shift # fnord + fi + shift # arg + dst_arg=$arg + # Protect names problematic for 'test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + done +fi + +if test $# -eq 0; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call 'install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +if test -z "$dir_arg"; then + if test $# -gt 1 || test "$is_target_a_directory" = always; then + if test ! -d "$dst_arg"; then + echo "$0: $dst_arg: Is not a directory." >&2 + exit 1 + fi + fi +fi + +if test -z "$dir_arg"; then + do_exit='(exit $ret); exit $ret' + trap "ret=129; $do_exit" 1 + trap "ret=130; $do_exit" 2 + trap "ret=141; $do_exit" 13 + trap "ret=143; $do_exit" 15 + + # Set umask so as not to create temps with too-generous modes. + # However, 'strip' requires both read and write access to temps. + case $mode in + # Optimize common cases. + *644) cp_umask=133;; + *755) cp_umask=22;; + + *[0-7]) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw='% 200' + fi + cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; + *) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw=,u+rw + fi + cp_umask=$mode$u_plus_rw;; + esac +fi + +for src +do + # Protect names problematic for 'test' and other utilities. + case $src in + -* | [=\(\)!]) src=./$src;; + esac + + if test -n "$dir_arg"; then + dst=$src + dstdir=$dst + test -d "$dstdir" + dstdir_status=$? + else + + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dst_arg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + dst=$dst_arg + + # If destination is a directory, append the input filename. + if test -d "$dst"; then + if test "$is_target_a_directory" = never; then + echo "$0: $dst_arg: Is a directory" >&2 + exit 1 + fi + dstdir=$dst + dstbase=`basename "$src"` + case $dst in + */) dst=$dst$dstbase;; + *) dst=$dst/$dstbase;; + esac + dstdir_status=0 + else + dstdir=`dirname "$dst"` + test -d "$dstdir" + dstdir_status=$? + fi + fi + + case $dstdir in + */) dstdirslash=$dstdir;; + *) dstdirslash=$dstdir/;; + esac + + obsolete_mkdir_used=false + + if test $dstdir_status != 0; then + case $posix_mkdir in + '') + # Create intermediate dirs using mode 755 as modified by the umask. + # This is like FreeBSD 'install' as of 1997-10-28. + umask=`umask` + case $stripcmd.$umask in + # Optimize common cases. + *[2367][2367]) mkdir_umask=$umask;; + .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; + + *[0-7]) + mkdir_umask=`expr $umask + 22 \ + - $umask % 100 % 40 + $umask % 20 \ + - $umask % 10 % 4 + $umask % 2 + `;; + *) mkdir_umask=$umask,go-w;; + esac + + # With -d, create the new directory with the user-specified mode. + # Otherwise, rely on $mkdir_umask. + if test -n "$dir_arg"; then + mkdir_mode=-m$mode + else + mkdir_mode= + fi + + posix_mkdir=false + case $umask in + *[123567][0-7][0-7]) + # POSIX mkdir -p sets u+wx bits regardless of umask, which + # is incompatible with FreeBSD 'install' when (umask & 300) != 0. + ;; + *) + # Note that $RANDOM variable is not portable (e.g. dash); Use it + # here however when possible just to lower collision chance. + tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ + + trap 'ret=$?; rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null; exit $ret' 0 + + # Because "mkdir -p" follows existing symlinks and we likely work + # directly in world-writeable /tmp, make sure that the '$tmpdir' + # directory is successfully created first before we actually test + # 'mkdir -p' feature. + if (umask $mkdir_umask && + $mkdirprog $mkdir_mode "$tmpdir" && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 + then + if test -z "$dir_arg" || { + # Check for POSIX incompatibilities with -m. + # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or + # other-writable bit of parent directory when it shouldn't. + # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. + test_tmpdir="$tmpdir/a" + ls_ld_tmpdir=`ls -ld "$test_tmpdir"` + case $ls_ld_tmpdir in + d????-?r-*) different_mode=700;; + d????-?--*) different_mode=755;; + *) false;; + esac && + $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` + test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" + } + } + then posix_mkdir=: + fi + rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" + else + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null + fi + trap '' 0;; + esac;; + esac + + if + $posix_mkdir && ( + umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" + ) + then : + else + + # The umask is ridiculous, or mkdir does not conform to POSIX, + # or it failed possibly due to a race condition. Create the + # directory the slow way, step by step, checking for races as we go. + + case $dstdir in + /*) prefix='/';; + [-=\(\)!]*) prefix='./';; + *) prefix='';; + esac + + oIFS=$IFS + IFS=/ + set -f + set fnord $dstdir + shift + set +f + IFS=$oIFS + + prefixes= + + for d + do + test X"$d" = X && continue + + prefix=$prefix$d + if test -d "$prefix"; then + prefixes= + else + if $posix_mkdir; then + (umask=$mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break + # Don't fail if two instances are running concurrently. + test -d "$prefix" || exit 1 + else + case $prefix in + *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; + *) qprefix=$prefix;; + esac + prefixes="$prefixes '$qprefix'" + fi + fi + prefix=$prefix/ + done + + if test -n "$prefixes"; then + # Don't fail if two instances are running concurrently. + (umask $mkdir_umask && + eval "\$doit_exec \$mkdirprog $prefixes") || + test -d "$dstdir" || exit 1 + obsolete_mkdir_used=true + fi + fi + fi + + if test -n "$dir_arg"; then + { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && + { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || + test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 + else + + # Make a couple of temp file names in the proper directory. + dsttmp=${dstdirslash}_inst.$$_ + rmtmp=${dstdirslash}_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 + + # Copy the file name to the temp name. + (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && + + # and set any options; do chmod last to preserve setuid bits. + # + # If any of these fail, we abort the whole thing. If we want to + # ignore errors from any of these, just make sure not to ignore + # errors from the above "$doit $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && + { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && + { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && + + # If -C, don't bother to copy if it wouldn't change the file. + if $copy_on_change && + old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && + new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && + set -f && + set X $old && old=:$2:$4:$5:$6 && + set X $new && new=:$2:$4:$5:$6 && + set +f && + test "$old" = "$new" && + $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 + then + rm -f "$dsttmp" + else + # Rename the file to the real destination. + $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || + + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + { + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + test ! -f "$dst" || + $doit $rmcmd -f "$dst" 2>/dev/null || + { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && + { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } + } || + { echo "$0: cannot unlink or rename $dst" >&2 + (exit 1); exit 1 + } + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dst" + } + fi || exit 1 + + trap '' 0 + fi +done + +# Local variables: +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC0" +# time-stamp-end: "; # UTC" +# End: diff --git a/config/lib-ld.m4 b/config/lib-ld.m4 new file mode 100644 index 0000000..1244ff8 --- /dev/null +++ b/config/lib-ld.m4 @@ -0,0 +1,168 @@ +# lib-ld.m4 serial 9 +dnl Copyright (C) 1996-2003, 2009-2018 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 Subroutines of libtool.m4, +dnl with replacements s/_*LT_PATH/AC_LIB_PROG/ and s/lt_/acl_/ to avoid +dnl collision with libtool.m4. + +dnl From libtool-2.4. Sets the variable with_gnu_ld to yes or no. +AC_DEFUN([AC_LIB_PROG_LD_GNU], +[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], [acl_cv_prog_gnu_ld], +[# I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 </dev/null` in +*GNU* | *'with BFD'*) + acl_cv_prog_gnu_ld=yes + ;; +*) + acl_cv_prog_gnu_ld=no + ;; +esac]) +with_gnu_ld=$acl_cv_prog_gnu_ld +]) + +dnl From libtool-2.4. Sets the variable LD. +AC_DEFUN([AC_LIB_PROG_LD], +[AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl + +AC_ARG_WITH([gnu-ld], + [AS_HELP_STRING([--with-gnu-ld], + [assume the C compiler uses GNU ld [default=no]])], + [test "$withval" = no || with_gnu_ld=yes], + [with_gnu_ld=no])dnl + +# Prepare PATH_SEPARATOR. +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + # Determine PATH_SEPARATOR by trying to find /bin/sh in a PATH which + # contains only /bin. Note that ksh looks also at the FPATH variable, + # so we have to set that as well for the test. + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \ + && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \ + || PATH_SEPARATOR=';' + } +fi + +if test -n "$LD"; then + AC_MSG_CHECKING([for ld]) +elif test "$GCC" = yes; then + AC_MSG_CHECKING([for ld used by $CC]) +elif test "$with_gnu_ld" = yes; then + AC_MSG_CHECKING([for GNU ld]) +else + AC_MSG_CHECKING([for non-GNU ld]) +fi +if test -n "$LD"; then + # Let the user override the test with a path. + : +else + AC_CACHE_VAL([acl_cv_path_LD], + [ + acl_cv_path_LD= # Final result of this test + ac_prog=ld # Program to search in $PATH + if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + acl_output=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + acl_output=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $acl_output in + # Accept absolute paths. + [[\\/]]* | ?:[[\\/]]*) + re_direlt='/[[^/]][[^/]]*/\.\./' + # Canonicalize the pathname of ld + acl_output=`echo "$acl_output" | sed 's%\\\\%/%g'` + while echo "$acl_output" | grep "$re_direlt" > /dev/null 2>&1; do + acl_output=`echo $acl_output | sed "s%$re_direlt%/%"` + done + # Got the pathname. No search in PATH is needed. + acl_cv_path_LD="$acl_output" + ac_prog= + ;; + "") + # If it fails, then pretend we aren't using GCC. + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac + fi + if test -n "$ac_prog"; then + # Search for $ac_prog in $PATH. + acl_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$acl_save_ifs" + 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 variants of GNU ld 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="$acl_save_ifs" + fi + case $host in + *-*-aix*) + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if defined __powerpc64__ || defined _ARCH_PPC64 + int ok; + #else + error fail + #endif + ]])], + [# The compiler produces 64-bit code. Add option '-b64' so that the + # linker groks 64-bit object files. + case "$acl_cv_path_LD " in + *" -b64 "*) ;; + *) acl_cv_path_LD="$acl_cv_path_LD -b64" ;; + esac + ], []) + ;; + sparc64-*-netbsd*) + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if defined __sparcv9 || defined __arch64__ + int ok; + #else + error fail + #endif + ]])], + [], + [# The compiler produces 32-bit code. Add option '-m elf32_sparc' + # so that the linker groks 32-bit object files. + case "$acl_cv_path_LD " in + *" -m elf32_sparc "*) ;; + *) acl_cv_path_LD="$acl_cv_path_LD -m elf32_sparc" ;; + esac + ]) + ;; + esac + ]) + LD="$acl_cv_path_LD" +fi +if test -n "$LD"; then + AC_MSG_RESULT([$LD]) +else + AC_MSG_RESULT([no]) + AC_MSG_ERROR([no acceptable ld found in \$PATH]) +fi +AC_LIB_PROG_LD_GNU +]) diff --git a/config/lib-link.m4 b/config/lib-link.m4 new file mode 100644 index 0000000..df77db9 --- /dev/null +++ b/config/lib-link.m4 @@ -0,0 +1,777 @@ +# lib-link.m4 serial 26 (gettext-0.18.2) +dnl Copyright (C) 2001-2018 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],[m4_translit([$1],[./+-], [____])]) + pushdef([NAME],[m4_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],[m4_translit([$1],[./+-], [____])]) + pushdef([NAME],[m4_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" + dnl If $LIB[]NAME contains some -l options, add it to the end of LIBS, + dnl because these -l options might require -L options that are present in + dnl LIBS. -l options benefit only from the -L options listed before it. + dnl Otherwise, add it to the front of LIBS, because it may be a static + dnl library that depends on another static library that is present in LIBS. + dnl Static libraries benefit only from the static libraries listed after + dnl it. + case " $LIB[]NAME" in + *" -l"*) LIBS="$LIBS $LIB[]NAME" ;; + *) LIBS="$LIB[]NAME $LIBS" ;; + esac + AC_LINK_IFELSE( + [AC_LANG_PROGRAM([[$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_libname_spec, +dnl acl_library_names_spec, +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],[m4_translit([$1],[abcdefghijklmnopqrstuvwxyz./+-], + [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])]) + define([acl_frompackage_]NAME, [$2]) + popdef([NAME]) + pushdef([PACK],[$2]) + pushdef([PACKUP],[m4_translit(PACK,[abcdefghijklmnopqrstuvwxyz./+-], + [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])]) + define([acl_libsinpackage_]PACKUP, + m4_ifdef([acl_libsinpackage_]PACKUP, [m4_defn([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],[m4_translit([$1],[abcdefghijklmnopqrstuvwxyz./+-], + [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])]) + pushdef([PACK],[m4_ifdef([acl_frompackage_]NAME, [acl_frompackage_]NAME, lib[$1])]) + pushdef([PACKUP],[m4_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],[m4_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/config/lib-prefix.m4 b/config/lib-prefix.m4 new file mode 100644 index 0000000..16b26fb --- /dev/null +++ b/config/lib-prefix.m4 @@ -0,0 +1,255 @@ +# lib-prefix.m4 serial 11 +dnl Copyright (C) 2001-2005, 2008-2018 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]) + AC_REQUIRE([gl_HOST_CPU_C_ABI]) + dnl Allow the user to override the result by setting acl_cv_libdirstems. + AC_CACHE_CHECK([for the common suffixes of directories in the library search path], + [acl_cv_libdirstems], + [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 <https://docs.oracle.com/cd/E19253-01/816-5138/dev-env/index.html>. + 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_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#ifdef _LP64 + int ok; + #else + error fail + #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 + ;; + *) + dnl If $CC generates code for a 32-bit ABI, the libraries are + dnl surely under $prefix/lib, not $prefix/lib64. + case "$gl_cv_host_cpu_c_abi" in + i386 | arm | armhf | arm64-ilp32 | hppa | ia64-ilp32 | mips | mipsn32 | powerpc | s390 | sparc) + ;; + *) # x86_64 | arm64 | hppa64 | ia64 | mips64 | powerpc64* | s390x | sparc64 | ... + dnl The result is a property of the system. However, non-system + dnl compilers sometimes have odd library search paths. Therefore + dnl prefer asking /usr/bin/gcc, if available, rather than $CC. + searchpath=`(if test -f /usr/bin/gcc \ + && LC_ALL=C /usr/bin/gcc -print-search-dirs >/dev/null 2>/dev/null; then \ + LC_ALL=C /usr/bin/gcc -print-search-dirs; \ + else \ + LC_ALL=C $CC -print-search-dirs; \ + fi) 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 + ;; + esac + test -n "$acl_libdirstem2" || acl_libdirstem2="$acl_libdirstem" + acl_cv_libdirstems="$acl_libdirstem,$acl_libdirstem2" + ]) + # Decompose acl_cv_libdirstems into acl_libdirstem and acl_libdirstem2. + acl_libdirstem=`echo "$acl_cv_libdirstems" | sed -e 's/,.*//'` + acl_libdirstem2=`echo "$acl_cv_libdirstems" | sed -e '/,/s/.*,//'` +]) diff --git a/config/libopts.m4 b/config/libopts.m4 new file mode 100644 index 0000000..e2bf50e --- /dev/null +++ b/config/libopts.m4 @@ -0,0 +1,448 @@ + +dnl do always before generated macros: +dnl +AC_DEFUN([INVOKE_LIBOPTS_MACROS_FIRST],[ + AC_REQUIRE([AC_HEADER_STDC]) + AC_HEADER_DIRENT + + # ================= + # AC_CHECK_HEADERS + # ================= + AC_CHECK_HEADERS([ \ + sys/mman.h sys/param.h sys/poll.h sys/procset.h \ + sys/select.h sys/socket.h sys/stropts.h sys/time.h \ + sys/un.h sys/wait.h dlfcn.h errno.h \ + fcntl.h libgen.h libintl.h memory.h \ + netinet/in.h setjmp.h stdbool.h sysexits.h \ + unistd.h utime.h]) + + AC_CHECK_HEADERS([stdarg.h varargs.h], + [lo_have_arg_hdr=true;break], + [lo_have_arg_hdr=false]) + + AC_CHECK_HEADERS([string.h strings.h], + [lo_have_str_hdr=true;break], + [lo_have_str_hdr=false]) + + AC_CHECK_HEADERS([limits.h sys/limits.h values.h], + [lo_have_lim_hdr=true;break], + [lo_have_lim_hdr=false]) + + AC_CHECK_HEADERS([inttypes.h stdint.h], + [lo_have_typ_hdr=true;break], + [lo_have_typ_hdr=false]) + gl_STDNORETURN_H + + # ---------------------------------------------------------------------- + # check for various programs used during the build. + # On OS/X, "wchar.h" needs "runetype.h" to work properly. + # ---------------------------------------------------------------------- + AC_CHECK_HEADERS([runetype.h wchar.h], [], [],[ + AC_INCLUDES_DEFAULT + #if HAVE_RUNETYPE_H + # include <runetype.h> + #endif + ]) + + AC_ARG_ENABLE([nls], + AS_HELP_STRING([--disable-nls],[disable nls support in libopts])) + AS_IF([test "x$enable_nls" != "xno" && \ + test "X${ac_cv_header_libintl_h}" = Xyes], [ + AC_DEFINE([ENABLE_NLS],[1],[nls support in libopts])]) + + # -------------------------------------------- + # Verify certain entries from AC_CHECK_HEADERS + # -------------------------------------------- + [${lo_have_arg_hdr} || \ + ]AC_MSG_ERROR([you must have stdarg.h or varargs.h on your system])[ + + ${lo_have_str_hdr} || \ + ]AC_MSG_ERROR([you must have string.h or strings.h on your system])[ + + ${lo_have_lim_hdr} || \ + ]AC_MSG_ERROR( + [you must have one of limits.h, sys/limits.h or values.h])[ + + ${lo_have_typ_hdr} || \ + ]AC_MSG_ERROR([you must have inttypes.h or stdint.h on your system])[ + + for f in sys_types sys_param sys_stat string errno stdlib memory setjmp + do eval as_ac_var=\${ac_cv_header_${f}_h} + test "X${as_ac_var}" = Xyes || { + ]AC_MSG_ERROR([you must have ${f}.h on your system])[ + } + done + test "X${ac_cv_header_inttypes_h-no}" = Xyes || \ + echo '#include <stdint.h>' > inttypes.h] + + # ---------------------------------------------------------------------- + # Checks for typedefs + # ---------------------------------------------------------------------- + AC_CHECK_TYPES(wchar_t) + AC_CHECK_TYPES(wint_t, [], [], [ + AC_INCLUDES_DEFAULT + #if HAVE_RUNETYPE_H + # include <runetype.h> + #endif + #if HAVE_WCHAR_H + # include <wchar.h> + #endif + ]) + AC_CHECK_TYPES([int8_t, uint8_t, int16_t, uint16_t, int32_t, uint32_t, + intptr_t, uintptr_t, uint_t, pid_t, size_t, ptrdiff_t]) + AC_CHECK_SIZEOF(char *, 8) + AC_CHECK_SIZEOF(int, 4) + AC_CHECK_SIZEOF(long, 8) + AC_CHECK_SIZEOF(short, 2) + + # ------------ + # AC_CHECK_LIB + # ------------ + AC_CHECK_LIB(gen, pathfind) + AC_CHECK_LIB(intl,gettext) + AC_FUNC_VPRINTF + AC_FUNC_FORK + AC_CHECK_FUNCS([mmap canonicalize_file_name snprintf strdup strchr \ + strrchr strsignal fchmod fstat chmod]) + AC_PROG_SED + [while : + do + test -x "$POSIX_SHELL" && break + POSIX_SHELL=`which bash` + test -x "$POSIX_SHELL" && break + POSIX_SHELL=`which dash` + test -x "$POSIX_SHELL" && break + POSIX_SHELL=/usr/xpg4/bin/sh + test -x "$POSIX_SHELL" && break + POSIX_SHELL=`/bin/sh -c ' + exec 2>/dev/null + if ! true ; then exit 1 ; fi + echo /bin/sh'` + test -x "$POSIX_SHELL" && break + ]AC_MSG_ERROR([cannot locate a working POSIX shell])[ + done] + AC_DEFINE_UNQUOTED([POSIX_SHELL], ["${POSIX_SHELL}"], + [define to a working POSIX compliant shell]) + AC_SUBST([POSIX_SHELL]) +]) + +dnl +dnl @synopsis INVOKE_LIBOPTS_MACROS +dnl +dnl This macro will invoke the AutoConf macros specified in libopts.def +dnl that have not been disabled with "omit-invocation". +dnl +AC_DEFUN([LIBOPTS_WITH_REGEX_HEADER],[ + AC_ARG_WITH([regex-header], + AS_HELP_STRING([--with-regex-header], [a reg expr header is specified]), + [libopts_cv_with_regex_header=${with_regex_header}], + AC_CACHE_CHECK([whether a reg expr header is specified], libopts_cv_with_regex_header, + libopts_cv_with_regex_header=no) + ) # end of AC_ARG_WITH + if test "X${libopts_cv_with_regex_header}" != Xno + then + AC_DEFINE_UNQUOTED([REGEX_HEADER],[<${libopts_cv_with_regex_header}>]) + else + AC_DEFINE([REGEX_HEADER],[<regex.h>],[name of regex header file]) + fi + +]) # end of AC_DEFUN of LIBOPTS_WITH_REGEX_HEADER + + +AC_DEFUN([LIBOPTS_WITHLIB_REGEX],[ + AC_ARG_WITH([libregex], + AS_HELP_STRING([--with-libregex], [libregex installation prefix]), + [libopts_cv_with_libregex_root=${with_libregex}], + AC_CACHE_CHECK([whether with-libregex was specified], libopts_cv_with_libregex_root, + libopts_cv_with_libregex_root=no) + ) # end of AC_ARG_WITH libregex + + if test "${with_libregex+set}" = set && \ + test "X${withval}" = Xno + then ## disabled by request + libopts_cv_with_libregex_root=no + libopts_cv_with_libregex_cflags=no + libopts_cv_with_libregex_libs=no + else + + AC_ARG_WITH([libregex-cflags], + AS_HELP_STRING([--with-libregex-cflags], [libregex compile flags]), + [libopts_cv_with_libregex_cflags=${with_libregex_cflags}], + AC_CACHE_CHECK([whether with-libregex-cflags was specified], libopts_cv_with_libregex_cflags, + libopts_cv_with_libregex_cflags=no) + ) # end of AC_ARG_WITH libregex-cflags + + AC_ARG_WITH([libregex-libs], + AS_HELP_STRING([--with-libregex-libs], [libregex link command arguments]), + [libopts_cv_with_libregex_libs=${with_libregex_libs}], + AC_CACHE_CHECK([whether with-libregex-libs was specified], libopts_cv_with_libregex_libs, + libopts_cv_with_libregex_libs=no) + ) # end of AC_ARG_WITH libregex-libs + + case "X${libopts_cv_with_libregex_cflags}" in + Xyes|Xno|X ) + case "X${libopts_cv_with_libregex_root}" in + Xyes|Xno|X ) libopts_cv_with_libregex_cflags=no ;; + * ) libopts_cv_with_libregex_cflags=-I${libopts_cv_with_libregex_root}/include ;; + esac + esac + case "X${libopts_cv_with_libregex_libs}" in + Xyes|Xno|X ) + case "X${libopts_cv_with_libregex_root}" in + Xyes|Xno|X ) libopts_cv_with_libregex_libs=no ;; + * ) libopts_cv_with_libregex_libs="-L${libopts_cv_with_libregex_root}/lib -lregex" ;; + esac + esac + libopts_save_CPPFLAGS="${CPPFLAGS}" + libopts_save_LIBS="${LIBS}" + case "X${libopts_cv_with_libregex_cflags}" in + Xyes|Xno|X ) + libopts_cv_with_libregex_cflags="" ;; + * ) CPPFLAGS="${CPPFLAGS} ${libopts_cv_with_libregex_cflags}" ;; + esac + case "X${libopts_cv_with_libregex_libs}" in + Xyes|Xno|X ) + libopts_cv_with_libregex_libs="" ;; + * ) + LIBS="${LIBS} ${libopts_cv_with_libregex_libs}" ;; + esac + LIBREGEX_CFLAGS="" + LIBREGEX_LIBS="" + AC_MSG_CHECKING([whether libregex functions properly]) + AC_CACHE_VAL([libopts_cv_with_libregex],[ + AC_RUN_IFELSE([AC_LANG_SOURCE([@%:@include <stdio.h> +@%:@include <stdlib.h> +@%:@include <sys/types.h> +@%:@include REGEX_HEADER +static regex_t re; +void comp_re(char const * pzPat) { + int res = regcomp( &re, pzPat, REG_EXTENDED|REG_ICASE|REG_NEWLINE ); + if (res == 0) return; + exit( res ); } +int main() { + regmatch_t m@<:@2@:>@; + comp_re( "^.*\@S|@" ); + comp_re( "()|no.*" ); + comp_re( "." ); + if (regexec( &re, "X", 2, m, 0 ) != 0) return 1; + if ((m@<:@0@:>@.rm_so != 0) || (m@<:@0@:>@.rm_eo != 1)) { + fputs( "error: regex -->.<-- did not match\n", stderr ); + return 1; + } + return 0; }] )], + [libopts_cv_with_libregex=yes], [libopts_cv_with_libregex=no], + [libopts_cv_with_libregex=no]) # end of AC_RUN_IFELSE + ]) # end of AC_CACHE_VAL for libopts_cv_with_libregex + fi ## disabled by request + AC_MSG_RESULT([${libopts_cv_with_libregex}]) + if test "X${libopts_cv_with_libregex}" != Xno + then + AC_DEFINE([WITH_LIBREGEX],[1], + [Define this if a working libregex can be found]) + else + CPPFLAGS="${libopts_save_CPPFLAGS}" + LIBS="${libopts_save_LIBS}" + libopts_cv_with_libregex_root=no +libopts_cv_with_libregex_cflags=no +libopts_cv_with_libregex_libs=no +libopts_cv_with_libregex=no + fi + +]) # end of AC_DEFUN of LIBOPTS_WITHLIB_REGEX + + +AC_DEFUN([LIBOPTS_RUN_PATHFIND],[ + AC_MSG_CHECKING([whether pathfind(3) works]) + AC_CACHE_VAL([libopts_cv_run_pathfind],[ + AC_RUN_IFELSE([AC_LANG_SOURCE([@%:@include <string.h> +@%:@include <stdlib.h> +int main (int argc, char ** argv) { + char * pz = pathfind( getenv( "PATH" ), "sh", "x" ); + return (pz == 0) ? 1 : 0; +}] )], + [libopts_cv_run_pathfind=yes],[libopts_cv_run_pathfind=no],[libopts_cv_run_pathfind=no] + ) # end of RUN_IFELSE + ]) # end of AC_CACHE_VAL for libopts_cv_run_pathfind + AC_MSG_RESULT([${libopts_cv_run_pathfind}]) + if test "X${libopts_cv_run_pathfind}" != Xno + then + AC_DEFINE([HAVE_PATHFIND],[1], + [Define this if pathfind(3) works]) + fi + +]) # end of AC_DEFUN of LIBOPTS_RUN_PATHFIND + + +AC_DEFUN([LIBOPTS_TEST_DEV_ZERO],[ + AC_MSG_CHECKING([whether /dev/zero is readable device]) + AC_CACHE_VAL([libopts_cv_test_dev_zero],[ + libopts_cv_test_dev_zero=`exec 2> /dev/null +dzero=\`ls -lL /dev/zero | egrep ^c......r\` +test -z "${dzero}" && exit 1 +echo ${dzero}` + if test $? -ne 0 || test -z "$libopts_cv_test_dev_zero" + then libopts_cv_test_dev_zero=no + fi + ]) # end of CACHE_VAL of libopts_cv_test_dev_zero + AC_MSG_RESULT([${libopts_cv_test_dev_zero}]) + if test "X${libopts_cv_test_dev_zero}" != Xno + then + AC_DEFINE([HAVE_DEV_ZERO],[1], + [Define this if /dev/zero is readable device]) + fi + +]) # end of AC_DEFUN of LIBOPTS_TEST_DEV_ZERO + + +AC_DEFUN([LIBOPTS_RUN_REALPATH],[ + AC_MSG_CHECKING([whether we have a functional realpath(3C)]) + AC_CACHE_VAL([libopts_cv_run_realpath],[ + AC_RUN_IFELSE([AC_LANG_SOURCE([@%:@include <limits.h> +@%:@include <stdlib.h> +int main (int argc, char ** argv) { +@%:@ifndef PATH_MAX +choke me!! +@%:@else + char zPath@<:@PATH_MAX+1@:>@; +@%:@endif + char *pz = realpath(argv@<:@0@:>@, zPath); + return (pz == zPath) ? 0 : 1; +}] )], + [libopts_cv_run_realpath=yes],[libopts_cv_run_realpath=no],[libopts_cv_run_realpath=no] + ) # end of RUN_IFELSE + ]) # end of AC_CACHE_VAL for libopts_cv_run_realpath + AC_MSG_RESULT([${libopts_cv_run_realpath}]) + if test "X${libopts_cv_run_realpath}" != Xno + then + AC_DEFINE([HAVE_REALPATH],[1], + [Define this if we have a functional realpath(3C)]) + fi + +]) # end of AC_DEFUN of LIBOPTS_RUN_REALPATH + + +AC_DEFUN([LIBOPTS_RUN_STRFTIME],[ + AC_MSG_CHECKING([whether strftime() works]) + AC_CACHE_VAL([libopts_cv_run_strftime],[ + AC_RUN_IFELSE([AC_LANG_SOURCE([@%:@include <time.h> +@%:@include <string.h> +char t_buf@<:@ 64 @:>@; +int main() { + static char const z@<:@@:>@ = "Thursday Aug 28 240"; + struct tm tm; + tm.tm_sec = 36; /* seconds after the minute @<:@0, 61@:>@ */ + tm.tm_min = 44; /* minutes after the hour @<:@0, 59@:>@ */ + tm.tm_hour = 12; /* hour since midnight @<:@0, 23@:>@ */ + tm.tm_mday = 28; /* day of the month @<:@1, 31@:>@ */ + tm.tm_mon = 7; /* months since January @<:@0, 11@:>@ */ + tm.tm_year = 86; /* years since 1900 */ + tm.tm_wday = 4; /* days since Sunday @<:@0, 6@:>@ */ + tm.tm_yday = 239; /* days since January 1 @<:@0, 365@:>@ */ + tm.tm_isdst = 1; /* flag for daylight savings time */ + strftime( t_buf, sizeof( t_buf ), "%A %b %d %j", &tm ); + return (strcmp( t_buf, z ) != 0); }] )], + [libopts_cv_run_strftime=yes],[libopts_cv_run_strftime=no],[libopts_cv_run_strftime=no] + ) # end of RUN_IFELSE + ]) # end of AC_CACHE_VAL for libopts_cv_run_strftime + AC_MSG_RESULT([${libopts_cv_run_strftime}]) + if test "X${libopts_cv_run_strftime}" != Xno + then + AC_DEFINE([HAVE_STRFTIME],[1], + [Define this if strftime() works]) + fi + +]) # end of AC_DEFUN of LIBOPTS_RUN_STRFTIME + + +AC_DEFUN([LIBOPTS_RUN_FOPEN_BINARY],[ + AC_MSG_CHECKING([whether fopen accepts "b" mode]) + AC_CACHE_VAL([libopts_cv_run_fopen_binary],[ + AC_RUN_IFELSE([AC_LANG_SOURCE([@%:@include <stdio.h> +int main (int argc, char ** argv) { +FILE * fp = fopen("conftest.@S|@ac_ext", "rb"); +return (fp == NULL) ? 1 : fclose(fp); }] )], + [libopts_cv_run_fopen_binary=yes],[libopts_cv_run_fopen_binary=no],[libopts_cv_run_fopen_binary=no] + ) # end of RUN_IFELSE + ]) # end of AC_CACHE_VAL for libopts_cv_run_fopen_binary + AC_MSG_RESULT([${libopts_cv_run_fopen_binary}]) + if test "X${libopts_cv_run_fopen_binary}" != Xno + then + AC_DEFINE([FOPEN_BINARY_FLAG],"b", + [fopen(3) accepts a 'b' in the mode flag]) + else + AC_DEFINE([FOPEN_BINARY_FLAG],"", + [fopen(3) accepts a 'b' in the mode flag]) + fi + +]) # end of AC_DEFUN of LIBOPTS_RUN_FOPEN_BINARY + + +AC_DEFUN([LIBOPTS_RUN_FOPEN_TEXT],[ + AC_MSG_CHECKING([whether fopen accepts "t" mode]) + AC_CACHE_VAL([libopts_cv_run_fopen_text],[ + AC_RUN_IFELSE([AC_LANG_SOURCE([@%:@include <stdio.h> +int main (int argc, char ** argv) { +FILE * fp = fopen("conftest.@S|@ac_ext", "rt"); +return (fp == NULL) ? 1 : fclose(fp); }] )], + [libopts_cv_run_fopen_text=yes],[libopts_cv_run_fopen_text=no],[libopts_cv_run_fopen_text=no] + ) # end of RUN_IFELSE + ]) # end of AC_CACHE_VAL for libopts_cv_run_fopen_text + AC_MSG_RESULT([${libopts_cv_run_fopen_text}]) + if test "X${libopts_cv_run_fopen_text}" != Xno + then + AC_DEFINE([FOPEN_TEXT_FLAG],"t", + [fopen(3) accepts a 't' in the mode flag]) + else + AC_DEFINE([FOPEN_TEXT_FLAG],"", + [fopen(3) accepts a 't' in the mode flag]) + fi + +]) # end of AC_DEFUN of LIBOPTS_RUN_FOPEN_TEXT + + +AC_DEFUN([LIBOPTS_DISABLE_OPTIONAL_ARGS],[ + AC_ARG_ENABLE([optional-args], + AS_HELP_STRING([--disable-optional-args], [not wanting optional option args]), + [libopts_cv_enable_optional_args=${enable_optional_args}], + AC_CACHE_CHECK([whether not wanting optional option args], libopts_cv_enable_optional_args, + libopts_cv_enable_optional_args=yes) + ) # end of AC_ARG_ENABLE + if test "X${libopts_cv_enable_optional_args}" = Xno + then + AC_DEFINE([NO_OPTIONAL_OPT_ARGS], [1], + [Define this if optional arguments are disallowed]) + fi + +]) # end of AC_DEFUN of LIBOPTS_DISABLE_OPTIONAL_ARGS + + +AC_DEFUN([INVOKE_LIBOPTS_MACROS],[ + AC_REQUIRE([INVOKE_LIBOPTS_MACROS_FIRST]) + # Check to see if a reg expr header is specified. + LIBOPTS_WITH_REGEX_HEADER + + # Check to see if a working libregex can be found. + LIBOPTS_WITHLIB_REGEX + + # Check to see if pathfind(3) works. + LIBOPTS_RUN_PATHFIND + + # Check to see if /dev/zero is readable device. + LIBOPTS_TEST_DEV_ZERO + + # Check to see if we have a functional realpath(3C). + LIBOPTS_RUN_REALPATH + + # Check to see if strftime() works. + LIBOPTS_RUN_STRFTIME + + # Check to see if fopen accepts "b" mode. + LIBOPTS_RUN_FOPEN_BINARY + + # Check to see if fopen accepts "t" mode. + LIBOPTS_RUN_FOPEN_TEXT + + # Check to see if not wanting optional option args. + LIBOPTS_DISABLE_OPTIONAL_ARGS + +]) # end AC_DEFUN of INVOKE_LIBOPTS_MACROS diff --git a/config/liboptschk.m4 b/config/liboptschk.m4 new file mode 100644 index 0000000..9d107d6 --- /dev/null +++ b/config/liboptschk.m4 @@ -0,0 +1,27 @@ +# liboptschk.m4 serial 2 (autogen - 5.11.4) +dnl Copyright (C) 2005-2018 by Bruce Korb - all rights reserved +dnl +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 +AC_DEFUN([ag_FIND_LIBOPTS], + [if test "X${ac_cv_header_autoopts_options_h}" = Xno + then : + else + f=`autoopts-config cflags` 2>/dev/null + if test X"${f}" = X + then + : + else + AC_DEFINE([HAVE_LIBOPTS],[1],[define if we can find libopts]) + CFLAGS="${CFLAGS} ${f}" + ao_CFLAGS="${f}" + AC_SUBST(ao_CFLAGS) + + f=`autoopts-config ldflags` 2>/dev/null + LIBS="${LIBS} ${f}" + ao_LIBS="${f}" + AC_SUBST(ao_LIBS) + fi + fi]) diff --git a/config/libtool.m4 b/config/libtool.m4 new file mode 100644 index 0000000..a3bc337 --- /dev/null +++ b/config/libtool.m4 @@ -0,0 +1,8369 @@ +# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- +# +# Copyright (C) 1996-2001, 2003-2015 Free Software Foundation, Inc. +# Written by Gordon Matzigkeit, 1996 +# +# 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. + +m4_define([_LT_COPYING], [dnl +# Copyright (C) 2014 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# GNU Libtool is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of of the License, or +# (at your option) any later version. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program or library that is built +# using GNU Libtool, you may include this file under the same +# distribution terms that you use for the rest of that program. +# +# GNU Libtool is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +]) + +# serial 58 LT_INIT + + +# LT_PREREQ(VERSION) +# ------------------ +# Complain and exit if this libtool version is less that VERSION. +m4_defun([LT_PREREQ], +[m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1, + [m4_default([$3], + [m4_fatal([Libtool version $1 or higher is required], + 63)])], + [$2])]) + + +# _LT_CHECK_BUILDDIR +# ------------------ +# Complain if the absolute build directory name contains unusual characters +m4_defun([_LT_CHECK_BUILDDIR], +[case `pwd` in + *\ * | *\ *) + AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;; +esac +]) + + +# LT_INIT([OPTIONS]) +# ------------------ +AC_DEFUN([LT_INIT], +[AC_PREREQ([2.62])dnl We use AC_PATH_PROGS_FEATURE_CHECK +AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl +AC_BEFORE([$0], [LT_LANG])dnl +AC_BEFORE([$0], [LT_OUTPUT])dnl +AC_BEFORE([$0], [LTDL_INIT])dnl +m4_require([_LT_CHECK_BUILDDIR])dnl + +dnl Autoconf doesn't catch unexpanded LT_ macros by default: +m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl +m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl +dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4 +dnl unless we require an AC_DEFUNed macro: +AC_REQUIRE([LTOPTIONS_VERSION])dnl +AC_REQUIRE([LTSUGAR_VERSION])dnl +AC_REQUIRE([LTVERSION_VERSION])dnl +AC_REQUIRE([LTOBSOLETE_VERSION])dnl +m4_require([_LT_PROG_LTMAIN])dnl + +_LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}]) + +dnl Parse OPTIONS +_LT_SET_OPTIONS([$0], [$1]) + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS=$ltmain + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' +AC_SUBST(LIBTOOL)dnl + +_LT_SETUP + +# Only expand once: +m4_define([LT_INIT]) +])# LT_INIT + +# Old names: +AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT]) +AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_PROG_LIBTOOL], []) +dnl AC_DEFUN([AM_PROG_LIBTOOL], []) + + +# _LT_PREPARE_CC_BASENAME +# ----------------------- +m4_defun([_LT_PREPARE_CC_BASENAME], [ +# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. +func_cc_basename () +{ + for cc_temp in @S|@*""; do + case $cc_temp in + compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; + distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; + \-*) ;; + *) break;; + esac + done + func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` +} +])# _LT_PREPARE_CC_BASENAME + + +# _LT_CC_BASENAME(CC) +# ------------------- +# It would be clearer to call AC_REQUIREs from _LT_PREPARE_CC_BASENAME, +# but that macro is also expanded into generated libtool script, which +# arranges for $SED and $ECHO to be set by different means. +m4_defun([_LT_CC_BASENAME], +[m4_require([_LT_PREPARE_CC_BASENAME])dnl +AC_REQUIRE([_LT_DECL_SED])dnl +AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl +func_cc_basename $1 +cc_basename=$func_cc_basename_result +]) + + +# _LT_FILEUTILS_DEFAULTS +# ---------------------- +# It is okay to use these file commands and assume they have been set +# sensibly after 'm4_require([_LT_FILEUTILS_DEFAULTS])'. +m4_defun([_LT_FILEUTILS_DEFAULTS], +[: ${CP="cp -f"} +: ${MV="mv -f"} +: ${RM="rm -f"} +])# _LT_FILEUTILS_DEFAULTS + + +# _LT_SETUP +# --------- +m4_defun([_LT_SETUP], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl +AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl + +_LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl +dnl +_LT_DECL([], [host_alias], [0], [The host system])dnl +_LT_DECL([], [host], [0])dnl +_LT_DECL([], [host_os], [0])dnl +dnl +_LT_DECL([], [build_alias], [0], [The build system])dnl +_LT_DECL([], [build], [0])dnl +_LT_DECL([], [build_os], [0])dnl +dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([LT_PATH_LD])dnl +AC_REQUIRE([LT_PATH_NM])dnl +dnl +AC_REQUIRE([AC_PROG_LN_S])dnl +test -z "$LN_S" && LN_S="ln -s" +_LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl +dnl +AC_REQUIRE([LT_CMD_MAX_LEN])dnl +_LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl +_LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl +dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_CHECK_SHELL_FEATURES])dnl +m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl +m4_require([_LT_CMD_RELOAD])dnl +m4_require([_LT_CHECK_MAGIC_METHOD])dnl +m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl +m4_require([_LT_CMD_OLD_ARCHIVE])dnl +m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl +m4_require([_LT_WITH_SYSROOT])dnl +m4_require([_LT_CMD_TRUNCATE])dnl + +_LT_CONFIG_LIBTOOL_INIT([ +# See if we are running on zsh, and set the options that allow our +# commands through without removal of \ escapes INIT. +if test -n "\${ZSH_VERSION+set}"; then + setopt NO_GLOB_SUBST +fi +]) +if test -n "${ZSH_VERSION+set}"; then + setopt NO_GLOB_SUBST +fi + +_LT_CHECK_OBJDIR + +m4_require([_LT_TAG_COMPILER])dnl + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test set != "${COLLECT_NAMES+set}"; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Global variables: +ofile=libtool +can_build_shared=yes + +# All known linkers require a '.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a + +with_gnu_ld=$lt_cv_prog_gnu_ld + +old_CC=$CC +old_CFLAGS=$CFLAGS + +# Set sane defaults for various variables +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS +test -z "$LD" && LD=ld +test -z "$ac_objext" && ac_objext=o + +_LT_CC_BASENAME([$compiler]) + +# Only perform the check for file, if the check method requires it +test -z "$MAGIC_CMD" && MAGIC_CMD=file +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + _LT_PATH_MAGIC + fi + ;; +esac + +# Use C for the default configuration in the libtool script +LT_SUPPORTED_TAG([CC]) +_LT_LANG_C_CONFIG +_LT_LANG_DEFAULT_CONFIG +_LT_CONFIG_COMMANDS +])# _LT_SETUP + + +# _LT_PREPARE_SED_QUOTE_VARS +# -------------------------- +# Define a few sed substitution that help us do robust quoting. +m4_defun([_LT_PREPARE_SED_QUOTE_VARS], +[# Backslashify metacharacters that are still active within +# double-quoted strings. +sed_quote_subst='s/\([["`$\\]]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\([["`\\]]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to delay expansion of an escaped single quote. +delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' +]) + +# _LT_PROG_LTMAIN +# --------------- +# Note that this code is called both from 'configure', and 'config.status' +# now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, +# 'config.status' has no value for ac_aux_dir unless we are using Automake, +# so we pass a copy along to make sure it has a sensible value anyway. +m4_defun([_LT_PROG_LTMAIN], +[m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl +_LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) +ltmain=$ac_aux_dir/ltmain.sh +])# _LT_PROG_LTMAIN + + +## ------------------------------------- ## +## Accumulate code for creating libtool. ## +## ------------------------------------- ## + +# So that we can recreate a full libtool script including additional +# tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS +# in macros and then make a single call at the end using the 'libtool' +# label. + + +# _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS]) +# ---------------------------------------- +# Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later. +m4_define([_LT_CONFIG_LIBTOOL_INIT], +[m4_ifval([$1], + [m4_append([_LT_OUTPUT_LIBTOOL_INIT], + [$1 +])])]) + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_INIT]) + + +# _LT_CONFIG_LIBTOOL([COMMANDS]) +# ------------------------------ +# Register COMMANDS to be passed to AC_CONFIG_COMMANDS later. +m4_define([_LT_CONFIG_LIBTOOL], +[m4_ifval([$1], + [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS], + [$1 +])])]) + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS]) + + +# _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS]) +# ----------------------------------------------------- +m4_defun([_LT_CONFIG_SAVE_COMMANDS], +[_LT_CONFIG_LIBTOOL([$1]) +_LT_CONFIG_LIBTOOL_INIT([$2]) +]) + + +# _LT_FORMAT_COMMENT([COMMENT]) +# ----------------------------- +# Add leading comment marks to the start of each line, and a trailing +# full-stop to the whole comment if one is not present already. +m4_define([_LT_FORMAT_COMMENT], +[m4_ifval([$1], [ +m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])], + [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.]) +)]) + + + +## ------------------------ ## +## FIXME: Eliminate VARNAME ## +## ------------------------ ## + + +# _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?]) +# ------------------------------------------------------------------- +# CONFIGNAME is the name given to the value in the libtool script. +# VARNAME is the (base) name used in the configure script. +# VALUE may be 0, 1 or 2 for a computed quote escaped value based on +# VARNAME. Any other value will be used directly. +m4_define([_LT_DECL], +[lt_if_append_uniq([lt_decl_varnames], [$2], [, ], + [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name], + [m4_ifval([$1], [$1], [$2])]) + lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3]) + m4_ifval([$4], + [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])]) + lt_dict_add_subkey([lt_decl_dict], [$2], + [tagged?], [m4_ifval([$5], [yes], [no])])]) +]) + + +# _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION]) +# -------------------------------------------------------- +m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])]) + + +# lt_decl_tag_varnames([SEPARATOR], [VARNAME1...]) +# ------------------------------------------------ +m4_define([lt_decl_tag_varnames], +[_lt_decl_filter([tagged?], [yes], $@)]) + + +# _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..]) +# --------------------------------------------------------- +m4_define([_lt_decl_filter], +[m4_case([$#], + [0], [m4_fatal([$0: too few arguments: $#])], + [1], [m4_fatal([$0: too few arguments: $#: $1])], + [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)], + [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)], + [lt_dict_filter([lt_decl_dict], $@)])[]dnl +]) + + +# lt_decl_quote_varnames([SEPARATOR], [VARNAME1...]) +# -------------------------------------------------- +m4_define([lt_decl_quote_varnames], +[_lt_decl_filter([value], [1], $@)]) + + +# lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...]) +# --------------------------------------------------- +m4_define([lt_decl_dquote_varnames], +[_lt_decl_filter([value], [2], $@)]) + + +# lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) +# --------------------------------------------------- +m4_define([lt_decl_varnames_tagged], +[m4_assert([$# <= 2])dnl +_$0(m4_quote(m4_default([$1], [[, ]])), + m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]), + m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))]) +m4_define([_lt_decl_varnames_tagged], +[m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])]) + + +# lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) +# ------------------------------------------------ +m4_define([lt_decl_all_varnames], +[_$0(m4_quote(m4_default([$1], [[, ]])), + m4_if([$2], [], + m4_quote(lt_decl_varnames), + m4_quote(m4_shift($@))))[]dnl +]) +m4_define([_lt_decl_all_varnames], +[lt_join($@, lt_decl_varnames_tagged([$1], + lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl +]) + + +# _LT_CONFIG_STATUS_DECLARE([VARNAME]) +# ------------------------------------ +# Quote a variable value, and forward it to 'config.status' so that its +# declaration there will have the same value as in 'configure'. VARNAME +# must have a single quote delimited value for this to work. +m4_define([_LT_CONFIG_STATUS_DECLARE], +[$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`']) + + +# _LT_CONFIG_STATUS_DECLARATIONS +# ------------------------------ +# We delimit libtool config variables with single quotes, so when +# we write them to config.status, we have to be sure to quote all +# embedded single quotes properly. In configure, this macro expands +# each variable declared with _LT_DECL (and _LT_TAGDECL) into: +# +# <var>='`$ECHO "$<var>" | $SED "$delay_single_quote_subst"`' +m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], +[m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames), + [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])]) + + +# _LT_LIBTOOL_TAGS +# ---------------- +# Output comment and list of tags supported by the script +m4_defun([_LT_LIBTOOL_TAGS], +[_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl +available_tags='_LT_TAGS'dnl +]) + + +# _LT_LIBTOOL_DECLARE(VARNAME, [TAG]) +# ----------------------------------- +# Extract the dictionary values for VARNAME (optionally with TAG) and +# expand to a commented shell variable setting: +# +# # Some comment about what VAR is for. +# visible_name=$lt_internal_name +m4_define([_LT_LIBTOOL_DECLARE], +[_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], + [description])))[]dnl +m4_pushdef([_libtool_name], + m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl +m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])), + [0], [_libtool_name=[$]$1], + [1], [_libtool_name=$lt_[]$1], + [2], [_libtool_name=$lt_[]$1], + [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl +m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl +]) + + +# _LT_LIBTOOL_CONFIG_VARS +# ----------------------- +# Produce commented declarations of non-tagged libtool config variables +# suitable for insertion in the LIBTOOL CONFIG section of the 'libtool' +# script. Tagged libtool config variables (even for the LIBTOOL CONFIG +# section) are produced by _LT_LIBTOOL_TAG_VARS. +m4_defun([_LT_LIBTOOL_CONFIG_VARS], +[m4_foreach([_lt_var], + m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)), + [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])]) + + +# _LT_LIBTOOL_TAG_VARS(TAG) +# ------------------------- +m4_define([_LT_LIBTOOL_TAG_VARS], +[m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames), + [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])]) + + +# _LT_TAGVAR(VARNAME, [TAGNAME]) +# ------------------------------ +m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) + + +# _LT_CONFIG_COMMANDS +# ------------------- +# Send accumulated output to $CONFIG_STATUS. Thanks to the lists of +# variables for single and double quote escaping we saved from calls +# to _LT_DECL, we can put quote escaped variables declarations +# into 'config.status', and then the shell code to quote escape them in +# for loops in 'config.status'. Finally, any additional code accumulated +# from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. +m4_defun([_LT_CONFIG_COMMANDS], +[AC_PROVIDE_IFELSE([LT_OUTPUT], + dnl If the libtool generation code has been placed in $CONFIG_LT, + dnl instead of duplicating it all over again into config.status, + dnl then we will have config.status run $CONFIG_LT later, so it + dnl needs to know what name is stored there: + [AC_CONFIG_COMMANDS([libtool], + [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])], + dnl If the libtool generation code is destined for config.status, + dnl expand the accumulated commands and init code now: + [AC_CONFIG_COMMANDS([libtool], + [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])]) +])#_LT_CONFIG_COMMANDS + + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT], +[ + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +sed_quote_subst='$sed_quote_subst' +double_quote_subst='$double_quote_subst' +delay_variable_subst='$delay_variable_subst' +_LT_CONFIG_STATUS_DECLARATIONS +LTCC='$LTCC' +LTCFLAGS='$LTCFLAGS' +compiler='$compiler_DEFAULT' + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$[]1 +_LTECHO_EOF' +} + +# Quote evaled strings. +for var in lt_decl_all_varnames([[ \ +]], lt_decl_quote_varnames); do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[[\\\\\\\`\\"\\\$]]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +# Double-quote double-evaled strings. +for var in lt_decl_all_varnames([[ \ +]], lt_decl_dquote_varnames); do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[[\\\\\\\`\\"\\\$]]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +_LT_OUTPUT_LIBTOOL_INIT +]) + +# _LT_GENERATED_FILE_INIT(FILE, [COMMENT]) +# ------------------------------------ +# Generate a child script FILE with all initialization necessary to +# reuse the environment learned by the parent script, and make the +# file executable. If COMMENT is supplied, it is inserted after the +# '#!' sequence but before initialization text begins. After this +# macro, additional text can be appended to FILE to form the body of +# the child script. The macro ends with non-zero status if the +# file could not be fully written (such as if the disk is full). +m4_ifdef([AS_INIT_GENERATED], +[m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])], +[m4_defun([_LT_GENERATED_FILE_INIT], +[m4_require([AS_PREPARE])]dnl +[m4_pushdef([AS_MESSAGE_LOG_FD])]dnl +[lt_write_fail=0 +cat >$1 <<_ASEOF || lt_write_fail=1 +#! $SHELL +# Generated by $as_me. +$2 +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$1 <<\_ASEOF || lt_write_fail=1 +AS_SHELL_SANITIZE +_AS_PREPARE +exec AS_MESSAGE_FD>&1 +_ASEOF +test 0 = "$lt_write_fail" && chmod +x $1[]dnl +m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT + +# LT_OUTPUT +# --------- +# This macro allows early generation of the libtool script (before +# AC_OUTPUT is called), incase it is used in configure for compilation +# tests. +AC_DEFUN([LT_OUTPUT], +[: ${CONFIG_LT=./config.lt} +AC_MSG_NOTICE([creating $CONFIG_LT]) +_LT_GENERATED_FILE_INIT(["$CONFIG_LT"], +[# Run this file to recreate a libtool stub with the current configuration.]) + +cat >>"$CONFIG_LT" <<\_LTEOF +lt_cl_silent=false +exec AS_MESSAGE_LOG_FD>>config.log +{ + echo + AS_BOX([Running $as_me.]) +} >&AS_MESSAGE_LOG_FD + +lt_cl_help="\ +'$as_me' creates a local libtool stub from the current configuration, +for use in further configure time tests before the real libtool is +generated. + +Usage: $[0] [[OPTIONS]] + + -h, --help print this help, then exit + -V, --version print version number, then exit + -q, --quiet do not print progress messages + -d, --debug don't remove temporary files + +Report bugs to <bug-libtool@gnu.org>." + +lt_cl_version="\ +m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl +m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) +configured by $[0], generated by m4_PACKAGE_STRING. + +Copyright (C) 2011 Free Software Foundation, Inc. +This config.lt script is free software; the Free Software Foundation +gives unlimited permision to copy, distribute and modify it." + +while test 0 != $[#] +do + case $[1] in + --version | --v* | -V ) + echo "$lt_cl_version"; exit 0 ;; + --help | --h* | -h ) + echo "$lt_cl_help"; exit 0 ;; + --debug | --d* | -d ) + debug=: ;; + --quiet | --q* | --silent | --s* | -q ) + lt_cl_silent=: ;; + + -*) AC_MSG_ERROR([unrecognized option: $[1] +Try '$[0] --help' for more information.]) ;; + + *) AC_MSG_ERROR([unrecognized argument: $[1] +Try '$[0] --help' for more information.]) ;; + esac + shift +done + +if $lt_cl_silent; then + exec AS_MESSAGE_FD>/dev/null +fi +_LTEOF + +cat >>"$CONFIG_LT" <<_LTEOF +_LT_OUTPUT_LIBTOOL_COMMANDS_INIT +_LTEOF + +cat >>"$CONFIG_LT" <<\_LTEOF +AC_MSG_NOTICE([creating $ofile]) +_LT_OUTPUT_LIBTOOL_COMMANDS +AS_EXIT(0) +_LTEOF +chmod +x "$CONFIG_LT" + +# configure is writing to config.log, but config.lt does its own redirection, +# appending to config.log, which fails on DOS, as config.log is still kept +# open by configure. Here we exec the FD to /dev/null, effectively closing +# config.log, so it can be properly (re)opened and appended to by config.lt. +lt_cl_success=: +test yes = "$silent" && + lt_config_lt_args="$lt_config_lt_args --quiet" +exec AS_MESSAGE_LOG_FD>/dev/null +$SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false +exec AS_MESSAGE_LOG_FD>>config.log +$lt_cl_success || AS_EXIT(1) +])# LT_OUTPUT + + +# _LT_CONFIG(TAG) +# --------------- +# If TAG is the built-in tag, create an initial libtool script with a +# default configuration from the untagged config vars. Otherwise add code +# to config.status for appending the configuration named by TAG from the +# matching tagged config vars. +m4_defun([_LT_CONFIG], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +_LT_CONFIG_SAVE_COMMANDS([ + m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl + m4_if(_LT_TAG, [C], [ + # See if we are running on zsh, and set the options that allow our + # commands through without removal of \ escapes. + if test -n "${ZSH_VERSION+set}"; then + setopt NO_GLOB_SUBST + fi + + cfgfile=${ofile}T + trap "$RM \"$cfgfile\"; exit 1" 1 2 15 + $RM "$cfgfile" + + cat <<_LT_EOF >> "$cfgfile" +#! $SHELL +# Generated automatically by $as_me ($PACKAGE) $VERSION +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# NOTE: Changes made to this file will be lost: look at ltmain.sh. + +# Provide generalized library-building support services. +# Written by Gordon Matzigkeit, 1996 + +_LT_COPYING +_LT_LIBTOOL_TAGS + +# Configured defaults for sys_lib_dlsearch_path munging. +: \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"} + +# ### BEGIN LIBTOOL CONFIG +_LT_LIBTOOL_CONFIG_VARS +_LT_LIBTOOL_TAG_VARS +# ### END LIBTOOL CONFIG + +_LT_EOF + + cat <<'_LT_EOF' >> "$cfgfile" + +# ### BEGIN FUNCTIONS SHARED WITH CONFIGURE + +_LT_PREPARE_MUNGE_PATH_LIST +_LT_PREPARE_CC_BASENAME + +# ### END FUNCTIONS SHARED WITH CONFIGURE + +_LT_EOF + + case $host_os in + aix3*) + cat <<\_LT_EOF >> "$cfgfile" +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test set != "${COLLECT_NAMES+set}"; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +_LT_EOF + ;; + esac + + _LT_PROG_LTMAIN + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '$q' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + mv -f "$cfgfile" "$ofile" || + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" +], +[cat <<_LT_EOF >> "$ofile" + +dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded +dnl in a comment (ie after a #). +# ### BEGIN LIBTOOL TAG CONFIG: $1 +_LT_LIBTOOL_TAG_VARS(_LT_TAG) +# ### END LIBTOOL TAG CONFIG: $1 +_LT_EOF +])dnl /m4_if +], +[m4_if([$1], [], [ + PACKAGE='$PACKAGE' + VERSION='$VERSION' + RM='$RM' + ofile='$ofile'], []) +])dnl /_LT_CONFIG_SAVE_COMMANDS +])# _LT_CONFIG + + +# LT_SUPPORTED_TAG(TAG) +# --------------------- +# Trace this macro to discover what tags are supported by the libtool +# --tag option, using: +# autoconf --trace 'LT_SUPPORTED_TAG:$1' +AC_DEFUN([LT_SUPPORTED_TAG], []) + + +# C support is built-in for now +m4_define([_LT_LANG_C_enabled], []) +m4_define([_LT_TAGS], []) + + +# LT_LANG(LANG) +# ------------- +# Enable libtool support for the given language if not already enabled. +AC_DEFUN([LT_LANG], +[AC_BEFORE([$0], [LT_OUTPUT])dnl +m4_case([$1], + [C], [_LT_LANG(C)], + [C++], [_LT_LANG(CXX)], + [Go], [_LT_LANG(GO)], + [Java], [_LT_LANG(GCJ)], + [Fortran 77], [_LT_LANG(F77)], + [Fortran], [_LT_LANG(FC)], + [Windows Resource], [_LT_LANG(RC)], + [m4_ifdef([_LT_LANG_]$1[_CONFIG], + [_LT_LANG($1)], + [m4_fatal([$0: unsupported language: "$1"])])])dnl +])# LT_LANG + + +# _LT_LANG(LANGNAME) +# ------------------ +m4_defun([_LT_LANG], +[m4_ifdef([_LT_LANG_]$1[_enabled], [], + [LT_SUPPORTED_TAG([$1])dnl + m4_append([_LT_TAGS], [$1 ])dnl + m4_define([_LT_LANG_]$1[_enabled], [])dnl + _LT_LANG_$1_CONFIG($1)])dnl +])# _LT_LANG + + +m4_ifndef([AC_PROG_GO], [ +############################################################ +# NOTE: This macro has been submitted for inclusion into # +# GNU Autoconf as AC_PROG_GO. When it is available in # +# a released version of Autoconf we should remove this # +# macro and use it instead. # +############################################################ +m4_defun([AC_PROG_GO], +[AC_LANG_PUSH(Go)dnl +AC_ARG_VAR([GOC], [Go compiler command])dnl +AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl +_AC_ARG_VAR_LDFLAGS()dnl +AC_CHECK_TOOL(GOC, gccgo) +if test -z "$GOC"; then + if test -n "$ac_tool_prefix"; then + AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo]) + fi +fi +if test -z "$GOC"; then + AC_CHECK_PROG(GOC, gccgo, gccgo, false) +fi +])#m4_defun +])#m4_ifndef + + +# _LT_LANG_DEFAULT_CONFIG +# ----------------------- +m4_defun([_LT_LANG_DEFAULT_CONFIG], +[AC_PROVIDE_IFELSE([AC_PROG_CXX], + [LT_LANG(CXX)], + [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])]) + +AC_PROVIDE_IFELSE([AC_PROG_F77], + [LT_LANG(F77)], + [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])]) + +AC_PROVIDE_IFELSE([AC_PROG_FC], + [LT_LANG(FC)], + [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])]) + +dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal +dnl pulling things in needlessly. +AC_PROVIDE_IFELSE([AC_PROG_GCJ], + [LT_LANG(GCJ)], + [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], + [LT_LANG(GCJ)], + [AC_PROVIDE_IFELSE([LT_PROG_GCJ], + [LT_LANG(GCJ)], + [m4_ifdef([AC_PROG_GCJ], + [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])]) + m4_ifdef([A][M_PROG_GCJ], + [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])]) + m4_ifdef([LT_PROG_GCJ], + [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) + +AC_PROVIDE_IFELSE([AC_PROG_GO], + [LT_LANG(GO)], + [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])]) + +AC_PROVIDE_IFELSE([LT_PROG_RC], + [LT_LANG(RC)], + [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) +])# _LT_LANG_DEFAULT_CONFIG + +# Obsolete macros: +AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) +AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) +AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) +AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) +AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_CXX], []) +dnl AC_DEFUN([AC_LIBTOOL_F77], []) +dnl AC_DEFUN([AC_LIBTOOL_FC], []) +dnl AC_DEFUN([AC_LIBTOOL_GCJ], []) +dnl AC_DEFUN([AC_LIBTOOL_RC], []) + + +# _LT_TAG_COMPILER +# ---------------- +m4_defun([_LT_TAG_COMPILER], +[AC_REQUIRE([AC_PROG_CC])dnl + +_LT_DECL([LTCC], [CC], [1], [A C compiler])dnl +_LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl +_LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl +_LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC +])# _LT_TAG_COMPILER + + +# _LT_COMPILER_BOILERPLATE +# ------------------------ +# Check for compiler boilerplate output or warnings with +# the simple compiler test code. +m4_defun([_LT_COMPILER_BOILERPLATE], +[m4_require([_LT_DECL_SED])dnl +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* +])# _LT_COMPILER_BOILERPLATE + + +# _LT_LINKER_BOILERPLATE +# ---------------------- +# Check for linker boilerplate output or warnings with +# the simple link test code. +m4_defun([_LT_LINKER_BOILERPLATE], +[m4_require([_LT_DECL_SED])dnl +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* +])# _LT_LINKER_BOILERPLATE + +# _LT_REQUIRED_DARWIN_CHECKS +# ------------------------- +m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ + case $host_os in + rhapsody* | darwin*) + AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) + AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) + AC_CHECK_TOOL([LIPO], [lipo], [:]) + AC_CHECK_TOOL([OTOOL], [otool], [:]) + AC_CHECK_TOOL([OTOOL64], [otool64], [:]) + _LT_DECL([], [DSYMUTIL], [1], + [Tool to manipulate archived DWARF debug symbol files on Mac OS X]) + _LT_DECL([], [NMEDIT], [1], + [Tool to change global to local symbols on Mac OS X]) + _LT_DECL([], [LIPO], [1], + [Tool to manipulate fat objects and archives on Mac OS X]) + _LT_DECL([], [OTOOL], [1], + [ldd/readelf like tool for Mach-O binaries on Mac OS X]) + _LT_DECL([], [OTOOL64], [1], + [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4]) + + AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], + [lt_cv_apple_cc_single_mod=no + if test -z "$LT_MULTI_MODULE"; then + # By default we will add the -single_module flag. You can override + # by either setting the environment variable LT_MULTI_MODULE + # non-empty at configure time, or by adding -multi_module to the + # link flags. + rm -rf libconftest.dylib* + echo "int foo(void){return 1;}" > conftest.c + echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ +-dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ + -dynamiclib -Wl,-single_module conftest.c 2>conftest.err + _lt_result=$? + # If there is a non-empty error log, and "single_module" + # appears in it, assume the flag caused a linker warning + if test -s conftest.err && $GREP single_module conftest.err; then + cat conftest.err >&AS_MESSAGE_LOG_FD + # Otherwise, if the output was created with a 0 exit code from + # the compiler, it worked. + elif test -f libconftest.dylib && test 0 = "$_lt_result"; then + lt_cv_apple_cc_single_mod=yes + else + cat conftest.err >&AS_MESSAGE_LOG_FD + fi + rm -rf libconftest.dylib* + rm -f conftest.* + fi]) + + AC_CACHE_CHECK([for -exported_symbols_list linker flag], + [lt_cv_ld_exported_symbols_list], + [lt_cv_ld_exported_symbols_list=no + save_LDFLAGS=$LDFLAGS + echo "_main" > conftest.sym + LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" + AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], + [lt_cv_ld_exported_symbols_list=yes], + [lt_cv_ld_exported_symbols_list=no]) + LDFLAGS=$save_LDFLAGS + ]) + + AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load], + [lt_cv_ld_force_load=no + cat > conftest.c << _LT_EOF +int forced_loaded() { return 2;} +_LT_EOF + echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD + echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD + $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD + echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD + $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD + cat > conftest.c << _LT_EOF +int main() { return 0;} +_LT_EOF + echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err + _lt_result=$? + if test -s conftest.err && $GREP force_load conftest.err; then + cat conftest.err >&AS_MESSAGE_LOG_FD + elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then + lt_cv_ld_force_load=yes + else + cat conftest.err >&AS_MESSAGE_LOG_FD + fi + rm -f conftest.err libconftest.a conftest conftest.c + rm -rf conftest.dSYM + ]) + case $host_os in + rhapsody* | darwin1.[[012]]) + _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;; + darwin1.*) + _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; + darwin*) # darwin 5.x on + # if running on 10.5 or later, the deployment target defaults + # to the OS version, if on x86, and 10.4, the deployment + # target defaults to 10.4. Don't you love it? + case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in + 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*) + _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; + 10.[[012]][[,.]]*) + _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; + 10.*) + _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; + esac + ;; + esac + if test yes = "$lt_cv_apple_cc_single_mod"; then + _lt_dar_single_mod='$single_module' + fi + if test yes = "$lt_cv_ld_exported_symbols_list"; then + _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym' + else + _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib' + fi + if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then + _lt_dsymutil='~$DSYMUTIL $lib || :' + else + _lt_dsymutil= + fi + ;; + esac +]) + + +# _LT_DARWIN_LINKER_FEATURES([TAG]) +# --------------------------------- +# Checks for linker and compiler features on darwin +m4_defun([_LT_DARWIN_LINKER_FEATURES], +[ + m4_require([_LT_REQUIRED_DARWIN_CHECKS]) + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_automatic, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + if test yes = "$lt_cv_ld_force_load"; then + _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes], + [FC], [_LT_TAGVAR(compiler_needs_object, $1)=yes]) + else + _LT_TAGVAR(whole_archive_flag_spec, $1)='' + fi + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)=$_lt_dar_allow_undefined + case $cc_basename in + ifort*|nagfor*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test yes = "$_lt_dar_can_shared"; then + output_verbose_link_cmd=func_echo_all + _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" + _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" + _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" + _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" + m4_if([$1], [CXX], +[ if test yes != "$lt_cv_apple_cc_single_mod"; then + _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil" + _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil" + fi +],[]) + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi +]) + +# _LT_SYS_MODULE_PATH_AIX([TAGNAME]) +# ---------------------------------- +# Links a minimal program and checks the executable +# for the system default hardcoded library path. In most cases, +# this is /usr/lib:/lib, but when the MPI compilers are used +# the location of the communication and MPI libs are included too. +# If we don't find anything, use the default library path according +# to the aix ld manual. +# Store the results from the different compilers for each TAGNAME. +# Allow to override them for all tags through lt_cv_aix_libpath. +m4_defun([_LT_SYS_MODULE_PATH_AIX], +[m4_require([_LT_DECL_SED])dnl +if test set = "${lt_cv_aix_libpath+set}"; then + aix_libpath=$lt_cv_aix_libpath +else + AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])], + [AC_LINK_IFELSE([AC_LANG_PROGRAM],[ + lt_aix_libpath_sed='[ + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }]' + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi],[]) + if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=/usr/lib:/lib + fi + ]) + aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1]) +fi +])# _LT_SYS_MODULE_PATH_AIX + + +# _LT_SHELL_INIT(ARG) +# ------------------- +m4_define([_LT_SHELL_INIT], +[m4_divert_text([M4SH-INIT], [$1 +])])# _LT_SHELL_INIT + + + +# _LT_PROG_ECHO_BACKSLASH +# ----------------------- +# Find how we can fake an echo command that does not interpret backslash. +# In particular, with Autoconf 2.60 or later we add some code to the start +# of the generated configure script that will find a shell with a builtin +# printf (that we can use as an echo command). +m4_defun([_LT_PROG_ECHO_BACKSLASH], +[ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + +AC_MSG_CHECKING([how to print strings]) +# Test print first, because it will be a builtin if present. +if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ + test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='print -r --' +elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='printf %s\n' +else + # Use this function as a fallback that always works. + func_fallback_echo () + { + eval 'cat <<_LTECHO_EOF +$[]1 +_LTECHO_EOF' + } + ECHO='func_fallback_echo' +fi + +# func_echo_all arg... +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "$*" +} + +case $ECHO in + printf*) AC_MSG_RESULT([printf]) ;; + print*) AC_MSG_RESULT([print -r]) ;; + *) AC_MSG_RESULT([cat]) ;; +esac + +m4_ifdef([_AS_DETECT_SUGGESTED], +[_AS_DETECT_SUGGESTED([ + test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || ( + ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' + ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO + ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + PATH=/empty FPATH=/empty; export PATH FPATH + test "X`printf %s $ECHO`" = "X$ECHO" \ + || test "X`print -r -- $ECHO`" = "X$ECHO" )])]) + +_LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) +_LT_DECL([], [ECHO], [1], [An echo program that protects backslashes]) +])# _LT_PROG_ECHO_BACKSLASH + + +# _LT_WITH_SYSROOT +# ---------------- +AC_DEFUN([_LT_WITH_SYSROOT], +[AC_MSG_CHECKING([for sysroot]) +AC_ARG_WITH([sysroot], +[AS_HELP_STRING([--with-sysroot@<:@=DIR@:>@], + [Search for dependent libraries within DIR (or the compiler's sysroot + if not specified).])], +[], [with_sysroot=no]) + +dnl lt_sysroot will always be passed unquoted. We quote it here +dnl in case the user passed a directory name. +lt_sysroot= +case $with_sysroot in #( + yes) + if test yes = "$GCC"; then + lt_sysroot=`$CC --print-sysroot 2>/dev/null` + fi + ;; #( + /*) + lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` + ;; #( + no|'') + ;; #( + *) + AC_MSG_RESULT([$with_sysroot]) + AC_MSG_ERROR([The sysroot must be an absolute path.]) + ;; +esac + + AC_MSG_RESULT([${lt_sysroot:-no}]) +_LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl +[dependent libraries, and where our libraries should be installed.])]) + +# _LT_ENABLE_LOCK +# --------------- +m4_defun([_LT_ENABLE_LOCK], +[AC_ARG_ENABLE([libtool-lock], + [AS_HELP_STRING([--disable-libtool-lock], + [avoid locking (might break parallel builds)])]) +test no = "$enable_libtool_lock" || enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out what ABI is being produced by ac_compile, and set mode + # options accordingly. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE=32 + ;; + *ELF-64*) + HPUX_IA64_MODE=64 + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + if test yes = "$lt_cv_prog_gnu_ld"; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +mips64*-*linux*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + emul=elf + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + emul="${emul}32" + ;; + *64-bit*) + emul="${emul}64" + ;; + esac + case `/usr/bin/file conftest.$ac_objext` in + *MSB*) + emul="${emul}btsmip" + ;; + *LSB*) + emul="${emul}ltsmip" + ;; + esac + case `/usr/bin/file conftest.$ac_objext` in + *N32*) + emul="${emul}n32" + ;; + esac + LD="${LD-ld} -m $emul" + fi + rm -rf conftest* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ +s390*-*linux*|s390*-*tpf*|sparc*-*linux*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. Note that the listed cases only cover the + # situations where additional linker options are needed (such as when + # doing 32-bit compilation for a host where ld defaults to 64-bit, or + # vice versa); the common cases where no linker options are needed do + # not appear in the list. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.o` in + *32-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_i386_fbsd" + ;; + x86_64-*linux*) + case `/usr/bin/file conftest.o` in + *x86-64*) + LD="${LD-ld} -m elf32_x86_64" + ;; + *) + LD="${LD-ld} -m elf_i386" + ;; + esac + ;; + powerpc64le-*linux*) + LD="${LD-ld} -m elf32lppclinux" + ;; + powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_x86_64_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + powerpcle-*linux*) + LD="${LD-ld} -m elf64lppc" + ;; + powerpc-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*|s390*-*tpf*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS=$CFLAGS + CFLAGS="$CFLAGS -belf" + AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, + [AC_LANG_PUSH(C) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) + AC_LANG_POP]) + if test yes != "$lt_cv_cc_needs_belf"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS=$SAVE_CFLAGS + fi + ;; +*-*solaris*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) + case $host in + i?86-*-solaris*|x86_64-*-solaris*) + LD="${LD-ld} -m elf_x86_64" + ;; + sparc*-*-solaris*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + # GNU ld 2.21 introduced _sol2 emulations. Use them if available. + if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then + LD=${LD-ld}_sol2 + fi + ;; + *) + if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then + LD="${LD-ld} -64" + fi + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; +esac + +need_locks=$enable_libtool_lock +])# _LT_ENABLE_LOCK + + +# _LT_PROG_AR +# ----------- +m4_defun([_LT_PROG_AR], +[AC_CHECK_TOOLS(AR, [ar], false) +: ${AR=ar} +: ${AR_FLAGS=cru} +_LT_DECL([], [AR], [1], [The archiver]) +_LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive]) + +AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file], + [lt_cv_ar_at_file=no + AC_COMPILE_IFELSE([AC_LANG_PROGRAM], + [echo conftest.$ac_objext > conftest.lst + lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD' + AC_TRY_EVAL([lt_ar_try]) + if test 0 -eq "$ac_status"; then + # Ensure the archiver fails upon bogus file names. + rm -f conftest.$ac_objext libconftest.a + AC_TRY_EVAL([lt_ar_try]) + if test 0 -ne "$ac_status"; then + lt_cv_ar_at_file=@ + fi + fi + rm -f conftest.* libconftest.a + ]) + ]) + +if test no = "$lt_cv_ar_at_file"; then + archiver_list_spec= +else + archiver_list_spec=$lt_cv_ar_at_file +fi +_LT_DECL([], [archiver_list_spec], [1], + [How to feed a file listing to the archiver]) +])# _LT_PROG_AR + + +# _LT_CMD_OLD_ARCHIVE +# ------------------- +m4_defun([_LT_CMD_OLD_ARCHIVE], +[_LT_PROG_AR + +AC_CHECK_TOOL(STRIP, strip, :) +test -z "$STRIP" && STRIP=: +_LT_DECL([], [STRIP], [1], [A symbol stripping program]) + +AC_CHECK_TOOL(RANLIB, ranlib, :) +test -z "$RANLIB" && RANLIB=: +_LT_DECL([], [RANLIB], [1], + [Commands used to install an old-style archive]) + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + bitrig* | openbsd*) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" + ;; + *) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" +fi + +case $host_os in + darwin*) + lock_old_archive_extraction=yes ;; + *) + lock_old_archive_extraction=no ;; +esac +_LT_DECL([], [old_postinstall_cmds], [2]) +_LT_DECL([], [old_postuninstall_cmds], [2]) +_LT_TAGDECL([], [old_archive_cmds], [2], + [Commands used to build an old-style archive]) +_LT_DECL([], [lock_old_archive_extraction], [0], + [Whether to use a lock for old archive extraction]) +])# _LT_CMD_OLD_ARCHIVE + + +# _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) +# ---------------------------------------------------------------- +# Check whether the given compiler option works +AC_DEFUN([_LT_COMPILER_OPTION], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_SED])dnl +AC_CACHE_CHECK([$1], [$2], + [$2=no + m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$3" ## exclude from sc_useless_quotes_in_assignment + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi + fi + $RM conftest* +]) + +if test yes = "[$]$2"; then + m4_if([$5], , :, [$5]) +else + m4_if([$6], , :, [$6]) +fi +])# _LT_COMPILER_OPTION + +# Old name: +AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], []) + + +# _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [ACTION-SUCCESS], [ACTION-FAILURE]) +# ---------------------------------------------------- +# Check whether the given linker option works +AC_DEFUN([_LT_LINKER_OPTION], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_SED])dnl +AC_CACHE_CHECK([$1], [$2], + [$2=no + save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS $3" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&AS_MESSAGE_LOG_FD + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi + else + $2=yes + fi + fi + $RM -r conftest* + LDFLAGS=$save_LDFLAGS +]) + +if test yes = "[$]$2"; then + m4_if([$4], , :, [$4]) +else + m4_if([$5], , :, [$5]) +fi +])# _LT_LINKER_OPTION + +# Old name: +AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], []) + + +# LT_CMD_MAX_LEN +#--------------- +AC_DEFUN([LT_CMD_MAX_LEN], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +# find the maximum length of command line arguments +AC_MSG_CHECKING([the maximum length of command line arguments]) +AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl + i=0 + teststring=ABCD + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw* | cegcc*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + mint*) + # On MiNT this can take a long time and run out of memory. + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + os2*) + # The test takes a long time on OS/2. + lt_cv_sys_max_cmd_len=8192 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` + if test -n "$lt_cv_sys_max_cmd_len" && \ + test undefined != "$lt_cv_sys_max_cmd_len"; then + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + else + # Make teststring a little bigger before we do anything with it. + # a 1K string should be a reasonable start. + for i in 1 2 3 4 5 6 7 8; do + teststring=$teststring$teststring + done + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + while { test X`env echo "$teststring$teststring" 2>/dev/null` \ + = "X$teststring$teststring"; } >/dev/null 2>&1 && + test 17 != "$i" # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + # Only check the string length outside the loop. + lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` + teststring= + # Add a significant safety factor because C++ compilers can tack on + # massive amounts of additional arguments before passing them to the + # linker. It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + fi + ;; + esac +]) +if test -n "$lt_cv_sys_max_cmd_len"; then + AC_MSG_RESULT($lt_cv_sys_max_cmd_len) +else + AC_MSG_RESULT(none) +fi +max_cmd_len=$lt_cv_sys_max_cmd_len +_LT_DECL([], [max_cmd_len], [0], + [What is the maximum length of a command?]) +])# LT_CMD_MAX_LEN + +# Old name: +AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], []) + + +# _LT_HEADER_DLFCN +# ---------------- +m4_defun([_LT_HEADER_DLFCN], +[AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl +])# _LT_HEADER_DLFCN + + +# _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, +# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) +# ---------------------------------------------------------------- +m4_defun([_LT_TRY_DLOPEN_SELF], +[m4_require([_LT_HEADER_DLFCN])dnl +if test yes = "$cross_compiling"; then : + [$4] +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +[#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include <dlfcn.h> +#endif + +#include <stdio.h> + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisibility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +}] +_LT_EOF + if AC_TRY_EVAL(ac_link) && test -s "conftest$ac_exeext" 2>/dev/null; then + (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) $1 ;; + x$lt_dlneed_uscore) $2 ;; + x$lt_dlunknown|x*) $3 ;; + esac + else : + # compilation failed + $3 + fi +fi +rm -fr conftest* +])# _LT_TRY_DLOPEN_SELF + + +# LT_SYS_DLOPEN_SELF +# ------------------ +AC_DEFUN([LT_SYS_DLOPEN_SELF], +[m4_require([_LT_HEADER_DLFCN])dnl +if test yes != "$enable_dlopen"; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen=load_add_on + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32* | cegcc*) + lt_cv_dlopen=LoadLibrary + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen=dlopen + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl],[ + lt_cv_dlopen=dyld + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ]) + ;; + + tpf*) + # Don't try to run any link tests for TPF. We know it's impossible + # because TPF is a cross-compiler, and we know how we open DSOs. + lt_cv_dlopen=dlopen + lt_cv_dlopen_libs= + lt_cv_dlopen_self=no + ;; + + *) + AC_CHECK_FUNC([shl_load], + [lt_cv_dlopen=shl_load], + [AC_CHECK_LIB([dld], [shl_load], + [lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld], + [AC_CHECK_FUNC([dlopen], + [lt_cv_dlopen=dlopen], + [AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl], + [AC_CHECK_LIB([svld], [dlopen], + [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld], + [AC_CHECK_LIB([dld], [dld_link], + [lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld]) + ]) + ]) + ]) + ]) + ]) + ;; + esac + + if test no = "$lt_cv_dlopen"; then + enable_dlopen=no + else + enable_dlopen=yes + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS=$CPPFLAGS + test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS=$LDFLAGS + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS=$LIBS + LIBS="$lt_cv_dlopen_libs $LIBS" + + AC_CACHE_CHECK([whether a program can dlopen itself], + lt_cv_dlopen_self, [dnl + _LT_TRY_DLOPEN_SELF( + lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, + lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) + ]) + + if test yes = "$lt_cv_dlopen_self"; then + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" + AC_CACHE_CHECK([whether a statically linked program can dlopen itself], + lt_cv_dlopen_self_static, [dnl + _LT_TRY_DLOPEN_SELF( + lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, + lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) + ]) + fi + + CPPFLAGS=$save_CPPFLAGS + LDFLAGS=$save_LDFLAGS + LIBS=$save_LIBS + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi +_LT_DECL([dlopen_support], [enable_dlopen], [0], + [Whether dlopen is supported]) +_LT_DECL([dlopen_self], [enable_dlopen_self], [0], + [Whether dlopen of programs is supported]) +_LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0], + [Whether dlopen of statically linked programs is supported]) +])# LT_SYS_DLOPEN_SELF + +# Old name: +AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], []) + + +# _LT_COMPILER_C_O([TAGNAME]) +# --------------------------- +# Check to see if options -c and -o are simultaneously supported by compiler. +# This macro does not hard code the compiler like AC_PROG_CC_C_O. +m4_defun([_LT_COMPILER_C_O], +[m4_require([_LT_DECL_SED])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_TAG_COMPILER])dnl +AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], + [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)], + [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes + fi + fi + chmod u+w . 2>&AS_MESSAGE_LOG_FD + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* +]) +_LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1], + [Does compiler simultaneously support -c and -o options?]) +])# _LT_COMPILER_C_O + + +# _LT_COMPILER_FILE_LOCKS([TAGNAME]) +# ---------------------------------- +# Check to see if we can do hard links to lock some files if needed +m4_defun([_LT_COMPILER_FILE_LOCKS], +[m4_require([_LT_ENABLE_LOCK])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +_LT_COMPILER_C_O([$1]) + +hard_links=nottested +if test no = "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" && test no != "$need_locks"; then + # do not overwrite the value of need_locks provided by the user + AC_MSG_CHECKING([if we can lock with hard links]) + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + AC_MSG_RESULT([$hard_links]) + if test no = "$hard_links"; then + AC_MSG_WARN(['$CC' does not support '-c -o', so 'make -j' may be unsafe]) + need_locks=warn + fi +else + need_locks=no +fi +_LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?]) +])# _LT_COMPILER_FILE_LOCKS + + +# _LT_CHECK_OBJDIR +# ---------------- +m4_defun([_LT_CHECK_OBJDIR], +[AC_CACHE_CHECK([for objdir], [lt_cv_objdir], +[rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null]) +objdir=$lt_cv_objdir +_LT_DECL([], [objdir], [0], + [The name of the directory that contains temporary libtool files])dnl +m4_pattern_allow([LT_OBJDIR])dnl +AC_DEFINE_UNQUOTED([LT_OBJDIR], "$lt_cv_objdir/", + [Define to the sub-directory where libtool stores uninstalled libraries.]) +])# _LT_CHECK_OBJDIR + + +# _LT_LINKER_HARDCODE_LIBPATH([TAGNAME]) +# -------------------------------------- +# Check hardcoding attributes. +m4_defun([_LT_LINKER_HARDCODE_LIBPATH], +[AC_MSG_CHECKING([how to hardcode library paths into programs]) +_LT_TAGVAR(hardcode_action, $1)= +if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || + test -n "$_LT_TAGVAR(runpath_var, $1)" || + test yes = "$_LT_TAGVAR(hardcode_automatic, $1)"; then + + # We can hardcode non-existent directories. + if test no != "$_LT_TAGVAR(hardcode_direct, $1)" && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" && + test no != "$_LT_TAGVAR(hardcode_minus_L, $1)"; then + # Linking always hardcodes the temporary library directory. + _LT_TAGVAR(hardcode_action, $1)=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + _LT_TAGVAR(hardcode_action, $1)=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + _LT_TAGVAR(hardcode_action, $1)=unsupported +fi +AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) + +if test relink = "$_LT_TAGVAR(hardcode_action, $1)" || + test yes = "$_LT_TAGVAR(inherit_rpath, $1)"; then + # Fast installation is not supported + enable_fast_install=no +elif test yes = "$shlibpath_overrides_runpath" || + test no = "$enable_shared"; then + # Fast installation is not necessary + enable_fast_install=needless +fi +_LT_TAGDECL([], [hardcode_action], [0], + [How to hardcode a shared library path into an executable]) +])# _LT_LINKER_HARDCODE_LIBPATH + + +# _LT_CMD_STRIPLIB +# ---------------- +m4_defun([_LT_CMD_STRIPLIB], +[m4_require([_LT_DECL_EGREP]) +striplib= +old_striplib= +AC_MSG_CHECKING([whether stripping libraries is possible]) +if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + AC_MSG_RESULT([yes]) +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP"; then + striplib="$STRIP -x" + old_striplib="$STRIP -S" + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + fi + ;; + *) + AC_MSG_RESULT([no]) + ;; + esac +fi +_LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) +_LT_DECL([], [striplib], [1]) +])# _LT_CMD_STRIPLIB + + +# _LT_PREPARE_MUNGE_PATH_LIST +# --------------------------- +# Make sure func_munge_path_list() is defined correctly. +m4_defun([_LT_PREPARE_MUNGE_PATH_LIST], +[[# func_munge_path_list VARIABLE PATH +# ----------------------------------- +# VARIABLE is name of variable containing _space_ separated list of +# directories to be munged by the contents of PATH, which is string +# having a format: +# "DIR[:DIR]:" +# string "DIR[ DIR]" will be prepended to VARIABLE +# ":DIR[:DIR]" +# string "DIR[ DIR]" will be appended to VARIABLE +# "DIRP[:DIRP]::[DIRA:]DIRA" +# string "DIRP[ DIRP]" will be prepended to VARIABLE and string +# "DIRA[ DIRA]" will be appended to VARIABLE +# "DIR[:DIR]" +# VARIABLE will be replaced by "DIR[ DIR]" +func_munge_path_list () +{ + case x@S|@2 in + x) + ;; + *:) + eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'` \@S|@@S|@1\" + ;; + x:*) + eval @S|@1=\"\@S|@@S|@1 `$ECHO @S|@2 | $SED 's/:/ /g'`\" + ;; + *::*) + eval @S|@1=\"\@S|@@S|@1\ `$ECHO @S|@2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" + eval @S|@1=\"`$ECHO @S|@2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \@S|@@S|@1\" + ;; + *) + eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'`\" + ;; + esac +} +]])# _LT_PREPARE_PATH_LIST + + +# _LT_SYS_DYNAMIC_LINKER([TAG]) +# ----------------------------- +# PORTME Fill in your ld.so characteristics +m4_defun([_LT_SYS_DYNAMIC_LINKER], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_OBJDUMP])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_CHECK_SHELL_FEATURES])dnl +m4_require([_LT_PREPARE_MUNGE_PATH_LIST])dnl +AC_MSG_CHECKING([dynamic linker characteristics]) +m4_if([$1], + [], [ +if test yes = "$GCC"; then + case $host_os in + darwin*) lt_awk_arg='/^libraries:/,/LR/' ;; + *) lt_awk_arg='/^libraries:/' ;; + esac + case $host_os in + mingw* | cegcc*) lt_sed_strip_eq='s|=\([[A-Za-z]]:\)|\1|g' ;; + *) lt_sed_strip_eq='s|=/|/|g' ;; + esac + lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` + case $lt_search_path_spec in + *\;*) + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` + ;; + *) + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` + ;; + esac + # Ok, now we have the path, separated by spaces, we can step through it + # and add multilib dir if necessary... + lt_tmp_lt_search_path_spec= + lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + # ...but if some path component already ends with the multilib dir we assume + # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer). + case "$lt_multi_os_dir; $lt_search_path_spec " in + "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*) + lt_multi_os_dir= + ;; + esac + for lt_sys_path in $lt_search_path_spec; do + if test -d "$lt_sys_path$lt_multi_os_dir"; then + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir" + elif test -n "$lt_multi_os_dir"; then + test -d "$lt_sys_path" && \ + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" + fi + done + lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' +BEGIN {RS = " "; FS = "/|\n";} { + lt_foo = ""; + lt_count = 0; + for (lt_i = NF; lt_i > 0; lt_i--) { + if ($lt_i != "" && $lt_i != ".") { + if ($lt_i == "..") { + lt_count++; + } else { + if (lt_count == 0) { + lt_foo = "/" $lt_i lt_foo; + } else { + lt_count--; + } + } + } + } + if (lt_foo != "") { lt_freq[[lt_foo]]++; } + if (lt_freq[[lt_foo]] == 1) { print lt_foo; } +}'` + # AWK program above erroneously prepends '/' to C:/dos/paths + # for these hosts. + case $host_os in + mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ + $SED 's|/\([[A-Za-z]]:\)|\1|g'` ;; + esac + sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi]) +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=.so +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +AC_ARG_VAR([LT_SYS_LIBRARY_PATH], +[User-defined run-time library search path.]) + +case $host_os in +aix3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='$libname$release$shared_ext$major' + ;; + +aix[[4-9]]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test ia64 = "$host_cpu"; then + # AIX 5 supports IA64 + library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line '#! .'. This would cause the generated library to + # depend on '.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[[01]] | aix4.[[01]].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # Using Import Files as archive members, it is possible to support + # filename-based versioning of shared library archives on AIX. While + # this would work for both with and without runtime linking, it will + # prevent static linking of such archives. So we do filename-based + # shared library versioning with .so extension only, which is used + # when both runtime linking and shared linking is enabled. + # Unfortunately, runtime linking may impact performance, so we do + # not want this to be the default eventually. Also, we use the + # versioned .so libs for executables only if there is the -brtl + # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. + # To allow for filename-based versioning support, we need to create + # libNAME.so.V as an archive file, containing: + # *) an Import File, referring to the versioned filename of the + # archive as well as the shared archive member, telling the + # bitwidth (32 or 64) of that shared object, and providing the + # list of exported symbols of that shared object, eventually + # decorated with the 'weak' keyword + # *) the shared object with the F_LOADONLY flag set, to really avoid + # it being seen by the linker. + # At run time we better use the real file rather than another symlink, + # but for link time we create the symlink libNAME.so -> libNAME.so.V + + case $with_aix_soname,$aix_use_runtimelinking in + # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + aix,yes) # traditional libtool + dynamic_linker='AIX unversionable lib.so' + # If using run time linking (on AIX 4.2 or later) use lib<name>.so + # instead of lib<name>.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + ;; + aix,no) # traditional AIX only + dynamic_linker='AIX lib.a[(]lib.so.V[)]' + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' + ;; + svr4,*) # full svr4 only + dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)]" + library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' + # We do not specify a path in Import Files, so LIBPATH fires. + shlibpath_overrides_runpath=yes + ;; + *,yes) # both, prefer svr4 + dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)], lib.a[(]lib.so.V[)]" + library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' + # unpreferred sharedlib libNAME.a needs extra handling + postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' + postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' + # We do not specify a path in Import Files, so LIBPATH fires. + shlibpath_overrides_runpath=yes + ;; + *,no) # both, prefer aix + dynamic_linker="AIX lib.a[(]lib.so.V[)], lib.so.V[(]$shared_archive_member_spec.o[)]" + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' + # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling + postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' + postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' + ;; + esac + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='$libname$shared_ext' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[[45]]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=.dll + need_version=no + need_lib_prefix=no + + case $GCC,$cc_basename in + yes,*) + # gcc + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' +m4_if([$1], [],[ + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"]) + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' + ;; + esac + dynamic_linker='Win32 ld.exe' + ;; + + *,cl*) + # Native MSVC + libname_spec='$name' + soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' + library_names_spec='$libname.dll.lib' + + case $build_os in + mingw*) + sys_lib_search_path_spec= + lt_save_ifs=$IFS + IFS=';' + for lt_path in $LIB + do + IFS=$lt_save_ifs + # Let DOS variable expansion print the short 8.3 style file name. + lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` + sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" + done + IFS=$lt_save_ifs + # Convert to MSYS style. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'` + ;; + cygwin*) + # Convert to unix form, then to dos form, then back to unix form + # but this time dos style (no spaces!) so that the unix form looks + # like /cygdrive/c/PROGRA~1:/cygdr... + sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` + sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` + sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + ;; + *) + sys_lib_search_path_spec=$LIB + if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then + # It is most probably a Windows format PATH. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # FIXME: find the short name or the path components, as spaces are + # common. (e.g. "Program Files" -> "PROGRA~1") + ;; + esac + + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + dynamic_linker='Win32 link.exe' + ;; + + *) + # Assume MSVC wrapper + library_names_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext $libname.lib' + dynamic_linker='Win32 ld.exe' + ;; + esac + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' + soname_spec='$libname$release$major$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' +m4_if([$1], [],[ + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[[23]].*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2.*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[[01]]* | freebsdelf3.[[01]]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ + freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +haiku*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + dynamic_linker="$host_os runtime_loader" + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LIBRARY_PATH + shlibpath_overrides_runpath=no + sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + if test 32 = "$HPUX_IA64_MODE"; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + sys_lib_dlsearch_path_spec=/usr/lib/hpux32 + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + sys_lib_dlsearch_path_spec=/usr/lib/hpux64 + fi + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555, ... + postinstall_cmds='chmod 555 $lib' + # or fails outright, so override atomically: + install_override_mode=555 + ;; + +interix[[3-9]]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test yes = "$lt_cv_prog_gnu_ld"; then + version_type=linux # correct to gnu/linux during the next big refactor + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" + sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +linux*android*) + version_type=none # Android doesn't support versioned libraries. + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext' + soname_spec='$libname$release$shared_ext' + finish_cmds= + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + dynamic_linker='Android linker' + # Don't embed -rpath directories since the linker doesn't support them. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + + # Some binutils ld are patched to set DT_RUNPATH + AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath], + [lt_cv_shlibpath_overrides_runpath=no + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \ + LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\"" + AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], + [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null], + [lt_cv_shlibpath_overrides_runpath=yes])]) + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + ]) + shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Ideally, we could use ldconfig to report *all* directores which are + # searched for libraries, however this is still not possible. Aside from not + # being certain /sbin/ldconfig is available, command + # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, + # even though it is searched at run-time. Try to do the best guess by + # appending ld.so.conf contents (and includes) to the search path. + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd* | bitrig*) + version_type=sunos + sys_lib_dlsearch_path_spec=/usr/lib + need_lib_prefix=no + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + need_version=no + else + need_version=yes + fi + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +os2*) + libname_spec='$name' + version_type=windows + shrext_cmds=.dll + need_version=no + need_lib_prefix=no + # OS/2 can only load a DLL with a base name of 8 characters or less. + soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; + v=$($ECHO $release$versuffix | tr -d .-); + n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); + $ECHO $n$v`$shared_ext' + library_names_spec='${libname}_dll.$libext' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=BEGINLIBPATH + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test yes = "$with_gnu_ld"; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec; then + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' + soname_spec='$libname$shared_ext.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=sco + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test yes = "$with_gnu_ld"; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +AC_MSG_RESULT([$dynamic_linker]) +test no = "$dynamic_linker" && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test yes = "$GCC"; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then + sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec +fi + +if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then + sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec +fi + +# remember unaugmented sys_lib_dlsearch_path content for libtool script decls... +configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec + +# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code +func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" + +# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool +configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH + +_LT_DECL([], [variables_saved_for_relink], [1], + [Variables whose values should be saved in libtool wrapper scripts and + restored at link time]) +_LT_DECL([], [need_lib_prefix], [0], + [Do we need the "lib" prefix for modules?]) +_LT_DECL([], [need_version], [0], [Do we need a version for libraries?]) +_LT_DECL([], [version_type], [0], [Library versioning type]) +_LT_DECL([], [runpath_var], [0], [Shared library runtime path variable]) +_LT_DECL([], [shlibpath_var], [0],[Shared library path variable]) +_LT_DECL([], [shlibpath_overrides_runpath], [0], + [Is shlibpath searched before the hard-coded library search path?]) +_LT_DECL([], [libname_spec], [1], [Format of library name prefix]) +_LT_DECL([], [library_names_spec], [1], + [[List of archive names. First name is the real one, the rest are links. + The last name is the one that the linker finds with -lNAME]]) +_LT_DECL([], [soname_spec], [1], + [[The coded name of the library, if different from the real name]]) +_LT_DECL([], [install_override_mode], [1], + [Permission mode override for installation of shared libraries]) +_LT_DECL([], [postinstall_cmds], [2], + [Command to use after installation of a shared archive]) +_LT_DECL([], [postuninstall_cmds], [2], + [Command to use after uninstallation of a shared archive]) +_LT_DECL([], [finish_cmds], [2], + [Commands used to finish a libtool library installation in a directory]) +_LT_DECL([], [finish_eval], [1], + [[As "finish_cmds", except a single script fragment to be evaled but + not shown]]) +_LT_DECL([], [hardcode_into_libs], [0], + [Whether we should hardcode library paths into libraries]) +_LT_DECL([], [sys_lib_search_path_spec], [2], + [Compile-time system search path for libraries]) +_LT_DECL([sys_lib_dlsearch_path_spec], [configure_time_dlsearch_path], [2], + [Detected run-time system search path for libraries]) +_LT_DECL([], [configure_time_lt_sys_library_path], [2], + [Explicit LT_SYS_LIBRARY_PATH set during ./configure time]) +])# _LT_SYS_DYNAMIC_LINKER + + +# _LT_PATH_TOOL_PREFIX(TOOL) +# -------------------------- +# find a file program that can recognize shared library +AC_DEFUN([_LT_PATH_TOOL_PREFIX], +[m4_require([_LT_DECL_EGREP])dnl +AC_MSG_CHECKING([for $1]) +AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, +[case $MAGIC_CMD in +[[\\/*] | ?:[\\/]*]) + lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD=$MAGIC_CMD + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR +dnl $ac_dummy forces splitting on constant user-supplied paths. +dnl POSIX.2 word splitting is done only on the output of word expansions, +dnl not every word. This closes a longstanding sh security hole. + ac_dummy="m4_if([$2], , $PATH, [$2])" + for ac_dir in $ac_dummy; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$1"; then + lt_cv_path_MAGIC_CMD=$ac_dir/"$1" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD=$lt_cv_path_MAGIC_CMD + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS=$lt_save_ifs + MAGIC_CMD=$lt_save_MAGIC_CMD + ;; +esac]) +MAGIC_CMD=$lt_cv_path_MAGIC_CMD +if test -n "$MAGIC_CMD"; then + AC_MSG_RESULT($MAGIC_CMD) +else + AC_MSG_RESULT(no) +fi +_LT_DECL([], [MAGIC_CMD], [0], + [Used to examine libraries when file_magic_cmd begins with "file"])dnl +])# _LT_PATH_TOOL_PREFIX + +# Old name: +AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) + + +# _LT_PATH_MAGIC +# -------------- +# find a file program that can recognize a shared library +m4_defun([_LT_PATH_MAGIC], +[_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) + else + MAGIC_CMD=: + fi +fi +])# _LT_PATH_MAGIC + + +# LT_PATH_LD +# ---------- +# find the pathname to the GNU or non-GNU linker +AC_DEFUN([LT_PATH_LD], +[AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_PROG_ECHO_BACKSLASH])dnl + +AC_ARG_WITH([gnu-ld], + [AS_HELP_STRING([--with-gnu-ld], + [assume the C compiler uses GNU ld @<:@default=no@:>@])], + [test no = "$withval" || with_gnu_ld=yes], + [with_gnu_ld=no])dnl + +ac_prog=ld +if test yes = "$GCC"; then + # Check if gcc -print-prog-name=ld gives a path. + AC_MSG_CHECKING([for ld used by $CC]) + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return, which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [[\\/]]* | ?:[[\\/]]*) + re_direlt='/[[^/]][[^/]]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD=$ac_prog + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test yes = "$with_gnu_ld"; then + AC_MSG_CHECKING([for GNU ld]) +else + AC_MSG_CHECKING([for non-GNU ld]) +fi +AC_CACHE_VAL(lt_cv_path_LD, +[if test -z "$LD"; then + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD=$ac_dir/$ac_prog + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in + *GNU* | *'with BFD'*) + test no != "$with_gnu_ld" && break + ;; + *) + test yes != "$with_gnu_ld" && break + ;; + esac + fi + done + IFS=$lt_save_ifs +else + lt_cv_path_LD=$LD # Let the user override the test with a path. +fi]) +LD=$lt_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]) +_LT_PATH_LD_GNU +AC_SUBST([LD]) + +_LT_TAGDECL([], [LD], [1], [The linker used to build libraries]) +])# LT_PATH_LD + +# Old names: +AU_ALIAS([AM_PROG_LD], [LT_PATH_LD]) +AU_ALIAS([AC_PROG_LD], [LT_PATH_LD]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_PROG_LD], []) +dnl AC_DEFUN([AC_PROG_LD], []) + + +# _LT_PATH_LD_GNU +#- -------------- +m4_defun([_LT_PATH_LD_GNU], +[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_cv_prog_gnu_ld, +[# I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 </dev/null` in +*GNU* | *'with BFD'*) + lt_cv_prog_gnu_ld=yes + ;; +*) + lt_cv_prog_gnu_ld=no + ;; +esac]) +with_gnu_ld=$lt_cv_prog_gnu_ld +])# _LT_PATH_LD_GNU + + +# _LT_CMD_RELOAD +# -------------- +# find reload flag for linker +# -- PORTME Some linkers may need a different reload flag. +m4_defun([_LT_CMD_RELOAD], +[AC_CACHE_CHECK([for $LD option to reload object files], + lt_cv_ld_reload_flag, + [lt_cv_ld_reload_flag='-r']) +reload_flag=$lt_cv_ld_reload_flag +case $reload_flag in +"" | " "*) ;; +*) reload_flag=" $reload_flag" ;; +esac +reload_cmds='$LD$reload_flag -o $output$reload_objs' +case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + if test yes != "$GCC"; then + reload_cmds=false + fi + ;; + darwin*) + if test yes = "$GCC"; then + reload_cmds='$LTCC $LTCFLAGS -nostdlib $wl-r -o $output$reload_objs' + else + reload_cmds='$LD$reload_flag -o $output$reload_objs' + fi + ;; +esac +_LT_TAGDECL([], [reload_flag], [1], [How to create reloadable object files])dnl +_LT_TAGDECL([], [reload_cmds], [2])dnl +])# _LT_CMD_RELOAD + + +# _LT_PATH_DD +# ----------- +# find a working dd +m4_defun([_LT_PATH_DD], +[AC_CACHE_CHECK([for a working dd], [ac_cv_path_lt_DD], +[printf 0123456789abcdef0123456789abcdef >conftest.i +cat conftest.i conftest.i >conftest2.i +: ${lt_DD:=$DD} +AC_PATH_PROGS_FEATURE_CHECK([lt_DD], [dd], +[if "$ac_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then + cmp -s conftest.i conftest.out \ + && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=: +fi]) +rm -f conftest.i conftest2.i conftest.out]) +])# _LT_PATH_DD + + +# _LT_CMD_TRUNCATE +# ---------------- +# find command to truncate a binary pipe +m4_defun([_LT_CMD_TRUNCATE], +[m4_require([_LT_PATH_DD]) +AC_CACHE_CHECK([how to truncate binary pipes], [lt_cv_truncate_bin], +[printf 0123456789abcdef0123456789abcdef >conftest.i +cat conftest.i conftest.i >conftest2.i +lt_cv_truncate_bin= +if "$ac_cv_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then + cmp -s conftest.i conftest.out \ + && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1" +fi +rm -f conftest.i conftest2.i conftest.out +test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q"]) +_LT_DECL([lt_truncate_bin], [lt_cv_truncate_bin], [1], + [Command to truncate a binary pipe]) +])# _LT_CMD_TRUNCATE + + +# _LT_CHECK_MAGIC_METHOD +# ---------------------- +# how to check for library dependencies +# -- PORTME fill in with the dynamic library characteristics +m4_defun([_LT_CHECK_MAGIC_METHOD], +[m4_require([_LT_DECL_EGREP]) +m4_require([_LT_DECL_OBJDUMP]) +AC_CACHE_CHECK([how to recognize dependent libraries], +lt_cv_deplibs_check_method, +[lt_cv_file_magic_cmd='$MAGIC_CMD' +lt_cv_file_magic_test_file= +lt_cv_deplibs_check_method='unknown' +# Need to set the preceding variable on all platforms that support +# interlibrary dependencies. +# 'none' -- dependencies not supported. +# 'unknown' -- same as none, but documents that we really don't know. +# 'pass_all' -- all dependencies passed with no checks. +# 'test_compile' -- check by making test program. +# 'file_magic [[regex]]' -- check by looking for files in library path +# that responds to the $file_magic_cmd with a given extended regex. +# If you have 'file' or equivalent on your system and you're not sure +# whether 'pass_all' will *always* work, you probably want this one. + +case $host_os in +aix[[4-9]]*) + lt_cv_deplibs_check_method=pass_all + ;; + +beos*) + lt_cv_deplibs_check_method=pass_all + ;; + +bsdi[[45]]*) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)' + lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_test_file=/shlib/libc.so + ;; + +cygwin*) + # func_win32_libid is a shell function defined in ltmain.sh + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + ;; + +mingw* | pw32*) + # Base MSYS/MinGW do not provide the 'file' command needed by + # func_win32_libid shell function, so use a weaker test based on 'objdump', + # unless we find 'file', for example because we are cross-compiling. + if ( file / ) >/dev/null 2>&1; then + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + else + # Keep this pattern in sync with the one in func_win32_libid. + lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' + lt_cv_file_magic_cmd='$OBJDUMP -f' + fi + ;; + +cegcc*) + # use the weaker test based on 'objdump'. See mingw*. + lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method=pass_all + ;; + +freebsd* | dragonfly*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +haiku*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'] + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +interix[[3-9]]*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +*nto* | *qnx*) + lt_cv_deplibs_check_method=pass_all + ;; + +openbsd* | bitrig*) + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +rdos*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.3*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +tpf*) + lt_cv_deplibs_check_method=pass_all + ;; +os2*) + lt_cv_deplibs_check_method=pass_all + ;; +esac +]) + +file_magic_glob= +want_nocaseglob=no +if test "$build" = "$host"; then + case $host_os in + mingw* | pw32*) + if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then + want_nocaseglob=yes + else + file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"` + fi + ;; + esac +fi + +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown + +_LT_DECL([], [deplibs_check_method], [1], + [Method to check whether dependent libraries are shared objects]) +_LT_DECL([], [file_magic_cmd], [1], + [Command to use when deplibs_check_method = "file_magic"]) +_LT_DECL([], [file_magic_glob], [1], + [How to find potential files when deplibs_check_method = "file_magic"]) +_LT_DECL([], [want_nocaseglob], [1], + [Find potential files using nocaseglob when deplibs_check_method = "file_magic"]) +])# _LT_CHECK_MAGIC_METHOD + + +# LT_PATH_NM +# ---------- +# find the pathname to a BSD- or MS-compatible name lister +AC_DEFUN([LT_PATH_NM], +[AC_REQUIRE([AC_PROG_CC])dnl +AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, +[if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM=$NM +else + lt_nm_to_check=${ac_tool_prefix}nm + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + tmp_nm=$ac_dir/$lt_tmp_nm + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the 'sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty + case $build_os in + mingw*) lt_bad_file=conftest.nm/nofile ;; + *) lt_bad_file=/dev/null ;; + esac + case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in + *$lt_bad_file* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break 2 + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break 2 + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + ;; + esac + fi + done + IFS=$lt_save_ifs + done + : ${lt_cv_path_NM=no} +fi]) +if test no != "$lt_cv_path_NM"; then + NM=$lt_cv_path_NM +else + # Didn't find any BSD compatible name lister, look for dumpbin. + if test -n "$DUMPBIN"; then : + # Let the user override the test. + else + AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :) + case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in + *COFF*) + DUMPBIN="$DUMPBIN -symbols -headers" + ;; + *) + DUMPBIN=: + ;; + esac + fi + AC_SUBST([DUMPBIN]) + if test : != "$DUMPBIN"; then + NM=$DUMPBIN + fi +fi +test -z "$NM" && NM=nm +AC_SUBST([NM]) +_LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl + +AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface], + [lt_cv_nm_interface="BSD nm" + echo "int some_variable = 0;" > conftest.$ac_ext + (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$ac_compile" 2>conftest.err) + cat conftest.err >&AS_MESSAGE_LOG_FD + (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD) + (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) + cat conftest.err >&AS_MESSAGE_LOG_FD + (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD) + cat conftest.out >&AS_MESSAGE_LOG_FD + if $GREP 'External.*some_variable' conftest.out > /dev/null; then + lt_cv_nm_interface="MS dumpbin" + fi + rm -f conftest*]) +])# LT_PATH_NM + +# Old names: +AU_ALIAS([AM_PROG_NM], [LT_PATH_NM]) +AU_ALIAS([AC_PROG_NM], [LT_PATH_NM]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_PROG_NM], []) +dnl AC_DEFUN([AC_PROG_NM], []) + +# _LT_CHECK_SHAREDLIB_FROM_LINKLIB +# -------------------------------- +# how to determine the name of the shared library +# associated with a specific link library. +# -- PORTME fill in with the dynamic library characteristics +m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB], +[m4_require([_LT_DECL_EGREP]) +m4_require([_LT_DECL_OBJDUMP]) +m4_require([_LT_DECL_DLLTOOL]) +AC_CACHE_CHECK([how to associate runtime and link libraries], +lt_cv_sharedlib_from_linklib_cmd, +[lt_cv_sharedlib_from_linklib_cmd='unknown' + +case $host_os in +cygwin* | mingw* | pw32* | cegcc*) + # two different shell functions defined in ltmain.sh; + # decide which one to use based on capabilities of $DLLTOOL + case `$DLLTOOL --help 2>&1` in + *--identify-strict*) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib + ;; + *) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback + ;; + esac + ;; +*) + # fallback: assume linklib IS sharedlib + lt_cv_sharedlib_from_linklib_cmd=$ECHO + ;; +esac +]) +sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd +test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO + +_LT_DECL([], [sharedlib_from_linklib_cmd], [1], + [Command to associate shared and link libraries]) +])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB + + +# _LT_PATH_MANIFEST_TOOL +# ---------------------- +# locate the manifest tool +m4_defun([_LT_PATH_MANIFEST_TOOL], +[AC_CHECK_TOOL(MANIFEST_TOOL, mt, :) +test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt +AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool], + [lt_cv_path_mainfest_tool=no + echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD + $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out + cat conftest.err >&AS_MESSAGE_LOG_FD + if $GREP 'Manifest Tool' conftest.out > /dev/null; then + lt_cv_path_mainfest_tool=yes + fi + rm -f conftest*]) +if test yes != "$lt_cv_path_mainfest_tool"; then + MANIFEST_TOOL=: +fi +_LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl +])# _LT_PATH_MANIFEST_TOOL + + +# _LT_DLL_DEF_P([FILE]) +# --------------------- +# True iff FILE is a Windows DLL '.def' file. +# Keep in sync with func_dll_def_p in the libtool script +AC_DEFUN([_LT_DLL_DEF_P], +[dnl + test DEF = "`$SED -n dnl + -e '\''s/^[[ ]]*//'\'' dnl Strip leading whitespace + -e '\''/^\(;.*\)*$/d'\'' dnl Delete empty lines and comments + -e '\''s/^\(EXPORTS\|LIBRARY\)\([[ ]].*\)*$/DEF/p'\'' dnl + -e q dnl Only consider the first "real" line + $1`" dnl +])# _LT_DLL_DEF_P + + +# LT_LIB_M +# -------- +# check for math library +AC_DEFUN([LT_LIB_M], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +LIBM= +case $host in +*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*) + # These system don't have libm, or don't need it + ;; +*-ncr-sysv4.3*) + AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM=-lmw) + AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") + ;; +*) + AC_CHECK_LIB(m, cos, LIBM=-lm) + ;; +esac +AC_SUBST([LIBM]) +])# LT_LIB_M + +# Old name: +AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_CHECK_LIBM], []) + + +# _LT_COMPILER_NO_RTTI([TAGNAME]) +# ------------------------------- +m4_defun([_LT_COMPILER_NO_RTTI], +[m4_require([_LT_TAG_COMPILER])dnl + +_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= + +if test yes = "$GCC"; then + case $cc_basename in + nvcc*) + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;; + *) + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;; + esac + + _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], + lt_cv_prog_compiler_rtti_exceptions, + [-fno-rtti -fno-exceptions], [], + [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) +fi +_LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1], + [Compiler flag to turn off builtin functions]) +])# _LT_COMPILER_NO_RTTI + + +# _LT_CMD_GLOBAL_SYMBOLS +# ---------------------- +m4_defun([_LT_CMD_GLOBAL_SYMBOLS], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([LT_PATH_NM])dnl +AC_REQUIRE([LT_PATH_LD])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_TAG_COMPILER])dnl + +# Check for command to grab the raw symbol name followed by C symbol from nm. +AC_MSG_CHECKING([command to parse $NM output from $compiler object]) +AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], +[ +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[[BCDEGRST]]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[[BCDT]]' + ;; +cygwin* | mingw* | pw32* | cegcc*) + symcode='[[ABCDGISTW]]' + ;; +hpux*) + if test ia64 = "$host_cpu"; then + symcode='[[ABCDEGRST]]' + fi + ;; +irix* | nonstopux*) + symcode='[[BCDEGRST]]' + ;; +osf*) + symcode='[[BCDEGQRST]]' + ;; +solaris*) + symcode='[[BDRT]]' + ;; +sco3.2v5*) + symcode='[[DT]]' + ;; +sysv4.2uw2*) + symcode='[[DT]]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[[ABDT]]' + ;; +sysv4) + symcode='[[DFNSTU]]' + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[[ABCDGIRSTW]]' ;; +esac + +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Gets list of data symbols to import. + lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'" + # Adjust the below global symbol transforms to fixup imported variables. + lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'" + lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'" + lt_c_name_lib_hook="\ + -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\ + -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'" +else + # Disable hooks by default. + lt_cv_sys_global_symbol_to_import= + lt_cdecl_hook= + lt_c_name_hook= + lt_c_name_lib_hook= +fi + +# Transform an extracted symbol line into a proper C declaration. +# Some systems (esp. on ia64) link data and code symbols differently, +# so use this general approach. +lt_cv_sys_global_symbol_to_cdecl="sed -n"\ +$lt_cdecl_hook\ +" -e 's/^T .* \(.*\)$/extern int \1();/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n"\ +$lt_c_name_hook\ +" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'" + +# Transform an extracted symbol line into symbol name with lib prefix and +# symbol address. +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\ +$lt_c_name_lib_hook\ +" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ +" -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'" + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# Try without a prefix underscore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # Write the raw and C identifiers. + if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Fake it for dumpbin and say T for any non-static function, + # D for any global variable and I for any imported variable. + # Also find C++ and __fastcall symbols from MSVC++, + # which start with @ or ?. + lt_cv_sys_global_symbol_pipe="$AWK ['"\ +" {last_section=section; section=\$ 3};"\ +" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ +" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ +" /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\ +" /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\ +" /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\ +" \$ 0!~/External *\|/{next};"\ +" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ +" {if(hide[section]) next};"\ +" {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\ +" {split(\$ 0,a,/\||\r/); split(a[2],s)};"\ +" s[1]~/^[@?]/{print f,s[1],s[1]; next};"\ +" s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\ +" ' prfx=^$ac_symprfx]" + else + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + fi + lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext <<_LT_EOF +#ifdef __cplusplus +extern "C" { +#endif +char nm_test_var; +void nm_test_func(void); +void nm_test_func(void){} +#ifdef __cplusplus +} +#endif +int main(){nm_test_var='a';nm_test_func();return(0);} +_LT_EOF + + if AC_TRY_EVAL(ac_compile); then + # Now try to grab the symbols. + nlist=conftest.nm + if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if $GREP ' nm_test_var$' "$nlist" >/dev/null; then + if $GREP ' nm_test_func$' "$nlist" >/dev/null; then + cat <<_LT_EOF > conftest.$ac_ext +/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ +#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE +/* DATA imports from DLLs on WIN32 can't be const, because runtime + relocations are performed -- see ld's documentation on pseudo-relocs. */ +# define LT@&t@_DLSYM_CONST +#elif defined __osf__ +/* This system does not cope well with relocations in const data. */ +# define LT@&t@_DLSYM_CONST +#else +# define LT@&t@_DLSYM_CONST const +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +_LT_EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' + + cat <<_LT_EOF >> conftest.$ac_ext + +/* The mapping between symbol names and symbols. */ +LT@&t@_DLSYM_CONST struct { + const char *name; + void *address; +} +lt__PROGRAM__LTX_preloaded_symbols[[]] = +{ + { "@PROGRAM@", (void *) 0 }, +_LT_EOF + $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext + cat <<\_LT_EOF >> conftest.$ac_ext + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt__PROGRAM__LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif +_LT_EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_globsym_save_LIBS=$LIBS + lt_globsym_save_CFLAGS=$CFLAGS + LIBS=conftstm.$ac_objext + CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" + if AC_TRY_EVAL(ac_link) && test -s conftest$ac_exeext; then + pipe_works=yes + fi + LIBS=$lt_globsym_save_LIBS + CFLAGS=$lt_globsym_save_CFLAGS + else + echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD + fi + else + echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD + cat conftest.$ac_ext >&5 + fi + rm -rf conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test yes = "$pipe_works"; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done +]) +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + AC_MSG_RESULT(failed) +else + AC_MSG_RESULT(ok) +fi + +# Response file support. +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + nm_file_list_spec='@' +elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then + nm_file_list_spec='@' +fi + +_LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], + [Take the output of nm and produce a listing of raw symbols and C names]) +_LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], + [Transform the output of nm in a proper C declaration]) +_LT_DECL([global_symbol_to_import], [lt_cv_sys_global_symbol_to_import], [1], + [Transform the output of nm into a list of symbols to manually relocate]) +_LT_DECL([global_symbol_to_c_name_address], + [lt_cv_sys_global_symbol_to_c_name_address], [1], + [Transform the output of nm in a C name address pair]) +_LT_DECL([global_symbol_to_c_name_address_lib_prefix], + [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], + [Transform the output of nm in a C name address pair when lib prefix is needed]) +_LT_DECL([nm_interface], [lt_cv_nm_interface], [1], + [The name lister interface]) +_LT_DECL([], [nm_file_list_spec], [1], + [Specify filename containing input files for $NM]) +]) # _LT_CMD_GLOBAL_SYMBOLS + + +# _LT_COMPILER_PIC([TAGNAME]) +# --------------------------- +m4_defun([_LT_COMPILER_PIC], +[m4_require([_LT_TAG_COMPILER])dnl +_LT_TAGVAR(lt_prog_compiler_wl, $1)= +_LT_TAGVAR(lt_prog_compiler_pic, $1)= +_LT_TAGVAR(lt_prog_compiler_static, $1)= + +m4_if([$1], [CXX], [ + # C++ specific cases for pic, static, wl, etc. + if test yes = "$GXX"; then + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the '-m68020' flag to GCC prevents building anything better, + # like '-m68040'. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + case $host_os in + os2*) + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' + ;; + esac + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + *djgpp*) + # DJGPP does not support shared libraries at all + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + _LT_TAGVAR(lt_prog_compiler_static, $1)= + ;; + interix[[3-9]]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + else + case $host_os in + aix[[4-9]]*) + # All AIX code is PIC. + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + chorus*) + case $cc_basename in + cxch68*) + # Green Hills C++ Compiler + # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" + ;; + esac + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + dgux*) + case $cc_basename in + ec++*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + ghcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + freebsd* | dragonfly*) + # FreeBSD uses GNU C++ + ;; + hpux9* | hpux10* | hpux11*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' + if test ia64 != "$host_cpu"; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + fi + ;; + aCC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + ;; + *) + ;; + esac + ;; + interix*) + # This is c89, which is MS Visual C++ (no shared libs) + # Anyone wants to do a port? + ;; + irix5* | irix6* | nonstopux*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + # CC pic flag -KPIC is the default. + ;; + *) + ;; + esac + ;; + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + case $cc_basename in + KCC*) + # KAI C++ Compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + ecpc* ) + # old Intel C++ for x86_64, which still supported -KPIC. + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + icpc* ) + # Intel C++, used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + cxx*) + # Compaq C++ + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*) + # IBM XL 8.0, 9.0 on PPC and BlueGene + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + esac + ;; + esac + ;; + lynxos*) + ;; + m88k*) + ;; + mvs*) + case $cc_basename in + cxx*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' + ;; + *) + ;; + esac + ;; + netbsd*) + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + ;; + RCC*) + # Rational C++ 2.4.1 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + cxx*) + # Digital/Compaq C++ + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + *) + ;; + esac + ;; + psos*) + ;; + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + gcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + ;; + *) + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + lcc*) + # Lucid + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + *) + ;; + esac + ;; + vxworks*) + ;; + *) + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +], +[ + if test yes = "$GCC"; then + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the '-m68020' flag to GCC prevents building anything better, + # like '-m68040'. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + case $host_os in + os2*) + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' + ;; + esac + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + _LT_TAGVAR(lt_prog_compiler_static, $1)= + ;; + + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + + interix[[3-9]]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + enable_shared=no + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + + case $cc_basename in + nvcc*) # Cuda Compiler Driver 2.2 + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker ' + if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)" + fi + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + case $cc_basename in + nagfor*) + # NAG Fortran compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + esac + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + case $host_os in + os2*) + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' + ;; + esac + ;; + + hpux9* | hpux10* | hpux11*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC (with -KPIC) is the default. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + case $cc_basename in + # old Intel for x86_64, which still supported -KPIC. + ecc*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + # icc used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + icc* | ifort*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + # Lahey Fortran 8.1. + lf95*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared' + _LT_TAGVAR(lt_prog_compiler_static, $1)='--static' + ;; + nagfor*) + # NAG Fortran compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + tcc*) + # Fabrice Bellard et al's Tiny C Compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + ccc*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All Alpha code is PIC. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + xl* | bgxl* | bgf* | mpixl*) + # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='' + ;; + *Sun\ F* | *Sun*Fortran*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + *Sun\ C*) + # Sun C 5.9 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + ;; + *Intel*\ [[CF]]*Compiler*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + *Portland\ Group*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + esac + ;; + esac + ;; + + newsos6) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + + osf3* | osf4* | osf5*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All OSF/1 code is PIC. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + rdos*) + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + solaris*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + case $cc_basename in + f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; + *) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; + esac + ;; + + sunos4*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + unicos*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + + uts4*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + *) + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +]) +case $host_os in + # For platforms that do not support PIC, -DPIC is meaningless: + *djgpp*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])" + ;; +esac + +AC_CACHE_CHECK([for $compiler option to produce PIC], + [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)], + [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) +_LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1) + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then + _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works], + [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)], + [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [], + [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in + "" | " "*) ;; + *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;; + esac], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) +fi +_LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1], + [Additional compiler flags for building library objects]) + +_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], + [How to pass a linker flag through the compiler]) +# +# Check to make sure the static flag actually works. +# +wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\" +_LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], + _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1), + $lt_tmp_static_flag, + [], + [_LT_TAGVAR(lt_prog_compiler_static, $1)=]) +_LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], + [Compiler flag to prevent dynamic linking]) +])# _LT_COMPILER_PIC + + +# _LT_LINKER_SHLIBS([TAGNAME]) +# ---------------------------- +# See if the linker supports building shared libraries. +m4_defun([_LT_LINKER_SHLIBS], +[AC_REQUIRE([LT_PATH_LD])dnl +AC_REQUIRE([LT_PATH_NM])dnl +m4_require([_LT_PATH_MANIFEST_TOOL])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl +m4_require([_LT_TAG_COMPILER])dnl +AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) +m4_if([$1], [CXX], [ + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] + case $host_os in + aix[[4-9]]*) + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to GNU nm, but means don't demangle to AIX nm. + # Without the "-l" option, or with the "-B" option, AIX nm treats + # weak defined symbols like other global defined symbols, whereas + # GNU nm marks them as "W". + # While the 'weak' keyword is ignored in the Export File, we need + # it in the Import File for the 'aix-soname' feature, so we have + # to replace the "-B" option with "-P" for AIX nm. + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' + else + _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' + fi + ;; + pw32*) + _LT_TAGVAR(export_symbols_cmds, $1)=$ltdll_cmds + ;; + cygwin* | mingw* | cegcc*) + case $cc_basename in + cl*) + _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + ;; + *) + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] + ;; + esac + ;; + *) + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + ;; + esac +], [ + runpath_var= + _LT_TAGVAR(allow_undefined_flag, $1)= + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(archive_cmds, $1)= + _LT_TAGVAR(archive_expsym_cmds, $1)= + _LT_TAGVAR(compiler_needs_object, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + _LT_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(hardcode_automatic, $1)=no + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_TAGVAR(hardcode_libdir_separator, $1)= + _LT_TAGVAR(hardcode_minus_L, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + _LT_TAGVAR(inherit_rpath, $1)=no + _LT_TAGVAR(link_all_deplibs, $1)=unknown + _LT_TAGVAR(module_cmds, $1)= + _LT_TAGVAR(module_expsym_cmds, $1)= + _LT_TAGVAR(old_archive_from_new_cmds, $1)= + _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)= + _LT_TAGVAR(thread_safe_flag_spec, $1)= + _LT_TAGVAR(whole_archive_flag_spec, $1)= + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + _LT_TAGVAR(include_expsyms, $1)= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ' (' and ')$', so one must not match beginning or + # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc', + # as well as any symbol that contains 'd'. + _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + # Exclude shared library initialization/finalization symbols. +dnl Note also adjust exclude_expsyms for C++ above. + extract_expsyms_cmds= + + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test yes != "$GCC"; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd* | bitrig*) + with_gnu_ld=no + ;; + esac + + _LT_TAGVAR(ld_shlibs, $1)=yes + + # On some targets, GNU ld is compatible enough with the native linker + # that we're better off using the native interface for both. + lt_use_gnu_ld_interface=no + if test yes = "$with_gnu_ld"; then + case $host_os in + aix*) + # The AIX port of GNU ld has always aspired to compatibility + # with the native linker. However, as the warning in the GNU ld + # block says, versions before 2.19.5* couldn't really create working + # shared libraries, regardless of the interface used. + case `$LD -v 2>&1` in + *\ \(GNU\ Binutils\)\ 2.19.5*) ;; + *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;; + *\ \(GNU\ Binutils\)\ [[3-9]]*) ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + fi + + if test yes = "$lt_use_gnu_ld_interface"; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='$wl' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then + _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + supports_anon_versioning=no + case `$LD -v | $SED -e 's/([^)]\+)\s\+//' 2>&1` in + *GNU\ gold*) supports_anon_versioning=yes ;; + *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix[[3-9]]*) + # On AIX/PPC, the GNU linker is very broken + if test ia64 != "$host_cpu"; then + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: the GNU linker, at least up to release 2.19, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to install binutils +*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. +*** You will then need to restart the configuration process. + +_LT_EOF + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='' + ;; + m68k) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach <jrb3@best.com> says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file, use it as + # is; otherwise, prepend EXPORTS... + _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + haiku*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + os2*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + shrext_cmds=.dll + _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + prefix_cmds="$SED"~ + if test EXPORTS = "`$SED 1q $export_symbols`"; then + prefix_cmds="$prefix_cmds -e 1d"; + fi~ + prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ + cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + ;; + + interix[[3-9]]*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) + tmp_diet=no + if test linux-dietlibc = "$host_os"; then + case $cc_basename in + diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) + esac + fi + if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ + && test no = "$tmp_diet" + then + tmp_addflag=' $pic_flag' + tmp_sharedflag='-shared' + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group f77 and f90 compilers + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + lf95*) # Lahey Fortran 8.1 + _LT_TAGVAR(whole_archive_flag_spec, $1)= + tmp_sharedflag='--shared' ;; + nagfor*) # NAGFOR 5.3 + tmp_sharedflag='-Wl,-shared' ;; + xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) + tmp_sharedflag='-qmkshrobj' + tmp_addflag= ;; + nvcc*) # Cuda Compiler Driver 2.2 + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 + tmp_sharedflag='-G' ;; + esac + _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + + if test yes = "$supports_anon_versioning"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' + fi + + case $cc_basename in + tcc*) + _LT_TAGVAR(export_dynamic_flag_spec, $1)='-rdynamic' + ;; + xlf* | bgf* | bgxlf* | mpixlf*) + # IBM XL Fortran 10.1 on PPC cannot create shared libs itself + _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' + if test yes = "$supports_anon_versioning"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' + fi + ;; + esac + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + sunos4*) + _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + + if test no = "$_LT_TAGVAR(ld_shlibs, $1)"; then + runpath_var= + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + _LT_TAGVAR(hardcode_direct, $1)=unsupported + fi + ;; + + aix[[4-9]]*) + if test ia64 = "$host_cpu"; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag= + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to GNU nm, but means don't demangle to AIX nm. + # Without the "-l" option, or with the "-B" option, AIX nm treats + # weak defined symbols like other global defined symbols, whereas + # GNU nm marks them as "W". + # While the 'weak' keyword is ignored in the Export File, we need + # it in the Import File for the 'aix-soname' feature, so we have + # to replace the "-B" option with "-P" for AIX nm. + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' + else + _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # have runtime linking enabled, and use it for executables. + # For shared libraries, we enable/disable runtime linking + # depending on the kind of the shared library created - + # when "with_aix_soname,aix_use_runtimelinking" is: + # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables + # "aix,yes" lib.so shared, rtl:yes, for executables + # lib.a static archive + # "both,no" lib.so.V(shr.o) shared, rtl:yes + # lib.a(lib.so.V) shared, rtl:no, for executables + # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a(lib.so.V) shared, rtl:no + # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a static archive + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) + for ld_flag in $LDFLAGS; do + if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then + aix_use_runtimelinking=yes + break + fi + done + if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then + # With aix-soname=svr4, we create the lib.so.V shared archives only, + # so we don't have lib.a shared libs to link our executables. + # We have to force runtime linking in this case. + aix_use_runtimelinking=yes + LDFLAGS="$LDFLAGS -Wl,-brtl" + fi + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_TAGVAR(archive_cmds, $1)='' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='$wl-f,' + case $with_aix_soname,$aix_use_runtimelinking in + aix,*) ;; # traditional, no import file + svr4,* | *,yes) # use import file + # The Import File defines what to hardcode. + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=no + ;; + esac + + if test yes = "$GCC"; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`$CC -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + _LT_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)= + fi + ;; + esac + shared_flag='-shared' + if test yes = "$aix_use_runtimelinking"; then + shared_flag="$shared_flag "'$wl-G' + fi + # Need to ensure runtime linking is disabled for the traditional + # shared library, or the linker may eventually find shared libraries + # /with/ Import File - we do not want to mix them. + shared_flag_aix='-shared' + shared_flag_svr4='-shared $wl-G' + else + # not using gcc + if test ia64 = "$host_cpu"; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test yes = "$aix_use_runtimelinking"; then + shared_flag='$wl-G' + else + shared_flag='$wl-bM:SRE' + fi + shared_flag_aix='$wl-bM:SRE' + shared_flag_svr4='$wl-G' + fi + fi + + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + _LT_TAGVAR(always_export_symbols, $1)=yes + if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(allow_undefined_flag, $1)='-berok' + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag + else + if test ia64 = "$host_cpu"; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib' + _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok' + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok' + if test yes = "$with_gnu_ld"; then + # We only use this code for GNU lds that support --whole-archive. + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' + # -brtl affects multiple linker settings, -berok does not and is overridden later + compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`' + if test svr4 != "$with_aix_soname"; then + # This is similar to how AIX traditionally builds its shared libraries. + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' + fi + if test aix != "$with_aix_soname"; then + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' + else + # used by -dlpreopen to get the symbols + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV $output_objdir/$realname.d/$soname $output_objdir' + fi + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d' + fi + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='' + ;; + m68k) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + ;; + + bsdi[[45]]*) + _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + case $cc_basename in + cl*) + # Native MSVC + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=.dll + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' + _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then + cp "$export_symbols" "$output_objdir/$soname.def"; + echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; + else + $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' + # Don't use ranlib + _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' + _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile=$lt_outputfile.exe + lt_tool_outputfile=$lt_tool_outputfile.exe + ;; + esac~ + if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # Assume MSVC wrapper + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=.dll + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + # FIXME: Should let the user specify the lib program. + _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + ;; + esac + ;; + + darwin* | rhapsody*) + _LT_DARWIN_LINKER_FEATURES($1) + ;; + + dgux*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2.*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | dragonfly*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + hpux9*) + if test yes = "$GCC"; then + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + else + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_direct, $1)=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + ;; + + hpux10*) + if test yes,no = "$GCC,$with_gnu_ld"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test no = "$with_gnu_ld"; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + fi + ;; + + hpux11*) + if test yes,no = "$GCC,$with_gnu_ld"; then + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + m4_if($1, [], [ + # Older versions of the 11.00 compiler do not understand -b yet + # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) + _LT_LINKER_OPTION([if $CC understands -b], + _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b], + [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'], + [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])], + [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags']) + ;; + esac + fi + if test no = "$with_gnu_ld"; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + case $host_cpu in + hppa*64*|ia64*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + *) + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test yes = "$GCC"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + # Try to use the -exported_symbol ld option, if it does not + # work, assume that -exports_file does not work either and + # implicitly export all symbols. + # This should be the same for all languages, so no per-tag cache variable. + AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol], + [lt_cv_irix_exported_symbol], + [save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null" + AC_LINK_IFELSE( + [AC_LANG_SOURCE( + [AC_LANG_CASE([C], [[int foo (void) { return 0; }]], + [C++], [[int foo (void) { return 0; }]], + [Fortran 77], [[ + subroutine foo + end]], + [Fortran], [[ + subroutine foo + end]])])], + [lt_cv_irix_exported_symbol=yes], + [lt_cv_irix_exported_symbol=no]) + LDFLAGS=$save_LDFLAGS]) + if test yes = "$lt_cv_irix_exported_symbol"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib' + fi + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(inherit_rpath, $1)=yes + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + linux*) + case $cc_basename in + tcc*) + # Fabrice Bellard et al's Tiny C Compiler + _LT_TAGVAR(ld_shlibs, $1)=yes + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + newsos6) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *nto* | *qnx*) + ;; + + openbsd* | bitrig*) + if test -f /usr/libexec/ld.so; then + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + fi + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + os2*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + shrext_cmds=.dll + _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + prefix_cmds="$SED"~ + if test EXPORTS = "`$SED 1q $export_symbols`"; then + prefix_cmds="$prefix_cmds -e 1d"; + fi~ + prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ + cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + ;; + + osf3*) + if test yes = "$GCC"; then + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + else + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test yes = "$GCC"; then + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + else + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp' + + # Both c and cxx compiler support -rpath directly + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + solaris*) + _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' + if test yes = "$GCC"; then + wlarc='$wl' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + else + case `$CC -V 2>&1` in + *"Compilers 5.0"*) + wlarc='' + _LT_TAGVAR(archive_cmds, $1)='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' + ;; + *) + wlarc='$wl' + _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + ;; + esac + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands '-z linker_flag'. GCC discards it without '$wl', + # but is careful enough not to reorder. + # Supported since Solaris 2.6 (maybe 2.5.1?) + if test yes = "$GCC"; then + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' + fi + ;; + esac + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + sunos4*) + if test sequent = "$host_vendor"; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4) + case $host_vendor in + sni) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' + _LT_TAGVAR(hardcode_direct, $1)=no + ;; + motorola) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4.3*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + _LT_TAGVAR(ld_shlibs, $1)=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) + _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + + if test yes = "$GCC"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We CANNOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' + _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport' + runpath_var='LD_RUN_PATH' + + if test yes = "$GCC"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + + if test sni = "$host_vendor"; then + case $host in + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Blargedynsym' + ;; + esac + fi + fi +]) +AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) +test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no + +_LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld + +_LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl +_LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl +_LT_DECL([], [extract_expsyms_cmds], [2], + [The commands to extract the exported symbol list from a shared archive]) + +# +# Do we need to explicitly link libc? +# +case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in +x|xyes) + # Assume -lc should be added + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + + if test yes,yes = "$GCC,$enable_shared"; then + case $_LT_TAGVAR(archive_cmds, $1) in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + AC_CACHE_CHECK([whether -lc should be explicitly linked in], + [lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1), + [$RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if AC_TRY_EVAL(ac_compile) 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) + pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1) + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1) + _LT_TAGVAR(allow_undefined_flag, $1)= + if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) + then + lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no + else + lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes + fi + _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + ]) + _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1) + ;; + esac + fi + ;; +esac + +_LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0], + [Whether or not to add -lc for building shared libraries]) +_LT_TAGDECL([allow_libtool_libs_with_static_runtimes], + [enable_shared_with_static_runtimes], [0], + [Whether or not to disallow shared libs when runtime libs are static]) +_LT_TAGDECL([], [export_dynamic_flag_spec], [1], + [Compiler flag to allow reflexive dlopens]) +_LT_TAGDECL([], [whole_archive_flag_spec], [1], + [Compiler flag to generate shared objects directly from archives]) +_LT_TAGDECL([], [compiler_needs_object], [1], + [Whether the compiler copes with passing no objects directly]) +_LT_TAGDECL([], [old_archive_from_new_cmds], [2], + [Create an old-style archive from a shared archive]) +_LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2], + [Create a temporary old-style archive to link instead of a shared archive]) +_LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive]) +_LT_TAGDECL([], [archive_expsym_cmds], [2]) +_LT_TAGDECL([], [module_cmds], [2], + [Commands used to build a loadable module if different from building + a shared archive.]) +_LT_TAGDECL([], [module_expsym_cmds], [2]) +_LT_TAGDECL([], [with_gnu_ld], [1], + [Whether we are building with GNU ld or not]) +_LT_TAGDECL([], [allow_undefined_flag], [1], + [Flag that allows shared libraries with undefined symbols to be built]) +_LT_TAGDECL([], [no_undefined_flag], [1], + [Flag that enforces no undefined symbols]) +_LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], + [Flag to hardcode $libdir into a binary during linking. + This must work even if $libdir does not exist]) +_LT_TAGDECL([], [hardcode_libdir_separator], [1], + [Whether we need a single "-rpath" flag with a separated argument]) +_LT_TAGDECL([], [hardcode_direct], [0], + [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes + DIR into the resulting binary]) +_LT_TAGDECL([], [hardcode_direct_absolute], [0], + [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes + DIR into the resulting binary and the resulting library dependency is + "absolute", i.e impossible to change by setting $shlibpath_var if the + library is relocated]) +_LT_TAGDECL([], [hardcode_minus_L], [0], + [Set to "yes" if using the -LDIR flag during linking hardcodes DIR + into the resulting binary]) +_LT_TAGDECL([], [hardcode_shlibpath_var], [0], + [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR + into the resulting binary]) +_LT_TAGDECL([], [hardcode_automatic], [0], + [Set to "yes" if building a shared library automatically hardcodes DIR + into the library and all subsequent libraries and executables linked + against it]) +_LT_TAGDECL([], [inherit_rpath], [0], + [Set to yes if linker adds runtime paths of dependent libraries + to runtime path list]) +_LT_TAGDECL([], [link_all_deplibs], [0], + [Whether libtool must link a program against all its dependency libraries]) +_LT_TAGDECL([], [always_export_symbols], [0], + [Set to "yes" if exported symbols are required]) +_LT_TAGDECL([], [export_symbols_cmds], [2], + [The commands to list exported symbols]) +_LT_TAGDECL([], [exclude_expsyms], [1], + [Symbols that should not be listed in the preloaded symbols]) +_LT_TAGDECL([], [include_expsyms], [1], + [Symbols that must always be exported]) +_LT_TAGDECL([], [prelink_cmds], [2], + [Commands necessary for linking programs (against libraries) with templates]) +_LT_TAGDECL([], [postlink_cmds], [2], + [Commands necessary for finishing linking programs]) +_LT_TAGDECL([], [file_list_spec], [1], + [Specify filename containing input files]) +dnl FIXME: Not yet implemented +dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1], +dnl [Compiler flag to generate thread safe objects]) +])# _LT_LINKER_SHLIBS + + +# _LT_LANG_C_CONFIG([TAG]) +# ------------------------ +# Ensure that the configuration variables for a C compiler are suitably +# defined. These variables are subsequently used by _LT_CONFIG to write +# the compiler configuration to 'libtool'. +m4_defun([_LT_LANG_C_CONFIG], +[m4_require([_LT_DECL_EGREP])dnl +lt_save_CC=$CC +AC_LANG_PUSH(C) + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}' + +_LT_TAG_COMPILER +# Save the default compiler, since it gets overwritten when the other +# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. +compiler_DEFAULT=$CC + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + LT_SYS_DLOPEN_SELF + _LT_CMD_STRIPLIB + + # Report what library types will actually be built + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test no = "$can_build_shared" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test yes = "$enable_shared" && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + + aix[[4-9]]*) + if test ia64 != "$host_cpu"; then + case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in + yes,aix,yes) ;; # shared object as lib.so file only + yes,svr4,*) ;; # shared object as lib.so archive member only + yes,*) enable_static=no ;; # shared object in lib.a archive as well + esac + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test yes = "$enable_shared" || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_CONFIG($1) +fi +AC_LANG_POP +CC=$lt_save_CC +])# _LT_LANG_C_CONFIG + + +# _LT_LANG_CXX_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for a C++ compiler are suitably +# defined. These variables are subsequently used by _LT_CONFIG to write +# the compiler configuration to 'libtool'. +m4_defun([_LT_LANG_CXX_CONFIG], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_PATH_MANIFEST_TOOL])dnl +if test -n "$CXX" && ( test no != "$CXX" && + ( (test g++ = "$CXX" && `g++ -v >/dev/null 2>&1` ) || + (test g++ != "$CXX"))); then + AC_PROG_CXXCPP +else + _lt_caught_CXX_error=yes +fi + +AC_LANG_PUSH(C++) +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(compiler_needs_object, $1)=no +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for C++ test sources. +ac_ext=cpp + +# Object file extension for compiled C++ test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the CXX compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test yes != "$_lt_caught_CXX_error"; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="int some_variable = 0;" + + # Code to be used in simple link tests + lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC=$CC + lt_save_CFLAGS=$CFLAGS + lt_save_LD=$LD + lt_save_GCC=$GCC + GCC=$GXX + lt_save_with_gnu_ld=$with_gnu_ld + lt_save_path_LD=$lt_cv_path_LD + if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then + lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx + else + $as_unset lt_cv_prog_gnu_ld + fi + if test -n "${lt_cv_path_LDCXX+set}"; then + lt_cv_path_LD=$lt_cv_path_LDCXX + else + $as_unset lt_cv_path_LD + fi + test -z "${LDCXX+set}" || LD=$LDCXX + CC=${CXX-"c++"} + CFLAGS=$CXXFLAGS + compiler=$CC + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + + if test -n "$compiler"; then + # We don't want -fno-exception when compiling C++ code, so set the + # no_builtin_flag separately + if test yes = "$GXX"; then + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' + else + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= + fi + + if test yes = "$GXX"; then + # Set up default GNU C++ configuration + + LT_PATH_LD + + # Check if GNU C++ uses GNU ld as the underlying linker, since the + # archiving commands below assume that GNU ld is being used. + if test yes = "$with_gnu_ld"; then + _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' + + # If archive_cmds runs LD, not CC, wlarc should be empty + # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to + # investigate it a little bit more. (MM) + wlarc='$wl' + + # ancient GNU ld didn't support --whole-archive et. al. + if eval "`$CC -print-prog-name=ld` --help 2>&1" | + $GREP 'no-whole-archive' > /dev/null; then + _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + with_gnu_ld=no + wlarc= + + # A generic and very simple default shared library creation + # command for GNU C++ for the case where it uses the native + # linker, instead of GNU ld. If possible, this setting should + # overridden to take advantage of the native linker features on + # the platform it is being used on. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + fi + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + + else + GXX=no + with_gnu_ld=no + wlarc= + fi + + # PORTME: fill in a description of your system's C++ link characteristics + AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) + _LT_TAGVAR(ld_shlibs, $1)=yes + case $host_os in + aix3*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aix[[4-9]]*) + if test ia64 = "$host_cpu"; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag= + else + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # have runtime linking enabled, and use it for executables. + # For shared libraries, we enable/disable runtime linking + # depending on the kind of the shared library created - + # when "with_aix_soname,aix_use_runtimelinking" is: + # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables + # "aix,yes" lib.so shared, rtl:yes, for executables + # lib.a static archive + # "both,no" lib.so.V(shr.o) shared, rtl:yes + # lib.a(lib.so.V) shared, rtl:no, for executables + # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a(lib.so.V) shared, rtl:no + # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a static archive + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) + for ld_flag in $LDFLAGS; do + case $ld_flag in + *-brtl*) + aix_use_runtimelinking=yes + break + ;; + esac + done + if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then + # With aix-soname=svr4, we create the lib.so.V shared archives only, + # so we don't have lib.a shared libs to link our executables. + # We have to force runtime linking in this case. + aix_use_runtimelinking=yes + LDFLAGS="$LDFLAGS -Wl,-brtl" + fi + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_TAGVAR(archive_cmds, $1)='' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='$wl-f,' + case $with_aix_soname,$aix_use_runtimelinking in + aix,*) ;; # no import file + svr4,* | *,yes) # use import file + # The Import File defines what to hardcode. + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=no + ;; + esac + + if test yes = "$GXX"; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`$CC -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + _LT_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)= + fi + esac + shared_flag='-shared' + if test yes = "$aix_use_runtimelinking"; then + shared_flag=$shared_flag' $wl-G' + fi + # Need to ensure runtime linking is disabled for the traditional + # shared library, or the linker may eventually find shared libraries + # /with/ Import File - we do not want to mix them. + shared_flag_aix='-shared' + shared_flag_svr4='-shared $wl-G' + else + # not using gcc + if test ia64 = "$host_cpu"; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test yes = "$aix_use_runtimelinking"; then + shared_flag='$wl-G' + else + shared_flag='$wl-bM:SRE' + fi + shared_flag_aix='$wl-bM:SRE' + shared_flag_svr4='$wl-G' + fi + fi + + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to + # export. + _LT_TAGVAR(always_export_symbols, $1)=yes + if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + # The "-G" linker flag allows undefined symbols. + _LT_TAGVAR(no_undefined_flag, $1)='-bernotok' + # Determine the default libpath from the value encoded in an empty + # executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" + + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag + else + if test ia64 = "$host_cpu"; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib' + _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok' + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok' + if test yes = "$with_gnu_ld"; then + # We only use this code for GNU lds that support --whole-archive. + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' + # -brtl affects multiple linker settings, -berok does not and is overridden later + compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`' + if test svr4 != "$with_aix_soname"; then + # This is similar to how AIX traditionally builds its shared + # libraries. Need -bnortl late, we may have -brtl in LDFLAGS. + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' + fi + if test aix != "$with_aix_soname"; then + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' + else + # used by -dlpreopen to get the symbols + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV $output_objdir/$realname.d/$soname $output_objdir' + fi + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d' + fi + fi + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach <jrb3@best.com> says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + chorus*) + case $cc_basename in + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + cygwin* | mingw* | pw32* | cegcc*) + case $GXX,$cc_basename in + ,cl* | no,cl*) + # Native MSVC + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=.dll + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' + _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then + cp "$export_symbols" "$output_objdir/$soname.def"; + echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; + else + $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + # Don't use ranlib + _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' + _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile=$lt_outputfile.exe + lt_tool_outputfile=$lt_tool_outputfile.exe + ;; + esac~ + func_to_tool_file "$lt_outputfile"~ + if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # g++ + # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file, use it as + # is; otherwise, prepend EXPORTS... + _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + darwin* | rhapsody*) + _LT_DARWIN_LINKER_FEATURES($1) + ;; + + os2*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + shrext_cmds=.dll + _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + prefix_cmds="$SED"~ + if test EXPORTS = "`$SED 1q $export_symbols`"; then + prefix_cmds="$prefix_cmds -e 1d"; + fi~ + prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ + cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + ;; + + dgux*) + case $cc_basename in + ec++*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + ghcx*) + # Green Hills C++ Compiler + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + freebsd2.*) + # C++ shared libraries reported to be fairly broken before + # switch to ELF + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + freebsd-elf*) + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + ;; + + freebsd* | dragonfly*) + # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF + # conventions + _LT_TAGVAR(ld_shlibs, $1)=yes + ;; + + haiku*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + hpux9*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aCC*) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test yes = "$GXX"; then + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + hpux10*|hpux11*) + if test no = "$with_gnu_ld"; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + case $host_cpu in + hppa*64*|ia64*) + ;; + *) + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + ;; + esac + fi + case $host_cpu in + hppa*64*|ia64*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + *) + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + ;; + esac + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aCC*) + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test yes = "$GXX"; then + if test no = "$with_gnu_ld"; then + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + fi + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + interix[[3-9]]*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + irix5* | irix6*) + case $cc_basename in + CC*) + # SGI C++ + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + + # Archives containing C++ object files must be created using + # "CC -ar", where "CC" is the IRIX C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' + ;; + *) + if test yes = "$GXX"; then + if test no = "$with_gnu_ld"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` -o $lib' + fi + fi + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + esac + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(inherit_rpath, $1)=yes + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv \$templib $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' + ;; + icpc* | ecpc* ) + # Intel C++ + with_gnu_ld=yes + # version 8.0 and above of icpc choke on multiply defined symbols + # if we add $predep_objects and $postdep_objects, however 7.1 and + # earlier do not add the objects themselves. + case `$CC -V 2>&1` in + *"Version 7."*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 8.0 or newer + tmp_idyn= + case $host_cpu in + ia64*) tmp_idyn=' -i_dynamic';; + esac + _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + case `$CC -V` in + *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*) + _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ + compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' + _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ + $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ + $RANLIB $oldlib' + _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 6 and above use weak symbols + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl--rpath $wl$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + ;; + cxx*) + # Compaq C++ + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib $wl-retain-symbols-file $wl$export_symbols' + + runpath_var=LD_RUN_PATH + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' + ;; + xl* | mpixl* | bgxl*) + # IBM XL 8.0 on PPC, with GNU ld + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' + _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + if test yes = "$supports_anon_versioning"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' + fi + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' + _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file $wl$export_symbols' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + + # Not sure whether something based on + # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 + # would be better. + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' + ;; + esac + ;; + esac + ;; + + lynxos*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + m88k*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + mvs*) + case $cc_basename in + cxx*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' + wlarc= + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + fi + # Workaround some broken pre-1.5 toolchains + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' + ;; + + *nto* | *qnx*) + _LT_TAGVAR(ld_shlibs, $1)=yes + ;; + + openbsd* | bitrig*) + if test -f /usr/libexec/ld.so; then + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file,$export_symbols -o $lib' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' + fi + output_verbose_link_cmd=func_echo_all + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Archives containing C++ object files must be created using + # the KAI C++ compiler. + case $host in + osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; + *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; + esac + ;; + RCC*) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + cxx*) + case $host in + osf3*) + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $soname `test -n "$verstring" && func_echo_all "$wl-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + ;; + *) + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ + echo "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname $wl-input $wl$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~ + $RM $lib.exp' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test yes,no = "$GXX,$with_gnu_ld"; then + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' + case $host in + osf3*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + psos*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + lcc*) + # Lucid + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_TAGVAR(archive_cmds_need_lc,$1)=yes + _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' + _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G$allow_undefined_flag $wl-M $wl$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands '-z linker_flag'. + # Supported since Solaris 2.6 (maybe 2.5.1?) + _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' + ;; + esac + _LT_TAGVAR(link_all_deplibs, $1)=yes + + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' + ;; + gcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' + + # The C++ compiler must be used to create the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' + ;; + *) + # GNU C++ compiler with Solaris linker + if test yes,no = "$GXX,$with_gnu_ld"; then + _LT_TAGVAR(no_undefined_flag, $1)=' $wl-z ${wl}defs' + if $CC --version | $GREP -v '^2\.7' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + else + # g++ 2.7 appears to require '-G' NOT '-shared' on this + # platform. + _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + fi + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $wl$libdir' + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' + ;; + esac + fi + ;; + esac + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) + _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We CANNOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' + _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport' + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~ + '"$_LT_TAGVAR(old_archive_cmds, $1)" + _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~ + '"$_LT_TAGVAR(reload_cmds, $1)" + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + vxworks*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + + AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) + test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no + + _LT_TAGVAR(GCC, $1)=$GXX + _LT_TAGVAR(LD, $1)=$LD + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_SYS_HIDDEN_LIBDEPS($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS + LDCXX=$LD + LD=$lt_save_LD + GCC=$lt_save_GCC + with_gnu_ld=$lt_save_with_gnu_ld + lt_cv_path_LDCXX=$lt_cv_path_LD + lt_cv_path_LD=$lt_save_path_LD + lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld + lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld +fi # test yes != "$_lt_caught_CXX_error" + +AC_LANG_POP +])# _LT_LANG_CXX_CONFIG + + +# _LT_FUNC_STRIPNAME_CNF +# ---------------------- +# func_stripname_cnf prefix suffix name +# strip PREFIX and SUFFIX off of NAME. +# PREFIX and SUFFIX must not contain globbing or regex special +# characters, hashes, percent signs, but SUFFIX may contain a leading +# dot (in which case that matches only a dot). +# +# This function is identical to the (non-XSI) version of func_stripname, +# except this one can be used by m4 code that may be executed by configure, +# rather than the libtool script. +m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl +AC_REQUIRE([_LT_DECL_SED]) +AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH]) +func_stripname_cnf () +{ + case @S|@2 in + .*) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%\\\\@S|@2\$%%"`;; + *) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%@S|@2\$%%"`;; + esac +} # func_stripname_cnf +])# _LT_FUNC_STRIPNAME_CNF + + +# _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) +# --------------------------------- +# Figure out "hidden" library dependencies from verbose +# compiler output when linking a shared library. +# Parse the compiler output and extract the necessary +# objects, libraries and library flags. +m4_defun([_LT_SYS_HIDDEN_LIBDEPS], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl +# Dependencies to place before and after the object being linked: +_LT_TAGVAR(predep_objects, $1)= +_LT_TAGVAR(postdep_objects, $1)= +_LT_TAGVAR(predeps, $1)= +_LT_TAGVAR(postdeps, $1)= +_LT_TAGVAR(compiler_lib_search_path, $1)= + +dnl we can't use the lt_simple_compile_test_code here, +dnl because it contains code intended for an executable, +dnl not a library. It's possible we should let each +dnl tag define a new lt_????_link_test_code variable, +dnl but it's only used here... +m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF +int a; +void foo (void) { a = 0; } +_LT_EOF +], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF +class Foo +{ +public: + Foo (void) { a = 0; } +private: + int a; +}; +_LT_EOF +], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF + subroutine foo + implicit none + integer*4 a + a=0 + return + end +_LT_EOF +], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF + subroutine foo + implicit none + integer a + a=0 + return + end +_LT_EOF +], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF +public class foo { + private int a; + public void bar (void) { + a = 0; + } +}; +_LT_EOF +], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF +package foo +func foo() { +} +_LT_EOF +]) + +_lt_libdeps_save_CFLAGS=$CFLAGS +case "$CC $CFLAGS " in #( +*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; +*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; +*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; +esac + +dnl Parse the compiler output and extract the necessary +dnl objects, libraries and library flags. +if AC_TRY_EVAL(ac_compile); then + # Parse the compiler output and extract the necessary + # objects, libraries and library flags. + + # Sentinel used to keep track of whether or not we are before + # the conftest object file. + pre_test_object_deps_done=no + + for p in `eval "$output_verbose_link_cmd"`; do + case $prev$p in + + -L* | -R* | -l*) + # Some compilers place space between "-{L,R}" and the path. + # Remove the space. + if test x-L = "$p" || + test x-R = "$p"; then + prev=$p + continue + fi + + # Expand the sysroot to ease extracting the directories later. + if test -z "$prev"; then + case $p in + -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; + -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; + -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; + esac + fi + case $p in + =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; + esac + if test no = "$pre_test_object_deps_done"; then + case $prev in + -L | -R) + # Internal compiler library paths should come after those + # provided the user. The postdeps already come after the + # user supplied libs so there is no need to process them. + if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then + _LT_TAGVAR(compiler_lib_search_path, $1)=$prev$p + else + _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} $prev$p" + fi + ;; + # The "-l" case would never come before the object being + # linked, so don't bother handling this case. + esac + else + if test -z "$_LT_TAGVAR(postdeps, $1)"; then + _LT_TAGVAR(postdeps, $1)=$prev$p + else + _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} $prev$p" + fi + fi + prev= + ;; + + *.lto.$objext) ;; # Ignore GCC LTO objects + *.$objext) + # This assumes that the test object file only shows up + # once in the compiler output. + if test "$p" = "conftest.$objext"; then + pre_test_object_deps_done=yes + continue + fi + + if test no = "$pre_test_object_deps_done"; then + if test -z "$_LT_TAGVAR(predep_objects, $1)"; then + _LT_TAGVAR(predep_objects, $1)=$p + else + _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" + fi + else + if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then + _LT_TAGVAR(postdep_objects, $1)=$p + else + _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" + fi + fi + ;; + + *) ;; # Ignore the rest. + + esac + done + + # Clean up. + rm -f a.out a.exe +else + echo "libtool.m4: error: problem compiling $1 test program" +fi + +$RM -f confest.$objext +CFLAGS=$_lt_libdeps_save_CFLAGS + +# PORTME: override above test on systems where it is broken +m4_if([$1], [CXX], +[case $host_os in +interix[[3-9]]*) + # Interix 3.5 installs completely hosed .la files for C++, so rather than + # hack all around it, let's just trust "g++" to DTRT. + _LT_TAGVAR(predep_objects,$1)= + _LT_TAGVAR(postdep_objects,$1)= + _LT_TAGVAR(postdeps,$1)= + ;; +esac +]) + +case " $_LT_TAGVAR(postdeps, $1) " in +*" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; +esac + _LT_TAGVAR(compiler_lib_search_dirs, $1)= +if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then + _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | $SED -e 's! -L! !g' -e 's!^ !!'` +fi +_LT_TAGDECL([], [compiler_lib_search_dirs], [1], + [The directories searched by this compiler when creating a shared library]) +_LT_TAGDECL([], [predep_objects], [1], + [Dependencies to place before and after the objects being linked to + create a shared library]) +_LT_TAGDECL([], [postdep_objects], [1]) +_LT_TAGDECL([], [predeps], [1]) +_LT_TAGDECL([], [postdeps], [1]) +_LT_TAGDECL([], [compiler_lib_search_path], [1], + [The library search path used internally by the compiler when linking + a shared library]) +])# _LT_SYS_HIDDEN_LIBDEPS + + +# _LT_LANG_F77_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for a Fortran 77 compiler are +# suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to 'libtool'. +m4_defun([_LT_LANG_F77_CONFIG], +[AC_LANG_PUSH(Fortran 77) +if test -z "$F77" || test no = "$F77"; then + _lt_disable_F77=yes +fi + +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for f77 test sources. +ac_ext=f + +# Object file extension for compiled f77 test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the F77 compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test yes != "$_lt_disable_F77"; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="\ + subroutine t + return + end +" + + # Code to be used in simple link tests + lt_simple_link_test_code="\ + program t + end +" + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC=$CC + lt_save_GCC=$GCC + lt_save_CFLAGS=$CFLAGS + CC=${F77-"f77"} + CFLAGS=$FFLAGS + compiler=$CC + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + GCC=$G77 + if test -n "$compiler"; then + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test no = "$can_build_shared" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test yes = "$enable_shared" && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + aix[[4-9]]*) + if test ia64 != "$host_cpu"; then + case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in + yes,aix,yes) ;; # shared object as lib.so file only + yes,svr4,*) ;; # shared object as lib.so archive member only + yes,*) enable_static=no ;; # shared object in lib.a archive as well + esac + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test yes = "$enable_shared" || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_TAGVAR(GCC, $1)=$G77 + _LT_TAGVAR(LD, $1)=$LD + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + GCC=$lt_save_GCC + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS +fi # test yes != "$_lt_disable_F77" + +AC_LANG_POP +])# _LT_LANG_F77_CONFIG + + +# _LT_LANG_FC_CONFIG([TAG]) +# ------------------------- +# Ensure that the configuration variables for a Fortran compiler are +# suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to 'libtool'. +m4_defun([_LT_LANG_FC_CONFIG], +[AC_LANG_PUSH(Fortran) + +if test -z "$FC" || test no = "$FC"; then + _lt_disable_FC=yes +fi + +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for fc test sources. +ac_ext=${ac_fc_srcext-f} + +# Object file extension for compiled fc test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the FC compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test yes != "$_lt_disable_FC"; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="\ + subroutine t + return + end +" + + # Code to be used in simple link tests + lt_simple_link_test_code="\ + program t + end +" + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC=$CC + lt_save_GCC=$GCC + lt_save_CFLAGS=$CFLAGS + CC=${FC-"f95"} + CFLAGS=$FCFLAGS + compiler=$CC + GCC=$ac_cv_fc_compiler_gnu + + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + + if test -n "$compiler"; then + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test no = "$can_build_shared" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test yes = "$enable_shared" && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + aix[[4-9]]*) + if test ia64 != "$host_cpu"; then + case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in + yes,aix,yes) ;; # shared object as lib.so file only + yes,svr4,*) ;; # shared object as lib.so archive member only + yes,*) enable_static=no ;; # shared object in lib.a archive as well + esac + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test yes = "$enable_shared" || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_TAGVAR(GCC, $1)=$ac_cv_fc_compiler_gnu + _LT_TAGVAR(LD, $1)=$LD + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_SYS_HIDDEN_LIBDEPS($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + GCC=$lt_save_GCC + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS +fi # test yes != "$_lt_disable_FC" + +AC_LANG_POP +])# _LT_LANG_FC_CONFIG + + +# _LT_LANG_GCJ_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for the GNU Java Compiler compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to 'libtool'. +m4_defun([_LT_LANG_GCJ_CONFIG], +[AC_REQUIRE([LT_PROG_GCJ])dnl +AC_LANG_SAVE + +# Source file extension for Java test sources. +ac_ext=java + +# Object file extension for compiled Java test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="class foo {}" + +# Code to be used in simple link tests +lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_CFLAGS=$CFLAGS +lt_save_GCC=$GCC +GCC=yes +CC=${GCJ-"gcj"} +CFLAGS=$GCJFLAGS +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_TAGVAR(LD, $1)=$LD +_LT_CC_BASENAME([$compiler]) + +# GCJ did not exist at the time GCC didn't implicitly link libc in. +_LT_TAGVAR(archive_cmds_need_lc, $1)=no + +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) +fi + +AC_LANG_RESTORE + +GCC=$lt_save_GCC +CC=$lt_save_CC +CFLAGS=$lt_save_CFLAGS +])# _LT_LANG_GCJ_CONFIG + + +# _LT_LANG_GO_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for the GNU Go compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to 'libtool'. +m4_defun([_LT_LANG_GO_CONFIG], +[AC_REQUIRE([LT_PROG_GO])dnl +AC_LANG_SAVE + +# Source file extension for Go test sources. +ac_ext=go + +# Object file extension for compiled Go test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="package main; func main() { }" + +# Code to be used in simple link tests +lt_simple_link_test_code='package main; func main() { }' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_CFLAGS=$CFLAGS +lt_save_GCC=$GCC +GCC=yes +CC=${GOC-"gccgo"} +CFLAGS=$GOFLAGS +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_TAGVAR(LD, $1)=$LD +_LT_CC_BASENAME([$compiler]) + +# Go did not exist at the time GCC didn't implicitly link libc in. +_LT_TAGVAR(archive_cmds_need_lc, $1)=no + +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) +fi + +AC_LANG_RESTORE + +GCC=$lt_save_GCC +CC=$lt_save_CC +CFLAGS=$lt_save_CFLAGS +])# _LT_LANG_GO_CONFIG + + +# _LT_LANG_RC_CONFIG([TAG]) +# ------------------------- +# Ensure that the configuration variables for the Windows resource compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to 'libtool'. +m4_defun([_LT_LANG_RC_CONFIG], +[AC_REQUIRE([LT_PROG_RC])dnl +AC_LANG_SAVE + +# Source file extension for RC test sources. +ac_ext=rc + +# Object file extension for compiled RC test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' + +# Code to be used in simple link tests +lt_simple_link_test_code=$lt_simple_compile_test_code + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_CFLAGS=$CFLAGS +lt_save_GCC=$GCC +GCC= +CC=${RC-"windres"} +CFLAGS= +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_CC_BASENAME([$compiler]) +_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes + +if test -n "$compiler"; then + : + _LT_CONFIG($1) +fi + +GCC=$lt_save_GCC +AC_LANG_RESTORE +CC=$lt_save_CC +CFLAGS=$lt_save_CFLAGS +])# _LT_LANG_RC_CONFIG + + +# LT_PROG_GCJ +# ----------- +AC_DEFUN([LT_PROG_GCJ], +[m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], + [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], + [AC_CHECK_TOOL(GCJ, gcj,) + test set = "${GCJFLAGS+set}" || GCJFLAGS="-g -O2" + AC_SUBST(GCJFLAGS)])])[]dnl +]) + +# Old name: +AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_GCJ], []) + + +# LT_PROG_GO +# ---------- +AC_DEFUN([LT_PROG_GO], +[AC_CHECK_TOOL(GOC, gccgo,) +]) + + +# LT_PROG_RC +# ---------- +AC_DEFUN([LT_PROG_RC], +[AC_CHECK_TOOL(RC, windres,) +]) + +# Old name: +AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_RC], []) + + +# _LT_DECL_EGREP +# -------------- +# If we don't have a new enough Autoconf to choose the best grep +# available, choose the one first in the user's PATH. +m4_defun([_LT_DECL_EGREP], +[AC_REQUIRE([AC_PROG_EGREP])dnl +AC_REQUIRE([AC_PROG_FGREP])dnl +test -z "$GREP" && GREP=grep +_LT_DECL([], [GREP], [1], [A grep program that handles long lines]) +_LT_DECL([], [EGREP], [1], [An ERE matcher]) +_LT_DECL([], [FGREP], [1], [A literal string matcher]) +dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too +AC_SUBST([GREP]) +]) + + +# _LT_DECL_OBJDUMP +# -------------- +# If we don't have a new enough Autoconf to choose the best objdump +# available, choose the one first in the user's PATH. +m4_defun([_LT_DECL_OBJDUMP], +[AC_CHECK_TOOL(OBJDUMP, objdump, false) +test -z "$OBJDUMP" && OBJDUMP=objdump +_LT_DECL([], [OBJDUMP], [1], [An object symbol dumper]) +AC_SUBST([OBJDUMP]) +]) + +# _LT_DECL_DLLTOOL +# ---------------- +# Ensure DLLTOOL variable is set. +m4_defun([_LT_DECL_DLLTOOL], +[AC_CHECK_TOOL(DLLTOOL, dlltool, false) +test -z "$DLLTOOL" && DLLTOOL=dlltool +_LT_DECL([], [DLLTOOL], [1], [DLL creation program]) +AC_SUBST([DLLTOOL]) +]) + +# _LT_DECL_SED +# ------------ +# Check for a fully-functional sed program, that truncates +# as few characters as possible. Prefer GNU sed if found. +m4_defun([_LT_DECL_SED], +[AC_PROG_SED +test -z "$SED" && SED=sed +Xsed="$SED -e 1s/^X//" +_LT_DECL([], [SED], [1], [A sed program that does not truncate output]) +_LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], + [Sed that helps us avoid accidentally triggering echo(1) options like -n]) +])# _LT_DECL_SED + +m4_ifndef([AC_PROG_SED], [ +############################################################ +# NOTE: This macro has been submitted for inclusion into # +# GNU Autoconf as AC_PROG_SED. When it is available in # +# a released version of Autoconf we should remove this # +# macro and use it instead. # +############################################################ + +m4_defun([AC_PROG_SED], +[AC_MSG_CHECKING([for a sed that does not truncate output]) +AC_CACHE_VAL(lt_cv_path_SED, +[# Loop through the user's path and test for sed and gsed. +# Then use that list of sed's as ones to test for truncation. +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for lt_ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then + lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" + fi + done + done +done +IFS=$as_save_IFS +lt_ac_max=0 +lt_ac_count=0 +# Add /usr/xpg4/bin/sed as it is typically found on Solaris +# along with /bin/sed that truncates output. +for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do + test ! -f "$lt_ac_sed" && continue + cat /dev/null > conftest.in + lt_ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >conftest.in + # Check for GNU sed and select it if it is found. + if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then + lt_cv_path_SED=$lt_ac_sed + break + fi + while true; do + cat conftest.in conftest.in >conftest.tmp + mv conftest.tmp conftest.in + cp conftest.in conftest.nl + echo >>conftest.nl + $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break + cmp -s conftest.out conftest.nl || break + # 10000 chars as input seems more than enough + test 10 -lt "$lt_ac_count" && break + lt_ac_count=`expr $lt_ac_count + 1` + if test "$lt_ac_count" -gt "$lt_ac_max"; then + lt_ac_max=$lt_ac_count + lt_cv_path_SED=$lt_ac_sed + fi + done +done +]) +SED=$lt_cv_path_SED +AC_SUBST([SED]) +AC_MSG_RESULT([$SED]) +])#AC_PROG_SED +])#m4_ifndef + +# Old name: +AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_SED], []) + + +# _LT_CHECK_SHELL_FEATURES +# ------------------------ +# Find out whether the shell is Bourne or XSI compatible, +# or has some other useful features. +m4_defun([_LT_CHECK_SHELL_FEATURES], +[if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + lt_unset=unset +else + lt_unset=false +fi +_LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl + +# test EBCDIC or ASCII +case `echo X|tr X '\101'` in + A) # ASCII based system + # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr + lt_SP2NL='tr \040 \012' + lt_NL2SP='tr \015\012 \040\040' + ;; + *) # EBCDIC based system + lt_SP2NL='tr \100 \n' + lt_NL2SP='tr \r\n \100\100' + ;; +esac +_LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl +_LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl +])# _LT_CHECK_SHELL_FEATURES + + +# _LT_PATH_CONVERSION_FUNCTIONS +# ----------------------------- +# Determine what file name conversion functions should be used by +# func_to_host_file (and, implicitly, by func_to_host_path). These are needed +# for certain cross-compile configurations and native mingw. +m4_defun([_LT_PATH_CONVERSION_FUNCTIONS], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_MSG_CHECKING([how to convert $build file names to $host format]) +AC_CACHE_VAL(lt_cv_to_host_file_cmd, +[case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 + ;; + esac + ;; + *-*-cygwin* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin + ;; + esac + ;; + * ) # unhandled hosts (and "normal" native builds) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; +esac +]) +to_host_file_cmd=$lt_cv_to_host_file_cmd +AC_MSG_RESULT([$lt_cv_to_host_file_cmd]) +_LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd], + [0], [convert $build file names to $host format])dnl + +AC_MSG_CHECKING([how to convert $build file names to toolchain format]) +AC_CACHE_VAL(lt_cv_to_tool_file_cmd, +[#assume ordinary cross tools, or native build. +lt_cv_to_tool_file_cmd=func_convert_file_noop +case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 + ;; + esac + ;; +esac +]) +to_tool_file_cmd=$lt_cv_to_tool_file_cmd +AC_MSG_RESULT([$lt_cv_to_tool_file_cmd]) +_LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd], + [0], [convert $build files to toolchain format])dnl +])# _LT_PATH_CONVERSION_FUNCTIONS diff --git a/config/ltmain.sh b/config/ltmain.sh new file mode 100644 index 0000000..0f0a2da --- /dev/null +++ b/config/ltmain.sh @@ -0,0 +1,11147 @@ +#! /bin/sh +## DO NOT EDIT - This file generated from ./build-aux/ltmain.in +## by inline-source v2014-01-03.01 + +# libtool (GNU libtool) 2.4.6 +# Provide generalized library-building support services. +# Written by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996 + +# Copyright (C) 1996-2015 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# GNU Libtool is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# As a special exception to the GNU General Public License, +# if you distribute this file as part of a program or library that +# is built using GNU Libtool, you may include this file under the +# same distribution terms that you use for the rest of that program. +# +# GNU Libtool is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + + +PROGRAM=libtool +PACKAGE=libtool +VERSION=2.4.6 +package_revision=2.4.6 + + +## ------ ## +## Usage. ## +## ------ ## + +# Run './libtool --help' for help with using this script from the +# command line. + + +## ------------------------------- ## +## User overridable command paths. ## +## ------------------------------- ## + +# After configure completes, it has a better idea of some of the +# shell tools we need than the defaults used by the functions shared +# with bootstrap, so set those here where they can still be over- +# ridden by the user, but otherwise take precedence. + +: ${AUTOCONF="autoconf"} +: ${AUTOMAKE="automake"} + + +## -------------------------- ## +## Source external libraries. ## +## -------------------------- ## + +# Much of our low-level functionality needs to be sourced from external +# libraries, which are installed to $pkgauxdir. + +# Set a version string for this script. +scriptversion=2015-01-20.17; # UTC + +# General shell script boiler plate, and helper functions. +# Written by Gary V. Vaughan, 2004 + +# Copyright (C) 2004-2015 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# 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. + +# As a special exception to the GNU General Public License, if you distribute +# this file as part of a program or library that is built using GNU Libtool, +# you may include this file under the same distribution terms that you use +# for the rest of that program. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNES FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +# Please report bugs or propose patches to gary@gnu.org. + + +## ------ ## +## Usage. ## +## ------ ## + +# Evaluate this file near the top of your script to gain access to +# the functions and variables defined here: +# +# . `echo "$0" | ${SED-sed} 's|[^/]*$||'`/build-aux/funclib.sh +# +# If you need to override any of the default environment variable +# settings, do that before evaluating this file. + + +## -------------------- ## +## Shell normalisation. ## +## -------------------- ## + +# Some shells need a little help to be as Bourne compatible as possible. +# Before doing anything else, make sure all that help has been provided! + +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac +fi + +# NLS nuisances: We save the old values in case they are required later. +_G_user_locale= +_G_safe_locale= +for _G_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES +do + eval "if test set = \"\${$_G_var+set}\"; then + save_$_G_var=\$$_G_var + $_G_var=C + export $_G_var + _G_user_locale=\"$_G_var=\\\$save_\$_G_var; \$_G_user_locale\" + _G_safe_locale=\"$_G_var=C; \$_G_safe_locale\" + fi" +done + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +# Make sure IFS has a sensible default +sp=' ' +nl=' +' +IFS="$sp $nl" + +# There are apparently some retarded systems that use ';' as a PATH separator! +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + + +## ------------------------- ## +## Locate command utilities. ## +## ------------------------- ## + + +# func_executable_p FILE +# ---------------------- +# Check that FILE is an executable regular file. +func_executable_p () +{ + test -f "$1" && test -x "$1" +} + + +# func_path_progs PROGS_LIST CHECK_FUNC [PATH] +# -------------------------------------------- +# Search for either a program that responds to --version with output +# containing "GNU", or else returned by CHECK_FUNC otherwise, by +# trying all the directories in PATH with each of the elements of +# PROGS_LIST. +# +# CHECK_FUNC should accept the path to a candidate program, and +# set $func_check_prog_result if it truncates its output less than +# $_G_path_prog_max characters. +func_path_progs () +{ + _G_progs_list=$1 + _G_check_func=$2 + _G_PATH=${3-"$PATH"} + + _G_path_prog_max=0 + _G_path_prog_found=false + _G_save_IFS=$IFS; IFS=${PATH_SEPARATOR-:} + for _G_dir in $_G_PATH; do + IFS=$_G_save_IFS + test -z "$_G_dir" && _G_dir=. + for _G_prog_name in $_G_progs_list; do + for _exeext in '' .EXE; do + _G_path_prog=$_G_dir/$_G_prog_name$_exeext + func_executable_p "$_G_path_prog" || continue + case `"$_G_path_prog" --version 2>&1` in + *GNU*) func_path_progs_result=$_G_path_prog _G_path_prog_found=: ;; + *) $_G_check_func $_G_path_prog + func_path_progs_result=$func_check_prog_result + ;; + esac + $_G_path_prog_found && break 3 + done + done + done + IFS=$_G_save_IFS + test -z "$func_path_progs_result" && { + echo "no acceptable sed could be found in \$PATH" >&2 + exit 1 + } +} + + +# We want to be able to use the functions in this file before configure +# has figured out where the best binaries are kept, which means we have +# to search for them ourselves - except when the results are already set +# where we skip the searches. + +# Unless the user overrides by setting SED, search the path for either GNU +# sed, or the sed that truncates its output the least. +test -z "$SED" && { + _G_sed_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ + for _G_i in 1 2 3 4 5 6 7; do + _G_sed_script=$_G_sed_script$nl$_G_sed_script + done + echo "$_G_sed_script" 2>/dev/null | sed 99q >conftest.sed + _G_sed_script= + + func_check_prog_sed () + { + _G_path_prog=$1 + + _G_count=0 + printf 0123456789 >conftest.in + while : + do + cat conftest.in conftest.in >conftest.tmp + mv conftest.tmp conftest.in + cp conftest.in conftest.nl + echo '' >> conftest.nl + "$_G_path_prog" -f conftest.sed <conftest.nl >conftest.out 2>/dev/null || break + diff conftest.out conftest.nl >/dev/null 2>&1 || break + _G_count=`expr $_G_count + 1` + if test "$_G_count" -gt "$_G_path_prog_max"; then + # Best one so far, save it but keep looking for a better one + func_check_prog_result=$_G_path_prog + _G_path_prog_max=$_G_count + fi + # 10*(2^10) chars as input seems more than enough + test 10 -lt "$_G_count" && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out + } + + func_path_progs "sed gsed" func_check_prog_sed $PATH:/usr/xpg4/bin + rm -f conftest.sed + SED=$func_path_progs_result +} + + +# Unless the user overrides by setting GREP, search the path for either GNU +# grep, or the grep that truncates its output the least. +test -z "$GREP" && { + func_check_prog_grep () + { + _G_path_prog=$1 + + _G_count=0 + _G_path_prog_max=0 + printf 0123456789 >conftest.in + while : + do + cat conftest.in conftest.in >conftest.tmp + mv conftest.tmp conftest.in + cp conftest.in conftest.nl + echo 'GREP' >> conftest.nl + "$_G_path_prog" -e 'GREP$' -e '-(cannot match)-' <conftest.nl >conftest.out 2>/dev/null || break + diff conftest.out conftest.nl >/dev/null 2>&1 || break + _G_count=`expr $_G_count + 1` + if test "$_G_count" -gt "$_G_path_prog_max"; then + # Best one so far, save it but keep looking for a better one + func_check_prog_result=$_G_path_prog + _G_path_prog_max=$_G_count + fi + # 10*(2^10) chars as input seems more than enough + test 10 -lt "$_G_count" && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out + } + + func_path_progs "grep ggrep" func_check_prog_grep $PATH:/usr/xpg4/bin + GREP=$func_path_progs_result +} + + +## ------------------------------- ## +## User overridable command paths. ## +## ------------------------------- ## + +# All uppercase variable names are used for environment variables. These +# variables can be overridden by the user before calling a script that +# uses them if a suitable command of that name is not already available +# in the command search PATH. + +: ${CP="cp -f"} +: ${ECHO="printf %s\n"} +: ${EGREP="$GREP -E"} +: ${FGREP="$GREP -F"} +: ${LN_S="ln -s"} +: ${MAKE="make"} +: ${MKDIR="mkdir"} +: ${MV="mv -f"} +: ${RM="rm -f"} +: ${SHELL="${CONFIG_SHELL-/bin/sh}"} + + +## -------------------- ## +## Useful sed snippets. ## +## -------------------- ## + +sed_dirname='s|/[^/]*$||' +sed_basename='s|^.*/||' + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +sed_quote_subst='s|\([`"$\\]\)|\\\1|g' + +# Same as above, but do not quote variable references. +sed_double_quote_subst='s/\(["`\\]\)/\\\1/g' + +# Sed substitution that turns a string into a regex matching for the +# string literally. +sed_make_literal_regex='s|[].[^$\\*\/]|\\&|g' + +# Sed substitution that converts a w32 file name or path +# that contains forward slashes, into one that contains +# (escaped) backslashes. A very naive implementation. +sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' + +# Re-'\' parameter expansions in output of sed_double_quote_subst that +# were '\'-ed in input to the same. If an odd number of '\' preceded a +# '$' in input to sed_double_quote_subst, that '$' was protected from +# expansion. Since each input '\' is now two '\'s, look for any number +# of runs of four '\'s followed by two '\'s and then a '$'. '\' that '$'. +_G_bs='\\' +_G_bs2='\\\\' +_G_bs4='\\\\\\\\' +_G_dollar='\$' +sed_double_backslash="\ + s/$_G_bs4/&\\ +/g + s/^$_G_bs2$_G_dollar/$_G_bs&/ + s/\\([^$_G_bs]\\)$_G_bs2$_G_dollar/\\1$_G_bs2$_G_bs$_G_dollar/g + s/\n//g" + + +## ----------------- ## +## Global variables. ## +## ----------------- ## + +# Except for the global variables explicitly listed below, the following +# functions in the '^func_' namespace, and the '^require_' namespace +# variables initialised in the 'Resource management' section, sourcing +# this file will not pollute your global namespace with anything +# else. There's no portable way to scope variables in Bourne shell +# though, so actually running these functions will sometimes place +# results into a variable named after the function, and often use +# temporary variables in the '^_G_' namespace. If you are careful to +# avoid using those namespaces casually in your sourcing script, things +# should continue to work as you expect. And, of course, you can freely +# overwrite any of the functions or variables defined here before +# calling anything to customize them. + +EXIT_SUCCESS=0 +EXIT_FAILURE=1 +EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing. +EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. + +# Allow overriding, eg assuming that you follow the convention of +# putting '$debug_cmd' at the start of all your functions, you can get +# bash to show function call trace with: +# +# debug_cmd='eval echo "${FUNCNAME[0]} $*" >&2' bash your-script-name +debug_cmd=${debug_cmd-":"} +exit_cmd=: + +# By convention, finish your script with: +# +# exit $exit_status +# +# so that you can set exit_status to non-zero if you want to indicate +# something went wrong during execution without actually bailing out at +# the point of failure. +exit_status=$EXIT_SUCCESS + +# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh +# is ksh but when the shell is invoked as "sh" and the current value of +# the _XPG environment variable is not equal to 1 (one), the special +# positional parameter $0, within a function call, is the name of the +# function. +progpath=$0 + +# The name of this program. +progname=`$ECHO "$progpath" |$SED "$sed_basename"` + +# Make sure we have an absolute progpath for reexecution: +case $progpath in + [\\/]*|[A-Za-z]:\\*) ;; + *[\\/]*) + progdir=`$ECHO "$progpath" |$SED "$sed_dirname"` + progdir=`cd "$progdir" && pwd` + progpath=$progdir/$progname + ;; + *) + _G_IFS=$IFS + IFS=${PATH_SEPARATOR-:} + for progdir in $PATH; do + IFS=$_G_IFS + test -x "$progdir/$progname" && break + done + IFS=$_G_IFS + test -n "$progdir" || progdir=`pwd` + progpath=$progdir/$progname + ;; +esac + + +## ----------------- ## +## Standard options. ## +## ----------------- ## + +# The following options affect the operation of the functions defined +# below, and should be set appropriately depending on run-time para- +# meters passed on the command line. + +opt_dry_run=false +opt_quiet=false +opt_verbose=false + +# Categories 'all' and 'none' are always available. Append any others +# you will pass as the first argument to func_warning from your own +# code. +warning_categories= + +# By default, display warnings according to 'opt_warning_types'. Set +# 'warning_func' to ':' to elide all warnings, or func_fatal_error to +# treat the next displayed warning as a fatal error. +warning_func=func_warn_and_continue + +# Set to 'all' to display all warnings, 'none' to suppress all +# warnings, or a space delimited list of some subset of +# 'warning_categories' to display only the listed warnings. +opt_warning_types=all + + +## -------------------- ## +## Resource management. ## +## -------------------- ## + +# This section contains definitions for functions that each ensure a +# particular resource (a file, or a non-empty configuration variable for +# example) is available, and if appropriate to extract default values +# from pertinent package files. Call them using their associated +# 'require_*' variable to ensure that they are executed, at most, once. +# +# It's entirely deliberate that calling these functions can set +# variables that don't obey the namespace limitations obeyed by the rest +# of this file, in order that that they be as useful as possible to +# callers. + + +# require_term_colors +# ------------------- +# Allow display of bold text on terminals that support it. +require_term_colors=func_require_term_colors +func_require_term_colors () +{ + $debug_cmd + + test -t 1 && { + # COLORTERM and USE_ANSI_COLORS environment variables take + # precedence, because most terminfo databases neglect to describe + # whether color sequences are supported. + test -n "${COLORTERM+set}" && : ${USE_ANSI_COLORS="1"} + + if test 1 = "$USE_ANSI_COLORS"; then + # Standard ANSI escape sequences + tc_reset='' + tc_bold=''; tc_standout='' + tc_red=''; tc_green='' + tc_blue=''; tc_cyan='' + else + # Otherwise trust the terminfo database after all. + test -n "`tput sgr0 2>/dev/null`" && { + tc_reset=`tput sgr0` + test -n "`tput bold 2>/dev/null`" && tc_bold=`tput bold` + tc_standout=$tc_bold + test -n "`tput smso 2>/dev/null`" && tc_standout=`tput smso` + test -n "`tput setaf 1 2>/dev/null`" && tc_red=`tput setaf 1` + test -n "`tput setaf 2 2>/dev/null`" && tc_green=`tput setaf 2` + test -n "`tput setaf 4 2>/dev/null`" && tc_blue=`tput setaf 4` + test -n "`tput setaf 5 2>/dev/null`" && tc_cyan=`tput setaf 5` + } + fi + } + + require_term_colors=: +} + + +## ----------------- ## +## Function library. ## +## ----------------- ## + +# This section contains a variety of useful functions to call in your +# scripts. Take note of the portable wrappers for features provided by +# some modern shells, which will fall back to slower equivalents on +# less featureful shells. + + +# func_append VAR VALUE +# --------------------- +# Append VALUE onto the existing contents of VAR. + + # We should try to minimise forks, especially on Windows where they are + # unreasonably slow, so skip the feature probes when bash or zsh are + # being used: + if test set = "${BASH_VERSION+set}${ZSH_VERSION+set}"; then + : ${_G_HAVE_ARITH_OP="yes"} + : ${_G_HAVE_XSI_OPS="yes"} + # The += operator was introduced in bash 3.1 + case $BASH_VERSION in + [12].* | 3.0 | 3.0*) ;; + *) + : ${_G_HAVE_PLUSEQ_OP="yes"} + ;; + esac + fi + + # _G_HAVE_PLUSEQ_OP + # Can be empty, in which case the shell is probed, "yes" if += is + # useable or anything else if it does not work. + test -z "$_G_HAVE_PLUSEQ_OP" \ + && (eval 'x=a; x+=" b"; test "a b" = "$x"') 2>/dev/null \ + && _G_HAVE_PLUSEQ_OP=yes + +if test yes = "$_G_HAVE_PLUSEQ_OP" +then + # This is an XSI compatible shell, allowing a faster implementation... + eval 'func_append () + { + $debug_cmd + + eval "$1+=\$2" + }' +else + # ...otherwise fall back to using expr, which is often a shell builtin. + func_append () + { + $debug_cmd + + eval "$1=\$$1\$2" + } +fi + + +# func_append_quoted VAR VALUE +# ---------------------------- +# Quote VALUE and append to the end of shell variable VAR, separated +# by a space. +if test yes = "$_G_HAVE_PLUSEQ_OP"; then + eval 'func_append_quoted () + { + $debug_cmd + + func_quote_for_eval "$2" + eval "$1+=\\ \$func_quote_for_eval_result" + }' +else + func_append_quoted () + { + $debug_cmd + + func_quote_for_eval "$2" + eval "$1=\$$1\\ \$func_quote_for_eval_result" + } +fi + + +# func_append_uniq VAR VALUE +# -------------------------- +# Append unique VALUE onto the existing contents of VAR, assuming +# entries are delimited by the first character of VALUE. For example: +# +# func_append_uniq options " --another-option option-argument" +# +# will only append to $options if " --another-option option-argument " +# is not already present somewhere in $options already (note spaces at +# each end implied by leading space in second argument). +func_append_uniq () +{ + $debug_cmd + + eval _G_current_value='`$ECHO $'$1'`' + _G_delim=`expr "$2" : '\(.\)'` + + case $_G_delim$_G_current_value$_G_delim in + *"$2$_G_delim"*) ;; + *) func_append "$@" ;; + esac +} + + +# func_arith TERM... +# ------------------ +# Set func_arith_result to the result of evaluating TERMs. + test -z "$_G_HAVE_ARITH_OP" \ + && (eval 'test 2 = $(( 1 + 1 ))') 2>/dev/null \ + && _G_HAVE_ARITH_OP=yes + +if test yes = "$_G_HAVE_ARITH_OP"; then + eval 'func_arith () + { + $debug_cmd + + func_arith_result=$(( $* )) + }' +else + func_arith () + { + $debug_cmd + + func_arith_result=`expr "$@"` + } +fi + + +# func_basename FILE +# ------------------ +# Set func_basename_result to FILE with everything up to and including +# the last / stripped. +if test yes = "$_G_HAVE_XSI_OPS"; then + # If this shell supports suffix pattern removal, then use it to avoid + # forking. Hide the definitions single quotes in case the shell chokes + # on unsupported syntax... + _b='func_basename_result=${1##*/}' + _d='case $1 in + */*) func_dirname_result=${1%/*}$2 ;; + * ) func_dirname_result=$3 ;; + esac' + +else + # ...otherwise fall back to using sed. + _b='func_basename_result=`$ECHO "$1" |$SED "$sed_basename"`' + _d='func_dirname_result=`$ECHO "$1" |$SED "$sed_dirname"` + if test "X$func_dirname_result" = "X$1"; then + func_dirname_result=$3 + else + func_append func_dirname_result "$2" + fi' +fi + +eval 'func_basename () +{ + $debug_cmd + + '"$_b"' +}' + + +# func_dirname FILE APPEND NONDIR_REPLACEMENT +# ------------------------------------------- +# Compute the dirname of FILE. If nonempty, add APPEND to the result, +# otherwise set result to NONDIR_REPLACEMENT. +eval 'func_dirname () +{ + $debug_cmd + + '"$_d"' +}' + + +# func_dirname_and_basename FILE APPEND NONDIR_REPLACEMENT +# -------------------------------------------------------- +# Perform func_basename and func_dirname in a single function +# call: +# dirname: Compute the dirname of FILE. If nonempty, +# add APPEND to the result, otherwise set result +# to NONDIR_REPLACEMENT. +# value returned in "$func_dirname_result" +# basename: Compute filename of FILE. +# value retuned in "$func_basename_result" +# For efficiency, we do not delegate to the functions above but instead +# duplicate the functionality here. +eval 'func_dirname_and_basename () +{ + $debug_cmd + + '"$_b"' + '"$_d"' +}' + + +# func_echo ARG... +# ---------------- +# Echo program name prefixed message. +func_echo () +{ + $debug_cmd + + _G_message=$* + + func_echo_IFS=$IFS + IFS=$nl + for _G_line in $_G_message; do + IFS=$func_echo_IFS + $ECHO "$progname: $_G_line" + done + IFS=$func_echo_IFS +} + + +# func_echo_all ARG... +# -------------------- +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "$*" +} + + +# func_echo_infix_1 INFIX ARG... +# ------------------------------ +# Echo program name, followed by INFIX on the first line, with any +# additional lines not showing INFIX. +func_echo_infix_1 () +{ + $debug_cmd + + $require_term_colors + + _G_infix=$1; shift + _G_indent=$_G_infix + _G_prefix="$progname: $_G_infix: " + _G_message=$* + + # Strip color escape sequences before counting printable length + for _G_tc in "$tc_reset" "$tc_bold" "$tc_standout" "$tc_red" "$tc_green" "$tc_blue" "$tc_cyan" + do + test -n "$_G_tc" && { + _G_esc_tc=`$ECHO "$_G_tc" | $SED "$sed_make_literal_regex"` + _G_indent=`$ECHO "$_G_indent" | $SED "s|$_G_esc_tc||g"` + } + done + _G_indent="$progname: "`echo "$_G_indent" | $SED 's|.| |g'`" " ## exclude from sc_prohibit_nested_quotes + + func_echo_infix_1_IFS=$IFS + IFS=$nl + for _G_line in $_G_message; do + IFS=$func_echo_infix_1_IFS + $ECHO "$_G_prefix$tc_bold$_G_line$tc_reset" >&2 + _G_prefix=$_G_indent + done + IFS=$func_echo_infix_1_IFS +} + + +# func_error ARG... +# ----------------- +# Echo program name prefixed message to standard error. +func_error () +{ + $debug_cmd + + $require_term_colors + + func_echo_infix_1 " $tc_standout${tc_red}error$tc_reset" "$*" >&2 +} + + +# func_fatal_error ARG... +# ----------------------- +# Echo program name prefixed message to standard error, and exit. +func_fatal_error () +{ + $debug_cmd + + func_error "$*" + exit $EXIT_FAILURE +} + + +# func_grep EXPRESSION FILENAME +# ----------------------------- +# Check whether EXPRESSION matches any line of FILENAME, without output. +func_grep () +{ + $debug_cmd + + $GREP "$1" "$2" >/dev/null 2>&1 +} + + +# func_len STRING +# --------------- +# Set func_len_result to the length of STRING. STRING may not +# start with a hyphen. + test -z "$_G_HAVE_XSI_OPS" \ + && (eval 'x=a/b/c; + test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \ + && _G_HAVE_XSI_OPS=yes + +if test yes = "$_G_HAVE_XSI_OPS"; then + eval 'func_len () + { + $debug_cmd + + func_len_result=${#1} + }' +else + func_len () + { + $debug_cmd + + func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len` + } +fi + + +# func_mkdir_p DIRECTORY-PATH +# --------------------------- +# Make sure the entire path to DIRECTORY-PATH is available. +func_mkdir_p () +{ + $debug_cmd + + _G_directory_path=$1 + _G_dir_list= + + if test -n "$_G_directory_path" && test : != "$opt_dry_run"; then + + # Protect directory names starting with '-' + case $_G_directory_path in + -*) _G_directory_path=./$_G_directory_path ;; + esac + + # While some portion of DIR does not yet exist... + while test ! -d "$_G_directory_path"; do + # ...make a list in topmost first order. Use a colon delimited + # list incase some portion of path contains whitespace. + _G_dir_list=$_G_directory_path:$_G_dir_list + + # If the last portion added has no slash in it, the list is done + case $_G_directory_path in */*) ;; *) break ;; esac + + # ...otherwise throw away the child directory and loop + _G_directory_path=`$ECHO "$_G_directory_path" | $SED -e "$sed_dirname"` + done + _G_dir_list=`$ECHO "$_G_dir_list" | $SED 's|:*$||'` + + func_mkdir_p_IFS=$IFS; IFS=: + for _G_dir in $_G_dir_list; do + IFS=$func_mkdir_p_IFS + # mkdir can fail with a 'File exist' error if two processes + # try to create one of the directories concurrently. Don't + # stop in that case! + $MKDIR "$_G_dir" 2>/dev/null || : + done + IFS=$func_mkdir_p_IFS + + # Bail out if we (or some other process) failed to create a directory. + test -d "$_G_directory_path" || \ + func_fatal_error "Failed to create '$1'" + fi +} + + +# func_mktempdir [BASENAME] +# ------------------------- +# Make a temporary directory that won't clash with other running +# libtool processes, and avoids race conditions if possible. If +# given, BASENAME is the basename for that directory. +func_mktempdir () +{ + $debug_cmd + + _G_template=${TMPDIR-/tmp}/${1-$progname} + + if test : = "$opt_dry_run"; then + # Return a directory name, but don't create it in dry-run mode + _G_tmpdir=$_G_template-$$ + else + + # If mktemp works, use that first and foremost + _G_tmpdir=`mktemp -d "$_G_template-XXXXXXXX" 2>/dev/null` + + if test ! -d "$_G_tmpdir"; then + # Failing that, at least try and use $RANDOM to avoid a race + _G_tmpdir=$_G_template-${RANDOM-0}$$ + + func_mktempdir_umask=`umask` + umask 0077 + $MKDIR "$_G_tmpdir" + umask $func_mktempdir_umask + fi + + # If we're not in dry-run mode, bomb out on failure + test -d "$_G_tmpdir" || \ + func_fatal_error "cannot create temporary directory '$_G_tmpdir'" + fi + + $ECHO "$_G_tmpdir" +} + + +# func_normal_abspath PATH +# ------------------------ +# Remove doubled-up and trailing slashes, "." path components, +# and cancel out any ".." path components in PATH after making +# it an absolute path. +func_normal_abspath () +{ + $debug_cmd + + # These SED scripts presuppose an absolute path with a trailing slash. + _G_pathcar='s|^/\([^/]*\).*$|\1|' + _G_pathcdr='s|^/[^/]*||' + _G_removedotparts=':dotsl + s|/\./|/|g + t dotsl + s|/\.$|/|' + _G_collapseslashes='s|/\{1,\}|/|g' + _G_finalslash='s|/*$|/|' + + # Start from root dir and reassemble the path. + func_normal_abspath_result= + func_normal_abspath_tpath=$1 + func_normal_abspath_altnamespace= + case $func_normal_abspath_tpath in + "") + # Empty path, that just means $cwd. + func_stripname '' '/' "`pwd`" + func_normal_abspath_result=$func_stripname_result + return + ;; + # The next three entries are used to spot a run of precisely + # two leading slashes without using negated character classes; + # we take advantage of case's first-match behaviour. + ///*) + # Unusual form of absolute path, do nothing. + ;; + //*) + # Not necessarily an ordinary path; POSIX reserves leading '//' + # and for example Cygwin uses it to access remote file shares + # over CIFS/SMB, so we conserve a leading double slash if found. + func_normal_abspath_altnamespace=/ + ;; + /*) + # Absolute path, do nothing. + ;; + *) + # Relative path, prepend $cwd. + func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath + ;; + esac + + # Cancel out all the simple stuff to save iterations. We also want + # the path to end with a slash for ease of parsing, so make sure + # there is one (and only one) here. + func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$_G_removedotparts" -e "$_G_collapseslashes" -e "$_G_finalslash"` + while :; do + # Processed it all yet? + if test / = "$func_normal_abspath_tpath"; then + # If we ascended to the root using ".." the result may be empty now. + if test -z "$func_normal_abspath_result"; then + func_normal_abspath_result=/ + fi + break + fi + func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$_G_pathcar"` + func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$_G_pathcdr"` + # Figure out what to do with it + case $func_normal_abspath_tcomponent in + "") + # Trailing empty path component, ignore it. + ;; + ..) + # Parent dir; strip last assembled component from result. + func_dirname "$func_normal_abspath_result" + func_normal_abspath_result=$func_dirname_result + ;; + *) + # Actual path component, append it. + func_append func_normal_abspath_result "/$func_normal_abspath_tcomponent" + ;; + esac + done + # Restore leading double-slash if one was found on entry. + func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result +} + + +# func_notquiet ARG... +# -------------------- +# Echo program name prefixed message only when not in quiet mode. +func_notquiet () +{ + $debug_cmd + + $opt_quiet || func_echo ${1+"$@"} + + # A bug in bash halts the script if the last line of a function + # fails when set -e is in force, so we need another command to + # work around that: + : +} + + +# func_relative_path SRCDIR DSTDIR +# -------------------------------- +# Set func_relative_path_result to the relative path from SRCDIR to DSTDIR. +func_relative_path () +{ + $debug_cmd + + func_relative_path_result= + func_normal_abspath "$1" + func_relative_path_tlibdir=$func_normal_abspath_result + func_normal_abspath "$2" + func_relative_path_tbindir=$func_normal_abspath_result + + # Ascend the tree starting from libdir + while :; do + # check if we have found a prefix of bindir + case $func_relative_path_tbindir in + $func_relative_path_tlibdir) + # found an exact match + func_relative_path_tcancelled= + break + ;; + $func_relative_path_tlibdir*) + # found a matching prefix + func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir" + func_relative_path_tcancelled=$func_stripname_result + if test -z "$func_relative_path_result"; then + func_relative_path_result=. + fi + break + ;; + *) + func_dirname $func_relative_path_tlibdir + func_relative_path_tlibdir=$func_dirname_result + if test -z "$func_relative_path_tlibdir"; then + # Have to descend all the way to the root! + func_relative_path_result=../$func_relative_path_result + func_relative_path_tcancelled=$func_relative_path_tbindir + break + fi + func_relative_path_result=../$func_relative_path_result + ;; + esac + done + + # Now calculate path; take care to avoid doubling-up slashes. + func_stripname '' '/' "$func_relative_path_result" + func_relative_path_result=$func_stripname_result + func_stripname '/' '/' "$func_relative_path_tcancelled" + if test -n "$func_stripname_result"; then + func_append func_relative_path_result "/$func_stripname_result" + fi + + # Normalisation. If bindir is libdir, return '.' else relative path. + if test -n "$func_relative_path_result"; then + func_stripname './' '' "$func_relative_path_result" + func_relative_path_result=$func_stripname_result + fi + + test -n "$func_relative_path_result" || func_relative_path_result=. + + : +} + + +# func_quote_for_eval ARG... +# -------------------------- +# Aesthetically quote ARGs to be evaled later. +# This function returns two values: +# i) func_quote_for_eval_result +# double-quoted, suitable for a subsequent eval +# ii) func_quote_for_eval_unquoted_result +# has all characters that are still active within double +# quotes backslashified. +func_quote_for_eval () +{ + $debug_cmd + + func_quote_for_eval_unquoted_result= + func_quote_for_eval_result= + while test 0 -lt $#; do + case $1 in + *[\\\`\"\$]*) + _G_unquoted_arg=`printf '%s\n' "$1" |$SED "$sed_quote_subst"` ;; + *) + _G_unquoted_arg=$1 ;; + esac + if test -n "$func_quote_for_eval_unquoted_result"; then + func_append func_quote_for_eval_unquoted_result " $_G_unquoted_arg" + else + func_append func_quote_for_eval_unquoted_result "$_G_unquoted_arg" + fi + + case $_G_unquoted_arg in + # Double-quote args containing shell metacharacters to delay + # word splitting, command substitution and variable expansion + # for a subsequent eval. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + _G_quoted_arg=\"$_G_unquoted_arg\" + ;; + *) + _G_quoted_arg=$_G_unquoted_arg + ;; + esac + + if test -n "$func_quote_for_eval_result"; then + func_append func_quote_for_eval_result " $_G_quoted_arg" + else + func_append func_quote_for_eval_result "$_G_quoted_arg" + fi + shift + done +} + + +# func_quote_for_expand ARG +# ------------------------- +# Aesthetically quote ARG to be evaled later; same as above, +# but do not quote variable references. +func_quote_for_expand () +{ + $debug_cmd + + case $1 in + *[\\\`\"]*) + _G_arg=`$ECHO "$1" | $SED \ + -e "$sed_double_quote_subst" -e "$sed_double_backslash"` ;; + *) + _G_arg=$1 ;; + esac + + case $_G_arg in + # Double-quote args containing shell metacharacters to delay + # word splitting and command substitution for a subsequent eval. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + _G_arg=\"$_G_arg\" + ;; + esac + + func_quote_for_expand_result=$_G_arg +} + + +# func_stripname PREFIX SUFFIX NAME +# --------------------------------- +# strip PREFIX and SUFFIX from NAME, and store in func_stripname_result. +# PREFIX and SUFFIX must not contain globbing or regex special +# characters, hashes, percent signs, but SUFFIX may contain a leading +# dot (in which case that matches only a dot). +if test yes = "$_G_HAVE_XSI_OPS"; then + eval 'func_stripname () + { + $debug_cmd + + # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are + # positional parameters, so assign one to ordinary variable first. + func_stripname_result=$3 + func_stripname_result=${func_stripname_result#"$1"} + func_stripname_result=${func_stripname_result%"$2"} + }' +else + func_stripname () + { + $debug_cmd + + case $2 in + .*) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%\\\\$2\$%%"`;; + *) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%$2\$%%"`;; + esac + } +fi + + +# func_show_eval CMD [FAIL_EXP] +# ----------------------------- +# Unless opt_quiet is true, then output CMD. Then, if opt_dryrun is +# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP +# is given, then evaluate it. +func_show_eval () +{ + $debug_cmd + + _G_cmd=$1 + _G_fail_exp=${2-':'} + + func_quote_for_expand "$_G_cmd" + eval "func_notquiet $func_quote_for_expand_result" + + $opt_dry_run || { + eval "$_G_cmd" + _G_status=$? + if test 0 -ne "$_G_status"; then + eval "(exit $_G_status); $_G_fail_exp" + fi + } +} + + +# func_show_eval_locale CMD [FAIL_EXP] +# ------------------------------------ +# Unless opt_quiet is true, then output CMD. Then, if opt_dryrun is +# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP +# is given, then evaluate it. Use the saved locale for evaluation. +func_show_eval_locale () +{ + $debug_cmd + + _G_cmd=$1 + _G_fail_exp=${2-':'} + + $opt_quiet || { + func_quote_for_expand "$_G_cmd" + eval "func_echo $func_quote_for_expand_result" + } + + $opt_dry_run || { + eval "$_G_user_locale + $_G_cmd" + _G_status=$? + eval "$_G_safe_locale" + if test 0 -ne "$_G_status"; then + eval "(exit $_G_status); $_G_fail_exp" + fi + } +} + + +# func_tr_sh +# ---------- +# Turn $1 into a string suitable for a shell variable name. +# Result is stored in $func_tr_sh_result. All characters +# not in the set a-zA-Z0-9_ are replaced with '_'. Further, +# if $1 begins with a digit, a '_' is prepended as well. +func_tr_sh () +{ + $debug_cmd + + case $1 in + [0-9]* | *[!a-zA-Z0-9_]*) + func_tr_sh_result=`$ECHO "$1" | $SED -e 's/^\([0-9]\)/_\1/' -e 's/[^a-zA-Z0-9_]/_/g'` + ;; + * ) + func_tr_sh_result=$1 + ;; + esac +} + + +# func_verbose ARG... +# ------------------- +# Echo program name prefixed message in verbose mode only. +func_verbose () +{ + $debug_cmd + + $opt_verbose && func_echo "$*" + + : +} + + +# func_warn_and_continue ARG... +# ----------------------------- +# Echo program name prefixed warning message to standard error. +func_warn_and_continue () +{ + $debug_cmd + + $require_term_colors + + func_echo_infix_1 "${tc_red}warning$tc_reset" "$*" >&2 +} + + +# func_warning CATEGORY ARG... +# ---------------------------- +# Echo program name prefixed warning message to standard error. Warning +# messages can be filtered according to CATEGORY, where this function +# elides messages where CATEGORY is not listed in the global variable +# 'opt_warning_types'. +func_warning () +{ + $debug_cmd + + # CATEGORY must be in the warning_categories list! + case " $warning_categories " in + *" $1 "*) ;; + *) func_internal_error "invalid warning category '$1'" ;; + esac + + _G_category=$1 + shift + + case " $opt_warning_types " in + *" $_G_category "*) $warning_func ${1+"$@"} ;; + esac +} + + +# func_sort_ver VER1 VER2 +# ----------------------- +# 'sort -V' is not generally available. +# Note this deviates from the version comparison in automake +# in that it treats 1.5 < 1.5.0, and treats 1.4.4a < 1.4-p3a +# but this should suffice as we won't be specifying old +# version formats or redundant trailing .0 in bootstrap.conf. +# If we did want full compatibility then we should probably +# use m4_version_compare from autoconf. +func_sort_ver () +{ + $debug_cmd + + printf '%s\n%s\n' "$1" "$2" \ + | sort -t. -k 1,1n -k 2,2n -k 3,3n -k 4,4n -k 5,5n -k 6,6n -k 7,7n -k 8,8n -k 9,9n +} + +# func_lt_ver PREV CURR +# --------------------- +# Return true if PREV and CURR are in the correct order according to +# func_sort_ver, otherwise false. Use it like this: +# +# func_lt_ver "$prev_ver" "$proposed_ver" || func_fatal_error "..." +func_lt_ver () +{ + $debug_cmd + + test "x$1" = x`func_sort_ver "$1" "$2" | $SED 1q` +} + + +# Local variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC" +# time-stamp-time-zone: "UTC" +# End: +#! /bin/sh + +# Set a version string for this script. +scriptversion=2014-01-07.03; # UTC + +# A portable, pluggable option parser for Bourne shell. +# Written by Gary V. Vaughan, 2010 + +# Copyright (C) 2010-2015 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +# Please report bugs or propose patches to gary@gnu.org. + + +## ------ ## +## Usage. ## +## ------ ## + +# This file is a library for parsing options in your shell scripts along +# with assorted other useful supporting features that you can make use +# of too. +# +# For the simplest scripts you might need only: +# +# #!/bin/sh +# . relative/path/to/funclib.sh +# . relative/path/to/options-parser +# scriptversion=1.0 +# func_options ${1+"$@"} +# eval set dummy "$func_options_result"; shift +# ...rest of your script... +# +# In order for the '--version' option to work, you will need to have a +# suitably formatted comment like the one at the top of this file +# starting with '# Written by ' and ending with '# warranty; '. +# +# For '-h' and '--help' to work, you will also need a one line +# description of your script's purpose in a comment directly above the +# '# Written by ' line, like the one at the top of this file. +# +# The default options also support '--debug', which will turn on shell +# execution tracing (see the comment above debug_cmd below for another +# use), and '--verbose' and the func_verbose function to allow your script +# to display verbose messages only when your user has specified +# '--verbose'. +# +# After sourcing this file, you can plug processing for additional +# options by amending the variables from the 'Configuration' section +# below, and following the instructions in the 'Option parsing' +# section further down. + +## -------------- ## +## Configuration. ## +## -------------- ## + +# You should override these variables in your script after sourcing this +# file so that they reflect the customisations you have added to the +# option parser. + +# The usage line for option parsing errors and the start of '-h' and +# '--help' output messages. You can embed shell variables for delayed +# expansion at the time the message is displayed, but you will need to +# quote other shell meta-characters carefully to prevent them being +# expanded when the contents are evaled. +usage='$progpath [OPTION]...' + +# Short help message in response to '-h' and '--help'. Add to this or +# override it after sourcing this library to reflect the full set of +# options your script accepts. +usage_message="\ + --debug enable verbose shell tracing + -W, --warnings=CATEGORY + report the warnings falling in CATEGORY [all] + -v, --verbose verbosely report processing + --version print version information and exit + -h, --help print short or long help message and exit +" + +# Additional text appended to 'usage_message' in response to '--help'. +long_help_message=" +Warning categories include: + 'all' show all warnings + 'none' turn off all the warnings + 'error' warnings are treated as fatal errors" + +# Help message printed before fatal option parsing errors. +fatal_help="Try '\$progname --help' for more information." + + + +## ------------------------- ## +## Hook function management. ## +## ------------------------- ## + +# This section contains functions for adding, removing, and running hooks +# to the main code. A hook is just a named list of of function, that can +# be run in order later on. + +# func_hookable FUNC_NAME +# ----------------------- +# Declare that FUNC_NAME will run hooks added with +# 'func_add_hook FUNC_NAME ...'. +func_hookable () +{ + $debug_cmd + + func_append hookable_fns " $1" +} + + +# func_add_hook FUNC_NAME HOOK_FUNC +# --------------------------------- +# Request that FUNC_NAME call HOOK_FUNC before it returns. FUNC_NAME must +# first have been declared "hookable" by a call to 'func_hookable'. +func_add_hook () +{ + $debug_cmd + + case " $hookable_fns " in + *" $1 "*) ;; + *) func_fatal_error "'$1' does not accept hook functions." ;; + esac + + eval func_append ${1}_hooks '" $2"' +} + + +# func_remove_hook FUNC_NAME HOOK_FUNC +# ------------------------------------ +# Remove HOOK_FUNC from the list of functions called by FUNC_NAME. +func_remove_hook () +{ + $debug_cmd + + eval ${1}_hooks='`$ECHO "\$'$1'_hooks" |$SED "s| '$2'||"`' +} + + +# func_run_hooks FUNC_NAME [ARG]... +# --------------------------------- +# Run all hook functions registered to FUNC_NAME. +# It is assumed that the list of hook functions contains nothing more +# than a whitespace-delimited list of legal shell function names, and +# no effort is wasted trying to catch shell meta-characters or preserve +# whitespace. +func_run_hooks () +{ + $debug_cmd + + case " $hookable_fns " in + *" $1 "*) ;; + *) func_fatal_error "'$1' does not support hook funcions.n" ;; + esac + + eval _G_hook_fns=\$$1_hooks; shift + + for _G_hook in $_G_hook_fns; do + eval $_G_hook '"$@"' + + # store returned options list back into positional + # parameters for next 'cmd' execution. + eval _G_hook_result=\$${_G_hook}_result + eval set dummy "$_G_hook_result"; shift + done + + func_quote_for_eval ${1+"$@"} + func_run_hooks_result=$func_quote_for_eval_result +} + + + +## --------------- ## +## Option parsing. ## +## --------------- ## + +# In order to add your own option parsing hooks, you must accept the +# full positional parameter list in your hook function, remove any +# options that you action, and then pass back the remaining unprocessed +# options in '<hooked_function_name>_result', escaped suitably for +# 'eval'. Like this: +# +# my_options_prep () +# { +# $debug_cmd +# +# # Extend the existing usage message. +# usage_message=$usage_message' +# -s, --silent don'\''t print informational messages +# ' +# +# func_quote_for_eval ${1+"$@"} +# my_options_prep_result=$func_quote_for_eval_result +# } +# func_add_hook func_options_prep my_options_prep +# +# +# my_silent_option () +# { +# $debug_cmd +# +# # Note that for efficiency, we parse as many options as we can +# # recognise in a loop before passing the remainder back to the +# # caller on the first unrecognised argument we encounter. +# while test $# -gt 0; do +# opt=$1; shift +# case $opt in +# --silent|-s) opt_silent=: ;; +# # Separate non-argument short options: +# -s*) func_split_short_opt "$_G_opt" +# set dummy "$func_split_short_opt_name" \ +# "-$func_split_short_opt_arg" ${1+"$@"} +# shift +# ;; +# *) set dummy "$_G_opt" "$*"; shift; break ;; +# esac +# done +# +# func_quote_for_eval ${1+"$@"} +# my_silent_option_result=$func_quote_for_eval_result +# } +# func_add_hook func_parse_options my_silent_option +# +# +# my_option_validation () +# { +# $debug_cmd +# +# $opt_silent && $opt_verbose && func_fatal_help "\ +# '--silent' and '--verbose' options are mutually exclusive." +# +# func_quote_for_eval ${1+"$@"} +# my_option_validation_result=$func_quote_for_eval_result +# } +# func_add_hook func_validate_options my_option_validation +# +# You'll alse need to manually amend $usage_message to reflect the extra +# options you parse. It's preferable to append if you can, so that +# multiple option parsing hooks can be added safely. + + +# func_options [ARG]... +# --------------------- +# All the functions called inside func_options are hookable. See the +# individual implementations for details. +func_hookable func_options +func_options () +{ + $debug_cmd + + func_options_prep ${1+"$@"} + eval func_parse_options \ + ${func_options_prep_result+"$func_options_prep_result"} + eval func_validate_options \ + ${func_parse_options_result+"$func_parse_options_result"} + + eval func_run_hooks func_options \ + ${func_validate_options_result+"$func_validate_options_result"} + + # save modified positional parameters for caller + func_options_result=$func_run_hooks_result +} + + +# func_options_prep [ARG]... +# -------------------------- +# All initialisations required before starting the option parse loop. +# Note that when calling hook functions, we pass through the list of +# positional parameters. If a hook function modifies that list, and +# needs to propogate that back to rest of this script, then the complete +# modified list must be put in 'func_run_hooks_result' before +# returning. +func_hookable func_options_prep +func_options_prep () +{ + $debug_cmd + + # Option defaults: + opt_verbose=false + opt_warning_types= + + func_run_hooks func_options_prep ${1+"$@"} + + # save modified positional parameters for caller + func_options_prep_result=$func_run_hooks_result +} + + +# func_parse_options [ARG]... +# --------------------------- +# The main option parsing loop. +func_hookable func_parse_options +func_parse_options () +{ + $debug_cmd + + func_parse_options_result= + + # this just eases exit handling + while test $# -gt 0; do + # Defer to hook functions for initial option parsing, so they + # get priority in the event of reusing an option name. + func_run_hooks func_parse_options ${1+"$@"} + + # Adjust func_parse_options positional parameters to match + eval set dummy "$func_run_hooks_result"; shift + + # Break out of the loop if we already parsed every option. + test $# -gt 0 || break + + _G_opt=$1 + shift + case $_G_opt in + --debug|-x) debug_cmd='set -x' + func_echo "enabling shell trace mode" + $debug_cmd + ;; + + --no-warnings|--no-warning|--no-warn) + set dummy --warnings none ${1+"$@"} + shift + ;; + + --warnings|--warning|-W) + test $# = 0 && func_missing_arg $_G_opt && break + case " $warning_categories $1" in + *" $1 "*) + # trailing space prevents matching last $1 above + func_append_uniq opt_warning_types " $1" + ;; + *all) + opt_warning_types=$warning_categories + ;; + *none) + opt_warning_types=none + warning_func=: + ;; + *error) + opt_warning_types=$warning_categories + warning_func=func_fatal_error + ;; + *) + func_fatal_error \ + "unsupported warning category: '$1'" + ;; + esac + shift + ;; + + --verbose|-v) opt_verbose=: ;; + --version) func_version ;; + -\?|-h) func_usage ;; + --help) func_help ;; + + # Separate optargs to long options (plugins may need this): + --*=*) func_split_equals "$_G_opt" + set dummy "$func_split_equals_lhs" \ + "$func_split_equals_rhs" ${1+"$@"} + shift + ;; + + # Separate optargs to short options: + -W*) + func_split_short_opt "$_G_opt" + set dummy "$func_split_short_opt_name" \ + "$func_split_short_opt_arg" ${1+"$@"} + shift + ;; + + # Separate non-argument short options: + -\?*|-h*|-v*|-x*) + func_split_short_opt "$_G_opt" + set dummy "$func_split_short_opt_name" \ + "-$func_split_short_opt_arg" ${1+"$@"} + shift + ;; + + --) break ;; + -*) func_fatal_help "unrecognised option: '$_G_opt'" ;; + *) set dummy "$_G_opt" ${1+"$@"}; shift; break ;; + esac + done + + # save modified positional parameters for caller + func_quote_for_eval ${1+"$@"} + func_parse_options_result=$func_quote_for_eval_result +} + + +# func_validate_options [ARG]... +# ------------------------------ +# Perform any sanity checks on option settings and/or unconsumed +# arguments. +func_hookable func_validate_options +func_validate_options () +{ + $debug_cmd + + # Display all warnings if -W was not given. + test -n "$opt_warning_types" || opt_warning_types=" $warning_categories" + + func_run_hooks func_validate_options ${1+"$@"} + + # Bail if the options were screwed! + $exit_cmd $EXIT_FAILURE + + # save modified positional parameters for caller + func_validate_options_result=$func_run_hooks_result +} + + + +## ----------------- ## +## Helper functions. ## +## ----------------- ## + +# This section contains the helper functions used by the rest of the +# hookable option parser framework in ascii-betical order. + + +# func_fatal_help ARG... +# ---------------------- +# Echo program name prefixed message to standard error, followed by +# a help hint, and exit. +func_fatal_help () +{ + $debug_cmd + + eval \$ECHO \""Usage: $usage"\" + eval \$ECHO \""$fatal_help"\" + func_error ${1+"$@"} + exit $EXIT_FAILURE +} + + +# func_help +# --------- +# Echo long help message to standard output and exit. +func_help () +{ + $debug_cmd + + func_usage_message + $ECHO "$long_help_message" + exit 0 +} + + +# func_missing_arg ARGNAME +# ------------------------ +# Echo program name prefixed message to standard error and set global +# exit_cmd. +func_missing_arg () +{ + $debug_cmd + + func_error "Missing argument for '$1'." + exit_cmd=exit +} + + +# func_split_equals STRING +# ------------------------ +# Set func_split_equals_lhs and func_split_equals_rhs shell variables after +# splitting STRING at the '=' sign. +test -z "$_G_HAVE_XSI_OPS" \ + && (eval 'x=a/b/c; + test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \ + && _G_HAVE_XSI_OPS=yes + +if test yes = "$_G_HAVE_XSI_OPS" +then + # This is an XSI compatible shell, allowing a faster implementation... + eval 'func_split_equals () + { + $debug_cmd + + func_split_equals_lhs=${1%%=*} + func_split_equals_rhs=${1#*=} + test "x$func_split_equals_lhs" = "x$1" \ + && func_split_equals_rhs= + }' +else + # ...otherwise fall back to using expr, which is often a shell builtin. + func_split_equals () + { + $debug_cmd + + func_split_equals_lhs=`expr "x$1" : 'x\([^=]*\)'` + func_split_equals_rhs= + test "x$func_split_equals_lhs" = "x$1" \ + || func_split_equals_rhs=`expr "x$1" : 'x[^=]*=\(.*\)$'` + } +fi #func_split_equals + + +# func_split_short_opt SHORTOPT +# ----------------------------- +# Set func_split_short_opt_name and func_split_short_opt_arg shell +# variables after splitting SHORTOPT after the 2nd character. +if test yes = "$_G_HAVE_XSI_OPS" +then + # This is an XSI compatible shell, allowing a faster implementation... + eval 'func_split_short_opt () + { + $debug_cmd + + func_split_short_opt_arg=${1#??} + func_split_short_opt_name=${1%"$func_split_short_opt_arg"} + }' +else + # ...otherwise fall back to using expr, which is often a shell builtin. + func_split_short_opt () + { + $debug_cmd + + func_split_short_opt_name=`expr "x$1" : 'x-\(.\)'` + func_split_short_opt_arg=`expr "x$1" : 'x-.\(.*\)$'` + } +fi #func_split_short_opt + + +# func_usage +# ---------- +# Echo short help message to standard output and exit. +func_usage () +{ + $debug_cmd + + func_usage_message + $ECHO "Run '$progname --help |${PAGER-more}' for full usage" + exit 0 +} + + +# func_usage_message +# ------------------ +# Echo short help message to standard output. +func_usage_message () +{ + $debug_cmd + + eval \$ECHO \""Usage: $usage"\" + echo + $SED -n 's|^# || + /^Written by/{ + x;p;x + } + h + /^Written by/q' < "$progpath" + echo + eval \$ECHO \""$usage_message"\" +} + + +# func_version +# ------------ +# Echo version message to standard output and exit. +func_version () +{ + $debug_cmd + + printf '%s\n' "$progname $scriptversion" + $SED -n ' + /(C)/!b go + :more + /\./!{ + N + s|\n# | | + b more + } + :go + /^# Written by /,/# warranty; / { + s|^# || + s|^# *$|| + s|\((C)\)[ 0-9,-]*[ ,-]\([1-9][0-9]* \)|\1 \2| + p + } + /^# Written by / { + s|^# || + p + } + /^warranty; /q' < "$progpath" + + exit $? +} + + +# Local variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC" +# time-stamp-time-zone: "UTC" +# End: + +# Set a version string. +scriptversion='(GNU libtool) 2.4.6' + + +# func_echo ARG... +# ---------------- +# Libtool also displays the current mode in messages, so override +# funclib.sh func_echo with this custom definition. +func_echo () +{ + $debug_cmd + + _G_message=$* + + func_echo_IFS=$IFS + IFS=$nl + for _G_line in $_G_message; do + IFS=$func_echo_IFS + $ECHO "$progname${opt_mode+: $opt_mode}: $_G_line" + done + IFS=$func_echo_IFS +} + + +# func_warning ARG... +# ------------------- +# Libtool warnings are not categorized, so override funclib.sh +# func_warning with this simpler definition. +func_warning () +{ + $debug_cmd + + $warning_func ${1+"$@"} +} + + +## ---------------- ## +## Options parsing. ## +## ---------------- ## + +# Hook in the functions to make sure our own options are parsed during +# the option parsing loop. + +usage='$progpath [OPTION]... [MODE-ARG]...' + +# Short help message in response to '-h'. +usage_message="Options: + --config show all configuration variables + --debug enable verbose shell tracing + -n, --dry-run display commands without modifying any files + --features display basic configuration information and exit + --mode=MODE use operation mode MODE + --no-warnings equivalent to '-Wnone' + --preserve-dup-deps don't remove duplicate dependency libraries + --quiet, --silent don't print informational messages + --tag=TAG use configuration variables from tag TAG + -v, --verbose print more informational messages than default + --version print version information + -W, --warnings=CATEGORY report the warnings falling in CATEGORY [all] + -h, --help, --help-all print short, long, or detailed help message +" + +# Additional text appended to 'usage_message' in response to '--help'. +func_help () +{ + $debug_cmd + + func_usage_message + $ECHO "$long_help_message + +MODE must be one of the following: + + clean remove files from the build directory + compile compile a source file into a libtool object + execute automatically set library path, then run a program + finish complete the installation of libtool libraries + install install libraries or executables + link create a library or an executable + uninstall remove libraries from an installed directory + +MODE-ARGS vary depending on the MODE. When passed as first option, +'--mode=MODE' may be abbreviated as 'MODE' or a unique abbreviation of that. +Try '$progname --help --mode=MODE' for a more detailed description of MODE. + +When reporting a bug, please describe a test case to reproduce it and +include the following information: + + host-triplet: $host + shell: $SHELL + compiler: $LTCC + compiler flags: $LTCFLAGS + linker: $LD (gnu? $with_gnu_ld) + version: $progname (GNU libtool) 2.4.6 + automake: `($AUTOMAKE --version) 2>/dev/null |$SED 1q` + autoconf: `($AUTOCONF --version) 2>/dev/null |$SED 1q` + +Report bugs to <bug-libtool@gnu.org>. +GNU libtool home page: <http://www.gnu.org/software/libtool/>. +General help using GNU software: <http://www.gnu.org/gethelp/>." + exit 0 +} + + +# func_lo2o OBJECT-NAME +# --------------------- +# Transform OBJECT-NAME from a '.lo' suffix to the platform specific +# object suffix. + +lo2o=s/\\.lo\$/.$objext/ +o2lo=s/\\.$objext\$/.lo/ + +if test yes = "$_G_HAVE_XSI_OPS"; then + eval 'func_lo2o () + { + case $1 in + *.lo) func_lo2o_result=${1%.lo}.$objext ;; + * ) func_lo2o_result=$1 ;; + esac + }' + + # func_xform LIBOBJ-OR-SOURCE + # --------------------------- + # Transform LIBOBJ-OR-SOURCE from a '.o' or '.c' (or otherwise) + # suffix to a '.lo' libtool-object suffix. + eval 'func_xform () + { + func_xform_result=${1%.*}.lo + }' +else + # ...otherwise fall back to using sed. + func_lo2o () + { + func_lo2o_result=`$ECHO "$1" | $SED "$lo2o"` + } + + func_xform () + { + func_xform_result=`$ECHO "$1" | $SED 's|\.[^.]*$|.lo|'` + } +fi + + +# func_fatal_configuration ARG... +# ------------------------------- +# Echo program name prefixed message to standard error, followed by +# a configuration failure hint, and exit. +func_fatal_configuration () +{ + func__fatal_error ${1+"$@"} \ + "See the $PACKAGE documentation for more information." \ + "Fatal configuration error." +} + + +# func_config +# ----------- +# Display the configuration for all the tags in this script. +func_config () +{ + re_begincf='^# ### BEGIN LIBTOOL' + re_endcf='^# ### END LIBTOOL' + + # Default configuration. + $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath" + + # Now print the configurations for the tags. + for tagname in $taglist; do + $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath" + done + + exit $? +} + + +# func_features +# ------------- +# Display the features supported by this script. +func_features () +{ + echo "host: $host" + if test yes = "$build_libtool_libs"; then + echo "enable shared libraries" + else + echo "disable shared libraries" + fi + if test yes = "$build_old_libs"; then + echo "enable static libraries" + else + echo "disable static libraries" + fi + + exit $? +} + + +# func_enable_tag TAGNAME +# ----------------------- +# Verify that TAGNAME is valid, and either flag an error and exit, or +# enable the TAGNAME tag. We also add TAGNAME to the global $taglist +# variable here. +func_enable_tag () +{ + # Global variable: + tagname=$1 + + re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$" + re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$" + sed_extractcf=/$re_begincf/,/$re_endcf/p + + # Validate tagname. + case $tagname in + *[!-_A-Za-z0-9,/]*) + func_fatal_error "invalid tag name: $tagname" + ;; + esac + + # Don't test for the "default" C tag, as we know it's + # there but not specially marked. + case $tagname in + CC) ;; + *) + if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then + taglist="$taglist $tagname" + + # Evaluate the configuration. Be careful to quote the path + # and the sed script, to avoid splitting on whitespace, but + # also don't use non-portable quotes within backquotes within + # quotes we have to do it in 2 steps: + extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"` + eval "$extractedcf" + else + func_error "ignoring unknown tag $tagname" + fi + ;; + esac +} + + +# func_check_version_match +# ------------------------ +# Ensure that we are using m4 macros, and libtool script from the same +# release of libtool. +func_check_version_match () +{ + if test "$package_revision" != "$macro_revision"; then + if test "$VERSION" != "$macro_version"; then + if test -z "$macro_version"; then + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, but the +$progname: definition of this LT_INIT comes from an older release. +$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION +$progname: and run autoconf again. +_LT_EOF + else + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, but the +$progname: definition of this LT_INIT comes from $PACKAGE $macro_version. +$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION +$progname: and run autoconf again. +_LT_EOF + fi + else + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision, +$progname: but the definition of this LT_INIT comes from revision $macro_revision. +$progname: You should recreate aclocal.m4 with macros from revision $package_revision +$progname: of $PACKAGE $VERSION and run autoconf again. +_LT_EOF + fi + + exit $EXIT_MISMATCH + fi +} + + +# libtool_options_prep [ARG]... +# ----------------------------- +# Preparation for options parsed by libtool. +libtool_options_prep () +{ + $debug_mode + + # Option defaults: + opt_config=false + opt_dlopen= + opt_dry_run=false + opt_help=false + opt_mode= + opt_preserve_dup_deps=false + opt_quiet=false + + nonopt= + preserve_args= + + # Shorthand for --mode=foo, only valid as the first argument + case $1 in + clean|clea|cle|cl) + shift; set dummy --mode clean ${1+"$@"}; shift + ;; + compile|compil|compi|comp|com|co|c) + shift; set dummy --mode compile ${1+"$@"}; shift + ;; + execute|execut|execu|exec|exe|ex|e) + shift; set dummy --mode execute ${1+"$@"}; shift + ;; + finish|finis|fini|fin|fi|f) + shift; set dummy --mode finish ${1+"$@"}; shift + ;; + install|instal|insta|inst|ins|in|i) + shift; set dummy --mode install ${1+"$@"}; shift + ;; + link|lin|li|l) + shift; set dummy --mode link ${1+"$@"}; shift + ;; + uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) + shift; set dummy --mode uninstall ${1+"$@"}; shift + ;; + esac + + # Pass back the list of options. + func_quote_for_eval ${1+"$@"} + libtool_options_prep_result=$func_quote_for_eval_result +} +func_add_hook func_options_prep libtool_options_prep + + +# libtool_parse_options [ARG]... +# --------------------------------- +# Provide handling for libtool specific options. +libtool_parse_options () +{ + $debug_cmd + + # Perform our own loop to consume as many options as possible in + # each iteration. + while test $# -gt 0; do + _G_opt=$1 + shift + case $_G_opt in + --dry-run|--dryrun|-n) + opt_dry_run=: + ;; + + --config) func_config ;; + + --dlopen|-dlopen) + opt_dlopen="${opt_dlopen+$opt_dlopen +}$1" + shift + ;; + + --preserve-dup-deps) + opt_preserve_dup_deps=: ;; + + --features) func_features ;; + + --finish) set dummy --mode finish ${1+"$@"}; shift ;; + + --help) opt_help=: ;; + + --help-all) opt_help=': help-all' ;; + + --mode) test $# = 0 && func_missing_arg $_G_opt && break + opt_mode=$1 + case $1 in + # Valid mode arguments: + clean|compile|execute|finish|install|link|relink|uninstall) ;; + + # Catch anything else as an error + *) func_error "invalid argument for $_G_opt" + exit_cmd=exit + break + ;; + esac + shift + ;; + + --no-silent|--no-quiet) + opt_quiet=false + func_append preserve_args " $_G_opt" + ;; + + --no-warnings|--no-warning|--no-warn) + opt_warning=false + func_append preserve_args " $_G_opt" + ;; + + --no-verbose) + opt_verbose=false + func_append preserve_args " $_G_opt" + ;; + + --silent|--quiet) + opt_quiet=: + opt_verbose=false + func_append preserve_args " $_G_opt" + ;; + + --tag) test $# = 0 && func_missing_arg $_G_opt && break + opt_tag=$1 + func_append preserve_args " $_G_opt $1" + func_enable_tag "$1" + shift + ;; + + --verbose|-v) opt_quiet=false + opt_verbose=: + func_append preserve_args " $_G_opt" + ;; + + # An option not handled by this hook function: + *) set dummy "$_G_opt" ${1+"$@"}; shift; break ;; + esac + done + + + # save modified positional parameters for caller + func_quote_for_eval ${1+"$@"} + libtool_parse_options_result=$func_quote_for_eval_result +} +func_add_hook func_parse_options libtool_parse_options + + + +# libtool_validate_options [ARG]... +# --------------------------------- +# Perform any sanity checks on option settings and/or unconsumed +# arguments. +libtool_validate_options () +{ + # save first non-option argument + if test 0 -lt $#; then + nonopt=$1 + shift + fi + + # preserve --debug + test : = "$debug_cmd" || func_append preserve_args " --debug" + + case $host in + # Solaris2 added to fix http://debbugs.gnu.org/cgi/bugreport.cgi?bug=16452 + # see also: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59788 + *cygwin* | *mingw* | *pw32* | *cegcc* | *solaris2* | *os2*) + # don't eliminate duplications in $postdeps and $predeps + opt_duplicate_compiler_generated_deps=: + ;; + *) + opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps + ;; + esac + + $opt_help || { + # Sanity checks first: + func_check_version_match + + test yes != "$build_libtool_libs" \ + && test yes != "$build_old_libs" \ + && func_fatal_configuration "not configured to build any kind of library" + + # Darwin sucks + eval std_shrext=\"$shrext_cmds\" + + # Only execute mode is allowed to have -dlopen flags. + if test -n "$opt_dlopen" && test execute != "$opt_mode"; then + func_error "unrecognized option '-dlopen'" + $ECHO "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # Change the help message to a mode-specific one. + generic_help=$help + help="Try '$progname --help --mode=$opt_mode' for more information." + } + + # Pass back the unparsed argument list + func_quote_for_eval ${1+"$@"} + libtool_validate_options_result=$func_quote_for_eval_result +} +func_add_hook func_validate_options libtool_validate_options + + +# Process options as early as possible so that --help and --version +# can return quickly. +func_options ${1+"$@"} +eval set dummy "$func_options_result"; shift + + + +## ----------- ## +## Main. ## +## ----------- ## + +magic='%%%MAGIC variable%%%' +magic_exe='%%%MAGIC EXE variable%%%' + +# Global variables. +extracted_archives= +extracted_serial=0 + +# If this variable is set in any of the actions, the command in it +# will be execed at the end. This prevents here-documents from being +# left over by shells. +exec_cmd= + + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +$1 +_LTECHO_EOF' +} + +# func_generated_by_libtool +# True iff stdin has been generated by Libtool. This function is only +# a basic sanity check; it will hardly flush out determined imposters. +func_generated_by_libtool_p () +{ + $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1 +} + +# func_lalib_p file +# True iff FILE is a libtool '.la' library or '.lo' object file. +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_lalib_p () +{ + test -f "$1" && + $SED -e 4q "$1" 2>/dev/null | func_generated_by_libtool_p +} + +# func_lalib_unsafe_p file +# True iff FILE is a libtool '.la' library or '.lo' object file. +# This function implements the same check as func_lalib_p without +# resorting to external programs. To this end, it redirects stdin and +# closes it afterwards, without saving the original file descriptor. +# As a safety measure, use it only where a negative result would be +# fatal anyway. Works if 'file' does not exist. +func_lalib_unsafe_p () +{ + lalib_p=no + if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then + for lalib_p_l in 1 2 3 4 + do + read lalib_p_line + case $lalib_p_line in + \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;; + esac + done + exec 0<&5 5<&- + fi + test yes = "$lalib_p" +} + +# func_ltwrapper_script_p file +# True iff FILE is a libtool wrapper script +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_script_p () +{ + test -f "$1" && + $lt_truncate_bin < "$1" 2>/dev/null | func_generated_by_libtool_p +} + +# func_ltwrapper_executable_p file +# True iff FILE is a libtool wrapper executable +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_executable_p () +{ + func_ltwrapper_exec_suffix= + case $1 in + *.exe) ;; + *) func_ltwrapper_exec_suffix=.exe ;; + esac + $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1 +} + +# func_ltwrapper_scriptname file +# Assumes file is an ltwrapper_executable +# uses $file to determine the appropriate filename for a +# temporary ltwrapper_script. +func_ltwrapper_scriptname () +{ + func_dirname_and_basename "$1" "" "." + func_stripname '' '.exe' "$func_basename_result" + func_ltwrapper_scriptname_result=$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper +} + +# func_ltwrapper_p file +# True iff FILE is a libtool wrapper script or wrapper executable +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_p () +{ + func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1" +} + + +# func_execute_cmds commands fail_cmd +# Execute tilde-delimited COMMANDS. +# If FAIL_CMD is given, eval that upon failure. +# FAIL_CMD may read-access the current command in variable CMD! +func_execute_cmds () +{ + $debug_cmd + + save_ifs=$IFS; IFS='~' + for cmd in $1; do + IFS=$sp$nl + eval cmd=\"$cmd\" + IFS=$save_ifs + func_show_eval "$cmd" "${2-:}" + done + IFS=$save_ifs +} + + +# func_source file +# Source FILE, adding directory component if necessary. +# Note that it is not necessary on cygwin/mingw to append a dot to +# FILE even if both FILE and FILE.exe exist: automatic-append-.exe +# behavior happens only for exec(3), not for open(2)! Also, sourcing +# 'FILE.' does not work on cygwin managed mounts. +func_source () +{ + $debug_cmd + + case $1 in + */* | *\\*) . "$1" ;; + *) . "./$1" ;; + esac +} + + +# func_resolve_sysroot PATH +# Replace a leading = in PATH with a sysroot. Store the result into +# func_resolve_sysroot_result +func_resolve_sysroot () +{ + func_resolve_sysroot_result=$1 + case $func_resolve_sysroot_result in + =*) + func_stripname '=' '' "$func_resolve_sysroot_result" + func_resolve_sysroot_result=$lt_sysroot$func_stripname_result + ;; + esac +} + +# func_replace_sysroot PATH +# If PATH begins with the sysroot, replace it with = and +# store the result into func_replace_sysroot_result. +func_replace_sysroot () +{ + case $lt_sysroot:$1 in + ?*:"$lt_sysroot"*) + func_stripname "$lt_sysroot" '' "$1" + func_replace_sysroot_result='='$func_stripname_result + ;; + *) + # Including no sysroot. + func_replace_sysroot_result=$1 + ;; + esac +} + +# func_infer_tag arg +# Infer tagged configuration to use if any are available and +# if one wasn't chosen via the "--tag" command line option. +# Only attempt this if the compiler in the base compile +# command doesn't match the default compiler. +# arg is usually of the form 'gcc ...' +func_infer_tag () +{ + $debug_cmd + + if test -n "$available_tags" && test -z "$tagname"; then + CC_quoted= + for arg in $CC; do + func_append_quoted CC_quoted "$arg" + done + CC_expanded=`func_echo_all $CC` + CC_quoted_expanded=`func_echo_all $CC_quoted` + case $@ in + # Blanks in the command may have been stripped by the calling shell, + # but not from the CC environment variable when configure was run. + " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ + " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;; + # Blanks at the start of $base_compile will cause this to fail + # if we don't check for them as well. + *) + for z in $available_tags; do + if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then + # Evaluate the configuration. + eval "`$SED -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" + CC_quoted= + for arg in $CC; do + # Double-quote args containing other shell metacharacters. + func_append_quoted CC_quoted "$arg" + done + CC_expanded=`func_echo_all $CC` + CC_quoted_expanded=`func_echo_all $CC_quoted` + case "$@ " in + " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ + " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) + # The compiler in the base compile command matches + # the one in the tagged configuration. + # Assume this is the tagged configuration we want. + tagname=$z + break + ;; + esac + fi + done + # If $tagname still isn't set, then no tagged configuration + # was found and let the user know that the "--tag" command + # line option must be used. + if test -z "$tagname"; then + func_echo "unable to infer tagged configuration" + func_fatal_error "specify a tag with '--tag'" +# else +# func_verbose "using $tagname tagged configuration" + fi + ;; + esac + fi +} + + + +# func_write_libtool_object output_name pic_name nonpic_name +# Create a libtool object file (analogous to a ".la" file), +# but don't create it if we're doing a dry run. +func_write_libtool_object () +{ + write_libobj=$1 + if test yes = "$build_libtool_libs"; then + write_lobj=\'$2\' + else + write_lobj=none + fi + + if test yes = "$build_old_libs"; then + write_oldobj=\'$3\' + else + write_oldobj=none + fi + + $opt_dry_run || { + cat >${write_libobj}T <<EOF +# $write_libobj - a libtool object file +# Generated by $PROGRAM (GNU $PACKAGE) $VERSION +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# Name of the PIC object. +pic_object=$write_lobj + +# Name of the non-PIC object +non_pic_object=$write_oldobj + +EOF + $MV "${write_libobj}T" "$write_libobj" + } +} + + +################################################## +# FILE NAME AND PATH CONVERSION HELPER FUNCTIONS # +################################################## + +# func_convert_core_file_wine_to_w32 ARG +# Helper function used by file name conversion functions when $build is *nix, +# and $host is mingw, cygwin, or some other w32 environment. Relies on a +# correctly configured wine environment available, with the winepath program +# in $build's $PATH. +# +# ARG is the $build file name to be converted to w32 format. +# Result is available in $func_convert_core_file_wine_to_w32_result, and will +# be empty on error (or when ARG is empty) +func_convert_core_file_wine_to_w32 () +{ + $debug_cmd + + func_convert_core_file_wine_to_w32_result=$1 + if test -n "$1"; then + # Unfortunately, winepath does not exit with a non-zero error code, so we + # are forced to check the contents of stdout. On the other hand, if the + # command is not found, the shell will set an exit code of 127 and print + # *an error message* to stdout. So we must check for both error code of + # zero AND non-empty stdout, which explains the odd construction: + func_convert_core_file_wine_to_w32_tmp=`winepath -w "$1" 2>/dev/null` + if test "$?" -eq 0 && test -n "$func_convert_core_file_wine_to_w32_tmp"; then + func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" | + $SED -e "$sed_naive_backslashify"` + else + func_convert_core_file_wine_to_w32_result= + fi + fi +} +# end: func_convert_core_file_wine_to_w32 + + +# func_convert_core_path_wine_to_w32 ARG +# Helper function used by path conversion functions when $build is *nix, and +# $host is mingw, cygwin, or some other w32 environment. Relies on a correctly +# configured wine environment available, with the winepath program in $build's +# $PATH. Assumes ARG has no leading or trailing path separator characters. +# +# ARG is path to be converted from $build format to win32. +# Result is available in $func_convert_core_path_wine_to_w32_result. +# Unconvertible file (directory) names in ARG are skipped; if no directory names +# are convertible, then the result may be empty. +func_convert_core_path_wine_to_w32 () +{ + $debug_cmd + + # unfortunately, winepath doesn't convert paths, only file names + func_convert_core_path_wine_to_w32_result= + if test -n "$1"; then + oldIFS=$IFS + IFS=: + for func_convert_core_path_wine_to_w32_f in $1; do + IFS=$oldIFS + func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f" + if test -n "$func_convert_core_file_wine_to_w32_result"; then + if test -z "$func_convert_core_path_wine_to_w32_result"; then + func_convert_core_path_wine_to_w32_result=$func_convert_core_file_wine_to_w32_result + else + func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result" + fi + fi + done + IFS=$oldIFS + fi +} +# end: func_convert_core_path_wine_to_w32 + + +# func_cygpath ARGS... +# Wrapper around calling the cygpath program via LT_CYGPATH. This is used when +# when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2) +# $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or +# (2), returns the Cygwin file name or path in func_cygpath_result (input +# file name or path is assumed to be in w32 format, as previously converted +# from $build's *nix or MSYS format). In case (3), returns the w32 file name +# or path in func_cygpath_result (input file name or path is assumed to be in +# Cygwin format). Returns an empty string on error. +# +# ARGS are passed to cygpath, with the last one being the file name or path to +# be converted. +# +# Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH +# environment variable; do not put it in $PATH. +func_cygpath () +{ + $debug_cmd + + if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then + func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null` + if test "$?" -ne 0; then + # on failure, ensure result is empty + func_cygpath_result= + fi + else + func_cygpath_result= + func_error "LT_CYGPATH is empty or specifies non-existent file: '$LT_CYGPATH'" + fi +} +#end: func_cygpath + + +# func_convert_core_msys_to_w32 ARG +# Convert file name or path ARG from MSYS format to w32 format. Return +# result in func_convert_core_msys_to_w32_result. +func_convert_core_msys_to_w32 () +{ + $debug_cmd + + # awkward: cmd appends spaces to result + func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null | + $SED -e 's/[ ]*$//' -e "$sed_naive_backslashify"` +} +#end: func_convert_core_msys_to_w32 + + +# func_convert_file_check ARG1 ARG2 +# Verify that ARG1 (a file name in $build format) was converted to $host +# format in ARG2. Otherwise, emit an error message, but continue (resetting +# func_to_host_file_result to ARG1). +func_convert_file_check () +{ + $debug_cmd + + if test -z "$2" && test -n "$1"; then + func_error "Could not determine host file name corresponding to" + func_error " '$1'" + func_error "Continuing, but uninstalled executables may not work." + # Fallback: + func_to_host_file_result=$1 + fi +} +# end func_convert_file_check + + +# func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH +# Verify that FROM_PATH (a path in $build format) was converted to $host +# format in TO_PATH. Otherwise, emit an error message, but continue, resetting +# func_to_host_file_result to a simplistic fallback value (see below). +func_convert_path_check () +{ + $debug_cmd + + if test -z "$4" && test -n "$3"; then + func_error "Could not determine the host path corresponding to" + func_error " '$3'" + func_error "Continuing, but uninstalled executables may not work." + # Fallback. This is a deliberately simplistic "conversion" and + # should not be "improved". See libtool.info. + if test "x$1" != "x$2"; then + lt_replace_pathsep_chars="s|$1|$2|g" + func_to_host_path_result=`echo "$3" | + $SED -e "$lt_replace_pathsep_chars"` + else + func_to_host_path_result=$3 + fi + fi +} +# end func_convert_path_check + + +# func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG +# Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT +# and appending REPL if ORIG matches BACKPAT. +func_convert_path_front_back_pathsep () +{ + $debug_cmd + + case $4 in + $1 ) func_to_host_path_result=$3$func_to_host_path_result + ;; + esac + case $4 in + $2 ) func_append func_to_host_path_result "$3" + ;; + esac +} +# end func_convert_path_front_back_pathsep + + +################################################## +# $build to $host FILE NAME CONVERSION FUNCTIONS # +################################################## +# invoked via '$to_host_file_cmd ARG' +# +# In each case, ARG is the path to be converted from $build to $host format. +# Result will be available in $func_to_host_file_result. + + +# func_to_host_file ARG +# Converts the file name ARG from $build format to $host format. Return result +# in func_to_host_file_result. +func_to_host_file () +{ + $debug_cmd + + $to_host_file_cmd "$1" +} +# end func_to_host_file + + +# func_to_tool_file ARG LAZY +# converts the file name ARG from $build format to toolchain format. Return +# result in func_to_tool_file_result. If the conversion in use is listed +# in (the comma separated) LAZY, no conversion takes place. +func_to_tool_file () +{ + $debug_cmd + + case ,$2, in + *,"$to_tool_file_cmd",*) + func_to_tool_file_result=$1 + ;; + *) + $to_tool_file_cmd "$1" + func_to_tool_file_result=$func_to_host_file_result + ;; + esac +} +# end func_to_tool_file + + +# func_convert_file_noop ARG +# Copy ARG to func_to_host_file_result. +func_convert_file_noop () +{ + func_to_host_file_result=$1 +} +# end func_convert_file_noop + + +# func_convert_file_msys_to_w32 ARG +# Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic +# conversion to w32 is not available inside the cwrapper. Returns result in +# func_to_host_file_result. +func_convert_file_msys_to_w32 () +{ + $debug_cmd + + func_to_host_file_result=$1 + if test -n "$1"; then + func_convert_core_msys_to_w32 "$1" + func_to_host_file_result=$func_convert_core_msys_to_w32_result + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_msys_to_w32 + + +# func_convert_file_cygwin_to_w32 ARG +# Convert file name ARG from Cygwin to w32 format. Returns result in +# func_to_host_file_result. +func_convert_file_cygwin_to_w32 () +{ + $debug_cmd + + func_to_host_file_result=$1 + if test -n "$1"; then + # because $build is cygwin, we call "the" cygpath in $PATH; no need to use + # LT_CYGPATH in this case. + func_to_host_file_result=`cygpath -m "$1"` + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_cygwin_to_w32 + + +# func_convert_file_nix_to_w32 ARG +# Convert file name ARG from *nix to w32 format. Requires a wine environment +# and a working winepath. Returns result in func_to_host_file_result. +func_convert_file_nix_to_w32 () +{ + $debug_cmd + + func_to_host_file_result=$1 + if test -n "$1"; then + func_convert_core_file_wine_to_w32 "$1" + func_to_host_file_result=$func_convert_core_file_wine_to_w32_result + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_nix_to_w32 + + +# func_convert_file_msys_to_cygwin ARG +# Convert file name ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. +# Returns result in func_to_host_file_result. +func_convert_file_msys_to_cygwin () +{ + $debug_cmd + + func_to_host_file_result=$1 + if test -n "$1"; then + func_convert_core_msys_to_w32 "$1" + func_cygpath -u "$func_convert_core_msys_to_w32_result" + func_to_host_file_result=$func_cygpath_result + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_msys_to_cygwin + + +# func_convert_file_nix_to_cygwin ARG +# Convert file name ARG from *nix to Cygwin format. Requires Cygwin installed +# in a wine environment, working winepath, and LT_CYGPATH set. Returns result +# in func_to_host_file_result. +func_convert_file_nix_to_cygwin () +{ + $debug_cmd + + func_to_host_file_result=$1 + if test -n "$1"; then + # convert from *nix to w32, then use cygpath to convert from w32 to cygwin. + func_convert_core_file_wine_to_w32 "$1" + func_cygpath -u "$func_convert_core_file_wine_to_w32_result" + func_to_host_file_result=$func_cygpath_result + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_nix_to_cygwin + + +############################################# +# $build to $host PATH CONVERSION FUNCTIONS # +############################################# +# invoked via '$to_host_path_cmd ARG' +# +# In each case, ARG is the path to be converted from $build to $host format. +# The result will be available in $func_to_host_path_result. +# +# Path separators are also converted from $build format to $host format. If +# ARG begins or ends with a path separator character, it is preserved (but +# converted to $host format) on output. +# +# All path conversion functions are named using the following convention: +# file name conversion function : func_convert_file_X_to_Y () +# path conversion function : func_convert_path_X_to_Y () +# where, for any given $build/$host combination the 'X_to_Y' value is the +# same. If conversion functions are added for new $build/$host combinations, +# the two new functions must follow this pattern, or func_init_to_host_path_cmd +# will break. + + +# func_init_to_host_path_cmd +# Ensures that function "pointer" variable $to_host_path_cmd is set to the +# appropriate value, based on the value of $to_host_file_cmd. +to_host_path_cmd= +func_init_to_host_path_cmd () +{ + $debug_cmd + + if test -z "$to_host_path_cmd"; then + func_stripname 'func_convert_file_' '' "$to_host_file_cmd" + to_host_path_cmd=func_convert_path_$func_stripname_result + fi +} + + +# func_to_host_path ARG +# Converts the path ARG from $build format to $host format. Return result +# in func_to_host_path_result. +func_to_host_path () +{ + $debug_cmd + + func_init_to_host_path_cmd + $to_host_path_cmd "$1" +} +# end func_to_host_path + + +# func_convert_path_noop ARG +# Copy ARG to func_to_host_path_result. +func_convert_path_noop () +{ + func_to_host_path_result=$1 +} +# end func_convert_path_noop + + +# func_convert_path_msys_to_w32 ARG +# Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic +# conversion to w32 is not available inside the cwrapper. Returns result in +# func_to_host_path_result. +func_convert_path_msys_to_w32 () +{ + $debug_cmd + + func_to_host_path_result=$1 + if test -n "$1"; then + # Remove leading and trailing path separator characters from ARG. MSYS + # behavior is inconsistent here; cygpath turns them into '.;' and ';.'; + # and winepath ignores them completely. + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" + func_to_host_path_result=$func_convert_core_msys_to_w32_result + func_convert_path_check : ";" \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" + fi +} +# end func_convert_path_msys_to_w32 + + +# func_convert_path_cygwin_to_w32 ARG +# Convert path ARG from Cygwin to w32 format. Returns result in +# func_to_host_file_result. +func_convert_path_cygwin_to_w32 () +{ + $debug_cmd + + func_to_host_path_result=$1 + if test -n "$1"; then + # See func_convert_path_msys_to_w32: + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"` + func_convert_path_check : ";" \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" + fi +} +# end func_convert_path_cygwin_to_w32 + + +# func_convert_path_nix_to_w32 ARG +# Convert path ARG from *nix to w32 format. Requires a wine environment and +# a working winepath. Returns result in func_to_host_file_result. +func_convert_path_nix_to_w32 () +{ + $debug_cmd + + func_to_host_path_result=$1 + if test -n "$1"; then + # See func_convert_path_msys_to_w32: + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" + func_to_host_path_result=$func_convert_core_path_wine_to_w32_result + func_convert_path_check : ";" \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" + fi +} +# end func_convert_path_nix_to_w32 + + +# func_convert_path_msys_to_cygwin ARG +# Convert path ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. +# Returns result in func_to_host_file_result. +func_convert_path_msys_to_cygwin () +{ + $debug_cmd + + func_to_host_path_result=$1 + if test -n "$1"; then + # See func_convert_path_msys_to_w32: + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" + func_cygpath -u -p "$func_convert_core_msys_to_w32_result" + func_to_host_path_result=$func_cygpath_result + func_convert_path_check : : \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" : "$1" + fi +} +# end func_convert_path_msys_to_cygwin + + +# func_convert_path_nix_to_cygwin ARG +# Convert path ARG from *nix to Cygwin format. Requires Cygwin installed in a +# a wine environment, working winepath, and LT_CYGPATH set. Returns result in +# func_to_host_file_result. +func_convert_path_nix_to_cygwin () +{ + $debug_cmd + + func_to_host_path_result=$1 + if test -n "$1"; then + # Remove leading and trailing path separator characters from + # ARG. msys behavior is inconsistent here, cygpath turns them + # into '.;' and ';.', and winepath ignores them completely. + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" + func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result" + func_to_host_path_result=$func_cygpath_result + func_convert_path_check : : \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" : "$1" + fi +} +# end func_convert_path_nix_to_cygwin + + +# func_dll_def_p FILE +# True iff FILE is a Windows DLL '.def' file. +# Keep in sync with _LT_DLL_DEF_P in libtool.m4 +func_dll_def_p () +{ + $debug_cmd + + func_dll_def_p_tmp=`$SED -n \ + -e 's/^[ ]*//' \ + -e '/^\(;.*\)*$/d' \ + -e 's/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p' \ + -e q \ + "$1"` + test DEF = "$func_dll_def_p_tmp" +} + + +# func_mode_compile arg... +func_mode_compile () +{ + $debug_cmd + + # Get the compilation command and the source file. + base_compile= + srcfile=$nonopt # always keep a non-empty value in "srcfile" + suppress_opt=yes + suppress_output= + arg_mode=normal + libobj= + later= + pie_flag= + + for arg + do + case $arg_mode in + arg ) + # do not "continue". Instead, add this to base_compile + lastarg=$arg + arg_mode=normal + ;; + + target ) + libobj=$arg + arg_mode=normal + continue + ;; + + normal ) + # Accept any command-line options. + case $arg in + -o) + test -n "$libobj" && \ + func_fatal_error "you cannot specify '-o' more than once" + arg_mode=target + continue + ;; + + -pie | -fpie | -fPIE) + func_append pie_flag " $arg" + continue + ;; + + -shared | -static | -prefer-pic | -prefer-non-pic) + func_append later " $arg" + continue + ;; + + -no-suppress) + suppress_opt=no + continue + ;; + + -Xcompiler) + arg_mode=arg # the next one goes into the "base_compile" arg list + continue # The current "srcfile" will either be retained or + ;; # replaced later. I would guess that would be a bug. + + -Wc,*) + func_stripname '-Wc,' '' "$arg" + args=$func_stripname_result + lastarg= + save_ifs=$IFS; IFS=, + for arg in $args; do + IFS=$save_ifs + func_append_quoted lastarg "$arg" + done + IFS=$save_ifs + func_stripname ' ' '' "$lastarg" + lastarg=$func_stripname_result + + # Add the arguments to base_compile. + func_append base_compile " $lastarg" + continue + ;; + + *) + # Accept the current argument as the source file. + # The previous "srcfile" becomes the current argument. + # + lastarg=$srcfile + srcfile=$arg + ;; + esac # case $arg + ;; + esac # case $arg_mode + + # Aesthetically quote the previous argument. + func_append_quoted base_compile "$lastarg" + done # for arg + + case $arg_mode in + arg) + func_fatal_error "you must specify an argument for -Xcompile" + ;; + target) + func_fatal_error "you must specify a target with '-o'" + ;; + *) + # Get the name of the library object. + test -z "$libobj" && { + func_basename "$srcfile" + libobj=$func_basename_result + } + ;; + esac + + # Recognize several different file suffixes. + # If the user specifies -o file.o, it is replaced with file.lo + case $libobj in + *.[cCFSifmso] | \ + *.ada | *.adb | *.ads | *.asm | \ + *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \ + *.[fF][09]? | *.for | *.java | *.go | *.obj | *.sx | *.cu | *.cup) + func_xform "$libobj" + libobj=$func_xform_result + ;; + esac + + case $libobj in + *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;; + *) + func_fatal_error "cannot determine name of library object from '$libobj'" + ;; + esac + + func_infer_tag $base_compile + + for arg in $later; do + case $arg in + -shared) + test yes = "$build_libtool_libs" \ + || func_fatal_configuration "cannot build a shared library" + build_old_libs=no + continue + ;; + + -static) + build_libtool_libs=no + build_old_libs=yes + continue + ;; + + -prefer-pic) + pic_mode=yes + continue + ;; + + -prefer-non-pic) + pic_mode=no + continue + ;; + esac + done + + func_quote_for_eval "$libobj" + test "X$libobj" != "X$func_quote_for_eval_result" \ + && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \ + && func_warning "libobj name '$libobj' may not contain shell special characters." + func_dirname_and_basename "$obj" "/" "" + objname=$func_basename_result + xdir=$func_dirname_result + lobj=$xdir$objdir/$objname + + test -z "$base_compile" && \ + func_fatal_help "you must specify a compilation command" + + # Delete any leftover library objects. + if test yes = "$build_old_libs"; then + removelist="$obj $lobj $libobj ${libobj}T" + else + removelist="$lobj $libobj ${libobj}T" + fi + + # On Cygwin there's no "real" PIC flag so we must build both object types + case $host_os in + cygwin* | mingw* | pw32* | os2* | cegcc*) + pic_mode=default + ;; + esac + if test no = "$pic_mode" && test pass_all != "$deplibs_check_method"; then + # non-PIC code in shared libraries is not supported + pic_mode=default + fi + + # Calculate the filename of the output object if compiler does + # not support -o with -c + if test no = "$compiler_c_o"; then + output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.$objext + lockfile=$output_obj.lock + else + output_obj= + need_locks=no + lockfile= + fi + + # Lock this critical section if it is needed + # We use this script file to make the link, it avoids creating a new file + if test yes = "$need_locks"; then + until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do + func_echo "Waiting for $lockfile to be removed" + sleep 2 + done + elif test warn = "$need_locks"; then + if test -f "$lockfile"; then + $ECHO "\ +*** ERROR, $lockfile exists and contains: +`cat $lockfile 2>/dev/null` + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support '-c' and '-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + func_append removelist " $output_obj" + $ECHO "$srcfile" > "$lockfile" + fi + + $opt_dry_run || $RM $removelist + func_append removelist " $lockfile" + trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15 + + func_to_tool_file "$srcfile" func_convert_file_msys_to_w32 + srcfile=$func_to_tool_file_result + func_quote_for_eval "$srcfile" + qsrcfile=$func_quote_for_eval_result + + # Only build a PIC object if we are building libtool libraries. + if test yes = "$build_libtool_libs"; then + # Without this assignment, base_compile gets emptied. + fbsd_hideous_sh_bug=$base_compile + + if test no != "$pic_mode"; then + command="$base_compile $qsrcfile $pic_flag" + else + # Don't build PIC code + command="$base_compile $qsrcfile" + fi + + func_mkdir_p "$xdir$objdir" + + if test -z "$output_obj"; then + # Place PIC objects in $objdir + func_append command " -o $lobj" + fi + + func_show_eval_locale "$command" \ + 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE' + + if test warn = "$need_locks" && + test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then + $ECHO "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support '-c' and '-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed, then go on to compile the next one + if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then + func_show_eval '$MV "$output_obj" "$lobj"' \ + 'error=$?; $opt_dry_run || $RM $removelist; exit $error' + fi + + # Allow error messages only from the first compilation. + if test yes = "$suppress_opt"; then + suppress_output=' >/dev/null 2>&1' + fi + fi + + # Only build a position-dependent object if we build old libraries. + if test yes = "$build_old_libs"; then + if test yes != "$pic_mode"; then + # Don't build PIC code + command="$base_compile $qsrcfile$pie_flag" + else + command="$base_compile $qsrcfile $pic_flag" + fi + if test yes = "$compiler_c_o"; then + func_append command " -o $obj" + fi + + # Suppress compiler output if we already did a PIC compilation. + func_append command "$suppress_output" + func_show_eval_locale "$command" \ + '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' + + if test warn = "$need_locks" && + test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then + $ECHO "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support '-c' and '-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed + if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then + func_show_eval '$MV "$output_obj" "$obj"' \ + 'error=$?; $opt_dry_run || $RM $removelist; exit $error' + fi + fi + + $opt_dry_run || { + func_write_libtool_object "$libobj" "$objdir/$objname" "$objname" + + # Unlock the critical section if it was locked + if test no != "$need_locks"; then + removelist=$lockfile + $RM "$lockfile" + fi + } + + exit $EXIT_SUCCESS +} + +$opt_help || { + test compile = "$opt_mode" && func_mode_compile ${1+"$@"} +} + +func_mode_help () +{ + # We need to display help for each of the modes. + case $opt_mode in + "") + # Generic help is extracted from the usage comments + # at the start of this file. + func_help + ;; + + clean) + $ECHO \ +"Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE... + +Remove files from the build directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically '/bin/rm'). RM-OPTIONS are options (such as '-f') to be passed +to RM. + +If FILE is a libtool library, object or program, all the files associated +with it are deleted. Otherwise, only FILE itself is deleted using RM." + ;; + + compile) + $ECHO \ +"Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE + +Compile a source file into a libtool library object. + +This mode accepts the following additional options: + + -o OUTPUT-FILE set the output file name to OUTPUT-FILE + -no-suppress do not suppress compiler output for multiple passes + -prefer-pic try to build PIC objects only + -prefer-non-pic try to build non-PIC objects only + -shared do not build a '.o' file suitable for static linking + -static only build a '.o' file suitable for static linking + -Wc,FLAG pass FLAG directly to the compiler + +COMPILE-COMMAND is a command to be used in creating a 'standard' object file +from the given SOURCEFILE. + +The output file name is determined by removing the directory component from +SOURCEFILE, then substituting the C source code suffix '.c' with the +library object suffix, '.lo'." + ;; + + execute) + $ECHO \ +"Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]... + +Automatically set library path, then run a program. + +This mode accepts the following additional options: + + -dlopen FILE add the directory containing FILE to the library path + +This mode sets the library path environment variable according to '-dlopen' +flags. + +If any of the ARGS are libtool executable wrappers, then they are translated +into their corresponding uninstalled binary, and any of their required library +directories are added to the library path. + +Then, COMMAND is executed, with ARGS as arguments." + ;; + + finish) + $ECHO \ +"Usage: $progname [OPTION]... --mode=finish [LIBDIR]... + +Complete the installation of libtool libraries. + +Each LIBDIR is a directory that contains libtool libraries. + +The commands that this mode executes may require superuser privileges. Use +the '--dry-run' option if you just want to see what would be executed." + ;; + + install) + $ECHO \ +"Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND... + +Install executables or libraries. + +INSTALL-COMMAND is the installation command. The first component should be +either the 'install' or 'cp' program. + +The following components of INSTALL-COMMAND are treated specially: + + -inst-prefix-dir PREFIX-DIR Use PREFIX-DIR as a staging area for installation + +The rest of the components are interpreted as arguments to that command (only +BSD-compatible install options are recognized)." + ;; + + link) + $ECHO \ +"Usage: $progname [OPTION]... --mode=link LINK-COMMAND... + +Link object files or libraries together to form another library, or to +create an executable program. + +LINK-COMMAND is a command using the C compiler that you would use to create +a program from several object files. + +The following components of LINK-COMMAND are treated specially: + + -all-static do not do any dynamic linking at all + -avoid-version do not add a version suffix if possible + -bindir BINDIR specify path to binaries directory (for systems where + libraries must be found in the PATH setting at runtime) + -dlopen FILE '-dlpreopen' FILE if it cannot be dlopened at runtime + -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols + -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) + -export-symbols SYMFILE + try to export only the symbols listed in SYMFILE + -export-symbols-regex REGEX + try to export only the symbols matching REGEX + -LLIBDIR search LIBDIR for required installed libraries + -lNAME OUTPUT-FILE requires the installed library libNAME + -module build a library that can dlopened + -no-fast-install disable the fast-install mode + -no-install link a not-installable executable + -no-undefined declare that a library does not refer to external symbols + -o OUTPUT-FILE create OUTPUT-FILE from the specified objects + -objectlist FILE use a list of object files found in FILE to specify objects + -os2dllname NAME force a short DLL name on OS/2 (no effect on other OSes) + -precious-files-regex REGEX + don't remove output files matching REGEX + -release RELEASE specify package release information + -rpath LIBDIR the created library will eventually be installed in LIBDIR + -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries + -shared only do dynamic linking of libtool libraries + -shrext SUFFIX override the standard shared library file extension + -static do not do any dynamic linking of uninstalled libtool libraries + -static-libtool-libs + do not do any dynamic linking of libtool libraries + -version-info CURRENT[:REVISION[:AGE]] + specify library version info [each variable defaults to 0] + -weak LIBNAME declare that the target provides the LIBNAME interface + -Wc,FLAG + -Xcompiler FLAG pass linker-specific FLAG directly to the compiler + -Wl,FLAG + -Xlinker FLAG pass linker-specific FLAG directly to the linker + -XCClinker FLAG pass link-specific FLAG to the compiler driver (CC) + +All other options (arguments beginning with '-') are ignored. + +Every other argument is treated as a filename. Files ending in '.la' are +treated as uninstalled libtool libraries, other files are standard or library +object files. + +If the OUTPUT-FILE ends in '.la', then a libtool library is created, +only library objects ('.lo' files) may be specified, and '-rpath' is +required, except when creating a convenience library. + +If OUTPUT-FILE ends in '.a' or '.lib', then a standard library is created +using 'ar' and 'ranlib', or on Windows using 'lib'. + +If OUTPUT-FILE ends in '.lo' or '.$objext', then a reloadable object file +is created, otherwise an executable program is created." + ;; + + uninstall) + $ECHO \ +"Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... + +Remove libraries from an installation directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically '/bin/rm'). RM-OPTIONS are options (such as '-f') to be passed +to RM. + +If FILE is a libtool library, all the files associated with it are deleted. +Otherwise, only FILE itself is deleted using RM." + ;; + + *) + func_fatal_help "invalid operation mode '$opt_mode'" + ;; + esac + + echo + $ECHO "Try '$progname --help' for more information about other modes." +} + +# Now that we've collected a possible --mode arg, show help if necessary +if $opt_help; then + if test : = "$opt_help"; then + func_mode_help + else + { + func_help noexit + for opt_mode in compile link execute install finish uninstall clean; do + func_mode_help + done + } | $SED -n '1p; 2,$s/^Usage:/ or: /p' + { + func_help noexit + for opt_mode in compile link execute install finish uninstall clean; do + echo + func_mode_help + done + } | + $SED '1d + /^When reporting/,/^Report/{ + H + d + } + $x + /information about other modes/d + /more detailed .*MODE/d + s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/' + fi + exit $? +fi + + +# func_mode_execute arg... +func_mode_execute () +{ + $debug_cmd + + # The first argument is the command name. + cmd=$nonopt + test -z "$cmd" && \ + func_fatal_help "you must specify a COMMAND" + + # Handle -dlopen flags immediately. + for file in $opt_dlopen; do + test -f "$file" \ + || func_fatal_help "'$file' is not a file" + + dir= + case $file in + *.la) + func_resolve_sysroot "$file" + file=$func_resolve_sysroot_result + + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$file" \ + || func_fatal_help "'$lib' is not a valid libtool archive" + + # Read the libtool library. + dlname= + library_names= + func_source "$file" + + # Skip this library if it cannot be dlopened. + if test -z "$dlname"; then + # Warn if it was a shared library. + test -n "$library_names" && \ + func_warning "'$file' was not linked with '-export-dynamic'" + continue + fi + + func_dirname "$file" "" "." + dir=$func_dirname_result + + if test -f "$dir/$objdir/$dlname"; then + func_append dir "/$objdir" + else + if test ! -f "$dir/$dlname"; then + func_fatal_error "cannot find '$dlname' in '$dir' or '$dir/$objdir'" + fi + fi + ;; + + *.lo) + # Just add the directory containing the .lo file. + func_dirname "$file" "" "." + dir=$func_dirname_result + ;; + + *) + func_warning "'-dlopen' is ignored for non-libtool libraries and objects" + continue + ;; + esac + + # Get the absolute pathname. + absdir=`cd "$dir" && pwd` + test -n "$absdir" && dir=$absdir + + # Now add the directory to shlibpath_var. + if eval "test -z \"\$$shlibpath_var\""; then + eval "$shlibpath_var=\"\$dir\"" + else + eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" + fi + done + + # This variable tells wrapper scripts just to set shlibpath_var + # rather than running their programs. + libtool_execute_magic=$magic + + # Check if any of the arguments is a wrapper script. + args= + for file + do + case $file in + -* | *.la | *.lo ) ;; + *) + # Do a test to see if this is really a libtool program. + if func_ltwrapper_script_p "$file"; then + func_source "$file" + # Transform arg to wrapped name. + file=$progdir/$program + elif func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + func_source "$func_ltwrapper_scriptname_result" + # Transform arg to wrapped name. + file=$progdir/$program + fi + ;; + esac + # Quote arguments (to preserve shell metacharacters). + func_append_quoted args "$file" + done + + if $opt_dry_run; then + # Display what would be done. + if test -n "$shlibpath_var"; then + eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\"" + echo "export $shlibpath_var" + fi + $ECHO "$cmd$args" + exit $EXIT_SUCCESS + else + if test -n "$shlibpath_var"; then + # Export the shlibpath_var. + eval "export $shlibpath_var" + fi + + # Restore saved environment variables + for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES + do + eval "if test \"\${save_$lt_var+set}\" = set; then + $lt_var=\$save_$lt_var; export $lt_var + else + $lt_unset $lt_var + fi" + done + + # Now prepare to actually exec the command. + exec_cmd=\$cmd$args + fi +} + +test execute = "$opt_mode" && func_mode_execute ${1+"$@"} + + +# func_mode_finish arg... +func_mode_finish () +{ + $debug_cmd + + libs= + libdirs= + admincmds= + + for opt in "$nonopt" ${1+"$@"} + do + if test -d "$opt"; then + func_append libdirs " $opt" + + elif test -f "$opt"; then + if func_lalib_unsafe_p "$opt"; then + func_append libs " $opt" + else + func_warning "'$opt' is not a valid libtool archive" + fi + + else + func_fatal_error "invalid argument '$opt'" + fi + done + + if test -n "$libs"; then + if test -n "$lt_sysroot"; then + sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"` + sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;" + else + sysroot_cmd= + fi + + # Remove sysroot references + if $opt_dry_run; then + for lib in $libs; do + echo "removing references to $lt_sysroot and '=' prefixes from $lib" + done + else + tmpdir=`func_mktempdir` + for lib in $libs; do + $SED -e "$sysroot_cmd s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \ + > $tmpdir/tmp-la + mv -f $tmpdir/tmp-la $lib + done + ${RM}r "$tmpdir" + fi + fi + + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then + for libdir in $libdirs; do + if test -n "$finish_cmds"; then + # Do each command in the finish commands. + func_execute_cmds "$finish_cmds" 'admincmds="$admincmds +'"$cmd"'"' + fi + if test -n "$finish_eval"; then + # Do the single finish_eval. + eval cmds=\"$finish_eval\" + $opt_dry_run || eval "$cmds" || func_append admincmds " + $cmds" + fi + done + fi + + # Exit here if they wanted silent mode. + $opt_quiet && exit $EXIT_SUCCESS + + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then + echo "----------------------------------------------------------------------" + echo "Libraries have been installed in:" + for libdir in $libdirs; do + $ECHO " $libdir" + done + echo + echo "If you ever happen to want to link against installed libraries" + echo "in a given directory, LIBDIR, you must either use libtool, and" + echo "specify the full pathname of the library, or use the '-LLIBDIR'" + echo "flag during linking and do at least one of the following:" + if test -n "$shlibpath_var"; then + echo " - add LIBDIR to the '$shlibpath_var' environment variable" + echo " during execution" + fi + if test -n "$runpath_var"; then + echo " - add LIBDIR to the '$runpath_var' environment variable" + echo " during linking" + fi + if test -n "$hardcode_libdir_flag_spec"; then + libdir=LIBDIR + eval flag=\"$hardcode_libdir_flag_spec\" + + $ECHO " - use the '$flag' linker flag" + fi + if test -n "$admincmds"; then + $ECHO " - have your system administrator run these commands:$admincmds" + fi + if test -f /etc/ld.so.conf; then + echo " - have your system administrator add LIBDIR to '/etc/ld.so.conf'" + fi + echo + + echo "See any operating system documentation about shared libraries for" + case $host in + solaris2.[6789]|solaris2.1[0-9]) + echo "more information, such as the ld(1), crle(1) and ld.so(8) manual" + echo "pages." + ;; + *) + echo "more information, such as the ld(1) and ld.so(8) manual pages." + ;; + esac + echo "----------------------------------------------------------------------" + fi + exit $EXIT_SUCCESS +} + +test finish = "$opt_mode" && func_mode_finish ${1+"$@"} + + +# func_mode_install arg... +func_mode_install () +{ + $debug_cmd + + # There may be an optional sh(1) argument at the beginning of + # install_prog (especially on Windows NT). + if test "$SHELL" = "$nonopt" || test /bin/sh = "$nonopt" || + # Allow the use of GNU shtool's install command. + case $nonopt in *shtool*) :;; *) false;; esac + then + # Aesthetically quote it. + func_quote_for_eval "$nonopt" + install_prog="$func_quote_for_eval_result " + arg=$1 + shift + else + install_prog= + arg=$nonopt + fi + + # The real first argument should be the name of the installation program. + # Aesthetically quote it. + func_quote_for_eval "$arg" + func_append install_prog "$func_quote_for_eval_result" + install_shared_prog=$install_prog + case " $install_prog " in + *[\\\ /]cp\ *) install_cp=: ;; + *) install_cp=false ;; + esac + + # We need to accept at least all the BSD install flags. + dest= + files= + opts= + prev= + install_type= + isdir=false + stripme= + no_mode=: + for arg + do + arg2= + if test -n "$dest"; then + func_append files " $dest" + dest=$arg + continue + fi + + case $arg in + -d) isdir=: ;; + -f) + if $install_cp; then :; else + prev=$arg + fi + ;; + -g | -m | -o) + prev=$arg + ;; + -s) + stripme=" -s" + continue + ;; + -*) + ;; + *) + # If the previous option needed an argument, then skip it. + if test -n "$prev"; then + if test X-m = "X$prev" && test -n "$install_override_mode"; then + arg2=$install_override_mode + no_mode=false + fi + prev= + else + dest=$arg + continue + fi + ;; + esac + + # Aesthetically quote the argument. + func_quote_for_eval "$arg" + func_append install_prog " $func_quote_for_eval_result" + if test -n "$arg2"; then + func_quote_for_eval "$arg2" + fi + func_append install_shared_prog " $func_quote_for_eval_result" + done + + test -z "$install_prog" && \ + func_fatal_help "you must specify an install program" + + test -n "$prev" && \ + func_fatal_help "the '$prev' option requires an argument" + + if test -n "$install_override_mode" && $no_mode; then + if $install_cp; then :; else + func_quote_for_eval "$install_override_mode" + func_append install_shared_prog " -m $func_quote_for_eval_result" + fi + fi + + if test -z "$files"; then + if test -z "$dest"; then + func_fatal_help "no file or destination specified" + else + func_fatal_help "you must specify a destination" + fi + fi + + # Strip any trailing slash from the destination. + func_stripname '' '/' "$dest" + dest=$func_stripname_result + + # Check to see that the destination is a directory. + test -d "$dest" && isdir=: + if $isdir; then + destdir=$dest + destname= + else + func_dirname_and_basename "$dest" "" "." + destdir=$func_dirname_result + destname=$func_basename_result + + # Not a directory, so check to see that there is only one file specified. + set dummy $files; shift + test "$#" -gt 1 && \ + func_fatal_help "'$dest' is not a directory" + fi + case $destdir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + for file in $files; do + case $file in + *.lo) ;; + *) + func_fatal_help "'$destdir' must be an absolute directory name" + ;; + esac + done + ;; + esac + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic=$magic + + staticlibs= + future_libdirs= + current_libdirs= + for file in $files; do + + # Do each installation. + case $file in + *.$libext) + # Do the static libraries later. + func_append staticlibs " $file" + ;; + + *.la) + func_resolve_sysroot "$file" + file=$func_resolve_sysroot_result + + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$file" \ + || func_fatal_help "'$file' is not a valid libtool archive" + + library_names= + old_library= + relink_command= + func_source "$file" + + # Add the libdir to current_libdirs if it is the destination. + if test "X$destdir" = "X$libdir"; then + case "$current_libdirs " in + *" $libdir "*) ;; + *) func_append current_libdirs " $libdir" ;; + esac + else + # Note the libdir as a future libdir. + case "$future_libdirs " in + *" $libdir "*) ;; + *) func_append future_libdirs " $libdir" ;; + esac + fi + + func_dirname "$file" "/" "" + dir=$func_dirname_result + func_append dir "$objdir" + + if test -n "$relink_command"; then + # Determine the prefix the user has applied to our future dir. + inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"` + + # Don't allow the user to place us outside of our expected + # location b/c this prevents finding dependent libraries that + # are installed to the same prefix. + # At present, this check doesn't affect windows .dll's that + # are installed into $libdir/../bin (currently, that works fine) + # but it's something to keep an eye on. + test "$inst_prefix_dir" = "$destdir" && \ + func_fatal_error "error: cannot install '$file' to a directory not ending in $libdir" + + if test -n "$inst_prefix_dir"; then + # Stick the inst_prefix_dir data into the link command. + relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` + else + relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"` + fi + + func_warning "relinking '$file'" + func_show_eval "$relink_command" \ + 'func_fatal_error "error: relink '\''$file'\'' with the above command before installing it"' + fi + + # See the names of the shared library. + set dummy $library_names; shift + if test -n "$1"; then + realname=$1 + shift + + srcname=$realname + test -n "$relink_command" && srcname=${realname}T + + # Install the shared library and build the symlinks. + func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \ + 'exit $?' + tstripme=$stripme + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + case $realname in + *.dll.a) + tstripme= + ;; + esac + ;; + os2*) + case $realname in + *_dll.a) + tstripme= + ;; + esac + ;; + esac + if test -n "$tstripme" && test -n "$striplib"; then + func_show_eval "$striplib $destdir/$realname" 'exit $?' + fi + + if test "$#" -gt 0; then + # Delete the old symlinks, and create new ones. + # Try 'ln -sf' first, because the 'ln' binary might depend on + # the symlink we replace! Solaris /bin/ln does not understand -f, + # so we also need to try rm && ln -s. + for linkname + do + test "$linkname" != "$realname" \ + && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })" + done + fi + + # Do each command in the postinstall commands. + lib=$destdir/$realname + func_execute_cmds "$postinstall_cmds" 'exit $?' + fi + + # Install the pseudo-library for information purposes. + func_basename "$file" + name=$func_basename_result + instname=$dir/${name}i + func_show_eval "$install_prog $instname $destdir/$name" 'exit $?' + + # Maybe install the static library, too. + test -n "$old_library" && func_append staticlibs " $dir/$old_library" + ;; + + *.lo) + # Install (i.e. copy) a libtool object. + + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile=$destdir/$destname + else + func_basename "$file" + destfile=$func_basename_result + destfile=$destdir/$destfile + fi + + # Deduce the name of the destination old-style object file. + case $destfile in + *.lo) + func_lo2o "$destfile" + staticdest=$func_lo2o_result + ;; + *.$objext) + staticdest=$destfile + destfile= + ;; + *) + func_fatal_help "cannot copy a libtool object to '$destfile'" + ;; + esac + + # Install the libtool object if requested. + test -n "$destfile" && \ + func_show_eval "$install_prog $file $destfile" 'exit $?' + + # Install the old object if enabled. + if test yes = "$build_old_libs"; then + # Deduce the name of the old-style object file. + func_lo2o "$file" + staticobj=$func_lo2o_result + func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?' + fi + exit $EXIT_SUCCESS + ;; + + *) + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile=$destdir/$destname + else + func_basename "$file" + destfile=$func_basename_result + destfile=$destdir/$destfile + fi + + # If the file is missing, and there is a .exe on the end, strip it + # because it is most likely a libtool script we actually want to + # install + stripped_ext= + case $file in + *.exe) + if test ! -f "$file"; then + func_stripname '' '.exe' "$file" + file=$func_stripname_result + stripped_ext=.exe + fi + ;; + esac + + # Do a test to see if this is really a libtool program. + case $host in + *cygwin* | *mingw*) + if func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + wrapper=$func_ltwrapper_scriptname_result + else + func_stripname '' '.exe' "$file" + wrapper=$func_stripname_result + fi + ;; + *) + wrapper=$file + ;; + esac + if func_ltwrapper_script_p "$wrapper"; then + notinst_deplibs= + relink_command= + + func_source "$wrapper" + + # Check the variables that should have been set. + test -z "$generated_by_libtool_version" && \ + func_fatal_error "invalid libtool wrapper script '$wrapper'" + + finalize=: + for lib in $notinst_deplibs; do + # Check to see that each library is installed. + libdir= + if test -f "$lib"; then + func_source "$lib" + fi + libfile=$libdir/`$ECHO "$lib" | $SED 's%^.*/%%g'` + if test -n "$libdir" && test ! -f "$libfile"; then + func_warning "'$lib' has not been installed in '$libdir'" + finalize=false + fi + done + + relink_command= + func_source "$wrapper" + + outputname= + if test no = "$fast_install" && test -n "$relink_command"; then + $opt_dry_run || { + if $finalize; then + tmpdir=`func_mktempdir` + func_basename "$file$stripped_ext" + file=$func_basename_result + outputname=$tmpdir/$file + # Replace the output file specification. + relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'` + + $opt_quiet || { + func_quote_for_expand "$relink_command" + eval "func_echo $func_quote_for_expand_result" + } + if eval "$relink_command"; then : + else + func_error "error: relink '$file' with the above command before installing it" + $opt_dry_run || ${RM}r "$tmpdir" + continue + fi + file=$outputname + else + func_warning "cannot relink '$file'" + fi + } + else + # Install the binary that we compiled earlier. + file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"` + fi + fi + + # remove .exe since cygwin /usr/bin/install will append another + # one anyway + case $install_prog,$host in + */usr/bin/install*,*cygwin*) + case $file:$destfile in + *.exe:*.exe) + # this is ok + ;; + *.exe:*) + destfile=$destfile.exe + ;; + *:*.exe) + func_stripname '' '.exe' "$destfile" + destfile=$func_stripname_result + ;; + esac + ;; + esac + func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?' + $opt_dry_run || if test -n "$outputname"; then + ${RM}r "$tmpdir" + fi + ;; + esac + done + + for file in $staticlibs; do + func_basename "$file" + name=$func_basename_result + + # Set up the ranlib parameters. + oldlib=$destdir/$name + func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 + tool_oldlib=$func_to_tool_file_result + + func_show_eval "$install_prog \$file \$oldlib" 'exit $?' + + if test -n "$stripme" && test -n "$old_striplib"; then + func_show_eval "$old_striplib $tool_oldlib" 'exit $?' + fi + + # Do each command in the postinstall commands. + func_execute_cmds "$old_postinstall_cmds" 'exit $?' + done + + test -n "$future_libdirs" && \ + func_warning "remember to run '$progname --finish$future_libdirs'" + + if test -n "$current_libdirs"; then + # Maybe just do a dry run. + $opt_dry_run && current_libdirs=" -n$current_libdirs" + exec_cmd='$SHELL "$progpath" $preserve_args --finish$current_libdirs' + else + exit $EXIT_SUCCESS + fi +} + +test install = "$opt_mode" && func_mode_install ${1+"$@"} + + +# func_generate_dlsyms outputname originator pic_p +# Extract symbols from dlprefiles and create ${outputname}S.o with +# a dlpreopen symbol table. +func_generate_dlsyms () +{ + $debug_cmd + + my_outputname=$1 + my_originator=$2 + my_pic_p=${3-false} + my_prefix=`$ECHO "$my_originator" | $SED 's%[^a-zA-Z0-9]%_%g'` + my_dlsyms= + + if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then + if test -n "$NM" && test -n "$global_symbol_pipe"; then + my_dlsyms=${my_outputname}S.c + else + func_error "not configured to extract global symbols from dlpreopened files" + fi + fi + + if test -n "$my_dlsyms"; then + case $my_dlsyms in + "") ;; + *.c) + # Discover the nlist of each of the dlfiles. + nlist=$output_objdir/$my_outputname.nm + + func_show_eval "$RM $nlist ${nlist}S ${nlist}T" + + # Parse the name list into a source file. + func_verbose "creating $output_objdir/$my_dlsyms" + + $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\ +/* $my_dlsyms - symbol resolution table for '$my_outputname' dlsym emulation. */ +/* Generated by $PROGRAM (GNU $PACKAGE) $VERSION */ + +#ifdef __cplusplus +extern \"C\" { +#endif + +#if defined __GNUC__ && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4)) +#pragma GCC diagnostic ignored \"-Wstrict-prototypes\" +#endif + +/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ +#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE +/* DATA imports from DLLs on WIN32 can't be const, because runtime + relocations are performed -- see ld's documentation on pseudo-relocs. */ +# define LT_DLSYM_CONST +#elif defined __osf__ +/* This system does not cope well with relocations in const data. */ +# define LT_DLSYM_CONST +#else +# define LT_DLSYM_CONST const +#endif + +#define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0) + +/* External symbol declarations for the compiler. */\ +" + + if test yes = "$dlself"; then + func_verbose "generating symbol list for '$output'" + + $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist" + + # Add our own program objects to the symbol list. + progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP` + for progfile in $progfiles; do + func_to_tool_file "$progfile" func_convert_file_msys_to_w32 + func_verbose "extracting global C symbols from '$func_to_tool_file_result'" + $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'" + done + + if test -n "$exclude_expsyms"; then + $opt_dry_run || { + eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + } + fi + + if test -n "$export_symbols_regex"; then + $opt_dry_run || { + eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + } + fi + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + export_symbols=$output_objdir/$outputname.exp + $opt_dry_run || { + $RM $export_symbols + eval "$SED -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' + case $host in + *cygwin* | *mingw* | *cegcc* ) + eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' + eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' + ;; + esac + } + else + $opt_dry_run || { + eval "$SED -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' + eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + case $host in + *cygwin* | *mingw* | *cegcc* ) + eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' + eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' + ;; + esac + } + fi + fi + + for dlprefile in $dlprefiles; do + func_verbose "extracting global C symbols from '$dlprefile'" + func_basename "$dlprefile" + name=$func_basename_result + case $host in + *cygwin* | *mingw* | *cegcc* ) + # if an import library, we need to obtain dlname + if func_win32_import_lib_p "$dlprefile"; then + func_tr_sh "$dlprefile" + eval "curr_lafile=\$libfile_$func_tr_sh_result" + dlprefile_dlbasename= + if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then + # Use subshell, to avoid clobbering current variable values + dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"` + if test -n "$dlprefile_dlname"; then + func_basename "$dlprefile_dlname" + dlprefile_dlbasename=$func_basename_result + else + # no lafile. user explicitly requested -dlpreopen <import library>. + $sharedlib_from_linklib_cmd "$dlprefile" + dlprefile_dlbasename=$sharedlib_from_linklib_result + fi + fi + $opt_dry_run || { + if test -n "$dlprefile_dlbasename"; then + eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"' + else + func_warning "Could not compute DLL name from $name" + eval '$ECHO ": $name " >> "$nlist"' + fi + func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 + eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe | + $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'" + } + else # not an import lib + $opt_dry_run || { + eval '$ECHO ": $name " >> "$nlist"' + func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 + eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" + } + fi + ;; + *) + $opt_dry_run || { + eval '$ECHO ": $name " >> "$nlist"' + func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 + eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" + } + ;; + esac + done + + $opt_dry_run || { + # Make sure we have at least an empty file. + test -f "$nlist" || : > "$nlist" + + if test -n "$exclude_expsyms"; then + $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T + $MV "$nlist"T "$nlist" + fi + + # Try sorting and uniquifying the output. + if $GREP -v "^: " < "$nlist" | + if sort -k 3 </dev/null >/dev/null 2>&1; then + sort -k 3 + else + sort +2 + fi | + uniq > "$nlist"S; then + : + else + $GREP -v "^: " < "$nlist" > "$nlist"S + fi + + if test -f "$nlist"S; then + eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"' + else + echo '/* NONE */' >> "$output_objdir/$my_dlsyms" + fi + + func_show_eval '$RM "${nlist}I"' + if test -n "$global_symbol_to_import"; then + eval "$global_symbol_to_import"' < "$nlist"S > "$nlist"I' + fi + + echo >> "$output_objdir/$my_dlsyms" "\ + +/* The mapping between symbol names and symbols. */ +typedef struct { + const char *name; + void *address; +} lt_dlsymlist; +extern LT_DLSYM_CONST lt_dlsymlist +lt_${my_prefix}_LTX_preloaded_symbols[];\ +" + + if test -s "$nlist"I; then + echo >> "$output_objdir/$my_dlsyms" "\ +static void lt_syminit(void) +{ + LT_DLSYM_CONST lt_dlsymlist *symbol = lt_${my_prefix}_LTX_preloaded_symbols; + for (; symbol->name; ++symbol) + {" + $SED 's/.*/ if (STREQ (symbol->name, \"&\")) symbol->address = (void *) \&&;/' < "$nlist"I >> "$output_objdir/$my_dlsyms" + echo >> "$output_objdir/$my_dlsyms" "\ + } +}" + fi + echo >> "$output_objdir/$my_dlsyms" "\ +LT_DLSYM_CONST lt_dlsymlist +lt_${my_prefix}_LTX_preloaded_symbols[] = +{ {\"$my_originator\", (void *) 0}," + + if test -s "$nlist"I; then + echo >> "$output_objdir/$my_dlsyms" "\ + {\"@INIT@\", (void *) <_syminit}," + fi + + case $need_lib_prefix in + no) + eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms" + ;; + *) + eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms" + ;; + esac + echo >> "$output_objdir/$my_dlsyms" "\ + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt_${my_prefix}_LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif\ +" + } # !$opt_dry_run + + pic_flag_for_symtable= + case "$compile_command " in + *" -static "*) ;; + *) + case $host in + # compiling the symbol table file with pic_flag works around + # a FreeBSD bug that causes programs to crash when -lm is + # linked before any other PIC object. But we must not use + # pic_flag when linking with -static. The problem exists in + # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. + *-*-freebsd2.*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) + pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;; + *-*-hpux*) + pic_flag_for_symtable=" $pic_flag" ;; + *) + $my_pic_p && pic_flag_for_symtable=" $pic_flag" + ;; + esac + ;; + esac + symtab_cflags= + for arg in $LTCFLAGS; do + case $arg in + -pie | -fpie | -fPIE) ;; + *) func_append symtab_cflags " $arg" ;; + esac + done + + # Now compile the dynamic symbol file. + func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?' + + # Clean up the generated files. + func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T" "${nlist}I"' + + # Transform the symbol file into the correct name. + symfileobj=$output_objdir/${my_outputname}S.$objext + case $host in + *cygwin* | *mingw* | *cegcc* ) + if test -f "$output_objdir/$my_outputname.def"; then + compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` + else + compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` + fi + ;; + *) + compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` + ;; + esac + ;; + *) + func_fatal_error "unknown suffix for '$my_dlsyms'" + ;; + esac + else + # We keep going just in case the user didn't refer to + # lt_preloaded_symbols. The linker will fail if global_symbol_pipe + # really was required. + + # Nullify the symbol file. + compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"` + fi +} + +# func_cygming_gnu_implib_p ARG +# This predicate returns with zero status (TRUE) if +# ARG is a GNU/binutils-style import library. Returns +# with nonzero status (FALSE) otherwise. +func_cygming_gnu_implib_p () +{ + $debug_cmd + + func_to_tool_file "$1" func_convert_file_msys_to_w32 + func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'` + test -n "$func_cygming_gnu_implib_tmp" +} + +# func_cygming_ms_implib_p ARG +# This predicate returns with zero status (TRUE) if +# ARG is an MS-style import library. Returns +# with nonzero status (FALSE) otherwise. +func_cygming_ms_implib_p () +{ + $debug_cmd + + func_to_tool_file "$1" func_convert_file_msys_to_w32 + func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'` + test -n "$func_cygming_ms_implib_tmp" +} + +# func_win32_libid arg +# return the library type of file 'arg' +# +# Need a lot of goo to handle *both* DLLs and import libs +# Has to be a shell function in order to 'eat' the argument +# that is supplied when $file_magic_command is called. +# Despite the name, also deal with 64 bit binaries. +func_win32_libid () +{ + $debug_cmd + + win32_libid_type=unknown + win32_fileres=`file -L $1 2>/dev/null` + case $win32_fileres in + *ar\ archive\ import\ library*) # definitely import + win32_libid_type="x86 archive import" + ;; + *ar\ archive*) # could be an import, or static + # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD. + if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | + $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then + case $nm_interface in + "MS dumpbin") + if func_cygming_ms_implib_p "$1" || + func_cygming_gnu_implib_p "$1" + then + win32_nmres=import + else + win32_nmres= + fi + ;; + *) + func_to_tool_file "$1" func_convert_file_msys_to_w32 + win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" | + $SED -n -e ' + 1,100{ + / I /{ + s|.*|import| + p + q + } + }'` + ;; + esac + case $win32_nmres in + import*) win32_libid_type="x86 archive import";; + *) win32_libid_type="x86 archive static";; + esac + fi + ;; + *DLL*) + win32_libid_type="x86 DLL" + ;; + *executable*) # but shell scripts are "executable" too... + case $win32_fileres in + *MS\ Windows\ PE\ Intel*) + win32_libid_type="x86 DLL" + ;; + esac + ;; + esac + $ECHO "$win32_libid_type" +} + +# func_cygming_dll_for_implib ARG +# +# Platform-specific function to extract the +# name of the DLL associated with the specified +# import library ARG. +# Invoked by eval'ing the libtool variable +# $sharedlib_from_linklib_cmd +# Result is available in the variable +# $sharedlib_from_linklib_result +func_cygming_dll_for_implib () +{ + $debug_cmd + + sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"` +} + +# func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs +# +# The is the core of a fallback implementation of a +# platform-specific function to extract the name of the +# DLL associated with the specified import library LIBNAME. +# +# SECTION_NAME is either .idata$6 or .idata$7, depending +# on the platform and compiler that created the implib. +# +# Echos the name of the DLL associated with the +# specified import library. +func_cygming_dll_for_implib_fallback_core () +{ + $debug_cmd + + match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"` + $OBJDUMP -s --section "$1" "$2" 2>/dev/null | + $SED '/^Contents of section '"$match_literal"':/{ + # Place marker at beginning of archive member dllname section + s/.*/====MARK====/ + p + d + } + # These lines can sometimes be longer than 43 characters, but + # are always uninteresting + /:[ ]*file format pe[i]\{,1\}-/d + /^In archive [^:]*:/d + # Ensure marker is printed + /^====MARK====/p + # Remove all lines with less than 43 characters + /^.\{43\}/!d + # From remaining lines, remove first 43 characters + s/^.\{43\}//' | + $SED -n ' + # Join marker and all lines until next marker into a single line + /^====MARK====/ b para + H + $ b para + b + :para + x + s/\n//g + # Remove the marker + s/^====MARK====// + # Remove trailing dots and whitespace + s/[\. \t]*$// + # Print + /./p' | + # we now have a list, one entry per line, of the stringified + # contents of the appropriate section of all members of the + # archive that possess that section. Heuristic: eliminate + # all those that have a first or second character that is + # a '.' (that is, objdump's representation of an unprintable + # character.) This should work for all archives with less than + # 0x302f exports -- but will fail for DLLs whose name actually + # begins with a literal '.' or a single character followed by + # a '.'. + # + # Of those that remain, print the first one. + $SED -e '/^\./d;/^.\./d;q' +} + +# func_cygming_dll_for_implib_fallback ARG +# Platform-specific function to extract the +# name of the DLL associated with the specified +# import library ARG. +# +# This fallback implementation is for use when $DLLTOOL +# does not support the --identify-strict option. +# Invoked by eval'ing the libtool variable +# $sharedlib_from_linklib_cmd +# Result is available in the variable +# $sharedlib_from_linklib_result +func_cygming_dll_for_implib_fallback () +{ + $debug_cmd + + if func_cygming_gnu_implib_p "$1"; then + # binutils import library + sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"` + elif func_cygming_ms_implib_p "$1"; then + # ms-generated import library + sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"` + else + # unknown + sharedlib_from_linklib_result= + fi +} + + +# func_extract_an_archive dir oldlib +func_extract_an_archive () +{ + $debug_cmd + + f_ex_an_ar_dir=$1; shift + f_ex_an_ar_oldlib=$1 + if test yes = "$lock_old_archive_extraction"; then + lockfile=$f_ex_an_ar_oldlib.lock + until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do + func_echo "Waiting for $lockfile to be removed" + sleep 2 + done + fi + func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \ + 'stat=$?; rm -f "$lockfile"; exit $stat' + if test yes = "$lock_old_archive_extraction"; then + $opt_dry_run || rm -f "$lockfile" + fi + if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then + : + else + func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" + fi +} + + +# func_extract_archives gentop oldlib ... +func_extract_archives () +{ + $debug_cmd + + my_gentop=$1; shift + my_oldlibs=${1+"$@"} + my_oldobjs= + my_xlib= + my_xabs= + my_xdir= + + for my_xlib in $my_oldlibs; do + # Extract the objects. + case $my_xlib in + [\\/]* | [A-Za-z]:[\\/]*) my_xabs=$my_xlib ;; + *) my_xabs=`pwd`"/$my_xlib" ;; + esac + func_basename "$my_xlib" + my_xlib=$func_basename_result + my_xlib_u=$my_xlib + while :; do + case " $extracted_archives " in + *" $my_xlib_u "*) + func_arith $extracted_serial + 1 + extracted_serial=$func_arith_result + my_xlib_u=lt$extracted_serial-$my_xlib ;; + *) break ;; + esac + done + extracted_archives="$extracted_archives $my_xlib_u" + my_xdir=$my_gentop/$my_xlib_u + + func_mkdir_p "$my_xdir" + + case $host in + *-darwin*) + func_verbose "Extracting $my_xabs" + # Do not bother doing anything if just a dry run + $opt_dry_run || { + darwin_orig_dir=`pwd` + cd $my_xdir || exit $? + darwin_archive=$my_xabs + darwin_curdir=`pwd` + func_basename "$darwin_archive" + darwin_base_archive=$func_basename_result + darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true` + if test -n "$darwin_arches"; then + darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'` + darwin_arch= + func_verbose "$darwin_base_archive has multiple architectures $darwin_arches" + for darwin_arch in $darwin_arches; do + func_mkdir_p "unfat-$$/$darwin_base_archive-$darwin_arch" + $LIPO -thin $darwin_arch -output "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive" "$darwin_archive" + cd "unfat-$$/$darwin_base_archive-$darwin_arch" + func_extract_an_archive "`pwd`" "$darwin_base_archive" + cd "$darwin_curdir" + $RM "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive" + done # $darwin_arches + ## Okay now we've a bunch of thin objects, gotta fatten them up :) + darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$sed_basename" | sort -u` + darwin_file= + darwin_files= + for darwin_file in $darwin_filelist; do + darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP` + $LIPO -create -output "$darwin_file" $darwin_files + done # $darwin_filelist + $RM -rf unfat-$$ + cd "$darwin_orig_dir" + else + cd $darwin_orig_dir + func_extract_an_archive "$my_xdir" "$my_xabs" + fi # $darwin_arches + } # !$opt_dry_run + ;; + *) + func_extract_an_archive "$my_xdir" "$my_xabs" + ;; + esac + my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP` + done + + func_extract_archives_result=$my_oldobjs +} + + +# func_emit_wrapper [arg=no] +# +# Emit a libtool wrapper script on stdout. +# Don't directly open a file because we may want to +# incorporate the script contents within a cygwin/mingw +# wrapper executable. Must ONLY be called from within +# func_mode_link because it depends on a number of variables +# set therein. +# +# ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR +# variable will take. If 'yes', then the emitted script +# will assume that the directory where it is stored is +# the $objdir directory. This is a cygwin/mingw-specific +# behavior. +func_emit_wrapper () +{ + func_emit_wrapper_arg1=${1-no} + + $ECHO "\ +#! $SHELL + +# $output - temporary wrapper script for $objdir/$outputname +# Generated by $PROGRAM (GNU $PACKAGE) $VERSION +# +# The $output program cannot be directly executed until all the libtool +# libraries that it depends on are installed. +# +# This wrapper script should never be moved out of the build directory. +# If it is, it will not operate correctly. + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +sed_quote_subst='$sed_quote_subst' + +# Be Bourne compatible +if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac +fi +BIN_SH=xpg4; export BIN_SH # for Tru64 +DUALCASE=1; export DUALCASE # for MKS sh + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +relink_command=\"$relink_command\" + +# This environment variable determines our operation mode. +if test \"\$libtool_install_magic\" = \"$magic\"; then + # install mode needs the following variables: + generated_by_libtool_version='$macro_version' + notinst_deplibs='$notinst_deplibs' +else + # When we are sourced in execute mode, \$file and \$ECHO are already set. + if test \"\$libtool_execute_magic\" != \"$magic\"; then + file=\"\$0\"" + + qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"` + $ECHO "\ + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$1 +_LTECHO_EOF' +} + ECHO=\"$qECHO\" + fi + +# Very basic option parsing. These options are (a) specific to +# the libtool wrapper, (b) are identical between the wrapper +# /script/ and the wrapper /executable/ that is used only on +# windows platforms, and (c) all begin with the string "--lt-" +# (application programs are unlikely to have options that match +# this pattern). +# +# There are only two supported options: --lt-debug and +# --lt-dump-script. There is, deliberately, no --lt-help. +# +# The first argument to this parsing function should be the +# script's $0 value, followed by "$@". +lt_option_debug= +func_parse_lt_options () +{ + lt_script_arg0=\$0 + shift + for lt_opt + do + case \"\$lt_opt\" in + --lt-debug) lt_option_debug=1 ;; + --lt-dump-script) + lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\` + test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=. + lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\` + cat \"\$lt_dump_D/\$lt_dump_F\" + exit 0 + ;; + --lt-*) + \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2 + exit 1 + ;; + esac + done + + # Print the debug banner immediately: + if test -n \"\$lt_option_debug\"; then + echo \"$outputname:$output:\$LINENO: libtool wrapper (GNU $PACKAGE) $VERSION\" 1>&2 + fi +} + +# Used when --lt-debug. Prints its arguments to stdout +# (redirection is the responsibility of the caller) +func_lt_dump_args () +{ + lt_dump_args_N=1; + for lt_arg + do + \$ECHO \"$outputname:$output:\$LINENO: newargv[\$lt_dump_args_N]: \$lt_arg\" + lt_dump_args_N=\`expr \$lt_dump_args_N + 1\` + done +} + +# Core function for launching the target application +func_exec_program_core () +{ +" + case $host in + # Backslashes separate directories on plain windows + *-*-mingw | *-*-os2* | *-cegcc*) + $ECHO "\ + if test -n \"\$lt_option_debug\"; then + \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir\\\\\$program\" 1>&2 + func_lt_dump_args \${1+\"\$@\"} 1>&2 + fi + exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} +" + ;; + + *) + $ECHO "\ + if test -n \"\$lt_option_debug\"; then + \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir/\$program\" 1>&2 + func_lt_dump_args \${1+\"\$@\"} 1>&2 + fi + exec \"\$progdir/\$program\" \${1+\"\$@\"} +" + ;; + esac + $ECHO "\ + \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2 + exit 1 +} + +# A function to encapsulate launching the target application +# Strips options in the --lt-* namespace from \$@ and +# launches target application with the remaining arguments. +func_exec_program () +{ + case \" \$* \" in + *\\ --lt-*) + for lt_wr_arg + do + case \$lt_wr_arg in + --lt-*) ;; + *) set x \"\$@\" \"\$lt_wr_arg\"; shift;; + esac + shift + done ;; + esac + func_exec_program_core \${1+\"\$@\"} +} + + # Parse options + func_parse_lt_options \"\$0\" \${1+\"\$@\"} + + # Find the directory that this script lives in. + thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\` + test \"x\$thisdir\" = \"x\$file\" && thisdir=. + + # Follow symbolic links until we get to the real thisdir. + file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\` + while test -n \"\$file\"; do + destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\` + + # If there was a directory component, then change thisdir. + if test \"x\$destdir\" != \"x\$file\"; then + case \"\$destdir\" in + [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; + *) thisdir=\"\$thisdir/\$destdir\" ;; + esac + fi + + file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\` + file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\` + done + + # Usually 'no', except on cygwin/mingw when embedded into + # the cwrapper. + WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1 + if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then + # special case for '.' + if test \"\$thisdir\" = \".\"; then + thisdir=\`pwd\` + fi + # remove .libs from thisdir + case \"\$thisdir\" in + *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;; + $objdir ) thisdir=. ;; + esac + fi + + # Try to get the absolute directory name. + absdir=\`cd \"\$thisdir\" && pwd\` + test -n \"\$absdir\" && thisdir=\"\$absdir\" +" + + if test yes = "$fast_install"; then + $ECHO "\ + program=lt-'$outputname'$exeext + progdir=\"\$thisdir/$objdir\" + + if test ! -f \"\$progdir/\$program\" || + { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | $SED 1q\`; \\ + test \"X\$file\" != \"X\$progdir/\$program\"; }; then + + file=\"\$\$-\$program\" + + if test ! -d \"\$progdir\"; then + $MKDIR \"\$progdir\" + else + $RM \"\$progdir/\$file\" + fi" + + $ECHO "\ + + # relink executable if necessary + if test -n \"\$relink_command\"; then + if relink_command_output=\`eval \$relink_command 2>&1\`; then : + else + \$ECHO \"\$relink_command_output\" >&2 + $RM \"\$progdir/\$file\" + exit 1 + fi + fi + + $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || + { $RM \"\$progdir/\$program\"; + $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; } + $RM \"\$progdir/\$file\" + fi" + else + $ECHO "\ + program='$outputname' + progdir=\"\$thisdir/$objdir\" +" + fi + + $ECHO "\ + + if test -f \"\$progdir/\$program\"; then" + + # fixup the dll searchpath if we need to. + # + # Fix the DLL searchpath if we need to. Do this before prepending + # to shlibpath, because on Windows, both are PATH and uninstalled + # libraries must come first. + if test -n "$dllsearchpath"; then + $ECHO "\ + # Add the dll search path components to the executable PATH + PATH=$dllsearchpath:\$PATH +" + fi + + # Export our shlibpath_var if we have one. + if test yes = "$shlibpath_overrides_runpath" && test -n "$shlibpath_var" && test -n "$temp_rpath"; then + $ECHO "\ + # Add our own library path to $shlibpath_var + $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" + + # Some systems cannot cope with colon-terminated $shlibpath_var + # The second colon is a workaround for a bug in BeOS R4 sed + $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\` + + export $shlibpath_var +" + fi + + $ECHO "\ + if test \"\$libtool_execute_magic\" != \"$magic\"; then + # Run the actual program with our arguments. + func_exec_program \${1+\"\$@\"} + fi + else + # The program doesn't exist. + \$ECHO \"\$0: error: '\$progdir/\$program' does not exist\" 1>&2 + \$ECHO \"This script is just a wrapper for \$program.\" 1>&2 + \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2 + exit 1 + fi +fi\ +" +} + + +# func_emit_cwrapperexe_src +# emit the source code for a wrapper executable on stdout +# Must ONLY be called from within func_mode_link because +# it depends on a number of variable set therein. +func_emit_cwrapperexe_src () +{ + cat <<EOF + +/* $cwrappersource - temporary wrapper executable for $objdir/$outputname + Generated by $PROGRAM (GNU $PACKAGE) $VERSION + + The $output program cannot be directly executed until all the libtool + libraries that it depends on are installed. + + This wrapper executable should never be moved out of the build directory. + If it is, it will not operate correctly. +*/ +EOF + cat <<"EOF" +#ifdef _MSC_VER +# define _CRT_SECURE_NO_DEPRECATE 1 +#endif +#include <stdio.h> +#include <stdlib.h> +#ifdef _MSC_VER +# include <direct.h> +# include <process.h> +# include <io.h> +#else +# include <unistd.h> +# include <stdint.h> +# ifdef __CYGWIN__ +# include <io.h> +# endif +#endif +#include <malloc.h> +#include <stdarg.h> +#include <assert.h> +#include <string.h> +#include <ctype.h> +#include <errno.h> +#include <fcntl.h> +#include <sys/stat.h> + +#define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0) + +/* declarations of non-ANSI functions */ +#if defined __MINGW32__ +# ifdef __STRICT_ANSI__ +int _putenv (const char *); +# endif +#elif defined __CYGWIN__ +# ifdef __STRICT_ANSI__ +char *realpath (const char *, char *); +int putenv (char *); +int setenv (const char *, const char *, int); +# endif +/* #elif defined other_platform || defined ... */ +#endif + +/* portability defines, excluding path handling macros */ +#if defined _MSC_VER +# define setmode _setmode +# define stat _stat +# define chmod _chmod +# define getcwd _getcwd +# define putenv _putenv +# define S_IXUSR _S_IEXEC +#elif defined __MINGW32__ +# define setmode _setmode +# define stat _stat +# define chmod _chmod +# define getcwd _getcwd +# define putenv _putenv +#elif defined __CYGWIN__ +# define HAVE_SETENV +# define FOPEN_WB "wb" +/* #elif defined other platforms ... */ +#endif + +#if defined PATH_MAX +# define LT_PATHMAX PATH_MAX +#elif defined MAXPATHLEN +# define LT_PATHMAX MAXPATHLEN +#else +# define LT_PATHMAX 1024 +#endif + +#ifndef S_IXOTH +# define S_IXOTH 0 +#endif +#ifndef S_IXGRP +# define S_IXGRP 0 +#endif + +/* path handling portability macros */ +#ifndef DIR_SEPARATOR +# define DIR_SEPARATOR '/' +# define PATH_SEPARATOR ':' +#endif + +#if defined _WIN32 || defined __MSDOS__ || defined __DJGPP__ || \ + defined __OS2__ +# define HAVE_DOS_BASED_FILE_SYSTEM +# define FOPEN_WB "wb" +# ifndef DIR_SEPARATOR_2 +# define DIR_SEPARATOR_2 '\\' +# endif +# ifndef PATH_SEPARATOR_2 +# define PATH_SEPARATOR_2 ';' +# endif +#endif + +#ifndef DIR_SEPARATOR_2 +# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) +#else /* DIR_SEPARATOR_2 */ +# define IS_DIR_SEPARATOR(ch) \ + (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) +#endif /* DIR_SEPARATOR_2 */ + +#ifndef PATH_SEPARATOR_2 +# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) +#else /* PATH_SEPARATOR_2 */ +# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) +#endif /* PATH_SEPARATOR_2 */ + +#ifndef FOPEN_WB +# define FOPEN_WB "w" +#endif +#ifndef _O_BINARY +# define _O_BINARY 0 +#endif + +#define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) +#define XFREE(stale) do { \ + if (stale) { free (stale); stale = 0; } \ +} while (0) + +#if defined LT_DEBUGWRAPPER +static int lt_debug = 1; +#else +static int lt_debug = 0; +#endif + +const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */ + +void *xmalloc (size_t num); +char *xstrdup (const char *string); +const char *base_name (const char *name); +char *find_executable (const char *wrapper); +char *chase_symlinks (const char *pathspec); +int make_executable (const char *path); +int check_executable (const char *path); +char *strendzap (char *str, const char *pat); +void lt_debugprintf (const char *file, int line, const char *fmt, ...); +void lt_fatal (const char *file, int line, const char *message, ...); +static const char *nonnull (const char *s); +static const char *nonempty (const char *s); +void lt_setenv (const char *name, const char *value); +char *lt_extend_str (const char *orig_value, const char *add, int to_end); +void lt_update_exe_path (const char *name, const char *value); +void lt_update_lib_path (const char *name, const char *value); +char **prepare_spawn (char **argv); +void lt_dump_script (FILE *f); +EOF + + cat <<EOF +#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 5) +# define externally_visible volatile +#else +# define externally_visible __attribute__((externally_visible)) volatile +#endif +externally_visible const char * MAGIC_EXE = "$magic_exe"; +const char * LIB_PATH_VARNAME = "$shlibpath_var"; +EOF + + if test yes = "$shlibpath_overrides_runpath" && test -n "$shlibpath_var" && test -n "$temp_rpath"; then + func_to_host_path "$temp_rpath" + cat <<EOF +const char * LIB_PATH_VALUE = "$func_to_host_path_result"; +EOF + else + cat <<"EOF" +const char * LIB_PATH_VALUE = ""; +EOF + fi + + if test -n "$dllsearchpath"; then + func_to_host_path "$dllsearchpath:" + cat <<EOF +const char * EXE_PATH_VARNAME = "PATH"; +const char * EXE_PATH_VALUE = "$func_to_host_path_result"; +EOF + else + cat <<"EOF" +const char * EXE_PATH_VARNAME = ""; +const char * EXE_PATH_VALUE = ""; +EOF + fi + + if test yes = "$fast_install"; then + cat <<EOF +const char * TARGET_PROGRAM_NAME = "lt-$outputname"; /* hopefully, no .exe */ +EOF + else + cat <<EOF +const char * TARGET_PROGRAM_NAME = "$outputname"; /* hopefully, no .exe */ +EOF + fi + + + cat <<"EOF" + +#define LTWRAPPER_OPTION_PREFIX "--lt-" + +static const char *ltwrapper_option_prefix = LTWRAPPER_OPTION_PREFIX; +static const char *dumpscript_opt = LTWRAPPER_OPTION_PREFIX "dump-script"; +static const char *debug_opt = LTWRAPPER_OPTION_PREFIX "debug"; + +int +main (int argc, char *argv[]) +{ + char **newargz; + int newargc; + char *tmp_pathspec; + char *actual_cwrapper_path; + char *actual_cwrapper_name; + char *target_name; + char *lt_argv_zero; + int rval = 127; + + int i; + + program_name = (char *) xstrdup (base_name (argv[0])); + newargz = XMALLOC (char *, (size_t) argc + 1); + + /* very simple arg parsing; don't want to rely on getopt + * also, copy all non cwrapper options to newargz, except + * argz[0], which is handled differently + */ + newargc=0; + for (i = 1; i < argc; i++) + { + if (STREQ (argv[i], dumpscript_opt)) + { +EOF + case $host in + *mingw* | *cygwin* ) + # make stdout use "unix" line endings + echo " setmode(1,_O_BINARY);" + ;; + esac + + cat <<"EOF" + lt_dump_script (stdout); + return 0; + } + if (STREQ (argv[i], debug_opt)) + { + lt_debug = 1; + continue; + } + if (STREQ (argv[i], ltwrapper_option_prefix)) + { + /* however, if there is an option in the LTWRAPPER_OPTION_PREFIX + namespace, but it is not one of the ones we know about and + have already dealt with, above (inluding dump-script), then + report an error. Otherwise, targets might begin to believe + they are allowed to use options in the LTWRAPPER_OPTION_PREFIX + namespace. The first time any user complains about this, we'll + need to make LTWRAPPER_OPTION_PREFIX a configure-time option + or a configure.ac-settable value. + */ + lt_fatal (__FILE__, __LINE__, + "unrecognized %s option: '%s'", + ltwrapper_option_prefix, argv[i]); + } + /* otherwise ... */ + newargz[++newargc] = xstrdup (argv[i]); + } + newargz[++newargc] = NULL; + +EOF + cat <<EOF + /* The GNU banner must be the first non-error debug message */ + lt_debugprintf (__FILE__, __LINE__, "libtool wrapper (GNU $PACKAGE) $VERSION\n"); +EOF + cat <<"EOF" + lt_debugprintf (__FILE__, __LINE__, "(main) argv[0]: %s\n", argv[0]); + lt_debugprintf (__FILE__, __LINE__, "(main) program_name: %s\n", program_name); + + tmp_pathspec = find_executable (argv[0]); + if (tmp_pathspec == NULL) + lt_fatal (__FILE__, __LINE__, "couldn't find %s", argv[0]); + lt_debugprintf (__FILE__, __LINE__, + "(main) found exe (before symlink chase) at: %s\n", + tmp_pathspec); + + actual_cwrapper_path = chase_symlinks (tmp_pathspec); + lt_debugprintf (__FILE__, __LINE__, + "(main) found exe (after symlink chase) at: %s\n", + actual_cwrapper_path); + XFREE (tmp_pathspec); + + actual_cwrapper_name = xstrdup (base_name (actual_cwrapper_path)); + strendzap (actual_cwrapper_path, actual_cwrapper_name); + + /* wrapper name transforms */ + strendzap (actual_cwrapper_name, ".exe"); + tmp_pathspec = lt_extend_str (actual_cwrapper_name, ".exe", 1); + XFREE (actual_cwrapper_name); + actual_cwrapper_name = tmp_pathspec; + tmp_pathspec = 0; + + /* target_name transforms -- use actual target program name; might have lt- prefix */ + target_name = xstrdup (base_name (TARGET_PROGRAM_NAME)); + strendzap (target_name, ".exe"); + tmp_pathspec = lt_extend_str (target_name, ".exe", 1); + XFREE (target_name); + target_name = tmp_pathspec; + tmp_pathspec = 0; + + lt_debugprintf (__FILE__, __LINE__, + "(main) libtool target name: %s\n", + target_name); +EOF + + cat <<EOF + newargz[0] = + XMALLOC (char, (strlen (actual_cwrapper_path) + + strlen ("$objdir") + 1 + strlen (actual_cwrapper_name) + 1)); + strcpy (newargz[0], actual_cwrapper_path); + strcat (newargz[0], "$objdir"); + strcat (newargz[0], "/"); +EOF + + cat <<"EOF" + /* stop here, and copy so we don't have to do this twice */ + tmp_pathspec = xstrdup (newargz[0]); + + /* do NOT want the lt- prefix here, so use actual_cwrapper_name */ + strcat (newargz[0], actual_cwrapper_name); + + /* DO want the lt- prefix here if it exists, so use target_name */ + lt_argv_zero = lt_extend_str (tmp_pathspec, target_name, 1); + XFREE (tmp_pathspec); + tmp_pathspec = NULL; +EOF + + case $host_os in + mingw*) + cat <<"EOF" + { + char* p; + while ((p = strchr (newargz[0], '\\')) != NULL) + { + *p = '/'; + } + while ((p = strchr (lt_argv_zero, '\\')) != NULL) + { + *p = '/'; + } + } +EOF + ;; + esac + + cat <<"EOF" + XFREE (target_name); + XFREE (actual_cwrapper_path); + XFREE (actual_cwrapper_name); + + lt_setenv ("BIN_SH", "xpg4"); /* for Tru64 */ + lt_setenv ("DUALCASE", "1"); /* for MSK sh */ + /* Update the DLL searchpath. EXE_PATH_VALUE ($dllsearchpath) must + be prepended before (that is, appear after) LIB_PATH_VALUE ($temp_rpath) + because on Windows, both *_VARNAMEs are PATH but uninstalled + libraries must come first. */ + lt_update_exe_path (EXE_PATH_VARNAME, EXE_PATH_VALUE); + lt_update_lib_path (LIB_PATH_VARNAME, LIB_PATH_VALUE); + + lt_debugprintf (__FILE__, __LINE__, "(main) lt_argv_zero: %s\n", + nonnull (lt_argv_zero)); + for (i = 0; i < newargc; i++) + { + lt_debugprintf (__FILE__, __LINE__, "(main) newargz[%d]: %s\n", + i, nonnull (newargz[i])); + } + +EOF + + case $host_os in + mingw*) + cat <<"EOF" + /* execv doesn't actually work on mingw as expected on unix */ + newargz = prepare_spawn (newargz); + rval = (int) _spawnv (_P_WAIT, lt_argv_zero, (const char * const *) newargz); + if (rval == -1) + { + /* failed to start process */ + lt_debugprintf (__FILE__, __LINE__, + "(main) failed to launch target \"%s\": %s\n", + lt_argv_zero, nonnull (strerror (errno))); + return 127; + } + return rval; +EOF + ;; + *) + cat <<"EOF" + execv (lt_argv_zero, newargz); + return rval; /* =127, but avoids unused variable warning */ +EOF + ;; + esac + + cat <<"EOF" +} + +void * +xmalloc (size_t num) +{ + void *p = (void *) malloc (num); + if (!p) + lt_fatal (__FILE__, __LINE__, "memory exhausted"); + + return p; +} + +char * +xstrdup (const char *string) +{ + return string ? strcpy ((char *) xmalloc (strlen (string) + 1), + string) : NULL; +} + +const char * +base_name (const char *name) +{ + const char *base; + +#if defined HAVE_DOS_BASED_FILE_SYSTEM + /* Skip over the disk name in MSDOS pathnames. */ + if (isalpha ((unsigned char) name[0]) && name[1] == ':') + name += 2; +#endif + + for (base = name; *name; name++) + if (IS_DIR_SEPARATOR (*name)) + base = name + 1; + return base; +} + +int +check_executable (const char *path) +{ + struct stat st; + + lt_debugprintf (__FILE__, __LINE__, "(check_executable): %s\n", + nonempty (path)); + if ((!path) || (!*path)) + return 0; + + if ((stat (path, &st) >= 0) + && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) + return 1; + else + return 0; +} + +int +make_executable (const char *path) +{ + int rval = 0; + struct stat st; + + lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n", + nonempty (path)); + if ((!path) || (!*path)) + return 0; + + if (stat (path, &st) >= 0) + { + rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR); + } + return rval; +} + +/* Searches for the full path of the wrapper. Returns + newly allocated full path name if found, NULL otherwise + Does not chase symlinks, even on platforms that support them. +*/ +char * +find_executable (const char *wrapper) +{ + int has_slash = 0; + const char *p; + const char *p_next; + /* static buffer for getcwd */ + char tmp[LT_PATHMAX + 1]; + size_t tmp_len; + char *concat_name; + + lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n", + nonempty (wrapper)); + + if ((wrapper == NULL) || (*wrapper == '\0')) + return NULL; + + /* Absolute path? */ +#if defined HAVE_DOS_BASED_FILE_SYSTEM + if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':') + { + concat_name = xstrdup (wrapper); + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } + else + { +#endif + if (IS_DIR_SEPARATOR (wrapper[0])) + { + concat_name = xstrdup (wrapper); + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } +#if defined HAVE_DOS_BASED_FILE_SYSTEM + } +#endif + + for (p = wrapper; *p; p++) + if (*p == '/') + { + has_slash = 1; + break; + } + if (!has_slash) + { + /* no slashes; search PATH */ + const char *path = getenv ("PATH"); + if (path != NULL) + { + for (p = path; *p; p = p_next) + { + const char *q; + size_t p_len; + for (q = p; *q; q++) + if (IS_PATH_SEPARATOR (*q)) + break; + p_len = (size_t) (q - p); + p_next = (*q == '\0' ? q : q + 1); + if (p_len == 0) + { + /* empty path: current directory */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", + nonnull (strerror (errno))); + tmp_len = strlen (tmp); + concat_name = + XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, tmp, tmp_len); + concat_name[tmp_len] = '/'; + strcpy (concat_name + tmp_len + 1, wrapper); + } + else + { + concat_name = + XMALLOC (char, p_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, p, p_len); + concat_name[p_len] = '/'; + strcpy (concat_name + p_len + 1, wrapper); + } + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } + } + /* not found in PATH; assume curdir */ + } + /* Relative path | not found in path: prepend cwd */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", + nonnull (strerror (errno))); + tmp_len = strlen (tmp); + concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, tmp, tmp_len); + concat_name[tmp_len] = '/'; + strcpy (concat_name + tmp_len + 1, wrapper); + + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + return NULL; +} + +char * +chase_symlinks (const char *pathspec) +{ +#ifndef S_ISLNK + return xstrdup (pathspec); +#else + char buf[LT_PATHMAX]; + struct stat s; + char *tmp_pathspec = xstrdup (pathspec); + char *p; + int has_symlinks = 0; + while (strlen (tmp_pathspec) && !has_symlinks) + { + lt_debugprintf (__FILE__, __LINE__, + "checking path component for symlinks: %s\n", + tmp_pathspec); + if (lstat (tmp_pathspec, &s) == 0) + { + if (S_ISLNK (s.st_mode) != 0) + { + has_symlinks = 1; + break; + } + + /* search backwards for last DIR_SEPARATOR */ + p = tmp_pathspec + strlen (tmp_pathspec) - 1; + while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) + p--; + if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) + { + /* no more DIR_SEPARATORS left */ + break; + } + *p = '\0'; + } + else + { + lt_fatal (__FILE__, __LINE__, + "error accessing file \"%s\": %s", + tmp_pathspec, nonnull (strerror (errno))); + } + } + XFREE (tmp_pathspec); + + if (!has_symlinks) + { + return xstrdup (pathspec); + } + + tmp_pathspec = realpath (pathspec, buf); + if (tmp_pathspec == 0) + { + lt_fatal (__FILE__, __LINE__, + "could not follow symlinks for %s", pathspec); + } + return xstrdup (tmp_pathspec); +#endif +} + +char * +strendzap (char *str, const char *pat) +{ + size_t len, patlen; + + assert (str != NULL); + assert (pat != NULL); + + len = strlen (str); + patlen = strlen (pat); + + if (patlen <= len) + { + str += len - patlen; + if (STREQ (str, pat)) + *str = '\0'; + } + return str; +} + +void +lt_debugprintf (const char *file, int line, const char *fmt, ...) +{ + va_list args; + if (lt_debug) + { + (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line); + va_start (args, fmt); + (void) vfprintf (stderr, fmt, args); + va_end (args); + } +} + +static void +lt_error_core (int exit_status, const char *file, + int line, const char *mode, + const char *message, va_list ap) +{ + fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode); + vfprintf (stderr, message, ap); + fprintf (stderr, ".\n"); + + if (exit_status >= 0) + exit (exit_status); +} + +void +lt_fatal (const char *file, int line, const char *message, ...) +{ + va_list ap; + va_start (ap, message); + lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap); + va_end (ap); +} + +static const char * +nonnull (const char *s) +{ + return s ? s : "(null)"; +} + +static const char * +nonempty (const char *s) +{ + return (s && !*s) ? "(empty)" : nonnull (s); +} + +void +lt_setenv (const char *name, const char *value) +{ + lt_debugprintf (__FILE__, __LINE__, + "(lt_setenv) setting '%s' to '%s'\n", + nonnull (name), nonnull (value)); + { +#ifdef HAVE_SETENV + /* always make a copy, for consistency with !HAVE_SETENV */ + char *str = xstrdup (value); + setenv (name, str, 1); +#else + size_t len = strlen (name) + 1 + strlen (value) + 1; + char *str = XMALLOC (char, len); + sprintf (str, "%s=%s", name, value); + if (putenv (str) != EXIT_SUCCESS) + { + XFREE (str); + } +#endif + } +} + +char * +lt_extend_str (const char *orig_value, const char *add, int to_end) +{ + char *new_value; + if (orig_value && *orig_value) + { + size_t orig_value_len = strlen (orig_value); + size_t add_len = strlen (add); + new_value = XMALLOC (char, add_len + orig_value_len + 1); + if (to_end) + { + strcpy (new_value, orig_value); + strcpy (new_value + orig_value_len, add); + } + else + { + strcpy (new_value, add); + strcpy (new_value + add_len, orig_value); + } + } + else + { + new_value = xstrdup (add); + } + return new_value; +} + +void +lt_update_exe_path (const char *name, const char *value) +{ + lt_debugprintf (__FILE__, __LINE__, + "(lt_update_exe_path) modifying '%s' by prepending '%s'\n", + nonnull (name), nonnull (value)); + + if (name && *name && value && *value) + { + char *new_value = lt_extend_str (getenv (name), value, 0); + /* some systems can't cope with a ':'-terminated path #' */ + size_t len = strlen (new_value); + while ((len > 0) && IS_PATH_SEPARATOR (new_value[len-1])) + { + new_value[--len] = '\0'; + } + lt_setenv (name, new_value); + XFREE (new_value); + } +} + +void +lt_update_lib_path (const char *name, const char *value) +{ + lt_debugprintf (__FILE__, __LINE__, + "(lt_update_lib_path) modifying '%s' by prepending '%s'\n", + nonnull (name), nonnull (value)); + + if (name && *name && value && *value) + { + char *new_value = lt_extend_str (getenv (name), value, 0); + lt_setenv (name, new_value); + XFREE (new_value); + } +} + +EOF + case $host_os in + mingw*) + cat <<"EOF" + +/* Prepares an argument vector before calling spawn(). + Note that spawn() does not by itself call the command interpreter + (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") : + ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + GetVersionEx(&v); + v.dwPlatformId == VER_PLATFORM_WIN32_NT; + }) ? "cmd.exe" : "command.com"). + Instead it simply concatenates the arguments, separated by ' ', and calls + CreateProcess(). We must quote the arguments since Win32 CreateProcess() + interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a + special way: + - Space and tab are interpreted as delimiters. They are not treated as + delimiters if they are surrounded by double quotes: "...". + - Unescaped double quotes are removed from the input. Their only effect is + that within double quotes, space and tab are treated like normal + characters. + - Backslashes not followed by double quotes are not special. + - But 2*n+1 backslashes followed by a double quote become + n backslashes followed by a double quote (n >= 0): + \" -> " + \\\" -> \" + \\\\\" -> \\" + */ +#define SHELL_SPECIAL_CHARS "\"\\ \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" +#define SHELL_SPACE_CHARS " \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" +char ** +prepare_spawn (char **argv) +{ + size_t argc; + char **new_argv; + size_t i; + + /* Count number of arguments. */ + for (argc = 0; argv[argc] != NULL; argc++) + ; + + /* Allocate new argument vector. */ + new_argv = XMALLOC (char *, argc + 1); + + /* Put quoted arguments into the new argument vector. */ + for (i = 0; i < argc; i++) + { + const char *string = argv[i]; + + if (string[0] == '\0') + new_argv[i] = xstrdup ("\"\""); + else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL) + { + int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL); + size_t length; + unsigned int backslashes; + const char *s; + char *quoted_string; + char *p; + + length = 0; + backslashes = 0; + if (quote_around) + length++; + for (s = string; *s != '\0'; s++) + { + char c = *s; + if (c == '"') + length += backslashes + 1; + length++; + if (c == '\\') + backslashes++; + else + backslashes = 0; + } + if (quote_around) + length += backslashes + 1; + + quoted_string = XMALLOC (char, length + 1); + + p = quoted_string; + backslashes = 0; + if (quote_around) + *p++ = '"'; + for (s = string; *s != '\0'; s++) + { + char c = *s; + if (c == '"') + { + unsigned int j; + for (j = backslashes + 1; j > 0; j--) + *p++ = '\\'; + } + *p++ = c; + if (c == '\\') + backslashes++; + else + backslashes = 0; + } + if (quote_around) + { + unsigned int j; + for (j = backslashes; j > 0; j--) + *p++ = '\\'; + *p++ = '"'; + } + *p = '\0'; + + new_argv[i] = quoted_string; + } + else + new_argv[i] = (char *) string; + } + new_argv[argc] = NULL; + + return new_argv; +} +EOF + ;; + esac + + cat <<"EOF" +void lt_dump_script (FILE* f) +{ +EOF + func_emit_wrapper yes | + $SED -n -e ' +s/^\(.\{79\}\)\(..*\)/\1\ +\2/ +h +s/\([\\"]\)/\\\1/g +s/$/\\n/ +s/\([^\n]*\).*/ fputs ("\1", f);/p +g +D' + cat <<"EOF" +} +EOF +} +# end: func_emit_cwrapperexe_src + +# func_win32_import_lib_p ARG +# True if ARG is an import lib, as indicated by $file_magic_cmd +func_win32_import_lib_p () +{ + $debug_cmd + + case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in + *import*) : ;; + *) false ;; + esac +} + +# func_suncc_cstd_abi +# !!ONLY CALL THIS FOR SUN CC AFTER $compile_command IS FULLY EXPANDED!! +# Several compiler flags select an ABI that is incompatible with the +# Cstd library. Avoid specifying it if any are in CXXFLAGS. +func_suncc_cstd_abi () +{ + $debug_cmd + + case " $compile_command " in + *" -compat=g "*|*\ -std=c++[0-9][0-9]\ *|*" -library=stdcxx4 "*|*" -library=stlport4 "*) + suncc_use_cstd_abi=no + ;; + *) + suncc_use_cstd_abi=yes + ;; + esac +} + +# func_mode_link arg... +func_mode_link () +{ + $debug_cmd + + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + # It is impossible to link a dll without this setting, and + # we shouldn't force the makefile maintainer to figure out + # what system we are compiling for in order to pass an extra + # flag for every libtool invocation. + # allow_undefined=no + + # FIXME: Unfortunately, there are problems with the above when trying + # to make a dll that has undefined symbols, in which case not + # even a static library is built. For now, we need to specify + # -no-undefined on the libtool link line when we can be certain + # that all symbols are satisfied, otherwise we get a static library. + allow_undefined=yes + ;; + *) + allow_undefined=yes + ;; + esac + libtool_args=$nonopt + base_compile="$nonopt $@" + compile_command=$nonopt + finalize_command=$nonopt + + compile_rpath= + finalize_rpath= + compile_shlibpath= + finalize_shlibpath= + convenience= + old_convenience= + deplibs= + old_deplibs= + compiler_flags= + linker_flags= + dllsearchpath= + lib_search_path=`pwd` + inst_prefix_dir= + new_inherited_linker_flags= + + avoid_version=no + bindir= + dlfiles= + dlprefiles= + dlself=no + export_dynamic=no + export_symbols= + export_symbols_regex= + generated= + libobjs= + ltlibs= + module=no + no_install=no + objs= + os2dllname= + non_pic_objects= + precious_files_regex= + prefer_static_libs=no + preload=false + prev= + prevarg= + release= + rpath= + xrpath= + perm_rpath= + temp_rpath= + thread_safe=no + vinfo= + vinfo_number=no + weak_libs= + single_module=$wl-single_module + func_infer_tag $base_compile + + # We need to know -static, to get the right output filenames. + for arg + do + case $arg in + -shared) + test yes != "$build_libtool_libs" \ + && func_fatal_configuration "cannot build a shared library" + build_old_libs=no + break + ;; + -all-static | -static | -static-libtool-libs) + case $arg in + -all-static) + if test yes = "$build_libtool_libs" && test -z "$link_static_flag"; then + func_warning "complete static linking is impossible in this configuration" + fi + if test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=yes + ;; + -static) + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=built + ;; + -static-libtool-libs) + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=yes + ;; + esac + build_libtool_libs=no + build_old_libs=yes + break + ;; + esac + done + + # See if our shared archives depend on static archives. + test -n "$old_archive_from_new_cmds" && build_old_libs=yes + + # Go through the arguments, transforming them on the way. + while test "$#" -gt 0; do + arg=$1 + shift + func_quote_for_eval "$arg" + qarg=$func_quote_for_eval_unquoted_result + func_append libtool_args " $func_quote_for_eval_result" + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + case $prev in + output) + func_append compile_command " @OUTPUT@" + func_append finalize_command " @OUTPUT@" + ;; + esac + + case $prev in + bindir) + bindir=$arg + prev= + continue + ;; + dlfiles|dlprefiles) + $preload || { + # Add the symbol object into the linking commands. + func_append compile_command " @SYMFILE@" + func_append finalize_command " @SYMFILE@" + preload=: + } + case $arg in + *.la | *.lo) ;; # We handle these cases below. + force) + if test no = "$dlself"; then + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + self) + if test dlprefiles = "$prev"; then + dlself=yes + elif test dlfiles = "$prev" && test yes != "$dlopen_self"; then + dlself=yes + else + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + *) + if test dlfiles = "$prev"; then + func_append dlfiles " $arg" + else + func_append dlprefiles " $arg" + fi + prev= + continue + ;; + esac + ;; + expsyms) + export_symbols=$arg + test -f "$arg" \ + || func_fatal_error "symbol file '$arg' does not exist" + prev= + continue + ;; + expsyms_regex) + export_symbols_regex=$arg + prev= + continue + ;; + framework) + case $host in + *-*-darwin*) + case "$deplibs " in + *" $qarg.ltframework "*) ;; + *) func_append deplibs " $qarg.ltframework" # this is fixed later + ;; + esac + ;; + esac + prev= + continue + ;; + inst_prefix) + inst_prefix_dir=$arg + prev= + continue + ;; + mllvm) + # Clang does not use LLVM to link, so we can simply discard any + # '-mllvm $arg' options when doing the link step. + prev= + continue + ;; + objectlist) + if test -f "$arg"; then + save_arg=$arg + moreargs= + for fil in `cat "$save_arg"` + do +# func_append moreargs " $fil" + arg=$fil + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if func_lalib_unsafe_p "$arg"; then + pic_object= + non_pic_object= + + # Read the .lo file + func_source "$arg" + + if test -z "$pic_object" || + test -z "$non_pic_object" || + test none = "$pic_object" && + test none = "$non_pic_object"; then + func_fatal_error "cannot find name of object for '$arg'" + fi + + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir=$func_dirname_result + + if test none != "$pic_object"; then + # Prepend the subdirectory the object is found in. + pic_object=$xdir$pic_object + + if test dlfiles = "$prev"; then + if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then + func_append dlfiles " $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test dlprefiles = "$prev"; then + # Preload the old-style object. + func_append dlprefiles " $pic_object" + prev= + fi + + # A PIC object. + func_append libobjs " $pic_object" + arg=$pic_object + fi + + # Non-PIC object. + if test none != "$non_pic_object"; then + # Prepend the subdirectory the object is found in. + non_pic_object=$xdir$non_pic_object + + # A standard non-PIC object + func_append non_pic_objects " $non_pic_object" + if test -z "$pic_object" || test none = "$pic_object"; then + arg=$non_pic_object + fi + else + # If the PIC object exists, use it instead. + # $xdir was prepended to $pic_object above. + non_pic_object=$pic_object + func_append non_pic_objects " $non_pic_object" + fi + else + # Only an error if not doing a dry-run. + if $opt_dry_run; then + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir=$func_dirname_result + + func_lo2o "$arg" + pic_object=$xdir$objdir/$func_lo2o_result + non_pic_object=$xdir$func_lo2o_result + func_append libobjs " $pic_object" + func_append non_pic_objects " $non_pic_object" + else + func_fatal_error "'$arg' is not a valid libtool object" + fi + fi + done + else + func_fatal_error "link input file '$arg' does not exist" + fi + arg=$save_arg + prev= + continue + ;; + os2dllname) + os2dllname=$arg + prev= + continue + ;; + precious_regex) + precious_files_regex=$arg + prev= + continue + ;; + release) + release=-$arg + prev= + continue + ;; + rpath | xrpath) + # We need an absolute path. + case $arg in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + func_fatal_error "only absolute run-paths are allowed" + ;; + esac + if test rpath = "$prev"; then + case "$rpath " in + *" $arg "*) ;; + *) func_append rpath " $arg" ;; + esac + else + case "$xrpath " in + *" $arg "*) ;; + *) func_append xrpath " $arg" ;; + esac + fi + prev= + continue + ;; + shrext) + shrext_cmds=$arg + prev= + continue + ;; + weak) + func_append weak_libs " $arg" + prev= + continue + ;; + xcclinker) + func_append linker_flags " $qarg" + func_append compiler_flags " $qarg" + prev= + func_append compile_command " $qarg" + func_append finalize_command " $qarg" + continue + ;; + xcompiler) + func_append compiler_flags " $qarg" + prev= + func_append compile_command " $qarg" + func_append finalize_command " $qarg" + continue + ;; + xlinker) + func_append linker_flags " $qarg" + func_append compiler_flags " $wl$qarg" + prev= + func_append compile_command " $wl$qarg" + func_append finalize_command " $wl$qarg" + continue + ;; + *) + eval "$prev=\"\$arg\"" + prev= + continue + ;; + esac + fi # test -n "$prev" + + prevarg=$arg + + case $arg in + -all-static) + if test -n "$link_static_flag"; then + # See comment for -static flag below, for more details. + func_append compile_command " $link_static_flag" + func_append finalize_command " $link_static_flag" + fi + continue + ;; + + -allow-undefined) + # FIXME: remove this flag sometime in the future. + func_fatal_error "'-allow-undefined' must not be used because it is the default" + ;; + + -avoid-version) + avoid_version=yes + continue + ;; + + -bindir) + prev=bindir + continue + ;; + + -dlopen) + prev=dlfiles + continue + ;; + + -dlpreopen) + prev=dlprefiles + continue + ;; + + -export-dynamic) + export_dynamic=yes + continue + ;; + + -export-symbols | -export-symbols-regex) + if test -n "$export_symbols" || test -n "$export_symbols_regex"; then + func_fatal_error "more than one -exported-symbols argument is not allowed" + fi + if test X-export-symbols = "X$arg"; then + prev=expsyms + else + prev=expsyms_regex + fi + continue + ;; + + -framework) + prev=framework + continue + ;; + + -inst-prefix-dir) + prev=inst_prefix + continue + ;; + + # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* + # so, if we see these flags be careful not to treat them like -L + -L[A-Z][A-Z]*:*) + case $with_gcc/$host in + no/*-*-irix* | /*-*-irix*) + func_append compile_command " $arg" + func_append finalize_command " $arg" + ;; + esac + continue + ;; + + -L*) + func_stripname "-L" '' "$arg" + if test -z "$func_stripname_result"; then + if test "$#" -gt 0; then + func_fatal_error "require no space between '-L' and '$1'" + else + func_fatal_error "need path for '-L' option" + fi + fi + func_resolve_sysroot "$func_stripname_result" + dir=$func_resolve_sysroot_result + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + absdir=`cd "$dir" && pwd` + test -z "$absdir" && \ + func_fatal_error "cannot determine absolute directory name of '$dir'" + dir=$absdir + ;; + esac + case "$deplibs " in + *" -L$dir "* | *" $arg "*) + # Will only happen for absolute or sysroot arguments + ;; + *) + # Preserve sysroot, but never include relative directories + case $dir in + [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;; + *) func_append deplibs " -L$dir" ;; + esac + func_append lib_search_path " $dir" + ;; + esac + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'` + case :$dllsearchpath: in + *":$dir:"*) ;; + ::) dllsearchpath=$dir;; + *) func_append dllsearchpath ":$dir";; + esac + case :$dllsearchpath: in + *":$testbindir:"*) ;; + ::) dllsearchpath=$testbindir;; + *) func_append dllsearchpath ":$testbindir";; + esac + ;; + esac + continue + ;; + + -l*) + if test X-lc = "X$arg" || test X-lm = "X$arg"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*) + # These systems don't actually have a C or math library (as such) + continue + ;; + *-*-os2*) + # These systems don't actually have a C library (as such) + test X-lc = "X$arg" && continue + ;; + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*) + # Do not include libc due to us having libc/libc_r. + test X-lc = "X$arg" && continue + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C and math libraries are in the System framework + func_append deplibs " System.ltframework" + continue + ;; + *-*-sco3.2v5* | *-*-sco5v6*) + # Causes problems with __ctype + test X-lc = "X$arg" && continue + ;; + *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) + # Compiler inserts libc in the correct place for threads to work + test X-lc = "X$arg" && continue + ;; + esac + elif test X-lc_r = "X$arg"; then + case $host in + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*) + # Do not include libc_r directly, use -pthread flag. + continue + ;; + esac + fi + func_append deplibs " $arg" + continue + ;; + + -mllvm) + prev=mllvm + continue + ;; + + -module) + module=yes + continue + ;; + + # Tru64 UNIX uses -model [arg] to determine the layout of C++ + # classes, name mangling, and exception handling. + # Darwin uses the -arch flag to determine output architecture. + -model|-arch|-isysroot|--sysroot) + func_append compiler_flags " $arg" + func_append compile_command " $arg" + func_append finalize_command " $arg" + prev=xcompiler + continue + ;; + + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ + |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) + func_append compiler_flags " $arg" + func_append compile_command " $arg" + func_append finalize_command " $arg" + case "$new_inherited_linker_flags " in + *" $arg "*) ;; + * ) func_append new_inherited_linker_flags " $arg" ;; + esac + continue + ;; + + -multi_module) + single_module=$wl-multi_module + continue + ;; + + -no-fast-install) + fast_install=no + continue + ;; + + -no-install) + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*) + # The PATH hackery in wrapper scripts is required on Windows + # and Darwin in order for the loader to find any dlls it needs. + func_warning "'-no-install' is ignored for $host" + func_warning "assuming '-no-fast-install' instead" + fast_install=no + ;; + *) no_install=yes ;; + esac + continue + ;; + + -no-undefined) + allow_undefined=no + continue + ;; + + -objectlist) + prev=objectlist + continue + ;; + + -os2dllname) + prev=os2dllname + continue + ;; + + -o) prev=output ;; + + -precious-files-regex) + prev=precious_regex + continue + ;; + + -release) + prev=release + continue + ;; + + -rpath) + prev=rpath + continue + ;; + + -R) + prev=xrpath + continue + ;; + + -R*) + func_stripname '-R' '' "$arg" + dir=$func_stripname_result + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + =*) + func_stripname '=' '' "$dir" + dir=$lt_sysroot$func_stripname_result + ;; + *) + func_fatal_error "only absolute run-paths are allowed" + ;; + esac + case "$xrpath " in + *" $dir "*) ;; + *) func_append xrpath " $dir" ;; + esac + continue + ;; + + -shared) + # The effects of -shared are defined in a previous loop. + continue + ;; + + -shrext) + prev=shrext + continue + ;; + + -static | -static-libtool-libs) + # The effects of -static are defined in a previous loop. + # We used to do the same as -all-static on platforms that + # didn't have a PIC flag, but the assumption that the effects + # would be equivalent was wrong. It would break on at least + # Digital Unix and AIX. + continue + ;; + + -thread-safe) + thread_safe=yes + continue + ;; + + -version-info) + prev=vinfo + continue + ;; + + -version-number) + prev=vinfo + vinfo_number=yes + continue + ;; + + -weak) + prev=weak + continue + ;; + + -Wc,*) + func_stripname '-Wc,' '' "$arg" + args=$func_stripname_result + arg= + save_ifs=$IFS; IFS=, + for flag in $args; do + IFS=$save_ifs + func_quote_for_eval "$flag" + func_append arg " $func_quote_for_eval_result" + func_append compiler_flags " $func_quote_for_eval_result" + done + IFS=$save_ifs + func_stripname ' ' '' "$arg" + arg=$func_stripname_result + ;; + + -Wl,*) + func_stripname '-Wl,' '' "$arg" + args=$func_stripname_result + arg= + save_ifs=$IFS; IFS=, + for flag in $args; do + IFS=$save_ifs + func_quote_for_eval "$flag" + func_append arg " $wl$func_quote_for_eval_result" + func_append compiler_flags " $wl$func_quote_for_eval_result" + func_append linker_flags " $func_quote_for_eval_result" + done + IFS=$save_ifs + func_stripname ' ' '' "$arg" + arg=$func_stripname_result + ;; + + -Xcompiler) + prev=xcompiler + continue + ;; + + -Xlinker) + prev=xlinker + continue + ;; + + -XCClinker) + prev=xcclinker + continue + ;; + + # -msg_* for osf cc + -msg_*) + func_quote_for_eval "$arg" + arg=$func_quote_for_eval_result + ;; + + # Flags to be passed through unchanged, with rationale: + # -64, -mips[0-9] enable 64-bit mode for the SGI compiler + # -r[0-9][0-9]* specify processor for the SGI compiler + # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler + # +DA*, +DD* enable 64-bit mode for the HP compiler + # -q* compiler args for the IBM compiler + # -m*, -t[45]*, -txscale* architecture-specific flags for GCC + # -F/path path to uninstalled frameworks, gcc on darwin + # -p, -pg, --coverage, -fprofile-* profiling flags for GCC + # -fstack-protector* stack protector flags for GCC + # @file GCC response files + # -tp=* Portland pgcc target processor selection + # --sysroot=* for sysroot support + # -O*, -g*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization + # -stdlib=* select c++ std lib with clang + -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ + -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \ + -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*) + func_quote_for_eval "$arg" + arg=$func_quote_for_eval_result + func_append compile_command " $arg" + func_append finalize_command " $arg" + func_append compiler_flags " $arg" + continue + ;; + + -Z*) + if test os2 = "`expr $host : '.*\(os2\)'`"; then + # OS/2 uses -Zxxx to specify OS/2-specific options + compiler_flags="$compiler_flags $arg" + func_append compile_command " $arg" + func_append finalize_command " $arg" + case $arg in + -Zlinker | -Zstack) + prev=xcompiler + ;; + esac + continue + else + # Otherwise treat like 'Some other compiler flag' below + func_quote_for_eval "$arg" + arg=$func_quote_for_eval_result + fi + ;; + + # Some other compiler flag. + -* | +*) + func_quote_for_eval "$arg" + arg=$func_quote_for_eval_result + ;; + + *.$objext) + # A standard object. + func_append objs " $arg" + ;; + + *.lo) + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if func_lalib_unsafe_p "$arg"; then + pic_object= + non_pic_object= + + # Read the .lo file + func_source "$arg" + + if test -z "$pic_object" || + test -z "$non_pic_object" || + test none = "$pic_object" && + test none = "$non_pic_object"; then + func_fatal_error "cannot find name of object for '$arg'" + fi + + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir=$func_dirname_result + + test none = "$pic_object" || { + # Prepend the subdirectory the object is found in. + pic_object=$xdir$pic_object + + if test dlfiles = "$prev"; then + if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then + func_append dlfiles " $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test dlprefiles = "$prev"; then + # Preload the old-style object. + func_append dlprefiles " $pic_object" + prev= + fi + + # A PIC object. + func_append libobjs " $pic_object" + arg=$pic_object + } + + # Non-PIC object. + if test none != "$non_pic_object"; then + # Prepend the subdirectory the object is found in. + non_pic_object=$xdir$non_pic_object + + # A standard non-PIC object + func_append non_pic_objects " $non_pic_object" + if test -z "$pic_object" || test none = "$pic_object"; then + arg=$non_pic_object + fi + else + # If the PIC object exists, use it instead. + # $xdir was prepended to $pic_object above. + non_pic_object=$pic_object + func_append non_pic_objects " $non_pic_object" + fi + else + # Only an error if not doing a dry-run. + if $opt_dry_run; then + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir=$func_dirname_result + + func_lo2o "$arg" + pic_object=$xdir$objdir/$func_lo2o_result + non_pic_object=$xdir$func_lo2o_result + func_append libobjs " $pic_object" + func_append non_pic_objects " $non_pic_object" + else + func_fatal_error "'$arg' is not a valid libtool object" + fi + fi + ;; + + *.$libext) + # An archive. + func_append deplibs " $arg" + func_append old_deplibs " $arg" + continue + ;; + + *.la) + # A libtool-controlled library. + + func_resolve_sysroot "$arg" + if test dlfiles = "$prev"; then + # This library was specified with -dlopen. + func_append dlfiles " $func_resolve_sysroot_result" + prev= + elif test dlprefiles = "$prev"; then + # The library was specified with -dlpreopen. + func_append dlprefiles " $func_resolve_sysroot_result" + prev= + else + func_append deplibs " $func_resolve_sysroot_result" + fi + continue + ;; + + # Some other compiler argument. + *) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + func_quote_for_eval "$arg" + arg=$func_quote_for_eval_result + ;; + esac # arg + + # Now actually substitute the argument into the commands. + if test -n "$arg"; then + func_append compile_command " $arg" + func_append finalize_command " $arg" + fi + done # argument parsing loop + + test -n "$prev" && \ + func_fatal_help "the '$prevarg' option requires an argument" + + if test yes = "$export_dynamic" && test -n "$export_dynamic_flag_spec"; then + eval arg=\"$export_dynamic_flag_spec\" + func_append compile_command " $arg" + func_append finalize_command " $arg" + fi + + oldlibs= + # calculate the name of the file, without its directory + func_basename "$output" + outputname=$func_basename_result + libobjs_save=$libobjs + + if test -n "$shlibpath_var"; then + # get the directories listed in $shlibpath_var + eval shlib_search_path=\`\$ECHO \"\$$shlibpath_var\" \| \$SED \'s/:/ /g\'\` + else + shlib_search_path= + fi + eval sys_lib_search_path=\"$sys_lib_search_path_spec\" + eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" + + # Definition is injected by LT_CONFIG during libtool generation. + func_munge_path_list sys_lib_dlsearch_path "$LT_SYS_LIBRARY_PATH" + + func_dirname "$output" "/" "" + output_objdir=$func_dirname_result$objdir + func_to_tool_file "$output_objdir/" + tool_output_objdir=$func_to_tool_file_result + # Create the object directory. + func_mkdir_p "$output_objdir" + + # Determine the type of output + case $output in + "") + func_fatal_help "you must specify an output file" + ;; + *.$libext) linkmode=oldlib ;; + *.lo | *.$objext) linkmode=obj ;; + *.la) linkmode=lib ;; + *) linkmode=prog ;; # Anything else should be a program. + esac + + specialdeplibs= + + libs= + # Find all interdependent deplibs by searching for libraries + # that are linked more than once (e.g. -la -lb -la) + for deplib in $deplibs; do + if $opt_preserve_dup_deps; then + case "$libs " in + *" $deplib "*) func_append specialdeplibs " $deplib" ;; + esac + fi + func_append libs " $deplib" + done + + if test lib = "$linkmode"; then + libs="$predeps $libs $compiler_lib_search_path $postdeps" + + # Compute libraries that are listed more than once in $predeps + # $postdeps and mark them as special (i.e., whose duplicates are + # not to be eliminated). + pre_post_deps= + if $opt_duplicate_compiler_generated_deps; then + for pre_post_dep in $predeps $postdeps; do + case "$pre_post_deps " in + *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;; + esac + func_append pre_post_deps " $pre_post_dep" + done + fi + pre_post_deps= + fi + + deplibs= + newdependency_libs= + newlib_search_path= + need_relink=no # whether we're linking any uninstalled libtool libraries + notinst_deplibs= # not-installed libtool libraries + notinst_path= # paths that contain not-installed libtool libraries + + case $linkmode in + lib) + passes="conv dlpreopen link" + for file in $dlfiles $dlprefiles; do + case $file in + *.la) ;; + *) + func_fatal_help "libraries can '-dlopen' only libtool libraries: $file" + ;; + esac + done + ;; + prog) + compile_deplibs= + finalize_deplibs= + alldeplibs=false + newdlfiles= + newdlprefiles= + passes="conv scan dlopen dlpreopen link" + ;; + *) passes="conv" + ;; + esac + + for pass in $passes; do + # The preopen pass in lib mode reverses $deplibs; put it back here + # so that -L comes before libs that need it for instance... + if test lib,link = "$linkmode,$pass"; then + ## FIXME: Find the place where the list is rebuilt in the wrong + ## order, and fix it there properly + tmp_deplibs= + for deplib in $deplibs; do + tmp_deplibs="$deplib $tmp_deplibs" + done + deplibs=$tmp_deplibs + fi + + if test lib,link = "$linkmode,$pass" || + test prog,scan = "$linkmode,$pass"; then + libs=$deplibs + deplibs= + fi + if test prog = "$linkmode"; then + case $pass in + dlopen) libs=$dlfiles ;; + dlpreopen) libs=$dlprefiles ;; + link) libs="$deplibs %DEPLIBS% $dependency_libs" ;; + esac + fi + if test lib,dlpreopen = "$linkmode,$pass"; then + # Collect and forward deplibs of preopened libtool libs + for lib in $dlprefiles; do + # Ignore non-libtool-libs + dependency_libs= + func_resolve_sysroot "$lib" + case $lib in + *.la) func_source "$func_resolve_sysroot_result" ;; + esac + + # Collect preopened libtool deplibs, except any this library + # has declared as weak libs + for deplib in $dependency_libs; do + func_basename "$deplib" + deplib_base=$func_basename_result + case " $weak_libs " in + *" $deplib_base "*) ;; + *) func_append deplibs " $deplib" ;; + esac + done + done + libs=$dlprefiles + fi + if test dlopen = "$pass"; then + # Collect dlpreopened libraries + save_deplibs=$deplibs + deplibs= + fi + + for deplib in $libs; do + lib= + found=false + case $deplib in + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ + |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) + if test prog,link = "$linkmode,$pass"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + func_append compiler_flags " $deplib" + if test lib = "$linkmode"; then + case "$new_inherited_linker_flags " in + *" $deplib "*) ;; + * ) func_append new_inherited_linker_flags " $deplib" ;; + esac + fi + fi + continue + ;; + -l*) + if test lib != "$linkmode" && test prog != "$linkmode"; then + func_warning "'-l' is ignored for archives/objects" + continue + fi + func_stripname '-l' '' "$deplib" + name=$func_stripname_result + if test lib = "$linkmode"; then + searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path" + else + searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path" + fi + for searchdir in $searchdirs; do + for search_ext in .la $std_shrext .so .a; do + # Search the libtool library + lib=$searchdir/lib$name$search_ext + if test -f "$lib"; then + if test .la = "$search_ext"; then + found=: + else + found=false + fi + break 2 + fi + done + done + if $found; then + # deplib is a libtool library + # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, + # We need to do some special things here, and not later. + if test yes = "$allow_libtool_libs_with_static_runtimes"; then + case " $predeps $postdeps " in + *" $deplib "*) + if func_lalib_p "$lib"; then + library_names= + old_library= + func_source "$lib" + for l in $old_library $library_names; do + ll=$l + done + if test "X$ll" = "X$old_library"; then # only static version available + found=false + func_dirname "$lib" "" "." + ladir=$func_dirname_result + lib=$ladir/$old_library + if test prog,link = "$linkmode,$pass"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs" + fi + continue + fi + fi + ;; + *) ;; + esac + fi + else + # deplib doesn't seem to be a libtool library + if test prog,link = "$linkmode,$pass"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs" + fi + continue + fi + ;; # -l + *.ltframework) + if test prog,link = "$linkmode,$pass"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + if test lib = "$linkmode"; then + case "$new_inherited_linker_flags " in + *" $deplib "*) ;; + * ) func_append new_inherited_linker_flags " $deplib" ;; + esac + fi + fi + continue + ;; + -L*) + case $linkmode in + lib) + deplibs="$deplib $deplibs" + test conv = "$pass" && continue + newdependency_libs="$deplib $newdependency_libs" + func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + func_append newlib_search_path " $func_resolve_sysroot_result" + ;; + prog) + if test conv = "$pass"; then + deplibs="$deplib $deplibs" + continue + fi + if test scan = "$pass"; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + func_append newlib_search_path " $func_resolve_sysroot_result" + ;; + *) + func_warning "'-L' is ignored for archives/objects" + ;; + esac # linkmode + continue + ;; # -L + -R*) + if test link = "$pass"; then + func_stripname '-R' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + dir=$func_resolve_sysroot_result + # Make sure the xrpath contains only unique directories. + case "$xrpath " in + *" $dir "*) ;; + *) func_append xrpath " $dir" ;; + esac + fi + deplibs="$deplib $deplibs" + continue + ;; + *.la) + func_resolve_sysroot "$deplib" + lib=$func_resolve_sysroot_result + ;; + *.$libext) + if test conv = "$pass"; then + deplibs="$deplib $deplibs" + continue + fi + case $linkmode in + lib) + # Linking convenience modules into shared libraries is allowed, + # but linking other static libraries is non-portable. + case " $dlpreconveniencelibs " in + *" $deplib "*) ;; + *) + valid_a_lib=false + case $deplibs_check_method in + match_pattern*) + set dummy $deplibs_check_method; shift + match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` + if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \ + | $EGREP "$match_pattern_regex" > /dev/null; then + valid_a_lib=: + fi + ;; + pass_all) + valid_a_lib=: + ;; + esac + if $valid_a_lib; then + echo + $ECHO "*** Warning: Linking the shared library $output against the" + $ECHO "*** static library $deplib is not portable!" + deplibs="$deplib $deplibs" + else + echo + $ECHO "*** Warning: Trying to link with static lib archive $deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because the file extensions .$libext of this argument makes me believe" + echo "*** that it is just a static archive that I should not use here." + fi + ;; + esac + continue + ;; + prog) + if test link != "$pass"; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + continue + ;; + esac # linkmode + ;; # *.$libext + *.lo | *.$objext) + if test conv = "$pass"; then + deplibs="$deplib $deplibs" + elif test prog = "$linkmode"; then + if test dlpreopen = "$pass" || test yes != "$dlopen_support" || test no = "$build_libtool_libs"; then + # If there is no dlopen support or we're linking statically, + # we need to preload. + func_append newdlprefiles " $deplib" + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + func_append newdlfiles " $deplib" + fi + fi + continue + ;; + %DEPLIBS%) + alldeplibs=: + continue + ;; + esac # case $deplib + + $found || test -f "$lib" \ + || func_fatal_error "cannot find the library '$lib' or unhandled argument '$deplib'" + + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$lib" \ + || func_fatal_error "'$lib' is not a valid libtool archive" + + func_dirname "$lib" "" "." + ladir=$func_dirname_result + + dlname= + dlopen= + dlpreopen= + libdir= + library_names= + old_library= + inherited_linker_flags= + # If the library was installed with an old release of libtool, + # it will not redefine variables installed, or shouldnotlink + installed=yes + shouldnotlink=no + avoidtemprpath= + + + # Read the .la file + func_source "$lib" + + # Convert "-framework foo" to "foo.ltframework" + if test -n "$inherited_linker_flags"; then + tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'` + for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do + case " $new_inherited_linker_flags " in + *" $tmp_inherited_linker_flag "*) ;; + *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";; + esac + done + fi + dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + if test lib,link = "$linkmode,$pass" || + test prog,scan = "$linkmode,$pass" || + { test prog != "$linkmode" && test lib != "$linkmode"; }; then + test -n "$dlopen" && func_append dlfiles " $dlopen" + test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen" + fi + + if test conv = "$pass"; then + # Only check for convenience libraries + deplibs="$lib $deplibs" + if test -z "$libdir"; then + if test -z "$old_library"; then + func_fatal_error "cannot find name of link library for '$lib'" + fi + # It is a libtool convenience library, so add in its objects. + func_append convenience " $ladir/$objdir/$old_library" + func_append old_convenience " $ladir/$objdir/$old_library" + elif test prog != "$linkmode" && test lib != "$linkmode"; then + func_fatal_error "'$lib' is not a convenience library" + fi + tmp_libs= + for deplib in $dependency_libs; do + deplibs="$deplib $deplibs" + if $opt_preserve_dup_deps; then + case "$tmp_libs " in + *" $deplib "*) func_append specialdeplibs " $deplib" ;; + esac + fi + func_append tmp_libs " $deplib" + done + continue + fi # $pass = conv + + + # Get the name of the library we link against. + linklib= + if test -n "$old_library" && + { test yes = "$prefer_static_libs" || + test built,no = "$prefer_static_libs,$installed"; }; then + linklib=$old_library + else + for l in $old_library $library_names; do + linklib=$l + done + fi + if test -z "$linklib"; then + func_fatal_error "cannot find name of link library for '$lib'" + fi + + # This library was specified with -dlopen. + if test dlopen = "$pass"; then + test -z "$libdir" \ + && func_fatal_error "cannot -dlopen a convenience library: '$lib'" + if test -z "$dlname" || + test yes != "$dlopen_support" || + test no = "$build_libtool_libs" + then + # If there is no dlname, no dlopen support or we're linking + # statically, we need to preload. We also need to preload any + # dependent libraries so libltdl's deplib preloader doesn't + # bomb out in the load deplibs phase. + func_append dlprefiles " $lib $dependency_libs" + else + func_append newdlfiles " $lib" + fi + continue + fi # $pass = dlopen + + # We need an absolute path. + case $ladir in + [\\/]* | [A-Za-z]:[\\/]*) abs_ladir=$ladir ;; + *) + abs_ladir=`cd "$ladir" && pwd` + if test -z "$abs_ladir"; then + func_warning "cannot determine absolute directory name of '$ladir'" + func_warning "passing it literally to the linker, although it might fail" + abs_ladir=$ladir + fi + ;; + esac + func_basename "$lib" + laname=$func_basename_result + + # Find the relevant object directory and library name. + if test yes = "$installed"; then + if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then + func_warning "library '$lib' was moved." + dir=$ladir + absdir=$abs_ladir + libdir=$abs_ladir + else + dir=$lt_sysroot$libdir + absdir=$lt_sysroot$libdir + fi + test yes = "$hardcode_automatic" && avoidtemprpath=yes + else + if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then + dir=$ladir + absdir=$abs_ladir + # Remove this search path later + func_append notinst_path " $abs_ladir" + else + dir=$ladir/$objdir + absdir=$abs_ladir/$objdir + # Remove this search path later + func_append notinst_path " $abs_ladir" + fi + fi # $installed = yes + func_stripname 'lib' '.la' "$laname" + name=$func_stripname_result + + # This library was specified with -dlpreopen. + if test dlpreopen = "$pass"; then + if test -z "$libdir" && test prog = "$linkmode"; then + func_fatal_error "only libraries may -dlpreopen a convenience library: '$lib'" + fi + case $host in + # special handling for platforms with PE-DLLs. + *cygwin* | *mingw* | *cegcc* ) + # Linker will automatically link against shared library if both + # static and shared are present. Therefore, ensure we extract + # symbols from the import library if a shared library is present + # (otherwise, the dlopen module name will be incorrect). We do + # this by putting the import library name into $newdlprefiles. + # We recover the dlopen module name by 'saving' the la file + # name in a special purpose variable, and (later) extracting the + # dlname from the la file. + if test -n "$dlname"; then + func_tr_sh "$dir/$linklib" + eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname" + func_append newdlprefiles " $dir/$linklib" + else + func_append newdlprefiles " $dir/$old_library" + # Keep a list of preopened convenience libraries to check + # that they are being used correctly in the link pass. + test -z "$libdir" && \ + func_append dlpreconveniencelibs " $dir/$old_library" + fi + ;; + * ) + # Prefer using a static library (so that no silly _DYNAMIC symbols + # are required to link). + if test -n "$old_library"; then + func_append newdlprefiles " $dir/$old_library" + # Keep a list of preopened convenience libraries to check + # that they are being used correctly in the link pass. + test -z "$libdir" && \ + func_append dlpreconveniencelibs " $dir/$old_library" + # Otherwise, use the dlname, so that lt_dlopen finds it. + elif test -n "$dlname"; then + func_append newdlprefiles " $dir/$dlname" + else + func_append newdlprefiles " $dir/$linklib" + fi + ;; + esac + fi # $pass = dlpreopen + + if test -z "$libdir"; then + # Link the convenience library + if test lib = "$linkmode"; then + deplibs="$dir/$old_library $deplibs" + elif test prog,link = "$linkmode,$pass"; then + compile_deplibs="$dir/$old_library $compile_deplibs" + finalize_deplibs="$dir/$old_library $finalize_deplibs" + else + deplibs="$lib $deplibs" # used for prog,scan pass + fi + continue + fi + + + if test prog = "$linkmode" && test link != "$pass"; then + func_append newlib_search_path " $ladir" + deplibs="$lib $deplibs" + + linkalldeplibs=false + if test no != "$link_all_deplibs" || test -z "$library_names" || + test no = "$build_libtool_libs"; then + linkalldeplibs=: + fi + + tmp_libs= + for deplib in $dependency_libs; do + case $deplib in + -L*) func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + func_append newlib_search_path " $func_resolve_sysroot_result" + ;; + esac + # Need to link against all dependency_libs? + if $linkalldeplibs; then + deplibs="$deplib $deplibs" + else + # Need to hardcode shared library paths + # or/and link against static libraries + newdependency_libs="$deplib $newdependency_libs" + fi + if $opt_preserve_dup_deps; then + case "$tmp_libs " in + *" $deplib "*) func_append specialdeplibs " $deplib" ;; + esac + fi + func_append tmp_libs " $deplib" + done # for deplib + continue + fi # $linkmode = prog... + + if test prog,link = "$linkmode,$pass"; then + if test -n "$library_names" && + { { test no = "$prefer_static_libs" || + test built,yes = "$prefer_static_libs,$installed"; } || + test -z "$old_library"; }; then + # We need to hardcode the library path + if test -n "$shlibpath_var" && test -z "$avoidtemprpath"; then + # Make sure the rpath contains only unique directories. + case $temp_rpath: in + *"$absdir:"*) ;; + *) func_append temp_rpath "$absdir:" ;; + esac + fi + + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) func_append compile_rpath " $absdir" ;; + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + ;; + esac + fi # $linkmode,$pass = prog,link... + + if $alldeplibs && + { test pass_all = "$deplibs_check_method" || + { test yes = "$build_libtool_libs" && + test -n "$library_names"; }; }; then + # We only need to search for static libraries + continue + fi + fi + + link_static=no # Whether the deplib will be linked statically + use_static_libs=$prefer_static_libs + if test built = "$use_static_libs" && test yes = "$installed"; then + use_static_libs=no + fi + if test -n "$library_names" && + { test no = "$use_static_libs" || test -z "$old_library"; }; then + case $host in + *cygwin* | *mingw* | *cegcc* | *os2*) + # No point in relinking DLLs because paths are not encoded + func_append notinst_deplibs " $lib" + need_relink=no + ;; + *) + if test no = "$installed"; then + func_append notinst_deplibs " $lib" + need_relink=yes + fi + ;; + esac + # This is a shared library + + # Warn about portability, can't link against -module's on some + # systems (darwin). Don't bleat about dlopened modules though! + dlopenmodule= + for dlpremoduletest in $dlprefiles; do + if test "X$dlpremoduletest" = "X$lib"; then + dlopenmodule=$dlpremoduletest + break + fi + done + if test -z "$dlopenmodule" && test yes = "$shouldnotlink" && test link = "$pass"; then + echo + if test prog = "$linkmode"; then + $ECHO "*** Warning: Linking the executable $output against the loadable module" + else + $ECHO "*** Warning: Linking the shared library $output against the loadable module" + fi + $ECHO "*** $linklib is not portable!" + fi + if test lib = "$linkmode" && + test yes = "$hardcode_into_libs"; then + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) func_append compile_rpath " $absdir" ;; + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + ;; + esac + fi + + if test -n "$old_archive_from_expsyms_cmds"; then + # figure out the soname + set dummy $library_names + shift + realname=$1 + shift + libname=`eval "\\$ECHO \"$libname_spec\""` + # use dlname if we got it. it's perfectly good, no? + if test -n "$dlname"; then + soname=$dlname + elif test -n "$soname_spec"; then + # bleh windows + case $host in + *cygwin* | mingw* | *cegcc* | *os2*) + func_arith $current - $age + major=$func_arith_result + versuffix=-$major + ;; + esac + eval soname=\"$soname_spec\" + else + soname=$realname + fi + + # Make a new name for the extract_expsyms_cmds to use + soroot=$soname + func_basename "$soroot" + soname=$func_basename_result + func_stripname 'lib' '.dll' "$soname" + newlib=libimp-$func_stripname_result.a + + # If the library has no export list, then create one now + if test -f "$output_objdir/$soname-def"; then : + else + func_verbose "extracting exported symbol list from '$soname'" + func_execute_cmds "$extract_expsyms_cmds" 'exit $?' + fi + + # Create $newlib + if test -f "$output_objdir/$newlib"; then :; else + func_verbose "generating import library for '$soname'" + func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?' + fi + # make sure the library variables are pointing to the new library + dir=$output_objdir + linklib=$newlib + fi # test -n "$old_archive_from_expsyms_cmds" + + if test prog = "$linkmode" || test relink != "$opt_mode"; then + add_shlibpath= + add_dir= + add= + lib_linked=yes + case $hardcode_action in + immediate | unsupported) + if test no = "$hardcode_direct"; then + add=$dir/$linklib + case $host in + *-*-sco3.2v5.0.[024]*) add_dir=-L$dir ;; + *-*-sysv4*uw2*) add_dir=-L$dir ;; + *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ + *-*-unixware7*) add_dir=-L$dir ;; + *-*-darwin* ) + # if the lib is a (non-dlopened) module then we cannot + # link against it, someone is ignoring the earlier warnings + if /usr/bin/file -L $add 2> /dev/null | + $GREP ": [^:]* bundle" >/dev/null; then + if test "X$dlopenmodule" != "X$lib"; then + $ECHO "*** Warning: lib $linklib is a module, not a shared library" + if test -z "$old_library"; then + echo + echo "*** And there doesn't seem to be a static archive available" + echo "*** The link will probably fail, sorry" + else + add=$dir/$old_library + fi + elif test -n "$old_library"; then + add=$dir/$old_library + fi + fi + esac + elif test no = "$hardcode_minus_L"; then + case $host in + *-*-sunos*) add_shlibpath=$dir ;; + esac + add_dir=-L$dir + add=-l$name + elif test no = "$hardcode_shlibpath_var"; then + add_shlibpath=$dir + add=-l$name + else + lib_linked=no + fi + ;; + relink) + if test yes = "$hardcode_direct" && + test no = "$hardcode_direct_absolute"; then + add=$dir/$linklib + elif test yes = "$hardcode_minus_L"; then + add_dir=-L$absdir + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case $libdir in + [\\/]*) + func_append add_dir " -L$inst_prefix_dir$libdir" + ;; + esac + fi + add=-l$name + elif test yes = "$hardcode_shlibpath_var"; then + add_shlibpath=$dir + add=-l$name + else + lib_linked=no + fi + ;; + *) lib_linked=no ;; + esac + + if test yes != "$lib_linked"; then + func_fatal_configuration "unsupported hardcode properties" + fi + + if test -n "$add_shlibpath"; then + case :$compile_shlibpath: in + *":$add_shlibpath:"*) ;; + *) func_append compile_shlibpath "$add_shlibpath:" ;; + esac + fi + if test prog = "$linkmode"; then + test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" + test -n "$add" && compile_deplibs="$add $compile_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + if test yes != "$hardcode_direct" && + test yes != "$hardcode_minus_L" && + test yes = "$hardcode_shlibpath_var"; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) func_append finalize_shlibpath "$libdir:" ;; + esac + fi + fi + fi + + if test prog = "$linkmode" || test relink = "$opt_mode"; then + add_shlibpath= + add_dir= + add= + # Finalize command for both is simple: just hardcode it. + if test yes = "$hardcode_direct" && + test no = "$hardcode_direct_absolute"; then + add=$libdir/$linklib + elif test yes = "$hardcode_minus_L"; then + add_dir=-L$libdir + add=-l$name + elif test yes = "$hardcode_shlibpath_var"; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) func_append finalize_shlibpath "$libdir:" ;; + esac + add=-l$name + elif test yes = "$hardcode_automatic"; then + if test -n "$inst_prefix_dir" && + test -f "$inst_prefix_dir$libdir/$linklib"; then + add=$inst_prefix_dir$libdir/$linklib + else + add=$libdir/$linklib + fi + else + # We cannot seem to hardcode it, guess we'll fake it. + add_dir=-L$libdir + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case $libdir in + [\\/]*) + func_append add_dir " -L$inst_prefix_dir$libdir" + ;; + esac + fi + add=-l$name + fi + + if test prog = "$linkmode"; then + test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" + test -n "$add" && finalize_deplibs="$add $finalize_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + fi + fi + elif test prog = "$linkmode"; then + # Here we assume that one of hardcode_direct or hardcode_minus_L + # is not unsupported. This is valid on all known static and + # shared platforms. + if test unsupported != "$hardcode_direct"; then + test -n "$old_library" && linklib=$old_library + compile_deplibs="$dir/$linklib $compile_deplibs" + finalize_deplibs="$dir/$linklib $finalize_deplibs" + else + compile_deplibs="-l$name -L$dir $compile_deplibs" + finalize_deplibs="-l$name -L$dir $finalize_deplibs" + fi + elif test yes = "$build_libtool_libs"; then + # Not a shared library + if test pass_all != "$deplibs_check_method"; then + # We're trying link a shared library against a static one + # but the system doesn't support it. + + # Just print a warning and add the library to dependency_libs so + # that the program can be linked against the static library. + echo + $ECHO "*** Warning: This system cannot link to static lib archive $lib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have." + if test yes = "$module"; then + echo "*** But as you try to build a module library, libtool will still create " + echo "*** a static module, that should work as long as the dlopening application" + echo "*** is linked with the -dlopen flag to resolve symbols at runtime." + if test -z "$global_symbol_pipe"; then + echo + echo "*** However, this would only work if libtool was able to extract symbol" + echo "*** lists from a program, using 'nm' or equivalent, but libtool could" + echo "*** not find such a program. So, this module is probably useless." + echo "*** 'nm' from GNU binutils and a full rebuild may help." + fi + if test no = "$build_old_libs"; then + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + else + deplibs="$dir/$old_library $deplibs" + link_static=yes + fi + fi # link shared/static library? + + if test lib = "$linkmode"; then + if test -n "$dependency_libs" && + { test yes != "$hardcode_into_libs" || + test yes = "$build_old_libs" || + test yes = "$link_static"; }; then + # Extract -R from dependency_libs + temp_deplibs= + for libdir in $dependency_libs; do + case $libdir in + -R*) func_stripname '-R' '' "$libdir" + temp_xrpath=$func_stripname_result + case " $xrpath " in + *" $temp_xrpath "*) ;; + *) func_append xrpath " $temp_xrpath";; + esac;; + *) func_append temp_deplibs " $libdir";; + esac + done + dependency_libs=$temp_deplibs + fi + + func_append newlib_search_path " $absdir" + # Link against this library + test no = "$link_static" && newdependency_libs="$abs_ladir/$laname $newdependency_libs" + # ... and its dependency_libs + tmp_libs= + for deplib in $dependency_libs; do + newdependency_libs="$deplib $newdependency_libs" + case $deplib in + -L*) func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result";; + *) func_resolve_sysroot "$deplib" ;; + esac + if $opt_preserve_dup_deps; then + case "$tmp_libs " in + *" $func_resolve_sysroot_result "*) + func_append specialdeplibs " $func_resolve_sysroot_result" ;; + esac + fi + func_append tmp_libs " $func_resolve_sysroot_result" + done + + if test no != "$link_all_deplibs"; then + # Add the search paths of all dependency libraries + for deplib in $dependency_libs; do + path= + case $deplib in + -L*) path=$deplib ;; + *.la) + func_resolve_sysroot "$deplib" + deplib=$func_resolve_sysroot_result + func_dirname "$deplib" "" "." + dir=$func_dirname_result + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) absdir=$dir ;; + *) + absdir=`cd "$dir" && pwd` + if test -z "$absdir"; then + func_warning "cannot determine absolute directory name of '$dir'" + absdir=$dir + fi + ;; + esac + if $GREP "^installed=no" $deplib > /dev/null; then + case $host in + *-*-darwin*) + depdepl= + eval deplibrary_names=`$SED -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` + if test -n "$deplibrary_names"; then + for tmp in $deplibrary_names; do + depdepl=$tmp + done + if test -f "$absdir/$objdir/$depdepl"; then + depdepl=$absdir/$objdir/$depdepl + darwin_install_name=`$OTOOL -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` + if test -z "$darwin_install_name"; then + darwin_install_name=`$OTOOL64 -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` + fi + func_append compiler_flags " $wl-dylib_file $wl$darwin_install_name:$depdepl" + func_append linker_flags " -dylib_file $darwin_install_name:$depdepl" + path= + fi + fi + ;; + *) + path=-L$absdir/$objdir + ;; + esac + else + eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + test -z "$libdir" && \ + func_fatal_error "'$deplib' is not a valid libtool archive" + test "$absdir" != "$libdir" && \ + func_warning "'$deplib' seems to be moved" + + path=-L$absdir + fi + ;; + esac + case " $deplibs " in + *" $path "*) ;; + *) deplibs="$path $deplibs" ;; + esac + done + fi # link_all_deplibs != no + fi # linkmode = lib + done # for deplib in $libs + if test link = "$pass"; then + if test prog = "$linkmode"; then + compile_deplibs="$new_inherited_linker_flags $compile_deplibs" + finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs" + else + compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + fi + fi + dependency_libs=$newdependency_libs + if test dlpreopen = "$pass"; then + # Link the dlpreopened libraries before other libraries + for deplib in $save_deplibs; do + deplibs="$deplib $deplibs" + done + fi + if test dlopen != "$pass"; then + test conv = "$pass" || { + # Make sure lib_search_path contains only unique directories. + lib_search_path= + for dir in $newlib_search_path; do + case "$lib_search_path " in + *" $dir "*) ;; + *) func_append lib_search_path " $dir" ;; + esac + done + newlib_search_path= + } + + if test prog,link = "$linkmode,$pass"; then + vars="compile_deplibs finalize_deplibs" + else + vars=deplibs + fi + for var in $vars dependency_libs; do + # Add libraries to $var in reverse order + eval tmp_libs=\"\$$var\" + new_libs= + for deplib in $tmp_libs; do + # FIXME: Pedantically, this is the right thing to do, so + # that some nasty dependency loop isn't accidentally + # broken: + #new_libs="$deplib $new_libs" + # Pragmatically, this seems to cause very few problems in + # practice: + case $deplib in + -L*) new_libs="$deplib $new_libs" ;; + -R*) ;; + *) + # And here is the reason: when a library appears more + # than once as an explicit dependence of a library, or + # is implicitly linked in more than once by the + # compiler, it is considered special, and multiple + # occurrences thereof are not removed. Compare this + # with having the same library being listed as a + # dependency of multiple other libraries: in this case, + # we know (pedantically, we assume) the library does not + # need to be listed more than once, so we keep only the + # last copy. This is not always right, but it is rare + # enough that we require users that really mean to play + # such unportable linking tricks to link the library + # using -Wl,-lname, so that libtool does not consider it + # for duplicate removal. + case " $specialdeplibs " in + *" $deplib "*) new_libs="$deplib $new_libs" ;; + *) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$deplib $new_libs" ;; + esac + ;; + esac + ;; + esac + done + tmp_libs= + for deplib in $new_libs; do + case $deplib in + -L*) + case " $tmp_libs " in + *" $deplib "*) ;; + *) func_append tmp_libs " $deplib" ;; + esac + ;; + *) func_append tmp_libs " $deplib" ;; + esac + done + eval $var=\"$tmp_libs\" + done # for var + fi + + # Add Sun CC postdeps if required: + test CXX = "$tagname" && { + case $host_os in + linux*) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C++ 5.9 + func_suncc_cstd_abi + + if test no != "$suncc_use_cstd_abi"; then + func_append postdeps ' -library=Cstd -library=Crun' + fi + ;; + esac + ;; + + solaris*) + func_cc_basename "$CC" + case $func_cc_basename_result in + CC* | sunCC*) + func_suncc_cstd_abi + + if test no != "$suncc_use_cstd_abi"; then + func_append postdeps ' -library=Cstd -library=Crun' + fi + ;; + esac + ;; + esac + } + + # Last step: remove runtime libs from dependency_libs + # (they stay in deplibs) + tmp_libs= + for i in $dependency_libs; do + case " $predeps $postdeps $compiler_lib_search_path " in + *" $i "*) + i= + ;; + esac + if test -n "$i"; then + func_append tmp_libs " $i" + fi + done + dependency_libs=$tmp_libs + done # for pass + if test prog = "$linkmode"; then + dlfiles=$newdlfiles + fi + if test prog = "$linkmode" || test lib = "$linkmode"; then + dlprefiles=$newdlprefiles + fi + + case $linkmode in + oldlib) + if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then + func_warning "'-dlopen' is ignored for archives" + fi + + case " $deplibs" in + *\ -l* | *\ -L*) + func_warning "'-l' and '-L' are ignored for archives" ;; + esac + + test -n "$rpath" && \ + func_warning "'-rpath' is ignored for archives" + + test -n "$xrpath" && \ + func_warning "'-R' is ignored for archives" + + test -n "$vinfo" && \ + func_warning "'-version-info/-version-number' is ignored for archives" + + test -n "$release" && \ + func_warning "'-release' is ignored for archives" + + test -n "$export_symbols$export_symbols_regex" && \ + func_warning "'-export-symbols' is ignored for archives" + + # Now set the variables for building old libraries. + build_libtool_libs=no + oldlibs=$output + func_append objs "$old_deplibs" + ;; + + lib) + # Make sure we only generate libraries of the form 'libNAME.la'. + case $outputname in + lib*) + func_stripname 'lib' '.la' "$outputname" + name=$func_stripname_result + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + ;; + *) + test no = "$module" \ + && func_fatal_help "libtool library '$output' must begin with 'lib'" + + if test no != "$need_lib_prefix"; then + # Add the "lib" prefix for modules if required + func_stripname '' '.la' "$outputname" + name=$func_stripname_result + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + else + func_stripname '' '.la' "$outputname" + libname=$func_stripname_result + fi + ;; + esac + + if test -n "$objs"; then + if test pass_all != "$deplibs_check_method"; then + func_fatal_error "cannot build libtool library '$output' from non-libtool objects on this host:$objs" + else + echo + $ECHO "*** Warning: Linking the shared library $output against the non-libtool" + $ECHO "*** objects $objs is not portable!" + func_append libobjs " $objs" + fi + fi + + test no = "$dlself" \ + || func_warning "'-dlopen self' is ignored for libtool libraries" + + set dummy $rpath + shift + test 1 -lt "$#" \ + && func_warning "ignoring multiple '-rpath's for a libtool library" + + install_libdir=$1 + + oldlibs= + if test -z "$rpath"; then + if test yes = "$build_libtool_libs"; then + # Building a libtool convenience library. + # Some compilers have problems with a '.al' extension so + # convenience libraries should have the same extension an + # archive normally would. + oldlibs="$output_objdir/$libname.$libext $oldlibs" + build_libtool_libs=convenience + build_old_libs=yes + fi + + test -n "$vinfo" && \ + func_warning "'-version-info/-version-number' is ignored for convenience libraries" + + test -n "$release" && \ + func_warning "'-release' is ignored for convenience libraries" + else + + # Parse the version information argument. + save_ifs=$IFS; IFS=: + set dummy $vinfo 0 0 0 + shift + IFS=$save_ifs + + test -n "$7" && \ + func_fatal_help "too many parameters to '-version-info'" + + # convert absolute version numbers to libtool ages + # this retains compatibility with .la files and attempts + # to make the code below a bit more comprehensible + + case $vinfo_number in + yes) + number_major=$1 + number_minor=$2 + number_revision=$3 + # + # There are really only two kinds -- those that + # use the current revision as the major version + # and those that subtract age and use age as + # a minor version. But, then there is irix + # that has an extra 1 added just for fun + # + case $version_type in + # correct linux to gnu/linux during the next big refactor + darwin|freebsd-elf|linux|osf|windows|none) + func_arith $number_major + $number_minor + current=$func_arith_result + age=$number_minor + revision=$number_revision + ;; + freebsd-aout|qnx|sunos) + current=$number_major + revision=$number_minor + age=0 + ;; + irix|nonstopux) + func_arith $number_major + $number_minor + current=$func_arith_result + age=$number_minor + revision=$number_minor + lt_irix_increment=no + ;; + esac + ;; + no) + current=$1 + revision=$2 + age=$3 + ;; + esac + + # Check that each of the things are valid numbers. + case $current in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "CURRENT '$current' must be a nonnegative integer" + func_fatal_error "'$vinfo' is not valid version information" + ;; + esac + + case $revision in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "REVISION '$revision' must be a nonnegative integer" + func_fatal_error "'$vinfo' is not valid version information" + ;; + esac + + case $age in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "AGE '$age' must be a nonnegative integer" + func_fatal_error "'$vinfo' is not valid version information" + ;; + esac + + if test "$age" -gt "$current"; then + func_error "AGE '$age' is greater than the current interface number '$current'" + func_fatal_error "'$vinfo' is not valid version information" + fi + + # Calculate the version variables. + major= + versuffix= + verstring= + case $version_type in + none) ;; + + darwin) + # Like Linux, but with the current version available in + # verstring for coding it into the library header + func_arith $current - $age + major=.$func_arith_result + versuffix=$major.$age.$revision + # Darwin ld doesn't like 0 for these options... + func_arith $current + 1 + minor_current=$func_arith_result + xlcverstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision" + verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" + # On Darwin other compilers + case $CC in + nagfor*) + verstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision" + ;; + *) + verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" + ;; + esac + ;; + + freebsd-aout) + major=.$current + versuffix=.$current.$revision + ;; + + freebsd-elf) + func_arith $current - $age + major=.$func_arith_result + versuffix=$major.$age.$revision + ;; + + irix | nonstopux) + if test no = "$lt_irix_increment"; then + func_arith $current - $age + else + func_arith $current - $age + 1 + fi + major=$func_arith_result + + case $version_type in + nonstopux) verstring_prefix=nonstopux ;; + *) verstring_prefix=sgi ;; + esac + verstring=$verstring_prefix$major.$revision + + # Add in all the interfaces that we are compatible with. + loop=$revision + while test 0 -ne "$loop"; do + func_arith $revision - $loop + iface=$func_arith_result + func_arith $loop - 1 + loop=$func_arith_result + verstring=$verstring_prefix$major.$iface:$verstring + done + + # Before this point, $major must not contain '.'. + major=.$major + versuffix=$major.$revision + ;; + + linux) # correct to gnu/linux during the next big refactor + func_arith $current - $age + major=.$func_arith_result + versuffix=$major.$age.$revision + ;; + + osf) + func_arith $current - $age + major=.$func_arith_result + versuffix=.$current.$age.$revision + verstring=$current.$age.$revision + + # Add in all the interfaces that we are compatible with. + loop=$age + while test 0 -ne "$loop"; do + func_arith $current - $loop + iface=$func_arith_result + func_arith $loop - 1 + loop=$func_arith_result + verstring=$verstring:$iface.0 + done + + # Make executables depend on our current version. + func_append verstring ":$current.0" + ;; + + qnx) + major=.$current + versuffix=.$current + ;; + + sco) + major=.$current + versuffix=.$current + ;; + + sunos) + major=.$current + versuffix=.$current.$revision + ;; + + windows) + # Use '-' rather than '.', since we only want one + # extension on DOS 8.3 file systems. + func_arith $current - $age + major=$func_arith_result + versuffix=-$major + ;; + + *) + func_fatal_configuration "unknown library version type '$version_type'" + ;; + esac + + # Clear the version info if we defaulted, and they specified a release. + if test -z "$vinfo" && test -n "$release"; then + major= + case $version_type in + darwin) + # we can't check for "0.0" in archive_cmds due to quoting + # problems, so we reset it completely + verstring= + ;; + *) + verstring=0.0 + ;; + esac + if test no = "$need_version"; then + versuffix= + else + versuffix=.0.0 + fi + fi + + # Remove version info from name if versioning should be avoided + if test yes,no = "$avoid_version,$need_version"; then + major= + versuffix= + verstring= + fi + + # Check to see if the archive will have undefined symbols. + if test yes = "$allow_undefined"; then + if test unsupported = "$allow_undefined_flag"; then + if test yes = "$build_old_libs"; then + func_warning "undefined symbols not allowed in $host shared libraries; building static only" + build_libtool_libs=no + else + func_fatal_error "can't build $host shared library unless -no-undefined is specified" + fi + fi + else + # Don't allow undefined symbols. + allow_undefined_flag=$no_undefined_flag + fi + + fi + + func_generate_dlsyms "$libname" "$libname" : + func_append libobjs " $symfileobj" + test " " = "$libobjs" && libobjs= + + if test relink != "$opt_mode"; then + # Remove our outputs, but don't remove object files since they + # may have been created when compiling PIC objects. + removelist= + tempremovelist=`$ECHO "$output_objdir/*"` + for p in $tempremovelist; do + case $p in + *.$objext | *.gcno) + ;; + $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/$libname$release.*) + if test -n "$precious_files_regex"; then + if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 + then + continue + fi + fi + func_append removelist " $p" + ;; + *) ;; + esac + done + test -n "$removelist" && \ + func_show_eval "${RM}r \$removelist" + fi + + # Now set the variables for building old libraries. + if test yes = "$build_old_libs" && test convenience != "$build_libtool_libs"; then + func_append oldlibs " $output_objdir/$libname.$libext" + + # Transform .lo files to .o files. + oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; $lo2o" | $NL2SP` + fi + + # Eliminate all temporary directories. + #for path in $notinst_path; do + # lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"` + # deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"` + # dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"` + #done + + if test -n "$xrpath"; then + # If the user specified any rpath flags, then add them. + temp_xrpath= + for libdir in $xrpath; do + func_replace_sysroot "$libdir" + func_append temp_xrpath " -R$func_replace_sysroot_result" + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + done + if test yes != "$hardcode_into_libs" || test yes = "$build_old_libs"; then + dependency_libs="$temp_xrpath $dependency_libs" + fi + fi + + # Make sure dlfiles contains only unique files that won't be dlpreopened + old_dlfiles=$dlfiles + dlfiles= + for lib in $old_dlfiles; do + case " $dlprefiles $dlfiles " in + *" $lib "*) ;; + *) func_append dlfiles " $lib" ;; + esac + done + + # Make sure dlprefiles contains only unique files + old_dlprefiles=$dlprefiles + dlprefiles= + for lib in $old_dlprefiles; do + case "$dlprefiles " in + *" $lib "*) ;; + *) func_append dlprefiles " $lib" ;; + esac + done + + if test yes = "$build_libtool_libs"; then + if test -n "$rpath"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*) + # these systems don't actually have a c library (as such)! + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C library is in the System framework + func_append deplibs " System.ltframework" + ;; + *-*-netbsd*) + # Don't link with libc until the a.out ld.so is fixed. + ;; + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc due to us having libc/libc_r. + ;; + *-*-sco3.2v5* | *-*-sco5v6*) + # Causes problems with __ctype + ;; + *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) + # Compiler inserts libc in the correct place for threads to work + ;; + *) + # Add libc to deplibs on all other systems if necessary. + if test yes = "$build_libtool_need_lc"; then + func_append deplibs " -lc" + fi + ;; + esac + fi + + # Transform deplibs into only deplibs that can be linked in shared. + name_save=$name + libname_save=$libname + release_save=$release + versuffix_save=$versuffix + major_save=$major + # I'm not sure if I'm treating the release correctly. I think + # release should show up in the -l (ie -lgmp5) so we don't want to + # add it in twice. Is that correct? + release= + versuffix= + major= + newdeplibs= + droppeddeps=no + case $deplibs_check_method in + pass_all) + # Don't check for shared/static. Everything works. + # This might be a little naive. We might want to check + # whether the library exists or not. But this is on + # osf3 & osf4 and I'm not really sure... Just + # implementing what was already the behavior. + newdeplibs=$deplibs + ;; + test_compile) + # This code stresses the "libraries are programs" paradigm to its + # limits. Maybe even breaks it. We compile a program, linking it + # against the deplibs as a proxy for the library. Then we can check + # whether they linked in statically or dynamically with ldd. + $opt_dry_run || $RM conftest.c + cat > conftest.c <<EOF + int main() { return 0; } +EOF + $opt_dry_run || $RM conftest + if $LTCC $LTCFLAGS -o conftest conftest.c $deplibs; then + ldd_output=`ldd conftest` + for i in $deplibs; do + case $i in + -l*) + func_stripname -l '' "$i" + name=$func_stripname_result + if test yes = "$allow_libtool_libs_with_static_runtimes"; then + case " $predeps $postdeps " in + *" $i "*) + func_append newdeplibs " $i" + i= + ;; + esac + fi + if test -n "$i"; then + libname=`eval "\\$ECHO \"$libname_spec\""` + deplib_matches=`eval "\\$ECHO \"$library_names_spec\""` + set dummy $deplib_matches; shift + deplib_match=$1 + if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0; then + func_append newdeplibs " $i" + else + droppeddeps=yes + echo + $ECHO "*** Warning: dynamic linker does not accept needed library $i." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which I believe you do not have" + echo "*** because a test_compile did reveal that the linker did not use it for" + echo "*** its dynamic dependency list that programs get resolved with at runtime." + fi + fi + ;; + *) + func_append newdeplibs " $i" + ;; + esac + done + else + # Error occurred in the first compile. Let's try to salvage + # the situation: Compile a separate program for each library. + for i in $deplibs; do + case $i in + -l*) + func_stripname -l '' "$i" + name=$func_stripname_result + $opt_dry_run || $RM conftest + if $LTCC $LTCFLAGS -o conftest conftest.c $i; then + ldd_output=`ldd conftest` + if test yes = "$allow_libtool_libs_with_static_runtimes"; then + case " $predeps $postdeps " in + *" $i "*) + func_append newdeplibs " $i" + i= + ;; + esac + fi + if test -n "$i"; then + libname=`eval "\\$ECHO \"$libname_spec\""` + deplib_matches=`eval "\\$ECHO \"$library_names_spec\""` + set dummy $deplib_matches; shift + deplib_match=$1 + if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0; then + func_append newdeplibs " $i" + else + droppeddeps=yes + echo + $ECHO "*** Warning: dynamic linker does not accept needed library $i." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because a test_compile did reveal that the linker did not use this one" + echo "*** as a dynamic dependency that programs can get resolved with at runtime." + fi + fi + else + droppeddeps=yes + echo + $ECHO "*** Warning! Library $i is needed by this library but I was not able to" + echo "*** make it link in! You will probably need to install it or some" + echo "*** library that it depends on before this library will be fully" + echo "*** functional. Installing it before continuing would be even better." + fi + ;; + *) + func_append newdeplibs " $i" + ;; + esac + done + fi + ;; + file_magic*) + set dummy $deplibs_check_method; shift + file_magic_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` + for a_deplib in $deplibs; do + case $a_deplib in + -l*) + func_stripname -l '' "$a_deplib" + name=$func_stripname_result + if test yes = "$allow_libtool_libs_with_static_runtimes"; then + case " $predeps $postdeps " in + *" $a_deplib "*) + func_append newdeplibs " $a_deplib" + a_deplib= + ;; + esac + fi + if test -n "$a_deplib"; then + libname=`eval "\\$ECHO \"$libname_spec\""` + if test -n "$file_magic_glob"; then + libnameglob=`func_echo_all "$libname" | $SED -e $file_magic_glob` + else + libnameglob=$libname + fi + test yes = "$want_nocaseglob" && nocaseglob=`shopt -p nocaseglob` + for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do + if test yes = "$want_nocaseglob"; then + shopt -s nocaseglob + potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null` + $nocaseglob + else + potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null` + fi + for potent_lib in $potential_libs; do + # Follow soft links. + if ls -lLd "$potent_lib" 2>/dev/null | + $GREP " -> " >/dev/null; then + continue + fi + # The statement above tries to avoid entering an + # endless loop below, in case of cyclic links. + # We might still enter an endless loop, since a link + # loop can be closed while we follow links, + # but so what? + potlib=$potent_lib + while test -h "$potlib" 2>/dev/null; do + potliblink=`ls -ld $potlib | $SED 's/.* -> //'` + case $potliblink in + [\\/]* | [A-Za-z]:[\\/]*) potlib=$potliblink;; + *) potlib=`$ECHO "$potlib" | $SED 's|[^/]*$||'`"$potliblink";; + esac + done + if eval $file_magic_cmd \"\$potlib\" 2>/dev/null | + $SED -e 10q | + $EGREP "$file_magic_regex" > /dev/null; then + func_append newdeplibs " $a_deplib" + a_deplib= + break 2 + fi + done + done + fi + if test -n "$a_deplib"; then + droppeddeps=yes + echo + $ECHO "*** Warning: linker path does not have real file for library $a_deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib"; then + $ECHO "*** with $libname but no candidates were found. (...for file magic test)" + else + $ECHO "*** with $libname and none of the candidates passed a file format test" + $ECHO "*** using a file magic. Last file checked: $potlib" + fi + fi + ;; + *) + # Add a -L argument. + func_append newdeplibs " $a_deplib" + ;; + esac + done # Gone through all deplibs. + ;; + match_pattern*) + set dummy $deplibs_check_method; shift + match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` + for a_deplib in $deplibs; do + case $a_deplib in + -l*) + func_stripname -l '' "$a_deplib" + name=$func_stripname_result + if test yes = "$allow_libtool_libs_with_static_runtimes"; then + case " $predeps $postdeps " in + *" $a_deplib "*) + func_append newdeplibs " $a_deplib" + a_deplib= + ;; + esac + fi + if test -n "$a_deplib"; then + libname=`eval "\\$ECHO \"$libname_spec\""` + for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do + potential_libs=`ls $i/$libname[.-]* 2>/dev/null` + for potent_lib in $potential_libs; do + potlib=$potent_lib # see symlink-check above in file_magic test + if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \ + $EGREP "$match_pattern_regex" > /dev/null; then + func_append newdeplibs " $a_deplib" + a_deplib= + break 2 + fi + done + done + fi + if test -n "$a_deplib"; then + droppeddeps=yes + echo + $ECHO "*** Warning: linker path does not have real file for library $a_deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib"; then + $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)" + else + $ECHO "*** with $libname and none of the candidates passed a file format test" + $ECHO "*** using a regex pattern. Last file checked: $potlib" + fi + fi + ;; + *) + # Add a -L argument. + func_append newdeplibs " $a_deplib" + ;; + esac + done # Gone through all deplibs. + ;; + none | unknown | *) + newdeplibs= + tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'` + if test yes = "$allow_libtool_libs_with_static_runtimes"; then + for i in $predeps $postdeps; do + # can't use Xsed below, because $i might contain '/' + tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s|$i||"` + done + fi + case $tmp_deplibs in + *[!\ \ ]*) + echo + if test none = "$deplibs_check_method"; then + echo "*** Warning: inter-library dependencies are not supported in this platform." + else + echo "*** Warning: inter-library dependencies are not known to be supported." + fi + echo "*** All declared inter-library dependencies are being dropped." + droppeddeps=yes + ;; + esac + ;; + esac + versuffix=$versuffix_save + major=$major_save + release=$release_save + libname=$libname_save + name=$name_save + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library with the System framework + newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'` + ;; + esac + + if test yes = "$droppeddeps"; then + if test yes = "$module"; then + echo + echo "*** Warning: libtool could not satisfy all declared inter-library" + $ECHO "*** dependencies of module $libname. Therefore, libtool will create" + echo "*** a static module, that should work as long as the dlopening" + echo "*** application is linked with the -dlopen flag." + if test -z "$global_symbol_pipe"; then + echo + echo "*** However, this would only work if libtool was able to extract symbol" + echo "*** lists from a program, using 'nm' or equivalent, but libtool could" + echo "*** not find such a program. So, this module is probably useless." + echo "*** 'nm' from GNU binutils and a full rebuild may help." + fi + if test no = "$build_old_libs"; then + oldlibs=$output_objdir/$libname.$libext + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + else + echo "*** The inter-library dependencies that have been dropped here will be" + echo "*** automatically added whenever a program is linked with this library" + echo "*** or is declared to -dlopen it." + + if test no = "$allow_undefined"; then + echo + echo "*** Since this library must not contain undefined symbols," + echo "*** because either the platform does not support them or" + echo "*** it was explicitly requested with -no-undefined," + echo "*** libtool will only create a static version of it." + if test no = "$build_old_libs"; then + oldlibs=$output_objdir/$libname.$libext + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + fi + fi + # Done checking deplibs! + deplibs=$newdeplibs + fi + # Time to change all our "foo.ltframework" stuff back to "-framework foo" + case $host in + *-*-darwin*) + newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + ;; + esac + + # move library search paths that coincide with paths to not yet + # installed libraries to the beginning of the library search list + new_libs= + for path in $notinst_path; do + case " $new_libs " in + *" -L$path/$objdir "*) ;; + *) + case " $deplibs " in + *" -L$path/$objdir "*) + func_append new_libs " -L$path/$objdir" ;; + esac + ;; + esac + done + for deplib in $deplibs; do + case $deplib in + -L*) + case " $new_libs " in + *" $deplib "*) ;; + *) func_append new_libs " $deplib" ;; + esac + ;; + *) func_append new_libs " $deplib" ;; + esac + done + deplibs=$new_libs + + # All the library-specific variables (install_libdir is set above). + library_names= + old_library= + dlname= + + # Test again, we may have decided not to build it any more + if test yes = "$build_libtool_libs"; then + # Remove $wl instances when linking with ld. + # FIXME: should test the right _cmds variable. + case $archive_cmds in + *\$LD\ *) wl= ;; + esac + if test yes = "$hardcode_into_libs"; then + # Hardcode the library paths + hardcode_libdirs= + dep_rpath= + rpath=$finalize_rpath + test relink = "$opt_mode" || rpath=$compile_rpath$rpath + for libdir in $rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + func_replace_sysroot "$libdir" + libdir=$func_replace_sysroot_result + if test -z "$hardcode_libdirs"; then + hardcode_libdirs=$libdir + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + func_append dep_rpath " $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) func_append perm_rpath " $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir=$hardcode_libdirs + eval "dep_rpath=\"$hardcode_libdir_flag_spec\"" + fi + if test -n "$runpath_var" && test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + func_append rpath "$dir:" + done + eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" + fi + test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" + fi + + shlibpath=$finalize_shlibpath + test relink = "$opt_mode" || shlibpath=$compile_shlibpath$shlibpath + if test -n "$shlibpath"; then + eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" + fi + + # Get the real and link names of the library. + eval shared_ext=\"$shrext_cmds\" + eval library_names=\"$library_names_spec\" + set dummy $library_names + shift + realname=$1 + shift + + if test -n "$soname_spec"; then + eval soname=\"$soname_spec\" + else + soname=$realname + fi + if test -z "$dlname"; then + dlname=$soname + fi + + lib=$output_objdir/$realname + linknames= + for link + do + func_append linknames " $link" + done + + # Use standard objects if they are pic + test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP` + test "X$libobjs" = "X " && libobjs= + + delfiles= + if test -n "$export_symbols" && test -n "$include_expsyms"; then + $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp" + export_symbols=$output_objdir/$libname.uexp + func_append delfiles " $export_symbols" + fi + + orig_export_symbols= + case $host_os in + cygwin* | mingw* | cegcc*) + if test -n "$export_symbols" && test -z "$export_symbols_regex"; then + # exporting using user supplied symfile + func_dll_def_p "$export_symbols" || { + # and it's NOT already a .def file. Must figure out + # which of the given symbols are data symbols and tag + # them as such. So, trigger use of export_symbols_cmds. + # export_symbols gets reassigned inside the "prepare + # the list of exported symbols" if statement, so the + # include_expsyms logic still works. + orig_export_symbols=$export_symbols + export_symbols= + always_export_symbols=yes + } + fi + ;; + esac + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + if test yes = "$always_export_symbols" || test -n "$export_symbols_regex"; then + func_verbose "generating symbol list for '$libname.la'" + export_symbols=$output_objdir/$libname.exp + $opt_dry_run || $RM $export_symbols + cmds=$export_symbols_cmds + save_ifs=$IFS; IFS='~' + for cmd1 in $cmds; do + IFS=$save_ifs + # Take the normal branch if the nm_file_list_spec branch + # doesn't work or if tool conversion is not needed. + case $nm_file_list_spec~$to_tool_file_cmd in + *~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*) + try_normal_branch=yes + eval cmd=\"$cmd1\" + func_len " $cmd" + len=$func_len_result + ;; + *) + try_normal_branch=no + ;; + esac + if test yes = "$try_normal_branch" \ + && { test "$len" -lt "$max_cmd_len" \ + || test "$max_cmd_len" -le -1; } + then + func_show_eval "$cmd" 'exit $?' + skipped_export=false + elif test -n "$nm_file_list_spec"; then + func_basename "$output" + output_la=$func_basename_result + save_libobjs=$libobjs + save_output=$output + output=$output_objdir/$output_la.nm + func_to_tool_file "$output" + libobjs=$nm_file_list_spec$func_to_tool_file_result + func_append delfiles " $output" + func_verbose "creating $NM input file list: $output" + for obj in $save_libobjs; do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" + done > "$output" + eval cmd=\"$cmd1\" + func_show_eval "$cmd" 'exit $?' + output=$save_output + libobjs=$save_libobjs + skipped_export=false + else + # The command line is too long to execute in one step. + func_verbose "using reloadable object file for export list..." + skipped_export=: + # Break out early, otherwise skipped_export may be + # set to false by a later but shorter cmd. + break + fi + done + IFS=$save_ifs + if test -n "$export_symbols_regex" && test : != "$skipped_export"; then + func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + func_show_eval '$MV "${export_symbols}T" "$export_symbols"' + fi + fi + fi + + if test -n "$export_symbols" && test -n "$include_expsyms"; then + tmp_export_symbols=$export_symbols + test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols + $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' + fi + + if test : != "$skipped_export" && test -n "$orig_export_symbols"; then + # The given exports_symbols file has to be filtered, so filter it. + func_verbose "filter symbol list for '$libname.la' to tag DATA exports" + # FIXME: $output_objdir/$libname.filter potentially contains lots of + # 's' commands, which not all seds can handle. GNU sed should be fine + # though. Also, the filter scales superlinearly with the number of + # global variables. join(1) would be nice here, but unfortunately + # isn't a blessed tool. + $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter + func_append delfiles " $export_symbols $output_objdir/$libname.filter" + export_symbols=$output_objdir/$libname.def + $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols + fi + + tmp_deplibs= + for test_deplib in $deplibs; do + case " $convenience " in + *" $test_deplib "*) ;; + *) + func_append tmp_deplibs " $test_deplib" + ;; + esac + done + deplibs=$tmp_deplibs + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec" && + test yes = "$compiler_needs_object" && + test -z "$libobjs"; then + # extract the archives, so we have objects to list. + # TODO: could optimize this to just extract one archive. + whole_archive_flag_spec= + fi + if test -n "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + test "X$libobjs" = "X " && libobjs= + else + gentop=$output_objdir/${outputname}x + func_append generated " $gentop" + + func_extract_archives $gentop $convenience + func_append libobjs " $func_extract_archives_result" + test "X$libobjs" = "X " && libobjs= + fi + fi + + if test yes = "$thread_safe" && test -n "$thread_safe_flag_spec"; then + eval flag=\"$thread_safe_flag_spec\" + func_append linker_flags " $flag" + fi + + # Make a backup of the uninstalled library when relinking + if test relink = "$opt_mode"; then + $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $? + fi + + # Do each of the archive commands. + if test yes = "$module" && test -n "$module_cmds"; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + eval test_cmds=\"$module_expsym_cmds\" + cmds=$module_expsym_cmds + else + eval test_cmds=\"$module_cmds\" + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + eval test_cmds=\"$archive_expsym_cmds\" + cmds=$archive_expsym_cmds + else + eval test_cmds=\"$archive_cmds\" + cmds=$archive_cmds + fi + fi + + if test : != "$skipped_export" && + func_len " $test_cmds" && + len=$func_len_result && + test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then + : + else + # The command line is too long to link in one step, link piecewise + # or, if using GNU ld and skipped_export is not :, use a linker + # script. + + # Save the value of $output and $libobjs because we want to + # use them later. If we have whole_archive_flag_spec, we + # want to use save_libobjs as it was before + # whole_archive_flag_spec was expanded, because we can't + # assume the linker understands whole_archive_flag_spec. + # This may have to be revisited, in case too many + # convenience libraries get linked in and end up exceeding + # the spec. + if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + fi + save_output=$output + func_basename "$output" + output_la=$func_basename_result + + # Clear the reloadable object creation command queue and + # initialize k to one. + test_cmds= + concat_cmds= + objlist= + last_robj= + k=1 + + if test -n "$save_libobjs" && test : != "$skipped_export" && test yes = "$with_gnu_ld"; then + output=$output_objdir/$output_la.lnkscript + func_verbose "creating GNU ld script: $output" + echo 'INPUT (' > $output + for obj in $save_libobjs + do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" >> $output + done + echo ')' >> $output + func_append delfiles " $output" + func_to_tool_file "$output" + output=$func_to_tool_file_result + elif test -n "$save_libobjs" && test : != "$skipped_export" && test -n "$file_list_spec"; then + output=$output_objdir/$output_la.lnk + func_verbose "creating linker input file list: $output" + : > $output + set x $save_libobjs + shift + firstobj= + if test yes = "$compiler_needs_object"; then + firstobj="$1 " + shift + fi + for obj + do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" >> $output + done + func_append delfiles " $output" + func_to_tool_file "$output" + output=$firstobj\"$file_list_spec$func_to_tool_file_result\" + else + if test -n "$save_libobjs"; then + func_verbose "creating reloadable object files..." + output=$output_objdir/$output_la-$k.$objext + eval test_cmds=\"$reload_cmds\" + func_len " $test_cmds" + len0=$func_len_result + len=$len0 + + # Loop over the list of objects to be linked. + for obj in $save_libobjs + do + func_len " $obj" + func_arith $len + $func_len_result + len=$func_arith_result + if test -z "$objlist" || + test "$len" -lt "$max_cmd_len"; then + func_append objlist " $obj" + else + # The command $test_cmds is almost too long, add a + # command to the queue. + if test 1 -eq "$k"; then + # The first file doesn't have a previous command to add. + reload_objs=$objlist + eval concat_cmds=\"$reload_cmds\" + else + # All subsequent reloadable object files will link in + # the last one created. + reload_objs="$objlist $last_robj" + eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\" + fi + last_robj=$output_objdir/$output_la-$k.$objext + func_arith $k + 1 + k=$func_arith_result + output=$output_objdir/$output_la-$k.$objext + objlist=" $obj" + func_len " $last_robj" + func_arith $len0 + $func_len_result + len=$func_arith_result + fi + done + # Handle the remaining objects by creating one last + # reloadable object file. All subsequent reloadable object + # files will link in the last one created. + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + reload_objs="$objlist $last_robj" + eval concat_cmds=\"\$concat_cmds$reload_cmds\" + if test -n "$last_robj"; then + eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" + fi + func_append delfiles " $output" + + else + output= + fi + + ${skipped_export-false} && { + func_verbose "generating symbol list for '$libname.la'" + export_symbols=$output_objdir/$libname.exp + $opt_dry_run || $RM $export_symbols + libobjs=$output + # Append the command to create the export file. + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\" + if test -n "$last_robj"; then + eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" + fi + } + + test -n "$save_libobjs" && + func_verbose "creating a temporary reloadable object file: $output" + + # Loop through the commands generated above and execute them. + save_ifs=$IFS; IFS='~' + for cmd in $concat_cmds; do + IFS=$save_ifs + $opt_quiet || { + func_quote_for_expand "$cmd" + eval "func_echo $func_quote_for_expand_result" + } + $opt_dry_run || eval "$cmd" || { + lt_exit=$? + + # Restore the uninstalled library and exit + if test relink = "$opt_mode"; then + ( cd "$output_objdir" && \ + $RM "${realname}T" && \ + $MV "${realname}U" "$realname" ) + fi + + exit $lt_exit + } + done + IFS=$save_ifs + + if test -n "$export_symbols_regex" && ${skipped_export-false}; then + func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + func_show_eval '$MV "${export_symbols}T" "$export_symbols"' + fi + fi + + ${skipped_export-false} && { + if test -n "$export_symbols" && test -n "$include_expsyms"; then + tmp_export_symbols=$export_symbols + test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols + $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' + fi + + if test -n "$orig_export_symbols"; then + # The given exports_symbols file has to be filtered, so filter it. + func_verbose "filter symbol list for '$libname.la' to tag DATA exports" + # FIXME: $output_objdir/$libname.filter potentially contains lots of + # 's' commands, which not all seds can handle. GNU sed should be fine + # though. Also, the filter scales superlinearly with the number of + # global variables. join(1) would be nice here, but unfortunately + # isn't a blessed tool. + $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter + func_append delfiles " $export_symbols $output_objdir/$libname.filter" + export_symbols=$output_objdir/$libname.def + $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols + fi + } + + libobjs=$output + # Restore the value of output. + output=$save_output + + if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + test "X$libobjs" = "X " && libobjs= + fi + # Expand the library linking commands again to reset the + # value of $libobjs for piecewise linking. + + # Do each of the archive commands. + if test yes = "$module" && test -n "$module_cmds"; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + cmds=$module_expsym_cmds + else + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + cmds=$archive_expsym_cmds + else + cmds=$archive_cmds + fi + fi + fi + + if test -n "$delfiles"; then + # Append the command to remove temporary files to $cmds. + eval cmds=\"\$cmds~\$RM $delfiles\" + fi + + # Add any objects from preloaded convenience libraries + if test -n "$dlprefiles"; then + gentop=$output_objdir/${outputname}x + func_append generated " $gentop" + + func_extract_archives $gentop $dlprefiles + func_append libobjs " $func_extract_archives_result" + test "X$libobjs" = "X " && libobjs= + fi + + save_ifs=$IFS; IFS='~' + for cmd in $cmds; do + IFS=$sp$nl + eval cmd=\"$cmd\" + IFS=$save_ifs + $opt_quiet || { + func_quote_for_expand "$cmd" + eval "func_echo $func_quote_for_expand_result" + } + $opt_dry_run || eval "$cmd" || { + lt_exit=$? + + # Restore the uninstalled library and exit + if test relink = "$opt_mode"; then + ( cd "$output_objdir" && \ + $RM "${realname}T" && \ + $MV "${realname}U" "$realname" ) + fi + + exit $lt_exit + } + done + IFS=$save_ifs + + # Restore the uninstalled library and exit + if test relink = "$opt_mode"; then + $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $? + + if test -n "$convenience"; then + if test -z "$whole_archive_flag_spec"; then + func_show_eval '${RM}r "$gentop"' + fi + fi + + exit $EXIT_SUCCESS + fi + + # Create links to the real library. + for linkname in $linknames; do + if test "$realname" != "$linkname"; then + func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?' + fi + done + + # If -module or -export-dynamic was specified, set the dlname. + if test yes = "$module" || test yes = "$export_dynamic"; then + # On all known operating systems, these are identical. + dlname=$soname + fi + fi + ;; + + obj) + if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then + func_warning "'-dlopen' is ignored for objects" + fi + + case " $deplibs" in + *\ -l* | *\ -L*) + func_warning "'-l' and '-L' are ignored for objects" ;; + esac + + test -n "$rpath" && \ + func_warning "'-rpath' is ignored for objects" + + test -n "$xrpath" && \ + func_warning "'-R' is ignored for objects" + + test -n "$vinfo" && \ + func_warning "'-version-info' is ignored for objects" + + test -n "$release" && \ + func_warning "'-release' is ignored for objects" + + case $output in + *.lo) + test -n "$objs$old_deplibs" && \ + func_fatal_error "cannot build library object '$output' from non-libtool objects" + + libobj=$output + func_lo2o "$libobj" + obj=$func_lo2o_result + ;; + *) + libobj= + obj=$output + ;; + esac + + # Delete the old objects. + $opt_dry_run || $RM $obj $libobj + + # Objects from convenience libraries. This assumes + # single-version convenience libraries. Whenever we create + # different ones for PIC/non-PIC, this we'll have to duplicate + # the extraction. + reload_conv_objs= + gentop= + # if reload_cmds runs $LD directly, get rid of -Wl from + # whole_archive_flag_spec and hope we can get by with turning comma + # into space. + case $reload_cmds in + *\$LD[\ \$]*) wl= ;; + esac + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec"; then + eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" + test -n "$wl" || tmp_whole_archive_flags=`$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'` + reload_conv_objs=$reload_objs\ $tmp_whole_archive_flags + else + gentop=$output_objdir/${obj}x + func_append generated " $gentop" + + func_extract_archives $gentop $convenience + reload_conv_objs="$reload_objs $func_extract_archives_result" + fi + fi + + # If we're not building shared, we need to use non_pic_objs + test yes = "$build_libtool_libs" || libobjs=$non_pic_objects + + # Create the old-style object. + reload_objs=$objs$old_deplibs' '`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; /\.lib$/d; $lo2o" | $NL2SP`' '$reload_conv_objs + + output=$obj + func_execute_cmds "$reload_cmds" 'exit $?' + + # Exit if we aren't doing a library object file. + if test -z "$libobj"; then + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + exit $EXIT_SUCCESS + fi + + test yes = "$build_libtool_libs" || { + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + # Create an invalid libtool object if no PIC, so that we don't + # accidentally link it into a program. + # $show "echo timestamp > $libobj" + # $opt_dry_run || eval "echo timestamp > $libobj" || exit $? + exit $EXIT_SUCCESS + } + + if test -n "$pic_flag" || test default != "$pic_mode"; then + # Only do commands if we really have different PIC objects. + reload_objs="$libobjs $reload_conv_objs" + output=$libobj + func_execute_cmds "$reload_cmds" 'exit $?' + fi + + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + exit $EXIT_SUCCESS + ;; + + prog) + case $host in + *cygwin*) func_stripname '' '.exe' "$output" + output=$func_stripname_result.exe;; + esac + test -n "$vinfo" && \ + func_warning "'-version-info' is ignored for programs" + + test -n "$release" && \ + func_warning "'-release' is ignored for programs" + + $preload \ + && test unknown,unknown,unknown = "$dlopen_support,$dlopen_self,$dlopen_self_static" \ + && func_warning "'LT_INIT([dlopen])' not used. Assuming no dlopen support." + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library is the System framework + compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'` + finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'` + ;; + esac + + case $host in + *-*-darwin*) + # Don't allow lazy linking, it breaks C++ global constructors + # But is supposedly fixed on 10.4 or later (yay!). + if test CXX = "$tagname"; then + case ${MACOSX_DEPLOYMENT_TARGET-10.0} in + 10.[0123]) + func_append compile_command " $wl-bind_at_load" + func_append finalize_command " $wl-bind_at_load" + ;; + esac + fi + # Time to change all our "foo.ltframework" stuff back to "-framework foo" + compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + ;; + esac + + + # move library search paths that coincide with paths to not yet + # installed libraries to the beginning of the library search list + new_libs= + for path in $notinst_path; do + case " $new_libs " in + *" -L$path/$objdir "*) ;; + *) + case " $compile_deplibs " in + *" -L$path/$objdir "*) + func_append new_libs " -L$path/$objdir" ;; + esac + ;; + esac + done + for deplib in $compile_deplibs; do + case $deplib in + -L*) + case " $new_libs " in + *" $deplib "*) ;; + *) func_append new_libs " $deplib" ;; + esac + ;; + *) func_append new_libs " $deplib" ;; + esac + done + compile_deplibs=$new_libs + + + func_append compile_command " $compile_deplibs" + func_append finalize_command " $finalize_deplibs" + + if test -n "$rpath$xrpath"; then + # If the user specified any rpath flags, then add them. + for libdir in $rpath $xrpath; do + # This is the magic to use -rpath. + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + done + fi + + # Now hardcode the library paths + rpath= + hardcode_libdirs= + for libdir in $compile_rpath $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs=$libdir + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + func_append rpath " $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) func_append perm_rpath " $libdir" ;; + esac + fi + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + testbindir=`$ECHO "$libdir" | $SED -e 's*/lib$*/bin*'` + case :$dllsearchpath: in + *":$libdir:"*) ;; + ::) dllsearchpath=$libdir;; + *) func_append dllsearchpath ":$libdir";; + esac + case :$dllsearchpath: in + *":$testbindir:"*) ;; + ::) dllsearchpath=$testbindir;; + *) func_append dllsearchpath ":$testbindir";; + esac + ;; + esac + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir=$hardcode_libdirs + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + compile_rpath=$rpath + + rpath= + hardcode_libdirs= + for libdir in $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs=$libdir + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + func_append rpath " $flag" + fi + elif test -n "$runpath_var"; then + case "$finalize_perm_rpath " in + *" $libdir "*) ;; + *) func_append finalize_perm_rpath " $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir=$hardcode_libdirs + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + finalize_rpath=$rpath + + if test -n "$libobjs" && test yes = "$build_old_libs"; then + # Transform all the library objects into standard objects. + compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP` + finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP` + fi + + func_generate_dlsyms "$outputname" "@PROGRAM@" false + + # template prelinking step + if test -n "$prelink_cmds"; then + func_execute_cmds "$prelink_cmds" 'exit $?' + fi + + wrappers_required=: + case $host in + *cegcc* | *mingw32ce*) + # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway. + wrappers_required=false + ;; + *cygwin* | *mingw* ) + test yes = "$build_libtool_libs" || wrappers_required=false + ;; + *) + if test no = "$need_relink" || test yes != "$build_libtool_libs"; then + wrappers_required=false + fi + ;; + esac + $wrappers_required || { + # Replace the output file specification. + compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'` + link_command=$compile_command$compile_rpath + + # We have no uninstalled library dependencies, so finalize right now. + exit_status=0 + func_show_eval "$link_command" 'exit_status=$?' + + if test -n "$postlink_cmds"; then + func_to_tool_file "$output" + postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` + func_execute_cmds "$postlink_cmds" 'exit $?' + fi + + # Delete the generated files. + if test -f "$output_objdir/${outputname}S.$objext"; then + func_show_eval '$RM "$output_objdir/${outputname}S.$objext"' + fi + + exit $exit_status + } + + if test -n "$compile_shlibpath$finalize_shlibpath"; then + compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" + fi + if test -n "$finalize_shlibpath"; then + finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" + fi + + compile_var= + finalize_var= + if test -n "$runpath_var"; then + if test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + func_append rpath "$dir:" + done + compile_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + if test -n "$finalize_perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $finalize_perm_rpath; do + func_append rpath "$dir:" + done + finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + fi + + if test yes = "$no_install"; then + # We don't need to create a wrapper script. + link_command=$compile_var$compile_command$compile_rpath + # Replace the output file specification. + link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'` + # Delete the old output file. + $opt_dry_run || $RM $output + # Link the executable and exit + func_show_eval "$link_command" 'exit $?' + + if test -n "$postlink_cmds"; then + func_to_tool_file "$output" + postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` + func_execute_cmds "$postlink_cmds" 'exit $?' + fi + + exit $EXIT_SUCCESS + fi + + case $hardcode_action,$fast_install in + relink,*) + # Fast installation is not supported + link_command=$compile_var$compile_command$compile_rpath + relink_command=$finalize_var$finalize_command$finalize_rpath + + func_warning "this platform does not like uninstalled shared libraries" + func_warning "'$output' will be relinked during installation" + ;; + *,yes) + link_command=$finalize_var$compile_command$finalize_rpath + relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'` + ;; + *,no) + link_command=$compile_var$compile_command$compile_rpath + relink_command=$finalize_var$finalize_command$finalize_rpath + ;; + *,needless) + link_command=$finalize_var$compile_command$finalize_rpath + relink_command= + ;; + esac + + # Replace the output file specification. + link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` + + # Delete the old output files. + $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname + + func_show_eval "$link_command" 'exit $?' + + if test -n "$postlink_cmds"; then + func_to_tool_file "$output_objdir/$outputname" + postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` + func_execute_cmds "$postlink_cmds" 'exit $?' + fi + + # Now create the wrapper script. + func_verbose "creating $output" + + # Quote the relink command for shipping. + if test -n "$relink_command"; then + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + func_quote_for_eval "$var_value" + relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" + fi + done + relink_command="(cd `pwd`; $relink_command)" + relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` + fi + + # Only actually do things if not in dry run mode. + $opt_dry_run || { + # win32 will think the script is a binary if it has + # a .exe suffix, so we strip it off here. + case $output in + *.exe) func_stripname '' '.exe' "$output" + output=$func_stripname_result ;; + esac + # test for cygwin because mv fails w/o .exe extensions + case $host in + *cygwin*) + exeext=.exe + func_stripname '' '.exe' "$outputname" + outputname=$func_stripname_result ;; + *) exeext= ;; + esac + case $host in + *cygwin* | *mingw* ) + func_dirname_and_basename "$output" "" "." + output_name=$func_basename_result + output_path=$func_dirname_result + cwrappersource=$output_path/$objdir/lt-$output_name.c + cwrapper=$output_path/$output_name.exe + $RM $cwrappersource $cwrapper + trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 + + func_emit_cwrapperexe_src > $cwrappersource + + # The wrapper executable is built using the $host compiler, + # because it contains $host paths and files. If cross- + # compiling, it, like the target executable, must be + # executed on the $host or under an emulation environment. + $opt_dry_run || { + $LTCC $LTCFLAGS -o $cwrapper $cwrappersource + $STRIP $cwrapper + } + + # Now, create the wrapper script for func_source use: + func_ltwrapper_scriptname $cwrapper + $RM $func_ltwrapper_scriptname_result + trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15 + $opt_dry_run || { + # note: this script will not be executed, so do not chmod. + if test "x$build" = "x$host"; then + $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result + else + func_emit_wrapper no > $func_ltwrapper_scriptname_result + fi + } + ;; + * ) + $RM $output + trap "$RM $output; exit $EXIT_FAILURE" 1 2 15 + + func_emit_wrapper no > $output + chmod +x $output + ;; + esac + } + exit $EXIT_SUCCESS + ;; + esac + + # See if we need to build an old-fashioned archive. + for oldlib in $oldlibs; do + + case $build_libtool_libs in + convenience) + oldobjs="$libobjs_save $symfileobj" + addlibs=$convenience + build_libtool_libs=no + ;; + module) + oldobjs=$libobjs_save + addlibs=$old_convenience + build_libtool_libs=no + ;; + *) + oldobjs="$old_deplibs $non_pic_objects" + $preload && test -f "$symfileobj" \ + && func_append oldobjs " $symfileobj" + addlibs=$old_convenience + ;; + esac + + if test -n "$addlibs"; then + gentop=$output_objdir/${outputname}x + func_append generated " $gentop" + + func_extract_archives $gentop $addlibs + func_append oldobjs " $func_extract_archives_result" + fi + + # Do each command in the archive commands. + if test -n "$old_archive_from_new_cmds" && test yes = "$build_libtool_libs"; then + cmds=$old_archive_from_new_cmds + else + + # Add any objects from preloaded convenience libraries + if test -n "$dlprefiles"; then + gentop=$output_objdir/${outputname}x + func_append generated " $gentop" + + func_extract_archives $gentop $dlprefiles + func_append oldobjs " $func_extract_archives_result" + fi + + # POSIX demands no paths to be encoded in archives. We have + # to avoid creating archives with duplicate basenames if we + # might have to extract them afterwards, e.g., when creating a + # static archive out of a convenience library, or when linking + # the entirety of a libtool archive into another (currently + # not supported by libtool). + if (for obj in $oldobjs + do + func_basename "$obj" + $ECHO "$func_basename_result" + done | sort | sort -uc >/dev/null 2>&1); then + : + else + echo "copying selected object files to avoid basename conflicts..." + gentop=$output_objdir/${outputname}x + func_append generated " $gentop" + func_mkdir_p "$gentop" + save_oldobjs=$oldobjs + oldobjs= + counter=1 + for obj in $save_oldobjs + do + func_basename "$obj" + objbase=$func_basename_result + case " $oldobjs " in + " ") oldobjs=$obj ;; + *[\ /]"$objbase "*) + while :; do + # Make sure we don't pick an alternate name that also + # overlaps. + newobj=lt$counter-$objbase + func_arith $counter + 1 + counter=$func_arith_result + case " $oldobjs " in + *[\ /]"$newobj "*) ;; + *) if test ! -f "$gentop/$newobj"; then break; fi ;; + esac + done + func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" + func_append oldobjs " $gentop/$newobj" + ;; + *) func_append oldobjs " $obj" ;; + esac + done + fi + func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 + tool_oldlib=$func_to_tool_file_result + eval cmds=\"$old_archive_cmds\" + + func_len " $cmds" + len=$func_len_result + if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then + cmds=$old_archive_cmds + elif test -n "$archiver_list_spec"; then + func_verbose "using command file archive linking..." + for obj in $oldobjs + do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" + done > $output_objdir/$libname.libcmd + func_to_tool_file "$output_objdir/$libname.libcmd" + oldobjs=" $archiver_list_spec$func_to_tool_file_result" + cmds=$old_archive_cmds + else + # the command line is too long to link in one step, link in parts + func_verbose "using piecewise archive linking..." + save_RANLIB=$RANLIB + RANLIB=: + objlist= + concat_cmds= + save_oldobjs=$oldobjs + oldobjs= + # Is there a better way of finding the last object in the list? + for obj in $save_oldobjs + do + last_oldobj=$obj + done + eval test_cmds=\"$old_archive_cmds\" + func_len " $test_cmds" + len0=$func_len_result + len=$len0 + for obj in $save_oldobjs + do + func_len " $obj" + func_arith $len + $func_len_result + len=$func_arith_result + func_append objlist " $obj" + if test "$len" -lt "$max_cmd_len"; then + : + else + # the above command should be used before it gets too long + oldobjs=$objlist + if test "$obj" = "$last_oldobj"; then + RANLIB=$save_RANLIB + fi + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\$concat_cmds$old_archive_cmds\" + objlist= + len=$len0 + fi + done + RANLIB=$save_RANLIB + oldobjs=$objlist + if test -z "$oldobjs"; then + eval cmds=\"\$concat_cmds\" + else + eval cmds=\"\$concat_cmds~\$old_archive_cmds\" + fi + fi + fi + func_execute_cmds "$cmds" 'exit $?' + done + + test -n "$generated" && \ + func_show_eval "${RM}r$generated" + + # Now create the libtool archive. + case $output in + *.la) + old_library= + test yes = "$build_old_libs" && old_library=$libname.$libext + func_verbose "creating $output" + + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + func_quote_for_eval "$var_value" + relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" + fi + done + # Quote the link command for shipping. + relink_command="(cd `pwd`; $SHELL \"$progpath\" $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" + relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` + if test yes = "$hardcode_automatic"; then + relink_command= + fi + + # Only create the output if not a dry run. + $opt_dry_run || { + for installed in no yes; do + if test yes = "$installed"; then + if test -z "$install_libdir"; then + break + fi + output=$output_objdir/${outputname}i + # Replace all uninstalled libtool libraries with the installed ones + newdependency_libs= + for deplib in $dependency_libs; do + case $deplib in + *.la) + func_basename "$deplib" + name=$func_basename_result + func_resolve_sysroot "$deplib" + eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result` + test -z "$libdir" && \ + func_fatal_error "'$deplib' is not a valid libtool archive" + func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name" + ;; + -L*) + func_stripname -L '' "$deplib" + func_replace_sysroot "$func_stripname_result" + func_append newdependency_libs " -L$func_replace_sysroot_result" + ;; + -R*) + func_stripname -R '' "$deplib" + func_replace_sysroot "$func_stripname_result" + func_append newdependency_libs " -R$func_replace_sysroot_result" + ;; + *) func_append newdependency_libs " $deplib" ;; + esac + done + dependency_libs=$newdependency_libs + newdlfiles= + + for lib in $dlfiles; do + case $lib in + *.la) + func_basename "$lib" + name=$func_basename_result + eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + test -z "$libdir" && \ + func_fatal_error "'$lib' is not a valid libtool archive" + func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name" + ;; + *) func_append newdlfiles " $lib" ;; + esac + done + dlfiles=$newdlfiles + newdlprefiles= + for lib in $dlprefiles; do + case $lib in + *.la) + # Only pass preopened files to the pseudo-archive (for + # eventual linking with the app. that links it) if we + # didn't already link the preopened objects directly into + # the library: + func_basename "$lib" + name=$func_basename_result + eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + test -z "$libdir" && \ + func_fatal_error "'$lib' is not a valid libtool archive" + func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name" + ;; + esac + done + dlprefiles=$newdlprefiles + else + newdlfiles= + for lib in $dlfiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;; + *) abs=`pwd`"/$lib" ;; + esac + func_append newdlfiles " $abs" + done + dlfiles=$newdlfiles + newdlprefiles= + for lib in $dlprefiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;; + *) abs=`pwd`"/$lib" ;; + esac + func_append newdlprefiles " $abs" + done + dlprefiles=$newdlprefiles + fi + $RM $output + # place dlname in correct position for cygwin + # In fact, it would be nice if we could use this code for all target + # systems that can't hard-code library paths into their executables + # and that have no shared library path variable independent of PATH, + # but it turns out we can't easily determine that from inspecting + # libtool variables, so we have to hard-code the OSs to which it + # applies here; at the moment, that means platforms that use the PE + # object format with DLL files. See the long comment at the top of + # tests/bindir.at for full details. + tdlname=$dlname + case $host,$output,$installed,$module,$dlname in + *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) + # If a -bindir argument was supplied, place the dll there. + if test -n "$bindir"; then + func_relative_path "$install_libdir" "$bindir" + tdlname=$func_relative_path_result/$dlname + else + # Otherwise fall back on heuristic. + tdlname=../bin/$dlname + fi + ;; + esac + $ECHO > $output "\ +# $outputname - a libtool library file +# Generated by $PROGRAM (GNU $PACKAGE) $VERSION +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# The name that we can dlopen(3). +dlname='$tdlname' + +# Names of this library. +library_names='$library_names' + +# The name of the static archive. +old_library='$old_library' + +# Linker flags that cannot go in dependency_libs. +inherited_linker_flags='$new_inherited_linker_flags' + +# Libraries that this one depends upon. +dependency_libs='$dependency_libs' + +# Names of additional weak libraries provided by this library +weak_library_names='$weak_libs' + +# Version information for $libname. +current=$current +age=$age +revision=$revision + +# Is this an already installed library? +installed=$installed + +# Should we warn about portability when linking against -modules? +shouldnotlink=$module + +# Files to dlopen/dlpreopen +dlopen='$dlfiles' +dlpreopen='$dlprefiles' + +# Directory that this library needs to be installed in: +libdir='$install_libdir'" + if test no,yes = "$installed,$need_relink"; then + $ECHO >> $output "\ +relink_command=\"$relink_command\"" + fi + done + } + + # Do a symbolic link so that the libtool archive can be found in + # LD_LIBRARY_PATH before the program is installed. + func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?' + ;; + esac + exit $EXIT_SUCCESS +} + +if test link = "$opt_mode" || test relink = "$opt_mode"; then + func_mode_link ${1+"$@"} +fi + + +# func_mode_uninstall arg... +func_mode_uninstall () +{ + $debug_cmd + + RM=$nonopt + files= + rmforce=false + exit_status=0 + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic=$magic + + for arg + do + case $arg in + -f) func_append RM " $arg"; rmforce=: ;; + -*) func_append RM " $arg" ;; + *) func_append files " $arg" ;; + esac + done + + test -z "$RM" && \ + func_fatal_help "you must specify an RM program" + + rmdirs= + + for file in $files; do + func_dirname "$file" "" "." + dir=$func_dirname_result + if test . = "$dir"; then + odir=$objdir + else + odir=$dir/$objdir + fi + func_basename "$file" + name=$func_basename_result + test uninstall = "$opt_mode" && odir=$dir + + # Remember odir for removal later, being careful to avoid duplicates + if test clean = "$opt_mode"; then + case " $rmdirs " in + *" $odir "*) ;; + *) func_append rmdirs " $odir" ;; + esac + fi + + # Don't error if the file doesn't exist and rm -f was used. + if { test -L "$file"; } >/dev/null 2>&1 || + { test -h "$file"; } >/dev/null 2>&1 || + test -f "$file"; then + : + elif test -d "$file"; then + exit_status=1 + continue + elif $rmforce; then + continue + fi + + rmfiles=$file + + case $name in + *.la) + # Possibly a libtool archive, so verify it. + if func_lalib_p "$file"; then + func_source $dir/$name + + # Delete the libtool libraries and symlinks. + for n in $library_names; do + func_append rmfiles " $odir/$n" + done + test -n "$old_library" && func_append rmfiles " $odir/$old_library" + + case $opt_mode in + clean) + case " $library_names " in + *" $dlname "*) ;; + *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;; + esac + test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i" + ;; + uninstall) + if test -n "$library_names"; then + # Do each command in the postuninstall commands. + func_execute_cmds "$postuninstall_cmds" '$rmforce || exit_status=1' + fi + + if test -n "$old_library"; then + # Do each command in the old_postuninstall commands. + func_execute_cmds "$old_postuninstall_cmds" '$rmforce || exit_status=1' + fi + # FIXME: should reinstall the best remaining shared library. + ;; + esac + fi + ;; + + *.lo) + # Possibly a libtool object, so verify it. + if func_lalib_p "$file"; then + + # Read the .lo file + func_source $dir/$name + + # Add PIC object to the list of files to remove. + if test -n "$pic_object" && test none != "$pic_object"; then + func_append rmfiles " $dir/$pic_object" + fi + + # Add non-PIC object to the list of files to remove. + if test -n "$non_pic_object" && test none != "$non_pic_object"; then + func_append rmfiles " $dir/$non_pic_object" + fi + fi + ;; + + *) + if test clean = "$opt_mode"; then + noexename=$name + case $file in + *.exe) + func_stripname '' '.exe' "$file" + file=$func_stripname_result + func_stripname '' '.exe' "$name" + noexename=$func_stripname_result + # $file with .exe has already been added to rmfiles, + # add $file without .exe + func_append rmfiles " $file" + ;; + esac + # Do a test to see if this is a libtool program. + if func_ltwrapper_p "$file"; then + if func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + relink_command= + func_source $func_ltwrapper_scriptname_result + func_append rmfiles " $func_ltwrapper_scriptname_result" + else + relink_command= + func_source $dir/$noexename + fi + + # note $name still contains .exe if it was in $file originally + # as does the version of $file that was added into $rmfiles + func_append rmfiles " $odir/$name $odir/${name}S.$objext" + if test yes = "$fast_install" && test -n "$relink_command"; then + func_append rmfiles " $odir/lt-$name" + fi + if test "X$noexename" != "X$name"; then + func_append rmfiles " $odir/lt-$noexename.c" + fi + fi + fi + ;; + esac + func_show_eval "$RM $rmfiles" 'exit_status=1' + done + + # Try to remove the $objdir's in the directories where we deleted files + for dir in $rmdirs; do + if test -d "$dir"; then + func_show_eval "rmdir $dir >/dev/null 2>&1" + fi + done + + exit $exit_status +} + +if test uninstall = "$opt_mode" || test clean = "$opt_mode"; then + func_mode_uninstall ${1+"$@"} +fi + +test -z "$opt_mode" && { + help=$generic_help + func_fatal_help "you must specify a MODE" +} + +test -z "$exec_cmd" && \ + func_fatal_help "invalid operation mode '$opt_mode'" + +if test -n "$exec_cmd"; then + eval exec "$exec_cmd" + exit $EXIT_FAILURE +fi + +exit $exit_status + + +# The TAGs below are defined such that we never get into a situation +# where we disable both kinds of libraries. Given conflicting +# choices, we go for a static library, that is the most portable, +# since we can't tell whether shared libraries were disabled because +# the user asked for that or because the platform doesn't support +# them. This is particularly important on AIX, because we don't +# support having both static and shared libraries enabled at the same +# time on that platform, so we default to a shared-only configuration. +# If a disable-shared tag is given, we'll fallback to a static-only +# configuration. But we'll never go from static-only to shared-only. + +# ### BEGIN LIBTOOL TAG CONFIG: disable-shared +build_libtool_libs=no +build_old_libs=yes +# ### END LIBTOOL TAG CONFIG: disable-shared + +# ### BEGIN LIBTOOL TAG CONFIG: disable-static +build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` +# ### END LIBTOOL TAG CONFIG: disable-static + +# Local Variables: +# mode:shell-script +# sh-indentation:2 +# End: diff --git a/config/ltoptions.m4 b/config/ltoptions.m4 new file mode 100644 index 0000000..94b0829 --- /dev/null +++ b/config/ltoptions.m4 @@ -0,0 +1,437 @@ +# Helper functions for option handling. -*- Autoconf -*- +# +# Copyright (C) 2004-2005, 2007-2009, 2011-2015 Free Software +# Foundation, Inc. +# Written by Gary V. Vaughan, 2004 +# +# 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 8 ltoptions.m4 + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) + + +# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) +# ------------------------------------------ +m4_define([_LT_MANGLE_OPTION], +[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) + + +# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) +# --------------------------------------- +# Set option OPTION-NAME for macro MACRO-NAME, and if there is a +# matching handler defined, dispatch to it. Other OPTION-NAMEs are +# saved as a flag. +m4_define([_LT_SET_OPTION], +[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl +m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), + _LT_MANGLE_DEFUN([$1], [$2]), + [m4_warning([Unknown $1 option '$2'])])[]dnl +]) + + +# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) +# ------------------------------------------------------------ +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +m4_define([_LT_IF_OPTION], +[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) + + +# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) +# ------------------------------------------------------- +# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME +# are set. +m4_define([_LT_UNLESS_OPTIONS], +[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), + [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), + [m4_define([$0_found])])])[]dnl +m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 +])[]dnl +]) + + +# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) +# ---------------------------------------- +# OPTION-LIST is a space-separated list of Libtool options associated +# with MACRO-NAME. If any OPTION has a matching handler declared with +# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about +# the unknown option and exit. +m4_defun([_LT_SET_OPTIONS], +[# Set options +m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), + [_LT_SET_OPTION([$1], _LT_Option)]) + +m4_if([$1],[LT_INIT],[ + dnl + dnl Simply set some default values (i.e off) if boolean options were not + dnl specified: + _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no + ]) + _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no + ]) + dnl + dnl If no reference was made to various pairs of opposing options, then + dnl we run the default mode handler for the pair. For example, if neither + dnl 'shared' nor 'disable-shared' was passed, we enable building of shared + dnl archives by default: + _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) + _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) + _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) + _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], + [_LT_ENABLE_FAST_INSTALL]) + _LT_UNLESS_OPTIONS([LT_INIT], [aix-soname=aix aix-soname=both aix-soname=svr4], + [_LT_WITH_AIX_SONAME([aix])]) + ]) +])# _LT_SET_OPTIONS + + +## --------------------------------- ## +## Macros to handle LT_INIT options. ## +## --------------------------------- ## + +# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) +# ----------------------------------------- +m4_define([_LT_MANGLE_DEFUN], +[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) + + +# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) +# ----------------------------------------------- +m4_define([LT_OPTION_DEFINE], +[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl +])# LT_OPTION_DEFINE + + +# dlopen +# ------ +LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes +]) + +AU_DEFUN([AC_LIBTOOL_DLOPEN], +[_LT_SET_OPTION([LT_INIT], [dlopen]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the 'dlopen' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) + + +# win32-dll +# --------- +# Declare package support for building win32 dll's. +LT_OPTION_DEFINE([LT_INIT], [win32-dll], +[enable_win32_dll=yes + +case $host in +*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) + AC_CHECK_TOOL(AS, as, false) + AC_CHECK_TOOL(DLLTOOL, dlltool, false) + AC_CHECK_TOOL(OBJDUMP, objdump, false) + ;; +esac + +test -z "$AS" && AS=as +_LT_DECL([], [AS], [1], [Assembler program])dnl + +test -z "$DLLTOOL" && DLLTOOL=dlltool +_LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl + +test -z "$OBJDUMP" && OBJDUMP=objdump +_LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl +])# win32-dll + +AU_DEFUN([AC_LIBTOOL_WIN32_DLL], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +_LT_SET_OPTION([LT_INIT], [win32-dll]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the 'win32-dll' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) + + +# _LT_ENABLE_SHARED([DEFAULT]) +# ---------------------------- +# implement the --enable-shared flag, and supports the 'shared' and +# 'disable-shared' LT_INIT options. +# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. +m4_define([_LT_ENABLE_SHARED], +[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([shared], + [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], + [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for pkg in $enableval; do + IFS=$lt_save_ifs + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS=$lt_save_ifs + ;; + esac], + [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) + + _LT_DECL([build_libtool_libs], [enable_shared], [0], + [Whether or not to build shared libraries]) +])# _LT_ENABLE_SHARED + +LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) + +# Old names: +AC_DEFUN([AC_ENABLE_SHARED], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) +]) + +AC_DEFUN([AC_DISABLE_SHARED], +[_LT_SET_OPTION([LT_INIT], [disable-shared]) +]) + +AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) +AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_ENABLE_SHARED], []) +dnl AC_DEFUN([AM_DISABLE_SHARED], []) + + + +# _LT_ENABLE_STATIC([DEFAULT]) +# ---------------------------- +# implement the --enable-static flag, and support the 'static' and +# 'disable-static' LT_INIT options. +# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. +m4_define([_LT_ENABLE_STATIC], +[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([static], + [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], + [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for pkg in $enableval; do + IFS=$lt_save_ifs + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS=$lt_save_ifs + ;; + esac], + [enable_static=]_LT_ENABLE_STATIC_DEFAULT) + + _LT_DECL([build_old_libs], [enable_static], [0], + [Whether or not to build static libraries]) +])# _LT_ENABLE_STATIC + +LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) + +# Old names: +AC_DEFUN([AC_ENABLE_STATIC], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) +]) + +AC_DEFUN([AC_DISABLE_STATIC], +[_LT_SET_OPTION([LT_INIT], [disable-static]) +]) + +AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) +AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_ENABLE_STATIC], []) +dnl AC_DEFUN([AM_DISABLE_STATIC], []) + + + +# _LT_ENABLE_FAST_INSTALL([DEFAULT]) +# ---------------------------------- +# implement the --enable-fast-install flag, and support the 'fast-install' +# and 'disable-fast-install' LT_INIT options. +# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. +m4_define([_LT_ENABLE_FAST_INSTALL], +[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([fast-install], + [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], + [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for pkg in $enableval; do + IFS=$lt_save_ifs + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS=$lt_save_ifs + ;; + esac], + [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) + +_LT_DECL([fast_install], [enable_fast_install], [0], + [Whether or not to optimize for fast installation])dnl +])# _LT_ENABLE_FAST_INSTALL + +LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) + +# Old names: +AU_DEFUN([AC_ENABLE_FAST_INSTALL], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you put +the 'fast-install' option into LT_INIT's first parameter.]) +]) + +AU_DEFUN([AC_DISABLE_FAST_INSTALL], +[_LT_SET_OPTION([LT_INIT], [disable-fast-install]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you put +the 'disable-fast-install' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) +dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) + + +# _LT_WITH_AIX_SONAME([DEFAULT]) +# ---------------------------------- +# implement the --with-aix-soname flag, and support the `aix-soname=aix' +# and `aix-soname=both' and `aix-soname=svr4' LT_INIT options. DEFAULT +# is either `aix', `both' or `svr4'. If omitted, it defaults to `aix'. +m4_define([_LT_WITH_AIX_SONAME], +[m4_define([_LT_WITH_AIX_SONAME_DEFAULT], [m4_if($1, svr4, svr4, m4_if($1, both, both, aix))])dnl +shared_archive_member_spec= +case $host,$enable_shared in +power*-*-aix[[5-9]]*,yes) + AC_MSG_CHECKING([which variant of shared library versioning to provide]) + AC_ARG_WITH([aix-soname], + [AS_HELP_STRING([--with-aix-soname=aix|svr4|both], + [shared library versioning (aka "SONAME") variant to provide on AIX, @<:@default=]_LT_WITH_AIX_SONAME_DEFAULT[@:>@.])], + [case $withval in + aix|svr4|both) + ;; + *) + AC_MSG_ERROR([Unknown argument to --with-aix-soname]) + ;; + esac + lt_cv_with_aix_soname=$with_aix_soname], + [AC_CACHE_VAL([lt_cv_with_aix_soname], + [lt_cv_with_aix_soname=]_LT_WITH_AIX_SONAME_DEFAULT) + with_aix_soname=$lt_cv_with_aix_soname]) + AC_MSG_RESULT([$with_aix_soname]) + if test aix != "$with_aix_soname"; then + # For the AIX way of multilib, we name the shared archive member + # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o', + # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File. + # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag, + # the AIX toolchain works better with OBJECT_MODE set (default 32). + if test 64 = "${OBJECT_MODE-32}"; then + shared_archive_member_spec=shr_64 + else + shared_archive_member_spec=shr + fi + fi + ;; +*) + with_aix_soname=aix + ;; +esac + +_LT_DECL([], [shared_archive_member_spec], [0], + [Shared archive member basename, for filename based shared library versioning on AIX])dnl +])# _LT_WITH_AIX_SONAME + +LT_OPTION_DEFINE([LT_INIT], [aix-soname=aix], [_LT_WITH_AIX_SONAME([aix])]) +LT_OPTION_DEFINE([LT_INIT], [aix-soname=both], [_LT_WITH_AIX_SONAME([both])]) +LT_OPTION_DEFINE([LT_INIT], [aix-soname=svr4], [_LT_WITH_AIX_SONAME([svr4])]) + + +# _LT_WITH_PIC([MODE]) +# -------------------- +# implement the --with-pic flag, and support the 'pic-only' and 'no-pic' +# LT_INIT options. +# MODE is either 'yes' or 'no'. If omitted, it defaults to 'both'. +m4_define([_LT_WITH_PIC], +[AC_ARG_WITH([pic], + [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@], + [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], + [lt_p=${PACKAGE-default} + case $withval in + yes|no) pic_mode=$withval ;; + *) + pic_mode=default + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for lt_pkg in $withval; do + IFS=$lt_save_ifs + if test "X$lt_pkg" = "X$lt_p"; then + pic_mode=yes + fi + done + IFS=$lt_save_ifs + ;; + esac], + [pic_mode=m4_default([$1], [default])]) + +_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl +])# _LT_WITH_PIC + +LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) +LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) + +# Old name: +AU_DEFUN([AC_LIBTOOL_PICMODE], +[_LT_SET_OPTION([LT_INIT], [pic-only]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the 'pic-only' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) + +## ----------------- ## +## LTDL_INIT Options ## +## ----------------- ## + +m4_define([_LTDL_MODE], []) +LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], + [m4_define([_LTDL_MODE], [nonrecursive])]) +LT_OPTION_DEFINE([LTDL_INIT], [recursive], + [m4_define([_LTDL_MODE], [recursive])]) +LT_OPTION_DEFINE([LTDL_INIT], [subproject], + [m4_define([_LTDL_MODE], [subproject])]) + +m4_define([_LTDL_TYPE], []) +LT_OPTION_DEFINE([LTDL_INIT], [installable], + [m4_define([_LTDL_TYPE], [installable])]) +LT_OPTION_DEFINE([LTDL_INIT], [convenience], + [m4_define([_LTDL_TYPE], [convenience])]) diff --git a/config/ltsugar.m4 b/config/ltsugar.m4 new file mode 100644 index 0000000..48bc934 --- /dev/null +++ b/config/ltsugar.m4 @@ -0,0 +1,124 @@ +# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- +# +# Copyright (C) 2004-2005, 2007-2008, 2011-2015 Free Software +# Foundation, Inc. +# Written by Gary V. Vaughan, 2004 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 6 ltsugar.m4 + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) + + +# lt_join(SEP, ARG1, [ARG2...]) +# ----------------------------- +# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their +# associated separator. +# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier +# versions in m4sugar had bugs. +m4_define([lt_join], +[m4_if([$#], [1], [], + [$#], [2], [[$2]], + [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) +m4_define([_lt_join], +[m4_if([$#$2], [2], [], + [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) + + +# lt_car(LIST) +# lt_cdr(LIST) +# ------------ +# Manipulate m4 lists. +# These macros are necessary as long as will still need to support +# Autoconf-2.59, which quotes differently. +m4_define([lt_car], [[$1]]) +m4_define([lt_cdr], +[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], + [$#], 1, [], + [m4_dquote(m4_shift($@))])]) +m4_define([lt_unquote], $1) + + +# lt_append(MACRO-NAME, STRING, [SEPARATOR]) +# ------------------------------------------ +# Redefine MACRO-NAME to hold its former content plus 'SEPARATOR''STRING'. +# Note that neither SEPARATOR nor STRING are expanded; they are appended +# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). +# No SEPARATOR is output if MACRO-NAME was previously undefined (different +# than defined and empty). +# +# This macro is needed until we can rely on Autoconf 2.62, since earlier +# versions of m4sugar mistakenly expanded SEPARATOR but not STRING. +m4_define([lt_append], +[m4_define([$1], + m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) + + + +# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) +# ---------------------------------------------------------- +# Produce a SEP delimited list of all paired combinations of elements of +# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list +# has the form PREFIXmINFIXSUFFIXn. +# Needed until we can rely on m4_combine added in Autoconf 2.62. +m4_define([lt_combine], +[m4_if(m4_eval([$# > 3]), [1], + [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl +[[m4_foreach([_Lt_prefix], [$2], + [m4_foreach([_Lt_suffix], + ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, + [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) + + +# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) +# ----------------------------------------------------------------------- +# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited +# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. +m4_define([lt_if_append_uniq], +[m4_ifdef([$1], + [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], + [lt_append([$1], [$2], [$3])$4], + [$5])], + [lt_append([$1], [$2], [$3])$4])]) + + +# lt_dict_add(DICT, KEY, VALUE) +# ----------------------------- +m4_define([lt_dict_add], +[m4_define([$1($2)], [$3])]) + + +# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) +# -------------------------------------------- +m4_define([lt_dict_add_subkey], +[m4_define([$1($2:$3)], [$4])]) + + +# lt_dict_fetch(DICT, KEY, [SUBKEY]) +# ---------------------------------- +m4_define([lt_dict_fetch], +[m4_ifval([$3], + m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), + m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) + + +# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) +# ----------------------------------------------------------------- +m4_define([lt_if_dict_fetch], +[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], + [$5], + [$6])]) + + +# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) +# -------------------------------------------------------------- +m4_define([lt_dict_filter], +[m4_if([$5], [], [], + [lt_join(m4_quote(m4_default([$4], [[, ]])), + lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), + [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl +]) diff --git a/config/ltversion.m4 b/config/ltversion.m4 new file mode 100644 index 0000000..fa04b52 --- /dev/null +++ b/config/ltversion.m4 @@ -0,0 +1,23 @@ +# ltversion.m4 -- version numbers -*- Autoconf -*- +# +# Copyright (C) 2004, 2011-2015 Free Software Foundation, Inc. +# Written by Scott James Remnant, 2004 +# +# 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. + +# @configure_input@ + +# serial 4179 ltversion.m4 +# This file is part of GNU Libtool + +m4_define([LT_PACKAGE_VERSION], [2.4.6]) +m4_define([LT_PACKAGE_REVISION], [2.4.6]) + +AC_DEFUN([LTVERSION_VERSION], +[macro_version='2.4.6' +macro_revision='2.4.6' +_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) +_LT_DECL(, macro_revision, 0) +]) diff --git a/config/lt~obsolete.m4 b/config/lt~obsolete.m4 new file mode 100644 index 0000000..c6b26f8 --- /dev/null +++ b/config/lt~obsolete.m4 @@ -0,0 +1,99 @@ +# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- +# +# Copyright (C) 2004-2005, 2007, 2009, 2011-2015 Free Software +# Foundation, Inc. +# Written by Scott James Remnant, 2004. +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 5 lt~obsolete.m4 + +# These exist entirely to fool aclocal when bootstrapping libtool. +# +# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN), +# which have later been changed to m4_define as they aren't part of the +# exported API, or moved to Autoconf or Automake where they belong. +# +# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN +# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us +# using a macro with the same name in our local m4/libtool.m4 it'll +# pull the old libtool.m4 in (it doesn't see our shiny new m4_define +# and doesn't know about Autoconf macros at all.) +# +# So we provide this file, which has a silly filename so it's always +# included after everything else. This provides aclocal with the +# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything +# because those macros already exist, or will be overwritten later. +# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. +# +# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. +# Yes, that means every name once taken will need to remain here until +# we give up compatibility with versions before 1.7, at which point +# we need to keep only those names which we still refer to. + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) + +m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) +m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) +m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) +m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) +m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) +m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) +m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) +m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) +m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) +m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) +m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) +m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) +m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) +m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) +m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) +m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) +m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) +m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) +m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) +m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) +m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) +m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) +m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) +m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) +m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) +m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) +m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) +m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) +m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) +m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) +m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) +m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) +m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) +m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) +m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) +m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) +m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) +m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) +m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) +m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) +m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) +m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) +m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) +m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) +m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) +m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) +m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) +m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) +m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) +m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) +m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])]) +m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])]) +m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])]) +m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])]) +m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])]) +m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])]) +m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])]) diff --git a/config/missing b/config/missing new file mode 100755 index 0000000..625aeb1 --- /dev/null +++ b/config/missing @@ -0,0 +1,215 @@ +#! /bin/sh +# Common wrapper for a few potentially missing GNU programs. + +scriptversion=2018-03-07.03; # UTC + +# Copyright (C) 1996-2018 Free Software Foundation, Inc. +# Originally written by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996. + +# 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. If not, see <https://www.gnu.org/licenses/>. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +if test $# -eq 0; then + echo 1>&2 "Try '$0 --help' for more information" + exit 1 +fi + +case $1 in + + --is-lightweight) + # Used by our autoconf macros to check whether the available missing + # script is modern enough. + exit 0 + ;; + + --run) + # Back-compat with the calling convention used by older automake. + shift + ;; + + -h|--h|--he|--hel|--help) + echo "\ +$0 [OPTION]... PROGRAM [ARGUMENT]... + +Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due +to PROGRAM being missing or too old. + +Options: + -h, --help display this help and exit + -v, --version output version information and exit + +Supported PROGRAM values: + aclocal autoconf autoheader autom4te automake makeinfo + bison yacc flex lex help2man + +Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and +'g' are ignored when checking the name. + +Send bug reports to <bug-automake@gnu.org>." + exit $? + ;; + + -v|--v|--ve|--ver|--vers|--versi|--versio|--version) + echo "missing $scriptversion (GNU Automake)" + exit $? + ;; + + -*) + echo 1>&2 "$0: unknown '$1' option" + echo 1>&2 "Try '$0 --help' for more information" + exit 1 + ;; + +esac + +# Run the given program, remember its exit status. +"$@"; st=$? + +# If it succeeded, we are done. +test $st -eq 0 && exit 0 + +# Also exit now if we it failed (or wasn't found), and '--version' was +# passed; such an option is passed most likely to detect whether the +# program is present and works. +case $2 in --version|--help) exit $st;; esac + +# Exit code 63 means version mismatch. This often happens when the user +# tries to use an ancient version of a tool on a file that requires a +# minimum version. +if test $st -eq 63; then + msg="probably too old" +elif test $st -eq 127; then + # Program was missing. + msg="missing on your system" +else + # Program was found and executed, but failed. Give up. + exit $st +fi + +perl_URL=https://www.perl.org/ +flex_URL=https://github.com/westes/flex +gnu_software_URL=https://www.gnu.org/software + +program_details () +{ + case $1 in + aclocal|automake) + echo "The '$1' program is part of the GNU Automake package:" + echo "<$gnu_software_URL/automake>" + echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:" + echo "<$gnu_software_URL/autoconf>" + echo "<$gnu_software_URL/m4/>" + echo "<$perl_URL>" + ;; + autoconf|autom4te|autoheader) + echo "The '$1' program is part of the GNU Autoconf package:" + echo "<$gnu_software_URL/autoconf/>" + echo "It also requires GNU m4 and Perl in order to run:" + echo "<$gnu_software_URL/m4/>" + echo "<$perl_URL>" + ;; + esac +} + +give_advice () +{ + # Normalize program name to check for. + normalized_program=`echo "$1" | sed ' + s/^gnu-//; t + s/^gnu//; t + s/^g//; t'` + + printf '%s\n' "'$1' is $msg." + + configure_deps="'configure.ac' or m4 files included by 'configure.ac'" + case $normalized_program in + autoconf*) + echo "You should only need it if you modified 'configure.ac'," + echo "or m4 files included by it." + program_details 'autoconf' + ;; + autoheader*) + echo "You should only need it if you modified 'acconfig.h' or" + echo "$configure_deps." + program_details 'autoheader' + ;; + automake*) + echo "You should only need it if you modified 'Makefile.am' or" + echo "$configure_deps." + program_details 'automake' + ;; + aclocal*) + echo "You should only need it if you modified 'acinclude.m4' or" + echo "$configure_deps." + program_details 'aclocal' + ;; + autom4te*) + echo "You might have modified some maintainer files that require" + echo "the 'autom4te' program to be rebuilt." + program_details 'autom4te' + ;; + bison*|yacc*) + echo "You should only need it if you modified a '.y' file." + echo "You may want to install the GNU Bison package:" + echo "<$gnu_software_URL/bison/>" + ;; + lex*|flex*) + echo "You should only need it if you modified a '.l' file." + echo "You may want to install the Fast Lexical Analyzer package:" + echo "<$flex_URL>" + ;; + help2man*) + echo "You should only need it if you modified a dependency" \ + "of a man page." + echo "You may want to install the GNU Help2man package:" + echo "<$gnu_software_URL/help2man/>" + ;; + makeinfo*) + echo "You should only need it if you modified a '.texi' file, or" + echo "any other file indirectly affecting the aspect of the manual." + echo "You might want to install the Texinfo package:" + echo "<$gnu_software_URL/texinfo/>" + echo "The spurious makeinfo call might also be the consequence of" + echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might" + echo "want to install GNU make:" + echo "<$gnu_software_URL/make/>" + ;; + *) + echo "You might have modified some files without having the proper" + echo "tools for further handling them. Check the 'README' file, it" + echo "often tells you about the needed prerequisites for installing" + echo "this package. You may also peek at any GNU archive site, in" + echo "case some other package contains this missing '$1' program." + ;; + esac +} + +give_advice "$1" | sed -e '1s/^/WARNING: /' \ + -e '2,$s/^/ /' >&2 + +# Propagate the correct exit status (expected to be 127 for a program +# not found, 63 for a program that failed due to version mismatch). +exit $st + +# Local variables: +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC0" +# time-stamp-end: "; # UTC" +# End: diff --git a/config/mk-shdefs.in b/config/mk-shdefs.in new file mode 100644 index 0000000..68aed2a --- /dev/null +++ b/config/mk-shdefs.in @@ -0,0 +1,138 @@ +#! @CONFIG_SHELL@ +# -*- Mode: shell-script -*- + +## mk-shdefs.in - extract the substitutions in config.status into +## environment variables. +## +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen 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. +## +## AutoGen is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License along +## with this program. If not, see <http://www.gnu.org/licenses/>. + +die() { + echo "$prog fatal error: $*" + kill -TERM $progpid + exit 1 +} >&2 + +init() { + prog=`basename $1 .sh` + progpid=$$ + + if (exec 2> /dev/null ; unset CDPATH) + then unset CDPATH + elif test ${#CDPATH} -gt 0 + then CDPATH= + fi + + SED='@SED@' + AWK='@AWK@' + GREP='@GREP@' + EGREP='@EGREP@' + target=`basename $2` + builddir=`dirname $2` + builddir=`cd $builddir >/dev/null && pwd` + srcdir=`dirname $1` + srcdir=`cd $srcdir >/dev/null && pwd` + + cd ${builddir} || die no builddir + + # top_builddir may be relative to the build directory that corresponds + # to the source directory for this file. Make it absolute + # + top_builddir=`cd @top_builddir@ >/dev/null && pwd` + top_srcdir=` + cd ${builddir} >/dev/null && cd @top_srcdir@ >/dev/null && pwd` + + rm -f ${target} + exec 3> shdef-temp.in || die cannot create output + cd .. +} + +mk_config() { + cat >&3 <<- _EOF_ + prefix='@prefix@' + exec_prefix="@exec_prefix@" + PACKAGE_TARNAME='@PACKAGE_TARNAME@' + _EOF_ + + # Skip the stuff we force to be first + # + skip_list='top_srcdir|top_builddir|prefix|exec_prefix|PACKAGE_TARNAME' + + # skip the autoconf/automake internal names + # + skip_list=${skip_list}"|a[mc]_.*|.*_TRUE|.*_FALSE|HAVE_.*|AM*" + + # These must be in the correct order. Ensure it and don't do 'em twice + # + eval_fmt='eval "%s=\\"@%s@\\""\n' + for v in datarootdir mandir localedir infodir docdir datadir \ + libdir libexecdir sbindir bindir \ + includedir localstatedir sharedstatedir sysconfdir oldincludedir + do printf "${eval_fmt}" $v $v + skip_list=${skip_list}"|$v" + done >&3 + + for f in `${GREP} '^S\["' config.status` + do + v=`echo "$f" | ${SED} 's/".=.*//;s/[SD]\["//'` + x=`echo "$v" | ${EGREP} "^($skip_list)\$"` + test "X$x" = X || continue + + case "$f" in + *'$('* ) : ;; # no make file only substitutions + *'missing --run '* ) : ;; # no bootstrap tools + S*\$* ) printf "${eval_fmt}" $v $v ;; + S* ) echo "$v='@$v@'" ;; + esac + done >&3 + + exec 3>&- +} + +configure() { + cd config + + ../config.status --file shdef-temp + { + cmd='`set -o | '${AWK}" '/^allexport/ {print \$2}'"\` + cat <<- _EOF_ + #! `which echo` this-file-should-be-sourced,-not-executed + # -*- Mode: shell-script -*- + + case "$cmd" in + on ) cleara=: ;; + * ) cleara='set +a' ; set -a ;; + esac + + top_srcdir="$top_srcdir" + top_builddir="$top_builddir" + _EOF_ + + cat shdef-temp + echo 'eval $cleara' + } > ${target} + + rm -f shdef-temp* +} + +set -x +exec 9>&2 +tmp=$(mktemp --suffix=.tdir -d /tmp/shdefs-XXXXXXXXX) +exec 2>> $tmp/mk-shdef.log +init $0 $1 +mk_config +configure +exec 2>&9 9>&- diff --git a/config/onceonly.m4 b/config/onceonly.m4 new file mode 100644 index 0000000..5ab3dd7 --- /dev/null +++ b/config/onceonly.m4 @@ -0,0 +1,104 @@ +# onceonly.m4 serial 9 +dnl Copyright (C) 2002-2003, 2005-2006, 2008-2018 Free Software Foundation, +dnl Inc. +dnl +dnl This file is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 3 of the License, or +dnl (at your option) any later version. +dnl +dnl This file is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +dnl GNU General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with this file. If not, see <https://www.gnu.org/licenses/>. +dnl +dnl As a special exception to the GNU General Public License, +dnl this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. + +dnl This file defines some "once only" variants of standard autoconf macros. +dnl AC_CHECK_HEADERS_ONCE like AC_CHECK_HEADERS +dnl AC_CHECK_FUNCS_ONCE like AC_CHECK_FUNCS +dnl AC_CHECK_DECLS_ONCE like AC_CHECK_DECLS +dnl AC_REQUIRE([AC_FUNC_STRCOLL]) like AC_FUNC_STRCOLL +dnl The advantage is that the check for each of the headers/functions/decls +dnl will be put only once into the 'configure' file. It keeps the size of +dnl the 'configure' file down, and avoids redundant output when 'configure' +dnl is run. +dnl The drawback is that the checks cannot be conditionalized. If you write +dnl if some_condition; then gl_CHECK_HEADERS(stdlib.h); fi +dnl inside an AC_DEFUNed function, the gl_CHECK_HEADERS macro call expands to +dnl empty, and the check will be inserted before the body of the AC_DEFUNed +dnl function. + +dnl The original code implemented AC_CHECK_HEADERS_ONCE and AC_CHECK_FUNCS_ONCE +dnl in terms of AC_DEFUN and AC_REQUIRE. This implementation uses diversions to +dnl named sections DEFAULTS and INIT_PREPARE in order to check all requested +dnl headers at once, thus reducing the size of 'configure'. It is known to work +dnl with autoconf 2.57..2.62 at least . The size reduction is ca. 9%. + +dnl Autoconf version 2.59 plus gnulib is required; this file is not needed +dnl with Autoconf 2.60 or greater. But note that autoconf's implementation of +dnl AC_CHECK_DECLS_ONCE expects a comma-separated list of symbols as first +dnl argument! +AC_PREREQ([2.59]) + +# AC_CHECK_HEADERS_ONCE(HEADER1 HEADER2 ...) is a once-only variant of +# AC_CHECK_HEADERS(HEADER1 HEADER2 ...). +AC_DEFUN([AC_CHECK_HEADERS_ONCE], [ + : + m4_foreach_w([gl_HEADER_NAME], [$1], [ + AC_DEFUN([gl_CHECK_HEADER_]m4_quote(m4_translit(gl_HEADER_NAME, + [./-], [___])), [ + m4_divert_text([INIT_PREPARE], + [gl_header_list="$gl_header_list gl_HEADER_NAME"]) + gl_HEADERS_EXPANSION + AH_TEMPLATE(AS_TR_CPP([HAVE_]m4_defn([gl_HEADER_NAME])), + [Define to 1 if you have the <]m4_defn([gl_HEADER_NAME])[> header file.]) + ]) + AC_REQUIRE([gl_CHECK_HEADER_]m4_quote(m4_translit(gl_HEADER_NAME, + [./-], [___]))) + ]) +]) +m4_define([gl_HEADERS_EXPANSION], [ + m4_divert_text([DEFAULTS], [gl_header_list=]) + AC_CHECK_HEADERS([$gl_header_list]) + m4_define([gl_HEADERS_EXPANSION], []) +]) + +# AC_CHECK_FUNCS_ONCE(FUNC1 FUNC2 ...) is a once-only variant of +# AC_CHECK_FUNCS(FUNC1 FUNC2 ...). +AC_DEFUN([AC_CHECK_FUNCS_ONCE], [ + : + m4_foreach_w([gl_FUNC_NAME], [$1], [ + AC_DEFUN([gl_CHECK_FUNC_]m4_defn([gl_FUNC_NAME]), [ + m4_divert_text([INIT_PREPARE], + [gl_func_list="$gl_func_list gl_FUNC_NAME"]) + gl_FUNCS_EXPANSION + AH_TEMPLATE(AS_TR_CPP([HAVE_]m4_defn([gl_FUNC_NAME])), + [Define to 1 if you have the ']m4_defn([gl_FUNC_NAME])[' function.]) + ]) + AC_REQUIRE([gl_CHECK_FUNC_]m4_defn([gl_FUNC_NAME])) + ]) +]) +m4_define([gl_FUNCS_EXPANSION], [ + m4_divert_text([DEFAULTS], [gl_func_list=]) + AC_CHECK_FUNCS([$gl_func_list]) + m4_define([gl_FUNCS_EXPANSION], []) +]) + +# AC_CHECK_DECLS_ONCE(DECL1 DECL2 ...) is a once-only variant of +# AC_CHECK_DECLS(DECL1, DECL2, ...). +AC_DEFUN([AC_CHECK_DECLS_ONCE], [ + : + m4_foreach_w([gl_DECL_NAME], [$1], [ + AC_DEFUN([gl_CHECK_DECL_]m4_defn([gl_DECL_NAME]), [ + AC_CHECK_DECLS(m4_defn([gl_DECL_NAME])) + ]) + AC_REQUIRE([gl_CHECK_DECL_]m4_defn([gl_DECL_NAME])) + ]) +]) diff --git a/config/pkg.m4 b/config/pkg.m4 new file mode 100644 index 0000000..82bea96 --- /dev/null +++ b/config/pkg.m4 @@ -0,0 +1,275 @@ +dnl pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- +dnl serial 11 (pkg-config-0.29.1) +dnl +dnl Copyright © 2004 Scott James Remnant <scott@netsplit.com>. +dnl Copyright © 2012-2015 Dan Nicholson <dbn.lists@gmail.com> +dnl +dnl This program is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 2 of the License, or +dnl (at your option) any later version. +dnl +dnl This program is distributed in the hope that it will be useful, but +dnl WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with this program; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +dnl 02111-1307, USA. +dnl +dnl As a special exception to the GNU General Public License, if you +dnl distribute this file as part of a program that contains a +dnl configuration script generated by Autoconf, you may include it under +dnl the same distribution terms that you use for the rest of that +dnl program. + +dnl PKG_PREREQ(MIN-VERSION) +dnl ----------------------- +dnl Since: 0.29 +dnl +dnl Verify that the version of the pkg-config macros are at least +dnl MIN-VERSION. Unlike PKG_PROG_PKG_CONFIG, which checks the user's +dnl installed version of pkg-config, this checks the developer's version +dnl of pkg.m4 when generating configure. +dnl +dnl To ensure that this macro is defined, also add: +dnl m4_ifndef([PKG_PREREQ], +dnl [m4_fatal([must install pkg-config 0.29 or later before running autoconf/autogen])]) +dnl +dnl See the "Since" comment for each macro you use to see what version +dnl of the macros you require. +m4_defun([PKG_PREREQ], +[m4_define([PKG_MACROS_VERSION], [0.29.1]) +m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1, + [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])]) +])dnl PKG_PREREQ + +dnl PKG_PROG_PKG_CONFIG([MIN-VERSION]) +dnl ---------------------------------- +dnl Since: 0.16 +dnl +dnl Search for the pkg-config tool and set the PKG_CONFIG variable to +dnl first found in the path. Checks that the version of pkg-config found +dnl is at least MIN-VERSION. If MIN-VERSION is not specified, 0.9.0 is +dnl used since that's the first version where most current features of +dnl pkg-config existed. +AC_DEFUN([PKG_PROG_PKG_CONFIG], +[m4_pattern_forbid([^_?PKG_[A-Z_]+$]) +m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$]) +m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$]) +AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility]) +AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path]) +AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path]) + +if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then + AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) +fi +if test -n "$PKG_CONFIG"; then + _pkg_min_version=m4_default([$1], [0.9.0]) + AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version]) + if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + PKG_CONFIG="" + fi +fi[]dnl +])dnl PKG_PROG_PKG_CONFIG + +dnl PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +dnl ------------------------------------------------------------------- +dnl Since: 0.18 +dnl +dnl Check to see whether a particular set of modules exists. Similar to +dnl PKG_CHECK_MODULES(), but does not set variables or print errors. +dnl +dnl Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG]) +dnl only at the first occurence in configure.ac, so if the first place +dnl it's called might be skipped (such as if it is within an "if", you +dnl have to call PKG_CHECK_EXISTS manually +AC_DEFUN([PKG_CHECK_EXISTS], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +if test -n "$PKG_CONFIG" && \ + AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then + m4_default([$2], [:]) +m4_ifvaln([$3], [else + $3])dnl +fi]) + +dnl _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) +dnl --------------------------------------------- +dnl Internal wrapper calling pkg-config via PKG_CONFIG and setting +dnl pkg_failed based on the result. +m4_define([_PKG_CONFIG], +[if test -n "$$1"; then + pkg_cv_[]$1="$$1" + elif test -n "$PKG_CONFIG"; then + PKG_CHECK_EXISTS([$3], + [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes ], + [pkg_failed=yes]) + else + pkg_failed=untried +fi[]dnl +])dnl _PKG_CONFIG + +dnl _PKG_SHORT_ERRORS_SUPPORTED +dnl --------------------------- +dnl Internal check to see if pkg-config supports short errors. +AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG]) +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi[]dnl +])dnl _PKG_SHORT_ERRORS_SUPPORTED + + +dnl PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], +dnl [ACTION-IF-NOT-FOUND]) +dnl -------------------------------------------------------------- +dnl Since: 0.4.0 +dnl +dnl Note that if there is a possibility the first call to +dnl PKG_CHECK_MODULES might not happen, you should be sure to include an +dnl explicit call to PKG_PROG_PKG_CONFIG in your configure.ac +AC_DEFUN([PKG_CHECK_MODULES], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl +AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl + +pkg_failed=no +AC_MSG_CHECKING([for $1]) + +_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) +_PKG_CONFIG([$1][_LIBS], [libs], [$2]) + +m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS +and $1[]_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details.]) + +if test $pkg_failed = yes; then + AC_MSG_RESULT([no]) + _PKG_SHORT_ERRORS_SUPPORTED + if test $_pkg_short_errors_supported = yes; then + $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1` + else + $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD + + m4_default([$4], [AC_MSG_ERROR( +[Package requirements ($2) were not met: + +$$1_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +_PKG_TEXT])[]dnl + ]) +elif test $pkg_failed = untried; then + AC_MSG_RESULT([no]) + m4_default([$4], [AC_MSG_FAILURE( +[The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +_PKG_TEXT + +To get pkg-config, see <http://pkg-config.freedesktop.org/>.])[]dnl + ]) +else + $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS + $1[]_LIBS=$pkg_cv_[]$1[]_LIBS + AC_MSG_RESULT([yes]) + $3 +fi[]dnl +])dnl PKG_CHECK_MODULES + + +dnl PKG_CHECK_MODULES_STATIC(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], +dnl [ACTION-IF-NOT-FOUND]) +dnl --------------------------------------------------------------------- +dnl Since: 0.29 +dnl +dnl Checks for existence of MODULES and gathers its build flags with +dnl static libraries enabled. Sets VARIABLE-PREFIX_CFLAGS from --cflags +dnl and VARIABLE-PREFIX_LIBS from --libs. +dnl +dnl Note that if there is a possibility the first call to +dnl PKG_CHECK_MODULES_STATIC might not happen, you should be sure to +dnl include an explicit call to PKG_PROG_PKG_CONFIG in your +dnl configure.ac. +AC_DEFUN([PKG_CHECK_MODULES_STATIC], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +_save_PKG_CONFIG=$PKG_CONFIG +PKG_CONFIG="$PKG_CONFIG --static" +PKG_CHECK_MODULES($@) +PKG_CONFIG=$_save_PKG_CONFIG[]dnl +])dnl PKG_CHECK_MODULES_STATIC + + +dnl PKG_INSTALLDIR([DIRECTORY]) +dnl ------------------------- +dnl Since: 0.27 +dnl +dnl Substitutes the variable pkgconfigdir as the location where a module +dnl should install pkg-config .pc files. By default the directory is +dnl $libdir/pkgconfig, but the default can be changed by passing +dnl DIRECTORY. The user can override through the --with-pkgconfigdir +dnl parameter. +AC_DEFUN([PKG_INSTALLDIR], +[m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])]) +m4_pushdef([pkg_description], + [pkg-config installation directory @<:@]pkg_default[@:>@]) +AC_ARG_WITH([pkgconfigdir], + [AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],, + [with_pkgconfigdir=]pkg_default) +AC_SUBST([pkgconfigdir], [$with_pkgconfigdir]) +m4_popdef([pkg_default]) +m4_popdef([pkg_description]) +])dnl PKG_INSTALLDIR + + +dnl PKG_NOARCH_INSTALLDIR([DIRECTORY]) +dnl -------------------------------- +dnl Since: 0.27 +dnl +dnl Substitutes the variable noarch_pkgconfigdir as the location where a +dnl module should install arch-independent pkg-config .pc files. By +dnl default the directory is $datadir/pkgconfig, but the default can be +dnl changed by passing DIRECTORY. The user can override through the +dnl --with-noarch-pkgconfigdir parameter. +AC_DEFUN([PKG_NOARCH_INSTALLDIR], +[m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])]) +m4_pushdef([pkg_description], + [pkg-config arch-independent installation directory @<:@]pkg_default[@:>@]) +AC_ARG_WITH([noarch-pkgconfigdir], + [AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],, + [with_noarch_pkgconfigdir=]pkg_default) +AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir]) +m4_popdef([pkg_default]) +m4_popdef([pkg_description]) +])dnl PKG_NOARCH_INSTALLDIR + + +dnl PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE, +dnl [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +dnl ------------------------------------------- +dnl Since: 0.28 +dnl +dnl Retrieves the value of the pkg-config variable for the given module. +AC_DEFUN([PKG_CHECK_VAR], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl + +_PKG_CONFIG([$1], [variable="][$3]["], [$2]) +AS_VAR_COPY([$1], [pkg_cv_][$1]) + +AS_VAR_IF([$1], [""], [$5], [$4])dnl +])dnl PKG_CHECK_VAR diff --git a/config/snprintfv.m4 b/config/snprintfv.m4 new file mode 100644 index 0000000..02d6fd0 --- /dev/null +++ b/config/snprintfv.m4 @@ -0,0 +1,98 @@ + +dnl AC_SNPRINTFV_CONVENIENCE[(dir)] - sets LIBSNPRINTFV to the link flags for +dnl the snprintfv convenience library and INCSNPRINTFV to the include flags for +dnl the snprintfv header and adds --enable-snprintfv-convenience to the +dnl configure arguments. Note that AC_CONFIG_SUBDIRS is not called. If DIR +dnl is not provided, it is assumed to be `snprintfv'. LIBSNPRINTFV will be +dnl prefixed with '${top_builddir}/' and INCSNPRINTFV will be prefixed with +dnl '${top_srcdir}/' (note the single quotes!). If your package is not +dnl flat and you're not using automake, define top_builddir and +dnl top_srcdir appropriately in the Makefiles. +AC_DEFUN([AC_SNPRINTFV_CONVENIENCE], +[case $enable_snprintfv_convenience in + no) AC_MSG_ERROR([this package needs a convenience snprintfv]) ;; + "") enable_snprintfv_convenience=yes + ac_configure_args="$ac_configure_args --enable-snprintfv-convenience" ;; + esac + LIBSNPRINTFV='${top_builddir}/'ifelse($#,1,[$1],['snprintfv'])/snprintfv/libsnprintfvc.la + INCSNPRINTFV='-I${top_builddir}/'ifelse($#,1,[$1],['snprintfv'])' -I${top_srcdir}/'ifelse($#,1,[$1],['snprintfv']) + AC_SUBST(LIBSNPRINTFV) + AC_SUBST(INCSNPRINTFV) +]) + +AC_DEFUN([INVOKE_SNPRINTFV_MACROS],[ + AC_SNPRINTFV_CONVENIENCE + # ---------------------------------------------------------------------- + # Set up and process configure options + # ---------------------------------------------------------------------- + AC_ARG_ENABLE(snprintfv-install, + [ --enable-snprintfv-install install libsnprintfv [yes]]) + AM_CONDITIONAL(INSTALL_SNPRINTFV, + test x"${enable_snprintfv_install-no}" != xno) + AM_CONDITIONAL(CONVENIENCE_SNPRINTFV, + test x"${enable_snprintfv_convenience-no}" != xno) + AM_CONDITIONAL(SUBDIR_SNPRINTFV, + test x"${enable_subdir-no}" != xno) + + AM_WITH_DMALLOC + AC_PROG_AWK + + # ---------------------------------------------------------------------- + # check for various programs used during the build. + # On OS/X, "wchar.h" needs "runetype.h" to work properly. + # ---------------------------------------------------------------------- + AC_CHECK_HEADERS([runetype.h wchar.h], [], [],[ + AC_INCLUDES_DEFAULT + #if HAVE_RUNETYPE_H + # include <runetype.h> + #endif + ]) + dnl am_cv_prog_cc_stdc is set by AC_PROG_CC_STDC + case x$am_cv_prog_cc_stdc in + xno) + # Non ansi C => won't work with stdarg.h + AC_CHECK_HEADER(varargs.h) + ;; + *) + case x$ac_cv_header_varargs_h in + xyes) + # Parent package is using varargs.h which is incompatible with + # stdarg.h, so we do the same. + AC_CHECK_HEADER(varargs.h) + ;; + *) + # If stdarg.h is present define HAVE_STDARG_H, otherwise if varargs.h + # is present define HAVE_VARARGS_H. + AC_CHECK_HEADERS(stdarg.h varargs.h, break) + ;; + esac + ;; + esac + + case x$ac_cv_header_stdarg_h$ac_cv_header_varargs_h in + x*yes*) ;; + *) AC_MSG_ERROR(Could not find either stdarg.h or varargs.h.) ;; + esac + + # ---------------------------------------------------------------------- + # Checks for typedefs + # ---------------------------------------------------------------------- + AC_CHECK_TYPES(wchar_t) + AC_CHECK_TYPES(wint_t, [], [], [ + AC_INCLUDES_DEFAULT + #if HAVE_RUNETYPE_H + # include <runetype.h> + #endif + #if HAVE_WCHAR_H + # include <wchar.h> + #endif + ]) + AC_CHECK_TYPES([long double]) + + # ---------------------------------------------------------------------- + # Checks for library calls + # ---------------------------------------------------------------------- + AC_REPLACE_FUNCS(strtoul ldexpl frexpl) + AC_CHECK_LIB(m, log) + AC_CHECK_FUNCS(copysign copysignl) +]) diff --git a/config/stdnoreturn.m4 b/config/stdnoreturn.m4 new file mode 100644 index 0000000..a7ce376 --- /dev/null +++ b/config/stdnoreturn.m4 @@ -0,0 +1,51 @@ +# Check for stdnoreturn.h that conforms to C11. + +dnl Copyright 2012-2018 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. + +# Prepare for substituting <stdnoreturn.h> if it is not supported. + +AC_DEFUN([gl_STDNORETURN_H], +[ + AC_REQUIRE([AC_CANONICAL_HOST]) + case "$host_os" in + cygwin*) + dnl Regardless whether a working <stdnoreturn.h> exists or not, + dnl we need our own <stdnoreturn.h>, because of the definition + dnl of _Noreturn done by gnulib-common.m4. + STDNORETURN_H='stdnoreturn.h' + ;; + *) + AC_CACHE_CHECK([for working stdnoreturn.h], + [gl_cv_header_working_stdnoreturn_h], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[#include <stdlib.h> + #include <stdnoreturn.h> + /* Do not check for 'noreturn' after the return type. + C11 allows it, but it's rarely done that way + and circa-2012 bleeding-edge GCC rejects it when given + -Werror=old-style-declaration. */ + noreturn void foo1 (void) { exit (0); } + _Noreturn void foo2 (void) { exit (0); } + int testit (int argc, char **argv) + { + if (argc & 1) + return 0; + (argv[0][0] ? foo1 : foo2) (); + } + ]])], + [gl_cv_header_working_stdnoreturn_h=yes], + [gl_cv_header_working_stdnoreturn_h=no])]) + if test $gl_cv_header_working_stdnoreturn_h = yes; then + STDNORETURN_H='' + else + STDNORETURN_H='stdnoreturn.h' + fi + ;; + esac + AC_SUBST([STDNORETURN_H]) + AM_CONDITIONAL([GL_GENERATE_STDNORETURN_H], [test -n "$STDNORETURN_H"]) +]) diff --git a/config/test-driver b/config/test-driver new file mode 100755 index 0000000..b8521a4 --- /dev/null +++ b/config/test-driver @@ -0,0 +1,148 @@ +#! /bin/sh +# test-driver - basic testsuite driver script. + +scriptversion=2018-03-07.03; # UTC + +# Copyright (C) 2011-2018 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. If not, see <https://www.gnu.org/licenses/>. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# This file is maintained in Automake, please report +# bugs to <bug-automake@gnu.org> or send patches to +# <automake-patches@gnu.org>. + +# Make unconditional expansion of undefined variables an error. This +# helps a lot in preventing typo-related bugs. +set -u + +usage_error () +{ + echo "$0: $*" >&2 + print_usage >&2 + exit 2 +} + +print_usage () +{ + cat <<END +Usage: + test-driver --test-name=NAME --log-file=PATH --trs-file=PATH + [--expect-failure={yes|no}] [--color-tests={yes|no}] + [--enable-hard-errors={yes|no}] [--] + TEST-SCRIPT [TEST-SCRIPT-ARGUMENTS] +The '--test-name', '--log-file' and '--trs-file' options are mandatory. +END +} + +test_name= # Used for reporting. +log_file= # Where to save the output of the test script. +trs_file= # Where to save the metadata of the test run. +expect_failure=no +color_tests=no +enable_hard_errors=yes +while test $# -gt 0; do + case $1 in + --help) print_usage; exit $?;; + --version) echo "test-driver $scriptversion"; exit $?;; + --test-name) test_name=$2; shift;; + --log-file) log_file=$2; shift;; + --trs-file) trs_file=$2; shift;; + --color-tests) color_tests=$2; shift;; + --expect-failure) expect_failure=$2; shift;; + --enable-hard-errors) enable_hard_errors=$2; shift;; + --) shift; break;; + -*) usage_error "invalid option: '$1'";; + *) break;; + esac + shift +done + +missing_opts= +test x"$test_name" = x && missing_opts="$missing_opts --test-name" +test x"$log_file" = x && missing_opts="$missing_opts --log-file" +test x"$trs_file" = x && missing_opts="$missing_opts --trs-file" +if test x"$missing_opts" != x; then + usage_error "the following mandatory options are missing:$missing_opts" +fi + +if test $# -eq 0; then + usage_error "missing argument" +fi + +if test $color_tests = yes; then + # Keep this in sync with 'lib/am/check.am:$(am__tty_colors)'. + red='' # Red. + grn='' # Green. + lgn='' # Light green. + blu='' # Blue. + mgn='' # Magenta. + std='' # No color. +else + red= grn= lgn= blu= mgn= std= +fi + +do_exit='rm -f $log_file $trs_file; (exit $st); exit $st' +trap "st=129; $do_exit" 1 +trap "st=130; $do_exit" 2 +trap "st=141; $do_exit" 13 +trap "st=143; $do_exit" 15 + +# Test script is run here. +"$@" >$log_file 2>&1 +estatus=$? + +if test $enable_hard_errors = no && test $estatus -eq 99; then + tweaked_estatus=1 +else + tweaked_estatus=$estatus +fi + +case $tweaked_estatus:$expect_failure in + 0:yes) col=$red res=XPASS recheck=yes gcopy=yes;; + 0:*) col=$grn res=PASS recheck=no gcopy=no;; + 77:*) col=$blu res=SKIP recheck=no gcopy=yes;; + 99:*) col=$mgn res=ERROR recheck=yes gcopy=yes;; + *:yes) col=$lgn res=XFAIL recheck=no gcopy=yes;; + *:*) col=$red res=FAIL recheck=yes gcopy=yes;; +esac + +# Report the test outcome and exit status in the logs, so that one can +# know whether the test passed or failed simply by looking at the '.log' +# file, without the need of also peaking into the corresponding '.trs' +# file (automake bug#11814). +echo "$res $test_name (exit status: $estatus)" >>$log_file + +# Report outcome to console. +echo "${col}${res}${std}: $test_name" + +# Register the test result, and other relevant metadata. +echo ":test-result: $res" > $trs_file +echo ":global-test-result: $res" >> $trs_file +echo ":recheck: $recheck" >> $trs_file +echo ":copy-in-global-log: $gcopy" >> $trs_file + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC0" +# time-stamp-end: "; # UTC" +# End: diff --git a/config/texinfo.tex b/config/texinfo.tex new file mode 100644 index 0000000..ac5c1d9 --- /dev/null +++ b/config/texinfo.tex @@ -0,0 +1,11727 @@ +% texinfo.tex -- TeX macros to handle Texinfo files. +% +% Load plain if necessary, i.e., if running under initex. +\expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi +% +\def\texinfoversion{2018-02-12.17} +% +% Copyright 1985, 1986, 1988, 1990, 1991, 1992, 1993, 1994, 1995, +% 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, +% 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 +% Free Software Foundation, Inc. +% +% This texinfo.tex file is free software: you can redistribute it and/or +% modify it under the terms of the GNU General Public License as +% published by the Free Software Foundation, either version 3 of the +% License, or (at your option) any later version. +% +% This texinfo.tex file is distributed in the hope that 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 <https://www.gnu.org/licenses/>. +% +% As a special exception, when this file is read by TeX when processing +% a Texinfo source document, you may use the result without +% restriction. This Exception is an additional permission under section 7 +% of the GNU General Public License, version 3 ("GPLv3"). +% +% Please try the latest version of texinfo.tex before submitting bug +% reports; you can get the latest version from: +% https://ftp.gnu.org/gnu/texinfo/ (the Texinfo release area), or +% https://ftpmirror.gnu.org/texinfo/ (same, via a mirror), or +% https://www.gnu.org/software/texinfo/ (the Texinfo home page) +% The texinfo.tex in any given distribution could well be out +% of date, so if that's what you're using, please check. +% +% Send bug reports to bug-texinfo@gnu.org. Please include including a +% complete document in each bug report with which we can reproduce the +% problem. Patches are, of course, greatly appreciated. +% +% To process a Texinfo manual with TeX, it's most reliable to use the +% texi2dvi shell script that comes with the distribution. For a simple +% manual foo.texi, however, you can get away with this: +% tex foo.texi +% texindex foo.?? +% tex foo.texi +% tex foo.texi +% dvips foo.dvi -o # or whatever; this makes foo.ps. +% The extra TeX runs get the cross-reference information correct. +% Sometimes one run after texindex suffices, and sometimes you need more +% than two; texi2dvi does it as many times as necessary. +% +% It is possible to adapt texinfo.tex for other languages, to some +% extent. You can get the existing language-specific files from the +% full Texinfo distribution. +% +% The GNU Texinfo home page is https://www.gnu.org/software/texinfo. + + +\message{Loading texinfo [version \texinfoversion]:} + +% If in a .fmt file, print the version number +% and turn on active characters that we couldn't do earlier because +% they might have appeared in the input file name. +\everyjob{\message{[Texinfo version \texinfoversion]}% + \catcode`+=\active \catcode`\_=\active} + +% LaTeX's \typeout. This ensures that the messages it is used for +% are identical in format to the corresponding ones from latex/pdflatex. +\def\typeout{\immediate\write17}% + +\chardef\other=12 + +% We never want plain's \outer definition of \+ in Texinfo. +% For @tex, we can use \tabalign. +\let\+ = \relax + +% Save some plain tex macros whose names we will redefine. +\let\ptexb=\b +\let\ptexbullet=\bullet +\let\ptexc=\c +\let\ptexcomma=\, +\let\ptexdot=\. +\let\ptexdots=\dots +\let\ptexend=\end +\let\ptexequiv=\equiv +\let\ptexexclam=\! +\let\ptexfootnote=\footnote +\let\ptexgtr=> +\let\ptexhat=^ +\let\ptexi=\i +\let\ptexindent=\indent +\let\ptexinsert=\insert +\let\ptexlbrace=\{ +\let\ptexless=< +\let\ptexnewwrite\newwrite +\let\ptexnoindent=\noindent +\let\ptexplus=+ +\let\ptexraggedright=\raggedright +\let\ptexrbrace=\} +\let\ptexslash=\/ +\let\ptexsp=\sp +\let\ptexstar=\* +\let\ptexsup=\sup +\let\ptext=\t +\let\ptextop=\top +{\catcode`\'=\active \global\let\ptexquoteright'}% active in plain's math mode + +% If this character appears in an error message or help string, it +% starts a new line in the output. +\newlinechar = `^^J + +% Use TeX 3.0's \inputlineno to get the line number, for better error +% messages, but if we're using an old version of TeX, don't do anything. +% +\ifx\inputlineno\thisisundefined + \let\linenumber = \empty % Pre-3.0. +\else + \def\linenumber{l.\the\inputlineno:\space} +\fi + +% Set up fixed words for English if not already set. +\ifx\putwordAppendix\undefined \gdef\putwordAppendix{Appendix}\fi +\ifx\putwordChapter\undefined \gdef\putwordChapter{Chapter}\fi +\ifx\putworderror\undefined \gdef\putworderror{error}\fi +\ifx\putwordfile\undefined \gdef\putwordfile{file}\fi +\ifx\putwordin\undefined \gdef\putwordin{in}\fi +\ifx\putwordIndexIsEmpty\undefined \gdef\putwordIndexIsEmpty{(Index is empty)}\fi +\ifx\putwordIndexNonexistent\undefined \gdef\putwordIndexNonexistent{(Index is nonexistent)}\fi +\ifx\putwordInfo\undefined \gdef\putwordInfo{Info}\fi +\ifx\putwordInstanceVariableof\undefined \gdef\putwordInstanceVariableof{Instance Variable of}\fi +\ifx\putwordMethodon\undefined \gdef\putwordMethodon{Method on}\fi +\ifx\putwordNoTitle\undefined \gdef\putwordNoTitle{No Title}\fi +\ifx\putwordof\undefined \gdef\putwordof{of}\fi +\ifx\putwordon\undefined \gdef\putwordon{on}\fi +\ifx\putwordpage\undefined \gdef\putwordpage{page}\fi +\ifx\putwordsection\undefined \gdef\putwordsection{section}\fi +\ifx\putwordSection\undefined \gdef\putwordSection{Section}\fi +\ifx\putwordsee\undefined \gdef\putwordsee{see}\fi +\ifx\putwordSee\undefined \gdef\putwordSee{See}\fi +\ifx\putwordShortTOC\undefined \gdef\putwordShortTOC{Short Contents}\fi +\ifx\putwordTOC\undefined \gdef\putwordTOC{Table of Contents}\fi +% +\ifx\putwordMJan\undefined \gdef\putwordMJan{January}\fi +\ifx\putwordMFeb\undefined \gdef\putwordMFeb{February}\fi +\ifx\putwordMMar\undefined \gdef\putwordMMar{March}\fi +\ifx\putwordMApr\undefined \gdef\putwordMApr{April}\fi +\ifx\putwordMMay\undefined \gdef\putwordMMay{May}\fi +\ifx\putwordMJun\undefined \gdef\putwordMJun{June}\fi +\ifx\putwordMJul\undefined \gdef\putwordMJul{July}\fi +\ifx\putwordMAug\undefined \gdef\putwordMAug{August}\fi +\ifx\putwordMSep\undefined \gdef\putwordMSep{September}\fi +\ifx\putwordMOct\undefined \gdef\putwordMOct{October}\fi +\ifx\putwordMNov\undefined \gdef\putwordMNov{November}\fi +\ifx\putwordMDec\undefined \gdef\putwordMDec{December}\fi +% +\ifx\putwordDefmac\undefined \gdef\putwordDefmac{Macro}\fi +\ifx\putwordDefspec\undefined \gdef\putwordDefspec{Special Form}\fi +\ifx\putwordDefvar\undefined \gdef\putwordDefvar{Variable}\fi +\ifx\putwordDefopt\undefined \gdef\putwordDefopt{User Option}\fi +\ifx\putwordDeffunc\undefined \gdef\putwordDeffunc{Function}\fi + +% Give the space character the catcode for a space. +\def\spaceisspace{\catcode`\ =10\relax} + +% Likewise for ^^M, the end of line character. +\def\endlineisspace{\catcode13=10\relax} + +\chardef\dashChar = `\- +\chardef\slashChar = `\/ +\chardef\underChar = `\_ + +% Ignore a token. +% +\def\gobble#1{} + +% The following is used inside several \edef's. +\def\makecsname#1{\expandafter\noexpand\csname#1\endcsname} + +% Hyphenation fixes. +\hyphenation{ + Flor-i-da Ghost-script Ghost-view Mac-OS Post-Script + auto-ma-ti-cal-ly ap-pen-dix bit-map bit-maps + data-base data-bases eshell fall-ing half-way long-est man-u-script + man-u-scripts mini-buf-fer mini-buf-fers over-view par-a-digm + par-a-digms rath-er rec-tan-gu-lar ro-bot-ics se-vere-ly set-up spa-ces + spell-ing spell-ings + stand-alone strong-est time-stamp time-stamps which-ever white-space + wide-spread wrap-around +} + +% Sometimes it is convenient to have everything in the transcript file +% and nothing on the terminal. We don't just call \tracingall here, +% since that produces some useless output on the terminal. We also make +% some effort to order the tracing commands to reduce output in the log +% file; cf. trace.sty in LaTeX. +% +\def\gloggingall{\begingroup \globaldefs = 1 \loggingall \endgroup}% +\def\loggingall{% + \tracingstats2 + \tracingpages1 + \tracinglostchars2 % 2 gives us more in etex + \tracingparagraphs1 + \tracingoutput1 + \tracingmacros2 + \tracingrestores1 + \showboxbreadth\maxdimen \showboxdepth\maxdimen + \ifx\eTeXversion\thisisundefined\else % etex gives us more logging + \tracingscantokens1 + \tracingifs1 + \tracinggroups1 + \tracingnesting2 + \tracingassigns1 + \fi + \tracingcommands3 % 3 gives us more in etex + \errorcontextlines16 +}% + +% @errormsg{MSG}. Do the index-like expansions on MSG, but if things +% aren't perfect, it's not the end of the world, being an error message, +% after all. +% +\def\errormsg{\begingroup \indexnofonts \doerrormsg} +\def\doerrormsg#1{\errmessage{#1}} + +% add check for \lastpenalty to plain's definitions. If the last thing +% we did was a \nobreak, we don't want to insert more space. +% +\def\smallbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\smallskipamount + \removelastskip\penalty-50\smallskip\fi\fi} +\def\medbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\medskipamount + \removelastskip\penalty-100\medskip\fi\fi} +\def\bigbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\bigskipamount + \removelastskip\penalty-200\bigskip\fi\fi} + +% Output routine +% + +% For a final copy, take out the rectangles +% that mark overfull boxes (in case you have decided +% that the text looks ok even though it passes the margin). +% +\def\finalout{\overfullrule=0pt } + +% Do @cropmarks to get crop marks. +% +\newif\ifcropmarks +\let\cropmarks = \cropmarkstrue +% +% Dimensions to add cropmarks at corners. +% Added by P. A. MacKay, 12 Nov. 1986 +% +\newdimen\outerhsize \newdimen\outervsize % set by the paper size routines +\newdimen\cornerlong \cornerlong=1pc +\newdimen\cornerthick \cornerthick=.3pt +\newdimen\topandbottommargin \topandbottommargin=.75in + +% Output a mark which sets \thischapter, \thissection and \thiscolor. +% We dump everything together because we only have one kind of mark. +% This works because we only use \botmark / \topmark, not \firstmark. +% +% A mark contains a subexpression of the \ifcase ... \fi construct. +% \get*marks macros below extract the needed part using \ifcase. +% +% Another complication is to let the user choose whether \thischapter +% (\thissection) refers to the chapter (section) in effect at the top +% of a page, or that at the bottom of a page. + +% \domark is called twice inside \chapmacro, to add one +% mark before the section break, and one after. +% In the second call \prevchapterdefs is the same as \lastchapterdefs, +% and \prevsectiondefs is the same as \lastsectiondefs. +% Then if the page is not broken at the mark, some of the previous +% section appears on the page, and we can get the name of this section +% from \firstmark for @everyheadingmarks top. +% @everyheadingmarks bottom uses \botmark. +% +% See page 260 of The TeXbook. +\def\domark{% + \toks0=\expandafter{\lastchapterdefs}% + \toks2=\expandafter{\lastsectiondefs}% + \toks4=\expandafter{\prevchapterdefs}% + \toks6=\expandafter{\prevsectiondefs}% + \toks8=\expandafter{\lastcolordefs}% + \mark{% + \the\toks0 \the\toks2 % 0: marks for @everyheadingmarks top + \noexpand\or \the\toks4 \the\toks6 % 1: for @everyheadingmarks bottom + \noexpand\else \the\toks8 % 2: color marks + }% +} + +% \gettopheadingmarks, \getbottomheadingmarks, +% \getcolormarks - extract needed part of mark. +% +% \topmark doesn't work for the very first chapter (after the title +% page or the contents), so we use \firstmark there -- this gets us +% the mark with the chapter defs, unless the user sneaks in, e.g., +% @setcolor (or @url, or @link, etc.) between @contents and the very +% first @chapter. +\def\gettopheadingmarks{% + \ifcase0\topmark\fi + \ifx\thischapter\empty \ifcase0\firstmark\fi \fi +} +\def\getbottomheadingmarks{\ifcase1\botmark\fi} +\def\getcolormarks{\ifcase2\topmark\fi} + +% Avoid "undefined control sequence" errors. +\def\lastchapterdefs{} +\def\lastsectiondefs{} +\def\lastsection{} +\def\prevchapterdefs{} +\def\prevsectiondefs{} +\def\lastcolordefs{} + +% Margin to add to right of even pages, to left of odd pages. +\newdimen\bindingoffset +\newdimen\normaloffset +\newdimen\txipagewidth \newdimen\txipageheight + +% Main output routine. +% +\chardef\PAGE = 255 +\output = {\onepageout{\pagecontents\PAGE}} + +\newbox\headlinebox +\newbox\footlinebox + +% \onepageout takes a vbox as an argument. +% \shipout a vbox for a single page, adding an optional header, footer, +% cropmarks, and footnote. This also causes index entries for this page +% to be written to the auxiliary files. +% +\def\onepageout#1{% + \ifcropmarks \hoffset=0pt \else \hoffset=\normaloffset \fi + % + \ifodd\pageno \advance\hoffset by \bindingoffset + \else \advance\hoffset by -\bindingoffset\fi + % + % Common context changes for both heading and footing. + % Do this outside of the \shipout so @code etc. will be expanded in + % the headline as they should be, not taken literally (outputting ''code). + \def\commmonheadfootline{\let\hsize=\txipagewidth \texinfochars} + % + % Retrieve the information for the headings from the marks in the page, + % and call Plain TeX's \makeheadline and \makefootline, which use the + % values in \headline and \footline. + % + % This is used to check if we are on the first page of a chapter. + \ifcase1\topmark\fi + \let\prevchaptername\thischaptername + \ifcase0\firstmark\fi + \let\curchaptername\thischaptername + % + \ifodd\pageno \getoddheadingmarks \else \getevenheadingmarks \fi + \ifodd\pageno \getoddfootingmarks \else \getevenfootingmarks \fi + % + \ifx\curchaptername\prevchaptername + \let\thischapterheading\thischapter + \else + % \thischapterheading is the same as \thischapter except it is blank + % for the first page of a chapter. This is to prevent the chapter name + % being shown twice. + \def\thischapterheading{}% + \fi + % + \global\setbox\headlinebox = \vbox{\commmonheadfootline \makeheadline}% + \global\setbox\footlinebox = \vbox{\commmonheadfootline \makefootline}% + % + {% + % Set context for writing to auxiliary files like index files. + % Have to do this stuff outside the \shipout because we want it to + % take effect in \write's, yet the group defined by the \vbox ends + % before the \shipout runs. + % + \indexdummies % don't expand commands in the output. + \normalturnoffactive % \ in index entries must not stay \, e.g., if + % the page break happens to be in the middle of an example. + % We don't want .vr (or whatever) entries like this: + % \entry{{\indexbackslash }acronym}{32}{\code {\acronym}} + % "\acronym" won't work when it's read back in; + % it needs to be + % {\code {{\backslashcurfont }acronym} + \shipout\vbox{% + % Do this early so pdf references go to the beginning of the page. + \ifpdfmakepagedest \pdfdest name{\the\pageno} xyz\fi + % + \ifcropmarks \vbox to \outervsize\bgroup + \hsize = \outerhsize + \vskip-\topandbottommargin + \vtop to0pt{% + \line{\ewtop\hfil\ewtop}% + \nointerlineskip + \line{% + \vbox{\moveleft\cornerthick\nstop}% + \hfill + \vbox{\moveright\cornerthick\nstop}% + }% + \vss}% + \vskip\topandbottommargin + \line\bgroup + \hfil % center the page within the outer (page) hsize. + \ifodd\pageno\hskip\bindingoffset\fi + \vbox\bgroup + \fi + % + \unvbox\headlinebox + \pagebody{#1}% + \ifdim\ht\footlinebox > 0pt + % Only leave this space if the footline is nonempty. + % (We lessened \vsize for it in \oddfootingyyy.) + % The \baselineskip=24pt in plain's \makefootline has no effect. + \vskip 24pt + \unvbox\footlinebox + \fi + % + \ifcropmarks + \egroup % end of \vbox\bgroup + \hfil\egroup % end of (centering) \line\bgroup + \vskip\topandbottommargin plus1fill minus1fill + \boxmaxdepth = \cornerthick + \vbox to0pt{\vss + \line{% + \vbox{\moveleft\cornerthick\nsbot}% + \hfill + \vbox{\moveright\cornerthick\nsbot}% + }% + \nointerlineskip + \line{\ewbot\hfil\ewbot}% + }% + \egroup % \vbox from first cropmarks clause + \fi + }% end of \shipout\vbox + }% end of group with \indexdummies + \advancepageno + \ifnum\outputpenalty>-20000 \else\dosupereject\fi +} + +\newinsert\margin \dimen\margin=\maxdimen + +% Main part of page, including any footnotes +\def\pagebody#1{\vbox to\txipageheight{\boxmaxdepth=\maxdepth #1}} +{\catcode`\@ =11 +\gdef\pagecontents#1{\ifvoid\topins\else\unvbox\topins\fi +% marginal hacks, juha@viisa.uucp (Juha Takala) +\ifvoid\margin\else % marginal info is present + \rlap{\kern\hsize\vbox to\z@{\kern1pt\box\margin \vss}}\fi +\dimen@=\dp#1\relax \unvbox#1\relax +\ifvoid\footins\else\vskip\skip\footins\footnoterule \unvbox\footins\fi +\ifr@ggedbottom \kern-\dimen@ \vfil \fi} +} + +% Here are the rules for the cropmarks. Note that they are +% offset so that the space between them is truly \outerhsize or \outervsize +% (P. A. MacKay, 12 November, 1986) +% +\def\ewtop{\vrule height\cornerthick depth0pt width\cornerlong} +\def\nstop{\vbox + {\hrule height\cornerthick depth\cornerlong width\cornerthick}} +\def\ewbot{\vrule height0pt depth\cornerthick width\cornerlong} +\def\nsbot{\vbox + {\hrule height\cornerlong depth\cornerthick width\cornerthick}} + + +% Argument parsing + +% Parse an argument, then pass it to #1. The argument is the rest of +% the input line (except we remove a trailing comment). #1 should be a +% macro which expects an ordinary undelimited TeX argument. +% For example, \def\foo{\parsearg\fooxxx}. +% +\def\parsearg{\parseargusing{}} +\def\parseargusing#1#2{% + \def\argtorun{#2}% + \begingroup + \obeylines + \spaceisspace + #1% + \parseargline\empty% Insert the \empty token, see \finishparsearg below. +} + +{\obeylines % + \gdef\parseargline#1^^M{% + \endgroup % End of the group started in \parsearg. + \argremovecomment #1\comment\ArgTerm% + }% +} + +% First remove any @comment, then any @c comment. Also remove a @texinfoc +% comment (see \scanmacro for details). Pass the result on to \argcheckspaces. +\def\argremovecomment#1\comment#2\ArgTerm{\argremovec #1\c\ArgTerm} +\def\argremovec#1\c#2\ArgTerm{\argremovetexinfoc #1\texinfoc\ArgTerm} +\def\argremovetexinfoc#1\texinfoc#2\ArgTerm{\argcheckspaces#1\^^M\ArgTerm} + +% Each occurrence of `\^^M' or `<space>\^^M' is replaced by a single space. +% +% \argremovec might leave us with trailing space, e.g., +% @end itemize @c foo +% This space token undergoes the same procedure and is eventually removed +% by \finishparsearg. +% +\def\argcheckspaces#1\^^M{\argcheckspacesX#1\^^M \^^M} +\def\argcheckspacesX#1 \^^M{\argcheckspacesY#1\^^M} +\def\argcheckspacesY#1\^^M#2\^^M#3\ArgTerm{% + \def\temp{#3}% + \ifx\temp\empty + % Do not use \next, perhaps the caller of \parsearg uses it; reuse \temp: + \let\temp\finishparsearg + \else + \let\temp\argcheckspaces + \fi + % Put the space token in: + \temp#1 #3\ArgTerm +} + +% If a _delimited_ argument is enclosed in braces, they get stripped; so +% to get _exactly_ the rest of the line, we had to prevent such situation. +% We prepended an \empty token at the very beginning and we expand it now, +% just before passing the control to \argtorun. +% (Similarly, we have to think about #3 of \argcheckspacesY above: it is +% either the null string, or it ends with \^^M---thus there is no danger +% that a pair of braces would be stripped. +% +% But first, we have to remove the trailing space token. +% +\def\finishparsearg#1 \ArgTerm{\expandafter\argtorun\expandafter{#1}} + + +% \parseargdef - define a command taking an argument on the line +% +% \parseargdef\foo{...} +% is roughly equivalent to +% \def\foo{\parsearg\Xfoo} +% \def\Xfoo#1{...} +\def\parseargdef#1{% + \expandafter \doparseargdef \csname\string#1\endcsname #1% +} +\def\doparseargdef#1#2{% + \def#2{\parsearg#1}% + \def#1##1% +} + +% Several utility definitions with active space: +{ + \obeyspaces + \gdef\obeyedspace{ } + + % Make each space character in the input produce a normal interword + % space in the output. Don't allow a line break at this space, as this + % is used only in environments like @example, where each line of input + % should produce a line of output anyway. + % + \gdef\sepspaces{\obeyspaces\let =\tie} + + % If an index command is used in an @example environment, any spaces + % therein should become regular spaces in the raw index file, not the + % expansion of \tie (\leavevmode \penalty \@M \ ). + \gdef\unsepspaces{\let =\space} +} + + +\def\flushcr{\ifx\par\lisppar \def\next##1{}\else \let\next=\relax \fi \next} + +% Define the framework for environments in texinfo.tex. It's used like this: +% +% \envdef\foo{...} +% \def\Efoo{...} +% +% It's the responsibility of \envdef to insert \begingroup before the +% actual body; @end closes the group after calling \Efoo. \envdef also +% defines \thisenv, so the current environment is known; @end checks +% whether the environment name matches. The \checkenv macro can also be +% used to check whether the current environment is the one expected. +% +% Non-false conditionals (@iftex, @ifset) don't fit into this, so they +% are not treated as environments; they don't open a group. (The +% implementation of @end takes care not to call \endgroup in this +% special case.) + + +% At run-time, environments start with this: +\def\startenvironment#1{\begingroup\def\thisenv{#1}} +% initialize +\let\thisenv\empty + +% ... but they get defined via ``\envdef\foo{...}'': +\long\def\envdef#1#2{\def#1{\startenvironment#1#2}} +\def\envparseargdef#1#2{\parseargdef#1{\startenvironment#1#2}} + +% Check whether we're in the right environment: +\def\checkenv#1{% + \def\temp{#1}% + \ifx\thisenv\temp + \else + \badenverr + \fi +} + +% Environment mismatch, #1 expected: +\def\badenverr{% + \errhelp = \EMsimple + \errmessage{This command can appear only \inenvironment\temp, + not \inenvironment\thisenv}% +} +\def\inenvironment#1{% + \ifx#1\empty + outside of any environment% + \else + in environment \expandafter\string#1% + \fi +} + +% @end foo executes the definition of \Efoo. +% But first, it executes a specialized version of \checkenv +% +\parseargdef\end{% + \if 1\csname iscond.#1\endcsname + \else + % The general wording of \badenverr may not be ideal. + \expandafter\checkenv\csname#1\endcsname + \csname E#1\endcsname + \endgroup + \fi +} + +\newhelp\EMsimple{Press RETURN to continue.} + + +% Be sure we're in horizontal mode when doing a tie, since we make space +% equivalent to this in @example-like environments. Otherwise, a space +% at the beginning of a line will start with \penalty -- and +% since \penalty is valid in vertical mode, we'd end up putting the +% penalty on the vertical list instead of in the new paragraph. +{\catcode`@ = 11 + % Avoid using \@M directly, because that causes trouble + % if the definition is written into an index file. + \global\let\tiepenalty = \@M + \gdef\tie{\leavevmode\penalty\tiepenalty\ } +} + +% @: forces normal size whitespace following. +\def\:{\spacefactor=1000 } + +% @* forces a line break. +\def\*{\unskip\hfil\break\hbox{}\ignorespaces} + +% @/ allows a line break. +\let\/=\allowbreak + +% @. is an end-of-sentence period. +\def\.{.\spacefactor=\endofsentencespacefactor\space} + +% @! is an end-of-sentence bang. +\def\!{!\spacefactor=\endofsentencespacefactor\space} + +% @? is an end-of-sentence query. +\def\?{?\spacefactor=\endofsentencespacefactor\space} + +% @frenchspacing on|off says whether to put extra space after punctuation. +% +\def\onword{on} +\def\offword{off} +% +\parseargdef\frenchspacing{% + \def\temp{#1}% + \ifx\temp\onword \plainfrenchspacing + \else\ifx\temp\offword \plainnonfrenchspacing + \else + \errhelp = \EMsimple + \errmessage{Unknown @frenchspacing option `\temp', must be on|off}% + \fi\fi +} + +% @w prevents a word break. Without the \leavevmode, @w at the +% beginning of a paragraph, when TeX is still in vertical mode, would +% produce a whole line of output instead of starting the paragraph. +\def\w#1{\leavevmode\hbox{#1}} + +% @group ... @end group forces ... to be all on one page, by enclosing +% it in a TeX vbox. We use \vtop instead of \vbox to construct the box +% to keep its height that of a normal line. According to the rules for +% \topskip (p.114 of the TeXbook), the glue inserted is +% max (\topskip - \ht (first item), 0). If that height is large, +% therefore, no glue is inserted, and the space between the headline and +% the text is small, which looks bad. +% +% Another complication is that the group might be very large. This can +% cause the glue on the previous page to be unduly stretched, because it +% does not have much material. In this case, it's better to add an +% explicit \vfill so that the extra space is at the bottom. The +% threshold for doing this is if the group is more than \vfilllimit +% percent of a page (\vfilllimit can be changed inside of @tex). +% +\newbox\groupbox +\def\vfilllimit{0.7} +% +\envdef\group{% + \ifnum\catcode`\^^M=\active \else + \errhelp = \groupinvalidhelp + \errmessage{@group invalid in context where filling is enabled}% + \fi + \startsavinginserts + % + \setbox\groupbox = \vtop\bgroup + % Do @comment since we are called inside an environment such as + % @example, where each end-of-line in the input causes an + % end-of-line in the output. We don't want the end-of-line after + % the `@group' to put extra space in the output. Since @group + % should appear on a line by itself (according to the Texinfo + % manual), we don't worry about eating any user text. + \comment +} +% +% The \vtop produces a box with normal height and large depth; thus, TeX puts +% \baselineskip glue before it, and (when the next line of text is done) +% \lineskip glue after it. Thus, space below is not quite equal to space +% above. But it's pretty close. +\def\Egroup{% + % To get correct interline space between the last line of the group + % and the first line afterwards, we have to propagate \prevdepth. + \endgraf % Not \par, as it may have been set to \lisppar. + \global\dimen1 = \prevdepth + \egroup % End the \vtop. + \addgroupbox + \prevdepth = \dimen1 + \checkinserts +} + +\def\addgroupbox{ + % \dimen0 is the vertical size of the group's box. + \dimen0 = \ht\groupbox \advance\dimen0 by \dp\groupbox + % \dimen2 is how much space is left on the page (more or less). + \dimen2 = \txipageheight \advance\dimen2 by -\pagetotal + % if the group doesn't fit on the current page, and it's a big big + % group, force a page break. + \ifdim \dimen0 > \dimen2 + \ifdim \pagetotal < \vfilllimit\txipageheight + \page + \fi + \fi + \box\groupbox +} + +% +% TeX puts in an \escapechar (i.e., `@') at the beginning of the help +% message, so this ends up printing `@group can only ...'. +% +\newhelp\groupinvalidhelp{% +group can only be used in environments such as @example,^^J% +where each line of input produces a line of output.} + +% @need space-in-mils +% forces a page break if there is not space-in-mils remaining. + +\newdimen\mil \mil=0.001in + +\parseargdef\need{% + % Ensure vertical mode, so we don't make a big box in the middle of a + % paragraph. + \par + % + % If the @need value is less than one line space, it's useless. + \dimen0 = #1\mil + \dimen2 = \ht\strutbox + \advance\dimen2 by \dp\strutbox + \ifdim\dimen0 > \dimen2 + % + % Do a \strut just to make the height of this box be normal, so the + % normal leading is inserted relative to the preceding line. + % And a page break here is fine. + \vtop to #1\mil{\strut\vfil}% + % + % TeX does not even consider page breaks if a penalty added to the + % main vertical list is 10000 or more. But in order to see if the + % empty box we just added fits on the page, we must make it consider + % page breaks. On the other hand, we don't want to actually break the + % page after the empty box. So we use a penalty of 9999. + % + % There is an extremely small chance that TeX will actually break the + % page at this \penalty, if there are no other feasible breakpoints in + % sight. (If the user is using lots of big @group commands, which + % almost-but-not-quite fill up a page, TeX will have a hard time doing + % good page breaking, for example.) However, I could not construct an + % example where a page broke at this \penalty; if it happens in a real + % document, then we can reconsider our strategy. + \penalty9999 + % + % Back up by the size of the box, whether we did a page break or not. + \kern -#1\mil + % + % Do not allow a page break right after this kern. + \nobreak + \fi +} + +% @br forces paragraph break (and is undocumented). + +\let\br = \par + +% @page forces the start of a new page. +% +\def\page{\par\vfill\supereject} + +% @exdent text.... +% outputs text on separate line in roman font, starting at standard page margin + +% This records the amount of indent in the innermost environment. +% That's how much \exdent should take out. +\newskip\exdentamount + +% This defn is used inside fill environments such as @defun. +\parseargdef\exdent{\hfil\break\hbox{\kern -\exdentamount{\rm#1}}\hfil\break} + +% This defn is used inside nofill environments such as @example. +\parseargdef\nofillexdent{{\advance \leftskip by -\exdentamount + \leftline{\hskip\leftskip{\rm#1}}}} + +% @inmargin{WHICH}{TEXT} puts TEXT in the WHICH margin next to the current +% paragraph. For more general purposes, use the \margin insertion +% class. WHICH is `l' or `r'. Not documented, written for gawk manual. +% +\newskip\inmarginspacing \inmarginspacing=1cm +\def\strutdepth{\dp\strutbox} +% +\def\doinmargin#1#2{\strut\vadjust{% + \nobreak + \kern-\strutdepth + \vtop to \strutdepth{% + \baselineskip=\strutdepth + \vss + % if you have multiple lines of stuff to put here, you'll need to + % make the vbox yourself of the appropriate size. + \ifx#1l% + \llap{\ignorespaces #2\hskip\inmarginspacing}% + \else + \rlap{\hskip\hsize \hskip\inmarginspacing \ignorespaces #2}% + \fi + \null + }% +}} +\def\inleftmargin{\doinmargin l} +\def\inrightmargin{\doinmargin r} +% +% @inmargin{TEXT [, RIGHT-TEXT]} +% (if RIGHT-TEXT is given, use TEXT for left page, RIGHT-TEXT for right; +% else use TEXT for both). +% +\def\inmargin#1{\parseinmargin #1,,\finish} +\def\parseinmargin#1,#2,#3\finish{% not perfect, but better than nothing. + \setbox0 = \hbox{\ignorespaces #2}% + \ifdim\wd0 > 0pt + \def\lefttext{#1}% have both texts + \def\righttext{#2}% + \else + \def\lefttext{#1}% have only one text + \def\righttext{#1}% + \fi + % + \ifodd\pageno + \def\temp{\inrightmargin\righttext}% odd page -> outside is right margin + \else + \def\temp{\inleftmargin\lefttext}% + \fi + \temp +} + +% @include FILE -- \input text of FILE. +% +\def\include{\parseargusing\filenamecatcodes\includezzz} +\def\includezzz#1{% + \pushthisfilestack + \def\thisfile{#1}% + {% + \makevalueexpandable % we want to expand any @value in FILE. + \turnoffactive % and allow special characters in the expansion + \indexnofonts % Allow `@@' and other weird things in file names. + \wlog{texinfo.tex: doing @include of #1^^J}% + \edef\temp{\noexpand\input #1 }% + % + % This trickery is to read FILE outside of a group, in case it makes + % definitions, etc. + \expandafter + }\temp + \popthisfilestack +} +\def\filenamecatcodes{% + \catcode`\\=\other + \catcode`~=\other + \catcode`^=\other + \catcode`_=\other + \catcode`|=\other + \catcode`<=\other + \catcode`>=\other + \catcode`+=\other + \catcode`-=\other + \catcode`\`=\other + \catcode`\'=\other +} + +\def\pushthisfilestack{% + \expandafter\pushthisfilestackX\popthisfilestack\StackTerm +} +\def\pushthisfilestackX{% + \expandafter\pushthisfilestackY\thisfile\StackTerm +} +\def\pushthisfilestackY #1\StackTerm #2\StackTerm {% + \gdef\popthisfilestack{\gdef\thisfile{#1}\gdef\popthisfilestack{#2}}% +} + +\def\popthisfilestack{\errthisfilestackempty} +\def\errthisfilestackempty{\errmessage{Internal error: + the stack of filenames is empty.}} +% +\def\thisfile{} + +% @center line +% outputs that line, centered. +% +\parseargdef\center{% + \ifhmode + \let\centersub\centerH + \else + \let\centersub\centerV + \fi + \centersub{\hfil \ignorespaces#1\unskip \hfil}% + \let\centersub\relax % don't let the definition persist, just in case +} +\def\centerH#1{{% + \hfil\break + \advance\hsize by -\leftskip + \advance\hsize by -\rightskip + \line{#1}% + \break +}} +% +\newcount\centerpenalty +\def\centerV#1{% + % The idea here is the same as in \startdefun, \cartouche, etc.: if + % @center is the first thing after a section heading, we need to wipe + % out the negative parskip inserted by \sectionheading, but still + % prevent a page break here. + \centerpenalty = \lastpenalty + \ifnum\centerpenalty>10000 \vskip\parskip \fi + \ifnum\centerpenalty>9999 \penalty\centerpenalty \fi + \line{\kern\leftskip #1\kern\rightskip}% +} + +% @sp n outputs n lines of vertical space +% +\parseargdef\sp{\vskip #1\baselineskip} + +% @comment ...line which is ignored... +% @c is the same as @comment +% @ignore ... @end ignore is another way to write a comment + + +\def\c{\begingroup \catcode`\^^M=\active% +\catcode`\@=\other \catcode`\{=\other \catcode`\}=\other% +\cxxx} +{\catcode`\^^M=\active \gdef\cxxx#1^^M{\endgroup}} +% +\let\comment\c + +% @paragraphindent NCHARS +% We'll use ems for NCHARS, close enough. +% NCHARS can also be the word `asis' or `none'. +% We cannot feasibly implement @paragraphindent asis, though. +% +\def\asisword{asis} % no translation, these are keywords +\def\noneword{none} +% +\parseargdef\paragraphindent{% + \def\temp{#1}% + \ifx\temp\asisword + \else + \ifx\temp\noneword + \defaultparindent = 0pt + \else + \defaultparindent = #1em + \fi + \fi + \parindent = \defaultparindent +} + +% @exampleindent NCHARS +% We'll use ems for NCHARS like @paragraphindent. +% It seems @exampleindent asis isn't necessary, but +% I preserve it to make it similar to @paragraphindent. +\parseargdef\exampleindent{% + \def\temp{#1}% + \ifx\temp\asisword + \else + \ifx\temp\noneword + \lispnarrowing = 0pt + \else + \lispnarrowing = #1em + \fi + \fi +} + +% @firstparagraphindent WORD +% If WORD is `none', then suppress indentation of the first paragraph +% after a section heading. If WORD is `insert', then do indent at such +% paragraphs. +% +% The paragraph indentation is suppressed or not by calling +% \suppressfirstparagraphindent, which the sectioning commands do. +% We switch the definition of this back and forth according to WORD. +% By default, we suppress indentation. +% +\def\suppressfirstparagraphindent{\dosuppressfirstparagraphindent} +\def\insertword{insert} +% +\parseargdef\firstparagraphindent{% + \def\temp{#1}% + \ifx\temp\noneword + \let\suppressfirstparagraphindent = \dosuppressfirstparagraphindent + \else\ifx\temp\insertword + \let\suppressfirstparagraphindent = \relax + \else + \errhelp = \EMsimple + \errmessage{Unknown @firstparagraphindent option `\temp'}% + \fi\fi +} + +% Here is how we actually suppress indentation. Redefine \everypar to +% \kern backwards by \parindent, and then reset itself to empty. +% +% We also make \indent itself not actually do anything until the next +% paragraph. +% +\gdef\dosuppressfirstparagraphindent{% + \gdef\indent {\restorefirstparagraphindent \indent}% + \gdef\noindent{\restorefirstparagraphindent \noindent}% + \global\everypar = {\kern -\parindent \restorefirstparagraphindent}% +} +% +\gdef\restorefirstparagraphindent{% + \global\let\indent = \ptexindent + \global\let\noindent = \ptexnoindent + \global\everypar = {}% +} + + +% @refill is a no-op. +\let\refill=\relax + +% @setfilename INFO-FILENAME - ignored +\let\setfilename=\comment + +% @bye. +\outer\def\bye{\pagealignmacro\tracingstats=1\ptexend} + + +\message{pdf,} +% adobe `portable' document format +\newcount\tempnum +\newcount\lnkcount +\newtoks\filename +\newcount\filenamelength +\newcount\pgn +\newtoks\toksA +\newtoks\toksB +\newtoks\toksC +\newtoks\toksD +\newbox\boxA +\newbox\boxB +\newcount\countA +\newif\ifpdf +\newif\ifpdfmakepagedest + +% +% For LuaTeX +% + +\newif\iftxiuseunicodedestname +\txiuseunicodedestnamefalse % For pdfTeX etc. + +\ifx\luatexversion\thisisundefined +\else + % Use Unicode destination names + \txiuseunicodedestnametrue + % Escape PDF strings with converting UTF-16 from UTF-8 + \begingroup + \catcode`\%=12 + \directlua{ + function UTF16oct(str) + tex.sprint(string.char(0x5c) .. '376' .. string.char(0x5c) .. '377') + for c in string.utfvalues(str) do + if c < 0x10000 then + tex.sprint( + string.format(string.char(0x5c) .. string.char(0x25) .. '03o' .. + string.char(0x5c) .. string.char(0x25) .. '03o', + (c / 256), (c % 256))) + else + c = c - 0x10000 + local c_hi = c / 1024 + 0xd800 + local c_lo = c % 1024 + 0xdc00 + tex.sprint( + string.format(string.char(0x5c) .. string.char(0x25) .. '03o' .. + string.char(0x5c) .. string.char(0x25) .. '03o' .. + string.char(0x5c) .. string.char(0x25) .. '03o' .. + string.char(0x5c) .. string.char(0x25) .. '03o', + (c_hi / 256), (c_hi % 256), + (c_lo / 256), (c_lo % 256))) + end + end + end + } + \endgroup + \def\pdfescapestrutfsixteen#1{\directlua{UTF16oct('\luaescapestring{#1}')}} + % Escape PDF strings without converting + \begingroup + \directlua{ + function PDFescstr(str) + for c in string.bytes(str) do + if c <= 0x20 or c >= 0x80 or c == 0x28 or c == 0x29 or c == 0x5c then + tex.sprint( + string.format(string.char(0x5c) .. string.char(0x25) .. '03o', + c)) + else + tex.sprint(string.char(c)) + end + end + end + } + \endgroup + \def\pdfescapestring#1{\directlua{PDFescstr('\luaescapestring{#1}')}} + \ifnum\luatexversion>84 + % For LuaTeX >= 0.85 + \def\pdfdest{\pdfextension dest} + \let\pdfoutput\outputmode + \def\pdfliteral{\pdfextension literal} + \def\pdfcatalog{\pdfextension catalog} + \def\pdftexversion{\numexpr\pdffeedback version\relax} + \let\pdfximage\saveimageresource + \let\pdfrefximage\useimageresource + \let\pdflastximage\lastsavedimageresourceindex + \def\pdfendlink{\pdfextension endlink\relax} + \def\pdfoutline{\pdfextension outline} + \def\pdfstartlink{\pdfextension startlink} + \def\pdffontattr{\pdfextension fontattr} + \def\pdfobj{\pdfextension obj} + \def\pdflastobj{\numexpr\pdffeedback lastobj\relax} + \let\pdfpagewidth\pagewidth + \let\pdfpageheight\pageheight + \edef\pdfhorigin{\pdfvariable horigin} + \edef\pdfvorigin{\pdfvariable vorigin} + \fi +\fi + +% when pdftex is run in dvi mode, \pdfoutput is defined (so \pdfoutput=1 +% can be set). So we test for \relax and 0 as well as being undefined. +\ifx\pdfoutput\thisisundefined +\else + \ifx\pdfoutput\relax + \else + \ifcase\pdfoutput + \else + \pdftrue + \fi + \fi +\fi + +% PDF uses PostScript string constants for the names of xref targets, +% for display in the outlines, and in other places. Thus, we have to +% double any backslashes. Otherwise, a name like "\node" will be +% interpreted as a newline (\n), followed by o, d, e. Not good. +% +% See http://www.ntg.nl/pipermail/ntg-pdftex/2004-July/000654.html and +% related messages. The final outcome is that it is up to the TeX user +% to double the backslashes and otherwise make the string valid, so +% that's what we do. pdftex 1.30.0 (ca.2005) introduced a primitive to +% do this reliably, so we use it. + +% #1 is a control sequence in which to do the replacements, +% which we \xdef. +\def\txiescapepdf#1{% + \ifx\pdfescapestring\thisisundefined + % No primitive available; should we give a warning or log? + % Many times it won't matter. + \xdef#1{#1}% + \else + % The expandable \pdfescapestring primitive escapes parentheses, + % backslashes, and other special chars. + \xdef#1{\pdfescapestring{#1}}% + \fi +} +\def\txiescapepdfutfsixteen#1{% + \ifx\pdfescapestrutfsixteen\thisisundefined + % No UTF-16 converting macro available. + \txiescapepdf{#1}% + \else + \xdef#1{\pdfescapestrutfsixteen{#1}}% + \fi +} + +\newhelp\nopdfimagehelp{Texinfo supports .png, .jpg, .jpeg, and .pdf images +with PDF output, and none of those formats could be found. (.eps cannot +be supported due to the design of the PDF format; use regular TeX (DVI +output) for that.)} + +\ifpdf + % + % Color manipulation macros using ideas from pdfcolor.tex, + % except using rgb instead of cmyk; the latter is said to render as a + % very dark gray on-screen and a very dark halftone in print, instead + % of actual black. The dark red here is dark enough to print on paper as + % nearly black, but still distinguishable for online viewing. We use + % black by default, though. + \def\rgbDarkRed{0.50 0.09 0.12} + \def\rgbBlack{0 0 0} + % + % rg sets the color for filling (usual text, etc.); + % RG sets the color for stroking (thin rules, e.g., normal _'s). + \def\pdfsetcolor#1{\pdfliteral{#1 rg #1 RG}} + % + % Set color, and create a mark which defines \thiscolor accordingly, + % so that \makeheadline knows which color to restore. + \def\setcolor#1{% + \xdef\lastcolordefs{\gdef\noexpand\thiscolor{#1}}% + \domark + \pdfsetcolor{#1}% + } + % + \def\maincolor{\rgbBlack} + \pdfsetcolor{\maincolor} + \edef\thiscolor{\maincolor} + \def\lastcolordefs{} + % + \def\makefootline{% + \baselineskip24pt + \line{\pdfsetcolor{\maincolor}\the\footline}% + } + % + \def\makeheadline{% + \vbox to 0pt{% + \vskip-22.5pt + \line{% + \vbox to8.5pt{}% + % Extract \thiscolor definition from the marks. + \getcolormarks + % Typeset the headline with \maincolor, then restore the color. + \pdfsetcolor{\maincolor}\the\headline\pdfsetcolor{\thiscolor}% + }% + \vss + }% + \nointerlineskip + } + % + % + \pdfcatalog{/PageMode /UseOutlines} + % + % #1 is image name, #2 width (might be empty/whitespace), #3 height (ditto). + \def\dopdfimage#1#2#3{% + \def\pdfimagewidth{#2}\setbox0 = \hbox{\ignorespaces #2}% + \def\pdfimageheight{#3}\setbox2 = \hbox{\ignorespaces #3}% + % + % pdftex (and the PDF format) support .pdf, .png, .jpg (among + % others). Let's try in that order, PDF first since if + % someone has a scalable image, presumably better to use that than a + % bitmap. + \let\pdfimgext=\empty + \begingroup + \openin 1 #1.pdf \ifeof 1 + \openin 1 #1.PDF \ifeof 1 + \openin 1 #1.png \ifeof 1 + \openin 1 #1.jpg \ifeof 1 + \openin 1 #1.jpeg \ifeof 1 + \openin 1 #1.JPG \ifeof 1 + \errhelp = \nopdfimagehelp + \errmessage{Could not find image file #1 for pdf}% + \else \gdef\pdfimgext{JPG}% + \fi + \else \gdef\pdfimgext{jpeg}% + \fi + \else \gdef\pdfimgext{jpg}% + \fi + \else \gdef\pdfimgext{png}% + \fi + \else \gdef\pdfimgext{PDF}% + \fi + \else \gdef\pdfimgext{pdf}% + \fi + \closein 1 + \endgroup + % + % without \immediate, ancient pdftex seg faults when the same image is + % included twice. (Version 3.14159-pre-1.0-unofficial-20010704.) + \ifnum\pdftexversion < 14 + \immediate\pdfimage + \else + \immediate\pdfximage + \fi + \ifdim \wd0 >0pt width \pdfimagewidth \fi + \ifdim \wd2 >0pt height \pdfimageheight \fi + \ifnum\pdftexversion<13 + #1.\pdfimgext + \else + {#1.\pdfimgext}% + \fi + \ifnum\pdftexversion < 14 \else + \pdfrefximage \pdflastximage + \fi} + % + \def\setpdfdestname#1{{% + % We have to set dummies so commands such as @code, and characters + % such as \, aren't expanded when present in a section title. + \indexnofonts + \makevalueexpandable + \turnoffactive + \iftxiuseunicodedestname + \ifx \declaredencoding \latone + % Pass through Latin-1 characters. + % LuaTeX with byte wise I/O converts Latin-1 characters to Unicode. + \else + \ifx \declaredencoding \utfeight + % Pass through Unicode characters. + \else + % Use ASCII approximations in destination names. + \passthroughcharsfalse + \fi + \fi + \else + % Use ASCII approximations in destination names. + \passthroughcharsfalse + \fi + \def\pdfdestname{#1}% + \txiescapepdf\pdfdestname + }} + % + \def\setpdfoutlinetext#1{{% + \indexnofonts + \makevalueexpandable + \turnoffactive + \ifx \declaredencoding \latone + % The PDF format can use an extended form of Latin-1 in bookmark + % strings. See Appendix D of the PDF Reference, Sixth Edition, for + % the "PDFDocEncoding". + \passthroughcharstrue + % Pass through Latin-1 characters. + % LuaTeX: Convert to Unicode + % pdfTeX: Use Latin-1 as PDFDocEncoding + \def\pdfoutlinetext{#1}% + \else + \ifx \declaredencoding \utfeight + \ifx\luatexversion\thisisundefined + % For pdfTeX with UTF-8. + % TODO: the PDF format can use UTF-16 in bookmark strings, + % but the code for this isn't done yet. + % Use ASCII approximations. + \passthroughcharsfalse + \def\pdfoutlinetext{#1}% + \else + % For LuaTeX with UTF-8. + % Pass through Unicode characters for title texts. + \passthroughcharstrue + \def\pdfoutlinetext{#1}% + \fi + \else + % For non-Latin-1 or non-UTF-8 encodings. + % Use ASCII approximations. + \passthroughcharsfalse + \def\pdfoutlinetext{#1}% + \fi + \fi + % LuaTeX: Convert to UTF-16 + % pdfTeX: Use Latin-1 as PDFDocEncoding + \txiescapepdfutfsixteen\pdfoutlinetext + }} + % + \def\pdfmkdest#1{% + \setpdfdestname{#1}% + \safewhatsit{\pdfdest name{\pdfdestname} xyz}% + } + % + % used to mark target names; must be expandable. + \def\pdfmkpgn#1{#1} + % + % by default, use black for everything. + \def\urlcolor{\rgbBlack} + \def\linkcolor{\rgbBlack} + \def\endlink{\setcolor{\maincolor}\pdfendlink} + % + % Adding outlines to PDF; macros for calculating structure of outlines + % come from Petr Olsak + \def\expnumber#1{\expandafter\ifx\csname#1\endcsname\relax 0% + \else \csname#1\endcsname \fi} + \def\advancenumber#1{\tempnum=\expnumber{#1}\relax + \advance\tempnum by 1 + \expandafter\xdef\csname#1\endcsname{\the\tempnum}} + % + % #1 is the section text, which is what will be displayed in the + % outline by the pdf viewer. #2 is the pdf expression for the number + % of subentries (or empty, for subsubsections). #3 is the node text, + % which might be empty if this toc entry had no corresponding node. + % #4 is the page number + % + \def\dopdfoutline#1#2#3#4{% + % Generate a link to the node text if that exists; else, use the + % page number. We could generate a destination for the section + % text in the case where a section has no node, but it doesn't + % seem worth the trouble, since most documents are normally structured. + \setpdfoutlinetext{#1} + \setpdfdestname{#3} + \ifx\pdfdestname\empty + \def\pdfdestname{#4}% + \fi + % + \pdfoutline goto name{\pdfmkpgn{\pdfdestname}}#2{\pdfoutlinetext}% + } + % + \def\pdfmakeoutlines{% + \begingroup + % Read toc silently, to get counts of subentries for \pdfoutline. + \def\partentry##1##2##3##4{}% ignore parts in the outlines + \def\numchapentry##1##2##3##4{% + \def\thischapnum{##2}% + \def\thissecnum{0}% + \def\thissubsecnum{0}% + }% + \def\numsecentry##1##2##3##4{% + \advancenumber{chap\thischapnum}% + \def\thissecnum{##2}% + \def\thissubsecnum{0}% + }% + \def\numsubsecentry##1##2##3##4{% + \advancenumber{sec\thissecnum}% + \def\thissubsecnum{##2}% + }% + \def\numsubsubsecentry##1##2##3##4{% + \advancenumber{subsec\thissubsecnum}% + }% + \def\thischapnum{0}% + \def\thissecnum{0}% + \def\thissubsecnum{0}% + % + % use \def rather than \let here because we redefine \chapentry et + % al. a second time, below. + \def\appentry{\numchapentry}% + \def\appsecentry{\numsecentry}% + \def\appsubsecentry{\numsubsecentry}% + \def\appsubsubsecentry{\numsubsubsecentry}% + \def\unnchapentry{\numchapentry}% + \def\unnsecentry{\numsecentry}% + \def\unnsubsecentry{\numsubsecentry}% + \def\unnsubsubsecentry{\numsubsubsecentry}% + \readdatafile{toc}% + % + % Read toc second time, this time actually producing the outlines. + % The `-' means take the \expnumber as the absolute number of + % subentries, which we calculated on our first read of the .toc above. + % + % We use the node names as the destinations. + \def\numchapentry##1##2##3##4{% + \dopdfoutline{##1}{count-\expnumber{chap##2}}{##3}{##4}}% + \def\numsecentry##1##2##3##4{% + \dopdfoutline{##1}{count-\expnumber{sec##2}}{##3}{##4}}% + \def\numsubsecentry##1##2##3##4{% + \dopdfoutline{##1}{count-\expnumber{subsec##2}}{##3}{##4}}% + \def\numsubsubsecentry##1##2##3##4{% count is always zero + \dopdfoutline{##1}{}{##3}{##4}}% + % + % PDF outlines are displayed using system fonts, instead of + % document fonts. Therefore we cannot use special characters, + % since the encoding is unknown. For example, the eogonek from + % Latin 2 (0xea) gets translated to a | character. Info from + % Staszek Wawrykiewicz, 19 Jan 2004 04:09:24 +0100. + % + % TODO this right, we have to translate 8-bit characters to + % their "best" equivalent, based on the @documentencoding. Too + % much work for too little return. Just use the ASCII equivalents + % we use for the index sort strings. + % + \indexnofonts + \setupdatafile + % We can have normal brace characters in the PDF outlines, unlike + % Texinfo index files. So set that up. + \def\{{\lbracecharliteral}% + \def\}{\rbracecharliteral}% + \catcode`\\=\active \otherbackslash + \input \tocreadfilename + \endgroup + } + {\catcode`[=1 \catcode`]=2 + \catcode`{=\other \catcode`}=\other + \gdef\lbracecharliteral[{]% + \gdef\rbracecharliteral[}]% + ] + % + \def\skipspaces#1{\def\PP{#1}\def\D{|}% + \ifx\PP\D\let\nextsp\relax + \else\let\nextsp\skipspaces + \addtokens{\filename}{\PP}% + \advance\filenamelength by 1 + \fi + \nextsp} + \def\getfilename#1{% + \filenamelength=0 + % If we don't expand the argument now, \skipspaces will get + % snagged on things like "@value{foo}". + \edef\temp{#1}% + \expandafter\skipspaces\temp|\relax + } + \ifnum\pdftexversion < 14 + \let \startlink \pdfannotlink + \else + \let \startlink \pdfstartlink + \fi + % make a live url in pdf output. + \def\pdfurl#1{% + \begingroup + % it seems we really need yet another set of dummies; have not + % tried to figure out what each command should do in the context + % of @url. for now, just make @/ a no-op, that's the only one + % people have actually reported a problem with. + % + \normalturnoffactive + \def\@{@}% + \let\/=\empty + \makevalueexpandable + % do we want to go so far as to use \indexnofonts instead of just + % special-casing \var here? + \def\var##1{##1}% + % + \leavevmode\setcolor{\urlcolor}% + \startlink attr{/Border [0 0 0]}% + user{/Subtype /Link /A << /S /URI /URI (#1) >>}% + \endgroup} + \def\pdfgettoks#1.{\setbox\boxA=\hbox{\toksA={#1.}\toksB={}\maketoks}} + \def\addtokens#1#2{\edef\addtoks{\noexpand#1={\the#1#2}}\addtoks} + \def\adn#1{\addtokens{\toksC}{#1}\global\countA=1\let\next=\maketoks} + \def\poptoks#1#2|ENDTOKS|{\let\first=#1\toksD={#1}\toksA={#2}} + \def\maketoks{% + \expandafter\poptoks\the\toksA|ENDTOKS|\relax + \ifx\first0\adn0 + \else\ifx\first1\adn1 \else\ifx\first2\adn2 \else\ifx\first3\adn3 + \else\ifx\first4\adn4 \else\ifx\first5\adn5 \else\ifx\first6\adn6 + \else\ifx\first7\adn7 \else\ifx\first8\adn8 \else\ifx\first9\adn9 + \else + \ifnum0=\countA\else\makelink\fi + \ifx\first.\let\next=\done\else + \let\next=\maketoks + \addtokens{\toksB}{\the\toksD} + \ifx\first,\addtokens{\toksB}{\space}\fi + \fi + \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi + \next} + \def\makelink{\addtokens{\toksB}% + {\noexpand\pdflink{\the\toksC}}\toksC={}\global\countA=0} + \def\pdflink#1{% + \startlink attr{/Border [0 0 0]} goto name{\pdfmkpgn{#1}} + \setcolor{\linkcolor}#1\endlink} + \def\done{\edef\st{\global\noexpand\toksA={\the\toksB}}\st} +\else + % non-pdf mode + \let\pdfmkdest = \gobble + \let\pdfurl = \gobble + \let\endlink = \relax + \let\setcolor = \gobble + \let\pdfsetcolor = \gobble + \let\pdfmakeoutlines = \relax +\fi % \ifx\pdfoutput + +% +% For XeTeX +% +\ifx\XeTeXrevision\thisisundefined +\else + % + % XeTeX version check + % + \ifnum\strcmp{\the\XeTeXversion\XeTeXrevision}{0.99996}>-1 + % TeX Live 2016 contains XeTeX 0.99996 and xdvipdfmx 20160307. + % It can use the `dvipdfmx:config' special (from TeX Live SVN r40941). + % For avoiding PDF destination name replacement, we use this special + % instead of xdvipdfmx's command line option `-C 0x0010'. + \special{dvipdfmx:config C 0x0010} + % XeTeX 0.99995+ comes with xdvipdfmx 20160307+. + % It can handle Unicode destination names for PDF. + \txiuseunicodedestnametrue + \else + % XeTeX < 0.99996 (TeX Live < 2016) cannot use the + % `dvipdfmx:config' special. + % So for avoiding PDF destination name replacement, + % xdvipdfmx's command line option `-C 0x0010' is necessary. + % + % XeTeX < 0.99995 can not handle Unicode destination names for PDF + % because xdvipdfmx 20150315 has a UTF-16 conversion issue. + % It is fixed by xdvipdfmx 20160106 (TeX Live SVN r39753). + \txiuseunicodedestnamefalse + \fi + % + % Color support + % + \def\rgbDarkRed{0.50 0.09 0.12} + \def\rgbBlack{0 0 0} + % + \def\pdfsetcolor#1{\special{pdf:scolor [#1]}} + % + % Set color, and create a mark which defines \thiscolor accordingly, + % so that \makeheadline knows which color to restore. + \def\setcolor#1{% + \xdef\lastcolordefs{\gdef\noexpand\thiscolor{#1}}% + \domark + \pdfsetcolor{#1}% + } + % + \def\maincolor{\rgbBlack} + \pdfsetcolor{\maincolor} + \edef\thiscolor{\maincolor} + \def\lastcolordefs{} + % + \def\makefootline{% + \baselineskip24pt + \line{\pdfsetcolor{\maincolor}\the\footline}% + } + % + \def\makeheadline{% + \vbox to 0pt{% + \vskip-22.5pt + \line{% + \vbox to8.5pt{}% + % Extract \thiscolor definition from the marks. + \getcolormarks + % Typeset the headline with \maincolor, then restore the color. + \pdfsetcolor{\maincolor}\the\headline\pdfsetcolor{\thiscolor}% + }% + \vss + }% + \nointerlineskip + } + % + % PDF outline support + % + % Emulate pdfTeX primitive + \def\pdfdest name#1 xyz{% + \special{pdf:dest (#1) [@thispage /XYZ @xpos @ypos null]}% + } + % + \def\setpdfdestname#1{{% + % We have to set dummies so commands such as @code, and characters + % such as \, aren't expanded when present in a section title. + \indexnofonts + \makevalueexpandable + \turnoffactive + \iftxiuseunicodedestname + % Pass through Unicode characters. + \else + % Use ASCII approximations in destination names. + \passthroughcharsfalse + \fi + \def\pdfdestname{#1}% + \txiescapepdf\pdfdestname + }} + % + \def\setpdfoutlinetext#1{{% + \turnoffactive + % Always use Unicode characters in title texts. + \def\pdfoutlinetext{#1}% + % For XeTeX, xdvipdfmx converts to UTF-16. + % So we do not convert. + \txiescapepdf\pdfoutlinetext + }} + % + \def\pdfmkdest#1{% + \setpdfdestname{#1}% + \safewhatsit{\pdfdest name{\pdfdestname} xyz}% + } + % + % by default, use black for everything. + \def\urlcolor{\rgbBlack} + \def\linkcolor{\rgbBlack} + \def\endlink{\setcolor{\maincolor}\pdfendlink} + % + \def\dopdfoutline#1#2#3#4{% + \setpdfoutlinetext{#1} + \setpdfdestname{#3} + \ifx\pdfdestname\empty + \def\pdfdestname{#4}% + \fi + % + \special{pdf:out [-] #2 << /Title (\pdfoutlinetext) /A + << /S /GoTo /D (\pdfdestname) >> >> }% + } + % + \def\pdfmakeoutlines{% + \begingroup + % + % For XeTeX, counts of subentries are not necessary. + % Therefore, we read toc only once. + % + % We use node names as destinations. + \def\partentry##1##2##3##4{}% ignore parts in the outlines + \def\numchapentry##1##2##3##4{% + \dopdfoutline{##1}{1}{##3}{##4}}% + \def\numsecentry##1##2##3##4{% + \dopdfoutline{##1}{2}{##3}{##4}}% + \def\numsubsecentry##1##2##3##4{% + \dopdfoutline{##1}{3}{##3}{##4}}% + \def\numsubsubsecentry##1##2##3##4{% + \dopdfoutline{##1}{4}{##3}{##4}}% + % + \let\appentry\numchapentry% + \let\appsecentry\numsecentry% + \let\appsubsecentry\numsubsecentry% + \let\appsubsubsecentry\numsubsubsecentry% + \let\unnchapentry\numchapentry% + \let\unnsecentry\numsecentry% + \let\unnsubsecentry\numsubsecentry% + \let\unnsubsubsecentry\numsubsubsecentry% + % + % For XeTeX, xdvipdfmx converts strings to UTF-16. + % Therefore, the encoding and the language may not be considered. + % + \indexnofonts + \setupdatafile + % We can have normal brace characters in the PDF outlines, unlike + % Texinfo index files. So set that up. + \def\{{\lbracecharliteral}% + \def\}{\rbracecharliteral}% + \catcode`\\=\active \otherbackslash + \input \tocreadfilename + \endgroup + } + {\catcode`[=1 \catcode`]=2 + \catcode`{=\other \catcode`}=\other + \gdef\lbracecharliteral[{]% + \gdef\rbracecharliteral[}]% + ] + + \special{pdf:docview << /PageMode /UseOutlines >> } + % ``\special{pdf:tounicode ...}'' is not necessary + % because xdvipdfmx converts strings from UTF-8 to UTF-16 without it. + % However, due to a UTF-16 conversion issue of xdvipdfmx 20150315, + % ``\special{pdf:dest ...}'' cannot handle non-ASCII strings. + % It is fixed by xdvipdfmx 20160106 (TeX Live SVN r39753). +% + \def\skipspaces#1{\def\PP{#1}\def\D{|}% + \ifx\PP\D\let\nextsp\relax + \else\let\nextsp\skipspaces + \addtokens{\filename}{\PP}% + \advance\filenamelength by 1 + \fi + \nextsp} + \def\getfilename#1{% + \filenamelength=0 + % If we don't expand the argument now, \skipspaces will get + % snagged on things like "@value{foo}". + \edef\temp{#1}% + \expandafter\skipspaces\temp|\relax + } + % make a live url in pdf output. + \def\pdfurl#1{% + \begingroup + % it seems we really need yet another set of dummies; have not + % tried to figure out what each command should do in the context + % of @url. for now, just make @/ a no-op, that's the only one + % people have actually reported a problem with. + % + \normalturnoffactive + \def\@{@}% + \let\/=\empty + \makevalueexpandable + % do we want to go so far as to use \indexnofonts instead of just + % special-casing \var here? + \def\var##1{##1}% + % + \leavevmode\setcolor{\urlcolor}% + \special{pdf:bann << /Border [0 0 0] + /Subtype /Link /A << /S /URI /URI (#1) >> >>}% + \endgroup} + \def\endlink{\setcolor{\maincolor}\special{pdf:eann}} + \def\pdfgettoks#1.{\setbox\boxA=\hbox{\toksA={#1.}\toksB={}\maketoks}} + \def\addtokens#1#2{\edef\addtoks{\noexpand#1={\the#1#2}}\addtoks} + \def\adn#1{\addtokens{\toksC}{#1}\global\countA=1\let\next=\maketoks} + \def\poptoks#1#2|ENDTOKS|{\let\first=#1\toksD={#1}\toksA={#2}} + \def\maketoks{% + \expandafter\poptoks\the\toksA|ENDTOKS|\relax + \ifx\first0\adn0 + \else\ifx\first1\adn1 \else\ifx\first2\adn2 \else\ifx\first3\adn3 + \else\ifx\first4\adn4 \else\ifx\first5\adn5 \else\ifx\first6\adn6 + \else\ifx\first7\adn7 \else\ifx\first8\adn8 \else\ifx\first9\adn9 + \else + \ifnum0=\countA\else\makelink\fi + \ifx\first.\let\next=\done\else + \let\next=\maketoks + \addtokens{\toksB}{\the\toksD} + \ifx\first,\addtokens{\toksB}{\space}\fi + \fi + \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi + \next} + \def\makelink{\addtokens{\toksB}% + {\noexpand\pdflink{\the\toksC}}\toksC={}\global\countA=0} + \def\pdflink#1{% + \special{pdf:bann << /Border [0 0 0] + /Type /Annot /Subtype /Link /A << /S /GoTo /D (#1) >> >>}% + \setcolor{\linkcolor}#1\endlink} + \def\done{\edef\st{\global\noexpand\toksA={\the\toksB}}\st} +% + % + % @image support + % + % #1 is image name, #2 width (might be empty/whitespace), #3 height (ditto). + \def\doxeteximage#1#2#3{% + \def\xeteximagewidth{#2}\setbox0 = \hbox{\ignorespaces #2}% + \def\xeteximageheight{#3}\setbox2 = \hbox{\ignorespaces #3}% + % + % XeTeX (and the PDF format) supports .pdf, .png, .jpg (among + % others). Let's try in that order, PDF first since if + % someone has a scalable image, presumably better to use that than a + % bitmap. + \let\xeteximgext=\empty + \begingroup + \openin 1 #1.pdf \ifeof 1 + \openin 1 #1.PDF \ifeof 1 + \openin 1 #1.png \ifeof 1 + \openin 1 #1.jpg \ifeof 1 + \openin 1 #1.jpeg \ifeof 1 + \openin 1 #1.JPG \ifeof 1 + \errmessage{Could not find image file #1 for XeTeX}% + \else \gdef\xeteximgext{JPG}% + \fi + \else \gdef\xeteximgext{jpeg}% + \fi + \else \gdef\xeteximgext{jpg}% + \fi + \else \gdef\xeteximgext{png}% + \fi + \else \gdef\xeteximgext{PDF}% + \fi + \else \gdef\xeteximgext{pdf}% + \fi + \closein 1 + \endgroup + % + \def\xetexpdfext{pdf}% + \ifx\xeteximgext\xetexpdfext + \XeTeXpdffile "#1".\xeteximgext "" + \else + \def\xetexpdfext{PDF}% + \ifx\xeteximgext\xetexpdfext + \XeTeXpdffile "#1".\xeteximgext "" + \else + \XeTeXpicfile "#1".\xeteximgext "" + \fi + \fi + \ifdim \wd0 >0pt width \xeteximagewidth \fi + \ifdim \wd2 >0pt height \xeteximageheight \fi \relax + } +\fi + + +% +\message{fonts,} + +% Set the baselineskip to #1, and the lineskip and strut size +% correspondingly. There is no deep meaning behind these magic numbers +% used as factors; they just match (closely enough) what Knuth defined. +% +\def\lineskipfactor{.08333} +\def\strutheightpercent{.70833} +\def\strutdepthpercent {.29167} +% +% can get a sort of poor man's double spacing by redefining this. +\def\baselinefactor{1} +% +\newdimen\textleading +\def\setleading#1{% + \dimen0 = #1\relax + \normalbaselineskip = \baselinefactor\dimen0 + \normallineskip = \lineskipfactor\normalbaselineskip + \normalbaselines + \setbox\strutbox =\hbox{% + \vrule width0pt height\strutheightpercent\baselineskip + depth \strutdepthpercent \baselineskip + }% +} + +% PDF CMaps. See also LaTeX's t1.cmap. +% +% do nothing with this by default. +\expandafter\let\csname cmapOT1\endcsname\gobble +\expandafter\let\csname cmapOT1IT\endcsname\gobble +\expandafter\let\csname cmapOT1TT\endcsname\gobble + +% if we are producing pdf, and we have \pdffontattr, then define cmaps. +% (\pdffontattr was introduced many years ago, but people still run +% older pdftex's; it's easy to conditionalize, so we do.) +\ifpdf \ifx\pdffontattr\thisisundefined \else + \begingroup + \catcode`\^^M=\active \def^^M{^^J}% Output line endings as the ^^J char. + \catcode`\%=12 \immediate\pdfobj stream {%!PS-Adobe-3.0 Resource-CMap +%%DocumentNeededResources: ProcSet (CIDInit) +%%IncludeResource: ProcSet (CIDInit) +%%BeginResource: CMap (TeX-OT1-0) +%%Title: (TeX-OT1-0 TeX OT1 0) +%%Version: 1.000 +%%EndComments +/CIDInit /ProcSet findresource begin +12 dict begin +begincmap +/CIDSystemInfo +<< /Registry (TeX) +/Ordering (OT1) +/Supplement 0 +>> def +/CMapName /TeX-OT1-0 def +/CMapType 2 def +1 begincodespacerange +<00> <7F> +endcodespacerange +8 beginbfrange +<00> <01> <0393> +<09> <0A> <03A8> +<23> <26> <0023> +<28> <3B> <0028> +<3F> <5B> <003F> +<5D> <5E> <005D> +<61> <7A> <0061> +<7B> <7C> <2013> +endbfrange +40 beginbfchar +<02> <0398> +<03> <039B> +<04> <039E> +<05> <03A0> +<06> <03A3> +<07> <03D2> +<08> <03A6> +<0B> <00660066> +<0C> <00660069> +<0D> <0066006C> +<0E> <006600660069> +<0F> <00660066006C> +<10> <0131> +<11> <0237> +<12> <0060> +<13> <00B4> +<14> <02C7> +<15> <02D8> +<16> <00AF> +<17> <02DA> +<18> <00B8> +<19> <00DF> +<1A> <00E6> +<1B> <0153> +<1C> <00F8> +<1D> <00C6> +<1E> <0152> +<1F> <00D8> +<21> <0021> +<22> <201D> +<27> <2019> +<3C> <00A1> +<3D> <003D> +<3E> <00BF> +<5C> <201C> +<5F> <02D9> +<60> <2018> +<7D> <02DD> +<7E> <007E> +<7F> <00A8> +endbfchar +endcmap +CMapName currentdict /CMap defineresource pop +end +end +%%EndResource +%%EOF + }\endgroup + \expandafter\edef\csname cmapOT1\endcsname#1{% + \pdffontattr#1{/ToUnicode \the\pdflastobj\space 0 R}% + }% +% +% \cmapOT1IT + \begingroup + \catcode`\^^M=\active \def^^M{^^J}% Output line endings as the ^^J char. + \catcode`\%=12 \immediate\pdfobj stream {%!PS-Adobe-3.0 Resource-CMap +%%DocumentNeededResources: ProcSet (CIDInit) +%%IncludeResource: ProcSet (CIDInit) +%%BeginResource: CMap (TeX-OT1IT-0) +%%Title: (TeX-OT1IT-0 TeX OT1IT 0) +%%Version: 1.000 +%%EndComments +/CIDInit /ProcSet findresource begin +12 dict begin +begincmap +/CIDSystemInfo +<< /Registry (TeX) +/Ordering (OT1IT) +/Supplement 0 +>> def +/CMapName /TeX-OT1IT-0 def +/CMapType 2 def +1 begincodespacerange +<00> <7F> +endcodespacerange +8 beginbfrange +<00> <01> <0393> +<09> <0A> <03A8> +<25> <26> <0025> +<28> <3B> <0028> +<3F> <5B> <003F> +<5D> <5E> <005D> +<61> <7A> <0061> +<7B> <7C> <2013> +endbfrange +42 beginbfchar +<02> <0398> +<03> <039B> +<04> <039E> +<05> <03A0> +<06> <03A3> +<07> <03D2> +<08> <03A6> +<0B> <00660066> +<0C> <00660069> +<0D> <0066006C> +<0E> <006600660069> +<0F> <00660066006C> +<10> <0131> +<11> <0237> +<12> <0060> +<13> <00B4> +<14> <02C7> +<15> <02D8> +<16> <00AF> +<17> <02DA> +<18> <00B8> +<19> <00DF> +<1A> <00E6> +<1B> <0153> +<1C> <00F8> +<1D> <00C6> +<1E> <0152> +<1F> <00D8> +<21> <0021> +<22> <201D> +<23> <0023> +<24> <00A3> +<27> <2019> +<3C> <00A1> +<3D> <003D> +<3E> <00BF> +<5C> <201C> +<5F> <02D9> +<60> <2018> +<7D> <02DD> +<7E> <007E> +<7F> <00A8> +endbfchar +endcmap +CMapName currentdict /CMap defineresource pop +end +end +%%EndResource +%%EOF + }\endgroup + \expandafter\edef\csname cmapOT1IT\endcsname#1{% + \pdffontattr#1{/ToUnicode \the\pdflastobj\space 0 R}% + }% +% +% \cmapOT1TT + \begingroup + \catcode`\^^M=\active \def^^M{^^J}% Output line endings as the ^^J char. + \catcode`\%=12 \immediate\pdfobj stream {%!PS-Adobe-3.0 Resource-CMap +%%DocumentNeededResources: ProcSet (CIDInit) +%%IncludeResource: ProcSet (CIDInit) +%%BeginResource: CMap (TeX-OT1TT-0) +%%Title: (TeX-OT1TT-0 TeX OT1TT 0) +%%Version: 1.000 +%%EndComments +/CIDInit /ProcSet findresource begin +12 dict begin +begincmap +/CIDSystemInfo +<< /Registry (TeX) +/Ordering (OT1TT) +/Supplement 0 +>> def +/CMapName /TeX-OT1TT-0 def +/CMapType 2 def +1 begincodespacerange +<00> <7F> +endcodespacerange +5 beginbfrange +<00> <01> <0393> +<09> <0A> <03A8> +<21> <26> <0021> +<28> <5F> <0028> +<61> <7E> <0061> +endbfrange +32 beginbfchar +<02> <0398> +<03> <039B> +<04> <039E> +<05> <03A0> +<06> <03A3> +<07> <03D2> +<08> <03A6> +<0B> <2191> +<0C> <2193> +<0D> <0027> +<0E> <00A1> +<0F> <00BF> +<10> <0131> +<11> <0237> +<12> <0060> +<13> <00B4> +<14> <02C7> +<15> <02D8> +<16> <00AF> +<17> <02DA> +<18> <00B8> +<19> <00DF> +<1A> <00E6> +<1B> <0153> +<1C> <00F8> +<1D> <00C6> +<1E> <0152> +<1F> <00D8> +<20> <2423> +<27> <2019> +<60> <2018> +<7F> <00A8> +endbfchar +endcmap +CMapName currentdict /CMap defineresource pop +end +end +%%EndResource +%%EOF + }\endgroup + \expandafter\edef\csname cmapOT1TT\endcsname#1{% + \pdffontattr#1{/ToUnicode \the\pdflastobj\space 0 R}% + }% +\fi\fi + + +% Set the font macro #1 to the font named \fontprefix#2. +% #3 is the font's design size, #4 is a scale factor, #5 is the CMap +% encoding (only OT1, OT1IT and OT1TT are allowed, or empty to omit). +% Example: +% #1 = \textrm +% #2 = \rmshape +% #3 = 10 +% #4 = \mainmagstep +% #5 = OT1 +% +\def\setfont#1#2#3#4#5{% + \font#1=\fontprefix#2#3 scaled #4 + \csname cmap#5\endcsname#1% +} +% This is what gets called when #5 of \setfont is empty. +\let\cmap\gobble +% +% (end of cmaps) + +% Use cm as the default font prefix. +% To specify the font prefix, you must define \fontprefix +% before you read in texinfo.tex. +\ifx\fontprefix\thisisundefined +\def\fontprefix{cm} +\fi +% Support font families that don't use the same naming scheme as CM. +\def\rmshape{r} +\def\rmbshape{bx} % where the normal face is bold +\def\bfshape{b} +\def\bxshape{bx} +\def\ttshape{tt} +\def\ttbshape{tt} +\def\ttslshape{sltt} +\def\itshape{ti} +\def\itbshape{bxti} +\def\slshape{sl} +\def\slbshape{bxsl} +\def\sfshape{ss} +\def\sfbshape{ss} +\def\scshape{csc} +\def\scbshape{csc} + +% Definitions for a main text size of 11pt. (The default in Texinfo.) +% +\def\definetextfontsizexi{% +% Text fonts (11.2pt, magstep1). +\def\textnominalsize{11pt} +\edef\mainmagstep{\magstephalf} +\setfont\textrm\rmshape{10}{\mainmagstep}{OT1} +\setfont\texttt\ttshape{10}{\mainmagstep}{OT1TT} +\setfont\textbf\bfshape{10}{\mainmagstep}{OT1} +\setfont\textit\itshape{10}{\mainmagstep}{OT1IT} +\setfont\textsl\slshape{10}{\mainmagstep}{OT1} +\setfont\textsf\sfshape{10}{\mainmagstep}{OT1} +\setfont\textsc\scshape{10}{\mainmagstep}{OT1} +\setfont\textttsl\ttslshape{10}{\mainmagstep}{OT1TT} +\font\texti=cmmi10 scaled \mainmagstep +\font\textsy=cmsy10 scaled \mainmagstep +\def\textecsize{1095} + +% A few fonts for @defun names and args. +\setfont\defbf\bfshape{10}{\magstep1}{OT1} +\setfont\deftt\ttshape{10}{\magstep1}{OT1TT} +\setfont\defsl\slshape{10}{\magstep1}{OT1TT} +\setfont\defttsl\ttslshape{10}{\magstep1}{OT1TT} +\def\df{\let\ttfont=\deftt \let\bffont = \defbf +\let\ttslfont=\defttsl \let\slfont=\defsl \bf} + +% Fonts for indices, footnotes, small examples (9pt). +\def\smallnominalsize{9pt} +\setfont\smallrm\rmshape{9}{1000}{OT1} +\setfont\smalltt\ttshape{9}{1000}{OT1TT} +\setfont\smallbf\bfshape{10}{900}{OT1} +\setfont\smallit\itshape{9}{1000}{OT1IT} +\setfont\smallsl\slshape{9}{1000}{OT1} +\setfont\smallsf\sfshape{9}{1000}{OT1} +\setfont\smallsc\scshape{10}{900}{OT1} +\setfont\smallttsl\ttslshape{10}{900}{OT1TT} +\font\smalli=cmmi9 +\font\smallsy=cmsy9 +\def\smallecsize{0900} + +% Fonts for small examples (8pt). +\def\smallernominalsize{8pt} +\setfont\smallerrm\rmshape{8}{1000}{OT1} +\setfont\smallertt\ttshape{8}{1000}{OT1TT} +\setfont\smallerbf\bfshape{10}{800}{OT1} +\setfont\smallerit\itshape{8}{1000}{OT1IT} +\setfont\smallersl\slshape{8}{1000}{OT1} +\setfont\smallersf\sfshape{8}{1000}{OT1} +\setfont\smallersc\scshape{10}{800}{OT1} +\setfont\smallerttsl\ttslshape{10}{800}{OT1TT} +\font\smalleri=cmmi8 +\font\smallersy=cmsy8 +\def\smallerecsize{0800} + +% Fonts for math mode superscripts (7pt). +\def\sevennominalsize{7pt} +\setfont\sevenrm\rmshape{7}{1000}{OT1} +\setfont\seventt\ttshape{10}{700}{OT1TT} +\setfont\sevenbf\bfshape{10}{700}{OT1} +\setfont\sevenit\itshape{7}{1000}{OT1IT} +\setfont\sevensl\slshape{10}{700}{OT1} +\setfont\sevensf\sfshape{10}{700}{OT1} +\setfont\sevensc\scshape{10}{700}{OT1} +\setfont\seventtsl\ttslshape{10}{700}{OT1TT} +\font\seveni=cmmi7 +\font\sevensy=cmsy7 +\def\sevenecsize{0700} + +% Fonts for title page (20.4pt): +\def\titlenominalsize{20pt} +\setfont\titlerm\rmbshape{12}{\magstep3}{OT1} +\setfont\titleit\itbshape{10}{\magstep4}{OT1IT} +\setfont\titlesl\slbshape{10}{\magstep4}{OT1} +\setfont\titlett\ttbshape{12}{\magstep3}{OT1TT} +\setfont\titlettsl\ttslshape{10}{\magstep4}{OT1TT} +\setfont\titlesf\sfbshape{17}{\magstep1}{OT1} +\let\titlebf=\titlerm +\setfont\titlesc\scbshape{10}{\magstep4}{OT1} +\font\titlei=cmmi12 scaled \magstep3 +\font\titlesy=cmsy10 scaled \magstep4 +\def\titleecsize{2074} + +% Chapter (and unnumbered) fonts (17.28pt). +\def\chapnominalsize{17pt} +\setfont\chaprm\rmbshape{12}{\magstep2}{OT1} +\setfont\chapit\itbshape{10}{\magstep3}{OT1IT} +\setfont\chapsl\slbshape{10}{\magstep3}{OT1} +\setfont\chaptt\ttbshape{12}{\magstep2}{OT1TT} +\setfont\chapttsl\ttslshape{10}{\magstep3}{OT1TT} +\setfont\chapsf\sfbshape{17}{1000}{OT1} +\let\chapbf=\chaprm +\setfont\chapsc\scbshape{10}{\magstep3}{OT1} +\font\chapi=cmmi12 scaled \magstep2 +\font\chapsy=cmsy10 scaled \magstep3 +\def\chapecsize{1728} + +% Section fonts (14.4pt). +\def\secnominalsize{14pt} +\setfont\secrm\rmbshape{12}{\magstep1}{OT1} +\setfont\secrmnotbold\rmshape{12}{\magstep1}{OT1} +\setfont\secit\itbshape{10}{\magstep2}{OT1IT} +\setfont\secsl\slbshape{10}{\magstep2}{OT1} +\setfont\sectt\ttbshape{12}{\magstep1}{OT1TT} +\setfont\secttsl\ttslshape{10}{\magstep2}{OT1TT} +\setfont\secsf\sfbshape{12}{\magstep1}{OT1} +\let\secbf\secrm +\setfont\secsc\scbshape{10}{\magstep2}{OT1} +\font\seci=cmmi12 scaled \magstep1 +\font\secsy=cmsy10 scaled \magstep2 +\def\sececsize{1440} + +% Subsection fonts (13.15pt). +\def\ssecnominalsize{13pt} +\setfont\ssecrm\rmbshape{12}{\magstephalf}{OT1} +\setfont\ssecit\itbshape{10}{1315}{OT1IT} +\setfont\ssecsl\slbshape{10}{1315}{OT1} +\setfont\ssectt\ttbshape{12}{\magstephalf}{OT1TT} +\setfont\ssecttsl\ttslshape{10}{1315}{OT1TT} +\setfont\ssecsf\sfbshape{12}{\magstephalf}{OT1} +\let\ssecbf\ssecrm +\setfont\ssecsc\scbshape{10}{1315}{OT1} +\font\sseci=cmmi12 scaled \magstephalf +\font\ssecsy=cmsy10 scaled 1315 +\def\ssececsize{1200} + +% Reduced fonts for @acronym in text (10pt). +\def\reducednominalsize{10pt} +\setfont\reducedrm\rmshape{10}{1000}{OT1} +\setfont\reducedtt\ttshape{10}{1000}{OT1TT} +\setfont\reducedbf\bfshape{10}{1000}{OT1} +\setfont\reducedit\itshape{10}{1000}{OT1IT} +\setfont\reducedsl\slshape{10}{1000}{OT1} +\setfont\reducedsf\sfshape{10}{1000}{OT1} +\setfont\reducedsc\scshape{10}{1000}{OT1} +\setfont\reducedttsl\ttslshape{10}{1000}{OT1TT} +\font\reducedi=cmmi10 +\font\reducedsy=cmsy10 +\def\reducedecsize{1000} + +\textleading = 13.2pt % line spacing for 11pt CM +\textfonts % reset the current fonts +\rm +} % end of 11pt text font size definitions, \definetextfontsizexi + + +% Definitions to make the main text be 10pt Computer Modern, with +% section, chapter, etc., sizes following suit. This is for the GNU +% Press printing of the Emacs 22 manual. Maybe other manuals in the +% future. Used with @smallbook, which sets the leading to 12pt. +% +\def\definetextfontsizex{% +% Text fonts (10pt). +\def\textnominalsize{10pt} +\edef\mainmagstep{1000} +\setfont\textrm\rmshape{10}{\mainmagstep}{OT1} +\setfont\texttt\ttshape{10}{\mainmagstep}{OT1TT} +\setfont\textbf\bfshape{10}{\mainmagstep}{OT1} +\setfont\textit\itshape{10}{\mainmagstep}{OT1IT} +\setfont\textsl\slshape{10}{\mainmagstep}{OT1} +\setfont\textsf\sfshape{10}{\mainmagstep}{OT1} +\setfont\textsc\scshape{10}{\mainmagstep}{OT1} +\setfont\textttsl\ttslshape{10}{\mainmagstep}{OT1TT} +\font\texti=cmmi10 scaled \mainmagstep +\font\textsy=cmsy10 scaled \mainmagstep +\def\textecsize{1000} + +% A few fonts for @defun names and args. +\setfont\defbf\bfshape{10}{\magstephalf}{OT1} +\setfont\deftt\ttshape{10}{\magstephalf}{OT1TT} +\setfont\defsl\slshape{10}{\magstephalf}{OT1TT} +\setfont\defttsl\ttslshape{10}{\magstephalf}{OT1TT} +\def\df{\let\ttfont=\deftt \let\bffont = \defbf +\let\slfont=\defsl \let\ttslfont=\defttsl \bf} + +% Fonts for indices, footnotes, small examples (9pt). +\def\smallnominalsize{9pt} +\setfont\smallrm\rmshape{9}{1000}{OT1} +\setfont\smalltt\ttshape{9}{1000}{OT1TT} +\setfont\smallbf\bfshape{10}{900}{OT1} +\setfont\smallit\itshape{9}{1000}{OT1IT} +\setfont\smallsl\slshape{9}{1000}{OT1} +\setfont\smallsf\sfshape{9}{1000}{OT1} +\setfont\smallsc\scshape{10}{900}{OT1} +\setfont\smallttsl\ttslshape{10}{900}{OT1TT} +\font\smalli=cmmi9 +\font\smallsy=cmsy9 +\def\smallecsize{0900} + +% Fonts for small examples (8pt). +\def\smallernominalsize{8pt} +\setfont\smallerrm\rmshape{8}{1000}{OT1} +\setfont\smallertt\ttshape{8}{1000}{OT1TT} +\setfont\smallerbf\bfshape{10}{800}{OT1} +\setfont\smallerit\itshape{8}{1000}{OT1IT} +\setfont\smallersl\slshape{8}{1000}{OT1} +\setfont\smallersf\sfshape{8}{1000}{OT1} +\setfont\smallersc\scshape{10}{800}{OT1} +\setfont\smallerttsl\ttslshape{10}{800}{OT1TT} +\font\smalleri=cmmi8 +\font\smallersy=cmsy8 +\def\smallerecsize{0800} + +% Fonts for math mode superscripts (7pt). +\def\sevennominalsize{7pt} +\setfont\sevenrm\rmshape{7}{1000}{OT1} +\setfont\seventt\ttshape{10}{700}{OT1TT} +\setfont\sevenbf\bfshape{10}{700}{OT1} +\setfont\sevenit\itshape{7}{1000}{OT1IT} +\setfont\sevensl\slshape{10}{700}{OT1} +\setfont\sevensf\sfshape{10}{700}{OT1} +\setfont\sevensc\scshape{10}{700}{OT1} +\setfont\seventtsl\ttslshape{10}{700}{OT1TT} +\font\seveni=cmmi7 +\font\sevensy=cmsy7 +\def\sevenecsize{0700} + +% Fonts for title page (20.4pt): +\def\titlenominalsize{20pt} +\setfont\titlerm\rmbshape{12}{\magstep3}{OT1} +\setfont\titleit\itbshape{10}{\magstep4}{OT1IT} +\setfont\titlesl\slbshape{10}{\magstep4}{OT1} +\setfont\titlett\ttbshape{12}{\magstep3}{OT1TT} +\setfont\titlettsl\ttslshape{10}{\magstep4}{OT1TT} +\setfont\titlesf\sfbshape{17}{\magstep1}{OT1} +\let\titlebf=\titlerm +\setfont\titlesc\scbshape{10}{\magstep4}{OT1} +\font\titlei=cmmi12 scaled \magstep3 +\font\titlesy=cmsy10 scaled \magstep4 +\def\titleecsize{2074} + +% Chapter fonts (14.4pt). +\def\chapnominalsize{14pt} +\setfont\chaprm\rmbshape{12}{\magstep1}{OT1} +\setfont\chapit\itbshape{10}{\magstep2}{OT1IT} +\setfont\chapsl\slbshape{10}{\magstep2}{OT1} +\setfont\chaptt\ttbshape{12}{\magstep1}{OT1TT} +\setfont\chapttsl\ttslshape{10}{\magstep2}{OT1TT} +\setfont\chapsf\sfbshape{12}{\magstep1}{OT1} +\let\chapbf\chaprm +\setfont\chapsc\scbshape{10}{\magstep2}{OT1} +\font\chapi=cmmi12 scaled \magstep1 +\font\chapsy=cmsy10 scaled \magstep2 +\def\chapecsize{1440} + +% Section fonts (12pt). +\def\secnominalsize{12pt} +\setfont\secrm\rmbshape{12}{1000}{OT1} +\setfont\secit\itbshape{10}{\magstep1}{OT1IT} +\setfont\secsl\slbshape{10}{\magstep1}{OT1} +\setfont\sectt\ttbshape{12}{1000}{OT1TT} +\setfont\secttsl\ttslshape{10}{\magstep1}{OT1TT} +\setfont\secsf\sfbshape{12}{1000}{OT1} +\let\secbf\secrm +\setfont\secsc\scbshape{10}{\magstep1}{OT1} +\font\seci=cmmi12 +\font\secsy=cmsy10 scaled \magstep1 +\def\sececsize{1200} + +% Subsection fonts (10pt). +\def\ssecnominalsize{10pt} +\setfont\ssecrm\rmbshape{10}{1000}{OT1} +\setfont\ssecit\itbshape{10}{1000}{OT1IT} +\setfont\ssecsl\slbshape{10}{1000}{OT1} +\setfont\ssectt\ttbshape{10}{1000}{OT1TT} +\setfont\ssecttsl\ttslshape{10}{1000}{OT1TT} +\setfont\ssecsf\sfbshape{10}{1000}{OT1} +\let\ssecbf\ssecrm +\setfont\ssecsc\scbshape{10}{1000}{OT1} +\font\sseci=cmmi10 +\font\ssecsy=cmsy10 +\def\ssececsize{1000} + +% Reduced fonts for @acronym in text (9pt). +\def\reducednominalsize{9pt} +\setfont\reducedrm\rmshape{9}{1000}{OT1} +\setfont\reducedtt\ttshape{9}{1000}{OT1TT} +\setfont\reducedbf\bfshape{10}{900}{OT1} +\setfont\reducedit\itshape{9}{1000}{OT1IT} +\setfont\reducedsl\slshape{9}{1000}{OT1} +\setfont\reducedsf\sfshape{9}{1000}{OT1} +\setfont\reducedsc\scshape{10}{900}{OT1} +\setfont\reducedttsl\ttslshape{10}{900}{OT1TT} +\font\reducedi=cmmi9 +\font\reducedsy=cmsy9 +\def\reducedecsize{0900} + +\divide\parskip by 2 % reduce space between paragraphs +\textleading = 12pt % line spacing for 10pt CM +\textfonts % reset the current fonts +\rm +} % end of 10pt text font size definitions, \definetextfontsizex + +% Fonts for short table of contents. +\setfont\shortcontrm\rmshape{12}{1000}{OT1} +\setfont\shortcontbf\bfshape{10}{\magstep1}{OT1} % no cmb12 +\setfont\shortcontsl\slshape{12}{1000}{OT1} +\setfont\shortconttt\ttshape{12}{1000}{OT1TT} + + +% We provide the user-level command +% @fonttextsize 10 +% (or 11) to redefine the text font size. pt is assumed. +% +\def\xiword{11} +\def\xword{10} +\def\xwordpt{10pt} +% +\parseargdef\fonttextsize{% + \def\textsizearg{#1}% + %\wlog{doing @fonttextsize \textsizearg}% + % + % Set \globaldefs so that documents can use this inside @tex, since + % makeinfo 4.8 does not support it, but we need it nonetheless. + % + \begingroup \globaldefs=1 + \ifx\textsizearg\xword \definetextfontsizex + \else \ifx\textsizearg\xiword \definetextfontsizexi + \else + \errhelp=\EMsimple + \errmessage{@fonttextsize only supports `10' or `11', not `\textsizearg'} + \fi\fi + \endgroup +} + +% +% Change the current font style to #1, remembering it in \curfontstyle. +% For now, we do not accumulate font styles: @b{@i{foo}} prints foo in +% italics, not bold italics. +% +\def\setfontstyle#1{% + \def\curfontstyle{#1}% not as a control sequence, because we are \edef'd. + \csname #1font\endcsname % change the current font +} + +\def\rm{\fam=0 \setfontstyle{rm}} +\def\it{\fam=\itfam \setfontstyle{it}} +\def\sl{\fam=\slfam \setfontstyle{sl}} +\def\bf{\fam=\bffam \setfontstyle{bf}}\def\bfstylename{bf} +\def\tt{\fam=\ttfam \setfontstyle{tt}} + +% Texinfo sort of supports the sans serif font style, which plain TeX does not. +% So we set up a \sf. +\newfam\sffam +\def\sf{\fam=\sffam \setfontstyle{sf}} + +% We don't need math for this font style. +\def\ttsl{\setfontstyle{ttsl}} + + +% In order for the font changes to affect most math symbols and letters, +% we have to define the \textfont of the standard families. +% We don't bother to reset \scriptscriptfont; awaiting user need. +% +\def\resetmathfonts{% + \textfont0=\rmfont \textfont1=\ifont \textfont2=\syfont + \textfont\itfam=\itfont \textfont\slfam=\slfont \textfont\bffam=\bffont + \textfont\ttfam=\ttfont \textfont\sffam=\sffont + % + % Fonts for superscript. Note that the 7pt fonts are used regardless + % of the current font size. + \scriptfont0=\sevenrm \scriptfont1=\seveni \scriptfont2=\sevensy + \scriptfont\itfam=\sevenit \scriptfont\slfam=\sevensl + \scriptfont\bffam=\sevenbf \scriptfont\ttfam=\seventt + \scriptfont\sffam=\sevensf +} + +% + +% The font-changing commands (all called \...fonts) redefine the meanings +% of \STYLEfont, instead of just \STYLE. We do this because \STYLE needs +% to also set the current \fam for math mode. Our \STYLE (e.g., \rm) +% commands hardwire \STYLEfont to set the current font. +% +% The fonts used for \ifont are for "math italics" (\itfont is for italics +% in regular text). \syfont is also used in math mode only. +% +% Each font-changing command also sets the names \lsize (one size lower) +% and \lllsize (three sizes lower). These relative commands are used +% in, e.g., the LaTeX logo and acronyms. +% +% This all needs generalizing, badly. +% + +\def\assignfonts#1{% + \expandafter\let\expandafter\rmfont\csname #1rm\endcsname + \expandafter\let\expandafter\itfont\csname #1it\endcsname + \expandafter\let\expandafter\slfont\csname #1sl\endcsname + \expandafter\let\expandafter\bffont\csname #1bf\endcsname + \expandafter\let\expandafter\ttfont\csname #1tt\endcsname + \expandafter\let\expandafter\smallcaps\csname #1sc\endcsname + \expandafter\let\expandafter\sffont \csname #1sf\endcsname + \expandafter\let\expandafter\ifont \csname #1i\endcsname + \expandafter\let\expandafter\syfont \csname #1sy\endcsname + \expandafter\let\expandafter\ttslfont\csname #1ttsl\endcsname +} + +\newif\ifrmisbold + +% Select smaller font size with the current style. Used to change font size +% in, e.g., the LaTeX logo and acronyms. If we are using bold fonts for +% normal roman text, also use bold fonts for roman text in the smaller size. +\def\switchtolllsize{% + \expandafter\assignfonts\expandafter{\lllsize}% + \ifrmisbold + \let\rmfont\bffont + \fi + \csname\curfontstyle\endcsname +}% + +\def\switchtolsize{% + \expandafter\assignfonts\expandafter{\lsize}% + \ifrmisbold + \let\rmfont\bffont + \fi + \csname\curfontstyle\endcsname +}% + +\def\definefontsetatsize#1#2#3#4#5{% +\expandafter\def\csname #1fonts\endcsname{% + \def\curfontsize{#1}% + \def\lsize{#2}\def\lllsize{#3}% + \csname rmisbold#5\endcsname + \assignfonts{#1}% + \resetmathfonts + \setleading{#4}% +}} + +\definefontsetatsize{text} {reduced}{smaller}{\textleading}{false} +\definefontsetatsize{title} {chap} {subsec} {27pt} {true} +\definefontsetatsize{chap} {sec} {text} {19pt} {true} +\definefontsetatsize{sec} {subsec} {reduced}{17pt} {true} +\definefontsetatsize{ssec} {text} {small} {15pt} {true} +\definefontsetatsize{reduced}{small} {smaller}{10.5pt}{false} +\definefontsetatsize{small} {smaller}{smaller}{10.5pt}{false} +\definefontsetatsize{smaller}{smaller}{smaller}{9.5pt} {false} + +\def\titlefont#1{{\titlefonts\rm #1}} +\let\subsecfonts = \ssecfonts +\let\subsubsecfonts = \ssecfonts + +% Define these just so they can be easily changed for other fonts. +\def\angleleft{$\langle$} +\def\angleright{$\rangle$} + +% Set the fonts to use with the @small... environments. +\let\smallexamplefonts = \smallfonts + +% About \smallexamplefonts. If we use \smallfonts (9pt), @smallexample +% can fit this many characters: +% 8.5x11=86 smallbook=72 a4=90 a5=69 +% If we use \scriptfonts (8pt), then we can fit this many characters: +% 8.5x11=90+ smallbook=80 a4=90+ a5=77 +% For me, subjectively, the few extra characters that fit aren't worth +% the additional smallness of 8pt. So I'm making the default 9pt. +% +% By the way, for comparison, here's what fits with @example (10pt): +% 8.5x11=71 smallbook=60 a4=75 a5=58 +% --karl, 24jan03. + +% Set up the default fonts, so we can use them for creating boxes. +% +\definetextfontsizexi + + +\message{markup,} + +% Check if we are currently using a typewriter font. Since all the +% Computer Modern typewriter fonts have zero interword stretch (and +% shrink), and it is reasonable to expect all typewriter fonts to have +% this property, we can check that font parameter. +% +\def\ifmonospace{\ifdim\fontdimen3\font=0pt } + +% Markup style infrastructure. \defmarkupstylesetup\INITMACRO will +% define and register \INITMACRO to be called on markup style changes. +% \INITMACRO can check \currentmarkupstyle for the innermost +% style. + +\let\currentmarkupstyle\empty + +\def\setupmarkupstyle#1{% + \def\currentmarkupstyle{#1}% + \markupstylesetup +} + +\let\markupstylesetup\empty + +\def\defmarkupstylesetup#1{% + \expandafter\def\expandafter\markupstylesetup + \expandafter{\markupstylesetup #1}% + \def#1% +} + +% Markup style setup for left and right quotes. +\defmarkupstylesetup\markupsetuplq{% + \expandafter\let\expandafter \temp + \csname markupsetuplq\currentmarkupstyle\endcsname + \ifx\temp\relax \markupsetuplqdefault \else \temp \fi +} + +\defmarkupstylesetup\markupsetuprq{% + \expandafter\let\expandafter \temp + \csname markupsetuprq\currentmarkupstyle\endcsname + \ifx\temp\relax \markupsetuprqdefault \else \temp \fi +} + +{ +\catcode`\'=\active +\catcode`\`=\active + +\gdef\markupsetuplqdefault{\let`\lq} +\gdef\markupsetuprqdefault{\let'\rq} + +\gdef\markupsetcodequoteleft{\let`\codequoteleft} +\gdef\markupsetcodequoteright{\let'\codequoteright} +} + +\let\markupsetuplqcode \markupsetcodequoteleft +\let\markupsetuprqcode \markupsetcodequoteright +% +\let\markupsetuplqexample \markupsetcodequoteleft +\let\markupsetuprqexample \markupsetcodequoteright +% +\let\markupsetuplqkbd \markupsetcodequoteleft +\let\markupsetuprqkbd \markupsetcodequoteright +% +\let\markupsetuplqsamp \markupsetcodequoteleft +\let\markupsetuprqsamp \markupsetcodequoteright +% +\let\markupsetuplqverb \markupsetcodequoteleft +\let\markupsetuprqverb \markupsetcodequoteright +% +\let\markupsetuplqverbatim \markupsetcodequoteleft +\let\markupsetuprqverbatim \markupsetcodequoteright + +% Allow an option to not use regular directed right quote/apostrophe +% (char 0x27), but instead the undirected quote from cmtt (char 0x0d). +% The undirected quote is ugly, so don't make it the default, but it +% works for pasting with more pdf viewers (at least evince), the +% lilypond developers report. xpdf does work with the regular 0x27. +% +\def\codequoteright{% + \ifmonospace + \expandafter\ifx\csname SETtxicodequoteundirected\endcsname\relax + \expandafter\ifx\csname SETcodequoteundirected\endcsname\relax + '% + \else \char'15 \fi + \else \char'15 \fi + \else + '% + \fi +} +% +% and a similar option for the left quote char vs. a grave accent. +% Modern fonts display ASCII 0x60 as a grave accent, so some people like +% the code environments to do likewise. +% +\def\codequoteleft{% + \ifmonospace + \expandafter\ifx\csname SETtxicodequotebacktick\endcsname\relax + \expandafter\ifx\csname SETcodequotebacktick\endcsname\relax + % [Knuth] pp. 380,381,391 + % \relax disables Spanish ligatures ?` and !` of \tt font. + \relax`% + \else \char'22 \fi + \else \char'22 \fi + \else + \relax`% + \fi +} + +% Commands to set the quote options. +% +\parseargdef\codequoteundirected{% + \def\temp{#1}% + \ifx\temp\onword + \expandafter\let\csname SETtxicodequoteundirected\endcsname + = t% + \else\ifx\temp\offword + \expandafter\let\csname SETtxicodequoteundirected\endcsname + = \relax + \else + \errhelp = \EMsimple + \errmessage{Unknown @codequoteundirected value `\temp', must be on|off}% + \fi\fi +} +% +\parseargdef\codequotebacktick{% + \def\temp{#1}% + \ifx\temp\onword + \expandafter\let\csname SETtxicodequotebacktick\endcsname + = t% + \else\ifx\temp\offword + \expandafter\let\csname SETtxicodequotebacktick\endcsname + = \relax + \else + \errhelp = \EMsimple + \errmessage{Unknown @codequotebacktick value `\temp', must be on|off}% + \fi\fi +} + +% [Knuth] pp. 380,381,391, disable Spanish ligatures ?` and !` of \tt font. +\def\noligaturesquoteleft{\relax\lq} + +% Count depth in font-changes, for error checks +\newcount\fontdepth \fontdepth=0 + +% Font commands. + +% #1 is the font command (\sl or \it), #2 is the text to slant. +% If we are in a monospaced environment, however, 1) always use \ttsl, +% and 2) do not add an italic correction. +\def\dosmartslant#1#2{% + \ifusingtt + {{\ttsl #2}\let\next=\relax}% + {\def\next{{#1#2}\futurelet\next\smartitaliccorrection}}% + \next +} +\def\smartslanted{\dosmartslant\sl} +\def\smartitalic{\dosmartslant\it} + +% Output an italic correction unless \next (presumed to be the following +% character) is such as not to need one. +\def\smartitaliccorrection{% + \ifx\next,% + \else\ifx\next-% + \else\ifx\next.% + \else\ifx\next\.% + \else\ifx\next\comma% + \else\ptexslash + \fi\fi\fi\fi\fi + \aftersmartic +} + +% Unconditional use \ttsl, and no ic. @var is set to this for defuns. +\def\ttslanted#1{{\ttsl #1}} + +% @cite is like \smartslanted except unconditionally use \sl. We never want +% ttsl for book titles, do we? +\def\cite#1{{\sl #1}\futurelet\next\smartitaliccorrection} + +\def\aftersmartic{} +\def\var#1{% + \let\saveaftersmartic = \aftersmartic + \def\aftersmartic{\null\let\aftersmartic=\saveaftersmartic}% + \smartslanted{#1}% +} + +\let\i=\smartitalic +\let\slanted=\smartslanted +\let\dfn=\smartslanted +\let\emph=\smartitalic + +% Explicit font changes: @r, @sc, undocumented @ii. +\def\r#1{{\rm #1}} % roman font +\def\sc#1{{\smallcaps#1}} % smallcaps font +\def\ii#1{{\it #1}} % italic font + +% @b, explicit bold. Also @strong. +\def\b#1{{\bf #1}} +\let\strong=\b + +% @sansserif, explicit sans. +\def\sansserif#1{{\sf #1}} + +% We can't just use \exhyphenpenalty, because that only has effect at +% the end of a paragraph. Restore normal hyphenation at the end of the +% group within which \nohyphenation is presumably called. +% +\def\nohyphenation{\hyphenchar\font = -1 \aftergroup\restorehyphenation} +\def\restorehyphenation{\hyphenchar\font = `- } + +% Set sfcode to normal for the chars that usually have another value. +% Can't use plain's \frenchspacing because it uses the `\x notation, and +% sometimes \x has an active definition that messes things up. +% +\catcode`@=11 + \def\plainfrenchspacing{% + \sfcode`\.=\@m \sfcode`\?=\@m \sfcode`\!=\@m + \sfcode`\:=\@m \sfcode`\;=\@m \sfcode`\,=\@m + \def\endofsentencespacefactor{1000}% for @. and friends + } + \def\plainnonfrenchspacing{% + \sfcode`\.3000\sfcode`\?3000\sfcode`\!3000 + \sfcode`\:2000\sfcode`\;1500\sfcode`\,1250 + \def\endofsentencespacefactor{3000}% for @. and friends + } +\catcode`@=\other +\def\endofsentencespacefactor{3000}% default + +% @t, explicit typewriter. +\def\t#1{% + {\tt \rawbackslash \plainfrenchspacing #1}% + \null +} + +% @samp. +\def\samp#1{{\setupmarkupstyle{samp}\lq\tclose{#1}\rq\null}} + +% @indicateurl is \samp, that is, with quotes. +\let\indicateurl=\samp + +% @code (and similar) prints in typewriter, but with spaces the same +% size as normal in the surrounding text, without hyphenation, etc. +% This is a subroutine for that. +\def\tclose#1{% + {% + % Change normal interword space to be same as for the current font. + \spaceskip = \fontdimen2\font + % + % Switch to typewriter. + \tt + % + % But `\ ' produces the large typewriter interword space. + \def\ {{\spaceskip = 0pt{} }}% + % + % Turn off hyphenation. + \nohyphenation + % + \rawbackslash + \plainfrenchspacing + #1% + }% + \null % reset spacefactor to 1000 +} + +% We *must* turn on hyphenation at `-' and `_' in @code. +% (But see \codedashfinish below.) +% Otherwise, it is too hard to avoid overfull hboxes +% in the Emacs manual, the Library manual, etc. +% +% Unfortunately, TeX uses one parameter (\hyphenchar) to control +% both hyphenation at - and hyphenation within words. +% We must therefore turn them both off (\tclose does that) +% and arrange explicitly to hyphenate at a dash. -- rms. +{ + \catcode`\-=\active \catcode`\_=\active + \catcode`\'=\active \catcode`\`=\active + \global\let'=\rq \global\let`=\lq % default definitions + % + \global\def\code{\begingroup + \setupmarkupstyle{code}% + % The following should really be moved into \setupmarkupstyle handlers. + \catcode\dashChar=\active \catcode\underChar=\active + \ifallowcodebreaks + \let-\codedash + \let_\codeunder + \else + \let-\normaldash + \let_\realunder + \fi + % Given -foo (with a single dash), we do not want to allow a break + % after the hyphen. + \global\let\codedashprev=\codedash + % + \codex + } + % + \gdef\codedash{\futurelet\next\codedashfinish} + \gdef\codedashfinish{% + \normaldash % always output the dash character itself. + % + % Now, output a discretionary to allow a line break, unless + % (a) the next character is a -, or + % (b) the preceding character is a -. + % E.g., given --posix, we do not want to allow a break after either -. + % Given --foo-bar, we do want to allow a break between the - and the b. + \ifx\next\codedash \else + \ifx\codedashprev\codedash + \else \discretionary{}{}{}\fi + \fi + % we need the space after the = for the case when \next itself is a + % space token; it would get swallowed otherwise. As in @code{- a}. + \global\let\codedashprev= \next + } +} +\def\normaldash{-} +% +\def\codex #1{\tclose{#1}\endgroup} + +\def\codeunder{% + % this is all so @math{@code{var_name}+1} can work. In math mode, _ + % is "active" (mathcode"8000) and \normalunderscore (or \char95, etc.) + % will therefore expand the active definition of _, which is us + % (inside @code that is), therefore an endless loop. + \ifusingtt{\ifmmode + \mathchar"075F % class 0=ordinary, family 7=ttfam, pos 0x5F=_. + \else\normalunderscore \fi + \discretionary{}{}{}}% + {\_}% +} + +% An additional complication: the above will allow breaks after, e.g., +% each of the four underscores in __typeof__. This is bad. +% @allowcodebreaks provides a document-level way to turn breaking at - +% and _ on and off. +% +\newif\ifallowcodebreaks \allowcodebreakstrue + +\def\keywordtrue{true} +\def\keywordfalse{false} + +\parseargdef\allowcodebreaks{% + \def\txiarg{#1}% + \ifx\txiarg\keywordtrue + \allowcodebreakstrue + \else\ifx\txiarg\keywordfalse + \allowcodebreaksfalse + \else + \errhelp = \EMsimple + \errmessage{Unknown @allowcodebreaks option `\txiarg', must be true|false}% + \fi\fi +} + +% For @command, @env, @file, @option quotes seem unnecessary, +% so use \code rather than \samp. +\let\command=\code +\let\env=\code +\let\file=\code +\let\option=\code + +% @uref (abbreviation for `urlref') aka @url takes an optional +% (comma-separated) second argument specifying the text to display and +% an optional third arg as text to display instead of (rather than in +% addition to) the url itself. First (mandatory) arg is the url. + +% TeX-only option to allow changing PDF output to show only the second +% arg (if given), and not the url (which is then just the link target). +\newif\ifurefurlonlylink + +% The main macro is \urefbreak, which allows breaking at expected +% places within the url. (There used to be another version, which +% didn't support automatic breaking.) +\def\urefbreak{\begingroup \urefcatcodes \dourefbreak} +\let\uref=\urefbreak +% +\def\dourefbreak#1{\urefbreakfinish #1,,,\finish} +\def\urefbreakfinish#1,#2,#3,#4\finish{% doesn't work in @example + \unsepspaces + \pdfurl{#1}% + \setbox0 = \hbox{\ignorespaces #3}% + \ifdim\wd0 > 0pt + \unhbox0 % third arg given, show only that + \else + \setbox0 = \hbox{\ignorespaces #2}% look for second arg + \ifdim\wd0 > 0pt + \ifpdf + % For pdfTeX and LuaTeX + \ifurefurlonlylink + % PDF plus option to not display url, show just arg + \unhbox0 + \else + % PDF, normally display both arg and url for consistency, + % visibility, if the pdf is eventually used to print, etc. + \unhbox0\ (\urefcode{#1})% + \fi + \else + \ifx\XeTeXrevision\thisisundefined + \unhbox0\ (\urefcode{#1})% DVI, always show arg and url + \else + % For XeTeX + \ifurefurlonlylink + % PDF plus option to not display url, show just arg + \unhbox0 + \else + % PDF, normally display both arg and url for consistency, + % visibility, if the pdf is eventually used to print, etc. + \unhbox0\ (\urefcode{#1})% + \fi + \fi + \fi + \else + \urefcode{#1}% only url given, so show it + \fi + \fi + \endlink +\endgroup} + +% Allow line breaks around only a few characters (only). +\def\urefcatcodes{% + \catcode`\&=\active \catcode`\.=\active + \catcode`\#=\active \catcode`\?=\active + \catcode`\/=\active +} +{ + \urefcatcodes + % + \global\def\urefcode{\begingroup + \setupmarkupstyle{code}% + \urefcatcodes + \let&\urefcodeamp + \let.\urefcodedot + \let#\urefcodehash + \let?\urefcodequest + \let/\urefcodeslash + \codex + } + % + % By default, they are just regular characters. + \global\def&{\normalamp} + \global\def.{\normaldot} + \global\def#{\normalhash} + \global\def?{\normalquest} + \global\def/{\normalslash} +} + +% we put a little stretch before and after the breakable chars, to help +% line breaking of long url's. The unequal skips make look better in +% cmtt at least, especially for dots. +\def\urefprestretchamount{.13em} +\def\urefpoststretchamount{.1em} +\def\urefprestretch{\urefprebreak \hskip0pt plus\urefprestretchamount\relax} +\def\urefpoststretch{\urefpostbreak \hskip0pt plus\urefprestretchamount\relax} +% +\def\urefcodeamp{\urefprestretch \&\urefpoststretch} +\def\urefcodedot{\urefprestretch .\urefpoststretch} +\def\urefcodehash{\urefprestretch \#\urefpoststretch} +\def\urefcodequest{\urefprestretch ?\urefpoststretch} +\def\urefcodeslash{\futurelet\next\urefcodeslashfinish} +{ + \catcode`\/=\active + \global\def\urefcodeslashfinish{% + \urefprestretch \slashChar + % Allow line break only after the final / in a sequence of + % slashes, to avoid line break between the slashes in http://. + \ifx\next/\else \urefpoststretch \fi + } +} + +% One more complication: by default we'll break after the special +% characters, but some people like to break before the special chars, so +% allow that. Also allow no breaking at all, for manual control. +% +\parseargdef\urefbreakstyle{% + \def\txiarg{#1}% + \ifx\txiarg\wordnone + \def\urefprebreak{\nobreak}\def\urefpostbreak{\nobreak} + \else\ifx\txiarg\wordbefore + \def\urefprebreak{\allowbreak}\def\urefpostbreak{\nobreak} + \else\ifx\txiarg\wordafter + \def\urefprebreak{\nobreak}\def\urefpostbreak{\allowbreak} + \else + \errhelp = \EMsimple + \errmessage{Unknown @urefbreakstyle setting `\txiarg'}% + \fi\fi\fi +} +\def\wordafter{after} +\def\wordbefore{before} +\def\wordnone{none} + +\urefbreakstyle after + +% @url synonym for @uref, since that's how everyone uses it. +% +\let\url=\uref + +% rms does not like angle brackets --karl, 17may97. +% So now @email is just like @uref, unless we are pdf. +% +%\def\email#1{\angleleft{\tt #1}\angleright} +\ifpdf + \def\email#1{\doemail#1,,\finish} + \def\doemail#1,#2,#3\finish{\begingroup + \unsepspaces + \pdfurl{mailto:#1}% + \setbox0 = \hbox{\ignorespaces #2}% + \ifdim\wd0>0pt\unhbox0\else\code{#1}\fi + \endlink + \endgroup} +\else + \ifx\XeTeXrevision\thisisundefined + \let\email=\uref + \else + \def\email#1{\doemail#1,,\finish} + \def\doemail#1,#2,#3\finish{\begingroup + \unsepspaces + \pdfurl{mailto:#1}% + \setbox0 = \hbox{\ignorespaces #2}% + \ifdim\wd0>0pt\unhbox0\else\code{#1}\fi + \endlink + \endgroup} + \fi +\fi + +% @kbdinputstyle -- arg is `distinct' (@kbd uses slanted tty font always), +% `example' (@kbd uses ttsl only inside of @example and friends), +% or `code' (@kbd uses normal tty font always). +\parseargdef\kbdinputstyle{% + \def\txiarg{#1}% + \ifx\txiarg\worddistinct + \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\ttsl}% + \else\ifx\txiarg\wordexample + \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\tt}% + \else\ifx\txiarg\wordcode + \gdef\kbdexamplefont{\tt}\gdef\kbdfont{\tt}% + \else + \errhelp = \EMsimple + \errmessage{Unknown @kbdinputstyle setting `\txiarg'}% + \fi\fi\fi +} +\def\worddistinct{distinct} +\def\wordexample{example} +\def\wordcode{code} + +% Default is `distinct'. +\kbdinputstyle distinct + +% @kbd is like @code, except that if the argument is just one @key command, +% then @kbd has no effect. +\def\kbd#1{{\def\look{#1}\expandafter\kbdsub\look??\par}} + +\def\xkey{\key} +\def\kbdsub#1#2#3\par{% + \def\one{#1}\def\three{#3}\def\threex{??}% + \ifx\one\xkey\ifx\threex\three \key{#2}% + \else{\tclose{\kbdfont\setupmarkupstyle{kbd}\look}}\fi + \else{\tclose{\kbdfont\setupmarkupstyle{kbd}\look}}\fi +} + +% definition of @key that produces a lozenge. Doesn't adjust to text size. +%\setfont\keyrm\rmshape{8}{1000}{OT1} +%\font\keysy=cmsy9 +%\def\key#1{{\keyrm\textfont2=\keysy \leavevmode\hbox{% +% \raise0.4pt\hbox{\angleleft}\kern-.08em\vtop{% +% \vbox{\hrule\kern-0.4pt +% \hbox{\raise0.4pt\hbox{\vphantom{\angleleft}}#1}}% +% \kern-0.4pt\hrule}% +% \kern-.06em\raise0.4pt\hbox{\angleright}}}} + +% definition of @key with no lozenge. If the current font is already +% monospace, don't change it; that way, we respect @kbdinputstyle. But +% if it isn't monospace, then use \tt. +% +\def\key#1{{\setupmarkupstyle{key}% + \nohyphenation + \ifmonospace\else\tt\fi + #1}\null} + +% @clicksequence{File @click{} Open ...} +\def\clicksequence#1{\begingroup #1\endgroup} + +% @clickstyle @arrow (by default) +\parseargdef\clickstyle{\def\click{#1}} +\def\click{\arrow} + +% Typeset a dimension, e.g., `in' or `pt'. The only reason for the +% argument is to make the input look right: @dmn{pt} instead of @dmn{}pt. +% +\def\dmn#1{\thinspace #1} + +% @acronym for "FBI", "NATO", and the like. +% We print this one point size smaller, since it's intended for +% all-uppercase. +% +\def\acronym#1{\doacronym #1,,\finish} +\def\doacronym#1,#2,#3\finish{% + {\switchtolsize #1}% + \def\temp{#2}% + \ifx\temp\empty \else + \space ({\unsepspaces \ignorespaces \temp \unskip})% + \fi + \null % reset \spacefactor=1000 +} + +% @abbr for "Comput. J." and the like. +% No font change, but don't do end-of-sentence spacing. +% +\def\abbr#1{\doabbr #1,,\finish} +\def\doabbr#1,#2,#3\finish{% + {\plainfrenchspacing #1}% + \def\temp{#2}% + \ifx\temp\empty \else + \space ({\unsepspaces \ignorespaces \temp \unskip})% + \fi + \null % reset \spacefactor=1000 +} + +% @asis just yields its argument. Used with @table, for example. +% +\def\asis#1{#1} + +% @math outputs its argument in math mode. +% +% One complication: _ usually means subscripts, but it could also mean +% an actual _ character, as in @math{@var{some_variable} + 1}. So make +% _ active, and distinguish by seeing if the current family is \slfam, +% which is what @var uses. +{ + \catcode`\_ = \active + \gdef\mathunderscore{% + \catcode`\_=\active + \def_{\ifnum\fam=\slfam \_\else\sb\fi}% + } +} +% Another complication: we want \\ (and @\) to output a math (or tt) \. +% FYI, plain.tex uses \\ as a temporary control sequence (for no +% particular reason), but this is not advertised and we don't care. +% +% The \mathchar is class=0=ordinary, family=7=ttfam, position=5C=\. +\def\mathbackslash{\ifnum\fam=\ttfam \mathchar"075C \else\backslash \fi} +% +\def\math{% + \ifmmode\else % only go into math if not in math mode already + \tex + \mathunderscore + \let\\ = \mathbackslash + \mathactive + % make the texinfo accent commands work in math mode + \let\"=\ddot + \let\'=\acute + \let\==\bar + \let\^=\hat + \let\`=\grave + \let\u=\breve + \let\v=\check + \let\~=\tilde + \let\dotaccent=\dot + % have to provide another name for sup operator + \let\mathopsup=\sup + $\expandafter\finishmath\fi +} +\def\finishmath#1{#1$\endgroup} % Close the group opened by \tex. + +% Some active characters (such as <) are spaced differently in math. +% We have to reset their definitions in case the @math was an argument +% to a command which sets the catcodes (such as @item or @section). +% +{ + \catcode`^ = \active + \catcode`< = \active + \catcode`> = \active + \catcode`+ = \active + \catcode`' = \active + \gdef\mathactive{% + \let^ = \ptexhat + \let< = \ptexless + \let> = \ptexgtr + \let+ = \ptexplus + \let' = \ptexquoteright + } +} + +% for @sub and @sup, if in math mode, just do a normal sub/superscript. +% If in text, use math to place as sub/superscript, but switch +% into text mode, with smaller fonts. This is a different font than the +% one used for real math sub/superscripts (8pt vs. 7pt), but let's not +% fix it (significant additions to font machinery) until someone notices. +% +\def\sub{\ifmmode \expandafter\sb \else \expandafter\finishsub\fi} +\def\finishsub#1{$\sb{\hbox{\switchtolllsize #1}}$}% +% +\def\sup{\ifmmode \expandafter\ptexsp \else \expandafter\finishsup\fi} +\def\finishsup#1{$\ptexsp{\hbox{\switchtolllsize #1}}$}% + +% @inlinefmt{FMTNAME,PROCESSED-TEXT} and @inlineraw{FMTNAME,RAW-TEXT}. +% Ignore unless FMTNAME == tex; then it is like @iftex and @tex, +% except specified as a normal braced arg, so no newlines to worry about. +% +\def\outfmtnametex{tex} +% +\long\def\inlinefmt#1{\doinlinefmt #1,\finish} +\long\def\doinlinefmt#1,#2,\finish{% + \def\inlinefmtname{#1}% + \ifx\inlinefmtname\outfmtnametex \ignorespaces #2\fi +} +% +% @inlinefmtifelse{FMTNAME,THEN-TEXT,ELSE-TEXT} expands THEN-TEXT if +% FMTNAME is tex, else ELSE-TEXT. +\long\def\inlinefmtifelse#1{\doinlinefmtifelse #1,,,\finish} +\long\def\doinlinefmtifelse#1,#2,#3,#4,\finish{% + \def\inlinefmtname{#1}% + \ifx\inlinefmtname\outfmtnametex \ignorespaces #2\else \ignorespaces #3\fi +} +% +% For raw, must switch into @tex before parsing the argument, to avoid +% setting catcodes prematurely. Doing it this way means that, for +% example, @inlineraw{html, foo{bar} gets a parse error instead of being +% ignored. But this isn't important because if people want a literal +% *right* brace they would have to use a command anyway, so they may as +% well use a command to get a left brace too. We could re-use the +% delimiter character idea from \verb, but it seems like overkill. +% +\long\def\inlineraw{\tex \doinlineraw} +\long\def\doinlineraw#1{\doinlinerawtwo #1,\finish} +\def\doinlinerawtwo#1,#2,\finish{% + \def\inlinerawname{#1}% + \ifx\inlinerawname\outfmtnametex \ignorespaces #2\fi + \endgroup % close group opened by \tex. +} + +% @inlineifset{VAR, TEXT} expands TEXT if VAR is @set. +% +\long\def\inlineifset#1{\doinlineifset #1,\finish} +\long\def\doinlineifset#1,#2,\finish{% + \def\inlinevarname{#1}% + \expandafter\ifx\csname SET\inlinevarname\endcsname\relax + \else\ignorespaces#2\fi +} + +% @inlineifclear{VAR, TEXT} expands TEXT if VAR is not @set. +% +\long\def\inlineifclear#1{\doinlineifclear #1,\finish} +\long\def\doinlineifclear#1,#2,\finish{% + \def\inlinevarname{#1}% + \expandafter\ifx\csname SET\inlinevarname\endcsname\relax \ignorespaces#2\fi +} + + +\message{glyphs,} +% and logos. + +% @@ prints an @, as does @atchar{}. +\def\@{\char64 } +\let\atchar=\@ + +% @{ @} @lbracechar{} @rbracechar{} all generate brace characters. +\def\lbracechar{{\ifmonospace\char123\else\ensuremath\lbrace\fi}} +\def\rbracechar{{\ifmonospace\char125\else\ensuremath\rbrace\fi}} +\let\{=\lbracechar +\let\}=\rbracechar + +% @comma{} to avoid , parsing problems. +\let\comma = , + +% Accents: @, @dotaccent @ringaccent @ubaraccent @udotaccent +% Others are defined by plain TeX: @` @' @" @^ @~ @= @u @v @H. +\let\, = \ptexc +\let\dotaccent = \ptexdot +\def\ringaccent#1{{\accent23 #1}} +\let\tieaccent = \ptext +\let\ubaraccent = \ptexb +\let\udotaccent = \d + +% Other special characters: @questiondown @exclamdown @ordf @ordm +% Plain TeX defines: @AA @AE @O @OE @L (plus lowercase versions) @ss. +\def\questiondown{?`} +\def\exclamdown{!`} +\def\ordf{\leavevmode\raise1ex\hbox{\switchtolllsize \underbar{a}}} +\def\ordm{\leavevmode\raise1ex\hbox{\switchtolllsize \underbar{o}}} + +% Dotless i and dotless j, used for accents. +\def\imacro{i} +\def\jmacro{j} +\def\dotless#1{% + \def\temp{#1}% + \ifx\temp\imacro \ifmmode\imath \else\ptexi \fi + \else\ifx\temp\jmacro \ifmmode\jmath \else\j \fi + \else \errmessage{@dotless can be used only with i or j}% + \fi\fi +} + +% The \TeX{} logo, as in plain, but resetting the spacing so that a +% period following counts as ending a sentence. (Idea found in latex.) +% +\edef\TeX{\TeX \spacefactor=1000 } + +% @LaTeX{} logo. Not quite the same results as the definition in +% latex.ltx, since we use a different font for the raised A; it's most +% convenient for us to use an explicitly smaller font, rather than using +% the \scriptstyle font (since we don't reset \scriptstyle and +% \scriptscriptstyle). +% +\def\LaTeX{% + L\kern-.36em + {\setbox0=\hbox{T}% + \vbox to \ht0{\hbox{% + \ifx\textnominalsize\xwordpt + % for 10pt running text, lllsize (8pt) is too small for the A in LaTeX. + % Revert to plain's \scriptsize, which is 7pt. + \count255=\the\fam $\fam\count255 \scriptstyle A$% + \else + % For 11pt, we can use our lllsize. + \switchtolllsize A% + \fi + }% + \vss + }}% + \kern-.15em + \TeX +} + +% Some math mode symbols. Define \ensuremath to switch into math mode +% unless we are already there. Expansion tricks may not be needed here, +% but safer, and can't hurt. +\def\ensuremath{\ifmmode \expandafter\asis \else\expandafter\ensuredmath \fi} +\def\ensuredmath#1{$\relax#1$} +% +\def\bullet{\ensuremath\ptexbullet} +\def\geq{\ensuremath\ge} +\def\leq{\ensuremath\le} +\def\minus{\ensuremath-} + +% @dots{} outputs an ellipsis using the current font. +% We do .5em per period so that it has the same spacing in the cm +% typewriter fonts as three actual period characters; on the other hand, +% in other typewriter fonts three periods are wider than 1.5em. So do +% whichever is larger. +% +\def\dots{% + \leavevmode + \setbox0=\hbox{...}% get width of three periods + \ifdim\wd0 > 1.5em + \dimen0 = \wd0 + \else + \dimen0 = 1.5em + \fi + \hbox to \dimen0{% + \hskip 0pt plus.25fil + .\hskip 0pt plus1fil + .\hskip 0pt plus1fil + .\hskip 0pt plus.5fil + }% +} + +% @enddots{} is an end-of-sentence ellipsis. +% +\def\enddots{% + \dots + \spacefactor=\endofsentencespacefactor +} + +% @point{}, @result{}, @expansion{}, @print{}, @equiv{}. +% +% Since these characters are used in examples, they should be an even number of +% \tt widths. Each \tt character is 1en, so two makes it 1em. +% +\def\point{$\star$} +\def\arrow{\leavevmode\raise.05ex\hbox to 1em{\hfil$\rightarrow$\hfil}} +\def\result{\leavevmode\raise.05ex\hbox to 1em{\hfil$\Rightarrow$\hfil}} +\def\expansion{\leavevmode\hbox to 1em{\hfil$\mapsto$\hfil}} +\def\print{\leavevmode\lower.1ex\hbox to 1em{\hfil$\dashv$\hfil}} +\def\equiv{\leavevmode\hbox to 1em{\hfil$\ptexequiv$\hfil}} + +% The @error{} command. +% Adapted from the TeXbook's \boxit. +% +\newbox\errorbox +% +{\ttfont \global\dimen0 = 3em}% Width of the box. +\dimen2 = .55pt % Thickness of rules +% The text. (`r' is open on the right, `e' somewhat less so on the left.) +\setbox0 = \hbox{\kern-.75pt \reducedsf \putworderror\kern-1.5pt} +% +\setbox\errorbox=\hbox to \dimen0{\hfil + \hsize = \dimen0 \advance\hsize by -5.8pt % Space to left+right. + \advance\hsize by -2\dimen2 % Rules. + \vbox{% + \hrule height\dimen2 + \hbox{\vrule width\dimen2 \kern3pt % Space to left of text. + \vtop{\kern2.4pt \box0 \kern2.4pt}% Space above/below. + \kern3pt\vrule width\dimen2}% Space to right. + \hrule height\dimen2} + \hfil} +% +\def\error{\leavevmode\lower.7ex\copy\errorbox} + +% @pounds{} is a sterling sign, which Knuth put in the CM italic font. +% +\def\pounds{{\it\$}} + +% @euro{} comes from a separate font, depending on the current style. +% We use the free feym* fonts from the eurosym package by Henrik +% Theiling, which support regular, slanted, bold and bold slanted (and +% "outlined" (blackboard board, sort of) versions, which we don't need). +% It is available from http://www.ctan.org/tex-archive/fonts/eurosym. +% +% Although only regular is the truly official Euro symbol, we ignore +% that. The Euro is designed to be slightly taller than the regular +% font height. +% +% feymr - regular +% feymo - slanted +% feybr - bold +% feybo - bold slanted +% +% There is no good (free) typewriter version, to my knowledge. +% A feymr10 euro is ~7.3pt wide, while a normal cmtt10 char is ~5.25pt wide. +% Hmm. +% +% Also doesn't work in math. Do we need to do math with euro symbols? +% Hope not. +% +% +\def\euro{{\eurofont e}} +\def\eurofont{% + % We set the font at each command, rather than predefining it in + % \textfonts and the other font-switching commands, so that + % installations which never need the symbol don't have to have the + % font installed. + % + % There is only one designed size (nominal 10pt), so we always scale + % that to the current nominal size. + % + % By the way, simply using "at 1em" works for cmr10 and the like, but + % does not work for cmbx10 and other extended/shrunken fonts. + % + \def\eurosize{\csname\curfontsize nominalsize\endcsname}% + % + \ifx\curfontstyle\bfstylename + % bold: + \font\thiseurofont = \ifusingit{feybo10}{feybr10} at \eurosize + \else + % regular: + \font\thiseurofont = \ifusingit{feymo10}{feymr10} at \eurosize + \fi + \thiseurofont +} + +% Glyphs from the EC fonts. We don't use \let for the aliases, because +% sometimes we redefine the original macro, and the alias should reflect +% the redefinition. +% +% Use LaTeX names for the Icelandic letters. +\def\DH{{\ecfont \char"D0}} % Eth +\def\dh{{\ecfont \char"F0}} % eth +\def\TH{{\ecfont \char"DE}} % Thorn +\def\th{{\ecfont \char"FE}} % thorn +% +\def\guillemetleft{{\ecfont \char"13}} +\def\guillemotleft{\guillemetleft} +\def\guillemetright{{\ecfont \char"14}} +\def\guillemotright{\guillemetright} +\def\guilsinglleft{{\ecfont \char"0E}} +\def\guilsinglright{{\ecfont \char"0F}} +\def\quotedblbase{{\ecfont \char"12}} +\def\quotesinglbase{{\ecfont \char"0D}} +% +% This positioning is not perfect (see the ogonek LaTeX package), but +% we have the precomposed glyphs for the most common cases. We put the +% tests to use those glyphs in the single \ogonek macro so we have fewer +% dummy definitions to worry about for index entries, etc. +% +% ogonek is also used with other letters in Lithuanian (IOU), but using +% the precomposed glyphs for those is not so easy since they aren't in +% the same EC font. +\def\ogonek#1{{% + \def\temp{#1}% + \ifx\temp\macrocharA\Aogonek + \else\ifx\temp\macrochara\aogonek + \else\ifx\temp\macrocharE\Eogonek + \else\ifx\temp\macrochare\eogonek + \else + \ecfont \setbox0=\hbox{#1}% + \ifdim\ht0=1ex\accent"0C #1% + \else\ooalign{\unhbox0\crcr\hidewidth\char"0C \hidewidth}% + \fi + \fi\fi\fi\fi + }% +} +\def\Aogonek{{\ecfont \char"81}}\def\macrocharA{A} +\def\aogonek{{\ecfont \char"A1}}\def\macrochara{a} +\def\Eogonek{{\ecfont \char"86}}\def\macrocharE{E} +\def\eogonek{{\ecfont \char"A6}}\def\macrochare{e} +% +% Use the European Computer Modern fonts (cm-super in outline format) +% for non-CM glyphs. That is ec* for regular text and tc* for the text +% companion symbols (LaTeX TS1 encoding). Both are part of the ec +% package and follow the same conventions. +% +\def\ecfont{\etcfont{e}} +\def\tcfont{\etcfont{t}} +% +\def\etcfont#1{% + % We can't distinguish serif/sans and italic/slanted, but this + % is used for crude hacks anyway (like adding French and German + % quotes to documents typeset with CM, where we lose kerning), so + % hopefully nobody will notice/care. + \edef\ecsize{\csname\curfontsize ecsize\endcsname}% + \edef\nominalsize{\csname\curfontsize nominalsize\endcsname}% + \ifmonospace + % typewriter: + \font\thisecfont = #1ctt\ecsize \space at \nominalsize + \else + \ifx\curfontstyle\bfstylename + % bold: + \font\thisecfont = #1cb\ifusingit{i}{x}\ecsize \space at \nominalsize + \else + % regular: + \font\thisecfont = #1c\ifusingit{ti}{rm}\ecsize \space at \nominalsize + \fi + \fi + \thisecfont +} + +% @registeredsymbol - R in a circle. The font for the R should really +% be smaller yet, but lllsize is the best we can do for now. +% Adapted from the plain.tex definition of \copyright. +% +\def\registeredsymbol{% + $^{{\ooalign{\hfil\raise.07ex\hbox{\switchtolllsize R}% + \hfil\crcr\Orb}}% + }$% +} + +% @textdegree - the normal degrees sign. +% +\def\textdegree{$^\circ$} + +% Laurent Siebenmann reports \Orb undefined with: +% Textures 1.7.7 (preloaded format=plain 93.10.14) (68K) 16 APR 2004 02:38 +% so we'll define it if necessary. +% +\ifx\Orb\thisisundefined +\def\Orb{\mathhexbox20D} +\fi + +% Quotes. +\chardef\quotedblleft="5C +\chardef\quotedblright=`\" +\chardef\quoteleft=`\` +\chardef\quoteright=`\' + + +\message{page headings,} + +\newskip\titlepagetopglue \titlepagetopglue = 1.5in +\newskip\titlepagebottomglue \titlepagebottomglue = 2pc + +% First the title page. Must do @settitle before @titlepage. +\newif\ifseenauthor +\newif\iffinishedtitlepage + +% @setcontentsaftertitlepage used to do an implicit @contents or +% @shortcontents after @end titlepage, but it is now obsolete. +\def\setcontentsaftertitlepage{% + \errmessage{@setcontentsaftertitlepage has been removed as a Texinfo + command; move your @contents command if you want the contents + after the title page.}}% +\def\setshortcontentsaftertitlepage{% + \errmessage{@setshortcontentsaftertitlepage has been removed as a Texinfo + command; move your @shortcontents and @contents commands if you + want the contents after the title page.}}% + +\parseargdef\shorttitlepage{% + \begingroup \hbox{}\vskip 1.5in \chaprm \centerline{#1}% + \endgroup\page\hbox{}\page} + +\envdef\titlepage{% + % Open one extra group, as we want to close it in the middle of \Etitlepage. + \begingroup + \parindent=0pt \textfonts + % Leave some space at the very top of the page. + \vglue\titlepagetopglue + % No rule at page bottom unless we print one at the top with @title. + \finishedtitlepagetrue + % + % Most title ``pages'' are actually two pages long, with space + % at the top of the second. We don't want the ragged left on the second. + \let\oldpage = \page + \def\page{% + \iffinishedtitlepage\else + \finishtitlepage + \fi + \let\page = \oldpage + \page + \null + }% +} + +\def\Etitlepage{% + \iffinishedtitlepage\else + \finishtitlepage + \fi + % It is important to do the page break before ending the group, + % because the headline and footline are only empty inside the group. + % If we use the new definition of \page, we always get a blank page + % after the title page, which we certainly don't want. + \oldpage + \endgroup + % + % Need this before the \...aftertitlepage checks so that if they are + % in effect the toc pages will come out with page numbers. + \HEADINGSon +} + +\def\finishtitlepage{% + \vskip4pt \hrule height 2pt width \hsize + \vskip\titlepagebottomglue + \finishedtitlepagetrue +} + +% Settings used for typesetting titles: no hyphenation, no indentation, +% don't worry much about spacing, ragged right. This should be used +% inside a \vbox, and fonts need to be set appropriately first. \par should +% be specified before the end of the \vbox, since a vbox is a group. +% +\def\raggedtitlesettings{% + \rm + \hyphenpenalty=10000 + \parindent=0pt + \tolerance=5000 + \ptexraggedright +} + +% Macros to be used within @titlepage: + +\let\subtitlerm=\rmfont +\def\subtitlefont{\subtitlerm \normalbaselineskip = 13pt \normalbaselines} + +\parseargdef\title{% + \checkenv\titlepage + \vbox{\titlefonts \raggedtitlesettings #1\par}% + % print a rule at the page bottom also. + \finishedtitlepagefalse + \vskip4pt \hrule height 4pt width \hsize \vskip4pt +} + +\parseargdef\subtitle{% + \checkenv\titlepage + {\subtitlefont \rightline{#1}}% +} + +% @author should come last, but may come many times. +% It can also be used inside @quotation. +% +\parseargdef\author{% + \def\temp{\quotation}% + \ifx\thisenv\temp + \def\quotationauthor{#1}% printed in \Equotation. + \else + \checkenv\titlepage + \ifseenauthor\else \vskip 0pt plus 1filll \seenauthortrue \fi + {\secfonts\rm \leftline{#1}}% + \fi +} + + +% Set up page headings and footings. + +\let\thispage=\folio + +\newtoks\evenheadline % headline on even pages +\newtoks\oddheadline % headline on odd pages +\newtoks\evenfootline % footline on even pages +\newtoks\oddfootline % footline on odd pages + +% Now make \makeheadline and \makefootline in Plain TeX use those variables +\headline={{\textfonts\rm \ifodd\pageno \the\oddheadline + \else \the\evenheadline \fi}} +\footline={{\textfonts\rm \ifodd\pageno \the\oddfootline + \else \the\evenfootline \fi}\HEADINGShook} +\let\HEADINGShook=\relax + +% Commands to set those variables. +% For example, this is what @headings on does +% @evenheading @thistitle|@thispage|@thischapter +% @oddheading @thischapter|@thispage|@thistitle +% @evenfooting @thisfile|| +% @oddfooting ||@thisfile + + +\def\evenheading{\parsearg\evenheadingxxx} +\def\evenheadingxxx #1{\evenheadingyyy #1\|\|\|\|\finish} +\def\evenheadingyyy #1\|#2\|#3\|#4\finish{% +\global\evenheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} + +\def\oddheading{\parsearg\oddheadingxxx} +\def\oddheadingxxx #1{\oddheadingyyy #1\|\|\|\|\finish} +\def\oddheadingyyy #1\|#2\|#3\|#4\finish{% +\global\oddheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} + +\parseargdef\everyheading{\oddheadingxxx{#1}\evenheadingxxx{#1}}% + +\def\evenfooting{\parsearg\evenfootingxxx} +\def\evenfootingxxx #1{\evenfootingyyy #1\|\|\|\|\finish} +\def\evenfootingyyy #1\|#2\|#3\|#4\finish{% +\global\evenfootline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} + +\def\oddfooting{\parsearg\oddfootingxxx} +\def\oddfootingxxx #1{\oddfootingyyy #1\|\|\|\|\finish} +\def\oddfootingyyy #1\|#2\|#3\|#4\finish{% + \global\oddfootline = {\rlap{\centerline{#2}}\line{#1\hfil#3}}% + % + % Leave some space for the footline. Hopefully ok to assume + % @evenfooting will not be used by itself. + \global\advance\txipageheight by -12pt + \global\advance\vsize by -12pt +} + +\parseargdef\everyfooting{\oddfootingxxx{#1}\evenfootingxxx{#1}} + +% @evenheadingmarks top \thischapter <- chapter at the top of a page +% @evenheadingmarks bottom \thischapter <- chapter at the bottom of a page +% +% The same set of arguments for: +% +% @oddheadingmarks +% @evenfootingmarks +% @oddfootingmarks +% @everyheadingmarks +% @everyfootingmarks + +% These define \getoddheadingmarks, \getevenheadingmarks, +% \getoddfootingmarks, and \getevenfootingmarks, each to one of +% \gettopheadingmarks, \getbottomheadingmarks. +% +\def\evenheadingmarks{\headingmarks{even}{heading}} +\def\oddheadingmarks{\headingmarks{odd}{heading}} +\def\evenfootingmarks{\headingmarks{even}{footing}} +\def\oddfootingmarks{\headingmarks{odd}{footing}} +\parseargdef\everyheadingmarks{\headingmarks{even}{heading}{#1} + \headingmarks{odd}{heading}{#1} } +\parseargdef\everyfootingmarks{\headingmarks{even}{footing}{#1} + \headingmarks{odd}{footing}{#1} } +% #1 = even/odd, #2 = heading/footing, #3 = top/bottom. +\def\headingmarks#1#2#3 {% + \expandafter\let\expandafter\temp \csname get#3headingmarks\endcsname + \global\expandafter\let\csname get#1#2marks\endcsname \temp +} + +\everyheadingmarks bottom +\everyfootingmarks bottom + +% @headings double turns headings on for double-sided printing. +% @headings single turns headings on for single-sided printing. +% @headings off turns them off. +% @headings on same as @headings double, retained for compatibility. +% @headings after turns on double-sided headings after this page. +% @headings doubleafter turns on double-sided headings after this page. +% @headings singleafter turns on single-sided headings after this page. +% By default, they are off at the start of a document, +% and turned `on' after @end titlepage. + +\parseargdef\headings{\csname HEADINGS#1\endcsname} + +\def\headingsoff{% non-global headings elimination + \evenheadline={\hfil}\evenfootline={\hfil}% + \oddheadline={\hfil}\oddfootline={\hfil}% +} + +\def\HEADINGSoff{{\globaldefs=1 \headingsoff}} % global setting +\HEADINGSoff % it's the default + +% When we turn headings on, set the page number to 1. +% For double-sided printing, put current file name in lower left corner, +% chapter name on inside top of right hand pages, document +% title on inside top of left hand pages, and page numbers on outside top +% edge of all pages. +\def\HEADINGSdouble{% +\global\pageno=1 +\global\evenfootline={\hfil} +\global\oddfootline={\hfil} +\global\evenheadline={\line{\folio\hfil\thistitle}} +\global\oddheadline={\line{\thischapterheading\hfil\folio}} +\global\let\contentsalignmacro = \chapoddpage +} +\let\contentsalignmacro = \chappager + +% For single-sided printing, chapter title goes across top left of page, +% page number on top right. +\def\HEADINGSsingle{% +\global\pageno=1 +\global\evenfootline={\hfil} +\global\oddfootline={\hfil} +\global\evenheadline={\line{\thischapterheading\hfil\folio}} +\global\oddheadline={\line{\thischapterheading\hfil\folio}} +\global\let\contentsalignmacro = \chappager +} +\def\HEADINGSon{\HEADINGSdouble} + +\def\HEADINGSafter{\let\HEADINGShook=\HEADINGSdoublex} +\let\HEADINGSdoubleafter=\HEADINGSafter +\def\HEADINGSdoublex{% +\global\evenfootline={\hfil} +\global\oddfootline={\hfil} +\global\evenheadline={\line{\folio\hfil\thistitle}} +\global\oddheadline={\line{\thischapterheading\hfil\folio}} +\global\let\contentsalignmacro = \chapoddpage +} + +\def\HEADINGSsingleafter{\let\HEADINGShook=\HEADINGSsinglex} +\def\HEADINGSsinglex{% +\global\evenfootline={\hfil} +\global\oddfootline={\hfil} +\global\evenheadline={\line{\thischapterheading\hfil\folio}} +\global\oddheadline={\line{\thischapterheading\hfil\folio}} +\global\let\contentsalignmacro = \chappager +} + +% Subroutines used in generating headings +% This produces Day Month Year style of output. +% Only define if not already defined, in case a txi-??.tex file has set +% up a different format (e.g., txi-cs.tex does this). +\ifx\today\thisisundefined +\def\today{% + \number\day\space + \ifcase\month + \or\putwordMJan\or\putwordMFeb\or\putwordMMar\or\putwordMApr + \or\putwordMMay\or\putwordMJun\or\putwordMJul\or\putwordMAug + \or\putwordMSep\or\putwordMOct\or\putwordMNov\or\putwordMDec + \fi + \space\number\year} +\fi + +% @settitle line... specifies the title of the document, for headings. +% It generates no output of its own. +\def\thistitle{\putwordNoTitle} +\def\settitle{\parsearg{\gdef\thistitle}} + + +\message{tables,} +% Tables -- @table, @ftable, @vtable, @item(x). + +% default indentation of table text +\newdimen\tableindent \tableindent=.8in +% default indentation of @itemize and @enumerate text +\newdimen\itemindent \itemindent=.3in +% margin between end of table item and start of table text. +\newdimen\itemmargin \itemmargin=.1in + +% used internally for \itemindent minus \itemmargin +\newdimen\itemmax + +% Note @table, @ftable, and @vtable define @item, @itemx, etc., with +% these defs. +% They also define \itemindex +% to index the item name in whatever manner is desired (perhaps none). + +\newif\ifitemxneedsnegativevskip + +\def\itemxpar{\par\ifitemxneedsnegativevskip\nobreak\vskip-\parskip\nobreak\fi} + +\def\internalBitem{\smallbreak \parsearg\itemzzz} +\def\internalBitemx{\itemxpar \parsearg\itemzzz} + +\def\itemzzz #1{\begingroup % + \advance\hsize by -\rightskip + \advance\hsize by -\tableindent + \setbox0=\hbox{\itemindicate{#1}}% + \itemindex{#1}% + \nobreak % This prevents a break before @itemx. + % + % If the item text does not fit in the space we have, put it on a line + % by itself, and do not allow a page break either before or after that + % line. We do not start a paragraph here because then if the next + % command is, e.g., @kindex, the whatsit would get put into the + % horizontal list on a line by itself, resulting in extra blank space. + \ifdim \wd0>\itemmax + % + % Make this a paragraph so we get the \parskip glue and wrapping, + % but leave it ragged-right. + \begingroup + \advance\leftskip by-\tableindent + \advance\hsize by\tableindent + \advance\rightskip by0pt plus1fil\relax + \leavevmode\unhbox0\par + \endgroup + % + % We're going to be starting a paragraph, but we don't want the + % \parskip glue -- logically it's part of the @item we just started. + \nobreak \vskip-\parskip + % + % Stop a page break at the \parskip glue coming up. However, if + % what follows is an environment such as @example, there will be no + % \parskip glue; then the negative vskip we just inserted would + % cause the example and the item to crash together. So we use this + % bizarre value of 10001 as a signal to \aboveenvbreak to insert + % \parskip glue after all. Section titles are handled this way also. + % + \penalty 10001 + \endgroup + \itemxneedsnegativevskipfalse + \else + % The item text fits into the space. Start a paragraph, so that the + % following text (if any) will end up on the same line. + \noindent + % Do this with kerns and \unhbox so that if there is a footnote in + % the item text, it can migrate to the main vertical list and + % eventually be printed. + \nobreak\kern-\tableindent + \dimen0 = \itemmax \advance\dimen0 by \itemmargin \advance\dimen0 by -\wd0 + \unhbox0 + \nobreak\kern\dimen0 + \endgroup + \itemxneedsnegativevskiptrue + \fi +} + +\def\item{\errmessage{@item while not in a list environment}} +\def\itemx{\errmessage{@itemx while not in a list environment}} + +% @table, @ftable, @vtable. +\envdef\table{% + \let\itemindex\gobble + \tablecheck{table}% +} +\envdef\ftable{% + \def\itemindex ##1{\doind {fn}{\code{##1}}}% + \tablecheck{ftable}% +} +\envdef\vtable{% + \def\itemindex ##1{\doind {vr}{\code{##1}}}% + \tablecheck{vtable}% +} +\def\tablecheck#1{% + \ifnum \the\catcode`\^^M=\active + \endgroup + \errmessage{This command won't work in this context; perhaps the problem is + that we are \inenvironment\thisenv}% + \def\next{\doignore{#1}}% + \else + \let\next\tablex + \fi + \next +} +\def\tablex#1{% + \def\itemindicate{#1}% + \parsearg\tabley +} +\def\tabley#1{% + {% + \makevalueexpandable + \edef\temp{\noexpand\tablez #1\space\space\space}% + \expandafter + }\temp \endtablez +} +\def\tablez #1 #2 #3 #4\endtablez{% + \aboveenvbreak + \ifnum 0#1>0 \advance \leftskip by #1\mil \fi + \ifnum 0#2>0 \tableindent=#2\mil \fi + \ifnum 0#3>0 \advance \rightskip by #3\mil \fi + \itemmax=\tableindent + \advance \itemmax by -\itemmargin + \advance \leftskip by \tableindent + \exdentamount=\tableindent + \parindent = 0pt + \parskip = \smallskipamount + \ifdim \parskip=0pt \parskip=2pt \fi + \let\item = \internalBitem + \let\itemx = \internalBitemx +} +\def\Etable{\endgraf\afterenvbreak} +\let\Eftable\Etable +\let\Evtable\Etable +\let\Eitemize\Etable +\let\Eenumerate\Etable + +% This is the counter used by @enumerate, which is really @itemize + +\newcount \itemno + +\envdef\itemize{\parsearg\doitemize} + +\def\doitemize#1{% + \aboveenvbreak + \itemmax=\itemindent + \advance\itemmax by -\itemmargin + \advance\leftskip by \itemindent + \exdentamount=\itemindent + \parindent=0pt + \parskip=\smallskipamount + \ifdim\parskip=0pt \parskip=2pt \fi + % + % Try typesetting the item mark so that if the document erroneously says + % something like @itemize @samp (intending @table), there's an error + % right away at the @itemize. It's not the best error message in the + % world, but it's better than leaving it to the @item. This means if + % the user wants an empty mark, they have to say @w{} not just @w. + \def\itemcontents{#1}% + \setbox0 = \hbox{\itemcontents}% + % + % @itemize with no arg is equivalent to @itemize @bullet. + \ifx\itemcontents\empty\def\itemcontents{\bullet}\fi + % + \let\item=\itemizeitem +} + +% Definition of @item while inside @itemize and @enumerate. +% +\def\itemizeitem{% + \advance\itemno by 1 % for enumerations + {\let\par=\endgraf \smallbreak}% reasonable place to break + {% + % If the document has an @itemize directly after a section title, a + % \nobreak will be last on the list, and \sectionheading will have + % done a \vskip-\parskip. In that case, we don't want to zero + % parskip, or the item text will crash with the heading. On the + % other hand, when there is normal text preceding the item (as there + % usually is), we do want to zero parskip, or there would be too much + % space. In that case, we won't have a \nobreak before. At least + % that's the theory. + \ifnum\lastpenalty<10000 \parskip=0in \fi + \noindent + \hbox to 0pt{\hss \itemcontents \kern\itemmargin}% + % + \ifinner\else + \vadjust{\penalty 1200}% not good to break after first line of item. + \fi + % We can be in inner vertical mode in a footnote, although an + % @itemize looks awful there. + }% + \flushcr +} + +% \splitoff TOKENS\endmark defines \first to be the first token in +% TOKENS, and \rest to be the remainder. +% +\def\splitoff#1#2\endmark{\def\first{#1}\def\rest{#2}}% + +% Allow an optional argument of an uppercase letter, lowercase letter, +% or number, to specify the first label in the enumerated list. No +% argument is the same as `1'. +% +\envparseargdef\enumerate{\enumeratey #1 \endenumeratey} +\def\enumeratey #1 #2\endenumeratey{% + % If we were given no argument, pretend we were given `1'. + \def\thearg{#1}% + \ifx\thearg\empty \def\thearg{1}\fi + % + % Detect if the argument is a single token. If so, it might be a + % letter. Otherwise, the only valid thing it can be is a number. + % (We will always have one token, because of the test we just made. + % This is a good thing, since \splitoff doesn't work given nothing at + % all -- the first parameter is undelimited.) + \expandafter\splitoff\thearg\endmark + \ifx\rest\empty + % Only one token in the argument. It could still be anything. + % A ``lowercase letter'' is one whose \lccode is nonzero. + % An ``uppercase letter'' is one whose \lccode is both nonzero, and + % not equal to itself. + % Otherwise, we assume it's a number. + % + % We need the \relax at the end of the \ifnum lines to stop TeX from + % continuing to look for a <number>. + % + \ifnum\lccode\expandafter`\thearg=0\relax + \numericenumerate % a number (we hope) + \else + % It's a letter. + \ifnum\lccode\expandafter`\thearg=\expandafter`\thearg\relax + \lowercaseenumerate % lowercase letter + \else + \uppercaseenumerate % uppercase letter + \fi + \fi + \else + % Multiple tokens in the argument. We hope it's a number. + \numericenumerate + \fi +} + +% An @enumerate whose labels are integers. The starting integer is +% given in \thearg. +% +\def\numericenumerate{% + \itemno = \thearg + \startenumeration{\the\itemno}% +} + +% The starting (lowercase) letter is in \thearg. +\def\lowercaseenumerate{% + \itemno = \expandafter`\thearg + \startenumeration{% + % Be sure we're not beyond the end of the alphabet. + \ifnum\itemno=0 + \errmessage{No more lowercase letters in @enumerate; get a bigger + alphabet}% + \fi + \char\lccode\itemno + }% +} + +% The starting (uppercase) letter is in \thearg. +\def\uppercaseenumerate{% + \itemno = \expandafter`\thearg + \startenumeration{% + % Be sure we're not beyond the end of the alphabet. + \ifnum\itemno=0 + \errmessage{No more uppercase letters in @enumerate; get a bigger + alphabet} + \fi + \char\uccode\itemno + }% +} + +% Call \doitemize, adding a period to the first argument and supplying the +% common last two arguments. Also subtract one from the initial value in +% \itemno, since @item increments \itemno. +% +\def\startenumeration#1{% + \advance\itemno by -1 + \doitemize{#1.}\flushcr +} + +% @alphaenumerate and @capsenumerate are abbreviations for giving an arg +% to @enumerate. +% +\def\alphaenumerate{\enumerate{a}} +\def\capsenumerate{\enumerate{A}} +\def\Ealphaenumerate{\Eenumerate} +\def\Ecapsenumerate{\Eenumerate} + + +% @multitable macros +% Amy Hendrickson, 8/18/94, 3/6/96 +% +% @multitable ... @end multitable will make as many columns as desired. +% Contents of each column will wrap at width given in preamble. Width +% can be specified either with sample text given in a template line, +% or in percent of \hsize, the current width of text on page. + +% Table can continue over pages but will only break between lines. + +% To make preamble: +% +% Either define widths of columns in terms of percent of \hsize: +% @multitable @columnfractions .25 .3 .45 +% @item ... +% +% Numbers following @columnfractions are the percent of the total +% current hsize to be used for each column. You may use as many +% columns as desired. + + +% Or use a template: +% @multitable {Column 1 template} {Column 2 template} {Column 3 template} +% @item ... +% using the widest term desired in each column. + +% Each new table line starts with @item, each subsequent new column +% starts with @tab. Empty columns may be produced by supplying @tab's +% with nothing between them for as many times as empty columns are needed, +% ie, @tab@tab@tab will produce two empty columns. + +% @item, @tab do not need to be on their own lines, but it will not hurt +% if they are. + +% Sample multitable: + +% @multitable {Column 1 template} {Column 2 template} {Column 3 template} +% @item first col stuff @tab second col stuff @tab third col +% @item +% first col stuff +% @tab +% second col stuff +% @tab +% third col +% @item first col stuff @tab second col stuff +% @tab Many paragraphs of text may be used in any column. +% +% They will wrap at the width determined by the template. +% @item@tab@tab This will be in third column. +% @end multitable + +% Default dimensions may be reset by user. +% @multitableparskip is vertical space between paragraphs in table. +% @multitableparindent is paragraph indent in table. +% @multitablecolmargin is horizontal space to be left between columns. +% @multitablelinespace is space to leave between table items, baseline +% to baseline. +% 0pt means it depends on current normal line spacing. +% +\newskip\multitableparskip +\newskip\multitableparindent +\newdimen\multitablecolspace +\newskip\multitablelinespace +\multitableparskip=0pt +\multitableparindent=6pt +\multitablecolspace=12pt +\multitablelinespace=0pt + +% Macros used to set up halign preamble: +% +\let\endsetuptable\relax +\def\xendsetuptable{\endsetuptable} +\let\columnfractions\relax +\def\xcolumnfractions{\columnfractions} +\newif\ifsetpercent + +% #1 is the @columnfraction, usually a decimal number like .5, but might +% be just 1. We just use it, whatever it is. +% +\def\pickupwholefraction#1 {% + \global\advance\colcount by 1 + \expandafter\xdef\csname col\the\colcount\endcsname{#1\hsize}% + \setuptable +} + +\newcount\colcount +\def\setuptable#1{% + \def\firstarg{#1}% + \ifx\firstarg\xendsetuptable + \let\go = \relax + \else + \ifx\firstarg\xcolumnfractions + \global\setpercenttrue + \else + \ifsetpercent + \let\go\pickupwholefraction + \else + \global\advance\colcount by 1 + \setbox0=\hbox{#1\unskip\space}% Add a normal word space as a + % separator; typically that is always in the input, anyway. + \expandafter\xdef\csname col\the\colcount\endcsname{\the\wd0}% + \fi + \fi + \ifx\go\pickupwholefraction + % Put the argument back for the \pickupwholefraction call, so + % we'll always have a period there to be parsed. + \def\go{\pickupwholefraction#1}% + \else + \let\go = \setuptable + \fi% + \fi + \go +} + +% multitable-only commands. +% +% @headitem starts a heading row, which we typeset in bold. Assignments +% have to be global since we are inside the implicit group of an +% alignment entry. \everycr below resets \everytab so we don't have to +% undo it ourselves. +\def\headitemfont{\b}% for people to use in the template row; not changeable +\def\headitem{% + \checkenv\multitable + \crcr + \gdef\headitemcrhook{\nobreak}% attempt to avoid page break after headings + \global\everytab={\bf}% can't use \headitemfont since the parsing differs + \the\everytab % for the first item +}% +% +% default for tables with no headings. +\let\headitemcrhook=\relax +% +% A \tab used to include \hskip1sp. But then the space in a template +% line is not enough. That is bad. So let's go back to just `&' until +% we again encounter the problem the 1sp was intended to solve. +% --karl, nathan@acm.org, 20apr99. +\def\tab{\checkenv\multitable &\the\everytab}% + +% @multitable ... @end multitable definitions: +% +\newtoks\everytab % insert after every tab. +% +\envdef\multitable{% + \vskip\parskip + \startsavinginserts + % + % @item within a multitable starts a normal row. + % We use \def instead of \let so that if one of the multitable entries + % contains an @itemize, we don't choke on the \item (seen as \crcr aka + % \endtemplate) expanding \doitemize. + \def\item{\crcr}% + % + \tolerance=9500 + \hbadness=9500 + \setmultitablespacing + \parskip=\multitableparskip + \parindent=\multitableparindent + \overfullrule=0pt + \global\colcount=0 + % + \everycr = {% + \noalign{% + \global\everytab={}% Reset from possible headitem. + \global\colcount=0 % Reset the column counter. + % + % Check for saved footnotes, etc.: + \checkinserts + % + % Perhaps a \nobreak, then reset: + \headitemcrhook + \global\let\headitemcrhook=\relax + }% + }% + % + \parsearg\domultitable +} +\def\domultitable#1{% + % To parse everything between @multitable and @item: + \setuptable#1 \endsetuptable + % + % This preamble sets up a generic column definition, which will + % be used as many times as user calls for columns. + % \vtop will set a single line and will also let text wrap and + % continue for many paragraphs if desired. + \halign\bgroup &% + \global\advance\colcount by 1 + \multistrut + \vtop{% + % Use the current \colcount to find the correct column width: + \hsize=\expandafter\csname col\the\colcount\endcsname + % + % In order to keep entries from bumping into each other + % we will add a \leftskip of \multitablecolspace to all columns after + % the first one. + % + % If a template has been used, we will add \multitablecolspace + % to the width of each template entry. + % + % If the user has set preamble in terms of percent of \hsize we will + % use that dimension as the width of the column, and the \leftskip + % will keep entries from bumping into each other. Table will start at + % left margin and final column will justify at right margin. + % + % Make sure we don't inherit \rightskip from the outer environment. + \rightskip=0pt + \ifnum\colcount=1 + % The first column will be indented with the surrounding text. + \advance\hsize by\leftskip + \else + \ifsetpercent \else + % If user has not set preamble in terms of percent of \hsize + % we will advance \hsize by \multitablecolspace. + \advance\hsize by \multitablecolspace + \fi + % In either case we will make \leftskip=\multitablecolspace: + \leftskip=\multitablecolspace + \fi + % Ignoring space at the beginning and end avoids an occasional spurious + % blank line, when TeX decides to break the line at the space before the + % box from the multistrut, so the strut ends up on a line by itself. + % For example: + % @multitable @columnfractions .11 .89 + % @item @code{#} + % @tab Legal holiday which is valid in major parts of the whole country. + % Is automatically provided with highlighting sequences respectively + % marking characters. + \noindent\ignorespaces##\unskip\multistrut + }\cr +} +\def\Emultitable{% + \crcr + \egroup % end the \halign + \global\setpercentfalse +} + +\def\setmultitablespacing{% + \def\multistrut{\strut}% just use the standard line spacing + % + % Compute \multitablelinespace (if not defined by user) for use in + % \multitableparskip calculation. We used define \multistrut based on + % this, but (ironically) that caused the spacing to be off. + % See bug-texinfo report from Werner Lemberg, 31 Oct 2004 12:52:20 +0100. +\ifdim\multitablelinespace=0pt +\setbox0=\vbox{X}\global\multitablelinespace=\the\baselineskip +\global\advance\multitablelinespace by-\ht0 +\fi +% Test to see if parskip is larger than space between lines of +% table. If not, do nothing. +% If so, set to same dimension as multitablelinespace. +\ifdim\multitableparskip>\multitablelinespace +\global\multitableparskip=\multitablelinespace +\global\advance\multitableparskip-7pt % to keep parskip somewhat smaller + % than skip between lines in the table. +\fi% +\ifdim\multitableparskip=0pt +\global\multitableparskip=\multitablelinespace +\global\advance\multitableparskip-7pt % to keep parskip somewhat smaller + % than skip between lines in the table. +\fi} + + +\message{conditionals,} + +% @iftex, @ifnotdocbook, @ifnothtml, @ifnotinfo, @ifnotplaintext, +% @ifnotxml always succeed. They currently do nothing; we don't +% attempt to check whether the conditionals are properly nested. But we +% have to remember that they are conditionals, so that @end doesn't +% attempt to close an environment group. +% +\def\makecond#1{% + \expandafter\let\csname #1\endcsname = \relax + \expandafter\let\csname iscond.#1\endcsname = 1 +} +\makecond{iftex} +\makecond{ifnotdocbook} +\makecond{ifnothtml} +\makecond{ifnotinfo} +\makecond{ifnotplaintext} +\makecond{ifnotxml} + +% Ignore @ignore, @ifhtml, @ifinfo, and the like. +% +\def\direntry{\doignore{direntry}} +\def\documentdescription{\doignore{documentdescription}} +\def\docbook{\doignore{docbook}} +\def\html{\doignore{html}} +\def\ifdocbook{\doignore{ifdocbook}} +\def\ifhtml{\doignore{ifhtml}} +\def\ifinfo{\doignore{ifinfo}} +\def\ifnottex{\doignore{ifnottex}} +\def\ifplaintext{\doignore{ifplaintext}} +\def\ifxml{\doignore{ifxml}} +\def\ignore{\doignore{ignore}} +\def\menu{\doignore{menu}} +\def\xml{\doignore{xml}} + +% Ignore text until a line `@end #1', keeping track of nested conditionals. +% +% A count to remember the depth of nesting. +\newcount\doignorecount + +\def\doignore#1{\begingroup + % Scan in ``verbatim'' mode: + \obeylines + \catcode`\@ = \other + \catcode`\{ = \other + \catcode`\} = \other + % + % Make sure that spaces turn into tokens that match what \doignoretext wants. + \spaceisspace + % + % Count number of #1's that we've seen. + \doignorecount = 0 + % + % Swallow text until we reach the matching `@end #1'. + \dodoignore{#1}% +} + +{ \catcode`_=11 % We want to use \_STOP_ which cannot appear in texinfo source. + \obeylines % + % + \gdef\dodoignore#1{% + % #1 contains the command name as a string, e.g., `ifinfo'. + % + % Define a command to find the next `@end #1'. + \long\def\doignoretext##1^^M@end #1{% + \doignoretextyyy##1^^M@#1\_STOP_}% + % + % And this command to find another #1 command, at the beginning of a + % line. (Otherwise, we would consider a line `@c @ifset', for + % example, to count as an @ifset for nesting.) + \long\def\doignoretextyyy##1^^M@#1##2\_STOP_{\doignoreyyy{##2}\_STOP_}% + % + % And now expand that command. + \doignoretext ^^M% + }% +} + +\def\doignoreyyy#1{% + \def\temp{#1}% + \ifx\temp\empty % Nothing found. + \let\next\doignoretextzzz + \else % Found a nested condition, ... + \advance\doignorecount by 1 + \let\next\doignoretextyyy % ..., look for another. + % If we're here, #1 ends with ^^M\ifinfo (for example). + \fi + \next #1% the token \_STOP_ is present just after this macro. +} + +% We have to swallow the remaining "\_STOP_". +% +\def\doignoretextzzz#1{% + \ifnum\doignorecount = 0 % We have just found the outermost @end. + \let\next\enddoignore + \else % Still inside a nested condition. + \advance\doignorecount by -1 + \let\next\doignoretext % Look for the next @end. + \fi + \next +} + +% Finish off ignored text. +{ \obeylines% + % Ignore anything after the last `@end #1'; this matters in verbatim + % environments, where otherwise the newline after an ignored conditional + % would result in a blank line in the output. + \gdef\enddoignore#1^^M{\endgroup\ignorespaces}% +} + + +% @set VAR sets the variable VAR to an empty value. +% @set VAR REST-OF-LINE sets VAR to the value REST-OF-LINE. +% +% Since we want to separate VAR from REST-OF-LINE (which might be +% empty), we can't just use \parsearg; we have to insert a space of our +% own to delimit the rest of the line, and then take it out again if we +% didn't need it. +% We rely on the fact that \parsearg sets \catcode`\ =10. +% +\parseargdef\set{\setyyy#1 \endsetyyy} +\def\setyyy#1 #2\endsetyyy{% + {% + \makevalueexpandable + \def\temp{#2}% + \edef\next{\gdef\makecsname{SET#1}}% + \ifx\temp\empty + \next{}% + \else + \setzzz#2\endsetzzz + \fi + }% +} +% Remove the trailing space \setxxx inserted. +\def\setzzz#1 \endsetzzz{\next{#1}} + +% @clear VAR clears (i.e., unsets) the variable VAR. +% +\parseargdef\clear{% + {% + \makevalueexpandable + \global\expandafter\let\csname SET#1\endcsname=\relax + }% +} + +% @value{foo} gets the text saved in variable foo. +\def\value{\begingroup\makevalueexpandable\valuexxx} +\def\valuexxx#1{\expandablevalue{#1}\endgroup} +{ + \catcode`\-=\active \catcode`\_=\active + % + \gdef\makevalueexpandable{% + \let\value = \expandablevalue + % We don't want these characters active, ... + \catcode`\-=\other \catcode`\_=\other + % ..., but we might end up with active ones in the argument if + % we're called from @code, as @code{@value{foo-bar_}}, though. + % So \let them to their normal equivalents. + \let-\normaldash \let_\normalunderscore + } +} + +% We have this subroutine so that we can handle at least some @value's +% properly in indexes (we call \makevalueexpandable in \indexdummies). +% The command has to be fully expandable (if the variable is set), since +% the result winds up in the index file. This means that if the +% variable's value contains other Texinfo commands, it's almost certain +% it will fail (although perhaps we could fix that with sufficient work +% to do a one-level expansion on the result, instead of complete). +% +% Unfortunately, this has the consequence that when _ is in the *value* +% of an @set, it does not print properly in the roman fonts (get the cmr +% dot accent at position 126 instead). No fix comes to mind, and it's +% been this way since 2003 or earlier, so just ignore it. +% +\def\expandablevalue#1{% + \expandafter\ifx\csname SET#1\endcsname\relax + {[No value for ``#1'']}% + \message{Variable `#1', used in @value, is not set.}% + \else + \csname SET#1\endcsname + \fi +} + +% Like \expandablevalue, but completely expandable (the \message in the +% definition above operates at the execution level of TeX). Used when +% writing to auxiliary files, due to the expansion that \write does. +% If flag is undefined, pass through an unexpanded @value command: maybe it +% will be set by the time it is read back in. +% +% NB flag names containing - or _ may not work here. +\def\dummyvalue#1{% + \expandafter\ifx\csname SET#1\endcsname\relax + \noexpand\value{#1}% + \else + \csname SET#1\endcsname + \fi +} + +% Used for @value's in index entries to form the sort key: expand the @value +% if possible, otherwise sort late. +\def\indexnofontsvalue#1{% + \expandafter\ifx\csname SET#1\endcsname\relax + ZZZZZZZ + \else + \csname SET#1\endcsname + \fi +} + +% @ifset VAR ... @end ifset reads the `...' iff VAR has been defined +% with @set. +% +% To get the special treatment we need for `@end ifset,' we call +% \makecond and then redefine. +% +\makecond{ifset} +\def\ifset{\parsearg{\doifset{\let\next=\ifsetfail}}} +\def\doifset#1#2{% + {% + \makevalueexpandable + \let\next=\empty + \expandafter\ifx\csname SET#2\endcsname\relax + #1% If not set, redefine \next. + \fi + \expandafter + }\next +} +\def\ifsetfail{\doignore{ifset}} + +% @ifclear VAR ... @end executes the `...' iff VAR has never been +% defined with @set, or has been undefined with @clear. +% +% The `\else' inside the `\doifset' parameter is a trick to reuse the +% above code: if the variable is not set, do nothing, if it is set, +% then redefine \next to \ifclearfail. +% +\makecond{ifclear} +\def\ifclear{\parsearg{\doifset{\else \let\next=\ifclearfail}}} +\def\ifclearfail{\doignore{ifclear}} + +% @ifcommandisdefined CMD ... @end executes the `...' if CMD (written +% without the @) is in fact defined. We can only feasibly check at the +% TeX level, so something like `mathcode' is going to considered +% defined even though it is not a Texinfo command. +% +\makecond{ifcommanddefined} +\def\ifcommanddefined{\parsearg{\doifcmddefined{\let\next=\ifcmddefinedfail}}} +% +\def\doifcmddefined#1#2{{% + \makevalueexpandable + \let\next=\empty + \expandafter\ifx\csname #2\endcsname\relax + #1% If not defined, \let\next as above. + \fi + \expandafter + }\next +} +\def\ifcmddefinedfail{\doignore{ifcommanddefined}} + +% @ifcommandnotdefined CMD ... handled similar to @ifclear above. +\makecond{ifcommandnotdefined} +\def\ifcommandnotdefined{% + \parsearg{\doifcmddefined{\else \let\next=\ifcmdnotdefinedfail}}} +\def\ifcmdnotdefinedfail{\doignore{ifcommandnotdefined}} + +% Set the `txicommandconditionals' variable, so documents have a way to +% test if the @ifcommand...defined conditionals are available. +\set txicommandconditionals + +% @dircategory CATEGORY -- specify a category of the dir file +% which this file should belong to. Ignore this in TeX. +\let\dircategory=\comment + +% @defininfoenclose. +\let\definfoenclose=\comment + + +\message{indexing,} +% Index generation facilities + +% Define \newwrite to be identical to plain tex's \newwrite +% except not \outer, so it can be used within macros and \if's. +\edef\newwrite{\makecsname{ptexnewwrite}} + +% \newindex {foo} defines an index named IX. +% It automatically defines \IXindex such that +% \IXindex ...rest of line... puts an entry in the index IX. +% It also defines \IXindfile to be the number of the output channel for +% the file that accumulates this index. The file's extension is IX. +% The name of an index should be no more than 2 characters long +% for the sake of vms. +% +\def\newindex#1{% + \expandafter\chardef\csname#1indfile\endcsname=0 + \expandafter\xdef\csname#1index\endcsname{% % Define @#1index + \noexpand\doindex{#1}} +} + +% @defindex foo == \newindex{foo} +% +\def\defindex{\parsearg\newindex} + +% Define @defcodeindex, like @defindex except put all entries in @code. +% +\def\defcodeindex{\parsearg\newcodeindex} +% +\def\newcodeindex#1{% + \expandafter\chardef\csname#1indfile\endcsname=0 + \expandafter\xdef\csname#1index\endcsname{% + \noexpand\docodeindex{#1}}% +} + +% The default indices: +\newindex{cp}% concepts, +\newcodeindex{fn}% functions, +\newcodeindex{vr}% variables, +\newcodeindex{tp}% types, +\newcodeindex{ky}% keys +\newcodeindex{pg}% and programs. + + +% @synindex foo bar makes index foo feed into index bar. +% Do this instead of @defindex foo if you don't want it as a separate index. +% +% @syncodeindex foo bar similar, but put all entries made for index foo +% inside @code. +% +\def\synindex#1 #2 {\dosynindex\doindex{#1}{#2}} +\def\syncodeindex#1 #2 {\dosynindex\docodeindex{#1}{#2}} + +% #1 is \doindex or \docodeindex, #2 the index getting redefined (foo), +% #3 the target index (bar). +\def\dosynindex#1#2#3{% + \requireopenindexfile{#3}% + % redefine \fooindfile: + \expandafter\let\expandafter\temp\expandafter=\csname#3indfile\endcsname + \expandafter\let\csname#2indfile\endcsname=\temp + % redefine \fooindex: + \expandafter\xdef\csname#2index\endcsname{\noexpand#1{#3}}% +} + +% Define \doindex, the driver for all index macros. +% Argument #1 is generated by the calling \fooindex macro, +% and it is the two-letter name of the index. + +\def\doindex#1{\edef\indexname{#1}\parsearg\doindexxxx} +\def\doindexxxx #1{\doind{\indexname}{#1}} + +% like the previous two, but they put @code around the argument. +\def\docodeindex#1{\edef\indexname{#1}\parsearg\docodeindexxxx} +\def\docodeindexxxx #1{\doind{\indexname}{\code{#1}}} + + +% Used when writing an index entry out to an index file to prevent +% expansion of Texinfo commands that can appear in an index entry. +% +\def\indexdummies{% + \escapechar = `\\ % use backslash in output files. + \definedummyletter\@% + \definedummyletter\ % + % + % For texindex which always views { and } as separators. + \def\{{\lbracechar{}}% + \def\}{\rbracechar{}}% + % + % Do the redefinitions. + \definedummies +} + +% Used for the aux and toc files, where @ is the escape character. +% +\def\atdummies{% + \definedummyletter\@% + \definedummyletter\ % + \definedummyletter\{% + \definedummyletter\}% + % + % Do the redefinitions. + \definedummies + \otherbackslash +} + +% \definedummyword defines \#1 as \string\#1\space, thus effectively +% preventing its expansion. This is used only for control words, +% not control letters, because the \space would be incorrect for +% control characters, but is needed to separate the control word +% from whatever follows. +% +% These can be used both for control words that take an argument and +% those that do not. If it is followed by {arg} in the input, then +% that will dutifully get written to the index (or wherever). +% +% For control letters, we have \definedummyletter, which omits the +% space. +% +\def\definedummyword #1{\def#1{\string#1\space}}% +\def\definedummyletter#1{\def#1{\string#1}}% +\let\definedummyaccent\definedummyletter + +% Called from \indexdummies and \atdummies, to effectively prevent +% the expansion of commands. +% +\def\definedummies{% + % + \let\commondummyword\definedummyword + \let\commondummyletter\definedummyletter + \let\commondummyaccent\definedummyaccent + \commondummiesnofonts + % + \definedummyletter\_% + \definedummyletter\-% + % + % Non-English letters. + \definedummyword\AA + \definedummyword\AE + \definedummyword\DH + \definedummyword\L + \definedummyword\O + \definedummyword\OE + \definedummyword\TH + \definedummyword\aa + \definedummyword\ae + \definedummyword\dh + \definedummyword\exclamdown + \definedummyword\l + \definedummyword\o + \definedummyword\oe + \definedummyword\ordf + \definedummyword\ordm + \definedummyword\questiondown + \definedummyword\ss + \definedummyword\th + % + % Although these internal commands shouldn't show up, sometimes they do. + \definedummyword\bf + \definedummyword\gtr + \definedummyword\hat + \definedummyword\less + \definedummyword\sf + \definedummyword\sl + \definedummyword\tclose + \definedummyword\tt + % + \definedummyword\LaTeX + \definedummyword\TeX + % + % Assorted special characters. + \definedummyword\atchar + \definedummyword\arrow + \definedummyword\bullet + \definedummyword\comma + \definedummyword\copyright + \definedummyword\registeredsymbol + \definedummyword\dots + \definedummyword\enddots + \definedummyword\entrybreak + \definedummyword\equiv + \definedummyword\error + \definedummyword\euro + \definedummyword\expansion + \definedummyword\geq + \definedummyword\guillemetleft + \definedummyword\guillemetright + \definedummyword\guilsinglleft + \definedummyword\guilsinglright + \definedummyword\lbracechar + \definedummyword\leq + \definedummyword\mathopsup + \definedummyword\minus + \definedummyword\ogonek + \definedummyword\pounds + \definedummyword\point + \definedummyword\print + \definedummyword\quotedblbase + \definedummyword\quotedblleft + \definedummyword\quotedblright + \definedummyword\quoteleft + \definedummyword\quoteright + \definedummyword\quotesinglbase + \definedummyword\rbracechar + \definedummyword\result + \definedummyword\sub + \definedummyword\sup + \definedummyword\textdegree + % + % We want to disable all macros so that they are not expanded by \write. + \macrolist + \let\value\dummyvalue + % + \normalturnoffactive +} + +% \commondummiesnofonts: common to \definedummies and \indexnofonts. +% Define \commondummyletter, \commondummyaccent and \commondummyword before +% using. Used for accents, font commands, and various control letters. +% +\def\commondummiesnofonts{% + % Control letters and accents. + \commondummyletter\!% + \commondummyaccent\"% + \commondummyaccent\'% + \commondummyletter\*% + \commondummyaccent\,% + \commondummyletter\.% + \commondummyletter\/% + \commondummyletter\:% + \commondummyaccent\=% + \commondummyletter\?% + \commondummyaccent\^% + \commondummyaccent\`% + \commondummyaccent\~% + \commondummyword\u + \commondummyword\v + \commondummyword\H + \commondummyword\dotaccent + \commondummyword\ogonek + \commondummyword\ringaccent + \commondummyword\tieaccent + \commondummyword\ubaraccent + \commondummyword\udotaccent + \commondummyword\dotless + % + % Texinfo font commands. + \commondummyword\b + \commondummyword\i + \commondummyword\r + \commondummyword\sansserif + \commondummyword\sc + \commondummyword\slanted + \commondummyword\t + % + % Commands that take arguments. + \commondummyword\abbr + \commondummyword\acronym + \commondummyword\anchor + \commondummyword\cite + \commondummyword\code + \commondummyword\command + \commondummyword\dfn + \commondummyword\dmn + \commondummyword\email + \commondummyword\emph + \commondummyword\env + \commondummyword\file + \commondummyword\image + \commondummyword\indicateurl + \commondummyword\inforef + \commondummyword\kbd + \commondummyword\key + \commondummyword\math + \commondummyword\option + \commondummyword\pxref + \commondummyword\ref + \commondummyword\samp + \commondummyword\strong + \commondummyword\tie + \commondummyword\U + \commondummyword\uref + \commondummyword\url + \commondummyword\var + \commondummyword\verb + \commondummyword\w + \commondummyword\xref +} + +% For testing: output @{ and @} in index sort strings as \{ and \}. +\newif\ifusebracesinindexes + +\let\indexlbrace\relax +\let\indexrbrace\relax + +{\catcode`\@=0 +\catcode`\\=13 + @gdef@backslashdisappear{@def\{}} +} + +{ +\catcode`\<=13 +\catcode`\-=13 +\catcode`\`=13 + \gdef\indexnonalnumdisappear{% + \expandafter\ifx\csname SETtxiindexlquoteignore\endcsname\relax\else + % @set txiindexlquoteignore makes us ignore left quotes in the sort term. + % (Introduced for FSFS 2nd ed.) + \let`=\empty + \fi + % + \expandafter\ifx\csname SETtxiindexbackslashignore\endcsname\relax\else + \backslashdisappear + \fi + % + \expandafter\ifx\csname SETtxiindexhyphenignore\endcsname\relax\else + \def-{}% + \fi + \expandafter\ifx\csname SETtxiindexlessthanignore\endcsname\relax\else + \def<{}% + \fi + \expandafter\ifx\csname SETtxiindexatsignignore\endcsname\relax\else + \def\@{}% + \fi + } + + \gdef\indexnonalnumreappear{% + \useindexbackslash + \let-\normaldash + \let<\normalless + \def\@{@}% + } +} + + +% \indexnofonts is used when outputting the strings to sort the index +% by, and when constructing control sequence names. It eliminates all +% control sequences and just writes whatever the best ASCII sort string +% would be for a given command (usually its argument). +% +\def\indexnofonts{% + % Accent commands should become @asis. + \def\commondummyaccent##1{\let##1\asis}% + % We can just ignore other control letters. + \def\commondummyletter##1{\let##1\empty}% + % All control words become @asis by default; overrides below. + \let\commondummyword\commondummyaccent + \commondummiesnofonts + % + % Don't no-op \tt, since it isn't a user-level command + % and is used in the definitions of the active chars like <, >, |, etc. + % Likewise with the other plain tex font commands. + %\let\tt=\asis + % + \def\ { }% + \def\@{@}% + \def\_{\normalunderscore}% + \def\-{}% @- shouldn't affect sorting + % + \uccode`\1=`\{ \uppercase{\def\{{1}}% + \uccode`\1=`\} \uppercase{\def\}{1}}% + \let\lbracechar\{% + \let\rbracechar\}% + % + % Non-English letters. + \def\AA{AA}% + \def\AE{AE}% + \def\DH{DZZ}% + \def\L{L}% + \def\OE{OE}% + \def\O{O}% + \def\TH{TH}% + \def\aa{aa}% + \def\ae{ae}% + \def\dh{dzz}% + \def\exclamdown{!}% + \def\l{l}% + \def\oe{oe}% + \def\ordf{a}% + \def\ordm{o}% + \def\o{o}% + \def\questiondown{?}% + \def\ss{ss}% + \def\th{th}% + % + \def\LaTeX{LaTeX}% + \def\TeX{TeX}% + % + % Assorted special characters. \defglyph gives the control sequence a + % definition that removes the {} that follows its use. + \defglyph\atchar{@}% + \defglyph\arrow{->}% + \defglyph\bullet{bullet}% + \defglyph\comma{,}% + \defglyph\copyright{copyright}% + \defglyph\dots{...}% + \defglyph\enddots{...}% + \defglyph\equiv{==}% + \defglyph\error{error}% + \defglyph\euro{euro}% + \defglyph\expansion{==>}% + \defglyph\geq{>=}% + \defglyph\guillemetleft{<<}% + \defglyph\guillemetright{>>}% + \defglyph\guilsinglleft{<}% + \defglyph\guilsinglright{>}% + \defglyph\leq{<=}% + \defglyph\lbracechar{\{}% + \defglyph\minus{-}% + \defglyph\point{.}% + \defglyph\pounds{pounds}% + \defglyph\print{-|}% + \defglyph\quotedblbase{"}% + \defglyph\quotedblleft{"}% + \defglyph\quotedblright{"}% + \defglyph\quoteleft{`}% + \defglyph\quoteright{'}% + \defglyph\quotesinglbase{,}% + \defglyph\rbracechar{\}}% + \defglyph\registeredsymbol{R}% + \defglyph\result{=>}% + \defglyph\textdegree{o}% + % + % We need to get rid of all macros, leaving only the arguments (if present). + % Of course this is not nearly correct, but it is the best we can do for now. + % makeinfo does not expand macros in the argument to @deffn, which ends up + % writing an index entry, and texindex isn't prepared for an index sort entry + % that starts with \. + % + % Since macro invocations are followed by braces, we can just redefine them + % to take a single TeX argument. The case of a macro invocation that + % goes to end-of-line is not handled. + % + \macrolist + \let\value\indexnofontsvalue +} +\def\defglyph#1#2{\def#1##1{#2}} % see above + + + + +\let\SETmarginindex=\relax % put index entries in margin (undocumented)? + +% Most index entries go through here, but \dosubind is the general case. +% #1 is the index name, #2 is the entry text. +\def\doind#1#2{\dosubind{#1}{#2}{}} + +% There is also \dosubind {index}{topic}{subtopic} +% which makes an entry in a two-level index such as the operation index. +% TODO: Two-level index? Operation index? + +% Workhorse for all indexes. +% #1 is name of index, #2 is stuff to put there, #3 is subentry -- +% empty if called from \doind, as we usually are (the main exception +% is with most defuns, which call us directly). +% +\def\dosubind#1#2#3{% + \iflinks + {% + \requireopenindexfile{#1}% + % Store the main index entry text (including the third arg). + \toks0 = {#2}% + % If third arg is present, precede it with a space. + \def\thirdarg{#3}% + \ifx\thirdarg\empty \else + \toks0 = \expandafter{\the\toks0 \space #3}% + \fi + % + \edef\writeto{\csname#1indfile\endcsname}% + % + \safewhatsit\dosubindwrite + }% + \fi +} + +% Check if an index file has been opened, and if not, open it. +\def\requireopenindexfile#1{% +\ifnum\csname #1indfile\endcsname=0 + \expandafter\newwrite \csname#1indfile\endcsname + \edef\suffix{#1}% + % A .fls suffix would conflict with the file extension for the output + % of -recorder, so use .f1s instead. + \ifx\suffix\indexisfl\def\suffix{f1}\fi + % Open the file + \immediate\openout\csname#1indfile\endcsname \jobname.\suffix + % Using \immediate above here prevents an object entering into the current + % box, which could confound checks such as those in \safewhatsit for + % preceding skips. + \typeout{Writing index file \jobname.\suffix}% +\fi} +\def\indexisfl{fl} + +% Output \ as {\indexbackslash}, because \ is an escape character in +% the index files. +\let\indexbackslash=\relax +{\catcode`\@=0 \catcode`\\=\active + @gdef@useindexbackslash{@def\{{@indexbackslash}}} +} + +% Definition for writing index entry text. +\def\sortas#1{\ignorespaces}% + +% Definition for writing index entry sort key. Should occur at the at +% the beginning of the index entry, like +% @cindex @sortas{september} \september +% The \ignorespaces takes care of following space, but there's no way +% to remove space before it. +{ +\catcode`\-=13 +\gdef\indexwritesortas{% + \begingroup + \indexnonalnumreappear + \indexwritesortasxxx} +\gdef\indexwritesortasxxx#1{% + \xdef\indexsortkey{#1}\endgroup} +} + + +% Write the entry in \toks0 to the index file. +% +\def\dosubindwrite{% + % Put the index entry in the margin if desired. + \ifx\SETmarginindex\relax\else + \insert\margin{\hbox{\vrule height8pt depth3pt width0pt \the\toks0}}% + \fi + % + % Remember, we are within a group. + \indexdummies % Must do this here, since \bf, etc expand at this stage + \useindexbackslash % \indexbackslash isn't defined now so it will be output + % as is; and it will print as backslash. + % The braces around \indexbrace are recognized by texindex. + % + % Get the string to sort by, by processing the index entry with all + % font commands turned off. + {\indexnofonts + \def\lbracechar{{\indexlbrace}}% + \def\rbracechar{{\indexrbrace}}% + \let\{=\lbracechar + \let\}=\rbracechar + \indexnonalnumdisappear + \xdef\indexsortkey{}% + \let\sortas=\indexwritesortas + \edef\temp{\the\toks0}% + \setbox\dummybox = \hbox{\temp}% Make sure to execute any \sortas + \ifx\indexsortkey\empty + \xdef\indexsortkey{\temp}% + \ifx\indexsortkey\empty\xdef\indexsortkey{ }\fi + \fi + }% + % + % Set up the complete index entry, with both the sort key and + % the original text, including any font commands. We write + % three arguments to \entry to the .?? file (four in the + % subentry case), texindex reduces to two when writing the .??s + % sorted result. + \edef\temp{% + \write\writeto{% + \string\entry{\indexsortkey}{\noexpand\folio}{\the\toks0}}% + }% + \temp +} +\newbox\dummybox % used above + +% Take care of unwanted page breaks/skips around a whatsit: +% +% If a skip is the last thing on the list now, preserve it +% by backing up by \lastskip, doing the \write, then inserting +% the skip again. Otherwise, the whatsit generated by the +% \write or \pdfdest will make \lastskip zero. The result is that +% sequences like this: +% @end defun +% @tindex whatever +% @defun ... +% will have extra space inserted, because the \medbreak in the +% start of the @defun won't see the skip inserted by the @end of +% the previous defun. +% +% But don't do any of this if we're not in vertical mode. We +% don't want to do a \vskip and prematurely end a paragraph. +% +% Avoid page breaks due to these extra skips, too. +% +% But wait, there is a catch there: +% We'll have to check whether \lastskip is zero skip. \ifdim is not +% sufficient for this purpose, as it ignores stretch and shrink parts +% of the skip. The only way seems to be to check the textual +% representation of the skip. +% +% The following is almost like \def\zeroskipmacro{0.0pt} except that +% the ``p'' and ``t'' characters have catcode \other, not 11 (letter). +% +\edef\zeroskipmacro{\expandafter\the\csname z@skip\endcsname} +% +\newskip\whatsitskip +\newcount\whatsitpenalty +% +% ..., ready, GO: +% +\def\safewhatsit#1{\ifhmode + #1% + \else + % \lastskip and \lastpenalty cannot both be nonzero simultaneously. + \whatsitskip = \lastskip + \edef\lastskipmacro{\the\lastskip}% + \whatsitpenalty = \lastpenalty + % + % If \lastskip is nonzero, that means the last item was a + % skip. And since a skip is discardable, that means this + % -\whatsitskip glue we're inserting is preceded by a + % non-discardable item, therefore it is not a potential + % breakpoint, therefore no \nobreak needed. + \ifx\lastskipmacro\zeroskipmacro + \else + \vskip-\whatsitskip + \fi + % + #1% + % + \ifx\lastskipmacro\zeroskipmacro + % If \lastskip was zero, perhaps the last item was a penalty, and + % perhaps it was >=10000, e.g., a \nobreak. In that case, we want + % to re-insert the same penalty (values >10000 are used for various + % signals); since we just inserted a non-discardable item, any + % following glue (such as a \parskip) would be a breakpoint. For example: + % @deffn deffn-whatever + % @vindex index-whatever + % Description. + % would allow a break between the index-whatever whatsit + % and the "Description." paragraph. + \ifnum\whatsitpenalty>9999 \penalty\whatsitpenalty \fi + \else + % On the other hand, if we had a nonzero \lastskip, + % this make-up glue would be preceded by a non-discardable item + % (the whatsit from the \write), so we must insert a \nobreak. + \nobreak\vskip\whatsitskip + \fi +\fi} + +% The index entry written in the file actually looks like +% \entry {sortstring}{page}{topic} +% or +% \entry {sortstring}{page}{topic}{subtopic} +% The texindex program reads in these files and writes files +% containing these kinds of lines: +% \initial {c} +% before the first topic whose initial is c +% \entry {topic}{pagelist} +% for a topic that is used without subtopics +% \primary {topic} +% for the beginning of a topic that is used with subtopics +% \secondary {subtopic}{pagelist} +% for each subtopic. + +% Define the user-accessible indexing commands +% @findex, @vindex, @kindex, @cindex. + +\def\findex {\fnindex} +\def\kindex {\kyindex} +\def\cindex {\cpindex} +\def\vindex {\vrindex} +\def\tindex {\tpindex} +\def\pindex {\pgindex} + +\def\cindexsub {\begingroup\obeylines\cindexsub} +{\obeylines % +\gdef\cindexsub "#1" #2^^M{\endgroup % +\dosubind{cp}{#2}{#1}}} + +% Define the macros used in formatting output of the sorted index material. + +% @printindex causes a particular index (the ??s file) to get printed. +% It does not print any chapter heading (usually an @unnumbered). +% +\parseargdef\printindex{\begingroup + \dobreak \chapheadingskip{10000}% + % + \smallfonts \rm + \tolerance = 9500 + \plainfrenchspacing + \everypar = {}% don't want the \kern\-parindent from indentation suppression. + % + % See if the index file exists and is nonempty. + % Change catcode of @ here so that if the index file contains + % \initial {@} + % as its first line, TeX doesn't complain about mismatched braces + % (because it thinks @} is a control sequence). + \catcode`\@ = 12 + % See comment in \requireopenindexfile. + \def\indexname{#1}\ifx\indexname\indexisfl\def\indexname{f1}\fi + \openin 1 \jobname.\indexname s + \ifeof 1 + % \enddoublecolumns gets confused if there is no text in the index, + % and it loses the chapter title and the aux file entries for the + % index. The easiest way to prevent this problem is to make sure + % there is some text. + \putwordIndexNonexistent + \typeout{No file \jobname.\indexname s.}% + \else + \catcode`\\ = 0 + % + % If the index file exists but is empty, then \openin leaves \ifeof + % false. We have to make TeX try to read something from the file, so + % it can discover if there is anything in it. + \read 1 to \thisline + \ifeof 1 + \putwordIndexIsEmpty + \else + % Index files are almost Texinfo source, but we use \ as the escape + % character. It would be better to use @, but that's too big a change + % to make right now. + \def\indexbackslash{\ttbackslash}% + \let\indexlbrace\{ % Likewise, set these sequences for braces + \let\indexrbrace\} % used in the sort key. + \begindoublecolumns + \let\dotheinsertentrybox\dotheinsertentryboxwithpenalty + % + % Read input from the index file line by line. + \loopdo + \ifeof1 \else + \read 1 to \nextline + \fi + % + \indexinputprocessing + \thisline + % + \ifeof1\else + \let\thisline\nextline + \repeat + %% + \enddoublecolumns + \fi + \fi + \closein 1 +\endgroup} +\def\loopdo#1\repeat{\def\body{#1}\loopdoxxx} +\def\loopdoxxx{\let\next=\relax\body\let\next=\loopdoxxx\fi\next} + +\def\indexinputprocessing{% + \ifeof1 + \let\firsttoken\relax + \else + \edef\act{\gdef\noexpand\firsttoken{\getfirsttoken\nextline}}% + \act + \fi +} +\def\getfirsttoken#1{\expandafter\getfirsttokenx#1\endfirsttoken} +\long\def\getfirsttokenx#1#2\endfirsttoken{\noexpand#1} + + +% These macros are used by the sorted index file itself. +% Change them to control the appearance of the index. + +{\catcode`\/=13 \catcode`\-=13 \catcode`\^=13 \catcode`\~=13 \catcode`\_=13 +\catcode`\|=13 \catcode`\<=13 \catcode`\>=13 \catcode`\+=13 \catcode`\"=13 +\catcode`\$=3 +\gdef\initialglyphs{% + % Some changes for non-alphabetic characters. Using the glyphs from the + % math fonts looks more consistent than the typewriter font used elsewhere + % for these characters. + \def\indexbackslash{\math{\backslash}}% + \let\\=\indexbackslash + % + % Can't get bold backslash so don't use bold forward slash + \catcode`\/=13 + \def/{{\secrmnotbold \normalslash}}% + \def-{{\normaldash\normaldash}}% en dash `--' + \def^{{\chapbf \normalcaret}}% + \def~{{\chapbf \normaltilde}}% + \def\_{% + \leavevmode \kern.07em \vbox{\hrule width.3em height.1ex}\kern .07em }% + \def|{$\vert$}% + \def<{$\less$}% + \def>{$\gtr$}% + \def+{$\normalplus$}% +}} + +\def\initial{% + \bgroup + \initialglyphs + \initialx +} + +\def\initialx#1{% + % Remove any glue we may have, we'll be inserting our own. + \removelastskip + % + % We like breaks before the index initials, so insert a bonus. + % The glue before the bonus allows a little bit of space at the + % bottom of a column to reduce an increase in inter-line spacing. + \nobreak + \vskip 0pt plus 5\baselineskip + \penalty -300 + \vskip 0pt plus -5\baselineskip + % + % Typeset the initial. Making this add up to a whole number of + % baselineskips increases the chance of the dots lining up from column + % to column. It still won't often be perfect, because of the stretch + % we need before each entry, but it's better. + % + % No shrink because it confuses \balancecolumns. + \vskip 1.67\baselineskip plus 1\baselineskip + \leftline{\secfonts \kern-0.05em \secbf #1}% + % \secfonts is inside the argument of \leftline so that the change of + % \baselineskip will not affect any glue inserted before the vbox that + % \leftline creates. + % Do our best not to break after the initial. + \nobreak + \vskip .33\baselineskip plus .1\baselineskip + \egroup % \initialglyphs +} + +\newdimen\entryrightmargin +\entryrightmargin=0pt + +% \entry typesets a paragraph consisting of the text (#1), dot leaders, and +% then page number (#2) flushed to the right margin. It is used for index +% and table of contents entries. The paragraph is indented by \leftskip. +% +\def\entry{% + \begingroup + % + % For pdfTeX and XeTeX. + % The redefinition of \domark stops marks being added in \pdflink to + % preserve coloured links across page boundaries. Otherwise the marks + % would get in the way of \lastbox in \insertentrybox. + \let\domark\relax + % + % Start a new paragraph if necessary, so our assignments below can't + % affect previous text. + \par + % + % No extra space above this paragraph. + \parskip = 0in + % + % When reading the text of entry, convert explicit line breaks + % from @* into spaces. The user might give these in long section + % titles, for instance. + \def\*{\unskip\space\ignorespaces}% + \def\entrybreak{\hfil\break}% An undocumented command + % + % Swallow the left brace of the text (first parameter): + \afterassignment\doentry + \let\temp = +} +\def\entrybreak{\unskip\space\ignorespaces}% +\def\doentry{% + % Save the text of the entry + \global\setbox\boxA=\hbox\bgroup + \bgroup % Instead of the swallowed brace. + \noindent + \aftergroup\finishentry + % And now comes the text of the entry. + % Not absorbing as a macro argument reduces the chance of problems + % with catcodes occurring. +} +{\catcode`\@=11 +\gdef\finishentry#1{% + \egroup % end box A + \dimen@ = \wd\boxA % Length of text of entry + \global\setbox\boxA=\hbox\bgroup\unhbox\boxA + % #1 is the page number. + % + % Get the width of the page numbers, and only use + % leaders if they are present. + \global\setbox\boxB = \hbox{#1}% + \ifdim\wd\boxB = 0pt + \null\nobreak\hfill\ % + \else + % + \null\nobreak\indexdotfill % Have leaders before the page number. + % + \ifpdf + \pdfgettoks#1.% + \hskip\skip\thinshrinkable\the\toksA + \else + \ifx\XeTeXrevision\thisisundefined + \hskip\skip\thinshrinkable #1% + \else + \pdfgettoks#1.% + \hskip\skip\thinshrinkable\the\toksA + \fi + \fi + \fi + \egroup % end \boxA + \ifdim\wd\boxB = 0pt + \global\setbox\entrybox=\vbox{\unhbox\boxA}% + \else + \global\setbox\entrybox=\vbox\bgroup + % We want the text of the entries to be aligned to the left, and the + % page numbers to be aligned to the right. + % + \parindent = 0pt + \advance\leftskip by 0pt plus 1fil + \advance\leftskip by 0pt plus -1fill + \rightskip = 0pt plus -1fil + \advance\rightskip by 0pt plus 1fill + % Cause last line, which could consist of page numbers on their own + % if the list of page numbers is long, to be aligned to the right. + \parfillskip=0pt plus -1fill + % + \advance\rightskip by \entryrightmargin + % Determine how far we can stretch into the margin. + % This allows, e.g., "Appendix H GNU Free Documentation License" to + % fit on one line in @letterpaper format. + \ifdim\entryrightmargin>2.1em + \dimen@i=2.1em + \else + \dimen@i=0em + \fi + \advance \parfillskip by 0pt minus 1\dimen@i + % + \dimen@ii = \hsize + \advance\dimen@ii by -1\leftskip + \advance\dimen@ii by -1\entryrightmargin + \advance\dimen@ii by 1\dimen@i + \ifdim\wd\boxA > \dimen@ii % If the entry doesn't fit in one line + \ifdim\dimen@ > 0.8\dimen@ii % due to long index text + % Try to split the text roughly evenly. \dimen@ will be the length of + % the first line. + \dimen@ = 0.7\dimen@ + \dimen@ii = \hsize + \ifnum\dimen@>\dimen@ii + % If the entry is too long (for example, if it needs more than + % two lines), use all the space in the first line. + \dimen@ = \dimen@ii + \fi + \advance\leftskip by 0pt plus 1fill % ragged right + \advance \dimen@ by 1\rightskip + \parshape = 2 0pt \dimen@ 0em \dimen@ii + % Ideally we'd add a finite glue at the end of the first line only, + % instead of using \parshape with explicit line lengths, but TeX + % doesn't seem to provide a way to do such a thing. + % + % Indent all lines but the first one. + \advance\leftskip by 1em + \advance\parindent by -1em + \fi\fi + \indent % start paragraph + \unhbox\boxA + % + % Do not prefer a separate line ending with a hyphen to fewer lines. + \finalhyphendemerits = 0 + % + % Word spacing - no stretch + \spaceskip=\fontdimen2\font minus \fontdimen4\font + % + \linepenalty=1000 % Discourage line breaks. + \hyphenpenalty=5000 % Discourage hyphenation. + % + \par % format the paragraph + \egroup % The \vbox + \fi + \endgroup + \dotheinsertentrybox +}} + +\newskip\thinshrinkable +\skip\thinshrinkable=.15em minus .15em + +\newbox\entrybox +\def\insertentrybox{% + \ourunvbox\entrybox +} + +% default definition +\let\dotheinsertentrybox\insertentrybox + +% Use \lastbox to take apart vbox box by box, and add each sub-box +% to the current vertical list. +\def\ourunvbox#1{% +\bgroup % for local binding of \delayedbox + % Remove the last box from box #1 + \global\setbox#1=\vbox{% + \unvbox#1% + \unskip % remove any glue + \unpenalty + \global\setbox\interbox=\lastbox + }% + \setbox\delayedbox=\box\interbox + \ifdim\ht#1=0pt\else + \ourunvbox#1 % Repeat on what's left of the box + \nobreak + \fi + \box\delayedbox +\egroup +} +\newbox\delayedbox +\newbox\interbox + +% Used from \printindex. \firsttoken should be the first token +% after the \entry. If it's not another \entry, we are at the last +% line of a group of index entries, so insert a penalty to discourage +% widowed index entries. +\def\dotheinsertentryboxwithpenalty{% + \ifx\firsttoken\isentry + \else + \penalty 9000 + \fi + \insertentrybox +} +\def\isentry{\entry}% + +% Like plain.tex's \dotfill, except uses up at least 1 em. +% The filll stretch here overpowers both the fil and fill stretch to push +% the page number to the right. +\def\indexdotfill{\cleaders + \hbox{$\mathsurround=0pt \mkern1.5mu.\mkern1.5mu$}\hskip 1em plus 1filll} + + +\def\primary #1{\line{#1\hfil}} + +\newskip\secondaryindent \secondaryindent=0.5cm +\def\secondary#1#2{{% + \parfillskip=0in + \parskip=0in + \hangindent=1in + \hangafter=1 + \noindent\hskip\secondaryindent\hbox{#1}\indexdotfill + \ifpdf + \pdfgettoks#2.\ \the\toksA % The page number ends the paragraph. + \else + \ifx\XeTeXrevision\thisisundefined + #2 + \else + \pdfgettoks#2.\ \the\toksA % The page number ends the paragraph. + \fi + \fi + \par +}} + +% Define two-column mode, which we use to typeset indexes. +% Adapted from the TeXbook, page 416, which is to say, +% the manmac.tex format used to print the TeXbook itself. +\catcode`\@=11 % private names + +\newbox\partialpage +\newdimen\doublecolumnhsize + +% Use inside an output routine to save \topmark and \firstmark +\def\savemarks{% + \global\savedtopmark=\expandafter{\topmark }% + \global\savedfirstmark=\expandafter{\firstmark }% +} +\newtoks\savedtopmark +\newtoks\savedfirstmark + +% Set \topmark and \firstmark for next time \output runs. +% Can't be run from withinside \output (because any material +% added while an output routine is active, including +% penalties, is saved for after it finishes). The page so far +% should be empty, otherwise what's on it will be thrown away. +\def\restoremarks{% + \mark{\the\savedtopmark}% + \bgroup\output = {% + \setbox\dummybox=\box\PAGE + }abc\eject\egroup + % "abc" because output routine doesn't fire for a completely empty page. + \mark{\the\savedfirstmark}% +} + +\def\begindoublecolumns{\begingroup % ended by \enddoublecolumns + % If not much space left on page, start a new page. + \ifdim\pagetotal>0.8\vsize\vfill\eject\fi + % + % Grab any single-column material above us. + \output = {% + % + % Here is a possibility not foreseen in manmac: if we accumulate a + % whole lot of material, we might end up calling this \output + % routine twice in a row (see the doublecol-lose test, which is + % essentially a couple of indexes with @setchapternewpage off). In + % that case we just ship out what is in \partialpage with the normal + % output routine. Generally, \partialpage will be empty when this + % runs and this will be a no-op. See the indexspread.tex test case. + \ifvoid\partialpage \else + \onepageout{\pagecontents\partialpage}% + \fi + % + \global\setbox\partialpage = \vbox{% + % Unvbox the main output page. + \unvbox\PAGE + \kern-\topskip \kern\baselineskip + }% + \savemarks + }% + \eject % run that output routine to set \partialpage + \restoremarks + % + % We recover the two marks that the last output routine saved in order + % to propagate the information in marks added around a chapter heading, + % which could be otherwise be lost by the time the final page is output. + % + % + % Use the double-column output routine for subsequent pages. + \output = {\doublecolumnout}% + % + % Change the page size parameters. We could do this once outside this + % routine, in each of @smallbook, @afourpaper, and the default 8.5x11 + % format, but then we repeat the same computation. Repeating a couple + % of assignments once per index is clearly meaningless for the + % execution time, so we may as well do it in one place. + % + % First we halve the line length, less a little for the gutter between + % the columns. We compute the gutter based on the line length, so it + % changes automatically with the paper format. The magic constant + % below is chosen so that the gutter has the same value (well, +-<1pt) + % as it did when we hard-coded it. + % + % We put the result in a separate register, \doublecolumhsize, so we + % can restore it in \pagesofar, after \hsize itself has (potentially) + % been clobbered. + % + \doublecolumnhsize = \hsize + \advance\doublecolumnhsize by -.04154\hsize + \divide\doublecolumnhsize by 2 + \hsize = \doublecolumnhsize + % + % Double the \vsize as well. + \advance\vsize by -\ht\partialpage + \vsize = 2\vsize + % + % For the benefit of balancing columns + \advance\baselineskip by 0pt plus 0.5pt +} + +% The double-column output routine for all double-column pages except +% the last, which is done by \balancecolumns. +% +\def\doublecolumnout{% + % + \splittopskip=\topskip \splitmaxdepth=\maxdepth + % Get the available space for the double columns -- the normal + % (undoubled) page height minus any material left over from the + % previous page. + \dimen@ = \vsize + \divide\dimen@ by 2 + % + % box0 will be the left-hand column, box2 the right. + \setbox0=\vsplit\PAGE to\dimen@ \setbox2=\vsplit\PAGE to\dimen@ + \global\advance\vsize by 2\ht\partialpage + \onepageout\pagesofar + \unvbox\PAGE + \penalty\outputpenalty +} +% +% Re-output the contents of the output page -- any previous material, +% followed by the two boxes we just split, in box0 and box2. +\def\pagesofar{% + \unvbox\partialpage + % + \hsize = \doublecolumnhsize + \wd0=\hsize \wd2=\hsize + \hbox to\txipagewidth{\box0\hfil\box2}% +} + + +% Finished with with double columns. +\def\enddoublecolumns{% + % The following penalty ensures that the page builder is exercised + % _before_ we change the output routine. This is necessary in the + % following situation: + % + % The last section of the index consists only of a single entry. + % Before this section, \pagetotal is less than \pagegoal, so no + % break occurs before the last section starts. However, the last + % section, consisting of \initial and the single \entry, does not + % fit on the page and has to be broken off. Without the following + % penalty the page builder will not be exercised until \eject + % below, and by that time we'll already have changed the output + % routine to the \balancecolumns version, so the next-to-last + % double-column page will be processed with \balancecolumns, which + % is wrong: The two columns will go to the main vertical list, with + % the broken-off section in the recent contributions. As soon as + % the output routine finishes, TeX starts reconsidering the page + % break. The two columns and the broken-off section both fit on the + % page, because the two columns now take up only half of the page + % goal. When TeX sees \eject from below which follows the final + % section, it invokes the new output routine that we've set after + % \balancecolumns below; \onepageout will try to fit the two columns + % and the final section into the vbox of \txipageheight (see + % \pagebody), causing an overfull box. + % + % Note that glue won't work here, because glue does not exercise the + % page builder, unlike penalties (see The TeXbook, pp. 280-281). + \penalty0 + % + \output = {% + % Split the last of the double-column material. + \savemarks + \balancecolumns + }% + \eject % call the \output just set + \ifdim\pagetotal=0pt + % Having called \balancecolumns once, we do not + % want to call it again. Therefore, reset \output to its normal + % definition right away. + \global\output = {\onepageout{\pagecontents\PAGE}}% + % + \endgroup % started in \begindoublecolumns + \restoremarks + % Leave the double-column material on the current page, no automatic + % page break. + \box\balancedcolumns + % + % \pagegoal was set to the doubled \vsize above, since we restarted + % the current page. We're now back to normal single-column + % typesetting, so reset \pagegoal to the normal \vsize. + \global\vsize = \txipageheight % + \pagegoal = \txipageheight % + \else + % We had some left-over material. This might happen when \doublecolumnout + % is called in \balancecolumns. Try again. + \expandafter\enddoublecolumns + \fi +} +\newbox\balancedcolumns +\setbox\balancedcolumns=\vbox{shouldnt see this}% +% +% Only called for the last of the double column material. \doublecolumnout +% does the others. +\def\balancecolumns{% + \setbox0 = \vbox{\unvbox\PAGE}% like \box255 but more efficient, see p.120. + \dimen@ = \ht0 + \advance\dimen@ by \topskip + \advance\dimen@ by-\baselineskip + \ifdim\dimen@<5\baselineskip + % Don't split a short final column in two. + \setbox2=\vbox{}% + \global\setbox\balancedcolumns=\vbox{\pagesofar}% + \else + \divide\dimen@ by 2 % target to split to + \dimen@ii = \dimen@ + \splittopskip = \topskip + % Loop until left column is at least as high as the right column. + {% + \vbadness = 10000 + \loop + \global\setbox3 = \copy0 + \global\setbox1 = \vsplit3 to \dimen@ + \ifdim\ht1<\ht3 + \global\advance\dimen@ by 1pt + \repeat + }% + % Now the left column is in box 1, and the right column in box 3. + % + % Check whether the left column has come out higher than the page itself. + % (Note that we have doubled \vsize for the double columns, so + % the actual height of the page is 0.5\vsize). + \ifdim2\ht1>\vsize + % It appears that we have been called upon to balance too much material. + % Output some of it with \doublecolumnout, leaving the rest on the page. + \setbox\PAGE=\box0 + \doublecolumnout + \else + % Compare the heights of the two columns. + \ifdim4\ht1>5\ht3 + % Column heights are too different, so don't make their bottoms + % flush with each other. + \setbox2=\vbox to \ht1 {\unvbox3\vfill}% + \setbox0=\vbox to \ht1 {\unvbox1\vfill}% + \else + % Make column bottoms flush with each other. + \setbox2=\vbox to\ht1{\unvbox3\unskip}% + \setbox0=\vbox to\ht1{\unvbox1\unskip}% + \fi + \global\setbox\balancedcolumns=\vbox{\pagesofar}% + \fi + \fi + % +} +\catcode`\@ = \other + + +\message{sectioning,} +% Chapters, sections, etc. + +% Let's start with @part. +\outer\parseargdef\part{\partzzz{#1}} +\def\partzzz#1{% + \chapoddpage + \null + \vskip.3\vsize % move it down on the page a bit + \begingroup + \noindent \titlefonts\rm #1\par % the text + \let\lastnode=\empty % no node to associate with + \writetocentry{part}{#1}{}% but put it in the toc + \headingsoff % no headline or footline on the part page + % This outputs a mark at the end of the page that clears \thischapter + % and \thissection, as is done in \startcontents. + \let\pchapsepmacro\relax + \chapmacro{}{Yomitfromtoc}{}% + \chapoddpage + \endgroup +} + +% \unnumberedno is an oxymoron. But we count the unnumbered +% sections so that we can refer to them unambiguously in the pdf +% outlines by their "section number". We avoid collisions with chapter +% numbers by starting them at 10000. (If a document ever has 10000 +% chapters, we're in trouble anyway, I'm sure.) +\newcount\unnumberedno \unnumberedno = 10000 +\newcount\chapno +\newcount\secno \secno=0 +\newcount\subsecno \subsecno=0 +\newcount\subsubsecno \subsubsecno=0 + +% This counter is funny since it counts through charcodes of letters A, B, ... +\newcount\appendixno \appendixno = `\@ +% +% \def\appendixletter{\char\the\appendixno} +% We do the following ugly conditional instead of the above simple +% construct for the sake of pdftex, which needs the actual +% letter in the expansion, not just typeset. +% +\def\appendixletter{% + \ifnum\appendixno=`A A% + \else\ifnum\appendixno=`B B% + \else\ifnum\appendixno=`C C% + \else\ifnum\appendixno=`D D% + \else\ifnum\appendixno=`E E% + \else\ifnum\appendixno=`F F% + \else\ifnum\appendixno=`G G% + \else\ifnum\appendixno=`H H% + \else\ifnum\appendixno=`I I% + \else\ifnum\appendixno=`J J% + \else\ifnum\appendixno=`K K% + \else\ifnum\appendixno=`L L% + \else\ifnum\appendixno=`M M% + \else\ifnum\appendixno=`N N% + \else\ifnum\appendixno=`O O% + \else\ifnum\appendixno=`P P% + \else\ifnum\appendixno=`Q Q% + \else\ifnum\appendixno=`R R% + \else\ifnum\appendixno=`S S% + \else\ifnum\appendixno=`T T% + \else\ifnum\appendixno=`U U% + \else\ifnum\appendixno=`V V% + \else\ifnum\appendixno=`W W% + \else\ifnum\appendixno=`X X% + \else\ifnum\appendixno=`Y Y% + \else\ifnum\appendixno=`Z Z% + % The \the is necessary, despite appearances, because \appendixletter is + % expanded while writing the .toc file. \char\appendixno is not + % expandable, thus it is written literally, thus all appendixes come out + % with the same letter (or @) in the toc without it. + \else\char\the\appendixno + \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi + \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi} + +% Each @chapter defines these (using marks) as the number+name, number +% and name of the chapter. Page headings and footings can use +% these. @section does likewise. +\def\thischapter{} +\def\thischapternum{} +\def\thischaptername{} +\def\thissection{} +\def\thissectionnum{} +\def\thissectionname{} + +\newcount\absseclevel % used to calculate proper heading level +\newcount\secbase\secbase=0 % @raisesections/@lowersections modify this count + +% @raisesections: treat @section as chapter, @subsection as section, etc. +\def\raisesections{\global\advance\secbase by -1} +\let\up=\raisesections % original BFox name + +% @lowersections: treat @chapter as section, @section as subsection, etc. +\def\lowersections{\global\advance\secbase by 1} +\let\down=\lowersections % original BFox name + +% we only have subsub. +\chardef\maxseclevel = 3 +% +% A numbered section within an unnumbered changes to unnumbered too. +% To achieve this, remember the "biggest" unnum. sec. we are currently in: +\chardef\unnlevel = \maxseclevel +% +% Trace whether the current chapter is an appendix or not: +% \chapheadtype is "N" or "A", unnumbered chapters are ignored. +\def\chapheadtype{N} + +% Choose a heading macro +% #1 is heading type +% #2 is heading level +% #3 is text for heading +\def\genhead#1#2#3{% + % Compute the abs. sec. level: + \absseclevel=#2 + \advance\absseclevel by \secbase + % Make sure \absseclevel doesn't fall outside the range: + \ifnum \absseclevel < 0 + \absseclevel = 0 + \else + \ifnum \absseclevel > 3 + \absseclevel = 3 + \fi + \fi + % The heading type: + \def\headtype{#1}% + \if \headtype U% + \ifnum \absseclevel < \unnlevel + \chardef\unnlevel = \absseclevel + \fi + \else + % Check for appendix sections: + \ifnum \absseclevel = 0 + \edef\chapheadtype{\headtype}% + \else + \if \headtype A\if \chapheadtype N% + \errmessage{@appendix... within a non-appendix chapter}% + \fi\fi + \fi + % Check for numbered within unnumbered: + \ifnum \absseclevel > \unnlevel + \def\headtype{U}% + \else + \chardef\unnlevel = 3 + \fi + \fi + % Now print the heading: + \if \headtype U% + \ifcase\absseclevel + \unnumberedzzz{#3}% + \or \unnumberedseczzz{#3}% + \or \unnumberedsubseczzz{#3}% + \or \unnumberedsubsubseczzz{#3}% + \fi + \else + \if \headtype A% + \ifcase\absseclevel + \appendixzzz{#3}% + \or \appendixsectionzzz{#3}% + \or \appendixsubseczzz{#3}% + \or \appendixsubsubseczzz{#3}% + \fi + \else + \ifcase\absseclevel + \chapterzzz{#3}% + \or \seczzz{#3}% + \or \numberedsubseczzz{#3}% + \or \numberedsubsubseczzz{#3}% + \fi + \fi + \fi + \suppressfirstparagraphindent +} + +% an interface: +\def\numhead{\genhead N} +\def\apphead{\genhead A} +\def\unnmhead{\genhead U} + +% @chapter, @appendix, @unnumbered. Increment top-level counter, reset +% all lower-level sectioning counters to zero. +% +% Also set \chaplevelprefix, which we prepend to @float sequence numbers +% (e.g., figures), q.v. By default (before any chapter), that is empty. +\let\chaplevelprefix = \empty +% +\outer\parseargdef\chapter{\numhead0{#1}} % normally numhead0 calls chapterzzz +\def\chapterzzz#1{% + % section resetting is \global in case the chapter is in a group, such + % as an @include file. + \global\secno=0 \global\subsecno=0 \global\subsubsecno=0 + \global\advance\chapno by 1 + % + % Used for \float. + \gdef\chaplevelprefix{\the\chapno.}% + \resetallfloatnos + % + % \putwordChapter can contain complex things in translations. + \toks0=\expandafter{\putwordChapter}% + \message{\the\toks0 \space \the\chapno}% + % + % Write the actual heading. + \chapmacro{#1}{Ynumbered}{\the\chapno}% + % + % So @section and the like are numbered underneath this chapter. + \global\let\section = \numberedsec + \global\let\subsection = \numberedsubsec + \global\let\subsubsection = \numberedsubsubsec +} + +\outer\parseargdef\appendix{\apphead0{#1}} % normally calls appendixzzz +% +\def\appendixzzz#1{% + \global\secno=0 \global\subsecno=0 \global\subsubsecno=0 + \global\advance\appendixno by 1 + \gdef\chaplevelprefix{\appendixletter.}% + \resetallfloatnos + % + % \putwordAppendix can contain complex things in translations. + \toks0=\expandafter{\putwordAppendix}% + \message{\the\toks0 \space \appendixletter}% + % + \chapmacro{#1}{Yappendix}{\appendixletter}% + % + \global\let\section = \appendixsec + \global\let\subsection = \appendixsubsec + \global\let\subsubsection = \appendixsubsubsec +} + +% normally unnmhead0 calls unnumberedzzz: +\outer\parseargdef\unnumbered{\unnmhead0{#1}} +\def\unnumberedzzz#1{% + \global\secno=0 \global\subsecno=0 \global\subsubsecno=0 + \global\advance\unnumberedno by 1 + % + % Since an unnumbered has no number, no prefix for figures. + \global\let\chaplevelprefix = \empty + \resetallfloatnos + % + % This used to be simply \message{#1}, but TeX fully expands the + % argument to \message. Therefore, if #1 contained @-commands, TeX + % expanded them. For example, in `@unnumbered The @cite{Book}', TeX + % expanded @cite (which turns out to cause errors because \cite is meant + % to be executed, not expanded). + % + % Anyway, we don't want the fully-expanded definition of @cite to appear + % as a result of the \message, we just want `@cite' itself. We use + % \the<toks register> to achieve this: TeX expands \the<toks> only once, + % simply yielding the contents of <toks register>. (We also do this for + % the toc entries.) + \toks0 = {#1}% + \message{(\the\toks0)}% + % + \chapmacro{#1}{Ynothing}{\the\unnumberedno}% + % + \global\let\section = \unnumberedsec + \global\let\subsection = \unnumberedsubsec + \global\let\subsubsection = \unnumberedsubsubsec +} + +% @centerchap is like @unnumbered, but the heading is centered. +\outer\parseargdef\centerchap{% + \let\centerparametersmaybe = \centerparameters + \unnmhead0{#1}% + \let\centerparametersmaybe = \relax +} + +% @top is like @unnumbered. +\let\top\unnumbered + +% Sections. +% +\outer\parseargdef\numberedsec{\numhead1{#1}} % normally calls seczzz +\def\seczzz#1{% + \global\subsecno=0 \global\subsubsecno=0 \global\advance\secno by 1 + \sectionheading{#1}{sec}{Ynumbered}{\the\chapno.\the\secno}% +} + +% normally calls appendixsectionzzz: +\outer\parseargdef\appendixsection{\apphead1{#1}} +\def\appendixsectionzzz#1{% + \global\subsecno=0 \global\subsubsecno=0 \global\advance\secno by 1 + \sectionheading{#1}{sec}{Yappendix}{\appendixletter.\the\secno}% +} +\let\appendixsec\appendixsection + +% normally calls unnumberedseczzz: +\outer\parseargdef\unnumberedsec{\unnmhead1{#1}} +\def\unnumberedseczzz#1{% + \global\subsecno=0 \global\subsubsecno=0 \global\advance\secno by 1 + \sectionheading{#1}{sec}{Ynothing}{\the\unnumberedno.\the\secno}% +} + +% Subsections. +% +% normally calls numberedsubseczzz: +\outer\parseargdef\numberedsubsec{\numhead2{#1}} +\def\numberedsubseczzz#1{% + \global\subsubsecno=0 \global\advance\subsecno by 1 + \sectionheading{#1}{subsec}{Ynumbered}{\the\chapno.\the\secno.\the\subsecno}% +} + +% normally calls appendixsubseczzz: +\outer\parseargdef\appendixsubsec{\apphead2{#1}} +\def\appendixsubseczzz#1{% + \global\subsubsecno=0 \global\advance\subsecno by 1 + \sectionheading{#1}{subsec}{Yappendix}% + {\appendixletter.\the\secno.\the\subsecno}% +} + +% normally calls unnumberedsubseczzz: +\outer\parseargdef\unnumberedsubsec{\unnmhead2{#1}} +\def\unnumberedsubseczzz#1{% + \global\subsubsecno=0 \global\advance\subsecno by 1 + \sectionheading{#1}{subsec}{Ynothing}% + {\the\unnumberedno.\the\secno.\the\subsecno}% +} + +% Subsubsections. +% +% normally numberedsubsubseczzz: +\outer\parseargdef\numberedsubsubsec{\numhead3{#1}} +\def\numberedsubsubseczzz#1{% + \global\advance\subsubsecno by 1 + \sectionheading{#1}{subsubsec}{Ynumbered}% + {\the\chapno.\the\secno.\the\subsecno.\the\subsubsecno}% +} + +% normally appendixsubsubseczzz: +\outer\parseargdef\appendixsubsubsec{\apphead3{#1}} +\def\appendixsubsubseczzz#1{% + \global\advance\subsubsecno by 1 + \sectionheading{#1}{subsubsec}{Yappendix}% + {\appendixletter.\the\secno.\the\subsecno.\the\subsubsecno}% +} + +% normally unnumberedsubsubseczzz: +\outer\parseargdef\unnumberedsubsubsec{\unnmhead3{#1}} +\def\unnumberedsubsubseczzz#1{% + \global\advance\subsubsecno by 1 + \sectionheading{#1}{subsubsec}{Ynothing}% + {\the\unnumberedno.\the\secno.\the\subsecno.\the\subsubsecno}% +} + +% These macros control what the section commands do, according +% to what kind of chapter we are in (ordinary, appendix, or unnumbered). +% Define them by default for a numbered chapter. +\let\section = \numberedsec +\let\subsection = \numberedsubsec +\let\subsubsection = \numberedsubsubsec + +% Define @majorheading, @heading and @subheading + +\def\majorheading{% + {\advance\chapheadingskip by 10pt \chapbreak }% + \parsearg\chapheadingzzz +} + +\def\chapheading{\chapbreak \parsearg\chapheadingzzz} +\def\chapheadingzzz#1{% + \vbox{\chapfonts \raggedtitlesettings #1\par}% + \nobreak\bigskip \nobreak + \suppressfirstparagraphindent +} + +% @heading, @subheading, @subsubheading. +\parseargdef\heading{\sectionheading{#1}{sec}{Yomitfromtoc}{} + \suppressfirstparagraphindent} +\parseargdef\subheading{\sectionheading{#1}{subsec}{Yomitfromtoc}{} + \suppressfirstparagraphindent} +\parseargdef\subsubheading{\sectionheading{#1}{subsubsec}{Yomitfromtoc}{} + \suppressfirstparagraphindent} + +% These macros generate a chapter, section, etc. heading only +% (including whitespace, linebreaking, etc. around it), +% given all the information in convenient, parsed form. + +% Args are the skip and penalty (usually negative) +\def\dobreak#1#2{\par\ifdim\lastskip<#1\removelastskip\penalty#2\vskip#1\fi} + +% Parameter controlling skip before chapter headings (if needed) +\newskip\chapheadingskip + +% Define plain chapter starts, and page on/off switching for it. +\def\chapbreak{\dobreak \chapheadingskip {-4000}} + +% Start a new page +\def\chappager{\par\vfill\supereject} + +% \chapoddpage - start on an odd page for a new chapter +% Because \domark is called before \chapoddpage, the filler page will +% get the headings for the next chapter, which is wrong. But we don't +% care -- we just disable all headings on the filler page. +\def\chapoddpage{% + \chappager + \ifodd\pageno \else + \begingroup + \headingsoff + \null + \chappager + \endgroup + \fi +} + +\parseargdef\setchapternewpage{\csname CHAPPAG#1\endcsname} + +\def\CHAPPAGoff{% +\global\let\contentsalignmacro = \chappager +\global\let\pchapsepmacro=\chapbreak +\global\let\pagealignmacro=\chappager} + +\def\CHAPPAGon{% +\global\let\contentsalignmacro = \chappager +\global\let\pchapsepmacro=\chappager +\global\let\pagealignmacro=\chappager +\global\def\HEADINGSon{\HEADINGSsingle}} + +\def\CHAPPAGodd{% +\global\let\contentsalignmacro = \chapoddpage +\global\let\pchapsepmacro=\chapoddpage +\global\let\pagealignmacro=\chapoddpage +\global\def\HEADINGSon{\HEADINGSdouble}} + +\CHAPPAGon + +% \chapmacro - Chapter opening. +% +% #1 is the text, #2 is the section type (Ynumbered, Ynothing, +% Yappendix, Yomitfromtoc), #3 the chapter number. +% Not used for @heading series. +% +% To test against our argument. +\def\Ynothingkeyword{Ynothing} +\def\Yappendixkeyword{Yappendix} +\def\Yomitfromtockeyword{Yomitfromtoc} +% +\def\chapmacro#1#2#3{% + \expandafter\ifx\thisenv\titlepage\else + \checkenv{}% chapters, etc., should not start inside an environment. + \fi + % FIXME: \chapmacro is currently called from inside \titlepage when + % \setcontentsaftertitlepage to print the "Table of Contents" heading, but + % this should probably be done by \sectionheading with an option to print + % in chapter size. + % + % Insert the first mark before the heading break (see notes for \domark). + \let\prevchapterdefs=\lastchapterdefs + \let\prevsectiondefs=\lastsectiondefs + \gdef\lastsectiondefs{\gdef\thissectionname{}\gdef\thissectionnum{}% + \gdef\thissection{}}% + % + \def\temptype{#2}% + \ifx\temptype\Ynothingkeyword + \gdef\lastchapterdefs{\gdef\thischaptername{#1}\gdef\thischapternum{}% + \gdef\thischapter{\thischaptername}}% + \else\ifx\temptype\Yomitfromtockeyword + \gdef\lastchapterdefs{\gdef\thischaptername{#1}\gdef\thischapternum{}% + \gdef\thischapter{}}% + \else\ifx\temptype\Yappendixkeyword + \toks0={#1}% + \xdef\lastchapterdefs{% + \gdef\noexpand\thischaptername{\the\toks0}% + \gdef\noexpand\thischapternum{\appendixletter}% + % \noexpand\putwordAppendix avoids expanding indigestible + % commands in some of the translations. + \gdef\noexpand\thischapter{\noexpand\putwordAppendix{} + \noexpand\thischapternum: + \noexpand\thischaptername}% + }% + \else + \toks0={#1}% + \xdef\lastchapterdefs{% + \gdef\noexpand\thischaptername{\the\toks0}% + \gdef\noexpand\thischapternum{\the\chapno}% + % \noexpand\putwordChapter avoids expanding indigestible + % commands in some of the translations. + \gdef\noexpand\thischapter{\noexpand\putwordChapter{} + \noexpand\thischapternum: + \noexpand\thischaptername}% + }% + \fi\fi\fi + % + % Output the mark. Pass it through \safewhatsit, to take care of + % the preceding space. + \safewhatsit\domark + % + % Insert the chapter heading break. + \pchapsepmacro + % + % Now the second mark, after the heading break. No break points + % between here and the heading. + \let\prevchapterdefs=\lastchapterdefs + \let\prevsectiondefs=\lastsectiondefs + \domark + % + {% + \chapfonts \rm + \let\footnote=\errfootnoteheading % give better error message + % + % Have to define \lastsection before calling \donoderef, because the + % xref code eventually uses it. On the other hand, it has to be called + % after \pchapsepmacro, or the headline will change too soon. + \gdef\lastsection{#1}% + % + % Only insert the separating space if we have a chapter/appendix + % number, and don't print the unnumbered ``number''. + \ifx\temptype\Ynothingkeyword + \setbox0 = \hbox{}% + \def\toctype{unnchap}% + \else\ifx\temptype\Yomitfromtockeyword + \setbox0 = \hbox{}% contents like unnumbered, but no toc entry + \def\toctype{omit}% + \else\ifx\temptype\Yappendixkeyword + \setbox0 = \hbox{\putwordAppendix{} #3\enspace}% + \def\toctype{app}% + \else + \setbox0 = \hbox{#3\enspace}% + \def\toctype{numchap}% + \fi\fi\fi + % + % Write the toc entry for this chapter. Must come before the + % \donoderef, because we include the current node name in the toc + % entry, and \donoderef resets it to empty. + \writetocentry{\toctype}{#1}{#3}% + % + % For pdftex, we have to write out the node definition (aka, make + % the pdfdest) after any page break, but before the actual text has + % been typeset. If the destination for the pdf outline is after the + % text, then jumping from the outline may wind up with the text not + % being visible, for instance under high magnification. + \donoderef{#2}% + % + % Typeset the actual heading. + \nobreak % Avoid page breaks at the interline glue. + \vbox{\raggedtitlesettings \hangindent=\wd0 \centerparametersmaybe + \unhbox0 #1\par}% + }% + \nobreak\bigskip % no page break after a chapter title + \nobreak +} + +% @centerchap -- centered and unnumbered. +\let\centerparametersmaybe = \relax +\def\centerparameters{% + \advance\rightskip by 3\rightskip + \leftskip = \rightskip + \parfillskip = 0pt +} + + +% Section titles. These macros combine the section number parts and +% call the generic \sectionheading to do the printing. +% +\newskip\secheadingskip +\def\secheadingbreak{\dobreak \secheadingskip{-1000}} + +% Subsection titles. +\newskip\subsecheadingskip +\def\subsecheadingbreak{\dobreak \subsecheadingskip{-500}} + +% Subsubsection titles. +\def\subsubsecheadingskip{\subsecheadingskip} +\def\subsubsecheadingbreak{\subsecheadingbreak} + + +% Print any size, any type, section title. +% +% #1 is the text of the title, +% #2 is the section level (sec/subsec/subsubsec), +% #3 is the section type (Ynumbered, Ynothing, Yappendix, Yomitfromtoc), +% #4 is the section number. +% +\def\seckeyword{sec} +% +\def\sectionheading#1#2#3#4{% + {% + \def\sectionlevel{#2}% + \def\temptype{#3}% + % + % It is ok for the @heading series commands to appear inside an + % environment (it's been historically allowed, though the logic is + % dubious), but not the others. + \ifx\temptype\Yomitfromtockeyword\else + \checkenv{}% non-@*heading should not be in an environment. + \fi + \let\footnote=\errfootnoteheading + % + % Switch to the right set of fonts. + \csname #2fonts\endcsname \rm + % + % Insert first mark before the heading break (see notes for \domark). + \let\prevsectiondefs=\lastsectiondefs + \ifx\temptype\Ynothingkeyword + \ifx\sectionlevel\seckeyword + \gdef\lastsectiondefs{\gdef\thissectionname{#1}\gdef\thissectionnum{}% + \gdef\thissection{\thissectionname}}% + \fi + \else\ifx\temptype\Yomitfromtockeyword + % Don't redefine \thissection. + \else\ifx\temptype\Yappendixkeyword + \ifx\sectionlevel\seckeyword + \toks0={#1}% + \xdef\lastsectiondefs{% + \gdef\noexpand\thissectionname{\the\toks0}% + \gdef\noexpand\thissectionnum{#4}% + % \noexpand\putwordSection avoids expanding indigestible + % commands in some of the translations. + \gdef\noexpand\thissection{\noexpand\putwordSection{} + \noexpand\thissectionnum: + \noexpand\thissectionname}% + }% + \fi + \else + \ifx\sectionlevel\seckeyword + \toks0={#1}% + \xdef\lastsectiondefs{% + \gdef\noexpand\thissectionname{\the\toks0}% + \gdef\noexpand\thissectionnum{#4}% + % \noexpand\putwordSection avoids expanding indigestible + % commands in some of the translations. + \gdef\noexpand\thissection{\noexpand\putwordSection{} + \noexpand\thissectionnum: + \noexpand\thissectionname}% + }% + \fi + \fi\fi\fi + % + % Go into vertical mode. Usually we'll already be there, but we + % don't want the following whatsit to end up in a preceding paragraph + % if the document didn't happen to have a blank line. + \par + % + % Output the mark. Pass it through \safewhatsit, to take care of + % the preceding space. + \safewhatsit\domark + % + % Insert space above the heading. + \csname #2headingbreak\endcsname + % + % Now the second mark, after the heading break. No break points + % between here and the heading. + \global\let\prevsectiondefs=\lastsectiondefs + \domark + % + % Only insert the space after the number if we have a section number. + \ifx\temptype\Ynothingkeyword + \setbox0 = \hbox{}% + \def\toctype{unn}% + \gdef\lastsection{#1}% + \else\ifx\temptype\Yomitfromtockeyword + % for @headings -- no section number, don't include in toc, + % and don't redefine \lastsection. + \setbox0 = \hbox{}% + \def\toctype{omit}% + \let\sectionlevel=\empty + \else\ifx\temptype\Yappendixkeyword + \setbox0 = \hbox{#4\enspace}% + \def\toctype{app}% + \gdef\lastsection{#1}% + \else + \setbox0 = \hbox{#4\enspace}% + \def\toctype{num}% + \gdef\lastsection{#1}% + \fi\fi\fi + % + % Write the toc entry (before \donoderef). See comments in \chapmacro. + \writetocentry{\toctype\sectionlevel}{#1}{#4}% + % + % Write the node reference (= pdf destination for pdftex). + % Again, see comments in \chapmacro. + \donoderef{#3}% + % + % Interline glue will be inserted when the vbox is completed. + % That glue will be a valid breakpoint for the page, since it'll be + % preceded by a whatsit (usually from the \donoderef, or from the + % \writetocentry if there was no node). We don't want to allow that + % break, since then the whatsits could end up on page n while the + % section is on page n+1, thus toc/etc. are wrong. Debian bug 276000. + \nobreak + % + % Output the actual section heading. + \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \ptexraggedright + \hangindent=\wd0 % zero if no section number + \unhbox0 #1}% + }% + % Add extra space after the heading -- half of whatever came above it. + % Don't allow stretch, though. + \kern .5 \csname #2headingskip\endcsname + % + % Do not let the kern be a potential breakpoint, as it would be if it + % was followed by glue. + \nobreak + % + % We'll almost certainly start a paragraph next, so don't let that + % glue accumulate. (Not a breakpoint because it's preceded by a + % discardable item.) However, when a paragraph is not started next + % (\startdefun, \cartouche, \center, etc.), this needs to be wiped out + % or the negative glue will cause weirdly wrong output, typically + % obscuring the section heading with something else. + \vskip-\parskip + % + % This is so the last item on the main vertical list is a known + % \penalty > 10000, so \startdefun, etc., can recognize the situation + % and do the needful. + \penalty 10001 +} + + +\message{toc,} +% Table of contents. +\newwrite\tocfile + +% Write an entry to the toc file, opening it if necessary. +% Called from @chapter, etc. +% +% Example usage: \writetocentry{sec}{Section Name}{\the\chapno.\the\secno} +% We append the current node name (if any) and page number as additional +% arguments for the \{chap,sec,...}entry macros which will eventually +% read this. The node name is used in the pdf outlines as the +% destination to jump to. +% +% We open the .toc file for writing here instead of at @setfilename (or +% any other fixed time) so that @contents can be anywhere in the document. +% But if #1 is `omit', then we don't do anything. This is used for the +% table of contents chapter openings themselves. +% +\newif\iftocfileopened +\def\omitkeyword{omit}% +% +\def\writetocentry#1#2#3{% + \edef\writetoctype{#1}% + \ifx\writetoctype\omitkeyword \else + \iftocfileopened\else + \immediate\openout\tocfile = \jobname.toc + \global\tocfileopenedtrue + \fi + % + \iflinks + {\atdummies + \edef\temp{% + \write\tocfile{@#1entry{#2}{#3}{\lastnode}{\noexpand\folio}}}% + \temp + }% + \fi + \fi + % + % Tell \shipout to create a pdf destination on each page, if we're + % writing pdf. These are used in the table of contents. We can't + % just write one on every page because the title pages are numbered + % 1 and 2 (the page numbers aren't printed), and so are the first + % two pages of the document. Thus, we'd have two destinations named + % `1', and two named `2'. + \ifpdf + \global\pdfmakepagedesttrue + \else + \ifx\XeTeXrevision\thisisundefined + \else + \global\pdfmakepagedesttrue + \fi + \fi +} + + +% These characters do not print properly in the Computer Modern roman +% fonts, so we must take special care. This is more or less redundant +% with the Texinfo input format setup at the end of this file. +% +\def\activecatcodes{% + \catcode`\"=\active + \catcode`\$=\active + \catcode`\<=\active + \catcode`\>=\active + \catcode`\\=\active + \catcode`\^=\active + \catcode`\_=\active + \catcode`\|=\active + \catcode`\~=\active +} + + +% Read the toc file, which is essentially Texinfo input. +\def\readtocfile{% + \setupdatafile + \activecatcodes + \input \tocreadfilename +} + +\newskip\contentsrightmargin \contentsrightmargin=1in +\newcount\savepageno +\newcount\lastnegativepageno \lastnegativepageno = -1 + +% Prepare to read what we've written to \tocfile. +% +\def\startcontents#1{% + % If @setchapternewpage on, and @headings double, the contents should + % start on an odd page, unlike chapters. Thus, we maintain + % \contentsalignmacro in parallel with \pagealignmacro. + % From: Torbjorn Granlund <tege@matematik.su.se> + \contentsalignmacro + \immediate\closeout\tocfile + % + % Don't need to put `Contents' or `Short Contents' in the headline. + % It is abundantly clear what they are. + \chapmacro{#1}{Yomitfromtoc}{}% + % + \savepageno = \pageno + \begingroup % Set up to handle contents files properly. + \raggedbottom % Worry more about breakpoints than the bottom. + \entryrightmargin=\contentsrightmargin % Don't use the full line length. + % + % Roman numerals for page numbers. + \ifnum \pageno>0 \global\pageno = \lastnegativepageno \fi +} + +% redefined for the two-volume lispref. We always output on +% \jobname.toc even if this is redefined. +% +\def\tocreadfilename{\jobname.toc} + +% Normal (long) toc. +% +\def\contents{% + \startcontents{\putwordTOC}% + \openin 1 \tocreadfilename\space + \ifeof 1 \else + \readtocfile + \fi + \vfill \eject + \contentsalignmacro % in case @setchapternewpage odd is in effect + \ifeof 1 \else + \pdfmakeoutlines + \fi + \closein 1 + \endgroup + \lastnegativepageno = \pageno + \global\pageno = \savepageno +} + +% And just the chapters. +\def\summarycontents{% + \startcontents{\putwordShortTOC}% + % + \let\partentry = \shortpartentry + \let\numchapentry = \shortchapentry + \let\appentry = \shortchapentry + \let\unnchapentry = \shortunnchapentry + % We want a true roman here for the page numbers. + \secfonts + \let\rm=\shortcontrm \let\bf=\shortcontbf + \let\sl=\shortcontsl \let\tt=\shortconttt + \rm + \hyphenpenalty = 10000 + \advance\baselineskip by 1pt % Open it up a little. + \def\numsecentry##1##2##3##4{} + \let\appsecentry = \numsecentry + \let\unnsecentry = \numsecentry + \let\numsubsecentry = \numsecentry + \let\appsubsecentry = \numsecentry + \let\unnsubsecentry = \numsecentry + \let\numsubsubsecentry = \numsecentry + \let\appsubsubsecentry = \numsecentry + \let\unnsubsubsecentry = \numsecentry + \openin 1 \tocreadfilename\space + \ifeof 1 \else + \readtocfile + \fi + \closein 1 + \vfill \eject + \contentsalignmacro % in case @setchapternewpage odd is in effect + \endgroup + \lastnegativepageno = \pageno + \global\pageno = \savepageno +} +\let\shortcontents = \summarycontents + +% Typeset the label for a chapter or appendix for the short contents. +% The arg is, e.g., `A' for an appendix, or `3' for a chapter. +% +\def\shortchaplabel#1{% + % This space should be enough, since a single number is .5em, and the + % widest letter (M) is 1em, at least in the Computer Modern fonts. + % But use \hss just in case. + % (This space doesn't include the extra space that gets added after + % the label; that gets put in by \shortchapentry above.) + % + % We'd like to right-justify chapter numbers, but that looks strange + % with appendix letters. And right-justifying numbers and + % left-justifying letters looks strange when there is less than 10 + % chapters. Have to read the whole toc once to know how many chapters + % there are before deciding ... + \hbox to 1em{#1\hss}% +} + +% These macros generate individual entries in the table of contents. +% The first argument is the chapter or section name. +% The last argument is the page number. +% The arguments in between are the chapter number, section number, ... + +% Parts, in the main contents. Replace the part number, which doesn't +% exist, with an empty box. Let's hope all the numbers have the same width. +% Also ignore the page number, which is conventionally not printed. +\def\numeralbox{\setbox0=\hbox{8}\hbox to \wd0{\hfil}} +\def\partentry#1#2#3#4{% + % Add stretch and a bonus for breaking the page before the part heading. + % This reduces the chance of the page being broken immediately after the + % part heading, before a following chapter heading. + \vskip 0pt plus 5\baselineskip + \penalty-300 + \vskip 0pt plus -5\baselineskip + \dochapentry{\numeralbox\labelspace#1}{}% +} +% +% Parts, in the short toc. +\def\shortpartentry#1#2#3#4{% + \penalty-300 + \vskip.5\baselineskip plus.15\baselineskip minus.1\baselineskip + \shortchapentry{{\bf #1}}{\numeralbox}{}{}% +} + +% Chapters, in the main contents. +\def\numchapentry#1#2#3#4{\dochapentry{#2\labelspace#1}{#4}} + +% Chapters, in the short toc. +% See comments in \dochapentry re vbox and related settings. +\def\shortchapentry#1#2#3#4{% + \tocentry{\shortchaplabel{#2}\labelspace #1}{\doshortpageno\bgroup#4\egroup}% +} + +% Appendices, in the main contents. +% Need the word Appendix, and a fixed-size box. +% +\def\appendixbox#1{% + % We use M since it's probably the widest letter. + \setbox0 = \hbox{\putwordAppendix{} M}% + \hbox to \wd0{\putwordAppendix{} #1\hss}} +% +\def\appentry#1#2#3#4{\dochapentry{\appendixbox{#2}\hskip.7em#1}{#4}} + +% Unnumbered chapters. +\def\unnchapentry#1#2#3#4{\dochapentry{#1}{#4}} +\def\shortunnchapentry#1#2#3#4{\tocentry{#1}{\doshortpageno\bgroup#4\egroup}} + +% Sections. +\def\numsecentry#1#2#3#4{\dosecentry{#2\labelspace#1}{#4}} +\let\appsecentry=\numsecentry +\def\unnsecentry#1#2#3#4{\dosecentry{#1}{#4}} + +% Subsections. +\def\numsubsecentry#1#2#3#4{\dosubsecentry{#2\labelspace#1}{#4}} +\let\appsubsecentry=\numsubsecentry +\def\unnsubsecentry#1#2#3#4{\dosubsecentry{#1}{#4}} + +% And subsubsections. +\def\numsubsubsecentry#1#2#3#4{\dosubsubsecentry{#2\labelspace#1}{#4}} +\let\appsubsubsecentry=\numsubsubsecentry +\def\unnsubsubsecentry#1#2#3#4{\dosubsubsecentry{#1}{#4}} + +% This parameter controls the indentation of the various levels. +% Same as \defaultparindent. +\newdimen\tocindent \tocindent = 15pt + +% Now for the actual typesetting. In all these, #1 is the text and #2 is the +% page number. +% +% If the toc has to be broken over pages, we want it to be at chapters +% if at all possible; hence the \penalty. +\def\dochapentry#1#2{% + \penalty-300 \vskip1\baselineskip plus.33\baselineskip minus.25\baselineskip + \begingroup + % Move the page numbers slightly to the right + \advance\entryrightmargin by -0.05em + \chapentryfonts + \tocentry{#1}{\dopageno\bgroup#2\egroup}% + \endgroup + \nobreak\vskip .25\baselineskip plus.1\baselineskip +} + +\def\dosecentry#1#2{\begingroup + \secentryfonts \leftskip=\tocindent + \tocentry{#1}{\dopageno\bgroup#2\egroup}% +\endgroup} + +\def\dosubsecentry#1#2{\begingroup + \subsecentryfonts \leftskip=2\tocindent + \tocentry{#1}{\dopageno\bgroup#2\egroup}% +\endgroup} + +\def\dosubsubsecentry#1#2{\begingroup + \subsubsecentryfonts \leftskip=3\tocindent + \tocentry{#1}{\dopageno\bgroup#2\egroup}% +\endgroup} + +% We use the same \entry macro as for the index entries. +\let\tocentry = \entry + +% Space between chapter (or whatever) number and the title. +\def\labelspace{\hskip1em \relax} + +\def\dopageno#1{{\rm #1}} +\def\doshortpageno#1{{\rm #1}} + +\def\chapentryfonts{\secfonts \rm} +\def\secentryfonts{\textfonts} +\def\subsecentryfonts{\textfonts} +\def\subsubsecentryfonts{\textfonts} + + +\message{environments,} +% @foo ... @end foo. + +% @tex ... @end tex escapes into raw TeX temporarily. +% One exception: @ is still an escape character, so that @end tex works. +% But \@ or @@ will get a plain @ character. + +\envdef\tex{% + \setupmarkupstyle{tex}% + \catcode `\\=0 \catcode `\{=1 \catcode `\}=2 + \catcode `\$=3 \catcode `\&=4 \catcode `\#=6 + \catcode `\^=7 \catcode `\_=8 \catcode `\~=\active \let~=\tie + \catcode `\%=14 + \catcode `\+=\other + \catcode `\"=\other + \catcode `\|=\other + \catcode `\<=\other + \catcode `\>=\other + \catcode `\`=\other + \catcode `\'=\other + % + % ' is active in math mode (mathcode"8000). So reset it, and all our + % other math active characters (just in case), to plain's definitions. + \mathactive + % + % Inverse of the list at the beginning of the file. + \let\b=\ptexb + \let\bullet=\ptexbullet + \let\c=\ptexc + \let\,=\ptexcomma + \let\.=\ptexdot + \let\dots=\ptexdots + \let\equiv=\ptexequiv + \let\!=\ptexexclam + \let\i=\ptexi + \let\indent=\ptexindent + \let\noindent=\ptexnoindent + \let\{=\ptexlbrace + \let\+=\tabalign + \let\}=\ptexrbrace + \let\/=\ptexslash + \let\sp=\ptexsp + \let\*=\ptexstar + %\let\sup=\ptexsup % do not redefine, we want @sup to work in math mode + \let\t=\ptext + \expandafter \let\csname top\endcsname=\ptextop % we've made it outer + \let\frenchspacing=\plainfrenchspacing + % + \def\endldots{\mathinner{\ldots\ldots\ldots\ldots}}% + \def\enddots{\relax\ifmmode\endldots\else$\mathsurround=0pt \endldots\,$\fi}% + \def\@{@}% +} +% There is no need to define \Etex. + +% Define @lisp ... @end lisp. +% @lisp environment forms a group so it can rebind things, +% including the definition of @end lisp (which normally is erroneous). + +% Amount to narrow the margins by for @lisp. +\newskip\lispnarrowing \lispnarrowing=0.4in + +% This is the definition that ^^M gets inside @lisp, @example, and other +% such environments. \null is better than a space, since it doesn't +% have any width. +\def\lisppar{\null\endgraf} + +% This space is always present above and below environments. +\newskip\envskipamount \envskipamount = 0pt + +% Make spacing and below environment symmetrical. We use \parskip here +% to help in doing that, since in @example-like environments \parskip +% is reset to zero; thus the \afterenvbreak inserts no space -- but the +% start of the next paragraph will insert \parskip. +% +\def\aboveenvbreak{{% + % =10000 instead of <10000 because of a special case in \itemzzz and + % \sectionheading, q.v. + \ifnum \lastpenalty=10000 \else + \advance\envskipamount by \parskip + \endgraf + \ifdim\lastskip<\envskipamount + \removelastskip + \ifnum\lastpenalty<10000 + % Penalize breaking before the environment, because preceding text + % often leads into it. + \penalty100 + \fi + \vskip\envskipamount + \fi + \fi +}} + +\def\afterenvbreak{{% + % =10000 instead of <10000 because of a special case in \itemzzz and + % \sectionheading, q.v. + \ifnum \lastpenalty=10000 \else + \advance\envskipamount by \parskip + \endgraf + \ifdim\lastskip<\envskipamount + \removelastskip + % it's not a good place to break if the last penalty was \nobreak + % or better ... + \ifnum\lastpenalty<10000 \penalty-50 \fi + \vskip\envskipamount + \fi + \fi +}} + +% \nonarrowing is a flag. If "set", @lisp etc don't narrow margins; it will +% also clear it, so that its embedded environments do the narrowing again. +\let\nonarrowing=\relax + +% @cartouche ... @end cartouche: draw rectangle w/rounded corners around +% environment contents. +\font\circle=lcircle10 +\newdimen\circthick +\newdimen\cartouter\newdimen\cartinner +\newskip\normbskip\newskip\normpskip\newskip\normlskip +\circthick=\fontdimen8\circle +% +\def\ctl{{\circle\char'013\hskip -6pt}}% 6pt from pl file: 1/2charwidth +\def\ctr{{\hskip 6pt\circle\char'010}} +\def\cbl{{\circle\char'012\hskip -6pt}} +\def\cbr{{\hskip 6pt\circle\char'011}} +\def\carttop{\hbox to \cartouter{\hskip\lskip + \ctl\leaders\hrule height\circthick\hfil\ctr + \hskip\rskip}} +\def\cartbot{\hbox to \cartouter{\hskip\lskip + \cbl\leaders\hrule height\circthick\hfil\cbr + \hskip\rskip}} +% +\newskip\lskip\newskip\rskip + +\envdef\cartouche{% + \ifhmode\par\fi % can't be in the midst of a paragraph. + \startsavinginserts + \lskip=\leftskip \rskip=\rightskip + \leftskip=0pt\rightskip=0pt % we want these *outside*. + \cartinner=\hsize \advance\cartinner by-\lskip + \advance\cartinner by-\rskip + \cartouter=\hsize + \advance\cartouter by 18.4pt % allow for 3pt kerns on either + % side, and for 6pt waste from + % each corner char, and rule thickness + \normbskip=\baselineskip \normpskip=\parskip \normlskip=\lineskip + % + % If this cartouche directly follows a sectioning command, we need the + % \parskip glue (backspaced over by default) or the cartouche can + % collide with the section heading. + \ifnum\lastpenalty>10000 \vskip\parskip \penalty\lastpenalty \fi + % + \setbox\groupbox=\vbox\bgroup + \baselineskip=0pt\parskip=0pt\lineskip=0pt + \carttop + \hbox\bgroup + \hskip\lskip + \vrule\kern3pt + \vbox\bgroup + \kern3pt + \hsize=\cartinner + \baselineskip=\normbskip + \lineskip=\normlskip + \parskip=\normpskip + \vskip -\parskip + \comment % For explanation, see the end of def\group. +} +\def\Ecartouche{% + \ifhmode\par\fi + \kern3pt + \egroup + \kern3pt\vrule + \hskip\rskip + \egroup + \cartbot + \egroup + \addgroupbox + \checkinserts +} + + +% This macro is called at the beginning of all the @example variants, +% inside a group. +\newdimen\nonfillparindent +\def\nonfillstart{% + \aboveenvbreak + \ifdim\hfuzz < 12pt \hfuzz = 12pt \fi % Don't be fussy + \sepspaces % Make spaces be word-separators rather than space tokens. + \let\par = \lisppar % don't ignore blank lines + \obeylines % each line of input is a line of output + \parskip = 0pt + % Turn off paragraph indentation but redefine \indent to emulate + % the normal \indent. + \nonfillparindent=\parindent + \parindent = 0pt + \let\indent\nonfillindent + % + \emergencystretch = 0pt % don't try to avoid overfull boxes + \ifx\nonarrowing\relax + \advance \leftskip by \lispnarrowing + \exdentamount=\lispnarrowing + \else + \let\nonarrowing = \relax + \fi + \let\exdent=\nofillexdent +} + +\begingroup +\obeyspaces +% We want to swallow spaces (but not other tokens) after the fake +% @indent in our nonfill-environments, where spaces are normally +% active and set to @tie, resulting in them not being ignored after +% @indent. +\gdef\nonfillindent{\futurelet\temp\nonfillindentcheck}% +\gdef\nonfillindentcheck{% +\ifx\temp % +\expandafter\nonfillindentgobble% +\else% +\leavevmode\nonfillindentbox% +\fi% +}% +\endgroup +\def\nonfillindentgobble#1{\nonfillindent} +\def\nonfillindentbox{\hbox to \nonfillparindent{\hss}} + +% If you want all examples etc. small: @set dispenvsize small. +% If you want even small examples the full size: @set dispenvsize nosmall. +% This affects the following displayed environments: +% @example, @display, @format, @lisp +% +\def\smallword{small} +\def\nosmallword{nosmall} +\let\SETdispenvsize\relax +\def\setnormaldispenv{% + \ifx\SETdispenvsize\smallword + % end paragraph for sake of leading, in case document has no blank + % line. This is redundant with what happens in \aboveenvbreak, but + % we need to do it before changing the fonts, and it's inconvenient + % to change the fonts afterward. + \ifnum \lastpenalty=10000 \else \endgraf \fi + \smallexamplefonts \rm + \fi +} +\def\setsmalldispenv{% + \ifx\SETdispenvsize\nosmallword + \else + \ifnum \lastpenalty=10000 \else \endgraf \fi + \smallexamplefonts \rm + \fi +} + +% We often define two environments, @foo and @smallfoo. +% Let's do it in one command. #1 is the env name, #2 the definition. +\def\makedispenvdef#1#2{% + \expandafter\envdef\csname#1\endcsname {\setnormaldispenv #2}% + \expandafter\envdef\csname small#1\endcsname {\setsmalldispenv #2}% + \expandafter\let\csname E#1\endcsname \afterenvbreak + \expandafter\let\csname Esmall#1\endcsname \afterenvbreak +} + +% Define two environment synonyms (#1 and #2) for an environment. +\def\maketwodispenvdef#1#2#3{% + \makedispenvdef{#1}{#3}% + \makedispenvdef{#2}{#3}% +} +% +% @lisp: indented, narrowed, typewriter font; +% @example: same as @lisp. +% +% @smallexample and @smalllisp: use smaller fonts. +% Originally contributed by Pavel@xerox. +% +\maketwodispenvdef{lisp}{example}{% + \nonfillstart + \tt\setupmarkupstyle{example}% + \let\kbdfont = \kbdexamplefont % Allow @kbd to do something special. + \gobble % eat return +} +% @display/@smalldisplay: same as @lisp except keep current font. +% +\makedispenvdef{display}{% + \nonfillstart + \gobble +} + +% @format/@smallformat: same as @display except don't narrow margins. +% +\makedispenvdef{format}{% + \let\nonarrowing = t% + \nonfillstart + \gobble +} + +% @flushleft: same as @format, but doesn't obey \SETdispenvsize. +\envdef\flushleft{% + \let\nonarrowing = t% + \nonfillstart + \gobble +} +\let\Eflushleft = \afterenvbreak + +% @flushright. +% +\envdef\flushright{% + \let\nonarrowing = t% + \nonfillstart + \advance\leftskip by 0pt plus 1fill\relax + \gobble +} +\let\Eflushright = \afterenvbreak + + +% @raggedright does more-or-less normal line breaking but no right +% justification. From plain.tex. Don't stretch around special +% characters in urls in this environment, since the stretch at the right +% should be enough. +\envdef\raggedright{% + \rightskip0pt plus2.4em \spaceskip.3333em \xspaceskip.5em\relax + \def\urefprestretchamount{0pt}% + \def\urefpoststretchamount{0pt}% +} +\let\Eraggedright\par + +\envdef\raggedleft{% + \parindent=0pt \leftskip0pt plus2em + \spaceskip.3333em \xspaceskip.5em \parfillskip=0pt + \hbadness=10000 % Last line will usually be underfull, so turn off + % badness reporting. +} +\let\Eraggedleft\par + +\envdef\raggedcenter{% + \parindent=0pt \rightskip0pt plus1em \leftskip0pt plus1em + \spaceskip.3333em \xspaceskip.5em \parfillskip=0pt + \hbadness=10000 % Last line will usually be underfull, so turn off + % badness reporting. +} +\let\Eraggedcenter\par + + +% @quotation does normal linebreaking (hence we can't use \nonfillstart) +% and narrows the margins. We keep \parskip nonzero in general, since +% we're doing normal filling. So, when using \aboveenvbreak and +% \afterenvbreak, temporarily make \parskip 0. +% +\makedispenvdef{quotation}{\quotationstart} +% +\def\quotationstart{% + \indentedblockstart % same as \indentedblock, but increase right margin too. + \ifx\nonarrowing\relax + \advance\rightskip by \lispnarrowing + \fi + \parsearg\quotationlabel +} + +% We have retained a nonzero parskip for the environment, since we're +% doing normal filling. +% +\def\Equotation{% + \par + \ifx\quotationauthor\thisisundefined\else + % indent a bit. + \leftline{\kern 2\leftskip \sl ---\quotationauthor}% + \fi + {\parskip=0pt \afterenvbreak}% +} +\def\Esmallquotation{\Equotation} + +% If we're given an argument, typeset it in bold with a colon after. +\def\quotationlabel#1{% + \def\temp{#1}% + \ifx\temp\empty \else + {\bf #1: }% + \fi +} + +% @indentedblock is like @quotation, but indents only on the left and +% has no optional argument. +% +\makedispenvdef{indentedblock}{\indentedblockstart} +% +\def\indentedblockstart{% + {\parskip=0pt \aboveenvbreak}% because \aboveenvbreak inserts \parskip + \parindent=0pt + % + % @cartouche defines \nonarrowing to inhibit narrowing at next level down. + \ifx\nonarrowing\relax + \advance\leftskip by \lispnarrowing + \exdentamount = \lispnarrowing + \else + \let\nonarrowing = \relax + \fi +} + +% Keep a nonzero parskip for the environment, since we're doing normal filling. +% +\def\Eindentedblock{% + \par + {\parskip=0pt \afterenvbreak}% +} +\def\Esmallindentedblock{\Eindentedblock} + + +% LaTeX-like @verbatim...@end verbatim and @verb{<char>...<char>} +% If we want to allow any <char> as delimiter, +% we need the curly braces so that makeinfo sees the @verb command, eg: +% `@verbx...x' would look like the '@verbx' command. --janneke@gnu.org +% +% [Knuth]: Donald Ervin Knuth, 1996. The TeXbook. +% +% [Knuth] p.344; only we need to do the other characters Texinfo sets +% active too. Otherwise, they get lost as the first character on a +% verbatim line. +\def\dospecials{% + \do\ \do\\\do\{\do\}\do\$\do\&% + \do\#\do\^\do\^^K\do\_\do\^^A\do\%\do\~% + \do\<\do\>\do\|\do\@\do+\do\"% + % Don't do the quotes -- if we do, @set txicodequoteundirected and + % @set txicodequotebacktick will not have effect on @verb and + % @verbatim, and ?` and !` ligatures won't get disabled. + %\do\`\do\'% +} +% +% [Knuth] p. 380 +\def\uncatcodespecials{% + \def\do##1{\catcode`##1=\other}\dospecials} +% +% Setup for the @verb command. +% +% Eight spaces for a tab +\begingroup + \catcode`\^^I=\active + \gdef\tabeightspaces{\catcode`\^^I=\active\def^^I{\ \ \ \ \ \ \ \ }} +\endgroup +% +\def\setupverb{% + \tt % easiest (and conventionally used) font for verbatim + \def\par{\leavevmode\endgraf}% + \setupmarkupstyle{verb}% + \tabeightspaces + % Respect line breaks, + % print special symbols as themselves, and + % make each space count + % must do in this order: + \obeylines \uncatcodespecials \sepspaces +} + +% Setup for the @verbatim environment +% +% Real tab expansion. +\newdimen\tabw \setbox0=\hbox{\tt\space} \tabw=8\wd0 % tab amount +% +% We typeset each line of the verbatim in an \hbox, so we can handle +% tabs. The \global is in case the verbatim line starts with an accent, +% or some other command that starts with a begin-group. Otherwise, the +% entire \verbbox would disappear at the corresponding end-group, before +% it is typeset. Meanwhile, we can't have nested verbatim commands +% (can we?), so the \global won't be overwriting itself. +\newbox\verbbox +\def\starttabbox{\global\setbox\verbbox=\hbox\bgroup} +% +\begingroup + \catcode`\^^I=\active + \gdef\tabexpand{% + \catcode`\^^I=\active + \def^^I{\leavevmode\egroup + \dimen\verbbox=\wd\verbbox % the width so far, or since the previous tab + \divide\dimen\verbbox by\tabw + \multiply\dimen\verbbox by\tabw % compute previous multiple of \tabw + \advance\dimen\verbbox by\tabw % advance to next multiple of \tabw + \wd\verbbox=\dimen\verbbox \box\verbbox \starttabbox + }% + } +\endgroup + +% start the verbatim environment. +\def\setupverbatim{% + \let\nonarrowing = t% + \nonfillstart + \tt % easiest (and conventionally used) font for verbatim + % The \leavevmode here is for blank lines. Otherwise, we would + % never \starttabox and the \egroup would end verbatim mode. + \def\par{\leavevmode\egroup\box\verbbox\endgraf}% + \tabexpand + \setupmarkupstyle{verbatim}% + % Respect line breaks, + % print special symbols as themselves, and + % make each space count. + % Must do in this order: + \obeylines \uncatcodespecials \sepspaces + \everypar{\starttabbox}% +} + +% Do the @verb magic: verbatim text is quoted by unique +% delimiter characters. Before first delimiter expect a +% right brace, after last delimiter expect closing brace: +% +% \def\doverb'{'<char>#1<char>'}'{#1} +% +% [Knuth] p. 382; only eat outer {} +\begingroup + \catcode`[=1\catcode`]=2\catcode`\{=\other\catcode`\}=\other + \gdef\doverb{#1[\def\next##1#1}[##1\endgroup]\next] +\endgroup +% +\def\verb{\begingroup\setupverb\doverb} +% +% +% Do the @verbatim magic: define the macro \doverbatim so that +% the (first) argument ends when '@end verbatim' is reached, ie: +% +% \def\doverbatim#1@end verbatim{#1} +% +% For Texinfo it's a lot easier than for LaTeX, +% because texinfo's \verbatim doesn't stop at '\end{verbatim}': +% we need not redefine '\', '{' and '}'. +% +% Inspired by LaTeX's verbatim command set [latex.ltx] +% +\begingroup + \catcode`\ =\active + \obeylines % + % ignore everything up to the first ^^M, that's the newline at the end + % of the @verbatim input line itself. Otherwise we get an extra blank + % line in the output. + \xdef\doverbatim#1^^M#2@end verbatim{#2\noexpand\end\gobble verbatim}% + % We really want {...\end verbatim} in the body of the macro, but + % without the active space; thus we have to use \xdef and \gobble. +\endgroup +% +\envdef\verbatim{% + \setupverbatim\doverbatim +} +\let\Everbatim = \afterenvbreak + + +% @verbatiminclude FILE - insert text of file in verbatim environment. +% +\def\verbatiminclude{\parseargusing\filenamecatcodes\doverbatiminclude} +% +\def\doverbatiminclude#1{% + {% + \makevalueexpandable + \setupverbatim + \indexnofonts % Allow `@@' and other weird things in file names. + \wlog{texinfo.tex: doing @verbatiminclude of #1^^J}% + \input #1 + \afterenvbreak + }% +} + +% @copying ... @end copying. +% Save the text away for @insertcopying later. +% +% We save the uninterpreted tokens, rather than creating a box. +% Saving the text in a box would be much easier, but then all the +% typesetting commands (@smallbook, font changes, etc.) have to be done +% beforehand -- and a) we want @copying to be done first in the source +% file; b) letting users define the frontmatter in as flexible order as +% possible is desirable. +% +\def\copying{\checkenv{}\begingroup\scanargctxt\docopying} +\def\docopying#1@end copying{\endgroup\def\copyingtext{#1}} +% +\def\insertcopying{% + \begingroup + \parindent = 0pt % paragraph indentation looks wrong on title page + \scanexp\copyingtext + \endgroup +} + + +\message{defuns,} +% @defun etc. + +\newskip\defbodyindent \defbodyindent=.4in +\newskip\defargsindent \defargsindent=50pt +\newskip\deflastargmargin \deflastargmargin=18pt +\newcount\defunpenalty + +% Start the processing of @deffn: +\def\startdefun{% + \ifnum\lastpenalty<10000 + \medbreak + \defunpenalty=10003 % Will keep this @deffn together with the + % following @def command, see below. + \else + % If there are two @def commands in a row, we'll have a \nobreak, + % which is there to keep the function description together with its + % header. But if there's nothing but headers, we need to allow a + % break somewhere. Check specifically for penalty 10002, inserted + % by \printdefunline, instead of 10000, since the sectioning + % commands also insert a nobreak penalty, and we don't want to allow + % a break between a section heading and a defun. + % + % As a further refinement, we avoid "club" headers by signalling + % with penalty of 10003 after the very first @deffn in the + % sequence (see above), and penalty of 10002 after any following + % @def command. + \ifnum\lastpenalty=10002 \penalty2000 \else \defunpenalty=10002 \fi + % + % Similarly, after a section heading, do not allow a break. + % But do insert the glue. + \medskip % preceded by discardable penalty, so not a breakpoint + \fi + % + \parindent=0in + \advance\leftskip by \defbodyindent + \exdentamount=\defbodyindent +} + +\def\dodefunx#1{% + % First, check whether we are in the right environment: + \checkenv#1% + % + % As above, allow line break if we have multiple x headers in a row. + % It's not a great place, though. + \ifnum\lastpenalty=10002 \penalty3000 \else \defunpenalty=10002 \fi + % + % And now, it's time to reuse the body of the original defun: + \expandafter\gobbledefun#1% +} +\def\gobbledefun#1\startdefun{} + +% \printdefunline \deffnheader{text} +% +\def\printdefunline#1#2{% + \begingroup + % call \deffnheader: + #1#2 \endheader + % common ending: + \interlinepenalty = 10000 + \advance\rightskip by 0pt plus 1fil\relax + \endgraf + \nobreak\vskip -\parskip + \penalty\defunpenalty % signal to \startdefun and \dodefunx + % Some of the @defun-type tags do not enable magic parentheses, + % rendering the following check redundant. But we don't optimize. + \checkparencounts + \endgroup +} + +\def\Edefun{\endgraf\medbreak} + +% \makedefun{deffn} creates \deffn, \deffnx and \Edeffn; +% the only thing remaining is to define \deffnheader. +% +\def\makedefun#1{% + \expandafter\let\csname E#1\endcsname = \Edefun + \edef\temp{\noexpand\domakedefun + \makecsname{#1}\makecsname{#1x}\makecsname{#1header}}% + \temp +} + +% \domakedefun \deffn \deffnx \deffnheader { (defn. of \deffnheader) } +% +% Define \deffn and \deffnx, without parameters. +% \deffnheader has to be defined explicitly. +% +\def\domakedefun#1#2#3{% + \envdef#1{% + \startdefun + \doingtypefnfalse % distinguish typed functions from all else + \parseargusing\activeparens{\printdefunline#3}% + }% + \def#2{\dodefunx#1}% + \def#3% +} + +\newif\ifdoingtypefn % doing typed function? +\newif\ifrettypeownline % typeset return type on its own line? + +% @deftypefnnewline on|off says whether the return type of typed functions +% are printed on their own line. This affects @deftypefn, @deftypefun, +% @deftypeop, and @deftypemethod. +% +\parseargdef\deftypefnnewline{% + \def\temp{#1}% + \ifx\temp\onword + \expandafter\let\csname SETtxideftypefnnl\endcsname + = \empty + \else\ifx\temp\offword + \expandafter\let\csname SETtxideftypefnnl\endcsname + = \relax + \else + \errhelp = \EMsimple + \errmessage{Unknown @txideftypefnnl value `\temp', + must be on|off}% + \fi\fi +} + +% Untyped functions: + +% @deffn category name args +\makedefun{deffn}{\deffngeneral{}} + +% @deffn category class name args +\makedefun{defop}#1 {\defopon{#1\ \putwordon}} + +% \defopon {category on}class name args +\def\defopon#1#2 {\deffngeneral{\putwordon\ \code{#2}}{#1\ \code{#2}} } + +% \deffngeneral {subind}category name args +% +\def\deffngeneral#1#2 #3 #4\endheader{% + % Remember that \dosubind{fn}{foo}{} is equivalent to \doind{fn}{foo}. + \dosubind{fn}{\code{#3}}{#1}% + \defname{#2}{}{#3}\magicamp\defunargs{#4\unskip}% +} + +% Typed functions: + +% @deftypefn category type name args +\makedefun{deftypefn}{\deftypefngeneral{}} + +% @deftypeop category class type name args +\makedefun{deftypeop}#1 {\deftypeopon{#1\ \putwordon}} + +% \deftypeopon {category on}class type name args +\def\deftypeopon#1#2 {\deftypefngeneral{\putwordon\ \code{#2}}{#1\ \code{#2}} } + +% \deftypefngeneral {subind}category type name args +% +\def\deftypefngeneral#1#2 #3 #4 #5\endheader{% + \dosubind{fn}{\code{#4}}{#1}% + \doingtypefntrue + \defname{#2}{#3}{#4}\defunargs{#5\unskip}% +} + +% Typed variables: + +% @deftypevr category type var args +\makedefun{deftypevr}{\deftypecvgeneral{}} + +% @deftypecv category class type var args +\makedefun{deftypecv}#1 {\deftypecvof{#1\ \putwordof}} + +% \deftypecvof {category of}class type var args +\def\deftypecvof#1#2 {\deftypecvgeneral{\putwordof\ \code{#2}}{#1\ \code{#2}} } + +% \deftypecvgeneral {subind}category type var args +% +\def\deftypecvgeneral#1#2 #3 #4 #5\endheader{% + \dosubind{vr}{\code{#4}}{#1}% + \defname{#2}{#3}{#4}\defunargs{#5\unskip}% +} + +% Untyped variables: + +% @defvr category var args +\makedefun{defvr}#1 {\deftypevrheader{#1} {} } + +% @defcv category class var args +\makedefun{defcv}#1 {\defcvof{#1\ \putwordof}} + +% \defcvof {category of}class var args +\def\defcvof#1#2 {\deftypecvof{#1}#2 {} } + +% Types: + +% @deftp category name args +\makedefun{deftp}#1 #2 #3\endheader{% + \doind{tp}{\code{#2}}% + \defname{#1}{}{#2}\defunargs{#3\unskip}% +} + +% Remaining @defun-like shortcuts: +\makedefun{defun}{\deffnheader{\putwordDeffunc} } +\makedefun{defmac}{\deffnheader{\putwordDefmac} } +\makedefun{defspec}{\deffnheader{\putwordDefspec} } +\makedefun{deftypefun}{\deftypefnheader{\putwordDeffunc} } +\makedefun{defvar}{\defvrheader{\putwordDefvar} } +\makedefun{defopt}{\defvrheader{\putwordDefopt} } +\makedefun{deftypevar}{\deftypevrheader{\putwordDefvar} } +\makedefun{defmethod}{\defopon\putwordMethodon} +\makedefun{deftypemethod}{\deftypeopon\putwordMethodon} +\makedefun{defivar}{\defcvof\putwordInstanceVariableof} +\makedefun{deftypeivar}{\deftypecvof\putwordInstanceVariableof} + +% \defname, which formats the name of the @def (not the args). +% #1 is the category, such as "Function". +% #2 is the return type, if any. +% #3 is the function name. +% +% We are followed by (but not passed) the arguments, if any. +% +\def\defname#1#2#3{% + \par + % Get the values of \leftskip and \rightskip as they were outside the @def... + \advance\leftskip by -\defbodyindent + % + % Determine if we are typesetting the return type of a typed function + % on a line by itself. + \rettypeownlinefalse + \ifdoingtypefn % doing a typed function specifically? + % then check user option for putting return type on its own line: + \expandafter\ifx\csname SETtxideftypefnnl\endcsname\relax \else + \rettypeownlinetrue + \fi + \fi + % + % How we'll format the category name. Putting it in brackets helps + % distinguish it from the body text that may end up on the next line + % just below it. + \def\temp{#1}% + \setbox0=\hbox{\kern\deflastargmargin \ifx\temp\empty\else [\rm\temp]\fi} + % + % Figure out line sizes for the paragraph shape. We'll always have at + % least two. + \tempnum = 2 + % + % The first line needs space for \box0; but if \rightskip is nonzero, + % we need only space for the part of \box0 which exceeds it: + \dimen0=\hsize \advance\dimen0 by -\wd0 \advance\dimen0 by \rightskip + % + % If doing a return type on its own line, we'll have another line. + \ifrettypeownline + \advance\tempnum by 1 + \def\maybeshapeline{0in \hsize}% + \else + \def\maybeshapeline{}% + \fi + % + % The continuations: + \dimen2=\hsize \advance\dimen2 by -\defargsindent + % + % The final paragraph shape: + \parshape \tempnum 0in \dimen0 \maybeshapeline \defargsindent \dimen2 + % + % Put the category name at the right margin. + \noindent + \hbox to 0pt{% + \hfil\box0 \kern-\hsize + % \hsize has to be shortened this way: + \kern\leftskip + % Intentionally do not respect \rightskip, since we need the space. + }% + % + % Allow all lines to be underfull without complaint: + \tolerance=10000 \hbadness=10000 + \exdentamount=\defbodyindent + {% + % defun fonts. We use typewriter by default (used to be bold) because: + % . we're printing identifiers, they should be in tt in principle. + % . in languages with many accents, such as Czech or French, it's + % common to leave accents off identifiers. The result looks ok in + % tt, but exceedingly strange in rm. + % . we don't want -- and --- to be treated as ligatures. + % . this still does not fix the ?` and !` ligatures, but so far no + % one has made identifiers using them :). + \df \tt + \def\temp{#2}% text of the return type + \ifx\temp\empty\else + \tclose{\temp}% typeset the return type + \ifrettypeownline + % put return type on its own line; prohibit line break following: + \hfil\vadjust{\nobreak}\break + \else + \space % type on same line, so just followed by a space + \fi + \fi % no return type + #3% output function name + }% + {\rm\enskip}% hskip 0.5 em of \rmfont + % + \boldbrax + % arguments will be output next, if any. +} + +% Print arguments in slanted roman (not ttsl), inconsistently with using +% tt for the name. This is because literal text is sometimes needed in +% the argument list (groff manual), and ttsl and tt are not very +% distinguishable. Prevent hyphenation at `-' chars. +% +\def\defunargs#1{% + % use sl by default (not ttsl), + % tt for the names. + \df \sl \hyphenchar\font=0 + % + % On the other hand, if an argument has two dashes (for instance), we + % want a way to get ttsl. We used to recommend @var for that, so + % leave the code in, but it's strange for @var to lead to typewriter. + % Nowadays we recommend @code, since the difference between a ttsl hyphen + % and a tt hyphen is pretty tiny. @code also disables ?` !`. + \def\var##1{{\setupmarkupstyle{var}\ttslanted{##1}}}% + #1% + \sl\hyphenchar\font=45 +} + +% We want ()&[] to print specially on the defun line. +% +\def\activeparens{% + \catcode`\(=\active \catcode`\)=\active + \catcode`\[=\active \catcode`\]=\active + \catcode`\&=\active +} + +% Make control sequences which act like normal parenthesis chars. +\let\lparen = ( \let\rparen = ) + +% Be sure that we always have a definition for `(', etc. For example, +% if the fn name has parens in it, \boldbrax will not be in effect yet, +% so TeX would otherwise complain about undefined control sequence. +{ + \activeparens + \global\let(=\lparen \global\let)=\rparen + \global\let[=\lbrack \global\let]=\rbrack + \global\let& = \& + + \gdef\boldbrax{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb} + \gdef\magicamp{\let&=\amprm} +} + +\newcount\parencount + +% If we encounter &foo, then turn on ()-hacking afterwards +\newif\ifampseen +\def\amprm#1 {\ampseentrue{\bf\ }} + +\def\parenfont{% + \ifampseen + % At the first level, print parens in roman, + % otherwise use the default font. + \ifnum \parencount=1 \rm \fi + \else + % The \sf parens (in \boldbrax) actually are a little bolder than + % the contained text. This is especially needed for [ and ] . + \sf + \fi +} +\def\infirstlevel#1{% + \ifampseen + \ifnum\parencount=1 + #1% + \fi + \fi +} +\def\bfafterword#1 {#1 \bf} + +\def\opnr{% + \global\advance\parencount by 1 + {\parenfont(}% + \infirstlevel \bfafterword +} +\def\clnr{% + {\parenfont)}% + \infirstlevel \sl + \global\advance\parencount by -1 +} + +\newcount\brackcount +\def\lbrb{% + \global\advance\brackcount by 1 + {\bf[}% +} +\def\rbrb{% + {\bf]}% + \global\advance\brackcount by -1 +} + +\def\checkparencounts{% + \ifnum\parencount=0 \else \badparencount \fi + \ifnum\brackcount=0 \else \badbrackcount \fi +} +% these should not use \errmessage; the glibc manual, at least, actually +% has such constructs (when documenting function pointers). +\def\badparencount{% + \message{Warning: unbalanced parentheses in @def...}% + \global\parencount=0 +} +\def\badbrackcount{% + \message{Warning: unbalanced square brackets in @def...}% + \global\brackcount=0 +} + + +\message{macros,} +% @macro. + +% To do this right we need a feature of e-TeX, \scantokens, +% which we arrange to emulate with a temporary file in ordinary TeX. +\ifx\eTeXversion\thisisundefined + \newwrite\macscribble + \def\scantokens#1{% + \toks0={#1}% + \immediate\openout\macscribble=\jobname.tmp + \immediate\write\macscribble{\the\toks0}% + \immediate\closeout\macscribble + \input \jobname.tmp + } +\fi + +% alias because \c means cedilla in @tex or @math +\let\texinfoc=\c + +\newcount\savedcatcodeone +\newcount\savedcatcodetwo + +% Used at the time of macro expansion. +% Argument is macro body with arguments substituted +\def\scanmacro#1{% + \newlinechar`\^^M + \def\xeatspaces{\eatspaces}% + % + % Temporarily undo catcode changes of \printindex. Set catcode of @ to + % 0 so that @-commands in macro expansions aren't printed literally when + % formatting an index file, where \ is used as the escape character. + \savedcatcodeone=\catcode`\@ + \savedcatcodetwo=\catcode`\\ + \catcode`\@=0 + \catcode`\\=\active + % + % Process the macro body under the current catcode regime. + \scantokens{#1@texinfoc}% + % + \catcode`\@=\savedcatcodeone + \catcode`\\=\savedcatcodetwo + % + % The \texinfoc is to remove the \newlinechar added by \scantokens, and + % can be noticed by \parsearg. + % We avoid surrounding the call to \scantokens with \bgroup and \egroup + % to allow macros to open or close groups themselves. +} + +% Used for copying and captions +\def\scanexp#1{% + \expandafter\scanmacro\expandafter{#1}% +} + +\newcount\paramno % Count of parameters +\newtoks\macname % Macro name +\newif\ifrecursive % Is it recursive? + +% List of all defined macros in the form +% \commondummyword\macro1\commondummyword\macro2... +% Currently is also contains all @aliases; the list can be split +% if there is a need. +\def\macrolist{} + +% Add the macro to \macrolist +\def\addtomacrolist#1{\expandafter \addtomacrolistxxx \csname#1\endcsname} +\def\addtomacrolistxxx#1{% + \toks0 = \expandafter{\macrolist\commondummyword#1}% + \xdef\macrolist{\the\toks0}% +} + +% Utility routines. +% This does \let #1 = #2, with \csnames; that is, +% \let \csname#1\endcsname = \csname#2\endcsname +% (except of course we have to play expansion games). +% +\def\cslet#1#2{% + \expandafter\let + \csname#1\expandafter\endcsname + \csname#2\endcsname +} + +% Trim leading and trailing spaces off a string. +% Concepts from aro-bend problem 15 (see CTAN). +{\catcode`\@=11 +\gdef\eatspaces #1{\expandafter\trim@\expandafter{#1 }} +\gdef\trim@ #1{\trim@@ @#1 @ #1 @ @@} +\gdef\trim@@ #1@ #2@ #3@@{\trim@@@\empty #2 @} +\def\unbrace#1{#1} +\unbrace{\gdef\trim@@@ #1 } #2@{#1} +} + +% Trim a single trailing ^^M off a string. +{\catcode`\^^M=\other \catcode`\Q=3% +\gdef\eatcr #1{\eatcra #1Q^^MQ}% +\gdef\eatcra#1^^MQ{\eatcrb#1Q}% +\gdef\eatcrb#1Q#2Q{#1}% +} + +% Macro bodies are absorbed as an argument in a context where +% all characters are catcode 10, 11 or 12, except \ which is active +% (as in normal texinfo). It is necessary to change the definition of \ +% to recognize macro arguments; this is the job of \mbodybackslash. +% +% Non-ASCII encodings make 8-bit characters active, so un-activate +% them to avoid their expansion. Must do this non-globally, to +% confine the change to the current group. +% +% It's necessary to have hard CRs when the macro is executed. This is +% done by making ^^M (\endlinechar) catcode 12 when reading the macro +% body, and then making it the \newlinechar in \scanmacro. +% +\def\scanctxt{% used as subroutine + \catcode`\"=\other + \catcode`\+=\other + \catcode`\<=\other + \catcode`\>=\other + \catcode`\^=\other + \catcode`\_=\other + \catcode`\|=\other + \catcode`\~=\other + \passthroughcharstrue +} + +\def\scanargctxt{% used for copying and captions, not macros. + \scanctxt + \catcode`\@=\other + \catcode`\\=\other + \catcode`\^^M=\other +} + +\def\macrobodyctxt{% used for @macro definitions + \scanctxt + \catcode`\ =\other + \catcode`\@=\other + \catcode`\{=\other + \catcode`\}=\other + \catcode`\^^M=\other + \usembodybackslash +} + +% Used when scanning braced macro arguments. Note, however, that catcode +% changes here are ineffectual if the macro invocation was nested inside +% an argument to another Texinfo command. +\def\macroargctxt{% + \scanctxt + \catcode`\ =\active + \catcode`\^^M=\other + \catcode`\\=\active +} + +\def\macrolineargctxt{% used for whole-line arguments without braces + \scanctxt + \catcode`\{=\other + \catcode`\}=\other +} + +% \mbodybackslash is the definition of \ in @macro bodies. +% It maps \foo\ => \csname macarg.foo\endcsname => #N +% where N is the macro parameter number. +% We define \csname macarg.\endcsname to be \realbackslash, so +% \\ in macro replacement text gets you a backslash. +% +{\catcode`@=0 @catcode`@\=@active + @gdef@usembodybackslash{@let\=@mbodybackslash} + @gdef@mbodybackslash#1\{@csname macarg.#1@endcsname} +} +\expandafter\def\csname macarg.\endcsname{\realbackslash} + +\def\margbackslash#1{\char`\#1 } + +\def\macro{\recursivefalse\parsearg\macroxxx} +\def\rmacro{\recursivetrue\parsearg\macroxxx} + +\def\macroxxx#1{% + \getargs{#1}% now \macname is the macname and \argl the arglist + \ifx\argl\empty % no arguments + \paramno=0\relax + \else + \expandafter\parsemargdef \argl;% + \if\paramno>256\relax + \ifx\eTeXversion\thisisundefined + \errhelp = \EMsimple + \errmessage{You need eTeX to compile a file with macros with more than 256 arguments} + \fi + \fi + \fi + \if1\csname ismacro.\the\macname\endcsname + \message{Warning: redefining \the\macname}% + \else + \expandafter\ifx\csname \the\macname\endcsname \relax + \else \errmessage{Macro name \the\macname\space already defined}\fi + \global\cslet{macsave.\the\macname}{\the\macname}% + \global\expandafter\let\csname ismacro.\the\macname\endcsname=1% + \addtomacrolist{\the\macname}% + \fi + \begingroup \macrobodyctxt + \ifrecursive \expandafter\parsermacbody + \else \expandafter\parsemacbody + \fi} + +\parseargdef\unmacro{% + \if1\csname ismacro.#1\endcsname + \global\cslet{#1}{macsave.#1}% + \global\expandafter\let \csname ismacro.#1\endcsname=0% + % Remove the macro name from \macrolist: + \begingroup + \expandafter\let\csname#1\endcsname \relax + \let\commondummyword\unmacrodo + \xdef\macrolist{\macrolist}% + \endgroup + \else + \errmessage{Macro #1 not defined}% + \fi +} + +% Called by \do from \dounmacro on each macro. The idea is to omit any +% macro definitions that have been changed to \relax. +% +\def\unmacrodo#1{% + \ifx #1\relax + % remove this + \else + \noexpand\commondummyword \noexpand#1% + \fi +} + +% \getargs -- Parse the arguments to a @macro line. Set \macname to +% the name of the macro, and \argl to the braced argument list. +\def\getargs#1{\getargsxxx#1{}} +\def\getargsxxx#1#{\getmacname #1 \relax\getmacargs} +\def\getmacname#1 #2\relax{\macname={#1}} +\def\getmacargs#1{\def\argl{#1}} +% This made use of the feature that if the last token of a +% <parameter list> is #, then the preceding argument is delimited by +% an opening brace, and that opening brace is not consumed. + +% Parse the optional {params} list to @macro or @rmacro. +% Set \paramno to the number of arguments, +% and \paramlist to a parameter text for the macro (e.g. #1,#2,#3 for a +% three-param macro.) Define \macarg.BLAH for each BLAH in the params +% list to some hook where the argument is to be expanded. If there are +% less than 10 arguments that hook is to be replaced by ##N where N +% is the position in that list, that is to say the macro arguments are to be +% defined `a la TeX in the macro body. +% +% That gets used by \mbodybackslash (above). +% +% If there are 10 or more arguments, a different technique is used: see +% \parsemmanyargdef. +% +\def\parsemargdef#1;{% + \paramno=0\def\paramlist{}% + \let\hash\relax + % \hash is redefined to `#' later to get it into definitions + \let\xeatspaces\relax + \parsemargdefxxx#1,;,% + \ifnum\paramno<10\relax\else + \paramno0\relax + \parsemmanyargdef@@#1,;,% 10 or more arguments + \fi +} +\def\parsemargdefxxx#1,{% + \if#1;\let\next=\relax + \else \let\next=\parsemargdefxxx + \advance\paramno by 1 + \expandafter\edef\csname macarg.\eatspaces{#1}\endcsname + {\xeatspaces{\hash\the\paramno}}% + \edef\paramlist{\paramlist\hash\the\paramno,}% + \fi\next} + +% \parsemacbody, \parsermacbody +% +% Read recursive and nonrecursive macro bodies. (They're different since +% rec and nonrec macros end differently.) +% +% We are in \macrobodyctxt, and the \xdef causes backslashshes in the macro +% body to be transformed. +% Set \macrobody to the body of the macro, and call \defmacro. +% +{\catcode`\ =\other\long\gdef\parsemacbody#1@end macro{% +\xdef\macrobody{\eatcr{#1}}\endgroup\defmacro}}% +{\catcode`\ =\other\long\gdef\parsermacbody#1@end rmacro{% +\xdef\macrobody{\eatcr{#1}}\endgroup\defmacro}}% + +% Make @ a letter, so that we can make private-to-Texinfo macro names. +\edef\texiatcatcode{\the\catcode`\@} +\catcode `@=11\relax + +%%%%%%%%%%%%%% Code for > 10 arguments only %%%%%%%%%%%%%%%%%% + +% If there are 10 or more arguments, a different technique is used, where the +% hook remains in the body, and when macro is to be expanded the body is +% processed again to replace the arguments. +% +% In that case, the hook is \the\toks N-1, and we simply set \toks N-1 to the +% argument N value and then \edef the body (nothing else will expand because of +% the catcode regime under which the body was input). +% +% If you compile with TeX (not eTeX), and you have macros with 10 or more +% arguments, no macro can have more than 256 arguments (else error). +% +% In case that there are 10 or more arguments we parse again the arguments +% list to set new definitions for the \macarg.BLAH macros corresponding to +% each BLAH argument. It was anyhow needed to parse already once this list +% in order to count the arguments, and as macros with at most 9 arguments +% are by far more frequent than macro with 10 or more arguments, defining +% twice the \macarg.BLAH macros does not cost too much processing power. +\def\parsemmanyargdef@@#1,{% + \if#1;\let\next=\relax + \else + \let\next=\parsemmanyargdef@@ + \edef\tempb{\eatspaces{#1}}% + \expandafter\def\expandafter\tempa + \expandafter{\csname macarg.\tempb\endcsname}% + % Note that we need some extra \noexpand\noexpand, this is because we + % don't want \the to be expanded in the \parsermacbody as it uses an + % \xdef . + \expandafter\edef\tempa + {\noexpand\noexpand\noexpand\the\toks\the\paramno}% + \advance\paramno by 1\relax + \fi\next} + + +\let\endargs@\relax +\let\nil@\relax +\def\nilm@{\nil@}% +\long\def\nillm@{\nil@}% + +% This macro is expanded during the Texinfo macro expansion, not during its +% definition. It gets all the arguments' values and assigns them to macros +% macarg.ARGNAME +% +% #1 is the macro name +% #2 is the list of argument names +% #3 is the list of argument values +\def\getargvals@#1#2#3{% + \def\macargdeflist@{}% + \def\saveparamlist@{#2}% Need to keep a copy for parameter expansion. + \def\paramlist{#2,\nil@}% + \def\macroname{#1}% + \begingroup + \macroargctxt + \def\argvaluelist{#3,\nil@}% + \def\@tempa{#3}% + \ifx\@tempa\empty + \setemptyargvalues@ + \else + \getargvals@@ + \fi +} +\def\getargvals@@{% + \ifx\paramlist\nilm@ + % Some sanity check needed here that \argvaluelist is also empty. + \ifx\argvaluelist\nillm@ + \else + \errhelp = \EMsimple + \errmessage{Too many arguments in macro `\macroname'!}% + \fi + \let\next\macargexpandinbody@ + \else + \ifx\argvaluelist\nillm@ + % No more arguments values passed to macro. Set remaining named-arg + % macros to empty. + \let\next\setemptyargvalues@ + \else + % pop current arg name into \@tempb + \def\@tempa##1{\pop@{\@tempb}{\paramlist}##1\endargs@}% + \expandafter\@tempa\expandafter{\paramlist}% + % pop current argument value into \@tempc + \def\@tempa##1{\longpop@{\@tempc}{\argvaluelist}##1\endargs@}% + \expandafter\@tempa\expandafter{\argvaluelist}% + % Here \@tempb is the current arg name and \@tempc is the current arg value. + % First place the new argument macro definition into \@tempd + \expandafter\macname\expandafter{\@tempc}% + \expandafter\let\csname macarg.\@tempb\endcsname\relax + \expandafter\def\expandafter\@tempe\expandafter{% + \csname macarg.\@tempb\endcsname}% + \edef\@tempd{\long\def\@tempe{\the\macname}}% + \push@\@tempd\macargdeflist@ + \let\next\getargvals@@ + \fi + \fi + \next +} + +\def\push@#1#2{% + \expandafter\expandafter\expandafter\def + \expandafter\expandafter\expandafter#2% + \expandafter\expandafter\expandafter{% + \expandafter#1#2}% +} + +% Replace arguments by their values in the macro body, and place the result +% in macro \@tempa. +% +\def\macvalstoargs@{% + % To do this we use the property that token registers that are \the'ed + % within an \edef expand only once. So we are going to place all argument + % values into respective token registers. + % + % First we save the token context, and initialize argument numbering. + \begingroup + \paramno0\relax + % Then, for each argument number #N, we place the corresponding argument + % value into a new token list register \toks#N + \expandafter\putargsintokens@\saveparamlist@,;,% + % Then, we expand the body so that argument are replaced by their + % values. The trick for values not to be expanded themselves is that they + % are within tokens and that tokens expand only once in an \edef . + \edef\@tempc{\csname mac.\macroname .body\endcsname}% + % Now we restore the token stack pointer to free the token list registers + % which we have used, but we make sure that expanded body is saved after + % group. + \expandafter + \endgroup + \expandafter\def\expandafter\@tempa\expandafter{\@tempc}% + } + +% Define the named-macro outside of this group and then close this group. +% +\def\macargexpandinbody@{% + \expandafter + \endgroup + \macargdeflist@ + % First the replace in body the macro arguments by their values, the result + % is in \@tempa . + \macvalstoargs@ + % Then we point at the \norecurse or \gobble (for recursive) macro value + % with \@tempb . + \expandafter\let\expandafter\@tempb\csname mac.\macroname .recurse\endcsname + % Depending on whether it is recursive or not, we need some tailing + % \egroup . + \ifx\@tempb\gobble + \let\@tempc\relax + \else + \let\@tempc\egroup + \fi + % And now we do the real job: + \edef\@tempd{\noexpand\@tempb{\macroname}\noexpand\scanmacro{\@tempa}\@tempc}% + \@tempd +} + +\def\putargsintokens@#1,{% + \if#1;\let\next\relax + \else + \let\next\putargsintokens@ + % First we allocate the new token list register, and give it a temporary + % alias \@tempb . + \toksdef\@tempb\the\paramno + % Then we place the argument value into that token list register. + \expandafter\let\expandafter\@tempa\csname macarg.#1\endcsname + \expandafter\@tempb\expandafter{\@tempa}% + \advance\paramno by 1\relax + \fi + \next +} + +% Trailing missing arguments are set to empty. +% +\def\setemptyargvalues@{% + \ifx\paramlist\nilm@ + \let\next\macargexpandinbody@ + \else + \expandafter\setemptyargvaluesparser@\paramlist\endargs@ + \let\next\setemptyargvalues@ + \fi + \next +} + +\def\setemptyargvaluesparser@#1,#2\endargs@{% + \expandafter\def\expandafter\@tempa\expandafter{% + \expandafter\def\csname macarg.#1\endcsname{}}% + \push@\@tempa\macargdeflist@ + \def\paramlist{#2}% +} + +% #1 is the element target macro +% #2 is the list macro +% #3,#4\endargs@ is the list value +\def\pop@#1#2#3,#4\endargs@{% + \def#1{#3}% + \def#2{#4}% +} +\long\def\longpop@#1#2#3,#4\endargs@{% + \long\def#1{#3}% + \long\def#2{#4}% +} + + +%%%%%%%%%%%%%% End of code for > 10 arguments %%%%%%%%%%%%%%%%%% + + +% This defines a Texinfo @macro or @rmacro, called by \parsemacbody. +% \macrobody has the body of the macro in it, with placeholders for +% its parameters, looking like "\xeatspaces{\hash 1}". +% \paramno is the number of parameters +% \paramlist is a TeX parameter text, e.g. "#1,#2,#3," +% There are four cases: macros of zero, one, up to nine, and many arguments. +% \xdef is used so that macro definitions will survive the file +% they're defined in: @include reads the file inside a group. +% +\def\defmacro{% + \let\hash=##% convert placeholders to macro parameter chars + \ifnum\paramno=1 + \def\xeatspaces##1{##1}% + % This removes the pair of braces around the argument. We don't + % use \eatspaces, because this can cause ends of lines to be lost + % when the argument to \eatspaces is read, leading to line-based + % commands like "@itemize" not being read correctly. + \else + \let\xeatspaces\relax % suppress expansion + \fi + \ifcase\paramno + % 0 + \expandafter\xdef\csname\the\macname\endcsname{% + \bgroup + \noexpand\spaceisspace + \noexpand\endlineisspace + \noexpand\expandafter % skip any whitespace after the macro name. + \expandafter\noexpand\csname\the\macname @@@\endcsname}% + \expandafter\xdef\csname\the\macname @@@\endcsname{% + \egroup + \noexpand\scanmacro{\macrobody}}% + \or % 1 + \expandafter\xdef\csname\the\macname\endcsname{% + \bgroup + \noexpand\braceorline + \expandafter\noexpand\csname\the\macname @@@\endcsname}% + \expandafter\xdef\csname\the\macname @@@\endcsname##1{% + \egroup + \noexpand\scanmacro{\macrobody}% + }% + \else % at most 9 + \ifnum\paramno<10\relax + % @MACNAME sets the context for reading the macro argument + % @MACNAME@@ gets the argument, processes backslashes and appends a + % comma. + % @MACNAME@@@ removes braces surrounding the argument list. + % @MACNAME@@@@ scans the macro body with arguments substituted. + \expandafter\xdef\csname\the\macname\endcsname{% + \bgroup + \noexpand\expandafter % This \expandafter skip any spaces after the + \noexpand\macroargctxt % macro before we change the catcode of space. + \noexpand\expandafter + \expandafter\noexpand\csname\the\macname @@\endcsname}% + \expandafter\xdef\csname\the\macname @@\endcsname##1{% + \noexpand\passargtomacro + \expandafter\noexpand\csname\the\macname @@@\endcsname{##1,}}% + \expandafter\xdef\csname\the\macname @@@\endcsname##1{% + \expandafter\noexpand\csname\the\macname @@@@\endcsname ##1}% + \expandafter\expandafter + \expandafter\xdef + \expandafter\expandafter + \csname\the\macname @@@@\endcsname\paramlist{% + \egroup\noexpand\scanmacro{\macrobody}}% + \else % 10 or more: + \expandafter\xdef\csname\the\macname\endcsname{% + \noexpand\getargvals@{\the\macname}{\argl}% + }% + \global\expandafter\let\csname mac.\the\macname .body\endcsname\macrobody + \global\expandafter\let\csname mac.\the\macname .recurse\endcsname\gobble + \fi + \fi} + +\catcode `\@\texiatcatcode\relax % end private-to-Texinfo catcodes + +\def\norecurse#1{\bgroup\cslet{#1}{macsave.#1}} + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +{\catcode`\@=0 \catcode`\\=13 % We need to manipulate \ so use @ as escape +@catcode`@_=11 % private names +@catcode`@!=11 % used as argument separator + +% \passargtomacro#1#2 - +% Call #1 with a list of tokens #2, with any doubled backslashes in #2 +% compressed to one. +% +% This implementation works by expansion, and not execution (so we cannot use +% \def or similar). This reduces the risk of this failing in contexts where +% complete expansion is done with no execution (for example, in writing out to +% an auxiliary file for an index entry). +% +% State is kept in the input stream: the argument passed to +% @look_ahead, @gobble_and_check_finish and @add_segment is +% +% THE_MACRO ARG_RESULT ! {PENDING_BS} NEXT_TOKEN (... rest of input) +% +% where: +% THE_MACRO - name of the macro we want to call +% ARG_RESULT - argument list we build to pass to that macro +% PENDING_BS - either a backslash or nothing +% NEXT_TOKEN - used to look ahead in the input stream to see what's coming next + +@gdef@passargtomacro#1#2{% + @add_segment #1!{}@relax#2\@_finish\% +} +@gdef@_finish{@_finishx} @global@let@_finishx@relax + +% #1 - THE_MACRO ARG_RESULT +% #2 - PENDING_BS +% #3 - NEXT_TOKEN +% #4 used to look ahead +% +% If the next token is not a backslash, process the rest of the argument; +% otherwise, remove the next token. +@gdef@look_ahead#1!#2#3#4{% + @ifx#4\% + @expandafter@gobble_and_check_finish + @else + @expandafter@add_segment + @fi#1!{#2}#4#4% +} + +% #1 - THE_MACRO ARG_RESULT +% #2 - PENDING_BS +% #3 - NEXT_TOKEN +% #4 should be a backslash, which is gobbled. +% #5 looks ahead +% +% Double backslash found. Add a single backslash, and look ahead. +@gdef@gobble_and_check_finish#1!#2#3#4#5{% + @add_segment#1\!{}#5#5% +} + +@gdef@is_fi{@fi} + +% #1 - THE_MACRO ARG_RESULT +% #2 - PENDING_BS +% #3 - NEXT_TOKEN +% #4 is input stream until next backslash +% +% Input stream is either at the start of the argument, or just after a +% backslash sequence, either a lone backslash, or a doubled backslash. +% NEXT_TOKEN contains the first token in the input stream: if it is \finish, +% finish; otherwise, append to ARG_RESULT the segment of the argument up until +% the next backslash. PENDING_BACKSLASH contains a backslash to represent +% a backslash just before the start of the input stream that has not been +% added to ARG_RESULT. +@gdef@add_segment#1!#2#3#4\{% +@ifx#3@_finish + @call_the_macro#1!% +@else + % append the pending backslash to the result, followed by the next segment + @expandafter@is_fi@look_ahead#1#2#4!{\}@fi + % this @fi is discarded by @look_ahead. + % we can't get rid of it with \expandafter because we don't know how + % long #4 is. +} + +% #1 - THE_MACRO +% #2 - ARG_RESULT +% #3 discards the res of the conditional in @add_segment, and @is_fi ends the +% conditional. +@gdef@call_the_macro#1#2!#3@fi{@is_fi #1{#2}} + +} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% \braceorline MAC is used for a one-argument macro MAC. It checks +% whether the next non-whitespace character is a {. It sets the context +% for reading the argument (slightly different in the two cases). Then, +% to read the argument, in the whole-line case, it then calls the regular +% \parsearg MAC; in the lbrace case, it calls \passargtomacro MAC. +% +\def\braceorline#1{\let\macnamexxx=#1\futurelet\nchar\braceorlinexxx} +\def\braceorlinexxx{% + \ifx\nchar\bgroup + \macroargctxt + \expandafter\passargtomacro + \else + \macrolineargctxt\expandafter\parsearg + \fi \macnamexxx} + + +% @alias. +% We need some trickery to remove the optional spaces around the equal +% sign. Make them active and then expand them all to nothing. +% +\def\alias{\parseargusing\obeyspaces\aliasxxx} +\def\aliasxxx #1{\aliasyyy#1\relax} +\def\aliasyyy #1=#2\relax{% + {% + \expandafter\let\obeyedspace=\empty + \addtomacrolist{#1}% + \xdef\next{\global\let\makecsname{#1}=\makecsname{#2}}% + }% + \next +} + + +\message{cross references,} + +\newwrite\auxfile +\newif\ifhavexrefs % True if xref values are known. +\newif\ifwarnedxrefs % True if we warned once that they aren't known. + +% @inforef is relatively simple. +\def\inforef #1{\inforefzzz #1,,,,**} +\def\inforefzzz #1,#2,#3,#4**{% + \putwordSee{} \putwordInfo{} \putwordfile{} \file{\ignorespaces #3{}}, + node \samp{\ignorespaces#1{}}} + +% @node's only job in TeX is to define \lastnode, which is used in +% cross-references. The @node line might or might not have commas, and +% might or might not have spaces before the first comma, like: +% @node foo , bar , ... +% We don't want such trailing spaces in the node name. +% +\parseargdef\node{\checkenv{}\donode #1 ,\finishnodeparse} +% +% also remove a trailing comma, in case of something like this: +% @node Help-Cross, , , Cross-refs +\def\donode#1 ,#2\finishnodeparse{\dodonode #1,\finishnodeparse} +\def\dodonode#1,#2\finishnodeparse{\gdef\lastnode{#1}} + +\let\nwnode=\node +\let\lastnode=\empty + +% Write a cross-reference definition for the current node. #1 is the +% type (Ynumbered, Yappendix, Ynothing). +% +\def\donoderef#1{% + \ifx\lastnode\empty\else + \setref{\lastnode}{#1}% + \global\let\lastnode=\empty + \fi +} + +% @anchor{NAME} -- define xref target at arbitrary point. +% +\newcount\savesfregister +% +\def\savesf{\relax \ifhmode \savesfregister=\spacefactor \fi} +\def\restoresf{\relax \ifhmode \spacefactor=\savesfregister \fi} +\def\anchor#1{\savesf \setref{#1}{Ynothing}\restoresf \ignorespaces} + +% \setref{NAME}{SNT} defines a cross-reference point NAME (a node or an +% anchor), which consists of three parts: +% 1) NAME-title - the current sectioning name taken from \lastsection, +% or the anchor name. +% 2) NAME-snt - section number and type, passed as the SNT arg, or +% empty for anchors. +% 3) NAME-pg - the page number. +% +% This is called from \donoderef, \anchor, and \dofloat. In the case of +% floats, there is an additional part, which is not written here: +% 4) NAME-lof - the text as it should appear in a @listoffloats. +% +\def\setref#1#2{% + \pdfmkdest{#1}% + \iflinks + {% + \requireauxfile + \atdummies % preserve commands, but don't expand them + % match definition in \xrdef, \refx, \xrefX. + \def\value##1{##1}% + \edef\writexrdef##1##2{% + \write\auxfile{@xrdef{#1-% #1 of \setref, expanded by the \edef + ##1}{##2}}% these are parameters of \writexrdef + }% + \toks0 = \expandafter{\lastsection}% + \immediate \writexrdef{title}{\the\toks0 }% + \immediate \writexrdef{snt}{\csname #2\endcsname}% \Ynumbered etc. + \safewhatsit{\writexrdef{pg}{\folio}}% will be written later, at \shipout + }% + \fi +} + +% @xrefautosectiontitle on|off says whether @section(ing) names are used +% automatically in xrefs, if the third arg is not explicitly specified. +% This was provided as a "secret" @set xref-automatic-section-title +% variable, now it's official. +% +\parseargdef\xrefautomaticsectiontitle{% + \def\temp{#1}% + \ifx\temp\onword + \expandafter\let\csname SETxref-automatic-section-title\endcsname + = \empty + \else\ifx\temp\offword + \expandafter\let\csname SETxref-automatic-section-title\endcsname + = \relax + \else + \errhelp = \EMsimple + \errmessage{Unknown @xrefautomaticsectiontitle value `\temp', + must be on|off}% + \fi\fi +} + +% +% @xref, @pxref, and @ref generate cross-references. For \xrefX, #1 is +% the node name, #2 the name of the Info cross-reference, #3 the printed +% node name, #4 the name of the Info file, #5 the name of the printed +% manual. All but the node name can be omitted. +% +\def\pxref{\putwordsee{} \xrefXX} +\def\xref{\putwordSee{} \xrefXX} +\def\ref{\xrefXX} + +\def\xrefXX#1{\def\xrefXXarg{#1}\futurelet\tokenafterxref\xrefXXX} +\def\xrefXXX{\expandafter\xrefX\expandafter[\xrefXXarg,,,,,,,]} +% +\newbox\toprefbox +\newbox\printedrefnamebox +\newbox\infofilenamebox +\newbox\printedmanualbox +% +\def\xrefX[#1,#2,#3,#4,#5,#6]{\begingroup + \unsepspaces + % + % Get args without leading/trailing spaces. + \def\printedrefname{\ignorespaces #3}% + \setbox\printedrefnamebox = \hbox{\printedrefname\unskip}% + % + \def\infofilename{\ignorespaces #4}% + \setbox\infofilenamebox = \hbox{\infofilename\unskip}% + % + \def\printedmanual{\ignorespaces #5}% + \setbox\printedmanualbox = \hbox{\printedmanual\unskip}% + % + % If the printed reference name (arg #3) was not explicitly given in + % the @xref, figure out what we want to use. + \ifdim \wd\printedrefnamebox = 0pt + % No printed node name was explicitly given. + \expandafter\ifx\csname SETxref-automatic-section-title\endcsname \relax + % Not auto section-title: use node name inside the square brackets. + \def\printedrefname{\ignorespaces #1}% + \else + % Auto section-title: use chapter/section title inside + % the square brackets if we have it. + \ifdim \wd\printedmanualbox > 0pt + % It is in another manual, so we don't have it; use node name. + \def\printedrefname{\ignorespaces #1}% + \else + \ifhavexrefs + % We (should) know the real title if we have the xref values. + \def\printedrefname{\refx{#1-title}{}}% + \else + % Otherwise just copy the Info node name. + \def\printedrefname{\ignorespaces #1}% + \fi% + \fi + \fi + \fi + % + % Make link in pdf output. + \ifpdf + % For pdfTeX and LuaTeX + {\indexnofonts + \makevalueexpandable + \turnoffactive + % This expands tokens, so do it after making catcode changes, so _ + % etc. don't get their TeX definitions. This ignores all spaces in + % #4, including (wrongly) those in the middle of the filename. + \getfilename{#4}% + % + % This (wrongly) does not take account of leading or trailing + % spaces in #1, which should be ignored. + \setpdfdestname{#1}% + % + \ifx\pdfdestname\empty + \def\pdfdestname{Top}% no empty targets + \fi + % + \leavevmode + \startlink attr{/Border [0 0 0]}% + \ifnum\filenamelength>0 + goto file{\the\filename.pdf} name{\pdfdestname}% + \else + goto name{\pdfmkpgn{\pdfdestname}}% + \fi + }% + \setcolor{\linkcolor}% + \else + \ifx\XeTeXrevision\thisisundefined + \else + % For XeTeX + {\indexnofonts + \makevalueexpandable + \turnoffactive + % This expands tokens, so do it after making catcode changes, so _ + % etc. don't get their TeX definitions. This ignores all spaces in + % #4, including (wrongly) those in the middle of the filename. + \getfilename{#4}% + % + % This (wrongly) does not take account of leading or trailing + % spaces in #1, which should be ignored. + \setpdfdestname{#1}% + % + \ifx\pdfdestname\empty + \def\pdfdestname{Top}% no empty targets + \fi + % + \leavevmode + \ifnum\filenamelength>0 + % With default settings, + % XeTeX (xdvipdfmx) replaces link destination names with integers. + % In this case, the replaced destination names of + % remote PDFs are no longer known. In order to avoid a replacement, + % you can use xdvipdfmx's command line option `-C 0x0010'. + % If you use XeTeX 0.99996+ (TeX Live 2016+), + % this command line option is no longer necessary + % because we can use the `dvipdfmx:config' special. + \special{pdf:bann << /Border [0 0 0] /Type /Annot /Subtype /Link /A + << /S /GoToR /F (\the\filename.pdf) /D (\pdfdestname) >> >>}% + \else + \special{pdf:bann << /Border [0 0 0] /Type /Annot /Subtype /Link /A + << /S /GoTo /D (\pdfdestname) >> >>}% + \fi + }% + \setcolor{\linkcolor}% + \fi + \fi + {% + % Have to otherify everything special to allow the \csname to + % include an _ in the xref name, etc. + \indexnofonts + \turnoffactive + \def\value##1{##1}% + \expandafter\global\expandafter\let\expandafter\Xthisreftitle + \csname XR#1-title\endcsname + }% + % + % Float references are printed completely differently: "Figure 1.2" + % instead of "[somenode], p.3". \iffloat distinguishes them by + % \Xthisreftitle being set to a magic string. + \iffloat\Xthisreftitle + % If the user specified the print name (third arg) to the ref, + % print it instead of our usual "Figure 1.2". + \ifdim\wd\printedrefnamebox = 0pt + \refx{#1-snt}{}% + \else + \printedrefname + \fi + % + % If the user also gave the printed manual name (fifth arg), append + % "in MANUALNAME". + \ifdim \wd\printedmanualbox > 0pt + \space \putwordin{} \cite{\printedmanual}% + \fi + \else + % node/anchor (non-float) references. + % + % If we use \unhbox to print the node names, TeX does not insert + % empty discretionaries after hyphens, which means that it will not + % find a line break at a hyphen in a node names. Since some manuals + % are best written with fairly long node names, containing hyphens, + % this is a loss. Therefore, we give the text of the node name + % again, so it is as if TeX is seeing it for the first time. + % + \ifdim \wd\printedmanualbox > 0pt + % Cross-manual reference with a printed manual name. + % + \crossmanualxref{\cite{\printedmanual\unskip}}% + % + \else\ifdim \wd\infofilenamebox > 0pt + % Cross-manual reference with only an info filename (arg 4), no + % printed manual name (arg 5). This is essentially the same as + % the case above; we output the filename, since we have nothing else. + % + \crossmanualxref{\code{\infofilename\unskip}}% + % + \else + % Reference within this manual. + % + % _ (for example) has to be the character _ for the purposes of the + % control sequence corresponding to the node, but it has to expand + % into the usual \leavevmode...\vrule stuff for purposes of + % printing. So we \turnoffactive for the \refx-snt, back on for the + % printing, back off for the \refx-pg. + {\turnoffactive + % Only output a following space if the -snt ref is nonempty; for + % @unnumbered and @anchor, it won't be. + \setbox2 = \hbox{\ignorespaces \refx{#1-snt}{}}% + \ifdim \wd2 > 0pt \refx{#1-snt}\space\fi + }% + % output the `[mynode]' via the macro below so it can be overridden. + \xrefprintnodename\printedrefname + % + % But we always want a comma and a space: + ,\space + % + % output the `page 3'. + \turnoffactive \putwordpage\tie\refx{#1-pg}{}% + % Add a , if xref followed by a space + \if\space\noexpand\tokenafterxref ,% + \else\ifx\ \tokenafterxref ,% @TAB + \else\ifx\*\tokenafterxref ,% @* + \else\ifx\ \tokenafterxref ,% @SPACE + \else\ifx\ + \tokenafterxref ,% @NL + \else\ifx\tie\tokenafterxref ,% @tie + \fi\fi\fi\fi\fi\fi + \fi\fi + \fi + \endlink +\endgroup} + +% Output a cross-manual xref to #1. Used just above (twice). +% +% Only include the text "Section ``foo'' in" if the foo is neither +% missing or Top. Thus, @xref{,,,foo,The Foo Manual} outputs simply +% "see The Foo Manual", the idea being to refer to the whole manual. +% +% But, this being TeX, we can't easily compare our node name against the +% string "Top" while ignoring the possible spaces before and after in +% the input. By adding the arbitrary 7sp below, we make it much less +% likely that a real node name would have the same width as "Top" (e.g., +% in a monospaced font). Hopefully it will never happen in practice. +% +% For the same basic reason, we retypeset the "Top" at every +% reference, since the current font is indeterminate. +% +\def\crossmanualxref#1{% + \setbox\toprefbox = \hbox{Top\kern7sp}% + \setbox2 = \hbox{\ignorespaces \printedrefname \unskip \kern7sp}% + \ifdim \wd2 > 7sp % nonempty? + \ifdim \wd2 = \wd\toprefbox \else % same as Top? + \putwordSection{} ``\printedrefname'' \putwordin{}\space + \fi + \fi + #1% +} + +% This macro is called from \xrefX for the `[nodename]' part of xref +% output. It's a separate macro only so it can be changed more easily, +% since square brackets don't work well in some documents. Particularly +% one that Bob is working on :). +% +\def\xrefprintnodename#1{[#1]} + +% Things referred to by \setref. +% +\def\Ynothing{} +\def\Yomitfromtoc{} +\def\Ynumbered{% + \ifnum\secno=0 + \putwordChapter@tie \the\chapno + \else \ifnum\subsecno=0 + \putwordSection@tie \the\chapno.\the\secno + \else \ifnum\subsubsecno=0 + \putwordSection@tie \the\chapno.\the\secno.\the\subsecno + \else + \putwordSection@tie \the\chapno.\the\secno.\the\subsecno.\the\subsubsecno + \fi\fi\fi +} +\def\Yappendix{% + \ifnum\secno=0 + \putwordAppendix@tie @char\the\appendixno{}% + \else \ifnum\subsecno=0 + \putwordSection@tie @char\the\appendixno.\the\secno + \else \ifnum\subsubsecno=0 + \putwordSection@tie @char\the\appendixno.\the\secno.\the\subsecno + \else + \putwordSection@tie + @char\the\appendixno.\the\secno.\the\subsecno.\the\subsubsecno + \fi\fi\fi +} + +% \refx{NAME}{SUFFIX} - reference a cross-reference string named NAME. SUFFIX +% is output afterwards if non-empty. +\def\refx#1#2{% + \requireauxfile + {% + \indexnofonts + \otherbackslash + \def\value##1{##1}% + \expandafter\global\expandafter\let\expandafter\thisrefX + \csname XR#1\endcsname + }% + \ifx\thisrefX\relax + % If not defined, say something at least. + \angleleft un\-de\-fined\angleright + \iflinks + \ifhavexrefs + {\toks0 = {#1}% avoid expansion of possibly-complex value + \message{\linenumber Undefined cross reference `\the\toks0'.}}% + \else + \ifwarnedxrefs\else + \global\warnedxrefstrue + \message{Cross reference values unknown; you must run TeX again.}% + \fi + \fi + \fi + \else + % It's defined, so just use it. + \thisrefX + \fi + #2% Output the suffix in any case. +} + +% This is the macro invoked by entries in the aux file. Define a control +% sequence for a cross-reference target (we prepend XR to the control sequence +% name to avoid collisions). The value is the page number. If this is a float +% type, we have more work to do. +% +\def\xrdef#1#2{% + {% Expand the node or anchor name to remove control sequences. + % \turnoffactive stops 8-bit characters being changed to commands + % like @'e. \refx does the same to retrieve the value in the definition. + \indexnofonts + \turnoffactive + \def\value##1{##1}% + \xdef\safexrefname{#1}% + }% + % + \bgroup + \expandafter\gdef\csname XR\safexrefname\endcsname{#2}% + \egroup + % We put the \gdef inside a group to avoid the definitions building up on + % TeX's save stack, which can cause it to run out of space for aux files with + % thousands of lines. \gdef doesn't use the save stack, but \csname does + % when it defines an unknown control sequence as \relax. + % + % Was that xref control sequence that we just defined for a float? + \expandafter\iffloat\csname XR\safexrefname\endcsname + % it was a float, and we have the (safe) float type in \iffloattype. + \expandafter\let\expandafter\floatlist + \csname floatlist\iffloattype\endcsname + % + % Is this the first time we've seen this float type? + \expandafter\ifx\floatlist\relax + \toks0 = {\do}% yes, so just \do + \else + % had it before, so preserve previous elements in list. + \toks0 = \expandafter{\floatlist\do}% + \fi + % + % Remember this xref in the control sequence \floatlistFLOATTYPE, + % for later use in \listoffloats. + \expandafter\xdef\csname floatlist\iffloattype\endcsname{\the\toks0 + {\safexrefname}}% + \fi +} + +% If working on a large document in chapters, it is convenient to +% be able to disable indexing, cross-referencing, and contents, for test runs. +% This is done with @novalidate at the beginning of the file. +% +\newif\iflinks \linkstrue % by default we want the aux files. +\let\novalidate = \linksfalse + +% Used when writing to the aux file, or when using data from it. +\def\requireauxfile{% + \iflinks + \tryauxfile + % Open the new aux file. TeX will close it automatically at exit. + \immediate\openout\auxfile=\jobname.aux + \fi + \global\let\requireauxfile=\relax % Only do this once. +} + +% Read the last existing aux file, if any. No error if none exists. +% +\def\tryauxfile{% + \openin 1 \jobname.aux + \ifeof 1 \else + \readdatafile{aux}% + \global\havexrefstrue + \fi + \closein 1 +} + +\def\setupdatafile{% + \catcode`\^^@=\other + \catcode`\^^A=\other + \catcode`\^^B=\other + \catcode`\^^C=\other + \catcode`\^^D=\other + \catcode`\^^E=\other + \catcode`\^^F=\other + \catcode`\^^G=\other + \catcode`\^^H=\other + \catcode`\^^K=\other + \catcode`\^^L=\other + \catcode`\^^N=\other + \catcode`\^^P=\other + \catcode`\^^Q=\other + \catcode`\^^R=\other + \catcode`\^^S=\other + \catcode`\^^T=\other + \catcode`\^^U=\other + \catcode`\^^V=\other + \catcode`\^^W=\other + \catcode`\^^X=\other + \catcode`\^^Z=\other + \catcode`\^^[=\other + \catcode`\^^\=\other + \catcode`\^^]=\other + \catcode`\^^^=\other + \catcode`\^^_=\other + % It was suggested to set the catcode of ^ to 7, which would allow ^^e4 etc. + % in xref tags, i.e., node names. But since ^^e4 notation isn't + % supported in the main text, it doesn't seem desirable. Furthermore, + % that is not enough: for node names that actually contain a ^ + % character, we would end up writing a line like this: 'xrdef {'hat + % b-title}{'hat b} and \xrdef does a \csname...\endcsname on the first + % argument, and \hat is not an expandable control sequence. It could + % all be worked out, but why? Either we support ^^ or we don't. + % + % The other change necessary for this was to define \auxhat: + % \def\auxhat{\def^{'hat }}% extra space so ok if followed by letter + % and then to call \auxhat in \setq. + % + \catcode`\^=\other + % + % Special characters. Should be turned off anyway, but... + \catcode`\~=\other + \catcode`\[=\other + \catcode`\]=\other + \catcode`\"=\other + \catcode`\_=\other + \catcode`\|=\other + \catcode`\<=\other + \catcode`\>=\other + \catcode`\$=\other + \catcode`\#=\other + \catcode`\&=\other + \catcode`\%=\other + \catcode`+=\other % avoid \+ for paranoia even though we've turned it off + % + % This is to support \ in node names and titles, since the \ + % characters end up in a \csname. It's easier than + % leaving it active and making its active definition an actual \ + % character. What I don't understand is why it works in the *value* + % of the xrdef. Seems like it should be a catcode12 \, and that + % should not typeset properly. But it works, so I'm moving on for + % now. --karl, 15jan04. + \catcode`\\=\other + % + % @ is our escape character in .aux files, and we need braces. + \catcode`\{=1 + \catcode`\}=2 + \catcode`\@=0 +} + +\def\readdatafile#1{% +\begingroup + \setupdatafile + \input\jobname.#1 +\endgroup} + + +\message{insertions,} +% including footnotes. + +\newcount \footnoteno + +% The trailing space in the following definition for supereject is +% vital for proper filling; pages come out unaligned when you do a +% pagealignmacro call if that space before the closing brace is +% removed. (Generally, numeric constants should always be followed by a +% space to prevent strange expansion errors.) +\def\supereject{\par\penalty -20000\footnoteno =0 } + +% @footnotestyle is meaningful for Info output only. +\let\footnotestyle=\comment + +{\catcode `\@=11 +% +% Auto-number footnotes. Otherwise like plain. +\gdef\footnote{% + \global\advance\footnoteno by \@ne + \edef\thisfootno{$^{\the\footnoteno}$}% + % + % In case the footnote comes at the end of a sentence, preserve the + % extra spacing after we do the footnote number. + \let\@sf\empty + \ifhmode\edef\@sf{\spacefactor\the\spacefactor}\ptexslash\fi + % + % Remove inadvertent blank space before typesetting the footnote number. + \unskip + \thisfootno\@sf + \dofootnote +}% + +% Don't bother with the trickery in plain.tex to not require the +% footnote text as a parameter. Our footnotes don't need to be so general. +% +% Oh yes, they do; otherwise, @ifset (and anything else that uses +% \parseargline) fails inside footnotes because the tokens are fixed when +% the footnote is read. --karl, 16nov96. +% +\gdef\dofootnote{% + \insert\footins\bgroup + % + % Nested footnotes are not supported in TeX, that would take a lot + % more work. (\startsavinginserts does not suffice.) + \let\footnote=\errfootnotenest + % + % We want to typeset this text as a normal paragraph, even if the + % footnote reference occurs in (for example) a display environment. + % So reset some parameters. + \hsize=\txipagewidth + \interlinepenalty\interfootnotelinepenalty + \splittopskip\ht\strutbox % top baseline for broken footnotes + \splitmaxdepth\dp\strutbox + \floatingpenalty\@MM + \leftskip\z@skip + \rightskip\z@skip + \spaceskip\z@skip + \xspaceskip\z@skip + \parindent\defaultparindent + % + \smallfonts \rm + % + % Because we use hanging indentation in footnotes, a @noindent appears + % to exdent this text, so make it be a no-op. makeinfo does not use + % hanging indentation so @noindent can still be needed within footnote + % text after an @example or the like (not that this is good style). + \let\noindent = \relax + % + % Hang the footnote text off the number. Use \everypar in case the + % footnote extends for more than one paragraph. + \everypar = {\hang}% + \textindent{\thisfootno}% + % + % Don't crash into the line above the footnote text. Since this + % expands into a box, it must come within the paragraph, lest it + % provide a place where TeX can split the footnote. + \footstrut + % + % Invoke rest of plain TeX footnote routine. + \futurelet\next\fo@t +} +}%end \catcode `\@=11 + +\def\errfootnotenest{% + \errhelp=\EMsimple + \errmessage{Nested footnotes not supported in texinfo.tex, + even though they work in makeinfo; sorry} +} + +\def\errfootnoteheading{% + \errhelp=\EMsimple + \errmessage{Footnotes in chapters, sections, etc., are not supported} +} + +% In case a @footnote appears in a vbox, save the footnote text and create +% the real \insert just after the vbox finished. Otherwise, the insertion +% would be lost. +% Similarly, if a @footnote appears inside an alignment, save the footnote +% text to a box and make the \insert when a row of the table is finished. +% And the same can be done for other insert classes. --kasal, 16nov03. +% +% Replace the \insert primitive by a cheating macro. +% Deeper inside, just make sure that the saved insertions are not spilled +% out prematurely. +% +\def\startsavinginserts{% + \ifx \insert\ptexinsert + \let\insert\saveinsert + \else + \let\checkinserts\relax + \fi +} + +% This \insert replacement works for both \insert\footins{foo} and +% \insert\footins\bgroup foo\egroup, but it doesn't work for \insert27{foo}. +% +\def\saveinsert#1{% + \edef\next{\noexpand\savetobox \makeSAVEname#1}% + \afterassignment\next + % swallow the left brace + \let\temp = +} +\def\makeSAVEname#1{\makecsname{SAVE\expandafter\gobble\string#1}} +\def\savetobox#1{\global\setbox#1 = \vbox\bgroup \unvbox#1} + +\def\checksaveins#1{\ifvoid#1\else \placesaveins#1\fi} + +\def\placesaveins#1{% + \ptexinsert \csname\expandafter\gobblesave\string#1\endcsname + {\box#1}% +} + +% eat @SAVE -- beware, all of them have catcode \other: +{ + \def\dospecials{\do S\do A\do V\do E} \uncatcodespecials % ;-) + \gdef\gobblesave @SAVE{} +} + +% initialization: +\def\newsaveins #1{% + \edef\next{\noexpand\newsaveinsX \makeSAVEname#1}% + \next +} +\def\newsaveinsX #1{% + \csname newbox\endcsname #1% + \expandafter\def\expandafter\checkinserts\expandafter{\checkinserts + \checksaveins #1}% +} + +% initialize: +\let\checkinserts\empty +\newsaveins\footins +\newsaveins\margin + + +% @image. We use the macros from epsf.tex to support this. +% If epsf.tex is not installed and @image is used, we complain. +% +% Check for and read epsf.tex up front. If we read it only at @image +% time, we might be inside a group, and then its definitions would get +% undone and the next image would fail. +\openin 1 = epsf.tex +\ifeof 1 \else + % Do not bother showing banner with epsf.tex v2.7k (available in + % doc/epsf.tex and on ctan). + \def\epsfannounce{\toks0 = }% + \input epsf.tex +\fi +\closein 1 +% +% We will only complain once about lack of epsf.tex. +\newif\ifwarnednoepsf +\newhelp\noepsfhelp{epsf.tex must be installed for images to + work. It is also included in the Texinfo distribution, or you can get + it from https://ctan.org/texarchive/macros/texinfo/texinfo/doc/epsf.tex.} +% +\def\image#1{% + \ifx\epsfbox\thisisundefined + \ifwarnednoepsf \else + \errhelp = \noepsfhelp + \errmessage{epsf.tex not found, images will be ignored}% + \global\warnednoepsftrue + \fi + \else + \imagexxx #1,,,,,\finish + \fi +} +% +% Arguments to @image: +% #1 is (mandatory) image filename; we tack on .eps extension. +% #2 is (optional) width, #3 is (optional) height. +% #4 is (ignored optional) html alt text. +% #5 is (ignored optional) extension. +% #6 is just the usual extra ignored arg for parsing stuff. +\newif\ifimagevmode +\def\imagexxx#1,#2,#3,#4,#5,#6\finish{\begingroup + \catcode`\^^M = 5 % in case we're inside an example + \normalturnoffactive % allow _ et al. in names + \def\xprocessmacroarg{\eatspaces}% in case we are being used via a macro + % If the image is by itself, center it. + \ifvmode + \imagevmodetrue + \else \ifx\centersub\centerV + % for @center @image, we need a vbox so we can have our vertical space + \imagevmodetrue + \vbox\bgroup % vbox has better behavior than vtop herev + \fi\fi + % + \ifimagevmode + \nobreak\medskip + % Usually we'll have text after the image which will insert + % \parskip glue, so insert it here too to equalize the space + % above and below. + \nobreak\vskip\parskip + \nobreak + \fi + % + % Leave vertical mode so that indentation from an enclosing + % environment such as @quotation is respected. + % However, if we're at the top level, we don't want the + % normal paragraph indentation. + % On the other hand, if we are in the case of @center @image, we don't + % want to start a paragraph, which will create a hsize-width box and + % eradicate the centering. + \ifx\centersub\centerV\else \noindent \fi + % + % Output the image. + \ifpdf + % For pdfTeX and LuaTeX <= 0.80 + \dopdfimage{#1}{#2}{#3}% + \else + \ifx\XeTeXrevision\thisisundefined + % For epsf.tex + % \epsfbox itself resets \epsf?size at each figure. + \setbox0 = \hbox{\ignorespaces #2}% + \ifdim\wd0 > 0pt \epsfxsize=#2\relax \fi + \setbox0 = \hbox{\ignorespaces #3}% + \ifdim\wd0 > 0pt \epsfysize=#3\relax \fi + \epsfbox{#1.eps}% + \else + % For XeTeX + \doxeteximage{#1}{#2}{#3}% + \fi + \fi + % + \ifimagevmode + \medskip % space after a standalone image + \fi + \ifx\centersub\centerV \egroup \fi +\endgroup} + + +% @float FLOATTYPE,LABEL,LOC ... @end float for displayed figures, tables, +% etc. We don't actually implement floating yet, we always include the +% float "here". But it seemed the best name for the future. +% +\envparseargdef\float{\eatcommaspace\eatcommaspace\dofloat#1, , ,\finish} + +% There may be a space before second and/or third parameter; delete it. +\def\eatcommaspace#1, {#1,} + +% #1 is the optional FLOATTYPE, the text label for this float, typically +% "Figure", "Table", "Example", etc. Can't contain commas. If omitted, +% this float will not be numbered and cannot be referred to. +% +% #2 is the optional xref label. Also must be present for the float to +% be referable. +% +% #3 is the optional positioning argument; for now, it is ignored. It +% will somehow specify the positions allowed to float to (here, top, bottom). +% +% We keep a separate counter for each FLOATTYPE, which we reset at each +% chapter-level command. +\let\resetallfloatnos=\empty +% +\def\dofloat#1,#2,#3,#4\finish{% + \let\thiscaption=\empty + \let\thisshortcaption=\empty + % + % don't lose footnotes inside @float. + % + % BEWARE: when the floats start float, we have to issue warning whenever an + % insert appears inside a float which could possibly float. --kasal, 26may04 + % + \startsavinginserts + % + % We can't be used inside a paragraph. + \par + % + \vtop\bgroup + \def\floattype{#1}% + \def\floatlabel{#2}% + \def\floatloc{#3}% we do nothing with this yet. + % + \ifx\floattype\empty + \let\safefloattype=\empty + \else + {% + % the floattype might have accents or other special characters, + % but we need to use it in a control sequence name. + \indexnofonts + \turnoffactive + \xdef\safefloattype{\floattype}% + }% + \fi + % + % If label is given but no type, we handle that as the empty type. + \ifx\floatlabel\empty \else + % We want each FLOATTYPE to be numbered separately (Figure 1, + % Table 1, Figure 2, ...). (And if no label, no number.) + % + \expandafter\getfloatno\csname\safefloattype floatno\endcsname + \global\advance\floatno by 1 + % + {% + % This magic value for \lastsection is output by \setref as the + % XREFLABEL-title value. \xrefX uses it to distinguish float + % labels (which have a completely different output format) from + % node and anchor labels. And \xrdef uses it to construct the + % lists of floats. + % + \edef\lastsection{\floatmagic=\safefloattype}% + \setref{\floatlabel}{Yfloat}% + }% + \fi + % + % start with \parskip glue, I guess. + \vskip\parskip + % + % Don't suppress indentation if a float happens to start a section. + \restorefirstparagraphindent +} + +% we have these possibilities: +% @float Foo,lbl & @caption{Cap}: Foo 1.1: Cap +% @float Foo,lbl & no caption: Foo 1.1 +% @float Foo & @caption{Cap}: Foo: Cap +% @float Foo & no caption: Foo +% @float ,lbl & Caption{Cap}: 1.1: Cap +% @float ,lbl & no caption: 1.1 +% @float & @caption{Cap}: Cap +% @float & no caption: +% +\def\Efloat{% + \let\floatident = \empty + % + % In all cases, if we have a float type, it comes first. + \ifx\floattype\empty \else \def\floatident{\floattype}\fi + % + % If we have an xref label, the number comes next. + \ifx\floatlabel\empty \else + \ifx\floattype\empty \else % if also had float type, need tie first. + \appendtomacro\floatident{\tie}% + \fi + % the number. + \appendtomacro\floatident{\chaplevelprefix\the\floatno}% + \fi + % + % Start the printed caption with what we've constructed in + % \floatident, but keep it separate; we need \floatident again. + \let\captionline = \floatident + % + \ifx\thiscaption\empty \else + \ifx\floatident\empty \else + \appendtomacro\captionline{: }% had ident, so need a colon between + \fi + % + % caption text. + \appendtomacro\captionline{\scanexp\thiscaption}% + \fi + % + % If we have anything to print, print it, with space before. + % Eventually this needs to become an \insert. + \ifx\captionline\empty \else + \vskip.5\parskip + \captionline + % + % Space below caption. + \vskip\parskip + \fi + % + % If have an xref label, write the list of floats info. Do this + % after the caption, to avoid chance of it being a breakpoint. + \ifx\floatlabel\empty \else + % Write the text that goes in the lof to the aux file as + % \floatlabel-lof. Besides \floatident, we include the short + % caption if specified, else the full caption if specified, else nothing. + {% + \requireauxfile + \atdummies + % + \ifx\thisshortcaption\empty + \def\gtemp{\thiscaption}% + \else + \def\gtemp{\thisshortcaption}% + \fi + \immediate\write\auxfile{@xrdef{\floatlabel-lof}{\floatident + \ifx\gtemp\empty \else : \gtemp \fi}}% + }% + \fi + \egroup % end of \vtop + % + \checkinserts +} + +% Append the tokens #2 to the definition of macro #1, not expanding either. +% +\def\appendtomacro#1#2{% + \expandafter\def\expandafter#1\expandafter{#1#2}% +} + +% @caption, @shortcaption +% +\def\caption{\docaption\thiscaption} +\def\shortcaption{\docaption\thisshortcaption} +\def\docaption{\checkenv\float \bgroup\scanargctxt\defcaption} +\def\defcaption#1#2{\egroup \def#1{#2}} + +% The parameter is the control sequence identifying the counter we are +% going to use. Create it if it doesn't exist and assign it to \floatno. +\def\getfloatno#1{% + \ifx#1\relax + % Haven't seen this figure type before. + \csname newcount\endcsname #1% + % + % Remember to reset this floatno at the next chap. + \expandafter\gdef\expandafter\resetallfloatnos + \expandafter{\resetallfloatnos #1=0 }% + \fi + \let\floatno#1% +} + +% \setref calls this to get the XREFLABEL-snt value. We want an @xref +% to the FLOATLABEL to expand to "Figure 3.1". We call \setref when we +% first read the @float command. +% +\def\Yfloat{\floattype@tie \chaplevelprefix\the\floatno}% + +% Magic string used for the XREFLABEL-title value, so \xrefX can +% distinguish floats from other xref types. +\def\floatmagic{!!float!!} + +% #1 is the control sequence we are passed; we expand into a conditional +% which is true if #1 represents a float ref. That is, the magic +% \lastsection value which we \setref above. +% +\def\iffloat#1{\expandafter\doiffloat#1==\finish} +% +% #1 is (maybe) the \floatmagic string. If so, #2 will be the +% (safe) float type for this float. We set \iffloattype to #2. +% +\def\doiffloat#1=#2=#3\finish{% + \def\temp{#1}% + \def\iffloattype{#2}% + \ifx\temp\floatmagic +} + +% @listoffloats FLOATTYPE - print a list of floats like a table of contents. +% +\parseargdef\listoffloats{% + \def\floattype{#1}% floattype + {% + % the floattype might have accents or other special characters, + % but we need to use it in a control sequence name. + \indexnofonts + \turnoffactive + \xdef\safefloattype{\floattype}% + }% + % + % \xrdef saves the floats as a \do-list in \floatlistSAFEFLOATTYPE. + \expandafter\ifx\csname floatlist\safefloattype\endcsname \relax + \ifhavexrefs + % if the user said @listoffloats foo but never @float foo. + \message{\linenumber No `\safefloattype' floats to list.}% + \fi + \else + \begingroup + \leftskip=\tocindent % indent these entries like a toc + \let\do=\listoffloatsdo + \csname floatlist\safefloattype\endcsname + \endgroup + \fi +} + +% This is called on each entry in a list of floats. We're passed the +% xref label, in the form LABEL-title, which is how we save it in the +% aux file. We strip off the -title and look up \XRLABEL-lof, which +% has the text we're supposed to typeset here. +% +% Figures without xref labels will not be included in the list (since +% they won't appear in the aux file). +% +\def\listoffloatsdo#1{\listoffloatsdoentry#1\finish} +\def\listoffloatsdoentry#1-title\finish{{% + % Can't fully expand XR#1-lof because it can contain anything. Just + % pass the control sequence. On the other hand, XR#1-pg is just the + % page number, and we want to fully expand that so we can get a link + % in pdf output. + \toksA = \expandafter{\csname XR#1-lof\endcsname}% + % + % use the same \entry macro we use to generate the TOC and index. + \edef\writeentry{\noexpand\entry{\the\toksA}{\csname XR#1-pg\endcsname}}% + \writeentry +}} + + +\message{localization,} + +% For single-language documents, @documentlanguage is usually given very +% early, just after @documentencoding. Single argument is the language +% (de) or locale (de_DE) abbreviation. +% +{ + \catcode`\_ = \active + \globaldefs=1 +\parseargdef\documentlanguage{% + \tex % read txi-??.tex file in plain TeX. + % Read the file by the name they passed if it exists. + \let_ = \normalunderscore % normal _ character for filename test + \openin 1 txi-#1.tex + \ifeof 1 + \documentlanguagetrywithoutunderscore #1_\finish + \else + \globaldefs = 1 % everything in the txi-LL files needs to persist + \input txi-#1.tex + \fi + \closein 1 + \endgroup % end raw TeX +} +% +% If they passed de_DE, and txi-de_DE.tex doesn't exist, +% try txi-de.tex. +% +\gdef\documentlanguagetrywithoutunderscore#1_#2\finish{% + \openin 1 txi-#1.tex + \ifeof 1 + \errhelp = \nolanghelp + \errmessage{Cannot read language file txi-#1.tex}% + \else + \globaldefs = 1 % everything in the txi-LL files needs to persist + \input txi-#1.tex + \fi + \closein 1 +} +}% end of special _ catcode +% +\newhelp\nolanghelp{The given language definition file cannot be found or +is empty. Maybe you need to install it? Putting it in the current +directory should work if nowhere else does.} + +% This macro is called from txi-??.tex files; the first argument is the +% \language name to set (without the "\lang@" prefix), the second and +% third args are \{left,right}hyphenmin. +% +% The language names to pass are determined when the format is built. +% See the etex.log file created at that time, e.g., +% /usr/local/texlive/2008/texmf-var/web2c/pdftex/etex.log. +% +% With TeX Live 2008, etex now includes hyphenation patterns for all +% available languages. This means we can support hyphenation in +% Texinfo, at least to some extent. (This still doesn't solve the +% accented characters problem.) +% +\catcode`@=11 +\def\txisetlanguage#1#2#3{% + % do not set the language if the name is undefined in the current TeX. + \expandafter\ifx\csname lang@#1\endcsname \relax + \message{no patterns for #1}% + \else + \global\language = \csname lang@#1\endcsname + \fi + % but there is no harm in adjusting the hyphenmin values regardless. + \global\lefthyphenmin = #2\relax + \global\righthyphenmin = #3\relax +} + +% XeTeX and LuaTeX can handle Unicode natively. +% Their default I/O uses UTF-8 sequences instead of a byte-wise operation. +% Other TeX engines' I/O (pdfTeX, etc.) is byte-wise. +% +\newif\iftxinativeunicodecapable +\newif\iftxiusebytewiseio + +\ifx\XeTeXrevision\thisisundefined + \ifx\luatexversion\thisisundefined + \txinativeunicodecapablefalse + \txiusebytewiseiotrue + \else + \txinativeunicodecapabletrue + \txiusebytewiseiofalse + \fi +\else + \txinativeunicodecapabletrue + \txiusebytewiseiofalse +\fi + +% Set I/O by bytes instead of UTF-8 sequence for XeTeX and LuaTex +% for non-UTF-8 (byte-wise) encodings. +% +\def\setbytewiseio{% + \ifx\XeTeXrevision\thisisundefined + \else + \XeTeXdefaultencoding "bytes" % For subsequent files to be read + \XeTeXinputencoding "bytes" % For document root file + % Unfortunately, there seems to be no corresponding XeTeX command for + % output encoding. This is a problem for auxiliary index and TOC files. + % The only solution would be perhaps to write out @U{...} sequences in + % place of non-ASCII characters. + \fi + + \ifx\luatexversion\thisisundefined + \else + \directlua{ + local utf8_char, byte, gsub = unicode.utf8.char, string.byte, string.gsub + local function convert_char (char) + return utf8_char(byte(char)) + end + + local function convert_line (line) + return gsub(line, ".", convert_char) + end + + callback.register("process_input_buffer", convert_line) + + local function convert_line_out (line) + local line_out = "" + for c in string.utfvalues(line) do + line_out = line_out .. string.char(c) + end + return line_out + end + + callback.register("process_output_buffer", convert_line_out) + } + \fi + + \txiusebytewiseiotrue +} + + +% Helpers for encodings. +% Set the catcode of characters 128 through 255 to the specified number. +% +\def\setnonasciicharscatcode#1{% + \count255=128 + \loop\ifnum\count255<256 + \global\catcode\count255=#1\relax + \advance\count255 by 1 + \repeat +} + +\def\setnonasciicharscatcodenonglobal#1{% + \count255=128 + \loop\ifnum\count255<256 + \catcode\count255=#1\relax + \advance\count255 by 1 + \repeat +} + +% @documentencoding sets the definition of non-ASCII characters +% according to the specified encoding. +% +\def\documentencoding{\parseargusing\filenamecatcodes\documentencodingzzz} +\def\documentencodingzzz#1{% + % + % Encoding being declared for the document. + \def\declaredencoding{\csname #1.enc\endcsname}% + % + % Supported encodings: names converted to tokens in order to be able + % to compare them with \ifx. + \def\ascii{\csname US-ASCII.enc\endcsname}% + \def\latnine{\csname ISO-8859-15.enc\endcsname}% + \def\latone{\csname ISO-8859-1.enc\endcsname}% + \def\lattwo{\csname ISO-8859-2.enc\endcsname}% + \def\utfeight{\csname UTF-8.enc\endcsname}% + % + \ifx \declaredencoding \ascii + \asciichardefs + % + \else \ifx \declaredencoding \lattwo + \iftxinativeunicodecapable + \setbytewiseio + \fi + \setnonasciicharscatcode\active + \lattwochardefs + % + \else \ifx \declaredencoding \latone + \iftxinativeunicodecapable + \setbytewiseio + \fi + \setnonasciicharscatcode\active + \latonechardefs + % + \else \ifx \declaredencoding \latnine + \iftxinativeunicodecapable + \setbytewiseio + \fi + \setnonasciicharscatcode\active + \latninechardefs + % + \else \ifx \declaredencoding \utfeight + \iftxinativeunicodecapable + % For native Unicode handling (XeTeX and LuaTeX) + \nativeunicodechardefs + \else + % For treating UTF-8 as byte sequences (TeX, eTeX and pdfTeX) + \setnonasciicharscatcode\active + % since we already invoked \utfeightchardefs at the top level + % (below), do not re-invoke it, otherwise our check for duplicated + % definitions gets triggered. Making non-ascii chars active is + % sufficient. + \fi + % + \else + \message{Ignoring unknown document encoding: #1.}% + % + \fi % utfeight + \fi % latnine + \fi % latone + \fi % lattwo + \fi % ascii + % + \ifx\XeTeXrevision\thisisundefined + \else + \ifx \declaredencoding \utfeight + \else + \ifx \declaredencoding \ascii + \else + \message{Warning: XeTeX with non-UTF-8 encodings cannot handle % + non-ASCII characters in auxiliary files.}% + \fi + \fi + \fi +} + +% emacs-page +% A message to be logged when using a character that isn't available +% the default font encoding (OT1). +% +\def\missingcharmsg#1{\message{Character missing, sorry: #1.}} + +% Take account of \c (plain) vs. \, (Texinfo) difference. +\def\cedilla#1{\ifx\c\ptexc\c{#1}\else\,{#1}\fi} + +% First, make active non-ASCII characters in order for them to be +% correctly categorized when TeX reads the replacement text of +% macros containing the character definitions. +\setnonasciicharscatcode\active +% + +\def\gdefchar#1#2{% +\gdef#1{% + \ifpassthroughchars + \string#1% + \else + #2% + \fi +}} + +% Latin1 (ISO-8859-1) character definitions. +\def\latonechardefs{% + \gdefchar^^a0{\tie} + \gdefchar^^a1{\exclamdown} + \gdefchar^^a2{{\tcfont \char162}} % cent + \gdefchar^^a3{\pounds{}} + \gdefchar^^a4{{\tcfont \char164}} % currency + \gdefchar^^a5{{\tcfont \char165}} % yen + \gdefchar^^a6{{\tcfont \char166}} % broken bar + \gdefchar^^a7{\S} + \gdefchar^^a8{\"{}} + \gdefchar^^a9{\copyright{}} + \gdefchar^^aa{\ordf} + \gdefchar^^ab{\guillemetleft{}} + \gdefchar^^ac{\ensuremath\lnot} + \gdefchar^^ad{\-} + \gdefchar^^ae{\registeredsymbol{}} + \gdefchar^^af{\={}} + % + \gdefchar^^b0{\textdegree} + \gdefchar^^b1{$\pm$} + \gdefchar^^b2{$^2$} + \gdefchar^^b3{$^3$} + \gdefchar^^b4{\'{}} + \gdefchar^^b5{$\mu$} + \gdefchar^^b6{\P} + \gdefchar^^b7{\ensuremath\cdot} + \gdefchar^^b8{\cedilla\ } + \gdefchar^^b9{$^1$} + \gdefchar^^ba{\ordm} + \gdefchar^^bb{\guillemetright{}} + \gdefchar^^bc{$1\over4$} + \gdefchar^^bd{$1\over2$} + \gdefchar^^be{$3\over4$} + \gdefchar^^bf{\questiondown} + % + \gdefchar^^c0{\`A} + \gdefchar^^c1{\'A} + \gdefchar^^c2{\^A} + \gdefchar^^c3{\~A} + \gdefchar^^c4{\"A} + \gdefchar^^c5{\ringaccent A} + \gdefchar^^c6{\AE} + \gdefchar^^c7{\cedilla C} + \gdefchar^^c8{\`E} + \gdefchar^^c9{\'E} + \gdefchar^^ca{\^E} + \gdefchar^^cb{\"E} + \gdefchar^^cc{\`I} + \gdefchar^^cd{\'I} + \gdefchar^^ce{\^I} + \gdefchar^^cf{\"I} + % + \gdefchar^^d0{\DH} + \gdefchar^^d1{\~N} + \gdefchar^^d2{\`O} + \gdefchar^^d3{\'O} + \gdefchar^^d4{\^O} + \gdefchar^^d5{\~O} + \gdefchar^^d6{\"O} + \gdefchar^^d7{$\times$} + \gdefchar^^d8{\O} + \gdefchar^^d9{\`U} + \gdefchar^^da{\'U} + \gdefchar^^db{\^U} + \gdefchar^^dc{\"U} + \gdefchar^^dd{\'Y} + \gdefchar^^de{\TH} + \gdefchar^^df{\ss} + % + \gdefchar^^e0{\`a} + \gdefchar^^e1{\'a} + \gdefchar^^e2{\^a} + \gdefchar^^e3{\~a} + \gdefchar^^e4{\"a} + \gdefchar^^e5{\ringaccent a} + \gdefchar^^e6{\ae} + \gdefchar^^e7{\cedilla c} + \gdefchar^^e8{\`e} + \gdefchar^^e9{\'e} + \gdefchar^^ea{\^e} + \gdefchar^^eb{\"e} + \gdefchar^^ec{\`{\dotless i}} + \gdefchar^^ed{\'{\dotless i}} + \gdefchar^^ee{\^{\dotless i}} + \gdefchar^^ef{\"{\dotless i}} + % + \gdefchar^^f0{\dh} + \gdefchar^^f1{\~n} + \gdefchar^^f2{\`o} + \gdefchar^^f3{\'o} + \gdefchar^^f4{\^o} + \gdefchar^^f5{\~o} + \gdefchar^^f6{\"o} + \gdefchar^^f7{$\div$} + \gdefchar^^f8{\o} + \gdefchar^^f9{\`u} + \gdefchar^^fa{\'u} + \gdefchar^^fb{\^u} + \gdefchar^^fc{\"u} + \gdefchar^^fd{\'y} + \gdefchar^^fe{\th} + \gdefchar^^ff{\"y} +} + +% Latin9 (ISO-8859-15) encoding character definitions. +\def\latninechardefs{% + % Encoding is almost identical to Latin1. + \latonechardefs + % + \gdefchar^^a4{\euro{}} + \gdefchar^^a6{\v S} + \gdefchar^^a8{\v s} + \gdefchar^^b4{\v Z} + \gdefchar^^b8{\v z} + \gdefchar^^bc{\OE} + \gdefchar^^bd{\oe} + \gdefchar^^be{\"Y} +} + +% Latin2 (ISO-8859-2) character definitions. +\def\lattwochardefs{% + \gdefchar^^a0{\tie} + \gdefchar^^a1{\ogonek{A}} + \gdefchar^^a2{\u{}} + \gdefchar^^a3{\L} + \gdefchar^^a4{\missingcharmsg{CURRENCY SIGN}} + \gdefchar^^a5{\v L} + \gdefchar^^a6{\'S} + \gdefchar^^a7{\S} + \gdefchar^^a8{\"{}} + \gdefchar^^a9{\v S} + \gdefchar^^aa{\cedilla S} + \gdefchar^^ab{\v T} + \gdefchar^^ac{\'Z} + \gdefchar^^ad{\-} + \gdefchar^^ae{\v Z} + \gdefchar^^af{\dotaccent Z} + % + \gdefchar^^b0{\textdegree{}} + \gdefchar^^b1{\ogonek{a}} + \gdefchar^^b2{\ogonek{ }} + \gdefchar^^b3{\l} + \gdefchar^^b4{\'{}} + \gdefchar^^b5{\v l} + \gdefchar^^b6{\'s} + \gdefchar^^b7{\v{}} + \gdefchar^^b8{\cedilla\ } + \gdefchar^^b9{\v s} + \gdefchar^^ba{\cedilla s} + \gdefchar^^bb{\v t} + \gdefchar^^bc{\'z} + \gdefchar^^bd{\H{}} + \gdefchar^^be{\v z} + \gdefchar^^bf{\dotaccent z} + % + \gdefchar^^c0{\'R} + \gdefchar^^c1{\'A} + \gdefchar^^c2{\^A} + \gdefchar^^c3{\u A} + \gdefchar^^c4{\"A} + \gdefchar^^c5{\'L} + \gdefchar^^c6{\'C} + \gdefchar^^c7{\cedilla C} + \gdefchar^^c8{\v C} + \gdefchar^^c9{\'E} + \gdefchar^^ca{\ogonek{E}} + \gdefchar^^cb{\"E} + \gdefchar^^cc{\v E} + \gdefchar^^cd{\'I} + \gdefchar^^ce{\^I} + \gdefchar^^cf{\v D} + % + \gdefchar^^d0{\DH} + \gdefchar^^d1{\'N} + \gdefchar^^d2{\v N} + \gdefchar^^d3{\'O} + \gdefchar^^d4{\^O} + \gdefchar^^d5{\H O} + \gdefchar^^d6{\"O} + \gdefchar^^d7{$\times$} + \gdefchar^^d8{\v R} + \gdefchar^^d9{\ringaccent U} + \gdefchar^^da{\'U} + \gdefchar^^db{\H U} + \gdefchar^^dc{\"U} + \gdefchar^^dd{\'Y} + \gdefchar^^de{\cedilla T} + \gdefchar^^df{\ss} + % + \gdefchar^^e0{\'r} + \gdefchar^^e1{\'a} + \gdefchar^^e2{\^a} + \gdefchar^^e3{\u a} + \gdefchar^^e4{\"a} + \gdefchar^^e5{\'l} + \gdefchar^^e6{\'c} + \gdefchar^^e7{\cedilla c} + \gdefchar^^e8{\v c} + \gdefchar^^e9{\'e} + \gdefchar^^ea{\ogonek{e}} + \gdefchar^^eb{\"e} + \gdefchar^^ec{\v e} + \gdefchar^^ed{\'{\dotless{i}}} + \gdefchar^^ee{\^{\dotless{i}}} + \gdefchar^^ef{\v d} + % + \gdefchar^^f0{\dh} + \gdefchar^^f1{\'n} + \gdefchar^^f2{\v n} + \gdefchar^^f3{\'o} + \gdefchar^^f4{\^o} + \gdefchar^^f5{\H o} + \gdefchar^^f6{\"o} + \gdefchar^^f7{$\div$} + \gdefchar^^f8{\v r} + \gdefchar^^f9{\ringaccent u} + \gdefchar^^fa{\'u} + \gdefchar^^fb{\H u} + \gdefchar^^fc{\"u} + \gdefchar^^fd{\'y} + \gdefchar^^fe{\cedilla t} + \gdefchar^^ff{\dotaccent{}} +} + +% UTF-8 character definitions. +% +% This code to support UTF-8 is based on LaTeX's utf8.def, with some +% changes for Texinfo conventions. It is included here under the GPL by +% permission from Frank Mittelbach and the LaTeX team. +% +\newcount\countUTFx +\newcount\countUTFy +\newcount\countUTFz + +\gdef\UTFviiiTwoOctets#1#2{\expandafter + \UTFviiiDefined\csname u8:#1\string #2\endcsname} +% +\gdef\UTFviiiThreeOctets#1#2#3{\expandafter + \UTFviiiDefined\csname u8:#1\string #2\string #3\endcsname} +% +\gdef\UTFviiiFourOctets#1#2#3#4{\expandafter + \UTFviiiDefined\csname u8:#1\string #2\string #3\string #4\endcsname} + +\gdef\UTFviiiDefined#1{% + \ifx #1\relax + \message{\linenumber Unicode char \string #1 not defined for Texinfo}% + \else + \expandafter #1% + \fi +} + +% Give non-ASCII bytes the active definitions for processing UTF-8 sequences +\begingroup + \catcode`\~13 + \catcode`\$12 + \catcode`\"12 + + % Loop from \countUTFx to \countUTFy, performing \UTFviiiTmp + % substituting ~ and $ with a character token of that value. + \def\UTFviiiLoop{% + \global\catcode\countUTFx\active + \uccode`\~\countUTFx + \uccode`\$\countUTFx + \uppercase\expandafter{\UTFviiiTmp}% + \advance\countUTFx by 1 + \ifnum\countUTFx < \countUTFy + \expandafter\UTFviiiLoop + \fi} + + % For bytes other than the first in a UTF-8 sequence. Not expected to + % be expanded except when writing to auxiliary files. + \countUTFx = "80 + \countUTFy = "C2 + \def\UTFviiiTmp{% + \gdef~{% + \ifpassthroughchars $\fi}}% + \UTFviiiLoop + + \countUTFx = "C2 + \countUTFy = "E0 + \def\UTFviiiTmp{% + \gdef~{% + \ifpassthroughchars $% + \else\expandafter\UTFviiiTwoOctets\expandafter$\fi}}% + \UTFviiiLoop + + \countUTFx = "E0 + \countUTFy = "F0 + \def\UTFviiiTmp{% + \gdef~{% + \ifpassthroughchars $% + \else\expandafter\UTFviiiThreeOctets\expandafter$\fi}}% + \UTFviiiLoop + + \countUTFx = "F0 + \countUTFy = "F4 + \def\UTFviiiTmp{% + \gdef~{% + \ifpassthroughchars $% + \else\expandafter\UTFviiiFourOctets\expandafter$\fi + }}% + \UTFviiiLoop +\endgroup + +\def\globallet{\global\let} % save some \expandafter's below + +% @U{xxxx} to produce U+xxxx, if we support it. +\def\U#1{% + \expandafter\ifx\csname uni:#1\endcsname \relax + \iftxinativeunicodecapable + % All Unicode characters can be used if native Unicode handling is + % active. However, if the font does not have the glyph, + % letters are missing. + \begingroup + \uccode`\.="#1\relax + \uppercase{.} + \endgroup + \else + \errhelp = \EMsimple + \errmessage{Unicode character U+#1 not supported, sorry}% + \fi + \else + \csname uni:#1\endcsname + \fi +} + +% These macros are used here to construct the name of a control +% sequence to be defined. +\def\UTFviiiTwoOctetsName#1#2{% + \csname u8:#1\string #2\endcsname}% +\def\UTFviiiThreeOctetsName#1#2#3{% + \csname u8:#1\string #2\string #3\endcsname}% +\def\UTFviiiFourOctetsName#1#2#3#4{% + \csname u8:#1\string #2\string #3\string #4\endcsname}% + +% For UTF-8 byte sequences (TeX, e-TeX and pdfTeX), +% provide a definition macro to replace a Unicode character; +% this gets used by the @U command +% +\begingroup + \catcode`\"=12 + \catcode`\<=12 + \catcode`\.=12 + \catcode`\,=12 + \catcode`\;=12 + \catcode`\!=12 + \catcode`\~=13 + \gdef\DeclareUnicodeCharacterUTFviii#1#2{% + \countUTFz = "#1\relax + \begingroup + \parseXMLCharref + + % Give \u8:... its definition. The sequence of seven \expandafter's + % expands after the \gdef three times, e.g. + % + % 1. \UTFviiTwoOctetsName B1 B2 + % 2. \csname u8:B1 \string B2 \endcsname + % 3. \u8: B1 B2 (a single control sequence token) + % + \expandafter\expandafter + \expandafter\expandafter + \expandafter\expandafter + \expandafter\gdef \UTFviiiTmp{#2}% + % + \expandafter\ifx\csname uni:#1\endcsname \relax \else + \message{Internal error, already defined: #1}% + \fi + % + % define an additional control sequence for this code point. + \expandafter\globallet\csname uni:#1\endcsname \UTFviiiTmp + \endgroup} + % + % Given the value in \countUTFz as a Unicode code point, set \UTFviiiTmp + % to the corresponding UTF-8 sequence. + \gdef\parseXMLCharref{% + \ifnum\countUTFz < "A0\relax + \errhelp = \EMsimple + \errmessage{Cannot define Unicode char value < 00A0}% + \else\ifnum\countUTFz < "800\relax + \parseUTFviiiA,% + \parseUTFviiiB C\UTFviiiTwoOctetsName.,% + \else\ifnum\countUTFz < "10000\relax + \parseUTFviiiA;% + \parseUTFviiiA,% + \parseUTFviiiB E\UTFviiiThreeOctetsName.{,;}% + \else + \parseUTFviiiA;% + \parseUTFviiiA,% + \parseUTFviiiA!% + \parseUTFviiiB F\UTFviiiFourOctetsName.{!,;}% + \fi\fi\fi + } + + % Extract a byte from the end of the UTF-8 representation of \countUTFx. + % It must be a non-initial byte in the sequence. + % Change \uccode of #1 for it to be used in \parseUTFviiiB as one + % of the bytes. + \gdef\parseUTFviiiA#1{% + \countUTFx = \countUTFz + \divide\countUTFz by 64 + \countUTFy = \countUTFz % Save to be the future value of \countUTFz. + \multiply\countUTFz by 64 + + % \countUTFz is now \countUTFx with the last 5 bits cleared. Subtract + % in order to get the last five bits. + \advance\countUTFx by -\countUTFz + + % Convert this to the byte in the UTF-8 sequence. + \advance\countUTFx by 128 + \uccode `#1\countUTFx + \countUTFz = \countUTFy} + + % Used to put a UTF-8 byte sequence into \UTFviiiTmp + % #1 is the increment for \countUTFz to yield a the first byte of the UTF-8 + % sequence. + % #2 is one of the \UTFviii*OctetsName macros. + % #3 is always a full stop (.) + % #4 is a template for the other bytes in the sequence. The values for these + % bytes is substituted in here with \uppercase using the \uccode's. + \gdef\parseUTFviiiB#1#2#3#4{% + \advance\countUTFz by "#10\relax + \uccode `#3\countUTFz + \uppercase{\gdef\UTFviiiTmp{#2#3#4}}} +\endgroup + +% For native Unicode handling (XeTeX and LuaTeX), +% provide a definition macro that sets a catcode to `other' non-globally +% +\def\DeclareUnicodeCharacterNativeOther#1#2{% + \catcode"#1=\other +} + +% https://en.wikipedia.org/wiki/Plane_(Unicode)#Basic_M +% U+0000..U+007F = https://en.wikipedia.org/wiki/Basic_Latin_(Unicode_block) +% U+0080..U+00FF = https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block) +% U+0100..U+017F = https://en.wikipedia.org/wiki/Latin_Extended-A +% U+0180..U+024F = https://en.wikipedia.org/wiki/Latin_Extended-B +% +% Many of our renditions are less than wonderful, and all the missing +% characters are available somewhere. Loading the necessary fonts +% awaits user request. We can't truly support Unicode without +% reimplementing everything that's been done in LaTeX for many years, +% plus probably using luatex or xetex, and who knows what else. +% We won't be doing that here in this simple file. But we can try to at +% least make most of the characters not bomb out. +% +\def\unicodechardefs{% + \DeclareUnicodeCharacter{00A0}{\tie}% + \DeclareUnicodeCharacter{00A1}{\exclamdown}% + \DeclareUnicodeCharacter{00A2}{{\tcfont \char162}}% 0242=cent + \DeclareUnicodeCharacter{00A3}{\pounds{}}% + \DeclareUnicodeCharacter{00A4}{{\tcfont \char164}}% 0244=currency + \DeclareUnicodeCharacter{00A5}{{\tcfont \char165}}% 0245=yen + \DeclareUnicodeCharacter{00A6}{{\tcfont \char166}}% 0246=brokenbar + \DeclareUnicodeCharacter{00A7}{\S}% + \DeclareUnicodeCharacter{00A8}{\"{ }}% + \DeclareUnicodeCharacter{00A9}{\copyright{}}% + \DeclareUnicodeCharacter{00AA}{\ordf}% + \DeclareUnicodeCharacter{00AB}{\guillemetleft{}}% + \DeclareUnicodeCharacter{00AC}{\ensuremath\lnot}% + \DeclareUnicodeCharacter{00AD}{\-}% + \DeclareUnicodeCharacter{00AE}{\registeredsymbol{}}% + \DeclareUnicodeCharacter{00AF}{\={ }}% + % + \DeclareUnicodeCharacter{00B0}{\ringaccent{ }}% + \DeclareUnicodeCharacter{00B1}{\ensuremath\pm}% + \DeclareUnicodeCharacter{00B2}{$^2$}% + \DeclareUnicodeCharacter{00B3}{$^3$}% + \DeclareUnicodeCharacter{00B4}{\'{ }}% + \DeclareUnicodeCharacter{00B5}{$\mu$}% + \DeclareUnicodeCharacter{00B6}{\P}% + \DeclareUnicodeCharacter{00B7}{\ensuremath\cdot}% + \DeclareUnicodeCharacter{00B8}{\cedilla{ }}% + \DeclareUnicodeCharacter{00B9}{$^1$}% + \DeclareUnicodeCharacter{00BA}{\ordm}% + \DeclareUnicodeCharacter{00BB}{\guillemetright{}}% + \DeclareUnicodeCharacter{00BC}{$1\over4$}% + \DeclareUnicodeCharacter{00BD}{$1\over2$}% + \DeclareUnicodeCharacter{00BE}{$3\over4$}% + \DeclareUnicodeCharacter{00BF}{\questiondown}% + % + \DeclareUnicodeCharacter{00C0}{\`A}% + \DeclareUnicodeCharacter{00C1}{\'A}% + \DeclareUnicodeCharacter{00C2}{\^A}% + \DeclareUnicodeCharacter{00C3}{\~A}% + \DeclareUnicodeCharacter{00C4}{\"A}% + \DeclareUnicodeCharacter{00C5}{\AA}% + \DeclareUnicodeCharacter{00C6}{\AE}% + \DeclareUnicodeCharacter{00C7}{\cedilla{C}}% + \DeclareUnicodeCharacter{00C8}{\`E}% + \DeclareUnicodeCharacter{00C9}{\'E}% + \DeclareUnicodeCharacter{00CA}{\^E}% + \DeclareUnicodeCharacter{00CB}{\"E}% + \DeclareUnicodeCharacter{00CC}{\`I}% + \DeclareUnicodeCharacter{00CD}{\'I}% + \DeclareUnicodeCharacter{00CE}{\^I}% + \DeclareUnicodeCharacter{00CF}{\"I}% + % + \DeclareUnicodeCharacter{00D0}{\DH}% + \DeclareUnicodeCharacter{00D1}{\~N}% + \DeclareUnicodeCharacter{00D2}{\`O}% + \DeclareUnicodeCharacter{00D3}{\'O}% + \DeclareUnicodeCharacter{00D4}{\^O}% + \DeclareUnicodeCharacter{00D5}{\~O}% + \DeclareUnicodeCharacter{00D6}{\"O}% + \DeclareUnicodeCharacter{00D7}{\ensuremath\times}% + \DeclareUnicodeCharacter{00D8}{\O}% + \DeclareUnicodeCharacter{00D9}{\`U}% + \DeclareUnicodeCharacter{00DA}{\'U}% + \DeclareUnicodeCharacter{00DB}{\^U}% + \DeclareUnicodeCharacter{00DC}{\"U}% + \DeclareUnicodeCharacter{00DD}{\'Y}% + \DeclareUnicodeCharacter{00DE}{\TH}% + \DeclareUnicodeCharacter{00DF}{\ss}% + % + \DeclareUnicodeCharacter{00E0}{\`a}% + \DeclareUnicodeCharacter{00E1}{\'a}% + \DeclareUnicodeCharacter{00E2}{\^a}% + \DeclareUnicodeCharacter{00E3}{\~a}% + \DeclareUnicodeCharacter{00E4}{\"a}% + \DeclareUnicodeCharacter{00E5}{\aa}% + \DeclareUnicodeCharacter{00E6}{\ae}% + \DeclareUnicodeCharacter{00E7}{\cedilla{c}}% + \DeclareUnicodeCharacter{00E8}{\`e}% + \DeclareUnicodeCharacter{00E9}{\'e}% + \DeclareUnicodeCharacter{00EA}{\^e}% + \DeclareUnicodeCharacter{00EB}{\"e}% + \DeclareUnicodeCharacter{00EC}{\`{\dotless{i}}}% + \DeclareUnicodeCharacter{00ED}{\'{\dotless{i}}}% + \DeclareUnicodeCharacter{00EE}{\^{\dotless{i}}}% + \DeclareUnicodeCharacter{00EF}{\"{\dotless{i}}}% + % + \DeclareUnicodeCharacter{00F0}{\dh}% + \DeclareUnicodeCharacter{00F1}{\~n}% + \DeclareUnicodeCharacter{00F2}{\`o}% + \DeclareUnicodeCharacter{00F3}{\'o}% + \DeclareUnicodeCharacter{00F4}{\^o}% + \DeclareUnicodeCharacter{00F5}{\~o}% + \DeclareUnicodeCharacter{00F6}{\"o}% + \DeclareUnicodeCharacter{00F7}{\ensuremath\div}% + \DeclareUnicodeCharacter{00F8}{\o}% + \DeclareUnicodeCharacter{00F9}{\`u}% + \DeclareUnicodeCharacter{00FA}{\'u}% + \DeclareUnicodeCharacter{00FB}{\^u}% + \DeclareUnicodeCharacter{00FC}{\"u}% + \DeclareUnicodeCharacter{00FD}{\'y}% + \DeclareUnicodeCharacter{00FE}{\th}% + \DeclareUnicodeCharacter{00FF}{\"y}% + % + \DeclareUnicodeCharacter{0100}{\=A}% + \DeclareUnicodeCharacter{0101}{\=a}% + \DeclareUnicodeCharacter{0102}{\u{A}}% + \DeclareUnicodeCharacter{0103}{\u{a}}% + \DeclareUnicodeCharacter{0104}{\ogonek{A}}% + \DeclareUnicodeCharacter{0105}{\ogonek{a}}% + \DeclareUnicodeCharacter{0106}{\'C}% + \DeclareUnicodeCharacter{0107}{\'c}% + \DeclareUnicodeCharacter{0108}{\^C}% + \DeclareUnicodeCharacter{0109}{\^c}% + \DeclareUnicodeCharacter{010A}{\dotaccent{C}}% + \DeclareUnicodeCharacter{010B}{\dotaccent{c}}% + \DeclareUnicodeCharacter{010C}{\v{C}}% + \DeclareUnicodeCharacter{010D}{\v{c}}% + \DeclareUnicodeCharacter{010E}{\v{D}}% + \DeclareUnicodeCharacter{010F}{d'}% + % + \DeclareUnicodeCharacter{0110}{\DH}% + \DeclareUnicodeCharacter{0111}{\dh}% + \DeclareUnicodeCharacter{0112}{\=E}% + \DeclareUnicodeCharacter{0113}{\=e}% + \DeclareUnicodeCharacter{0114}{\u{E}}% + \DeclareUnicodeCharacter{0115}{\u{e}}% + \DeclareUnicodeCharacter{0116}{\dotaccent{E}}% + \DeclareUnicodeCharacter{0117}{\dotaccent{e}}% + \DeclareUnicodeCharacter{0118}{\ogonek{E}}% + \DeclareUnicodeCharacter{0119}{\ogonek{e}}% + \DeclareUnicodeCharacter{011A}{\v{E}}% + \DeclareUnicodeCharacter{011B}{\v{e}}% + \DeclareUnicodeCharacter{011C}{\^G}% + \DeclareUnicodeCharacter{011D}{\^g}% + \DeclareUnicodeCharacter{011E}{\u{G}}% + \DeclareUnicodeCharacter{011F}{\u{g}}% + % + \DeclareUnicodeCharacter{0120}{\dotaccent{G}}% + \DeclareUnicodeCharacter{0121}{\dotaccent{g}}% + \DeclareUnicodeCharacter{0122}{\cedilla{G}}% + \DeclareUnicodeCharacter{0123}{\cedilla{g}}% + \DeclareUnicodeCharacter{0124}{\^H}% + \DeclareUnicodeCharacter{0125}{\^h}% + \DeclareUnicodeCharacter{0126}{\missingcharmsg{H WITH STROKE}}% + \DeclareUnicodeCharacter{0127}{\missingcharmsg{h WITH STROKE}}% + \DeclareUnicodeCharacter{0128}{\~I}% + \DeclareUnicodeCharacter{0129}{\~{\dotless{i}}}% + \DeclareUnicodeCharacter{012A}{\=I}% + \DeclareUnicodeCharacter{012B}{\={\dotless{i}}}% + \DeclareUnicodeCharacter{012C}{\u{I}}% + \DeclareUnicodeCharacter{012D}{\u{\dotless{i}}}% + \DeclareUnicodeCharacter{012E}{\ogonek{I}}% + \DeclareUnicodeCharacter{012F}{\ogonek{i}}% + % + \DeclareUnicodeCharacter{0130}{\dotaccent{I}}% + \DeclareUnicodeCharacter{0131}{\dotless{i}}% + \DeclareUnicodeCharacter{0132}{IJ}% + \DeclareUnicodeCharacter{0133}{ij}% + \DeclareUnicodeCharacter{0134}{\^J}% + \DeclareUnicodeCharacter{0135}{\^{\dotless{j}}}% + \DeclareUnicodeCharacter{0136}{\cedilla{K}}% + \DeclareUnicodeCharacter{0137}{\cedilla{k}}% + \DeclareUnicodeCharacter{0138}{\ensuremath\kappa}% + \DeclareUnicodeCharacter{0139}{\'L}% + \DeclareUnicodeCharacter{013A}{\'l}% + \DeclareUnicodeCharacter{013B}{\cedilla{L}}% + \DeclareUnicodeCharacter{013C}{\cedilla{l}}% + \DeclareUnicodeCharacter{013D}{L'}% should kern + \DeclareUnicodeCharacter{013E}{l'}% should kern + \DeclareUnicodeCharacter{013F}{L\U{00B7}}% + % + \DeclareUnicodeCharacter{0140}{l\U{00B7}}% + \DeclareUnicodeCharacter{0141}{\L}% + \DeclareUnicodeCharacter{0142}{\l}% + \DeclareUnicodeCharacter{0143}{\'N}% + \DeclareUnicodeCharacter{0144}{\'n}% + \DeclareUnicodeCharacter{0145}{\cedilla{N}}% + \DeclareUnicodeCharacter{0146}{\cedilla{n}}% + \DeclareUnicodeCharacter{0147}{\v{N}}% + \DeclareUnicodeCharacter{0148}{\v{n}}% + \DeclareUnicodeCharacter{0149}{'n}% + \DeclareUnicodeCharacter{014A}{\missingcharmsg{ENG}}% + \DeclareUnicodeCharacter{014B}{\missingcharmsg{eng}}% + \DeclareUnicodeCharacter{014C}{\=O}% + \DeclareUnicodeCharacter{014D}{\=o}% + \DeclareUnicodeCharacter{014E}{\u{O}}% + \DeclareUnicodeCharacter{014F}{\u{o}}% + % + \DeclareUnicodeCharacter{0150}{\H{O}}% + \DeclareUnicodeCharacter{0151}{\H{o}}% + \DeclareUnicodeCharacter{0152}{\OE}% + \DeclareUnicodeCharacter{0153}{\oe}% + \DeclareUnicodeCharacter{0154}{\'R}% + \DeclareUnicodeCharacter{0155}{\'r}% + \DeclareUnicodeCharacter{0156}{\cedilla{R}}% + \DeclareUnicodeCharacter{0157}{\cedilla{r}}% + \DeclareUnicodeCharacter{0158}{\v{R}}% + \DeclareUnicodeCharacter{0159}{\v{r}}% + \DeclareUnicodeCharacter{015A}{\'S}% + \DeclareUnicodeCharacter{015B}{\'s}% + \DeclareUnicodeCharacter{015C}{\^S}% + \DeclareUnicodeCharacter{015D}{\^s}% + \DeclareUnicodeCharacter{015E}{\cedilla{S}}% + \DeclareUnicodeCharacter{015F}{\cedilla{s}}% + % + \DeclareUnicodeCharacter{0160}{\v{S}}% + \DeclareUnicodeCharacter{0161}{\v{s}}% + \DeclareUnicodeCharacter{0162}{\cedilla{T}}% + \DeclareUnicodeCharacter{0163}{\cedilla{t}}% + \DeclareUnicodeCharacter{0164}{\v{T}}% + \DeclareUnicodeCharacter{0165}{\v{t}}% + \DeclareUnicodeCharacter{0166}{\missingcharmsg{H WITH STROKE}}% + \DeclareUnicodeCharacter{0167}{\missingcharmsg{h WITH STROKE}}% + \DeclareUnicodeCharacter{0168}{\~U}% + \DeclareUnicodeCharacter{0169}{\~u}% + \DeclareUnicodeCharacter{016A}{\=U}% + \DeclareUnicodeCharacter{016B}{\=u}% + \DeclareUnicodeCharacter{016C}{\u{U}}% + \DeclareUnicodeCharacter{016D}{\u{u}}% + \DeclareUnicodeCharacter{016E}{\ringaccent{U}}% + \DeclareUnicodeCharacter{016F}{\ringaccent{u}}% + % + \DeclareUnicodeCharacter{0170}{\H{U}}% + \DeclareUnicodeCharacter{0171}{\H{u}}% + \DeclareUnicodeCharacter{0172}{\ogonek{U}}% + \DeclareUnicodeCharacter{0173}{\ogonek{u}}% + \DeclareUnicodeCharacter{0174}{\^W}% + \DeclareUnicodeCharacter{0175}{\^w}% + \DeclareUnicodeCharacter{0176}{\^Y}% + \DeclareUnicodeCharacter{0177}{\^y}% + \DeclareUnicodeCharacter{0178}{\"Y}% + \DeclareUnicodeCharacter{0179}{\'Z}% + \DeclareUnicodeCharacter{017A}{\'z}% + \DeclareUnicodeCharacter{017B}{\dotaccent{Z}}% + \DeclareUnicodeCharacter{017C}{\dotaccent{z}}% + \DeclareUnicodeCharacter{017D}{\v{Z}}% + \DeclareUnicodeCharacter{017E}{\v{z}}% + \DeclareUnicodeCharacter{017F}{\missingcharmsg{LONG S}}% + % + \DeclareUnicodeCharacter{01C4}{D\v{Z}}% + \DeclareUnicodeCharacter{01C5}{D\v{z}}% + \DeclareUnicodeCharacter{01C6}{d\v{z}}% + \DeclareUnicodeCharacter{01C7}{LJ}% + \DeclareUnicodeCharacter{01C8}{Lj}% + \DeclareUnicodeCharacter{01C9}{lj}% + \DeclareUnicodeCharacter{01CA}{NJ}% + \DeclareUnicodeCharacter{01CB}{Nj}% + \DeclareUnicodeCharacter{01CC}{nj}% + \DeclareUnicodeCharacter{01CD}{\v{A}}% + \DeclareUnicodeCharacter{01CE}{\v{a}}% + \DeclareUnicodeCharacter{01CF}{\v{I}}% + % + \DeclareUnicodeCharacter{01D0}{\v{\dotless{i}}}% + \DeclareUnicodeCharacter{01D1}{\v{O}}% + \DeclareUnicodeCharacter{01D2}{\v{o}}% + \DeclareUnicodeCharacter{01D3}{\v{U}}% + \DeclareUnicodeCharacter{01D4}{\v{u}}% + % + \DeclareUnicodeCharacter{01E2}{\={\AE}}% + \DeclareUnicodeCharacter{01E3}{\={\ae}}% + \DeclareUnicodeCharacter{01E6}{\v{G}}% + \DeclareUnicodeCharacter{01E7}{\v{g}}% + \DeclareUnicodeCharacter{01E8}{\v{K}}% + \DeclareUnicodeCharacter{01E9}{\v{k}}% + % + \DeclareUnicodeCharacter{01F0}{\v{\dotless{j}}}% + \DeclareUnicodeCharacter{01F1}{DZ}% + \DeclareUnicodeCharacter{01F2}{Dz}% + \DeclareUnicodeCharacter{01F3}{dz}% + \DeclareUnicodeCharacter{01F4}{\'G}% + \DeclareUnicodeCharacter{01F5}{\'g}% + \DeclareUnicodeCharacter{01F8}{\`N}% + \DeclareUnicodeCharacter{01F9}{\`n}% + \DeclareUnicodeCharacter{01FC}{\'{\AE}}% + \DeclareUnicodeCharacter{01FD}{\'{\ae}}% + \DeclareUnicodeCharacter{01FE}{\'{\O}}% + \DeclareUnicodeCharacter{01FF}{\'{\o}}% + % + \DeclareUnicodeCharacter{021E}{\v{H}}% + \DeclareUnicodeCharacter{021F}{\v{h}}% + % + \DeclareUnicodeCharacter{0226}{\dotaccent{A}}% + \DeclareUnicodeCharacter{0227}{\dotaccent{a}}% + \DeclareUnicodeCharacter{0228}{\cedilla{E}}% + \DeclareUnicodeCharacter{0229}{\cedilla{e}}% + \DeclareUnicodeCharacter{022E}{\dotaccent{O}}% + \DeclareUnicodeCharacter{022F}{\dotaccent{o}}% + % + \DeclareUnicodeCharacter{0232}{\=Y}% + \DeclareUnicodeCharacter{0233}{\=y}% + \DeclareUnicodeCharacter{0237}{\dotless{j}}% + % + \DeclareUnicodeCharacter{02DB}{\ogonek{ }}% + % + % Greek letters upper case + \DeclareUnicodeCharacter{0391}{{\it A}}% + \DeclareUnicodeCharacter{0392}{{\it B}}% + \DeclareUnicodeCharacter{0393}{\ensuremath{\mit\Gamma}}% + \DeclareUnicodeCharacter{0394}{\ensuremath{\mit\Delta}}% + \DeclareUnicodeCharacter{0395}{{\it E}}% + \DeclareUnicodeCharacter{0396}{{\it Z}}% + \DeclareUnicodeCharacter{0397}{{\it H}}% + \DeclareUnicodeCharacter{0398}{\ensuremath{\mit\Theta}}% + \DeclareUnicodeCharacter{0399}{{\it I}}% + \DeclareUnicodeCharacter{039A}{{\it K}}% + \DeclareUnicodeCharacter{039B}{\ensuremath{\mit\Lambda}}% + \DeclareUnicodeCharacter{039C}{{\it M}}% + \DeclareUnicodeCharacter{039D}{{\it N}}% + \DeclareUnicodeCharacter{039E}{\ensuremath{\mit\Xi}}% + \DeclareUnicodeCharacter{039F}{{\it O}}% + \DeclareUnicodeCharacter{03A0}{\ensuremath{\mit\Pi}}% + \DeclareUnicodeCharacter{03A1}{{\it P}}% + %\DeclareUnicodeCharacter{03A2}{} % none - corresponds to final sigma + \DeclareUnicodeCharacter{03A3}{\ensuremath{\mit\Sigma}}% + \DeclareUnicodeCharacter{03A4}{{\it T}}% + \DeclareUnicodeCharacter{03A5}{\ensuremath{\mit\Upsilon}}% + \DeclareUnicodeCharacter{03A6}{\ensuremath{\mit\Phi}}% + \DeclareUnicodeCharacter{03A7}{{\it X}}% + \DeclareUnicodeCharacter{03A8}{\ensuremath{\mit\Psi}}% + \DeclareUnicodeCharacter{03A9}{\ensuremath{\mit\Omega}}% + % + % Vowels with accents + \DeclareUnicodeCharacter{0390}{\ensuremath{\ddot{\acute\iota}}}% + \DeclareUnicodeCharacter{03AC}{\ensuremath{\acute\alpha}}% + \DeclareUnicodeCharacter{03AD}{\ensuremath{\acute\epsilon}}% + \DeclareUnicodeCharacter{03AE}{\ensuremath{\acute\eta}}% + \DeclareUnicodeCharacter{03AF}{\ensuremath{\acute\iota}}% + \DeclareUnicodeCharacter{03B0}{\ensuremath{\acute{\ddot\upsilon}}}% + % + % Standalone accent + \DeclareUnicodeCharacter{0384}{\ensuremath{\acute{\ }}}% + % + % Greek letters lower case + \DeclareUnicodeCharacter{03B1}{\ensuremath\alpha}% + \DeclareUnicodeCharacter{03B2}{\ensuremath\beta}% + \DeclareUnicodeCharacter{03B3}{\ensuremath\gamma}% + \DeclareUnicodeCharacter{03B4}{\ensuremath\delta}% + \DeclareUnicodeCharacter{03B5}{\ensuremath\epsilon}% + \DeclareUnicodeCharacter{03B6}{\ensuremath\zeta}% + \DeclareUnicodeCharacter{03B7}{\ensuremath\eta}% + \DeclareUnicodeCharacter{03B8}{\ensuremath\theta}% + \DeclareUnicodeCharacter{03B9}{\ensuremath\iota}% + \DeclareUnicodeCharacter{03BA}{\ensuremath\kappa}% + \DeclareUnicodeCharacter{03BB}{\ensuremath\lambda}% + \DeclareUnicodeCharacter{03BC}{\ensuremath\mu}% + \DeclareUnicodeCharacter{03BD}{\ensuremath\nu}% + \DeclareUnicodeCharacter{03BE}{\ensuremath\xi}% + \DeclareUnicodeCharacter{03BF}{{\it o}}% omicron + \DeclareUnicodeCharacter{03C0}{\ensuremath\pi}% + \DeclareUnicodeCharacter{03C1}{\ensuremath\rho}% + \DeclareUnicodeCharacter{03C2}{\ensuremath\varsigma}% + \DeclareUnicodeCharacter{03C3}{\ensuremath\sigma}% + \DeclareUnicodeCharacter{03C4}{\ensuremath\tau}% + \DeclareUnicodeCharacter{03C5}{\ensuremath\upsilon}% + \DeclareUnicodeCharacter{03C6}{\ensuremath\phi}% + \DeclareUnicodeCharacter{03C7}{\ensuremath\chi}% + \DeclareUnicodeCharacter{03C8}{\ensuremath\psi}% + \DeclareUnicodeCharacter{03C9}{\ensuremath\omega}% + % + % More Greek vowels with accents + \DeclareUnicodeCharacter{03CA}{\ensuremath{\ddot\iota}}% + \DeclareUnicodeCharacter{03CB}{\ensuremath{\ddot\upsilon}}% + \DeclareUnicodeCharacter{03CC}{\ensuremath{\acute o}}% + \DeclareUnicodeCharacter{03CD}{\ensuremath{\acute\upsilon}}% + \DeclareUnicodeCharacter{03CE}{\ensuremath{\acute\omega}}% + % + % Variant Greek letters + \DeclareUnicodeCharacter{03D1}{\ensuremath\vartheta}% + \DeclareUnicodeCharacter{03D6}{\ensuremath\varpi}% + \DeclareUnicodeCharacter{03F1}{\ensuremath\varrho}% + % + \DeclareUnicodeCharacter{1E02}{\dotaccent{B}}% + \DeclareUnicodeCharacter{1E03}{\dotaccent{b}}% + \DeclareUnicodeCharacter{1E04}{\udotaccent{B}}% + \DeclareUnicodeCharacter{1E05}{\udotaccent{b}}% + \DeclareUnicodeCharacter{1E06}{\ubaraccent{B}}% + \DeclareUnicodeCharacter{1E07}{\ubaraccent{b}}% + \DeclareUnicodeCharacter{1E0A}{\dotaccent{D}}% + \DeclareUnicodeCharacter{1E0B}{\dotaccent{d}}% + \DeclareUnicodeCharacter{1E0C}{\udotaccent{D}}% + \DeclareUnicodeCharacter{1E0D}{\udotaccent{d}}% + \DeclareUnicodeCharacter{1E0E}{\ubaraccent{D}}% + \DeclareUnicodeCharacter{1E0F}{\ubaraccent{d}}% + % + \DeclareUnicodeCharacter{1E1E}{\dotaccent{F}}% + \DeclareUnicodeCharacter{1E1F}{\dotaccent{f}}% + % + \DeclareUnicodeCharacter{1E20}{\=G}% + \DeclareUnicodeCharacter{1E21}{\=g}% + \DeclareUnicodeCharacter{1E22}{\dotaccent{H}}% + \DeclareUnicodeCharacter{1E23}{\dotaccent{h}}% + \DeclareUnicodeCharacter{1E24}{\udotaccent{H}}% + \DeclareUnicodeCharacter{1E25}{\udotaccent{h}}% + \DeclareUnicodeCharacter{1E26}{\"H}% + \DeclareUnicodeCharacter{1E27}{\"h}% + % + \DeclareUnicodeCharacter{1E30}{\'K}% + \DeclareUnicodeCharacter{1E31}{\'k}% + \DeclareUnicodeCharacter{1E32}{\udotaccent{K}}% + \DeclareUnicodeCharacter{1E33}{\udotaccent{k}}% + \DeclareUnicodeCharacter{1E34}{\ubaraccent{K}}% + \DeclareUnicodeCharacter{1E35}{\ubaraccent{k}}% + \DeclareUnicodeCharacter{1E36}{\udotaccent{L}}% + \DeclareUnicodeCharacter{1E37}{\udotaccent{l}}% + \DeclareUnicodeCharacter{1E3A}{\ubaraccent{L}}% + \DeclareUnicodeCharacter{1E3B}{\ubaraccent{l}}% + \DeclareUnicodeCharacter{1E3E}{\'M}% + \DeclareUnicodeCharacter{1E3F}{\'m}% + % + \DeclareUnicodeCharacter{1E40}{\dotaccent{M}}% + \DeclareUnicodeCharacter{1E41}{\dotaccent{m}}% + \DeclareUnicodeCharacter{1E42}{\udotaccent{M}}% + \DeclareUnicodeCharacter{1E43}{\udotaccent{m}}% + \DeclareUnicodeCharacter{1E44}{\dotaccent{N}}% + \DeclareUnicodeCharacter{1E45}{\dotaccent{n}}% + \DeclareUnicodeCharacter{1E46}{\udotaccent{N}}% + \DeclareUnicodeCharacter{1E47}{\udotaccent{n}}% + \DeclareUnicodeCharacter{1E48}{\ubaraccent{N}}% + \DeclareUnicodeCharacter{1E49}{\ubaraccent{n}}% + % + \DeclareUnicodeCharacter{1E54}{\'P}% + \DeclareUnicodeCharacter{1E55}{\'p}% + \DeclareUnicodeCharacter{1E56}{\dotaccent{P}}% + \DeclareUnicodeCharacter{1E57}{\dotaccent{p}}% + \DeclareUnicodeCharacter{1E58}{\dotaccent{R}}% + \DeclareUnicodeCharacter{1E59}{\dotaccent{r}}% + \DeclareUnicodeCharacter{1E5A}{\udotaccent{R}}% + \DeclareUnicodeCharacter{1E5B}{\udotaccent{r}}% + \DeclareUnicodeCharacter{1E5E}{\ubaraccent{R}}% + \DeclareUnicodeCharacter{1E5F}{\ubaraccent{r}}% + % + \DeclareUnicodeCharacter{1E60}{\dotaccent{S}}% + \DeclareUnicodeCharacter{1E61}{\dotaccent{s}}% + \DeclareUnicodeCharacter{1E62}{\udotaccent{S}}% + \DeclareUnicodeCharacter{1E63}{\udotaccent{s}}% + \DeclareUnicodeCharacter{1E6A}{\dotaccent{T}}% + \DeclareUnicodeCharacter{1E6B}{\dotaccent{t}}% + \DeclareUnicodeCharacter{1E6C}{\udotaccent{T}}% + \DeclareUnicodeCharacter{1E6D}{\udotaccent{t}}% + \DeclareUnicodeCharacter{1E6E}{\ubaraccent{T}}% + \DeclareUnicodeCharacter{1E6F}{\ubaraccent{t}}% + % + \DeclareUnicodeCharacter{1E7C}{\~V}% + \DeclareUnicodeCharacter{1E7D}{\~v}% + \DeclareUnicodeCharacter{1E7E}{\udotaccent{V}}% + \DeclareUnicodeCharacter{1E7F}{\udotaccent{v}}% + % + \DeclareUnicodeCharacter{1E80}{\`W}% + \DeclareUnicodeCharacter{1E81}{\`w}% + \DeclareUnicodeCharacter{1E82}{\'W}% + \DeclareUnicodeCharacter{1E83}{\'w}% + \DeclareUnicodeCharacter{1E84}{\"W}% + \DeclareUnicodeCharacter{1E85}{\"w}% + \DeclareUnicodeCharacter{1E86}{\dotaccent{W}}% + \DeclareUnicodeCharacter{1E87}{\dotaccent{w}}% + \DeclareUnicodeCharacter{1E88}{\udotaccent{W}}% + \DeclareUnicodeCharacter{1E89}{\udotaccent{w}}% + \DeclareUnicodeCharacter{1E8A}{\dotaccent{X}}% + \DeclareUnicodeCharacter{1E8B}{\dotaccent{x}}% + \DeclareUnicodeCharacter{1E8C}{\"X}% + \DeclareUnicodeCharacter{1E8D}{\"x}% + \DeclareUnicodeCharacter{1E8E}{\dotaccent{Y}}% + \DeclareUnicodeCharacter{1E8F}{\dotaccent{y}}% + % + \DeclareUnicodeCharacter{1E90}{\^Z}% + \DeclareUnicodeCharacter{1E91}{\^z}% + \DeclareUnicodeCharacter{1E92}{\udotaccent{Z}}% + \DeclareUnicodeCharacter{1E93}{\udotaccent{z}}% + \DeclareUnicodeCharacter{1E94}{\ubaraccent{Z}}% + \DeclareUnicodeCharacter{1E95}{\ubaraccent{z}}% + \DeclareUnicodeCharacter{1E96}{\ubaraccent{h}}% + \DeclareUnicodeCharacter{1E97}{\"t}% + \DeclareUnicodeCharacter{1E98}{\ringaccent{w}}% + \DeclareUnicodeCharacter{1E99}{\ringaccent{y}}% + % + \DeclareUnicodeCharacter{1EA0}{\udotaccent{A}}% + \DeclareUnicodeCharacter{1EA1}{\udotaccent{a}}% + % + \DeclareUnicodeCharacter{1EB8}{\udotaccent{E}}% + \DeclareUnicodeCharacter{1EB9}{\udotaccent{e}}% + \DeclareUnicodeCharacter{1EBC}{\~E}% + \DeclareUnicodeCharacter{1EBD}{\~e}% + % + \DeclareUnicodeCharacter{1ECA}{\udotaccent{I}}% + \DeclareUnicodeCharacter{1ECB}{\udotaccent{i}}% + \DeclareUnicodeCharacter{1ECC}{\udotaccent{O}}% + \DeclareUnicodeCharacter{1ECD}{\udotaccent{o}}% + % + \DeclareUnicodeCharacter{1EE4}{\udotaccent{U}}% + \DeclareUnicodeCharacter{1EE5}{\udotaccent{u}}% + % + \DeclareUnicodeCharacter{1EF2}{\`Y}% + \DeclareUnicodeCharacter{1EF3}{\`y}% + \DeclareUnicodeCharacter{1EF4}{\udotaccent{Y}}% + % + \DeclareUnicodeCharacter{1EF8}{\~Y}% + \DeclareUnicodeCharacter{1EF9}{\~y}% + % + % Punctuation + \DeclareUnicodeCharacter{2013}{--}% + \DeclareUnicodeCharacter{2014}{---}% + \DeclareUnicodeCharacter{2018}{\quoteleft{}}% + \DeclareUnicodeCharacter{2019}{\quoteright{}}% + \DeclareUnicodeCharacter{201A}{\quotesinglbase{}}% + \DeclareUnicodeCharacter{201C}{\quotedblleft{}}% + \DeclareUnicodeCharacter{201D}{\quotedblright{}}% + \DeclareUnicodeCharacter{201E}{\quotedblbase{}}% + \DeclareUnicodeCharacter{2020}{\ensuremath\dagger}% + \DeclareUnicodeCharacter{2021}{\ensuremath\ddagger}% + \DeclareUnicodeCharacter{2022}{\bullet{}}% + \DeclareUnicodeCharacter{202F}{\thinspace}% + \DeclareUnicodeCharacter{2026}{\dots{}}% + \DeclareUnicodeCharacter{2039}{\guilsinglleft{}}% + \DeclareUnicodeCharacter{203A}{\guilsinglright{}}% + % + \DeclareUnicodeCharacter{20AC}{\euro{}}% + % + \DeclareUnicodeCharacter{2192}{\expansion{}}% + \DeclareUnicodeCharacter{21D2}{\result{}}% + % + % Mathematical symbols + \DeclareUnicodeCharacter{2200}{\ensuremath\forall}% + \DeclareUnicodeCharacter{2203}{\ensuremath\exists}% + \DeclareUnicodeCharacter{2208}{\ensuremath\in}% + \DeclareUnicodeCharacter{2212}{\minus{}}% + \DeclareUnicodeCharacter{2217}{\ast}% + \DeclareUnicodeCharacter{221E}{\ensuremath\infty}% + \DeclareUnicodeCharacter{2225}{\ensuremath\parallel}% + \DeclareUnicodeCharacter{2227}{\ensuremath\wedge}% + \DeclareUnicodeCharacter{2229}{\ensuremath\cap}% + \DeclareUnicodeCharacter{2261}{\equiv{}}% + \DeclareUnicodeCharacter{2264}{\ensuremath\leq}% + \DeclareUnicodeCharacter{2265}{\ensuremath\geq}% + \DeclareUnicodeCharacter{2282}{\ensuremath\subset}% + \DeclareUnicodeCharacter{2287}{\ensuremath\supseteq}% + % + \DeclareUnicodeCharacter{2016}{\ensuremath\Vert}% + \DeclareUnicodeCharacter{2032}{\ensuremath\prime}% + \DeclareUnicodeCharacter{210F}{\ensuremath\hbar}% + \DeclareUnicodeCharacter{2111}{\ensuremath\Im}% + \DeclareUnicodeCharacter{2113}{\ensuremath\ell}% + \DeclareUnicodeCharacter{2118}{\ensuremath\wp}% + \DeclareUnicodeCharacter{211C}{\ensuremath\Re}% + \DeclareUnicodeCharacter{2135}{\ensuremath\aleph}% + \DeclareUnicodeCharacter{2190}{\ensuremath\leftarrow}% + \DeclareUnicodeCharacter{2191}{\ensuremath\uparrow}% + \DeclareUnicodeCharacter{2193}{\ensuremath\downarrow}% + \DeclareUnicodeCharacter{2194}{\ensuremath\leftrightarrow}% + \DeclareUnicodeCharacter{2195}{\ensuremath\updownarrow}% + \DeclareUnicodeCharacter{2196}{\ensuremath\nwarrow}% + \DeclareUnicodeCharacter{2197}{\ensuremath\nearrow}% + \DeclareUnicodeCharacter{2198}{\ensuremath\searrow}% + \DeclareUnicodeCharacter{2199}{\ensuremath\swarrow}% + \DeclareUnicodeCharacter{21A6}{\ensuremath\mapsto}% + \DeclareUnicodeCharacter{21A9}{\ensuremath\hookleftarrow}% + \DeclareUnicodeCharacter{21AA}{\ensuremath\hookrightarrow}% + \DeclareUnicodeCharacter{21BC}{\ensuremath\leftharpoonup}% + \DeclareUnicodeCharacter{21BD}{\ensuremath\leftharpoondown}% + \DeclareUnicodeCharacter{21C0}{\ensuremath\rightharpoonup}% + \DeclareUnicodeCharacter{21C1}{\ensuremath\rightharpoondown}% + \DeclareUnicodeCharacter{21CC}{\ensuremath\rightleftharpoons}% + \DeclareUnicodeCharacter{21D0}{\ensuremath\Leftarrow}% + \DeclareUnicodeCharacter{21D1}{\ensuremath\Uparrow}% + \DeclareUnicodeCharacter{21D3}{\ensuremath\Downarrow}% + \DeclareUnicodeCharacter{21D4}{\ensuremath\Leftrightarrow}% + \DeclareUnicodeCharacter{21D5}{\ensuremath\Updownarrow}% + \DeclareUnicodeCharacter{2202}{\ensuremath\partial}% + \DeclareUnicodeCharacter{2205}{\ensuremath\emptyset}% + \DeclareUnicodeCharacter{2207}{\ensuremath\nabla}% + \DeclareUnicodeCharacter{2209}{\ensuremath\notin}% + \DeclareUnicodeCharacter{220B}{\ensuremath\owns}% + \DeclareUnicodeCharacter{220F}{\ensuremath\prod}% + \DeclareUnicodeCharacter{2210}{\ensuremath\coprod}% + \DeclareUnicodeCharacter{2211}{\ensuremath\sum}% + \DeclareUnicodeCharacter{2213}{\ensuremath\mp}% + \DeclareUnicodeCharacter{2218}{\ensuremath\circ}% + \DeclareUnicodeCharacter{221A}{\ensuremath\surd}% + \DeclareUnicodeCharacter{221D}{\ensuremath\propto}% + \DeclareUnicodeCharacter{2220}{\ensuremath\angle}% + \DeclareUnicodeCharacter{2223}{\ensuremath\mid}% + \DeclareUnicodeCharacter{2228}{\ensuremath\vee}% + \DeclareUnicodeCharacter{222A}{\ensuremath\cup}% + \DeclareUnicodeCharacter{222B}{\ensuremath\smallint}% + \DeclareUnicodeCharacter{222E}{\ensuremath\oint}% + \DeclareUnicodeCharacter{223C}{\ensuremath\sim}% + \DeclareUnicodeCharacter{2240}{\ensuremath\wr}% + \DeclareUnicodeCharacter{2243}{\ensuremath\simeq}% + \DeclareUnicodeCharacter{2245}{\ensuremath\cong}% + \DeclareUnicodeCharacter{2248}{\ensuremath\approx}% + \DeclareUnicodeCharacter{224D}{\ensuremath\asymp}% + \DeclareUnicodeCharacter{2250}{\ensuremath\doteq}% + \DeclareUnicodeCharacter{2260}{\ensuremath\neq}% + \DeclareUnicodeCharacter{226A}{\ensuremath\ll}% + \DeclareUnicodeCharacter{226B}{\ensuremath\gg}% + \DeclareUnicodeCharacter{227A}{\ensuremath\prec}% + \DeclareUnicodeCharacter{227B}{\ensuremath\succ}% + \DeclareUnicodeCharacter{2283}{\ensuremath\supset}% + \DeclareUnicodeCharacter{2286}{\ensuremath\subseteq}% + \DeclareUnicodeCharacter{228E}{\ensuremath\uplus}% + \DeclareUnicodeCharacter{2291}{\ensuremath\sqsubseteq}% + \DeclareUnicodeCharacter{2292}{\ensuremath\sqsupseteq}% + \DeclareUnicodeCharacter{2293}{\ensuremath\sqcap}% + \DeclareUnicodeCharacter{2294}{\ensuremath\sqcup}% + \DeclareUnicodeCharacter{2295}{\ensuremath\oplus}% + \DeclareUnicodeCharacter{2296}{\ensuremath\ominus}% + \DeclareUnicodeCharacter{2297}{\ensuremath\otimes}% + \DeclareUnicodeCharacter{2298}{\ensuremath\oslash}% + \DeclareUnicodeCharacter{2299}{\ensuremath\odot}% + \DeclareUnicodeCharacter{22A2}{\ensuremath\vdash}% + \DeclareUnicodeCharacter{22A3}{\ensuremath\dashv}% + \DeclareUnicodeCharacter{22A4}{\ensuremath\ptextop}% + \DeclareUnicodeCharacter{22A5}{\ensuremath\bot}% + \DeclareUnicodeCharacter{22A8}{\ensuremath\models}% + \DeclareUnicodeCharacter{22C0}{\ensuremath\bigwedge}% + \DeclareUnicodeCharacter{22C1}{\ensuremath\bigvee}% + \DeclareUnicodeCharacter{22C2}{\ensuremath\bigcap}% + \DeclareUnicodeCharacter{22C3}{\ensuremath\bigcup}% + \DeclareUnicodeCharacter{22C4}{\ensuremath\diamond}% + \DeclareUnicodeCharacter{22C5}{\ensuremath\cdot}% + \DeclareUnicodeCharacter{22C6}{\ensuremath\star}% + \DeclareUnicodeCharacter{22C8}{\ensuremath\bowtie}% + \DeclareUnicodeCharacter{2308}{\ensuremath\lceil}% + \DeclareUnicodeCharacter{2309}{\ensuremath\rceil}% + \DeclareUnicodeCharacter{230A}{\ensuremath\lfloor}% + \DeclareUnicodeCharacter{230B}{\ensuremath\rfloor}% + \DeclareUnicodeCharacter{2322}{\ensuremath\frown}% + \DeclareUnicodeCharacter{2323}{\ensuremath\smile}% + % + \DeclareUnicodeCharacter{25B3}{\ensuremath\triangle}% + \DeclareUnicodeCharacter{25B7}{\ensuremath\triangleright}% + \DeclareUnicodeCharacter{25BD}{\ensuremath\bigtriangledown}% + \DeclareUnicodeCharacter{25C1}{\ensuremath\triangleleft}% + \DeclareUnicodeCharacter{25C7}{\ensuremath\diamond}% + \DeclareUnicodeCharacter{2660}{\ensuremath\spadesuit}% + \DeclareUnicodeCharacter{2661}{\ensuremath\heartsuit}% + \DeclareUnicodeCharacter{2662}{\ensuremath\diamondsuit}% + \DeclareUnicodeCharacter{2663}{\ensuremath\clubsuit}% + \DeclareUnicodeCharacter{266D}{\ensuremath\flat}% + \DeclareUnicodeCharacter{266E}{\ensuremath\natural}% + \DeclareUnicodeCharacter{266F}{\ensuremath\sharp}% + \DeclareUnicodeCharacter{26AA}{\ensuremath\bigcirc}% + \DeclareUnicodeCharacter{27B9}{\ensuremath\rangle}% + \DeclareUnicodeCharacter{27C2}{\ensuremath\perp}% + \DeclareUnicodeCharacter{27E8}{\ensuremath\langle}% + \DeclareUnicodeCharacter{27F5}{\ensuremath\longleftarrow}% + \DeclareUnicodeCharacter{27F6}{\ensuremath\longrightarrow}% + \DeclareUnicodeCharacter{27F7}{\ensuremath\longleftrightarrow}% + \DeclareUnicodeCharacter{27FC}{\ensuremath\longmapsto}% + \DeclareUnicodeCharacter{29F5}{\ensuremath\setminus}% + \DeclareUnicodeCharacter{2A00}{\ensuremath\bigodot}% + \DeclareUnicodeCharacter{2A01}{\ensuremath\bigoplus}% + \DeclareUnicodeCharacter{2A02}{\ensuremath\bigotimes}% + \DeclareUnicodeCharacter{2A04}{\ensuremath\biguplus}% + \DeclareUnicodeCharacter{2A06}{\ensuremath\bigsqcup}% + \DeclareUnicodeCharacter{2A3F}{\ensuremath\amalg}% + \DeclareUnicodeCharacter{2AAF}{\ensuremath\preceq}% + \DeclareUnicodeCharacter{2AB0}{\ensuremath\succeq}% + % + \global\mathchardef\checkmark="1370% actually the square root sign + \DeclareUnicodeCharacter{2713}{\ensuremath\checkmark}% +}% end of \unicodechardefs + +% UTF-8 byte sequence (pdfTeX) definitions (replacing and @U command) +% It makes the setting that replace UTF-8 byte sequence. +\def\utfeightchardefs{% + \let\DeclareUnicodeCharacter\DeclareUnicodeCharacterUTFviii + \unicodechardefs +} + +% Whether the active definitions of non-ASCII characters expand to +% non-active tokens with the same character code. This is used to +% write characters literally, instead of using active definitions for +% printing the correct glyphs. +\newif\ifpassthroughchars +\passthroughcharsfalse + +% For native Unicode handling (XeTeX and LuaTeX), +% provide a definition macro to replace/pass-through a Unicode character +% +\def\DeclareUnicodeCharacterNative#1#2{% + \catcode"#1=\active + \def\dodeclareunicodecharacternative##1##2##3{% + \begingroup + \uccode`\~="##2\relax + \uppercase{\gdef~}{% + \ifpassthroughchars + ##1% + \else + ##3% + \fi + } + \endgroup + } + \begingroup + \uccode`\.="#1\relax + \uppercase{\def\UTFNativeTmp{.}}% + \expandafter\dodeclareunicodecharacternative\UTFNativeTmp{#1}{#2}% + \endgroup +} + +% Native Unicode handling (XeTeX and LuaTeX) character replacing definition. +% It activates the setting that replaces Unicode characters. +\def\nativeunicodechardefs{% + \let\DeclareUnicodeCharacter\DeclareUnicodeCharacterNative + \unicodechardefs +} + +% For native Unicode handling (XeTeX and LuaTeX), +% make the character token expand +% to the sequences given in \unicodechardefs for printing. +\def\DeclareUnicodeCharacterNativeAtU#1#2{% + \def\UTFAtUTmp{#2} + \expandafter\globallet\csname uni:#1\endcsname \UTFAtUTmp +} + +% @U command definitions for native Unicode handling (XeTeX and LuaTeX). +\def\nativeunicodechardefsatu{% + \let\DeclareUnicodeCharacter\DeclareUnicodeCharacterNativeAtU + \unicodechardefs +} + +% US-ASCII character definitions. +\def\asciichardefs{% nothing need be done + \relax +} + +% define all Unicode characters we know about, for the sake of @U. +\iftxinativeunicodecapable + \nativeunicodechardefsatu +\else + \utfeightchardefs +\fi + + +% Make non-ASCII characters printable again for compatibility with +% existing Texinfo documents that may use them, even without declaring a +% document encoding. +% +\setnonasciicharscatcode \other + + +\message{formatting,} + +\newdimen\defaultparindent \defaultparindent = 15pt + +\chapheadingskip = 15pt plus 4pt minus 2pt +\secheadingskip = 12pt plus 3pt minus 2pt +\subsecheadingskip = 9pt plus 2pt minus 2pt + +% Prevent underfull vbox error messages. +\vbadness = 10000 + +% Don't be very finicky about underfull hboxes, either. +\hbadness = 6666 + +% Following George Bush, get rid of widows and orphans. +\widowpenalty=10000 +\clubpenalty=10000 + +% Use TeX 3.0's \emergencystretch to help line breaking, but if we're +% using an old version of TeX, don't do anything. We want the amount of +% stretch added to depend on the line length, hence the dependence on +% \hsize. We call this whenever the paper size is set. +% +\def\setemergencystretch{% + \ifx\emergencystretch\thisisundefined + % Allow us to assign to \emergencystretch anyway. + \def\emergencystretch{\dimen0}% + \else + \emergencystretch = .15\hsize + \fi +} + +% Parameters in order: 1) textheight; 2) textwidth; +% 3) voffset; 4) hoffset; 5) binding offset; 6) topskip; +% 7) physical page height; 8) physical page width. +% +% We also call \setleading{\textleading}, so the caller should define +% \textleading. The caller should also set \parskip. +% +\def\internalpagesizes#1#2#3#4#5#6#7#8{% + \voffset = #3\relax + \topskip = #6\relax + \splittopskip = \topskip + % + \vsize = #1\relax + \advance\vsize by \topskip + \outervsize = \vsize + \advance\outervsize by 2\topandbottommargin + \txipageheight = \vsize + % + \hsize = #2\relax + \outerhsize = \hsize + \advance\outerhsize by 0.5in + \txipagewidth = \hsize + % + \normaloffset = #4\relax + \bindingoffset = #5\relax + % + \ifpdf + \pdfpageheight #7\relax + \pdfpagewidth #8\relax + % if we don't reset these, they will remain at "1 true in" of + % whatever layout pdftex was dumped with. + \pdfhorigin = 1 true in + \pdfvorigin = 1 true in + \else + \ifx\XeTeXrevision\thisisundefined + \special{papersize=#8,#7}% + \else + \pdfpageheight #7\relax + \pdfpagewidth #8\relax + % XeTeX does not have \pdfhorigin and \pdfvorigin. + \fi + \fi + % + \setleading{\textleading} + % + \parindent = \defaultparindent + \setemergencystretch +} + +% @letterpaper (the default). +\def\letterpaper{{\globaldefs = 1 + \parskip = 3pt plus 2pt minus 1pt + \textleading = 13.2pt + % + % If page is nothing but text, make it come out even. + \internalpagesizes{607.2pt}{6in}% that's 46 lines + {\voffset}{.25in}% + {\bindingoffset}{36pt}% + {11in}{8.5in}% +}} + +% Use @smallbook to reset parameters for 7x9.25 trim size. +\def\smallbook{{\globaldefs = 1 + \parskip = 2pt plus 1pt + \textleading = 12pt + % + \internalpagesizes{7.5in}{5in}% + {-.2in}{0in}% + {\bindingoffset}{16pt}% + {9.25in}{7in}% + % + \lispnarrowing = 0.3in + \tolerance = 700 + \contentsrightmargin = 0pt + \defbodyindent = .5cm +}} + +% Use @smallerbook to reset parameters for 6x9 trim size. +% (Just testing, parameters still in flux.) +\def\smallerbook{{\globaldefs = 1 + \parskip = 1.5pt plus 1pt + \textleading = 12pt + % + \internalpagesizes{7.4in}{4.8in}% + {-.2in}{-.4in}% + {0pt}{14pt}% + {9in}{6in}% + % + \lispnarrowing = 0.25in + \tolerance = 700 + \contentsrightmargin = 0pt + \defbodyindent = .4cm +}} + +% Use @afourpaper to print on European A4 paper. +\def\afourpaper{{\globaldefs = 1 + \parskip = 3pt plus 2pt minus 1pt + \textleading = 13.2pt + % + % Double-side printing via postscript on Laserjet 4050 + % prints double-sided nicely when \bindingoffset=10mm and \hoffset=-6mm. + % To change the settings for a different printer or situation, adjust + % \normaloffset until the front-side and back-side texts align. Then + % do the same for \bindingoffset. You can set these for testing in + % your texinfo source file like this: + % @tex + % \global\normaloffset = -6mm + % \global\bindingoffset = 10mm + % @end tex + \internalpagesizes{673.2pt}{160mm}% that's 51 lines + {\voffset}{\hoffset}% + {\bindingoffset}{44pt}% + {297mm}{210mm}% + % + \tolerance = 700 + \contentsrightmargin = 0pt + \defbodyindent = 5mm +}} + +% Use @afivepaper to print on European A5 paper. +% From romildo@urano.iceb.ufop.br, 2 July 2000. +% He also recommends making @example and @lisp be small. +\def\afivepaper{{\globaldefs = 1 + \parskip = 2pt plus 1pt minus 0.1pt + \textleading = 12.5pt + % + \internalpagesizes{160mm}{120mm}% + {\voffset}{\hoffset}% + {\bindingoffset}{8pt}% + {210mm}{148mm}% + % + \lispnarrowing = 0.2in + \tolerance = 800 + \contentsrightmargin = 0pt + \defbodyindent = 2mm + \tableindent = 12mm +}} + +% A specific text layout, 24x15cm overall, intended for A4 paper. +\def\afourlatex{{\globaldefs = 1 + \afourpaper + \internalpagesizes{237mm}{150mm}% + {\voffset}{4.6mm}% + {\bindingoffset}{7mm}% + {297mm}{210mm}% + % + % Must explicitly reset to 0 because we call \afourpaper. + \globaldefs = 0 +}} + +% Use @afourwide to print on A4 paper in landscape format. +\def\afourwide{{\globaldefs = 1 + \afourpaper + \internalpagesizes{241mm}{165mm}% + {\voffset}{-2.95mm}% + {\bindingoffset}{7mm}% + {297mm}{210mm}% + \globaldefs = 0 +}} + +% @pagesizes TEXTHEIGHT[,TEXTWIDTH] +% Perhaps we should allow setting the margins, \topskip, \parskip, +% and/or leading, also. Or perhaps we should compute them somehow. +% +\parseargdef\pagesizes{\pagesizesyyy #1,,\finish} +\def\pagesizesyyy#1,#2,#3\finish{{% + \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \hsize=#2\relax \fi + \globaldefs = 1 + % + \parskip = 3pt plus 2pt minus 1pt + \setleading{\textleading}% + % + \dimen0 = #1\relax + \advance\dimen0 by \voffset + \advance\dimen0 by 1in % reference point for DVI is 1 inch from top of page + % + \dimen2 = \hsize + \advance\dimen2 by \normaloffset + \advance\dimen2 by 1in % reference point is 1 inch from left edge of page + % + \internalpagesizes{#1}{\hsize}% + {\voffset}{\normaloffset}% + {\bindingoffset}{44pt}% + {\dimen0}{\dimen2}% +}} + +% Set default to letter. +% +\letterpaper + +% Default value of \hfuzz, for suppressing warnings about overfull hboxes. +\hfuzz = 1pt + + +\message{and turning on texinfo input format.} + +\def^^L{\par} % remove \outer, so ^L can appear in an @comment + +% DEL is a comment character, in case @c does not suffice. +\catcode`\^^? = 14 + +% Define macros to output various characters with catcode for normal text. +\catcode`\"=\other \def\normaldoublequote{"} +\catcode`\$=\other \def\normaldollar{$}%$ font-lock fix +\catcode`\+=\other \def\normalplus{+} +\catcode`\<=\other \def\normalless{<} +\catcode`\>=\other \def\normalgreater{>} +\catcode`\^=\other \def\normalcaret{^} +\catcode`\_=\other \def\normalunderscore{_} +\catcode`\|=\other \def\normalverticalbar{|} +\catcode`\~=\other \def\normaltilde{~} + +% This macro is used to make a character print one way in \tt +% (where it can probably be output as-is), and another way in other fonts, +% where something hairier probably needs to be done. +% +% #1 is what to print if we are indeed using \tt; #2 is what to print +% otherwise. Since all the Computer Modern typewriter fonts have zero +% interword stretch (and shrink), and it is reasonable to expect all +% typewriter fonts to have this, we can check that font parameter. +% +\def\ifusingtt#1#2{\ifdim \fontdimen3\font=0pt #1\else #2\fi} + +% Same as above, but check for italic font. Actually this also catches +% non-italic slanted fonts since it is impossible to distinguish them from +% italic fonts. But since this is only used by $ and it uses \sl anyway +% this is not a problem. +\def\ifusingit#1#2{\ifdim \fontdimen1\font>0pt #1\else #2\fi} + +% Set catcodes for Texinfo file + +% Active characters for printing the wanted glyph. +% Most of these we simply print from the \tt font, but for some, we can +% use math or other variants that look better in normal text. +% +\catcode`\"=\active +\def\activedoublequote{{\tt\char34}} +\let"=\activedoublequote +\catcode`\~=\active \def\activetilde{{\tt\char126}} \let~ = \activetilde +\chardef\hatchar=`\^ +\catcode`\^=\active \def\activehat{{\tt \hatchar}} \let^ = \activehat + +\catcode`\_=\active +\def_{\ifusingtt\normalunderscore\_} +\def\_{\leavevmode \kern.07em \vbox{\hrule width.3em height.1ex}\kern .07em } +\let\realunder=_ + +\catcode`\|=\active \def|{{\tt\char124}} + +\chardef \less=`\< +\catcode`\<=\active \def\activeless{{\tt \less}}\let< = \activeless +\chardef \gtr=`\> +\catcode`\>=\active \def\activegtr{{\tt \gtr}}\let> = \activegtr +\catcode`\+=\active \def+{{\tt \char 43}} +\catcode`\$=\active \def${\ifusingit{{\sl\$}}\normaldollar}%$ font-lock fix +\catcode`\-=\active \let-=\normaldash + + +% used for headline/footline in the output routine, in case the page +% breaks in the middle of an @tex block. +\def\texinfochars{% + \let< = \activeless + \let> = \activegtr + \let~ = \activetilde + \let^ = \activehat + \markupsetuplqdefault \markupsetuprqdefault + \let\b = \strong + \let\i = \smartitalic + % in principle, all other definitions in \tex have to be undone too. +} + +% Used sometimes to turn off (effectively) the active characters even after +% parsing them. +\def\turnoffactive{% + \normalturnoffactive + \otherbackslash +} + +\catcode`\@=0 + +% \backslashcurfont outputs one backslash character in current font, +% as in \char`\\. +\global\chardef\backslashcurfont=`\\ +\global\let\rawbackslashxx=\backslashcurfont % let existing .??s files work + +% \realbackslash is an actual character `\' with catcode other, and +% \doublebackslash is two of them (for the pdf outlines). +{\catcode`\\=\other @gdef@realbackslash{\} @gdef@doublebackslash{\\}} + +% In Texinfo, backslash is an active character; it prints the backslash +% in fixed width font. +\catcode`\\=\active % @ for escape char from now on. + +% Print a typewriter backslash. For math mode, we can't simply use +% \backslashcurfont: the story here is that in math mode, the \char +% of \backslashcurfont ends up printing the roman \ from the math symbol +% font (because \char in math mode uses the \mathcode, and plain.tex +% sets \mathcode`\\="026E). Hence we use an explicit \mathchar, +% which is the decimal equivalent of "715c (class 7, e.g., use \fam; +% ignored family value; char position "5C). We can't use " for the +% usual hex value because it has already been made active. + +@def@ttbackslash{{@tt @ifmmode @mathchar29020 @else @backslashcurfont @fi}} +@let@backslashchar = @ttbackslash % @backslashchar{} is for user documents. + +% \rawbackslash defines an active \ to do \backslashcurfont. +% \otherbackslash defines an active \ to be a literal `\' character with +% catcode other. We switch back and forth between these. +@gdef@rawbackslash{@let\=@backslashcurfont} +@gdef@otherbackslash{@let\=@realbackslash} + +% Same as @turnoffactive except outputs \ as {\tt\char`\\} instead of +% the literal character `\'. +% +{@catcode`- = @active + @gdef@normalturnoffactive{% + @passthroughcharstrue + @let-=@normaldash + @let"=@normaldoublequote + @let$=@normaldollar %$ font-lock fix + @let+=@normalplus + @let<=@normalless + @let>=@normalgreater + @let^=@normalcaret + @let_=@normalunderscore + @let|=@normalverticalbar + @let~=@normaltilde + @let\=@ttbackslash + @markupsetuplqdefault + @markupsetuprqdefault + @unsepspaces + } +} + +% If a .fmt file is being used, characters that might appear in a file +% name cannot be active until we have parsed the command line. +% So turn them off again, and have @fixbackslash turn them back on. +@catcode`+=@other @catcode`@_=@other + +% \enablebackslashhack - allow file to begin `\input texinfo' +% +% If a .fmt file is being used, we don't want the `\input texinfo' to show up. +% That is what \eatinput is for; after that, the `\' should revert to printing +% a backslash. +% If the file did not have a `\input texinfo', then it is turned off after +% the first line; otherwise the first `\' in the file would cause an error. +% This is used on the very last line of this file, texinfo.tex. +% We also use @c to call @fixbackslash, in case ends of lines are hidden. +{ +@catcode`@^=7 +@catcode`@^^M=13@gdef@enablebackslashhack{% + @global@let\ = @eatinput% + @catcode`@^^M=13% + @def@c{@fixbackslash@c}% + % Definition for the newline at the end of this file. + @def ^^M{@let^^M@secondlinenl}% + % Definition for a newline in the main Texinfo file. + @gdef @secondlinenl{@fixbackslash}% + % In case the first line has a whole-line command on it + @let@originalparsearg@parsearg + @def@parsearg{@fixbackslash@originalparsearg} +}} + +{@catcode`@^=7 @catcode`@^^M=13% +@gdef@eatinput input texinfo#1^^M{@fixbackslash}} + +% Emergency active definition of newline, in case an active newline token +% appears by mistake. +{@catcode`@^=7 @catcode13=13% +@gdef@enableemergencynewline{% + @gdef^^M{% + @par% + %<warning: active newline>@par% +}}} + + +@gdef@fixbackslash{% + @ifx\@eatinput @let\ = @ttbackslash @fi + @catcode13=5 % regular end of line + @enableemergencynewline + @let@c=@texinfoc + @let@parsearg@originalparsearg + % Also turn back on active characters that might appear in the input + % file name, in case not using a pre-dumped format. + @catcode`+=@active + @catcode`@_=@active + % + % If texinfo.cnf is present on the system, read it. + % Useful for site-wide @afourpaper, etc. This macro, @fixbackslash, gets + % called at the beginning of every Texinfo file. Not opening texinfo.cnf + % directly in this file, texinfo.tex, makes it possible to make a format + % file for Texinfo. + % + @openin 1 texinfo.cnf + @ifeof 1 @else @input texinfo.cnf @fi + @closein 1 +} + + +% Say @foo, not \foo, in error messages. +@escapechar = `@@ + +% These (along with & and #) are made active for url-breaking, so need +% active definitions as the normal characters. +@def@normaldot{.} +@def@normalquest{?} +@def@normalslash{/} + +% These look ok in all fonts, so just make them not special. +% @hashchar{} gets its own user-level command, because of #line. +@catcode`@& = @other @def@normalamp{&} +@catcode`@# = @other @def@normalhash{#} +@catcode`@% = @other @def@normalpercent{%} + +@let @hashchar = @normalhash + +@c Finally, make ` and ' active, so that txicodequoteundirected and +@c txicodequotebacktick work right in, e.g., @w{@code{`foo'}}. If we +@c don't make ` and ' active, @code will not get them as active chars. +@c Do this last of all since we use ` in the previous @catcode assignments. +@catcode`@'=@active +@catcode`@`=@active +@markupsetuplqdefault +@markupsetuprqdefault + +@c Local variables: +@c eval: (add-hook 'write-file-hooks 'time-stamp) +@c page-delimiter: "^\\\\message\\|emacs-page" +@c time-stamp-start: "def\\\\texinfoversion{" +@c time-stamp-format: "%:y-%02m-%02d.%02H" +@c time-stamp-end: "}" +@c End: + +@c vim:sw=2: + +@enablebackslashhack diff --git a/config/unlocked-io.m4 b/config/unlocked-io.m4 new file mode 100644 index 0000000..657f60d --- /dev/null +++ b/config/unlocked-io.m4 @@ -0,0 +1,41 @@ +# unlocked-io.m4 serial 15 + +# Copyright (C) 1998-2006, 2009-2012, 2014-2015, 2018 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. + +dnl From Jim Meyering. +dnl +dnl See if the glibc *_unlocked I/O macros or functions are available. +dnl Use only those *_unlocked macros or functions that are declared +dnl (because some of them were declared in Solaris 2.5.1 but were removed +dnl in Solaris 2.6, whereas we want binaries built on Solaris 2.5.1 to run +dnl on Solaris 2.6). + +AC_DEFUN([gl_FUNC_GLIBC_UNLOCKED_IO], +[ + AC_DEFINE([USE_UNLOCKED_IO], [1], + [Define to 1 if you want getc etc. to use unlocked I/O if available. + Unlocked I/O can improve performance in unithreaded apps, + but it is not safe for multithreaded apps.]) + + dnl Persuade glibc and Solaris <stdio.h> to declare + dnl fgets_unlocked(), fputs_unlocked() etc. + AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) + + AC_CHECK_DECLS_ONCE([clearerr_unlocked]) + AC_CHECK_DECLS_ONCE([feof_unlocked]) + AC_CHECK_DECLS_ONCE([ferror_unlocked]) + AC_CHECK_DECLS_ONCE([fflush_unlocked]) + AC_CHECK_DECLS_ONCE([fgets_unlocked]) + AC_CHECK_DECLS_ONCE([fputc_unlocked]) + AC_CHECK_DECLS_ONCE([fputs_unlocked]) + AC_CHECK_DECLS_ONCE([fread_unlocked]) + AC_CHECK_DECLS_ONCE([fwrite_unlocked]) + AC_CHECK_DECLS_ONCE([getc_unlocked]) + AC_CHECK_DECLS_ONCE([getchar_unlocked]) + AC_CHECK_DECLS_ONCE([putc_unlocked]) + AC_CHECK_DECLS_ONCE([putchar_unlocked]) +]) diff --git a/configure b/configure new file mode 100755 index 0000000..f149ede --- /dev/null +++ b/configure @@ -0,0 +1,21317 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.69 for GNU AutoGen 5.18.16. +# +# Report bugs to <autogen-users@lists.sourceforge.net>. +# +# +# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. +# +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +## PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +# Use a proper internal environment variable to ensure we don't fall + # into an infinite loop, continuously re-executing ourselves. + if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then + _as_can_reexec=no; export _as_can_reexec; + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +as_fn_exit 255 + fi + # We don't want this to propagate to other subprocesses. + { _as_can_reexec=; unset _as_can_reexec;} +if test "x$CONFIG_SHELL" = x; then + as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi +" + as_required="as_fn_return () { (exit \$1); } +as_fn_success () { as_fn_return 0; } +as_fn_failure () { as_fn_return 1; } +as_fn_ret_success () { return 0; } +as_fn_ret_failure () { return 1; } + +exitcode=0 +as_fn_success || { exitcode=1; echo as_fn_success failed.; } +as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } +as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } +as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } +if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : + +else + exitcode=1; echo positional parameters were not saved. +fi +test x\$exitcode = x0 || exit 1 +test -x / || exit 1" + as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 +test \$(( 1 + 1 )) = 2 || exit 1 + + test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || ( + ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' + ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO + ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO + PATH=/empty FPATH=/empty; export PATH FPATH + test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\ + || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1" + if (eval "$as_required") 2>/dev/null; then : + as_have_required=yes +else + as_have_required=no +fi + if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : + +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + as_found=: + case $as_dir in #( + /*) + for as_base in sh bash ksh sh5; do + # Try only shells that exist, to save several forks. + as_shell=$as_dir/$as_base + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : + CONFIG_SHELL=$as_shell as_have_required=yes + if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : + break 2 +fi +fi + done;; + esac + as_found=false +done +$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : + CONFIG_SHELL=$SHELL as_have_required=yes +fi; } +IFS=$as_save_IFS + + + if test "x$CONFIG_SHELL" != x; then : + export CONFIG_SHELL + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +exit 255 +fi + + if test x$as_have_required = xno; then : + $as_echo "$0: This script requires a shell more modern than all" + $as_echo "$0: the shells that I found on your system." + if test x${ZSH_VERSION+set} = xset ; then + $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" + $as_echo "$0: be upgraded to zsh 4.3.4 or later." + else + $as_echo "$0: Please tell bug-autoconf@gnu.org and +$0: autogen-users@lists.sourceforge.net about your system, +$0: including any error possibly output before this +$0: message. Then install a modern shell, or manually run +$0: the script under such a shell if you do have one." + fi + exit 1 +fi +fi +fi +SHELL=${CONFIG_SHELL-/bin/sh} +export SHELL +# Unset more variables known to interfere with behavior of common tools. +CLICOLOR_FORCE= GREP_OPTIONS= +unset CLICOLOR_FORCE GREP_OPTIONS + +## --------------------- ## +## M4sh Shell Functions. ## +## --------------------- ## +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + + + as_lineno_1=$LINENO as_lineno_1a=$LINENO + as_lineno_2=$LINENO as_lineno_2a=$LINENO + eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && + test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { + # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + + # If we had to re-execute with $CONFIG_SHELL, we're ensured to have + # already done that, so ensure we don't try to do so again and fall + # in an infinite loop. This has already happened in practice. + _as_can_reexec=no; export _as_can_reexec + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + +SHELL=${CONFIG_SHELL-/bin/sh} + + +test -n "$DJDIR" || exec 7<&0 </dev/null +exec 6>&1 + +# Name of the host. +# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= + +# Identity of this package. +PACKAGE_NAME='GNU AutoGen' +PACKAGE_TARNAME='autogen' +PACKAGE_VERSION='5.18.16' +PACKAGE_STRING='GNU AutoGen 5.18.16' +PACKAGE_BUGREPORT='autogen-users@lists.sourceforge.net' +PACKAGE_URL='http://www.gnu.org/software/autogen/' + +ac_unique_file="agen5/autogen.c" +# Factoring default headers for most tests. +ac_includes_default="\ +#include <stdio.h> +#ifdef HAVE_SYS_TYPES_H +# include <sys/types.h> +#endif +#ifdef HAVE_SYS_STAT_H +# include <sys/stat.h> +#endif +#ifdef STDC_HEADERS +# include <stdlib.h> +# include <stddef.h> +#else +# ifdef HAVE_STDLIB_H +# include <stdlib.h> +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +# include <memory.h> +# endif +# include <string.h> +#endif +#ifdef HAVE_STRINGS_H +# include <strings.h> +#endif +#ifdef HAVE_INTTYPES_H +# include <inttypes.h> +#endif +#ifdef HAVE_STDINT_H +# include <stdint.h> +#endif +#ifdef HAVE_UNISTD_H +# include <unistd.h> +#endif" + +ac_subst_vars='am__EXEEXT_FALSE +am__EXEEXT_TRUE +LTLIBOBJS +CONFIG_SHELL +WARN_CFLAGS +INCLIST +ENABLE_STATIC +DEBUG_ENABLED +ac_aux_dir +CLexe +GDexe +AGexe +CLnam +GDnam +AGnam +M4_SRC +LIBOBJS +SUBDIR_SNPRINTFV_FALSE +SUBDIR_SNPRINTFV_TRUE +CONVENIENCE_SNPRINTFV_FALSE +CONVENIENCE_SNPRINTFV_TRUE +INSTALL_SNPRINTFV_FALSE +INSTALL_SNPRINTFV_TRUE +INCSNPRINTFV +LIBSNPRINTFV +POSIX_SHELL +GL_GENERATE_STDNORETURN_H_FALSE +GL_GENERATE_STDNORETURN_H_TRUE +STDNORETURN_H +GUILE_LDFLAGS +GUILE_LTLIBS +HOST_CPU_C_ABI +HOST_CPU +GUILE_LIBS +GUILE_CFLAGS +GUILE_EFFECTIVE_VERSION +PKG_CONFIG_LIBDIR +PKG_CONFIG_PATH +PKG_CONFIG +AG_LDFLAGS +AG_TIMEOUT +HAVE_XML_LIB_FALSE +HAVE_XML_LIB_TRUE +AG_XML2 +LIBXML2_LIBS +LIBXML2_CFLAGS +AG_STATIC_AUTOGEN +DO_SHELL_CMDS_FALSE +DO_SHELL_CMDS_TRUE +AGEN5_TESTS +OPTS_TESTDIR +DYNAMIC_AG +NEED_PATHFIND_FALSE +NEED_PATHFIND_TRUE +TEXI2HTML +GO_AGE +GO_REVISION +GO_CURRENT +AO_TEMPLATE_VERSION +AO_AGE +AO_REVISION +AO_CURRENT +AG_MINOR_VERSION +AG_MAJOR_VERSION +AG_VERSION +LT_SYS_LIBRARY_PATH +OTOOL64 +OTOOL +LIPO +NMEDIT +DSYMUTIL +MANIFEST_TOOL +RANLIB +ac_ct_AR +AR +LN_S +NM +ac_ct_DUMPBIN +DUMPBIN +LD +FGREP +SED +LIBTOOL +OBJDUMP +DLLTOOL +AS +EGREP +GREP +CPP +am__fastdepCC_FALSE +am__fastdepCC_TRUE +CCDEPMODE +am__nodep +AMDEPBACKSLASH +AMDEP_FALSE +AMDEP_TRUE +am__include +DEPDIR +OBJEXT +EXEEXT +ac_ct_CC +CPPFLAGS +LDFLAGS +CFLAGS +CC +AM_BACKSLASH +AM_DEFAULT_VERBOSITY +AM_DEFAULT_V +AM_V +am__untar +am__tar +AMTAR +am__leading_dot +SET_MAKE +AWK +mkdir_p +MKDIR_P +INSTALL_STRIP_PROGRAM +STRIP +install_sh +MAKEINFO +AUTOHEADER +AUTOMAKE +AUTOCONF +ACLOCAL +VERSION +PACKAGE +CYGPATH_W +am__isrc +INSTALL_DATA +INSTALL_SCRIPT +INSTALL_PROGRAM +target_os +target_vendor +target_cpu +target +host_os +host_vendor +host_cpu +host +build_os +build_vendor +build_cpu +build +target_alias +host_alias +build_alias +LIBS +ECHO_T +ECHO_N +ECHO_C +DEFS +mandir +localedir +libdir +psdir +pdfdir +dvidir +htmldir +infodir +docdir +oldincludedir +includedir +localstatedir +sharedstatedir +sysconfdir +datadir +datarootdir +libexecdir +sbindir +bindir +program_transform_name +prefix +exec_prefix +PACKAGE_URL +PACKAGE_BUGREPORT +PACKAGE_STRING +PACKAGE_VERSION +PACKAGE_TARNAME +PACKAGE_NAME +PATH_SEPARATOR +SHELL +am__quote' +ac_subst_files='' +ac_user_opts=' +enable_option_checking +enable_silent_rules +enable_dependency_tracking +enable_shared +enable_static +with_pic +enable_fast_install +with_aix_soname +with_gnu_ld +with_sysroot +enable_libtool_lock +with_dmalloc +enable_shell +enable_static_autogen +with_libxml2 +with_libxml2_cflags +with_libxml2_libs +enable_timeout +enable_debug +with_packager +with_packager_version +with_packager_bug_reports +enable_rpath +enable_nls +with_regex_header +with_libregex +with_libregex_cflags +with_libregex_libs +enable_optional_args +enable_snprintfv_install +' + ac_precious_vars='build_alias +host_alias +target_alias +CC +CFLAGS +LDFLAGS +LIBS +CPPFLAGS +CPP +LT_SYS_LIBRARY_PATH +PKG_CONFIG +PKG_CONFIG_PATH +PKG_CONFIG_LIBDIR +GUILE_CFLAGS +GUILE_LIBS' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +ac_unrecognized_opts= +ac_unrecognized_sep= +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *=) ac_optarg= ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=\$ac_optarg ;; + + -without-* | --without-*) + ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) as_fn_error $? "unrecognized option: \`$ac_option' +Try \`$0 --help' for more information" + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + case $ac_envvar in #( + '' | [0-9]* | *[!_$as_cr_alnum]* ) + as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; + esac + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + as_fn_error $? "missing argument to $ac_option" +fi + +if test -n "$ac_unrecognized_opts"; then + case $enable_option_checking in + no) ;; + fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; + *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + esac +fi + +# Check all directory arguments for consistency. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir +do + eval ac_val=\$$ac_var + # Remove trailing slashes. + case $ac_val in + */ ) + ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` + eval $ac_var=\$ac_val;; + esac + # Be sure to have absolute directory names. + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + as_fn_error $? "working directory cannot be determined" +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + as_fn_error $? "pwd does not report name of working directory" + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$as_myself" || +$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_myself" : 'X\(//\)[^/]' \| \ + X"$as_myself" : 'X\(//\)$' \| \ + X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_myself" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures GNU AutoGen 5.18.16 to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking ...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/autogen] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF + +Program names: + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM run sed PROGRAM on installed program names + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] + --target=TARGET configure for building compilers for TARGET [HOST] +_ACEOF +fi + +if test -n "$ac_init_help"; then + case $ac_init_help in + short | recursive ) echo "Configuration of GNU AutoGen 5.18.16:";; + esac + cat <<\_ACEOF + +Optional Features: + --disable-option-checking ignore unrecognized --enable/--with options + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --enable-silent-rules less verbose build output (undo: "make V=1") + --disable-silent-rules verbose build output (undo: "make V=0") + --enable-dependency-tracking + do not reject slow dependency extractors + --disable-dependency-tracking + speeds up one-time build + --enable-shared[=PKGS] build shared libraries [default=yes] + --enable-static[=PKGS] build static libraries [default=yes] + --enable-fast-install[=PKGS] + optimize for fast installation [default=yes] + --disable-libtool-lock avoid locking (might break parallel builds) + --disable-shell shell scripts are desired + --enable-static-autogen statically link autogen to libopts + --enable-timeout specify an autogen timeout + --enable-debug wanting autogen debugging + --disable-rpath do not hardcode runtime library paths + --disable-nls disable nls support in libopts + --disable-optional-args not wanting optional option args + --enable-snprintfv-install install libsnprintfv yes + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use + both] + --with-aix-soname=aix|svr4|both + shared library versioning (aka "SONAME") variant to + provide on AIX, [default=aix]. + --with-gnu-ld assume the C compiler uses GNU ld [default=no] + --with-sysroot[=DIR] Search for dependent libraries within DIR (or the + compiler's sysroot if not specified). + --with-dmalloc use dmalloc, as in http://www.dmalloc.com + --with-libxml2 libxml2 installation prefix + --with-libxml2-cflags libxml2 compile flags + --with-libxml2-libs libxml2 link command arguments + --with-packager name of the packager of this software is supplied + --with-packager-version packager-specific version information is supplied + --with-packager-bug-reports + bug reporting URI/e-mail/etc. is supplied + --with-gnu-ld assume the C compiler uses GNU ld [default=no] + --with-regex-header a reg expr header is specified + --with-libregex libregex installation prefix + --with-libregex-cflags libregex compile flags + --with-libregex-libs libregex link command arguments + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a + nonstandard directory <lib dir> + LIBS libraries to pass to the linker, e.g. -l<library> + CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if + you have headers in a nonstandard directory <include dir> + CPP C preprocessor + LT_SYS_LIBRARY_PATH + User-defined run-time library search path. + PKG_CONFIG path to pkg-config utility + PKG_CONFIG_PATH + directories to add to pkg-config's search path + PKG_CONFIG_LIBDIR + path overriding pkg-config's built-in search path + GUILE_CFLAGS + C compiler flags for GUILE, overriding pkg-config + GUILE_LIBS linker flags for GUILE, overriding pkg-config + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +Report bugs to <autogen-users@lists.sourceforge.net>. +GNU AutoGen home page: <http://www.gnu.org/software/autogen/>. +General help using GNU software: <http://www.gnu.org/gethelp/>. +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || + { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || + continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +GNU AutoGen configure 5.18.16 +generated by GNU Autoconf 2.69 + +Copyright (C) 2012 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi + +## ------------------------ ## +## Autoconf initialization. ## +## ------------------------ ## + +# ac_fn_c_try_compile LINENO +# -------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_compile + +# ac_fn_c_try_cpp LINENO +# ---------------------- +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_cpp + +# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists, giving a warning if it cannot be compiled using +# the include files in INCLUDES and setting the cache variable VAR +# accordingly. +ac_fn_c_check_header_mongrel () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if eval \${$3+:} false; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +else + # Is the header compilable? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 +$as_echo_n "checking $2 usability... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_header_compiler=yes +else + ac_header_compiler=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 +$as_echo "$ac_header_compiler" >&6; } + +# Is the header present? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 +$as_echo_n "checking $2 presence... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <$2> +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + ac_header_preproc=yes +else + ac_header_preproc=no +fi +rm -f conftest.err conftest.i conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 +$as_echo "$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( + yes:no: ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 +$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} + ;; + no:yes:* ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 +$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 +$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 +$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 +$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} +( $as_echo "## -------------------------------------------------- ## +## Report this to autogen-users@lists.sourceforge.net ## +## -------------------------------------------------- ##" + ) | sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=\$ac_header_compiler" +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_mongrel + +# ac_fn_c_try_run LINENO +# ---------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes +# that executables *can* be run. +ac_fn_c_try_run () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then : + ac_retval=0 +else + $as_echo "$as_me: program exited with status $ac_status" >&5 + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=$ac_status +fi + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_run + +# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists and can be compiled using the include files in +# INCLUDES, setting the cache variable VAR accordingly. +ac_fn_c_check_header_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_compile + +# ac_fn_c_try_link LINENO +# ----------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + test -x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_link + +# ac_fn_c_check_func LINENO FUNC VAR +# ---------------------------------- +# Tests whether FUNC exists, setting the cache variable VAR accordingly +ac_fn_c_check_func () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Define $2 to an innocuous variant, in case <limits.h> declares $2. + For example, HP-UX 11i <limits.h> declares gettimeofday. */ +#define $2 innocuous_$2 + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $2 (); below. + Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + <limits.h> exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + +#undef $2 + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $2 (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$2 || defined __stub___$2 +choke me +#endif + +int +main () +{ +return $2 (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_func + +# ac_fn_c_check_decl LINENO SYMBOL VAR INCLUDES +# --------------------------------------------- +# Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR +# accordingly. +ac_fn_c_check_decl () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + as_decl_name=`echo $2|sed 's/ *(.*//'` + as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'` + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5 +$as_echo_n "checking whether $as_decl_name is declared... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +#ifndef $as_decl_name +#ifdef __cplusplus + (void) $as_decl_use; +#else + (void) $as_decl_name; +#endif +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_decl + +# ac_fn_c_check_type LINENO TYPE VAR INCLUDES +# ------------------------------------------- +# Tests whether TYPE exists after having included INCLUDES, setting cache +# variable VAR accordingly. +ac_fn_c_check_type () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=no" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +if (sizeof ($2)) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +if (sizeof (($2))) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + eval "$3=yes" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_type + +# ac_fn_c_compute_int LINENO EXPR VAR INCLUDES +# -------------------------------------------- +# Tries to find the compile-time value of EXPR in a program that includes +# INCLUDES, setting VAR accordingly. Returns whether the value could be +# computed +ac_fn_c_compute_int () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if test "$cross_compiling" = yes; then + # Depending upon the size, compute the lo and hi bounds. +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +static int test_array [1 - 2 * !(($2) >= 0)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_lo=0 ac_mid=0 + while :; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +static int test_array [1 - 2 * !(($2) <= $ac_mid)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_hi=$ac_mid; break +else + as_fn_arith $ac_mid + 1 && ac_lo=$as_val + if test $ac_lo -le $ac_mid; then + ac_lo= ac_hi= + break + fi + as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +static int test_array [1 - 2 * !(($2) < 0)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_hi=-1 ac_mid=-1 + while :; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +static int test_array [1 - 2 * !(($2) >= $ac_mid)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_lo=$ac_mid; break +else + as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val + if test $ac_mid -le $ac_hi; then + ac_lo= ac_hi= + break + fi + as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + ac_lo= ac_hi= +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +# Binary search between lo and hi bounds. +while test "x$ac_lo" != "x$ac_hi"; do + as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +static int test_array [1 - 2 * !(($2) <= $ac_mid)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_hi=$ac_mid +else + as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +done +case $ac_lo in #(( +?*) eval "$3=\$ac_lo"; ac_retval=0 ;; +'') ac_retval=1 ;; +esac + else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +static long int longval () { return $2; } +static unsigned long int ulongval () { return $2; } +#include <stdio.h> +#include <stdlib.h> +int +main () +{ + + FILE *f = fopen ("conftest.val", "w"); + if (! f) + return 1; + if (($2) < 0) + { + long int i = longval (); + if (i != ($2)) + return 1; + fprintf (f, "%ld", i); + } + else + { + unsigned long int i = ulongval (); + if (i != ($2)) + return 1; + fprintf (f, "%lu", i); + } + /* Do not output a trailing newline, as this causes \r\n confusion + on some platforms. */ + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + echo >>conftest.val; read $3 <conftest.val; ac_retval=0 +else + ac_retval=1 +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +rm -f conftest.val + + fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_compute_int + +# ac_fn_c_check_member LINENO AGGR MEMBER VAR INCLUDES +# ---------------------------------------------------- +# Tries to find if the field MEMBER exists in type AGGR, after including +# INCLUDES, setting cache variable VAR accordingly. +ac_fn_c_check_member () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2.$3" >&5 +$as_echo_n "checking for $2.$3... " >&6; } +if eval \${$4+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$5 +int +main () +{ +static $2 ac_aggr; +if (ac_aggr.$3) +return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$4=yes" +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$5 +int +main () +{ +static $2 ac_aggr; +if (sizeof ac_aggr.$3) +return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$4=yes" +else + eval "$4=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$4 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_member +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by GNU AutoGen $as_me 5.18.16, which was +generated by GNU Autoconf 2.69. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + $as_echo "PATH: $as_dir" + done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; + 2) + as_fn_append ac_configure_args1 " '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + as_fn_append ac_configure_args " '$ac_arg'" + ;; + esac + done +done +{ ac_configure_args0=; unset ac_configure_args0;} +{ ac_configure_args1=; unset ac_configure_args1;} + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + $as_echo "## ---------------- ## +## Cache variables. ## +## ---------------- ##" + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + $as_echo "## ----------------- ## +## Output variables. ## +## ----------------- ##" + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + $as_echo "## ------------------- ## +## File substitutions. ## +## ------------------- ##" + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + $as_echo "## ----------- ## +## confdefs.h. ## +## ----------- ##" + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + $as_echo "$as_me: caught signal $ac_signal" + $as_echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +$as_echo "/* confdefs.h */" > confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_URL "$PACKAGE_URL" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer an explicitly selected file to automatically selected ones. +ac_site_file1=NONE +ac_site_file2=NONE +if test -n "$CONFIG_SITE"; then + # We do not want a PATH search for config.site. + case $CONFIG_SITE in #(( + -*) ac_site_file1=./$CONFIG_SITE;; + */*) ac_site_file1=$CONFIG_SITE;; + *) ac_site_file1=./$CONFIG_SITE;; + esac +elif test "x$prefix" != xNONE; then + ac_site_file1=$prefix/share/config.site + ac_site_file2=$prefix/etc/config.site +else + ac_site_file1=$ac_default_prefix/share/config.site + ac_site_file2=$ac_default_prefix/etc/config.site +fi +for ac_site_file in "$ac_site_file1" "$ac_site_file2" +do + test "x$ac_site_file" = xNONE && continue + if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 +$as_echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" \ + || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "failed to load site script $ac_site_file +See \`config.log' for more details" "$LINENO" 5; } + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special files + # actually), so we avoid doing that. DJGPP emulates it as a regular file. + if test /dev/null != "$cache_file" && test -f "$cache_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 +$as_echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 +$as_echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + # differences in whitespace do not lead to failure. + ac_old_val_w=`echo x $ac_old_val` + ac_new_val_w=`echo x $ac_new_val` + if test "$ac_old_val_w" != "$ac_new_val_w"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 +$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + ac_cache_corrupted=: + else + { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + eval $ac_var=\$ac_old_val + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 +$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 +$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) as_fn_append ac_configure_args " '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 +$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} + as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 +fi +## -------------------- ## +## Main body of script. ## +## -------------------- ## + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + +ac_aux_dir= +for ac_dir in config "$srcdir"/config; do + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + as_fn_error $? "cannot find install-sh, install.sh, or shtool in config \"$srcdir\"/config" "$LINENO" 5 +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + +# Make sure we can run config.sub. +$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || + as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 +$as_echo_n "checking build system type... " >&6; } +if ${ac_cv_build+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_build_alias=$build_alias +test "x$ac_build_alias" = x && + ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` +test "x$ac_build_alias" = x && + as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 +ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 +$as_echo "$ac_cv_build" >&6; } +case $ac_cv_build in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; +esac +build=$ac_cv_build +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_build +shift +build_cpu=$1 +build_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +build_os=$* +IFS=$ac_save_IFS +case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 +$as_echo_n "checking host system type... " >&6; } +if ${ac_cv_host+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "x$host_alias" = x; then + ac_cv_host=$ac_cv_build +else + ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 +$as_echo "$ac_cv_host" >&6; } +case $ac_cv_host in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; +esac +host=$ac_cv_host +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_host +shift +host_cpu=$1 +host_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +host_os=$* +IFS=$ac_save_IFS +case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking target system type" >&5 +$as_echo_n "checking target system type... " >&6; } +if ${ac_cv_target+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "x$target_alias" = x; then + ac_cv_target=$ac_cv_host +else + ac_cv_target=`$SHELL "$ac_aux_dir/config.sub" $target_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $target_alias failed" "$LINENO" 5 +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_target" >&5 +$as_echo "$ac_cv_target" >&6; } +case $ac_cv_target in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical target" "$LINENO" 5;; +esac +target=$ac_cv_target +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_target +shift +target_cpu=$1 +target_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +target_os=$* +IFS=$ac_save_IFS +case $target_os in *\ *) target_os=`echo "$target_os" | sed 's/ /-/g'`;; esac + + +# The aliases save the names the user supplied, while $host etc. +# will get canonicalized. +test -n "$target_alias" && + test "$program_prefix$program_suffix$program_transform_name" = \ + NONENONEs,x,x, && + program_prefix=${target_alias}- +. $srcdir/VERSION +d=`dirname $0` +ag_top_srcdir=`cd $d && pwd` +ag_top_builddir=`pwd` +am__api_version='1.16' + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +# Reject install programs that cannot install multiple files. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 +$as_echo_n "checking for a BSD-compatible install... " >&6; } +if test -z "$INSTALL"; then +if ${ac_cv_path_install+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in #(( + ./ | .// | /[cC]/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + rm -rf conftest.one conftest.two conftest.dir + echo one > conftest.one + echo two > conftest.two + mkdir conftest.dir + if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && + test -s conftest.one && test -s conftest.two && + test -s conftest.dir/conftest.one && + test -s conftest.dir/conftest.two + then + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + fi + done + done + ;; +esac + + done +IFS=$as_save_IFS + +rm -rf conftest.one conftest.two conftest.dir + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 +$as_echo "$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 +$as_echo_n "checking whether build environment is sane... " >&6; } +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[\\\"\#\$\&\'\`$am_lf]*) + as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; +esac +case $srcdir in + *[\\\"\#\$\&\'\`$am_lf\ \ ]*) + as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; +esac + +# Do 'set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + am_has_slept=no + for am_try in 1 2; do + echo "timestamp, slept: $am_has_slept" > conftest.file + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + if test "$*" != "X $srcdir/configure conftest.file" \ + && test "$*" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + as_fn_error $? "ls -t appears to fail. Make sure there is not a broken + alias in your environment" "$LINENO" 5 + fi + if test "$2" = conftest.file || test $am_try -eq 2; then + break + fi + # Just in case. + sleep 1 + am_has_slept=yes + done + test "$2" = conftest.file + ) +then + # Ok. + : +else + as_fn_error $? "newly created file is older than distributed files! +Check your system clock" "$LINENO" 5 +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +# If we didn't sleep, we still need to ensure time stamps of config.status and +# generated files are strictly newer. +am_sleep_pid= +if grep 'slept: no' conftest.file >/dev/null 2>&1; then + ( sleep 1 ) & + am_sleep_pid=$! +fi + +rm -f conftest.file + +test "$program_prefix" != NONE && + program_transform_name="s&^&$program_prefix&;$program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s&\$&$program_suffix&;$program_transform_name" +# Double any \ or $. +# By default was `s,x,x', remove it if useless. +ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' +program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` + +# Expand $ac_aux_dir to an absolute path. +am_aux_dir=`cd "$ac_aux_dir" && pwd` + +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --is-lightweight"; then + am_missing_run="$MISSING " +else + am_missing_run= + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 +$as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;} +fi + +if test x"${install_sh+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi + +# Installed binaries are usually stripped using 'strip' when the user +# run "make install-strip". However 'strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the 'STRIP' environment variable to overrule this program. +if test "$cross_compiling" != no; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 +$as_echo_n "checking for a thread-safe mkdir -p... " >&6; } +if test -z "$MKDIR_P"; then + if ${ac_cv_path_mkdir+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in mkdir gmkdir; do + for ac_exec_ext in '' $ac_executable_extensions; do + as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue + case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( + 'mkdir (GNU coreutils) '* | \ + 'mkdir (coreutils) '* | \ + 'mkdir (fileutils) '4.1*) + ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext + break 3;; + esac + done + done + done +IFS=$as_save_IFS + +fi + + test -d ./--version && rmdir ./--version + if test "${ac_cv_path_mkdir+set}" = set; then + MKDIR_P="$ac_cv_path_mkdir -p" + else + # As a last resort, use the slow shell script. Don't cache a + # value for MKDIR_P within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + MKDIR_P="$ac_install_sh -d" + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 +$as_echo "$MKDIR_P" >&6; } + +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AWK+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AWK="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 +$as_echo "$AWK" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AWK" && break +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } +set x ${MAKE-make} +ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + SET_MAKE= +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + +rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null + +# Check whether --enable-silent-rules was given. +if test "${enable_silent_rules+set}" = set; then : + enableval=$enable_silent_rules; +fi + +case $enable_silent_rules in # ((( + yes) AM_DEFAULT_VERBOSITY=0;; + no) AM_DEFAULT_VERBOSITY=1;; + *) AM_DEFAULT_VERBOSITY=1;; +esac +am_make=${MAKE-make} +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 +$as_echo_n "checking whether $am_make supports nested variables... " >&6; } +if ${am_cv_make_support_nested_variables+:} false; then : + $as_echo_n "(cached) " >&6 +else + if $as_echo 'TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 +$as_echo "$am_cv_make_support_nested_variables" >&6; } +if test $am_cv_make_support_nested_variables = yes; then + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AM_BACKSLASH='\' + +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + am__isrc=' -I$(srcdir)' + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi + + +# Define the identity of the package. + PACKAGE='autogen' + VERSION='5.18.16' + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE "$PACKAGE" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define VERSION "$VERSION" +_ACEOF + +# Some tools Automake needs. + +ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} + + +AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} + + +AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} + + +AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} + + +MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} + +# For better backward compatibility. To be removed once Automake 1.9.x +# dies out for good. For more background, see: +# <https://lists.gnu.org/archive/html/automake/2012-07/msg00001.html> +# <https://lists.gnu.org/archive/html/automake/2012-07/msg00014.html> +mkdir_p='$(MKDIR_P)' + +# We need awk for the "check" target (and possibly the TAP driver). The +# system "awk" is bad on some platforms. +# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AMTAR='$${TAR-tar}' + + +# We'll loop over all known methods to create a tar archive until one works. +_am_tools='gnutar pax cpio none' + +am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' + + + + + + +# POSIX will say in a future version that running "rm -f" with no argument +# is OK; and we want to be able to make that assumption in our Makefile +# recipes. So use an aggressive probe to check that the usage we want is +# actually supported "in the wild" to an acceptable degree. +# See automake bug#10828. +# To make any issue more visible, cause the running configure to be aborted +# by default if the 'rm' program in use doesn't match our expectations; the +# user can still override this though. +if rm -f && rm -fr && rm -rf; then : OK; else + cat >&2 <<'END' +Oops! + +Your 'rm' program seems unable to run without file operands specified +on the command line, even when the '-f' option is present. This is contrary +to the behaviour of most rm programs out there, and not conforming with +the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542> + +Please tell bug-automake@gnu.org about your system, including the value +of your $PATH and any error possibly output before this message. This +can help us improve future automake versions. + +END + if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then + echo 'Configuration will proceed anyway, since you have set the' >&2 + echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 + echo >&2 + else + cat >&2 <<'END' +Aborting the configuration process, to ensure you take notice of the issue. + +You can download and install GNU coreutils to get an 'rm' implementation +that behaves properly: <https://www.gnu.org/software/coreutils/>. + +If you want to complete the configuration process using your problematic +'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM +to "yes", and re-run configure. + +END + as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 + fi +fi + +DEPDIR="${am__leading_dot}deps" + +ac_config_commands="$ac_config_commands depfiles" + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} supports the include directive" >&5 +$as_echo_n "checking whether ${MAKE-make} supports the include directive... " >&6; } +cat > confinc.mk << 'END' +am__doit: + @echo this is the am__doit target >confinc.out +.PHONY: am__doit +END +am__include="#" +am__quote= +# BSD make does it like this. +echo '.include "confinc.mk" # ignored' > confmf.BSD +# Other make implementations (GNU, Solaris 10, AIX) do it like this. +echo 'include confinc.mk # ignored' > confmf.GNU +_am_result=no +for s in GNU BSD; do + { echo "$as_me:$LINENO: ${MAKE-make} -f confmf.$s && cat confinc.out" >&5 + (${MAKE-make} -f confmf.$s && cat confinc.out) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + case $?:`cat confinc.out 2>/dev/null` in #( + '0:this is the am__doit target') : + case $s in #( + BSD) : + am__include='.include' am__quote='"' ;; #( + *) : + am__include='include' am__quote='' ;; +esac ;; #( + *) : + ;; +esac + if test "$am__include" != "#"; then + _am_result="yes ($s style)" + break + fi +done +rm -f confinc.* confmf.* +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${_am_result}" >&5 +$as_echo "${_am_result}" >&6; } + +# Check whether --enable-dependency-tracking was given. +if test "${enable_dependency_tracking+set}" = set; then : + enableval=$enable_dependency_tracking; +fi + +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' + am__nodep='_no' +fi + if test "x$enable_dependency_tracking" != xno; then + AMDEP_TRUE= + AMDEP_FALSE='#' +else + AMDEP_TRUE='#' + AMDEP_FALSE= +fi + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "no acceptable C compiler found in \$PATH +See \`config.log' for more details" "$LINENO" 5; } + +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 +$as_echo_n "checking whether the C compiler works... " >&6; } +ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` + +# The possible output files: +ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" + +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { { ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + ac_file='' +fi +if test -z "$ac_file"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +$as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "C compiler cannot create executables +See \`config.log' for more details" "$LINENO" 5; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 +$as_echo_n "checking for C compiler default output file name... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 +$as_echo "$ac_file" >&6; } +ac_exeext=$ac_cv_exeext + +rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 +$as_echo_n "checking for suffix of executables... " >&6; } +if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest conftest$ac_cv_exeext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 +$as_echo "$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdio.h> +int +main () +{ +FILE *f = fopen ("conftest.out", "w"); + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +ac_clean_files="$ac_clean_files conftest.out" +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 +$as_echo_n "checking whether we are cross compiling... " >&6; } +if test "$cross_compiling" != yes; then + { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if { ac_try='./conftest$ac_cv_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details" "$LINENO" 5; } + fi + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 +$as_echo "$cross_compiling" >&6; } + +rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 +$as_echo_n "checking for suffix of object files... " >&6; } +if ${ac_cv_objext+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of object files: cannot compile +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 +$as_echo "$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +if ${ac_cv_c_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if ${ac_cv_prog_cc_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +else + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if ${ac_cv_prog_cc_c89+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdarg.h> +#include <stdio.h> +struct stat; +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c89" != xno; then : + +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 +$as_echo_n "checking whether $CC understands -c and -o together... " >&6; } +if ${am_cv_prog_cc_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF + # Make sure it works both with $CC and with simple cc. + # Following AC_PROG_CC_C_O, we do the test twice because some + # compilers refuse to overwrite an existing .o file with -o, + # though they will create one. + am_cv_prog_cc_c_o=yes + for am_i in 1 2; do + if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 + ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } \ + && test -f conftest2.$ac_objext; then + : OK + else + am_cv_prog_cc_c_o=no + break + fi + done + rm -f core conftest* + unset am_i +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 +$as_echo "$am_cv_prog_cc_c_o" >&6; } +if test "$am_cv_prog_cc_c_o" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +depcc="$CC" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if ${am_cv_CC_dependencies_compiler_type+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CC_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with '-c' and '-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CC_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CC_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } +CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then + am__fastdepCC_TRUE= + am__fastdepCC_FALSE='#' +else + am__fastdepCC_TRUE='#' + am__fastdepCC_FALSE= +fi + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 +$as_echo_n "checking how to run the C preprocessor... " >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if ${ac_cv_prog_CPP+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + # <limits.h> exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <ac_nonexistent.h> +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 +$as_echo "$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + # <limits.h> exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <ac_nonexistent.h> +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 +$as_echo_n "checking for grep that handles long lines and -e... " >&6; } +if ${ac_cv_path_GREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$GREP"; then + ac_path_GREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_GREP" || continue +# Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_GREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_GREP"; then + as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_GREP=$GREP +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 +$as_echo "$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 +$as_echo_n "checking for egrep... " >&6; } +if ${ac_cv_path_EGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + if test -z "$EGREP"; then + ac_path_EGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_EGREP" || continue +# Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_EGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_EGREP"; then + as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_EGREP=$EGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 +$as_echo "$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if ${ac_cv_header_stdc+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdlib.h> +#include <stdarg.h> +#include <string.h> +#include <float.h> + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_stdc=yes +else + ac_cv_header_stdc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <string.h> + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdlib.h> + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then : + : +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <ctype.h> +#include <stdlib.h> +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + +else + ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +$as_echo "#define STDC_HEADERS 1" >>confdefs.h + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default +" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + + ac_fn_c_check_header_mongrel "$LINENO" "minix/config.h" "ac_cv_header_minix_config_h" "$ac_includes_default" +if test "x$ac_cv_header_minix_config_h" = xyes; then : + MINIX=yes +else + MINIX= +fi + + + if test "$MINIX" = yes; then + +$as_echo "#define _POSIX_SOURCE 1" >>confdefs.h + + +$as_echo "#define _POSIX_1_SOURCE 2" >>confdefs.h + + +$as_echo "#define _MINIX 1" >>confdefs.h + + +$as_echo "#define _NETBSD_SOURCE 1" >>confdefs.h + + fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether it is safe to define __EXTENSIONS__" >&5 +$as_echo_n "checking whether it is safe to define __EXTENSIONS__... " >&6; } +if ${ac_cv_safe_to_define___extensions__+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +# define __EXTENSIONS__ 1 + $ac_includes_default +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_safe_to_define___extensions__=yes +else + ac_cv_safe_to_define___extensions__=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_safe_to_define___extensions__" >&5 +$as_echo "$ac_cv_safe_to_define___extensions__" >&6; } + test $ac_cv_safe_to_define___extensions__ = yes && + $as_echo "#define __EXTENSIONS__ 1" >>confdefs.h + + $as_echo "#define _ALL_SOURCE 1" >>confdefs.h + + $as_echo "#define _DARWIN_C_SOURCE 1" >>confdefs.h + + $as_echo "#define _GNU_SOURCE 1" >>confdefs.h + + $as_echo "#define _NETBSD_SOURCE 1" >>confdefs.h + + $as_echo "#define _OPENBSD_SOURCE 1" >>confdefs.h + + $as_echo "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h + + $as_echo "#define __STDC_WANT_IEC_60559_ATTRIBS_EXT__ 1" >>confdefs.h + + $as_echo "#define __STDC_WANT_IEC_60559_BFP_EXT__ 1" >>confdefs.h + + $as_echo "#define __STDC_WANT_IEC_60559_DFP_EXT__ 1" >>confdefs.h + + $as_echo "#define __STDC_WANT_IEC_60559_FUNCS_EXT__ 1" >>confdefs.h + + $as_echo "#define __STDC_WANT_IEC_60559_TYPES_EXT__ 1" >>confdefs.h + + $as_echo "#define __STDC_WANT_LIB_EXT2__ 1" >>confdefs.h + + $as_echo "#define __STDC_WANT_MATH_SPEC_FUNCS__ 1" >>confdefs.h + + $as_echo "#define _TANDEM_SOURCE 1" >>confdefs.h + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether _XOPEN_SOURCE should be defined" >&5 +$as_echo_n "checking whether _XOPEN_SOURCE should be defined... " >&6; } +if ${ac_cv_should_define__xopen_source+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_should_define__xopen_source=no + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include <wchar.h> + mbstate_t x; +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #define _XOPEN_SOURCE 500 + #include <wchar.h> + mbstate_t x; +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_should_define__xopen_source=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_should_define__xopen_source" >&5 +$as_echo "$ac_cv_should_define__xopen_source" >&6; } + test $ac_cv_should_define__xopen_source = yes && + $as_echo "#define _XOPEN_SOURCE 500" >>confdefs.h + + $as_echo "#define _HPUX_ALT_XOPEN_SOCKET_API 1" >>confdefs.h + + + +enable_win32_dll=yes + +case $host in +*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args. +set dummy ${ac_tool_prefix}as; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AS+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AS"; then + ac_cv_prog_AS="$AS" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AS="${ac_tool_prefix}as" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AS=$ac_cv_prog_AS +if test -n "$AS"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AS" >&5 +$as_echo "$AS" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_AS"; then + ac_ct_AS=$AS + # Extract the first word of "as", so it can be a program name with args. +set dummy as; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_AS+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_AS"; then + ac_cv_prog_ac_ct_AS="$ac_ct_AS" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_AS="as" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_AS=$ac_cv_prog_ac_ct_AS +if test -n "$ac_ct_AS"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AS" >&5 +$as_echo "$ac_ct_AS" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_AS" = x; then + AS="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + AS=$ac_ct_AS + fi +else + AS="$ac_cv_prog_AS" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. +set dummy ${ac_tool_prefix}dlltool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DLLTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DLLTOOL"; then + ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DLLTOOL=$ac_cv_prog_DLLTOOL +if test -n "$DLLTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 +$as_echo "$DLLTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_DLLTOOL"; then + ac_ct_DLLTOOL=$DLLTOOL + # Extract the first word of "dlltool", so it can be a program name with args. +set dummy dlltool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DLLTOOL"; then + ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_DLLTOOL="dlltool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL +if test -n "$ac_ct_DLLTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 +$as_echo "$ac_ct_DLLTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_DLLTOOL" = x; then + DLLTOOL="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DLLTOOL=$ac_ct_DLLTOOL + fi +else + DLLTOOL="$ac_cv_prog_DLLTOOL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. +set dummy ${ac_tool_prefix}objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OBJDUMP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OBJDUMP"; then + ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OBJDUMP=$ac_cv_prog_OBJDUMP +if test -n "$OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 +$as_echo "$OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OBJDUMP"; then + ac_ct_OBJDUMP=$OBJDUMP + # Extract the first word of "objdump", so it can be a program name with args. +set dummy objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OBJDUMP"; then + ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_OBJDUMP="objdump" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP +if test -n "$ac_ct_OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 +$as_echo "$ac_ct_OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OBJDUMP" = x; then + OBJDUMP="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OBJDUMP=$ac_ct_OBJDUMP + fi +else + OBJDUMP="$ac_cv_prog_OBJDUMP" +fi + + ;; +esac + +test -z "$AS" && AS=as + + + + + +test -z "$DLLTOOL" && DLLTOOL=dlltool + + + + + +test -z "$OBJDUMP" && OBJDUMP=objdump + + + + + + + + +case `pwd` in + *\ * | *\ *) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 +$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; +esac + + + +macro_version='2.4.6' +macro_revision='2.4.6' + + + + + + + + + + + + + +ltmain=$ac_aux_dir/ltmain.sh + +# Backslashify metacharacters that are still active within +# double-quoted strings. +sed_quote_subst='s/\(["`$\\]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\(["`\\]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to delay expansion of an escaped single quote. +delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' + +ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 +$as_echo_n "checking how to print strings... " >&6; } +# Test print first, because it will be a builtin if present. +if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ + test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='print -r --' +elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='printf %s\n' +else + # Use this function as a fallback that always works. + func_fallback_echo () + { + eval 'cat <<_LTECHO_EOF +$1 +_LTECHO_EOF' + } + ECHO='func_fallback_echo' +fi + +# func_echo_all arg... +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "" +} + +case $ECHO in + printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5 +$as_echo "printf" >&6; } ;; + print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 +$as_echo "print -r" >&6; } ;; + *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5 +$as_echo "cat" >&6; } ;; +esac + + + + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 +$as_echo_n "checking for a sed that does not truncate output... " >&6; } +if ${ac_cv_path_SED+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ + for ac_i in 1 2 3 4 5 6 7; do + ac_script="$ac_script$as_nl$ac_script" + done + echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed + { ac_script=; unset ac_script;} + if test -z "$SED"; then + ac_path_SED_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_SED" || continue +# Check for GNU ac_path_SED and select it if it is found. + # Check for GNU $ac_path_SED +case `"$ac_path_SED" --version 2>&1` in +*GNU*) + ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo '' >> "conftest.nl" + "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_SED_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_SED="$ac_path_SED" + ac_path_SED_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_SED_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_SED"; then + as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 + fi +else + ac_cv_path_SED=$SED +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 +$as_echo "$ac_cv_path_SED" >&6; } + SED="$ac_cv_path_SED" + rm -f conftest.sed + +test -z "$SED" && SED=sed +Xsed="$SED -e 1s/^X//" + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 +$as_echo_n "checking for fgrep... " >&6; } +if ${ac_cv_path_FGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 + then ac_cv_path_FGREP="$GREP -F" + else + if test -z "$FGREP"; then + ac_path_FGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in fgrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_FGREP" || continue +# Check for GNU ac_path_FGREP and select it if it is found. + # Check for GNU $ac_path_FGREP +case `"$ac_path_FGREP" --version 2>&1` in +*GNU*) + ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'FGREP' >> "conftest.nl" + "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_FGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_FGREP="$ac_path_FGREP" + ac_path_FGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_FGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_FGREP"; then + as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_FGREP=$FGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 +$as_echo "$ac_cv_path_FGREP" >&6; } + FGREP="$ac_cv_path_FGREP" + + +test -z "$GREP" && GREP=grep + + + + + + + + + + + + + + + + + + + +# Check whether --with-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then : + withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes +else + with_gnu_ld=no +fi + +ac_prog=ld +if test yes = "$GCC"; then + # Check if gcc -print-prog-name=ld gives a path. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 +$as_echo_n "checking for ld used by $CC... " >&6; } + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return, which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | ?:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD=$ac_prog + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test yes = "$with_gnu_ld"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 +$as_echo_n "checking for GNU ld... " >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 +$as_echo_n "checking for non-GNU ld... " >&6; } +fi +if ${lt_cv_path_LD+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$LD"; then + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD=$ac_dir/$ac_prog + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in + *GNU* | *'with BFD'*) + test no != "$with_gnu_ld" && break + ;; + *) + test yes != "$with_gnu_ld" && break + ;; + esac + fi + done + IFS=$lt_save_ifs +else + lt_cv_path_LD=$LD # Let the user override the test with a path. +fi +fi + +LD=$lt_cv_path_LD +if test -n "$LD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5 +$as_echo "$LD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 +$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } +if ${lt_cv_prog_gnu_ld+:} false; then : + $as_echo_n "(cached) " >&6 +else + # I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 </dev/null` in +*GNU* | *'with BFD'*) + lt_cv_prog_gnu_ld=yes + ;; +*) + lt_cv_prog_gnu_ld=no + ;; +esac +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_gnu_ld" >&5 +$as_echo "$lt_cv_prog_gnu_ld" >&6; } +with_gnu_ld=$lt_cv_prog_gnu_ld + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 +$as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; } +if ${lt_cv_path_NM+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM=$NM +else + lt_nm_to_check=${ac_tool_prefix}nm + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + tmp_nm=$ac_dir/$lt_tmp_nm + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the 'sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty + case $build_os in + mingw*) lt_bad_file=conftest.nm/nofile ;; + *) lt_bad_file=/dev/null ;; + esac + case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in + *$lt_bad_file* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break 2 + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break 2 + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + ;; + esac + fi + done + IFS=$lt_save_ifs + done + : ${lt_cv_path_NM=no} +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 +$as_echo "$lt_cv_path_NM" >&6; } +if test no != "$lt_cv_path_NM"; then + NM=$lt_cv_path_NM +else + # Didn't find any BSD compatible name lister, look for dumpbin. + if test -n "$DUMPBIN"; then : + # Let the user override the test. + else + if test -n "$ac_tool_prefix"; then + for ac_prog in dumpbin "link -dump" + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DUMPBIN+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DUMPBIN"; then + ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DUMPBIN=$ac_cv_prog_DUMPBIN +if test -n "$DUMPBIN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 +$as_echo "$DUMPBIN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$DUMPBIN" && break + done +fi +if test -z "$DUMPBIN"; then + ac_ct_DUMPBIN=$DUMPBIN + for ac_prog in dumpbin "link -dump" +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DUMPBIN"; then + ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN +if test -n "$ac_ct_DUMPBIN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 +$as_echo "$ac_ct_DUMPBIN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_DUMPBIN" && break +done + + if test "x$ac_ct_DUMPBIN" = x; then + DUMPBIN=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DUMPBIN=$ac_ct_DUMPBIN + fi +fi + + case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in + *COFF*) + DUMPBIN="$DUMPBIN -symbols -headers" + ;; + *) + DUMPBIN=: + ;; + esac + fi + + if test : != "$DUMPBIN"; then + NM=$DUMPBIN + fi +fi +test -z "$NM" && NM=nm + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 +$as_echo_n "checking the name lister ($NM) interface... " >&6; } +if ${lt_cv_nm_interface+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_nm_interface="BSD nm" + echo "int some_variable = 0;" > conftest.$ac_ext + (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5) + (eval "$ac_compile" 2>conftest.err) + cat conftest.err >&5 + (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5) + (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) + cat conftest.err >&5 + (eval echo "\"\$as_me:$LINENO: output\"" >&5) + cat conftest.out >&5 + if $GREP 'External.*some_variable' conftest.out > /dev/null; then + lt_cv_nm_interface="MS dumpbin" + fi + rm -f conftest* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 +$as_echo "$lt_cv_nm_interface" >&6; } + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 +$as_echo_n "checking whether ln -s works... " >&6; } +LN_S=$as_ln_s +if test "$LN_S" = "ln -s"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 +$as_echo "no, using $LN_S" >&6; } +fi + +# find the maximum length of command line arguments +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 +$as_echo_n "checking the maximum length of command line arguments... " >&6; } +if ${lt_cv_sys_max_cmd_len+:} false; then : + $as_echo_n "(cached) " >&6 +else + i=0 + teststring=ABCD + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw* | cegcc*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + mint*) + # On MiNT this can take a long time and run out of memory. + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + os2*) + # The test takes a long time on OS/2. + lt_cv_sys_max_cmd_len=8192 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` + if test -n "$lt_cv_sys_max_cmd_len" && \ + test undefined != "$lt_cv_sys_max_cmd_len"; then + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + else + # Make teststring a little bigger before we do anything with it. + # a 1K string should be a reasonable start. + for i in 1 2 3 4 5 6 7 8; do + teststring=$teststring$teststring + done + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + while { test X`env echo "$teststring$teststring" 2>/dev/null` \ + = "X$teststring$teststring"; } >/dev/null 2>&1 && + test 17 != "$i" # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + # Only check the string length outside the loop. + lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` + teststring= + # Add a significant safety factor because C++ compilers can tack on + # massive amounts of additional arguments before passing them to the + # linker. It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + fi + ;; + esac + +fi + +if test -n "$lt_cv_sys_max_cmd_len"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 +$as_echo "$lt_cv_sys_max_cmd_len" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 +$as_echo "none" >&6; } +fi +max_cmd_len=$lt_cv_sys_max_cmd_len + + + + + + +: ${CP="cp -f"} +: ${MV="mv -f"} +: ${RM="rm -f"} + +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + lt_unset=unset +else + lt_unset=false +fi + + + + + +# test EBCDIC or ASCII +case `echo X|tr X '\101'` in + A) # ASCII based system + # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr + lt_SP2NL='tr \040 \012' + lt_NL2SP='tr \015\012 \040\040' + ;; + *) # EBCDIC based system + lt_SP2NL='tr \100 \n' + lt_NL2SP='tr \r\n \100\100' + ;; +esac + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5 +$as_echo_n "checking how to convert $build file names to $host format... " >&6; } +if ${lt_cv_to_host_file_cmd+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 + ;; + esac + ;; + *-*-cygwin* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin + ;; + esac + ;; + * ) # unhandled hosts (and "normal" native builds) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; +esac + +fi + +to_host_file_cmd=$lt_cv_to_host_file_cmd +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5 +$as_echo "$lt_cv_to_host_file_cmd" >&6; } + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5 +$as_echo_n "checking how to convert $build file names to toolchain format... " >&6; } +if ${lt_cv_to_tool_file_cmd+:} false; then : + $as_echo_n "(cached) " >&6 +else + #assume ordinary cross tools, or native build. +lt_cv_to_tool_file_cmd=func_convert_file_noop +case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 + ;; + esac + ;; +esac + +fi + +to_tool_file_cmd=$lt_cv_to_tool_file_cmd +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5 +$as_echo "$lt_cv_to_tool_file_cmd" >&6; } + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 +$as_echo_n "checking for $LD option to reload object files... " >&6; } +if ${lt_cv_ld_reload_flag+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_reload_flag='-r' +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 +$as_echo "$lt_cv_ld_reload_flag" >&6; } +reload_flag=$lt_cv_ld_reload_flag +case $reload_flag in +"" | " "*) ;; +*) reload_flag=" $reload_flag" ;; +esac +reload_cmds='$LD$reload_flag -o $output$reload_objs' +case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + if test yes != "$GCC"; then + reload_cmds=false + fi + ;; + darwin*) + if test yes = "$GCC"; then + reload_cmds='$LTCC $LTCFLAGS -nostdlib $wl-r -o $output$reload_objs' + else + reload_cmds='$LD$reload_flag -o $output$reload_objs' + fi + ;; +esac + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. +set dummy ${ac_tool_prefix}objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OBJDUMP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OBJDUMP"; then + ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OBJDUMP=$ac_cv_prog_OBJDUMP +if test -n "$OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 +$as_echo "$OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OBJDUMP"; then + ac_ct_OBJDUMP=$OBJDUMP + # Extract the first word of "objdump", so it can be a program name with args. +set dummy objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OBJDUMP"; then + ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_OBJDUMP="objdump" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP +if test -n "$ac_ct_OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 +$as_echo "$ac_ct_OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OBJDUMP" = x; then + OBJDUMP="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OBJDUMP=$ac_ct_OBJDUMP + fi +else + OBJDUMP="$ac_cv_prog_OBJDUMP" +fi + +test -z "$OBJDUMP" && OBJDUMP=objdump + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 +$as_echo_n "checking how to recognize dependent libraries... " >&6; } +if ${lt_cv_deplibs_check_method+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_file_magic_cmd='$MAGIC_CMD' +lt_cv_file_magic_test_file= +lt_cv_deplibs_check_method='unknown' +# Need to set the preceding variable on all platforms that support +# interlibrary dependencies. +# 'none' -- dependencies not supported. +# 'unknown' -- same as none, but documents that we really don't know. +# 'pass_all' -- all dependencies passed with no checks. +# 'test_compile' -- check by making test program. +# 'file_magic [[regex]]' -- check by looking for files in library path +# that responds to the $file_magic_cmd with a given extended regex. +# If you have 'file' or equivalent on your system and you're not sure +# whether 'pass_all' will *always* work, you probably want this one. + +case $host_os in +aix[4-9]*) + lt_cv_deplibs_check_method=pass_all + ;; + +beos*) + lt_cv_deplibs_check_method=pass_all + ;; + +bsdi[45]*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' + lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_test_file=/shlib/libc.so + ;; + +cygwin*) + # func_win32_libid is a shell function defined in ltmain.sh + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + ;; + +mingw* | pw32*) + # Base MSYS/MinGW do not provide the 'file' command needed by + # func_win32_libid shell function, so use a weaker test based on 'objdump', + # unless we find 'file', for example because we are cross-compiling. + if ( file / ) >/dev/null 2>&1; then + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + else + # Keep this pattern in sync with the one in func_win32_libid. + lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' + lt_cv_file_magic_cmd='$OBJDUMP -f' + fi + ;; + +cegcc*) + # use the weaker test based on 'objdump'. See mingw*. + lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method=pass_all + ;; + +freebsd* | dragonfly*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +haiku*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]' + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +interix[3-9]*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +*nto* | *qnx*) + lt_cv_deplibs_check_method=pass_all + ;; + +openbsd* | bitrig*) + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +rdos*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.3*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +tpf*) + lt_cv_deplibs_check_method=pass_all + ;; +os2*) + lt_cv_deplibs_check_method=pass_all + ;; +esac + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 +$as_echo "$lt_cv_deplibs_check_method" >&6; } + +file_magic_glob= +want_nocaseglob=no +if test "$build" = "$host"; then + case $host_os in + mingw* | pw32*) + if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then + want_nocaseglob=yes + else + file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"` + fi + ;; + esac +fi + +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown + + + + + + + + + + + + + + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. +set dummy ${ac_tool_prefix}dlltool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DLLTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DLLTOOL"; then + ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DLLTOOL=$ac_cv_prog_DLLTOOL +if test -n "$DLLTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 +$as_echo "$DLLTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_DLLTOOL"; then + ac_ct_DLLTOOL=$DLLTOOL + # Extract the first word of "dlltool", so it can be a program name with args. +set dummy dlltool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DLLTOOL"; then + ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_DLLTOOL="dlltool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL +if test -n "$ac_ct_DLLTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 +$as_echo "$ac_ct_DLLTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_DLLTOOL" = x; then + DLLTOOL="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DLLTOOL=$ac_ct_DLLTOOL + fi +else + DLLTOOL="$ac_cv_prog_DLLTOOL" +fi + +test -z "$DLLTOOL" && DLLTOOL=dlltool + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5 +$as_echo_n "checking how to associate runtime and link libraries... " >&6; } +if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_sharedlib_from_linklib_cmd='unknown' + +case $host_os in +cygwin* | mingw* | pw32* | cegcc*) + # two different shell functions defined in ltmain.sh; + # decide which one to use based on capabilities of $DLLTOOL + case `$DLLTOOL --help 2>&1` in + *--identify-strict*) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib + ;; + *) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback + ;; + esac + ;; +*) + # fallback: assume linklib IS sharedlib + lt_cv_sharedlib_from_linklib_cmd=$ECHO + ;; +esac + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5 +$as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; } +sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd +test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO + + + + + + + +if test -n "$ac_tool_prefix"; then + for ac_prog in ar + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AR="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AR=$ac_cv_prog_AR +if test -n "$AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 +$as_echo "$AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AR" && break + done +fi +if test -z "$AR"; then + ac_ct_AR=$AR + for ac_prog in ar +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_AR"; then + ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_AR="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_AR=$ac_cv_prog_ac_ct_AR +if test -n "$ac_ct_AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 +$as_echo "$ac_ct_AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_AR" && break +done + + if test "x$ac_ct_AR" = x; then + AR="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + AR=$ac_ct_AR + fi +fi + +: ${AR=ar} +: ${AR_FLAGS=cru} + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5 +$as_echo_n "checking for archiver @FILE support... " >&6; } +if ${lt_cv_ar_at_file+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ar_at_file=no + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + echo conftest.$ac_objext > conftest.lst + lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5' + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 + (eval $lt_ar_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if test 0 -eq "$ac_status"; then + # Ensure the archiver fails upon bogus file names. + rm -f conftest.$ac_objext libconftest.a + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 + (eval $lt_ar_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if test 0 -ne "$ac_status"; then + lt_cv_ar_at_file=@ + fi + fi + rm -f conftest.* libconftest.a + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5 +$as_echo "$lt_cv_ar_at_file" >&6; } + +if test no = "$lt_cv_ar_at_file"; then + archiver_list_spec= +else + archiver_list_spec=$lt_cv_ar_at_file +fi + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +test -z "$STRIP" && STRIP=: + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 +$as_echo "$RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 +$as_echo "$ac_ct_RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi +else + RANLIB="$ac_cv_prog_RANLIB" +fi + +test -z "$RANLIB" && RANLIB=: + + + + + + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + bitrig* | openbsd*) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" + ;; + *) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" +fi + +case $host_os in + darwin*) + lock_old_archive_extraction=yes ;; + *) + lock_old_archive_extraction=no ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + +# Check for command to grab the raw symbol name followed by C symbol from nm. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 +$as_echo_n "checking command to parse $NM output from $compiler object... " >&6; } +if ${lt_cv_sys_global_symbol_pipe+:} false; then : + $as_echo_n "(cached) " >&6 +else + +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[BCDEGRST]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([_A-Za-z][_A-Za-z0-9]*\)' + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[BCDT]' + ;; +cygwin* | mingw* | pw32* | cegcc*) + symcode='[ABCDGISTW]' + ;; +hpux*) + if test ia64 = "$host_cpu"; then + symcode='[ABCDEGRST]' + fi + ;; +irix* | nonstopux*) + symcode='[BCDEGRST]' + ;; +osf*) + symcode='[BCDEGQRST]' + ;; +solaris*) + symcode='[BDRT]' + ;; +sco3.2v5*) + symcode='[DT]' + ;; +sysv4.2uw2*) + symcode='[DT]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[ABDT]' + ;; +sysv4) + symcode='[DFNSTU]' + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[ABCDGIRSTW]' ;; +esac + +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Gets list of data symbols to import. + lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'" + # Adjust the below global symbol transforms to fixup imported variables. + lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'" + lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'" + lt_c_name_lib_hook="\ + -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\ + -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'" +else + # Disable hooks by default. + lt_cv_sys_global_symbol_to_import= + lt_cdecl_hook= + lt_c_name_hook= + lt_c_name_lib_hook= +fi + +# Transform an extracted symbol line into a proper C declaration. +# Some systems (esp. on ia64) link data and code symbols differently, +# so use this general approach. +lt_cv_sys_global_symbol_to_cdecl="sed -n"\ +$lt_cdecl_hook\ +" -e 's/^T .* \(.*\)$/extern int \1();/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n"\ +$lt_c_name_hook\ +" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'" + +# Transform an extracted symbol line into symbol name with lib prefix and +# symbol address. +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\ +$lt_c_name_lib_hook\ +" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ +" -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'" + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# Try without a prefix underscore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # Write the raw and C identifiers. + if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Fake it for dumpbin and say T for any non-static function, + # D for any global variable and I for any imported variable. + # Also find C++ and __fastcall symbols from MSVC++, + # which start with @ or ?. + lt_cv_sys_global_symbol_pipe="$AWK '"\ +" {last_section=section; section=\$ 3};"\ +" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ +" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ +" /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\ +" /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\ +" /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\ +" \$ 0!~/External *\|/{next};"\ +" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ +" {if(hide[section]) next};"\ +" {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\ +" {split(\$ 0,a,/\||\r/); split(a[2],s)};"\ +" s[1]~/^[@?]/{print f,s[1],s[1]; next};"\ +" s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\ +" ' prfx=^$ac_symprfx" + else + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + fi + lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext <<_LT_EOF +#ifdef __cplusplus +extern "C" { +#endif +char nm_test_var; +void nm_test_func(void); +void nm_test_func(void){} +#ifdef __cplusplus +} +#endif +int main(){nm_test_var='a';nm_test_func();return(0);} +_LT_EOF + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + # Now try to grab the symbols. + nlist=conftest.nm + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5 + (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if $GREP ' nm_test_var$' "$nlist" >/dev/null; then + if $GREP ' nm_test_func$' "$nlist" >/dev/null; then + cat <<_LT_EOF > conftest.$ac_ext +/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ +#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE +/* DATA imports from DLLs on WIN32 can't be const, because runtime + relocations are performed -- see ld's documentation on pseudo-relocs. */ +# define LT_DLSYM_CONST +#elif defined __osf__ +/* This system does not cope well with relocations in const data. */ +# define LT_DLSYM_CONST +#else +# define LT_DLSYM_CONST const +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +_LT_EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' + + cat <<_LT_EOF >> conftest.$ac_ext + +/* The mapping between symbol names and symbols. */ +LT_DLSYM_CONST struct { + const char *name; + void *address; +} +lt__PROGRAM__LTX_preloaded_symbols[] = +{ + { "@PROGRAM@", (void *) 0 }, +_LT_EOF + $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext + cat <<\_LT_EOF >> conftest.$ac_ext + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt__PROGRAM__LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif +_LT_EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_globsym_save_LIBS=$LIBS + lt_globsym_save_CFLAGS=$CFLAGS + LIBS=conftstm.$ac_objext + CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s conftest$ac_exeext; then + pipe_works=yes + fi + LIBS=$lt_globsym_save_LIBS + CFLAGS=$lt_globsym_save_CFLAGS + else + echo "cannot find nm_test_func in $nlist" >&5 + fi + else + echo "cannot find nm_test_var in $nlist" >&5 + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 + fi + else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + fi + rm -rf conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test yes = "$pipe_works"; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done + +fi + +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 +$as_echo "failed" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 +$as_echo "ok" >&6; } +fi + +# Response file support. +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + nm_file_list_spec='@' +elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then + nm_file_list_spec='@' +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5 +$as_echo_n "checking for sysroot... " >&6; } + +# Check whether --with-sysroot was given. +if test "${with_sysroot+set}" = set; then : + withval=$with_sysroot; +else + with_sysroot=no +fi + + +lt_sysroot= +case $with_sysroot in #( + yes) + if test yes = "$GCC"; then + lt_sysroot=`$CC --print-sysroot 2>/dev/null` + fi + ;; #( + /*) + lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` + ;; #( + no|'') + ;; #( + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_sysroot" >&5 +$as_echo "$with_sysroot" >&6; } + as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5 + ;; +esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5 +$as_echo "${lt_sysroot:-no}" >&6; } + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a working dd" >&5 +$as_echo_n "checking for a working dd... " >&6; } +if ${ac_cv_path_lt_DD+:} false; then : + $as_echo_n "(cached) " >&6 +else + printf 0123456789abcdef0123456789abcdef >conftest.i +cat conftest.i conftest.i >conftest2.i +: ${lt_DD:=$DD} +if test -z "$lt_DD"; then + ac_path_lt_DD_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in dd; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_lt_DD="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_lt_DD" || continue +if "$ac_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then + cmp -s conftest.i conftest.out \ + && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=: +fi + $ac_path_lt_DD_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_lt_DD"; then + : + fi +else + ac_cv_path_lt_DD=$lt_DD +fi + +rm -f conftest.i conftest2.i conftest.out +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_lt_DD" >&5 +$as_echo "$ac_cv_path_lt_DD" >&6; } + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to truncate binary pipes" >&5 +$as_echo_n "checking how to truncate binary pipes... " >&6; } +if ${lt_cv_truncate_bin+:} false; then : + $as_echo_n "(cached) " >&6 +else + printf 0123456789abcdef0123456789abcdef >conftest.i +cat conftest.i conftest.i >conftest2.i +lt_cv_truncate_bin= +if "$ac_cv_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then + cmp -s conftest.i conftest.out \ + && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1" +fi +rm -f conftest.i conftest2.i conftest.out +test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_truncate_bin" >&5 +$as_echo "$lt_cv_truncate_bin" >&6; } + + + + + + + +# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. +func_cc_basename () +{ + for cc_temp in $*""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac + done + func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` +} + +# Check whether --enable-libtool-lock was given. +if test "${enable_libtool_lock+set}" = set; then : + enableval=$enable_libtool_lock; +fi + +test no = "$enable_libtool_lock" || enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out what ABI is being produced by ac_compile, and set mode + # options accordingly. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE=32 + ;; + *ELF-64*) + HPUX_IA64_MODE=64 + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo '#line '$LINENO' "configure"' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + if test yes = "$lt_cv_prog_gnu_ld"; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +mips64*-*linux*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo '#line '$LINENO' "configure"' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + emul=elf + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + emul="${emul}32" + ;; + *64-bit*) + emul="${emul}64" + ;; + esac + case `/usr/bin/file conftest.$ac_objext` in + *MSB*) + emul="${emul}btsmip" + ;; + *LSB*) + emul="${emul}ltsmip" + ;; + esac + case `/usr/bin/file conftest.$ac_objext` in + *N32*) + emul="${emul}n32" + ;; + esac + LD="${LD-ld} -m $emul" + fi + rm -rf conftest* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ +s390*-*linux*|s390*-*tpf*|sparc*-*linux*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. Note that the listed cases only cover the + # situations where additional linker options are needed (such as when + # doing 32-bit compilation for a host where ld defaults to 64-bit, or + # vice versa); the common cases where no linker options are needed do + # not appear in the list. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.o` in + *32-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_i386_fbsd" + ;; + x86_64-*linux*) + case `/usr/bin/file conftest.o` in + *x86-64*) + LD="${LD-ld} -m elf32_x86_64" + ;; + *) + LD="${LD-ld} -m elf_i386" + ;; + esac + ;; + powerpc64le-*linux*) + LD="${LD-ld} -m elf32lppclinux" + ;; + powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_x86_64_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + powerpcle-*linux*) + LD="${LD-ld} -m elf64lppc" + ;; + powerpc-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*|s390*-*tpf*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS=$CFLAGS + CFLAGS="$CFLAGS -belf" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 +$as_echo_n "checking whether the C compiler needs -belf... " >&6; } +if ${lt_cv_cc_needs_belf+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_cc_needs_belf=yes +else + lt_cv_cc_needs_belf=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 +$as_echo "$lt_cv_cc_needs_belf" >&6; } + if test yes != "$lt_cv_cc_needs_belf"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS=$SAVE_CFLAGS + fi + ;; +*-*solaris*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) + case $host in + i?86-*-solaris*|x86_64-*-solaris*) + LD="${LD-ld} -m elf_x86_64" + ;; + sparc*-*-solaris*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + # GNU ld 2.21 introduced _sol2 emulations. Use them if available. + if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then + LD=${LD-ld}_sol2 + fi + ;; + *) + if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then + LD="${LD-ld} -64" + fi + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; +esac + +need_locks=$enable_libtool_lock + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args. +set dummy ${ac_tool_prefix}mt; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_MANIFEST_TOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$MANIFEST_TOOL"; then + ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL +if test -n "$MANIFEST_TOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5 +$as_echo "$MANIFEST_TOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_MANIFEST_TOOL"; then + ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL + # Extract the first word of "mt", so it can be a program name with args. +set dummy mt; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_MANIFEST_TOOL"; then + ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_MANIFEST_TOOL="mt" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL +if test -n "$ac_ct_MANIFEST_TOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5 +$as_echo "$ac_ct_MANIFEST_TOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_MANIFEST_TOOL" = x; then + MANIFEST_TOOL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL + fi +else + MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL" +fi + +test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5 +$as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; } +if ${lt_cv_path_mainfest_tool+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_path_mainfest_tool=no + echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5 + $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out + cat conftest.err >&5 + if $GREP 'Manifest Tool' conftest.out > /dev/null; then + lt_cv_path_mainfest_tool=yes + fi + rm -f conftest* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5 +$as_echo "$lt_cv_path_mainfest_tool" >&6; } +if test yes != "$lt_cv_path_mainfest_tool"; then + MANIFEST_TOOL=: +fi + + + + + + + case $host_os in + rhapsody* | darwin*) + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. +set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DSYMUTIL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DSYMUTIL"; then + ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DSYMUTIL=$ac_cv_prog_DSYMUTIL +if test -n "$DSYMUTIL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 +$as_echo "$DSYMUTIL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_DSYMUTIL"; then + ac_ct_DSYMUTIL=$DSYMUTIL + # Extract the first word of "dsymutil", so it can be a program name with args. +set dummy dsymutil; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DSYMUTIL"; then + ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL +if test -n "$ac_ct_DSYMUTIL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 +$as_echo "$ac_ct_DSYMUTIL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_DSYMUTIL" = x; then + DSYMUTIL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DSYMUTIL=$ac_ct_DSYMUTIL + fi +else + DSYMUTIL="$ac_cv_prog_DSYMUTIL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. +set dummy ${ac_tool_prefix}nmedit; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_NMEDIT+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$NMEDIT"; then + ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +NMEDIT=$ac_cv_prog_NMEDIT +if test -n "$NMEDIT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 +$as_echo "$NMEDIT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_NMEDIT"; then + ac_ct_NMEDIT=$NMEDIT + # Extract the first word of "nmedit", so it can be a program name with args. +set dummy nmedit; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_NMEDIT"; then + ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_NMEDIT="nmedit" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT +if test -n "$ac_ct_NMEDIT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 +$as_echo "$ac_ct_NMEDIT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_NMEDIT" = x; then + NMEDIT=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + NMEDIT=$ac_ct_NMEDIT + fi +else + NMEDIT="$ac_cv_prog_NMEDIT" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. +set dummy ${ac_tool_prefix}lipo; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_LIPO+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$LIPO"; then + ac_cv_prog_LIPO="$LIPO" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_LIPO="${ac_tool_prefix}lipo" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +LIPO=$ac_cv_prog_LIPO +if test -n "$LIPO"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 +$as_echo "$LIPO" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_LIPO"; then + ac_ct_LIPO=$LIPO + # Extract the first word of "lipo", so it can be a program name with args. +set dummy lipo; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_LIPO+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_LIPO"; then + ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_LIPO="lipo" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO +if test -n "$ac_ct_LIPO"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 +$as_echo "$ac_ct_LIPO" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_LIPO" = x; then + LIPO=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + LIPO=$ac_ct_LIPO + fi +else + LIPO="$ac_cv_prog_LIPO" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. +set dummy ${ac_tool_prefix}otool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OTOOL"; then + ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_OTOOL="${ac_tool_prefix}otool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OTOOL=$ac_cv_prog_OTOOL +if test -n "$OTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 +$as_echo "$OTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OTOOL"; then + ac_ct_OTOOL=$OTOOL + # Extract the first word of "otool", so it can be a program name with args. +set dummy otool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OTOOL"; then + ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_OTOOL="otool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL +if test -n "$ac_ct_OTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 +$as_echo "$ac_ct_OTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OTOOL" = x; then + OTOOL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OTOOL=$ac_ct_OTOOL + fi +else + OTOOL="$ac_cv_prog_OTOOL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. +set dummy ${ac_tool_prefix}otool64; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OTOOL64+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OTOOL64"; then + ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OTOOL64=$ac_cv_prog_OTOOL64 +if test -n "$OTOOL64"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 +$as_echo "$OTOOL64" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OTOOL64"; then + ac_ct_OTOOL64=$OTOOL64 + # Extract the first word of "otool64", so it can be a program name with args. +set dummy otool64; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OTOOL64"; then + ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_OTOOL64="otool64" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 +if test -n "$ac_ct_OTOOL64"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 +$as_echo "$ac_ct_OTOOL64" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OTOOL64" = x; then + OTOOL64=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OTOOL64=$ac_ct_OTOOL64 + fi +else + OTOOL64="$ac_cv_prog_OTOOL64" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 +$as_echo_n "checking for -single_module linker flag... " >&6; } +if ${lt_cv_apple_cc_single_mod+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_apple_cc_single_mod=no + if test -z "$LT_MULTI_MODULE"; then + # By default we will add the -single_module flag. You can override + # by either setting the environment variable LT_MULTI_MODULE + # non-empty at configure time, or by adding -multi_module to the + # link flags. + rm -rf libconftest.dylib* + echo "int foo(void){return 1;}" > conftest.c + echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ +-dynamiclib -Wl,-single_module conftest.c" >&5 + $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ + -dynamiclib -Wl,-single_module conftest.c 2>conftest.err + _lt_result=$? + # If there is a non-empty error log, and "single_module" + # appears in it, assume the flag caused a linker warning + if test -s conftest.err && $GREP single_module conftest.err; then + cat conftest.err >&5 + # Otherwise, if the output was created with a 0 exit code from + # the compiler, it worked. + elif test -f libconftest.dylib && test 0 = "$_lt_result"; then + lt_cv_apple_cc_single_mod=yes + else + cat conftest.err >&5 + fi + rm -rf libconftest.dylib* + rm -f conftest.* + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 +$as_echo "$lt_cv_apple_cc_single_mod" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 +$as_echo_n "checking for -exported_symbols_list linker flag... " >&6; } +if ${lt_cv_ld_exported_symbols_list+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_exported_symbols_list=no + save_LDFLAGS=$LDFLAGS + echo "_main" > conftest.sym + LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_ld_exported_symbols_list=yes +else + lt_cv_ld_exported_symbols_list=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 +$as_echo "$lt_cv_ld_exported_symbols_list" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 +$as_echo_n "checking for -force_load linker flag... " >&6; } +if ${lt_cv_ld_force_load+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_force_load=no + cat > conftest.c << _LT_EOF +int forced_loaded() { return 2;} +_LT_EOF + echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 + $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 + echo "$AR cru libconftest.a conftest.o" >&5 + $AR cru libconftest.a conftest.o 2>&5 + echo "$RANLIB libconftest.a" >&5 + $RANLIB libconftest.a 2>&5 + cat > conftest.c << _LT_EOF +int main() { return 0;} +_LT_EOF + echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 + $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err + _lt_result=$? + if test -s conftest.err && $GREP force_load conftest.err; then + cat conftest.err >&5 + elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then + lt_cv_ld_force_load=yes + else + cat conftest.err >&5 + fi + rm -f conftest.err libconftest.a conftest conftest.c + rm -rf conftest.dSYM + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 +$as_echo "$lt_cv_ld_force_load" >&6; } + case $host_os in + rhapsody* | darwin1.[012]) + _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;; + darwin1.*) + _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; + darwin*) # darwin 5.x on + # if running on 10.5 or later, the deployment target defaults + # to the OS version, if on x86, and 10.4, the deployment + # target defaults to 10.4. Don't you love it? + case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in + 10.0,*86*-darwin8*|10.0,*-darwin[91]*) + _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; + 10.[012][,.]*) + _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; + 10.*) + _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; + esac + ;; + esac + if test yes = "$lt_cv_apple_cc_single_mod"; then + _lt_dar_single_mod='$single_module' + fi + if test yes = "$lt_cv_ld_exported_symbols_list"; then + _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym' + else + _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib' + fi + if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then + _lt_dsymutil='~$DSYMUTIL $lib || :' + else + _lt_dsymutil= + fi + ;; + esac + +# func_munge_path_list VARIABLE PATH +# ----------------------------------- +# VARIABLE is name of variable containing _space_ separated list of +# directories to be munged by the contents of PATH, which is string +# having a format: +# "DIR[:DIR]:" +# string "DIR[ DIR]" will be prepended to VARIABLE +# ":DIR[:DIR]" +# string "DIR[ DIR]" will be appended to VARIABLE +# "DIRP[:DIRP]::[DIRA:]DIRA" +# string "DIRP[ DIRP]" will be prepended to VARIABLE and string +# "DIRA[ DIRA]" will be appended to VARIABLE +# "DIR[:DIR]" +# VARIABLE will be replaced by "DIR[ DIR]" +func_munge_path_list () +{ + case x$2 in + x) + ;; + *:) + eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\" + ;; + x:*) + eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\" + ;; + *::*) + eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" + eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\" + ;; + *) + eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\" + ;; + esac +} + +for ac_header in dlfcn.h +do : + ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default +" +if test "x$ac_cv_header_dlfcn_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_DLFCN_H 1 +_ACEOF + +fi + +done + + + + + +# Set options + + + + enable_dlopen=no + + + + # Check whether --enable-shared was given. +if test "${enable_shared+set}" = set; then : + enableval=$enable_shared; p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for pkg in $enableval; do + IFS=$lt_save_ifs + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS=$lt_save_ifs + ;; + esac +else + enable_shared=yes +fi + + + + + + + + + + # Check whether --enable-static was given. +if test "${enable_static+set}" = set; then : + enableval=$enable_static; p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for pkg in $enableval; do + IFS=$lt_save_ifs + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS=$lt_save_ifs + ;; + esac +else + enable_static=yes +fi + + + + + + + + + + +# Check whether --with-pic was given. +if test "${with_pic+set}" = set; then : + withval=$with_pic; lt_p=${PACKAGE-default} + case $withval in + yes|no) pic_mode=$withval ;; + *) + pic_mode=default + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for lt_pkg in $withval; do + IFS=$lt_save_ifs + if test "X$lt_pkg" = "X$lt_p"; then + pic_mode=yes + fi + done + IFS=$lt_save_ifs + ;; + esac +else + pic_mode=default +fi + + + + + + + + + # Check whether --enable-fast-install was given. +if test "${enable_fast_install+set}" = set; then : + enableval=$enable_fast_install; p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for pkg in $enableval; do + IFS=$lt_save_ifs + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS=$lt_save_ifs + ;; + esac +else + enable_fast_install=yes +fi + + + + + + + + + shared_archive_member_spec= +case $host,$enable_shared in +power*-*-aix[5-9]*,yes) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking which variant of shared library versioning to provide" >&5 +$as_echo_n "checking which variant of shared library versioning to provide... " >&6; } + +# Check whether --with-aix-soname was given. +if test "${with_aix_soname+set}" = set; then : + withval=$with_aix_soname; case $withval in + aix|svr4|both) + ;; + *) + as_fn_error $? "Unknown argument to --with-aix-soname" "$LINENO" 5 + ;; + esac + lt_cv_with_aix_soname=$with_aix_soname +else + if ${lt_cv_with_aix_soname+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_with_aix_soname=aix +fi + + with_aix_soname=$lt_cv_with_aix_soname +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_aix_soname" >&5 +$as_echo "$with_aix_soname" >&6; } + if test aix != "$with_aix_soname"; then + # For the AIX way of multilib, we name the shared archive member + # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o', + # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File. + # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag, + # the AIX toolchain works better with OBJECT_MODE set (default 32). + if test 64 = "${OBJECT_MODE-32}"; then + shared_archive_member_spec=shr_64 + else + shared_archive_member_spec=shr + fi + fi + ;; +*) + with_aix_soname=aix + ;; +esac + + + + + + + + + + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS=$ltmain + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +test -z "$LN_S" && LN_S="ln -s" + + + + + + + + + + + + + + +if test -n "${ZSH_VERSION+set}"; then + setopt NO_GLOB_SUBST +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 +$as_echo_n "checking for objdir... " >&6; } +if ${lt_cv_objdir+:} false; then : + $as_echo_n "(cached) " >&6 +else + rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 +$as_echo "$lt_cv_objdir" >&6; } +objdir=$lt_cv_objdir + + + + + +cat >>confdefs.h <<_ACEOF +#define LT_OBJDIR "$lt_cv_objdir/" +_ACEOF + + + + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test set != "${COLLECT_NAMES+set}"; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Global variables: +ofile=libtool +can_build_shared=yes + +# All known linkers require a '.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a + +with_gnu_ld=$lt_cv_prog_gnu_ld + +old_CC=$CC +old_CFLAGS=$CFLAGS + +# Set sane defaults for various variables +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS +test -z "$LD" && LD=ld +test -z "$ac_objext" && ac_objext=o + +func_cc_basename $compiler +cc_basename=$func_cc_basename_result + + +# Only perform the check for file, if the check method requires it +test -z "$MAGIC_CMD" && MAGIC_CMD=file +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 +$as_echo_n "checking for ${ac_tool_prefix}file... " >&6; } +if ${lt_cv_path_MAGIC_CMD+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD=$MAGIC_CMD + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/${ac_tool_prefix}file"; then + lt_cv_path_MAGIC_CMD=$ac_dir/"${ac_tool_prefix}file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD=$lt_cv_path_MAGIC_CMD + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS=$lt_save_ifs + MAGIC_CMD=$lt_save_MAGIC_CMD + ;; +esac +fi + +MAGIC_CMD=$lt_cv_path_MAGIC_CMD +if test -n "$MAGIC_CMD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 +$as_echo "$MAGIC_CMD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + + + +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5 +$as_echo_n "checking for file... " >&6; } +if ${lt_cv_path_MAGIC_CMD+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD=$MAGIC_CMD + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/file"; then + lt_cv_path_MAGIC_CMD=$ac_dir/"file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD=$lt_cv_path_MAGIC_CMD + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS=$lt_save_ifs + MAGIC_CMD=$lt_save_MAGIC_CMD + ;; +esac +fi + +MAGIC_CMD=$lt_cv_path_MAGIC_CMD +if test -n "$MAGIC_CMD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 +$as_echo "$MAGIC_CMD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + else + MAGIC_CMD=: + fi +fi + + fi + ;; +esac + +# Use C for the default configuration in the libtool script + +lt_save_CC=$CC +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +objext=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}' + + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + +# Save the default compiler, since it gets overwritten when the other +# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. +compiler_DEFAULT=$CC + +# save warnings/boilerplate of simple test code +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* + +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* + + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + +lt_prog_compiler_no_builtin_flag= + +if test yes = "$GCC"; then + case $cc_basename in + nvcc*) + lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; + *) + lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;; + esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 +$as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } +if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_rtti_exceptions=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="-fno-rtti -fno-exceptions" ## exclude from sc_useless_quotes_in_assignment + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_rtti_exceptions=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 +$as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; } + +if test yes = "$lt_cv_prog_compiler_rtti_exceptions"; then + lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" +else + : +fi + +fi + + + + + + + lt_prog_compiler_wl= +lt_prog_compiler_pic= +lt_prog_compiler_static= + + + if test yes = "$GCC"; then + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_static='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + fi + lt_prog_compiler_pic='-fPIC' + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + lt_prog_compiler_pic='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the '-m68020' flag to GCC prevents building anything better, + # like '-m68040'. + lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + lt_prog_compiler_pic='-DDLL_EXPORT' + case $host_os in + os2*) + lt_prog_compiler_static='$wl-static' + ;; + esac + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic='-fno-common' + ;; + + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + lt_prog_compiler_static= + ;; + + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + ;; + + interix[3-9]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + lt_prog_compiler_can_build_shared=no + enable_shared=no + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic='-fPIC -shared' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic=-Kconform_pic + fi + ;; + + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + + case $cc_basename in + nvcc*) # Cuda Compiler Driver 2.2 + lt_prog_compiler_wl='-Xlinker ' + if test -n "$lt_prog_compiler_pic"; then + lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic" + fi + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + lt_prog_compiler_wl='-Wl,' + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + else + lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic='-fno-common' + case $cc_basename in + nagfor*) + # NAG Fortran compiler + lt_prog_compiler_wl='-Wl,-Wl,,' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + esac + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic='-DDLL_EXPORT' + case $host_os in + os2*) + lt_prog_compiler_static='$wl-static' + ;; + esac + ;; + + hpux9* | hpux10* | hpux11*) + lt_prog_compiler_wl='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + lt_prog_compiler_static='$wl-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + lt_prog_compiler_wl='-Wl,' + # PIC (with -KPIC) is the default. + lt_prog_compiler_static='-non_shared' + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + case $cc_basename in + # old Intel for x86_64, which still supported -KPIC. + ecc*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-static' + ;; + # icc used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + icc* | ifort*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + # Lahey Fortran 8.1. + lf95*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='--shared' + lt_prog_compiler_static='--static' + ;; + nagfor*) + # NAG Fortran compiler + lt_prog_compiler_wl='-Wl,-Wl,,' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + tcc*) + # Fabrice Bellard et al's Tiny C Compiler + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fpic' + lt_prog_compiler_static='-Bstatic' + ;; + ccc*) + lt_prog_compiler_wl='-Wl,' + # All Alpha code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + xl* | bgxl* | bgf* | mpixl*) + # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-qpic' + lt_prog_compiler_static='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='' + ;; + *Sun\ F* | *Sun*Fortran*) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='-Qoption ld ' + ;; + *Sun\ C*) + # Sun C 5.9 + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='-Wl,' + ;; + *Intel*\ [CF]*Compiler*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + *Portland\ Group*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fpic' + lt_prog_compiler_static='-Bstatic' + ;; + esac + ;; + esac + ;; + + newsos6) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic='-fPIC -shared' + ;; + + osf3* | osf4* | osf5*) + lt_prog_compiler_wl='-Wl,' + # All OSF/1 code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + + rdos*) + lt_prog_compiler_static='-non_shared' + ;; + + solaris*) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + case $cc_basename in + f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) + lt_prog_compiler_wl='-Qoption ld ';; + *) + lt_prog_compiler_wl='-Wl,';; + esac + ;; + + sunos4*) + lt_prog_compiler_wl='-Qoption ld ' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic='-Kconform_pic' + lt_prog_compiler_static='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + unicos*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_can_build_shared=no + ;; + + uts4*) + lt_prog_compiler_pic='-pic' + lt_prog_compiler_static='-Bstatic' + ;; + + *) + lt_prog_compiler_can_build_shared=no + ;; + esac + fi + +case $host_os in + # For platforms that do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic= + ;; + *) + lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" + ;; +esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 +$as_echo_n "checking for $compiler option to produce PIC... " >&6; } +if ${lt_cv_prog_compiler_pic+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic=$lt_prog_compiler_pic +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5 +$as_echo "$lt_cv_prog_compiler_pic" >&6; } +lt_prog_compiler_pic=$lt_cv_prog_compiler_pic + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 +$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } +if ${lt_cv_prog_compiler_pic_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic_works=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic -DPIC" ## exclude from sc_useless_quotes_in_assignment + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_pic_works=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 +$as_echo "$lt_cv_prog_compiler_pic_works" >&6; } + +if test yes = "$lt_cv_prog_compiler_pic_works"; then + case $lt_prog_compiler_pic in + "" | " "*) ;; + *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; + esac +else + lt_prog_compiler_pic= + lt_prog_compiler_can_build_shared=no +fi + +fi + + + + + + + + + + + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } +if ${lt_cv_prog_compiler_static_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_static_works=no + save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_static_works=yes + fi + else + lt_cv_prog_compiler_static_works=yes + fi + fi + $RM -r conftest* + LDFLAGS=$save_LDFLAGS + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 +$as_echo "$lt_cv_prog_compiler_static_works" >&6; } + +if test yes = "$lt_cv_prog_compiler_static_works"; then + : +else + lt_prog_compiler_static= +fi + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 +$as_echo "$lt_cv_prog_compiler_c_o" >&6; } + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 +$as_echo "$lt_cv_prog_compiler_c_o" >&6; } + + + + +hard_links=nottested +if test no = "$lt_cv_prog_compiler_c_o" && test no != "$need_locks"; then + # do not overwrite the value of need_locks provided by the user + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 +$as_echo_n "checking if we can lock with hard links... " >&6; } + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 +$as_echo "$hard_links" >&6; } + if test no = "$hard_links"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5 +$as_echo "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + + runpath_var= + allow_undefined_flag= + always_export_symbols=no + archive_cmds= + archive_expsym_cmds= + compiler_needs_object=no + enable_shared_with_static_runtimes=no + export_dynamic_flag_spec= + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + hardcode_automatic=no + hardcode_direct=no + hardcode_direct_absolute=no + hardcode_libdir_flag_spec= + hardcode_libdir_separator= + hardcode_minus_L=no + hardcode_shlibpath_var=unsupported + inherit_rpath=no + link_all_deplibs=unknown + module_cmds= + module_expsym_cmds= + old_archive_from_new_cmds= + old_archive_from_expsyms_cmds= + thread_safe_flag_spec= + whole_archive_flag_spec= + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + include_expsyms= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ' (' and ')$', so one must not match beginning or + # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc', + # as well as any symbol that contains 'd'. + exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + # Exclude shared library initialization/finalization symbols. + extract_expsyms_cmds= + + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test yes != "$GCC"; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd* | bitrig*) + with_gnu_ld=no + ;; + esac + + ld_shlibs=yes + + # On some targets, GNU ld is compatible enough with the native linker + # that we're better off using the native interface for both. + lt_use_gnu_ld_interface=no + if test yes = "$with_gnu_ld"; then + case $host_os in + aix*) + # The AIX port of GNU ld has always aspired to compatibility + # with the native linker. However, as the warning in the GNU ld + # block says, versions before 2.19.5* couldn't really create working + # shared libraries, regardless of the interface used. + case `$LD -v 2>&1` in + *\ \(GNU\ Binutils\)\ 2.19.5*) ;; + *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;; + *\ \(GNU\ Binutils\)\ [3-9]*) ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + fi + + if test yes = "$lt_use_gnu_ld_interface"; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='$wl' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + export_dynamic_flag_spec='$wl--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' + else + whole_archive_flag_spec= + fi + supports_anon_versioning=no + case `$LD -v | $SED -e 's/(^)\+)\s\+//' 2>&1` in + *GNU\ gold*) supports_anon_versioning=yes ;; + *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix[3-9]*) + # On AIX/PPC, the GNU linker is very broken + if test ia64 != "$host_cpu"; then + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: the GNU linker, at least up to release 2.19, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to install binutils +*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. +*** You will then need to restart the configuration process. + +_LT_EOF + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='' + ;; + m68k) + archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag=unsupported + # Joseph Beckenbach <jrb3@best.com> says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + else + ld_shlibs=no + fi + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec='-L$libdir' + export_dynamic_flag_spec='$wl--export-all-symbols' + allow_undefined_flag=unsupported + always_export_symbols=no + enable_shared_with_static_runtimes=yes + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' + exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file, use it as + # is; otherwise, prepend EXPORTS... + archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs=no + fi + ;; + + haiku*) + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + link_all_deplibs=yes + ;; + + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported + shrext_cmds=.dll + archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + prefix_cmds="$SED"~ + if test EXPORTS = "`$SED 1q $export_symbols`"; then + prefix_cmds="$prefix_cmds -e 1d"; + fi~ + prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ + cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + enable_shared_with_static_runtimes=yes + ;; + + interix[3-9]*) + hardcode_direct=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='$wl-rpath,$libdir' + export_dynamic_flag_spec='$wl-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) + tmp_diet=no + if test linux-dietlibc = "$host_os"; then + case $cc_basename in + diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) + esac + fi + if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ + && test no = "$tmp_diet" + then + tmp_addflag=' $pic_flag' + tmp_sharedflag='-shared' + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group f77 and f90 compilers + whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + lf95*) # Lahey Fortran 8.1 + whole_archive_flag_spec= + tmp_sharedflag='--shared' ;; + nagfor*) # NAGFOR 5.3 + tmp_sharedflag='-Wl,-shared' ;; + xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) + tmp_sharedflag='-qmkshrobj' + tmp_addflag= ;; + nvcc*) # Cuda Compiler Driver 2.2 + whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + compiler_needs_object=yes + ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 + whole_archive_flag_spec='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + compiler_needs_object=yes + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 + tmp_sharedflag='-G' ;; + esac + archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + + if test yes = "$supports_anon_versioning"; then + archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' + fi + + case $cc_basename in + tcc*) + export_dynamic_flag_spec='-rdynamic' + ;; + xlf* | bgf* | bgxlf* | mpixlf*) + # IBM XL Fortran 10.1 on PPC cannot create shared libs itself + whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' + if test yes = "$supports_anon_versioning"; then + archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' + fi + ;; + esac + else + ld_shlibs=no + fi + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + ;; + + sunos4*) + archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + *) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + + if test no = "$ld_shlibs"; then + runpath_var= + hardcode_libdir_flag_spec= + export_dynamic_flag_spec= + whole_archive_flag_spec= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + allow_undefined_flag=unsupported + always_export_symbols=yes + archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L=yes + if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct=unsupported + fi + ;; + + aix[4-9]*) + if test ia64 = "$host_cpu"; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag= + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to GNU nm, but means don't demangle to AIX nm. + # Without the "-l" option, or with the "-B" option, AIX nm treats + # weak defined symbols like other global defined symbols, whereas + # GNU nm marks them as "W". + # While the 'weak' keyword is ignored in the Export File, we need + # it in the Import File for the 'aix-soname' feature, so we have + # to replace the "-B" option with "-P" for AIX nm. + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # have runtime linking enabled, and use it for executables. + # For shared libraries, we enable/disable runtime linking + # depending on the kind of the shared library created - + # when "with_aix_soname,aix_use_runtimelinking" is: + # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables + # "aix,yes" lib.so shared, rtl:yes, for executables + # lib.a static archive + # "both,no" lib.so.V(shr.o) shared, rtl:yes + # lib.a(lib.so.V) shared, rtl:no, for executables + # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a(lib.so.V) shared, rtl:no + # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a static archive + case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) + for ld_flag in $LDFLAGS; do + if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then + aix_use_runtimelinking=yes + break + fi + done + if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then + # With aix-soname=svr4, we create the lib.so.V shared archives only, + # so we don't have lib.a shared libs to link our executables. + # We have to force runtime linking in this case. + aix_use_runtimelinking=yes + LDFLAGS="$LDFLAGS -Wl,-brtl" + fi + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds='' + hardcode_direct=yes + hardcode_direct_absolute=yes + hardcode_libdir_separator=':' + link_all_deplibs=yes + file_list_spec='$wl-f,' + case $with_aix_soname,$aix_use_runtimelinking in + aix,*) ;; # traditional, no import file + svr4,* | *,yes) # use import file + # The Import File defines what to hardcode. + hardcode_direct=no + hardcode_direct_absolute=no + ;; + esac + + if test yes = "$GCC"; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`$CC -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + hardcode_direct=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L=yes + hardcode_libdir_flag_spec='-L$libdir' + hardcode_libdir_separator= + fi + ;; + esac + shared_flag='-shared' + if test yes = "$aix_use_runtimelinking"; then + shared_flag="$shared_flag "'$wl-G' + fi + # Need to ensure runtime linking is disabled for the traditional + # shared library, or the linker may eventually find shared libraries + # /with/ Import File - we do not want to mix them. + shared_flag_aix='-shared' + shared_flag_svr4='-shared $wl-G' + else + # not using gcc + if test ia64 = "$host_cpu"; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test yes = "$aix_use_runtimelinking"; then + shared_flag='$wl-G' + else + shared_flag='$wl-bM:SRE' + fi + shared_flag_aix='$wl-bM:SRE' + shared_flag_svr4='$wl-G' + fi + fi + + export_dynamic_flag_spec='$wl-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + always_export_symbols=yes + if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag='-berok' + # Determine the default libpath from the value encoded in an + # empty executable. + if test set = "${lt_cv_aix_libpath+set}"; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath_+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=/usr/lib:/lib + fi + +fi + + aix_libpath=$lt_cv_aix_libpath_ +fi + + hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath" + archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag + else + if test ia64 = "$host_cpu"; then + hardcode_libdir_flag_spec='$wl-R $libdir:/usr/lib:/lib' + allow_undefined_flag="-z nodefs" + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + if test set = "${lt_cv_aix_libpath+set}"; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath_+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=/usr/lib:/lib + fi + +fi + + aix_libpath=$lt_cv_aix_libpath_ +fi + + hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag=' $wl-bernotok' + allow_undefined_flag=' $wl-berok' + if test yes = "$with_gnu_ld"; then + # We only use this code for GNU lds that support --whole-archive. + whole_archive_flag_spec='$wl--whole-archive$convenience $wl--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec='$convenience' + fi + archive_cmds_need_lc=yes + archive_expsym_cmds='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' + # -brtl affects multiple linker settings, -berok does not and is overridden later + compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([, ]\\)%-berok\\1%g"`' + if test svr4 != "$with_aix_soname"; then + # This is similar to how AIX traditionally builds its shared libraries. + archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' + fi + if test aix != "$with_aix_soname"; then + archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' + else + # used by -dlpreopen to get the symbols + archive_expsym_cmds="$archive_expsym_cmds"'~$MV $output_objdir/$realname.d/$soname $output_objdir' + fi + archive_expsym_cmds="$archive_expsym_cmds"'~$RM -r $output_objdir/$realname.d' + fi + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='' + ;; + m68k) + archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + + bsdi[45]*) + export_dynamic_flag_spec=-rdynamic + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + case $cc_basename in + cl*) + # Native MSVC + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + always_export_symbols=yes + file_list_spec='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=.dll + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' + archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then + cp "$export_symbols" "$output_objdir/$soname.def"; + echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; + else + $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, )='true' + enable_shared_with_static_runtimes=yes + exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' + # Don't use ranlib + old_postinstall_cmds='chmod 644 $oldlib' + postlink_cmds='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile=$lt_outputfile.exe + lt_tool_outputfile=$lt_tool_outputfile.exe + ;; + esac~ + if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # Assume MSVC wrapper + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=.dll + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + old_archive_from_new_cmds='true' + # FIXME: Should let the user specify the lib program. + old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' + enable_shared_with_static_runtimes=yes + ;; + esac + ;; + + darwin* | rhapsody*) + + + archive_cmds_need_lc=no + hardcode_direct=no + hardcode_automatic=yes + hardcode_shlibpath_var=unsupported + if test yes = "$lt_cv_ld_force_load"; then + whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + + else + whole_archive_flag_spec='' + fi + link_all_deplibs=yes + allow_undefined_flag=$_lt_dar_allow_undefined + case $cc_basename in + ifort*|nagfor*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test yes = "$_lt_dar_can_shared"; then + output_verbose_link_cmd=func_echo_all + archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" + module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" + archive_expsym_cmds="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" + module_expsym_cmds="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" + + else + ld_shlibs=no + fi + + ;; + + dgux*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2.*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | dragonfly*) + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + hpux9*) + if test yes = "$GCC"; then + archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + else + archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + fi + hardcode_libdir_flag_spec='$wl+b $wl$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + export_dynamic_flag_spec='$wl-E' + ;; + + hpux10*) + if test yes,no = "$GCC,$with_gnu_ld"; then + archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test no = "$with_gnu_ld"; then + hardcode_libdir_flag_spec='$wl+b $wl$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + hardcode_direct_absolute=yes + export_dynamic_flag_spec='$wl-E' + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + fi + ;; + + hpux11*) + if test yes,no = "$GCC,$with_gnu_ld"; then + case $host_cpu in + hppa*64*) + archive_cmds='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + archive_cmds='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + + # Older versions of the 11.00 compiler do not understand -b yet + # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 +$as_echo_n "checking if $CC understands -b... " >&6; } +if ${lt_cv_prog_compiler__b+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler__b=no + save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS -b" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler__b=yes + fi + else + lt_cv_prog_compiler__b=yes + fi + fi + $RM -r conftest* + LDFLAGS=$save_LDFLAGS + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 +$as_echo "$lt_cv_prog_compiler__b" >&6; } + +if test yes = "$lt_cv_prog_compiler__b"; then + archive_cmds='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' +else + archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' +fi + + ;; + esac + fi + if test no = "$with_gnu_ld"; then + hardcode_libdir_flag_spec='$wl+b $wl$libdir' + hardcode_libdir_separator=: + + case $host_cpu in + hppa*64*|ia64*) + hardcode_direct=no + hardcode_shlibpath_var=no + ;; + *) + hardcode_direct=yes + hardcode_direct_absolute=yes + export_dynamic_flag_spec='$wl-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test yes = "$GCC"; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + # Try to use the -exported_symbol ld option, if it does not + # work, assume that -exports_file does not work either and + # implicitly export all symbols. + # This should be the same for all languages, so no per-tag cache variable. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5 +$as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; } +if ${lt_cv_irix_exported_symbol+:} false; then : + $as_echo_n "(cached) " >&6 +else + save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int foo (void) { return 0; } +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_irix_exported_symbol=yes +else + lt_cv_irix_exported_symbol=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5 +$as_echo "$lt_cv_irix_exported_symbol" >&6; } + if test yes = "$lt_cv_irix_exported_symbol"; then + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib' + fi + else + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + hardcode_libdir_separator=: + inherit_rpath=yes + link_all_deplibs=yes + ;; + + linux*) + case $cc_basename in + tcc*) + # Fabrice Bellard et al's Tiny C Compiler + ld_shlibs=yes + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + newsos6) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + hardcode_libdir_separator=: + hardcode_shlibpath_var=no + ;; + + *nto* | *qnx*) + ;; + + openbsd* | bitrig*) + if test -f /usr/libexec/ld.so; then + hardcode_direct=yes + hardcode_shlibpath_var=no + hardcode_direct_absolute=yes + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols' + hardcode_libdir_flag_spec='$wl-rpath,$libdir' + export_dynamic_flag_spec='$wl-E' + else + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='$wl-rpath,$libdir' + fi + else + ld_shlibs=no + fi + ;; + + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported + shrext_cmds=.dll + archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + prefix_cmds="$SED"~ + if test EXPORTS = "`$SED 1q $export_symbols`"; then + prefix_cmds="$prefix_cmds -e 1d"; + fi~ + prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ + cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + enable_shared_with_static_runtimes=yes + ;; + + osf3*) + if test yes = "$GCC"; then + allow_undefined_flag=' $wl-expect_unresolved $wl\*' + archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + hardcode_libdir_separator=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test yes = "$GCC"; then + allow_undefined_flag=' $wl-expect_unresolved $wl\*' + archive_cmds='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp' + + # Both c and cxx compiler support -rpath directly + hardcode_libdir_flag_spec='-rpath $libdir' + fi + archive_cmds_need_lc='no' + hardcode_libdir_separator=: + ;; + + solaris*) + no_undefined_flag=' -z defs' + if test yes = "$GCC"; then + wlarc='$wl' + archive_cmds='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + else + case `$CC -V 2>&1` in + *"Compilers 5.0"*) + wlarc='' + archive_cmds='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' + ;; + *) + wlarc='$wl' + archive_cmds='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + ;; + esac + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_shlibpath_var=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands '-z linker_flag'. GCC discards it without '$wl', + # but is careful enough not to reorder. + # Supported since Solaris 2.6 (maybe 2.5.1?) + if test yes = "$GCC"; then + whole_archive_flag_spec='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' + else + whole_archive_flag_spec='-z allextract$convenience -z defaultextract' + fi + ;; + esac + link_all_deplibs=yes + ;; + + sunos4*) + if test sequent = "$host_vendor"; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + archive_cmds='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + hardcode_libdir_flag_spec='-L$libdir' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + sysv4) + case $host_vendor in + sni) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' + reload_cmds='$CC -r -o $output$reload_objs' + hardcode_direct=no + ;; + motorola) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var=no + ;; + + sysv4.3*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + export_dynamic_flag_spec='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ld_shlibs=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + no_undefined_flag='$wl-z,text' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + runpath_var='LD_RUN_PATH' + + if test yes = "$GCC"; then + archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We CANNOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag='$wl-z,text' + allow_undefined_flag='$wl-z,nodefs' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='$wl-R,$libdir' + hardcode_libdir_separator=':' + link_all_deplibs=yes + export_dynamic_flag_spec='$wl-Bexport' + runpath_var='LD_RUN_PATH' + + if test yes = "$GCC"; then + archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + *) + ld_shlibs=no + ;; + esac + + if test sni = "$host_vendor"; then + case $host in + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + export_dynamic_flag_spec='$wl-Blargedynsym' + ;; + esac + fi + fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 +$as_echo "$ld_shlibs" >&6; } +test no = "$ld_shlibs" && can_build_shared=no + +with_gnu_ld=$with_gnu_ld + + + + + + + + + + + + + + + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc=yes + + if test yes,yes = "$GCC,$enable_shared"; then + case $archive_cmds in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 +$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } +if ${lt_cv_archive_cmds_need_lc+:} false; then : + $as_echo_n "(cached) " >&6 +else + $RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl + pic_flag=$lt_prog_compiler_pic + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag + allow_undefined_flag= + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 + (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + then + lt_cv_archive_cmds_need_lc=no + else + lt_cv_archive_cmds_need_lc=yes + fi + allow_undefined_flag=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 +$as_echo "$lt_cv_archive_cmds_need_lc" >&6; } + archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc + ;; + esac + fi + ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 +$as_echo_n "checking dynamic linker characteristics... " >&6; } + +if test yes = "$GCC"; then + case $host_os in + darwin*) lt_awk_arg='/^libraries:/,/LR/' ;; + *) lt_awk_arg='/^libraries:/' ;; + esac + case $host_os in + mingw* | cegcc*) lt_sed_strip_eq='s|=\([A-Za-z]:\)|\1|g' ;; + *) lt_sed_strip_eq='s|=/|/|g' ;; + esac + lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` + case $lt_search_path_spec in + *\;*) + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` + ;; + *) + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` + ;; + esac + # Ok, now we have the path, separated by spaces, we can step through it + # and add multilib dir if necessary... + lt_tmp_lt_search_path_spec= + lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + # ...but if some path component already ends with the multilib dir we assume + # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer). + case "$lt_multi_os_dir; $lt_search_path_spec " in + "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*) + lt_multi_os_dir= + ;; + esac + for lt_sys_path in $lt_search_path_spec; do + if test -d "$lt_sys_path$lt_multi_os_dir"; then + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir" + elif test -n "$lt_multi_os_dir"; then + test -d "$lt_sys_path" && \ + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" + fi + done + lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' +BEGIN {RS = " "; FS = "/|\n";} { + lt_foo = ""; + lt_count = 0; + for (lt_i = NF; lt_i > 0; lt_i--) { + if ($lt_i != "" && $lt_i != ".") { + if ($lt_i == "..") { + lt_count++; + } else { + if (lt_count == 0) { + lt_foo = "/" $lt_i lt_foo; + } else { + lt_count--; + } + } + } + } + if (lt_foo != "") { lt_freq[lt_foo]++; } + if (lt_freq[lt_foo] == 1) { print lt_foo; } +}'` + # AWK program above erroneously prepends '/' to C:/dos/paths + # for these hosts. + case $host_os in + mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ + $SED 's|/\([A-Za-z]:\)|\1|g'` ;; + esac + sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=.so +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + + + +case $host_os in +aix3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='$libname$release$shared_ext$major' + ;; + +aix[4-9]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test ia64 = "$host_cpu"; then + # AIX 5 supports IA64 + library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line '#! .'. This would cause the generated library to + # depend on '.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # Using Import Files as archive members, it is possible to support + # filename-based versioning of shared library archives on AIX. While + # this would work for both with and without runtime linking, it will + # prevent static linking of such archives. So we do filename-based + # shared library versioning with .so extension only, which is used + # when both runtime linking and shared linking is enabled. + # Unfortunately, runtime linking may impact performance, so we do + # not want this to be the default eventually. Also, we use the + # versioned .so libs for executables only if there is the -brtl + # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. + # To allow for filename-based versioning support, we need to create + # libNAME.so.V as an archive file, containing: + # *) an Import File, referring to the versioned filename of the + # archive as well as the shared archive member, telling the + # bitwidth (32 or 64) of that shared object, and providing the + # list of exported symbols of that shared object, eventually + # decorated with the 'weak' keyword + # *) the shared object with the F_LOADONLY flag set, to really avoid + # it being seen by the linker. + # At run time we better use the real file rather than another symlink, + # but for link time we create the symlink libNAME.so -> libNAME.so.V + + case $with_aix_soname,$aix_use_runtimelinking in + # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + aix,yes) # traditional libtool + dynamic_linker='AIX unversionable lib.so' + # If using run time linking (on AIX 4.2 or later) use lib<name>.so + # instead of lib<name>.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + ;; + aix,no) # traditional AIX only + dynamic_linker='AIX lib.a(lib.so.V)' + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' + ;; + svr4,*) # full svr4 only + dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o)" + library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' + # We do not specify a path in Import Files, so LIBPATH fires. + shlibpath_overrides_runpath=yes + ;; + *,yes) # both, prefer svr4 + dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o), lib.a(lib.so.V)" + library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' + # unpreferred sharedlib libNAME.a needs extra handling + postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' + postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' + # We do not specify a path in Import Files, so LIBPATH fires. + shlibpath_overrides_runpath=yes + ;; + *,no) # both, prefer aix + dynamic_linker="AIX lib.a(lib.so.V), lib.so.V($shared_archive_member_spec.o)" + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' + # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling + postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' + postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' + ;; + esac + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='$libname$shared_ext' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=.dll + need_version=no + need_lib_prefix=no + + case $GCC,$cc_basename in + yes,*) + # gcc + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + ;; + esac + dynamic_linker='Win32 ld.exe' + ;; + + *,cl*) + # Native MSVC + libname_spec='$name' + soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + library_names_spec='$libname.dll.lib' + + case $build_os in + mingw*) + sys_lib_search_path_spec= + lt_save_ifs=$IFS + IFS=';' + for lt_path in $LIB + do + IFS=$lt_save_ifs + # Let DOS variable expansion print the short 8.3 style file name. + lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` + sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" + done + IFS=$lt_save_ifs + # Convert to MSYS style. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` + ;; + cygwin*) + # Convert to unix form, then to dos form, then back to unix form + # but this time dos style (no spaces!) so that the unix form looks + # like /cygdrive/c/PROGRA~1:/cygdr... + sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` + sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` + sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + ;; + *) + sys_lib_search_path_spec=$LIB + if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # FIXME: find the short name or the path components, as spaces are + # common. (e.g. "Program Files" -> "PROGRA~1") + ;; + esac + + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + dynamic_linker='Win32 link.exe' + ;; + + *) + # Assume MSVC wrapper + library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib' + dynamic_linker='Win32 ld.exe' + ;; + esac + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' + soname_spec='$libname$release$major$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[23].*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2.*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +haiku*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + dynamic_linker="$host_os runtime_loader" + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LIBRARY_PATH + shlibpath_overrides_runpath=no + sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + if test 32 = "$HPUX_IA64_MODE"; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + sys_lib_dlsearch_path_spec=/usr/lib/hpux32 + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + sys_lib_dlsearch_path_spec=/usr/lib/hpux64 + fi + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555, ... + postinstall_cmds='chmod 555 $lib' + # or fails outright, so override atomically: + install_override_mode=555 + ;; + +interix[3-9]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test yes = "$lt_cv_prog_gnu_ld"; then + version_type=linux # correct to gnu/linux during the next big refactor + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" + sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +linux*android*) + version_type=none # Android doesn't support versioned libraries. + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext' + soname_spec='$libname$release$shared_ext' + finish_cmds= + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + dynamic_linker='Android linker' + # Don't embed -rpath directories since the linker doesn't support them. + hardcode_libdir_flag_spec='-L$libdir' + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + + # Some binutils ld are patched to set DT_RUNPATH + if ${lt_cv_shlibpath_overrides_runpath+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_shlibpath_overrides_runpath=no + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ + LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : + lt_cv_shlibpath_overrides_runpath=yes +fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + +fi + + shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Ideally, we could use ldconfig to report *all* directores which are + # searched for libraries, however this is still not possible. Aside from not + # being certain /sbin/ldconfig is available, command + # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, + # even though it is searched at run-time. Try to do the best guess by + # appending ld.so.conf contents (and includes) to the search path. + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd* | bitrig*) + version_type=sunos + sys_lib_dlsearch_path_spec=/usr/lib + need_lib_prefix=no + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + need_version=no + else + need_version=yes + fi + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +os2*) + libname_spec='$name' + version_type=windows + shrext_cmds=.dll + need_version=no + need_lib_prefix=no + # OS/2 can only load a DLL with a base name of 8 characters or less. + soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; + v=$($ECHO $release$versuffix | tr -d .-); + n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); + $ECHO $n$v`$shared_ext' + library_names_spec='${libname}_dll.$libext' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=BEGINLIBPATH + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test yes = "$with_gnu_ld"; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec; then + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' + soname_spec='$libname$shared_ext.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=sco + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test yes = "$with_gnu_ld"; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 +$as_echo "$dynamic_linker" >&6; } +test no = "$dynamic_linker" && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test yes = "$GCC"; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then + sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec +fi + +if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then + sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec +fi + +# remember unaugmented sys_lib_dlsearch_path content for libtool script decls... +configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec + +# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code +func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" + +# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool +configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 +$as_echo_n "checking how to hardcode library paths into programs... " >&6; } +hardcode_action= +if test -n "$hardcode_libdir_flag_spec" || + test -n "$runpath_var" || + test yes = "$hardcode_automatic"; then + + # We can hardcode non-existent directories. + if test no != "$hardcode_direct" && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, )" && + test no != "$hardcode_minus_L"; then + # Linking always hardcodes the temporary library directory. + hardcode_action=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action=unsupported +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 +$as_echo "$hardcode_action" >&6; } + +if test relink = "$hardcode_action" || + test yes = "$inherit_rpath"; then + # Fast installation is not supported + enable_fast_install=no +elif test yes = "$shlibpath_overrides_runpath" || + test no = "$enable_shared"; then + # Fast installation is not necessary + enable_fast_install=needless +fi + + + + + + + if test yes != "$enable_dlopen"; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen=load_add_on + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32* | cegcc*) + lt_cv_dlopen=LoadLibrary + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen=dlopen + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +$as_echo_n "checking for dlopen in -ldl... " >&6; } +if ${ac_cv_lib_dl_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dl_dlopen=yes +else + ac_cv_lib_dl_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +$as_echo "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = xyes; then : + lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl +else + + lt_cv_dlopen=dyld + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + +fi + + ;; + + tpf*) + # Don't try to run any link tests for TPF. We know it's impossible + # because TPF is a cross-compiler, and we know how we open DSOs. + lt_cv_dlopen=dlopen + lt_cv_dlopen_libs= + lt_cv_dlopen_self=no + ;; + + *) + ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" +if test "x$ac_cv_func_shl_load" = xyes; then : + lt_cv_dlopen=shl_load +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 +$as_echo_n "checking for shl_load in -ldld... " >&6; } +if ${ac_cv_lib_dld_shl_load+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char shl_load (); +int +main () +{ +return shl_load (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dld_shl_load=yes +else + ac_cv_lib_dld_shl_load=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 +$as_echo "$ac_cv_lib_dld_shl_load" >&6; } +if test "x$ac_cv_lib_dld_shl_load" = xyes; then : + lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld +else + ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" +if test "x$ac_cv_func_dlopen" = xyes; then : + lt_cv_dlopen=dlopen +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +$as_echo_n "checking for dlopen in -ldl... " >&6; } +if ${ac_cv_lib_dl_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dl_dlopen=yes +else + ac_cv_lib_dl_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +$as_echo "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = xyes; then : + lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 +$as_echo_n "checking for dlopen in -lsvld... " >&6; } +if ${ac_cv_lib_svld_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsvld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_svld_dlopen=yes +else + ac_cv_lib_svld_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 +$as_echo "$ac_cv_lib_svld_dlopen" >&6; } +if test "x$ac_cv_lib_svld_dlopen" = xyes; then : + lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 +$as_echo_n "checking for dld_link in -ldld... " >&6; } +if ${ac_cv_lib_dld_dld_link+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dld_link (); +int +main () +{ +return dld_link (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dld_dld_link=yes +else + ac_cv_lib_dld_dld_link=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 +$as_echo "$ac_cv_lib_dld_dld_link" >&6; } +if test "x$ac_cv_lib_dld_dld_link" = xyes; then : + lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld +fi + + +fi + + +fi + + +fi + + +fi + + +fi + + ;; + esac + + if test no = "$lt_cv_dlopen"; then + enable_dlopen=no + else + enable_dlopen=yes + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS=$CPPFLAGS + test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS=$LDFLAGS + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS=$LIBS + LIBS="$lt_cv_dlopen_libs $LIBS" + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 +$as_echo_n "checking whether a program can dlopen itself... " >&6; } +if ${lt_cv_dlopen_self+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test yes = "$cross_compiling"; then : + lt_cv_dlopen_self=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include <dlfcn.h> +#endif + +#include <stdio.h> + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisibility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +} +_LT_EOF + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self=no + fi +fi +rm -fr conftest* + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 +$as_echo "$lt_cv_dlopen_self" >&6; } + + if test yes = "$lt_cv_dlopen_self"; then + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 +$as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; } +if ${lt_cv_dlopen_self_static+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test yes = "$cross_compiling"; then : + lt_cv_dlopen_self_static=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include <dlfcn.h> +#endif + +#include <stdio.h> + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisibility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +} +_LT_EOF + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self_static=no + fi +fi +rm -fr conftest* + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 +$as_echo "$lt_cv_dlopen_self_static" >&6; } + fi + + CPPFLAGS=$save_CPPFLAGS + LDFLAGS=$save_LDFLAGS + LIBS=$save_LIBS + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi + + + + + + + + + + + + + + + + + +striplib= +old_striplib= +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 +$as_echo_n "checking whether stripping libraries is possible... " >&6; } +if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP"; then + striplib="$STRIP -x" + old_striplib="$STRIP -S" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + fi + ;; + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + ;; + esac +fi + + + + + + + + + + + + + # Report what library types will actually be built + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 +$as_echo_n "checking if libtool supports shared libraries... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 +$as_echo "$can_build_shared" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 +$as_echo_n "checking whether to build shared libraries... " >&6; } + test no = "$can_build_shared" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test yes = "$enable_shared" && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + + aix[4-9]*) + if test ia64 != "$host_cpu"; then + case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in + yes,aix,yes) ;; # shared object as lib.so file only + yes,svr4,*) ;; # shared object as lib.so archive member only + yes,*) enable_static=no ;; # shared object in lib.a archive as well + esac + fi + ;; + esac + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 +$as_echo "$enable_shared" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 +$as_echo_n "checking whether to build static libraries... " >&6; } + # Make sure either enable_shared or enable_static is yes. + test yes = "$enable_shared" || enable_static=yes + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 +$as_echo "$enable_static" >&6; } + + + + +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +CC=$lt_save_CC + + + + + + + + + + + + + + + + ac_config_commands="$ac_config_commands libtool" + + + + +# Only expand once: + + +# From configure.ac Revision: 4.34 . +config_start_time=`date +%s 2>/dev/null` +# ---------------------------------------------------------------------- +# Substitute VERSION vars here, so that they can be used by the Makefile +# ---------------------------------------------------------------------- + + + + + + +AO_TEMPLATE_VERSION=`expr '(' $AO_CURRENT '*' 4096 ')' + $AO_REVISION` + + + + + +cat >>confdefs.h <<_ACEOF +#define AO_CURRENT $AO_CURRENT +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define AO_REVISION $AO_REVISION +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define AO_AGE $AO_AGE +_ACEOF + +# ---------------------------------------------------------------------- +# Set up the environment to configure the snprintv subpackage using +# this version of AutoGen (as opposed to any installed version). +# ---------------------------------------------------------------------- +ag_srcdir=`\cd $srcdir && pwd` +if test x$ag_srcdir != x && test -d $ag_srcdir; then + : +else + ag_srcdir=.. +fi + +# ---------------------------------------------------------------------- +# If `configure' is invoked (in)directly via `make', ensure that it +# encounters no `make' conflicts. Ignore error if shell does not have +# unset, but at least set these to empty values. +# ---------------------------------------------------------------------- +MFLAGS= +MAKEFLAGS= +MAKELEVEL= +unset MFLAGS MAKEFLAGS MAKELEVEL 2>/dev/null + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if malloc debugging is wanted" >&5 +$as_echo_n "checking if malloc debugging is wanted... " >&6; } + +# Check whether --with-dmalloc was given. +if test "${with_dmalloc+set}" = set; then : + withval=$with_dmalloc; if test "$withval" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define WITH_DMALLOC 1" >>confdefs.h + + LIBS="$LIBS -ldmalloc" + LDFLAGS="$LDFLAGS -g" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + +# ---------------------------------------------------------------------- +# check for various programs used during the build. +# ---------------------------------------------------------------------- + case $ac_cv_prog_cc_stdc in #( + no) : + ac_cv_prog_cc_c99=no; ac_cv_prog_cc_c89=no ;; #( + *) : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C99" >&5 +$as_echo_n "checking for $CC option to accept ISO C99... " >&6; } +if ${ac_cv_prog_cc_c99+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c99=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdarg.h> +#include <stdbool.h> +#include <stdlib.h> +#include <wchar.h> +#include <stdio.h> + +// Check varargs macros. These examples are taken from C99 6.10.3.5. +#define debug(...) fprintf (stderr, __VA_ARGS__) +#define showlist(...) puts (#__VA_ARGS__) +#define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__)) +static void +test_varargs_macros (void) +{ + int x = 1234; + int y = 5678; + debug ("Flag"); + debug ("X = %d\n", x); + showlist (The first, second, and third items.); + report (x>y, "x is %d but y is %d", x, y); +} + +// Check long long types. +#define BIG64 18446744073709551615ull +#define BIG32 4294967295ul +#define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0) +#if !BIG_OK + your preprocessor is broken; +#endif +#if BIG_OK +#else + your preprocessor is broken; +#endif +static long long int bignum = -9223372036854775807LL; +static unsigned long long int ubignum = BIG64; + +struct incomplete_array +{ + int datasize; + double data[]; +}; + +struct named_init { + int number; + const wchar_t *name; + double average; +}; + +typedef const char *ccp; + +static inline int +test_restrict (ccp restrict text) +{ + // See if C++-style comments work. + // Iterate through items via the restricted pointer. + // Also check for declarations in for loops. + for (unsigned int i = 0; *(text+i) != '\0'; ++i) + continue; + return 0; +} + +// Check varargs and va_copy. +static void +test_varargs (const char *format, ...) +{ + va_list args; + va_start (args, format); + va_list args_copy; + va_copy (args_copy, args); + + const char *str; + int number; + float fnumber; + + while (*format) + { + switch (*format++) + { + case 's': // string + str = va_arg (args_copy, const char *); + break; + case 'd': // int + number = va_arg (args_copy, int); + break; + case 'f': // float + fnumber = va_arg (args_copy, double); + break; + default: + break; + } + } + va_end (args_copy); + va_end (args); +} + +int +main () +{ + + // Check bool. + _Bool success = false; + + // Check restrict. + if (test_restrict ("String literal") == 0) + success = true; + char *restrict newvar = "Another string"; + + // Check varargs. + test_varargs ("s, d' f .", "string", 65, 34.234); + test_varargs_macros (); + + // Check flexible array members. + struct incomplete_array *ia = + malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10)); + ia->datasize = 10; + for (int i = 0; i < ia->datasize; ++i) + ia->data[i] = i * 1.234; + + // Check named initializers. + struct named_init ni = { + .number = 34, + .name = L"Test wide string", + .average = 543.34343, + }; + + ni.number = 58; + + int dynamic_array[ni.number]; + dynamic_array[ni.number - 1] = 543; + + // work around unused variable warnings + return (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == 'x' + || dynamic_array[ni.number - 1] != 543); + + ; + return 0; +} +_ACEOF +for ac_arg in '' -std=gnu99 -std=c99 -c99 -AC99 -D_STDC_C99= -qlanglvl=extc99 +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c99=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c99" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c99" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c99" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5 +$as_echo "$ac_cv_prog_cc_c99" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c99" != xno; then : + ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c99 +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if ${ac_cv_prog_cc_c89+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdarg.h> +#include <stdio.h> +struct stat; +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c89" != xno; then : + ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c89 +else + ac_cv_prog_cc_stdc=no +fi + +fi + ;; +esac + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO Standard C" >&5 +$as_echo_n "checking for $CC option to accept ISO Standard C... " >&6; } + if ${ac_cv_prog_cc_stdc+:} false; then : + $as_echo_n "(cached) " >&6 +fi + + case $ac_cv_prog_cc_stdc in #( + no) : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; #( + '') : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; #( + *) : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_stdc" >&5 +$as_echo "$ac_cv_prog_cc_stdc" >&6; } ;; +esac + + + + + + + + + + ac_fn_c_check_decl "$LINENO" "clearerr_unlocked" "ac_cv_have_decl_clearerr_unlocked" "$ac_includes_default" +if test "x$ac_cv_have_decl_clearerr_unlocked" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_CLEARERR_UNLOCKED $ac_have_decl +_ACEOF + + + + ac_fn_c_check_decl "$LINENO" "feof_unlocked" "ac_cv_have_decl_feof_unlocked" "$ac_includes_default" +if test "x$ac_cv_have_decl_feof_unlocked" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_FEOF_UNLOCKED $ac_have_decl +_ACEOF + + + + ac_fn_c_check_decl "$LINENO" "ferror_unlocked" "ac_cv_have_decl_ferror_unlocked" "$ac_includes_default" +if test "x$ac_cv_have_decl_ferror_unlocked" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_FERROR_UNLOCKED $ac_have_decl +_ACEOF + + + + ac_fn_c_check_decl "$LINENO" "fflush_unlocked" "ac_cv_have_decl_fflush_unlocked" "$ac_includes_default" +if test "x$ac_cv_have_decl_fflush_unlocked" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_FFLUSH_UNLOCKED $ac_have_decl +_ACEOF + + + + ac_fn_c_check_decl "$LINENO" "fgets_unlocked" "ac_cv_have_decl_fgets_unlocked" "$ac_includes_default" +if test "x$ac_cv_have_decl_fgets_unlocked" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_FGETS_UNLOCKED $ac_have_decl +_ACEOF + + + + ac_fn_c_check_decl "$LINENO" "fputc_unlocked" "ac_cv_have_decl_fputc_unlocked" "$ac_includes_default" +if test "x$ac_cv_have_decl_fputc_unlocked" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_FPUTC_UNLOCKED $ac_have_decl +_ACEOF + + + + ac_fn_c_check_decl "$LINENO" "fputs_unlocked" "ac_cv_have_decl_fputs_unlocked" "$ac_includes_default" +if test "x$ac_cv_have_decl_fputs_unlocked" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_FPUTS_UNLOCKED $ac_have_decl +_ACEOF + + + + ac_fn_c_check_decl "$LINENO" "fread_unlocked" "ac_cv_have_decl_fread_unlocked" "$ac_includes_default" +if test "x$ac_cv_have_decl_fread_unlocked" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_FREAD_UNLOCKED $ac_have_decl +_ACEOF + + + + ac_fn_c_check_decl "$LINENO" "fwrite_unlocked" "ac_cv_have_decl_fwrite_unlocked" "$ac_includes_default" +if test "x$ac_cv_have_decl_fwrite_unlocked" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_FWRITE_UNLOCKED $ac_have_decl +_ACEOF + + + + ac_fn_c_check_decl "$LINENO" "getc_unlocked" "ac_cv_have_decl_getc_unlocked" "$ac_includes_default" +if test "x$ac_cv_have_decl_getc_unlocked" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_GETC_UNLOCKED $ac_have_decl +_ACEOF + + + + ac_fn_c_check_decl "$LINENO" "getchar_unlocked" "ac_cv_have_decl_getchar_unlocked" "$ac_includes_default" +if test "x$ac_cv_have_decl_getchar_unlocked" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_GETCHAR_UNLOCKED $ac_have_decl +_ACEOF + + + + ac_fn_c_check_decl "$LINENO" "putc_unlocked" "ac_cv_have_decl_putc_unlocked" "$ac_includes_default" +if test "x$ac_cv_have_decl_putc_unlocked" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_PUTC_UNLOCKED $ac_have_decl +_ACEOF + + + + ac_fn_c_check_decl "$LINENO" "putchar_unlocked" "ac_cv_have_decl_putchar_unlocked" "$ac_includes_default" +if test "x$ac_cv_have_decl_putchar_unlocked" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_PUTCHAR_UNLOCKED $ac_have_decl +_ACEOF + + + + +$as_echo "#define USE_UNLOCKED_IO 1" >>confdefs.h + + + + + + : + + + + + + + : + + + + + + + : + + + + + + + : + + + + + + + : + + + + + + + : + + + + + + + : + + + + + + + : + + + + + + + : + + + + + + + : + + + + + + + : + + + + + + + : + + + + + + + : + + + + + + + + + +# Extract the first word of "texi2html", so it can be a program name with args. +set dummy texi2html; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_TEXI2HTML+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$TEXI2HTML"; then + ac_cv_prog_TEXI2HTML="$TEXI2HTML" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_TEXI2HTML="texi2html" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_prog_TEXI2HTML" && ac_cv_prog_TEXI2HTML=":" +fi +fi +TEXI2HTML=$ac_cv_prog_TEXI2HTML +if test -n "$TEXI2HTML"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $TEXI2HTML" >&5 +$as_echo "$TEXI2HTML" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5 +$as_echo_n "checking for an ANSI C-conforming const... " >&6; } +if ${ac_cv_c_const+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + +#ifndef __cplusplus + /* Ultrix mips cc rejects this sort of thing. */ + typedef int charset[2]; + const charset cs = { 0, 0 }; + /* SunOS 4.1.1 cc rejects this. */ + char const *const *pcpcc; + char **ppc; + /* NEC SVR4.0.2 mips cc rejects this. */ + struct point {int x, y;}; + static struct point const zero = {0,0}; + /* AIX XL C 1.02.0.0 rejects this. + It does not let you subtract one const X* pointer from another in + an arm of an if-expression whose if-part is not a constant + expression */ + const char *g = "string"; + pcpcc = &g + (g ? g-g : 0); + /* HPUX 7.0 cc rejects these. */ + ++pcpcc; + ppc = (char**) pcpcc; + pcpcc = (char const *const *) ppc; + { /* SCO 3.2v4 cc rejects this sort of thing. */ + char tx; + char *t = &tx; + char const *s = 0 ? (char *) 0 : (char const *) 0; + + *t++ = 0; + if (s) return 0; + } + { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ + int x[] = {25, 17}; + const int *foo = &x[0]; + ++foo; + } + { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ + typedef const int *iptr; + iptr p = 0; + ++p; + } + { /* AIX XL C 1.02.0.0 rejects this sort of thing, saying + "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ + struct s { int j; const int *ap[3]; } bx; + struct s *b = &bx; b->j = 5; + } + { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ + const int foo = 10; + if (!foo) return 0; + } + return !cs[0] && !zero.x; +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_const=yes +else + ac_cv_c_const=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5 +$as_echo "$ac_cv_c_const" >&6; } +if test $ac_cv_c_const = no; then + +$as_echo "#define const /**/" >>confdefs.h + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5 +$as_echo_n "checking for inline... " >&6; } +if ${ac_cv_c_inline+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_c_inline=no +for ac_kw in inline __inline__ __inline; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifndef __cplusplus +typedef int foo_t; +static $ac_kw foo_t static_foo () {return 0; } +$ac_kw foo_t foo () {return 0; } +#endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_inline=$ac_kw +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + test "$ac_cv_c_inline" != no && break +done + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5 +$as_echo "$ac_cv_c_inline" >&6; } + +case $ac_cv_c_inline in + inline | yes) ;; + *) + case $ac_cv_c_inline in + no) ac_val=;; + *) ac_val=$ac_cv_c_inline;; + esac + cat >>confdefs.h <<_ACEOF +#ifndef __cplusplus +#define inline $ac_val +#endif +_ACEOF + ;; +esac + +# ---------------------------------------------------------------------- +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +$as_echo_n "checking for dlopen in -ldl... " >&6; } +if ${ac_cv_lib_dl_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dl_dlopen=yes +else + ac_cv_lib_dl_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +$as_echo "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBDL 1 +_ACEOF + + LIBS="-ldl $LIBS" + +fi + +# ---------------------------------------------------------------------- +ac_fn_c_check_type "$LINENO" "mode_t" "ac_cv_type_mode_t" "$ac_includes_default" +if test "x$ac_cv_type_mode_t" = xyes; then : + +else + +cat >>confdefs.h <<_ACEOF +#define mode_t int +_ACEOF + +fi + +ac_fn_c_check_type "$LINENO" "pid_t" "ac_cv_type_pid_t" "$ac_includes_default" +if test "x$ac_cv_type_pid_t" = xyes; then : + +else + +cat >>confdefs.h <<_ACEOF +#define pid_t int +_ACEOF + +fi + +ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" +if test "x$ac_cv_type_size_t" = xyes; then : + +else + +cat >>confdefs.h <<_ACEOF +#define size_t unsigned int +_ACEOF + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for uid_t in sys/types.h" >&5 +$as_echo_n "checking for uid_t in sys/types.h... " >&6; } +if ${ac_cv_type_uid_t+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <sys/types.h> + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "uid_t" >/dev/null 2>&1; then : + ac_cv_type_uid_t=yes +else + ac_cv_type_uid_t=no +fi +rm -f conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_uid_t" >&5 +$as_echo "$ac_cv_type_uid_t" >&6; } +if test $ac_cv_type_uid_t = no; then + +$as_echo "#define uid_t int" >>confdefs.h + + +$as_echo "#define gid_t int" >>confdefs.h + +fi + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for long double with more range or precision than double" >&5 +$as_echo_n "checking for long double with more range or precision than double... " >&6; } +if ${ac_cv_type_long_double_wider+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <float.h> + long double const a[] = + { + 0.0L, DBL_MIN, DBL_MAX, DBL_EPSILON, + LDBL_MIN, LDBL_MAX, LDBL_EPSILON + }; + long double + f (long double x) + { + return ((x + (unsigned long int) 10) * (-1 / x) + a[0] + + (x ? f (x) : 'c')); + } + +int +main () +{ +static int test_array [1 - 2 * !((0 < ((DBL_MAX_EXP < LDBL_MAX_EXP) + + (DBL_MANT_DIG < LDBL_MANT_DIG) + - (LDBL_MAX_EXP < DBL_MAX_EXP) + - (LDBL_MANT_DIG < DBL_MANT_DIG))) + && (int) LDBL_EPSILON == 0 + )]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_type_long_double_wider=yes +else + ac_cv_type_long_double_wider=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_long_double_wider" >&5 +$as_echo "$ac_cv_type_long_double_wider" >&6; } + if test $ac_cv_type_long_double_wider = yes; then + +$as_echo "#define HAVE_LONG_DOUBLE_WIDER 1" >>confdefs.h + + fi + + ac_cv_c_long_double=$ac_cv_type_long_double_wider + if test $ac_cv_c_long_double = yes; then + +$as_echo "#define HAVE_LONG_DOUBLE 1" >>confdefs.h + + fi + +if test x$ac_cv_type_long_double = xno; then + snv_long_double=double +else + snv_long_double='long double' +fi + +cat >>confdefs.h <<_ACEOF +#define SNV_LONG_DOUBLE $snv_long_double +_ACEOF + +ac_fn_c_check_type "$LINENO" "long long" "ac_cv_type_long_long" "$ac_includes_default" +if test "x$ac_cv_type_long_long" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_LONG_LONG 1 +_ACEOF + + +fi +ac_fn_c_check_type "$LINENO" "uintmax_t" "ac_cv_type_uintmax_t" "$ac_includes_default" +if test "x$ac_cv_type_uintmax_t" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_UINTMAX_T 1 +_ACEOF + + +fi +ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" +if test "x$ac_cv_type_size_t" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_SIZE_T 1 +_ACEOF + + +fi +ac_fn_c_check_type "$LINENO" "wchar_t" "ac_cv_type_wchar_t" "$ac_includes_default" +if test "x$ac_cv_type_wchar_t" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_WCHAR_T 1 +_ACEOF + + +fi + +# The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of char*" >&5 +$as_echo_n "checking size of char*... " >&6; } +if ${ac_cv_sizeof_charp+:} false; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (char*))" "ac_cv_sizeof_charp" "$ac_includes_default"; then : + +else + if test "$ac_cv_type_charp" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (char*) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_charp=0 + fi +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_charp" >&5 +$as_echo "$ac_cv_sizeof_charp" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_CHARP $ac_cv_sizeof_charp +_ACEOF + + +# The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of int" >&5 +$as_echo_n "checking size of int... " >&6; } +if ${ac_cv_sizeof_int+:} false; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (int))" "ac_cv_sizeof_int" "$ac_includes_default"; then : + +else + if test "$ac_cv_type_int" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (int) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_int=0 + fi +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_int" >&5 +$as_echo "$ac_cv_sizeof_int" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_INT $ac_cv_sizeof_int +_ACEOF + + +# The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long" >&5 +$as_echo_n "checking size of long... " >&6; } +if ${ac_cv_sizeof_long+:} false; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long))" "ac_cv_sizeof_long" "$ac_includes_default"; then : + +else + if test "$ac_cv_type_long" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (long) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_long=0 + fi +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long" >&5 +$as_echo "$ac_cv_sizeof_long" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_LONG $ac_cv_sizeof_long +_ACEOF + + +# The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of short" >&5 +$as_echo_n "checking size of short... " >&6; } +if ${ac_cv_sizeof_short+:} false; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (short))" "ac_cv_sizeof_short" "$ac_includes_default"; then : + +else + if test "$ac_cv_type_short" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (short) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_short=0 + fi +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_short" >&5 +$as_echo "$ac_cv_sizeof_short" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_SHORT $ac_cv_sizeof_short +_ACEOF + + +# ---------------------------------------------------------------------- + +# ---------------------------------------------------------------------- +# Do all our own macros +# ---------------------------------------------------------------------- + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for unsigned long long int" >&5 +$as_echo_n "checking for unsigned long long int... " >&6; } +if ${ac_cv_type_unsigned_long_long_int+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_type_unsigned_long_long_int=yes + if test "x${ac_cv_prog_cc_c99-no}" = xno; then + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + /* 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; +int +main () +{ +/* 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)); + ; + return 0; +} + +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + +else + ac_cv_type_unsigned_long_long_int=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_unsigned_long_long_int" >&5 +$as_echo "$ac_cv_type_unsigned_long_long_int" >&6; } + if test $ac_cv_type_unsigned_long_long_int = yes; then + +$as_echo "#define HAVE_UNSIGNED_LONG_LONG_INT 1" >>confdefs.h + + fi + + + stat_nsec_found=no + ac_fn_c_check_member "$LINENO" "struct stat" "st_mtim" "ac_cv_member_struct_stat_st_mtim" "#include <sys/stat.h> +" +if test "x$ac_cv_member_struct_stat_st_mtim" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_STRUCT_STAT_ST_MTIM 1 +_ACEOF + +stat_nsec_found=yes +fi +ac_fn_c_check_member "$LINENO" "struct stat" "st_mtimensec" "ac_cv_member_struct_stat_st_mtimensec" "#include <sys/stat.h> +" +if test "x$ac_cv_member_struct_stat_st_mtimensec" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_STRUCT_STAT_ST_MTIMENSEC 1 +_ACEOF + +stat_nsec_found=yes +fi +ac_fn_c_check_member "$LINENO" "struct stat" "st_mtimespec" "ac_cv_member_struct_stat_st_mtimespec" "#include <sys/stat.h> +" +if test "x$ac_cv_member_struct_stat_st_mtimespec" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_STRUCT_STAT_ST_MTIMESPEC 1 +_ACEOF + +stat_nsec_found=yes +fi + + for ac_func in strchr strlcpy snprintf dlopen utimensat clock_gettime +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing copysign" >&5 +$as_echo_n "checking for library containing copysign... " >&6; } +if ${ac_cv_search_copysign+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char copysign (); +int +main () +{ +return copysign (); + ; + return 0; +} +_ACEOF +for ac_lib in '' m; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_copysign=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_copysign+:} false; then : + break +fi +done +if ${ac_cv_search_copysign+:} false; then : + +else + ac_cv_search_copysign=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_copysign" >&5 +$as_echo "$ac_cv_search_copysign" >&6; } +ac_res=$ac_cv_search_copysign +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +$as_echo "#define HAVE_COPYSIGN 1" >>confdefs.h + +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing copysignl" >&5 +$as_echo_n "checking for library containing copysignl... " >&6; } +if ${ac_cv_search_copysignl+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char copysignl (); +int +main () +{ +return copysignl (); + ; + return 0; +} +_ACEOF +for ac_lib in '' m; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_copysignl=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_copysignl+:} false; then : + break +fi +done +if ${ac_cv_search_copysignl+:} false; then : + +else + ac_cv_search_copysignl=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_copysignl" >&5 +$as_echo "$ac_cv_search_copysignl" >&6; } +ac_res=$ac_cv_search_copysignl +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +$as_echo "#define HAVE_COPYSIGNL 1" >>confdefs.h + +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing modfl" >&5 +$as_echo_n "checking for library containing modfl... " >&6; } +if ${ac_cv_search_modfl+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char modfl (); +int +main () +{ +return modfl (); + ; + return 0; +} +_ACEOF +for ac_lib in '' m; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_modfl=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_modfl+:} false; then : + break +fi +done +if ${ac_cv_search_modfl+:} false; then : + +else + ac_cv_search_modfl=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_modfl" >&5 +$as_echo "$ac_cv_search_modfl" >&6; } +ac_res=$ac_cv_search_modfl +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +$as_echo "#define HAVE_MODFL 1" >>confdefs.h + +fi + + + # ---------------------------------------------------------------------- + # Check for the functions needed from libgen and libdl + # ---------------------------------------------------------------------- + + if test X$ac_cv_func_pathfind = Xyes; then + NEED_PATHFIND_TRUE= + NEED_PATHFIND_FALSE='#' +else + NEED_PATHFIND_TRUE='#' + NEED_PATHFIND_FALSE= +fi + + if test X$ac_cv_func_dlopen = Xyes + then DYNAMIC_AG=-export-dynamic + else DYNAMIC_AG="" + fi + + + for ac_header in libio.h ctype.h assert.h sys/resource.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + ac_fn_c_check_decl "$LINENO" "sigsetjmp" "ac_cv_have_decl_sigsetjmp" "#include <setjmp.h> +" +if test "x$ac_cv_have_decl_sigsetjmp" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_SIGSETJMP $ac_have_decl +_ACEOF + + ac_fn_c_check_decl "$LINENO" "sys_siglist" "ac_cv_have_decl_sys_siglist" "#include <signal.h> +/* NetBSD declares sys_siglist in unistd.h. */ +#ifdef HAVE_UNISTD_H +# include <unistd.h> +#endif + +" +if test "x$ac_cv_have_decl_sys_siglist" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_SYS_SIGLIST $ac_have_decl +_ACEOF + + + for ac_func in putenv getdate_r utimes futimes +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5 +$as_echo_n "checking for inline... " >&6; } +if ${ac_cv_c_inline+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_c_inline=no +for ac_kw in inline __inline__ __inline; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifndef __cplusplus +typedef int foo_t; +static $ac_kw foo_t static_foo () {return 0; } +$ac_kw foo_t foo () {return 0; } +#endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_inline=$ac_kw +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + test "$ac_cv_c_inline" != no && break +done + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5 +$as_echo "$ac_cv_c_inline" >&6; } + +case $ac_cv_c_inline in + inline | yes) ;; + *) + case $ac_cv_c_inline in + no) ac_val=;; + *) ac_val=$ac_cv_c_inline;; + esac + cat >>confdefs.h <<_ACEOF +#ifndef __cplusplus +#define inline $ac_val +#endif +_ACEOF + ;; +esac + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for long long int" >&5 +$as_echo_n "checking for long long int... " >&6; } +if ${ac_cv_type_long_long_int+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_type_long_long_int=yes + if test "x${ac_cv_prog_cc_c99-no}" = xno; then + ac_cv_type_long_long_int=$ac_cv_type_unsigned_long_long_int + if test $ac_cv_type_long_long_int = yes; then + if test "$cross_compiling" = yes; then : + : +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <limits.h> + #ifndef LLONG_MAX + # define HALF \ + (1LL << (sizeof (long long int) * CHAR_BIT - 2)) + # define LLONG_MAX (HALF - 1 + HALF) + #endif +int +main () +{ +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; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + +else + ac_cv_type_long_long_int=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + + fi + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_long_long_int" >&5 +$as_echo "$ac_cv_type_long_long_int" >&6; } + if test $ac_cv_type_long_long_int = yes; then + +$as_echo "#define HAVE_LONG_LONG_INT 1" >>confdefs.h + + fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 +$as_echo_n "checking for grep that handles long lines and -e... " >&6; } +if ${ac_cv_path_GREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$GREP"; then + ac_path_GREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_GREP" || continue +# Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_GREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_GREP"; then + as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_GREP=$GREP +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 +$as_echo "$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 +$as_echo_n "checking for egrep... " >&6; } +if ${ac_cv_path_EGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + if test -z "$EGREP"; then + ac_path_EGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_EGREP" || continue +# Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_EGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_EGREP"; then + as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_EGREP=$EGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 +$as_echo "$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 +$as_echo_n "checking for fgrep... " >&6; } +if ${ac_cv_path_FGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 + then ac_cv_path_FGREP="$GREP -F" + else + if test -z "$FGREP"; then + ac_path_FGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in fgrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_FGREP" || continue +# Check for GNU ac_path_FGREP and select it if it is found. + # Check for GNU $ac_path_FGREP +case `"$ac_path_FGREP" --version 2>&1` in +*GNU*) + ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'FGREP' >> "conftest.nl" + "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_FGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_FGREP="$ac_path_FGREP" + ac_path_FGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_FGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_FGREP"; then + as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_FGREP=$FGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 +$as_echo "$ac_cv_path_FGREP" >&6; } + FGREP="$ac_cv_path_FGREP" + + + + + + + + + + +if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. +set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_PKG_CONFIG+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $PKG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +PKG_CONFIG=$ac_cv_path_PKG_CONFIG +if test -n "$PKG_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 +$as_echo "$PKG_CONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_path_PKG_CONFIG"; then + ac_pt_PKG_CONFIG=$PKG_CONFIG + # Extract the first word of "pkg-config", so it can be a program name with args. +set dummy pkg-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $ac_pt_PKG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG +if test -n "$ac_pt_PKG_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 +$as_echo "$ac_pt_PKG_CONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_pt_PKG_CONFIG" = x; then + PKG_CONFIG="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + PKG_CONFIG=$ac_pt_PKG_CONFIG + fi +else + PKG_CONFIG="$ac_cv_path_PKG_CONFIG" +fi + +fi +if test -n "$PKG_CONFIG"; then + _pkg_min_version=0.9.0 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5 +$as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; } + if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + PKG_CONFIG="" + fi +fi + _guile_versions_to_search="2.2 2.0 1.8" + if test -n "$GUILE_EFFECTIVE_VERSION"; then + _guile_tmp="" + for v in $_guile_versions_to_search; do + if test "$v" = "$GUILE_EFFECTIVE_VERSION"; then + _guile_tmp=$v + fi + done + if test -z "$_guile_tmp"; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "searching for guile development files for versions $_guile_versions_to_search, but previously found $GUILE version $GUILE_EFFECTIVE_VERSION +See \`config.log' for more details" "$LINENO" 5; } + fi + _guile_versions_to_search=$GUILE_EFFECTIVE_VERSION + fi + GUILE_EFFECTIVE_VERSION="" + _guile_errors="" + for v in $_guile_versions_to_search; do + if test -z "$GUILE_EFFECTIVE_VERSION"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for guile $v" >&5 +$as_echo "$as_me: checking for guile $v" >&6;} + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"guile-\$v\""; } >&5 + ($PKG_CONFIG --exists --print-errors "guile-$v") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + GUILE_EFFECTIVE_VERSION=$v +fi + fi + done + + if test -z "$GUILE_EFFECTIVE_VERSION"; then + as_fn_error $? " +No Guile development packages were found. + +Please verify that you have Guile installed. If you installed Guile +from a binary distribution, please verify that you have also installed +the development packages. If you installed it yourself, you might need +to adjust your PKG_CONFIG_PATH; see the pkg-config man page for more. +" "$LINENO" 5 + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: found guile $GUILE_EFFECTIVE_VERSION" >&5 +$as_echo "$as_me: found guile $GUILE_EFFECTIVE_VERSION" >&6;} + + + + +# Check whether --with-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then : + withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes +else + with_gnu_ld=no +fi + +# Prepare PATH_SEPARATOR. +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + # Determine PATH_SEPARATOR by trying to find /bin/sh in a PATH which + # contains only /bin. Note that ksh looks also at the FPATH variable, + # so we have to set that as well for the test. + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \ + && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \ + || PATH_SEPARATOR=';' + } +fi + +if test -n "$LD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld" >&5 +$as_echo_n "checking for ld... " >&6; } +elif test "$GCC" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 +$as_echo_n "checking for ld used by $CC... " >&6; } +elif test "$with_gnu_ld" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 +$as_echo_n "checking for GNU ld... " >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 +$as_echo_n "checking for non-GNU ld... " >&6; } +fi +if test -n "$LD"; then + # Let the user override the test with a path. + : +else + if ${acl_cv_path_LD+:} false; then : + $as_echo_n "(cached) " >&6 +else + + acl_cv_path_LD= # Final result of this test + ac_prog=ld # Program to search in $PATH + if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + acl_output=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + acl_output=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $acl_output in + # Accept absolute paths. + [\\/]* | ?:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the pathname of ld + acl_output=`echo "$acl_output" | sed 's%\\\\%/%g'` + while echo "$acl_output" | grep "$re_direlt" > /dev/null 2>&1; do + acl_output=`echo $acl_output | sed "s%$re_direlt%/%"` + done + # Got the pathname. No search in PATH is needed. + acl_cv_path_LD="$acl_output" + ac_prog= + ;; + "") + # If it fails, then pretend we aren't using GCC. + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac + fi + if test -n "$ac_prog"; then + # Search for $ac_prog in $PATH. + acl_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$acl_save_ifs" + 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 variants of GNU ld 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="$acl_save_ifs" + fi + case $host in + *-*-aix*) + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#if defined __powerpc64__ || defined _ARCH_PPC64 + int ok; + #else + error fail + #endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + # The compiler produces 64-bit code. Add option '-b64' so that the + # linker groks 64-bit object files. + case "$acl_cv_path_LD " in + *" -b64 "*) ;; + *) acl_cv_path_LD="$acl_cv_path_LD -b64" ;; + esac + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ;; + sparc64-*-netbsd*) + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#if defined __sparcv9 || defined __arch64__ + int ok; + #else + error fail + #endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + # The compiler produces 32-bit code. Add option '-m elf32_sparc' + # so that the linker groks 32-bit object files. + case "$acl_cv_path_LD " in + *" -m elf32_sparc "*) ;; + *) acl_cv_path_LD="$acl_cv_path_LD -m elf32_sparc" ;; + esac + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ;; + esac + +fi + + LD="$acl_cv_path_LD" +fi +if test -n "$LD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5 +$as_echo "$LD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 +$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } +if ${acl_cv_prog_gnu_ld+:} false; then : + $as_echo_n "(cached) " >&6 +else + # I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 </dev/null` in +*GNU* | *'with BFD'*) + acl_cv_prog_gnu_ld=yes + ;; +*) + acl_cv_prog_gnu_ld=no + ;; +esac +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $acl_cv_prog_gnu_ld" >&5 +$as_echo "$acl_cv_prog_gnu_ld" >&6; } +with_gnu_ld=$acl_cv_prog_gnu_ld + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shared library run path origin" >&5 +$as_echo_n "checking for shared library run path origin... " >&6; } +if ${acl_cv_rpath+:} false; then : + $as_echo_n "(cached) " >&6 +else + + 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 + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $acl_cv_rpath" >&5 +$as_echo "$acl_cv_rpath" >&6; } + 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" + # Check whether --enable-rpath was given. +if test "${enable_rpath+set}" = set; then : + enableval=$enable_rpath; : +else + enable_rpath=yes +fi + + + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#ifdef _MSC_VER +MicrosoftCompiler +#endif + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "MicrosoftCompiler" >/dev/null 2>&1; then : + gl_asmext='asm' + gl_c_asm_opt='-c -Fa' + +else + gl_asmext='s' + gl_c_asm_opt='-S' + +fi +rm -f conftest* + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking host CPU and C ABI" >&5 +$as_echo_n "checking host CPU and C ABI... " >&6; } +if ${gl_cv_host_cpu_c_abi+:} false; then : + $as_echo_n "(cached) " >&6 +else + case "$host_cpu" in + + i[4567]86 ) + gl_cv_host_cpu_c_abi=i386 + ;; + + x86_64 ) + # On x86_64 systems, the C compiler may be generating code in one of + # these ABIs: + # - 64-bit instruction set, 64-bit pointers, 64-bit 'long': x86_64. + # - 64-bit instruction set, 64-bit pointers, 32-bit 'long': x86_64 + # with native Windows (mingw, MSVC). + # - 64-bit instruction set, 32-bit pointers, 32-bit 'long': x86_64-x32. + # - 32-bit instruction set, 32-bit pointers, 32-bit 'long': i386. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#if (defined __x86_64__ || defined __amd64__ \ + || defined _M_X64 || defined _M_AMD64) + int ok; + #else + error fail + #endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#if defined __ILP32__ || defined _ILP32 + int ok; + #else + error fail + #endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + gl_cv_host_cpu_c_abi=x86_64-x32 +else + gl_cv_host_cpu_c_abi=x86_64 +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +else + gl_cv_host_cpu_c_abi=i386 +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ;; + + alphaev[4-8] | alphaev56 | alphapca5[67] | alphaev6[78] ) + gl_cv_host_cpu_c_abi=alpha + ;; + + arm* | aarch64 ) + # Assume arm with EABI. + # On arm64 systems, the C compiler may be generating code in one of + # these ABIs: + # - aarch64 instruction set, 64-bit pointers, 64-bit 'long': arm64. + # - aarch64 instruction set, 32-bit pointers, 32-bit 'long': arm64-ilp32. + # - 32-bit instruction set, 32-bit pointers, 32-bit 'long': arm or armhf. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __aarch64__ + int ok; + #else + error fail + #endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#if defined __ILP32__ || defined _ILP32 + int ok; + #else + error fail + #endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + gl_cv_host_cpu_c_abi=arm64-ilp32 +else + gl_cv_host_cpu_c_abi=arm64 +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +else + # Don't distinguish little-endian and big-endian arm, since they + # don't require different machine code for simple operations and + # since the user can distinguish them through the preprocessor + # defines __ARMEL__ vs. __ARMEB__. + # But distinguish arm which passes floating-point arguments and + # return values in integer registers (r0, r1, ...) - this is + # gcc -mfloat-abi=soft or gcc -mfloat-abi=softfp - from arm which + # passes them in float registers (s0, s1, ...) and double registers + # (d0, d1, ...) - this is gcc -mfloat-abi=hard. GCC 4.6 or newer + # sets the preprocessor defines __ARM_PCS (for the first case) and + # __ARM_PCS_VFP (for the second case), but older GCC does not. + echo 'double ddd; void func (double dd) { ddd = dd; }' > conftest.c + # Look for a reference to the register d0 in the .s file. + { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $gl_c_asm_opt conftest.c' + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; } >/dev/null 2>&1 + if LC_ALL=C grep 'd0,' conftest.$gl_asmext >/dev/null; then + gl_cv_host_cpu_c_abi=armhf + else + gl_cv_host_cpu_c_abi=arm + fi + rm -f conftest* + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ;; + + hppa1.0 | hppa1.1 | hppa2.0* | hppa64 ) + # On hppa, the C compiler may be generating 32-bit code or 64-bit + # code. In the latter case, it defines _LP64 and __LP64__. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __LP64__ + int ok; + #else + error fail + #endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + gl_cv_host_cpu_c_abi=hppa64 +else + gl_cv_host_cpu_c_abi=hppa +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ;; + + ia64* ) + # On ia64 on HP-UX, the C compiler may be generating 64-bit code or + # 32-bit code. In the latter case, it defines _ILP32. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef _ILP32 + int ok; + #else + error fail + #endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + gl_cv_host_cpu_c_abi=ia64-ilp32 +else + gl_cv_host_cpu_c_abi=ia64 +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ;; + + mips* ) + # We should also check for (_MIPS_SZPTR == 64), but gcc keeps this + # at 32. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#if defined _MIPS_SZLONG && (_MIPS_SZLONG == 64) + int ok; + #else + error fail + #endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + gl_cv_host_cpu_c_abi=mips64 +else + # In the n32 ABI, _ABIN32 is defined, _ABIO32 is not defined (but + # may later get defined by <sgidefs.h>), and _MIPS_SIM == _ABIN32. + # In the 32 ABI, _ABIO32 is defined, _ABIN32 is not defined (but + # may later get defined by <sgidefs.h>), and _MIPS_SIM == _ABIO32. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#if (_MIPS_SIM == _ABIN32) + int ok; + #else + error fail + #endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + gl_cv_host_cpu_c_abi=mipsn32 +else + gl_cv_host_cpu_c_abi=mips +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ;; + + powerpc* ) + # Different ABIs are in use on AIX vs. Mac OS X vs. Linux,*BSD. + # No need to distinguish them here; the caller may distinguish + # them based on the OS. + # On powerpc64 systems, the C compiler may still be generating + # 32-bit code. And on powerpc-ibm-aix systems, the C compiler may + # be generating 64-bit code. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#if defined __powerpc64__ || defined _ARCH_PPC64 + int ok; + #else + error fail + #endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + # On powerpc64, there are two ABIs on Linux: The AIX compatible + # one and the ELFv2 one. The latter defines _CALL_ELF=2. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#if defined _CALL_ELF && _CALL_ELF == 2 + int ok; + #else + error fail + #endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + gl_cv_host_cpu_c_abi=powerpc64-elfv2 +else + gl_cv_host_cpu_c_abi=powerpc64 +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +else + gl_cv_host_cpu_c_abi=powerpc +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ;; + + rs6000 ) + gl_cv_host_cpu_c_abi=powerpc + ;; + + riscv32 | riscv64 ) + # There are 2 architectures (with variants): rv32* and rv64*. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#if __riscv_xlen == 64 + int ok; + #else + error fail + #endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + cpu=riscv64 +else + cpu=riscv32 +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + # There are 6 ABIs: ilp32, ilp32f, ilp32d, lp64, lp64f, lp64d. + # Size of 'long' and 'void *': + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#if defined __LP64__ + int ok; + #else + error fail + #endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + main_abi=lp64 +else + main_abi=ilp32 +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + # Float ABIs: + # __riscv_float_abi_double: + # 'float' and 'double' are passed in floating-point registers. + # __riscv_float_abi_single: + # 'float' are passed in floating-point registers. + # __riscv_float_abi_soft: + # No values are passed in floating-point registers. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#if defined __riscv_float_abi_double + int ok; + #else + error fail + #endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + float_abi=d +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#if defined __riscv_float_abi_single + int ok; + #else + error fail + #endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + float_abi=f +else + float_abi='' +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + gl_cv_host_cpu_c_abi="${cpu}-${main_abi}${float_abi}" + ;; + + s390* ) + # On s390x, the C compiler may be generating 64-bit (= s390x) code + # or 31-bit (= s390) code. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#if defined __LP64__ || defined __s390x__ + int ok; + #else + error fail + #endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + gl_cv_host_cpu_c_abi=s390x +else + gl_cv_host_cpu_c_abi=s390 +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ;; + + sparc | sparc64 ) + # UltraSPARCs running Linux have `uname -m` = "sparc64", but the + # C compiler still generates 32-bit code. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#if defined __sparcv9 || defined __arch64__ + int ok; + #else + error fail + #endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + gl_cv_host_cpu_c_abi=sparc64 +else + gl_cv_host_cpu_c_abi=sparc +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ;; + + *) + gl_cv_host_cpu_c_abi="$host_cpu" + ;; + esac + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_host_cpu_c_abi" >&5 +$as_echo "$gl_cv_host_cpu_c_abi" >&6; } + + HOST_CPU=`echo "$gl_cv_host_cpu_c_abi" | sed -e 's/-.*//'` + HOST_CPU_C_ABI="$gl_cv_host_cpu_c_abi" + + + + # This was + # AC_DEFINE_UNQUOTED([__${HOST_CPU}__]) + # AC_DEFINE_UNQUOTED([__${HOST_CPU_C_ABI}__]) + # earlier, but KAI C++ 3.2d doesn't like this. + sed -e 's/-/_/g' >> confdefs.h <<EOF +#ifndef __${HOST_CPU}__ +#define __${HOST_CPU}__ 1 +#endif +#ifndef __${HOST_CPU_C_ABI}__ +#define __${HOST_CPU_C_ABI}__ 1 +#endif +EOF + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for the common suffixes of directories in the library search path" >&5 +$as_echo_n "checking for the common suffixes of directories in the library search path... " >&6; } +if ${acl_cv_libdirstems+:} false; then : + $as_echo_n "(cached) " >&6 +else + acl_libdirstem=lib + acl_libdirstem2= + case "$host_os" in + solaris*) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for 64-bit host" >&5 +$as_echo_n "checking for 64-bit host... " >&6; } +if ${gl_cv_solaris_64bit+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef _LP64 + int ok; + #else + error fail + #endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + gl_cv_solaris_64bit=yes +else + gl_cv_solaris_64bit=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_solaris_64bit" >&5 +$as_echo "$gl_cv_solaris_64bit" >&6; } + 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 + ;; + *) + case "$gl_cv_host_cpu_c_abi" in + i386 | arm | armhf | arm64-ilp32 | hppa | ia64-ilp32 | mips | mipsn32 | powerpc | s390 | sparc) + ;; + *) # x86_64 | arm64 | hppa64 | ia64 | mips64 | powerpc64* | s390x | sparc64 | ... + searchpath=`(if test -f /usr/bin/gcc \ + && LC_ALL=C /usr/bin/gcc -print-search-dirs >/dev/null 2>/dev/null; then \ + LC_ALL=C /usr/bin/gcc -print-search-dirs; \ + else \ + LC_ALL=C $CC -print-search-dirs; \ + fi) 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 + ;; + esac + test -n "$acl_libdirstem2" || acl_libdirstem2="$acl_libdirstem" + acl_cv_libdirstems="$acl_libdirstem,$acl_libdirstem2" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $acl_cv_libdirstems" >&5 +$as_echo "$acl_cv_libdirstems" >&6; } + # Decompose acl_cv_libdirstems into acl_libdirstem and acl_libdirstem2. + acl_libdirstem=`echo "$acl_cv_libdirstems" | sed -e 's/,.*//'` + acl_libdirstem2=`echo "$acl_cv_libdirstems" | sed -e '/,/s/.*,//'` + + + + ac_header_dirent=no +for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h; do + as_ac_Header=`$as_echo "ac_cv_header_dirent_$ac_hdr" | $as_tr_sh` +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_hdr that defines DIR" >&5 +$as_echo_n "checking for $ac_hdr that defines DIR... " >&6; } +if eval \${$as_ac_Header+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <sys/types.h> +#include <$ac_hdr> + +int +main () +{ +if ((DIR *) 0) +return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$as_ac_Header=yes" +else + eval "$as_ac_Header=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$as_ac_Header + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_hdr" | $as_tr_cpp` 1 +_ACEOF + +ac_header_dirent=$ac_hdr; break +fi + +done +# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix. +if test $ac_header_dirent = dirent.h; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5 +$as_echo_n "checking for library containing opendir... " >&6; } +if ${ac_cv_search_opendir+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char opendir (); +int +main () +{ +return opendir (); + ; + return 0; +} +_ACEOF +for ac_lib in '' dir; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_opendir=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_opendir+:} false; then : + break +fi +done +if ${ac_cv_search_opendir+:} false; then : + +else + ac_cv_search_opendir=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5 +$as_echo "$ac_cv_search_opendir" >&6; } +ac_res=$ac_cv_search_opendir +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +fi + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5 +$as_echo_n "checking for library containing opendir... " >&6; } +if ${ac_cv_search_opendir+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char opendir (); +int +main () +{ +return opendir (); + ; + return 0; +} +_ACEOF +for ac_lib in '' x; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_opendir=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_opendir+:} false; then : + break +fi +done +if ${ac_cv_search_opendir+:} false; then : + +else + ac_cv_search_opendir=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5 +$as_echo "$ac_cv_search_opendir" >&6; } +ac_res=$ac_cv_search_opendir +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +fi + +fi + + + # ================= + # AC_CHECK_HEADERS + # ================= + for ac_header in \ + sys/mman.h sys/param.h sys/poll.h sys/procset.h \ + sys/select.h sys/socket.h sys/stropts.h sys/time.h \ + sys/un.h sys/wait.h dlfcn.h errno.h \ + fcntl.h libgen.h libintl.h memory.h \ + netinet/in.h setjmp.h stdbool.h sysexits.h \ + unistd.h utime.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + for ac_header in stdarg.h varargs.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + lo_have_arg_hdr=true;break +else + lo_have_arg_hdr=false +fi + +done + + + for ac_header in string.h strings.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + lo_have_str_hdr=true;break +else + lo_have_str_hdr=false +fi + +done + + + for ac_header in limits.h sys/limits.h values.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + lo_have_lim_hdr=true;break +else + lo_have_lim_hdr=false +fi + +done + + + for ac_header in inttypes.h stdint.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + lo_have_typ_hdr=true;break +else + lo_have_typ_hdr=false +fi + +done + + + + case "$host_os" in + cygwin*) + STDNORETURN_H='stdnoreturn.h' + ;; + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working stdnoreturn.h" >&5 +$as_echo_n "checking for working stdnoreturn.h... " >&6; } +if ${gl_cv_header_working_stdnoreturn_h+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdlib.h> + #include <stdnoreturn.h> + /* Do not check for 'noreturn' after the return type. + C11 allows it, but it's rarely done that way + and circa-2012 bleeding-edge GCC rejects it when given + -Werror=old-style-declaration. */ + noreturn void foo1 (void) { exit (0); } + _Noreturn void foo2 (void) { exit (0); } + int testit (int argc, char **argv) + { + if (argc & 1) + return 0; + (argv[0][0] ? foo1 : foo2) (); + } + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + gl_cv_header_working_stdnoreturn_h=yes +else + gl_cv_header_working_stdnoreturn_h=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_header_working_stdnoreturn_h" >&5 +$as_echo "$gl_cv_header_working_stdnoreturn_h" >&6; } + if test $gl_cv_header_working_stdnoreturn_h = yes; then + STDNORETURN_H='' + else + STDNORETURN_H='stdnoreturn.h' + fi + ;; + esac + + if test -n "$STDNORETURN_H"; then + GL_GENERATE_STDNORETURN_H_TRUE= + GL_GENERATE_STDNORETURN_H_FALSE='#' +else + GL_GENERATE_STDNORETURN_H_TRUE='#' + GL_GENERATE_STDNORETURN_H_FALSE= +fi + + + + # ---------------------------------------------------------------------- + # check for various programs used during the build. + # On OS/X, "wchar.h" needs "runetype.h" to work properly. + # ---------------------------------------------------------------------- + for ac_header in runetype.h wchar.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" " + $ac_includes_default + #if HAVE_RUNETYPE_H + # include <runetype.h> + #endif + +" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + # Check whether --enable-nls was given. +if test "${enable_nls+set}" = set; then : + enableval=$enable_nls; +fi + + if test "x$enable_nls" != "xno" && \ + test "X${ac_cv_header_libintl_h}" = Xyes; then : + + +$as_echo "#define ENABLE_NLS 1" >>confdefs.h + +fi + + # -------------------------------------------- + # Verify certain entries from AC_CHECK_HEADERS + # -------------------------------------------- + ${lo_have_arg_hdr} || \ + as_fn_error $? "you must have stdarg.h or varargs.h on your system" "$LINENO" 5 + + ${lo_have_str_hdr} || \ + as_fn_error $? "you must have string.h or strings.h on your system" "$LINENO" 5 + + ${lo_have_lim_hdr} || \ + as_fn_error $? "you must have one of limits.h, sys/limits.h or values.h" "$LINENO" 5 + + ${lo_have_typ_hdr} || \ + as_fn_error $? "you must have inttypes.h or stdint.h on your system" "$LINENO" 5 + + for f in sys_types sys_param sys_stat string errno stdlib memory setjmp + do eval as_ac_var=\${ac_cv_header_${f}_h} + test "X${as_ac_var}" = Xyes || { + as_fn_error $? "you must have ${f}.h on your system" "$LINENO" 5 + } + done + test "X${ac_cv_header_inttypes_h-no}" = Xyes || \ + echo '#include <stdint.h>' > inttypes.h + + # ---------------------------------------------------------------------- + # Checks for typedefs + # ---------------------------------------------------------------------- + ac_fn_c_check_type "$LINENO" "wchar_t" "ac_cv_type_wchar_t" "$ac_includes_default" +if test "x$ac_cv_type_wchar_t" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_WCHAR_T 1 +_ACEOF + + +fi + + ac_fn_c_check_type "$LINENO" "wint_t" "ac_cv_type_wint_t" " + $ac_includes_default + #if HAVE_RUNETYPE_H + # include <runetype.h> + #endif + #if HAVE_WCHAR_H + # include <wchar.h> + #endif + +" +if test "x$ac_cv_type_wint_t" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_WINT_T 1 +_ACEOF + + +fi + + ac_fn_c_check_type "$LINENO" "int8_t" "ac_cv_type_int8_t" "$ac_includes_default" +if test "x$ac_cv_type_int8_t" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_INT8_T 1 +_ACEOF + + +fi +ac_fn_c_check_type "$LINENO" "uint8_t" "ac_cv_type_uint8_t" "$ac_includes_default" +if test "x$ac_cv_type_uint8_t" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_UINT8_T 1 +_ACEOF + + +fi +ac_fn_c_check_type "$LINENO" "int16_t" "ac_cv_type_int16_t" "$ac_includes_default" +if test "x$ac_cv_type_int16_t" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_INT16_T 1 +_ACEOF + + +fi +ac_fn_c_check_type "$LINENO" "uint16_t" "ac_cv_type_uint16_t" "$ac_includes_default" +if test "x$ac_cv_type_uint16_t" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_UINT16_T 1 +_ACEOF + + +fi +ac_fn_c_check_type "$LINENO" "int32_t" "ac_cv_type_int32_t" "$ac_includes_default" +if test "x$ac_cv_type_int32_t" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_INT32_T 1 +_ACEOF + + +fi +ac_fn_c_check_type "$LINENO" "uint32_t" "ac_cv_type_uint32_t" "$ac_includes_default" +if test "x$ac_cv_type_uint32_t" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_UINT32_T 1 +_ACEOF + + +fi +ac_fn_c_check_type "$LINENO" "intptr_t" "ac_cv_type_intptr_t" "$ac_includes_default" +if test "x$ac_cv_type_intptr_t" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_INTPTR_T 1 +_ACEOF + + +fi +ac_fn_c_check_type "$LINENO" "uintptr_t" "ac_cv_type_uintptr_t" "$ac_includes_default" +if test "x$ac_cv_type_uintptr_t" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_UINTPTR_T 1 +_ACEOF + + +fi +ac_fn_c_check_type "$LINENO" "uint_t" "ac_cv_type_uint_t" "$ac_includes_default" +if test "x$ac_cv_type_uint_t" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_UINT_T 1 +_ACEOF + + +fi +ac_fn_c_check_type "$LINENO" "pid_t" "ac_cv_type_pid_t" "$ac_includes_default" +if test "x$ac_cv_type_pid_t" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_PID_T 1 +_ACEOF + + +fi +ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" +if test "x$ac_cv_type_size_t" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_SIZE_T 1 +_ACEOF + + +fi +ac_fn_c_check_type "$LINENO" "ptrdiff_t" "ac_cv_type_ptrdiff_t" "$ac_includes_default" +if test "x$ac_cv_type_ptrdiff_t" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_PTRDIFF_T 1 +_ACEOF + + +fi + + # The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of char *" >&5 +$as_echo_n "checking size of char *... " >&6; } +if ${ac_cv_sizeof_char_p+:} false; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (char *))" "ac_cv_sizeof_char_p" "$ac_includes_default"; then : + +else + if test "$ac_cv_type_char_p" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (char *) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_char_p=0 + fi +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_char_p" >&5 +$as_echo "$ac_cv_sizeof_char_p" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_CHAR_P $ac_cv_sizeof_char_p +_ACEOF + + + # The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of int" >&5 +$as_echo_n "checking size of int... " >&6; } +if ${ac_cv_sizeof_int+:} false; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (int))" "ac_cv_sizeof_int" "$ac_includes_default"; then : + +else + if test "$ac_cv_type_int" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (int) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_int=0 + fi +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_int" >&5 +$as_echo "$ac_cv_sizeof_int" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_INT $ac_cv_sizeof_int +_ACEOF + + + # The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long" >&5 +$as_echo_n "checking size of long... " >&6; } +if ${ac_cv_sizeof_long+:} false; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long))" "ac_cv_sizeof_long" "$ac_includes_default"; then : + +else + if test "$ac_cv_type_long" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (long) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_long=0 + fi +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long" >&5 +$as_echo "$ac_cv_sizeof_long" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_LONG $ac_cv_sizeof_long +_ACEOF + + + # The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of short" >&5 +$as_echo_n "checking size of short... " >&6; } +if ${ac_cv_sizeof_short+:} false; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (short))" "ac_cv_sizeof_short" "$ac_includes_default"; then : + +else + if test "$ac_cv_type_short" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (short) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_short=0 + fi +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_short" >&5 +$as_echo "$ac_cv_sizeof_short" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_SHORT $ac_cv_sizeof_short +_ACEOF + + + + # ------------ + # AC_CHECK_LIB + # ------------ + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pathfind in -lgen" >&5 +$as_echo_n "checking for pathfind in -lgen... " >&6; } +if ${ac_cv_lib_gen_pathfind+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lgen $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char pathfind (); +int +main () +{ +return pathfind (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_gen_pathfind=yes +else + ac_cv_lib_gen_pathfind=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gen_pathfind" >&5 +$as_echo "$ac_cv_lib_gen_pathfind" >&6; } +if test "x$ac_cv_lib_gen_pathfind" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBGEN 1 +_ACEOF + + LIBS="-lgen $LIBS" + +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gettext in -lintl" >&5 +$as_echo_n "checking for gettext in -lintl... " >&6; } +if ${ac_cv_lib_intl_gettext+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lintl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char gettext (); +int +main () +{ +return gettext (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_intl_gettext=yes +else + ac_cv_lib_intl_gettext=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_intl_gettext" >&5 +$as_echo "$ac_cv_lib_intl_gettext" >&6; } +if test "x$ac_cv_lib_intl_gettext" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBINTL 1 +_ACEOF + + LIBS="-lintl $LIBS" + +fi + + for ac_func in vprintf +do : + ac_fn_c_check_func "$LINENO" "vprintf" "ac_cv_func_vprintf" +if test "x$ac_cv_func_vprintf" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_VPRINTF 1 +_ACEOF + +ac_fn_c_check_func "$LINENO" "_doprnt" "ac_cv_func__doprnt" +if test "x$ac_cv_func__doprnt" = xyes; then : + +$as_echo "#define HAVE_DOPRNT 1" >>confdefs.h + +fi + +fi +done + + + for ac_header in vfork.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "vfork.h" "ac_cv_header_vfork_h" "$ac_includes_default" +if test "x$ac_cv_header_vfork_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_VFORK_H 1 +_ACEOF + +fi + +done + +for ac_func in fork vfork +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + +if test "x$ac_cv_func_fork" = xyes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working fork" >&5 +$as_echo_n "checking for working fork... " >&6; } +if ${ac_cv_func_fork_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + ac_cv_func_fork_works=cross +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ + + /* By Ruediger Kuhlmann. */ + return fork () < 0; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ac_cv_func_fork_works=yes +else + ac_cv_func_fork_works=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_fork_works" >&5 +$as_echo "$ac_cv_func_fork_works" >&6; } + +else + ac_cv_func_fork_works=$ac_cv_func_fork +fi +if test "x$ac_cv_func_fork_works" = xcross; then + case $host in + *-*-amigaos* | *-*-msdosdjgpp*) + # Override, as these systems have only a dummy fork() stub + ac_cv_func_fork_works=no + ;; + *) + ac_cv_func_fork_works=yes + ;; + esac + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: result $ac_cv_func_fork_works guessed because of cross compilation" >&5 +$as_echo "$as_me: WARNING: result $ac_cv_func_fork_works guessed because of cross compilation" >&2;} +fi +ac_cv_func_vfork_works=$ac_cv_func_vfork +if test "x$ac_cv_func_vfork" = xyes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working vfork" >&5 +$as_echo_n "checking for working vfork... " >&6; } +if ${ac_cv_func_vfork_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + ac_cv_func_vfork_works=cross +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Thanks to Paul Eggert for this test. */ +$ac_includes_default +#include <sys/wait.h> +#ifdef HAVE_VFORK_H +# include <vfork.h> +#endif +/* On some sparc systems, changes by the child to local and incoming + argument registers are propagated back to the parent. The compiler + is told about this with #include <vfork.h>, but some compilers + (e.g. gcc -O) don't grok <vfork.h>. Test for this by using a + static variable whose address is put into a register that is + clobbered by the vfork. */ +static void +#ifdef __cplusplus +sparc_address_test (int arg) +# else +sparc_address_test (arg) int arg; +#endif +{ + static pid_t child; + if (!child) { + child = vfork (); + if (child < 0) { + perror ("vfork"); + _exit(2); + } + if (!child) { + arg = getpid(); + write(-1, "", 0); + _exit (arg); + } + } +} + +int +main () +{ + pid_t parent = getpid (); + pid_t child; + + sparc_address_test (0); + + child = vfork (); + + if (child == 0) { + /* Here is another test for sparc vfork register problems. This + test uses lots of local variables, at least as many local + variables as main has allocated so far including compiler + temporaries. 4 locals are enough for gcc 1.40.3 on a Solaris + 4.1.3 sparc, but we use 8 to be safe. A buggy compiler should + reuse the register of parent for one of the local variables, + since it will think that parent can't possibly be used any more + in this routine. Assigning to the local variable will thus + munge parent in the parent process. */ + pid_t + p = getpid(), p1 = getpid(), p2 = getpid(), p3 = getpid(), + p4 = getpid(), p5 = getpid(), p6 = getpid(), p7 = getpid(); + /* Convince the compiler that p..p7 are live; otherwise, it might + use the same hardware register for all 8 local variables. */ + if (p != p1 || p != p2 || p != p3 || p != p4 + || p != p5 || p != p6 || p != p7) + _exit(1); + + /* On some systems (e.g. IRIX 3.3), vfork doesn't separate parent + from child file descriptors. If the child closes a descriptor + before it execs or exits, this munges the parent's descriptor + as well. Test for this by closing stdout in the child. */ + _exit(close(fileno(stdout)) != 0); + } else { + int status; + struct stat st; + + while (wait(&status) != child) + ; + return ( + /* Was there some problem with vforking? */ + child < 0 + + /* Did the child fail? (This shouldn't happen.) */ + || status + + /* Did the vfork/compiler bug occur? */ + || parent != getpid() + + /* Did the file descriptor bug occur? */ + || fstat(fileno(stdout), &st) != 0 + ); + } +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ac_cv_func_vfork_works=yes +else + ac_cv_func_vfork_works=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_vfork_works" >&5 +$as_echo "$ac_cv_func_vfork_works" >&6; } + +fi; +if test "x$ac_cv_func_fork_works" = xcross; then + ac_cv_func_vfork_works=$ac_cv_func_vfork + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: result $ac_cv_func_vfork_works guessed because of cross compilation" >&5 +$as_echo "$as_me: WARNING: result $ac_cv_func_vfork_works guessed because of cross compilation" >&2;} +fi + +if test "x$ac_cv_func_vfork_works" = xyes; then + +$as_echo "#define HAVE_WORKING_VFORK 1" >>confdefs.h + +else + +$as_echo "#define vfork fork" >>confdefs.h + +fi +if test "x$ac_cv_func_fork_works" = xyes; then + +$as_echo "#define HAVE_WORKING_FORK 1" >>confdefs.h + +fi + + for ac_func in mmap canonicalize_file_name snprintf strdup strchr \ + strrchr strsignal fchmod fstat chmod +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 +$as_echo_n "checking for a sed that does not truncate output... " >&6; } +if ${ac_cv_path_SED+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ + for ac_i in 1 2 3 4 5 6 7; do + ac_script="$ac_script$as_nl$ac_script" + done + echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed + { ac_script=; unset ac_script;} + if test -z "$SED"; then + ac_path_SED_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_SED" || continue +# Check for GNU ac_path_SED and select it if it is found. + # Check for GNU $ac_path_SED +case `"$ac_path_SED" --version 2>&1` in +*GNU*) + ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo '' >> "conftest.nl" + "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_SED_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_SED="$ac_path_SED" + ac_path_SED_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_SED_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_SED"; then + as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 + fi +else + ac_cv_path_SED=$SED +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 +$as_echo "$ac_cv_path_SED" >&6; } + SED="$ac_cv_path_SED" + rm -f conftest.sed + + while : + do + test -x "$POSIX_SHELL" && break + POSIX_SHELL=`which bash` + test -x "$POSIX_SHELL" && break + POSIX_SHELL=`which dash` + test -x "$POSIX_SHELL" && break + POSIX_SHELL=/usr/xpg4/bin/sh + test -x "$POSIX_SHELL" && break + POSIX_SHELL=`/bin/sh -c ' + exec 2>/dev/null + if ! true ; then exit 1 ; fi + echo /bin/sh'` + test -x "$POSIX_SHELL" && break + as_fn_error $? "cannot locate a working POSIX shell" "$LINENO" 5 + done + +cat >>confdefs.h <<_ACEOF +#define POSIX_SHELL "${POSIX_SHELL}" +_ACEOF + + + + + + # Check to see if shell scripts are desired. + + # Check whether --enable-shell was given. +if test "${enable_shell+set}" = set; then : + enableval=$enable_shell; ag_cv_enable_shell=${enable_shell} +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether shell scripts are desired" >&5 +$as_echo_n "checking whether shell scripts are desired... " >&6; } +if ${ag_cv_enable_shell+:} false; then : + $as_echo_n "(cached) " >&6 +else + ag_cv_enable_shell=yes +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ag_cv_enable_shell" >&5 +$as_echo "$ag_cv_enable_shell" >&6; } + +fi + # end of AC_ARG_ENABLE + if test "X${ag_cv_enable_shell}" != Xno + then + for ac_header in vfork.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "vfork.h" "ac_cv_header_vfork_h" "$ac_includes_default" +if test "x$ac_cv_header_vfork_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_VFORK_H 1 +_ACEOF + +fi + +done + +for ac_func in fork vfork +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + +if test "x$ac_cv_func_fork" = xyes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working fork" >&5 +$as_echo_n "checking for working fork... " >&6; } +if ${ac_cv_func_fork_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + ac_cv_func_fork_works=cross +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ + + /* By Ruediger Kuhlmann. */ + return fork () < 0; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ac_cv_func_fork_works=yes +else + ac_cv_func_fork_works=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_fork_works" >&5 +$as_echo "$ac_cv_func_fork_works" >&6; } + +else + ac_cv_func_fork_works=$ac_cv_func_fork +fi +if test "x$ac_cv_func_fork_works" = xcross; then + case $host in + *-*-amigaos* | *-*-msdosdjgpp*) + # Override, as these systems have only a dummy fork() stub + ac_cv_func_fork_works=no + ;; + *) + ac_cv_func_fork_works=yes + ;; + esac + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: result $ac_cv_func_fork_works guessed because of cross compilation" >&5 +$as_echo "$as_me: WARNING: result $ac_cv_func_fork_works guessed because of cross compilation" >&2;} +fi +ac_cv_func_vfork_works=$ac_cv_func_vfork +if test "x$ac_cv_func_vfork" = xyes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working vfork" >&5 +$as_echo_n "checking for working vfork... " >&6; } +if ${ac_cv_func_vfork_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + ac_cv_func_vfork_works=cross +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Thanks to Paul Eggert for this test. */ +$ac_includes_default +#include <sys/wait.h> +#ifdef HAVE_VFORK_H +# include <vfork.h> +#endif +/* On some sparc systems, changes by the child to local and incoming + argument registers are propagated back to the parent. The compiler + is told about this with #include <vfork.h>, but some compilers + (e.g. gcc -O) don't grok <vfork.h>. Test for this by using a + static variable whose address is put into a register that is + clobbered by the vfork. */ +static void +#ifdef __cplusplus +sparc_address_test (int arg) +# else +sparc_address_test (arg) int arg; +#endif +{ + static pid_t child; + if (!child) { + child = vfork (); + if (child < 0) { + perror ("vfork"); + _exit(2); + } + if (!child) { + arg = getpid(); + write(-1, "", 0); + _exit (arg); + } + } +} + +int +main () +{ + pid_t parent = getpid (); + pid_t child; + + sparc_address_test (0); + + child = vfork (); + + if (child == 0) { + /* Here is another test for sparc vfork register problems. This + test uses lots of local variables, at least as many local + variables as main has allocated so far including compiler + temporaries. 4 locals are enough for gcc 1.40.3 on a Solaris + 4.1.3 sparc, but we use 8 to be safe. A buggy compiler should + reuse the register of parent for one of the local variables, + since it will think that parent can't possibly be used any more + in this routine. Assigning to the local variable will thus + munge parent in the parent process. */ + pid_t + p = getpid(), p1 = getpid(), p2 = getpid(), p3 = getpid(), + p4 = getpid(), p5 = getpid(), p6 = getpid(), p7 = getpid(); + /* Convince the compiler that p..p7 are live; otherwise, it might + use the same hardware register for all 8 local variables. */ + if (p != p1 || p != p2 || p != p3 || p != p4 + || p != p5 || p != p6 || p != p7) + _exit(1); + + /* On some systems (e.g. IRIX 3.3), vfork doesn't separate parent + from child file descriptors. If the child closes a descriptor + before it execs or exits, this munges the parent's descriptor + as well. Test for this by closing stdout in the child. */ + _exit(close(fileno(stdout)) != 0); + } else { + int status; + struct stat st; + + while (wait(&status) != child) + ; + return ( + /* Was there some problem with vforking? */ + child < 0 + + /* Did the child fail? (This shouldn't happen.) */ + || status + + /* Did the vfork/compiler bug occur? */ + || parent != getpid() + + /* Did the file descriptor bug occur? */ + || fstat(fileno(stdout), &st) != 0 + ); + } +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ac_cv_func_vfork_works=yes +else + ac_cv_func_vfork_works=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_vfork_works" >&5 +$as_echo "$ac_cv_func_vfork_works" >&6; } + +fi; +if test "x$ac_cv_func_fork_works" = xcross; then + ac_cv_func_vfork_works=$ac_cv_func_vfork + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: result $ac_cv_func_vfork_works guessed because of cross compilation" >&5 +$as_echo "$as_me: WARNING: result $ac_cv_func_vfork_works guessed because of cross compilation" >&2;} +fi + +if test "x$ac_cv_func_vfork_works" = xyes; then + +$as_echo "#define HAVE_WORKING_VFORK 1" >>confdefs.h + +else + +$as_echo "#define vfork fork" >>confdefs.h + +fi +if test "x$ac_cv_func_fork_works" = xyes; then + +$as_echo "#define HAVE_WORKING_FORK 1" >>confdefs.h + +fi + + fi + + + + # Check to see if using shell scripts. + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether using shell scripts" >&5 +$as_echo_n "checking whether using shell scripts... " >&6; } + if ${ag_cv_test_do_shell+:} false; then : + $as_echo_n "(cached) " >&6 +else + + ag_cv_test_do_shell=`exec 2> /dev/null +test "x$ac_cv_func_fork_works" != xyes && \\ + test "x$ac_cv_func_vfork_works" != xyes && exit 1 +test "x$ag_cv_enable_shell" = xyes || exit 1 +echo yes` + if test $? -ne 0 || test -z "$ag_cv_test_do_shell" + then ag_cv_test_do_shell=no + fi + +fi + # end of CACHE_VAL of ag_cv_test_do_shell + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${ag_cv_test_do_shell}" >&5 +$as_echo "${ag_cv_test_do_shell}" >&6; } + if test "X${ag_cv_test_do_shell}" != Xno + then + + + +$as_echo "#define SHELL_ENABLED 1" >>confdefs.h + +OPTS_TESTDIR=test +AGEN5_TESTS='$(SHELL_TESTS) $(NOSHELL_TESTS)' + else + OPTS_TESTDIR= +AGEN5_TESTS='$(NOSHELL_TESTS)' + fi + if test "X${ag_cv_test_do_shell}" != Xno; then + DO_SHELL_CMDS_TRUE= + DO_SHELL_CMDS_FALSE='#' +else + DO_SHELL_CMDS_TRUE='#' + DO_SHELL_CMDS_FALSE= +fi + + + + + # Check to see if statically link autogen to libopts. + + # Check whether --enable-static-autogen was given. +if test "${enable_static_autogen+set}" = set; then : + enableval=$enable_static_autogen; ag_cv_enable_static_autogen=${enable_static_autogen} +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether statically link autogen to libopts" >&5 +$as_echo_n "checking whether statically link autogen to libopts... " >&6; } +if ${ag_cv_enable_static_autogen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ag_cv_enable_static_autogen=no +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ag_cv_enable_static_autogen" >&5 +$as_echo "$ag_cv_enable_static_autogen" >&6; } + +fi + # end of AC_ARG_ENABLE + if test "X${ag_cv_enable_static_autogen}" != Xno + then + +$as_echo "#define STATIC_AUTOGEN_ENABLED 1" >>confdefs.h + + AG_STATIC_AUTOGEN="-static" + else + AG_STATIC_AUTOGEN='' + fi + + + + + # Check to see if setjmp() links okay. + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether setjmp() links okay" >&5 +$as_echo_n "checking whether setjmp() links okay... " >&6; } + if ${ag_cv_link_setjmp+:} false; then : + $as_echo_n "(cached) " >&6 +else + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <setjmp.h> +int +main () +{ +jmp_buf bf; +if (setjmp(bf)) + return 0; +return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ag_cv_link_setjmp=yes +else + ag_cv_link_setjmp=no + +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext # end of AC_LINK_IFELSE + +fi + # end of AC_CACHE_VAL for ag_cv_link_setjmp + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${ag_cv_link_setjmp}" >&5 +$as_echo "${ag_cv_link_setjmp}" >&6; } + if test "X${ag_cv_link_setjmp}" != Xno + then + +$as_echo "#define HAVE_WORKING_SETJMP 1" >>confdefs.h + + fi + + + + # Check to see if __attribute__((format_arg(n))) works. + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether __attribute__((format_arg(n))) works" >&5 +$as_echo_n "checking whether __attribute__((format_arg(n))) works... " >&6; } + if ${ag_cv_compile_format_arg+:} false; then : + $as_echo_n "(cached) " >&6 +else + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdio.h> +char const * foo(char const * fmt, int v) __attribute__((format_arg(1))); +int +main () +{ + int i = 0; + printf(foo("argc is %d\n", i), i); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ag_cv_compile_format_arg=yes +else + ag_cv_compile_format_arg=no + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext # end of AC_COMPILE_IFELSE + +fi + # end of AC_CACHE_VAL for ag_cv_compile_format_arg + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${ag_cv_compile_format_arg}" >&5 +$as_echo "${ag_cv_compile_format_arg}" >&6; } + if test "X${ag_cv_compile_format_arg}" != Xno + then + format_arg_expansion="__attribute__((format_arg(_a)))" + else + format_arg_expansion="" + fi + +cat >>confdefs.h <<_ACEOF +#define ATTRIBUTE_FORMAT_ARG(_a) ${format_arg_expansion} +_ACEOF + + + + + # Check to see if sigsetjmp() links okay. + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether sigsetjmp() links okay" >&5 +$as_echo_n "checking whether sigsetjmp() links okay... " >&6; } + if ${ag_cv_link_sigsetjmp+:} false; then : + $as_echo_n "(cached) " >&6 +else + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <setjmp.h> +int +main () +{ +sigjmp_buf bf; +if (sigsetjmp(bf,0)) + return 0; +return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ag_cv_link_sigsetjmp=yes +else + ag_cv_link_sigsetjmp=no + +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext # end of AC_LINK_IFELSE + +fi + # end of AC_CACHE_VAL for ag_cv_link_sigsetjmp + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${ag_cv_link_sigsetjmp}" >&5 +$as_echo "${ag_cv_link_sigsetjmp}" >&6; } + if test "X${ag_cv_link_sigsetjmp}" != Xno + then + +$as_echo "#define HAVE_WORKING_SIGSETJMP 1" >>confdefs.h + + fi + + + + # Check to see if a working libxml2 can be found. + + +# Check whether --with-libxml2 was given. +if test "${with_libxml2+set}" = set; then : + withval=$with_libxml2; ag_cv_with_libxml2_root=${with_libxml2} +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether with-libxml2 was specified" >&5 +$as_echo_n "checking whether with-libxml2 was specified... " >&6; } +if ${ag_cv_with_libxml2_root+:} false; then : + $as_echo_n "(cached) " >&6 +else + ag_cv_with_libxml2_root=no +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ag_cv_with_libxml2_root" >&5 +$as_echo "$ag_cv_with_libxml2_root" >&6; } + +fi + # end of AC_ARG_WITH libxml2 + + if test "${with_libxml2+set}" = set && \ + test "X${withval}" = Xno + then ## disabled by request + ag_cv_with_libxml2_root=no + ag_cv_with_libxml2_cflags=no + ag_cv_with_libxml2_libs=no + else + + +# Check whether --with-libxml2-cflags was given. +if test "${with_libxml2_cflags+set}" = set; then : + withval=$with_libxml2_cflags; ag_cv_with_libxml2_cflags=${with_libxml2_cflags} +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether with-libxml2-cflags was specified" >&5 +$as_echo_n "checking whether with-libxml2-cflags was specified... " >&6; } +if ${ag_cv_with_libxml2_cflags+:} false; then : + $as_echo_n "(cached) " >&6 +else + ag_cv_with_libxml2_cflags=no +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ag_cv_with_libxml2_cflags" >&5 +$as_echo "$ag_cv_with_libxml2_cflags" >&6; } + +fi + # end of AC_ARG_WITH libxml2-cflags + + +# Check whether --with-libxml2-libs was given. +if test "${with_libxml2_libs+set}" = set; then : + withval=$with_libxml2_libs; ag_cv_with_libxml2_libs=${with_libxml2_libs} +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether with-libxml2-libs was specified" >&5 +$as_echo_n "checking whether with-libxml2-libs was specified... " >&6; } +if ${ag_cv_with_libxml2_libs+:} false; then : + $as_echo_n "(cached) " >&6 +else + ag_cv_with_libxml2_libs=no +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ag_cv_with_libxml2_libs" >&5 +$as_echo "$ag_cv_with_libxml2_libs" >&6; } + +fi + # end of AC_ARG_WITH libxml2-libs + + case "X${ag_cv_with_libxml2_cflags}" in + Xyes|Xno|X ) + case "X${ag_cv_with_libxml2_root}" in + Xyes|Xno|X ) ag_cv_with_libxml2_cflags=no ;; + * ) ag_cv_with_libxml2_cflags=-I${ag_cv_with_libxml2_root}/include ;; + esac + esac + case "X${ag_cv_with_libxml2_libs}" in + Xyes|Xno|X ) + case "X${ag_cv_with_libxml2_root}" in + Xyes|Xno|X ) ag_cv_with_libxml2_libs=no ;; + * ) ag_cv_with_libxml2_libs="-L${ag_cv_with_libxml2_root}/lib -lxml2" ;; + esac + esac + ag_save_CPPFLAGS="${CPPFLAGS}" + ag_save_LIBS="${LIBS}" + case "X${ag_cv_with_libxml2_cflags}" in + Xyes|Xno|X ) + f=`xml2-config --cflags 2>/dev/null` || f='' + test -n "${f}" && ag_cv_with_libxml2_cflags="${f}" && \ + { $as_echo "$as_me:${as_lineno-$LINENO}: xml2-config used for CFLAGS: $f" >&5 +$as_echo "$as_me: xml2-config used for CFLAGS: $f" >&6;} ;; + esac + case "X${ag_cv_with_libxml2_libs}" in + Xyes|Xno|X ) + f=`xml2-config --libs 2>/dev/null` || f='' + test -n "${f}" && ag_cv_with_libxml2_libs="${f}" && \ + { $as_echo "$as_me:${as_lineno-$LINENO}: xml2-config used for LIBS: $f" >&5 +$as_echo "$as_me: xml2-config used for LIBS: $f" >&6;} ;; + esac + case "X${ag_cv_with_libxml2_cflags}" in + Xyes|Xno|X ) + ag_cv_with_libxml2_cflags="" ;; + * ) CPPFLAGS="${CPPFLAGS} ${ag_cv_with_libxml2_cflags}" ;; + esac + case "X${ag_cv_with_libxml2_libs}" in + Xyes|Xno|X ) + LIBS="${LIBS} -lxml2" + ag_cv_with_libxml2_libs="-lxml2" ;; + * ) + LIBS="${LIBS} ${ag_cv_with_libxml2_libs}" ;; + esac + LIBXML2_CFLAGS="" + LIBXML2_LIBS="" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether libxml2 can be linked with" >&5 +$as_echo_n "checking whether libxml2 can be linked with... " >&6; } + if ${ag_cv_with_libxml2+:} false; then : + $as_echo_n "(cached) " >&6 +else + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <libxml/parser.h> +#include <libxml/tree.h> + +int main () { +xmlDocPtr p = xmlParseFile( "mumble.xml" ); } +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ag_cv_with_libxml2=yes +else + ag_cv_with_libxml2=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext # end of AC_LINK_IFELSE + +fi + # end of AC_CACHE_VAL for ag_cv_with_libxml2 + fi ## disabled by request + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${ag_cv_with_libxml2}" >&5 +$as_echo "${ag_cv_with_libxml2}" >&6; } + + + if test "X${ag_cv_with_libxml2}" != Xno + then + LIBXML2_CFLAGS="${ag_cv_with_libxml2_cflags}" + LIBXML2_LIBS="${ag_cv_with_libxml2_libs}" + CPPFLAGS="${ag_save_CPPFLAGS}" + LIBS="${ag_save_LIBS}" + + else + CPPFLAGS="${ag_save_CPPFLAGS}" + LIBS="${ag_save_LIBS}" + LIBXML2_CFLAGS='' + LIBXML2_LIBS='' + fi + + if test "X${ag_cv_with_libxml2}" != Xno; then + HAVE_XML_LIB_TRUE= + HAVE_XML_LIB_FALSE='#' +else + HAVE_XML_LIB_TRUE='#' + HAVE_XML_LIB_FALSE= +fi + + + + + # Check to see if sysinfo(2) is Solaris. + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether sysinfo(2) is Solaris" >&5 +$as_echo_n "checking whether sysinfo(2) is Solaris... " >&6; } + if ${ag_cv_run_solaris_sysinfo+:} false; then : + $as_echo_n "(cached) " >&6 +else + + if test "$cross_compiling" = yes; then : + ag_cv_run_solaris_sysinfo=no + +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <sys/systeminfo.h> +int main() { char z[ 256 ]; +long sz = sysinfo(SI_SYSNAME, z, sizeof(z)); +return (sz > 0) ? 0 : 1; } +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ag_cv_run_solaris_sysinfo=yes +else + ag_cv_run_solaris_sysinfo=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + # end of RUN_IFELSE + +fi + # end of AC_CACHE_VAL for ag_cv_run_solaris_sysinfo + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${ag_cv_run_solaris_sysinfo}" >&5 +$as_echo "${ag_cv_run_solaris_sysinfo}" >&6; } + if test "X${ag_cv_run_solaris_sysinfo}" != Xno + then + +$as_echo "#define HAVE_SOLARIS_SYSINFO 1" >>confdefs.h + + fi + + + + # Check to see if specify an autogen timeout. + + # Check whether --enable-timeout was given. +if test "${enable_timeout+set}" = set; then : + enableval=$enable_timeout; ag_cv_enable_timeout=${enable_timeout} +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether specify an autogen timeout" >&5 +$as_echo_n "checking whether specify an autogen timeout... " >&6; } +if ${ag_cv_enable_timeout+:} false; then : + $as_echo_n "(cached) " >&6 +else + ag_cv_enable_timeout=no +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ag_cv_enable_timeout" >&5 +$as_echo "$ag_cv_enable_timeout" >&6; } + +fi + # end of AC_ARG_ENABLE + if test "X${ag_cv_enable_timeout}" != Xno + then + +$as_echo "#define TIMEOUT_ENABLED 1" >>confdefs.h + + AG_TIMEOUT="${ag_cv_enable_timeout}" + else + AG_TIMEOUT='' + fi + + + + + # Check to see if strcspn matches prototype and works. + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether strcspn matches prototype and works" >&5 +$as_echo_n "checking whether strcspn matches prototype and works... " >&6; } + if ${ag_cv_run_strcspn+:} false; then : + $as_echo_n "(cached) " >&6 +else + + if test "$cross_compiling" = yes; then : + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot run test program while cross compiling +See \`config.log' for more details" "$LINENO" 5; } +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <string.h> +int main (int argc, char ** argv) { + char zRej[] = reject; + char zAcc[] = "a-ok-eject"; + return strcspn( zAcc, zRej ) - 5; +} + ag_cv_run_strcspn=yes +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ag_cv_run_strcspn=no +else + ag_cv_run_strcspn=no + +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + # end of RUN_IFELSE + +fi + # end of AC_CACHE_VAL for ag_cv_run_strcspn + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${ag_cv_run_strcspn}" >&5 +$as_echo "${ag_cv_run_strcspn}" >&6; } + if test "X${ag_cv_run_strcspn}" != Xno + then + +$as_echo "#define HAVE_STRCSPN 1" >>confdefs.h + + else + COMPATOBJ="$COMPATOBJ strcspn.lo" + fi + + + + # Check to see if uname(2) is POSIX. + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether uname(2) is POSIX" >&5 +$as_echo_n "checking whether uname(2) is POSIX... " >&6; } + if ${ag_cv_run_uname_syscall+:} false; then : + $as_echo_n "(cached) " >&6 +else + + if test "$cross_compiling" = yes; then : + ag_cv_run_uname_syscall=no + +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <sys/utsname.h> +int main() { struct utsname unm; +return uname( &unm ); } +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ag_cv_run_uname_syscall=yes +else + ag_cv_run_uname_syscall=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + # end of RUN_IFELSE + +fi + # end of AC_CACHE_VAL for ag_cv_run_uname_syscall + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${ag_cv_run_uname_syscall}" >&5 +$as_echo "${ag_cv_run_uname_syscall}" >&6; } + if test "X${ag_cv_run_uname_syscall}" != Xno + then + +$as_echo "#define HAVE_UNAME_SYSCALL 1" >>confdefs.h + + fi + + + + # Check to see if runtime library dirs can be specified. + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether runtime library dirs can be specified" >&5 +$as_echo_n "checking whether runtime library dirs can be specified... " >&6; } + if ${ag_cv_test_ldflags+:} false; then : + $as_echo_n "(cached) " >&6 +else + + ag_cv_test_ldflags=`exec 2> /dev/null +echo 'int main() { return 0; }' > conftest.$ac_ext +libs="${LIBS}" +LIBS="${LIBS} -Wl,-R/tmp" +if (eval $ac_link) > /dev/null 2>&1 +then echo '-Wl,-R${libdir}' ; rm -f conftest* ; exit 0 ; fi +LIBS="${libs} -R/tmp" +if (eval $ac_link) > /dev/null 2>&1 +then echo '-R${libdir}' ; rm -f conftest* ; exit 0 ; fi +rm -f conftest* ; exit 1` + if test $? -ne 0 || test -z "$ag_cv_test_ldflags" + then ag_cv_test_ldflags=no + fi + +fi + # end of CACHE_VAL of ag_cv_test_ldflags + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${ag_cv_test_ldflags}" >&5 +$as_echo "${ag_cv_test_ldflags}" >&6; } + if test "X${ag_cv_test_ldflags}" != Xno + then + AG_LDFLAGS="${ag_cv_test_ldflags}" + else + AG_LDFLAGS='' + fi + + + + + # Check to see if wanting autogen debugging. + + # Check whether --enable-debug was given. +if test "${enable_debug+set}" = set; then : + enableval=$enable_debug; ag_cv_enable_debug=${enable_debug} +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether wanting autogen debugging" >&5 +$as_echo_n "checking whether wanting autogen debugging... " >&6; } +if ${ag_cv_enable_debug+:} false; then : + $as_echo_n "(cached) " >&6 +else + ag_cv_enable_debug=no +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ag_cv_enable_debug" >&5 +$as_echo "$ag_cv_enable_debug" >&6; } + +fi + # end of AC_ARG_ENABLE + if test "X${ag_cv_enable_debug}" != Xno + then + +$as_echo "#define DEBUG_ENABLED 1" >>confdefs.h + + +$as_echo "#define DEBUG_ENABLED 1" >>confdefs.h + + f=`which dmalloc 2>/dev/null` + test -n "$f" && LIBS="${LIBS} -ldmalloc" + fi + + + + # Check to see if name of the packager of this software is supplied. + + +# Check whether --with-packager was given. +if test "${with_packager+set}" = set; then : + withval=$with_packager; ag_cv_with_group_packager=${with_packager} +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether name of the packager of this software is supplied" >&5 +$as_echo_n "checking whether name of the packager of this software is supplied... " >&6; } +if ${ag_cv_with_group_packager+:} false; then : + $as_echo_n "(cached) " >&6 +else + ag_cv_with_group_packager=no +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ag_cv_with_group_packager" >&5 +$as_echo "$ag_cv_with_group_packager" >&6; } + +fi + # end of AC_ARG_WITH + if test "X${ag_cv_with_group_packager}" != Xno + then + +cat >>confdefs.h <<_ACEOF +#define WITH_PACKAGER "${withval}" +_ACEOF + + fi + +# Check whether --with-packager-version was given. +if test "${with_packager_version+set}" = set; then : + withval=$with_packager_version; ag_cv_with_group_packager_version=${with_packager_version} +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether packager-specific version information is supplied" >&5 +$as_echo_n "checking whether packager-specific version information is supplied... " >&6; } +if ${ag_cv_with_group_packager_version+:} false; then : + $as_echo_n "(cached) " >&6 +else + ag_cv_with_group_packager_version=no +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ag_cv_with_group_packager_version" >&5 +$as_echo "$ag_cv_with_group_packager_version" >&6; } + +fi + # end of AC_ARG_WITH + if test "X${ag_cv_with_group_packager_version}" != Xno + then + +cat >>confdefs.h <<_ACEOF +#define WITH_PACKAGER_VERSION "${withval}" +_ACEOF + + fi + +# Check whether --with-packager-bug-reports was given. +if test "${with_packager_bug_reports+set}" = set; then : + withval=$with_packager_bug_reports; ag_cv_with_group_packager_bug_reports=${with_packager_bug_reports} +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether bug reporting URI/e-mail/etc. is supplied" >&5 +$as_echo_n "checking whether bug reporting URI/e-mail/etc. is supplied... " >&6; } +if ${ag_cv_with_group_packager_bug_reports+:} false; then : + $as_echo_n "(cached) " >&6 +else + ag_cv_with_group_packager_bug_reports=no +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ag_cv_with_group_packager_bug_reports" >&5 +$as_echo "$ag_cv_with_group_packager_bug_reports" >&6; } + +fi + # end of AC_ARG_WITH + if test "X${ag_cv_with_group_packager_bug_reports}" != Xno + then + +cat >>confdefs.h <<_ACEOF +#define WITH_PACKAGER_BUG_REPORTS "${withval}" +_ACEOF + + fi + if test "X$with_packager" != "X" || \ + test "X$with_packager_version$with_packager_bug_reports" = "X" + then : + else + + as_fn_error $? "--with-packager-{bug-reports,version} require --with-packager" "$LINENO" 5 + fi + + + + +if test X${INVOKE_AG_MACROS_LAST_done} != Xyes ; then + + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GUILE" >&5 +$as_echo_n "checking for GUILE... " >&6; } + +if test -n "$GUILE_CFLAGS"; then + pkg_cv_GUILE_CFLAGS="$GUILE_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"guile-\$GUILE_EFFECTIVE_VERSION\""; } >&5 + ($PKG_CONFIG --exists --print-errors "guile-$GUILE_EFFECTIVE_VERSION") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_GUILE_CFLAGS=`$PKG_CONFIG --cflags "guile-$GUILE_EFFECTIVE_VERSION" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$GUILE_LIBS"; then + pkg_cv_GUILE_LIBS="$GUILE_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"guile-\$GUILE_EFFECTIVE_VERSION\""; } >&5 + ($PKG_CONFIG --exists --print-errors "guile-$GUILE_EFFECTIVE_VERSION") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_GUILE_LIBS=`$PKG_CONFIG --libs "guile-$GUILE_EFFECTIVE_VERSION" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + GUILE_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "guile-$GUILE_EFFECTIVE_VERSION" 2>&1` + else + GUILE_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "guile-$GUILE_EFFECTIVE_VERSION" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$GUILE_PKG_ERRORS" >&5 + + as_fn_error $? "Package requirements (guile-$GUILE_EFFECTIVE_VERSION) were not met: + +$GUILE_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +Alternatively, you may set the environment variables GUILE_CFLAGS +and GUILE_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details." "$LINENO" 5 +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +Alternatively, you may set the environment variables GUILE_CFLAGS +and GUILE_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details. + +To get pkg-config, see <http://pkg-config.freedesktop.org/>. +See \`config.log' for more details" "$LINENO" 5; } +else + GUILE_CFLAGS=$pkg_cv_GUILE_CFLAGS + GUILE_LIBS=$pkg_cv_GUILE_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +fi + + + GUILE_LDFLAGS=$GUILE_LIBS + + + + + GUILE_LIBS= + if test "$enable_rpath" != no; then + if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then + rpathdirs= + next= + for opt in $GUILE_LDFLAGS; do + if test -n "$next"; then + dir="$next" + 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,,'` + 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 """"; then + for dir in $rpathdirs; do + GUILE_LIBS="${GUILE_LIBS}${GUILE_LIBS:+ }-R$dir" + done + else + if test -n "$acl_hardcode_libdir_separator"; then + 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" + GUILE_LIBS="$flag" + else + for dir in $rpathdirs; do + acl_save_libdir="$libdir" + libdir="$dir" + eval flag=\"$acl_hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + GUILE_LIBS="${GUILE_LIBS}${GUILE_LIBS:+ }$flag" + done + fi + fi + fi + fi + fi + + + GUILE_LIBS="$GUILE_LDFLAGS $GUILE_LIBS" + + + + GUILE_LTLIBS= + if test "$enable_rpath" != no; then + if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then + rpathdirs= + next= + for opt in $GUILE_LDFLAGS; do + if test -n "$next"; then + dir="$next" + 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,,'` + 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 ""yes""; then + for dir in $rpathdirs; do + GUILE_LTLIBS="${GUILE_LTLIBS}${GUILE_LTLIBS:+ }-R$dir" + done + else + if test -n "$acl_hardcode_libdir_separator"; then + 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" + GUILE_LTLIBS="$flag" + else + for dir in $rpathdirs; do + acl_save_libdir="$libdir" + libdir="$dir" + eval flag=\"$acl_hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + GUILE_LTLIBS="${GUILE_LTLIBS}${GUILE_LTLIBS:+ }$flag" + done + fi + fi + fi + fi + fi + + + GUILE_LTLIBS="$GUILE_LDFLAGS $GUILE_LTLIBS" + + + + + + + + test -x "${PKG_CONFIG}" || { + test -z "${PKG_CONFIG}" && PKG_CONFIG=pkg-config + f=`command -v ${PKG_CONFIG}` + test -x "${f}" && PKG_CONFIG="$f" + } + # Grab the first "-I" option that works + # + ag_gv=`gdir=\`${PKG_CONFIG} --cflags-only-I \ + guile-${GUILE_EFFECTIVE_VERSION} | \ + sed 's/ *-I/ /g'\` + test ${#gdir} -gt 1 || gdir=/usr/include + for d in $gdir + do test -f "$d/libguile/version.h" && gdir=$d && break + done + gdir=\`awk '/SCM_MICRO_VERSION/{ print $3 }' \ + "${gdir}/libguile/version.h"\` + test -n "$gdir" || exit 1 + IFS=' .' + set -- ${GUILE_EFFECTIVE_VERSION} + printf '%u%02u%03u' ${1} ${2} ${gdir} + ` + + test -n "$ag_gv" || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 1 "cannot determine Guile version +See \`config.log' for more details" "$LINENO" 5; } + test ${ag_gv} -ge 200000 || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot use pre-2.0 Guile +See \`config.log' for more details" "$LINENO" 5; } + +cat >>confdefs.h <<_ACEOF +#define GUILE_VERSION ${ag_gv} +_ACEOF + + + + # Check to see if a reg expr header is specified. + + +# Check whether --with-regex-header was given. +if test "${with_regex_header+set}" = set; then : + withval=$with_regex_header; libopts_cv_with_regex_header=${with_regex_header} +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a reg expr header is specified" >&5 +$as_echo_n "checking whether a reg expr header is specified... " >&6; } +if ${libopts_cv_with_regex_header+:} false; then : + $as_echo_n "(cached) " >&6 +else + libopts_cv_with_regex_header=no +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libopts_cv_with_regex_header" >&5 +$as_echo "$libopts_cv_with_regex_header" >&6; } + +fi + # end of AC_ARG_WITH + if test "X${libopts_cv_with_regex_header}" != Xno + then + cat >>confdefs.h <<_ACEOF +#define REGEX_HEADER <${libopts_cv_with_regex_header}> +_ACEOF + + else + +$as_echo "#define REGEX_HEADER <regex.h>" >>confdefs.h + + fi + + + + # Check to see if a working libregex can be found. + + +# Check whether --with-libregex was given. +if test "${with_libregex+set}" = set; then : + withval=$with_libregex; libopts_cv_with_libregex_root=${with_libregex} +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether with-libregex was specified" >&5 +$as_echo_n "checking whether with-libregex was specified... " >&6; } +if ${libopts_cv_with_libregex_root+:} false; then : + $as_echo_n "(cached) " >&6 +else + libopts_cv_with_libregex_root=no +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libopts_cv_with_libregex_root" >&5 +$as_echo "$libopts_cv_with_libregex_root" >&6; } + +fi + # end of AC_ARG_WITH libregex + + if test "${with_libregex+set}" = set && \ + test "X${withval}" = Xno + then ## disabled by request + libopts_cv_with_libregex_root=no + libopts_cv_with_libregex_cflags=no + libopts_cv_with_libregex_libs=no + else + + +# Check whether --with-libregex-cflags was given. +if test "${with_libregex_cflags+set}" = set; then : + withval=$with_libregex_cflags; libopts_cv_with_libregex_cflags=${with_libregex_cflags} +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether with-libregex-cflags was specified" >&5 +$as_echo_n "checking whether with-libregex-cflags was specified... " >&6; } +if ${libopts_cv_with_libregex_cflags+:} false; then : + $as_echo_n "(cached) " >&6 +else + libopts_cv_with_libregex_cflags=no +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libopts_cv_with_libregex_cflags" >&5 +$as_echo "$libopts_cv_with_libregex_cflags" >&6; } + +fi + # end of AC_ARG_WITH libregex-cflags + + +# Check whether --with-libregex-libs was given. +if test "${with_libregex_libs+set}" = set; then : + withval=$with_libregex_libs; libopts_cv_with_libregex_libs=${with_libregex_libs} +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether with-libregex-libs was specified" >&5 +$as_echo_n "checking whether with-libregex-libs was specified... " >&6; } +if ${libopts_cv_with_libregex_libs+:} false; then : + $as_echo_n "(cached) " >&6 +else + libopts_cv_with_libregex_libs=no +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libopts_cv_with_libregex_libs" >&5 +$as_echo "$libopts_cv_with_libregex_libs" >&6; } + +fi + # end of AC_ARG_WITH libregex-libs + + case "X${libopts_cv_with_libregex_cflags}" in + Xyes|Xno|X ) + case "X${libopts_cv_with_libregex_root}" in + Xyes|Xno|X ) libopts_cv_with_libregex_cflags=no ;; + * ) libopts_cv_with_libregex_cflags=-I${libopts_cv_with_libregex_root}/include ;; + esac + esac + case "X${libopts_cv_with_libregex_libs}" in + Xyes|Xno|X ) + case "X${libopts_cv_with_libregex_root}" in + Xyes|Xno|X ) libopts_cv_with_libregex_libs=no ;; + * ) libopts_cv_with_libregex_libs="-L${libopts_cv_with_libregex_root}/lib -lregex" ;; + esac + esac + libopts_save_CPPFLAGS="${CPPFLAGS}" + libopts_save_LIBS="${LIBS}" + case "X${libopts_cv_with_libregex_cflags}" in + Xyes|Xno|X ) + libopts_cv_with_libregex_cflags="" ;; + * ) CPPFLAGS="${CPPFLAGS} ${libopts_cv_with_libregex_cflags}" ;; + esac + case "X${libopts_cv_with_libregex_libs}" in + Xyes|Xno|X ) + libopts_cv_with_libregex_libs="" ;; + * ) + LIBS="${LIBS} ${libopts_cv_with_libregex_libs}" ;; + esac + LIBREGEX_CFLAGS="" + LIBREGEX_LIBS="" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether libregex functions properly" >&5 +$as_echo_n "checking whether libregex functions properly... " >&6; } + if ${libopts_cv_with_libregex+:} false; then : + $as_echo_n "(cached) " >&6 +else + + if test "$cross_compiling" = yes; then : + libopts_cv_with_libregex=no +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include REGEX_HEADER +static regex_t re; +void comp_re(char const * pzPat) { + int res = regcomp( &re, pzPat, REG_EXTENDED|REG_ICASE|REG_NEWLINE ); + if (res == 0) return; + exit( res ); } +int main() { + regmatch_t m[2]; + comp_re( "^.*\$" ); + comp_re( "()|no.*" ); + comp_re( "." ); + if (regexec( &re, "X", 2, m, 0 ) != 0) return 1; + if ((m[0].rm_so != 0) || (m[0].rm_eo != 1)) { + fputs( "error: regex -->.<-- did not match\n", stderr ); + return 1; + } + return 0; } +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + libopts_cv_with_libregex=yes +else + libopts_cv_with_libregex=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + # end of AC_RUN_IFELSE + +fi + # end of AC_CACHE_VAL for libopts_cv_with_libregex + fi ## disabled by request + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${libopts_cv_with_libregex}" >&5 +$as_echo "${libopts_cv_with_libregex}" >&6; } + if test "X${libopts_cv_with_libregex}" != Xno + then + +$as_echo "#define WITH_LIBREGEX 1" >>confdefs.h + + else + CPPFLAGS="${libopts_save_CPPFLAGS}" + LIBS="${libopts_save_LIBS}" + libopts_cv_with_libregex_root=no +libopts_cv_with_libregex_cflags=no +libopts_cv_with_libregex_libs=no +libopts_cv_with_libregex=no + fi + + + + # Check to see if pathfind(3) works. + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pathfind(3) works" >&5 +$as_echo_n "checking whether pathfind(3) works... " >&6; } + if ${libopts_cv_run_pathfind+:} false; then : + $as_echo_n "(cached) " >&6 +else + + if test "$cross_compiling" = yes; then : + libopts_cv_run_pathfind=no + +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <string.h> +#include <stdlib.h> +int main (int argc, char ** argv) { + char * pz = pathfind( getenv( "PATH" ), "sh", "x" ); + return (pz == 0) ? 1 : 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + libopts_cv_run_pathfind=yes +else + libopts_cv_run_pathfind=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + # end of RUN_IFELSE + +fi + # end of AC_CACHE_VAL for libopts_cv_run_pathfind + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${libopts_cv_run_pathfind}" >&5 +$as_echo "${libopts_cv_run_pathfind}" >&6; } + if test "X${libopts_cv_run_pathfind}" != Xno + then + +$as_echo "#define HAVE_PATHFIND 1" >>confdefs.h + + fi + + + + # Check to see if /dev/zero is readable device. + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether /dev/zero is readable device" >&5 +$as_echo_n "checking whether /dev/zero is readable device... " >&6; } + if ${libopts_cv_test_dev_zero+:} false; then : + $as_echo_n "(cached) " >&6 +else + + libopts_cv_test_dev_zero=`exec 2> /dev/null +dzero=\`ls -lL /dev/zero | egrep ^c......r\` +test -z "${dzero}" && exit 1 +echo ${dzero}` + if test $? -ne 0 || test -z "$libopts_cv_test_dev_zero" + then libopts_cv_test_dev_zero=no + fi + +fi + # end of CACHE_VAL of libopts_cv_test_dev_zero + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${libopts_cv_test_dev_zero}" >&5 +$as_echo "${libopts_cv_test_dev_zero}" >&6; } + if test "X${libopts_cv_test_dev_zero}" != Xno + then + +$as_echo "#define HAVE_DEV_ZERO 1" >>confdefs.h + + fi + + + + # Check to see if we have a functional realpath(3C). + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we have a functional realpath(3C)" >&5 +$as_echo_n "checking whether we have a functional realpath(3C)... " >&6; } + if ${libopts_cv_run_realpath+:} false; then : + $as_echo_n "(cached) " >&6 +else + + if test "$cross_compiling" = yes; then : + libopts_cv_run_realpath=no + +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <limits.h> +#include <stdlib.h> +int main (int argc, char ** argv) { +#ifndef PATH_MAX +choke me!! +#else + char zPath[PATH_MAX+1]; +#endif + char *pz = realpath(argv[0], zPath); + return (pz == zPath) ? 0 : 1; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + libopts_cv_run_realpath=yes +else + libopts_cv_run_realpath=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + # end of RUN_IFELSE + +fi + # end of AC_CACHE_VAL for libopts_cv_run_realpath + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${libopts_cv_run_realpath}" >&5 +$as_echo "${libopts_cv_run_realpath}" >&6; } + if test "X${libopts_cv_run_realpath}" != Xno + then + +$as_echo "#define HAVE_REALPATH 1" >>confdefs.h + + fi + + + + # Check to see if strftime() works. + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether strftime() works" >&5 +$as_echo_n "checking whether strftime() works... " >&6; } + if ${libopts_cv_run_strftime+:} false; then : + $as_echo_n "(cached) " >&6 +else + + if test "$cross_compiling" = yes; then : + libopts_cv_run_strftime=no + +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <time.h> +#include <string.h> +char t_buf[ 64 ]; +int main() { + static char const z[] = "Thursday Aug 28 240"; + struct tm tm; + tm.tm_sec = 36; /* seconds after the minute [0, 61] */ + tm.tm_min = 44; /* minutes after the hour [0, 59] */ + tm.tm_hour = 12; /* hour since midnight [0, 23] */ + tm.tm_mday = 28; /* day of the month [1, 31] */ + tm.tm_mon = 7; /* months since January [0, 11] */ + tm.tm_year = 86; /* years since 1900 */ + tm.tm_wday = 4; /* days since Sunday [0, 6] */ + tm.tm_yday = 239; /* days since January 1 [0, 365] */ + tm.tm_isdst = 1; /* flag for daylight savings time */ + strftime( t_buf, sizeof( t_buf ), "%A %b %d %j", &tm ); + return (strcmp( t_buf, z ) != 0); } +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + libopts_cv_run_strftime=yes +else + libopts_cv_run_strftime=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + # end of RUN_IFELSE + +fi + # end of AC_CACHE_VAL for libopts_cv_run_strftime + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${libopts_cv_run_strftime}" >&5 +$as_echo "${libopts_cv_run_strftime}" >&6; } + if test "X${libopts_cv_run_strftime}" != Xno + then + +$as_echo "#define HAVE_STRFTIME 1" >>confdefs.h + + fi + + + + # Check to see if fopen accepts "b" mode. + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether fopen accepts \"b\" mode" >&5 +$as_echo_n "checking whether fopen accepts \"b\" mode... " >&6; } + if ${libopts_cv_run_fopen_binary+:} false; then : + $as_echo_n "(cached) " >&6 +else + + if test "$cross_compiling" = yes; then : + libopts_cv_run_fopen_binary=no + +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdio.h> +int main (int argc, char ** argv) { +FILE * fp = fopen("conftest.$ac_ext", "rb"); +return (fp == NULL) ? 1 : fclose(fp); } +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + libopts_cv_run_fopen_binary=yes +else + libopts_cv_run_fopen_binary=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + # end of RUN_IFELSE + +fi + # end of AC_CACHE_VAL for libopts_cv_run_fopen_binary + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${libopts_cv_run_fopen_binary}" >&5 +$as_echo "${libopts_cv_run_fopen_binary}" >&6; } + if test "X${libopts_cv_run_fopen_binary}" != Xno + then + +$as_echo "#define FOPEN_BINARY_FLAG \"b\"" >>confdefs.h + + else + +$as_echo "#define FOPEN_BINARY_FLAG \"\"" >>confdefs.h + + fi + + + + # Check to see if fopen accepts "t" mode. + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether fopen accepts \"t\" mode" >&5 +$as_echo_n "checking whether fopen accepts \"t\" mode... " >&6; } + if ${libopts_cv_run_fopen_text+:} false; then : + $as_echo_n "(cached) " >&6 +else + + if test "$cross_compiling" = yes; then : + libopts_cv_run_fopen_text=no + +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdio.h> +int main (int argc, char ** argv) { +FILE * fp = fopen("conftest.$ac_ext", "rt"); +return (fp == NULL) ? 1 : fclose(fp); } +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + libopts_cv_run_fopen_text=yes +else + libopts_cv_run_fopen_text=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + # end of RUN_IFELSE + +fi + # end of AC_CACHE_VAL for libopts_cv_run_fopen_text + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${libopts_cv_run_fopen_text}" >&5 +$as_echo "${libopts_cv_run_fopen_text}" >&6; } + if test "X${libopts_cv_run_fopen_text}" != Xno + then + +$as_echo "#define FOPEN_TEXT_FLAG \"t\"" >>confdefs.h + + else + +$as_echo "#define FOPEN_TEXT_FLAG \"\"" >>confdefs.h + + fi + + + + # Check to see if not wanting optional option args. + + # Check whether --enable-optional-args was given. +if test "${enable_optional_args+set}" = set; then : + enableval=$enable_optional_args; libopts_cv_enable_optional_args=${enable_optional_args} +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether not wanting optional option args" >&5 +$as_echo_n "checking whether not wanting optional option args... " >&6; } +if ${libopts_cv_enable_optional_args+:} false; then : + $as_echo_n "(cached) " >&6 +else + libopts_cv_enable_optional_args=yes +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libopts_cv_enable_optional_args" >&5 +$as_echo "$libopts_cv_enable_optional_args" >&6; } + +fi + # end of AC_ARG_ENABLE + if test "X${libopts_cv_enable_optional_args}" = Xno + then + +$as_echo "#define NO_OPTIONAL_OPT_ARGS 1" >>confdefs.h + + fi + + + + + + test "X${ac_cv_header_sys_wait_h}" = Xyes || \ + as_fn_error $? "you must have sys/wait.h on your system" "$LINENO" 5 + + for ac_func in fopencookie funopen +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + break +fi +done + + case "${ac_cv_func_fopencookie}${ac_cv_func_funopen}" in + *yes* ) + +$as_echo "#define ENABLE_FMEMOPEN 1" >>confdefs.h + + ;; + esac + + # Note that BSD does not typedef these in its headers, but instead + # calls for them to be identical in signature to read(2), write(2), + # lseek(2), and close(2). Newlib however does include typedefs + # in its stdio.h for these, and they do not match the signatures + # of the BSD implementation. So this test relies on the fact + # that any typedef will succeed for BSD, while only one that + # matches the existing definitions in stdio.h will succeed for + # a newlib system. + + if test "X${ac_cv_func_funopen}" = Xyes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cookie_function_t type" >&5 +$as_echo_n "checking for cookie_function_t type... " >&6; } +if ${ag_cv_cookie_function_t+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdio.h> + typedef int cookie_read_function_t (void *, char *, int); + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ag_cv_cookie_function_t="bsd" +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdio.h> + typedef ssize_t cookie_read_function_t (void *, char *, size_t); + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ag_cv_cookie_function_t="newlib" +else + as_fn_error $? "Unknown flavor of cookie_XXX_t types" "$LINENO" 5 +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ag_cv_cookie_function_t" >&5 +$as_echo "$ag_cv_cookie_function_t" >&6; } + fi + if test "X${ag_cv_cookie_function_t}" = Xbsd; then + +$as_echo "#define NEED_COOKIE_FUNCTION_TYPEDEFS 1" >>confdefs.h + + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for static inline" >&5 +$as_echo_n "checking for static inline... " >&6; } +if ${snv_cv_static_inline+:} false; then : + $as_echo_n "(cached) " >&6 +else + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +static inline foo(bar) int bar; { return bar; } +int +main () +{ +return foo(0); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + snv_cv_static_inline='static inline' +else + snv_cv_static_inline='static' +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $snv_cv_static_inline" >&5 +$as_echo "$snv_cv_static_inline" >&6; } + +cat >>confdefs.h <<_ACEOF +#define SNV_INLINE ${snv_cv_static_inline} +_ACEOF + + if test "X${libopts_cv_with_libregex}" = Xno + then + echo "A POSIX compliant regcomp/regexec routine is required. + These are required for AutoGen to work correctly. If you have + such a library present on your system, you must specify it by + setting the LIBS environment variable, e.g., \"LIBS='-lregex'\". + If you do not have such a library on your system, then you should + download and install, for example, the one from: + ftp://ftp.gnu.org/gnu/rx/" >&2 + as_fn_error $? "Cannot find working POSIX regex library" "$LINENO" 5 + fi + INVOKE_AG_MACROS_LAST_done=yes +fi + + +if ! test x$ag_cv_sys_siglist = xyes +then + if ! test x$ac_cv_func_strsignal = xyes + then + echo "WARNING: strsignal will use POSIX names and Linux signal numbers" + fi +fi >&2 +if test "X${ag_cv_link_sigsetjmp}" = Xno +then + as_fn_error $? "AutoGen requires sigsetjmp(3)" "$LINENO" 5 +fi + + + + case "$host_os" in + cygwin*) + STDNORETURN_H='stdnoreturn.h' + ;; + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working stdnoreturn.h" >&5 +$as_echo_n "checking for working stdnoreturn.h... " >&6; } +if ${gl_cv_header_working_stdnoreturn_h+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdlib.h> + #include <stdnoreturn.h> + /* Do not check for 'noreturn' after the return type. + C11 allows it, but it's rarely done that way + and circa-2012 bleeding-edge GCC rejects it when given + -Werror=old-style-declaration. */ + noreturn void foo1 (void) { exit (0); } + _Noreturn void foo2 (void) { exit (0); } + int testit (int argc, char **argv) + { + if (argc & 1) + return 0; + (argv[0][0] ? foo1 : foo2) (); + } + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + gl_cv_header_working_stdnoreturn_h=yes +else + gl_cv_header_working_stdnoreturn_h=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_header_working_stdnoreturn_h" >&5 +$as_echo "$gl_cv_header_working_stdnoreturn_h" >&6; } + if test $gl_cv_header_working_stdnoreturn_h = yes; then + STDNORETURN_H='' + else + STDNORETURN_H='stdnoreturn.h' + fi + ;; + esac + + if test -n "$STDNORETURN_H"; then + GL_GENERATE_STDNORETURN_H_TRUE= + GL_GENERATE_STDNORETURN_H_FALSE='#' +else + GL_GENERATE_STDNORETURN_H_TRUE='#' + GL_GENERATE_STDNORETURN_H_FALSE= +fi + + +# ---------------------------------------------------------------------- +# Do SNPRINTFV macros +# ---------------------------------------------------------------------- + + case $enable_snprintfv_convenience in + no) as_fn_error $? "this package needs a convenience snprintfv" "$LINENO" 5 ;; + "") enable_snprintfv_convenience=yes + ac_configure_args="$ac_configure_args --enable-snprintfv-convenience" ;; + esac + LIBSNPRINTFV='${top_builddir}/''snprintfv'/snprintfv/libsnprintfvc.la + INCSNPRINTFV='-I${top_builddir}/''snprintfv'' -I${top_srcdir}/''snprintfv' + + + + # ---------------------------------------------------------------------- + # Set up and process configure options + # ---------------------------------------------------------------------- + # Check whether --enable-snprintfv-install was given. +if test "${enable_snprintfv_install+set}" = set; then : + enableval=$enable_snprintfv_install; +fi + + if test x"${enable_snprintfv_install-no}" != xno; then + INSTALL_SNPRINTFV_TRUE= + INSTALL_SNPRINTFV_FALSE='#' +else + INSTALL_SNPRINTFV_TRUE='#' + INSTALL_SNPRINTFV_FALSE= +fi + + if test x"${enable_snprintfv_convenience-no}" != xno; then + CONVENIENCE_SNPRINTFV_TRUE= + CONVENIENCE_SNPRINTFV_FALSE='#' +else + CONVENIENCE_SNPRINTFV_TRUE='#' + CONVENIENCE_SNPRINTFV_FALSE= +fi + + if test x"${enable_subdir-no}" != xno; then + SUBDIR_SNPRINTFV_TRUE= + SUBDIR_SNPRINTFV_FALSE='#' +else + SUBDIR_SNPRINTFV_TRUE='#' + SUBDIR_SNPRINTFV_FALSE= +fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if malloc debugging is wanted" >&5 +$as_echo_n "checking if malloc debugging is wanted... " >&6; } + +# Check whether --with-dmalloc was given. +if test "${with_dmalloc+set}" = set; then : + withval=$with_dmalloc; if test "$withval" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define WITH_DMALLOC 1" >>confdefs.h + + LIBS="$LIBS -ldmalloc" + LDFLAGS="$LDFLAGS -g" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AWK+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AWK="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 +$as_echo "$AWK" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AWK" && break +done + + + # ---------------------------------------------------------------------- + # check for various programs used during the build. + # On OS/X, "wchar.h" needs "runetype.h" to work properly. + # ---------------------------------------------------------------------- + for ac_header in runetype.h wchar.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" " + $ac_includes_default + #if HAVE_RUNETYPE_H + # include <runetype.h> + #endif + +" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + case x$am_cv_prog_cc_stdc in + xno) + # Non ansi C => won't work with stdarg.h + ac_fn_c_check_header_mongrel "$LINENO" "varargs.h" "ac_cv_header_varargs_h" "$ac_includes_default" +if test "x$ac_cv_header_varargs_h" = xyes; then : + +fi + + + ;; + *) + case x$ac_cv_header_varargs_h in + xyes) + # Parent package is using varargs.h which is incompatible with + # stdarg.h, so we do the same. + ac_fn_c_check_header_mongrel "$LINENO" "varargs.h" "ac_cv_header_varargs_h" "$ac_includes_default" +if test "x$ac_cv_header_varargs_h" = xyes; then : + +fi + + + ;; + *) + # If stdarg.h is present define HAVE_STDARG_H, otherwise if varargs.h + # is present define HAVE_VARARGS_H. + for ac_header in stdarg.h varargs.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + break +fi + +done + + ;; + esac + ;; + esac + + case x$ac_cv_header_stdarg_h$ac_cv_header_varargs_h in + x*yes*) ;; + *) as_fn_error $? "Could not find either stdarg.h or varargs.h." "$LINENO" 5 ;; + esac + + # ---------------------------------------------------------------------- + # Checks for typedefs + # ---------------------------------------------------------------------- + ac_fn_c_check_type "$LINENO" "wchar_t" "ac_cv_type_wchar_t" "$ac_includes_default" +if test "x$ac_cv_type_wchar_t" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_WCHAR_T 1 +_ACEOF + + +fi + + ac_fn_c_check_type "$LINENO" "wint_t" "ac_cv_type_wint_t" " + $ac_includes_default + #if HAVE_RUNETYPE_H + # include <runetype.h> + #endif + #if HAVE_WCHAR_H + # include <wchar.h> + #endif + +" +if test "x$ac_cv_type_wint_t" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_WINT_T 1 +_ACEOF + + +fi + + ac_fn_c_check_type "$LINENO" "long double" "ac_cv_type_long_double" "$ac_includes_default" +if test "x$ac_cv_type_long_double" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_LONG_DOUBLE 1 +_ACEOF + + +fi + + + # ---------------------------------------------------------------------- + # Checks for library calls + # ---------------------------------------------------------------------- + ac_fn_c_check_func "$LINENO" "strtoul" "ac_cv_func_strtoul" +if test "x$ac_cv_func_strtoul" = xyes; then : + $as_echo "#define HAVE_STRTOUL 1" >>confdefs.h + +else + case " $LIBOBJS " in + *" strtoul.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS strtoul.$ac_objext" + ;; +esac + +fi + +ac_fn_c_check_func "$LINENO" "ldexpl" "ac_cv_func_ldexpl" +if test "x$ac_cv_func_ldexpl" = xyes; then : + $as_echo "#define HAVE_LDEXPL 1" >>confdefs.h + +else + case " $LIBOBJS " in + *" ldexpl.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS ldexpl.$ac_objext" + ;; +esac + +fi + +ac_fn_c_check_func "$LINENO" "frexpl" "ac_cv_func_frexpl" +if test "x$ac_cv_func_frexpl" = xyes; then : + $as_echo "#define HAVE_FREXPL 1" >>confdefs.h + +else + case " $LIBOBJS " in + *" frexpl.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS frexpl.$ac_objext" + ;; +esac + +fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for log in -lm" >&5 +$as_echo_n "checking for log in -lm... " >&6; } +if ${ac_cv_lib_m_log+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lm $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char log (); +int +main () +{ +return log (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_m_log=yes +else + ac_cv_lib_m_log=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_log" >&5 +$as_echo "$ac_cv_lib_m_log" >&6; } +if test "x$ac_cv_lib_m_log" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBM 1 +_ACEOF + + LIBS="-lm $LIBS" + +fi + + for ac_func in copysign copysignl +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + +# ---------------------------------------------------------------------- +# Generate the make files. +# ---------------------------------------------------------------------- +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 +$as_echo_n "checking whether ln -s works... " >&6; } +LN_S=$as_ln_s +if test "$LN_S" = "ln -s"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 +$as_echo "no, using $LN_S" >&6; } +fi + + +test -f ./snprintfv/snprintfv/snprintfv.h \ + && rm -f ./snprintfv/snprintfv.h \ + && ${LN_S} `pwd`/snprintfv/snprintfv/snprintfv.h ./snprintfv/ + +AGnam=autogen${ac_exeext} +GDnam=getdefs${ac_exeext} +CLnam=columns${ac_exeext} +if test "X$cross_compiling" = Xyes +then + AGexe=`which ${AGnam}` + GDexe=`which ${GDnam}` + CLexe=`which ${CLnam}` +else + AGexe=${ag_top_builddir}/agen5/${AGnam} + GDexe=${ag_top_builddir}/getdefs/${GDnam} + CLexe=${ag_top_builddir}/columns/${CLnam} +fi +M4_SRC=`cd $srcdir/config ; echo [a-z]*.m4` +ENABLE_STATIC=${enable_static} +config_end_time=`date +%s 2>/dev/null` +time_delta=`expr ${config_end_time} - ${config_start_time} 2>/dev/null` + +if test -z "${AG_TIMEOUT}" +then + if test -z "${time_delta}" + then time_delta=10 + elif test ${time_delta} -lt 5 + then time_delta=5 ; fi + + AG_TIMEOUT=${time_delta} +fi + + +cat >>confdefs.h <<_ACEOF +#define AG_DEFAULT_TIMEOUT ${AG_TIMEOUT} +_ACEOF + + + + + + + + + + + + + + +if test "$ag_top_srcdir" = "$ag_top_builddir" +then + INCLIST='-I${top_builddir} -I${top_srcdir}/autoopts' +else + INCLIST='-I${top_builddir} -I${top_srcdir}' + INCLIST="${INCLIST} -I\${top_builddir}/autoopts -I\${top_srcdir}/autoopts" +fi + +WARN_CFLAGS= +test "X${GCC}" = Xyes && { + CFLAGS="$CFLAGS -Wno-format-contains-nul -fno-strict-aliasing" + WARN_CFLAGS="$CFLAGS "`echo -Wall -Werror -Wcast-align -Wmissing-prototypes \ + -Wpointer-arith -Wshadow -Wstrict-prototypes -Wwrite-strings \ + -Wstrict-aliasing=3 -Wextra -Wno-cast-qual` +} +ac_config_headers="$ac_config_headers config.h:config-h.in" + + + + +ac_config_files="$ac_config_files autoopts/mk-autoopts-pc" + +ac_config_files="$ac_config_files autoopts/autoopts-config" + + +ac_config_files="$ac_config_files autoopts/tpl/tpl-config.tlib:autoopts/tpl/tpl-config-tlib.in" + +ac_config_files="$ac_config_files doc/auto_gen.tpl:doc/auto_gen-tpl.in" + +ac_config_files="$ac_config_files autoopts/test/defs config/mk-shdefs pkg/pkg-env Makefile agen5/Makefile agen5/test/Makefile autoopts/Makefile autoopts/test/Makefile columns/Makefile compat/Makefile doc/Makefile getdefs/Makefile getdefs/test/Makefile pkg/Makefile snprintfv/Makefile xml2ag/Makefile xml2ag/test/Makefile" + + +ac_config_commands="$ac_config_commands stamp-h" + +CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} +f=`${CONFIG_SHELL} -c 'echo true | ( + exec 2>/dev/null ; read -u0 line ; echo $line ; )'` +test X$f = Xtrue || CONFIG_SHELL=`command -v bash` + + +cat >>confdefs.h <<_ACEOF +#define CONFIG_SHELL $CONFIG_SHELL +_ACEOF + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes: double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \. + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + if test "x$cache_file" != "x/dev/null"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 +$as_echo "$as_me: updating cache $cache_file" >&6;} + if test ! -f "$cache_file" || test -h "$cache_file"; then + cat confcache >"$cache_file" + else + case $cache_file in #( + */* | ?:*) + mv -f confcache "$cache_file"$$ && + mv -f "$cache_file"$$ "$cache_file" ;; #( + *) + mv -f confcache "$cache_file" ;; + esac + fi + fi + else + { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 +$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +U= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`$as_echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" + as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 +$as_echo_n "checking that generated files are newer than configure... " >&6; } + if test -n "$am_sleep_pid"; then + # Hide warnings about reused PIDs. + wait $am_sleep_pid 2>/dev/null + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 +$as_echo "done" >&6; } + if test -n "$EXEEXT"; then + am__EXEEXT_TRUE= + am__EXEEXT_FALSE='#' +else + am__EXEEXT_TRUE='#' + am__EXEEXT_FALSE= +fi + +if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then + as_fn_error $? "conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${NEED_PATHFIND_TRUE}" && test -z "${NEED_PATHFIND_FALSE}"; then + as_fn_error $? "conditional \"NEED_PATHFIND\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${DO_SHELL_CMDS_TRUE}" && test -z "${DO_SHELL_CMDS_FALSE}"; then + as_fn_error $? "conditional \"DO_SHELL_CMDS\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${HAVE_XML_LIB_TRUE}" && test -z "${HAVE_XML_LIB_FALSE}"; then + as_fn_error $? "conditional \"HAVE_XML_LIB\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${GL_GENERATE_STDNORETURN_H_TRUE}" && test -z "${GL_GENERATE_STDNORETURN_H_FALSE}"; then + as_fn_error $? "conditional \"GL_GENERATE_STDNORETURN_H\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${GL_GENERATE_STDNORETURN_H_TRUE}" && test -z "${GL_GENERATE_STDNORETURN_H_FALSE}"; then + as_fn_error $? "conditional \"GL_GENERATE_STDNORETURN_H\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${INSTALL_SNPRINTFV_TRUE}" && test -z "${INSTALL_SNPRINTFV_FALSE}"; then + as_fn_error $? "conditional \"INSTALL_SNPRINTFV\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${CONVENIENCE_SNPRINTFV_TRUE}" && test -z "${CONVENIENCE_SNPRINTFV_FALSE}"; then + as_fn_error $? "conditional \"CONVENIENCE_SNPRINTFV\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${SUBDIR_SNPRINTFV_TRUE}" && test -z "${SUBDIR_SNPRINTFV_FALSE}"; then + as_fn_error $? "conditional \"SUBDIR_SNPRINTFV\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi + +: "${CONFIG_STATUS=./config.status}" +ac_write_fail=0 +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} +as_write_fail=0 +cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false + +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +## PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 +## ----------------------------------- ## +## Main body of $CONFIG_STATUS script. ## +## ----------------------------------- ## +_ASEOF +test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# Save the log message, to keep $0 and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by GNU AutoGen $as_me 5.18.16, which was +generated by GNU Autoconf 2.69. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +case $ac_config_files in *" +"*) set x $ac_config_files; shift; ac_config_files=$*;; +esac + +case $ac_config_headers in *" +"*) set x $ac_config_headers; shift; ac_config_headers=$*;; +esac + + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# Files that config.status was made for. +config_files="$ac_config_files" +config_headers="$ac_config_headers" +config_commands="$ac_config_commands" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +ac_cs_usage="\ +\`$as_me' instantiates files and other configuration actions +from templates according to the current configuration. Unless the files +and actions are specified as TAGs, all are instantiated by default. + +Usage: $0 [OPTION]... [TAG]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + --config print configuration, then exit + -q, --quiet, --silent + do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Configuration commands: +$config_commands + +Report bugs to <autogen-users@lists.sourceforge.net>. +GNU AutoGen home page: <http://www.gnu.org/software/autogen/>. +General help using GNU software: <http://www.gnu.org/gethelp/>." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" +ac_cs_version="\\ +GNU AutoGen config.status 5.18.16 +configured by $0, generated by GNU Autoconf 2.69, + with options \\"\$ac_cs_config\\" + +Copyright (C) 2012 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +MKDIR_P='$MKDIR_P' +AWK='$AWK' +test -n "\$AWK" || AWK=awk +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# The default lists apply if the user does not specify any file. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=?*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + --*=) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg= + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + $as_echo "$ac_cs_version"; exit ;; + --config | --confi | --conf | --con | --co | --c ) + $as_echo "$ac_cs_config"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + '') as_fn_error $? "missing file argument" ;; + esac + as_fn_append CONFIG_FILES " '$ac_optarg'" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append CONFIG_HEADERS " '$ac_optarg'" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + as_fn_error $? "ambiguous option: \`$1' +Try \`$0 --help' for more information.";; + --help | --hel | -h ) + $as_echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) as_fn_error $? "unrecognized option: \`$1' +Try \`$0 --help' for more information." ;; + + *) as_fn_append ac_config_targets " $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +if \$ac_cs_recheck; then + set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + shift + \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 + CONFIG_SHELL='$SHELL' + export CONFIG_SHELL + exec "\$@" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + $as_echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# +# INIT-COMMANDS +# +AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}" + + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +sed_quote_subst='$sed_quote_subst' +double_quote_subst='$double_quote_subst' +delay_variable_subst='$delay_variable_subst' +AS='`$ECHO "$AS" | $SED "$delay_single_quote_subst"`' +DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`' +OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' +macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`' +macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`' +enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`' +enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`' +pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' +enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' +shared_archive_member_spec='`$ECHO "$shared_archive_member_spec" | $SED "$delay_single_quote_subst"`' +SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' +ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' +PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`' +host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' +host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' +host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' +build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`' +build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`' +build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`' +SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`' +Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`' +GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`' +EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`' +FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`' +LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`' +NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`' +LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`' +max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`' +ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`' +exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`' +lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`' +lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`' +lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`' +lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`' +lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`' +reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' +reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' +deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' +file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' +file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`' +want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`' +sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`' +AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' +AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' +archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`' +STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' +RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`' +old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`' +old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`' +old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`' +lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`' +CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`' +CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`' +compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' +GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_import='`$ECHO "$lt_cv_sys_global_symbol_to_import" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' +lt_cv_nm_interface='`$ECHO "$lt_cv_nm_interface" | $SED "$delay_single_quote_subst"`' +nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`' +lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`' +lt_cv_truncate_bin='`$ECHO "$lt_cv_truncate_bin" | $SED "$delay_single_quote_subst"`' +objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' +MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`' +lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`' +need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`' +MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`' +DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`' +NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`' +LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`' +OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`' +OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`' +libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`' +shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`' +extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`' +archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`' +enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`' +export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`' +whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`' +compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`' +old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`' +old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`' +archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`' +archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`' +module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`' +module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`' +with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' +allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' +no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' +hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' +hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' +hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`' +hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`' +hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`' +inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`' +link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`' +always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`' +export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`' +exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`' +include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`' +prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`' +postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`' +file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`' +variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`' +need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`' +need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`' +version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`' +runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`' +shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`' +shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`' +libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`' +library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`' +soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`' +install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`' +postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`' +postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`' +finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`' +finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`' +hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`' +sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`' +configure_time_dlsearch_path='`$ECHO "$configure_time_dlsearch_path" | $SED "$delay_single_quote_subst"`' +configure_time_lt_sys_library_path='`$ECHO "$configure_time_lt_sys_library_path" | $SED "$delay_single_quote_subst"`' +hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`' +enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`' +enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`' +enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' +old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' +striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' + +LTCC='$LTCC' +LTCFLAGS='$LTCFLAGS' +compiler='$compiler_DEFAULT' + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$1 +_LTECHO_EOF' +} + +# Quote evaled strings. +for var in AS \ +DLLTOOL \ +OBJDUMP \ +SHELL \ +ECHO \ +PATH_SEPARATOR \ +SED \ +GREP \ +EGREP \ +FGREP \ +LD \ +NM \ +LN_S \ +lt_SP2NL \ +lt_NL2SP \ +reload_flag \ +deplibs_check_method \ +file_magic_cmd \ +file_magic_glob \ +want_nocaseglob \ +sharedlib_from_linklib_cmd \ +AR \ +AR_FLAGS \ +archiver_list_spec \ +STRIP \ +RANLIB \ +CC \ +CFLAGS \ +compiler \ +lt_cv_sys_global_symbol_pipe \ +lt_cv_sys_global_symbol_to_cdecl \ +lt_cv_sys_global_symbol_to_import \ +lt_cv_sys_global_symbol_to_c_name_address \ +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ +lt_cv_nm_interface \ +nm_file_list_spec \ +lt_cv_truncate_bin \ +lt_prog_compiler_no_builtin_flag \ +lt_prog_compiler_pic \ +lt_prog_compiler_wl \ +lt_prog_compiler_static \ +lt_cv_prog_compiler_c_o \ +need_locks \ +MANIFEST_TOOL \ +DSYMUTIL \ +NMEDIT \ +LIPO \ +OTOOL \ +OTOOL64 \ +shrext_cmds \ +export_dynamic_flag_spec \ +whole_archive_flag_spec \ +compiler_needs_object \ +with_gnu_ld \ +allow_undefined_flag \ +no_undefined_flag \ +hardcode_libdir_flag_spec \ +hardcode_libdir_separator \ +exclude_expsyms \ +include_expsyms \ +file_list_spec \ +variables_saved_for_relink \ +libname_spec \ +library_names_spec \ +soname_spec \ +install_override_mode \ +finish_eval \ +old_striplib \ +striplib; do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[\\\\\\\`\\"\\\$]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +# Double-quote double-evaled strings. +for var in reload_cmds \ +old_postinstall_cmds \ +old_postuninstall_cmds \ +old_archive_cmds \ +extract_expsyms_cmds \ +old_archive_from_new_cmds \ +old_archive_from_expsyms_cmds \ +archive_cmds \ +archive_expsym_cmds \ +module_cmds \ +module_expsym_cmds \ +export_symbols_cmds \ +prelink_cmds \ +postlink_cmds \ +postinstall_cmds \ +postuninstall_cmds \ +finish_cmds \ +sys_lib_search_path_spec \ +configure_time_dlsearch_path \ +configure_time_lt_sys_library_path; do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[\\\\\\\`\\"\\\$]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +ac_aux_dir='$ac_aux_dir' + +# See if we are running on zsh, and set the options that allow our +# commands through without removal of \ escapes INIT. +if test -n "\${ZSH_VERSION+set}"; then + setopt NO_GLOB_SUBST +fi + + + PACKAGE='$PACKAGE' + VERSION='$VERSION' + RM='$RM' + ofile='$ofile' + + + + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; + "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; + "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h:config-h.in" ;; + "autoopts/mk-autoopts-pc") CONFIG_FILES="$CONFIG_FILES autoopts/mk-autoopts-pc" ;; + "autoopts/autoopts-config") CONFIG_FILES="$CONFIG_FILES autoopts/autoopts-config" ;; + "autoopts/tpl/tpl-config.tlib") CONFIG_FILES="$CONFIG_FILES autoopts/tpl/tpl-config.tlib:autoopts/tpl/tpl-config-tlib.in" ;; + "doc/auto_gen.tpl") CONFIG_FILES="$CONFIG_FILES doc/auto_gen.tpl:doc/auto_gen-tpl.in" ;; + "autoopts/test/defs") CONFIG_FILES="$CONFIG_FILES autoopts/test/defs" ;; + "config/mk-shdefs") CONFIG_FILES="$CONFIG_FILES config/mk-shdefs" ;; + "pkg/pkg-env") CONFIG_FILES="$CONFIG_FILES pkg/pkg-env" ;; + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "agen5/Makefile") CONFIG_FILES="$CONFIG_FILES agen5/Makefile" ;; + "agen5/test/Makefile") CONFIG_FILES="$CONFIG_FILES agen5/test/Makefile" ;; + "autoopts/Makefile") CONFIG_FILES="$CONFIG_FILES autoopts/Makefile" ;; + "autoopts/test/Makefile") CONFIG_FILES="$CONFIG_FILES autoopts/test/Makefile" ;; + "columns/Makefile") CONFIG_FILES="$CONFIG_FILES columns/Makefile" ;; + "compat/Makefile") CONFIG_FILES="$CONFIG_FILES compat/Makefile" ;; + "doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;; + "getdefs/Makefile") CONFIG_FILES="$CONFIG_FILES getdefs/Makefile" ;; + "getdefs/test/Makefile") CONFIG_FILES="$CONFIG_FILES getdefs/test/Makefile" ;; + "pkg/Makefile") CONFIG_FILES="$CONFIG_FILES pkg/Makefile" ;; + "snprintfv/Makefile") CONFIG_FILES="$CONFIG_FILES snprintfv/Makefile" ;; + "xml2ag/Makefile") CONFIG_FILES="$CONFIG_FILES xml2ag/Makefile" ;; + "xml2ag/test/Makefile") CONFIG_FILES="$CONFIG_FILES xml2ag/test/Makefile" ;; + "stamp-h") CONFIG_COMMANDS="$CONFIG_COMMANDS stamp-h" ;; + + *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers + test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= ac_tmp= + trap 'exit_status=$? + : "${ac_tmp:=$tmp}" + { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status +' 0 + trap 'as_fn_exit 1' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 +ac_tmp=$tmp + +# Set up the scripts for CONFIG_FILES section. +# No need to generate them if there are no CONFIG_FILES. +# This happens for instance with `./config.status config.h'. +if test -n "$CONFIG_FILES"; then + + +ac_cr=`echo X | tr X '\015'` +# On cygwin, bash can eat \r inside `` if the user requested igncr. +# But we know of no other shell where ac_cr would be empty at this +# point, so we can use a bashism as a fallback. +if test "x$ac_cr" = x; then + eval ac_cr=\$\'\\r\' +fi +ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null` +if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then + ac_cs_awk_cr='\\r' +else + ac_cs_awk_cr=$ac_cr +fi + +echo 'BEGIN {' >"$ac_tmp/subs1.awk" && +_ACEOF + + +{ + echo "cat >conf$$subs.awk <<_ACEOF" && + echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && + echo "_ACEOF" +} >conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 +ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + . ./conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + + ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` + if test $ac_delim_n = $ac_delim_num; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done +rm -f conf$$subs.sh + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && +_ACEOF +sed -n ' +h +s/^/S["/; s/!.*/"]=/ +p +g +s/^[^!]*!// +:repl +t repl +s/'"$ac_delim"'$// +t delim +:nl +h +s/\(.\{148\}\)..*/\1/ +t more1 +s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ +p +n +b repl +:more1 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t nl +:delim +h +s/\(.\{148\}\)..*/\1/ +t more2 +s/["\\]/\\&/g; s/^/"/; s/$/"/ +p +b +:more2 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t delim +' <conf$$subs.awk | sed ' +/^[^""]/{ + N + s/\n// +} +' >>$CONFIG_STATUS || ac_write_fail=1 +rm -f conf$$subs.awk +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACAWK +cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && + for (key in S) S_is_set[key] = 1 + FS = "" + +} +{ + line = $ 0 + nfields = split(line, field, "@") + substed = 0 + len = length(field[1]) + for (i = 2; i < nfields; i++) { + key = field[i] + keylen = length(key) + if (S_is_set[key]) { + value = S[key] + line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) + len += length(value) + length(field[++i]) + substed = 1 + } else + len += 1 + keylen + } + + print line +} + +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then + sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +else + cat +fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ + || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 +_ACEOF + +# VPATH may cause trouble with some makes, so we remove sole $(srcdir), +# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ +h +s/// +s/^/:/ +s/[ ]*$/:/ +s/:\$(srcdir):/:/g +s/:\${srcdir}:/:/g +s/:@srcdir@:/:/g +s/^:*// +s/:*$// +x +s/\(=[ ]*\).*/\1/ +G +s/\n// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +fi # test -n "$CONFIG_FILES" + +# Set up the scripts for CONFIG_HEADERS section. +# No need to generate them if there are no CONFIG_HEADERS. +# This happens for instance with `./config.status Makefile'. +if test -n "$CONFIG_HEADERS"; then +cat >"$ac_tmp/defines.awk" <<\_ACAWK || +BEGIN { +_ACEOF + +# Transform confdefs.h into an awk script `defines.awk', embedded as +# here-document in config.status, that substitutes the proper values into +# config.h.in to produce config.h. + +# Create a delimiter string that does not exist in confdefs.h, to ease +# handling of long lines. +ac_delim='%!_!# ' +for ac_last_try in false false :; do + ac_tt=`sed -n "/$ac_delim/p" confdefs.h` + if test -z "$ac_tt"; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +# For the awk script, D is an array of macro values keyed by name, +# likewise P contains macro parameters if any. Preserve backslash +# newline sequences. + +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +sed -n ' +s/.\{148\}/&'"$ac_delim"'/g +t rset +:rset +s/^[ ]*#[ ]*define[ ][ ]*/ / +t def +d +:def +s/\\$// +t bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3"/p +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p +d +:bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3\\\\\\n"\\/p +t cont +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p +t cont +d +:cont +n +s/.\{148\}/&'"$ac_delim"'/g +t clear +:clear +s/\\$// +t bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/"/p +d +:bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p +b cont +' <confdefs.h | sed ' +s/'"$ac_delim"'/"\\\ +"/g' >>$CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + for (key in D) D_is_set[key] = 1 + FS = "" +} +/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { + line = \$ 0 + split(line, arg, " ") + if (arg[1] == "#") { + defundef = arg[2] + mac1 = arg[3] + } else { + defundef = substr(arg[1], 2) + mac1 = arg[2] + } + split(mac1, mac2, "(") #) + macro = mac2[1] + prefix = substr(line, 1, index(line, defundef) - 1) + if (D_is_set[macro]) { + # Preserve the white space surrounding the "#". + print prefix "define", macro P[macro] D[macro] + next + } else { + # Replace #undef with comments. This is necessary, for example, + # in the case of _POSIX_SOURCE, which is predefined and required + # on some systems where configure will not decide to define it. + if (defundef == "undef") { + print "/*", prefix defundef, macro, "*/" + next + } + } +} +{ print } +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 +fi # test -n "$CONFIG_HEADERS" + + +eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" +shift +for ac_tag +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$ac_tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; + esac + case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + as_fn_append ac_file_inputs " '$ac_f'" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input='Generated from '` + $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +$as_echo "$as_me: creating $ac_file" >&6;} + fi + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`$as_echo "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac + + case $ac_tag in + *:-:* | *:-) cat >"$ac_tmp/stdin" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir="$ac_dir"; as_fn_mkdir_p + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac + ac_MKDIR_P=$MKDIR_P + case $MKDIR_P in + [\\/$]* | ?:[\\/]* ) ;; + */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= +ac_sed_dataroot=' +/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p' +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_sed_extra="$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s|@configure_input@|$ac_sed_conf_input|;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@top_build_prefix@&$ac_top_build_prefix&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +s&@MKDIR_P@&$ac_MKDIR_P&;t t +$ac_datarootdir_hack +" +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ + >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ + "$ac_tmp/out"`; test -z "$ac_out"; } && + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&5 +$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&2;} + + rm -f "$ac_tmp/stdin" + case $ac_file in + -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; + *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; + esac \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + ;; + :H) + # + # CONFIG_HEADER + # + if test x"$ac_file" != x-; then + { + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" + } >"$ac_tmp/config.h" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then + { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 +$as_echo "$as_me: $ac_file is unchanged" >&6;} + else + rm -f "$ac_file" + mv "$ac_tmp/config.h" "$ac_file" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + fi + else + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ + || as_fn_error $? "could not create -" "$LINENO" 5 + fi +# Compute "$ac_file"'s index in $config_headers. +_am_arg="$ac_file" +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || +$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$_am_arg" : 'X\(//\)[^/]' \| \ + X"$_am_arg" : 'X\(//\)$' \| \ + X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$_am_arg" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'`/stamp-h$_am_stamp_count + ;; + + :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 +$as_echo "$as_me: executing $ac_file commands" >&6;} + ;; + esac + + + case $ac_file$ac_mode in + "depfiles":C) test x"$AMDEP_TRUE" != x"" || { + # Older Autoconf quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + # TODO: see whether this extra hack can be removed once we start + # requiring Autoconf 2.70 or later. + case $CONFIG_FILES in #( + *\'*) : + eval set x "$CONFIG_FILES" ;; #( + *) : + set x $CONFIG_FILES ;; #( + *) : + ;; +esac + shift + # Used to flag and report bootstrapping failures. + am_rc=0 + for am_mf + do + # Strip MF so we end up with the name of the file. + am_mf=`$as_echo "$am_mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile which includes + # dependency-tracking related rules and includes. + # Grep'ing the whole file directly is not great: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \ + || continue + am_dirpart=`$as_dirname -- "$am_mf" || +$as_expr X"$am_mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$am_mf" : 'X\(//\)[^/]' \| \ + X"$am_mf" : 'X\(//\)$' \| \ + X"$am_mf" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$am_mf" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + am_filepart=`$as_basename -- "$am_mf" || +$as_expr X/"$am_mf" : '.*/\([^/][^/]*\)/*$' \| \ + X"$am_mf" : 'X\(//\)$' \| \ + X"$am_mf" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$am_mf" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + { echo "$as_me:$LINENO: cd "$am_dirpart" \ + && sed -e '/# am--include-marker/d' "$am_filepart" \ + | $MAKE -f - am--depfiles" >&5 + (cd "$am_dirpart" \ + && sed -e '/# am--include-marker/d' "$am_filepart" \ + | $MAKE -f - am--depfiles) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } || am_rc=$? + done + if test $am_rc -ne 0; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "Something went wrong bootstrapping makefile fragments + for automatic dependency tracking. Try re-running configure with the + '--disable-dependency-tracking' option to at least be able to build + the package (albeit without support for automatic dependency tracking). +See \`config.log' for more details" "$LINENO" 5; } + fi + { am_dirpart=; unset am_dirpart;} + { am_filepart=; unset am_filepart;} + { am_mf=; unset am_mf;} + { am_rc=; unset am_rc;} + rm -f conftest-deps.mk +} + ;; + "libtool":C) + + # See if we are running on zsh, and set the options that allow our + # commands through without removal of \ escapes. + if test -n "${ZSH_VERSION+set}"; then + setopt NO_GLOB_SUBST + fi + + cfgfile=${ofile}T + trap "$RM \"$cfgfile\"; exit 1" 1 2 15 + $RM "$cfgfile" + + cat <<_LT_EOF >> "$cfgfile" +#! $SHELL +# Generated automatically by $as_me ($PACKAGE) $VERSION +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# NOTE: Changes made to this file will be lost: look at ltmain.sh. + +# Provide generalized library-building support services. +# Written by Gordon Matzigkeit, 1996 + +# Copyright (C) 2014 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# GNU Libtool is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of of the License, or +# (at your option) any later version. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program or library that is built +# using GNU Libtool, you may include this file under the same +# distribution terms that you use for the rest of that program. +# +# GNU Libtool is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + + +# The names of the tagged configurations supported by this script. +available_tags='' + +# Configured defaults for sys_lib_dlsearch_path munging. +: \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"} + +# ### BEGIN LIBTOOL CONFIG + +# Assembler program. +AS=$lt_AS + +# DLL creation program. +DLLTOOL=$lt_DLLTOOL + +# Object dumper program. +OBJDUMP=$lt_OBJDUMP + +# Which release of libtool.m4 was used? +macro_version=$macro_version +macro_revision=$macro_revision + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# What type of objects to build. +pic_mode=$pic_mode + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# Shared archive member basename,for filename based shared library versioning on AIX. +shared_archive_member_spec=$shared_archive_member_spec + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# An echo program that protects backslashes. +ECHO=$lt_ECHO + +# The PATH separator for the build system. +PATH_SEPARATOR=$lt_PATH_SEPARATOR + +# The host system. +host_alias=$host_alias +host=$host +host_os=$host_os + +# The build system. +build_alias=$build_alias +build=$build +build_os=$build_os + +# A sed program that does not truncate output. +SED=$lt_SED + +# Sed that helps us avoid accidentally triggering echo(1) options like -n. +Xsed="\$SED -e 1s/^X//" + +# A grep program that handles long lines. +GREP=$lt_GREP + +# An ERE matcher. +EGREP=$lt_EGREP + +# A literal string matcher. +FGREP=$lt_FGREP + +# A BSD- or MS-compatible name lister. +NM=$lt_NM + +# Whether we need soft or hard links. +LN_S=$lt_LN_S + +# What is the maximum length of a command? +max_cmd_len=$max_cmd_len + +# Object file suffix (normally "o"). +objext=$ac_objext + +# Executable file suffix (normally ""). +exeext=$exeext + +# whether the shell understands "unset". +lt_unset=$lt_unset + +# turn spaces into newlines. +SP2NL=$lt_lt_SP2NL + +# turn newlines into spaces. +NL2SP=$lt_lt_NL2SP + +# convert \$build file names to \$host format. +to_host_file_cmd=$lt_cv_to_host_file_cmd + +# convert \$build files to toolchain format. +to_tool_file_cmd=$lt_cv_to_tool_file_cmd + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method = "file_magic". +file_magic_cmd=$lt_file_magic_cmd + +# How to find potential files when deplibs_check_method = "file_magic". +file_magic_glob=$lt_file_magic_glob + +# Find potential files using nocaseglob when deplibs_check_method = "file_magic". +want_nocaseglob=$lt_want_nocaseglob + +# Command to associate shared and link libraries. +sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd + +# The archiver. +AR=$lt_AR + +# Flags to create an archive. +AR_FLAGS=$lt_AR_FLAGS + +# How to feed a file listing to the archiver. +archiver_list_spec=$lt_archiver_list_spec + +# A symbol stripping program. +STRIP=$lt_STRIP + +# Commands used to install an old-style archive. +RANLIB=$lt_RANLIB +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Whether to use a lock for old archive extraction. +lock_old_archive_extraction=$lock_old_archive_extraction + +# A C compiler. +LTCC=$lt_CC + +# LTCC compiler flags. +LTCFLAGS=$lt_CFLAGS + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe + +# Transform the output of nm in a proper C declaration. +global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl + +# Transform the output of nm into a list of symbols to manually relocate. +global_symbol_to_import=$lt_lt_cv_sys_global_symbol_to_import + +# Transform the output of nm in a C name address pair. +global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address + +# Transform the output of nm in a C name address pair when lib prefix is needed. +global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix + +# The name lister interface. +nm_interface=$lt_lt_cv_nm_interface + +# Specify filename containing input files for \$NM. +nm_file_list_spec=$lt_nm_file_list_spec + +# The root where to search for dependent libraries,and where our libraries should be installed. +lt_sysroot=$lt_sysroot + +# Command to truncate a binary pipe. +lt_truncate_bin=$lt_lt_cv_truncate_bin + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# Used to examine libraries when file_magic_cmd begins with "file". +MAGIC_CMD=$MAGIC_CMD + +# Must we lock files when doing compilation? +need_locks=$lt_need_locks + +# Manifest tool. +MANIFEST_TOOL=$lt_MANIFEST_TOOL + +# Tool to manipulate archived DWARF debug symbol files on Mac OS X. +DSYMUTIL=$lt_DSYMUTIL + +# Tool to change global to local symbols on Mac OS X. +NMEDIT=$lt_NMEDIT + +# Tool to manipulate fat objects and archives on Mac OS X. +LIPO=$lt_LIPO + +# ldd/readelf like tool for Mach-O binaries on Mac OS X. +OTOOL=$lt_OTOOL + +# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. +OTOOL64=$lt_OTOOL64 + +# Old archive suffix (normally "a"). +libext=$libext + +# Shared library suffix (normally ".so"). +shrext_cmds=$lt_shrext_cmds + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at link time. +variables_saved_for_relink=$lt_variables_saved_for_relink + +# Do we need the "lib" prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Library versioning type. +version_type=$version_type + +# Shared library runtime path variable. +runpath_var=$runpath_var + +# Shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Permission mode override for installation of shared libraries. +install_override_mode=$lt_install_override_mode + +# Command to use after installation of a shared archive. +postinstall_cmds=$lt_postinstall_cmds + +# Command to use after uninstallation of a shared archive. +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# As "finish_cmds", except a single script fragment to be evaled but +# not shown. +finish_eval=$lt_finish_eval + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Compile-time system search path for libraries. +sys_lib_search_path_spec=$lt_sys_lib_search_path_spec + +# Detected run-time system search path for libraries. +sys_lib_dlsearch_path_spec=$lt_configure_time_dlsearch_path + +# Explicit LT_SYS_LIBRARY_PATH set during ./configure time. +configure_time_lt_sys_library_path=$lt_configure_time_lt_sys_library_path + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + + +# The linker used to build libraries. +LD=$lt_LD + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# Commands used to build an old-style archive. +old_archive_cmds=$lt_old_archive_cmds + +# A language specific compiler. +CC=$lt_compiler + +# Is the compiler the GNU compiler? +with_gcc=$GCC + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc + +# Whether or not to disallow shared libs when runtime libs are static. +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec + +# Whether the compiler copes with passing no objects directly. +compiler_needs_object=$lt_compiler_needs_object + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds + +# Commands used to build a shared archive. +archive_cmds=$lt_archive_cmds +archive_expsym_cmds=$lt_archive_expsym_cmds + +# Commands used to build a loadable module if different from building +# a shared archive. +module_cmds=$lt_module_cmds +module_expsym_cmds=$lt_module_expsym_cmds + +# Whether we are building with GNU ld or not. +with_gnu_ld=$lt_with_gnu_ld + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag + +# Flag that enforces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec + +# Whether we need a single "-rpath" flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator + +# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes +# DIR into the resulting binary. +hardcode_direct=$hardcode_direct + +# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes +# DIR into the resulting binary and the resulting library dependency is +# "absolute",i.e impossible to change by setting \$shlibpath_var if the +# library is relocated. +hardcode_direct_absolute=$hardcode_direct_absolute + +# Set to "yes" if using the -LDIR flag during linking hardcodes DIR +# into the resulting binary. +hardcode_minus_L=$hardcode_minus_L + +# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR +# into the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var + +# Set to "yes" if building a shared library automatically hardcodes DIR +# into the library and all subsequent libraries and executables linked +# against it. +hardcode_automatic=$hardcode_automatic + +# Set to yes if linker adds runtime paths of dependent libraries +# to runtime path list. +inherit_rpath=$inherit_rpath + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs + +# Set to "yes" if exported symbols are required. +always_export_symbols=$always_export_symbols + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms + +# Commands necessary for linking programs (against libraries) with templates. +prelink_cmds=$lt_prelink_cmds + +# Commands necessary for finishing linking programs. +postlink_cmds=$lt_postlink_cmds + +# Specify filename containing input files. +file_list_spec=$lt_file_list_spec + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action + +# ### END LIBTOOL CONFIG + +_LT_EOF + + cat <<'_LT_EOF' >> "$cfgfile" + +# ### BEGIN FUNCTIONS SHARED WITH CONFIGURE + +# func_munge_path_list VARIABLE PATH +# ----------------------------------- +# VARIABLE is name of variable containing _space_ separated list of +# directories to be munged by the contents of PATH, which is string +# having a format: +# "DIR[:DIR]:" +# string "DIR[ DIR]" will be prepended to VARIABLE +# ":DIR[:DIR]" +# string "DIR[ DIR]" will be appended to VARIABLE +# "DIRP[:DIRP]::[DIRA:]DIRA" +# string "DIRP[ DIRP]" will be prepended to VARIABLE and string +# "DIRA[ DIRA]" will be appended to VARIABLE +# "DIR[:DIR]" +# VARIABLE will be replaced by "DIR[ DIR]" +func_munge_path_list () +{ + case x$2 in + x) + ;; + *:) + eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\" + ;; + x:*) + eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\" + ;; + *::*) + eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" + eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\" + ;; + *) + eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\" + ;; + esac +} + + +# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. +func_cc_basename () +{ + for cc_temp in $*""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac + done + func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` +} + + +# ### END FUNCTIONS SHARED WITH CONFIGURE + +_LT_EOF + + case $host_os in + aix3*) + cat <<\_LT_EOF >> "$cfgfile" +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test set != "${COLLECT_NAMES+set}"; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +_LT_EOF + ;; + esac + + +ltmain=$ac_aux_dir/ltmain.sh + + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '$q' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + mv -f "$cfgfile" "$ofile" || + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" + + ;; + "autoopts/mk-autoopts-pc":F) chmod +x autoopts/mk-autoopts-pc ;; + "autoopts/autoopts-config":F) chmod +x autoopts/autoopts-config ;; + "stamp-h":C) test -z "$CONFIG_HEADERS" || echo timestamp > stamp-h ;; + + esac +done # for ac_tag + + +as_fn_exit 0 +_ACEOF +ac_clean_files=$ac_clean_files_save + +test $ac_write_fail = 0 || + as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || as_fn_exit 1 +fi +if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} +fi + + +echo \ +"------------------------------------------------------------------------ +Configuration: + + Source code location: ${srcdir} + Compiler: ${CC} + Compiler flags: ${CFLAGS} + Host System Type: ${host} + Install path: ${prefix} + + See config.h for further configuration information. +------------------------------------------------------------------------" diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..bea0892 --- /dev/null +++ b/configure.ac @@ -0,0 +1,247 @@ +dnl -*- Mode: autoconf -*- +dnl configure.ac --- GNU autoconf source for toplevel directory. +dnl +dnl Author: Bruce Korb <bkorb@gnu.org> +dnl +dnl This file is part of AutoGen. +dnl AutoGen Copyright (C) 1992-2017 by Bruce Korb - all rights reserved +dnl +dnl AutoGen is free software: you can redistribute it and/or modify it +dnl under the terms of the GNU General Public License as published by the +dnl Free Software Foundation, either version 3 of the License, or +dnl (at your option) any later version. +dnl +dnl AutoGen is distributed in the hope that it will be useful, but +dnl WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +dnl See the GNU General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License along +dnl with this program. If not, see <http://www.gnu.org/licenses/>. +dnl +AC_INIT([GNU AutoGen],[5.18.16],[autogen-users@lists.sourceforge.net]) +AC_CONFIG_SRCDIR([agen5/autogen.c]) +AC_CONFIG_AUX_DIR([config]) +AC_CANONICAL_TARGET +[. $srcdir/VERSION +d=`dirname $0` +ag_top_srcdir=`cd $d && pwd` +ag_top_builddir=`pwd`] +AM_INIT_AUTOMAKE([gnu check-news 1.5 dist-xz]) +AC_USE_SYSTEM_EXTENSIONS +AC_CONFIG_MACRO_DIR([config]) +AC_LIBTOOL_WIN32_DLL +m4_define(AC_PROVIDE_AC_LIBTOOL_WIN32_DLL) +AC_PROG_LIBTOOL +ifdef([AC_REVISION],AC_REVISION($Revision: 4.34 $),)dnl +[config_start_time=`date +%s 2>/dev/null`] +# ---------------------------------------------------------------------- +# Substitute VERSION vars here, so that they can be used by the Makefile +# ---------------------------------------------------------------------- +AC_SUBST(AG_VERSION) +AC_SUBST(AG_MAJOR_VERSION) +AC_SUBST(AG_MINOR_VERSION) +AC_SUBST(AO_CURRENT) +AC_SUBST(AO_REVISION) +AC_SUBST(AO_AGE) +[AO_TEMPLATE_VERSION=`expr '(' $AO_CURRENT '*' 4096 ')' + $AO_REVISION` +]dnl +AC_SUBST(AO_TEMPLATE_VERSION) +AC_SUBST(GO_CURRENT) +AC_SUBST(GO_REVISION) +AC_SUBST(GO_AGE) +AC_DEFINE_UNQUOTED(AO_CURRENT,$AO_CURRENT, + [Define this to the autoopts current interface number]) +AC_DEFINE_UNQUOTED(AO_REVISION,$AO_REVISION, + [Define this to the autoopts interface revision number]) +AC_DEFINE_UNQUOTED(AO_AGE,$AO_AGE, + [Define this to the autoopts interface age number]) +# ---------------------------------------------------------------------- +# Set up the environment to configure the snprintv subpackage using +# this version of AutoGen (as opposed to any installed version). +# ---------------------------------------------------------------------- +[ag_srcdir=`\cd $srcdir && pwd` +if test x$ag_srcdir != x && test -d $ag_srcdir; then + : +else + ag_srcdir=.. +fi + +# ---------------------------------------------------------------------- +# If `configure' is invoked (in)directly via `make', ensure that it +# encounters no `make' conflicts. Ignore error if shell does not have +# unset, but at least set these to empty values. +# ---------------------------------------------------------------------- +MFLAGS= +MAKEFLAGS= +MAKELEVEL= +unset MFLAGS MAKEFLAGS MAKELEVEL 2>/dev/null] + +AM_WITH_DMALLOC + +# ---------------------------------------------------------------------- +# check for various programs used during the build. +# ---------------------------------------------------------------------- +AC_PROG_CC_STDC +AM_PROG_CC_C_O +gl_FUNC_GLIBC_UNLOCKED_IO +AC_EXEEXT +AC_PROG_INSTALL +AC_PROG_LIBTOOL +AC_CHECK_PROG(TEXI2HTML, texi2html, texi2html, :) +AC_C_CONST +AC_C_INLINE +# ---------------------------------------------------------------------- +AC_CHECK_LIB(dl, dlopen) +# ---------------------------------------------------------------------- +AC_TYPE_MODE_T +AC_TYPE_PID_T +AC_TYPE_SIZE_T +AC_TYPE_UID_T +AC_C_LONG_DOUBLE +[if test x$ac_cv_type_long_double = xno; then + snv_long_double=double +else + snv_long_double='long double' +fi] +AC_DEFINE_UNQUOTED([SNV_LONG_DOUBLE],$snv_long_double, + [Define this to the long+double type]) +AC_CHECK_TYPES([long long, uintmax_t, size_t, wchar_t]) +AC_CHECK_SIZEOF(char*) +AC_CHECK_SIZEOF(int) +AC_CHECK_SIZEOF(long) +AC_CHECK_SIZEOF(short) +# ---------------------------------------------------------------------- + +# ---------------------------------------------------------------------- +# Do all our own macros +# ---------------------------------------------------------------------- +INVOKE_AG_MACROS +[ +if ! test x$ag_cv_sys_siglist = xyes +then + if ! test x$ac_cv_func_strsignal = xyes + then + echo "WARNING: strsignal will use POSIX names and Linux signal numbers" + fi +fi >&2 +if test "X${ag_cv_link_sigsetjmp}" = Xno +then] + AC_MSG_ERROR([AutoGen requires sigsetjmp(3)])[ +fi +] +gl_STDNORETURN_H +# ---------------------------------------------------------------------- +# Do SNPRINTFV macros +# ---------------------------------------------------------------------- +INVOKE_SNPRINTFV_MACROS +# ---------------------------------------------------------------------- +# Generate the make files. +# ---------------------------------------------------------------------- +AC_PROG_LN_S +[ +test -f ./snprintfv/snprintfv/snprintfv.h \ + && rm -f ./snprintfv/snprintfv.h \ + && ${LN_S} `pwd`/snprintfv/snprintfv/snprintfv.h ./snprintfv/ + +AGnam=autogen${ac_exeext} +GDnam=getdefs${ac_exeext} +CLnam=columns${ac_exeext} +if test "X$cross_compiling" = Xyes +then + AGexe=`which ${AGnam}` + GDexe=`which ${GDnam}` + CLexe=`which ${CLnam}` +else + AGexe=${ag_top_builddir}/agen5/${AGnam} + GDexe=${ag_top_builddir}/getdefs/${GDnam} + CLexe=${ag_top_builddir}/columns/${CLnam} +fi +M4_SRC=`cd $srcdir/config ; echo [a-z]*.m4` +ENABLE_STATIC=${enable_static} +config_end_time=`date +%s 2>/dev/null` +time_delta=`expr ${config_end_time} - ${config_start_time} 2>/dev/null` + +if test -z "${AG_TIMEOUT}" +then + if test -z "${time_delta}" + then time_delta=10 + elif test ${time_delta} -lt 5 + then time_delta=5 ; fi + + AG_TIMEOUT=${time_delta} +fi +] +AC_DEFINE_UNQUOTED(AG_DEFAULT_TIMEOUT, ${AG_TIMEOUT}, + [define to suitable timeout limit for shell command]) +AC_SUBST(M4_SRC) +AC_SUBST(AGnam) +AC_SUBST(GDnam) +AC_SUBST(CLnam) +AC_SUBST(AGexe) +AC_SUBST(GDexe) +AC_SUBST(CLexe) +AC_SUBST(AG_TIMEOUT) +AC_SUBST(ac_aux_dir) +AC_SUBST(LIBS) +AC_SUBST(DEBUG_ENABLED) +AC_SUBST(ENABLE_STATIC) +[ +if test "$ag_top_srcdir" = "$ag_top_builddir" +then + INCLIST='-I${top_builddir} -I${top_srcdir}/autoopts' +else + INCLIST='-I${top_builddir} -I${top_srcdir}' + INCLIST="${INCLIST} -I\${top_builddir}/autoopts -I\${top_srcdir}/autoopts" +fi +]AC_SUBST(INCLIST)[ +WARN_CFLAGS= +test "X${GCC}" = Xyes && { + CFLAGS="$CFLAGS -Wno-format-contains-nul -fno-strict-aliasing" + WARN_CFLAGS="$CFLAGS "`echo -Wall -Werror -Wcast-align -Wmissing-prototypes \ + -Wpointer-arith -Wshadow -Wstrict-prototypes -Wwrite-strings \ + -Wstrict-aliasing=3 -Wextra -Wno-cast-qual` +}]dnl -Wconversion -Wsign-conversion -Wstrict-overflow +AC_SUBST(WARN_CFLAGS) +AC_CONFIG_HEADER(config.h:config-h.in) +AH_TOP([#ifndef AUTOGEN_CONFIG_H]) +AH_TOP([#define AUTOGEN_CONFIG_H 1]) +AH_BOTTOM([#endif /* AUTOGEN_CONFIG_H */]) +AC_CONFIG_FILES([autoopts/mk-autoopts-pc], + [chmod +x autoopts/mk-autoopts-pc]) +AC_CONFIG_FILES([autoopts/autoopts-config], + [chmod +x autoopts/autoopts-config]) + +AC_CONFIG_FILES([autoopts/tpl/tpl-config.tlib:autoopts/tpl/tpl-config-tlib.in]) +AC_CONFIG_FILES([doc/auto_gen.tpl:doc/auto_gen-tpl.in]) +AC_CONFIG_FILES([ + autoopts/test/defs config/mk-shdefs pkg/pkg-env + Makefile agen5/Makefile agen5/test/Makefile + autoopts/Makefile autoopts/test/Makefile columns/Makefile + compat/Makefile doc/Makefile getdefs/Makefile + getdefs/test/Makefile pkg/Makefile snprintfv/Makefile + xml2ag/Makefile xml2ag/test/Makefile]) + +AC_CONFIG_COMMANDS([stamp-h], +[test -z "$CONFIG_HEADERS" || echo timestamp > stamp-h]) +[CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} +f=`${CONFIG_SHELL} -c 'echo true | ( + exec 2>/dev/null ; read -u0 line ; echo $line ; )'` +test X$f = Xtrue || CONFIG_SHELL=`command -v bash`] +AC_SUBST(CONFIG_SHELL) +AC_DEFINE_UNQUOTED(CONFIG_SHELL,$CONFIG_SHELL, + [Define this to a working Bourne shell]) +AC_OUTPUT + +echo \ +"------------------------------------------------------------------------ +Configuration: + + Source code location: ${srcdir} + Compiler: ${CC} + Compiler flags: ${CFLAGS} + Host System Type: ${host} + Install path: ${prefix} + + See config.h for further configuration information. +------------------------------------------------------------------------" diff --git a/doc/Makefile.am b/doc/Makefile.am new file mode 100644 index 0000000..0544729 --- /dev/null +++ b/doc/Makefile.am @@ -0,0 +1,71 @@ +## -*- Mode: Makefile -*- +## +## Makefile.am -- process this file with automake to produce Makefile.in +## +## Author: Bruce Korb <bkorb@gnu.org> +## +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen 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. +## +## AutoGen is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License along +## with this program. If not, see <http://www.gnu.org/licenses/>. +## --------------------------------------------------------------------- + +# This variable is needed to subvert automake's info rules. +# They don't work for generated texi files: +# +INFO_DEPS = autogen.info +MIexe = $(MAKEINFO) --no-split +MAKEINFOFLAGS = -I$(top_srcdir)/autoopts -I../autoopts +passenv = MAKE=$(MAKE) srcdir="$(srcdir)" SHELL="$(POSIX_SHELL)" \ + top_builddir="$(top_builddir)" top_srcdir="$(top_srcdir)" + +run_mktexi = $(passenv) $(POSIX_SHELL) $${dashx} \ + $(srcdir)/mk-agen-texi.sh +all : $(INFO_DEPS) + +BUILT_SOURCES = autogen.texi +info_TEXINFOS = $(BUILT_SOURCES) +EXTRA_DIST = \ + agdoc.texi auto-opts.tlib autogen-intro.texi \ + autogen-intro.texi autogen-texi.txt fdl.texi \ + gendocs_template libopts.texi mk-agen-texi.sh \ + invoke-autogen.texi invoke-columns.texi \ + invoke-getdefs.texi invoke-xml2ag.texi \ + invoke-snprintfv.texi snprintfv.texi \ + invoke-bitmaps.texi bitmaps.texi + +# MAINTAINERCLEANFILES = MakeDep.inc +TEXI2DVI_FLAGS = --texinfo='@pagesizes 9.5in,7.0in' + +agdoc.texi : # self-depends upon all executables + $(run_mktexi) $@ + +autogen.dvi : agdoc.texi +autogen.texi : agdoc.texi mk-agen-texi.sh + @test -f $@ || { $(run_mktexi) $@ ; } + +# Special rule for generating all the GNU standard formats. +# +autogen.txt : autogen.texi + $(MIexe) --fill-column=70 --paragraph-indent=0 --no-headers \ + --output=$@ autogen.texi + +clobber : maintainer-clean + +.NOTPARALLEL: + +gnudocs : $(srcdir)/gendocs_template agdoc.texi + $(run_mktexi) $@ + +# doc/Makefile.am ends here diff --git a/doc/Makefile.in b/doc/Makefile.in new file mode 100644 index 0000000..7e9a866 --- /dev/null +++ b/doc/Makefile.in @@ -0,0 +1,873 @@ +# Makefile.in generated by automake 1.16.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2018 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +subdir = doc +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/config/ag_macros.m4 \ + $(top_srcdir)/config/asm-underscore.m4 \ + $(top_srcdir)/config/extensions.m4 \ + $(top_srcdir)/config/guile.m4 \ + $(top_srcdir)/config/host-cpu-c-abi.m4 \ + $(top_srcdir)/config/lib-ld.m4 \ + $(top_srcdir)/config/lib-link.m4 \ + $(top_srcdir)/config/lib-prefix.m4 \ + $(top_srcdir)/config/libopts.m4 \ + $(top_srcdir)/config/libtool.m4 \ + $(top_srcdir)/config/ltoptions.m4 \ + $(top_srcdir)/config/ltsugar.m4 \ + $(top_srcdir)/config/ltversion.m4 \ + $(top_srcdir)/config/lt~obsolete.m4 \ + $(top_srcdir)/config/onceonly.m4 $(top_srcdir)/config/pkg.m4 \ + $(top_srcdir)/config/snprintfv.m4 \ + $(top_srcdir)/config/stdnoreturn.m4 \ + $(top_srcdir)/config/unlocked-io.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = auto_gen.tpl +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +AM_V_DVIPS = $(am__v_DVIPS_@AM_V@) +am__v_DVIPS_ = $(am__v_DVIPS_@AM_DEFAULT_V@) +am__v_DVIPS_0 = @echo " DVIPS " $@; +am__v_DVIPS_1 = +AM_V_MAKEINFO = $(am__v_MAKEINFO_@AM_V@) +am__v_MAKEINFO_ = $(am__v_MAKEINFO_@AM_DEFAULT_V@) +am__v_MAKEINFO_0 = @echo " MAKEINFO" $@; +am__v_MAKEINFO_1 = +AM_V_INFOHTML = $(am__v_INFOHTML_@AM_V@) +am__v_INFOHTML_ = $(am__v_INFOHTML_@AM_DEFAULT_V@) +am__v_INFOHTML_0 = @echo " INFOHTML" $@; +am__v_INFOHTML_1 = +AM_V_TEXI2DVI = $(am__v_TEXI2DVI_@AM_V@) +am__v_TEXI2DVI_ = $(am__v_TEXI2DVI_@AM_DEFAULT_V@) +am__v_TEXI2DVI_0 = @echo " TEXI2DVI" $@; +am__v_TEXI2DVI_1 = +AM_V_TEXI2PDF = $(am__v_TEXI2PDF_@AM_V@) +am__v_TEXI2PDF_ = $(am__v_TEXI2PDF_@AM_DEFAULT_V@) +am__v_TEXI2PDF_0 = @echo " TEXI2PDF" $@; +am__v_TEXI2PDF_1 = +AM_V_texinfo = $(am__v_texinfo_@AM_V@) +am__v_texinfo_ = $(am__v_texinfo_@AM_DEFAULT_V@) +am__v_texinfo_0 = -q +am__v_texinfo_1 = +AM_V_texidevnull = $(am__v_texidevnull_@AM_V@) +am__v_texidevnull_ = $(am__v_texidevnull_@AM_DEFAULT_V@) +am__v_texidevnull_0 = > /dev/null +am__v_texidevnull_1 = +TEXINFO_TEX = $(top_srcdir)/config/texinfo.tex +am__TEXINFO_TEX_DIR = $(top_srcdir)/config +DVIS = autogen.dvi +PDFS = autogen.pdf +PSS = autogen.ps +HTMLS = autogen.html +TEXINFOS = $(BUILT_SOURCES) +TEXI2DVI = texi2dvi +TEXI2PDF = $(TEXI2DVI) --pdf --batch +MAKEINFOHTML = $(MAKEINFO) --html +AM_MAKEINFOHTMLFLAGS = $(AM_MAKEINFOFLAGS) +DVIPS = dvips +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__installdirs = "$(DESTDIR)$(infodir)" +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/auto_gen-tpl.in \ + $(top_srcdir)/config/texinfo.tex +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AGEN5_TESTS = @AGEN5_TESTS@ +AG_LDFLAGS = @AG_LDFLAGS@ +AG_MAJOR_VERSION = @AG_MAJOR_VERSION@ +AG_MINOR_VERSION = @AG_MINOR_VERSION@ +AG_STATIC_AUTOGEN = @AG_STATIC_AUTOGEN@ +AG_TIMEOUT = @AG_TIMEOUT@ +AG_VERSION = @AG_VERSION@ +AG_XML2 = @AG_XML2@ +AGexe = @AGexe@ +AGnam = @AGnam@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AO_AGE = @AO_AGE@ +AO_CURRENT = @AO_CURRENT@ +AO_REVISION = @AO_REVISION@ +AO_TEMPLATE_VERSION = @AO_TEMPLATE_VERSION@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CLexe = @CLexe@ +CLnam = @CLnam@ +CONFIG_SHELL = @CONFIG_SHELL@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEBUG_ENABLED = @DEBUG_ENABLED@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +DYNAMIC_AG = @DYNAMIC_AG@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ENABLE_STATIC = @ENABLE_STATIC@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GDexe = @GDexe@ +GDnam = @GDnam@ +GO_AGE = @GO_AGE@ +GO_CURRENT = @GO_CURRENT@ +GO_REVISION = @GO_REVISION@ +GREP = @GREP@ +GUILE_CFLAGS = @GUILE_CFLAGS@ +GUILE_EFFECTIVE_VERSION = @GUILE_EFFECTIVE_VERSION@ +GUILE_LDFLAGS = @GUILE_LDFLAGS@ +GUILE_LIBS = @GUILE_LIBS@ +GUILE_LTLIBS = @GUILE_LTLIBS@ +HOST_CPU = @HOST_CPU@ +HOST_CPU_C_ABI = @HOST_CPU_C_ABI@ +INCLIST = @INCLIST@ +INCSNPRINTFV = @INCSNPRINTFV@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSNPRINTFV = @LIBSNPRINTFV@ +LIBTOOL = @LIBTOOL@ +LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ +LIBXML2_LIBS = @LIBXML2_LIBS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +M4_SRC = @M4_SRC@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPTS_TESTDIR = @OPTS_TESTDIR@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POSIX_SHELL = @POSIX_SHELL@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STDNORETURN_H = @STDNORETURN_H@ +STRIP = @STRIP@ +TEXI2HTML = @TEXI2HTML@ +VERSION = @VERSION@ +WARN_CFLAGS = @WARN_CFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_aux_dir = @ac_aux_dir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ + +# This variable is needed to subvert automake's info rules. +# They don't work for generated texi files: +# +INFO_DEPS = autogen.info +MIexe = $(MAKEINFO) --no-split +MAKEINFOFLAGS = -I$(top_srcdir)/autoopts -I../autoopts +passenv = MAKE=$(MAKE) srcdir="$(srcdir)" SHELL="$(POSIX_SHELL)" \ + top_builddir="$(top_builddir)" top_srcdir="$(top_srcdir)" + +run_mktexi = $(passenv) $(POSIX_SHELL) $${dashx} \ + $(srcdir)/mk-agen-texi.sh + +BUILT_SOURCES = autogen.texi +info_TEXINFOS = $(BUILT_SOURCES) +EXTRA_DIST = \ + agdoc.texi auto-opts.tlib autogen-intro.texi \ + autogen-intro.texi autogen-texi.txt fdl.texi \ + gendocs_template libopts.texi mk-agen-texi.sh \ + invoke-autogen.texi invoke-columns.texi \ + invoke-getdefs.texi invoke-xml2ag.texi \ + invoke-snprintfv.texi snprintfv.texi \ + invoke-bitmaps.texi bitmaps.texi + + +# MAINTAINERCLEANFILES = MakeDep.inc +TEXI2DVI_FLAGS = --texinfo='@pagesizes 9.5in,7.0in' +all: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) all-am + +.SUFFIXES: +.SUFFIXES: .dvi .html .info .pdf .ps .texi +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu doc/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu doc/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +auto_gen.tpl: $(top_builddir)/config.status $(srcdir)/auto_gen-tpl.in + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +.texi.info: + $(AM_V_MAKEINFO)restore=: && backupdir="$(am__leading_dot)am$$$$" && \ + am__cwd=`pwd` && $(am__cd) $(srcdir) && \ + rm -rf $$backupdir && mkdir $$backupdir && \ + if ($(MAKEINFO) --version) >/dev/null 2>&1; then \ + for f in $@ $@-[0-9] $@-[0-9][0-9] $(@:.info=).i[0-9] $(@:.info=).i[0-9][0-9]; do \ + if test -f $$f; then mv $$f $$backupdir; restore=mv; else :; fi; \ + done; \ + else :; fi && \ + cd "$$am__cwd"; \ + if $(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \ + -o $@ $<; \ + then \ + rc=0; \ + $(am__cd) $(srcdir); \ + else \ + rc=$$?; \ + $(am__cd) $(srcdir) && \ + $$restore $$backupdir/* `echo "./$@" | sed 's|[^/]*$$||'`; \ + fi; \ + rm -rf $$backupdir; exit $$rc + +.texi.dvi: + $(AM_V_TEXI2DVI)TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \ + MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)' \ + $(TEXI2DVI) $(AM_V_texinfo) --build-dir=$(@:.dvi=.t2d) -o $@ $(AM_V_texidevnull) \ + $< + +.texi.pdf: + $(AM_V_TEXI2PDF)TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \ + MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)' \ + $(TEXI2PDF) $(AM_V_texinfo) --build-dir=$(@:.pdf=.t2p) -o $@ $(AM_V_texidevnull) \ + $< + +.texi.html: + $(AM_V_MAKEINFO)rm -rf $(@:.html=.htp) + $(AM_V_at)if $(MAKEINFOHTML) $(AM_MAKEINFOHTMLFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \ + -o $(@:.html=.htp) $<; \ + then \ + rm -rf $@ && mv $(@:.html=.htp) $@; \ + else \ + rm -rf $(@:.html=.htp); exit 1; \ + fi +$(srcdir)/autogen.info: autogen.texi +autogen.pdf: autogen.texi +autogen.html: autogen.texi +.dvi.ps: + $(AM_V_DVIPS)TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \ + $(DVIPS) $(AM_V_texinfo) -o $@ $< + +uninstall-dvi-am: + @$(NORMAL_UNINSTALL) + @list='$(DVIS)'; test -n "$(dvidir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " rm -f '$(DESTDIR)$(dvidir)/$$f'"; \ + rm -f "$(DESTDIR)$(dvidir)/$$f"; \ + done + +uninstall-html-am: + @$(NORMAL_UNINSTALL) + @list='$(HTMLS)'; test -n "$(htmldir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " rm -rf '$(DESTDIR)$(htmldir)/$$f'"; \ + rm -rf "$(DESTDIR)$(htmldir)/$$f"; \ + done + +uninstall-info-am: + @$(PRE_UNINSTALL) + @if test -d '$(DESTDIR)$(infodir)' && $(am__can_run_installinfo); then \ + list='$(INFO_DEPS)'; \ + for file in $$list; do \ + relfile=`echo "$$file" | sed 's|^.*/||'`; \ + echo " install-info --info-dir='$(DESTDIR)$(infodir)' --remove '$(DESTDIR)$(infodir)/$$relfile'"; \ + if install-info --info-dir="$(DESTDIR)$(infodir)" --remove "$(DESTDIR)$(infodir)/$$relfile"; \ + then :; else test ! -f "$(DESTDIR)$(infodir)/$$relfile" || exit 1; fi; \ + done; \ + else :; fi + @$(NORMAL_UNINSTALL) + @list='$(INFO_DEPS)'; \ + for file in $$list; do \ + relfile=`echo "$$file" | sed 's|^.*/||'`; \ + relfile_i=`echo "$$relfile" | sed 's|\.info$$||;s|$$|.i|'`; \ + (if test -d "$(DESTDIR)$(infodir)" && cd "$(DESTDIR)$(infodir)"; then \ + echo " cd '$(DESTDIR)$(infodir)' && rm -f $$relfile $$relfile-[0-9] $$relfile-[0-9][0-9] $$relfile_i[0-9] $$relfile_i[0-9][0-9]"; \ + rm -f $$relfile $$relfile-[0-9] $$relfile-[0-9][0-9] $$relfile_i[0-9] $$relfile_i[0-9][0-9]; \ + else :; fi); \ + done + +uninstall-pdf-am: + @$(NORMAL_UNINSTALL) + @list='$(PDFS)'; test -n "$(pdfdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " rm -f '$(DESTDIR)$(pdfdir)/$$f'"; \ + rm -f "$(DESTDIR)$(pdfdir)/$$f"; \ + done + +uninstall-ps-am: + @$(NORMAL_UNINSTALL) + @list='$(PSS)'; test -n "$(psdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " rm -f '$(DESTDIR)$(psdir)/$$f'"; \ + rm -f "$(DESTDIR)$(psdir)/$$f"; \ + done + +dist-info: $(INFO_DEPS) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + list='$(INFO_DEPS)'; \ + for base in $$list; do \ + case $$base in \ + $(srcdir)/*) base=`echo "$$base" | sed "s|^$$srcdirstrip/||"`;; \ + esac; \ + if test -f $$base; then d=.; else d=$(srcdir); fi; \ + base_i=`echo "$$base" | sed 's|\.info$$||;s|$$|.i|'`; \ + for file in $$d/$$base $$d/$$base-[0-9] $$d/$$base-[0-9][0-9] $$d/$$base_i[0-9] $$d/$$base_i[0-9][0-9]; do \ + if test -f $$file; then \ + relfile=`expr "$$file" : "$$d/\(.*\)"`; \ + test -f "$(distdir)/$$relfile" || \ + cp -p $$file "$(distdir)/$$relfile"; \ + else :; fi; \ + done; \ + done + +mostlyclean-aminfo: + -rm -rf autogen.t2d autogen.t2p + +clean-aminfo: + -test -z "autogen.dvi autogen.pdf autogen.ps autogen.html" \ + || rm -rf autogen.dvi autogen.pdf autogen.ps autogen.html + +maintainer-clean-aminfo: + @list='$(INFO_DEPS)'; for i in $$list; do \ + i_i=`echo "$$i" | sed 's|\.info$$||;s|$$|.i|'`; \ + echo " rm -f $$i $$i-[0-9] $$i-[0-9][0-9] $$i_i[0-9] $$i_i[0-9][0-9]"; \ + rm -f $$i $$i-[0-9] $$i-[0-9][0-9] $$i_i[0-9] $$i_i[0-9][0-9]; \ + done +tags TAGS: + +ctags CTAGS: + +cscope cscopelist: + + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$(top_distdir)" distdir="$(distdir)" \ + dist-info +check-am: all-am +check: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) check-am +all-am: Makefile $(INFO_DEPS) +installdirs: + for dir in "$(DESTDIR)$(infodir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) +clean: clean-am + +clean-am: clean-aminfo clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: $(DVIS) + +html: html-am + +html-am: $(HTMLS) + +info: info-am + +info-am: $(INFO_DEPS) + +install-data-am: install-info-am + +install-dvi: install-dvi-am + +install-dvi-am: $(DVIS) + @$(NORMAL_INSTALL) + @list='$(DVIS)'; test -n "$(dvidir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(dvidir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(dvidir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(dvidir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(dvidir)" || exit $$?; \ + done +install-exec-am: + +install-html: install-html-am + +install-html-am: $(HTMLS) + @$(NORMAL_INSTALL) + @list='$(HTMLS)'; list2=; test -n "$(htmldir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(htmldir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(htmldir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p" || test -d "$$p"; then d=; else d="$(srcdir)/"; fi; \ + $(am__strip_dir) \ + d2=$$d$$p; \ + if test -d "$$d2"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(htmldir)/$$f'"; \ + $(MKDIR_P) "$(DESTDIR)$(htmldir)/$$f" || exit 1; \ + echo " $(INSTALL_DATA) '$$d2'/* '$(DESTDIR)$(htmldir)/$$f'"; \ + $(INSTALL_DATA) "$$d2"/* "$(DESTDIR)$(htmldir)/$$f" || exit $$?; \ + else \ + list2="$$list2 $$d2"; \ + fi; \ + done; \ + test -z "$$list2" || { echo "$$list2" | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(htmldir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(htmldir)" || exit $$?; \ + done; } +install-info: install-info-am + +install-info-am: $(INFO_DEPS) + @$(NORMAL_INSTALL) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + list='$(INFO_DEPS)'; test -n "$(infodir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(infodir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(infodir)" || exit 1; \ + fi; \ + for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + esac; \ + if test -f $$file; then d=.; else d=$(srcdir); fi; \ + file_i=`echo "$$file" | sed 's|\.info$$||;s|$$|.i|'`; \ + for ifile in $$d/$$file $$d/$$file-[0-9] $$d/$$file-[0-9][0-9] \ + $$d/$$file_i[0-9] $$d/$$file_i[0-9][0-9] ; do \ + if test -f $$ifile; then \ + echo "$$ifile"; \ + else : ; fi; \ + done; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(infodir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(infodir)" || exit $$?; done + @$(POST_INSTALL) + @if $(am__can_run_installinfo); then \ + list='$(INFO_DEPS)'; test -n "$(infodir)" || list=; \ + for file in $$list; do \ + relfile=`echo "$$file" | sed 's|^.*/||'`; \ + echo " install-info --info-dir='$(DESTDIR)$(infodir)' '$(DESTDIR)$(infodir)/$$relfile'";\ + install-info --info-dir="$(DESTDIR)$(infodir)" "$(DESTDIR)$(infodir)/$$relfile" || :;\ + done; \ + else : ; fi +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: $(PDFS) + @$(NORMAL_INSTALL) + @list='$(PDFS)'; test -n "$(pdfdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(pdfdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pdfdir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pdfdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(pdfdir)" || exit $$?; done +install-ps: install-ps-am + +install-ps-am: $(PSS) + @$(NORMAL_INSTALL) + @list='$(PSS)'; test -n "$(psdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(psdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(psdir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(psdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(psdir)" || exit $$?; done +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-aminfo \ + maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-aminfo mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: $(PDFS) + +ps: ps-am + +ps-am: $(PSS) + +uninstall-am: uninstall-dvi-am uninstall-html-am uninstall-info-am \ + uninstall-pdf-am uninstall-ps-am + +.MAKE: all check install install-am install-strip + +.PHONY: all all-am check check-am clean clean-aminfo clean-generic \ + clean-libtool cscopelist-am ctags-am dist-info distclean \ + distclean-generic distclean-libtool distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-aminfo maintainer-clean-generic mostlyclean \ + mostlyclean-aminfo mostlyclean-generic mostlyclean-libtool pdf \ + pdf-am ps ps-am tags-am uninstall uninstall-am \ + uninstall-dvi-am uninstall-html-am uninstall-info-am \ + uninstall-pdf-am uninstall-ps-am + +.PRECIOUS: Makefile + +all : $(INFO_DEPS) + +agdoc.texi : # self-depends upon all executables + $(run_mktexi) $@ + +autogen.dvi : agdoc.texi +autogen.texi : agdoc.texi mk-agen-texi.sh + @test -f $@ || { $(run_mktexi) $@ ; } + +# Special rule for generating all the GNU standard formats. +# +autogen.txt : autogen.texi + $(MIexe) --fill-column=70 --paragraph-indent=0 --no-headers \ + --output=$@ autogen.texi + +clobber : maintainer-clean + +.NOTPARALLEL: + +gnudocs : $(srcdir)/gendocs_template agdoc.texi + $(run_mktexi) $@ + +# doc/Makefile.am ends here + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/doc/agdoc.texi b/doc/agdoc.texi new file mode 100644 index 0000000..9982e56 --- /dev/null +++ b/doc/agdoc.texi @@ -0,0 +1,13580 @@ +@settitle GNU AutoGen - The Automated Program Generator +@setchapternewpage off +@syncodeindex pg cp +@c %**end of header +@copying +This manual is for GNU AutoGen version 5.18, updated August 2018. + +Copyright @copyright{} 1992-2018 by Bruce Korb. + +@quotation +Permission is granted to copy, distribute and/or modify this document +under the terms of the GNU Free Documentation License, Version 1.2 or +any later version published by the Free Software Foundation; with no +Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. +@end quotation +@end copying + +@ignore +EDIT THIS FILE WITH CAUTION (agdoc.texi) + +It has been AutoGen-ed +From the definitions /u/bkorb/tools/ag/autogen-bld/doc/ag-texi-32340.d/agdoc.def +and the template file auto_gen.tpl + +Plus bits and pieces gathered from all over the source/build +directories: + /u/bkorb/tools/ag/autogen-bld/doc/auto_gen.tpl + /u/bkorb/tools/ag/autogen-bld/agen5/opts.def + /u/bkorb/tools/ag/autogen-bld/doc/bitmaps.texi + /u/bkorb/tools/ag/autogen-bld/columns/invoke-columns.texi + /u/bkorb/tools/ag/autogen-bld/getdefs/invoke-getdefs.texi + /u/bkorb/tools/ag/autogen-bld/xml2ag/invoke-xml2ag.texi + /u/bkorb/tools/ag/autogen-bld/doc/snprintfv.texi + /u/bkorb/tools/ag/autogen-bld/agen5/defParse-fsm.c + /u/bkorb/tools/ag/autogen-bld/agen5/opts.h + /u/bkorb/tools/ag/autogen-bld/autoopts/libopts.texi + /u/bkorb/tools/ag/autogen-bld/doc/autogen-intro.texi + /u/bkorb/tools/ag/autogen-bld/agen5/invoke-autogen.texi + /u/bkorb/tools/ag/autogen-bld/agen5/agShell.c + /u/bkorb/tools/ag/autogen-bld/agen5/expExtract.c + /u/bkorb/tools/ag/autogen-bld/agen5/expFormat.c + /u/bkorb/tools/ag/autogen-bld/agen5/expGperf.c + /u/bkorb/tools/ag/autogen-bld/agen5/expGuile.c + /u/bkorb/tools/ag/autogen-bld/agen5/expMake.c + /u/bkorb/tools/ag/autogen-bld/agen5/expOutput.c + /u/bkorb/tools/ag/autogen-bld/agen5/expPrint.c + /u/bkorb/tools/ag/autogen-bld/agen5/expState.c + /u/bkorb/tools/ag/autogen-bld/agen5/expString.c + /u/bkorb/tools/ag/autogen-bld/agen5/fmemopen.c + /u/bkorb/tools/ag/autogen-bld/agen5/funcCase.c + /u/bkorb/tools/ag/autogen-bld/agen5/funcDef.c + /u/bkorb/tools/ag/autogen-bld/agen5/funcEval.c + /u/bkorb/tools/ag/autogen-bld/agen5/funcFor.c + /u/bkorb/tools/ag/autogen-bld/agen5/funcIf.c + /u/bkorb/tools/ag/autogen-bld/agen5/functions.c + /u/bkorb/tools/ag/autogen-bld/agen5/schemedef.scm + /u/bkorb/tools/ag/autogen-bld/doc/autogen-texi.txt + +@end ignore + +@dircategory GNU programming tools +@direntry +* AutoGen: (autogen). The Automated Program Generator +@end direntry + +@ifinfo +@ifnothtml +This file documents GNU AutoGen Version 5.18. + +AutoGen copyright @copyright{} 1992-2018 Bruce Korb +AutoOpts copyright @copyright{} 1992-2018 Bruce Korb +snprintfv copyright @copyright{} 1999-2000 Gary V. Vaughan + +AutoGen 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. + +AutoGen is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program. If not, see <http://www.gnu.org/licenses/>. + +@ignore +Permission is granted to process this file through TeX and print the +results, provided the printed document carries copying permission +notice identical to this one except for the removal of this paragraph. +@end ignore +@end ifnothtml +@end ifinfo + +@finalout +@titlepage +@title AutoGen - The Automated Program Generator +@subtitle For version 5.18, August 2018 +@author Bruce Korb +@author @email{bkorb@@gnu.org} + +@page +@vskip 0pt plus 1filll +AutoGen copyright @copyright{} 1992-2018 Bruce Korb +@sp 2 +This is the second edition of the GNU AutoGen documentation, +@sp 2 +Published by Bruce Korb, 910 Redwood Dr., Santa Cruz, CA 95060 + +AutoGen 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. + +AutoGen is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program. If not, see <http://www.gnu.org/licenses/>. + +@insertcopying +@end titlepage + +@node Top, Introduction, , (dir) +@top The Automated Program Generator +@comment node-name, next, previous, up + +This file documents AutoGen version 5.18. It is a tool designed +for generating program files that contain repetitive text with varied +substitutions. This document is very long because it is intended as a +reference document. For a quick start example, @xref{Example Usage}. + +The AutoGen distribution includes the basic generator engine and +several add-on libraries and programs. Of the most general interest +would be Automated Option processing, @xref{AutoOpts}, which also +includes stand-alone support for configuration file parsing, @xref{Features}. +@xref{Add-Ons, Add-on packages for AutoGen}, section for additional +programs and libraries associated with AutoGen. + +This edition documents version 5.18, August 2018. + +@ignore + +This file is part of AutoGen. +AutoGen is free software. +AutoGen is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + +AutoGen 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. + +AutoGen is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program. If not, see <http://www.gnu.org/licenses/>. + +This file has the following md5sum: + +43b91e8ca915626ed3818ffb1b71248b COPYING.gplv3 + +@end ignore +@menu +* Introduction:: AutoGen's Purpose +* Definitions File:: AutoGen Definitions File +* Template File:: AutoGen Template +* Augmenting AutoGen:: Augmenting AutoGen Features +* autogen Invocation:: Invoking AutoGen +* Installation:: Configuring and Installing +* AutoOpts:: Automated Option Processing +* Add-Ons:: Add-on packages for AutoGen +* Future:: Some ideas for the future. +* Copying This Manual:: Copying This Manual +* Concept Index:: General index +* Function Index:: Function index +@end menu + +@ignore +* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +@end ignore +@page +@node Introduction +@chapter Introduction +@cindex Introduction + +AutoGen is a tool designed for generating program files that contain +repetitive text with varied substitutions. Its goal is to simplify the +maintenance of programs that contain large amounts of repetitious text. +This is especially valuable if there are several blocks of such text +that must be kept synchronized in parallel tables. + +An obvious example is the problem of maintaining the code required for +processing program options and configuration settings. Processing options +requires a minimum of four different constructs be kept in proper order in +different places in your program. You need at least: + +@enumerate +@item +The flag character in the flag string, +@item +code to process the flag when it is encountered, +@item +a global state variable or two, and +@item +a line in the usage text. +@end enumerate + +@noindent +You will need more things besides this if you choose to implement long option +names, configuration (rc/ini) file processing, environment variable settings +and keep all the documentation for these up to date. This can be done +mechanically; with the proper templates and this program. In fact, it has +already been done and AutoGen itself uses it@: @xref{AutoOpts}. For a simple +example of Automated Option processing, @xref{Quick Start}. For a full list +of the Automated Option features, @xref{Features}. Be forewarned, though, the +feature list is ridiculously extensive. + +@menu +* Generalities:: The Purpose of AutoGen +* Example Usage:: A Simple Example +* csh/zsh caveat:: csh/zsh caveat +* Testimonial:: A User's Perspective +@end menu + +@c === SECTION MARKER + +@node Generalities +@section The Purpose of AutoGen + +The idea of this program is to have a text file, a template if +you will, that contains the general text of the desired output file. +That file includes substitution expressions and sections of text that are +replicated under the control of separate definition files. + +@cindex design goals + +AutoGen was designed with the following features: + +@enumerate +@item +The definitions are completely separate from the template. By completely +isolating the definitions from the template it greatly increases the +flexibility of the template implementation. A secondary goal is that a +template user only needs to specify those data that are necessary to describe +his application of a template. + +@item +Each datum in the definitions is named. Thus, the definitions can be +rearranged, augmented and become obsolete without it being necessary to +go back and clean up older definition files. Reduce incompatibilities! + +@item +Every definition name defines an array of values, even when there is +only one entry. These arrays of values are used to control the +replication of sections of the template. + +@item +There are named collections of definitions. They form a nested hierarchy. +Associated values are collected and associated with a group name. +These associated data are used collectively in sets of substitutions. + +@item +The template has special markers to indicate where substitutions are +required, much like the @code{$@{VAR@}} construct in a shell @code{here doc}. +These markers are not fixed strings. They are specified at the start of +each template. Template designers know best what fits into their +syntax and can avoid marker conflicts. + +We did this because it is burdensome and difficult to avoid conflicts +using either M4 tokenization or C preprocessor substitution rules. It +also makes it easier to specify expressions that transform the value. +Of course, our expressions are less cryptic than the shell methods. + +@item +These same markers are used, in conjunction with enclosed keywords, to +indicate sections of text that are to be skipped and for sections of +text that are to be repeated. This is a major improvement over using C +preprocessing macros. With the C preprocessor, you have no way of +selecting output text because it is an @i{un}varying, mechanical +substitution process. + +@item +Finally, we supply methods for carefully controlling the output. +Sometimes, it is just simply easier and clearer to compute some text or +a value in one context when its application needs to be later. So, +functions are available for saving text or values for later use. +@end enumerate + +@c === SECTION MARKER + +@node Example Usage +@section A Simple Example +@cindex example, simple AutoGen + +This is just one simple example that shows a few basic features. +If you are interested, you also may run "make check" with the +@code{VERBOSE} environment variable set and see a number of other +examples in the @file{agen5/test} directory. + +Assume you have an enumeration of names and you wish to associate some +string with each name. Assume also, for the sake of this example, +that it is either too complex or too large to maintain easily by hand. +We will start by writing an abbreviated version of what the result +is supposed to be. We will use that to construct our output templates. + +@noindent +In a header file, @file{list.h}, you define the enumeration +and the global array containing the associated strings: + +@example +typedef enum @{ + IDX_ALPHA, + IDX_BETA, + IDX_OMEGA @} list_enum; + +extern char const* az_name_list[ 3 ]; +@end example + +@noindent +Then you also have @file{list.c} that defines the actual strings: + +@example +#include "list.h" +char const* az_name_list[] = @{ + "some alpha stuff", + "more beta stuff", + "final omega stuff" @}; +@end example + +@noindent +First, we will define the information that is unique for each enumeration +name/string pair. This would be placed in a file named, @file{list.def}, +for example. + +@example +autogen definitions list; +list = @{ list_element = alpha; + list_info = "some alpha stuff"; @}; +list = @{ list_info = "more beta stuff"; + list_element = beta; @}; +list = @{ list_element = omega; + list_info = "final omega stuff"; @}; +@end example + +The @code{autogen definitions list;} entry defines the file as an AutoGen +definition file that uses a template named @code{list}. That is followed by +three @code{list} entries that define the associations between the +enumeration names and the strings. The order of the differently named +elements inside of list is unimportant. They are reversed inside of the +@code{beta} entry and the output is unaffected. + +Now, to actually create the output, we need a template or two that can be +expanded into the files you want. In this program, we use a single template +that is capable of multiple output files. The definitions above refer to a +@file{list} template, so it would normally be named, @file{list.tpl}. + +It looks something like this. +(For a full description, @xref{Template File}.) + +@example +[+ AutoGen5 template h c +] +[+ CASE (suffix) +][+ + == h +] +typedef enum @{[+ + FOR list "," +] + IDX_[+ (string-upcase! (get "list_element")) +][+ + ENDFOR list +] @} list_enum; + +extern char const* az_name_list[ [+ (count "list") +] ]; +[+ + + == c +] +#include "list.h" +char const* az_name_list[] = @{[+ + FOR list "," +] + "[+list_info+]"[+ + ENDFOR list +] @};[+ + +ESAC +] +@end example + +The @code{[+ AutoGen5 template h c +]} text tells AutoGen that this is +an AutoGen version 5 template file; that it is to be processed twice; +that the start macro marker is @code{[+}; and the end marker is +@code{+]}. The template will be processed first with a suffix value of +@code{h} and then with @code{c}. Normally, the suffix values are +appended to the @file{base-name} to create the output file name. + +The @code{[+ == h +]} and @code{[+ == c +]} @code{CASE} selection clauses +select different text for the two different passes. In this example, +the output is nearly disjoint and could have been put in two separate +templates. However, sometimes there are common sections and this is +just an example. + +The @code{[+FOR list "," +]} and @code{[+ ENDFOR list +]} clauses delimit +a block of text that will be repeated for every definition of @code{list}. +Inside of that block, the definition name-value pairs that +are members of each @code{list} are available for substitutions. + +The remainder of the macros are expressions. Some of these contain +special expression functions that are dependent on AutoGen named values; +others are simply Scheme expressions, the result of which will be +inserted into the output text. Other expressions are names of AutoGen +values. These values will be inserted into the output text. For example, +@code{[+list_info+]} will result in the value associated with +the name @code{list_info} being inserted between the double quotes and +@code{(string-upcase! (get "list_element"))} will first "get" the value +associated with the name @code{list_element}, then change the case of +all the letters to upper case. The result will be inserted into the +output document. + +If you have compiled AutoGen, you can copy out the template and definitions +as described above and run @code{autogen list.def}. This will produce +exactly the hypothesized desired output. + +One more point, too. Lets say you decided it was too much trouble to figure +out how to use AutoGen, so you created this enumeration and string list with +thousands of entries. Now, requirements have changed and it has become +necessary to map a string containing the enumeration name into the enumeration +number. With AutoGen, you just alter the template to emit the table of names. +It will be guaranteed to be in the correct order, missing none of the entries. +If you want to do that by hand, well, good luck. + +@c === SECTION MARKER + +@node csh/zsh caveat +@section csh/zsh caveat + +AutoGen tries to use your normal shell so that you can supply shell code +in a manner you are accustomed to using. If, however, you use csh or +zsh, you cannot do this. Csh is sufficiently difficult to program that +it is unsupported. Zsh, though largely programmable, also has some +anomalies that make it incompatible with AutoGen usage. Therefore, when +invoking AutoGen from these environments, you must be certain to set the +SHELL environment variable to a Bourne-derived shell, e.g., sh, ksh or +bash. + +Any shell you choose for your own scripts need to follow these basic +requirements: + +@enumerate +@item +It handles @code{trap ":" $sig} without output to standard out. This is done +when the server shell is first started. If your shell does not handle this, +then it may be able to by loading functions from its start up files. +@item +At the beginning of each scriptlet, the command @code{\\cd $PWD} +is inserted. This ensures that @code{cd} is not aliased to something +peculiar and each scriptlet starts life in the execution directory. +@item +At the end of each scriptlet, the command @code{echo mumble} is +appended. The program you use as a shell must emit the single +argument @code{mumble} on a line by itself. +@end enumerate + +@c === SECTION MARKER + +@node Testimonial +@section A User's Perspective + +@format +Alexandre wrote: +> +> I'd appreciate opinions from others about advantages/disadvantages of +> each of these macro packages. +@end format + +I am using AutoGen in my pet project, and find one of its best points to +be that it separates the operational data from the implementation. + +Indulge me for a few paragraphs, and all will be revealed: +In the manual, Bruce cites the example of maintaining command line flags +inside the source code; traditionally spreading usage information, flag +names, letters and processing across several functions (if not files). +Investing the time in writing a sort of boiler plate (a template in +AutoGen terminology) pays by moving all of the option details (usage, +flags names etc.) into a well structured table (a definition file if you +will), so that adding a new command line option becomes a simple matter +of adding a set of details to the table. + +So far so good! Of course, now that there is a template, writing all of +that tedious optargs processing and usage functions is no longer an +issue. Creating a table of the options needed for the new project and +running AutoGen generates all of the option processing code in C +automatically from just the tabular data. AutoGen in fact already ships +with such a template... AutoOpts. + +One final consequence of the good separation in the design of AutoGen is +that it is retargetable to a greater extent. The +egcs/gcc/fixinc/inclhack.def can equally be used (with different +templates) to create a shell script (inclhack.sh) or a c program +(fixincl.c). + +This is just the tip of the iceberg. AutoGen is far more powerful than +these examples might indicate, and has many other varied uses. I am +certain Bruce or I could supply you with many and varied examples, and I +would heartily recommend that you try it for your project and see for +yourself how it compares to m4. +@cindex m4 + +As an aside, I would be interested to see whether someone might be +persuaded to rationalise autoconf with AutoGen in place of m4... Ben, +are you listening? autoconf-3.0! `kay? =)O| + +@format +Sincerely, + Gary V. Vaughan +@end format + +@ignore +* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +@end ignore +@page +@node Definitions File +@chapter Definitions File +@cindex definitions file +@cindex .def file + +This chapter describes the syntax and semantics of the AutoGen +definition file. In order to instantiate a template, you normally must +provide a definitions file that identifies itself and contains some +value definitions. Consequently, we keep it very simple. For +"advanced" users, there are preprocessing directives, sparse +arrays, named indexes and comments that may be used as well. + +The definitions file is used to associate values with names. Every +value is implicitly an array of values, even if there is only one value. +Values may be either simple strings or compound collections of +name-value pairs. An array may not contain both simple and compound +members. Fundamentally, it is as simple as: + +@example +prog-name = "autogen"; +flag = @{ + name = templ_dirs; + value = L; + descrip = "Template search directory list"; +@}; +@end example + +For purposes of commenting and controlling the processing of the +definitions, C-style comments and most C preprocessing directives are +honored. The major exception is that the @code{#if} directive is +ignored, along with all following text through the matching +@code{#endif} directive. The C preprocessor is not actually invoked, so +C macro substitution is @strong{not} performed. + +@menu +* Identification:: The Identification Definition +* Definitions:: Named Definitions +* Index Assignments:: Assigning an Index to a Definition +* Dynamic Text:: Dynamic Text +* Directives:: Controlling What Gets Processed +* Predefines:: Pre-defined Names +* Comments:: Commenting Your Definitions +* Example:: What it all looks like. +* Full Syntax:: Finite State Machine Grammar +* Alternate Definition:: Alternate Definition Forms +@end menu + +@c === SECTION MARKER + +@node Identification +@section The Identification Definition +@cindex identification + +The first definition in this file is used to identify it as a +AutoGen file. It consists of the two keywords, +@samp{autogen} and @samp{definitions} followed by the default +template name and a terminating semi-colon (@code{;}). That is: + +@example + AutoGen Definitions @var{template-name}; +@end example + +@noindent +Note that, other than the name @var{template-name}, the words +@samp{AutoGen} and @samp{Definitions} are searched for without case +sensitivity. Most lookups in this program are case insensitive. + +@noindent +Also, if the input contains more identification definitions, +they will be ignored. This is done so that you may include +(@pxref{Directives}) other definition files without an identification +conflict. + +@cindex template file + +@noindent +AutoGen uses the name of the template to find the corresponding template +file. It searches for the file in the following way, stopping when +it finds the file: + +@enumerate +@item +It tries to open @file{./@var{template-name}}. If it fails, +@item +it tries @file{./@var{template-name}.tpl}. +@item +It searches for either of these files in the directories listed in the +templ-dirs command line option. +@end enumerate + +If AutoGen fails to find the template file in one of these places, +it prints an error message and exits. + +@c === SECTION MARKER + +@node Definitions +@section Named Definitions +@cindex definitions + +A name is a sequence of characters beginning with an alphabetic character +(@code{a} through @code{z}) followed by zero or more alpha-numeric +characters and/or separator characters: hyphen (@code{-}), underscore +(@code{_}) or carat (@code{^}). Names are case insensitive. + +Any name may have multiple values associated with it. Every name may be +considered a sparse array of one or more elements. If there is more than +one value, the values my be accessed by indexing the value with +@code{[index]} or by iterating over them using the FOR (@pxref{FOR}) AutoGen +macro on it, as described in the next chapter. Sparse arrays are specified +by specifying an index when defining an entry +(@pxref{Index Assignments,, Assigning an Index to a Definition}). + +There are two kinds of definitions, @samp{simple} and @samp{compound}. +They are defined thus (@pxref{Full Syntax}): + +@example +compound_name '=' '@{' definition-list '@}' ';' + +simple-name[2] '=' string ';' + +no^text^name ';' +@end example + +@noindent +@code{simple-name} has the third index (index number 2) defined here. +@code{No^text^name} is a simple definition with a shorthand empty string +value. The string values for definitions may be specified in any of +several formation rules. + +@menu +* def-list:: Definition List +* double-quote-string:: Double Quote String +* single-quote-string:: Single Quote String +* simple-string:: An Unquoted String +* shell-generated:: Shell Output String +* scheme-generated:: Scheme Result String +* here-string:: A Here String +* concat-string:: Concatenated Strings +@end menu + +@cindex simple definitions +@cindex compound definitions + +@node def-list +@subsection Definition List + +@code{definition-list} is a list of definitions that may or may not +contain nested compound definitions. Any such definitions may +@strong{only} be expanded within a @code{FOR} block iterating over the +containing compound definition. @xref{FOR}. + +Here is, again, the example definitions from the previous chapter, +with three additional name value pairs. Two with an empty value +assigned (@var{first} and @var{last}), and a "global" @var{group_name}. + +@example +autogen definitions list; +group_name = example; +list = @{ list_element = alpha; first; + list_info = "some alpha stuff"; @}; +list = @{ list_info = "more beta stuff"; + list_element = beta; @}; +list = @{ list_element = omega; last; + list_info = "final omega stuff"; @}; +@end example + +@node double-quote-string +@subsection Double Quote String + +@cindex string, double quote +The string follows the C-style escaping, using the backslash to quote +(escape) the following character(s). Certain letters are translated to +various control codes (e.g. @code{\n}, @code{\f}, @code{\t}, etc.). +@code{x} introduces a two character hex code. @code{0} (the digit zero) +introduces a one to three character octal code (note: an octal byte followed +by a digit must be represented with three octal digits, thus: @code{"\0001"} +yielding a NUL byte followed by the ASCII digit 1). Any other character +following the backslash escape is simply inserted, without error, into the +string being formed. + +Like ANSI "C", a series of these strings, possibly intermixed with +single quote strings, will be concatenated together. + +@node single-quote-string +@subsection Single Quote String + +@cindex string, single quote +This is similar to the shell single-quote string. However, escapes +@code{\} are honored before another escape, single quotes @code{'} +and hash characters @code{#}. This latter is done specifically +to disambiguate lines starting with a hash character inside +of a quoted string. In other words, + +@example +fumble = ' +#endif +'; +@end example + +could be misinterpreted by the definitions scanner, whereas +this would not: + +@example +fumble = ' +\#endif +'; +@end example + +@* +As with the double quote string, a series of these, even intermixed +with double quote strings, will be concatenated together. + +@node simple-string +@subsection An Unquoted String + +A simple string that does not contain white space @i{may} be left +unquoted. The string must not contain any of the characters special to +the definition text (i.e., @code{"}, @code{#}, @code{'}, @code{(}, +@code{)}, @code{,}, @code{;}, @code{<}, @code{=}, @code{>}, @code{[}, +@code{]}, @code{`}, @code{@{}, or @code{@}}). This list is subject to +change, but it will never contain underscore (@code{_}), period +(@code{.}), slash (@code{/}), colon (@code{:}), hyphen (@code{-}) or +backslash (@code{\\}). Basically, if the string looks like it is a +normal DOS or UNIX file or variable name, and it is not one of two +keywords (@samp{autogen} or @samp{definitions}) then it is OK to not +quote it, otherwise you should. + +@node shell-generated +@subsection Shell Output String +@cindex shell-generated string + +@cindex string, shell output +This is assembled according to the same rules as the double quote string, +except that there is no concatenation of strings and the resulting string is +written to a shell server process. The definition takes on the value of +the output string. + +NB@: The text is interpreted by a server shell. There may be left over +state from previous server shell processing. This scriptlet may also leave +state for subsequent processing. However, a @code{cd} to the original +directory is always issued before the new command is issued. + +@node scheme-generated +@subsection Scheme Result String + +A scheme result string must begin with an open parenthesis @code{(}. +The scheme expression will be evaluated by Guile and the +value will be the result. The AutoGen expression functions +are @strong{dis}abled at this stage, so do not use them. + +@node here-string +@subsection A Here String +@cindex here-string + +A @samp{here string} is formed in much the same way as a shell here doc. It +is denoted with two less than characters(@code{<<}) and, optionally, a hyphen. +This is followed by optional horizontal white space and an ending +marker-identifier. This marker must follow the syntax rules for identifiers. +Unlike the shell version, however, you must not quote this marker. + +The resulting string will start with the first character on the next line and +continue up to but not including the newline that precedes the line that +begins with the marker token. The characters are copied directly into the +result string. Mostly. + +If a hyphen follows the less than characters, then leading tabs will be +stripped and the terminating marker will be recognized even if preceded by +tabs. Also, if the first character on the line (after removing tabs) is a +backslash and the next character is a tab or space, then the backslash will +be removed as well. No other kind of processing is done on this string. + +Here are three examples: +@example +str1 = <<- STR_END + $quotes = " ' ` + STR_END; + +str2 = << STR_END + $quotes = " ' ` + STR_END; +STR_END; + +str3 = <<- STR_END + \ $quotes = " ' ` + STR_END; +@end example +The first string contains no new line characters. +The first character is the dollar sign, the last the back quote. + +The second string contains one new line character. The first character +is the tab character preceding the dollar sign. The last character is +the semicolon after the @code{STR_END}. That @code{STR_END} does not +end the string because it is not at the beginning of the line. In the +preceding case, the leading tab was stripped. + +The third string is almost identical to the first, except that the +first character is a tab. That is, it exactly matches the first line +of the second string. + +@node concat-string +@subsection Concatenated Strings +@cindex concat-string + +If single or double quote characters are used, +then you also have the option, a la ANSI-C syntax, +of implicitly concatenating a series of them together, +with intervening white space ignored. + +NB@: You @strong{cannot} use directives to alter the string +content. That is, + +@example +str = "fumble" +#ifdef LATER + "stumble" +#endif + ; +@end example + +@noindent +will result in a syntax error. The preprocessing directives are not +carried out by the C preprocessor. However, + +@example +str = '"fumble\n" +#ifdef LATER +" stumble\n" +#endif +'; +@end example + +@noindent +@strong{Will} work. It will enclose the @samp{#ifdef LATER} +and @samp{#endif} in the string. But it may also wreak +havoc with the definition processing directives. The hash +characters in the first column should be disambiguated with +an escape @code{\} or join them with previous lines: +@code{"fumble\n#ifdef LATER...}. + +@c === SECTION MARKER + +@node Index Assignments +@section Assigning an Index to a Definition +@cindex Definition Index + +In AutoGen, every name is implicitly an array of values. +When assigning values, they are usually implicitly +assigned to the next highest slot. They can also be +specified explicitly: + +@example +mumble[9] = stumble; +mumble[0] = grumble; +@end example + +@noindent +If, subsequently, you assign a value to @code{mumble} without an +index, its index will be @code{10}, not @code{1}. +If indexes are specified, they must not cause conflicts. + +@code{#define}-d names may also be used for index values. +This is equivalent to the above: + +@example +#define FIRST 0 +#define LAST 9 +mumble[LAST] = stumble; +mumble[FIRST] = grumble; +@end example + +All values in a range do @strong{not} have to be filled in. +If you leave gaps, then you will have a sparse array. This +is fine (@pxref{FOR}). You have your choice of iterating +over all the defined values, or iterating over a range +of slots. This: + +@example +[+ FOR mumble +][+ ENDFOR +] +@end example + +@noindent +iterates over all and only the defined entries, whereas this: + +@example +[+ FOR mumble (for-by 1) +][+ ENDFOR +] +@end example + +@noindent +will iterate over all 10 "slots". Your template will +likely have to contain something like this: + +@example +[+ IF (exist? (sprintf "mumble[%d]" (for-index))) +] +@end example + +@noindent +or else "mumble" will have to be a compound value that, +say, always contains a "grumble" value: + +@example +[+ IF (exist? "grumble") +] +@end example + +@c === SECTION MARKER + +@node Dynamic Text +@section Dynamic Text +@cindex Dynamic Definition Text + +There are several methods for including dynamic content inside a definitions +file. Three of them are mentioned above (@ref{shell-generated} and +@pxref{scheme-generated}) in the discussion of string formation rules. +Another method uses the @code{#shell} processing directive. +It will be discussed in the next section (@pxref{Directives}). +Guile/Scheme may also be used to yield to create definitions. + +When the Scheme expression is preceded by a backslash and single +quote, then the expression is expected to be an alist of +names and values that will be used to create AutoGen definitions. + +@noindent +This method can be be used as follows: + +@example +\'( (name (value-expression)) + (name2 (another-expr)) ) +@end example + +@noindent +This is entirely equivalent to: + +@example +name = (value-expression); +name2 = (another-expr); +@end example + +@noindent +Under the covers, the expression gets handed off to a Guile function +named @code{alist->autogen-def} in an expression that looks like this: + +@example +(alist->autogen-def + ( (name (value-expression)) (name2 (another-expr)) ) ) +@end example + +@node Directives +@section Controlling What Gets Processed +@cindex directives + +Definition processing directives can @strong{only} be processed +if the '#' character is the first character on a line. Also, if you +want a '#' as the first character of a line in one of your string +assignments, you should either escape it by preceding it with a +backslash @samp{\}, or by embedding it in the string as in @code{"\n#"}. + +All of the normal C preprocessing directives are recognized, though +several are ignored. There is also an additional @code{#shell} - +@code{#endshell} pair. Another minor difference is that AutoGen +directives must have the hash character (@code{#}) in column 1. +Unrecognized directives produce an error. + +The final tweak is that @code{#!} is treated as a comment line. +Using this feature, you can use: @samp{#! /usr/local/bin/autogen} +as the first line of a definitions file, set the mode to executable +and "run" the definitions file as if it were a direct invocation of +AutoGen. This was done for its hack value. + +The AutoGen recognized directives are: +@table @code +@item #assert +@cindex assert +@cindex assert directive +This directive @i{is} processed, but only if the expression begins with +either a back quote (@code{`}) or an open parenthesis (@code{(}). +Text within the back quotes are handed off to the shell for processing +and parenthesized text is handed off to Guile. Multiple line expressions +must be joined with backslashes. + +If the @code{shell-script} or @code{scheme-expr} do not yield @code{true} +valued results, autogen will be aborted. If @code{<anything else>} or +nothing at all is provided, then this directive is ignored. + +The result is @code{false} (and fails) if the result is empty, the +number zero, or a string that starts with the letters 'n' or 'f' ("no" +or "false"). + +@item #define +@cindex define +@cindex define directive +Will add the name to the define list as if it were a DEFINE program +argument. Its value will be the first non-whitespace token following +the name. Quotes are @strong{not} processed. + +After the definitions file has been processed, any remaining entries +in the define list will be added to the environment. + +@item #elif +@cindex elif +@cindex elif directive +Marks a transition in the #if directive. Error when out of context. +#if blocks are always ignored. + +@item #else +@cindex else +@cindex else directive +This must follow an @code{#if}, @code{#ifdef} or @code{#ifndef}. +If it follows the @code{#if}, then it will be ignored. Otherwise, +it will change the processing state to the reverse of what it was. + +@item #endif +@cindex endif +@cindex endif directive +This must follow an @code{#if}, @code{#ifdef} or @code{#ifndef}. +In all cases, this will resume normal processing of text. + +@item #endmac +@cindex endmac +@cindex endmac directive +Marks the end of the #macdef directive. Error when out of context. + +@item #endshell +@cindex endshell +@cindex endshell directive +Marks the end of the #shell directive. Error when out of context. + +@item #error +@cindex error +@cindex error directive +This directive will cause AutoGen to stop processing +and exit with a status of EXIT_FAILURE. + +@item #ident +@cindex ident +@cindex ident directive +Ignored directive. + +@item #if +@cindex if +@cindex if directive +@code{#if} expressions are not analyzed. @strong{Everything} from here +to the matching @code{#endif} is skipped. + +@item #ifdef +@cindex ifdef +@cindex ifdef directive +The definitions that follow, up to the matching @code{#endif} will be +processed only if there is a corresponding @code{-Dname} command line +option or if a @code{#define} of that name has been previously encountered. + +@item #ifndef +@cindex ifndef +@cindex ifndef directive +The definitions that follow, up to the matching @code{#endif} will be +processed only if the named value has @strong{not} been defined. + +@item #include +@cindex include +@cindex include directive +This directive will insert definitions from another file into +the current collection. If the file name is adorned with +double quotes or angle brackets (as in a C program), then the +include is ignored. + +@item #let +@cindex let +@cindex let directive +Ignored directive. + +@item #line +@cindex line +@cindex line directive +Alters the current line number and/or file name. You may wish to +use this directive if you extract definition source from other files. +@command{getdefs} uses this mechanism so AutoGen will report the correct +file and approximate line number of any errors found in extracted +definitions. + +@item #macdef +@cindex macdef +@cindex macdef directive +This is a new AT&T research preprocessing directive. Basically, it is +a multi-line #define that may include other preprocessing directives. +Text between this line and a #endmac directive are ignored. + +@item #option +@cindex option +@cindex option directive +This directive will pass the option name and associated text to the +AutoOpts optionLoadLine routine (@pxref{libopts-optionLoadLine}). The +option text may span multiple lines by continuing them with a backslash. +The backslash/newline pair will be replaced with two space characters. +This directive may be used to set a search path for locating template files +For example, this: + +@example +#option templ-dirs $ENVVAR/dirname +@end example +@noindent +will direct autogen to use the @code{ENVVAR} environment variable to find +a directory named @code{dirname} that (may) contain templates. Since these +directories are searched in most recently supplied first order, search +directories supplied in this way will be searched before any supplied on +the command line. + +@item #pragma +@cindex pragma +@cindex pragma directive +Ignored directive. + +@item #shell +@cindex shell +@cindex shell directive +Invokes @code{$SHELL} or @file{/bin/sh} on a script that should +generate AutoGen definitions. It does this using the same server +process that handles the back-quoted @code{`} text. +The block of text handed to the shell is terminated with +the #endshell directive. + +@strong{CAUTION}@: let not your @code{$SHELL} be @code{csh}. + +@item #undef +@cindex undef +@cindex undef directive +Will remove any entries from the define list +that match the undef name pattern. +@end table +@ignore +START == COMMENTS == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore + +@ignore +Resume input from autogen.texi +@end ignore + +@c === SECTION MARKER + +@node Predefines +@section Pre-defined Names +@cindex predefines + +When AutoGen starts, it tries to determine several names from the +operating environment and put them into environment variables for use in +both @code{#ifdef} tests in the definitions files and in shell scripts +with environment variable tests. @env{__autogen__} is always defined. +For other names, AutoGen will first try to use the POSIX version of the +@code{sysinfo(2)} system call. Failing that, it will try for the POSIX +@code{uname(2)} call. If neither is available, then only +"@env{__autogen__}" will be inserted into the environment. +In all cases, the associated names are converted to lower case, surrounded +by doubled underscores and non-symbol characters are replaced with +underscores. + +With Solaris on a sparc platform, @code{sysinfo(2)} is available. +The following strings are used: + +@itemize @bullet +@item +@code{SI_SYSNAME} (e.g., "__sunos__") +@item +@code{SI_HOSTNAME} (e.g., "__ellen__") +@item +@code{SI_ARCHITECTURE} (e.g., "__sparc__") +@item +@code{SI_HW_PROVIDER} (e.g., "__sun_microsystems__") +@item +@code{SI_PLATFORM} (e.g., "__sun_ultra_5_10__") +@item +@code{SI_MACHINE} (e.g., "__sun4u__") +@end itemize + +For Linux and other operating systems that only support the +@code{uname(2)} call, AutoGen will use these values: + +@itemize @bullet +@item +@code{sysname} (e.g., "__linux__") +@item +@code{machine} (e.g., "__i586__") +@item +@code{nodename} (e.g., "__bach__") +@end itemize + +By testing these pre-defines in my definitions, you can select +pieces of the definitions without resorting to writing shell +scripts that parse the output of @code{uname(1)}. You can also +segregate real C code from autogen definitions by testing for +"@code{__autogen__}". + +@example +#ifdef __bach__ + location = home; +#else + location = work; +#endif +@end example + +@c === SECTION MARKER + +@node Comments +@section Commenting Your Definitions +@cindex comments + +The definitions file may contain C and C++ style comments. + +@example +/* + * This is a comment. It continues for several lines and closes + * when the characters '*' and '/' appear together. + */ +// this comment is a single line comment +@end example + +@c === SECTION MARKER + +@node Example +@section What it all looks like. + +@noindent +This is an extended example: + +@example +autogen definitions @samp{template-name}; +/* + * This is a comment that describes what these + * definitions are all about. + */ +global = "value for a global text definition."; + +/* + * Include a standard set of definitions + */ +#include standards.def + +a_block = @{ + a_field; + a_subblock = @{ + sub_name = first; + sub_field = "sub value."; + @}; + +#ifdef FEATURE + a_subblock = @{ + sub_name = second; + @}; +#endif + +@}; +@end example + +@ignore +END == COMMENTS == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore +@node Full Syntax +@section Finite State Machine Grammar + +The preprocessing directives and comments are not part of the grammar. They +are handled by the scanner/lexer. The following was extracted directly from +the generated defParse-fsm.c source file. The "EVT:" is the token seen, +the "STATE:" is the current state and the entries in this table describe +the next state and the action to take. Invalid transitions were removed +from the table. + +@ignore +Extracted from $top_srcdir/agen5/defParse.y +@end ignore +@example +dp_trans_table[ DP_STATE_CT ][ DP_EVENT_CT ] = @{ + + /* STATE 0: DP_ST_INIT */ + @{ @{ DP_ST_NEED_DEF, NULL @}, /* EVT: AUTOGEN */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: DEFINITIONS */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: End-Of-File */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: VAR_NAME */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: OTHER_NAME */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: STRING */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: HERE_STRING */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: DELETE_ENT */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: NUMBER */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: ; */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: = */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: , */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: @{ */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: @} */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: [ */ + @{ DP_ST_INVALID, dp_do_invalid @} /* EVT: ] */ + + /* STATE 1: DP_ST_NEED_DEF */ + @{ @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: AUTOGEN */ + @{ DP_ST_NEED_TPL, NULL @}, /* EVT: DEFINITIONS */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: End-Of-File */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: VAR_NAME */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: OTHER_NAME */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: STRING */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: HERE_STRING */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: DELETE_ENT */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: NUMBER */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: ; */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: = */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: , */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: @{ */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: @} */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: [ */ + @{ DP_ST_INVALID, dp_do_invalid @} /* EVT: ] */ + + /* STATE 2: DP_ST_NEED_TPL */ + @{ @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: AUTOGEN */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: DEFINITIONS */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: End-Of-File */ + @{ DP_ST_NEED_SEMI, dp_do_tpl_name @}, /* EVT: VAR_NAME */ + @{ DP_ST_NEED_SEMI, dp_do_tpl_name @}, /* EVT: OTHER_NAME */ + @{ DP_ST_NEED_SEMI, dp_do_tpl_name @}, /* EVT: STRING */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: HERE_STRING */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: DELETE_ENT */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: NUMBER */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: ; */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: = */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: , */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: @{ */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: @} */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: [ */ + @{ DP_ST_INVALID, dp_do_invalid @} /* EVT: ] */ + + /* STATE 3: DP_ST_NEED_SEMI */ + @{ @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: AUTOGEN */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: DEFINITIONS */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: End-Of-File */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: VAR_NAME */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: OTHER_NAME */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: STRING */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: HERE_STRING */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: DELETE_ENT */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: NUMBER */ + @{ DP_ST_NEED_NAME, NULL @}, /* EVT: ; */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: = */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: , */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: @{ */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: @} */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: [ */ + @{ DP_ST_INVALID, dp_do_invalid @} /* EVT: ] */ + + /* STATE 4: DP_ST_NEED_NAME */ + @{ @{ DP_ST_NEED_DEF, NULL @}, /* EVT: AUTOGEN */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: DEFINITIONS */ + @{ DP_ST_DONE, dp_do_need_name_end @}, /* EVT: End-Of-File */ + @{ DP_ST_HAVE_NAME, dp_do_need_name_var_name @}, /* EVT: VAR_NAME */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: OTHER_NAME */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: STRING */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: HERE_STRING */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: DELETE_ENT */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: NUMBER */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: ; */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: = */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: , */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: @{ */ + @{ DP_ST_HAVE_VALUE, dp_do_end_block @}, /* EVT: @} */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: [ */ + @{ DP_ST_INVALID, dp_do_invalid @} /* EVT: ] */ + + /* STATE 5: DP_ST_HAVE_NAME */ + @{ @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: AUTOGEN */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: DEFINITIONS */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: End-Of-File */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: VAR_NAME */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: OTHER_NAME */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: STRING */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: HERE_STRING */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: DELETE_ENT */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: NUMBER */ + @{ DP_ST_NEED_NAME, dp_do_empty_val @}, /* EVT: ; */ + @{ DP_ST_NEED_VALUE, dp_do_have_name_lit_eq @}, /* EVT: = */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: , */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: @{ */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: @} */ + @{ DP_ST_NEED_IDX, NULL @}, /* EVT: [ */ + @{ DP_ST_INVALID, dp_do_invalid @} /* EVT: ] */ + + /* STATE 6: DP_ST_NEED_VALUE */ + @{ @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: AUTOGEN */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: DEFINITIONS */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: End-Of-File */ + @{ DP_ST_HAVE_VALUE, dp_do_str_value @}, /* EVT: VAR_NAME */ + @{ DP_ST_HAVE_VALUE, dp_do_str_value @}, /* EVT: OTHER_NAME */ + @{ DP_ST_HAVE_VALUE, dp_do_str_value @}, /* EVT: STRING */ + @{ DP_ST_HAVE_VALUE, dp_do_str_value @}, /* EVT: HERE_STRING */ + @{ DP_ST_NEED_NAME, dp_do_need_value_delete_ent @}, /* EVT: DELETE_ENT */ + @{ DP_ST_HAVE_VALUE, dp_do_str_value @}, /* EVT: NUMBER */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: ; */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: = */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: , */ + @{ DP_ST_NEED_NAME, dp_do_start_block @}, /* EVT: @{ */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: @} */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: [ */ + @{ DP_ST_INVALID, dp_do_invalid @} /* EVT: ] */ + + /* STATE 7: DP_ST_NEED_IDX */ + @{ @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: AUTOGEN */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: DEFINITIONS */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: End-Of-File */ + @{ DP_ST_NEED_CBKT, dp_do_indexed_name @}, /* EVT: VAR_NAME */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: OTHER_NAME */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: STRING */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: HERE_STRING */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: DELETE_ENT */ + @{ DP_ST_NEED_CBKT, dp_do_indexed_name @}, /* EVT: NUMBER */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: ; */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: = */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: , */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: @{ */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: @} */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: [ */ + @{ DP_ST_INVALID, dp_do_invalid @} /* EVT: ] */ + + /* STATE 8: DP_ST_NEED_CBKT */ + @{ @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: AUTOGEN */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: DEFINITIONS */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: End-Of-File */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: VAR_NAME */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: OTHER_NAME */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: STRING */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: HERE_STRING */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: DELETE_ENT */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: NUMBER */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: ; */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: = */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: , */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: @{ */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: @} */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: [ */ + @{ DP_ST_INDX_NAME, NULL @} /* EVT: ] */ + + /* STATE 9: DP_ST_INDX_NAME */ + @{ @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: AUTOGEN */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: DEFINITIONS */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: End-Of-File */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: VAR_NAME */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: OTHER_NAME */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: STRING */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: HERE_STRING */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: DELETE_ENT */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: NUMBER */ + @{ DP_ST_NEED_NAME, dp_do_empty_val @}, /* EVT: ; */ + @{ DP_ST_NEED_VALUE, NULL @}, /* EVT: = */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: , */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: @{ */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: @} */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: [ */ + @{ DP_ST_INVALID, dp_do_invalid @} /* EVT: ] */ + + /* STATE 10: DP_ST_HAVE_VALUE */ + @{ @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: AUTOGEN */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: DEFINITIONS */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: End-Of-File */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: VAR_NAME */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: OTHER_NAME */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: STRING */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: HERE_STRING */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: DELETE_ENT */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: NUMBER */ + @{ DP_ST_NEED_NAME, NULL @}, /* EVT: ; */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: = */ + @{ DP_ST_NEED_VALUE, dp_do_next_val @}, /* EVT: , */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: @{ */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: @} */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: [ */ + @{ DP_ST_INVALID, dp_do_invalid @} /* EVT: ] */ +@end example +@ignore +START == TEMPLATE == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore + +@c === SECTION MARKER + +@node Alternate Definition +@section Alternate Definition Forms +@cindex Alternate Definition + +There are several methods for supplying data values for templates. + +@table @samp +@item no definitions +It is entirely possible to write a template that does not depend upon +external definitions. Such a template would likely have an unvarying +output, but be convenient nonetheless because of an external library +of either AutoGen or Scheme functions, or both. This can be accommodated +by providing the @option{--override-tpl} and @option{--no-definitions} +options on the command line. @xref{autogen Invocation}. + +@item CGI +AutoGen behaves as a CGI server if the definitions input is from stdin +and the environment variable @env{REQUEST_METHOD} is defined +and set to either "GET" or "POST", @xref{AutoGen CGI}. Obviously, +all the values are constrained to strings because there is no way +to represent nested values. + +@item XML +AutoGen comes with a program named, @command{xml2ag}. Its output can +either be redirected to a file for later use, or the program can +be used as an AutoGen wrapper. @xref{xml2ag Invocation}. + +The introductory template example (@pxref{Example Usage}) can be rewritten +in XML as follows: + +@example +<EXAMPLE template="list.tpl"> +<LIST list_element="alpha" + list_info="some alpha stuff"/> +<LIST list_info="more beta stuff" + list_element="beta"/> +<LIST list_element="omega" + list_info="final omega stuff"/> +</EXAMPLE> +@end example + +A more XML-normal form might look like this: +@example +<EXAMPLE template="list.tpl"> +<LIST list_element="alpha">some alpha stuff</LIST> +<LIST list_element="beta" >more beta stuff</LIST> +<LIST list_element="omega">final omega stuff</LIST> +</EXAMPLE> +@end example +@noindent +but you would have to change the template @code{list-info} references +into @code{text} references. + +@item standard AutoGen definitions +Of course. :-) + +@end table + +@ignore +* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +@end ignore +@page +@node Template File +@chapter Template File +@cindex template file +@cindex .tpl file + +The AutoGen template file defines the content of the output text. +It is composed of two parts. The first part consists of a pseudo +macro invocation and commentary. It is followed by the template proper. + +@cindex pseudo macro +@cindex macro, pseudo +This pseudo macro is special. It is used to identify the file as a +AutoGen template file, fixing the starting and ending marks for +the macro invocations in the rest of the file, specifying the list +of suffixes to be generated by the template and, optionally, the +shell to use for processing shell commands embedded in the template. + +AutoGen-ing a file consists of copying text from the template to the +output file until a start macro marker is found. The text from the +start marker to the end marker constitutes the macro text. AutoGen +macros may cause sections of the template to be skipped or processed +several times. The process continues until the end of the template is +reached. The process is repeated once for each suffix specified in the +pseudo macro. + +This chapter describes the format of the AutoGen template macros +and the usage of the AutoGen native macros. Users may augment +these by defining their own macros, @xref{DEFINE}. + +@menu +* pseudo macro:: Format of the Pseudo Macro +* naming values:: Naming a value +* expression syntax:: Macro Expression Syntax +* AutoGen Functions:: AutoGen Scheme Functions +* Common Functions:: Common Scheme Functions +* native macros:: AutoGen Native Macros +* output controls:: Redirecting Output +@end menu + +@c === SECTION MARKER + +@node pseudo macro +@section Format of the Pseudo Macro +@cindex pseudo macro + +The pseudo macro is used to tell AutoGen how to process a template. +It tells autogen: + +@enumerate +@item +The start macro marker. It consists of punctuation characters used to +demarcate the start of a macro. It may be up to seven characters long and +must be the first non-whitespace characters in the file. + +@noindent +It is generally a good idea to use some sort of opening +bracket in the starting macro and closing bracket in the ending +macro (e.g. @code{@{}, @code{(}, @code{[}, or even @code{<} +in the starting macro). It helps both visually and with editors +capable of finding a balancing parenthesis. + +@item +That start marker must be immediately followed by the identifier strings +"AutoGen5" and then "template", though capitalization is not important. +@end enumerate + +@noindent +The next several components may be intermingled: + +@enumerate 3 +@item +Zero, one or more suffix specifications tell AutoGen how many times to +process the template file. No suffix specifications mean that it is to +be processed once and that the generated text is to be written to +@file{stdout}. The current suffix for each pass can be determined with the +@code{(suffix)} scheme function (@pxref{SCM suffix}). + +The suffix specification consists of a sequence of POSIX compliant file name +characters and, optionally, an equal sign and a file name formatting +specification. That specification may be either an ordinary sequence of +file name characters with zero, one or two "%s" formatting sequences in it, +or else it may be a Scheme expression that, when evaluated, produces such a +string. The Scheme result may not be empty. The two string arguments +allowed for that string are the base name of the definition file, and the +current suffix (that being the text to the left of the equal sign). (Note: +"POSIX compliant file name characters" consist of alphanumerics plus the +period (@code{.}), hyphen (@code{-}) and underscore (@code{_}) characters.) + +If the suffix begins with one of these three latter characters and +a formatting string is not specified, then that character is presumed to +be the suffix separator. Otherwise, without a specified format string, +a single period will separate the suffix from the base name in constructing +the output file name. + +@item +Shell specification: to specify that the template was written expecting a +particular shell to run the shell commands. By default, the shell used is the +autoconf-ed @env{CONFIG_SHELL}. This will usually be @file{/bin/sh}. The +shell is specified by a hash mark (@code{#}) followed by an exclamation mark +(@code{!}) followed by a full-path file name (e.g. @file{/usr/xpg4/bin/sh} on +Solaris): +@example +[= Autogen5 Template c +#!/usr/xpg4/bin/sh +=] +@end example + +@item +Comments: blank lines, lines starting with a hash mark (@code{#}) and not +specifying a shell, and edit mode markers (text between pairs of @code{-*-} +strings) are all treated as comments. + +@item +Some scheme expressions may be inserted in order to make configuration +changes before template processing begins. +@i{before template processing begins} means that there is no current +output file, no current suffix and, basically, none of the AutoGen +specific functions +(@pxref{AutoGen Functions}) may be invoked. + +The scheme expression can also be used, for example, to save a pre-existing +output file for later text extraction (@pxref{SCM extract}). + +@example +(shellf "mv -f %1$s.c %1$s.sav" (base-name)) +@end example +@end enumerate + +@noindent +After these must come the end macro marker: + +@enumerate 6 +@item +The punctuation characters used to demarcate the end of a macro. +Like the start marker, it must consist of seven or fewer punctuation +characters. +@end enumerate + +The ending macro marker has a few constraints on its content. Some of +them are just advisory, though. There is no special check for advisory +restrictions. + +@itemize @bullet +@item +It must not begin with a POSIX file name character (hyphen @code{-}, +underscore @code{_} or period @code{.}), the backslash (@code{\}) or +open parenthesis (@code{(}). These are used to identify a suffix +specification, indicate Scheme code and trim white space. + +@item +If it begins with an equal sign, then it +must be separated from any suffix specification by white space. + +@item +The closing marker may not begin with an open parenthesis, as that is used +to enclose a scheme expression. + +@item +It cannot begin with a backslash, as that is used to indicate white +space trimming after the end macro mark. If, in the body of the template, +you put the backslash character (@code{\}) before the end macro mark, then +any white space characters after the mark and through the newline character +are trimmed. + +@item +It is also helpful to avoid using the comment marker (@code{#}). +It might be seen as a comment within the pseudo macro. + +@item +You should avoid using any of the quote characters@: double, +single or back-quote. It won't confuse AutoGen, but it might well +confuse you and/or your editor. +@end itemize + +As an example, assume we want to use @code{[+} and @code{+]} as the start +and end macro markers, and we wish to produce a @file{.c} and a @file{.h} +file, then the pseudo macro might look something like this: + +@example +[+ AutoGen5 template -*- Mode: emacs-mode-of-choice -*- +h=chk-%s.h +c +# make sure we don't use csh: +(setenv "SHELL" "/bin/sh") +] +@end example + +The template proper starts after the pseudo-macro. The starting +character is either the first non-whitespace character or the first +character after the newline that follows the end macro marker. + +@c === SECTION MARKER + +@node naming values +@section Naming a value +@cindex naming values + +When an AutoGen value is specified in a template, it is specified by name. +The name may be a simple name, or a compound name of several components. +Since each named value in AutoGen is implicitly an array of one or more +values, each component may have an index associated with it. + +@noindent +It looks like this: + +@example +comp-name-1 . comp-name-2 [ 2 ] +@end example + +Note that if there are multiple components to a name, each component +name is separated by a dot (@code{.}). Indexes follow a component name, +enclosed in square brackets (@code{[} and @code{]}). The index may be +either an integer or an integer-valued define name. The first component +of the name is searched for in the current definition level. If not +found, higher levels will be searched until either a value is found, +or there are no more definition levels. Subsequent components of the +name must be found within the context of the newly-current definition +level. Also, if the named value is prefixed by a dot (@code{.}), +@cindex . +then the value search is started in the current context only. +Backtracking +@cindex backtrack +into other definition levels is prevented. + +If someone rewrites this, I'll incorporate it. :-) + +@c === SECTION MARKER + +@node expression syntax +@section Macro Expression Syntax +@cindex expression syntax + +AutoGen has two types of expressions: full expressions and basic ones. +A full AutoGen expression can appear by itself, or as the argument +to certain AutoGen built-in macros: CASE, IF, ELIF, INCLUDE, +INVOKE (explicit invocation, @pxref{INVOKE}), and WHILE. +If it appears by itself, the result is inserted into the output. +If it is an argument to one of these macros, the macro code +will act on it sensibly. + +You are constrained to basic expressions only when passing +arguments to user defined macros, @xref{DEFINE}. + +The syntax of a full AutoGen expression is: + +@example +[[ <apply-code> ] <value-name> ] [ <basic-expr-1> [ <basic-expr-2> ]] +@end example + +How the expression is evaluated depends upon the presence or absence +of the apply code and value name. The "value name" is the name of +an AutoGen defined value, or not. If it does not name such a value, +the expression result is generally the empty string. All expressions +must contain either a @var{value-name} or a @var{basic-expr}. + +@menu +* apply code:: Apply Code +* basic expression:: Basic Expression +@end menu + +@node apply code +@subsection Apply Code + +The "apply code" selected determines the method of evaluating the +expression. There are five apply codes, including the non-use +of an apply code. + +@table @samp +@item no apply code +This is the most common expression type. +Expressions of this sort come in three flavors: + +@table @samp +@item <value-name> +The result is the value of @var{value-name}, if defined. +Otherwise it is the empty string. + +@item <basic-expr> +The result of the basic expression is the result of the full expression, +@xref{basic expression}. + +@item <value-name> <basic-expr> +If there is a defined value for @var{value-name}, then the @var{basic-expr} +is evaluated. Otherwise, the result is the empty string. +@end table + +@item % <value-name> <basic-expr> +If @var{value-name} is defined, use @var{basic-expr} as a format +string for sprintf. Then, if the @var{basic-expr} is either a back-quoted +string or a parenthesized expression, then hand the result to the +appropriate interpreter for further evaluation. Otherwise, for single +and double quote strings, the result is the result of the sprintf operation. +Naturally, if @var{value-name} is not defined, the result is the empty +string. + +For example, assume that @samp{fumble} had the string value, @samp{stumble}: +@example +[+ % fumble `printf '%%x\\n' $%s` +] +@end example +This would cause the shell to evaluate "@samp{printf '%x\n' $stumble}". +Assuming that the shell variable @samp{stumble} had a numeric value, +the expression result would be that number, in hex. Note the need +for doubled percent characters and backslashes. + +@item ? <value-name> <basic-expr-1> <basic-expr-2> +Two @var{basic-expr}-s are required. If the @var{value-name} is +defined, then the first @var{basic-expr-1} is evaluated, otherwise +@var{basic-expr-2} is. + +@item - <value-name> <basic-expr> +Evaluate @var{basic-expr} only if @var{value-name} is @i{not} defined. + +@item ?% <value-name> <basic-expr-1> <basic-expr-2> +This combines the functions of @samp{?} and @samp{%}. If @var{value-name} is +defined, it behaves exactly like @samp{%}, above, using @var{basic-expr-1}. +If not defined, then @var{basic-expr-2} is evaluated. + +For example, assume again that @samp{fumble} had the string value, +@samp{stumble}: +@example +[+ ?% fumble `cat $%s` `pwd` +] +@end example +This would cause the shell to evaluate "@samp{cat $stumble}". +If @samp{fumble} were not defined, then the result would be the name +of our current directory. +@end table + +@node basic expression +@subsection Basic Expression + +A basic expression can have one of the following forms: + +@table @samp +@item 'STRING' +A single quoted string. Backslashes can be used to protect single +quotes (@code{'}), hash characters (@code{#}), or backslashes (@code{\}) +in the string. All other characters of STRING are output as-is when the +single quoted string is evaluated. Backslashes are processed before the hash +character for consistency with the definition syntax. It is needed there +to avoid preprocessing conflicts. + +@item "STRING" +A double quoted string. This is a cooked text string as in C, +except that they are not concatenated with adjacent strings. +Evaluating "@samp{STRING}" will output STRING with all +backslash sequences interpreted. + +@item `STRING` +A back quoted string. When this expression is evaluated, STRING +is first interpreted as a cooked string (as in `"STRING"') and +evaluated as a shell expression by the AutoGen server shell. This +expression is replaced by the @file{stdout} output of +the shell. + +@item (STRING) +A parenthesized expression. It will be passed to the Guile +interpreter for evaluation and replaced by the resulting value. +If there is a Scheme error in this expression, Guile 1.4 and Guile 1.6 +will report the template line number where the error occurs. Guile 1.7 +has lost this capability. + +Guile has the capability of creating and manipulating variables that +can be referenced later on in the template processing. If you define +such a variable, it is invisible to AutoGen. To reference its value, +you must use a Guile expression. For example, +@example +[+ (define my-var "some-string-value") +] +@end example +can have that string inserted later, but only as in: +@example +[+ (. my-var) +] +@end example + +Additionally, other than in the @code{%} and @code{?%} expressions, the +Guile expressions may be introduced with the Guile comment character +(@code{;}) and you may put a series of Guile expressions within a single +macro. They will be implicitly evaluated as if they were arguments +to the @code{(begin ...)} expression. The result will be the +result of the last Guile expression evaluated. +@end table + +@ignore +END == TEMPLATE == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore +@ignore + +* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +@end ignore +@page +@node AutoGen Functions +@section AutoGen Scheme Functions + +AutoGen uses Guile to interpret Scheme expressions within AutoGen +macros. All of the normal Guile functions are available, plus several +extensions (@pxref{Common Functions}) have been added to +augment the repertoire of string manipulation functions and +manage the state of AutoGen processing. + +This section describes those functions that are specific to AutoGen. +Please take note that these AutoGen specific functions are not loaded +and thus not made available until after the command line options have +been processed and the AutoGen definitions have been loaded. They may, +of course, be used in Scheme functions that get defined at those times, +but they cannot be invoked. + +@menu +* SCM ag-fprintf:: @file{ag-fprintf} - format to autogen stream +* SCM ag-function?:: @file{ag-function?} - test for function +* SCM base-name:: @file{base-name} - base output name +* SCM chdir:: @file{chdir} - Change current directory +* SCM count:: @file{count} - definition count +* SCM def-file:: @file{def-file} - definitions file name +* SCM def-file-line:: @file{def-file-line} - get a definition file+line number +* SCM dne:: @file{dne} - "Do Not Edit" warning +* SCM emit:: @file{emit} - emit the text for each argument +* SCM emit-string-table:: @file{emit-string-table} - output a string table +* SCM error:: @file{error} - display message and exit +* SCM exist?:: @file{exist?} - test for value name +* SCM find-file:: @file{find-file} - locate a file in the search path +* SCM first-for?:: @file{first-for?} - detect first iteration +* SCM for-by:: @file{for-by} - set iteration step +* SCM for-from:: @file{for-from} - set initial index +* SCM for-index:: @file{for-index} - get current loop index +* SCM for-sep:: @file{for-sep} - set loop separation string +* SCM for-to:: @file{for-to} - set ending index +* SCM found-for?:: @file{found-for?} - is current index in list? +* SCM get:: @file{get} - get named value +* SCM get-c-name:: @file{get-c-name} - get named value, mapped to C name syntax +* SCM get-down-name:: @file{get-down-name} - get lower cased named value, mapped to C name syntax +* SCM get-up-name:: @file{get-up-name} - get upper cased named value, mapped to C name syntax +* SCM high-lim:: @file{high-lim} - get highest value index +* SCM insert-file:: @file{insert-file} - insert the contents of a (list of) files. +* SCM insert-suspended:: @file{insert-suspended} - insert a named suspension in current output +* SCM last-for?:: @file{last-for?} - detect last iteration +* SCM len:: @file{len} - get count of values +* SCM low-lim:: @file{low-lim} - get lowest value index +* SCM make-header-guard:: @file{make-header-guard} - make self-inclusion guard +* SCM make-tmp-dir:: @file{make-tmp-dir} - create a temporary directory +* SCM match-value?:: @file{match-value?} - test for matching value +* SCM max-file-time:: @file{max-file-time} - get the maximum input file modification time +* SCM mk-gettextable:: @file{mk-gettextable} - print a string in a gettext-able format +* SCM out-delete:: @file{out-delete} - delete current output file +* SCM out-depth:: @file{out-depth} - output file stack depth +* SCM out-emit-suspended:: @file{out-emit-suspended} - emit the text of suspended output +* SCM out-line:: @file{out-line} - output file line number +* SCM out-move:: @file{out-move} - change name of output file +* SCM out-name:: @file{out-name} - current output file name +* SCM out-pop:: @file{out-pop} - close current output file +* SCM out-push-add:: @file{out-push-add} - append output to file +* SCM out-push-new:: @file{out-push-new} - purge and create output file +* SCM out-resume:: @file{out-resume} - resume suspended output file +* SCM out-suspend:: @file{out-suspend} - suspend current output file +* SCM out-switch:: @file{out-switch} - close and create new output +* SCM output-file-next-line:: @file{output-file-next-line} - print the file name and next line number +* SCM set-option:: @file{set-option} - Set a command line option +* SCM set-writable:: @file{set-writable} - Make the output file be writable +* SCM stack:: @file{stack} - make list of AutoGen values +* SCM stack-join:: @file{stack-join} - stack values then join them +* SCM suffix:: @file{suffix} - get the current suffix +* SCM tpl-file:: @file{tpl-file} - get the template file name +* SCM tpl-file-line:: @file{tpl-file-line} - get the template file+line number +* SCM tpl-file-next-line:: @file{tpl-file-next-line} - get the template file plus next line number +* SCM warn:: @file{warn} - display warning message and continue +* SCM autogen-version:: @file{autogen-version} - ``5.18.16'' +* SCM c-file-line-fmt:: format file info as, ``@code{#line nn "file"}'' +@end menu + + +@node SCM ag-fprintf +@subsection @file{ag-fprintf} - format to autogen stream +@findex ag-fprintf + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expOutput.c line 454. +@end ignore + +Usage: (ag-fprintf ag-diversion format [ format-arg ... ]) +@* +Format a string using arguments from the alist. +Write to a specified AutoGen diversion. +That may be either a specified suspended output stream +(@pxref{SCM out-suspend}) or an index into the output stack +(@pxref{SCM out-push-new}). @code{(ag-fprintf 0 ...)} is +equivalent to @code{(emit (sprintf ...))}, and +@code{(ag-fprintf 1 ...)} sends output to the most recently +suspended output stream. + +Arguments: +@* +ag-diversion - AutoGen diversion name or number +@* +format - formatting string +@* +format-arg - Optional - list of arguments to formatting string + +@node SCM ag-function? +@subsection @file{ag-function?} - test for function +@findex ag-function? + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expState.c line 360. +@end ignore + +Usage: (ag-function? ag-name) +@* +return SCM_BOOL_T if a specified name is a user-defined AutoGen +macro, otherwise return SCM_BOOL_F. + +Arguments: +@* +ag-name - name of AutoGen macro + +@node SCM base-name +@subsection @file{base-name} - base output name +@findex base-name + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expState.c line 197. +@end ignore + +Usage: (base-name) +@* +Returns a string containing the base name of the output file(s). +Generally, this is also the base name of the definitions file. + +This Scheme function takes no arguments. + +@node SCM chdir +@subsection @file{chdir} - Change current directory +@findex chdir + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/agShell.c line 29. +@end ignore + +Usage: (chdir dir) +@* +Sets the current directory for AutoGen. Shell commands will run +from this directory as well. This is a wrapper around the Guile +native function. It returns its directory name argument and +fails the program on failure. + +Arguments: +@* +dir - new directory name + +@node SCM count +@subsection @file{count} - definition count +@findex count + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expState.c line 292. +@end ignore + +Usage: (count ag-name) +@* +Count the number of entries for a definition. +The input argument must be a string containing the name +of the AutoGen values to be counted. If there is no +value associated with the name, the result is an SCM +immediate integer value of zero. + +Arguments: +@* +ag-name - name of AutoGen value + +@node SCM def-file +@subsection @file{def-file} - definitions file name +@findex def-file + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expState.c line 312. +@end ignore + +Usage: (def-file) +@* +Get the name of the definitions file. +Returns the name of the source file containing the AutoGen +definitions. + +This Scheme function takes no arguments. + +@node SCM def-file-line +@subsection @file{def-file-line} - get a definition file+line number +@findex def-file-line + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expState.c line 749. +@end ignore + +Usage: (def-file-line ag-name [ msg-fmt ]) +@* +Returns the file and line number of a AutoGen defined value, using +either the default format, "from %s line %d", or else the format you +supply. For example, if you want to insert a "C" language file-line +directive, you would supply the format "# %2$d \"%1$s\"", but that +is also already supplied with the scheme variable +@xref{SCM c-file-line-fmt}. You may use it thus: + +@example +(def-file-line "ag-def-name" c-file-line-fmt) +@end example + +It is also safe to use the formatting string, "%2$d". AutoGen uses +an argument vector version of printf: @xref{snprintfv}. + +Arguments: +@* +ag-name - name of AutoGen value +@* +msg-fmt - Optional - formatting for line message + +@node SCM dne +@subsection @file{dne} - "Do Not Edit" warning +@findex dne + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expFormat.c line 86. +@end ignore + +Usage: (dne prefix [ first_prefix ] [ optpfx ]) +@* +Generate a "DO NOT EDIT" or "EDIT WITH CARE" warning string. +Which depends on whether or not the @code{--writable} command line +option was set. + +The first argument may be an option: @samp{-D} or @samp{-d}, causing the +second and (potentially) third arguments to be interpreted as the first +and second arguments. The only useful option is @samp{-D}: + +@table @samp +@item -D +will add date, timestamp and version information. +@item -d +is ignored, but still accepted for compatibility with older versions +of the "dne" function where emitting the date was the default. +@end table + +If one of these options is specified, then the "prefix" and "first" +arguments are obtained from the following arguments. The presence (or +absence) of this option can be overridden with the environment variable, +@samp{AUTOGEN_DNE_DATE}. The date is disabled if the value is empty or +starts with one of the characters, @samp{0nNfF} -- zero or the first +letter of "no" or "false". + +The @code{prefix} argument is a per-line string prefix. The optional +second argument is a prefix for the first line only and, in read-only +mode, activates editor hints. + +@example +-*- buffer-read-only: t -*- vi: set ro: +@end example + +@noindent +The warning string also includes information about the template used +to construct the file and the definitions used in its instantiation. + +Arguments: +@* +prefix - string for starting each output line +@* +first_prefix - Optional - for the first output line +@* +optpfx - Optional - shifted prefix + +@node SCM emit +@subsection @file{emit} - emit the text for each argument +@findex emit + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcEval.c line 337. +@end ignore + +Usage: (emit alist ...) +@* +Walk the tree of arguments, displaying the values of displayable +SCM types. EXCEPTION: if the first argument is a number, then +that number is used to index the output stack. "0" is the default, +the current output. + +Arguments: +@* +alist - list of arguments to stringify and emit + +@node SCM emit-string-table +@subsection @file{emit-string-table} - output a string table +@findex emit-string-table + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/schemedef.scm line 294. +@end ignore + +Usage: (emit-string-table st-name) +@* +Emit into the current output stream a +@code{static char const} array named @code{st-name} +that will have @code{NUL} bytes between each inserted string. + +Arguments: +@* +st-name - the name of the array of characters + +@node SCM error +@subsection @file{error} - display message and exit +@findex error + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expFormat.c line 279. +@end ignore + +Usage: (error message) +@* +The argument is a string that printed out as part of an error +message. The message is formed from the formatting string: + +@example +DEFINITIONS ERROR in %s line %d for %s: %s\n +@end example + +The first three arguments to this format are provided by the +routine and are: The name of the template file, the line within +the template where the error was found, and the current output +file name. + +After displaying the message, the current output file is removed +and autogen exits with the EXIT_FAILURE error code. IF, however, +the argument begins with the number 0 (zero), or the string is the +empty string, then processing continues with the next suffix. + +Arguments: +@* +message - message to display before exiting + +@node SCM exist? +@subsection @file{exist?} - test for value name +@findex exist? + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expState.c line 326. +@end ignore + +Usage: (exist? ag-name) +@* +return SCM_BOOL_T iff a specified name has an AutoGen value. +The name may include indexes and/or member names. +All but the last member name must be an aggregate definition. +For example: +@example +(exist? "foo[3].bar.baz") +@end example +will yield true if all of the following is true: +@* +There is a member value of either group or string type +named @code{baz} for some group value @code{bar} that +is a member of the @code{foo} group with index @code{3}. +There may be multiple entries of @code{bar} within +@code{foo}, only one needs to contain a value for @code{baz}. + +Arguments: +@* +ag-name - name of AutoGen value + +@node SCM find-file +@subsection @file{find-file} - locate a file in the search path +@findex find-file + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expExtract.c line 318. +@end ignore + +Usage: (find-file file-name [ suffix ]) +@* +AutoGen has a search path that it uses to locate template and definition +files. This function will search the same list for @file{file-name}, both +with and without the @file{.suffix}, if provided. + +Arguments: +@* +file-name - name of file with text +@* +suffix - Optional - file suffix to try, too + +@node SCM first-for? +@subsection @file{first-for?} - detect first iteration +@findex first-for? + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcFor.c line 64. +@end ignore + +Usage: (first-for? [ for_var ]) +@* +Returns @code{SCM_BOOL_T} if the named FOR loop (or, if not named, the +current innermost loop) is on the first pass through the data. Outside +of any @code{FOR} loop, it returns @code{SCM_UNDEFINED}, @pxref{FOR}. + +Arguments: +@* +for_var - Optional - which for loop + +@node SCM for-by +@subsection @file{for-by} - set iteration step +@findex for-by + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcFor.c line 191. +@end ignore + +Usage: (for-by by) +@* +This function records the "step by" information +for an AutoGen FOR function. +Outside of the FOR macro itself, this function will emit an error. +@xref{FOR}. + +Arguments: +@* +by - the iteration increment for the AutoGen FOR macro + +@node SCM for-from +@subsection @file{for-from} - set initial index +@findex for-from + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcFor.c line 149. +@end ignore + +Usage: (for-from from) +@* +This function records the initial index information +for an AutoGen FOR function. +Outside of the FOR macro itself, this function will emit an error. +@xref{FOR}. + +Arguments: +@* +from - the initial index for the AutoGen FOR macro + +@node SCM for-index +@subsection @file{for-index} - get current loop index +@findex for-index + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcFor.c line 128. +@end ignore + +Usage: (for-index [ for_var ]) +@* +Returns the current index for the named @code{FOR} loop. +If not named, then the index for the innermost loop. +Outside of any FOR loop, it returns @code{SCM_UNDEFINED}, @xref{FOR}. + +Arguments: +@* +for_var - Optional - which for loop + +@node SCM for-sep +@subsection @file{for-sep} - set loop separation string +@findex for-sep + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcFor.c line 211. +@end ignore + +Usage: (for-sep separator) +@* +This function records the separation string that is to be inserted +between each iteration of an AutoGen FOR function. This is often +nothing more than a comma. +Outside of the FOR macro itself, this function will emit an error. + +Arguments: +@* +separator - the text to insert between the output of +each FOR iteration + +@node SCM for-to +@subsection @file{for-to} - set ending index +@findex for-to + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcFor.c line 170. +@end ignore + +Usage: (for-to to) +@* +This function records the terminating value information +for an AutoGen FOR function. +Outside of the FOR macro itself, this function will emit an error. +@xref{FOR}. + +Arguments: +@* +to - the final index for the AutoGen FOR macro + +@node SCM found-for? +@subsection @file{found-for?} - is current index in list? +@findex found-for? + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcFor.c line 108. +@end ignore + +Usage: (found-for? [ for_var ]) +@* +Returns SCM_BOOL_T if the currently indexed value is present, +otherwise SCM_BOOL_F. Outside of any FOR loop, it returns +SCM_UNDEFINED. @xref{FOR}. + +Arguments: +@* +for_var - Optional - which for loop + +@node SCM get +@subsection @file{get} - get named value +@findex get + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expState.c line 413. +@end ignore + +Usage: (get ag-name [ alt-val ]) +@* +Get the first string value associated with the name. +It will either return the associated string value (if +the name resolves), the alternate value (if one is provided), +or else the empty string. + +Arguments: +@* +ag-name - name of AutoGen value +@* +alt-val - Optional - value if not present + +@node SCM get-c-name +@subsection @file{get-c-name} - get named value, mapped to C name syntax +@findex get-c-name + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expState.c line 450. +@end ignore + +Usage: (get-c-name ag-name) +@* +Get the first string value associated with the name. It will either +return the associated string value (if the name resolves), the alternate +value (if one is provided), or else the empty string. The result is +passed through "string->c-name!". + +Arguments: +@* +ag-name - name of AutoGen value + +@node SCM get-down-name +@subsection @file{get-down-name} - get lower cased named value, mapped to C name syntax +@findex get-down-name + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expState.c line 488. +@end ignore + +Usage: (get-down-name ag-name) +@* +Get the first string value associated with the name. It will either +return the associated string value (if the name resolves), the alternate +value (if one is provided), or else the empty string. The result is +passed through "string->c-name!" and "string->down-case!". + +Arguments: +@* +ag-name - name of AutoGen value + +@node SCM get-up-name +@subsection @file{get-up-name} - get upper cased named value, mapped to C name syntax +@findex get-up-name + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expState.c line 469. +@end ignore + +Usage: (get-up-name ag-name) +@* +Get the first string value associated with the name. It will either +return the associated string value (if the name resolves), the alternate +value (if one is provided), or else the empty string. The result is +passed through "string->c-name!" and "string->up-case!". + +Arguments: +@* +ag-name - name of AutoGen value + +@node SCM high-lim +@subsection @file{high-lim} - get highest value index +@findex high-lim + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expState.c line 507. +@end ignore + +Usage: (high-lim ag-name) +@* +Returns the highest index associated with an array of definitions. +This is generally, but not necessarily, one less than the +@code{count} value. (The indexes may be specified, rendering a +non-zero based or sparse array of values.) + +This is very useful for specifying the size of a zero-based array +of values where not all values are present. For example: + +@example +tMyStruct myVals[ [+ (+ 1 (high-lim "my-val-list")) +] ]; +@end example + +Arguments: +@* +ag-name - name of AutoGen value + +@node SCM insert-file +@subsection @file{insert-file} - insert the contents of a (list of) files. +@findex insert-file + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcEval.c line 439. +@end ignore + +Usage: (insert-file alist ...) +@* +Insert the contents of one or more files. + +Arguments: +@* +alist - list of files to emit + +@node SCM insert-suspended +@subsection @file{insert-suspended} - insert a named suspension in current output +@findex insert-suspended + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/schemedef.scm line 133. +@end ignore + +Usage: (insert-suspended susp-name) +@* +Emit into the current output the output suspended under a +given diversion name. + +Arguments: +@* +susp-name - the name of the suspended output + +@node SCM last-for? +@subsection @file{last-for?} - detect last iteration +@findex last-for? + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcFor.c line 88. +@end ignore + +Usage: (last-for? [ for_var ]) +@* +Returns SCM_BOOL_T if the named FOR loop (or, if not named, the +current innermost loop) is on the last pass through the data. +Outside of any FOR loop, it returns SCM_UNDEFINED. +@xref{FOR}. + +Arguments: +@* +for_var - Optional - which for loop + +@node SCM len +@subsection @file{len} - get count of values +@findex len + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expState.c line 552. +@end ignore + +Usage: (len ag-name) +@* +If the named object is a group definition, then "len" is +the same as "count". Otherwise, if it is one or more text +definitions, then it is the sum of their string lengths. +If it is a single text definition, then it is equivalent to +@code{(string-length (get "ag-name"))}. + +Arguments: +@* +ag-name - name of AutoGen value + +@node SCM low-lim +@subsection @file{low-lim} - get lowest value index +@findex low-lim + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expState.c line 572. +@end ignore + +Usage: (low-lim ag-name) +@* +Returns the lowest index associated with an array of definitions. + +Arguments: +@* +ag-name - name of AutoGen value + +@node SCM make-header-guard +@subsection @file{make-header-guard} - make self-inclusion guard +@findex make-header-guard + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expOutput.c line 801. +@end ignore + +Usage: (make-header-guard name) +@* +This function will create a @code{#ifndef}/@code{#define} +sequence for protecting a header from multiple evaluation. +It will also set the Scheme variable @code{header-file} +to the name of the file being protected and it will set +@code{header-guard} to the name of the @code{#define} being +used to protect it. It is expected that this will be used +as follows: +@example +[+ (make-header-guard "group_name") +] +... +#endif /* [+ (. header-guard) +] */ + +#include "[+ (. header-file) +]" +@end example +@noindent +The @code{#define} name is composed as follows: + +@enumerate +@item +The first element is the string argument and a separating underscore. +@item +That is followed by the name of the header file with illegal +characters mapped to underscores. +@item +The end of the name is always, "@code{_GUARD}". +@item +Finally, the entire string is mapped to upper case. +@end enumerate + +The final @code{#define} name is stored in an SCM symbol named +@code{header-guard}. Consequently, the concluding @code{#endif} for the +file should read something like: + +@example +#endif /* [+ (. header-guard) +] */ +@end example + +The name of the header file (the current output file) is also stored +in an SCM symbol, @code{header-file}. Therefore, if you are also +generating a C file that uses the previously generated header file, +you can put this into that generated file: + +@example +#include "[+ (. header-file) +]" +@end example + +Obviously, if you are going to produce more than one header file from +a particular template, you will need to be careful how these SCM symbols +get handled. + +Arguments: +@* +name - header group name + +@node SCM make-tmp-dir +@subsection @file{make-tmp-dir} - create a temporary directory +@findex make-tmp-dir + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expOutput.c line 561. +@end ignore + +Usage: (make-tmp-dir) +@* +Create a directory that will be cleaned up upon exit. + +This Scheme function takes no arguments. + +@node SCM match-value? +@subsection @file{match-value?} - test for matching value +@findex match-value? + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expState.c line 381. +@end ignore + +Usage: (match-value? op ag-name test-str) +@* +This function answers the question, "Is there an AutoGen value named +@code{ag-name} with a value that matches the pattern @code{test-str} +using the match function @code{op}?" Return SCM_BOOL_T iff at least +one occurrence of the specified name has such a value. The operator +can be any function that takes two string arguments and yields a +boolean. It is expected that you will use one of the string matching +functions provided by AutoGen. +@* +The value name must follow the same rules as the +@code{ag-name} argument for @code{exist?} (@pxref{SCM exist?}). + +Arguments: +@* +op - boolean result operator +@* +ag-name - name of AutoGen value +@* +test-str - string to test against + +@node SCM max-file-time +@subsection @file{max-file-time} - get the maximum input file modification time +@findex max-file-time + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expState.c line 730. +@end ignore + +Usage: (max-file-time) +@* +returns the time stamp of the most recently modified sourc file as the +number of seconds since the epoch. If any input is dynamic +(a shell command), then it will be the current time. + +This Scheme function takes no arguments. + +@node SCM mk-gettextable +@subsection @file{mk-gettextable} - print a string in a gettext-able format +@findex mk-gettextable + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expString.c line 249. +@end ignore + +Usage: (mk-gettextable string) +@* +Returns SCM_UNDEFINED. The input text string is printed +to the current output as one puts() call per paragraph. + +Arguments: +@* +string - a multi-paragraph string + +@node SCM out-delete +@subsection @file{out-delete} - delete current output file +@findex out-delete + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expOutput.c line 201. +@end ignore + +Usage: (out-delete) +@* +Remove the current output file. Cease processing the template for +the current suffix. It is an error if there are @code{push}-ed +output files. Use the @code{(error "0")} scheme function instead. +@xref{output controls}. + +This Scheme function takes no arguments. + +@node SCM out-depth +@subsection @file{out-depth} - output file stack depth +@findex out-depth + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expOutput.c line 736. +@end ignore + +Usage: (out-depth) +@* +Returns the depth of the output file stack. +@xref{output controls}. + +This Scheme function takes no arguments. + +@node SCM out-emit-suspended +@subsection @file{out-emit-suspended} - emit the text of suspended output +@findex out-emit-suspended + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expOutput.c line 438. +@end ignore + +Usage: (out-emit-suspended susp_nm) +@* +This function is equivalent to +@code{(begin (out-resume <name>) (out-pop #t))} + +Arguments: +@* +susp_nm - A name tag of suspended output + +@node SCM out-line +@subsection @file{out-line} - output file line number +@findex out-line + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expOutput.c line 766. +@end ignore + +Usage: (out-line) +@* +Returns the current line number of the output file. +It rewinds and reads the file to count newlines. + +This Scheme function takes no arguments. + +@node SCM out-move +@subsection @file{out-move} - change name of output file +@findex out-move + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expOutput.c line 226. +@end ignore + +Usage: (out-move new-name) +@* +Rename current output file. @xref{output controls}. +Please note: changing the name will not save a temporary file from +being deleted. It @i{may}, however, be used on the root output file. + +Arguments: +@* +new-name - new name for the current output file + +@node SCM out-name +@subsection @file{out-name} - current output file name +@findex out-name + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expOutput.c line 749. +@end ignore + +Usage: (out-name) +@* +Returns the name of the current output file. If the current file +is a temporary, unnamed file, then it will scan up the chain until +a real output file name is found. +@xref{output controls}. + +This Scheme function takes no arguments. + +@node SCM out-pop +@subsection @file{out-pop} - close current output file +@findex out-pop + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expOutput.c line 273. +@end ignore + +Usage: (out-pop [ disp ]) +@* +If there has been a @code{push} on the output, then close that +file and go back to the previously open file. It is an error +if there has not been a @code{push}. @xref{output controls}. + +If there is no argument, no further action is taken. Otherwise, +the argument should be @code{#t} and the contents of the file +are returned by the function. + +Arguments: +@* +disp - Optional - return contents of the file + +@node SCM out-push-add +@subsection @file{out-push-add} - append output to file +@findex out-push-add + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expOutput.c line 537. +@end ignore + +Usage: (out-push-add file-name) +@* +Identical to @code{push-new}, except the contents are @strong{not} +purged, but appended to. @xref{output controls}. + +Arguments: +@* +file-name - name of the file to append text to + +@node SCM out-push-new +@subsection @file{out-push-new} - purge and create output file +@findex out-push-new + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expOutput.c line 592. +@end ignore + +Usage: (out-push-new [ file-name ]) +@* +Leave the current output file open, but purge and create +a new file that will remain open until a @code{pop} @code{delete} +or @code{switch} closes it. The file name is optional and, if omitted, +the output will be sent to a temporary file that will be deleted when +it is closed. +@xref{output controls}. + +Arguments: +@* +file-name - Optional - name of the file to create + +@node SCM out-resume +@subsection @file{out-resume} - resume suspended output file +@findex out-resume + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expOutput.c line 402. +@end ignore + +Usage: (out-resume susp_nm) +@* +If there has been a suspended output, then make that output descriptor +current again. That output must have been suspended with the same tag +name given to this routine as its argument. + +Arguments: +@* +susp_nm - A name tag for reactivating + +@node SCM out-suspend +@subsection @file{out-suspend} - suspend current output file +@findex out-suspend + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expOutput.c line 359. +@end ignore + +Usage: (out-suspend suspName) +@* +If there has been a @code{push} on the output, then set aside the output +descriptor for later reactiviation with @code{(out-resume "xxx")}. The +tag name need not reflect the name of the output file. In fact, the +output file may be an anonymous temporary file. You may also change the +tag every time you suspend output to a file, because the tag names are +forgotten as soon as the file has been "resumed". + +Arguments: +@* +suspName - A name tag for reactivating + +@node SCM out-switch +@subsection @file{out-switch} - close and create new output +@findex out-switch + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expOutput.c line 676. +@end ignore + +Usage: (out-switch file-name) +@* +Switch output files - close current file and make the current +file pointer refer to the new file. This is equivalent to +@code{out-pop} followed by @code{out-push-new}, except that +you may not pop the base level output file, but you may +@code{switch} it. @xref{output controls}. + +Arguments: +@* +file-name - name of the file to create + +@node SCM output-file-next-line +@subsection @file{output-file-next-line} - print the file name and next line number +@findex output-file-next-line + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expOutput.c line 321. +@end ignore + +Usage: (output-file-next-line [ line_off ] [ alt_fmt ]) +@* +Returns a string with the current output file name and line number. +The default format is: # <line+1> "<output-file-name>" The argument may be +either a number indicating an offset from the current output line number +or an alternate formatting string. If both are provided, then the first +must be a numeric offset. + +Be careful that you are directing output to the final output file. +Otherwise, you will get the file name and line number of the temporary +file. That won't be what you want. + +Arguments: +@* +line_off - Optional - offset to line number +@* +alt_fmt - Optional - alternate format string + +@node SCM set-option +@subsection @file{set-option} - Set a command line option +@findex set-option + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expState.c line 599. +@end ignore + +Usage: (set-option opt) +@* +The text argument must be an option name followed by any needed +option argument. Returns SCM_UNDEFINED. + +Arguments: +@* +opt - AutoGen option name + its argument + +@node SCM set-writable +@subsection @file{set-writable} - Make the output file be writable +@findex set-writable + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcIf.c line 469. +@end ignore + +Usage: (set-writable [ set? ]) +@* +This function will set the current output file to be writable +(or not). This is only effective if neither the @code{--writable} +nor @code{--not-writable} have been specified. This state +is reset when the current suffix's output is complete. + +Arguments: +@* +set? - Optional - boolean arg, false to make output non-writable + +@node SCM stack +@subsection @file{stack} - make list of AutoGen values +@findex stack + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expString.c line 707. +@end ignore + +Usage: (stack ag-name) +@* +Create a scheme list of all the strings that are associated +with a name. They must all be text values or we choke. + +Arguments: +@* +ag-name - AutoGen value name + +@node SCM stack-join +@subsection @file{stack-join} - stack values then join them +@findex stack-join + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/schemedef.scm line 387. +@end ignore + +Usage: (stack-join join ag-name) +@* +This function will collect all the values named @code{ag-name} +(see the @pxref{SCM stack, stack function}) and join them +separated by the @code{join} string (see the +@pxref{SCM join, join function}). + +Arguments: +@* +join - string between each element +@* +ag-name - name of autogen values to stack + +@node SCM suffix +@subsection @file{suffix} - get the current suffix +@findex suffix + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expState.c line 615. +@end ignore + +Usage: (suffix) +@* +Returns the current active suffix (@pxref{pseudo macro}). + +This Scheme function takes no arguments. + +@node SCM tpl-file +@subsection @file{tpl-file} - get the template file name +@findex tpl-file + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expState.c line 628. +@end ignore + +Usage: (tpl-file [ full_path ]) +@* +Returns the name of the current template file. +If @code{#t} is passed in as an argument, then the template +file is hunted for in the template search path. Otherwise, +just the unadorned name. + +Arguments: +@* +full_path - Optional - include full path to file + +@node SCM tpl-file-line +@subsection @file{tpl-file-line} - get the template file+line number +@findex tpl-file-line + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expState.c line 677. +@end ignore + +Usage: (tpl-file-line [ msg-fmt ]) +@* +Returns the file and line number of the current template macro using +either the default format, "from %s line %d", or else the format you +supply. For example, if you want to insert a "C" language file-line +directive, you would supply the format "# %2$d \"%1$s\"", but that +is also already supplied with the scheme variable +@xref{SCM c-file-line-fmt}. You may use it thus: +@example +(tpl-file-line c-file-line-fmt) +@end example + +It is also safe to use the formatting string, "%2$d". AutoGen uses +an argument vector version of printf: @xref{snprintfv}, +and it does not need to know the types of each argument in order to +skip forward to the second argument. + +Arguments: +@* +msg-fmt - Optional - formatting for line message + +@node SCM tpl-file-next-line +@subsection @file{tpl-file-next-line} - get the template file plus next line number +@findex tpl-file-next-line + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expState.c line 709. +@end ignore + +Usage: (tpl-file-next-line [ msg-fmt ]) +@* +This is almost the same as @xref{SCM tpl-file-line}, except that +the line referenced is the next line, per C compiler conventions, and +consequently defaults to the format: # <line-no+1> "<file-name>" + +Arguments: +@* +msg-fmt - Optional - formatting for line message + +@node SCM warn +@subsection @file{warn} - display warning message and continue +@findex warn + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expFormat.c line 252. +@end ignore + +Usage: (warn message) +@* +The argument is a string that printed out to stderr. +The message is formed from the formatting string: + +@example +@code{WARNING:} %s\n +@end example + +The template processing resumes after printing the message. + +Arguments: +@* +message - message to display + +@ignore +Generated from auto_gen.tpl line 291. +@end ignore + +@node SCM autogen-version +@subsection @file{autogen-version} - autogen version number +@findex autogen-version + +This is a symbol defining the current AutoGen version number string. +It was first defined in AutoGen-5.2.14. +It is currently ``5.18.16''. + +@node SCM c-file-line-fmt +@subsection format file info as, ``@code{#line nn "file"}'' +@findex c-file-line-fmt + +This is a symbol that can easily be used with the functions +@xref{SCM tpl-file-line}, and @xref{SCM def-file-line}. +These will emit C program @code{#line} directives pointing to template +and definitions text, respectively. +@ignore + +* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +@end ignore +@page +@node Common Functions +@section Common Scheme Functions + +This section describes a number of general purpose functions that make +the kind of string processing that AutoGen does a little easier. +Unlike the AutoGen specific functions (@pxref{AutoGen Functions}), +these functions are available for direct use during definition load time. +The equality test (@pxref{SCM =}) is ``overloaded'' to do string equivalence +comparisons. If you are looking for inequality, the Scheme/Lisp way +of spelling that is, ``(not (= ...))''. + +@menu +* SCM agpl:: @file{agpl} - GNU Affero General Public License +* SCM bsd:: @file{bsd} - BSD Public License +* SCM c-string:: @file{c-string} - emit string for ANSI C +* SCM error-source-line:: @file{error-source-line} - display of file & line +* SCM extract:: @file{extract} - extract text from another file +* SCM format-arg-count:: @file{format-arg-count} - count the args to a format +* SCM fprintf:: @file{fprintf} - format to a file +* SCM gperf:: @file{gperf} - perform a perfect hash function +* SCM gperf-code:: @file{gperf-code} - emit the source of the generated gperf program +* SCM gpl:: @file{gpl} - GNU General Public License +* SCM hide-email:: @file{hide-email} - convert eaddr to javascript +* SCM html-escape-encode:: @file{html-escape-encode} - encode html special characters +* SCM in?:: @file{in?} - test for string in list +* SCM join:: @file{join} - join string list with separator +* SCM kr-string:: @file{kr-string} - emit string for K&R C +* SCM lgpl:: @file{lgpl} - GNU Library General Public License +* SCM license:: @file{license} - an arbitrary license +* SCM license-description:: @file{license-description} - Emit a license description +* SCM license-full:: @file{license-full} - Emit the licensing information and description +* SCM license-info:: @file{license-info} - Emit the licensing information and copyright years +* SCM license-name:: @file{license-name} - Emit the name of the license +* SCM make-gperf:: @file{make-gperf} - build a perfect hash function program +* SCM makefile-script:: @file{makefile-script} - create makefile script +* SCM max:: @file{max} - maximum value in list +* SCM min:: @file{min} - minimum value in list +* SCM prefix:: @file{prefix} - prefix lines with a string +* SCM printf:: @file{printf} - format to stdout +* SCM raw-shell-str:: @file{raw-shell-str} - single quote shell string +* SCM shell:: @file{shell} - invoke a shell script +* SCM shell-str:: @file{shell-str} - double quote shell string +* SCM shellf:: @file{shellf} - format a string, run shell +* SCM sprintf:: @file{sprintf} - format a string +* SCM string-capitalize:: @file{string-capitalize} - capitalize a new string +* SCM string-capitalize!:: @file{string-capitalize!} - capitalize a string +* SCM *=*:: @file{string-contains-eqv?} - caseless substring +* SCM *==*:: @file{string-contains?} - substring match +* SCM string-downcase:: @file{string-downcase} - lower case a new string +* SCM string-downcase!:: @file{string-downcase!} - make a string be lower case +* SCM *~:: @file{string-end-eqv-match?} - caseless regex ending +* SCM *~~:: @file{string-end-match?} - regex match end +* SCM *=:: @file{string-ends-eqv?} - caseless string ending +* SCM *==:: @file{string-ends-with?} - string ending +* SCM ==:: @file{string-equals?} - string matching +* SCM ~:: @file{string-eqv-match?} - caseless regex match +* SCM =:: @file{string-eqv?} - caseless match +* SCM *~*:: @file{string-has-eqv-match?} - caseless regex contains +* SCM *~~*:: @file{string-has-match?} - contained regex match +* SCM ~~:: @file{string-match?} - regex match +* SCM ~*:: @file{string-start-eqv-match?} - caseless regex start +* SCM ~~*:: @file{string-start-match?} - regex match start +* SCM =*:: @file{string-starts-eqv?} - caseless string start +* SCM ==*:: @file{string-starts-with?} - string starting +* SCM string-substitute:: @file{string-substitute} - multiple global replacements +* SCM string-table-add:: @file{string-table-add} - Add an entry to a string table +* SCM string-table-add-ref:: @file{string-table-add-ref} - Add an entry to a string table, get reference +* SCM string-table-new:: @file{string-table-new} - create a string table +* SCM string-table-size:: @file{string-table-size} - print the current size of a string table +* SCM string->c-name!:: @file{string->c-name!} - map non-name chars to underscore +* SCM string->camelcase:: @file{string->camelcase} - make a string be CamelCase +* SCM string-tr:: @file{string-tr} - convert characters with new result +* SCM string-tr!:: @file{string-tr!} - convert characters +* SCM string-upcase:: @file{string-upcase} - upper case a new string +* SCM string-upcase!:: @file{string-upcase!} - make a string be upper case +* SCM sub-shell-str:: @file{sub-shell-str} - back quoted (sub-)shell string +* SCM sum:: @file{sum} - sum of values in list +* SCM time-string->number:: @file{time-string->number} - duration string to seconds +* SCM version-compare:: @file{version-compare} - compare two version numbers +@end menu + + +@node SCM agpl +@subsection @file{agpl} - GNU Affero General Public License +@findex agpl + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expFormat.c line 775. +@end ignore + +Usage: (agpl prog-name prefix) +@* +Emit a string that contains the GNU Affero General Public License. +This function is now deprecated. Please @xref{SCM license-description}. + +Arguments: +@* +prog-name - name of the program under the GPL +@* +prefix - String for starting each output line + +@node SCM bsd +@subsection @file{bsd} - BSD Public License +@findex bsd + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expFormat.c line 824. +@end ignore + +Usage: (bsd prog_name owner prefix) +@* +Emit a string that contains the Free BSD Public License. +This function is now deprecated. Please @xref{SCM license-description}. + +Arguments: +@* +prog_name - name of the program under the BSD +@* +owner - Grantor of the BSD License +@* +prefix - String for starting each output line + +@node SCM c-string +@subsection @file{c-string} - emit string for ANSI C +@findex c-string + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expString.c line 775. +@end ignore + +Usage: (c-string string) +@* +Reform a string so that, when printed, the C compiler will be able to +compile the data and construct a string that contains exactly what the +current string contains. Many non-printing characters are replaced with +escape sequences. Newlines are replaced with a backslash, an @code{n}, a +closing quote, a newline, seven spaces and another re-opening quote. The +compiler will implicitly concatenate them. The reader will see line +breaks. + +A K&R compiler will choke. Use @code{kr-string} for that compiler. + +Arguments: +@* +string - string to reformat + +@node SCM error-source-line +@subsection @file{error-source-line} - display of file & line +@findex error-source-line + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcEval.c line 318. +@end ignore + +Usage: (error-source-line) +@* +This function is only invoked just before Guile displays +an error message. It displays the file name and line number +that triggered the evaluation error. You should not need to +invoke this routine directly. Guile will do it automatically. + +This Scheme function takes no arguments. + +@node SCM extract +@subsection @file{extract} - extract text from another file +@findex extract + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expExtract.c line 191. +@end ignore + +Usage: (extract file-name marker-fmt [ caveat ] [ default ]) +@* +This function is used to help construct output files that may contain +text that is carried from one version of the output to the next. + +The first two arguments are required, the second are optional: + +@itemize @bullet +@item +The @code{file-name} argument is used to name the file that +contains the demarcated text. +@item +The @code{marker-fmt} is a formatting string that is used to construct +the starting and ending demarcation strings. The sprintf function is +given the @code{marker-fmt} with two arguments. The first is either +"START" or "END". The second is either "DO NOT CHANGE THIS COMMENT" +or the optional @code{caveat} argument. +@item +@code{caveat} is presumed to be absent if it is the empty string +(@code{""}). If absent, ``DO NOT CHANGE THIS COMMENT'' is used +as the second string argument to the @code{marker-fmt}. +@item +When a @code{default} argument is supplied and no pre-existing text +is found, then this text will be inserted between the START and END +markers. +@end itemize + +@noindent +The resulting strings are presumed to be unique within +the subject file. As a simplified example: + +@example +[+ (extract "fname" "// %s - SOMETHING - %s" "" +"example default") +] +@end example +@noindent +will result in the following text being inserted into the output: + +@example +// START - SOMETHING - DO NOT CHANGE THIS COMMENT +example default +// END - SOMETHING - DO NOT CHANGE THIS COMMENT +@end example + +@noindent +The ``@code{example default}'' string can then be carried forward to +the next generation of the output, @strong{@i{provided}} the output +is not named "@code{fname}" @i{and} the old output is renamed to +"@code{fname}" before AutoGen-eration begins. + +@table @strong +@item NB: +You can set aside previously generated source files inside the pseudo +macro with a Guile/scheme function, extract the text you want to keep +with this extract function. Just remember you should delete it at the +end, too. Here is an example from my Finite State Machine generator: + +@example +[+ AutoGen5 Template -*- Mode: text -*- +h=%s-fsm.h c=%s-fsm.c +(shellf +"test -f %1$s-fsm.h && mv -f %1$s-fsm.h .fsm.head +test -f %1$s-fsm.c && mv -f %1$s-fsm.c .fsm.code" (base-name)) ++] +@end example + +This code will move the two previously produced output files to files +named ".fsm.head" and ".fsm.code". At the end of the 'c' output +processing, I delete them. + +@item also NB: +This function presumes that the output file ought to be editable so +that the code between the @code{START} and @code{END} marks can be edited +by the template user. Consequently, when the @code{(extract ...)} function +is invoked, if the @code{writable} option has not been specified, then +it will be set at that point. If this is not the desired behavior, the +@code{--not-writable} command line option will override this. +Also, you may use the guile function @code{(chmod "file" mode-value)} +to override whatever AutoGen is using for the result mode. +@end table + +Arguments: +@* +file-name - name of file with text +@* +marker-fmt - format for marker text +@* +caveat - Optional - warn about changing marker +@* +default - Optional - default initial text + +@node SCM format-arg-count +@subsection @file{format-arg-count} - count the args to a format +@findex format-arg-count + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expPrint.c line 290. +@end ignore + +Usage: (format-arg-count format) +@* +Sometimes, it is useful to simply be able to figure out how many +arguments are required by a format string. For example, if you +are extracting a format string for the purpose of generating a +macro to invoke a printf-like function, you can run the +formatting string through this function to determine how many +arguments to provide for in the macro. e.g. for this extraction +text: +@example + + /*=fumble bumble + * fmt: 'stumble %s: %d\n' + =*/ +@end example + +@noindent +You may wish to generate a macro: +@example + + #define BUMBLE(a1,a2) printf_like(something,(a1),(a2)) +@end example + +@noindent +You can do this by knowing that the format needs two arguments. + +Arguments: +@* +format - formatting string + +@node SCM fprintf +@subsection @file{fprintf} - format to a file +@findex fprintf + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expPrint.c line 223. +@end ignore + +Usage: (fprintf port format [ format-arg ... ]) +@* +Format a string using arguments from the alist. +Write to a specified port. The result will NOT appear in your +output. Use this to print information messages to a template user. + +Arguments: +@* +port - Guile-scheme output port +@* +format - formatting string +@* +format-arg - Optional - list of arguments to formatting string + +@node SCM gperf +@subsection @file{gperf} - perform a perfect hash function +@findex gperf + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expGperf.c line 111. +@end ignore + +Usage: (gperf name str) +@* +Perform the perfect hash on the input string. This is only useful if +you have previously created a gperf program with the @code{make-gperf} +function @xref{SCM make-gperf}. The @code{name} you supply here must +match the name used to create the program and the string to hash must +be one of the strings supplied in the @code{make-gperf} string list. +The result will be a perfect hash index. + +See the documentation for @command{gperf(1GNU)} for more details. + +Arguments: +@* +name - name of hash list +@* +str - string to hash + +@node SCM gperf-code +@subsection @file{gperf-code} - emit the source of the generated gperf program +@findex gperf-code + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/schemedef.scm line 339. +@end ignore + +Usage: (gperf-code st-name) +@* +Returns the contents of the emitted code, suitable +for inclusion in another program. The interface contains +the following elements: + +@table @samp +@item struct @i{<st-name>}_index +containg the fields: @code{@{char const * name, int const id; @};} + +@item @i{<st-name>}_hash() +This is the hashing function with local only scope (static). + +@item @i{<st-name>}_find() +This is the searching and validation function. The first argument +is the string to look up, the second is its length. +It returns a pointer to the corresponding @code{@i{<st-name>}_index} +entry. +@end table + +Use this in your template as follows where "@i{<st-name>}" was +set to be "@code{lookup}": + +@example +[+ (make-gperf "lookup" (join "\n" (stack "name_list"))) +(gperf-code "lookup") +] +void my_fun(char * str) @{ +struct lookup_index * li = lookup_find(str, strlen(str)); +if (li != NULL) printf("%s yields %d\n", str, li->idx); +@end example + +Arguments: +@* +st-name - the name of the gperf hash list + +@node SCM gpl +@subsection @file{gpl} - GNU General Public License +@findex gpl + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expFormat.c line 751. +@end ignore + +Usage: (gpl prog-name prefix) +@* +Emit a string that contains the GNU General Public License. +This function is now deprecated. Please @xref{SCM license-description}. + +Arguments: +@* +prog-name - name of the program under the GPL +@* +prefix - String for starting each output line + +@node SCM hide-email +@subsection @file{hide-email} - convert eaddr to javascript +@findex hide-email + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expPrint.c line 246. +@end ignore + +Usage: (hide-email display eaddr) +@* +Hides an email address as a java scriptlett. +The 'mailto:' tag and the email address are coded bytes +rather than plain text. They are also broken up. + +Arguments: +@* +display - display text +@* +eaddr - email address + +@node SCM html-escape-encode +@subsection @file{html-escape-encode} - encode html special characters +@findex html-escape-encode + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/schemedef.scm line 110. +@end ignore + +Usage: (html-escape-encode str) +@* +This function will replace replace the characters @code{'&'}, +@code{'<'} and @code{'>'} characters with the HTML/XML +escape-encoded strings (@code{"&"}, @code{"<"}, and +@code{">"}, respectively). + +Arguments: +@* +str - string to make substitutions in + +@node SCM in? +@subsection @file{in?} - test for string in list +@findex in? + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expString.c line 267. +@end ignore + +Usage: (in? test-string string-list ...) +@* +Return SCM_BOOL_T if the first argument string is found +in one of the entries in the second (list-of-strings) argument. + +Arguments: +@* +test-string - string to look for +@* +string-list - list of strings to check + +@node SCM join +@subsection @file{join} - join string list with separator +@findex join + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expString.c line 334. +@end ignore + +Usage: (join separator list ...) +@* +With the first argument as the separator string, +joins together an a-list of strings into one long string. +The list may contain nested lists, partly because you +cannot always control that. + +Arguments: +@* +separator - string to insert between entries +@* +list - list of strings to join + +@node SCM kr-string +@subsection @file{kr-string} - emit string for K&R C +@findex kr-string + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expString.c line 749. +@end ignore + +Usage: (kr-string string) +@* +Reform a string so that, when printed, a K&R C compiler will be able +to compile the data and construct a string that contains exactly +what the current string contains. Many non-printing characters are +replaced with escape sequences. New-lines are replaced with a +backslash-n-backslash and newline sequence, + +Arguments: +@* +string - string to reformat + +@node SCM lgpl +@subsection @file{lgpl} - GNU Library General Public License +@findex lgpl + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expFormat.c line 799. +@end ignore + +Usage: (lgpl prog_name owner prefix) +@* +Emit a string that contains the GNU Library General Public License. +This function is now deprecated. Please @xref{SCM license-description}. + +Arguments: +@* +prog_name - name of the program under the LGPL +@* +owner - Grantor of the LGPL +@* +prefix - String for starting each output line + +@node SCM license +@subsection @file{license} - an arbitrary license +@findex license + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expFormat.c line 850. +@end ignore + +Usage: (license lic_name prog_name owner prefix) +@* +Emit a string that contains the named license. +This function is now deprecated. Please @xref{SCM license-description}. + +Arguments: +@* +lic_name - file name of the license +@* +prog_name - name of the licensed program or library +@* +owner - Grantor of the License +@* +prefix - String for starting each output line + +@node SCM license-description +@subsection @file{license-description} - Emit a license description +@findex license-description + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expFormat.c line 673. +@end ignore + +Usage: (license-description license prog-name prefix [ owner ]) +@* +Emit a string that contains a detailed license description, with +substitutions for program name, copyright holder and a per-line prefix. +This is the text typically used as part of a source file header. +For more details, @xref{SCM license-full, the license-full command}. + +Arguments: +@* +license - name of license type +@* +prog-name - name of the program under the GPL +@* +prefix - String for starting each output line +@* +owner - Optional - owner of the program + +@node SCM license-full +@subsection @file{license-full} - Emit the licensing information and description +@findex license-full + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expFormat.c line 616. +@end ignore + +Usage: (license-full license prog-name prefix [ owner ] [ years ]) +@* +Emit all the text that @code{license-info} and @code{license-description} +would emit (@pxref{SCM license-info, @code{license-info}}, +and @pxref{SCM license-description, @code{license-description}}), +with all the same substitutions. + +All of these depend upon the existence of a license file named after the +@code{license} argument with a @code{.lic} suffix. That file should +contain three blocks of text, each separated by two or more consecutive +newline characters (at least one completely blank line). + +The first section describes copyright attribution and the name of the usage +licence. For GNU software, this should be the text that is to be displayed +with the program version. Four text markers can be replaced: <PFX>, +<program>, <years> and <owner>. + +The second section is a short description of the terms of the license. +This is typically the kind of text that gets displayed in the header of +source files. Only the <PFX>, <owner> and <program> markers are +substituted. + +The third section is strictly the name of the license. +No marker substitutions are performed. + +@example +<PFX>Copyright (C) <years> <owner>, all rights reserved. +<PFX> +<PFX>This is free software. It is licensed for use, +<PFX>modification and redistribution under the terms +<PFX>of the GNU General Public License, version 3 or later +<PFX> <http://gnu.org/licenses/gpl.html> + +<PFX><program> is free software: you can redistribute it +<PFX>and/or modify it under the terms of the GNU General +<PFX>Public License as published by the Free Software ... + +the GNU General Public License, version 3 or later +@end example + +Arguments: +@* +license - name of license type +@* +prog-name - name of the program under the GPL +@* +prefix - String for starting each output line +@* +owner - Optional - owner of the program +@* +years - Optional - copyright years + +@node SCM license-info +@subsection @file{license-info} - Emit the licensing information and copyright years +@findex license-info + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expFormat.c line 697. +@end ignore + +Usage: (license-info license prog-name prefix [ owner ] [ years ]) +@* +Emit a string that contains the licensing description, with some +substitutions for program name, copyright holder, a list of years when the +source was modified, and a per-line prefix. This text typically includes a +brief license description and is often printed out when a program starts +running or as part of the @code{--version} output. +For more details, @xref{SCM license-full, the license-full command}. + +Arguments: +@* +license - name of license type +@* +prog-name - name of the program under the GPL +@* +prefix - String for starting each output line +@* +owner - Optional - owner of the program +@* +years - Optional - copyright years + +@node SCM license-name +@subsection @file{license-name} - Emit the name of the license +@findex license-name + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expFormat.c line 724. +@end ignore + +Usage: (license-name license) +@* +Emit a string that contains the full name of the license. + +Arguments: +@* +license - name of license type + +@node SCM make-gperf +@subsection @file{make-gperf} - build a perfect hash function program +@findex make-gperf + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expGperf.c line 41. +@end ignore + +Usage: (make-gperf name strings ...) +@* +Build a program to perform perfect hashes of a known list of input +strings. This function produces no output, but prepares a program +named, @file{gperf_<name>} for use by the gperf function +@xref{SCM gperf}. + +This program will be obliterated as AutoGen exits. +However, you may incorporate the generated hashing function +into your C program with commands something like the following: + +@example +[+ (shellf "sed '/^int main(/,$d;/^#line/d' $@{gpdir@}/%s.c" +name ) +] +@end example + +where @code{name} matches the name provided to this @code{make-perf} +function. @code{gpdir} is the variable used to store the name of the +temporary directory used to stash all the files. + +Arguments: +@* +name - name of hash list +@* +strings - list of strings to hash + +@node SCM makefile-script +@subsection @file{makefile-script} - create makefile script +@findex makefile-script + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expMake.c line 255. +@end ignore + +Usage: (makefile-script text) +@* +This function will take ordinary shell script text and reformat it +so that it will work properly inside of a makefile shell script. +Not every shell construct can be supported; the intent is to have +most ordinary scripts work without much, if any, alteration. + +The following transformations are performed on the source text: + +@enumerate +@item +Trailing whitespace on each line is stripped. + +@item +Except for the last line, the string, " ; \\" is appended to the end of +every line that does not end with certain special characters or keywords. +Note that this will mutilate multi-line quoted strings, but @command{make} +renders it impossible to use multi-line constructs anyway. + +@item +If the line ends with a backslash, it is left alone. + +@item +If the line ends with a semi-colon, conjunction operator, pipe (vertical +bar) or one of the keywords "then", "else" or "in", then a space and a +backslash is added, but no semi-colon. + +@item +The dollar sign character is doubled, unless it immediately precedes an +opening parenthesis or the single character make macros '*', '<', '@@', +'?' or '%'. Other single character make macros that do not have enclosing +parentheses will fail. For shell usage of the "$@@", "$?" and "$*" +macros, you must enclose them with curly braces, e.g., "$@{?@}". +The ksh construct @code{$(<command>)} will not work. Though some +@command{make}s accept @code{$@{var@}} constructs, this function will +assume it is for shell interpretation and double the dollar character. +You must use @code{$(var)} for all @command{make} substitutions. + +@item +Double dollar signs are replaced by four before the next character +is examined. + +@item +Every line is prefixed with a tab, unless the first line +already starts with a tab. + +@item +The newline character on the last line, if present, is suppressed. + +@item +Blank lines are stripped. + +@item +Lines starting with "@@ifdef", "@@ifndef", "@@else" and "@@endif" are +presumed to be autoconf "sed" expression tags. These lines will be +emitted as-is, with no tab prefix and no line splicing backslash. +These lines can then be processed at configure time with +@code{AC_CONFIG_FILES} sed expressions, similar to: + +@example +sed "/^@@ifdef foo/d;/^@@endif foo/d;/^@@ifndef foo/,/^@@endif foo/d" +@end example +@end enumerate + +@noindent +This function is intended to be used approximately as follows: + +@example +$(TARGET) : $(DEPENDENCIES) +<+ (out-push-new) +> +....mostly arbitrary shell script text.... +<+ (makefile-script (out-pop #t)) +> +@end example + +Arguments: +@* +text - the text of the script + +@node SCM max +@subsection @file{max} - maximum value in list +@findex max + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expGuile.c line 126. +@end ignore + +Usage: (max list ...) +@* +Return the maximum value in the list + +Arguments: +@* +list - list of values. Strings are converted to numbers + +@node SCM min +@subsection @file{min} - minimum value in list +@findex min + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expGuile.c line 185. +@end ignore + +Usage: (min list ...) +@* +Return the minimum value in the list + +Arguments: +@* +list - list of values. Strings are converted to numbers + +@node SCM prefix +@subsection @file{prefix} - prefix lines with a string +@findex prefix + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expString.c line 432. +@end ignore + +Usage: (prefix prefix text) +@* +Prefix every line in the second string with the first string. +This includes empty lines. Trailing white space will be removed +so if the prefix is all horizontal white space, then it will be +removed from otherwise blank lines. Also, if the last character +is a newline, then *two* prefixes will be inserted into the result +text. + +For example, if the first string is "# " and the second contains: +@example +"two\nlines\n" +@end example +@noindent +The result string will contain: +@example +# two +# lines +# +@end example + +The last line will be incomplete: no newline and no space after the +hash character, either. + +Arguments: +@* +prefix - string to insert at start of each line +@* +text - multi-line block of text + +@node SCM printf +@subsection @file{printf} - format to stdout +@findex printf + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expPrint.c line 200. +@end ignore + +Usage: (printf format [ format-arg ... ]) +@* +Format a string using arguments from the alist. +Write to the standard out port. The result will NOT appear in your +output. Use this to print information messages to a template user. +Use ``(sprintf ...)'' to add text to your document. + +Arguments: +@* +format - formatting string +@* +format-arg - Optional - list of arguments to formatting string + +@node SCM raw-shell-str +@subsection @file{raw-shell-str} - single quote shell string +@findex raw-shell-str + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expString.c line 521. +@end ignore + +Usage: (raw-shell-str string) +@* +Convert the text of the string into a singly quoted string +that a normal shell will process into the original string. +(It will not do macro expansion later, either.) +Contained single quotes become tripled, with the middle quote +escaped with a backslash. Normal shells will reconstitute the +original string. + +@strong{Notice}: some shells will not correctly handle unusual +non-printing characters. This routine works for most reasonably +conventional ASCII strings. + +Arguments: +@* +string - string to transform + +@node SCM shell +@subsection @file{shell} - invoke a shell script +@findex shell + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/agShell.c line 60. +@end ignore + +Usage: (shell command ...) +@* +Generate a string by writing the value to a server shell and reading the +output back in. The template programmer is responsible for ensuring that +it completes within 10 seconds. If it does not, the server will be +killed, the output tossed and a new server started. + +Please note: This is the same server process used by the '#shell' +definitions directive and backquoted @code{`} definitions. There may be +left over state from previous shell expressions and the @code{`} +processing in the declarations. However, a @code{cd} to the original +directory is always issued before the new command is issued. + +Also note: When initializing, autogen will set the environment +variable "AGexe" to the full path of the autogen executable. + +Arguments: +@* +command - shell command - the result is from stdout + +@node SCM shell-str +@subsection @file{shell-str} - double quote shell string +@findex shell-str + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expString.c line 618. +@end ignore + +Usage: (shell-str string) +@* +Convert the text of the string into a double quoted string that a normal +shell will process into the original string, almost. It will add the +escape character @code{\\} before two special characters to +accomplish this: the backslash @code{\\} and double quote @code{"}. + +@strong{Notice}: some shells will not correctly handle unusual +non-printing characters. This routine works for most reasonably +conventional ASCII strings. + +@strong{WARNING}: +@* +This function omits the extra backslash in front of a backslash, however, +if it is followed by either a backquote or a dollar sign. It must do this +because otherwise it would be impossible to protect the dollar sign or +backquote from shell evaluation. Consequently, it is not possible to +render the strings "\\$" or "\\`". The lesser of two evils. + +All others characters are copied directly into the output. + +The @code{sub-shell-str} variation of this routine behaves identically, +except that the extra backslash is omitted in front of @code{"} instead +of @code{`}. You have to think about it. I'm open to suggestions. + +Meanwhile, the best way to document is with a detailed output example. +If the backslashes make it through the text processing correctly, +below you will see what happens with three example strings. The first +example string contains a list of quoted @code{foo}s, the second is +the same with a single backslash before the quote characters and the +last is with two backslash escapes. Below each is the result of the +@code{raw-shell-str}, @code{shell-str} and @code{sub-shell-str} functions. + +@example +foo[0] ''foo'' 'foo' "foo" `foo` $foo +raw-shell-str -> \'\''foo'\'\'' '\''foo'\'' "foo" `foo` $foo' +shell-str -> "''foo'' 'foo' \"foo\" `foo` $foo" +sub-shell-str -> `''foo'' 'foo' "foo" \`foo\` $foo` + +foo[1] \'bar\' \"bar\" \`bar\` \$bar +raw-shell-str -> '\'\''bar\'\'' \"bar\" \`bar\` \$bar' +shell-str -> "\\'bar\\' \\\"bar\\\" \`bar\` \$bar" +sub-shell-str -> `\\'bar\\' \"bar\" \\\`bar\\\` \$bar` + +foo[2] \\'BAZ\\' \\"BAZ\\" \\`BAZ\\` \\$BAZ +raw-shell-str -> '\\'\''BAZ\\'\'' \\"BAZ\\" \\`BAZ\\` \\$BAZ' +shell-str -> "\\\\'BAZ\\\\' \\\\\"BAZ\\\\\" \\\`BAZ\\\` \\\$BAZ" +sub-shell-str -> `\\\\'BAZ\\\\' \\\"BAZ\\\" \\\\\`BAZ\\\\\` \\\$BAZ` +@end example + +There should be four, three, five and three backslashes for the four +examples on the last line, respectively. The next to last line should +have four, five, three and three backslashes. If this was not accurately +reproduced, take a look at the agen5/test/shell.test test. Notice the +backslashes in front of the dollar signs. It goes from zero to one to +three for the "cooked" string examples. + +Arguments: +@* +string - string to transform + +@node SCM shellf +@subsection @file{shellf} - format a string, run shell +@findex shellf + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/agShell.c line 108. +@end ignore + +Usage: (shellf format [ format-arg ... ]) +@* +Format a string using arguments from the alist, +then send the result to the shell for interpretation. + +Arguments: +@* +format - formatting string +@* +format-arg - Optional - list of arguments to formatting string + +@node SCM sprintf +@subsection @file{sprintf} - format a string +@findex sprintf + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expPrint.c line 178. +@end ignore + +Usage: (sprintf format [ format-arg ... ]) +@* +Format a string using arguments from the alist. + +Arguments: +@* +format - formatting string +@* +format-arg - Optional - list of arguments to formatting string + +@node SCM string-capitalize +@subsection @file{string-capitalize} - capitalize a new string +@findex string-capitalize + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expGuile.c line 425. +@end ignore + +Usage: (string-capitalize str) +@* +Create a new SCM string containing the same text as the original, +only all the first letter of each word is upper cased and all +other letters are made lower case. + +Arguments: +@* +str - input string + +@node SCM string-capitalize! +@subsection @file{string-capitalize!} - capitalize a string +@findex string-capitalize! + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expGuile.c line 382. +@end ignore + +Usage: (string-capitalize! str) +@* +capitalize all the words in an SCM string. + +Arguments: +@* +str - input/output string + +@node SCM *=* +@subsection @file{string-contains-eqv?} - caseless substring +@findex string-contains-eqv? +@findex *=* + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcCase.c line 229. +@end ignore + +Usage: (*=* text match) +@* +string-contains-eqv?: Test to see if a string contains an equivalent string. +`equivalent' means the strings match, but without regard +to character case and certain characters are considered `equivalent'. +Viz., '-', '_' and '^' are equivalent. + +Arguments: +@* +text - text to test for pattern +@* +match - pattern/substring to search for + +@node SCM *==* +@subsection @file{string-contains?} - substring match +@findex string-contains? +@findex *==* + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcCase.c line 96. +@end ignore + +Usage: (*==* text match) +@* +string-contains?: Test to see if a string contains a substring. "strstr(3)" +will find an address. + +Arguments: +@* +text - text to test for pattern +@* +match - pattern/substring to search for + +@node SCM string-downcase +@subsection @file{string-downcase} - lower case a new string +@findex string-downcase + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expGuile.c line 481. +@end ignore + +Usage: (string-downcase str) +@* +Create a new SCM string containing the same text as the original, +only all the upper case letters are changed to lower case. + +Arguments: +@* +str - input string + +@node SCM string-downcase! +@subsection @file{string-downcase!} - make a string be lower case +@findex string-downcase! + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expGuile.c line 450. +@end ignore + +Usage: (string-downcase! str) +@* +Change to lower case all the characters in an SCM string. + +Arguments: +@* +str - input/output string + +@node SCM *~ +@subsection @file{string-end-eqv-match?} - caseless regex ending +@findex string-end-eqv-match? +@findex *~ + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcCase.c line 501. +@end ignore + +Usage: (*~ text match) +@* +string-end-eqv-match?: Test to see if a string ends with a pattern. +Case is not significant. + +Arguments: +@* +text - text to test for pattern +@* +match - pattern/substring to search for + +@node SCM *~~ +@subsection @file{string-end-match?} - regex match end +@findex string-end-match? +@findex *~~ + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcCase.c line 488. +@end ignore + +Usage: (*~~ text match) +@* +string-end-match?: Test to see if a string ends with a pattern. +Case is significant. + +Arguments: +@* +text - text to test for pattern +@* +match - pattern/substring to search for + +@node SCM *= +@subsection @file{string-ends-eqv?} - caseless string ending +@findex string-ends-eqv? +@findex *= + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcCase.c line 277. +@end ignore + +Usage: (*= text match) +@* +string-ends-eqv?: Test to see if a string ends with an equivalent string. + +Arguments: +@* +text - text to test for pattern +@* +match - pattern/substring to search for + +@node SCM *== +@subsection @file{string-ends-with?} - string ending +@findex string-ends-with? +@findex *== + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcCase.c line 125. +@end ignore + +Usage: (*== text match) +@* +string-ends-with?: Test to see if a string ends with a substring. +strcmp(3) returns zero for comparing the string ends. + +Arguments: +@* +text - text to test for pattern +@* +match - pattern/substring to search for + +@node SCM == +@subsection @file{string-equals?} - string matching +@findex string-equals? +@findex == + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcCase.c line 200. +@end ignore + +Usage: (== text match) +@* +string-equals?: Test to see if two strings exactly match. + +Arguments: +@* +text - text to test for pattern +@* +match - pattern/substring to search for + +@node SCM ~ +@subsection @file{string-eqv-match?} - caseless regex match +@findex string-eqv-match? +@findex ~ + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcCase.c line 689. +@end ignore + +Usage: (~ text match) +@* +string-eqv-match?: Test to see if a string fully matches a pattern. +Case is not significant, but any character equivalences +must be expressed in your regular expression. + +Arguments: +@* +text - text to test for pattern +@* +match - pattern/substring to search for + +@node SCM = +@subsection @file{string-eqv?} - caseless match +@findex string-eqv? +@findex = + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcCase.c line 347. +@end ignore + +Usage: (= text match) +@* +string-eqv?: Test to see if two strings are equivalent. `equivalent' means the +strings match, but without regard to character case and certain +characters are considered `equivalent'. Viz., '-', '_' and '^' are +equivalent. If the arguments are not strings, then the result of the +numeric comparison is returned. + +This is an overloaded operation. If the arguments are both +numbers, then the query is passed through to @code{scm_num_eq_p()}, +otherwise the result depends on the SCMs being strictly equal. + +Arguments: +@* +text - text to test for pattern +@* +match - pattern/substring to search for + +@node SCM *~* +@subsection @file{string-has-eqv-match?} - caseless regex contains +@findex string-has-eqv-match? +@findex *~* + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcCase.c line 419. +@end ignore + +Usage: (*~* text match) +@* +string-has-eqv-match?: Test to see if a string contains a pattern. +Case is not significant. + +Arguments: +@* +text - text to test for pattern +@* +match - pattern/substring to search for + +@node SCM *~~* +@subsection @file{string-has-match?} - contained regex match +@findex string-has-match? +@findex *~~* + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcCase.c line 406. +@end ignore + +Usage: (*~~* text match) +@* +string-has-match?: Test to see if a string contains a pattern. +Case is significant. + +Arguments: +@* +text - text to test for pattern +@* +match - pattern/substring to search for + +@node SCM ~~ +@subsection @file{string-match?} - regex match +@findex string-match? +@findex ~~ + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcCase.c line 676. +@end ignore + +Usage: (~~ text match) +@* +string-match?: Test to see if a string fully matches a pattern. +Case is significant. + +Arguments: +@* +text - text to test for pattern +@* +match - pattern/substring to search for + +@node SCM ~* +@subsection @file{string-start-eqv-match?} - caseless regex start +@findex string-start-eqv-match? +@findex ~* + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcCase.c line 595. +@end ignore + +Usage: (~* text match) +@* +string-start-eqv-match?: Test to see if a string starts with a pattern. +Case is not significant. + +Arguments: +@* +text - text to test for pattern +@* +match - pattern/substring to search for + +@node SCM ~~* +@subsection @file{string-start-match?} - regex match start +@findex string-start-match? +@findex ~~* + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcCase.c line 582. +@end ignore + +Usage: (~~* text match) +@* +string-start-match?: Test to see if a string starts with a pattern. +Case is significant. + +Arguments: +@* +text - text to test for pattern +@* +match - pattern/substring to search for + +@node SCM =* +@subsection @file{string-starts-eqv?} - caseless string start +@findex string-starts-eqv? +@findex =* + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcCase.c line 314. +@end ignore + +Usage: (=* text match) +@* +string-starts-eqv?: Test to see if a string starts with an equivalent string. + +Arguments: +@* +text - text to test for pattern +@* +match - pattern/substring to search for + +@node SCM ==* +@subsection @file{string-starts-with?} - string starting +@findex string-starts-with? +@findex ==* + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcCase.c line 164. +@end ignore + +Usage: (==* text match) +@* +string-starts-with?: Test to see if a string starts with a substring. + +Arguments: +@* +text - text to test for pattern +@* +match - pattern/substring to search for + +@node SCM string-substitute +@subsection @file{string-substitute} - multiple global replacements +@findex string-substitute + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expString.c line 917. +@end ignore + +Usage: (string-substitute source match repl) +@* +@code{match} and @code{repl} may be either a single string or +a list of strings. Either way, they must have the same structure +and number of elements. For example, to replace all amphersands, +less than and greater than characters, do something like this: + +@example +(string-substitute source +(list "&" "<" ">") +(list "&" "<" ">")) +@end example + +Arguments: +@* +source - string to transform +@* +match - substring or substring list to be replaced +@* +repl - replacement strings or substrings + +@node SCM string-table-add +@subsection @file{string-table-add} - Add an entry to a string table +@findex string-table-add + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/schemedef.scm line 239. +@end ignore + +Usage: (string-table-add st-name str-val) +@* +Check for a duplicate string and, if none, then insert a new +string into the string table. In all cases, returns the +character index of the beginning of the string in the table. + +The returned index can be used in expressions like: +@example +string_array + <returned-value> +@end example +@noindent +that will yield the address of the first byte of the inserted +string. See the @file{strtable.test} AutoGen test for a usage +example. + +Arguments: +@* +st-name - the name of the array of characters +@* +str-val - the (possibly) new value to add + +@node SCM string-table-add-ref +@subsection @file{string-table-add-ref} - Add an entry to a string table, get reference +@findex string-table-add-ref + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/schemedef.scm line 277. +@end ignore + +Usage: (string-table-add-ref st-name str-val) +@* +Identical to string-table-add, except the value returned +is the string "st-name" '+' and the index returned by +string-table-add. + +Arguments: +@* +st-name - the name of the array of characters +@* +str-val - the (possibly) new value to add + +@node SCM string-table-new +@subsection @file{string-table-new} - create a string table +@findex string-table-new + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/schemedef.scm line 146. +@end ignore + +Usage: (string-table-new st-name) +@* +This function will create an array of characters. The companion +functions, (@xref{SCM string-table-add}, +@xref{SCM string-table-add-ref}, and +@pxref{SCM emit-string-table}) will insert text and emit the +populated table. + +With these functions, it should be much easier to construct +structures containing string offsets instead of string pointers. +That can be very useful when transmitting, storing or sharing data +with different address spaces. + +@noindent +Here is a brief example copied from the strtable.test test: + +@example +[+ (string-table-new "scribble") + (out-push-new) ;; redirect output to temporary + (define ct 1) +][+ + +FOR str IN that was the week that was +][+ + (set! ct (+ ct 1)) ++] + [+ (string-table-add-ref "scribble" (get "str")) +],[+ +ENDFOR +] +[+ (out-suspend "main") + (emit-string-table "scribble") + (ag-fprintf 0 "\nchar const *ap[%d] = @{" ct) + (out-resume "main") + (out-pop #t) ;; now dump out the redirected output +] + NULL @}; +@end example + +@noindent +Some explanation: + +@noindent +I added the @code{(out-push-new)} because the string table text is +diverted into an output stream named, ``scribble'' and I want to +have the string table emitted before the string table references. +The string table references are also emitted inside the @code{FOR} +loop. So, when the loop is done, the current output is suspended +under the name, ``main'' and the ``scribble'' table is then emitted +into the primary output. (@code{emit-string-table} inserts its +output directly into the current output stream. It does not need to +be the last function in an AutoGen macro block.) Next I +@code{ag-fprintf} the array-of-pointer declaration directly into the +current output. Finally I restore the ``main'' output stream and +@code{(out-pop #t)}-it into the main output stream. + +Here is the result. Note that duplicate strings are not repeated +in the string table: + +@example +static char const scribble[18] = + "that\0" "was\0" "the\0" "week\0"; + +char const *ap[7] = @{ + scribble+0, + scribble+5, + scribble+9, + scribble+13, + scribble+0, + scribble+5, + NULL @}; +@end example + +These functions use the global name space @code{stt-*} in addition to +the function names. + +If you utilize this in your programming, it is recommended that you +prevent printf format usage warnings with the GCC option +@code{-Wno-format-contains-nul} + +Arguments: +@* +st-name - the name of the array of characters + +@node SCM string-table-size +@subsection @file{string-table-size} - print the current size of a string table +@findex string-table-size + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/schemedef.scm line 326. +@end ignore + +Usage: (string-table-size st-name) +@* +Returns the current byte count of the string table. + +Arguments: +@* +st-name - the name of the array of characters + +@node SCM string->c-name! +@subsection @file{string->c-name!} - map non-name chars to underscore +@findex string->c-name! + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expGuile.c line 286. +@end ignore + +Usage: (string->c-name! str) +@* +Change all the graphic characters that are invalid in a C name token +into underscores. Whitespace characters are ignored. Any other +character type (i.e. non-graphic and non-white) will cause a failure. + +Arguments: +@* +str - input/output string + +@node SCM string->camelcase +@subsection @file{string->camelcase} - make a string be CamelCase +@findex string->camelcase + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expGuile.c line 505. +@end ignore + +Usage: (string->camelcase str) +@* +Capitalize the first letter of each block of letters and numbers, +and stripping out characters that are not alphanumerics. +For example, "alpha-beta0gamma" becomes "AlphaBeta0gamma". + +Arguments: +@* +str - input/output string + +@node SCM string-tr +@subsection @file{string-tr} - convert characters with new result +@findex string-tr + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expString.c line 897. +@end ignore + +Usage: (string-tr source match translation) +@* +This is identical to @code{string-tr!}, except that it does not +over-write the previous value. + +Arguments: +@* +source - string to transform +@* +match - characters to be converted +@* +translation - conversion list + +@node SCM string-tr! +@subsection @file{string-tr!} - convert characters +@findex string-tr! + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expString.c line 823. +@end ignore + +Usage: (string-tr! source match translation) +@* +This is the same as the @code{tr(1)} program, except the +string to transform is the first argument. The second and +third arguments are used to construct mapping arrays for the +transformation of the first argument. + +It is too bad this little program has so many different +and incompatible implementations! + +Arguments: +@* +source - string to transform +@* +match - characters to be converted +@* +translation - conversion list + +@node SCM string-upcase +@subsection @file{string-upcase} - upper case a new string +@findex string-upcase + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expGuile.c line 358. +@end ignore + +Usage: (string-upcase str) +@* +Create a new SCM string containing the same text as the original, +only all the lower case letters are changed to upper case. + +Arguments: +@* +str - input string + +@node SCM string-upcase! +@subsection @file{string-upcase!} - make a string be upper case +@findex string-upcase! + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expGuile.c line 327. +@end ignore + +Usage: (string-upcase! str) +@* +Change to upper case all the characters in an SCM string. + +Arguments: +@* +str - input/output string + +@node SCM sub-shell-str +@subsection @file{sub-shell-str} - back quoted (sub-)shell string +@findex sub-shell-str + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expString.c line 688. +@end ignore + +Usage: (sub-shell-str string) +@* +This function is substantially identical to @code{shell-str}, except +that the quoting character is @code{`} and the "leave the escape alone" +character is @code{"}. + +Arguments: +@* +string - string to transform + +@node SCM sum +@subsection @file{sum} - sum of values in list +@findex sum + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expGuile.c line 244. +@end ignore + +Usage: (sum list ...) +@* +Compute the sum of the list of expressions. + +Arguments: +@* +list - list of values. Strings are converted to numbers + +@node SCM time-string->number +@subsection @file{time-string->number} - duration string to seconds +@findex time-string->number + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expString.c line 959. +@end ignore + +Usage: (time-string->number time_spec) +@* +Convert the argument string to a time period in seconds. +The string may use multiple parts consisting of days, hours +minutes and seconds. These are indicated with a suffix of +@code{d}, @code{h}, @code{m} and @code{s} respectively. +Hours, minutes and seconds may also be represented with +@code{HH:MM:SS} or, without hours, as @code{MM:SS}. + +Arguments: +@* +time_spec - string to parse + +@node SCM version-compare +@subsection @file{version-compare} - compare two version numbers +@findex version-compare + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expState.c line 210. +@end ignore + +Usage: (version-compare op v1 v2) +@* +Converts v1 and v2 strings into 64 bit values and returns the +result of running 'op' on those values. It assumes that the version +is a 1 to 4 part dot-separated series of numbers. Suffixes like, +"5pre4" or "5-pre4" will be interpreted as two numbers. The first +number ("5" in this case) will be decremented and the number after +the "pre" will be added to 0xC000. (Unless your platform is unable +to support 64 bit integer arithmetic. Then it will be added to 0xC0.) +Consequently, these yield true: +@example +(version-compare > "5.8.5" "5.8.5-pre4") +(version-compare > "5.8.5-pre10" "5.8.5-pre4") +@end example + +Arguments: +@* +op - comparison operator +@* +v1 - first version +@* +v2 - compared-to version +@ignore +START == MACROS == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore + +@c === SECTION MARKER + +@node native macros +@section AutoGen Native Macros +@cindex native macros + +This section describes the various AutoGen natively defined macros. +Unlike the Scheme functions, some of these macros are "block macros" +with a scope that extends through a terminating macro. Block macros +must not overlap. That is to say, a block macro started within the +scope of an encompassing block macro must have its matching end macro +appear before the encompassing block macro is either ended or subdivided. + +The block macros are these: + +@table @code +@item CASE +This macro has scope through the @code{ESAC} macro. +The scope is subdivided by @code{SELECT} macros. +You must have at least one @code{SELECT} macro. + +@item DEFINE +This macro has scope through the @code{ENDDEF} macro. The defined +user macro can never be a block macro. This macro is extracted from +the template @i{before} the template is processed. Consequently, you +cannot select a definition based on context. You can, however, place +them all at the end of the file. + +@item FOR +This macro has scope through the @code{ENDFOR} macro. + +@item IF +This macro has scope through the @code{ENDIF} macro. +The scope may be subdivided by @code{ELIF} and @code{ELSE} +macros. Obviously, there may be only one @code{ELSE} macro +and it must be the last of these subdivisions. + +@item INCLUDE +This macro has the scope of the included file. +It is a block macro in the sense that the included +file must not contain any incomplete block macros. + +@item WHILE +This macro has scope through the @code{ENDWHILE} macro. +@end table +@ignore +END == MACROS == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore +@menu +* AGMacro syntax:: AutoGen Macro Syntax +* BREAK:: BREAK - Leave a FOR or WHILE macro +* CASE:: CASE - Select one of several template blocks +* COMMENT:: COMMENT - A block of comment to be ignored +* CONTINUE:: CONTINUE - Skip to end of a FOR or WHILE macro. +* DEBUG:: DEBUG - Print debug message to trace output +* DEFINE:: DEFINE - Define a user AutoGen macro +* ELIF:: ELIF - Alternate Conditional Template Block +* ELSE:: ELSE - Alternate Template Block +* ENDDEF:: ENDDEF - Ends a macro definition. +* ENDFOR:: ENDFOR - Terminates the @code{FOR} function template block +* ENDIF:: ENDIF - Terminate the @code{IF} Template Block +* ENDWHILE:: ENDWHILE - Terminate the @code{WHILE} Template Block +* ESAC:: ESAC - Terminate the @code{CASE} Template Block +* EXPR:: EXPR - Evaluate and emit an Expression +* FOR:: FOR - Emit a template block multiple times +* IF:: IF - Conditionally Emit a Template Block +* INCLUDE:: INCLUDE - Read in and emit a template block +* INVOKE:: INVOKE - Invoke a User Defined Macro +* RETURN:: RETURN - Leave an INVOKE-d (DEFINE) macro +* SELECT:: SELECT - Selection block for CASE function +* UNKNOWN:: UNKNOWN - Either a user macro or a value name. +* WHILE:: WHILE - Conditionally loop over a Template Block +* shell command:: Inserting text from a shell script +* guile command:: Inserting text from a scheme script +@end menu +@node AGMacro syntax +@subsection AutoGen Macro Syntax +@cindex macro syntax + +The general syntax is: + +@example +[ @{ <native-macro-name> | <user-defined-name> @} ] [ <arg> ... ] +@end example + +@noindent +The syntax for @code{<arg>} depends on the particular macro, +but is generally a full expression (@pxref{expression syntax}). +Here are the exceptions to that general rule: + +@enumerate +@item +@code{INVOKE} macros, implicit or explicit, must be followed by +a list of name/string value pairs. The string values are +@i{simple expressions}, as described above. + +That is, the @code{INVOKE} syntax is one of these two: +@example +<user-macro-name> [ <name> [ = <expression> ] ... ] + +INVOKE <name-expression> [ <name> [ = <expression> ] ... ] +@end example + +@item +AutoGen FOR macros must be in one of three forms: + +@example +FOR <name> [ <separator-string> ] + +FOR <name> (...Scheme expression list) + +FOR <name> IN <string-entry> [ ... ] +@end example +@noindent +where: +@table @samp +@item <name> +must be a simple name. +@item <separator-string> +is inserted between copies of the enclosed block. Do not try to use ``IN'' +as your separator string. It won't work. +@item <string-entry> +is an entry in a list of strings. ``@code{<name>}'' is assigned +each value from the ``@code{IN}'' list before expanding the @code{FOR} block. +@item (...Scheme expression list) +is expected to contain one or more of the @code{for-from}, +@code{for-to}, @code{for-by}, and @code{for-sep} functions. +(@xref{FOR}, and @ref{AutoGen Functions}) +@end table + +The first two forms iterate over the @code{FOR} block if @code{<name>} +is found in the AutoGen values. The last form will create the AutoGen +value named @code{<name>}. + +@item +AutoGen @code{DEFINE} macros must be followed by a simple name. +Anything after that is ignored. Consequently, that ``comment space'' +may be used to document any named values the macro expects to have +set up as arguments. @xref{DEFINE}. + +@item +The AutoGen @code{COMMENT}, @code{ELSE}, @code{ESAC} and the @code{END*} +macros take no arguments and ignore everything after the macro name +(e.g. see @ref{COMMENT}) +@end enumerate + +@node BREAK +@subsection BREAK - Leave a FOR or WHILE macro + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/functions.c line 38. +@end ignore + +@findex BREAK + +This will unwind the loop context and resume after ENDFOR/ENDWHILE. +Note that unless this happens to be the last iteration anyway, +the (last-for?) function will never yield "#t". + +@node CASE +@subsection CASE - Select one of several template blocks + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcCase.c line 818. +@end ignore + +@findex CASE + +The arguments are evaluated and converted to a string, if necessary. A +simple name will be interpreted as an AutoGen value name and its value will +be used by the @code{SELECT} macros (see the example below and the +expression evaluation function, @pxref{EXPR}). The scope of the macro is +up to the matching @code{ESAC} macro. Within the scope of a @code{CASE}, +this string is matched against case selection macros. There are sixteen +match macros that are derived from four different ways matches may be +performed, plus an "always true", "true if the AutoGen value was found", +and "true if no AutoGen value was found" matches. The codes for the +nineteen match macros are formed as follows: + +@enumerate +@item +Must the match start matching from the beginning of the string? +If not, then the match macro code starts with an asterisk (@code{*}). +@item +Must the match finish matching at the end of the string? +If not, then the match macro code ends with an asterisk (@code{*}). +@item +Is the match a pattern match or a string comparison? +If a comparison, use an equal sign (@code{=}). +If a pattern match, use a tilde (@code{~}). +@item +Is the match case sensitive? +If alphabetic case is important, double the tilde or equal sign. +@item +Do you need a default match when none of the others match? +Use a single asterisk (@code{*}). +@item +Do you need to distinguish between an empty string value and a value +that was not found? Use the non-existence test (@code{!E}) before +testing a full match against an empty string (@code{== ''}). +There is also an existence test (@code{+E}), more for symmetry than +for practical use. +@end enumerate + +@noindent +For example: + +@example +[+ CASE <full-expression> +] +[+ ~~* "[Tt]est" +]reg exp must match at start, not at end +[+ == "TeSt" +]a full-string, case sensitive compare +[+ = "TEST" +]a full-string, case insensitive compare +[+ !E +]not exists - matches if no AutoGen value found +[+ == "" +]expression yielded a zero-length string +[+ +E +]exists - matches if there is any value result +[+ * +]always match - no testing +[+ ESAC +] +@end example + +@code{<full-expression>} (@pxref{expression syntax}) may be any expression, +including the use of apply-codes and value-names. If the expression yields +a number, it is converted to a decimal string. + +These case selection codes have also been implemented as +Scheme expression functions using the same codes. They are documented +in this texi doc as ``string-*?'' predicates (@pxref{Common Functions}). + +@node COMMENT +@subsection COMMENT - A block of comment to be ignored + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/functions.c line 350. +@end ignore + +@findex COMMENT + +This function can be specified by the user, but there will +never be a situation where it will be invoked at emit time. +The macro is actually removed from the internal representation. + +If the native macro name code is @code{#}, then the +entire macro function is treated as a comment and ignored. + +@example +[+ # say what you want, but no '+' before any ']' chars +] +@end example + +@node CONTINUE +@subsection CONTINUE - Skip to end of a FOR or WHILE macro. + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/functions.c line 28. +@end ignore + +@findex CONTINUE + +This will skip the remainder of the loop and start the next. + +@node DEBUG +@subsection DEBUG - Print debug message to trace output + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcDef.c line 379. +@end ignore + +@findex DEBUG + +If the tracing level is at "debug-message" or above +(@pxref{autogen trace}), this macro prints a debug message to trace +output. This message is not evaluated. This macro can also be used to +set useful debugger breakpoints. By inserting [+DEBUG n+] into your +template, you can set a debugger breakpoint on the #n case element +below (in the AutoGen source) and step through the processing of +interesting parts of your template. + +To be useful, you have to have access to the source tree where autogen +was built and the template being processed. The definitions are also +helpful, but not crucial. Please contact the author if you think you +might actually want to use this. + +@node DEFINE +@subsection DEFINE - Define a user AutoGen macro + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcDef.c line 523. +@end ignore + +@findex DEFINE +@cindex define macro + +This function will define a new macro. You must provide a name for the +macro. You do not specify any arguments, though the invocation may +specify a set of name/value pairs that are to be active during the +processing of the macro. + +@example +[+ define foo +] +... macro body with macro functions ... +[+ enddef +] +... [+ foo bar='raw text' baz=<<text expression>> +] +@end example + +Once the macro has been defined, this new macro can be invoked by +specifying the macro name as the first token after the start macro marker. +Alternatively, you may make the invocation explicitly invoke a defined +macro by specifying @code{INVOKE} (@pxref{INVOKE}) in the macro +invocation. If you do that, the macro name can be computed with an +expression that gets evaluated every time the INVOKE macro is encountered. + +Any remaining text in the macro invocation will be used to create new +name/value pairs that only persist for the duration of the processing of +the macro. The expressions are evaluated the same way basic +expressions are evaluated. @xref{expression syntax}. + +The resulting definitions are handled much like regular +definitions, except: + +@enumerate +@item +The values may not be compound. That is, they may not contain +nested name/value pairs. +@item +The bindings go away when the macro is complete. +@item +The name/value pairs are separated by whitespace instead of +semi-colons. +@item +Sequences of strings are not concatenated. +@end enumerate + +@quotation +@strong{NB:} The macro is extracted from the template as the template is +scanned. You cannot conditionally define a macro by enclosing it in an +@code{IF}/@code{ENDIF} (@pxref{IF}) macro pair. If you need to dynamically +select the format of a @code{DEFINE}d macro, then put the flavors into +separate template files that simply define macros. @code{INCLUDE} +(@pxref{INCLUDE}) the appropriate template when you have computed which +you need. +@end quotation + +Due to this, it is acceptable and even a good idea to place all the +@code{DEFINE} macros at the end of the template. That puts the main +body of the template at the beginning of the file. + +@node ELIF +@subsection ELIF - Alternate Conditional Template Block + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcIf.c line 249. +@end ignore + +@findex ELIF + +This macro must only appear after an @code{IF} function, and +before any associated @code{ELSE} or @code{ENDIF} functions. +It denotes the start of an alternate template block for the +@code{IF} function. Its expression argument is evaluated as are +the arguments to @code{IF}. For a complete description @xref{IF}. + +@node ELSE +@subsection ELSE - Alternate Template Block + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcIf.c line 277. +@end ignore + +@findex ELSE + +This macro must only appear after an @code{IF} function, +and before the associated @code{ENDIF} function. +It denotes the start of an alternate template block for +the @code{IF} function. For a complete description @xref{IF}. + +@node ENDDEF +@subsection ENDDEF - Ends a macro definition. + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcDef.c line 587. +@end ignore + +@findex ENDDEF + +This macro ends the @code{DEFINE} function template block. +For a complete description @xref{DEFINE}. + +@node ENDFOR +@subsection ENDFOR - Terminates the @code{FOR} function template block + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcFor.c line 702. +@end ignore + +@findex ENDFOR + +This macro ends the @code{FOR} function template block. +For a complete description @xref{FOR}. + +@node ENDIF +@subsection ENDIF - Terminate the @code{IF} Template Block + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcIf.c line 123. +@end ignore + +@findex ENDIF + +This macro ends the @code{IF} function template block. +For a complete description @xref{IF}. + +@node ENDWHILE +@subsection ENDWHILE - Terminate the @code{WHILE} Template Block + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcIf.c line 206. +@end ignore + +@findex ENDWHILE + +This macro ends the @code{WHILE} function template block. +For a complete description @xref{WHILE}. + +@node ESAC +@subsection ESAC - Terminate the @code{CASE} Template Block + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcCase.c line 885. +@end ignore + +@findex ESAC + +This macro ends the @code{CASE} function template block. +For a complete description, @xref{CASE}. + +@node EXPR +@subsection EXPR - Evaluate and emit an Expression + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcEval.c line 562. +@end ignore + +@findex EXPR + +This macro does not have a name to cause it to be invoked +explicitly, though if a macro starts with one of the apply codes +or one of the simple expression markers, then an expression +macro is inferred. The result of the expression evaluation +(@pxref{expression syntax}) is written to the current output. + +@node FOR +@subsection FOR - Emit a template block multiple times + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcFor.c line 622. +@end ignore + +@findex FOR +@cindex looping, for +@cindex for loop + +This macro has a slight variation on the standard syntax: +@example +FOR <value-name> [ <separator-string> ] + +FOR <value-name> (...Scheme expression list) + +FOR <value-name> IN "string" [ ... ] +@end example + +Other than for the last form, the first macro argument must be the name of +an AutoGen value. If there is no value associated with the name, the +@code{FOR} template block is skipped entirely. The scope of the @code{FOR} +macro extends to the corresponding @code{ENDFOR} macro. The last form will +create an array of string values named @code{<value-name>} that only exists +within the context of this @code{FOR} loop. With this form, in order to +use a @code{separator-string}, you must code it into the end of the +template block using the @code{(last-for?)} predicate function +(@pxref{SCM last-for?}). + +If there are any arguments after the @code{value-name}, the initial +characters are used to determine the form. If the first character is +either a semi-colon (@code{;}) or an opening parenthesis (@code{(}), then +it is presumed to be a Scheme expression containing the FOR macro specific +functions @code{for-from}, @code{for-by}, @code{for-to}, and/or +@code{for-sep}. @xref{AutoGen Functions}. If it consists of an '@code{i}' +an '@code{n}' and separated by white space from more text, then the +@code{FOR x IN} form is processed. Otherwise, the remaining text is +presumed to be a string for inserting between each iteration of the loop. +This string will be emitted one time less than the number of iterations of +the loop. That is, it is emitted after each loop, excepting for the last +iteration. + +If the from/by/to functions are invoked, they will specify which copies of +the named value are to be processed. If there is no copy of the named +value associated with a particular index, the @code{FOR} template block +will be instantiated anyway. The template must use @code{found-for?} +(@pxref{SCM found-for?}) or other methods for detecting missing +definitions and emitting default text. In this fashion, you can insert +entries from a sparse or non-zero based array into a dense, zero based +array. + +@strong{NB:} the @code{for-from}, @code{for-to}, @code{for-by} and +@code{for-sep} functions are disabled outside of the context of the +@code{FOR} macro. Likewise, the @code{first-for?}, @code{last-for?} +@code{for-index}, and @code{found-for?} functions are disabled outside +of the range of a @code{FOR} block. + +@strong{Also:} the @code{<value-name>} must be a single level name, +not a compound name (@pxref{naming values}). + +@example +[+FOR var (for-from 0) (for-to <number>) (for-sep ",") +] +... text with @code{var}ious substitutions ...[+ +ENDFOR var+] +@end example + +@noindent +this will repeat the @code{... text with @code{var}ious +substitutions ...} <number>+1 times. Each repetition, +except for the last, will have a comma @code{,} after it. + +@example +[+FOR var ",\n" +] +... text with @code{var}ious substitutions ...[+ +ENDFOR var +] +@end example + +@noindent +This will do the same thing, but only for the index +values of @code{var} that have actually been defined. + +@node IF +@subsection IF - Conditionally Emit a Template Block + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcIf.c line 87. +@end ignore + +@findex IF +@cindex conditional emit +@cindex if test + +Conditional block. Its arguments are evaluated (@pxref{EXPR}) and +if the result is non-zero or a string with one or more bytes, +then the condition is true and the text from that point +until a matched @code{ELIF}, @code{ELSE} or @code{ENDIF} is emitted. +@code{ELIF} introduces a conditional alternative if the @code{IF} +clause evaluated FALSE and @code{ELSE} introduces an unconditional +alternative. + +@example +[+IF <full-expression> +] +emit things that are for the true condition[+ + +ELIF <full-expression-2> +] +emit things that are true maybe[+ + +ELSE "This may be a comment" +] +emit this if all but else fails[+ + +ENDIF "This may *also* be a comment" +] +@end example + +@noindent +@code{<full-expression>} may be any expression described in the +@code{EXPR} expression function, including the use of apply-codes +and value-names. If the expression yields an empty string, it +is interpreted as @i{false}. + +@node INCLUDE +@subsection INCLUDE - Read in and emit a template block + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/functions.c line 179. +@end ignore + +@findex INCLUDE + +The entire contents of the named file is inserted at this point. +The contents of the file are processed for macro expansion. The +arguments are eval-ed, so you may compute the name of the file to +be included. The included file must not contain any incomplete +function blocks. Function blocks are template text beginning with +any of the macro functions @samp{CASE}, @samp{DEFINE}, @samp{FOR}, +@samp{IF} and @samp{WHILE}; extending through their respective +terminating macro functions. + +@node INVOKE +@subsection INVOKE - Invoke a User Defined Macro + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcDef.c line 659. +@end ignore + +@findex INVOKE + +User defined macros may be invoked explicitly or implicitly. +If you invoke one implicitly, the macro must begin with the +name of the defined macro. Consequently, this may @strong{not} +be a computed value. If you explicitly invoke a user defined macro, +the macro begins with the macro name @code{INVOKE} followed by +a @i{basic expression} that must yield a known user defined macro. +A macro name _must_ be found, or AutoGen will issue a diagnostic +and exit. + +Arguments are passed to the invoked macro by name. +The text following the macro name must consist of a series of +names each of which is followed by an equal sign (@code{=}) and +a @i{basic expression} that yields a string. + +The string values may contain template macros that are parsed +the first time the macro is processed and evaluated again every +time the macro is evaluated. + +@node RETURN +@subsection RETURN - Leave an INVOKE-d (DEFINE) macro + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/functions.c line 95. +@end ignore + +@findex RETURN + +This will unwind looping constructs inside of a DEFINE-d macro and +return to the invocation point. The output files and diversions +@i{are left alone}. This means it is unwise to start diversions +in a DEFINEd macro and RETURN from it before you have handled the +diversion. Unless you are careful. Here is some rope for you. +Please be careful using it. + +@node SELECT +@subsection SELECT - Selection block for CASE function + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcCase.c line 1218. +@end ignore + +@findex SELECT + +This macro selects a block of text by matching an expression +against the sample text expression evaluated in the @code{CASE} +macro. @xref{CASE}. + +You do not specify a @code{SELECT} macro with the word ``select''. +Instead, you must use one of the 19 match operators described in +the @code{CASE} macro description. + +@node UNKNOWN +@subsection UNKNOWN - Either a user macro or a value name. + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/functions.c line 243. +@end ignore + +@findex UNKNOWN + +The macro text has started with a name not known to AutoGen. If, at run +time, it turns out to be the name of a defined macro, then that macro is +invoked. If it is not, then it is a conditional expression that is +evaluated only if the name is defined at the time the macro is invoked. + +You may not specify @code{UNKNOWN} explicitly. + +@node WHILE +@subsection WHILE - Conditionally loop over a Template Block + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcIf.c line 179. +@end ignore + +@findex WHILE +@cindex conditional emit +@cindex while test + +Conditionally repeated block. Its arguments are evaluated (@pxref{EXPR}) +and as long as the result is non-zero or a string with one or more bytes, +then the condition is true and the text from that point +until a matched @code{ENDWHILE} is emitted. + +@example +[+WHILE <full-expression> +] +emit things that are for the true condition[+ + +ENDWHILE +] +@end example + +@noindent +@code{<full-expression>} may be any expression described in the +@code{EXPR} expression function, including the use of apply-codes +and value-names. If the expression yields an empty string, it +is interpreted as @i{false}. +@node shell command +@subsection Inserting text from a shell script + +If the text between the start and end macro markers starts with an opening +curly brace ('@code{@{}') or is surrounded by back quotes ('@code{`}'), then +the text is handed off to the server shell for evaluation. The output to +standard out is inserted into the document. If the text starts with the +curly brace, all the text is passed off as is to the shell. If surrounded by +back quotes, then the string is ``cooked'' before being handed off to the +shell. + +@node guile command +@subsection Inserting text from a scheme script + +If the text between the start and end macro markers starts with a semi-colon +or an opening parenthesis, all the text is handed off to the Guile/scheme +processor. If the last result is text or a number, it is added (as text) +to the output document. + +@ignore +START == AUGMENTING == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore + +@c === SECTION MARKER + +@node output controls +@section Redirecting Output +@cindex Redirecting Output +@cindex diversion + +AutoGen provides a means for redirecting the template output to different +files or, in @file{M4} parlance, to various diversions. It is accomplished +by providing a set of Scheme functions named @code{out-*} +(@pxref{AutoGen Functions}). + +@table @samp +@item out-push-new (@pxref{SCM out-push-new}) +This allows you to logically "push" output files onto a stack. +If you supply a string name, then a file by that name is created +to hold the output. If you do not supply a name, then the text is +written to a scratch pad and retrieved by passing a @code{#t} argument +to the @code{out-pop} (@pxref{SCM out-pop}) function. + +@item out-pop (@pxref{SCM out-pop}) +This function closes the current output file and resumes output to the next +one in the stack. At least one output must have been pushed onto the output +stack with the @code{out-push-new} (@pxref{SCM out-push-new}) function. If +@code{#t} is passed in as an argument, then the entire contents of the +diversion (or file) is returned. + +@item out-suspend (@pxref{SCM out-suspend}) +This function does not close the current output, but instead sets it aside +for resumption by the given name with @code{out-resume}. The current output +must have been pushed on the output queue with @code{out-push-new} +(@pxref{SCM out-push-new}). + +@item out-resume (@pxref{SCM out-resume}) +This will put a named file descriptor back onto the top of +stack so that it becomes the current output again. + +@item out-switch (@pxref{SCM out-switch}) +This closes the current output and creates a new file, +purging any preexisting one. This is a shortcut for "pop" +followed by "push", but this can also be done at the base level. + +@item out-move (@pxref{SCM out-move}) +Renames the current output file without closing it. +@end table + +There are also several functions for determining the output +status. @xref{AutoGen Functions}. + +@ignore + +* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +@end ignore + +@page +@node Augmenting AutoGen +@chapter Augmenting AutoGen Features +@cindex Augmenting AutoGen + +AutoGen was designed to be simple to enhance. You can do it by +providing shell commands, Guile/Scheme macros or callout functions +that can be invoked as a Guile macro. Here is how you do these. + +@menu +* shell commands:: Shell Output Commands +* guile macros:: Guile Macros +* guile callouts:: Guile Callout Functions +* AutoGen macros:: AutoGen Macros +@end menu + +@c === SECTION MARKER + +@node shell commands +@section Shell Output Commands + +Shell commands are run inside of a server process. This means that, +unlike @file{make}, context is kept from one command to the next. +Consequently, you can define a shell function in one place inside of +your template and invoke it in another. You may also store values +in shell variables for later reference. If you load functions from +a file containing shell functions, they will remain until AutoGen exits. + +If your shell script should determine that AutoGen should stop +processing, the recommended method for stopping AutoGen is: +@example +die "some error text" +@end example + +@noindent +That is a shell function added by AutoGen. It will send a SIGTERM +to autogen and exit from the "persistent" shell. + +@c === SECTION MARKER + +@node guile macros +@section Guile Macros + +Guile also maintains context from one command to the next. This means you may +define functions and variables in one place and reference them elsewhere. +If your Scheme script should determine that AutoGen should stop +processing, the recommended method for stopping AutoGen is: +@example +(error "some error text") +@end example + +@c === SECTION MARKER + +@node guile callouts +@section Guile Callout Functions + +Callout functions must be registered with Guile to work. This can +be accomplished either by putting your routines into a shared library +that contains a @code{void scm_init(void)} routine that registers +these routines, or by building them into AutoGen. + +To build them into AutoGen, you must place your routines in the source +directory and name the files @file{exp*.c}. You also must have a stylized +comment that @file{getdefs} can find that conforms to the following: + +@example +/*=gfunc <function-name> + * + * what: <short one-liner> + * general_use: + * string: <invocation-name-string> + * exparg: <name>, <description> [, ['optional'] [, 'list']] + * doc: A long description telling people how to use + * this function. +=*/ +SCM +ag_scm_<function-name>( SCM arg_name[, ...] ) +@{ <code> @} +@end example + +@table @samp +@item gfunc +You must have this exactly thus. + +@item <function-name> +This must follow C syntax for variable names + +@item <short one-liner> +This should be about a half a line long. +It is used as a subsection title in this document. + +@item general_use: +You must supply this unless you are an AutoGen maintainer and are writing +a function that queries or modifies the state of AutoGen. + +@item <invocation-name-string> +Normally, the @var{function-name} string will be transformed into +a reasonable invocation name. However, that is not always true. +If the result does not suit your needs, then supply an alternate string. + +@item exparg: +You must supply one for each argument to your function. +All optional arguments must be last. +The last of the optional arguments may be a list, if you choose. + +@item doc: +Please say something meaningful. + +@item [, ...] +Do not actually specify an ANSI ellipsis here. You must provide +for all the arguments you specified with @var{exparg}. +@end table + +See the Guile documentation for more details. +More information is also available in a large comment at the +beginning of the @file{agen5/snarf.tpl} template file. + +@c === SECTION MARKER + +@node AutoGen macros +@section AutoGen Macros + +There are two kinds@: those you define yourself and AutoGen native. +The user-defined macros may be defined in your templates, +@xref{DEFINE}. + +As for AutoGen native macros, do not add any. It is easy to do, but I +won't like it. The basic functions needed to accomplish looping over +and selecting blocks of text have proved to be sufficient over a period +of several years. New text transformations can be easily added via any +of the AutoGen extension methods, as discussed above. + +@ignore +END == AUGMENTING == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore +@ignore + +Invocation section from invoke-autogen.texi + +@end ignore +@page + +@include invoke-autogen.texi + +@ignore +START == INSTALLATION == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore + +@page +@node Installation +@chapter Configuring and Installing + +@menu +* configuring:: Configuring AutoGen +* AutoGen CGI:: AutoGen as a CGI server +* signal names:: Signal Names +* installing:: Installing AutoGen +@end menu + +@c === SECTION MARKER + +@node configuring +@section Configuring AutoGen +@cindex configuring + +AutoGen is configured and built using Libtool, Automake and Autoconf. +Consequently, you can install it wherever you wish using the @samp{--prefix} +and other options. To the various configuration options supplied by these +tools, AutoGen adds a few of its own: + +@table @samp +@item --disable-shell +AutoGen is now capable of acting as a CGI forms server, @xref{AutoGen CGI}. +As such, it will gather its definitions using either @samp{GET} or +@samp{POST} methods. All you need to do is have a template named +@file{cgi.tpl} handy or specify a different one with a command line +option. + +However, doing this without disabling the server shell brings +considerable risk. If you were to pass user input to a script +that contained, say, the classic "@samp{`rm -rf /`}", you might have +a problem. This configuration option will cause shell template +commands to simply return the command string as the result. +No mistakes. Much safer. Strongly recommended. +The default is to have server shell scripting enabled. + +Disabling the shell will have some build side effects, too. + +@itemize @bullet +@item +Many of the make check tests will fail, since they assume +a working server shell. +@item +The getdefs and columns programs are not built. +The options are distributed as definition files and they +cannot be expanded with a shell-disabled AutoGen. +@item +Similarly, the documentation cannot be regenerated because +the documentation templates depend on subshell functionality. +@end itemize + +@item --enable-debug +Turning on AutoGen debugging enables very detailed inspection of +the input definitions and monitoring shell script processing. +These options are not particularly useful to anyone not directly +involved in maintaining AutoGen. If you do choose to enable AutoGen +debugging, be aware that the usage page was generated without these +options, so when the build process reaches the documentation rebuild, +there will be a failure. @samp{cd} into the @file{agen5} build +directory, @samp{make} the @samp{autogen.texi} file and all will +be well thereafter. + +@item --with-regex-header +@itemx --with-header-path +@itemx --with-regex-lib +These three work together to specify how to compile with and link to a +particular POSIX regular expression library. The value for +@file{--with-regex-header=value} must be the name of the relevant header file. +The AutoGen sources will attempt to include that source with a +@code{#include <value>} C preprocessing statement. The @var{path} from the +@option{--with-header-path=path} will be added to @code{CPPFLAGS} as +@option{-Ipath}. The @var{lib-specs} from @option{--with-regex-lib=lib-specs} +will be added to @code{LDFLAGS} without any adornment. +@end table + +@c === SECTION MARKER + +@page +@node AutoGen CGI +@section AutoGen as a CGI server + +AutoGen is now capable of acting as a CGI forms server. +It behaves as a CGI server if the definitions input is from stdin +and the environment variable @env{REQUEST_METHOD} is defined +and set to either "GET" or "POST". If set to anything else, +AutoGen will exit with a failure message. When set to one of those +values, the CGI data will be converted to AutoGen definitions +(@pxref{Definitions File}) and the template named "@file{cgi.tpl}" +will be processed. + +This works by including the name of the real template to process +in the form data and having the "@file{cgi.tpl}" template include +that template for processing. I do this for processing the form +@url{http://autogen.sourceforge.net/conftest.html}. The "@file{cgi.tpl}" +looks approximately like this: + +@example +<? AutoGen5 Template ?> +<? +IF (not (exist? "template")) ?><? + form-error ?><? + +ELIF (=* (get "template") "/") ?><? + form-error ?><? + +ELIF (define tpl-file (string-append "cgi-tpl/" + (get "template"))) + (access? tpl-file R_OK) ?><? + INCLUDE (. tpl-file) ?><? + +ELIF (set! tpl-file (string-append tpl-file ".tpl")) + (access? tpl-file R_OK) ?><? + INCLUDE (. tpl-file) ?><? + +ELSE ?><? + form-error ?><? +ENDIF ?> +@end example + +@noindent +This forces the template to be found in the "@file{cgi-tpl/}" +directory. Note also that there is no suffix specified in the +pseudo macro (@pxref{pseudo macro}). That tells AutoGen to emit +the output to @file{stdout}. + +The output is actually spooled until it is complete so that, +in the case of an error, the output can be discarded and a proper +error message can be written in its stead. + +@strong{Please also note} that it is advisable, @emph{especially} for network +accessible machines, to configure AutoGen (@pxref{configuring}) with +shell processing disabled (@option{--disable-shell}). That will make it +impossible for any referenced template to hand data to a subshell for +interpretation. + +@c === SECTION MARKER + +@node signal names +@section Signal Names +@cindex Signal Names + +When AutoGen is first built, it tries to use @code{psignal(3)}, +@code{sys_siglist}, @code{strsigno(3)} and @code{strsignal(3)} from the +host operating system. If your system does not supply these, the +AutoGen distribution will. However, it will use the distributed mapping +and this mapping is unlikely to match what your system uses. This can +be fixed. Once you have installed autogen, the mapping can be rebuilt +on the host operating system. To do so, you must perform the +following steps: + +@enumerate +@item +Build and install AutoGen in a place where it will be found in your +search path. +@item +@file{cd $@{top_srcdir@}/compat} +@item +@samp{autogen strsignal.def} +@item +Verify the results by examining the @file{strsignal.h} file produced. +@item +Re-build and re-install AutoGen. +@end enumerate + +If you have any problems or peculiarities that cause this process to +fail on your platform, please send me copies of the header files +containing the signal names and numbers, along with the full path names +of these files. I will endeavor to fix it. There is a shell script +inside of @file{strsignal.def} that tries to hunt down the information. + +@c === SECTION MARKER + +@node installing +@section Installing AutoGen +@cindex Installing + +There are several files that get installed. The number depend +whether or not both shared and archive libraries are to be +installed. The following assumes that everything is installed +relative to @env{$prefix}. You can, of course, use +@command{configure} to place these files where you wish. + +@strong{NB}@: AutoGen does not contain any compiled-in path names. +All support directories are located via option processing, +the environment variable @env{HOME} or finding the directory where +the executable came from. + +The installed files are: + +@enumerate +@item +The executables in @file{bin} (autogen, getdefs and columns). + +@item +The AutoOpts link libraries as @file{lib/libopts.*}. + +@item +An include file in @file{include/options.h}, needed for +Automated Option Processing (see next chapter). + +@item +Several template files and a scheme script in @file{share/autogen}, needed +for Automated Option Processing (@pxref{AutoOpts}), parsing definitions +written with scheme syntax (@pxref{Dynamic Text}), the templates for +producing documentation for your program (@pxref{documentation attributes}), +autoconf test macros, and AutoFSM. + +@item +Info-style help files as @file{info/autogen.info*}. +These files document AutoGen, the option processing +library AutoOpts, and several add-on components. + +@item +The three man pages for the three executables are installed in man/man1. +@end enumerate + +This program, library and supporting files can be installed +with three commands: + +@itemize @bullet +@item +<src-dir>/configure [ <configure-options> ] +@item +make +@item +make install +@end itemize + +However, you may wish to insert @samp{make check} +before the @samp{make install} command. + +If you do perform a @samp{make check} and there are any failures, you +will find the results in @file{<module>/test/FAILURES}. Needless to say, I +would be interested in seeing the contents of those files and any +associated messages. If you choose to go on and analyze one of these +failures, you will need to invoke the test scripts individually. You +may do so by specifying the test (or list of test) in the TESTS make +variable, thus: + +@example +gmake TESTS=test-name.test check +@end example + +I specify @command{gmake} because most makes will not let you override +internal definitions with command line arguments. @command{gmake} does. + +All of the AutoGen tests are written to honor the contents of the +@t{VERBOSE} environment variable. Normally, any commentary generated +during a test run is discarded unless the @t{VERBOSE} environment +variable is set. So, to see what is happening during the test, you +might invoke the following with @i{bash} or @i{ksh}: + +@example +VERBOSE=1 gmake TESTS="for.test forcomma.test" check +@end example + +@noindent +Or equivalently with @i{csh}: + +@example +env VERBOSE=1 gmake TESTS="for.test forcomma.test" check +@end example + +@ignore +END == INSTALLATION == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore +@page +@node AutoOpts +@chapter Automated Option Processing +@cindex autoopts + +AutoOpts 42.1 is bundled with AutoGen. It is a tool that virtually eliminates the +hassle of processing options and keeping man pages, info docs and usage text +up to date. This package allows you to specify several program attributes, +thousands of option types and many option attributes. From this, it then +produces all the code necessary to parse and handle the command line and +configuration file options, and the documentation that should go with your +program as well. +@ignore +START == AUTOOPTS == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore + +All the features notwithstanding, some applications simply have +well-established command line interfaces. Even still, those programs +may use the configuration file parsing portion of the library. +See the ``AutoOpts Features'' and ``Configuration File Format'' sections. + +@menu +* Features:: AutoOpts Features +* Licensing:: AutoOpts Licensing +* Caveats:: Developer and User Notes +* Quick Start:: Quick Start +* Option Definitions:: Option Definitions +* AutoOpts API:: Programmatic Interface +* Multi-Threading:: Multi-Threading +* option descriptor:: Option Descriptor File +* Using AutoOpts:: Using AutoOpts +* Presetting Options:: Configuring your program +* Config File Format:: Configuration File Format +* shell options:: AutoOpts for Shell Scripts +* AutoInfo:: Automated Info Docs +* AutoMan pages:: Automated Man Pages +* getopt_long:: Using getopt(3C) +* i18n:: Internationalizing AutoOpts +* Naming Conflicts:: Naming Conflicts +* All Attribute Names:: All Attribute Names +* Option Define Names:: Option Definition Name Index +@end menu + +@c === SECTION MARKER + +@node Features +@section AutoOpts Features +@cindex features + +AutoOpts supports option processing; option state saving; and +program documentation with innumerable features. Here, we list +a few obvious ones and some important ones, but the full list is +really defined by all the attributes defined in the @ref{Option Definitions} +section. + +@enumerate +@item +POSIX-compliant short (flag) option processing. + +@item +GNU-style long options processing. Long options +are recognized without case sensitivity, and they may be abbreviated. + +@item +Environment variable initializations, @xref{environrc}. + +@item +Initialization from configuration files (aka RC or INI files), and +saving the option state back into one, @xref{loading rcfile}. + +@item +Config files may be partitioned. One config file may be used by several +programs by partitioning it with lines containing, +@code{[PROGRAM_NAME]} or @code{<?program-name>}, @xref{loading rcfile}. + +@item +Config files may contain AutoOpts directives. +@code{<?auto-options [[option-text]]>} +may be used to set @code{AutoOpts} option processing options. +Viz., @acronym{GNU} usage layout versus @code{AutoOpts} conventional layout, +and @code{misuse-usage} versus @code{no-misuse-usage}, @xref{usage attributes}. + +@item +Options may be marked as @code{@i{dis}-abled} with a disablement prefix. +Such options may default to either an enabled or a disabled state. You +may also provide an enablement prefix, too, e.g., @option{--allow-mumble} +and @option{--prevent-mumble} (@pxref{Common Attributes}). + +@item +Verify that required options are present between the minimum and maximum +number of times on the command line. Verify that conflicting options do not +appear together. Verify that options requiring the presence of other options +are, in fact, used in the presence of other options. +See @xref{Common Attributes}, and @xref{Option Conflict Attributes}. + +@item +There are several @ref{automatic options, automatically supported options}. +They will have short flags if any options have option flags and the flags +are not suppressed. The associated flag may be altered or suppressed by +specifying no value or an alternate character for @code{xxx-value;} in +the option definition file. @code{xxx} is the name of the option below: + +@table @samp +@item --help +@itemx --more-help +These are always available. @samp{--more-help} will pass the full usage +text through a pager. +@item --usage +@vindex usage-opt +This is added to the option list if @code{usage-opt} is specified. +It yields the abbreviated usage to @file{stdout}. +@item --version +This is added to the option list if @code{version = xxx;} is specified. +@item --load-opts +@itemx --save-opts +These are added to the option list if @code{homerc} is specified. Mostly. +If, @code{disable-save} is specified, then @option{--save-opts} is disabled. +@end table + +@item +Various forms of main procedures can be added to the output, +@xref{Generated main}. There are four basic forms: + +@enumerate a +@item +A program that processes the arguments and writes to standard out +portable shell commands containing the digested options. + +@item +A program that will generate portable shell commands to parse the defined +options. The expectation is that this result will be copied into a +shell script and used there. + +@item +A @code{for-each} main that will invoke a named function once for either +each non-option argument on the command line or, if there are none, +then once for each non-blank, non-comment input line read from stdin. + +@item +A main procedure of your own design. Its code can be supplied in the +option description template or by incorporating another template. +@end enumerate + +@item +There are several methods for handling option arguments. +@itemize @bullet +@item +nothing (@pxref{OPT_ARG}) option argument strings are globally available. +@item +user supplied (@pxref{Option Argument Handling}) +@item +stack option arguments (@pxref{Option Argument Handling}) +@item +integer numbers (@pxref{arg-type number}) +@item +true or false valued (@pxref{arg-type boolean}) +@item +enumerated list of names (@pxref{arg-type keyword}) +@item +an enumeration (membership) set (@pxref{arg-type set membership}) +@item +a list of name/value pairs (option @code{subopts}) +(@pxref{arg-type hierarchy}) +@item +a time duration or a specific time and date +@item +validated file name (@pxref{arg-type file name}) +@item +optional option argument (@pxref{arg-optional}) +@end itemize + +@item +The generated usage text can be emitted in either AutoOpts standard format +(maximizing the information about each option), or GNU-ish normal form. The +default form is selected by either specifying or not specifying the +@code{gnu-usage} attribute (@pxref{information attributes}). This can be +overridden by the user himself with the @env{AUTOOPTS_USAGE} environment +variable. If it exists and is set to the string @samp{gnu}, it will force +GNU-ish style format; if it is set to the string @samp{autoopts}, it will +force AutoOpts standard format; otherwise, it will have no effect. + +@item +The usage text and many other strings are stored in a single character array +(@pxref{SCM string-table-new,string table functions}). This reduces fixup +costs when loading the program or library. The downside is that if GCC +detects that any of these strings are used in a printf format, you may get the +warning, @code{embedded '\0' in format}. To eliminate the warning, you must +provide GCC with the @option{-Wno-format-contains-nul} option. + +@item +If you compile with @code{ENABLE_NLS} defined and @code{_()} defined to a +localization function (e.g. @code{gettext(3GNU)}), then the option processing +code will be localizable (@pxref{i18n}). Provided also that you do not define +the @code{no-xlate} attribute to @emph{anything} +(@pxref{presentation attributes}). + +You should also ensure that the @code{ATTRIBUTE_FORMAT_ARG()} gets +@code{#define}-ed to something useful. There is an autoconf macro +named @code{AG_COMPILE_FORMAT_ARG} in @file{ag_macros.m4} that will +set it appropriately for you. If you do not do this, then translated +formatting strings may trigger GCC compiler warnings. + +@item +Provides a callable routine to parse +a text string as if it were from one of the rc/ini/config files, +hereafter referred to as a configuration file. + +@item +By adding a @samp{doc} and @samp{arg-name} attributes to each option, +AutoGen will also be able to produce a man page and the @samp{invoking} +section of a texinfo document. + +@item +Intermingled option processing. AutoOpts options may be intermingled with +command line operands and options processed with other parsing techniques. +This is accomplished by setting the @code{allow-errors} +(@pxref{program attributes}) attribute. When processing reaches a point +where @code{optionProcess} (@pxref{libopts-optionProcess}) needs to be called +again, the current option can be set with @code{RESTART_OPT(n)} +(@pxref{RESTART_OPT}) before calling @code{optionProcess}. + +See: @xref{library attributes}. + +@item +Library suppliers can specify command line options that their +client programs will accept. They specify option definitions +that get @code{#include}-d into the client option definitions +and they specify an "anchor" option that has a callback and must be invoked. +That will give the library access to the option state for their options. + +@item +library options. An AutoOpt-ed library may export its options for use in +an AutoOpt-ed program. This is done by providing an option definition file +that client programs @code{#include} into their own option definitions. +See ``AutoOpt-ed Library for AutoOpt-ed Program'' (@pxref{lib and program}) +for more details. +@end enumerate + +@c === SECTION MARKER + +@node Licensing +@section AutoOpts Licensing +@cindex Licensing + +When AutoGen is installed, the AutoOpts project is installed with it. +AutoOpts includes various AutoGen templates and a pair of shared +libraries. These libraries may be used under the terms of version 3 +of the GNU Lesser General Public License (LGPL). + +One of these libraries (@code{libopts}) is needed by programs that are built +using AutoOpts generated code. This library is available as a separate +``tear-off'' source tarball. It is redistributable for use under either of +two licenses: The above mentioned GNU Lesser General Public License, and +the advertising-clause-free BSD license. Both of these license terms are +incorporated into appropriate COPYING files included with the @code{libopts} +source tarball. This source may be incorporated into your package with +the following simple commands: + +@example +rm -rf libopts libopts-* +gunzip -c `autoopts-config libsrc` | \ + tar -xvf - +mv libopts-*.*.* libopts +@end example + +View the @file{libopts/README} file for further integration information. + +@c === SECTION MARKER + +@page +@node Caveats +@section Developer and User Notes + +The formatting of the usage message can be controlled with the use of the +@env{AUTOOPTS_USAGE} environment variable. If it contains any of five +possible comma separated values, it will affect @file{libopts} behavior. +Any extraneous or conflicting data will cause its value to be ignored. + +If the program attributes @code{long-usage} and @code{short-usage} have been +specified (@pxref{usage attributes,Usage and Version Info Display}), these +strings are used for displaying full usage and abbreviated usage. +``Full usage'' is used when usage is requested, ``abbreviated usage'' +when a usage error is detected. If these strings are not provided, +the usage text is computed. + +The @env{AUTOOPTS_USAGE} environment variable may be set to the comma and/or +white space separated list of the following strings: + +@table @samp +@item compute +Ignore the provision of @code{long-usage} and @code{short-usage} attributes, +and compute the usage strings. This is useful, for example, if you wish to +regenerate the basic form of these strings and either tweak them or translate +them. The methods used to compute the usage text are not suitable for +translation. + +@item gnu +@cindex gnu +The format of the usage text will be displayed in GNU-normal form. +The default display for @option{--version} will be to include a note +on licensing terms. + +@item autoopts +@cindex autoopts +The format of the extended usage will be in AutoOpts' native layout. The +default version display will be one line of text with the last token the +version. @code{gnu} and @code{autoopts} conflict and may not be used +together. + +@item no-misuse-usage +@cindex no-misuse-usage +When an option error is made on the command line, the abbreviated usage text +will be suppressed. An error message and the method for getting full usage +information will be displayed. + +@item misuse-usage +@cindex misuse-usage +When an option error is made on the command line, the abbreviated usage text +will be shown. @code{misuse-usage} and @code{no-misuse-usage} conflict and +may not be used together. +@end table + +@code{misuse-usage} and @code{autoopts} are the defaults. +These defaults may be flipped to @code{no-misuse-usage} and @code{gnu} +by specifying @code{gnu-usage} and @code{no-misuse-usage} +program attributes, respectively, in the option definition file. + +@noindent +@i{Note for developers}: + +The templates used to implement AutoOpts depend heavily upon token pasting. +That mens that if you name an option, @code{debug}, for example, the generated +header will expect to be able to emit @code{#define} macros such as this: +@example +#define DESC(n) (autogenOptions.pOptDesc[INDEX_OPT_## n]) +@end example +and expect @code{DESC(DEBUG)} to expand correctly into +@code{(autogenOptions.pOptDesc[INDEX_OPT_DEBUG])}. +If @code{DEBUG} is @code{#defined} to something else, then +that something else will be in the above expansion. + +If you discover you are having strange problems like this, +you may wish to use some variation of the @code{guard-option-names} +@xref{program attributes}. + +@c === SECTION MARKER + +@page +@node Quick Start +@section Quick Start +@cindex example, simple AutoOpts + +Since it is generally easier to start with a simple example than it is +to look at the options that AutoGen uses itself, here is a very simple +AutoOpts example. You can copy this example out of the Info file and +into a source file to try it. You can then embellish it into what you +really need. For more extensive examples, you can also examine the help +output and option definitions for the commands @command{columns}, +@command{getdefs} and @command{autogen} itself. + +If you are looking for a more extensive example, +you may search the autogen sources for files named @file{*opts.def}. +@command{xml2ag} is ridiculous and @command{autogen} is very lengthy, +but @command{columns} and @command{getdefs} are not too difficult. +The @command{sharutils} sources are fairly reasonable, too. + +@menu +* quick ao problem:: Example option requirements +* quick ao def:: Example option definitions +* quick ao build:: Build the example options +* quick ao help:: Example option help text +* quick ao usage:: Using the example options +* quick ao docs:: Example option documentation +@end menu + +@node quick ao problem +@subsection Example option requirements + +For our simple example, assume you have a program named @command{check} +that takes two options: + +@enumerate +@item +A list of directories to check over for whatever it is @command{check} does. +You want this option available as a POSIX-style flag option +and a GNU long option. You want to allow as many of these +as the user wishes. +@item +An option to show or not show the definition tree being used. +Only one occurrence is to be allowed, specifying one or the other. +@end enumerate + +@node quick ao def +@subsection Example option definitions + +@noindent +First, specify your program attributes and its options to AutoOpts, +as with the following example. + +@example +@ignore +END == AUTOOPTS == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore +AutoGen Definitions options; +prog-name = check; +prog-title = "Checkout Automated Options"; +long-opts; +gnu-usage; /* GNU style preferred to default */ + +main = @{ main-type = shell-process; @}; + +flag = @{ + name = check-dirs; + value = L; /* flag style option character */ + arg-type = string; /* option argument indication */ + max = NOLIMIT; /* occurrence limit (none) */ + stack-arg; /* save opt args in a stack */ + descrip = "Checkout directory list"; + doc = 'name of each directory that is to be "checked out".'; +@}; + +flag = @{ + name = show_defs; + descrip = "Show the definition tree"; + disable = dont; /* mark as enable/disable type */ + /* option. Disable as `dont-' */ + doc = 'disable, if you do not want to see the tree.'; +@}; +@end example + +@node quick ao build +@subsection Build the example options + +This program will produce a program that digests its options and +writes the values as shell script code to stdout. +Run the following short script to produce this program: +@example +base=check +BASE=`echo $base | tr '[a-z-]' '[A-Z_]'` +cflags="-DTEST_$@{BASE@} `autoopts-config cflags`" +ldflags="`autoopts-config ldflags`" +autogen $@{base@}.def +cc -o $@{base@} -g $@{cflags@} $@{base@}.c $@{ldflags@} +./$@{base@} --help +@end example + +@node quick ao help +@subsection Example option help text + +Running the build commands yields: + +@example + +exit 0 +@end example +@ignore +START == AUTOOPTS-MAIN == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore + +@node quick ao usage +@subsection Using the example options + +Normally, however, you would not use the @code{main} clause. Instead, +the file would be named something like @file{checkopt.def}, you would +compile @file{checkopt.c} the usual way, and link the object with the rest +of your program. + +The options are processed by calling @code{optionProcess} +(@pxref{libopts-optionProcess}): + +@example +main( int argc, char** argv ) +@{ + @{ + int optct = optionProcess( &checkOptions, argc, argv ); + argc -= optct; + argv += optct; + @} +@end example + +The options are tested and used as in the following fragment. +@code{ENABLED_OPT} is used instead of @code{HAVE_OPT} for the +@option{--show-defs} option because it is an enabled/disabled option type: + +@example + if ( ENABLED_OPT( SHOW_DEFS ) + && HAVE_OPT( CHECK_DIRS )) @{ + int dirct = STACKCT_OPT( CHECK_DIRS ); + char** dirs = STACKLST_OPT( CHECK_DIRS ); + while (dirct-- > 0) @{ + char* dir = *dirs++; + ... +@end example + +@node quick ao docs +@subsection Example option documentation + +The @code{doc} clauses are used in the flag stanzas for man pages and texinfo +invoking documentation. With the definition file described above, the two +following commands will produce the two documentation files @file{check.1} and +@file{invoke-check.texi}. The latter file will be generated as a chapter, +rather than a section or subsection. + +@example +autogen -Tagman-cmd check.def +autogen -DLEVEL=chapter -Tagtexi-cmd -binvoke-check.texi check.def +@end example + +@noindent +The result of which is left as an exercise for the reader. + +A lot of magic happens to make this happen. +The rest of this chapter will describe the myriad of option attributes +supported by AutoOpts. However, keep in mind that, in general, you won't +need much more than what was described in this "quick start" section. + +@node Option Definitions +@section Option Definitions +@cindex Option Definitions + +AutoOpts uses an AutoGen definitions file for the definitions of the +program options and overall configuration attributes. +The complete list of program and option attributes is quite extensive, +so if you are reading to understand how to use AutoOpts, I recommend +reading the "Quick Start" section (@pxref{Quick Start}) and paying +attention to the following: + +@enumerate +@item +@code{prog-name}, @code{prog-title}, and @code{argument}, program +attributes, @xref{program attributes}. +@item +@code{name} and @code{descrip} option attributes, @xref{Required Attributes}. +@item +@code{value} (flag character) and @code{min} (occurrence counts) +option attributes, @xref{Common Attributes}. +@item +@code{arg-type} from the option argument specification section, +@xref{Option Arguments}. +@item +Read the overall how to, @xref{Using AutoOpts}. +@item +Highly recommended, but not required, are the several "man" and +"info" documentation attributes, @xref{documentation attributes}. +@end enumerate + +Keep in mind that the majority are rarely used and can be safely +ignored. However, when you have special option processing requirements, +the flexibility is there. + +@menu +* program attributes:: Program Description Attributes +* library attributes:: Options for Library Code +* information attributes:: Program Information Attributes +* Generated main:: Generating main procedures +* option attributes:: Option Attributes +* Option Arguments:: Option Argument Specification +* Option Argument Handling:: Option Argument Handling +* Internationalizing Options:: Internationalizing Options +* documentation attributes:: Man and Info doc Attributes +* automatic options:: Automatically Supported Options +* standard options:: Library of Standard Options +@end menu + +@node program attributes +@subsection Program Description Attributes +@cindex program attributes + +The following global definitions are used to define attributes of the entire +program. These generally alter the configuration or global behavior of the +AutoOpts option parser. The first two are required of every program. The +third is required if there are to be any left over arguments (operands) +after option processing. The rest have been grouped below. Except as noted, +there may be only one copy of each of these definitions: + +@table @samp + +@item prog-name +@vindex prog-name +This attribute is required. Variable names derived from this name +are derived using @code{string->c_name!} (@pxref{SCM string->c-name!}). + +@item prog-title +@vindex prog-title +This attribute is required and may be any descriptive text. + +@item argument +@vindex argument +This attribute is required if your program uses operand arguments. +It specifies the syntax of the arguments that @strong{follow} the options. +It may not be empty, but if it is not supplied, then option processing +must consume all the arguments. If it is supplied and starts with an +open bracket (@code{[}), then there is no requirement on the presence or +absence of command line arguments following the options. Lastly, if it +is supplied and does not start with an open bracket, then option +processing must @strong{not} consume all of the command line arguments. + +@item config-header +@vindex config-header +If your build has a configuration header, it must be included before +anything else. Specifying the configuration header file name with this +attribute will cause that to happen. +@end table + +@menu +* usage attributes:: Usage and Version Info Display +* config attributes:: Program Configuration +* programming attributes:: Programming Details +* presentation attributes:: User Presentation Attributes +@end menu + +@c +@c = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +@c +@node usage attributes +@subsubsection Usage and Version Info Display + +These will affect the way usage is seen and whether or not version +information gets displayed. + +@table @samp +@item full-usage +@vindex full-usage +If this attribute is provided, it may specify the full length +usage text, or a variable name assignable to a @code{char const *} pointer, +or it may be empty. The meanings are determined by the length. +@itemize @bullet +@item +If not provided, the text will be computed as normal. +@item +If the length is zero, then the usage text will be derived from +the current settings and inserted as text into the generated .c file. +@item +If the length is 1 to 32 bytes, then it is presumed to be a variable +name that either points to or is an array of const chars. +@item +If it is longer than that, it is presumed to be the help text itself. +This text will be inserted into the generated .c file. +@end itemize + +This string should be readily translatable. Provision will be made +to translate it if this is provided, if the source code is compiled with +@code{ENABLE_NLS} defined, and @code{no-xlate} has not been set to the +value @emph{anything}. The untranslated text will be handed to +@code{dgettext("libopts", @i{txt})} and then @code{gettext(@i{txt})} +for translation, one paragraph at a time. + +To facilitate the creation and maintenance of this text, you can +force the string to be ignored and recomputed by specifying +@example +AUTOOPTS_USAGE=compute +@end example +@noindent +in the environment and requesting help or usage information. +See @xref{Caveats, Developer and User Notes}. + +@item short-usage +@vindex short-usage +If this attribute is provided, it is used to specify an abbreviated +version of the usage text. This text is constructed in the same way +as the @code{full-usage}, described above. + +@item gnu-usage +@vindex gnu-usage +AutoOpts normaly displays usage text in a format that provides more +information than the standard GNU layout, but that also means it is +not the standard GNU layout. This attribute changes the default to +GNU layout, with the @env{AUTOOPTS_USAGE} environment variable used +to request @code{autoopts} layout. +See @xref{Caveats, Developer and User Notes}. + +@item usage-opt +@vindex usage-opt +I apologize for too many confusing usages of usage. +This attribute specifies that @option{--usage} and/or @option{-u} be +supported. The help (usage) text displayed will be abbreviated +when compared to the default help text. + +@item no-misuse-usage +@vindex no-misuse-usage +When there is a command line syntax error, by default AutoOpts will +display the abbreviated usage text, rather than just a one line +``you goofed it, ask for usage'' message. You can change the default +behavior for your program by supplying this attribute. The user may +override this choice, again, with the @env{AUTOOPTS_USAGE} environment +variable. See @xref{Caveats, Developer and User Notes}. + +@item prog-group +@vindex prog-group +The version text in the @file{getopt.tpl} template will include this +text in parentheses after the program name, when this attribute is specified. +For example: +@example +mumble (stumble) 1.0 +@end example +@noindent +says that the @samp{mumble} program is version 1.0 and is part of the +@samp{stumble} group of programs. + +@item usage +@vindex usage +If your program has some cleanup work that must be done before exiting +on usage mode issues, or if you have to customize the usage message in +some way, specify this procedure and it will be called instead of the +default @code{optionUsage()} function. For example, if a program is +using the curses library and needs to invoke the usage display, then +you must arrange to call @code{endwin()} before invoking the library +function @code{optionUsage()}. This can be handled by specifying your +own usage function, thus: +@example +void +my_usage(tOptions * opts, int ex) +@{ + if (curses_window_active) + endwin(); + optionUsage(opts, ex); +@} +@end example + +@item version +@vindex version +Specifies the program version and activates the VERSION option, +@xref{automatic options}. +@end table + +@c +@c = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +@c +@node config attributes +@subsubsection Program Configuration + +Programs may be ``pre-configured'' before normal command line options +are processed (See @pxref{Immediate Action, Immediate Action Attributes}). +How configuration files and environment variables are handled get +specified with these attributes. + +@table @samp +@item disable-load +@itemx disable-save +@vindex disable-load +@vindex disable-save +Indicates that the command line usage of @option{--load-opts} and/or +@option{--save-opts} are disallowed. + +@item environrc +@vindex environrc +Indicates looking in the environment for values of variables named, +@env{PROGRAM_OPTNAME} or @env{PROGRAM}, where @env{PROGRAM} is the +upper cased @var{C-name} of the program and @samp{OPTNAME} is the +upper cased @var{C-name} of a specific option. The contents of +the @env{PROGRAM} variable, if found, are tokenized and processed. +The contents of @env{PROGRAM_OPTNAME} environment variables are taken +as the option argument to the option nameed @option{--optname}. + +@item homerc +@vindex homerc +Specifies that option settings may be loaded from and stored into +configuration files. Each instance of this attribute is either a directory +or a file using a specific path, a path based on an environment variable or +a path relative to installation directories. The method used depends on +the name. If the one entry is empty, it enables the loading and storing of +settings, but no specific files are searched for. Otherwise, a series of +configuration files are hunted down and, if found, loaded. + +If the first character of the @samp{homerc} value is not the dollar +character (@code{$}), then it is presumed to be a path name based on the +current directory. Otherwise, the method depends on the second character: + +@table @code +@item $ +The path is relative to the directory where the executable was found. +@item @@ +The path is relative to the package data directory, e.g. +@file{/usr/local/share/autogen}. +@item [a-zA-Z] +The path is derived from the named environment variable. +@end table + +Use as many as you like. The presence of this attribute +activates the @option{--save-opts} and @option{--load-opts} options. +However, saving into a file may be disabled with the @samp{disable-save}. +@xref{loading rcfile}. +See the @code{optionMakePath(3AGEN)} man page for excruciating details. + +@item rcfile +@vindex rcfile +Specifies the configuration file name. This is only useful if you +have provided at least one @code{homerc} attribute. +@example +default: .<prog-name>rc +@end example + +@item vendor-opt +@vindex vendor-opt +This option implements the @option{-W} vendor option command line option. + +For POSIX specified utilities, the options are constrained to the options +that are specified by POSIX. Extensions should be handled with @option{-W} +command line options, the short flag form. Long option name processing +must be disabled. In fact, the @code{long-opts} attribute must not be +provided, and some options must be specified without flag values. + +The @option{-W long-name} is processed by looking up the long option +name that follows it. It cannot be a short flag because that would +conflict with the POSIX flag name space. It will be processed as if +long options were accepted and @option{--long-name} were found on the +command line. +@end table + +@c +@c = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +@c +@node programming attributes +@subsubsection Programming Details + +These attributes affect some of the ways that the option data are +used and made available to the program. + +@table @samp +@item config-header +@vindex config-header +The contents of this attribute should be just the name of the configuration +file. A "#include" naming this file will be inserted at the top of the +generated header. + +@item exit-name +@itemx exit-desc +@vindex exit-name +@vindex exit-desc +These values should be defined as indexed values, thus: +@example +exit-name[0] = success; +exit-desc[0] = 'Successful program execution.'; +exit-name[1] = failure; +exit-desc[1] = 'The operation failed or command syntax was not valid.'; +@end example +By default, all programs have these effectively defined for them. +They may be overridden by explicitly defining any or all of these values. +Additional names and descriptions may be defined. +They will cause an enumeration to be emitted, like this one +for @command{getdefs}: +@example +typedef enum @{ + GETDEFS_EXIT_SUCCESS = 0, + GETDEFS_EXIT_FAILURE = 1 +@} getdefs_exit_code_t; +@end example +@noindent +which will be augmented by any @code{exit-name} definitions beyond @samp{1}. + +Some of the generated code will exit non-zero if there is an allocation error. +This exit will always be code @samp{1}, unless there is an exit named @samp{no_mem} +or @samp{nomem}. In that case, that value will be used. Additionally, if +there is such a value, and if @code{die-code} is specified, then a function +@code{nomem_err(size_t len, char const * what)} will be emitted as an inline +function for reporting out-of-memory conditions. + +@item usage-message +@vindex usage-message +This attribute will cause two procedures to be added to the code file: +@code{usage_message()} and @code{vusage_message()}, with any applicable prefix +(see @code{prefix}, below). They are declared in the +generated header, thus: +@example +noreturn extern void vusage_message(char const * fmt, va_list ap); +noreturn extern void usage_message(char const * fmt, ...); +@end example +@noindent +These functions print the message to @file{stderr} and invoke the usage +function with the exit code set to @code{1} (@code{EXIT_FAILURE}). + +@item die-code +@vindex die-code +This tells AutoOpts templates to emit code for @code{vdie()}, @code{die()}, +@code{fserr()}, and, possibly the @code{nomem_err()} functions. The latter is +emitted if an exit name of @samp{no-mem} or @samp{nomem} is specified. If the +@code{die-code} is assigned a text value, then that code will be inserted in +the @code{vdie} function immediately before it prints the death rattle +message. + +The profiles for these functions are: +@example +noreturn extern void vdie( int exit_code, char const * fmt, va_list); +noreturn extern void die( int exit_code, char const * fmt, ...); +noreturn extern void fserr(int exit_code, char const * op, char const * fname); +noreturn static inline void +nomem_err(size_t sz, char const * what) @{...@} +@end example + +@item export +@vindex export +This string is inserted into the .h interface file. Generally used for +global variables or @code{#include} directives required by +@code{flag-code} text and shared with other program text. +Do not specify your configuration header (@file{config.h}) in this +attribute or the @code{include} attribute. Instead, use +@code{config-header}, above. + +@item guard-option-names +@vindex guard-option-names +AutoOpts generates macros that presume that there are no @command{cpp} macros +with the same name as the option name. For example, if you have an option +named, @option{--debug}, then you must not use @code{#ifdef DEBUG} in your +code. If you specify this attribute, every option name will be guarded. If +the name is @code{#define}-d, then a warning will be issued and the name +undefined. If you do not specify this and there is a conflict, you will get +strange error messages. + +This attribute may be set to any of four recognized states: + +@itemize @bullet +@item +Not defined. AutoOpts will behave as described above. + +@item +Defined, but set to the empty string. Text will be emitted into the header +to undefine (@code{#undef}) any conflicting preprocessor macros. The code +will include compiler warnings (via @code{#warning}). Some compilers are +not ANSI-C-99 compliant yet and will error out on those warnings. You may +compile with @option{-DNO_OPTION_NAME_WARNINGS} to silence or mostly silence +them. + +@item +Defined and set to the string, @code{no-warning}. All of the needed +@code{#undef}s will be emitted, without any conflict checking @code{#warning} +directives emitted. + +@item +Defined and set to the string, @code{full-enum}. The option manipulation +preprocessor macros will not token paste the option names to the index +enumeration prefix. e.g. you will need to use @code{HAVE_OPT(INDEX_OPT_DEBUG)} +instead of @code{HAVE_OPT(DEBUG)}. +@end itemize + +@item include +@vindex include +This string is inserted into the .c file. Generally used for global +variables required only by @code{flag-code} program text. + +@item no-libopts +@vindex no-libopts +If you are going to handle your option processing with the @file{getopt.tpl} +template instead of using libopts, then specify this attribute. It will +suppress mention of @option{--more-help} in the generated documentation. +(@code{getopt_long} does not support @option{--more-help}.) + +@item prefix +@vindex prefix +This value is inserted into @strong{all} global names. This will +disambiguate them if more than one set of options are to be compiled +into a single program. +@end table + +@c +@c = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +@c +@node presentation attributes +@subsubsection User Presentation Attributes + +Attributes that affect the user's experience. + +@table @samp +@item allow-errors +@vindex allow-errors +The presence of this attribute indicates ignoring any command line +option errors. This may also be turned on and off by invoking the +macros @code{ERRSKIP_OPTERR} and @code{ERRSTOP_OPTERR} from the +generated interface file. + +@item long-opts +@vindex long-opts +@cindex named option mode +Presence indicates GNU-standard long option processing. Partial name +matches are accepted, if they are at least two characters long and the +partial match is unique. The matching is not case sensitive, and the +underscore, hyphen and carat characters are all equivalent (they match). + +If any options do not have an option value (flag character) specified, +and least one does specify such a value, then you must specify +@code{long-opts}. If none of your options specify an option value +(flag character) and you do not specify @code{long-opts}, then command +line arguments are processed in "named option mode". This means that: + +@itemize @bullet +@item +Every command line argument must be a long option. +@item +The flag markers @option{-} and @option{--} are completely optional. +@item +The @code{argument} program attribute is disallowed. +@item +One of the options may be specified as the default +(as long as it has a required option argument). +@end itemize + +@item no-xlate +@vindex no-xlate +Modifies when or whether option names get translated. If provided, +it must be assigned one of these values: +@table @samp +@item opt-cfg +to suppress option name translation for configuration file and and environment +variable processing. +@item opt +to suppress option name translation completely. The usage text will +always be translated if @code{ENABLE_NLS} is defined and you have +translations for that text. +@item anything +Specifies disabling all internationalization support for option code, completely. +@end table +See also the various @code{XLAT} interface entries in the +AutoOpts Programmatic Interface section (@pxref{AutoOpts API}). + +@item reorder-args +@vindex reorder-args +Normally, POSIX compliant commands do not allow for options to be interleaved +with operands. If this is necessary for historical reasons, there are two +approaches available: +@itemize @bullet +@item +Allow @code{optionProcess} to return the index of the operand like it normally +does and process the operand(s). When an operand is encountered that starts +with a hyphen, then set the AutoOpts current index with the @code{RESTART_OPT} +macro (see @pxref{RESTART_OPT}), and re-invoke @code{optionProcess}. This +will also allow you to process the operands in context. + +@item +Specify this attribute. AutoOpts will re-order the command arguments +so that the operands appear (in the original order) at the end of +the argument list. Differing configuration state is not possible +to detect after all options have been processed. +@end itemize + +@item resettable +@vindex resettable +Specifies that the @option{--reset-option} command line option is to be +supported. This makes it possible to suppress any setting that might be +found in a configuration file or environment variable. +@end table + +@node library attributes +@subsection Options for Library Code +@cindex library attributes + +Some libraries provide their own code for processing command line +options, and this may be used by programs that utilize AutoOpts. +You may also wish to write a library that gets configured with AutoOpts +options and config files. Such a library may either supply its own +configury routine and process its own options, or it may export its +option descriptions to programs that also use AutoOpts. This section +will describe how to do all of these different things. + +@menu +* lib and program:: AutoOpt-ed Library for AutoOpt-ed Program +* lib called:: AutoOpt-ed Library for Regular Program +* prog calls lib:: AutoOpt-ed Program Calls Regular Library +@end menu + +@node lib and program +@subsubsection AutoOpt-ed Library for AutoOpt-ed Program + +The library source code must provide an option definition file that consists +of only the attribute @code{library} +@vindex library +and @code{flag} entries. The @code{library} attribute does not need any +associated value, so it will generally appeary by itself on a line folowed +by a semi-colon. The first @code{flag} entry must contain the following +attributes: + +@table @samp +@item name +This name is used in the construction of a global pointer of type +@code{tOptDesc const*}. It is always required. +@item documentation +@vindex documentation +It tells @code{AutoOpts} that this option serves no normal purpose. +It will be used to add usage clarity and to locate option descriptors +in the library code. +@item descrip +This is a string that is inserted in the extended usage display +before the options specific to the current library. It is always required. +@item lib-name +@vindex lib-name +This should match the name of the library. This string is also used in +the construction of the option descriptor pointer name. In the end, it +looks like this: +@example +extern tOptDesc const* <<lib-name>>_<<name>>_optDesc_p; +@end example +@noindent +and is used in the macros generated for the library's @file{.h} file. +@end table + +In order to compile this @code{AutoOpts} using library, you must create a +special header that is not used by the client program. This is accomplished +by creating an option definition file that contains essentially exactly the +following: + +@example +AutoGen definitions options; +prog-name = does-not-matter; // but is always required +prog-title = 'also does not matter'; // also required +config-header = 'config.h'; // optional, but common +library; +#include library-options-only.def +@end example + +@noindent +and nothing else. AutoGen will produce only the @file{.h} file. +You may now compile your library, referencing just this @file{.h} file. +The macros it creates will utilize a global variable that will be defined +by the @code{AutoOpts}-using client program. That program will need to +have the following @code{#include} in @i{its} option definition file: + +@example +#include library-options-only.def +@end example + +@noindent +All the right things will magically happen so that the global variables +named @var{<<lib-name>>_<<name>>_optDesc_p} are initialized correctly. +For an example, please see the @code{AutoOpts} test script: +@file{autoopts/test/library.test}. + +@node lib called +@subsubsection AutoOpt-ed Library for Regular Program + +In this case, your library must provide an option processing function +to a calling program. This is accomplished by setting the @code{allow-errors} +global option attribute. Each time your option handling function is called, +you must determine where your scan is to resume and tell the AutoOpts library +by invoking: + +@example +RESTART_OPT(next_arg_index); +@end example + +@noindent +and then invoke @code{not_opt_index = optionProcess(...)}. +The @code{not_opt_index} value can be used to set @code{optind}, +if that is the global being used to scan the program argument array. + +In this method, do @strong{NOT} utilize the global @code{library} attribute. +Your library must specify its options as if it were a complete program. +You may choose to specify an alternate @code{usage()} function so that +usage for other parts of the option interface may be displayed as well. +See ``Program Information Attributes'' (@pxref{information attributes}). + +At the moment, there is no method for calling @code{optionUsage()} telling +it to produce just the information about the options and not the program +as a whole. Some later revision after somebody asks. + +@node prog calls lib +@subsubsection AutoOpt-ed Program Calls Regular Library + +As with providing an @code{AutoOpt}-ed library to a non-@code{AutoOpt}-ed +program, you must write the option description file as if you were writing +all the options for the program, but you should specify the +@code{allow-errors} global option attribute and you will likely want an +alternate @code{usage()} function (see ``Program Information Attributes'' +@pxref{information attributes}). In this case, though, when +@code{optionProcess()} returns, you need to test to see if there might be +library options. If there might be, then call the library's exported +routine for handling command line options, set the next-option-to-process +with the @code{RESTART_OPT()} macro, and recall @code{optionProcess()}. +Repeat until done. + +@node information attributes +@subsection Program Information Attributes +@cindex information attributes + +These attributes are used to define how and what information is displayed +to the user of the program. + +@table @samp +@item copyright +@vindex copyright +The @code{copyright} is a structured value containing three to five +values. If @code{copyright} is used, then the first three are required. + +@enumerate +@item +@vindex date +@file{date} - the list of applicable dates for the copyright. +@item +@vindex owner +@file{owner} - the name of the copyright holder. +@item +@vindex type +@file{type} - specifies the type of distribution license. +AutoOpts/AutoGen supports the text of the GNU Public License (@file{gpl}), +the GNU Lesser General Public License with Library extensions +(@file{lgpl}), the Modified Free BSD license (@file{mbsd}) and a few others. +Other licenses may be specified, but you must provide your own license file. +The list of license files provided by AutoOpts may be seen by typing: +@example +ls $(autoopts-config pkgdatadir)/*.lic +@end example +@item +@vindex text +@file{text} - the text of the copyright notice. This must be provided +if @file{type} is set to @file{NOTE}. +@item +@vindex author +@file{author} - in case the author name is to appear in the documentation +and is different from the copyright owner. +@item +@vindex eaddr +@file{eaddr} - email address for receiving praises and complaints. +Typically that of the author or copyright holder. +@end enumerate +@* +An example of this might be: +@example +copyright = @{ + date = "1992-2015"; + owner = "Bruce Korb"; + eaddr = 'bkorb@@gnu.org'; + type = GPL; +@}; +@end example + +@item detail +@vindex detail +This string is added to the usage output when the HELP option is +selected. + +@item explain +@vindex explain +Gives additional information whenever the usage routine is invoked. + +@item package +@vindex package +The name of the package the program belongs to. This will appear +parenthetically after the program name in the version and usage output, +e.g.: @code{autogen @i{(GNU autogen)} - The Automated Program Generator}. + +@item preserve-case +@vindex preserve-case +This attribute will not change anything except appearance. Normally, the +option names are all documented in lower case. However, if you specify this +attribute, then they will display in the case used in their specification. +Command line options will still be matched without case sensitivity. +This is useful for specifying option names in camel-case. + +@item prog-desc @strong{and} +@itemx opts-ptr +@vindex prog-desc +@vindex opts-ptr +These define global pointer variables that point to the program +descriptor and the first option descriptor for a library option. This +is intended for use by certain libraries that need command line and/or +initialization file option processing. These definitions have no effect +on the option template output, but are used for creating a library +interface file. Normally, the first "option" for a library will be a +documentation option that cannot be specified on the command line, but +is marked as @code{settable}. The library client program will invoke the +@code{SET_OPTION} macro which will invoke a handler function that will +finally set these global variables. + +@item usage +@vindex usage +Optionally names the usage procedure, if the library routine +@code{optionUsage()} does not work for you. If you specify +@code{my_usage} as the value of this attribute, for example, you will +use a procedure by that name for displaying usage. Of course, you will +need to provide that procedure and it must conform to this profile: +@example +void @i{my_usage}( tOptions* pOptions, int exitCode ) +@end example + +@item gnu-usage +@vindex gnu-usage +Normally, the default format produced by the @code{optionUsage} procedure +is @i{AutoOpts Standard}. By specifying this attribute, the default format +will be @i{GNU-ish style}. Either default may be overridden by the user with +the @env{AUTOOPTS_USAGE} environment variable. If it is set to @code{gnu} +or @code{autoopts}, it will alter the style appropriately. This attribute +will conflict with the @code{usage} attribute. + +@item reorder-args +@vindex reorder-args +Some applications traditionally require that the command operands be +intermixed with the command options. In order to handle that, the arguments +must be reordered. If you are writing such an application, specify this +global option. All of the options (and any associated option arguments) +will be brought to the beginning of the argument list. New applications +should not use this feature, if at all possible. This feature is +@i{disabled} if @env{POSIXLY_CORRECT} is defined in the environment. +@end table + +@node Generated main +@subsection Generating main procedures +@cindex main procedure + +When AutoOpts generates the code to parse the command line options, it has +the ability to produce any of several types of @code{main()} procedures. +This is done by specifying a global structured value for +@vindex main +@code{main}. The values that it contains are dependent on the value set for +the one value it must have: @code{main-type}. + +@vindex main-type +The recognized values for @code{main-type} are @code{guile}, +@code{shell-process}, @code{shell-parser}, @code{main}, @code{include}, +@code{invoke}, and @code{for-each}. + +@menu +* main guile:: guile: main and inner_main procedures +* main shell-process:: shell-process: emit Bourne shell results +* main shell-parser:: shell-parser: emit Bourne shell script +* main main:: main: user supplied main procedure +* main include:: include: code emitted from included template +* main invoke:: invoke: code emitted from AutoGen macro + +The @code{for-each} main procedure has a number of attributes that +must be specified: + +* main for-each:: for-each: perform function on each operand +* main-for-each-proc:: procedure to handle each argument +* main-for-each-type:: handler procedure type +* main-for-each-code:: code for handler procedure +* main-for-each-opts:: for-each main procedure options +@end menu + +@node main guile +@subsubsection guile: main and inner_main procedures + +When the @code{main-type} is specified to be @code{guile}, +a @code{main()} procedure is generated that calls @code{gh_enter()}, providing +it with a generated @code{inner_main()} to invoke. If you must perform +certain tasks before calling @code{gh_enter()}, you may specify such code +in the value for the +@vindex before-guile-boot +@code{before-guile-boot} attribute. + +The @code{inner_main()} procedure itself will process the command line +arguments (by calling @code{optionProcess()}, +@pxref{libopts-optionProcess}), and then either invoke the code +specified with the +@vindex guile-main +@code{guile-main} attribute, or else export the parsed options to Guile +symbols and invoke the @code{scm_shell()} function from the Guile library. +This latter will render the program nearly identical to the stock +@code{guile(1)} program. + +@node main shell-process +@subsubsection shell-process: emit Bourne shell results + +This will produce a @code{main()} procedure that parses the command line +options and emits to @file{stdout} Bourne shell commands that puts the +option state into environment variables. This can be used within a +shell script as follows: + +@example +unset OPTION_CT +eval "`opt_parser \"$@@\"`" +test $@{OPTION_CT@} -gt 0 && shift $@{OPTION_CT@} +@end example + +If the option parsing code detects an error or a request for usage or version, +it will emit a command to exit with an appropriate exit code to @file{stdout}. +This form of @code{main} will cause all messages, including requested usage +and version information, to be emitted to @file{stderr}. Otherwise, a numeric +value for @code{OPTION_CT} is guaranteed to be emitted, along with assignments +for all the options parsed, something along the lines of the following will be +written to @file{stdout} for evaluation: + +@example +OPTION_CT=4 +export OPTION_CT +MYPROG_SECOND='first' +export MYPROG_SECOND +MYPROG_ANOTHER=1 # 0x1 +export MYPROG_ANOTHER +@end example + +@noindent +If the arguments are to be reordered, however, then the resulting set +of operands will be emitted and @env{OPTION_CT} will be set to zero. +For example, the following would be appended to the above: + +@example +set -- 'operand1' 'operand2' 'operand3' +OPTION_CT=0 +@end example + +@noindent +@env{OPTION_CT} is set to zero since it is not necessary to shift +off any options. + +@node main shell-parser +@subsubsection shell-parser: emit Bourne shell script + +This will produce a @code{main()} procedure that emits a shell script +that will parse the command line options. That script can be emitted +to @file{stdout} or inserted or substituted into a pre-existing shell +script file. Improbable markers are used to identify previously inserted +parsing text: + +@example +# # # # # # # # # # -- do not modify this marker -- +@end example + +@noindent +The program is also pretty insistent upon starting its parsing script +on the second line. + +@node main main +@subsubsection main: user supplied main procedure + +You must supply a value for the @code{main-text} attribute. +You may also supply a value for +@vindex option-code +@code{option-code}. If you do, then the @code{optionProcess} invocation +will not be emitted into the code. AutoOpts will wrap the @code{main-text} +inside of: + +@example +int +main( int argc, char** argv ) +@{ + int res = <<success-exit-code>>; + @{ // replaced by option-code, if that exists + int ct = optionProcess( &<<prog-name>>Options, argc, argv); + argc -= ct; + argv += ct; + @} +<<main-text>> + return res; +@} +@end example + +@noindent +so you can most conveniently set the value with a @code{here string} +(@pxref{here-string}): + +@example +code = <<- _EndOfMainProc_ + <<your text goes here>> + _EndOfMainProc_; +@end example + +@node main include +@subsubsection include: code emitted from included template + +You must write a template to produce your main procedure. +You specify the name of the template with the @code{tpl} attribute +and it will be incorporated at the point where AutoOpts is ready +to emit the @code{main()} procedure. + +This can be very useful if, in your working environment, you have +many programs with highly similar @code{main()} procedures. All you need +to do is parameterize the variations and specify which variant is needed +within the @code{main} AutoOpts specification. Since you are coding +the template for this, the attributes needed for this variation would +be dictated by your template. + +Here is an example of an @code{include} variation: + +@example +main = @{ + main-type = include; + tpl = "main-template.tpl"; +@}; +@end example + +@node main invoke +@subsubsection invoke: code emitted from AutoGen macro + +You must write a template to produce your main procedure. That template +must contain a definition for the function specified with the @code{func} +attribute to this @code{main()} procedure specification. This +variation operates in much the same way as @code{include} +(@pxref{main include}) method. + +@node main for-each +@subsubsection for-each: perform function on each operand + +This produces a main procedure that invokes a procedure once for each operand +on the command line (non-option arguments), @strong{OR} once for each +non-blank, non-comment @code{stdin} input line. Leading and trailing white +space is trimmed from the input line and comment lines are lines that are +empty or begin with a comment character, defaulting to a hash ('#') character. + +@strong{NB}: +The @code{argument} program attribute (@pxref{program attributes}) +must begin with the @code{[} character, to indicate that there are +command operands, but that they are optional. + +@noindent +For an example of the produced main procedure, in the @file{autoopts/test} +build directory, type the following command and look at @file{main.c}: +@example +make verbose TESTS=main.test +@end example + +@node main-for-each-proc +@unnumberedsubsubsec procedure to handle each argument + +@vindex handler-proc +The @code{handler-proc} attribute is required. It is used to name the +procedure to call. That procedure is presumed to be external, but if +you provide the code for it, then the procedure is emitted as a static +procedure in the generated code. + +This procedure should return 0 on success, a cumulative error code on warning +and exit without returning on an unrecoverable error. As the cumulative +warning codes are @i{or}-ed together, the codes should be some sort of bit +mask in order to be ultimately decipherable (if you need to do that). + +If the called procedure needs to cause a fail-exit, it is expected to call +@code{exit(3)} directly. If you want to cause a warning exit code, then this +handler function should return a non-zero status. That value will be +@strong{OR}-ed into a result integer for computing the final exit code. E.g., +here is part of the emitted code: + +@example + int res = 0; + if (argc > 0) @{ + do @{ + res |= @var{my_handler}( *(argv++) ); + @} while (--argc > 0); + @} else @{ ... +@end example + +@node main-for-each-type +@unnumberedsubsubsec handler procedure type + +@vindex handler-type +If you do not supply the @code{handler-type} attribute, your handler +procedure must be the default type. The profile of the procedure must be: + +@example +int @var{my_handler}(char const * pz_entry); +@end example + +@noindent +However, if you do supply this attribute, you may set the value to any of +four alternate flavors: + +@table @samp +@item name-of-file +This is essentially the same as the default handler type, except that before +your procedure is invoked, the generated code has verified that the string +names an existing file. The profile is unchanged. + +@item file-X +Before calling your procedure, the file is f-opened according to the @code{X}, +where @code{X} may be any of the legal modes for @code{fopen(3C)}. In this +case, the profile for your procedure must be: + +@example +int @var{my_handler}(char const * pz_fname, FILE * entry_fp); +@end example + +@noindent +When processing inputs as file pointer stream files, there are several +ways of treating standard input. It may be an ordinary input file, +or it may contain a list of files to operate on. + +If the file handler type is more specifically set to @samp{file-r} and +a command line operand consists of a single hyphen, then @var{my_handler} +will be called with @code{entry_fp} set to @code{stdin} and the @code{pz_fname} +set to the translatable string, "standard input". Consequently, +in this case, if the input list is being read from @code{stdin}, a line +containing a hyphen by itself will be ignored. + +@item stdin-input +This attribute specifies that standard input is a data input file. +By default, @code{for-each} main procedures will read standard input for +operands if no operands appear on the command line. If there are operands +after the command line options, then standard input is typically ignored. +It can always be processed as an input data file, however, if a single bare +hyphen is put on the command line. + +@item text-of-file +@itemx some-text-of-file +Before calling your procedure, the contents of the file are read or mapped +into memory. (Excessively large files may cause problems.) The +@samp{some-text-of-file} disallows empty files. Both require regular files. +In this case, the profile for your procedure must be: + +@example +program_exit_code_t +@var{my_handler}(char const * fname, char * file_text, + size_t text_size); +@end example + +@noindent +Note that though the @code{file_text} is not @code{const}, any changes made to +it are not written back to the original file. It is merely a memory image of +the file contents. Also, the memory allocated to hold the text is +@code{text_size + 1} bytes long and the final byte is always @code{NUL}. The +file contents need not be text, as the data are read with the @code{read(2)} +system call. + +@code{file_text} is automatically freed, unless you specify a +@vindex handler-frees +@code{handler-frees} attribute. Then your code must @code{free(3)} the text. +@end table + +If you select one of these file type handlers, then on access or usage errors +the @code{PROGRAM_EXIT_FAILURE} exit code will, by default, be or-ed +into the final exit code. This can be changed by specifying the +global @code{file-fail-code} attribute and naming a different value. +That is, something other than @code{failure}. You may choose @code{success}, +in which case file access issues will not affect the exit code and the error +message will not be printed. + +@node main-for-each-code +@unnumberedsubsubsec code for handler procedure + +@vindex MYHANDLER-code +With the @code{MYHANDLER-code} attribute, you provide the code for +your handler procedure in the option definition file. Note that the +spelling of this attribute depends on the name provided with the +@code{handler-proc} attribute, so we represent it here with +@code{MYHANDLER} as a place holder. As an example, your @code{main()} +procedure specification might look something like this: + +@example +main = @{ + main-type = for-each; + handler-proc = @var{MYHANDLER}; + @var{MYHANDLER}-code = <<- EndOfMyCode + /* whatever you want to do */ + EndOfMyCode; +@}; +@end example + +@noindent +and instead of an emitted external reference, a procedure will be emitted +that looks like this: + +@example +static int +@var{MYHANDLER}( char const* pz_entry ) +@{ + int res = 0; + <<@var{MYHANDLER}-code goes here>> + return res; +@} +@end example + +@node main-for-each-opts +@unnumberedsubsubsec for-each main procedure options + +These attributes affect the main procedure and how it processes +each argument or input line. + +@table @samp +@item interleaved +@vindex interleaved +If this attribute is specified, then options and operands may be +interleaved. Arguments or input lines beginning with a hyphen will +cause it to be passed through to an option processing function and +will take effect for the remainder of the operands (or input lines) +processed. + +@item main-init +@vindex main-init +This is code that gets inserted after the options have been processed, but +before the handler procs get invoked. + +@item main-fini +@vindex main-fini +This is code that gets inserted after all the entries have been processed, +just before returning from @code{main()}. + +@item comment-char +@vindex comment-char +When reading operands from standard input, if you wish comment lines to +start with a character other than a hash (@code{#}) character, then +specify one character with this attribute. If string value is empty, +then only blank lines will be considered comments. +@end table + +@node option attributes +@subsection Option Attributes +@cindex option attributes + +For each option you wish to specify, you must have a block macro named +@code{flag} defined. There are two required attributes: @code{name} and +@code{descrip}. If any options do not have a @code{value} (traditional flag +character) attribute, then the @code{long-opts} program attribute must also +be defined. As a special exception, if no options have a @code{value} +@strong{and} @code{long-opts} is not defined @strong{and} @code{argument} is +not defined, then all arguments to the program are named options. In this +case, the @option{-} and @option{--} command line option markers are optional. + +@menu +* Required Attributes:: Required Attributes +* Common Attributes:: Common Option Attributes +* Immediate Action:: Immediate Action Attributes +* Option Conflict Attributes:: Option Conflict Attributes + +These option attributes do not fit well with the above categories. + +* opt-attr settable:: Program may set option +* opt-attr no-preset:: Option cannot be pre-configured +* opt-attr equivalence:: Option Equivalence Class +* opt-attr aliases:: Option Aliasing +* opt-attr default option:: Default Option +* opt-attr documentation:: Option Sectioning Comment +* opt-attr translators:: Translator Notes +@end menu + +@node Required Attributes +@subsubsection Required Attributes +@cindex Required Attributes + +Every option must have exactly one copy of both of these attributes. + +@table @samp +@item name +@vindex name +Long name for the option. Even if you are not accepting long options +and are only accepting flags, it must be provided. AutoOpts generates +private, named storage that requires this name. This name also causes +a @code{#define}-d name to be emitted. It must not conflict with any +other names you may be using in your program. + +For example, if your option name is, @code{debug} or @code{munged-up}, +you must not use the @code{#define} names @code{DEBUG} (or +@code{MUNGED_UP}) in your program for non-AutoOpts related purposes. +They are now used by AutoOpts. + +Sometimes (most especially under Windows), you may get a surprise. +For example, @code{INTERFACE} is apparently a user space name that +one should be free to use. Windows usurps this name. To solve this, +you must do one of the following: + +@enumerate +@item +Change the name of your option +@item +add the program attribute (@pxref{program attributes}): + +@example +export = '#undef INTERFACE'; +@end example +@item +add the program attribute: + +@example +guard-option-names; +@end example +@end enumerate + +@item descrip +@vindex descrip +Except for documentation options, a @strong{very} brief description of the +option. About 40 characters on one line, maximum, not counting any texinfo +markups. Texinfo markups are stripped before printing in the usage text. It +appears on the @code{usage()} output next to the option name. + +If, however, the option is a documentation option, it will appear on one or +more lines by itself. It is thus used to visually separate and comment upon +groups of options in the usage text. +@end table + +@node Common Attributes +@subsubsection Common Option Attributes +@cindex Common Option Attributes + +These option attributes are optional. Any that do appear in the +definition of a flag, may appear only once. + +@table @samp +@item value +@vindex value +The flag character to specify for traditional option flags, e.g., @option{-L}. + +@item max +@vindex max +Maximum occurrence count (invalid if @var{disable} present). +The default maximum is 1. @code{NOLIMIT} can be used for the value, +otherwise it must be a number or a @code{#define} that evaluates to a number. + +@item min +@vindex min +Minimum occurrence count. If present, then the option @strong{must} +appear on the command line. Do not define it with the value zero (0). + +@item must-set +@vindex must-set +If an option must be specified, but it need not be specified on +the command line, then specify this attribute for the option. + +@item deprecated +@vindex deprecated +There are two effects to this attribute: the usage text will not +show the option, and the generated documentation will mark it with: +@emph{NOTE: THIS OPTION IS DEPRECATED}. + +@item disable +@vindex disable +Prefix for disabling (inverting sense of) the option. Only useful +if long option names are being processed. When an option has this +attribute, the test @code{ENABLED_OPT(OPTNAME)} is false when either +of the following is true: +@itemize @bullet +@item +The option has not been specified and the @code{enable} attribute has +not been specified. +@item +The option has been specified with this disabling prefix. +@end itemize +To detect that the option has been specified with the disabling +prefix, you must use: +@example +HAVE_OPT(OPTNAME) && ! ENABLED_OPT(OPTNAME) +@end example + +@item enable +@vindex enable +Long-name prefix for enabling the option (invalid if @var{disable} +@strong{not} present). Only useful if long option names are being +processed. + +@item enabled +@vindex enabled +If default is for option being enabled. (Otherwise, the OPTST_DISABLED +bit is set at compile time.) Only useful if the option can be disabled. + +@item ifdef +@itemx ifndef +@itemx omitted-usage +@vindex ifdef +@vindex ifndef +@vindex omitted-usage +If an option is relevant on certain platforms or when certain features +are enabled or disabled, you can specify the compile time flag used +to indicate when the option should be compiled in or out. For example, +if you have a configurable feature, @code{mumble} that is indicated +with the compile time define, @code{WITH_MUMBLING}, then add: + +@example +ifdef = WITH_MUMBLING; +@end example + +@noindent +Take care when using these. There are several caveats: + +@itemize @bullet +@item +The case and spelling must match whatever is specified. +@item +Do not confuse these attributes with the AutoGen directives of the +same names, @xref{Directives}. These cause C preprocessing directives +to be inserted into the generated C text. +@item +Only one of @code{ifdef} and @code{ifndef} may apply to any one option. +@item +The @code{VALUE_OPT_} values are @code{#define}-d. If @code{WITH_MUMBLING} +is not defined, then the associated @code{VALUE_OPT_} value will not be +@code{#define}-d either. So, if you have an option named, @code{MUMBLING} +that is active only if @code{WITH_MUMBLING} is @code{#define}-d, then +@code{VALUE_OPT_MUMBLING} will be @code{#define}-d iff @code{WITH_MUMBLING} +is @code{#define}-d. Watch those switch statements. +@item +If you specify @code{omitted-usage}, then the option will be recognized +as disabled when it is configured out of the build, but will yield the +message, ``This option has been disabled.'' You may specify an alternate +message by giving @code{omitted-usage} a string value. e.g.: +@example +omitted-usage = 'you cannot do this'; +@end example +@end itemize + +@item no-command +@vindex no-command +This option specifies that the option is not allowed on the command line. +Such an option may not take a @code{value} (flag character) attribute. The +program must have the @code{homerc} (@pxref{program attributes}) option set. +@end table + +@node Immediate Action +@subsubsection Immediate Action Attributes +@cindex immediate action + +Certain options may need to be processed early. For example, in order to +suppress the processing of configuration files, it is necessary to process the +command line option @option{--no-load-opts} @strong{before} the config files +are processed. To accommodate this, certain options may have their enabled or +disabled forms marked for immediate processing. The consequence of this is +that they are processed ahead of all other options in the reverse of normal +order. + +Normally, the first options processed are the options specified in the first +@code{homerc} file, followed by then next @code{homerc} file through to the +end of config file processing. Next, environment variables are processed and +finally, the command line options. The later options override settings +processed earlier. That actually gives them higher priority. Command line +immediate action options actually have the lowest priority of all. They would +be used only if they are to have an effect on the processing of subsequent +options. + +@table @samp +@item immediate +@vindex immediate +Use this option attribute to specify that the enabled form of the option +is to be processed immediately. The @code{help} and @code{more-help} +options are so specified. They will also call @code{exit()} upon +completion, so they @strong{do} have an effect on the processing +of the remaining options :-). + +@item immed-disable +@vindex immed-disable +Use this option attribute to specify that the disabled form of the +option is to be processed immediately. The @code{load-opts} option is +so specified. The @option{--no-load-opts} command line option will +suppress the processing of config files and environment variables. +Contrariwise, the @option{--load-opts} command line option is +processed normally. That means that the options specified in that file +will be processed after all the @code{homerc} files and, in fact, after +options that precede it on the command line. + +@item also +If either the @code{immediate} or the @code{immed-disable} attributes +are set to the string, @code{also}, then the option will actually be +processed twice: first at the immediate processing phase and again +at the normal time. +@end table + +@node Option Conflict Attributes +@subsubsection Option Conflict Attributes +@cindex Option Conflict Attributes + +These attributes may be used as many times as you need. +They are used at the end of the option processing to verify +that the context within which each option is found does not +conflict with the presence or absence of other options. + +This is not a complete cover of all possible conflicts and +requirements, but it simple to implement and covers the +more common situations. + +@table @samp +@cindex flags-must +@item flags-must +one entry for every option that @strong{must} be present +when this option is present + +@cindex flags-cant +@item flags-cant +one entry for every option that @strong{cannot} be present +when this option is present +@end table + +@node opt-attr settable +@subsubsection Program may set option +@vindex settable +If the option can be set outside of option processing, specify +@code{settable}. If this attribute is defined, special macros for setting +this particular option will be inserted into the interface file. For example, +@code{TEMPL_DIRS} is a settable option for AutoGen, so a macro named +@code{SET_OPT_TEMPL_DIRS(a)} appears in the interface file. This attribute +interacts with the @var{documentation} attribute. + +@node opt-attr no-preset +@subsubsection Option cannot be pre-configured +@vindex no-preset +@cindex configuration file +If presetting this option is not allowed, specify @code{no-preset}. +(Thus, environment variables and values set in configuration files will be +ignored.) + +@node opt-attr equivalence +@subsubsection Option Equivalence Class +@vindex equivalence +Generally, when several options are mutually exclusive and basically serve the +purpose of selecting one of several processing modes, specify the +@code{equivalence} attribute. These options will be considered an +equivalence class. Sometimes, it is just easier to deal with them as such. +All members of the equivalence class must contain the same equivalenced-to +option, including the equivalenced-to option itself. Thus, it must be a class +member. + +For an option equivalence class, there is a single occurrence counter for +the class. It can be referenced with the interface macro, +@code{COUNT_OPT(BASE_OPTION)}, where @var{BASE_OPTION} is the equivalenced-to +option name. + +Also, please take careful note: since the options are mapped to the +equivalenced-to option descriptor, any option argument values are mapped to +that descriptor also. Be sure you know which ``equivalent option'' was +selected before getting an option argument value! + +During the presetting phase of option processing +(@pxref{Presetting Options}), equivalenced options may be specified. +However, if different equivalenced members are specified, only the last +instance will be recognized and the others will be discarded. A conflict +error is indicated only when multiple different members appear on the +command line itself. + +As an example of where equivalenced options might be useful, @code{cpio(1)} +has three options @option{-o}, @option{-i}, and @option{-p} that define the +operational mode of the program (@code{create}, @code{extract} and +@code{pass-through}, respectively). They form an equivalence class from +which one and only one member must appear on the command line. If +@code{cpio} were an AutoOpt-ed program, then each of these option +definitions would contain: + +@example +equivalence = create; +@end example + +and the program would be able to determine the operating mode +with code that worked something like this: + +@example +switch (WHICH_IDX_CREATE) @{ +case INDEX_OPT_CREATE: ... +case INDEX_OPT_EXTRACT: ... +case INDEX_OPT_PASS_THROUGH: ... +default: /* cannot happen */ +@} +@end example + +@node opt-attr aliases +@subsubsection Option Aliasing + +Sometimes, for backwards compatibility or tradition or just plain convenience, +it works better to define one option as a pure alias for another option. +For such situations, provide the following pieces of information: +@example +flag = @{ + name = @i{aliasing-option-name}; + value = @i{aliasing-flag-char}; // optional ! + aliases = @i{aliased-to-option}; +@}; +@end example +Do not provide anything else. The usage text for such an option will be: +@example + This is an alias for @i{aliased-to-option} +@end example + +@node opt-attr default option +@subsubsection Default Option +@vindex default +If your program processes its arguments in named option mode (See +@code{long-opts} in @ref{program attributes}), then you may select +@strong{one} of your options to be the default option. Do so by using +attribute @code{default} with one of the options. The option so specified +must have an @code{arg-type} (@pxref{Option Arguments}) specified, but not the +@code{arg-optional} (@pxref{arg-optional}) attribute. That is to say, the +option argument must be required. + +If you have done this, then any arguments that do not match an option name and +do not contain an equal sign (@code{=}) will be interpreted as an option +argument to the default option. + +@node opt-attr documentation +@subsubsection Option Sectioning Comment +This attribute means the option exists for the purpose of separating option +description text in the usage output and texi documentation. Without this +attribute, every option is a separate node in the texi docs. With this +attribute, the documentation options become texi doc nodes and the options are +collected under them. Choose the name attribute carefully because it will +appear in the texi documentation. + +Libraries may also choose to make it settable so that the library can +determine which command line option is the first one that pertains to the +library. + +@vindex documentation +If the @samp{documentation} attribute is present, then all other +attributes are disabled except @code{settable}, @code{call-proc} and +@code{flag-code}. @code{settable} must be and is only specified if +@code{call-proc}, @code{extract-code} or @code{flag-code} has been specified. +When present, the @code{descrip} attribute will be displayed only when the +@option{--help} option has been specified. It will be displayed flush to the +left hand margin and may consist of one or more lines of text, filled to 72 +columns. + +The name of the option will not be printed in the help text. It @i{will}, +however, be printed as section headers in the texi documentation. If the +attribute is given a non-empty value, this text will be reproduced in the man +page and texi doc immediately after the @code{descrip} text. + +@node opt-attr translators +@subsubsection Translator Notes +@vindex translators +If you need to give the translators a special note about a particular option, +please use the @code{translators} attribute. The attribute text will be +emitted into the generated @code{.c} text where the option related strings get +defined. To make a general comment about all of the option code, add comments +to an @code{include} attribute (@pxref{program attributes}). Do @strong{not} +use this attribute globally, or it will get emitted into every option +definition block. + +@node Option Arguments +@subsection Option Argument Specification +@cindex Option Arguments + +Command line options come in three flavors: options that do not +take arguments, those that do and those that may. Without an +"arg-type" attribute, AutoOpts will not process an argument to an +option. If "arg-type" is specified and "arg-optional" is also +specified, then the next command line token will be taken to +be an argument, unless it looks like the name of another option. + +If the argument type is specified to be anything other than "str[ing]", then +AutoOpts will specify a callback procedure to handle the argument. Some of +these procedures will be created and inserted into the generated @file{.c} +file, and others are already built into the @file{libopts} library. +Therefore, if you write your own callback procedure +(@pxref{Option Argument Handling}), then you must either not specify an +"arg-type" attribute, or else specify it to be of type "str[ing]". Your +callback function will be able to place its own restrictions on what that +string may contain or represent. + +Option argument handling attributes depend upon the value set for the +@vindex arg-type +@code{arg-type} attribute. It specifies the type of argument the option +will take. If not present, the option cannot take an argument. If present, +it must be an entry in the following table. The first three letters is +sufficient. + +@menu +* arg-type string:: Arg Type String +* arg-type number:: Arg Type Number +* arg-type boolean:: Arg Type Boolean +* arg-type keyword:: Arg Type Keyword +* arg-type set membership:: Arg Type Set Membership +* arg-type hierarchy:: Arg Type Hierarchical +* arg-type file name:: Arg Type File Name +* arg-type time-duration:: Arg Type Time Duration +* arg-type time-date:: Arg Type Time and Date + +Supporting attributes for particular argument types: + +* arg-keyword:: Keyword list +* arg-optional:: Option Argument Optional +* arg-default:: Default Option Argument Value +@end menu + +@node arg-type string +@subsubsection Arg Type String +@code{arg-type = string;} + +The argument may be any arbitrary string, though your program or option +callback procedure may place additional constraints upon it. + + +@node arg-type number +@subsubsection Arg Type Number +@code{arg-type = number;} + +The argument must be a correctly formed integer, without any trailing U's or +L's. AutoOpts contains a library procedure to convert the string to a number. +If you specify range checking with @code{arg-range} (see below), then AutoOpts +produces a special purpose procedure for this option. + +@table @samp +@item scaled +@vindex scaled +@code{scaled} marks the option so that suffixes of @samp{k}, @samp{K}, +@samp{m}, @samp{M}, @samp{g}, @samp{G}, @samp{t}, and @samp{T} will multiply +the given number by a power of 1000 or 1024. Lower case letters scale by a +power of 1000 and upper case scale by a power of 1024. + +@item arg-range +@vindex arg-range +@code{arg-range} is used to create a callback procedure for validating the +range of the option argument. It must match one of the range entries. Each +@code{arg-range} should consist of either an integer by itself or an integer +range. The integer range is specified by one or two integers separated by the +two character sequence, @code{->}. Be sure to quote the entire range string. +The definitions parser will not accept the range syntax as a single string +token. + +The generated procedure imposes the range constraints as follows: +@itemize @bullet +@item +A number by itself will match that one value. +@item +The high end of the range may not be @code{INT_MIN}, both for obvious +reasons and because that value is used to indicate a single-valued match. +@item +An omitted lower value implies a lower bound of INT_MIN. +@item +An omitted upper value implies a upper bound of INT_MAX. +@item +The argument value is required. It may not be optional. +@item +The value must match one of the entries. If it can match more than one, +then you have redundancies, but no harm will come of it. +@end itemize +@end table + + +@node arg-type boolean +@subsubsection Arg Type Boolean +@code{arg-type = boolean;} + +The argument will be interpreted and always yield either AG_TRUE or +AG_FALSE. False values are@: the empty string, the number zero, or a +string that starts with @code{f}, @code{F}, @code{n} or @code{N} +(representing False or No). Anything else will be interpreted as True. + + +@node arg-type keyword +@subsubsection Arg Type Keyword +@code{arg-type = keyword;} + +The argument must match a specified list of strings (@pxref{arg-keyword}). +Assuming you have named the option, @code{optn-name}, the strings will be +converted into an enumeration of type @code{te_Optn_Name} with the values +@code{OPTN_NAME_KEYWORD}.* If you have @strong{not} specified a default +value, the value @code{OPTN_NAME_UNDEFINED} will be inserted with the value +zero. The option will be initialized to that value. You may now use this +in your code as follows: + +@example +te_Optn_Name opt = OPT_VALUE_OPTN_NAME; +switch (opt) @{ +case OPTN_NAME_UNDEFINED: /* undefined things */ break; +case OPTN_NAME_KEYWORD: /* `keyword' things */ break; +default: /* utterly impossible */ ; +@} +@end example + +AutoOpts produces a special purpose procedure for this option. +You may not specify an alternate handling procedure. + +If you have need for the string name of the selected keyword, you +may obtain this with the macro, @code{OPT_OPTN_NAME_VAL2STR(val)}. +The value you pass would normally be @code{OPT_VALUE_OPTN_NAME}, +but anything with numeric value that is legal for @code{te_Optn_Name} +may be passed. Anything out of range will result in the string, +@samp{"*INVALID*"} being returned. The strings are read only. +It may be used as in: + +@example +te_Optn_Name opt = OPT_VALUE_OPTN_NAME; +printf( "you selected the %s keyword\n", + OPT_OPTN_NAME_VAL2STR(opt) ); +@end example + +* Note: you may replace the @code{OPTN_NAME} enumeration prefix with +another prefix by specifying a +@vindex prefix-enum +@code{prefix-enum} attribute. + +Finally, users may specify the argument either by name or by number. +Since the numeric equivalents change by having new entries inserted +into the keyword list, this would not be a recommended practice. +However, either @code{-1} or @code{~0} will always be equivalent to +specifying the last keyword. + +@node arg-type set membership +@subsubsection Arg Type Set Membership +@code{arg-type = set;} + +The argument must be a list of names each of which must match the strings +``@code{all}'', ``@code{none}'' or one of the keywords (@pxref{arg-keyword}) +specified for this option. @code{all} will turn on all membership bits and +@code{none} will turn them all off. Specifying one of the keywords will set +the corresponding set membership bit on (or off, if negated) . Literal +numbers may also be used and may, thereby, set or clear more than one bit. + +The membership result starts with the previous (or initialized) result. To +clear previous results, either start the membership string with @samp{none +} +or with the equals character (@samp{=}). To invert (bit flip) the final +result (regardless of whether the previous result is carried over or not), +start the string with a carat character (@samp{^}). If you wish to invert the +result and start without a carried over value, use one of the following: +@code{=^} or @code{^none+}. These are equivalent. + +The list of names or numbers must be separated by one of the following +characters: @samp{+-|!,} or whitespace. The comma is equivalent to +whitespace, except that only one may appear between two entries and it may not +appear in conjunction with the @var{or} bar (@samp{|}). The @samp{+|} leading +characters or unadorned name signify adding the next named bit to the mask, +and the @samp{-!} leading characters indicate removing it. + +The number of keywords allowed is constrained by the number of bits in a +pointer, as the bit set is kept in a @code{void *} pointer. + +If, for example, you specified @code{first} in your list of keywords, +then you can use the following code to test to see if either @code{first} +or @code{all} was specified: + +@example +uintptr_t opt = OPT_VALUE_OPTN_NAME; +if (opt & OPTN_NAME_FIRST) + /* OPTN_NAME_FIRST bit was set */ ; +@end example + +AutoOpts produces a special purpose procedure for this option. +To set multiple bits as the default (initial) value, you must +specify an initial numeric value (which might become inaccurate over +time), or else specify @code{arg-default} multiple times. Do not +specify a series of names conjoined with @code{+} symbols as the +value for any of the @code{arg-default} attributes. That works for +option parsing, but not for the option code generation. + +@node arg-type hierarchy +@subsubsection Arg Type Hierarchical +@code{arg-type = hierarchy;} +@* +@code{arg-type = nested;} + +This denotes an option with a structure-valued argument, a.k.a. +@code{subopts} in @code{getopts} terminology. The argument is parsed +and the values made available to the program via the find and +find next calls (@xref{libopts-optionFindValue}, +@xref{libopts-optionGetValue}, and +@pxref{libopts-optionFindNextValue}). + +@example +tOptionValue * val = optionGetValue(VALUE_OPT_OPTN_NAME, "name"); +while (val != NULL) @{ + process(val); + val = optionNextValue(VALUE_OPT_OPTN_NAME, val); + if (wrong_name(val, "name")) + break; +@} +@end example + + +@node arg-type file name +@subsubsection Arg Type File Name +@code{arg-type = file;} + +This argument type will have some validations on the argument and, +optionally, actually open the file. You must specify several additonal +attributes for the option: + +@table @samp +@item file-exists +@vindex file-exists +If not specified or empty, then the directory portion of the name is checked. +The directory must exist or the argument is rejected and the usage procedure +is invoked. + +Otherwise, both the directory as above and the full name is tested for +existence. If the value begins with the two letters @code{no}, then the file +must not pre-exist. Otherwise, the file is expected to exist. + +@item open-file +@vindex open-file +If not specified or empty, the file is left alone. +If the value begins with the four letters @code{desc}[@i{riptor}], then +@code{open(2)} is used and @code{optArg.argFd} is set. Otherwise, the +file is opened with @code{fopen} and @code{optArg.argFp} is set. + +@item file-mode +@vindex file-mode +If @code{open-file} is set and not empty, then you must specify the open mode. +Set the value to the flag bits or mode string as appropriate for the open +type. +@end table + + +@node arg-type time-duration +@subsubsection Arg Type Time Duration +@code{arg-type = time-duration;} + +The argument will be converted into a number of seconds. It may be +a multi-part number with different parts being multiplied into a seconds +value and added into the final result. Valid forms are in the table +below. Upper cased letters represent numbers that must be used in the +expressions. + +@table @samp +@item [[HH:]MM:]SS +@code{HH} is multiplied by @code{3600} and @code{MM} multiplied by @code{60} +before they are added to @code{SS}. This time specification may not be +followed by any other time specs. @code{HH} and @code{MM} are both optional, +though @code{HH} cannot be specified without @code{MM}. + +@item DAYS d +@code{DAYS} is multiplied by the number of seconds in a day. This value may +be followed by (and added to) values specified by @code{HH:MM:SS} or the +suffixed values below. If present, it must always be first. + +@item HRS h +@code{HRS} is multiplied by the number of seconds in an hour. This value may +be followed by (and added to) values specified by @code{MM:SS} or the +suffixed values below. + +@item MINS m +@code{MINS} is multiplied by the number of seconds in a minute. This value +may be followed by (and added to) a count of seconds. + +@item SECS s +This value can only be the last value in a time specification. The @code{s} +suffix is optional. +@end table + +@example + 5 d 1:10:05 ==> 5 days + 1 hour 10 minutes and 5 seconds + 5 d 1 h 10 m 5 ==> yields: 436205 seconds + 5d1h10m5s ==> same result -- spaces are optional. +@end example + +When saved into a config file, the value will be stored as a simple count +of seconds. There are actually more (many) accepted time duration strings. +The full documentation can be found with ISO-8601 documentation and the +more extedded documentation when @code{parse_duration()} becomes more widely +available. + + +@node arg-type time-date +@subsubsection Arg Type Time and Date +@code{arg-type = time-date;} + +The argument will be converted into the number of seconds since the epoch. +The conversion rules are very complicated, please see the +@file{getdate_r(3GNU)} man page. There are some additional restrictions: + +@enumerate +@item +Your project must be compiled with @code{PKGDATADIR} defined and naming a +valid directory. +@item +The @env{DATEMSK} environment variable will be set to the @file{datemsk} file +within that directory. +@end enumerate + +If that file is not accessible for any reason, the string will be +parsed as a time duration (@pxref{arg-type time-duration}) instead of a +specific date and time. + +@node arg-keyword +@subsubsection Keyword list +@vindex keyword +If the @code{arg-type} is @code{keyword} (@pxref{arg-type keyword}) or +@code{set-membership} (@pxref{arg-type set membership}), then you must specify +the list of keywords by a series of @code{keyword} entries. The interface +file will contain values for @env{@i{<OPTN_NAME>}_@i{<KEYWORD>}} for each +keyword entry. @code{keyword} option types will have an enumeration and +@code{set-membership} option types will have a set of unsigned bits +@code{#define}-d. + +If the @code{arg-type} is specifically @code{keyword}, you may also add +special handling code with a +@vindex extra-code +@code{extra-code} attribute. After @code{optionEnumerationVal} has +converted the input string into an enumeration, you may insert code to +process this enumeration value (@code{pOptDesc->optArg.argEnum}). + +@node arg-optional +@subsubsection Option Argument Optional +@vindex arg-optional +The @code{arg-optional} attribute indicates that the argument to the option is +optional (need not be specified on the command line). This is only valid if +the @var{arg-type} is @code{string} (@pxref{arg-type string}) or +@code{keyword} (@pxref{arg-type keyword}). If it is @code{keyword}, then this +attribute may also specify the default keyword to assume when the argument is +not supplied. If left empty, @var{arg-default} (@pxref{arg-default}) or the +zero-valued keyword will be used. + +The syntax rules for identifying the option argument are: +@itemize @bullet +@item +If the option is specified with a flag character and there is a character +following the flag character, then string following that flag character is the +option argument. +@item +If the flag character is the last character in an argument, then +the first character of the next argument is examined. If it is a hyphen, +then the option is presumed to not have an argument. Otherwise, the entire +next argument is the argument for the option. +@item +If the option is specified with a long option name and that name is ended with +an equal sign character (@code{=}), then everything after that character is the +option argument. +@item +If the long name is ended by the end of the argument, then the first character +of the next argument is examined, just as with the flag character ending an +argument string. +@end itemize + +This is overridden and the options are required if the libopts library +gets configured with @option{--disable-optional-args}. + +@node arg-default +@subsubsection Default Option Argument Value +@vindex arg-default +This specifies the default option argument value to be used when the option is +not specified or preset. You may specify multiple @code{arg-default} values +if the argument type is @code{set membership}. + +@node Option Argument Handling +@subsection Option Argument Handling +@cindex Option Argument Handling + +AutoOpts will either specify or automatically generate callback procedures +for options that take specialized arguments. The only option argument types +that are not specialized are plain string arguments and no argument at all. +For options that fall into one of those two categories, you may specify your +own callback function, as specified below. If you do this and if you +specify that options are resettable (@pxref{automatic options}), then your +option handling code @strong{must} look for the @samp{OPTST_RESET} bit in +the @code{fOptState} field of the option descriptor. + +If the option takes a string argument, then the @code{stack-arg} attribute can +be used to specify that the option is to be handled by the @code{libopts} +@code{stackOptArg()} and @code{unstackOptArg()} library procedures (see +below). In this case, you may not provide option handling code. + +Finally, @samp{documentation} options (@pxref{opt-attr documentation}) may +also be marked as @option{settable} (@pxref{opt-attr settable}) and have +special callback functions (either @samp{flag-code}, @samp{extract-code}, +or @samp{call-proc}). + +@table @samp +@item flag-code +@vindex flag-code +statements to execute when the option is encountered. This may be used in +conjunction with option argument types that cause AutoOpts to emit handler +code. If you do this, the @samp{flag-code} with index zero (0) is emitted +into the handler code @emph{before} the argument is handled, and the entry +with index one (1) is handled afterward. + +The generated procedure will be laid out something like this: + +@example +static void +doOpt<name>(tOptions* pOptions, tOptDesc* pOptDesc) +@{ +<flag-code[0]> +<AutoOpts defined handler code> +<flag-code[1]> +@} +@end example + +Only certain fields within the @code{tOptions} and @code{tOptDesc} +structures may be accessed. @xref{Option Processing Data}. When writing +this code, you must be very careful with the @code{pOptions} pointer. The +handler code is called with this pointer set to special values for handling +special situations. Your code must handle them. As an example, +look at @code{optionEnumerationVal} in @file{enum.c}. + +@item extract-code +@vindex extract-code +This is effectively identical to @code{flag-code}, except that the +source is kept in the output file instead of the definitions file +and you cannot use this in conjunction with options with arguments, +other than string arguments. + +A long comment is used to demarcate the code. You must not modify +that marker. @i{Before} regenerating the option code file, +the old file is renamed from MUMBLE.c to MUMBLE.c.save. The template +will be looking there for the text to copy into the new output file. + +@item call-proc +@vindex call-proc +external procedure to call when option is encountered. The calling +sequence must conform to the sequence defined above for the generated +procedure, @code{doOpt<name>}. It has the same restrictions +regarding the fields within the structures passed in as arguments. +@xref{Option Processing Data}. + +@item flag-proc +@vindex flag-proc +Name of another option whose @code{flag-code} can be executed +when this option is encountered. + +@item stack-arg +@vindex stack-arg +Call a special library routine to stack the option's arguments. Special +macros in the interface file are provided for determining how many of the +options were found (@code{STACKCT_OPT(NAME)}) and to obtain a pointer to a +list of pointers to the argument values (@code{STACKLST_OPT(NAME)}). +Obviously, for a stackable argument, the @code{max} attribute +(@pxref{Common Attributes}) needs to be set higher than @code{1}. + +If this stacked argument option has a disablement prefix, then the entire +stack of arguments will be cleared by specifying the option with that +disablement prefix. + +@item unstack-arg +@vindex unstack-arg +Call a special library routine to remove (@code{unstack}) strings +from a @code{stack-arg} option stack. This attribute must name +the option that is to be @code{unstacked}. Neither this option nor +the stacked argument option it references may be equivalenced to +another option. +@end table + +@node Internationalizing Options +@subsection Internationalizing Options +@cindex Internationalizing Options + +Normally, AutoOpts produces usage text that is difficult to translate. It is +pieced together on the fly using words and phrases scattered around here and +there, piecing together toe document. This does not translate well. + +Incorporated into this package are some ways around the problem. First, you +should specify the @code{full-usage} and @code{short-usage} program attributes +(@pxref{program attributes}). This will enable your translators to translate +the usage text as a whole. + +Your translators will also be able to translate long option names. The option +name translations will then become the names searched for both on the command +line and in configuration files. However, it will not affect the names of +environment variable names used to configure your program. + +If it is considered desireable to keep configuration files in the @code{C} +locale, then several macros are available to suppress or delay the +translations of option names at run time. These are all disabled if +@code{ENABLE_NLS} is not defined at compile time or if @code{no-xlate} has +been set to the value @emph{anything}. These macros @strong{must} +be invoked before the first invocation of @code{optionProcess}. + +@table @samp +@item OPT_NO_XLAT_CFG_NAMES; +@itemx OPT_XLAT_CFG_NAMES; +Disable (or enable) the translations of option names for configuration files. +If you enable translation for config files, then they will be translated for +command line options. + +@item OPT_NO_XLAT_OPT_NAMES; +@itemx OPT_XLAT_OPT_NAMES; +Disable (or enable) the translations of option names for command line +processing. If you disable the translation for command line processing, +you will also disable it for configuration file processing. Once translated, +the option names will remain translated. +@end table + +@node documentation attributes +@subsection Man and Info doc Attributes +@cindex documentation attributes + +AutoOpts includes AutoGen templates for producing abbreviated man pages +and for producing the invoking section of an info document. To take +advantage of these templates, you must add several attributes to your +option definitions. + +@menu +* per option attributes:: Per option documentation attributes +* global option attributes:: Global documentation attributes +@end menu + +@node per option attributes +@subsubsection Per option documentation attributes + +These attributes are sub-attributes (@i{sub-stanzas}) of the @code{flag} stanzas. + +@table @samp +@item arg-name +@vindex arg-name +If an option has an argument, the argument should have a name for +documentation purposes. It will default to @code{arg-type}, but +it will likely be clearer with something else like, @code{file-name} +instead of @code{string} (the type). + +@item doc +@vindex doc +First, every @code{flag} definition @emph{other than} @code{documentation} +definitions, must have a @code{doc} attribute defined. If the option takes +an argument, then it will need an @code{arg-name} attribute as well. The +@code{doc} text should be in plain sentences with minimal formatting. The +Texinfo commands @code{@@code}, and @code{@@var} will have its enclosed text +made into @strong{\fB} entries in the man page, and the @code{@@file} text +will be made into @strong{\fI} entries. The @code{arg-name} attribute is +used to display the option's argument in the man page. + +Options marked with the @code{documentation} attribute are for documenting +the usage text. All other options should have the @code{doc} attribute in +order to document the usage of the option in the generated man pages. + +Since these blocks of text are inserted into all output forms, +any markup text included in these blocks must be massaged for each +output format. By default, it is presumed to be @file{texi} format. +@end table + +@node global option attributes +@subsubsection Global documentation attributes +@table @samp +@item cmd-section +@vindex cmd-section +If your command is a game or a system management command, +specify this attribute with the value @code{5} or @code{8}, respectively. +The default is a user command (section 1). + +@item detail +@vindex detail +This attribute is used to add a very short explanation about what +a program is used for when the @code{title} attribute is insufficient. +If there is no @code{doc-section} stanza of type @code{DESCRIPTION}, then +this text is used for the man page DESCRIPTION section, too. + +@item addtogroup +@vindex addtogroup +This attribute tells the template that the generated code should be +surrounded with the following doxygen comments: +@example +/** @@file <header-or-code-file-name> + * @@addtogroup <value-of-addtogroup> + * @@@{ + */ +@end example +@noindent +and +@example +/** @@@} */ +@end example + +@item option-format +@vindex option-format +Specify the default markup style for the @code{doc} stanzas. +By default, it is @code{texi}, but @code{man} and @code{mdoc} may +also be selected. There are nine converter programs that do a partial +job of converting one form of markup into another. @command{texi2texi}, +@command{man2man} and @command{mdoc2mdoc} work pretty well. + +You may also post process the document by using @code{doc-sub} stanzas, +see below. + +@item option-info +@vindex option-info +This text will be inserted as a lead-in paragraph in the @code{OPTIONS} +section of the generated man page. + +@item doc-section +@vindex doc-section +This is a compound attribute that requires three @i{sub}attributes: + +@table @i +@item ds-format +This describes the format of the associated @code{ds-text} section. +@code{man}, @code{mdoc} and @code{texi} formats are supported. +Regardless of the chosen format, the formatting tags in the output +text will be converted to @code{man} macros for @code{man} pages, +@code{mdoc} macros for @code{mdoc} pages, and @code{texi} macros for +@code{texinfo} pages. + +@item ds-text +This is the descriptive text, written according to the rules for +@code{ds-format} documents. + +@item ds-type +This describes the section type. Basically, the title of the section +that will be added to all output documentation. There may be only one +@code{doc-section} for any given @code{ds-type}. If there are duplicates, +the results are undefined (it might work, it might not). + +There are five categories of @code{ds-type} sections. +They are those that the documentation templates would otherwise: +@enumerate +@item +always create itself, ignoring any @code{ds-type}s by this name. +These are marked, below, as @code{ao-only}. +@item +create, if none was provided. +These are marked, @code{alternate}. +@item +create, but augment if the @code{doc-section} was provided. +These are marked, @code{augments}. +@item +do nothing, but inserts them into the output in a prescribed order. +These are marked, @code{known} +@item +knows nothing about them. They will be alphabetized and inserted +after the list of leading sections and before the list of trailing +sections. These are not marked because I don't know their names. +@end enumerate + +Some of these are emitted by the documentation templates only if +certain conditions are met. If there are conditions, they are +explained below. If there are no conditions, then you will always +see the named section in the output. + +The output sections will appear in this order: +@table @samp +@item NAME +@code{ao-only}. +@item SYNOPSIS +@code{alternate}. +@item DESCRIPTION +@code{augments}. +@item OPTIONS +@code{ao-only}. +@item OPTION PRESETS +@code{ao-only}, if environment presets or configuration file processing +has been specified. +@item unknown +At this point, the unknown, alphabetized sections are inserted. +@item IMPLEMENTATION NOTES +@code{known} +@item ENVIRONMENT +@code{augments}, if environment presets have been specified. +@item FILES +@code{augments}, if configuration file processing has been specified. +@item EXAMPLES +@code{known} +@item EXIT STATUS +@code{augments}. +@item ERRORS +@code{known} +@item COMPATIBILITY +@code{known} +@item SEE ALSO +@code{known} +@item CONFORMING TO +@code{known} +@item HISTORY +@code{known} +@item AUTHORS +@code{alternate}, if the @code{copyright} stanza has either +an @code{author} or an @code{owner} attribute. +@item COPYRIGHT +@code{alternate}, if there is a @code{copyright} stanza. +@item BUGS +@code{augments}, if the @code{copyright} stanza has an +@code{eaddr} attribute. +@item NOTES +@code{augments}. +@end table +@end table + +@noindent +Here is an example of a @code{doc-section} for a @code{SEE ALSO} type. + +@example +doc-section = @{ + ds-type = 'SEE ALSO'; // or anything else + ds-format = 'man'; // or texi or mdoc format + ds-text = <<-_EOText_ + text relevant to this section type, + in the chosen format + _EOText_; +@}; +@end example + +@item doc-sub +@vindex doc-sub +This attribute will cause the resulting documentation to be post-processed. +This is normally with @command{sed}, see @code{doc-sub-cmd} below. +This attribute has several sub-attributes: + +@table @samp +@item sub-name +This is the name of an autogen text definition value, like @code{prog-name} +or @code{version}. In the @code{sub-text} field, occurrences of this +name preceded by two less than characters and followed by two greater +than characters will be replaced by the text value of the definition, +e.g. @samp{<<prog-name>>}. + +@item sub-text +The text that gets added to the command file for the post processing +program. + +@item sub-type +If this command only applies to certain types of output, specify +this with a regular expression that will match one of the valid +output format types, e.g. @samp{man|mdoc} will match those two kinds, +but not @code{texi} output. If omitted, it will always apply. +@end table + +For example, if you want to reference the program name in the @code{doc} +text for an option common to two programs, put @samp{#PROG#} into the +text. The following will replace all occrrences of @samp{#PROG#} +with the current value for @code{prog}: +@example +doc-sub = @{ + sub-name = prog-name; + sub-text = 's/#PROG#/<<prog-name>>/g'; +@}; +@end example + +@item doc-sub-cmd +@vindex doc-sub-cmd +A formatting string for constructing the post-processing command. +The first parameter is the name of the file with editing commands in it, +and the second is the file containing the unprocessed document. +The default value is: +@example +sed -f %s %s +@end example +@end table + +@node automatic options +@subsection Automatically Supported Options +@cindex automatic options + +AutoOpts provides automated support for several options. @code{help} and +@code{more-help} are always provided. The others are conditional upon +various global program attributes being defined @xref{program attributes}. + +Below are the option names and default flag values. The flags are activated +if and only if at least one user-defined option also uses a flag value. The +long names are supported as option names if @code{long-opts} has been +specified. These option flags may be deleted or changed to characters of your +choosing by specifying +@vindex more-help-value +@vindex usage-value +@vindex version-value +@vindex load-opts-value +@vindex reset-value +@code{xxx-value = "y";}, where @code{xxx} is one of the option names below and +@code{y} is either empty or the character of your choice. For example, to +change the help flag from @code{?} to @code{h}, specify +@vindex help-value +@code{help-value = "h";}; and to require that @code{save-opts} be specified +only with its long option name, specify +@vindex save-opts-value +@code{save-opts-value = "";}. + +Additionally, the procedure that prints out the program version may be +replaced by specifying @code{version-proc}. +@vindex version-proc +This procedure must be defined to be of external scope (non-static). +By default, the AutoOpts library provides @code{optionPrintVersion} +and it will be the specified callback function in the option +definition structure. + +With the exception of the @code{load-opts} option, none of these automatically +supported options will be recognized in configuration files or environment +variables. + +@table @samp +@item help -? +This option will immediately invoke the @code{USAGE()} procedure +and display the usage line, a description of each option with +its description and option usage information. This is followed +by the contents of the definition of the @code{detail} text macro. + +@item more-help -! +This option is identical to the @code{help} option, except that the +output is passed through a pager program. (@code{more} by default, or +the program identified by the @code{PAGER} environment variable.) + +@item usage -u +This option must be requested by specifying, @code{usage-opt} in the option +definition file. It will produce abbreviated help text to @file{stdout} and +exit with zero status (@code{EXIT_SUCCESS}). + +@item version -v + +This will print the program name, title and version. If it is not +followed by anything or is followed by the letter @code{v}, just the +program name and version will be printed. If followed by the letter +@code{c} and a value for @code{copyright} and @code{owner} have been +provided, then the copyright will be printed, too. If it is followed by +the letter @code{n}, then the full copyright notice (if available) will +be printed. The @code{version} attribute must be specified in the +option definition file. + +Because some target platforms discourage optional arguments to options, +the autoopts library can be compiled with @code{NO_OPTIONAL_OPT_ARGS} +defined. Alternatively, the @code{version-type} attribute can be added +to the option definitions and it can specify which flavor is preferred. +In either case, an argument to the @code{--version} option will then be +disallowed. + +@item load-opts -< +@cindex configuration file +This option will load options from the named file. They will be treated +exactly as if they were loaded from the normally found configuration files, +but will not be loaded until the option is actually processed. This can also +be used within another configuration file, causing them to nest. This is the +@strong{only} automatically supported option that can be activated inside of +config files or with environment variables. + +Specifying the negated form of the option (@option{--no-load-opts}) will +suppress the processing of configuration files and environment variables. + +This option is activated by specifying one or more @code{homerc} attributes. + +@item save-opts -> +@cindex configuration file +This option will cause the option state to be printed in the configuration +file format when option processing is done but not yet verified for +consistency. The program will terminate successfully without running when +this has completed. Note that for most shells you will have to quote or +escape the flag character to restrict special meanings to the shell. + +The output file will be the configuration file name (default or provided by +@code{rcfile}) in the last directory named in a @code{homerc} definition. + +This option may be set from within your program by invoking the +"@code{SET_OPT_SAVE_OPTS(@i{filename})}" macro (@pxref{SET_OPT_name}). +Invoking this macro will set the file name for saving the option processing +state, but the state will @strong{not} actually be saved. You must call +@code{optionSaveFile} to do that (@pxref{libopts-optionSaveFile}). +@strong{CAVEAT:} if, after invoking this macro, you call +@code{optionProcess}, the option processing state will be saved to this file +and @code{optionProcess} will not return. You may wish to invoke +@code{CLEAR_OPT( SAVE_OPTS )} (@pxref{CLEAR_OPT}) beforehand if you do need +to reinvoke @code{optionProcess}. + +This option is activated by specifying one or more @code{homerc} attributes. + +The method of saving the state may be altered by specifying flags before +the output file name. ``Flags'' are specified by placing a list of them +before the file name and separating them from the name with one or two +greater-than characters (``>''). There are three flags currently supported: + +@table @samp +@item default +If an option has a default value (has not been set), then the default value +is inserted as a comment. + +@item usage +Every option that can be processed from the configuration file will have a +comment that contains the usage string that gets printed with the @code{--help} text + +@item update +Instead of removing the old file and writing a new one, the output file is kept, +but any pre-existing segment labeled with @code{<?program prog-name>} is removed. +The new program segment is placed at the end of the file. This flag is implied if +the flags are separated from the file name with doubled greater-than characters. +In other words, @code{update,usage > @i{file-name}} and @code{usage >> @i{file-name}} +are identical. +@end table + +@item reset-option -R +This option takes the name of an option for the current program and resets its +state such that it is set back to its original, compile-time initialized +value. If the option state is subsequently stored (via @option{--save-opts}), +the named option will not appear in that file. + +This option is activated by specifying the @code{resettable} attribute. + +@strong{BEWARE}: If the @code{resettable} attribute is specified, all +option callbacks @strong{must} look for the @code{OPTST_RESET} bit in the +@code{fOptState} field of the option descriptor. If set, the @code{optCookie} +and @code{optArg} fields will be unchanged from their last setting. When the +callback returns, these fields will be set to their original values. If you +use this feature and you have allocated data hanging off of the cookie, you +need to deallocate it. +@end table + +@node standard options +@subsection Library of Standard Options +@cindex standard options + +AutoOpts has developed a set of standardized options. +You may incorporate these options in your program simply by @emph{first} +adding a @code{#define} for the options you want, and then the line, + +@example +#include stdoptions.def +@end example + +@noindent +in your option definitions. The supported options are specified thus: + +@example +#define DEBUG +#define DIRECTORY +#define DRY_RUN +#define INPUT +#define INTERACTIVE +#define OUTPUT +#define WARN + +#define SILENT +#define QUIET +#define BRIEF +#define VERBOSE +@end example + +By default, only the long form of the option will be available. +To specify the short (flag) form, suffix these names with @code{_FLAG}. +e.g., + +@example +#define DEBUG_FLAG +@end example + +@option{--silent}, @option{--quiet}, @option{--brief} and @option{--verbose} +are related in that they all indicate some level of diagnostic output. These +options are all designed to conflict with each other. Instead of four +different options, however, several levels can be incorporated by +@code{#define}-ing @code{VERBOSE_ENUM}. In conjunction with @code{VERBOSE}, +it incorporates the notion of @i{5} levels in an enumeration: @code{silent}, +@code{quiet}, @code{brief}, @code{informative} and @code{verbose}; with the +default being @code{brief}. + +@ignore +END == AUTOOPTS-MAIN == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore +Here is an example program that uses the following set of definitions: + +@example +AutoGen Definitions options; + +prog-name = default-test; +prog-title = 'Default Option Example'; +homerc = '$$/../share/default-test', '$HOME', '.'; +environrc; +long-opts; +gnu-usage; +usage-opt; +version = '1.0'; +main = @{ + main-type = shell-process; +@}; +#define DEBUG_FLAG +#define WARN_FLAG +#define WARN_LEVEL +#define VERBOSE_FLAG +#define VERBOSE_ENUM +#define DRY_RUN_FLAG +#define OUTPUT_FLAG +#define INPUT_FLAG +#define DIRECTORY_FLAG +#define INTERACTIVE_FLAG +#include stdoptions.def +@end example + +@noindent +Running a few simple commands on that definition file: + +@example +autogen default-test.def +copts="-DTEST_DEFAULT_TEST_OPTS `autoopts-config cflags`" +lopts="`autoopts-config ldflags`" +cc -o default-test $@{copts@} default-test.c $@{lopts@} +@end example + +@noindent +Yields a program which, when run with @file{--help}, prints out: + +@example + +exit 0 +@end example +@ignore +START == AUTOOPTS-API == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore + +@c === SECTION MARKER + +@node AutoOpts API +@section Programmatic Interface +@cindex AutoOpts API + +The user interface for access to the argument information is completely +defined in the generated header file and in the portions of the +distributed file "options.h" that are marked "public". + +In the following macros, text marked @var{<NAME>} or @var{name} +is the name of the option @strong{in upper case} and +@strong{segmented with underscores @code{_}}. The macros and enumerations +defined in the options header (interface) file are used as follows: + +To see how these @code{#define} macros are used in a program, +the reader is referred to the several @file{opts.h} files +included with the AutoGen sources. + +@menu +* Option Processing Data:: Data for Option Processing +* CLEAR_OPT:: CLEAR_OPT( <NAME> ) - Clear Option Markings +* COUNT_OPT:: COUNT_OPT( <NAME> ) - Definition Count +* DESC:: DESC( <NAME> ) - Option Descriptor +* DISABLE_OPT_name:: DISABLE_OPT_name - Disable an option +* ENABLED_OPT:: ENABLED_OPT( <NAME> ) - Is Option Enabled? +* ERRSKIP_OPTERR:: ERRSKIP_OPTERR - Ignore Option Errors +* ERRSTOP_OPTERR:: ERRSTOP_OPTERR - Stop on Errors +* HAVE_OPT:: HAVE_OPT( <NAME> ) - Have this option? +* ISSEL_OPT:: ISSEL_OPT( <NAME> ) - Is Option Selected? +* ISUNUSED_OPT:: ISUNUSED_OPT( <NAME> ) - Never Specified? +* OPTION_CT:: OPTION_CT - Full Count of Options +* OPT_ARG:: OPT_ARG( <NAME> ) - Option Argument String +* OPT_NO_XLAT_CFG_NAMES:: OPT_NO_XLAT_CFG_NAMES - option name xlation +* OPT_NO_XLAT_OPT_NAMES:: OPT_NO_XLAT_OPT_NAMES - option name xlation +* OPT_VALUE_name:: OPT_VALUE_name - Option Argument Value +* OPT_XLAT_CFG_NAMES:: OPT_XLAT_CFG_NAMES - option name xlation +* OPT_XLAT_OPT_NAMES:: OPT_XLAT_OPT_NAMES - option name xlation +* RESTART_OPT:: RESTART_OPT( n ) - Resume Option Processing +* SET_OPT_name:: SET_OPT_name - Force an option to be set +* STACKCT_OPT:: STACKCT_OPT( <NAME> ) - Stacked Arg Count +* STACKLST_OPT:: STACKLST_OPT( <NAME> ) - Argument Stack +* START_OPT:: START_OPT - Restart Option Processing +* STATE_OPT:: STATE_OPT( <NAME> ) - Option State +* USAGE:: USAGE( exit-code ) - Usage invocation macro +* VALUE_OPT_name:: VALUE_OPT_name - Option Flag Value +* VERSION:: VERSION - Version and Full Version +* WHICH_IDX_name:: WHICH_IDX_name - Which Equivalenced Index +* WHICH_OPT_name:: WHICH_OPT_name - Which Equivalenced Option +* teOptIndex:: teOptIndex - Option Index and Enumeration +* OPTIONS_STRUCT_VERSION:: OPTIONS_STRUCT_VERSION - active version +* libopts procedures:: libopts External Procedures +@end menu + +@node Option Processing Data +@subsection Data for Option Processing +@cindex Option Processing Data + +This section describes the data that may be accessed from within the +option processing callback routines. The following fields may be used +in the following ways and may be used for read only. The first set is +addressed from the @code{tOptDesc*} pointer: + +@table @samp +@cindex optIndex +@item optIndex +@cindex optValue +@item optValue +These may be used by option procedures to determine which option they +are working on (in case they handle several options). + +@cindex optActualIndex +@item optActualIndex +@cindex optActualValue +@item optActualValue +These may be used by option procedures to determine which option was +used to set the current option. This may be different from the above if +the options are members of an equivalence class. + +@cindex optOccCt +@item optOccCt +If AutoOpts is processing command line arguments, then this value will contain +the current occurrence count. During the option preset phase (reading +configuration files and examining environment variables), the value is zero. + +@cindex fOptState +@item fOptState +The field may be tested for the following bit values +(prefix each name with @code{OPTST_}, e.g. @code{OPTST_INIT}): + +@table @samp +@item INIT +Initial compiled value. As a bit test, it will always yield FALSE. + +@item SET +The option was set via the @code{SET_OPT()} macro. + +@item PRESET +@cindex configuration file +The option was set via a configuration file. + +@item DEFINED +The option was set via a command line option. + +@item SET_MASK +This is a mask of flags that show the set state, one of the +above four values. + +@item EQUIVALENCE +This bit is set when the option was selected by an equivalenced option. + +@item DISABLED +This bit is set if the option is to be disabled. +(Meaning it was a long option prefixed by the disablement prefix, or +the option has not been specified yet and initializes as @code{disabled}.) +@end table + +As an example of how this might be used, in AutoGen I want to allow +template writers to specify that the template output can be left +in a writable or read-only state. To support this, there is a Guile +function named @code{set-writable} (@pxref{SCM set-writable}). +Also, I provide for command options @option{--writable} and +@option{--not-writable}. I give precedence to command line and RC +file options, thus: + +@example +switch (STATE_OPT( WRITABLE )) @{ +case OPTST_DEFINED: +case OPTST_PRESET: + fprintf(stderr, zOverrideWarn, pCurTemplate->pzFileName, + pCurMacro->lineNo); + break; + +default: + if (gh_boolean_p( set ) && (set == SCM_BOOL_F)) + CLEAR_OPT( WRITABLE ); + else + SET_OPT_WRITABLE; +@} +@end example + +@cindex pzLastArg +@item pzLastArg +Pointer to the latest argument string. BEWARE@: If the argument type +is numeric, an enumeration or a bit mask, then this will be the +argument @strong{value} and not a pointer to a string. +@end table + +The following two fields are addressed from the @code{tOptions*} pointer: + +@table @samp +@cindex pzProgName +@item pzProgName +Points to a NUL-terminated string containing the current program +name, as retrieved from the argument vector. + +@cindex pzProgPath +@item pzProgPath +Points to a NUL-terminated string containing the full path of +the current program, as retrieved from the argument vector. +(If available on your system.) + +@end table + +Note@: these fields get filled in during the first call to +@code{optionProcess()}. All other fields are private, for the exclusive +use of AutoOpts code and are subject to change. + +@node CLEAR_OPT +@subsection CLEAR_OPT( <NAME> ) - Clear Option Markings +@findex CLEAR_OPT + +Make as if the option had never been specified. +@code{HAVE_OPT(<NAME>)} will yield @code{FALSE} +after invoking this macro. + +@node COUNT_OPT +@subsection COUNT_OPT( <NAME> ) - Definition Count +@findex COUNT_OPT + +This macro will tell you how many times the option was +specified on the command line. It does not include counts +of preset options. + +@example +if (COUNT_OPT( NAME ) != desired-count) @{ + make-an-undesirable-message. +@} +@end example + +@node DESC +@subsection DESC( <NAME> ) - Option Descriptor +@findex DESC + +This macro is used internally by other AutoOpt macros. +It is not for general use. It is used to obtain the option description +corresponding to its @strong{UPPER CASED} option name argument. +This is primarily used in other macro definitions. + +@node DISABLE_OPT_name +@subsection DISABLE_OPT_name - Disable an option +@findex DISABLE_OPT_name + +This macro is emitted if it is both settable +and it can be disabled. If it cannot be disabled, it may +always be CLEAR-ed (see above). + +The form of the macro will actually depend on whether the +option is equivalenced to another, and/or has an assigned +handler procedure. Unlike the @code{SET_OPT} macro, +this macro does not allow an option argument. + +@example +DISABLE_OPT_NAME; +@end example + +@node ENABLED_OPT +@subsection ENABLED_OPT( <NAME> ) - Is Option Enabled? +@findex ENABLED_OPT + +Yields true if the option defaults to disabled and +@code{ISUNUSED_OPT()} would yield true. It also yields true if +the option has been specified with a disablement prefix, +disablement value or the @code{DISABLE_OPT_NAME} macro was invoked. + +@node ERRSKIP_OPTERR +@subsection ERRSKIP_OPTERR - Ignore Option Errors +@findex ERRSKIP_OPTERR + +When it is necessary to continue (return to caller) +on option errors, invoke this option. It is reversible. +@xref{ERRSTOP_OPTERR}. + +@node ERRSTOP_OPTERR +@subsection ERRSTOP_OPTERR - Stop on Errors +@findex ERRSTOP_OPTERR + +After invoking this macro, if @code{optionProcess()} +encounters an error, it will call @code{exit(1)} rather than return. +This is the default processing mode. It can be overridden by +specifying @code{allow-errors} in the definitions file, +or invoking the macro @xref{ERRSKIP_OPTERR}. + +@node HAVE_OPT +@subsection HAVE_OPT( <NAME> ) - Have this option? +@findex HAVE_OPT + +This macro yields true if the option has been specified +in any fashion at all. It is used thus: + +@example +if (HAVE_OPT( NAME )) @{ + <do-things-associated-with-opt-name>; +@} +@end example + +@node ISSEL_OPT +@subsection ISSEL_OPT( <NAME> ) - Is Option Selected? +@findex ISSEL_OPT + +This macro yields true if the option has been +specified either on the command line or via a SET/DISABLE macro. + +@node ISUNUSED_OPT +@subsection ISUNUSED_OPT( <NAME> ) - Never Specified? +@findex ISUNUSED_OPT + +This macro yields true if the option has +never been specified, or has been cleared via the +@code{CLEAR_OPT()} macro. + +@node OPTION_CT +@subsection OPTION_CT - Full Count of Options +@findex OPTION_CT + +The full count of all options, both those defined +and those generated automatically by AutoOpts. This is primarily +used to initialize the program option descriptor structure. + +@node OPT_ARG +@subsection OPT_ARG( <NAME> ) - Option Argument String +@findex OPT_ARG + +The option argument value as a pointer to string. Note that argument +values that have been specified as numbers are stored as numbers or +keywords. For such options, use instead the @code{OPT_VALUE_name} +define. It is used thus: + +@example +if (HAVE_OPT( NAME )) @{ + char* p = OPT_ARG( NAME ); + <do-things-with-opt-name-argument-string>; +@} +@end example + +@node OPT_NO_XLAT_CFG_NAMES +@subsection OPT_NO_XLAT_CFG_NAMES - option name xlation +@findex OPT_NO_XLAT_CFG_NAMES + +Invoking this macro will disable the translation of option names only while +processing configuration files and environment variables. This must be +invoked before the first call to @code{optionProcess}.. You need not invoke +this if your option definition file contains the attribute assignment, +@code{no-xlate = opt-cfg;}. + +@node OPT_NO_XLAT_OPT_NAMES +@subsection OPT_NO_XLAT_OPT_NAMES - option name xlation +@findex OPT_NO_XLAT_OPT_NAMES + +Invoking this macro will completely disable the translation of option names. +This must be invoked before the first call to @code{optionProcess}. You need +not invoke this if your option definition file contains the attribute +assignment, @code{no-xlate = opt;}. + +@node OPT_VALUE_name +@subsection OPT_VALUE_name - Option Argument Value +@findex OPT_VALUE_name + +This macro gets emitted only for options that take numeric, keyword or set +membership arguments. The macro yields a word-sized integer containing the +enumeration, bit set or numeric value for the option argument. + +@example +int opt_val = OPT_VALUE_name; +@end example + +@node OPT_XLAT_CFG_NAMES +@subsection OPT_XLAT_CFG_NAMES - option name xlation +@findex OPT_XLAT_CFG_NAMES + +If @code{ENABLE_NLS} is defined and @code{no-xlate} has been not set to the +value @emph{anything}, this macro will cause the translation of option names +to happen before starting the processing of configuration files and +environment variables. This will change the recognition of options within the +@code{$PROGRAMNAME} environment variable, but will not alter the names used +for setting options via @code{$PROGRAMNAME_name} environment variables. + +This must be invoked before the first call to @code{optionProcess}. You might +need to use this macro if your option definition file contains the attribute +assignment, @code{no-xlate = opt;} or @code{no-xlate = opt-cfg;}, and +you have determined in some way that you wish to override that. + +@node OPT_XLAT_OPT_NAMES +@subsection OPT_XLAT_OPT_NAMES - option name xlation +@findex OPT_XLAT_OPT_NAMES + +If @code{ENABLE_NLS} is defined and @code{no-xlate} has been not set to the +value @emph{anything}, translate the option names before processing the +command line options. Long option names may thus be localized. (If the names +were translated before configuration processing, they will not be +re-translated.) + +This must be invoked before the first call to @code{optionProcess}. You might +need to use this macro if your option definition file contains the attribute +assignment, @code{no-xlate = opt;} and you have determined in some way that +you wish to override that. + +@node RESTART_OPT +@subsection RESTART_OPT( n ) - Resume Option Processing +@findex RESTART_OPT + +If option processing has stopped (either because of an error +or something was encountered that looked like a program argument), +it can be resumed by providing this macro with the index @code{n} +of the next option to process and calling @code{optionProcess()} again. + +@example +int main(int argc, char ** argv) @{ + for (int ai = 0; ai < argc ;) @{ + restart: + ai = optionProcess(&progOptions, argc, argv); + for (; ai < argc; ai++) @{ + char * arg = arg[ai]; + if (*arg == '-') @{ + RESTART_OPT(ai); + goto restart; + @} + process(arg); + @} + @} +@} +@end example + +If you want a program to operate this way, you might consider specifying a +@code{for-each} main function +(@pxref{main for-each, for-each main procedure}) with the @code{interleaved} +attribute. It will allow you to process interleaved operands and options from +either the command line or when reading them from standard input. + +@node SET_OPT_name +@subsection SET_OPT_name - Force an option to be set +@findex SET_OPT_name + +This macro gets emitted only when the given +option has the @code{settable} attribute specified. + +The form of the macro will actually depend on whether the option is +equivalenced to another, has an option argument and/or has an assigned +handler procedure. If the option has an argument, then this macro will +too. Beware that the argument is not reallocated, so the value must not +be on the stack or deallocated in any other way for as long as the value +might get referenced. + +If you have supplied at least one @file{homerc} file +(@pxref{program attributes}), this macro will be emitted for the +@option{--save-opts} option. + +@example +SET_OPT_SAVE_OPTS( "filename" ); +@end example + +@noindent +@xref{automatic options}, for a discussion of the implications of using +this particular example. + +@node STACKCT_OPT +@subsection STACKCT_OPT( <NAME> ) - Stacked Arg Count +@findex STACKCT_OPT + +When the option handling attribute is specified +as @code{stack_arg}, this macro may be used to determine how +many of them actually got stacked. + +Do not use this on options that have not been stacked or has not been +specified (the @code{stack_arg} attribute must have been specified, +and @code{HAVE_OPT(<NAME>)} must yield TRUE). +Otherwise, you will likely seg fault. + +@example +if (HAVE_OPT( NAME )) @{ + int ct = STACKCT_OPT( NAME ); + char** pp = STACKLST_OPT( NAME ); + + do @{ + char* p = *pp++; + do-things-with-p; + @} while (--ct > 0); +@} +@end example + +@node STACKLST_OPT +@subsection STACKLST_OPT( <NAME> ) - Argument Stack +@findex STACKLST_OPT + +The address of the list of pointers to the +option arguments. The pointers are ordered by the order in +which they were encountered in the option presets and +command line processing. + +Do not use this on options that have not been stacked or has not been +specified (the @code{stack_arg} attribute must have been specified, +and @code{HAVE_OPT(<OPTION>)} must yield TRUE). +Otherwise, you will likely seg fault. + +@example +if (HAVE_OPT( NAME )) @{ + int ct = STACKCT_OPT( NAME ); + char** pp = STACKLST_OPT( NAME ); + + do @{ + char* p = *pp++; + do-things-with-p; + @} while (--ct > 0); +@} +@end example + +@node START_OPT +@subsection START_OPT - Restart Option Processing +@findex START_OPT + +This is just a shortcut for RESTART_OPT(1) (@xref{RESTART_OPT}.) + +@node STATE_OPT +@subsection STATE_OPT( <NAME> ) - Option State +@findex STATE_OPT + +If you need to know if an option was set because of presetting actions +(configuration file processing or environment variables), versus a command +line entry versus one of the SET/DISABLE macros, then use this macro. It +will yield one of four values: @code{OPTST_INIT}, @code{OPTST_SET}, +@code{OPTST_PRESET} or @code{OPTST_DEFINED}. It is used thus: + +@example +switch (STATE_OPT( NAME )) @{ + case OPTST_INIT: + not-preset, set or on the command line. (unless CLEAR-ed) + + case OPTST_SET: + option set via the SET_OPT_NAME() macro. + + case OPTST_PRESET: + option set via an configuration file or environment variable + + case OPTST_DEFINED: + option set via a command line option. + + default: + cannot happen :) +@} +@end example + +@node USAGE +@subsection USAGE( exit-code ) - Usage invocation macro +@findex USAGE + +This macro invokes the procedure registered to display +the usage text. Normally, this will be @code{optionUsage} from the +AutoOpts library, but you may select another procedure by specifying +@code{usage = "proc_name"} program attribute. This procedure must +take two arguments@: first, a pointer to the option descriptor, and +second the exit code. The macro supplies the option descriptor +automatically. This routine is expected to call @code{exit(3)} with +the provided exit code. + +The @code{optionUsage} routine also behaves differently depending +on the exit code: + +@table @code +@item EXIT_SUCCESS (the value zero) +It is assumed that full usage help has been requested. Consequently, more +information is provided than when displaying usage and exiting with a +non-zero exit code. Output will be sent to @file{stdout} and the program will +exit with a zero status code. + +@item EX_USAGE (64) +The abbreviated usage will be printed to @file{stdout} and the program will +exit with a zero status code. @code{EX_USAGE} may or may not be 64. If your +system provides @file{/usr/include/sysexits.h} that has a different value, +then that value will be used. + +@item any other value +The abbreviated usage will be printed to stderr and the program will +exit with the provided status code. +@end table + +@node VALUE_OPT_name +@subsection VALUE_OPT_name - Option Flag Value +@findex VALUE_OPT_name + +This is a #define for the flag character used to +specify an option on the command line. If @code{value} was not +specified for the option, then it is a unique number associated +with the option. @code{option value} refers to this value, +@code{option argument} refers to the (optional) argument to the +option. + +@example +switch (WHICH_OPT_OTHER_OPT) @{ +case VALUE_OPT_NAME: + this-option-was-really-opt-name; +case VALUE_OPT_OTHER_OPT: + this-option-was-really-other-opt; +@} +@end example + +@node VERSION +@subsection VERSION - Version and Full Version +@findex VERSION + +If the @code{version} attribute is defined for the program, +then a stringified version will be #defined as PROGRAM_VERSION and +PROGRAM_FULL_VERSION. PROGRAM_FULL_VERSION is used for printing +the program version in response to the version option. The version +option is automatically supplied in response to this attribute, too. + +You may access PROGRAM_VERSION via @code{programOptions.pzFullVersion}. + +@node WHICH_IDX_name +@subsection WHICH_IDX_name - Which Equivalenced Index +@findex WHICH_IDX_name + +This macro gets emitted only for equivalenced-to options. It is used to +obtain the index for the one of the several equivalence class members +set the equivalenced-to option. + +@example +switch (WHICH_IDX_OTHER_OPT) @{ +case INDEX_OPT_NAME: + this-option-was-really-opt-name; +case INDEX_OPT_OTHER_OPT: + this-option-was-really-other-opt; +@} +@end example + +@node WHICH_OPT_name +@subsection WHICH_OPT_name - Which Equivalenced Option +@findex WHICH_OPT_name + +This macro gets emitted only for equivalenced-to options. It is used to +obtain the value code for the one of the several equivalence class members +set the equivalenced-to option. + +@example +switch (WHICH_OPT_OTHER_OPT) @{ +case VALUE_OPT_NAME: + this-option-was-really-opt-name; +case VALUE_OPT_OTHER_OPT: + this-option-was-really-other-opt; +@} +@end example + +@node teOptIndex +@subsection teOptIndex - Option Index and Enumeration +@findex teOptIndex + +This enum defines the complete set of options, both +user specified and automatically provided. This can be used, +for example, to distinguish which of the equivalenced options +was actually used. + +@example +switch (pOptDesc->optActualIndex) @{ +case INDEX_OPT_FIRST: + stuff; +case INDEX_OPT_DIFFERENT: + different-stuff; +default: + unknown-things; +@} +@end example + +@node OPTIONS_STRUCT_VERSION +@subsection OPTIONS_STRUCT_VERSION - active version + +You will not actually need to reference this value, but you need to be +aware that it is there. It is the first value in the option descriptor +that you pass to @code{optionProcess}. It contains a magic number and +version information. Normally, you should be able to work with a more +recent option library than the one you compiled with. However, if the +library is changed incompatibly, then the library will detect the out of +date magic marker, explain the difficulty and exit. You will then need +to rebuild and recompile your option definitions. This has rarely been +necessary. + +@ignore +END == AUTOOPTS-API == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore +@node libopts procedures +@subsection libopts External Procedures + +These are the routines that libopts users may call directly from their +code. There are several other routines that can be called by code +generated by the libopts option templates, but they are not to be +called from any other user code. The @file{options.h} header is +fairly clear about this, too. + +@menu +* libopts-ao_string_tokenize:: ao_string_tokenize +* libopts-configFileLoad:: configFileLoad +* libopts-optionFileLoad:: optionFileLoad +* libopts-optionFindNextValue:: optionFindNextValue +* libopts-optionFindValue:: optionFindValue +* libopts-optionFree:: optionFree +* libopts-optionGetValue:: optionGetValue +* libopts-optionLoadLine:: optionLoadLine +* libopts-optionMemberList:: optionMemberList +* libopts-optionNextValue:: optionNextValue +* libopts-optionOnlyUsage:: optionOnlyUsage +* libopts-optionPrintVersion:: optionPrintVersion +* libopts-optionPrintVersionAndReturn:: optionPrintVersionAndReturn +* libopts-optionProcess:: optionProcess +* libopts-optionRestore:: optionRestore +* libopts-optionSaveFile:: optionSaveFile +* libopts-optionSaveState:: optionSaveState +* libopts-optionUnloadNested:: optionUnloadNested +* libopts-optionVersion:: optionVersion +* libopts-strequate:: strequate +* libopts-streqvcmp:: streqvcmp +* libopts-streqvmap:: streqvmap +* libopts-strneqvcmp:: strneqvcmp +* libopts-strtransform:: strtransform +@end menu + +This subsection was automatically generated by AutoGen +using extracted information and the aginfo3.tpl template. + +@node libopts-ao_string_tokenize +@subsubsection ao_string_tokenize +@findex ao_string_tokenize + +tokenize an input string + +@noindent +Usage: +@example +token_list_t * res = ao_string_tokenize( string ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab string @tab @code{char const *} +@tab string to be tokenized +@item @tab returns @tab token_list_t * +@tab pointer to a structure that lists each token +@end multitable + +This function will convert one input string into a list of strings. +The list of strings is derived by separating the input based on +white space separation. However, if the input contains either single +or double quote characters, then the text after that character up to +a matching quote will become the string in the list. + +The returned pointer should be deallocated with @code{free(3C)} when +are done using the data. The data are placed in a single block of +allocated memory. Do not deallocate individual token/strings. + +The structure pointed to will contain at least these two fields: +@table @samp +@item tkn_ct +The number of tokens found in the input string. +@item tok_list +An array of @code{tkn_ct + 1} pointers to substring tokens, with +the last pointer set to NULL. +@end table + +There are two types of quoted strings: single quoted (@code{'}) and +double quoted (@code{"}). Singly quoted strings are fairly raw in that +escape characters (@code{\\}) are simply another character, except when +preceding the following characters: +@example +@code{\\} double backslashes reduce to one +@code{'} incorporates the single quote into the string +@code{\n} suppresses both the backslash and newline character +@end example + +Double quote strings are formed according to the rules of string +constants in ANSI-C programs. + +NULL is returned and @code{errno} will be set to indicate the problem: +@itemize @bullet +@item +@code{EINVAL} - There was an unterminated quoted string. +@item +@code{ENOENT} - The input string was empty. +@item +@code{ENOMEM} - There is not enough memory. +@end itemize + + +@node libopts-configFileLoad +@subsubsection configFileLoad +@findex configFileLoad + +parse a configuration file + +@noindent +Usage: +@example +const tOptionValue * res = configFileLoad( fname ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab fname @tab @code{char const *} +@tab the file to load +@item @tab returns @tab const tOptionValue * +@tab An allocated, compound value structure +@end multitable + +This routine will load a named configuration file and parse the +text as a hierarchically valued option. The option descriptor +created from an option definition file is not used via this interface. +The returned value is "named" with the input file name and is of +type "@code{OPARG_TYPE_HIERARCHY}". It may be used in calls to +@code{optionGetValue()}, @code{optionNextValue()} and +@code{optionUnloadNested()}. + +If the file cannot be loaded or processed, @code{NULL} is returned and +@var{errno} is set. It may be set by a call to either @code{open(2)} +@code{mmap(2)} or other file system calls, or it may be: +@itemize @bullet +@item +@code{ENOENT} - the file was not found. +@item +@code{ENOMSG} - the file was empty. +@item +@code{EINVAL} - the file contents are invalid -- not properly formed. +@item +@code{ENOMEM} - not enough memory to allocate the needed structures. +@end itemize + + +@node libopts-optionFileLoad +@subsubsection optionFileLoad +@findex optionFileLoad + +Load the locatable config files, in order + +@noindent +Usage: +@example +int res = optionFileLoad( opts, prog ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab opts @tab @code{tOptions *} +@tab program options descriptor + +@item @tab prog @tab @code{char const *} +@tab program name +@item @tab returns @tab int +@tab 0 -> SUCCESS, -1 -> FAILURE +@end multitable + +This function looks in all the specified directories for a configuration +file ("rc" file or "ini" file) and processes any found twice. The first +time through, they are processed in reverse order (last file first). At +that time, only "immediate action" configurables are processed. For +example, if the last named file specifies not processing any more +configuration files, then no more configuration files will be processed. +Such an option in the @strong{first} named directory will have no effect. + +Once the immediate action configurables have been handled, then the +directories are handled in normal, forward order. In that way, later +config files can override the settings of earlier config files. + +See the AutoOpts documentation for a thorough discussion of the +config file format. + +Configuration files not found or not decipherable are simply ignored. + +Returns the value, "-1" if the program options descriptor +is out of date or indecipherable. Otherwise, the value "0" will +always be returned. + + +@node libopts-optionFindNextValue +@subsubsection optionFindNextValue +@findex optionFindNextValue + +find a hierarcicaly valued option instance + +@noindent +Usage: +@example +const tOptionValue * res = optionFindNextValue( odesc, pPrevVal, name, value ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab odesc @tab @code{const tOptDesc *} +@tab an option with a nested arg type + +@item @tab pPrevVal @tab @code{const tOptionValue *} +@tab the last entry + +@item @tab name @tab @code{char const *} +@tab name of value to find + +@item @tab value @tab @code{char const *} +@tab the matching value +@item @tab returns @tab const tOptionValue * +@tab a compound value structure +@end multitable + +This routine will find the next entry in a nested value option or +configurable. It will search through the list and return the next entry +that matches the criteria. + +The returned result is NULL and errno is set: +@itemize @bullet +@item +@code{EINVAL} - the @code{pOptValue} does not point to a valid +hierarchical option value. +@item +@code{ENOENT} - no entry matched the given name. +@end itemize + + +@node libopts-optionFindValue +@subsubsection optionFindValue +@findex optionFindValue + +find a hierarcicaly valued option instance + +@noindent +Usage: +@example +const tOptionValue * res = optionFindValue( odesc, name, val ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab odesc @tab @code{const tOptDesc *} +@tab an option with a nested arg type + +@item @tab name @tab @code{char const *} +@tab name of value to find + +@item @tab val @tab @code{char const *} +@tab the matching value +@item @tab returns @tab const tOptionValue * +@tab a compound value structure +@end multitable + +This routine will find an entry in a nested value option or configurable. +It will search through the list and return a matching entry. + +The returned result is NULL and errno is set: +@itemize @bullet +@item +@code{EINVAL} - the @code{pOptValue} does not point to a valid +hierarchical option value. +@item +@code{ENOENT} - no entry matched the given name. +@end itemize + + +@node libopts-optionFree +@subsubsection optionFree +@findex optionFree + +free allocated option processing memory + +@noindent +Usage: +@example +optionFree( pOpts ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab pOpts @tab @code{tOptions *} +@tab program options descriptor +@end multitable + +AutoOpts sometimes allocates memory and puts pointers to it in the +option state structures. This routine deallocates all such memory. + +As long as memory has not been corrupted, +this routine is always successful. + + +@node libopts-optionGetValue +@subsubsection optionGetValue +@findex optionGetValue + +get a specific value from a hierarcical list + +@noindent +Usage: +@example +const tOptionValue * res = optionGetValue( pOptValue, valueName ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab pOptValue @tab @code{const tOptionValue *} +@tab a hierarchcal value + +@item @tab valueName @tab @code{char const *} +@tab name of value to get +@item @tab returns @tab const tOptionValue * +@tab a compound value structure +@end multitable + +This routine will find an entry in a nested value option or configurable. +If "valueName" is NULL, then the first entry is returned. Otherwise, +the first entry with a name that exactly matches the argument will be +returned. If there is no matching value, NULL is returned and errno is +set to ENOENT. If the provided option value is not a hierarchical value, +NULL is also returned and errno is set to EINVAL. + +The returned result is NULL and errno is set: +@itemize @bullet +@item +@code{EINVAL} - the @code{pOptValue} does not point to a valid +hierarchical option value. +@item +@code{ENOENT} - no entry matched the given name. +@end itemize + + +@node libopts-optionLoadLine +@subsubsection optionLoadLine +@findex optionLoadLine + +process a string for an option name and value + +@noindent +Usage: +@example +optionLoadLine( opts, line ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab opts @tab @code{tOptions *} +@tab program options descriptor + +@item @tab line @tab @code{char const *} +@tab NUL-terminated text +@end multitable + +This is a client program callable routine for setting options from, for +example, the contents of a file that they read in. Only one option may +appear in the text. It will be treated as a normal (non-preset) option. + +When passed a pointer to the option struct and a string, it will find +the option named by the first token on the string and set the option +argument to the remainder of the string. The caller must NUL terminate +the string. The caller need not skip over any introductory hyphens. +Any embedded new lines will be included in the option +argument. If the input looks like one or more quoted strings, then the +input will be "cooked". The "cooking" is identical to the string +formation used in AutoGen definition files (@pxref{basic expression}), +except that you may not use backquotes. + +Invalid options are silently ignored. Invalid option arguments +will cause a warning to print, but the function should return. + + +@node libopts-optionMemberList +@subsubsection optionMemberList +@findex optionMemberList + +Get the list of members of a bit mask set + +@noindent +Usage: +@example +char * res = optionMemberList( od ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab od @tab @code{tOptDesc *} +@tab the set membership option description +@item @tab returns @tab char * +@tab the names of the set bits +@end multitable + +This converts the OPT_VALUE_name mask value to a allocated string. +It is the caller's responsibility to free the string. + + +@node libopts-optionNextValue +@subsubsection optionNextValue +@findex optionNextValue + +get the next value from a hierarchical list + +@noindent +Usage: +@example +const tOptionValue * res = optionNextValue( pOptValue, pOldValue ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab pOptValue @tab @code{const tOptionValue *} +@tab a hierarchcal list value + +@item @tab pOldValue @tab @code{const tOptionValue *} +@tab a value from this list +@item @tab returns @tab const tOptionValue * +@tab a compound value structure +@end multitable + +This routine will return the next entry after the entry passed in. At the +end of the list, NULL will be returned. If the entry is not found on the +list, NULL will be returned and "@var{errno}" will be set to EINVAL. +The "@var{pOldValue}" must have been gotten from a prior call to this +routine or to "@code{opitonGetValue()}". + +The returned result is NULL and errno is set: +@itemize @bullet +@item +@code{EINVAL} - the @code{pOptValue} does not point to a valid +hierarchical option value or @code{pOldValue} does not point to a +member of that option value. +@item +@code{ENOENT} - the supplied @code{pOldValue} pointed to the last entry. +@end itemize + + +@node libopts-optionOnlyUsage +@subsubsection optionOnlyUsage +@findex optionOnlyUsage + +Print usage text for just the options + +@noindent +Usage: +@example +optionOnlyUsage( pOpts, ex_code ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab pOpts @tab @code{tOptions *} +@tab program options descriptor + +@item @tab ex_code @tab @code{int} +@tab exit code for calling exit(3) +@end multitable + +This routine will print only the usage for each option. +This function may be used when the emitted usage must incorporate +information not available to AutoOpts. + + +@node libopts-optionPrintVersion +@subsubsection optionPrintVersion +@findex optionPrintVersion + +Print the program version + +@noindent +Usage: +@example +optionPrintVersion( opts, od ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab opts @tab @code{tOptions *} +@tab program options descriptor + +@item @tab od @tab @code{tOptDesc *} +@tab the descriptor for this arg +@end multitable + +This routine will print the version to stdout. + + +@node libopts-optionPrintVersionAndReturn +@subsubsection optionPrintVersionAndReturn +@findex optionPrintVersionAndReturn + +Print the program version + +@noindent +Usage: +@example +optionPrintVersionAndReturn( opts, od ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab opts @tab @code{tOptions *} +@tab program options descriptor + +@item @tab od @tab @code{tOptDesc *} +@tab the descriptor for this arg +@end multitable + +This routine will print the version to stdout and return +instead of exiting. Please see the source for the +@code{print_ver} funtion for details on selecting how +verbose to be after this function returns. + + +@node libopts-optionProcess +@subsubsection optionProcess +@findex optionProcess + +this is the main option processing routine + +@noindent +Usage: +@example +int res = optionProcess( opts, a_ct, a_v ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab opts @tab @code{tOptions *} +@tab program options descriptor + +@item @tab a_ct @tab @code{int} +@tab program arg count + +@item @tab a_v @tab @code{char **} +@tab program arg vector +@item @tab returns @tab int +@tab the count of the arguments processed +@end multitable + +This is the main entry point for processing options. It is intended +that this procedure be called once at the beginning of the execution of +a program. Depending on options selected earlier, it is sometimes +necessary to stop and restart option processing, or to select completely +different sets of options. This can be done easily, but you generally +do not want to do this. + +The number of arguments processed always includes the program name. +If one of the arguments is "--", then it is counted and the processing +stops. If an error was encountered and errors are to be tolerated, then +the returned value is the index of the argument causing the error. +A hyphen by itself ("-") will also cause processing to stop and will +@emph{not} be counted among the processed arguments. A hyphen by itself +is treated as an operand. Encountering an operand stops option +processing. + +Errors will cause diagnostics to be printed. @code{exit(3)} may +or may not be called. It depends upon whether or not the options +were generated with the "allow-errors" attribute, or if the +ERRSKIP_OPTERR or ERRSTOP_OPTERR macros were invoked. + + +@node libopts-optionRestore +@subsubsection optionRestore +@findex optionRestore + +restore option state from memory copy + +@noindent +Usage: +@example +optionRestore( pOpts ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab pOpts @tab @code{tOptions *} +@tab program options descriptor +@end multitable + +Copy back the option state from saved memory. +The allocated memory is left intact, so this routine can be +called repeatedly without having to call optionSaveState again. +If you are restoring a state that was saved before the first call +to optionProcess(3AO), then you may change the contents of the +argc/argv parameters to optionProcess. + +If you have not called @code{optionSaveState} before, a diagnostic is +printed to @code{stderr} and exit is called. + + +@node libopts-optionSaveFile +@subsubsection optionSaveFile +@findex optionSaveFile + +saves the option state to a file + +@noindent +Usage: +@example +optionSaveFile( opts ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab opts @tab @code{tOptions *} +@tab program options descriptor +@end multitable + +This routine will save the state of option processing to a file. The name +of that file can be specified with the argument to the @code{--save-opts} +option, or by appending the @code{rcfile} attribute to the last +@code{homerc} attribute. If no @code{rcfile} attribute was specified, it +will default to @code{.@i{programname}rc}. If you wish to specify another +file, you should invoke the @code{SET_OPT_SAVE_OPTS(@i{filename})} macro. + +The recommend usage is as follows: +@example +optionProcess(&progOptions, argc, argv); +if (i_want_a_non_standard_place_for_this) +SET_OPT_SAVE_OPTS("myfilename"); +optionSaveFile(&progOptions); +@end example + +If no @code{homerc} file was specified, this routine will silently return +and do nothing. If the output file cannot be created or updated, a message +will be printed to @code{stderr} and the routine will return. + + +@node libopts-optionSaveState +@subsubsection optionSaveState +@findex optionSaveState + +saves the option state to memory + +@noindent +Usage: +@example +optionSaveState( pOpts ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab pOpts @tab @code{tOptions *} +@tab program options descriptor +@end multitable + +This routine will allocate enough memory to save the current option +processing state. If this routine has been called before, that memory +will be reused. You may only save one copy of the option state. This +routine may be called before optionProcess(3AO). If you do call it +before the first call to optionProcess, then you may also change the +contents of argc/argv after you call optionRestore(3AO) + +In fact, more strongly put: it is safest to only use this function +before having processed any options. In particular, the saving and +restoring of stacked string arguments and hierarchical values is +disabled. The values are not saved. + +If it fails to allocate the memory, +it will print a message to stderr and exit. +Otherwise, it will always succeed. + + +@node libopts-optionUnloadNested +@subsubsection optionUnloadNested +@findex optionUnloadNested + +Deallocate the memory for a nested value + +@noindent +Usage: +@example +optionUnloadNested( pOptVal ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab pOptVal @tab @code{tOptionValue const *} +@tab the hierarchical value +@end multitable + +A nested value needs to be deallocated. The pointer passed in should +have been gotten from a call to @code{configFileLoad()} (See +@pxref{libopts-configFileLoad}). + + +@node libopts-optionVersion +@subsubsection optionVersion +@findex optionVersion + +return the compiled AutoOpts version number + +@noindent +Usage: +@example +char const * res = optionVersion(); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab returns @tab char const * +@tab the version string in constant memory +@end multitable + +Returns the full version string compiled into the library. +The returned string cannot be modified. + + +@node libopts-strequate +@subsubsection strequate +@findex strequate + +map a list of characters to the same value + +@noindent +Usage: +@example +strequate( ch_list ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab ch_list @tab @code{char const *} +@tab characters to equivalence +@end multitable + +Each character in the input string get mapped to the first character +in the string. +This function name is mapped to option_strequate so as to not conflict +with the POSIX name space. + +none. + + +@node libopts-streqvcmp +@subsubsection streqvcmp +@findex streqvcmp + +compare two strings with an equivalence mapping + +@noindent +Usage: +@example +int res = streqvcmp( str1, str2 ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab str1 @tab @code{char const *} +@tab first string + +@item @tab str2 @tab @code{char const *} +@tab second string +@item @tab returns @tab int +@tab the difference between two differing characters +@end multitable + +Using a character mapping, two strings are compared for "equivalence". +Each input character is mapped to a comparison character and the +mapped-to characters are compared for the two NUL terminated input strings. +This function name is mapped to option_streqvcmp so as to not conflict +with the POSIX name space. + +none checked. Caller responsible for seg faults. + + +@node libopts-streqvmap +@subsubsection streqvmap +@findex streqvmap + +Set the character mappings for the streqv functions + +@noindent +Usage: +@example +streqvmap( from, to, ct ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab from @tab @code{char} +@tab Input character + +@item @tab to @tab @code{char} +@tab Mapped-to character + +@item @tab ct @tab @code{int} +@tab compare length +@end multitable + +Set the character mapping. If the count (@code{ct}) is set to zero, then +the map is cleared by setting all entries in the map to their index +value. Otherwise, the "@code{From}" character is mapped to the "@code{To}" +character. If @code{ct} is greater than 1, then @code{From} and @code{To} +are incremented and the process repeated until @code{ct} entries have been +set. For example, +@example +streqvmap('a', 'A', 26); +@end example +@noindent +will alter the mapping so that all English lower case letters +will map to upper case. + +This function name is mapped to option_streqvmap so as to not conflict +with the POSIX name space. + +none. + + +@node libopts-strneqvcmp +@subsubsection strneqvcmp +@findex strneqvcmp + +compare two strings with an equivalence mapping + +@noindent +Usage: +@example +int res = strneqvcmp( str1, str2, ct ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab str1 @tab @code{char const *} +@tab first string + +@item @tab str2 @tab @code{char const *} +@tab second string + +@item @tab ct @tab @code{int} +@tab compare length +@item @tab returns @tab int +@tab the difference between two differing characters +@end multitable + +Using a character mapping, two strings are compared for "equivalence". +Each input character is mapped to a comparison character and the +mapped-to characters are compared for the two NUL terminated input strings. +The comparison is limited to @code{ct} bytes. +This function name is mapped to option_strneqvcmp so as to not conflict +with the POSIX name space. + +none checked. Caller responsible for seg faults. + + +@node libopts-strtransform +@subsubsection strtransform +@findex strtransform + +convert a string into its mapped-to value + +@noindent +Usage: +@example +strtransform( dest, src ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab dest @tab @code{char *} +@tab output string + +@item @tab src @tab @code{char const *} +@tab input string +@end multitable + +Each character in the input string is mapped and the mapped-to +character is put into the output. +This function name is mapped to option_strtransform so as to not conflict +with the POSIX name space. + +The source and destination may be the same. + +none. +@ignore +START == AUTOOPTS-DATA == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore + +@c === SECTION MARKER + +@node Multi-Threading +@section Multi-Threading + +AutoOpts was designed to configure a program for running. This generally +happens before much real work has been started. Consequently, it is +expected to be run before multi-threaded applications have started multiple +threads. However, this is not always the case. Some applications may +need to reset and reload their running configuration, and some may use +@code{SET_OPT_xxx()} macros during processing. If you need to dynamically +change your option configuration in your multi-threaded application, it is +your responsibility to prevent all threads from accessing the option +configuration state, except the one altering the configuration. + +The various accessor macros (@code{HAVE_OPT()}, etc.) do not modify state +and are safe to use in a multi-threaded application. It is safe as long +as no other thread is concurrently modifying state, of course. + +@c === SECTION MARKER + +@node option descriptor +@section Option Descriptor File +@cindex option descriptor + +This is the module that is to be compiled and linked with your program. +It contains internal data and procedures subject to change. Basically, +it contains a single global data structure containing all the +information provided in the option definitions, plus a number of static +strings and any callout procedures that are specified or required. You +should never have need for looking at this, except, perhaps, to examine +the code generated for implementing the @code{flag-code} construct. + +@c === SECTION MARKER + +@node Using AutoOpts +@section Using AutoOpts +@cindex using AutoOpts + +There are actually several levels of @code{using} autoopts. +Which you choose depends upon how you plan to distribute +(or not) your application. + +@menu +* local use:: local-only use +* binary not installed:: binary distro, AutoOpts not installed +* binary pre-installed:: binary distro, AutoOpts pre-installed +* source pre-installed:: source distro, AutoOpts pre-installed +* source not installed:: source distro, AutoOpts not installed +@end menu + +@node local use +@subsection local-only use + +To use AutoOpts in your application where you do not have to +worry about distribution issues, your issues are simple and few. + +@itemize @bullet +@item +Create a file @samp{myopts.def}, according to the documentation above. +It is probably easiest to start with the example in @ref{Quick Start} +and edit it into the form you need. + +@item +Run AutoGen to create the option interface file (@code{myopts.h}) +and the option descriptor code (@code{myopts.c}): + +@example +autogen myopts.def +@end example + +@item +In all your source files where you need to refer to option state, +@code{#include "myopts.h"}. +@item +In your main routine, code something along the lines of: + +@example +#define ARGC_MIN some-lower-limit +#define ARGC_MAX some-upper-limit +main( int argc, char** argv ) +@{ + @{ + int arg_ct = optionProcess( &myprogOptions, argc, argv ); + argc -= arg_ct; + if ((argc < ARGC_MIN) || (argc > ARGC_MAX)) @{ + fprintf( stderr, "%s ERROR: remaining args (%d) " + "out of range\n", myprogOptions.pzProgName, + argc ); + + USAGE( EXIT_FAILURE ); + @} + argv += arg_ct; + @} + if (HAVE_OPT(OPTN_NAME)) + respond_to_optn_name(); + ... +@} +@end example + +@item +Compile @samp{myopts.c} and link your program +with the following additional arguments: + +@example +`autoopts-config cflags ldflags` myopts.c +@end example +@end itemize + +@node binary not installed +@subsection binary distro, AutoOpts not installed + +If you will be distributing (or copying) your project to a system that +does not have AutoOpts installed, you will need to statically link the +AutoOpts library, @code{libopts} into your program. Get the link information +with @code{static-libs} instead of @code{ldflags}: + +@example +`autoopts-config static-libs` +@end example + +@node binary pre-installed +@subsection binary distro, AutoOpts pre-installed + +If you will be distributing (or copying) your project to a system that does +have AutoOpts (or only @code{libopts}) installed, you will still need to +ensure that the library is findable at program load time, or you will still +have to statically link. The former can be accomplished by linking your +project with @option{--rpath} or by setting the @env{LD_LIBRARY_PATH} +appropriately. Otherwise, @xref{binary not installed}. + +@node source pre-installed +@subsection source distro, AutoOpts pre-installed + +If you will be distributing your project to a system that will build +your product but it may not be pre-installed with AutoOpts, you will +need to do some configuration checking before you start the build. +Assuming you are willing to fail the build if AutoOpts has not been +installed, you will still need to do a little work. + +AutoOpts is distributed with a configuration check M4 script, +@file{autoopts.m4}. It will add an @code{autoconf} macro named, +@code{AG_PATH_AUTOOPTS}. Add this to your @file{configure.ac} script +and use the following substitution values: + +@table @code +@item AUTOGEN +the name of the autogen executable +@item AUTOGEN_TPLIB +the directory where AutoGen template library is stored +@item AUTOOPTS_CFLAGS +the compile time options needed to find the AutoOpts headers +@item AUTOOPTS_LIBS +the link options required to access the @code{libopts} library +@end table + +@node source not installed +@subsection source distro, AutoOpts not installed + +If you will be distributing your project to a system that will build +your product but it may not be pre-installed with AutoOpts, you may +wish to incorporate the sources for @code{libopts} in your project. +To do this, I recommend reading the tear-off libopts library +@file{README} that you can find in the @file{pkg/libopts} directory. +You can also examine an example package (blocksort) that incorporates +this tear off library in the autogen distribution directory. There is +also a web page that describes what you need to do: +@example +@url{http://autogen.sourceforge.net/blocksort.html} +@end example + +Alternatively, you can pull the @code{libopts} library sources into +a build directory and build it for installation along with your package. +This can be done approximately as follows: +@example +tar -xzvf `autoopts-config libsrc` +cd libopts-* +./bootstrap +configure +make +make install +@end example +That will install the library, but not the headers or anything else. + +@c === SECTION MARKER + +@node Presetting Options +@section Configuring your program +@cindex shell options + +AutoOpts supports the notion of @code{presetting} the value or state of an +option. The values may be obtained either from environment variables or from +configuration files (@file{rc} or @file{ini} files). In order to take +advantage of this, the AutoOpts client program must specify these features in +the option descriptor file (@pxref{program attributes}) with the @code{rcfile} +or @code{environrc} attributes. + +@menu +* loading rcfile:: configuration file presets +* saving rcfile:: Saving the presets into a configuration file +* sample rcfile:: Creating a sample configuration file +* environrc:: environment variable presets +* config example:: Config file only example +@end menu + +It is also possible to configure your program @i{without} using +the command line option parsing code. This is done by using +only the following four functions from the @file{libopts} library: + +@table @samp +@item configFileLoad +(@pxref{libopts-configFileLoad}) will parse the contents of a config +file and return a pointer to a structure representing the hierarchical +value. The values are sorted alphabetically by the value name and all +entries with the same name will retain their original order. +Insertion sort is used. + +@item optionGetValue +(@pxref{libopts-optionGetValue}) will find the first value within the +hierarchy with a name that matches the name passed in. + +@item optionNextValue +(@pxref{libopts-optionNextValue}) will return the next value that +follows the value passed in as an argument. If you wish to get all +the values for a particular name, you must take note when the name +changes. + +@item optionUnloadNested +(@pxref{libopts-optionUnloadNested}). The pointer passed in must be +of type, @code{OPARG_TYPE_HIERARCHY} (see the autoopts/options.h +header file). @code{configFileLoad} will return a @code{tOptionValue} +pointer of that type. This function will release all the associated +memory. @code{AutoOpts} generated code uses this function for its own +needs. Client code should only call this function with pointers +gotten from @code{configFileLoad}. +@end table + +@node loading rcfile +@subsection configuration file presets +@cindex rcfile + +Configuration files are enabled by specifying the program attribute +@code{homerc} (@pxref{program attributes}). Any option not marked +with the @code{no-preset} attribute may appear in a configuration file. +The files loaded are selected both by the @code{homerc} entries and, +optionally, via a command line option. The first component of the +@code{homerc} entry may be an environment variable such as @env{$HOME}, or +it may also be @samp{$$} (@strong{two} dollar sign characters) to specify +the directory of the executable. For example: + +@example +homerc = "$$/../share/autogen"; +@end example + +@noindent +will cause the AutoOpts library to look in the normal autogen datadir +relative to the current installation directory for autogen. + +The configuration files are processed in the order they are specified by +the @code{homerc} attribute, so that each new file will normally override +the settings of the previous files. This may be overridden by marking some +options for @code{immediate action} (@pxref{Immediate Action}). Any such +options are acted upon in @strong{reverse} order. The disabled +@code{load-opts} (@option{--no-load-opts}) option, for example, is an +immediate action option. Its presence in the last @code{homerc} file will +prevent the processing of any prior @code{homerc} files because its effect +is immediate. + +Configuration file processing can be completely suppressed by specifying +@option{--no-load-opts} on the command line, or @code{PROGRAM_LOAD_OPTS=no} in +the environment (if @code{environrc} has been specified). + +See the @code{Configuration File Format} section (@pxref{Config File Format}) +for details on the format of the file. + +@node saving rcfile +@subsection Saving the presets into a configuration file + +When configuration files are enabled for an application, the user is +also provided with an automatically supplied @option{--save-opts} option. +All of the known option state will be written to either the specified +output file or, if it is not specified, then to the last specified +@code{homerc} file. + +@node sample rcfile +@subsection Creating a sample configuration file +@cindex sample rcfile + +AutoOpts is shipped with a template named, @file{rc-sample.tpl}. +If your option definition file specifies the @code{homerc} attribute, +then you may invoke @file{autogen} thus: + +@example +autogen -Trc-sample <your-option-def-file> +@end example + +This will, by default, produce a sample file named, +@file{sample-<prog-name>rc}. It will be named differently if you specify your +configuration (rc) file name with the @code{rcfile} attribute. In that case, +the output file will be named, @file{sample-<rcfile-name>}. It will contain +all of the program options not marked as @code{no-preset}. It will also +include the text from the @code{doc} attribute. + +@ignore +END == AUTOOPTS-DATA == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore +@noindent +Doing so with getdefs' option definitions yields this sample-getdefsrc file. +I tend to be wordy in my @code{doc} attributes: + +@example +# getdefs sample configuration file +## This source file is copyrighted and licensed under the following terms: +# +# Copyright (C) 1999-2018 Bruce Korb, all rights reserved. +# This is free software. It is licensed for use, modification and +# redistribution under the terms of the GNU General Public License, +# version 3 or later <http://gnu.org/licenses/gpl.html> +# +# getdefs 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. +# +# getdefs is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see <http://www.gnu.org/licenses/>. + +# defs_to_get -- Regexp to look for after the "/*=" +# +# +# +# +# If you want definitions only from a particular category, or even +# with names matching particular patterns, then specify this regular +# expression for the text that must follow the @@code@{/*=@}. +# Example: +# +#defs_to_get reg-ex + +# subblock -- subblock definition names +# +# +# +# +# This option is used to create shorthand entries for nested definitions. +# For example, with: +# @@table @@r +# @@item using subblock thus +# @@code@{--subblock=arg=argname,type,null@} +# @@item and defining an @@code@{arg@} thus +# @@code@{arg: this, char *@} +# @@item will then expand to: +# @@code@{arg = @@@{ argname = this; type = "char *"; @@@};@} +# @@end table +# The "this, char *" string is separated at the commas, with the +# white space removed. You may use characters other than commas by +# starting the value string with a punctuation character other than +# a single or double quote character. You may also omit intermediate +# values by placing the commas next to each other with no intervening +# white space. For example, "+mumble++yes+" will expand to: +# @@* +# @@code@{arg = @@@{ argname = mumble; null = "yes"; @@@};@}. +# Example: +# +#subblock sub-def + +# listattr -- attribute with list of values +# +# +# +# +# This option is used to create shorthand entries for definitions +# that generally appear several times. That is, they tend to be +# a list of values. For example, with: +# @@* +# @@code@{listattr=foo@} defined, the text: +# @@* +# @@code@{foo: this, is, a, multi-list@} will then expand to: +# @@* +# @@code@{foo = 'this', 'is', 'a', 'multi-list';@} +# @@* +# The texts are separated by the commas, with the +# white space removed. You may use characters other than commas by +# starting the value string with a punctuation character other than +# a single or double quote character. +# Example: +# +#listattr def + +# ordering -- Alphabetize or use named file +# +# +# +# +# By default, ordering is alphabetical by the entry name. Use, +# @@code@{no-ordering@} if order is unimportant. Use @@code@{ordering@} +# with no argument to order without case sensitivity. Use +# @@code@{ordering=<file-name>@} if chronological order is important. +# getdefs will maintain the text content of @@code@{file-name@}. +# @@code@{file-name@} need not exist. +# Example: +# +#ordering file-name + +# first_index -- The first index to apply to groups +# +# This configuration value takes an integer number as its argument. +# +# +# By default, the first occurrence of a named definition will have an +# index of zero. Sometimes, that needs to be a reserved value. Provide +# this option to specify a different starting point. +# Example: +# +#first_index 0 + +# filelist -- Insert source file names into defs +# +# +# +# +# Inserts the name of each input file into the output definitions. +# If no argument is supplied, the format will be: +# @@example +# infile = '%s'; +# @@end example +# If an argument is supplied, that string will be used for the entry +# name instead of @@var@{infile@}. +# Example: +# +#filelist file + +# assign -- Global assignments +# +# +# +# +# The argument to each copy of this option will be inserted into +# the output definitions, with only a semicolon attached. +# Example: +# +#assign ag-def + +# common_assign -- Assignments common to all blocks +# +# +# +# +# The argument to each copy of this option will be inserted into +# each output definition, with only a semicolon attached. +# Example: +# +#common_assign ag-def + +# copy -- File(s) to copy into definitions +# +# +# +# +# The content of each file named by these options will be inserted into +# the output definitions. +# Example: +# +#copy file + +# srcfile -- Insert source file name into each def +# +# +# +# +# Inserts the name of the input file where a definition was found +# into the output definition. +# If no argument is supplied, the format will be: +# @@example +# srcfile = '%s'; +# @@end example +# If an argument is supplied, that string will be used for the entry +# name instead of @@var@{srcfile@}. +# Example: +# +#srcfile file + +# linenum -- Insert source line number into each def +# +# +# +# +# Inserts the line number in the input file where a definition +# was found into the output definition. +# If no argument is supplied, the format will be: +# @@example +# linenum = '%s'; +# @@end example +# If an argument is supplied, that string will be used for the entry +# name instead of @@var@{linenum@}. +# Example: +# +#linenum def-name + +# input -- Input file to search for defs +# +# +# +# +# All files that are to be searched for definitions must be named on +# the command line or read from @@code@{stdin@}. If there is only one +# @@code@{input@} option and it is the string, "-", then the input file +# list is read from @@code@{stdin@}. If a command line argument is not +# an option name and does not contain an assignment operator +# (@@code@{=@}), then it defaults to being an input file name. +# At least one input file must be specified. +# Example: +# +#input src-file + +# output -- Output file to open +# +# +# +# +# If you are not sending the output to an AutoGen process, +# you may name an output file instead. +# Example: +# +#output file + +# autogen -- Invoke AutoGen with defs +# +# +# +# +# This is the default output mode. Specifying @@code@{no-autogen@} is +# equivalent to @@code@{output=-@}. If you supply an argument to this +# option, that program will be started as if it were AutoGen and +# its standard in will be set to the output definitions of this program. +# Example: +# +#autogen ag-cmd + +# template -- Template Name +# +# +# +# +# Specifies the template name to be used for generating the final output. +# Example: +# +#template file + +# agarg -- AutoGen Argument +# +# +# +# +# This is a pass-through argument. It allows you to specify any +# arbitrary argument to be passed to AutoGen. +# Example: +# +#agarg ag-opt + +# base_name -- Base name for output file(s) +# +# +# +# +# When output is going to AutoGen, a base name must either be supplied +# or derived. If this option is not supplied, then it is taken from +# the @@code@{template@} option. If that is not provided either, then +# it is set to the base name of the current directory. +# Example: +# +#base_name name +@end example +@ignore +START == AO-DATA1 == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore + +@node environrc +@subsection environment variable presets +@cindex environrc + +If the AutoOpts client program specifies @code{environrc} in its +option descriptor file, then environment variables will be used for +presetting option state. Variables will be looked for that are named, +@env{PROGRAM_OPTNAME} and @env{PROGRAM}. @env{PROGRAM} is the +upper cased @code{C-name} of the program, and @var{OPTNAME} is the +upper cased @code{C-name} of a specific option. (The @code{C-name}s +are the regular names with all special characters converted to +underscores (@code{_}).) + +Option specific environment variables are processed after (and thus +take precedence over) the contents of the @env{PROGRAM} environment +variable. The option argument string for these options takes on the +string value gotten from the environment. Consequently, you can only +have one instance of the @var{OPTNAME}. + +If a particular option may be disabled, then its disabled state is +indicated by setting the @env{PROGRAM_OPTNAME} value to the +disablement prefix. So, for example, if the disablement prefix were +@code{dont}, then you can disable the @code{optname} option by setting +the @env{PROGRAM_OPTNAME}' environment variable to @code{@i{dont}}. +@xref{Common Attributes}. + +The @env{PROGRAM} environment string is tokenized and parsed much +like a command line. Doubly quoted strings have backslash escapes +processed the same way they are processed in C program constant +strings. Singly quoted strings are pretty raw in that backslashes are +honored before other backslashes, apostrophes, newlines and cr/newline +pairs. The options must be introduced with hyphens in the same way as +the command line. + +Note that not all options may be preset. Options that are specified with the +@code{no-preset} attribute and the @option{--help}, @option{--more-help}, +and @option{--save-opts} auto-supported options may not be preset. + +@node config example +@subsection Config file only example +@cindex rcfile +@cindex Configuration File +@cindex Configuration File example + +If for some reason it is difficult or unworkable to integrate configuration +file processing with command line option parsing, the @code{libopts} +(@pxref{libopts procedures}) library can still be used to process +configuration files. Below is a @t{Hello, World!} greeting program that tries +to load a configuration file @file{hello.conf} to see if it should use an +alternate greeting or to personalize the salutation. +@ignore +END == AO-DATA1 == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore +@example +#include <config.h> +#include <sys/types.h> +#include <stdio.h> +#include <pwd.h> +#include <string.h> +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif +#include <autoopts/options.h> +int main(int argc, char ** argv) @{ + char const * greeting = "Hello"; + char const * greeted = "World"; + tOptionValue const * pOV = configFileLoad("hello.conf"); + + if (pOV != NULL) @{ + const tOptionValue* pGetV = optionGetValue(pOV, "greeting"); + + if ( (pGetV != NULL) + && (pGetV->valType == OPARG_TYPE_STRING)) + greeting = strdup(pGetV->v.strVal); + + pGetV = optionGetValue(pOV, "personalize"); + if (pGetV != NULL) @{ + struct passwd * pwe = getpwuid(getuid()); + if (pwe != NULL) + greeted = strdup(pwe->pw_gecos); + @} + + optionUnloadNested(pOV); /* deallocate config data */ + @} + printf("%s, %s!\n", greeting, greeted); + return 0; +@} +@end example + +@noindent +With that text in a file named ``hello.c'', this short script: + +@example +cc -o hello hello.c `autoopts-config cflags ldflags` +./hello +echo 'greeting Buzz off' > hello.conf +./hello +echo personalize > hello.conf +./hello +@end example + +@noindent +will produce the following output: + +@example +Hello, World! +Buzz off, World! +Hello, Bruce Korb,,,! +@end example +@ignore +START == AO-DATA2 == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore + +@c === SECTION MARKER + +@node Config File Format +@section Configuration File Format +@cindex Configuration File + +The configuration file is designed to associate names and values, much like +an AutoGen Definition File (@pxref{Definitions File}). Unfortunately, the +file formats are different. Specifically, AutoGen Definitions provide for +simpler methods for the precise control of a value string and provides for +dynamically computed content. Configuration files have some established +traditions in their layout. So, they are different, even though they do +both allow for a single name to be associated with multiple values and they +both allow for hierarchical values. + +@menu +* config name/string-value:: assigning a string value to a configurable +* config integer-values:: integer values +* config nested-values:: hierarchical values +* config directives:: configuration file directives +* config comments:: comments in the configuration file +@end menu + +@node config name/string-value +@subsection assigning a string value to a configurable + +The basic syntax is a name followed by a value on a single line. They are +separated from each other by either white space, a colon (@code{:}) or an +equal sign (@code{=}). The colon or equal sign may optionally be surrounded +by additional white space. If more than one value line is needed, a +backslash (@code{\}) may be used to continue the value. The backslash (but +not the newline) will be erased. Leading and trailing white space is always +stripped from the value. + +Fundamentally, it looks like this: + +@example +name value for that name +name = another \ + multi-line value \ + for that name. +name: a *third* value for @code{name} +@end example + +If you need more control over the content of the value, you may enclose the +value in XML style brackets: +@example +<name>value </name> +@end example +@noindent +Within these brackets you need not (must not) continue the value data with +backslashes. You may also select the string formation rules to use, just +add the attribute after the name, thus: @code{<name keep>}. + +@table @samp +@item keep +This mode will keep all text between the brackets and not strip any +white space. +@item uncooked +This mode strips leading and trailing white space, but not do any +quote processing. This is the default and need not be specified. +@item cooked +The text is trimmed of leading and trailing white space and XML encodings +are processed. These encodings are slightly expanded over the XML +specification. They are specified with an ampersand followed by a value +name or numeric value and then a semicolon: + +@table @samp +@item amp +@itemx lt +@itemx gt +@itemx quot +@itemx apos +@itemx #dd +@itemx #xHH + +These are all per fairly standad HTML and/or XML encodings. +Additionally: + +@item bs +The ASCII back space character. +@item ff +The ASCII form feed character. +@item ht +The ASCII horizontal (normal) tab character. +@item cr +The ASCII carriage return character. +@item vt +The ASCII vertical tab character. +@item bel +The ASCII alarm bell character. +@item nl +The ASCII new line character. +@item space +The ASCII space character. Normally not necessary, but if you want +to preserve leading or trailing space characters, then use this. +@end table +@end table + +And here is an example of an XML-styled value: + +@example +<name cooked> + This is&nl;&ht;another multi-line +&ht;string example. +</name> +@end example + +The string value associated with @code{name} will be exactly the text enclosed +in quotes with the encoded characters @code{cooked} as you would expect (three +text lines with the last line not ending with a newline, but ending with a +period). + +@node config integer-values +@subsection integer values + +A name can be specified as having an integer value. To do this, you +must use the XML-ish format and specify a @code{type} attribute for +the name: + +@example +<name type=integer> 1234 </name> +@end example + +Boolean, enumeration and set membership types will be added as time +allows. @code{type=string} is also supported, but also is the default. + +@node config nested-values +@subsection hierarchical values + +In order to specify a hierarchical value, you *must* use XML-styled +formatting, specifying a type that is shorter and easier to spell: + +@example +<structured-name type=nested> + [[....]] +</structured-name> +@end example + +@noindent +The ellipsis may be filled with any legal configuration file name/value +assignments. + +@node config directives +@subsection configuration file directives +@cindex autoopts directives + +The @code{<?} marker indicates an XML directive. +There is only one directive supported: program sectioning, +though two syntaxes are supported. + +If, for example, you have a collection of programs that work closely +together and, likely, have a common set of options, these programs may use a +single, sectioned, configuration file. The file may be sectioned in either +of two ways. The two ways may not be intermixed in a single configuration +file. All text before the first segmentation line is processed, then only +the segment that applies: + +@table @samp +@item <?auto-options ...> +The @code{...} ellipsis may contain AutoOpts option processing options. +Currently, that consists of one or both of: + +@table @code +@item gnu +@itemx autoopts +to indicate GNU-standard or AutoOpts-standard layout of usage and +version information, and/or + +@item misuse-usage +@itemx no-misuse-usage +to indicate whether the available options should be listed when +an invalid option appears on the command line. +@end table +@noindent +Anything else will be silently ignored. + +@item <?program prog-name> +The @code{<?} marker indicates an XML directive. +The file is partitioned by these lines and the options are processed +for the @code{prog-name} program only before the first @code{<?program} +directive and the program section with a matching program name. + +@item [PROG_NAME] +This is basically an alias for @code{<?program prog-name>}, except that +the program name must be upper cased and segmented only with underscores +and it is @strong{not} recognized as a program segment when updating +configuration files with the @code{--save-opts} option. In other words, +use this only for Windows compatibility. +@end table + +@noindent +Segmentation does not apply if the config file is being parsed with +the @code{configFileLoad(3AutoOpts)} function. + +@node config comments +@subsection comments in the configuration file + +Comments are lines beginning with a hash mark (@code{#}), +XML-style comments (@code{<!-- arbitrary text -->}), and +unrecognized XML directives. + +@example +# this is a comment +<!-- this is also + a comment --> +<?this is + a bad comment ;-> +@end example + +@c === SECTION MARKER + +@node shell options +@section AutoOpts for Shell Scripts +@cindex shell options +@cindex configuration file + +AutoOpts may be used with shell scripts either by automatically creating a +complete program that will process command line options and pass back +the results to the invoking shell by issuing shell variable assignment +commands, or it may be used to generate portable shell code that can +be inserted into your script. + +The functionality of these features, of course, is somewhat constrained +compared with the normal program facilities. Specifically, you cannot +invoke callout procedures with either of these methods. Additionally, +if you generate a shell script to do the parsing: + +@enumerate +@item +You cannot obtain options from configuration files. +@item +You cannot obtain options from environment variables. +@item +You cannot save the option state to an option file. +@item +Option conflict/requirement verification is disabled. +@end enumerate + +Both of these methods are enabled by running AutoGen on +the definitions file with the additional main procedure attribute: + +@example +main = @{ main-type = shell-process; @}; +@end example +@noindent +or: +@example +main = @{ main-type = shell-parser; @}; +@end example + +If you do not supply a @code{proc-to-call}, it will default to +@code{optionPutShell}. That will produce a program that will process the +options and generate shell text for the invoking shell to interpret +(@pxref{binary-parser}). If you supply the name, @code{optionParseShell}, +then you will have a program that will generate a shell script that can parse +the options (@pxref{script-parser}). If you supply a different procedure +name, you will have to provide that routine and it may do whatever you like. + +@menu +* binary-parser:: Parsing with an Executable +* script-parser:: Parsing with a Portable Script +@end menu + +@node binary-parser +@subsection Parsing with an Executable + +The following commands are approximately all that is needed +to build a shell script command line option parser from +an option definition file: + +@example +autogen -L <opt-template-dir> test-errors.def +cc -o test-errors -L <opt-lib-dir> -I <opt-include-dir> \ + -DTEST_PROGRAM_OPTS test-errors.c -lopts +@end example + +The resulting program can then be used within your shell script as follows: + +@example +eval `./test-errors "$@@"` +if [ -z "$@{OPTION_CT@}" ] ; then exit 1 ; fi +test $@{OPTION_CT@} -gt 0 && shift $@{OPTION_CT@} +@end example +@ignore +END == AO-DATA2 == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore + +Here is the usage output example from AutoOpts error handling +tests. The option definition has argument reordering enabled: + +@example +test_errors - Test AutoOpts for errors +Usage: errors [ -<flag> [<val>] | --<name>[@{=| @}<val>] ]... arg ... + Flg Arg Option-Name Description + -o no option The option option descrip + -s Str second The second option descrip + - may appear up to 10 times + -i --- ignored we have dumped this + -X no another Another option descrip + - may appear up to 5 times + -? no help display extended usage information and exit + -! no more-help extended usage information passed thru pager + -> opt save-opts save the option state to a config file + -< Str load-opts load options from a config file + - disabled as '--no-load-opts' + - may appear multiple times + +Options are specified by doubled hyphens and their name or by a single +hyphen and the flag character. +Operands and options may be intermixed. They will be reordered. + +The following option preset mechanisms are supported: + - reading file errorsRC +@end example + +Using the invocation, +@example + test-errors operand1 -s first operand2 -X -- -s operand3 +@end example +you get the following output for your shell script to evaluate: + +@example +OPTION_CT=4 +export OPTION_CT +TEST_ERRORS_SECOND='first' +export TEST_ERRORS_SECOND +TEST_ERRORS_ANOTHER=1 # 0x1 +export TEST_ERRORS_ANOTHER +set -- 'operand1' 'operand2' '-s' 'operand3' +OPTION_CT=0 +@end example +@node script-parser +@subsection Parsing with a Portable Script + +If you had used @code{test-main = optionParseShell} instead, then you can, +at this point, merely run the program and it will write the parsing +script to standard out. You may also provide this program with command +line options to specify the shell script file to create or edit, and you +may specify the shell program to use on the first shell script line. +That program's usage text would look something like the following +and the script parser itself would be very verbose: + +@example +genshellopt - Generate Shell Option Processing Script - Ver. 1 +Usage: genshellopt [ -<flag> [<val>] | --<name>[@{=| @}<val>] ]... + Flg Arg Option-Name Description + -o Str script Output Script File + -s Str shell Shell name (follows "#!" magic) + - disabled as '--no-shell' + - enabled by default + -v opt version output version information and exit + -? no help display extended usage information and exit + -! no more-help extended usage information passed thru pager + +Options are specified by doubled hyphens and their name or by a single +hyphen and the flag character. +Note that 'shell' is only useful if the output file does not already exist. +If it does, then the shell name and optional first argument will be +extracted from the script file. +If the script file already exists and contains Automated Option Processing +text, the second line of the file through the ending tag will be replaced +by the newly generated text. The first '#!' line will be regenerated. + +Please send bug reports to: <autogen-users@@lists.sourceforge.net> + += = = = = = = = + +This incarnation of genshell will produce +a shell script to parse the options for getdefs: + +getdefs (GNU AutoGen) - AutoGen Definition Extraction Tool - Ver. 1.5 +Usage: getdefs [ <option-name>[@{=| @}<val>] ]... + Arg Option-Name Description + Str defs-to-get Regexp to look for after the "/*=" + Str subblock subblock definition names + Str listattr attribute with list of values + opt ordering Alphabetize or use named file + Num first-index The first index to apply to groups + opt filelist Insert source file names into defs + Str assign Global assignments + Str common-assign Assignments common to all blocks + Str copy File(s) to copy into definitions + opt srcfile Insert source file name into each def + opt linenum Insert source line number into each def + Str input Input file to search for defs + Str output Output file to open + opt autogen Invoke AutoGen with defs + Str template Template Name + Str agarg AutoGen Argument + Str base-name Base name for output file(s) + @end example + +@noindent +Resulting in the following script: +@example +#! /bin/sh +# # # # # # # # # # -- do not modify this marker -- +# +# DO NOT EDIT THIS SECTION + OF /u/bkorb/tools/ag/autogen-bld/doc/ag-texi-32340.d/.ag-5GQlKL/genshellopt.sh +# +# From here to the next `-- do not modify this marker --', +# the text has been generated Sunday August 26, 2018 at 10:46:02 AM PDT +# From the GETDEFS option definitions +# +GETDEFS_LONGUSAGE_TEXT='getdefs error: invalid option descriptor for version +getdefs (GNU AutoGen) - AutoGen Definition Extraction Tool - Ver. 1.5 +Usage: getdefs [ <option-name>[@{=| @}<val>] ]... + +Specify which definitions are of interest and what to say about them: + + Arg Option-Name Description + Str defs-to-get Regexp to look for after the "/*=" + Str subblock subblock definition names + - may appear multiple times + Str listattr attribute with list of values + - may appear multiple times + +specify how to number the definitions: + + Arg Option-Name Description + opt ordering Alphabetize or use named file + - disabled as '\''--no-ordering'\'' + - enabled by default + Num first-index The first index to apply to groups + +Definition insertion options: + + Arg Option-Name Description + opt filelist Insert source file names into defs + Str assign Global assignments + - may appear multiple times + Str common-assign Assignments common to all blocks + - may appear multiple times + Str copy File(s) to copy into definitions + - may appear multiple times + opt srcfile Insert source file name into each def + opt linenum Insert source line number into each def + +specify which files to search for markers: + + Arg Option-Name Description + Str input Input file to search for defs + - may appear multiple times + - default option for unnamed options + +Definition output disposition options:: + + Arg Option-Name Description + Str output Output file to open + - an alternate for '\''autogen'\'' + opt autogen Invoke AutoGen with defs + - disabled as '\''--no-autogen'\'' + - enabled by default + Str template Template Name + Str agarg AutoGen Argument + - prohibits the option '\''output'\'' + - may appear multiple times + Str base-name Base name for output file(s) + - prohibits the option '\''output'\'' + +Version, usage and configuration options: + + Arg Option-Name Description + ' + +GETDEFS_USAGE_TEXT='getdefs (GNU AutoGen) - AutoGen Definition Extraction Tool - Ver. 1.5 +Usage: getdefs [ <option-name>[@{=| @}<val>] ]... + Arg Option-Name Description + Str defs-to-get Regexp to look for after the "/*=" + Str subblock subblock definition names + Str listattr attribute with list of values + opt ordering Alphabetize or use named file + Num first-index The first index to apply to groups + opt filelist Insert source file names into defs + Str assign Global assignments + Str common-assign Assignments common to all blocks + Str copy File(s) to copy into definitions + opt srcfile Insert source file name into each def + opt linenum Insert source line number into each def + Str input Input file to search for defs + Str output Output file to open + opt autogen Invoke AutoGen with defs + Str template Template Name + Str agarg AutoGen Argument + Str base-name Base name for output file(s) + getdefs error: invalid option descriptor for version' + + +GETDEFS_DEFS_TO_GET=$@{GETDEFS_DEFS_TO_GET@} +GETDEFS_DEFS_TO_GET_set=false +export GETDEFS_DEFS_TO_GET + +if test -z "$@{GETDEFS_SUBBLOCK@}" +then + GETDEFS_SUBBLOCK_CT=0 + export GETDEFS_SUBBLOCK_CT +else + GETDEFS_SUBBLOCK_CT=1 + GETDEFS_SUBBLOCK_1=$@{GETDEFS_SUBBLOCK@} + export GETDEFS_SUBBLOCK_CT GETDEFS_SUBBLOCK_1 +fi + +if test -z "$@{GETDEFS_LISTATTR@}" +then + GETDEFS_LISTATTR_CT=0 + export GETDEFS_LISTATTR_CT +else + GETDEFS_LISTATTR_CT=1 + GETDEFS_LISTATTR_1=$@{GETDEFS_LISTATTR@} + export GETDEFS_LISTATTR_CT GETDEFS_LISTATTR_1 +fi + +GETDEFS_ORDERING=$@{GETDEFS_ORDERING@} +GETDEFS_ORDERING_set=false +export GETDEFS_ORDERING + +GETDEFS_FIRST_INDEX=$@{GETDEFS_FIRST_INDEX-'0'@} +GETDEFS_FIRST_INDEX_set=false +export GETDEFS_FIRST_INDEX + +GETDEFS_FILELIST=$@{GETDEFS_FILELIST@} +GETDEFS_FILELIST_set=false +export GETDEFS_FILELIST + +if test -z "$@{GETDEFS_ASSIGN@}" +then + GETDEFS_ASSIGN_CT=0 + export GETDEFS_ASSIGN_CT +else + GETDEFS_ASSIGN_CT=1 + GETDEFS_ASSIGN_1=$@{GETDEFS_ASSIGN@} + export GETDEFS_ASSIGN_CT GETDEFS_ASSIGN_1 +fi + +if test -z "$@{GETDEFS_COMMON_ASSIGN@}" +then + GETDEFS_COMMON_ASSIGN_CT=0 + export GETDEFS_COMMON_ASSIGN_CT +else + GETDEFS_COMMON_ASSIGN_CT=1 + GETDEFS_COMMON_ASSIGN_1=$@{GETDEFS_COMMON_ASSIGN@} + export GETDEFS_COMMON_ASSIGN_CT GETDEFS_COMMON_ASSIGN_1 +fi + +if test -z "$@{GETDEFS_COPY@}" +then + GETDEFS_COPY_CT=0 + export GETDEFS_COPY_CT +else + GETDEFS_COPY_CT=1 + GETDEFS_COPY_1=$@{GETDEFS_COPY@} + export GETDEFS_COPY_CT GETDEFS_COPY_1 +fi + +GETDEFS_SRCFILE=$@{GETDEFS_SRCFILE@} +GETDEFS_SRCFILE_set=false +export GETDEFS_SRCFILE + +GETDEFS_LINENUM=$@{GETDEFS_LINENUM@} +GETDEFS_LINENUM_set=false +export GETDEFS_LINENUM + +if test -z "$@{GETDEFS_INPUT@}" +then + GETDEFS_INPUT_CT=0 + export GETDEFS_INPUT_CT +else + GETDEFS_INPUT_CT=1 + GETDEFS_INPUT_1=$@{GETDEFS_INPUT@} + export GETDEFS_INPUT_CT GETDEFS_INPUT_1 +fi + +GETDEFS_OUTPUT=$@{GETDEFS_OUTPUT@} +GETDEFS_OUTPUT_set=false +export GETDEFS_OUTPUT + +GETDEFS_AUTOGEN=$@{GETDEFS_AUTOGEN@} +GETDEFS_AUTOGEN_set=false +export GETDEFS_AUTOGEN + +GETDEFS_TEMPLATE=$@{GETDEFS_TEMPLATE@} +GETDEFS_TEMPLATE_set=false +export GETDEFS_TEMPLATE + +if test -z "$@{GETDEFS_AGARG@}" +then + GETDEFS_AGARG_CT=0 + export GETDEFS_AGARG_CT +else + GETDEFS_AGARG_CT=1 + GETDEFS_AGARG_1=$@{GETDEFS_AGARG@} + export GETDEFS_AGARG_CT GETDEFS_AGARG_1 +fi + +GETDEFS_BASE_NAME=$@{GETDEFS_BASE_NAME@} +GETDEFS_BASE_NAME_set=false +export GETDEFS_BASE_NAME + +ARG_COUNT=$# +OPT_ARG=$1 +while [ $# -gt 0 ] +do + OPT_ELEMENT='' + OPT_ARG_VAL='' + OPT_ARG=$@{1@} + OPT_CODE=`echo "X$@{OPT_ARG@}"|sed 's/^X-*//'` + shift + OPT_ARG=$1 + case "$@{OPT_CODE@}" in *=* ) + OPT_ARG_VAL=`echo "$@{OPT_CODE@}"|sed 's/^[^=]*=//'` + OPT_CODE=`echo "$@{OPT_CODE@}"|sed 's/=.*$//'` ;; esac + case "$@{OPT_CODE@}" in + 'de' | \ + 'def' | \ + 'defs' | \ + 'defs-' | \ + 'defs-t' | \ + 'defs-to' | \ + 'defs-to-' | \ + 'defs-to-g' | \ + 'defs-to-ge' | \ + 'defs-to-get' ) + if [ -n "$@{GETDEFS_DEFS_TO_GET@}" ] && $@{GETDEFS_DEFS_TO_GET_set@} ; then + echo 'Error: duplicate DEFS_TO_GET option' + echo "$GETDEFS_USAGE_TEXT" + exit 1 + fi >&2 + GETDEFS_DEFS_TO_GET_set=true + OPT_NAME='DEFS_TO_GET' + OPT_ARG_NEEDED=YES + ;; + + 'su' | \ + 'sub' | \ + 'subb' | \ + 'subbl' | \ + 'subblo' | \ + 'subbloc' | \ + 'subblock' ) + GETDEFS_SUBBLOCK_CT=`expr $@{GETDEFS_SUBBLOCK_CT@} + 1` + OPT_ELEMENT="_$@{GETDEFS_SUBBLOCK_CT@}" + OPT_NAME='SUBBLOCK' + OPT_ARG_NEEDED=YES + ;; + + 'li' | \ + 'lis' | \ + 'list' | \ + 'lista' | \ + 'listat' | \ + 'listatt' | \ + 'listattr' ) + GETDEFS_LISTATTR_CT=`expr $@{GETDEFS_LISTATTR_CT@} + 1` + OPT_ELEMENT="_$@{GETDEFS_LISTATTR_CT@}" + OPT_NAME='LISTATTR' + OPT_ARG_NEEDED=YES + ;; + + 'or' | \ + 'ord' | \ + 'orde' | \ + 'order' | \ + 'orderi' | \ + 'orderin' | \ + 'ordering' ) + if [ -n "$@{GETDEFS_ORDERING@}" ] && $@{GETDEFS_ORDERING_set@} ; then + echo 'Error: duplicate ORDERING option' + echo "$GETDEFS_USAGE_TEXT" + exit 1 + fi >&2 + GETDEFS_ORDERING_set=true + OPT_NAME='ORDERING' + eval GETDEFS_ORDERING$@{OPT_ELEMENT@}=true + export GETDEFS_ORDERING$@{OPT_ELEMENT@} + OPT_ARG_NEEDED=OK + ;; + + 'no-' | \ + 'no-o' | \ + 'no-or' | \ + 'no-ord' | \ + 'no-orde' | \ + 'no-order' | \ + 'no-orderi' | \ + 'no-orderin' | \ + 'no-ordering' ) + if [ -n "$@{GETDEFS_ORDERING@}" ] && $@{GETDEFS_ORDERING_set@} ; then + echo 'Error: duplicate ORDERING option' + echo "$GETDEFS_USAGE_TEXT" + exit 1 + fi >&2 + GETDEFS_ORDERING_set=true + GETDEFS_ORDERING='no' + export GETDEFS_ORDERING + OPT_NAME='ORDERING' + OPT_ARG_NEEDED=NO + ;; + + 'fi' | \ + 'fir' | \ + 'firs' | \ + 'first' | \ + 'first-' | \ + 'first-i' | \ + 'first-in' | \ + 'first-ind' | \ + 'first-inde' | \ + 'first-index' ) + if [ -n "$@{GETDEFS_FIRST_INDEX@}" ] && $@{GETDEFS_FIRST_INDEX_set@} ; then + echo 'Error: duplicate FIRST_INDEX option' + echo "$GETDEFS_USAGE_TEXT" + exit 1 + fi >&2 + GETDEFS_FIRST_INDEX_set=true + OPT_NAME='FIRST_INDEX' + OPT_ARG_NEEDED=YES + ;; + + 'fi' | \ + 'fil' | \ + 'file' | \ + 'filel' | \ + 'fileli' | \ + 'filelis' | \ + 'filelist' ) + if [ -n "$@{GETDEFS_FILELIST@}" ] && $@{GETDEFS_FILELIST_set@} ; then + echo 'Error: duplicate FILELIST option' + echo "$GETDEFS_USAGE_TEXT" + exit 1 + fi >&2 + GETDEFS_FILELIST_set=true + OPT_NAME='FILELIST' + eval GETDEFS_FILELIST$@{OPT_ELEMENT@}=true + export GETDEFS_FILELIST$@{OPT_ELEMENT@} + OPT_ARG_NEEDED=OK + ;; + + 'as' | \ + 'ass' | \ + 'assi' | \ + 'assig' | \ + 'assign' ) + GETDEFS_ASSIGN_CT=`expr $@{GETDEFS_ASSIGN_CT@} + 1` + OPT_ELEMENT="_$@{GETDEFS_ASSIGN_CT@}" + OPT_NAME='ASSIGN' + OPT_ARG_NEEDED=YES + ;; + + 'co' | \ + 'com' | \ + 'comm' | \ + 'commo' | \ + 'common' | \ + 'common-' | \ + 'common-a' | \ + 'common-as' | \ + 'common-ass' | \ + 'common-assi' | \ + 'common-assig' | \ + 'common-assign' ) + GETDEFS_COMMON_ASSIGN_CT=`expr $@{GETDEFS_COMMON_ASSIGN_CT@} + 1` + OPT_ELEMENT="_$@{GETDEFS_COMMON_ASSIGN_CT@}" + OPT_NAME='COMMON_ASSIGN' + OPT_ARG_NEEDED=YES + ;; + + 'co' | \ + 'cop' | \ + 'copy' ) + GETDEFS_COPY_CT=`expr $@{GETDEFS_COPY_CT@} + 1` + OPT_ELEMENT="_$@{GETDEFS_COPY_CT@}" + OPT_NAME='COPY' + OPT_ARG_NEEDED=YES + ;; + + 'sr' | \ + 'src' | \ + 'srcf' | \ + 'srcfi' | \ + 'srcfil' | \ + 'srcfile' ) + if [ -n "$@{GETDEFS_SRCFILE@}" ] && $@{GETDEFS_SRCFILE_set@} ; then + echo 'Error: duplicate SRCFILE option' + echo "$GETDEFS_USAGE_TEXT" + exit 1 + fi >&2 + GETDEFS_SRCFILE_set=true + OPT_NAME='SRCFILE' + eval GETDEFS_SRCFILE$@{OPT_ELEMENT@}=true + export GETDEFS_SRCFILE$@{OPT_ELEMENT@} + OPT_ARG_NEEDED=OK + ;; + + 'li' | \ + 'lin' | \ + 'line' | \ + 'linen' | \ + 'linenu' | \ + 'linenum' ) + if [ -n "$@{GETDEFS_LINENUM@}" ] && $@{GETDEFS_LINENUM_set@} ; then + echo 'Error: duplicate LINENUM option' + echo "$GETDEFS_USAGE_TEXT" + exit 1 + fi >&2 + GETDEFS_LINENUM_set=true + OPT_NAME='LINENUM' + eval GETDEFS_LINENUM$@{OPT_ELEMENT@}=true + export GETDEFS_LINENUM$@{OPT_ELEMENT@} + OPT_ARG_NEEDED=OK + ;; + + 'in' | \ + 'inp' | \ + 'inpu' | \ + 'input' ) + GETDEFS_INPUT_CT=`expr $@{GETDEFS_INPUT_CT@} + 1` + OPT_ELEMENT="_$@{GETDEFS_INPUT_CT@}" + OPT_NAME='INPUT' + OPT_ARG_NEEDED=YES + ;; + + 'ou' | \ + 'out' | \ + 'outp' | \ + 'outpu' | \ + 'output' ) + if [ -n "$@{GETDEFS_OUTPUT@}" ] && $@{GETDEFS_OUTPUT_set@} ; then + echo 'Error: duplicate OUTPUT option' + echo "$GETDEFS_USAGE_TEXT" + exit 1 + fi >&2 + GETDEFS_OUTPUT_set=true + OPT_NAME='OUTPUT' + OPT_ARG_NEEDED=YES + ;; + + 'au' | \ + 'aut' | \ + 'auto' | \ + 'autog' | \ + 'autoge' | \ + 'autogen' ) + if [ -n "$@{GETDEFS_AUTOGEN@}" ] && $@{GETDEFS_AUTOGEN_set@} ; then + echo 'Error: duplicate AUTOGEN option' + echo "$GETDEFS_USAGE_TEXT" + exit 1 + fi >&2 + GETDEFS_AUTOGEN_set=true + OPT_NAME='AUTOGEN' + eval GETDEFS_AUTOGEN$@{OPT_ELEMENT@}=true + export GETDEFS_AUTOGEN$@{OPT_ELEMENT@} + OPT_ARG_NEEDED=OK + ;; + + 'no-' | \ + 'no-a' | \ + 'no-au' | \ + 'no-aut' | \ + 'no-auto' | \ + 'no-autog' | \ + 'no-autoge' | \ + 'no-autogen' ) + if [ -n "$@{GETDEFS_AUTOGEN@}" ] && $@{GETDEFS_AUTOGEN_set@} ; then + echo 'Error: duplicate AUTOGEN option' + echo "$GETDEFS_USAGE_TEXT" + exit 1 + fi >&2 + GETDEFS_AUTOGEN_set=true + GETDEFS_AUTOGEN='no' + export GETDEFS_AUTOGEN + OPT_NAME='AUTOGEN' + OPT_ARG_NEEDED=NO + ;; + + 'te' | \ + 'tem' | \ + 'temp' | \ + 'templ' | \ + 'templa' | \ + 'templat' | \ + 'template' ) + if [ -n "$@{GETDEFS_TEMPLATE@}" ] && $@{GETDEFS_TEMPLATE_set@} ; then + echo 'Error: duplicate TEMPLATE option' + echo "$GETDEFS_USAGE_TEXT" + exit 1 + fi >&2 + GETDEFS_TEMPLATE_set=true + OPT_NAME='TEMPLATE' + OPT_ARG_NEEDED=YES + ;; + + 'ag' | \ + 'aga' | \ + 'agar' | \ + 'agarg' ) + GETDEFS_AGARG_CT=`expr $@{GETDEFS_AGARG_CT@} + 1` + OPT_ELEMENT="_$@{GETDEFS_AGARG_CT@}" + OPT_NAME='AGARG' + OPT_ARG_NEEDED=YES + ;; + + 'ba' | \ + 'bas' | \ + 'base' | \ + 'base-' | \ + 'base-n' | \ + 'base-na' | \ + 'base-nam' | \ + 'base-name' ) + if [ -n "$@{GETDEFS_BASE_NAME@}" ] && $@{GETDEFS_BASE_NAME_set@} ; then + echo 'Error: duplicate BASE_NAME option' + echo "$GETDEFS_USAGE_TEXT" + exit 1 + fi >&2 + GETDEFS_BASE_NAME_set=true + OPT_NAME='BASE_NAME' + OPT_ARG_NEEDED=YES + ;; + + 've' | \ + 'ver' | \ + 'vers' | \ + 'versi' | \ + 'versio' | \ + 'version' ) + echo "$GETDEFS_LONGUSAGE_TEXT" + exit 0 + ;; + + 'he' | \ + 'hel' | \ + 'help' ) + echo "$GETDEFS_LONGUSAGE_TEXT" + exit 0 + ;; + + 'mo' | \ + 'mor' | \ + 'more' | \ + 'more-' | \ + 'more-h' | \ + 'more-he' | \ + 'more-hel' | \ + 'more-help' ) + echo "$GETDEFS_LONGUSAGE_TEXT" | $@{PAGER-more@} + exit 0 + ;; + + 'sa' | \ + 'sav' | \ + 'save' | \ + 'save-' | \ + 'save-o' | \ + 'save-op' | \ + 'save-opt' | \ + 'save-opts' ) + echo 'Warning: Cannot save options files' >&2 + OPT_ARG_NEEDED=OK + ;; + + 'lo' | \ + 'loa' | \ + 'load' | \ + 'load-' | \ + 'load-o' | \ + 'load-op' | \ + 'load-opt' | \ + 'load-opts' ) + echo 'Warning: Cannot load options files' >&2 + OPT_ARG_NEEDED=YES + ;; + + 'no-' | \ + 'no-l' | \ + 'no-lo' | \ + 'no-loa' | \ + 'no-load' | \ + 'no-load-' | \ + 'no-load-o' | \ + 'no-load-op' | \ + 'no-load-opt' | \ + 'no-load-opts' ) + echo 'Warning: Cannot suppress the loading of options files' >&2 + OPT_ARG_NEEDED=NO + ;; + + * ) + echo Unknown option: "$@{OPT_CODE@}" >&2 + echo "$GETDEFS_USAGE_TEXT" >&2 + exit 1 + ;; + esac + case "$@{OPT_ARG_NEEDED@}" in + NO ) + OPT_ARG_VAL='' + ;; + YES ) + if [ -z "$@{OPT_ARG_VAL@}" ] + then + if [ $# -eq 0 ] + then + echo No argument provided for $@{OPT_NAME@} option + echo "$GETDEFS_USAGE_TEXT" + exit 1 + fi >&2 + OPT_ARG_VAL=$@{OPT_ARG@} + shift + OPT_ARG=$1 + fi + ;; + OK ) + if [ -z "$@{OPT_ARG_VAL@}" ] && [ $# -gt 0 ] + then + case "$@{OPT_ARG@}" in -* ) ;; * ) + OPT_ARG_VAL=$@{OPT_ARG@} + shift + OPT_ARG=$1 ;; esac + fi + ;; + esac + if [ -n "$@{OPT_ARG_VAL@}" ] + then + eval GETDEFS_$@{OPT_NAME@}$@{OPT_ELEMENT@}="'$@{OPT_ARG_VAL@}'" + export GETDEFS_$@{OPT_NAME@}$@{OPT_ELEMENT@} + fi +done +OPTION_COUNT=`expr $ARG_COUNT - $#` +OPERAND_COUNT=$# +unset OPT_PROCESS || : +unset OPT_ELEMENT || : +unset OPT_ARG || : +unset OPT_ARG_NEEDED || : +unset OPT_NAME || : +unset OPT_CODE || : +unset OPT_ARG_VAL || : + +# # # # # # # # # # +# +# END OF AUTOMATED OPTION PROCESSING +# +# # # # # # # # # # -- do not modify this marker -- + +env | grep '^GETDEFS_' +@end example +@ignore +START == AUTOINFO == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore + +@c === SECTION MARKER + +@node AutoInfo +@section Automated Info Docs +@cindex AutoInfo + +AutoOpts provides two templates for producing @file{.texi} documentation. +@file{agtexi-cmd.tpl} for the invoking section, and @file{aginfo3.tpl} for +describing exported library functions and macros. + +For both types of documents, the documentation level is selected by +passing a @samp{-DLEVEL=<level-name>} argument to AutoGen when you build +the document. (See the example invocation below.) + +Two files will be produced, a @file{.texi} file and a @file{.menu} file. +You should include the text in the @file{.menu} file in a @file{@@menu} +list, either with @file{@@include}-ing it or just copying text. +The @file{.texi} file should be @file{@@include}-ed where the invoking +section belongs in your document. + +The @file{.texi} file will contain an introductory paragraph, a menu +and a subordinate section for the invocation usage and for each +documented option. The introductory paragraph is normally the boiler +plate text, along the lines of: + +@example +This chapter documents the @@file@{AutoOpts@} generated usage text +and option meanings for the @@file@{your-program@} program. +@end example + +@noindent +or: + +@example +These are the publicly exported procedures from the lib@i{name} library. +Any other functions mentioned in the @i{header} file are for the private use +of the library. +@end example + +@menu +* command-info:: @code{invoking} info docs +* library-info:: library info docs +@end menu + +@node command-info +@subsection @code{invoking} info docs + +Using the option definitions for an AutoOpt client program, the +@file{agtexi-cmd.tpl} template will produce texinfo text that documents the +invocation of your program. The text emitted is designed to be included +in the full texinfo document for your product. It is not a stand-alone +document. The usage text for the @ref{autogen usage}, +@ref{getdefs usage} and @ref{columns usage} programs, are included in +this document and are all generated using this template. + +If your program's option definitions include a +@samp{prog-info-descrip} section, then that text will replace the +boilerplate introductory paragraph. + +@noindent +These files are produced by invoking the following command: + +@example +autogen -L $@{prefix@}/share/autogen -Tagtexi-cmd.tpl \ + -DLEVEL=section your-opts.def +@end example + +@noindent +Where @file{$@{prefix@}} is the AutoGen installation prefix +and @file{your-opts.def} is the name of your product's option +definition file. + +@node library-info +@subsection library info docs + +The @command{texinfo} doc for libraries is derived from mostly the same +information as is used for producing man pages @xref{man3}. The main +difference is that there is only one output file and the individual +functions are referenced from a @code{texi} menu. There is also +a small difference in the global attributes used: + +@multitable @columnfractions .02 .23 .65 +@item @tab lib_description +@tab A description of the library. This text appears before the menu. +If not provided, the standard boilerplate version will be inserted. +@item +@item @tab see_also +@tab The @code{SEE ALSO} functionality is not supported for the +@file{texinfo} documentation, so any @code{see_also} attribute will be +ignored. +@end multitable + +@noindent +These files are produced by invoking the following commands: + +@example +getdefs linenum srcfile template=aginfo3.tpl output=libexport.def \ + <source-file-list> + +autogen -L $@{prefix@}/share/autogen -DLEVEL=section libexport.def +@end example + +@noindent +Where @file{$@{prefix@}} is the AutoGen installation prefix +and @file{libexport.def} is some name that suits you. + +An example of this can be seen in this document, @xref{libopts procedures}. + +@c === SECTION MARKER + +@node AutoMan pages +@section Automated Man Pages +@cindex AutoMan pages + +AutoOpts provides two templates for producing man pages. +The command (@file{man1}) pages are derived from the options definition +file, and the library (@file{man3}) pages are derived from +stylized comments (@pxref{getdefs Invocation}). + +Man pages include a date in the footer. By default, this is derived from +the current date. However, this may be overridden with the @code{MAN_PAGE_DATE} +environment variable. If set and not empty, its contents will be copied +into where the output of @code{date '+%d %b %Y'} would otherwise go. + +Man pages may be formatted as either traditional man pages or using @code{mdoc} formatting. +The format is selected by selecting the appropriate template. + +@menu +* man1:: command line man pages +* man3:: library man pages +@end menu + +@node man1 +@subsection command line man pages + +Man pages for commands are documented using the @file{agman-cmd.tpl} +and @file{agmdoc-cmd.tpl} templates. If the options specify pulling +information from @file{RC}/@file{ini}/@file{cfg} files, then you may use +the @file{rc-sample.tpl} template to produce an example config file for +your program. + +Using the option definitions for an AutoOpts client program, +the @samp{agman-cmd.tpl} template will produce an nroff document +suitable for use as a @samp{man(1)} page document for a command +line command. The description section of the document is either +the @samp{prog-man-descrip} text, if present, or the @samp{detail} +text. + +Each option in the option definitions file is fully documented +in its usage. This includes all the information documented +above for each option (@pxref{option attributes}), plus +the @samp{doc} attribute is appended. Since the @samp{doc} +text is presumed to be designed for @code{texinfo} documentation, +@code{sed} is used to convert some constructs from @code{texi} +to @code{nroff}-for-@code{man}-pages. Specifically, + +@example +convert @@code, @@var and @@samp into \fB...\fP phrases +convert @@file into \fI...\fP phrases +Remove the '@@' prefix from curly braces +Indent example regions +Delete the example commands +Replace @samp{end example} command with ".br" +Replace the @samp{@@*} command with ".br" +@end example + +@noindent +This document is produced by invoking the following command: + +@example +autogen -L $@{prefix@}/share/autogen -Tagman-cmd.tpl options.def +@end example + +@noindent +Where @file{$@{prefix@}} is the AutoGen installation prefix and +@file{options.def} is the name of your product's option definition file. +I do not use this very much, so any feedback or improvements would be +greatly appreciated. + +@node man3 +@subsection library man pages + +Man pages for libraries are documented using the @file{agman3.tpl} template. + +Two global definitions are required, and then +one library man page is produced for each @code{export_func} definition +that is found. It is generally convenient to place these definitions +as @file{getdefs} comments (@pxref{getdefs Invocation}) near the procedure +definition, but they may also be a separate AutoGen definitions file +(@pxref{Definitions File}). Each function will be cross referenced +with their sister functions in a @file{SEE ALSO} section. A global +@code{see_also} definition will be appended to this cross referencing text. + +@noindent +The two global definitions required are: + +@multitable @columnfractions .02 .15 .77 +@item @tab library +@tab This is the name of your library, without the @file{lib} prefix. +The AutoOpts library is named @file{libopts.so...}, so the @code{library} +attribute would have the value @code{opts}. +@item +@item @tab header +@tab Generally, using a library with a compiled program entails +@code{#include}-ing a header file. Name that header with this attribute. +In the case of AutoOpts, it is generated and will vary based on the +name of the option definition file. Consequently, @file{your-opts.h} is +specified. +@end multitable + +@noindent +The @code{export_func} definition should contain the following attributes: + +@multitable @columnfractions .02 .15 .77 +@item @tab name +@tab The name of the procedure the library user may call. +@item @tab what +@tab A brief sentence describing what the procedure does. +@item @tab doc +@tab A detailed description of what the procedure does. +It may ramble on for as long as necessary to properly describe it. +@item @tab err +@tab A short description of how errors are handled. +@item @tab ret_type +@tab The data type returned by the procedure. +Omit this for @code{void} procedures. +@item @tab ret_desc +@tab Describe what the returned value is, if needed. +@item @tab private +@tab If specified, the function will @strong{not} be documented. +This is used, for example, to produce external declarations for functions +that are not available for public use, but are used in the generated text. +@item +@item @tab arg +@tab This is a compound attribute that contains: +@end multitable +@multitable @columnfractions .02 .15 .15 .62 +@item @tab @tab arg_type +@tab The data type of the argument. +@item @tab @tab arg_name +@tab A short name for it. +@item @tab @tab arg_desc +@tab A brief description. +@end multitable + +@noindent +As a @file{getdefs} comment, this would appear something like this: + +@example +/*=--subblock=arg=arg_type,arg_name,arg_desc =*/ +/*=* + * library: opts + * header: your-opts.h +=*/ +/*=export_func optionProcess + * + * what: this is the main option processing routine + * arg: + tOptions* + pOpts + program options descriptor + + * arg: + int + argc + program arg count + + * arg: + char** + argv + program arg vector + + * ret_type: int + * ret_desc: the count of the arguments processed + * + * doc: This is what it does. + * err: When it can't, it does this. +=*/ +@end example + +@noindent +Note the @code{subblock} and @code{library} comments. +@code{subblock} is an embedded @file{getdefs} +option (@pxref{getdefs subblock}) that tells it how to parse the +@code{arg} attribute. The @code{library} and @code{header} entries +are global definitions that apply to all the documented functions. + +@c === SECTION MARKER + +@node getopt_long +@section Using getopt(3C) +@cindex getopt_long + +There is a template named, @file{getopt.tpl} that is distributed with +AutoOpts. Using that template instead of @file{options.tpl} will produce +completely independent source code that will parse command line options. It +will utilize either the standard @code{getopt(3C)} or the GNU +@code{getopt_long(3GNU)} function to drive the parsing. Which is used is +selected by the presence or absence of the @code{long-opts} program attribute. +It will save you from being dependent upon the @code{libopts} library @i{and} +it produces code ready for internationalization. However, it also carries +with it some limitations on the use of AutoOpts features and some requirements +on the build environment. + +@strong{PLEASE NOTE}: in processing the option definitions to produce +the usage text, it is necessary to compile some generated code in a +temporary directory. That means that all the include directories +needed to compile the code must be full path names and not relative +directory names. ``.'' is a relative directory name. To specify +``-I.'' in the @code{CFLAGS} environment variable, you must expand it. +For example, use: +@example +CFLAGS=-I`pwd` +@end example + +@menu +* getopt limitations:: getopt feature limitations +* getopt building:: getopt build requirements +@end menu + +@node getopt limitations +@subsection getopt feature limitations + +This list of limitations is relative to the full list of AutoOpts +supported features, @xref{Features}. + +@enumerate +@item +You cannot automatically take advantage of environment variable options or +automated parsing of configuration files (@code{rc} or @code{ini} files). +Consequently, the resulting code does not support @file{--load-opts} or +@file{--save-opts} options automatically. + +@item +You cannot use set membership, enumerated, range checked or stacked +argument type options. In fact, you cannot use anything that depends +upon the @code{libopts} library. You are constrained to options that +take @code{@code{string}} arguments, though you may handle the option +argument with a callback procedure. + +@item +Special disablement and/or enablement prefixes are not recognized. + +@item +Option coordination with external libraries will not work. + +@item +Every option must be @code{settable} because the emitted code +depends upon the @code{SET_OPT_XXX} macros having been defined. +Specify this as a global (program) attribute. + +@item +You must specify a main procedure attribute (@pxref{Generated main}). +The @file{getopt.tpl} template depends upon being able to compile the +traditional .c file into a program and get it to emit the usage text. + +@item +For the same reason, the traditional option parsing table code must be +emitted @b{before} the @file{getopt.tpl} template gets expanded. + +@item +The usage text is, therefore, statically defined. +@end enumerate + +@node getopt building +@subsection getopt build requirements + +You must supply some compile and link options via environment variables. + +@table @samp +@item srcdir +In case the option definition file lives in a different directory. +@item CFLAGS +Any special flags required to compile. The flags from +@code{autoopts-config cflags} will be included automatically. Since +the creation of the option parsing code includes creating a program +that prints out help text, if it is necessary to include files from +various directories to compile that program, you will need to specify +those directories with @option{-Idirpath} text in the @code{CFLAGS}. +Some experimentation may be necessary in that case. + +@strong{NOTE}: the @option{-Idirpath} text is only needed if your option +callback functions include code that require additional @code{#include} +directives. +@item LDFLAGS +Any special flags required to link. The flags from +@code{autoopts-config ldflags} will be included automatically. This +is required only if additional link flags for the help text emission +program might be needed. +@item CC +This is needed only if @code{@code{cc}} cannot be found in @env{$PATH} +(or it is not the one you want). +@end table + +To use this, set the exported environment variables and specify @code{getopt} +as the default template in your option definitions file +(@pxref{Identification}). You will have @i{four} new files. Assuming your +definitions were in a file named @file{myprog-opts.def} and your program name +was specified as @file{progname}, the resulting files would be created: +@file{myprog-opts.h}, @file{myprog-opts.c}, @file{getopt-progname.h} and +@file{getopt-progname.c}. You must compile and link both @file{.c} files into +your program. If there are link failures, then you are using AutoOpts +features that require the @file{libopts} library. You must remove these +features, @xref{getopt limitations}. + +These generated files depend upon configure defines to work correctly. +Therefore, you must specify a @code{config-header} attribute +(@pxref{programming attributes}) and ensure it has @code{#defines} for +either @code{HAVE_STDINT_H} or @code{HAVE_INTTYPES_H}; either +@code{HAVE_SYS_LIMITS_H} or @code{HAVE_LIMITS_H}; and +@code{HAVE_SYSEXITS_H}, if the @file{sysexits.h} header is available. +The required header files for these defines are, respectively, +the @file{/usr/include} files named: +@itemize @bullet +@item stdint.h +@item inttypes.h +@item sys/limits.h +@item limits.h +@item sysexits.h +@end itemize + +@noindent +The following header files must also exist on the build platform: +@itemize @bullet +@item sys/types.h +@item stdio.h +@item string.h +@item unistd.h -- or, for getopt_long: +@item getopt.h +@end itemize +@c === SECTION MARKER + +@node i18n +@section Internationalizing AutoOpts +@cindex Internationalizing AutoOpts + +The generated code for AutoOpts will enable and disable the translation of +AutoOpts run time messages. If @code{ENABLE_NLS} is defined at compile time +and @code{no-xlate} has been not set to the value @emph{anything}, then the +@code{_()} macro may be used to specify a translation function. If undefined, +it will default to @code{gettext(3GNU)}. This define will also enable a +callback function that @code{optionProcess} invokes at the beginning of option +processing. The AutoOpts @code{libopts} library will always check for this +@emph{compiled with NLS} flag, so @code{libopts} does not need to be specially +compiled. The strings returned by the translation function will be +@code{strdup(3)-ed} and kept. They will not be re-translated, even if the +locale changes, but they will also not be dependent upon reused or unmappable +memory. + +You should also ensure that the @code{ATTRIBUTE_FORMAT_ARG()} gets +@code{#define}-ed to something useful. There is an autoconf macro +named @code{AG_COMPILE_FORMAT_ARG} in @file{ag_macros.m4} that will +set it appropriately for you. If you do not do this, then translated +formatting strings may trigger GCC compiler warnings. + +To internationalize option processing, you should first internationalize your +program. Then, the option processing strings can be added to your translation +text by processing the AutoOpts-generated @file{my-opts.c} file and adding the +distributed @file{po/usage-txt.pot} file. (Also by extracting the strings +yourself from the @file{usage-txt.h} file.) When you call +@code{optionProcess}, all of the user visible AutoOpts strings will be passed +through the localization procedure established with the @code{_()} +preprocessing macro. + +All of this is @emph{dis}-abled if you specify the global attribute +@code{no-xlate} to @emph{anything}. + +@c === SECTION MARKER + +@node Naming Conflicts +@section Naming Conflicts +@cindex Naming Conflicts + +AutoOpts generates a header file that contains many C preprocessing macros and +several external names. For the most part, they begin with either @code{opt_} +or @code{option}, or else they end with @code{_opt}. If this happens to +conflict with other macros you are using, or if you are compiling multiple +option sets in the same compilation unit, the conflicts can be avoided. You +may specify an external name @code{prefix} (@pxref{program attributes}) for +all of the names generated for each set of option definitions. + +Among these macros, several take an option name as a macro argument. +Sometimes, this will inconveniently conflict. For example, if you specify an +option named, @code{debug}, the emitted code will presume that @code{DEBUG} is +not a preprocessing name. Or also, if you are building on a Windows platform, +you may find that MicroSoft has usurped a number of user space names in its +header files. Consequently, you will get a preprocessing error if you use, +for example, @code{HAVE_OPT(DEBUG)} or @code{HAVE_OPT(INTERNAL)} +(@pxref{HAVE_OPT}) in your code. You may trigger an obvious warning for such +conflicts by specifying the @code{guard-option-names} attribute +(@pxref{program attributes}). That emitted code will also @code{#undef}-ine +the conflicting name. + +@node All Attribute Names +@section All Attribute Names + +This is the list of all the option attributes used in the various +option processing templates. There are several flavors of attributes, +and these are not distinguished here. + +@itemize @bullet +@item +Valid, current attributes that you are encouraged to use. +@item +Internally generated attributes that you cannot use at all. +I need to prefix these with a distinguished prefix. e.g. @code{ao-} +@item +Valid attributes, but are deprecated. Alternates should be documented. +@end itemize + +This list is derived by running many example option definitions through the +option generation and man page templates and noting which attributes are +actually used. There may be a few that are used but not exercised in my +testing. If so, I need to ferret those out and test them, too. + +@example +addtogroup aliases allow_errors arg_default +arg_name arg_optional arg_range arg_type +argument author call_proc cmd_section +comment_char concept config_header copyright +date default deprecated descrip +detail die_code disable disable_load +disable_save doc doc_section doc_sub +doc_sub_cmd documentation ds_format ds_text +ds_type eaddr enable enabled +environrc equivalence exit_desc exit_name +explain export extract_code field +file_fail_code flag flag_code flag_proc +flags_cant flags_must full_usage gnu_usage +guard_option_names handler_proc handler_type help_type +help_value home_rc homerc ifdef +ifndef immed_disable immediate include +interleaved keyword lib_name library +load_opts_value long_opts main_fini main_init +main_type max min more_help_value +must_set name no_command no_libopts +no_misuse_usage no_preset no_xlate omit_texi +omitted_usage open_file opt_state option_format +option_info owner package prefix +prefix_enum preserve_case prog_descrip prog_info_descrip +prog_man_descrip prog_name prog_title rcfile +reorder_args reset_value resettable save_opts_value +scaled set_desc set_index settable +short_usage stack_arg stdin_input sub_name +sub_text sub_type test_main translators +type unshar_file_code unstack_arg usage +usage_message usage_opt usage_value value +vendor_opt version version_proc version_value +@end example + +@node Option Define Names +@section Option Definition Name Index +@printindex vr + +@ignore +END == AUTOINFO == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore +@page +@node Add-Ons +@chapter Add-on packages for AutoGen + +This chapter includes several programs that either work closely +with AutoGen (extracting definitions or providing special formatting +functions), or leverage off of AutoGen technology. There is also +a formatting library that helps make AutoGen possible. + +AutoOpts ought to appear in this list as well, but since it is +the primary reason why many people would even look into AutoGen +at all, I decided to leave it in the list of chapters. + +@menu +* AutoFSM:: Automated Finite State Machine. +* AutoXDR:: Combined RPC Marshalling. +* AutoEvents:: Automated Event Management. +* Bit Maps:: Bit Maps and Enumerations. +* columns Invocation:: Invoking columns. +* getdefs Invocation:: Invoking getdefs. +* xml2ag Invocation:: Invoking xml2ag. +* snprintfv:: The extensible format printing library. +@end menu +@ignore +START == AUTOFSM == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore + +@c === SECTION MARKER + +@node AutoFSM +@section Automated Finite State Machine +@cindex AutoFSM +@cindex finite state machine + +The templates to generate a finite state machine in C or C++ is included +with AutoGen. The documentation is not. The documentation is in HTML +format for @uref{http://www.gnu.org/software/autogen/autofsm.html,viewing}, +or you can @uref{http://download.sourceforge.net/autogen/,download FSM}. + +@node AutoXDR +@section Combined RPC Marshalling +@cindex RPC +@cindex rpcgen +@cindex remote procedure call +@cindex AutoXDR +@cindex XDR + +The templates and NFSv4 definitions are not included with AutoGen in any way. +The folks that designed NFSv4 noticed that much time and bandwidth was +wasted sending queries and responses when many of them could be bundled. +The protocol bundles the data, but there is no support for it in rpcgen. +That means you have to write your own code to do that. Until now. +Download this and you will have a large, complex example of how to use +@code{AutoXDR} for generating the marshaling and unmarshaling of combined +RPC calls. There is a brief example +@uref{http://www.gnu.org/software/autogen/xdr/index.html,on the web}, but +you should @uref{http://download.sourceforge.net/autogen/,download AutoXDR}. + +@c === SECTION MARKER + +@node AutoEvents +@section Automated Event Management +@cindex AutoEvents + +Large software development projects invariably have a need to manage +the distribution and display of state information and state changes. +In other words, they need to manage their software events. Generally, +each such project invents its own way of accomplishing this and then +struggles to get all of its components to play the same way. It is a +difficult process and not always completely successful. This project +helps with that. + +AutoEvents completely separates the tasks of supplying the data +needed for a particular event from the methods used to manage the +distribution and display of that event. Consequently, the programmer +writing the code no longer has to worry about that part of the +problem. Likewise the persons responsible for designing the event +management and distribution no longer have to worry about getting +programmers to write conforming code. + +This is a work in progress. See my +@uref{http://www.gnu.org/software/autogen/autoevents.html,web page} +on the subject, if you are interested. +I have some useful things put together, but it is not ready +to call a product. + +@ignore +END == AUTOFSM == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore +@page +@ignore +* * * * * * * * * * * * * * * * * +@end ignore +@include invoke-bitmaps.texi + +@page +@ignore +* * * * * * * * * * * * * * * * * +@end ignore +@include invoke-columns.texi + +@page +@ignore +* * * * * * * * * * * * * * * * * +@end ignore +@include invoke-getdefs.texi + +@page +@ignore +* * * * * * * * * * * * * * * * * +@end ignore +@include invoke-xml2ag.texi + +@page +@ignore +* * * * * * * * * * * * * * * * * +@end ignore +@include invoke-snprintfv.texi +@ignore +START == FUTURE == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore +@ignore +END == FUTURE == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore +@page +@node Future +@chapter Some ideas for the future. +@cindex futures + +Here are some things that might happen in the distant future. + +@itemize @bullet +@item +Fix up current tools that contain +miserably complex perl, shell, sed, awk and m4 scripts +to instead use this tool. +@end itemize +@node Copying This Manual +@appendix Copying This Manual + +You may copy this manual under the terms of the FDL +(@url{http://gnu.org/licenses/fdl.texi,the GNU Free Documentation License}). + + + +@page +@node Concept Index +@unnumbered Concept Index + +@printindex cp +@page +@node Function Index +@unnumbered Function Index + +@printindex fn +@page +@contents +@bye + diff --git a/doc/auto-opts.tlib b/doc/auto-opts.tlib new file mode 100644 index 0000000..58c4d80 --- /dev/null +++ b/doc/auto-opts.tlib @@ -0,0 +1,469 @@ +[= -*- Mode: texinfo -*- + + AutoGen5 Template + +# This file is part of AutoGen. +# AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +# +# AutoGen 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. +# +# AutoGen is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see <http://www.gnu.org/licenses/>. +=] + +@page +@node AutoOpts +@chapter Automated Option Processing +@cindex autoopts + +AutoOpts [= +(make-tmp-dir) +(out-push-new) +=] +test ${#AGexe} -eq 0 -o ${#top_srcdir} -eq 0 -o ${top_builddir} -eq 0 && \ + die "AGexe, top_srcdir and top_builddir must be set" +ag_cmd="${AGexe} -L${top_srcdir}/autoopts/tpl" +test "X${top_srcdir}" = "X${top_builddir}" || \ + ag_cmd="${ag_cmd} -L${top_builddir}/autoopts/tpl" +readonly ag_cmd + +run_ag() { + echo ${ag_cmd} "$@" >&2 + ${ag_cmd} "$@" +} + +eval "`egrep '^AO_[A-Z]*=' ${top_srcdir}/VERSION`" 2> /dev/null +echo ${AO_CURRENT}.${AO_REVISION} +[= + +(shell (out-pop #t)) + +=] is bundled with AutoGen. It is a tool that virtually eliminates the +hassle of processing options and keeping man pages, info docs and usage text +up to date. This package allows you to specify several program attributes, +thousands of option types and many option attributes. From this, it then +produces all the code necessary to parse and handle the command line and +configuration file options, and the documentation that should go with your +program as well. +[= + +INVOKE get-text tag = autoopts =][= +(out-push-new (string-append tmp-dir "/check.def" )) + +=] +AutoGen Definitions options; +prog-name = check; +prog-title = "Checkout Automated Options"; +long-opts; +gnu-usage; /* GNU style preferred to default */ + +main = { main-type = shell-process; }; + +flag = { + name = check-dirs; + value = L; /* flag style option character */ + arg-type = string; /* option argument indication */ + max = NOLIMIT; /* occurrence limit (none) */ + stack-arg; /* save opt args in a stack */ + descrip = "Checkout directory list"; + doc = 'name of each directory that is to be "checked out".'; +}; + +flag = { + name = show_defs; + descrip = "Show the definition tree"; + disable = dont; /* mark as enable/disable type */ + /* option. Disable as `dont-' */ + doc = 'disable, if you do not want to see the tree.'; +}; +[= (texi-escape-encode (out-pop #t)) \=] +@end example + +@node quick ao build +@subsection Build the example options + +This program will produce a program that digests its options and +writes the values as shell script code to stdout. +Run the following short script to produce this program:[= # + +Developer note: the following only works when AutoGen has been installed. +Since this may be being built on a system where it has not been installed, +the code below ensures we are running out tools out of the build directory +=] +@example +[= + +(out-push-new (string-append tmp-dir "/mk-check.sh" )) + +\=] +base=check +BASE=`echo $base | tr '[a-z-]' '[A-Z_]'` +cflags="-DTEST_${BASE} `autoopts-config cflags`" +ldflags="`autoopts-config ldflags`" +autogen ${base}.def +cc -o ${base} -g ${cflags} ${base}.c ${ldflags} +./${base} --help +[= (texi-escape-encode (out-pop #t)) \=] +@end example + +@node quick ao help +@subsection Example option help text + +Running the build commands yields: + +@example +[= (out-push-new) \=] +base=check +cd ${tmp_dir} +( + PS4='>ck> ' + BASH_XTRACEFD=2 + exec 2> ${base}-msg.log 1>&2 + set -x + + test -f ${base}.def || die "cannot locate ${base}.def" + test ! -f ${base} || rm -f ${base} + echo "include = '#include \"compat/compat.h\"';" >> ${base}.def + f='@="@="'`echo ${INCLUDES} ${CFLAGS}`' @' + sed -e "s@^cc @${CC:-cc} -include ${top_builddir}/config.h @" \ + -e '/^cflags="/s'"${f}" \ + -e 's@^autogen @run_ag @' \ + mk-${base}.sh > mk-${base} + + . ./mk-${base} +) +test -x ./${base} || { + cat mk-${base} + printf '\n\nFAILURE LOG:\n\n' + cat ${base}-msg.log + tar czf /tmp/ck-fail.tgz . + die cannot create ${base} program +} >&2 + +./${base} --help | sed 's/\t/ /g' +[= + +(texi-escape-encode (shell (out-pop #t))) + +=] +@end example +[= + +INVOKE get-text tag = autoopts-main + +=] +Here is an example program that uses the following set of definitions: + +@example +[= + + (out-push-new (string-append tmp-dir "/default-test.def" )) + +=]AutoGen Definitions options; + +prog-name = default-test; +prog-title = 'Default Option Example'; +homerc = '$$/../share/default-test', '$HOME', '.'; +environrc; +long-opts; +gnu-usage; +usage-opt; +version = '1.0'; +main = { + main-type = shell-process; +}; +#define DEBUG_FLAG +#define WARN_FLAG +#define WARN_LEVEL +#define VERBOSE_FLAG +#define VERBOSE_ENUM +#define DRY_RUN_FLAG +#define OUTPUT_FLAG +#define INPUT_FLAG +#define DIRECTORY_FLAG +#define INTERACTIVE_FLAG +#include stdoptions.def +[= + + (texi-escape-encode (out-pop #t)) + +=]@end example + +@noindent +Running a few simple commands on that definition file: + +@example +autogen default-test.def +copts="-DTEST_DEFAULT_TEST_OPTS `autoopts-config cflags`" +lopts="`autoopts-config ldflags`" +cc -o default-test $@{copts@} default-test.c $@{lopts@} +@end example + +@noindent +Yields a program which, when run with @file{--help}, prints out: + +@example +[= (out-push-new) \=] +set -x +log_file=${tmp_dir}/ao-doc-log +exec 7>&2 ; exec 2>> ${log_file} +TOPDIR=`cd ${top_builddir} >/dev/null ; pwd` +OPTDIR=${TOPDIR}/autoopts + +{ + cd ${tmp_dir} + chmod 666 *.def + echo 'config-header = "config.h";' >> default-test.def + HOME=${tmp_dir} run_ag default-test.def + test -f default-test.c || die 'NO default-test.c PROGRAM' + + opts="-o default-test -DTEST_DEFAULT_TEST_OPTS ${INCLUDES}" + ${CC:-cc} ${CFLAGS} ${opts} default-test.c ${LIBS} || \ + rm -f ./default-test + + test -x ./default-test || { + exec 2>&7 + fail_text=`cat $log_file`$'\n\nprogram:\n'`cat default-test.c` + die 'NO default-test EXECUTABLE + '"$fail_text"' + === END FAIL TEXT' + } +} >&2 + +HOME=${tmp_dir} ${tmp_dir}/default-test --help | \ + sed 's, , ,g;s,\([@{}]\),@\1,g' + +exec 2>&7 7>&- +[= + (shell (out-pop #t)) +=] +@end example +[= + +INVOKE get-text tag = autoopts-api + +=] +[=` + +f=../autoopts/libopts.texi +test -f $f || { + f=${top_srcdir}/autoopts/libopts.texi + test -f $f || die "Cannot locate libopts.texi in $f" +} +cat $f + +`=] +[= + +INVOKE get-text tag = "autoopts-data" + +=] +@noindent +Doing so with getdefs' option definitions yields this sample-getdefsrc file. +I tend to be wordy in my @code{doc} attributes: + +@example +[= (texi-escape-encode (shell " + cd ${tmp_dir} + run_ag -Trc-sample.tpl ${top_srcdir}/getdefs/opts.def >/dev/null + test -f sample-getdefsrc || die did not create sample-getdefsrc + cat sample-getdefsrc +" )) =] +@end example +[= + +INVOKE get-text tag = "ao-data1" + +=] +@example[= +(out-push-new (string-append tmp-dir "/hello.c")) + +\=] + +#include <config.h> +#include <sys/types.h> +#include <stdio.h> +#include <pwd.h> +#include <string.h> +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif +#include <autoopts/options.h> +int main(int argc, char ** argv) { + char const * greeting = "Hello"; + char const * greeted = "World"; + tOptionValue const * pOV = configFileLoad("hello.conf"); + + if (pOV != NULL) { + const tOptionValue* pGetV = optionGetValue(pOV, "greeting"); + + if ( (pGetV != NULL) + && (pGetV->valType == OPARG_TYPE_STRING)) + greeting = strdup(pGetV->v.strVal); + + pGetV = optionGetValue(pOV, "personalize"); + if (pGetV != NULL) { + struct passwd * pwe = getpwuid(getuid()); + if (pwe != NULL) + greeted = strdup(pwe->pw_gecos); + } + + optionUnloadNested(pOV); /* deallocate config data */ + } + printf("%s, %s!\n", greeting, greeted); + return 0; +} +[= (texi-escape-encode (out-pop #t)) \=] +@end example + +@noindent +With that text in a file named ``hello.c'', this short script: + +@example +cc -o hello hello.c `autoopts-config cflags ldflags` +./hello +echo 'greeting Buzz off' > hello.conf +./hello +echo personalize > hello.conf +./hello +@end example + +@noindent +will produce the following output: + +@example +[= (texi-escape-encode (shell " +cd ${tmp_dir} +${CC:-cc} -o hello hello.c ${CFLAGS} ${LIBS} ${LDFLAGS} || \ + die cannot compile hello +./hello +echo 'greeting Buzz off' > hello.conf +./hello +echo personalize > hello.conf +./hello" +)) =] +@end example +[= + +INVOKE get-text tag = "ao-data2" + +=] +[= + + (out-push-new) + +=]( + exec 4>&2 2> ${tmp_dir}/err-test-log.txt + BASH_XTRACEFD=2 + PS4='>etl> ' + set -x + cd ${top_builddir}/autoopts/test || \ + die "cannot cd into ${top_builddir}/autoopts/test" + VERBOSE=true AUTOGEN_TRACE=every AUTOGEN_TRACE_OUT=">>$PWD/ag-log.txt" + export VERBOSE AUTOGEN_TRACE AUTOGEN_TRACE_OUT + ${MAKE:-make} check TESTS=errors.test 1>&2 || : + if test ! -x errors-testd/errors + then + exec 2>&4 + cat ${tmp_dir}/err-test-log.txt >&2 + die "no error usage in $PWD/errors-testd" + fi + cat <<-EOF + + Here is the usage output example from AutoOpts error handling + tests. The option definition has argument reordering enabled: + + @example +EOF + + ./errors-testd/errors -? | sed 's, , ,g;s,\([@{}]\),@\1,g' + cmd='errors operand1 -s first operand2 -X -- -s operand3' + cat <<-EOF + @end example + + Using the invocation, + @example + test-${cmd} + @end example + you get the following output for your shell script to evaluate: + + @example + `./errors-testd/${cmd}` + @end example +EOF +)[= + +(shell (out-pop #t)) + +=] +@node script-parser +@subsection Parsing with a Portable Script + +If you had used @code{test-main = optionParseShell} instead, then you can, +at this point, merely run the program and it will write the parsing +script to standard out. You may also provide this program with command +line options to specify the shell script file to create or edit, and you +may specify the shell program to use on the first shell script line. +That program's usage text would look something like the following +and the script parser itself would be very verbose: + +@example +[= ` + +log=${tmp_dir}/../genshellopt.log + +( + set -x + opts="-o genshellopt -DTEST_GETDEFS_OPTS ${INCLUDES}" + exec 3> ${tmp_dir}/genshellopt.def + cat ${top_srcdir}/getdefs/opts.def >&3 + echo "test_main = 'optionParseShell';" >&3 + echo 'config-header = "config.h";' >&3 + exec 3>&- + + cd ${tmp_dir} + HOME='' run_ag -t40 genshellopt.def + test $? -eq 0 || die "autogen failed to create genshellopt.c - See ${log}" + + ${CC} ${CFLAGS} ${opts} genshellopt.c ${LIBS} + test $? -eq 0 || { + head -n 50000 genshellopt.[ch] + die "could not compile genshellopt.c - See ${log}" + } +) > ${log} 2>&1 + +test -x ${tmp_dir}/genshellopt || \ + die "NO GENSHELLOPT PROGRAM - See ${log}" + +${tmp_dir}/genshellopt --help > ${tmp_dir}/genshellopt.hlp + +${tmp_dir}/genshellopt -o ${tmp_dir}/genshellopt.sh || \ + die cannot create ${tmp_dir}/genshellopt.sh + +sedcmd='s,\t, ,g;s,\\([@{}]\\),@\\1,g' +sed "${sedcmd}" ${tmp_dir}/genshellopt.hlp +cat <<- \_EOF_ + @end example + + @noindent + Resulting in the following script: + @example + _EOF_ + +sed "${sedcmd}" ${tmp_dir}/genshellopt.sh + +` =] +@end example +[= + +INVOKE get-text tag = autoinfo + +=] diff --git a/doc/auto_gen-tpl.in b/doc/auto_gen-tpl.in new file mode 100644 index 0000000..839b7e5 --- /dev/null +++ b/doc/auto_gen-tpl.in @@ -0,0 +1,679 @@ +[= AutoGen5 template + +texi + +## Documentation template +## +## Author: Bruce Korb <bkorb@gnu.org> +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen 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. +## +## AutoGen is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License along +## with this program. If not, see <http://www.gnu.org/licenses/>. +## --------------------------------------------------------------------- + +# Set up some global Scheme variables +# +(setenv "SHELL" "@CONFIG_SHELL@") + +(define texi-file-source (getenv "DOC_TEXT")) + +(define texi-escape-encode (lambda (in-str) + (string-substitute in-str + '("@" "{" "}") + '("@@" "@{" "@}") +) )) + +(define temp-txt "") +(define text-tag "") +(define func-name "") +(define func-str "") +(define func-name "") +(define func-str "") +(make-tmp-dir) + +=][= # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + +\=] +@settitle [= package =] - [= prog-title =] +@setchapternewpage off +@syncodeindex pg cp +@c %**end of header +@copying +This manual is for GNU AutoGen version [= ` + UPDATED=\`date '+%B %Y'\` + echo ${AG_REVISION}, updated ${UPDATED}` =]. + +Copyright @copyright{} [= copyright.date =] by Bruce Korb. + +@quotation +Permission is granted to copy, distribute and/or modify this document +under the terms of the GNU Free Documentation License, Version 1.2 or +any later version published by the Free Software Foundation; with no +Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. +@end quotation +@end copying + +@ignore +[=(set-writable) (dne "")=] + +Plus bits and pieces gathered from all over the source/build +directories: +[= ` for f in ${DOC_DEPENDS} ; do echo " $f" ; done ` =] + +@end ignore + +@dircategory GNU programming tools +@direntry +* AutoGen: (autogen). [= prog-title =] +@end direntry + +@ifinfo +@ifnothtml +This file documents [= package =] Version [=`echo ${AG_REVISION}`=]. + +AutoGen copyright @copyright{} [= copyright.date =] Bruce Korb +AutoOpts copyright @copyright{} [= copyright.date =] Bruce Korb +snprintfv copyright @copyright{} 1999-2000 Gary V. Vaughan + +[=(gpl "AutoGen" "")=] + +@ignore +Permission is granted to process this file through TeX and print the +results, provided the printed document carries copying permission +notice identical to this one except for the removal of this paragraph. +@end ignore +@end ifnothtml +@end ifinfo + +@finalout +@titlepage +@title AutoGen - [= prog-title =] +@subtitle For version [=` + echo ${AG_REVISION}, ${UPDATED} `=] +@author Bruce Korb +@author @email{[= (texi-escape-encode "bkorb@gnu.org") =]} + +@page +@vskip 0pt plus 1filll +AutoGen copyright @copyright{} [= copyright.date =] Bruce Korb +@sp 2 +This is the second edition of the GNU AutoGen documentation, +@sp 2 +Published by Bruce Korb, 910 Redwood Dr., Santa Cruz, CA 95060 + +[=(gpl "AutoGen" "")=] + +@insertcopying +@end titlepage + +@node Top, Introduction, , (dir) +@top The Automated Program Generator +@comment node-name, next, previous, up + +This file documents AutoGen version [=` + echo ${AG_REVISION}`=]. It is a tool designed +for generating program files that contain repetitive text with varied +substitutions. This document is very long because it is intended as a +reference document. For a quick start example, @xref{Example Usage}. + +The AutoGen distribution includes the basic generator engine and +several add-on libraries and programs. Of the most general interest +would be Automated Option processing, @xref{AutoOpts}, which also +includes stand-alone support for configuration file parsing, @xref{Features}. +@xref{Add-Ons, Add-on packages for AutoGen}, section for additional +programs and libraries associated with AutoGen. + +This edition documents version [=`echo ${AG_REVISION}, ${UPDATED}.`=] + +[=`cat autogen-intro.texi`=] + +@node Directives +@section Controlling What Gets Processed +@cindex directives + +Definition processing directives can @strong{only} be processed +if the '#' character is the first character on a line. Also, if you +want a '#' as the first character of a line in one of your string +assignments, you should either escape it by preceding it with a +backslash @samp{\}, or by embedding it in the string as in @code{"\n#"}. + +All of the normal C preprocessing directives are recognized, though +several are ignored. There is also an additional @code{#shell} - +@code{#endshell} pair. Another minor difference is that AutoGen +directives must have the hash character (@code{#}) in column 1. +Unrecognized directives produce an error. + +The final tweak is that @code{#!} is treated as a comment line. +Using this feature, you can use: @samp{#! /usr/local/bin/autogen} +as the first line of a definitions file, set the mode to executable +and "run" the definitions file as if it were a direct invocation of +AutoGen. This was done for its hack value. + +The AutoGen recognized directives are: +@table @code[=` +if test -z "$top_srcdir" || test ! -d "$top_srcdir" +then top_srcdir=.. ; fi +f=${top_srcdir}/agen5/defDirect.c +test -f ${f} || die missing $f + +load_comment() { + comment_text= + nl='' + while IFS= read -r line + do + case "X$line" in + X*' */' ) return ;; esac + + comment_text=${comment_text}${nl}$( + echo "$line" | sed 's/ *\\* *//') + nl=' +' + done + die 'end of comment not found' +} + +while IFS= read -r line +do + test "X$line" = "X/**" || continue + load_comment + IFS= read -r line || break + test "X$line" = "Xchar *" || continue + IFS= read -r line || die bad read + case "X$line" in + XdoDir_* ) + line=${line%%(*} + line=${line#doDir_} + ;; + * ) + continue + ;; + esac + { + printf '\n@item #%s\n@cindex %s\n@cindex %s directive\n' \ + $line $line $line + echo "$comment_text" + } > ${tmp_dir}/directive-$line +done < $f +cat ${tmp_dir}/directive-* +`=] +@end table +[= + +INVOKE get-text tag = COMMENTS + +=] +@node Full Syntax +@section Finite State Machine Grammar + +The preprocessing directives and comments are not part of the grammar. They +are handled by the scanner/lexer. The following was extracted directly from +the generated defParse-fsm.c source file. The "EVT:" is the token seen, +the "STATE:" is the current state and the entries in this table describe +the next state and the action to take. Invalid transitions were removed +from the table. + +@ignore +Extracted from $top_srcdir/agen5/defParse.y +@end ignore +@example +[= ` + +if test -z "$top_srcdir" || test ! -d "$top_srcdir" +then top_srcdir=.. ; fi +f=${top_srcdir}/agen5/defParse-fsm.c +test -f ${f} || die missing generated file: $f +sed -n -e '/^dp_trans_table/,/^};$/p' ${f} | \ + sed '/ \&dp_do_invalid /d;/^ *}/d;s/@/@@/g;s/{/@{/g;s/}/@}/g' + +` =] +@end example +[= + +INVOKE get-text tag = TEMPLATE + +=] +@ignore + +* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +@end ignore +@page +@node AutoGen Functions +@section AutoGen Scheme Functions + +AutoGen uses Guile to interpret Scheme expressions within AutoGen +macros. All of the normal Guile functions are available, plus several +extensions (@pxref{Common Functions}) have been added to +augment the repertoire of string manipulation functions and +manage the state of AutoGen processing. + +This section describes those functions that are specific to AutoGen. +Please take note that these AutoGen specific functions are not loaded +and thus not made available until after the command line options have +been processed and the AutoGen definitions have been loaded. They may, +of course, be used in Scheme functions that get defined at those times, +but they cannot be invoked. + +@menu[= + +FOR gfunc =][= + (if (not (exist? "name")) + (error "NO NAME")) =][= + + IF (not (exist? "general_use")) =][= + INVOKE emit-menu-entry =][= + ENDIF =][= + +ENDFOR gfunc =] +* SCM autogen-version:: @file{autogen-version} - ``[= version =]'' +* SCM c-file-line-fmt:: format file info as, ``@code{#line nn "file"}'' +@end menu + +[= +FOR gfunc =][= + IF (not (exist? "general_use")) =][= + INVOKE emit-scm-func =][= + ENDIF general_use =][= +ENDFOR gfunc +=] +@ignore +Generated [= (tpl-file-line) =]. +@end ignore + +@node SCM autogen-version +@subsection @file{autogen-version} - autogen version number +@findex autogen-version + +This is a symbol defining the current AutoGen version number string. +It was first defined in AutoGen-5.2.14. +It is currently ``[= version =]''. + +@node SCM c-file-line-fmt +@subsection format file info as, ``@code{#line nn "file"}'' +@findex c-file-line-fmt + +This is a symbol that can easily be used with the functions +@xref{SCM tpl-file-line}, and @xref{SCM def-file-line}. +These will emit C program @code{#line} directives pointing to template +and definitions text, respectively. +@ignore + +* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +@end ignore +@page +@node Common Functions +@section Common Scheme Functions + +This section describes a number of general purpose functions that make +the kind of string processing that AutoGen does a little easier. +Unlike the AutoGen specific functions (@pxref{AutoGen Functions}), +these functions are available for direct use during definition load time. +The equality test (@pxref{SCM =}) is ``overloaded'' to do string equivalence +comparisons. If you are looking for inequality, the Scheme/Lisp way +of spelling that is, ``(not (= ...))''. + +@menu[= + +FOR gfunc =][= + + IF (exist? "general_use") =][= + INVOKE emit-menu-entry =][= + ENDIF =][= + +ENDFOR gfunc + +=] +@end menu + +[= + +FOR gfunc =][= + IF (exist? "general_use") =][= + INVOKE emit-scm-func =][= + ENDIF general_use =][= +ENDFOR gfunc + +=][= + +INVOKE get-text tag = MACROS + +=] +@menu +* AGMacro syntax:: AutoGen Macro Syntax[= +FOR macfunc =][= + IF (exist? "desc") =][= + (sprintf "\n* %-18s %s - %s" + (string-append (get "name") "::" ) + (string-upcase! (get "name")) + (get "what") ) =][= + ENDIF =][= +ENDFOR macfunc=] +* shell command:: Inserting text from a shell script +* guile command:: Inserting text from a scheme script +@end menu +@node AGMacro syntax +@subsection AutoGen Macro Syntax +@cindex macro syntax + +The general syntax is: + +@example +[ @{ <native-macro-name> | <user-defined-name> @} ] [ <arg> ... ] +@end example + +@noindent +The syntax for @code{<arg>} depends on the particular macro, +but is generally a full expression (@pxref{expression syntax}). +Here are the exceptions to that general rule: + +@enumerate +@item +@code{INVOKE} macros, implicit or explicit, must be followed by +a list of name/string value pairs. The string values are +@i{simple expressions}, as described above. + +That is, the @code{INVOKE} syntax is one of these two: +@example +<user-macro-name> [ <name> [ = <expression> ] ... ] + +INVOKE <name-expression> [ <name> [ = <expression> ] ... ] +@end example + +@item +AutoGen FOR macros must be in one of three forms: + +@example +FOR <name> [ <separator-string> ] + +FOR <name> (...Scheme expression list) + +FOR <name> IN <string-entry> [ ... ] +@end example +@noindent +where: +@table @samp +@item <name> +must be a simple name. +@item <separator-string> +is inserted between copies of the enclosed block. Do not try to use ``IN'' +as your separator string. It won't work. +@item <string-entry> +is an entry in a list of strings. ``@code{<name>}'' is assigned +each value from the ``@code{IN}'' list before expanding the @code{FOR} block. +@item (...Scheme expression list) +is expected to contain one or more of the @code{for-from}, +@code{for-to}, @code{for-by}, and @code{for-sep} functions. +(@xref{FOR}, and @ref{AutoGen Functions}) +@end table + +The first two forms iterate over the @code{FOR} block if @code{<name>} +is found in the AutoGen values. The last form will create the AutoGen +value named @code{<name>}. + +@item +AutoGen @code{DEFINE} macros must be followed by a simple name. +Anything after that is ignored. Consequently, that ``comment space'' +may be used to document any named values the macro expects to have +set up as arguments. @xref{DEFINE}. + +@item +The AutoGen @code{COMMENT}, @code{ELSE}, @code{ESAC} and the @code{END*} +macros take no arguments and ignore everything after the macro name +(e.g. see @ref{COMMENT}) +@end enumerate[= # + + +@c FOR each defined function, +@c this code will insert the extracted documentation =][= + +FOR macfunc =][= + IF (exist? "desc") =] + +@node [=name=] +@subsection [=% name (string-upcase! "%s") =] - [=what=] +[= id-file =] +@findex [=% name (string-upcase! "%s") =][= + (if (exist? "cindex") + (string-append "\n@cindex " + (join "\n@cindex " (stack "cindex")) )) =] + +[=desc=][= + ENDIF desc exists =][= +ENDFOR macfunc=] +@node shell command +@subsection Inserting text from a shell script + +If the text between the start and end macro markers starts with an opening +curly brace ('@code{@{}') or is surrounded by back quotes ('@code{`}'), then +the text is handed off to the server shell for evaluation. The output to +standard out is inserted into the document. If the text starts with the +curly brace, all the text is passed off as is to the shell. If surrounded by +back quotes, then the string is ``cooked'' before being handed off to the +shell. + +@node guile command +@subsection Inserting text from a scheme script + +If the text between the start and end macro markers starts with a semi-colon +or an opening parenthesis, all the text is handed off to the Guile/scheme +processor. If the last result is text or a number, it is added (as text) +to the output document. + +[= + +INVOKE get-text tag = augmenting + +=] +@ignore + +Invocation section from [= ag-texi =] + +@end ignore +@page + +@include [= ag-texi =] + +[= + +INVOKE get-text tag = installation =][= +INCLUDE "auto-opts.tlib" + +=] +@page +@node Add-Ons +@chapter Add-on packages for AutoGen + +This chapter includes several programs that either work closely +with AutoGen (extracting definitions or providing special formatting +functions), or leverage off of AutoGen technology. There is also +a formatting library that helps make AutoGen possible. + +AutoOpts ought to appear in this list as well, but since it is +the primary reason why many people would even look into AutoGen +at all, I decided to leave it in the list of chapters. + +@menu +* AutoFSM:: Automated Finite State Machine. +* AutoXDR:: Combined RPC Marshalling. +* AutoEvents:: Automated Event Management. +* Bit Maps:: Bit Maps and Enumerations. +* columns Invocation:: Invoking columns. +* getdefs Invocation:: Invoking getdefs. +* xml2ag Invocation:: Invoking xml2ag. +* snprintfv:: The extensible format printing library. +@end menu +[= + +INVOKE get-text tag = autofsm + +=][= + +FOR addon-texi + +=] +@page +@ignore +* * * * * * * * * * * * * * * * * +@end ignore +@include [= addon-texi =] +[= + +ENDFOR =][= + +INVOKE get-text tag = Future + +=] +@page +@node Future +@chapter Some ideas for the future. +@cindex futures + +Here are some things that might happen in the distant future. + +@itemize @bullet +@item +Fix up current tools that contain +miserably complex perl, shell, sed, awk and m4 scripts +to instead use this tool. +@end itemize +@node Copying This Manual +@appendix Copying This Manual + +You may copy this manual under the terms of the FDL +(@url{http://gnu.org/licenses/fdl.texi,the GNU Free Documentation License}). + +[=`sed '1,/^@appendixsec/d' fdl.texi`=] + +@page +@node Concept Index +@unnumbered Concept Index + +@printindex cp +@page +@node Function Index +@unnumbered Function Index + +@printindex fn +@page +@contents +@bye +[= + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + +=][= + +DEFINE id-file =] +@ignore +Generated [= (tpl-file-line) =]. +Extracted from [=srcfile=] line [=linenum=]. +@end ignore +[= + +ENDDEF id-file + +# # # # # # # # # # # # # # # # # # # # =][= + +DEFINE get-text =][= + +(set! text-tag + (string-append "@ignore\n%s == " + (string-upcase! (get "tag")) " == %s or the surrounding 'ignore's\n" + "Extraction from autogen.texi\n" + "@end ignore" )) + +(extract texi-file-source text-tag) =][= + +ENDDEF get-text + +# # # # # # # # # # # # # # # # # # # # =][= + +DEFINE set-func-name =][= + + (set! func-name (shell (sprintf "echo '%s' | + sed -e 's/-p$/?/' -e 's/-x$/!/' -e 's/-to-/->/'" + (string-tr! (get "name") "A-Z_^" "a-z--") )) ) + + (set! func-str + (if (exist? "string") (get "string") func-name)) =][= + +ENDDEF + +# # # # # # # # # # # # # # # # # # # # =][= + +DEFINE emit-scm-func =][= + + INVOKE set-func-name =] +@node SCM [= (. func-str)=] +@subsection [= (string-append "@file{" func-name "} - " (get "what")) =] +@findex [= (. func-name) =][= +% string "\n@findex %s" =] +[= id-file =] +Usage: ([= (. func-str) =][= + + FOR exparg =] [= + + arg_optional "[ " =][=arg_name=][= arg_list " ..." =][= + arg_optional " ]" =][= + + ENDFOR exparg =]) +@* +[= string (string-append func-name ": ") =][= + (shell (string-append + "(sed \"s/^\\`'//\" <<\\_EODoc_\n" + (if (exist? "doc") (get "doc") "This function is not documented.") + "\n_EODoc_\n)" ))=] +[= + IF (exist? "exparg") =] +Arguments:[= + FOR exparg =] +@* +[=arg_name=] - [= + + arg_optional "Optional - " =][= + IF (exist? "arg_desc") =][=arg_desc=][= + ELSE =]Undocumented[= + ENDIF =][= + + ENDFOR exparg =][= + + ELSE + =] +This Scheme function takes no arguments.[= + ENDIF =] +[= + +ENDDEF + +# # # # # # # # # # # # # # # # # # # # =][= + +DEFINE emit-menu-entry =][= + + INVOKE set-func-name =][= + (sprintf "\n* SCM %-20s @file{%s} - %s" (string-append func-str "::") + func-name (get "what")) + =][= +ENDDEF emit-menu-entry + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + +=][= # + +;; Local Variables: +;; indent-tabs-mode: nil +;; mode: texinfo +;; End: + +auto_gen-tpl.in ends here =] diff --git a/doc/autogen-intro.texi b/doc/autogen-intro.texi new file mode 100644 index 0000000..f379f3c --- /dev/null +++ b/doc/autogen-intro.texi @@ -0,0 +1,819 @@ +@ignore + +This file is part of AutoGen. +AutoGen is free software. +AutoGen is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + +AutoGen 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. + +AutoGen is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program. If not, see <http://www.gnu.org/licenses/>. + +This file has the following md5sum: + +43b91e8ca915626ed3818ffb1b71248b COPYING.gplv3 + +@end ignore +@menu +* Introduction:: AutoGen's Purpose +* Definitions File:: AutoGen Definitions File +* Template File:: AutoGen Template +* Augmenting AutoGen:: Augmenting AutoGen Features +* autogen Invocation:: Invoking AutoGen +* Installation:: Configuring and Installing +* AutoOpts:: Automated Option Processing +* Add-Ons:: Add-on packages for AutoGen +* Future:: Some ideas for the future. +* Copying This Manual:: Copying This Manual +* Concept Index:: General index +* Function Index:: Function index +@end menu + +@ignore +* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +@end ignore +@page +@node Introduction +@chapter Introduction +@cindex Introduction + +AutoGen is a tool designed for generating program files that contain +repetitive text with varied substitutions. Its goal is to simplify the +maintenance of programs that contain large amounts of repetitious text. +This is especially valuable if there are several blocks of such text +that must be kept synchronized in parallel tables. + +An obvious example is the problem of maintaining the code required for +processing program options and configuration settings. Processing options +requires a minimum of four different constructs be kept in proper order in +different places in your program. You need at least: + +@enumerate +@item +The flag character in the flag string, +@item +code to process the flag when it is encountered, +@item +a global state variable or two, and +@item +a line in the usage text. +@end enumerate + +@noindent +You will need more things besides this if you choose to implement long option +names, configuration (rc/ini) file processing, environment variable settings +and keep all the documentation for these up to date. This can be done +mechanically; with the proper templates and this program. In fact, it has +already been done and AutoGen itself uses it@: @xref{AutoOpts}. For a simple +example of Automated Option processing, @xref{Quick Start}. For a full list +of the Automated Option features, @xref{Features}. Be forewarned, though, the +feature list is ridiculously extensive. + +@menu +* Generalities:: The Purpose of AutoGen +* Example Usage:: A Simple Example +* csh/zsh caveat:: csh/zsh caveat +* Testimonial:: A User's Perspective +@end menu + +@c === SECTION MARKER + +@node Generalities +@section The Purpose of AutoGen + +The idea of this program is to have a text file, a template if +you will, that contains the general text of the desired output file. +That file includes substitution expressions and sections of text that are +replicated under the control of separate definition files. + +@cindex design goals + +AutoGen was designed with the following features: + +@enumerate +@item +The definitions are completely separate from the template. By completely +isolating the definitions from the template it greatly increases the +flexibility of the template implementation. A secondary goal is that a +template user only needs to specify those data that are necessary to describe +his application of a template. + +@item +Each datum in the definitions is named. Thus, the definitions can be +rearranged, augmented and become obsolete without it being necessary to +go back and clean up older definition files. Reduce incompatibilities! + +@item +Every definition name defines an array of values, even when there is +only one entry. These arrays of values are used to control the +replication of sections of the template. + +@item +There are named collections of definitions. They form a nested hierarchy. +Associated values are collected and associated with a group name. +These associated data are used collectively in sets of substitutions. + +@item +The template has special markers to indicate where substitutions are +required, much like the @code{$@{VAR@}} construct in a shell @code{here doc}. +These markers are not fixed strings. They are specified at the start of +each template. Template designers know best what fits into their +syntax and can avoid marker conflicts. + +We did this because it is burdensome and difficult to avoid conflicts +using either M4 tokenization or C preprocessor substitution rules. It +also makes it easier to specify expressions that transform the value. +Of course, our expressions are less cryptic than the shell methods. + +@item +These same markers are used, in conjunction with enclosed keywords, to +indicate sections of text that are to be skipped and for sections of +text that are to be repeated. This is a major improvement over using C +preprocessing macros. With the C preprocessor, you have no way of +selecting output text because it is an @i{un}varying, mechanical +substitution process. + +@item +Finally, we supply methods for carefully controlling the output. +Sometimes, it is just simply easier and clearer to compute some text or +a value in one context when its application needs to be later. So, +functions are available for saving text or values for later use. +@end enumerate + +@c === SECTION MARKER + +@node Example Usage +@section A Simple Example +@cindex example, simple AutoGen + +This is just one simple example that shows a few basic features. +If you are interested, you also may run "make check" with the +@code{VERBOSE} environment variable set and see a number of other +examples in the @file{agen5/test} directory. + +Assume you have an enumeration of names and you wish to associate some +string with each name. Assume also, for the sake of this example, +that it is either too complex or too large to maintain easily by hand. +We will start by writing an abbreviated version of what the result +is supposed to be. We will use that to construct our output templates. + +@noindent +In a header file, @file{list.h}, you define the enumeration +and the global array containing the associated strings: + +@example +typedef enum @{ + IDX_ALPHA, + IDX_BETA, + IDX_OMEGA @} list_enum; + +extern char const* az_name_list[ 3 ]; +@end example + +@noindent +Then you also have @file{list.c} that defines the actual strings: + +@example +#include "list.h" +char const* az_name_list[] = @{ + "some alpha stuff", + "more beta stuff", + "final omega stuff" @}; +@end example + +@noindent +First, we will define the information that is unique for each enumeration +name/string pair. This would be placed in a file named, @file{list.def}, +for example. + +@example +autogen definitions list; +list = @{ list_element = alpha; + list_info = "some alpha stuff"; @}; +list = @{ list_info = "more beta stuff"; + list_element = beta; @}; +list = @{ list_element = omega; + list_info = "final omega stuff"; @}; +@end example + +The @code{autogen definitions list;} entry defines the file as an AutoGen +definition file that uses a template named @code{list}. That is followed by +three @code{list} entries that define the associations between the +enumeration names and the strings. The order of the differently named +elements inside of list is unimportant. They are reversed inside of the +@code{beta} entry and the output is unaffected. + +Now, to actually create the output, we need a template or two that can be +expanded into the files you want. In this program, we use a single template +that is capable of multiple output files. The definitions above refer to a +@file{list} template, so it would normally be named, @file{list.tpl}. + +It looks something like this. +(For a full description, @xref{Template File}.) + +@example +[+ AutoGen5 template h c +] +[+ CASE (suffix) +][+ + == h +] +typedef enum @{[+ + FOR list "," +] + IDX_[+ (string-upcase! (get "list_element")) +][+ + ENDFOR list +] @} list_enum; + +extern char const* az_name_list[ [+ (count "list") +] ]; +[+ + + == c +] +#include "list.h" +char const* az_name_list[] = @{[+ + FOR list "," +] + "[+list_info+]"[+ + ENDFOR list +] @};[+ + +ESAC +] +@end example + +The @code{[+ AutoGen5 template h c +]} text tells AutoGen that this is +an AutoGen version 5 template file; that it is to be processed twice; +that the start macro marker is @code{[+}; and the end marker is +@code{+]}. The template will be processed first with a suffix value of +@code{h} and then with @code{c}. Normally, the suffix values are +appended to the @file{base-name} to create the output file name. + +The @code{[+ == h +]} and @code{[+ == c +]} @code{CASE} selection clauses +select different text for the two different passes. In this example, +the output is nearly disjoint and could have been put in two separate +templates. However, sometimes there are common sections and this is +just an example. + +The @code{[+FOR list "," +]} and @code{[+ ENDFOR list +]} clauses delimit +a block of text that will be repeated for every definition of @code{list}. +Inside of that block, the definition name-value pairs that +are members of each @code{list} are available for substitutions. + +The remainder of the macros are expressions. Some of these contain +special expression functions that are dependent on AutoGen named values; +others are simply Scheme expressions, the result of which will be +inserted into the output text. Other expressions are names of AutoGen +values. These values will be inserted into the output text. For example, +@code{[+list_info+]} will result in the value associated with +the name @code{list_info} being inserted between the double quotes and +@code{(string-upcase! (get "list_element"))} will first "get" the value +associated with the name @code{list_element}, then change the case of +all the letters to upper case. The result will be inserted into the +output document. + +If you have compiled AutoGen, you can copy out the template and definitions +as described above and run @code{autogen list.def}. This will produce +exactly the hypothesized desired output. + +One more point, too. Lets say you decided it was too much trouble to figure +out how to use AutoGen, so you created this enumeration and string list with +thousands of entries. Now, requirements have changed and it has become +necessary to map a string containing the enumeration name into the enumeration +number. With AutoGen, you just alter the template to emit the table of names. +It will be guaranteed to be in the correct order, missing none of the entries. +If you want to do that by hand, well, good luck. + +@c === SECTION MARKER + +@node csh/zsh caveat +@section csh/zsh caveat + +AutoGen tries to use your normal shell so that you can supply shell code +in a manner you are accustomed to using. If, however, you use csh or +zsh, you cannot do this. Csh is sufficiently difficult to program that +it is unsupported. Zsh, though largely programmable, also has some +anomalies that make it incompatible with AutoGen usage. Therefore, when +invoking AutoGen from these environments, you must be certain to set the +SHELL environment variable to a Bourne-derived shell, e.g., sh, ksh or +bash. + +Any shell you choose for your own scripts need to follow these basic +requirements: + +@enumerate +@item +It handles @code{trap ":" $sig} without output to standard out. This is done +when the server shell is first started. If your shell does not handle this, +then it may be able to by loading functions from its start up files. +@item +At the beginning of each scriptlet, the command @code{\\cd $PWD} +is inserted. This ensures that @code{cd} is not aliased to something +peculiar and each scriptlet starts life in the execution directory. +@item +At the end of each scriptlet, the command @code{echo mumble} is +appended. The program you use as a shell must emit the single +argument @code{mumble} on a line by itself. +@end enumerate + +@c === SECTION MARKER + +@node Testimonial +@section A User's Perspective + +@format +Alexandre wrote: +> +> I'd appreciate opinions from others about advantages/disadvantages of +> each of these macro packages. +@end format + +I am using AutoGen in my pet project, and find one of its best points to +be that it separates the operational data from the implementation. + +Indulge me for a few paragraphs, and all will be revealed: +In the manual, Bruce cites the example of maintaining command line flags +inside the source code; traditionally spreading usage information, flag +names, letters and processing across several functions (if not files). +Investing the time in writing a sort of boiler plate (a template in +AutoGen terminology) pays by moving all of the option details (usage, +flags names etc.) into a well structured table (a definition file if you +will), so that adding a new command line option becomes a simple matter +of adding a set of details to the table. + +So far so good! Of course, now that there is a template, writing all of +that tedious optargs processing and usage functions is no longer an +issue. Creating a table of the options needed for the new project and +running AutoGen generates all of the option processing code in C +automatically from just the tabular data. AutoGen in fact already ships +with such a template... AutoOpts. + +One final consequence of the good separation in the design of AutoGen is +that it is retargetable to a greater extent. The +egcs/gcc/fixinc/inclhack.def can equally be used (with different +templates) to create a shell script (inclhack.sh) or a c program +(fixincl.c). + +This is just the tip of the iceberg. AutoGen is far more powerful than +these examples might indicate, and has many other varied uses. I am +certain Bruce or I could supply you with many and varied examples, and I +would heartily recommend that you try it for your project and see for +yourself how it compares to m4. +@cindex m4 + +As an aside, I would be interested to see whether someone might be +persuaded to rationalise autoconf with AutoGen in place of m4... Ben, +are you listening? autoconf-3.0! `kay? =)O| + +@format +Sincerely, + Gary V. Vaughan +@end format + +@ignore +* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +@end ignore +@page +@node Definitions File +@chapter Definitions File +@cindex definitions file +@cindex .def file + +This chapter describes the syntax and semantics of the AutoGen +definition file. In order to instantiate a template, you normally must +provide a definitions file that identifies itself and contains some +value definitions. Consequently, we keep it very simple. For +"advanced" users, there are preprocessing directives, sparse +arrays, named indexes and comments that may be used as well. + +The definitions file is used to associate values with names. Every +value is implicitly an array of values, even if there is only one value. +Values may be either simple strings or compound collections of +name-value pairs. An array may not contain both simple and compound +members. Fundamentally, it is as simple as: + +@example +prog-name = "autogen"; +flag = @{ + name = templ_dirs; + value = L; + descrip = "Template search directory list"; +@}; +@end example + +For purposes of commenting and controlling the processing of the +definitions, C-style comments and most C preprocessing directives are +honored. The major exception is that the @code{#if} directive is +ignored, along with all following text through the matching +@code{#endif} directive. The C preprocessor is not actually invoked, so +C macro substitution is @strong{not} performed. + +@menu +* Identification:: The Identification Definition +* Definitions:: Named Definitions +* Index Assignments:: Assigning an Index to a Definition +* Dynamic Text:: Dynamic Text +* Directives:: Controlling What Gets Processed +* Predefines:: Pre-defined Names +* Comments:: Commenting Your Definitions +* Example:: What it all looks like. +* Full Syntax:: Finite State Machine Grammar +* Alternate Definition:: Alternate Definition Forms +@end menu + +@c === SECTION MARKER + +@node Identification +@section The Identification Definition +@cindex identification + +The first definition in this file is used to identify it as a +AutoGen file. It consists of the two keywords, +@samp{autogen} and @samp{definitions} followed by the default +template name and a terminating semi-colon (@code{;}). That is: + +@example + AutoGen Definitions @var{template-name}; +@end example + +@noindent +Note that, other than the name @var{template-name}, the words +@samp{AutoGen} and @samp{Definitions} are searched for without case +sensitivity. Most lookups in this program are case insensitive. + +@noindent +Also, if the input contains more identification definitions, +they will be ignored. This is done so that you may include +(@pxref{Directives}) other definition files without an identification +conflict. + +@cindex template file + +@noindent +AutoGen uses the name of the template to find the corresponding template +file. It searches for the file in the following way, stopping when +it finds the file: + +@enumerate +@item +It tries to open @file{./@var{template-name}}. If it fails, +@item +it tries @file{./@var{template-name}.tpl}. +@item +It searches for either of these files in the directories listed in the +templ-dirs command line option. +@end enumerate + +If AutoGen fails to find the template file in one of these places, +it prints an error message and exits. + +@c === SECTION MARKER + +@node Definitions +@section Named Definitions +@cindex definitions + +A name is a sequence of characters beginning with an alphabetic character +(@code{a} through @code{z}) followed by zero or more alpha-numeric +characters and/or separator characters: hyphen (@code{-}), underscore +(@code{_}) or carat (@code{^}). Names are case insensitive. + +Any name may have multiple values associated with it. Every name may be +considered a sparse array of one or more elements. If there is more than +one value, the values my be accessed by indexing the value with +@code{[index]} or by iterating over them using the FOR (@pxref{FOR}) AutoGen +macro on it, as described in the next chapter. Sparse arrays are specified +by specifying an index when defining an entry +(@pxref{Index Assignments,, Assigning an Index to a Definition}). + +There are two kinds of definitions, @samp{simple} and @samp{compound}. +They are defined thus (@pxref{Full Syntax}): + +@example +compound_name '=' '@{' definition-list '@}' ';' + +simple-name[2] '=' string ';' + +no^text^name ';' +@end example + +@noindent +@code{simple-name} has the third index (index number 2) defined here. +@code{No^text^name} is a simple definition with a shorthand empty string +value. The string values for definitions may be specified in any of +several formation rules. + +@menu +* def-list:: Definition List +* double-quote-string:: Double Quote String +* single-quote-string:: Single Quote String +* simple-string:: An Unquoted String +* shell-generated:: Shell Output String +* scheme-generated:: Scheme Result String +* here-string:: A Here String +* concat-string:: Concatenated Strings +@end menu + +@cindex simple definitions +@cindex compound definitions + +@node def-list +@subsection Definition List + +@code{definition-list} is a list of definitions that may or may not +contain nested compound definitions. Any such definitions may +@strong{only} be expanded within a @code{FOR} block iterating over the +containing compound definition. @xref{FOR}. + +Here is, again, the example definitions from the previous chapter, +with three additional name value pairs. Two with an empty value +assigned (@var{first} and @var{last}), and a "global" @var{group_name}. + +@example +autogen definitions list; +group_name = example; +list = @{ list_element = alpha; first; + list_info = "some alpha stuff"; @}; +list = @{ list_info = "more beta stuff"; + list_element = beta; @}; +list = @{ list_element = omega; last; + list_info = "final omega stuff"; @}; +@end example + +@node double-quote-string +@subsection Double Quote String + +@cindex string, double quote +The string follows the C-style escaping, using the backslash to quote +(escape) the following character(s). Certain letters are translated to +various control codes (e.g. @code{\n}, @code{\f}, @code{\t}, etc.). +@code{x} introduces a two character hex code. @code{0} (the digit zero) +introduces a one to three character octal code (note: an octal byte followed +by a digit must be represented with three octal digits, thus: @code{"\0001"} +yielding a NUL byte followed by the ASCII digit 1). Any other character +following the backslash escape is simply inserted, without error, into the +string being formed. + +Like ANSI "C", a series of these strings, possibly intermixed with +single quote strings, will be concatenated together. + +@node single-quote-string +@subsection Single Quote String + +@cindex string, single quote +This is similar to the shell single-quote string. However, escapes +@code{\} are honored before another escape, single quotes @code{'} +and hash characters @code{#}. This latter is done specifically +to disambiguate lines starting with a hash character inside +of a quoted string. In other words, + +@example +fumble = ' +#endif +'; +@end example + +could be misinterpreted by the definitions scanner, whereas +this would not: + +@example +fumble = ' +\#endif +'; +@end example + +@* +As with the double quote string, a series of these, even intermixed +with double quote strings, will be concatenated together. + +@node simple-string +@subsection An Unquoted String + +A simple string that does not contain white space @i{may} be left +unquoted. The string must not contain any of the characters special to +the definition text (i.e., @code{"}, @code{#}, @code{'}, @code{(}, +@code{)}, @code{,}, @code{;}, @code{<}, @code{=}, @code{>}, @code{[}, +@code{]}, @code{`}, @code{@{}, or @code{@}}). This list is subject to +change, but it will never contain underscore (@code{_}), period +(@code{.}), slash (@code{/}), colon (@code{:}), hyphen (@code{-}) or +backslash (@code{\\}). Basically, if the string looks like it is a +normal DOS or UNIX file or variable name, and it is not one of two +keywords (@samp{autogen} or @samp{definitions}) then it is OK to not +quote it, otherwise you should. + +@node shell-generated +@subsection Shell Output String +@cindex shell-generated string + +@cindex string, shell output +This is assembled according to the same rules as the double quote string, +except that there is no concatenation of strings and the resulting string is +written to a shell server process. The definition takes on the value of +the output string. + +NB@: The text is interpreted by a server shell. There may be left over +state from previous server shell processing. This scriptlet may also leave +state for subsequent processing. However, a @code{cd} to the original +directory is always issued before the new command is issued. + +@node scheme-generated +@subsection Scheme Result String + +A scheme result string must begin with an open parenthesis @code{(}. +The scheme expression will be evaluated by Guile and the +value will be the result. The AutoGen expression functions +are @strong{dis}abled at this stage, so do not use them. + +@node here-string +@subsection A Here String +@cindex here-string + +A @samp{here string} is formed in much the same way as a shell here doc. It +is denoted with two less than characters(@code{<<}) and, optionally, a hyphen. +This is followed by optional horizontal white space and an ending +marker-identifier. This marker must follow the syntax rules for identifiers. +Unlike the shell version, however, you must not quote this marker. + +The resulting string will start with the first character on the next line and +continue up to but not including the newline that precedes the line that +begins with the marker token. The characters are copied directly into the +result string. Mostly. + +If a hyphen follows the less than characters, then leading tabs will be +stripped and the terminating marker will be recognized even if preceded by +tabs. Also, if the first character on the line (after removing tabs) is a +backslash and the next character is a tab or space, then the backslash will +be removed as well. No other kind of processing is done on this string. + +Here are three examples: +@example +str1 = <<- STR_END + $quotes = " ' ` + STR_END; + +str2 = << STR_END + $quotes = " ' ` + STR_END; +STR_END; + +str3 = <<- STR_END + \ $quotes = " ' ` + STR_END; +@end example +The first string contains no new line characters. +The first character is the dollar sign, the last the back quote. + +The second string contains one new line character. The first character +is the tab character preceding the dollar sign. The last character is +the semicolon after the @code{STR_END}. That @code{STR_END} does not +end the string because it is not at the beginning of the line. In the +preceding case, the leading tab was stripped. + +The third string is almost identical to the first, except that the +first character is a tab. That is, it exactly matches the first line +of the second string. + +@node concat-string +@subsection Concatenated Strings +@cindex concat-string + +If single or double quote characters are used, +then you also have the option, a la ANSI-C syntax, +of implicitly concatenating a series of them together, +with intervening white space ignored. + +NB@: You @strong{cannot} use directives to alter the string +content. That is, + +@example +str = "fumble" +#ifdef LATER + "stumble" +#endif + ; +@end example + +@noindent +will result in a syntax error. The preprocessing directives are not +carried out by the C preprocessor. However, + +@example +str = '"fumble\n" +#ifdef LATER +" stumble\n" +#endif +'; +@end example + +@noindent +@strong{Will} work. It will enclose the @samp{#ifdef LATER} +and @samp{#endif} in the string. But it may also wreak +havoc with the definition processing directives. The hash +characters in the first column should be disambiguated with +an escape @code{\} or join them with previous lines: +@code{"fumble\n#ifdef LATER...}. + +@c === SECTION MARKER + +@node Index Assignments +@section Assigning an Index to a Definition +@cindex Definition Index + +In AutoGen, every name is implicitly an array of values. +When assigning values, they are usually implicitly +assigned to the next highest slot. They can also be +specified explicitly: + +@example +mumble[9] = stumble; +mumble[0] = grumble; +@end example + +@noindent +If, subsequently, you assign a value to @code{mumble} without an +index, its index will be @code{10}, not @code{1}. +If indexes are specified, they must not cause conflicts. + +@code{#define}-d names may also be used for index values. +This is equivalent to the above: + +@example +#define FIRST 0 +#define LAST 9 +mumble[LAST] = stumble; +mumble[FIRST] = grumble; +@end example + +All values in a range do @strong{not} have to be filled in. +If you leave gaps, then you will have a sparse array. This +is fine (@pxref{FOR}). You have your choice of iterating +over all the defined values, or iterating over a range +of slots. This: + +@example +[+ FOR mumble +][+ ENDFOR +] +@end example + +@noindent +iterates over all and only the defined entries, whereas this: + +@example +[+ FOR mumble (for-by 1) +][+ ENDFOR +] +@end example + +@noindent +will iterate over all 10 "slots". Your template will +likely have to contain something like this: + +@example +[+ IF (exist? (sprintf "mumble[%d]" (for-index))) +] +@end example + +@noindent +or else "mumble" will have to be a compound value that, +say, always contains a "grumble" value: + +@example +[+ IF (exist? "grumble") +] +@end example + +@c === SECTION MARKER + +@node Dynamic Text +@section Dynamic Text +@cindex Dynamic Definition Text + +There are several methods for including dynamic content inside a definitions +file. Three of them are mentioned above (@ref{shell-generated} and +@pxref{scheme-generated}) in the discussion of string formation rules. +Another method uses the @code{#shell} processing directive. +It will be discussed in the next section (@pxref{Directives}). +Guile/Scheme may also be used to yield to create definitions. + +When the Scheme expression is preceded by a backslash and single +quote, then the expression is expected to be an alist of +names and values that will be used to create AutoGen definitions. + +@noindent +This method can be be used as follows: + +@example +\'( (name (value-expression)) + (name2 (another-expr)) ) +@end example + +@noindent +This is entirely equivalent to: + +@example +name = (value-expression); +name2 = (another-expr); +@end example + +@noindent +Under the covers, the expression gets handed off to a Guile function +named @code{alist->autogen-def} in an expression that looks like this: + +@example +(alist->autogen-def + ( (name (value-expression)) (name2 (another-expr)) ) ) +@end example diff --git a/doc/autogen-texi.txt b/doc/autogen-texi.txt new file mode 100644 index 0000000..951b532 --- /dev/null +++ b/doc/autogen-texi.txt @@ -0,0 +1,6114 @@ +@c -*- Mode: texinfo -*- +@setfilename autogen.info +@ignore +This file serves two purposes: + +1) it provides that stupid (at)setfilename so that automake will + deign to produce the documentation + +2) a text repository for documentation that would make the doc + template more confusing. + + + This file is part of AutoGen. + AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + + AutoGen 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. + + AutoGen is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program. If not, see <http://www.gnu.org/licenses/>. +@end ignore + +@ignore +START == COMMENTS == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore + +@ignore +Resume input from autogen.texi +@end ignore + +@c === SECTION MARKER + +@node Predefines +@section Pre-defined Names +@cindex predefines + +When AutoGen starts, it tries to determine several names from the +operating environment and put them into environment variables for use in +both @code{#ifdef} tests in the definitions files and in shell scripts +with environment variable tests. @env{__autogen__} is always defined. +For other names, AutoGen will first try to use the POSIX version of the +@code{sysinfo(2)} system call. Failing that, it will try for the POSIX +@code{uname(2)} call. If neither is available, then only +"@env{__autogen__}" will be inserted into the environment. +In all cases, the associated names are converted to lower case, surrounded +by doubled underscores and non-symbol characters are replaced with +underscores. + +With Solaris on a sparc platform, @code{sysinfo(2)} is available. +The following strings are used: + +@itemize @bullet +@item +@code{SI_SYSNAME} (e.g., "__sunos__") +@item +@code{SI_HOSTNAME} (e.g., "__ellen__") +@item +@code{SI_ARCHITECTURE} (e.g., "__sparc__") +@item +@code{SI_HW_PROVIDER} (e.g., "__sun_microsystems__") +@item +@code{SI_PLATFORM} (e.g., "__sun_ultra_5_10__") +@item +@code{SI_MACHINE} (e.g., "__sun4u__") +@end itemize + +For Linux and other operating systems that only support the +@code{uname(2)} call, AutoGen will use these values: + +@itemize @bullet +@item +@code{sysname} (e.g., "__linux__") +@item +@code{machine} (e.g., "__i586__") +@item +@code{nodename} (e.g., "__bach__") +@end itemize + +By testing these pre-defines in my definitions, you can select +pieces of the definitions without resorting to writing shell +scripts that parse the output of @code{uname(1)}. You can also +segregate real C code from autogen definitions by testing for +"@code{__autogen__}". + +@example +#ifdef __bach__ + location = home; +#else + location = work; +#endif +@end example + +@c === SECTION MARKER + +@node Comments +@section Commenting Your Definitions +@cindex comments + +The definitions file may contain C and C++ style comments. + +@example +/* + * This is a comment. It continues for several lines and closes + * when the characters '*' and '/' appear together. + */ +// this comment is a single line comment +@end example + +@c === SECTION MARKER + +@node Example +@section What it all looks like. + +@noindent +This is an extended example: + +@example +autogen definitions @samp{template-name}; +/* + * This is a comment that describes what these + * definitions are all about. + */ +global = "value for a global text definition."; + +/* + * Include a standard set of definitions + */ +#include standards.def + +a_block = @{ + a_field; + a_subblock = @{ + sub_name = first; + sub_field = "sub value."; + @}; + +#ifdef FEATURE + a_subblock = @{ + sub_name = second; + @}; +#endif + +@}; +@end example + +@ignore +END == COMMENTS == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore + +@ignore +START == TEMPLATE == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore + +@c === SECTION MARKER + +@node Alternate Definition +@section Alternate Definition Forms +@cindex Alternate Definition + +There are several methods for supplying data values for templates. + +@table @samp +@item no definitions +It is entirely possible to write a template that does not depend upon +external definitions. Such a template would likely have an unvarying +output, but be convenient nonetheless because of an external library +of either AutoGen or Scheme functions, or both. This can be accommodated +by providing the @option{--override-tpl} and @option{--no-definitions} +options on the command line. @xref{autogen Invocation}. + +@item CGI +AutoGen behaves as a CGI server if the definitions input is from stdin +and the environment variable @env{REQUEST_METHOD} is defined +and set to either "GET" or "POST", @xref{AutoGen CGI}. Obviously, +all the values are constrained to strings because there is no way +to represent nested values. + +@item XML +AutoGen comes with a program named, @command{xml2ag}. Its output can +either be redirected to a file for later use, or the program can +be used as an AutoGen wrapper. @xref{xml2ag Invocation}. + +The introductory template example (@pxref{Example Usage}) can be rewritten +in XML as follows: + +@example +<EXAMPLE template="list.tpl"> +<LIST list_element="alpha" + list_info="some alpha stuff"/> +<LIST list_info="more beta stuff" + list_element="beta"/> +<LIST list_element="omega" + list_info="final omega stuff"/> +</EXAMPLE> +@end example + +A more XML-normal form might look like this: +@example +<EXAMPLE template="list.tpl"> +<LIST list_element="alpha">some alpha stuff</LIST> +<LIST list_element="beta" >more beta stuff</LIST> +<LIST list_element="omega">final omega stuff</LIST> +</EXAMPLE> +@end example +@noindent +but you would have to change the template @code{list-info} references +into @code{text} references. + +@item standard AutoGen definitions +Of course. :-) + +@end table + +@ignore +* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +@end ignore +@page +@node Template File +@chapter Template File +@cindex template file +@cindex .tpl file + +The AutoGen template file defines the content of the output text. +It is composed of two parts. The first part consists of a pseudo +macro invocation and commentary. It is followed by the template proper. + +@cindex pseudo macro +@cindex macro, pseudo +This pseudo macro is special. It is used to identify the file as a +AutoGen template file, fixing the starting and ending marks for +the macro invocations in the rest of the file, specifying the list +of suffixes to be generated by the template and, optionally, the +shell to use for processing shell commands embedded in the template. + +AutoGen-ing a file consists of copying text from the template to the +output file until a start macro marker is found. The text from the +start marker to the end marker constitutes the macro text. AutoGen +macros may cause sections of the template to be skipped or processed +several times. The process continues until the end of the template is +reached. The process is repeated once for each suffix specified in the +pseudo macro. + +This chapter describes the format of the AutoGen template macros +and the usage of the AutoGen native macros. Users may augment +these by defining their own macros, @xref{DEFINE}. + +@menu +* pseudo macro:: Format of the Pseudo Macro +* naming values:: Naming a value +* expression syntax:: Macro Expression Syntax +* AutoGen Functions:: AutoGen Scheme Functions +* Common Functions:: Common Scheme Functions +* native macros:: AutoGen Native Macros +* output controls:: Redirecting Output +@end menu + +@c === SECTION MARKER + +@node pseudo macro +@section Format of the Pseudo Macro +@cindex pseudo macro + +The pseudo macro is used to tell AutoGen how to process a template. +It tells autogen: + +@enumerate +@item +The start macro marker. It consists of punctuation characters used to +demarcate the start of a macro. It may be up to seven characters long and +must be the first non-whitespace characters in the file. + +@noindent +It is generally a good idea to use some sort of opening +bracket in the starting macro and closing bracket in the ending +macro (e.g. @code{@{}, @code{(}, @code{[}, or even @code{<} +in the starting macro). It helps both visually and with editors +capable of finding a balancing parenthesis. + +@item +That start marker must be immediately followed by the identifier strings +"AutoGen5" and then "template", though capitalization is not important. +@end enumerate + +@noindent +The next several components may be intermingled: + +@enumerate 3 +@item +Zero, one or more suffix specifications tell AutoGen how many times to +process the template file. No suffix specifications mean that it is to +be processed once and that the generated text is to be written to +@file{stdout}. The current suffix for each pass can be determined with the +@code{(suffix)} scheme function (@pxref{SCM suffix}). + +The suffix specification consists of a sequence of POSIX compliant file name +characters and, optionally, an equal sign and a file name formatting +specification. That specification may be either an ordinary sequence of +file name characters with zero, one or two "%s" formatting sequences in it, +or else it may be a Scheme expression that, when evaluated, produces such a +string. The Scheme result may not be empty. The two string arguments +allowed for that string are the base name of the definition file, and the +current suffix (that being the text to the left of the equal sign). (Note: +"POSIX compliant file name characters" consist of alphanumerics plus the +period (@code{.}), hyphen (@code{-}) and underscore (@code{_}) characters.) + +If the suffix begins with one of these three latter characters and +a formatting string is not specified, then that character is presumed to +be the suffix separator. Otherwise, without a specified format string, +a single period will separate the suffix from the base name in constructing +the output file name. + +@item +Shell specification: to specify that the template was written expecting a +particular shell to run the shell commands. By default, the shell used is the +autoconf-ed @env{CONFIG_SHELL}. This will usually be @file{/bin/sh}. The +shell is specified by a hash mark (@code{#}) followed by an exclamation mark +(@code{!}) followed by a full-path file name (e.g. @file{/usr/xpg4/bin/sh} on +Solaris): +@example +[= Autogen5 Template c +#!/usr/xpg4/bin/sh +=] +@end example + +@item +Comments: blank lines, lines starting with a hash mark (@code{#}) and not +specifying a shell, and edit mode markers (text between pairs of @code{-*-} +strings) are all treated as comments. + +@item +Some scheme expressions may be inserted in order to make configuration +changes before template processing begins. +@i{before template processing begins} means that there is no current +output file, no current suffix and, basically, none of the AutoGen +specific functions +(@pxref{AutoGen Functions}) may be invoked. + +The scheme expression can also be used, for example, to save a pre-existing +output file for later text extraction (@pxref{SCM extract}). + +@example +(shellf "mv -f %1$s.c %1$s.sav" (base-name)) +@end example +@end enumerate + +@noindent +After these must come the end macro marker: + +@enumerate 6 +@item +The punctuation characters used to demarcate the end of a macro. +Like the start marker, it must consist of seven or fewer punctuation +characters. +@end enumerate + +The ending macro marker has a few constraints on its content. Some of +them are just advisory, though. There is no special check for advisory +restrictions. + +@itemize @bullet +@item +It must not begin with a POSIX file name character (hyphen @code{-}, +underscore @code{_} or period @code{.}), the backslash (@code{\}) or +open parenthesis (@code{(}). These are used to identify a suffix +specification, indicate Scheme code and trim white space. + +@item +If it begins with an equal sign, then it +must be separated from any suffix specification by white space. + +@item +The closing marker may not begin with an open parenthesis, as that is used +to enclose a scheme expression. + +@item +It cannot begin with a backslash, as that is used to indicate white +space trimming after the end macro mark. If, in the body of the template, +you put the backslash character (@code{\}) before the end macro mark, then +any white space characters after the mark and through the newline character +are trimmed. + +@item +It is also helpful to avoid using the comment marker (@code{#}). +It might be seen as a comment within the pseudo macro. + +@item +You should avoid using any of the quote characters@: double, +single or back-quote. It won't confuse AutoGen, but it might well +confuse you and/or your editor. +@end itemize + +As an example, assume we want to use @code{[+} and @code{+]} as the start +and end macro markers, and we wish to produce a @file{.c} and a @file{.h} +file, then the pseudo macro might look something like this: + +@example +[+ AutoGen5 template -*- Mode: emacs-mode-of-choice -*- +h=chk-%s.h +c +# make sure we don't use csh: +(setenv "SHELL" "/bin/sh") +] +@end example + +The template proper starts after the pseudo-macro. The starting +character is either the first non-whitespace character or the first +character after the newline that follows the end macro marker. + +@c === SECTION MARKER + +@node naming values +@section Naming a value +@cindex naming values + +When an AutoGen value is specified in a template, it is specified by name. +The name may be a simple name, or a compound name of several components. +Since each named value in AutoGen is implicitly an array of one or more +values, each component may have an index associated with it. + +@noindent +It looks like this: + +@example +comp-name-1 . comp-name-2 [ 2 ] +@end example + +Note that if there are multiple components to a name, each component +name is separated by a dot (@code{.}). Indexes follow a component name, +enclosed in square brackets (@code{[} and @code{]}). The index may be +either an integer or an integer-valued define name. The first component +of the name is searched for in the current definition level. If not +found, higher levels will be searched until either a value is found, +or there are no more definition levels. Subsequent components of the +name must be found within the context of the newly-current definition +level. Also, if the named value is prefixed by a dot (@code{.}), +@cindex . +then the value search is started in the current context only. +Backtracking +@cindex backtrack +into other definition levels is prevented. + +If someone rewrites this, I'll incorporate it. :-) + +@c === SECTION MARKER + +@node expression syntax +@section Macro Expression Syntax +@cindex expression syntax + +AutoGen has two types of expressions: full expressions and basic ones. +A full AutoGen expression can appear by itself, or as the argument +to certain AutoGen built-in macros: CASE, IF, ELIF, INCLUDE, +INVOKE (explicit invocation, @pxref{INVOKE}), and WHILE. +If it appears by itself, the result is inserted into the output. +If it is an argument to one of these macros, the macro code +will act on it sensibly. + +You are constrained to basic expressions only when passing +arguments to user defined macros, @xref{DEFINE}. + +The syntax of a full AutoGen expression is: + +@example +[[ <apply-code> ] <value-name> ] [ <basic-expr-1> [ <basic-expr-2> ]] +@end example + +How the expression is evaluated depends upon the presence or absence +of the apply code and value name. The "value name" is the name of +an AutoGen defined value, or not. If it does not name such a value, +the expression result is generally the empty string. All expressions +must contain either a @var{value-name} or a @var{basic-expr}. + +@menu +* apply code:: Apply Code +* basic expression:: Basic Expression +@end menu + +@node apply code +@subsection Apply Code + +The "apply code" selected determines the method of evaluating the +expression. There are five apply codes, including the non-use +of an apply code. + +@table @samp +@item no apply code +This is the most common expression type. +Expressions of this sort come in three flavors: + +@table @samp +@item <value-name> +The result is the value of @var{value-name}, if defined. +Otherwise it is the empty string. + +@item <basic-expr> +The result of the basic expression is the result of the full expression, +@xref{basic expression}. + +@item <value-name> <basic-expr> +If there is a defined value for @var{value-name}, then the @var{basic-expr} +is evaluated. Otherwise, the result is the empty string. +@end table + +@item % <value-name> <basic-expr> +If @var{value-name} is defined, use @var{basic-expr} as a format +string for sprintf. Then, if the @var{basic-expr} is either a back-quoted +string or a parenthesized expression, then hand the result to the +appropriate interpreter for further evaluation. Otherwise, for single +and double quote strings, the result is the result of the sprintf operation. +Naturally, if @var{value-name} is not defined, the result is the empty +string. + +For example, assume that @samp{fumble} had the string value, @samp{stumble}: +@example +[+ % fumble `printf '%%x\\n' $%s` +] +@end example +This would cause the shell to evaluate "@samp{printf '%x\n' $stumble}". +Assuming that the shell variable @samp{stumble} had a numeric value, +the expression result would be that number, in hex. Note the need +for doubled percent characters and backslashes. + +@item ? <value-name> <basic-expr-1> <basic-expr-2> +Two @var{basic-expr}-s are required. If the @var{value-name} is +defined, then the first @var{basic-expr-1} is evaluated, otherwise +@var{basic-expr-2} is. + +@item - <value-name> <basic-expr> +Evaluate @var{basic-expr} only if @var{value-name} is @i{not} defined. + +@item ?% <value-name> <basic-expr-1> <basic-expr-2> +This combines the functions of @samp{?} and @samp{%}. If @var{value-name} is +defined, it behaves exactly like @samp{%}, above, using @var{basic-expr-1}. +If not defined, then @var{basic-expr-2} is evaluated. + +For example, assume again that @samp{fumble} had the string value, +@samp{stumble}: +@example +[+ ?% fumble `cat $%s` `pwd` +] +@end example +This would cause the shell to evaluate "@samp{cat $stumble}". +If @samp{fumble} were not defined, then the result would be the name +of our current directory. +@end table + +@node basic expression +@subsection Basic Expression + +A basic expression can have one of the following forms: + +@table @samp +@item 'STRING' +A single quoted string. Backslashes can be used to protect single +quotes (@code{'}), hash characters (@code{#}), or backslashes (@code{\}) +in the string. All other characters of STRING are output as-is when the +single quoted string is evaluated. Backslashes are processed before the hash +character for consistency with the definition syntax. It is needed there +to avoid preprocessing conflicts. + +@item "STRING" +A double quoted string. This is a cooked text string as in C, +except that they are not concatenated with adjacent strings. +Evaluating "@samp{STRING}" will output STRING with all +backslash sequences interpreted. + +@item `STRING` +A back quoted string. When this expression is evaluated, STRING +is first interpreted as a cooked string (as in `"STRING"') and +evaluated as a shell expression by the AutoGen server shell. This +expression is replaced by the @file{stdout} output of +the shell. + +@item (STRING) +A parenthesized expression. It will be passed to the Guile +interpreter for evaluation and replaced by the resulting value. +If there is a Scheme error in this expression, Guile 1.4 and Guile 1.6 +will report the template line number where the error occurs. Guile 1.7 +has lost this capability. + +Guile has the capability of creating and manipulating variables that +can be referenced later on in the template processing. If you define +such a variable, it is invisible to AutoGen. To reference its value, +you must use a Guile expression. For example, +@example +[+ (define my-var "some-string-value") +] +@end example +can have that string inserted later, but only as in: +@example +[+ (. my-var) +] +@end example + +Additionally, other than in the @code{%} and @code{?%} expressions, the +Guile expressions may be introduced with the Guile comment character +(@code{;}) and you may put a series of Guile expressions within a single +macro. They will be implicitly evaluated as if they were arguments +to the @code{(begin ...)} expression. The result will be the +result of the last Guile expression evaluated. +@end table + +@ignore +END == TEMPLATE == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore + +@ignore +START == MACROS == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore + +@c === SECTION MARKER + +@node native macros +@section AutoGen Native Macros +@cindex native macros + +This section describes the various AutoGen natively defined macros. +Unlike the Scheme functions, some of these macros are "block macros" +with a scope that extends through a terminating macro. Block macros +must not overlap. That is to say, a block macro started within the +scope of an encompassing block macro must have its matching end macro +appear before the encompassing block macro is either ended or subdivided. + +The block macros are these: + +@table @code +@item CASE +This macro has scope through the @code{ESAC} macro. +The scope is subdivided by @code{SELECT} macros. +You must have at least one @code{SELECT} macro. + +@item DEFINE +This macro has scope through the @code{ENDDEF} macro. The defined +user macro can never be a block macro. This macro is extracted from +the template @i{before} the template is processed. Consequently, you +cannot select a definition based on context. You can, however, place +them all at the end of the file. + +@item FOR +This macro has scope through the @code{ENDFOR} macro. + +@item IF +This macro has scope through the @code{ENDIF} macro. +The scope may be subdivided by @code{ELIF} and @code{ELSE} +macros. Obviously, there may be only one @code{ELSE} macro +and it must be the last of these subdivisions. + +@item INCLUDE +This macro has the scope of the included file. +It is a block macro in the sense that the included +file must not contain any incomplete block macros. + +@item WHILE +This macro has scope through the @code{ENDWHILE} macro. +@end table +@ignore +END == MACROS == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore + +@ignore +START == AUGMENTING == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore + +@c === SECTION MARKER + +@node output controls +@section Redirecting Output +@cindex Redirecting Output +@cindex diversion + +AutoGen provides a means for redirecting the template output to different +files or, in @file{M4} parlance, to various diversions. It is accomplished +by providing a set of Scheme functions named @code{out-*} +(@pxref{AutoGen Functions}). + +@table @samp +@item out-push-new (@pxref{SCM out-push-new}) +This allows you to logically "push" output files onto a stack. +If you supply a string name, then a file by that name is created +to hold the output. If you do not supply a name, then the text is +written to a scratch pad and retrieved by passing a @code{#t} argument +to the @code{out-pop} (@pxref{SCM out-pop}) function. + +@item out-pop (@pxref{SCM out-pop}) +This function closes the current output file and resumes output to the next +one in the stack. At least one output must have been pushed onto the output +stack with the @code{out-push-new} (@pxref{SCM out-push-new}) function. If +@code{#t} is passed in as an argument, then the entire contents of the +diversion (or file) is returned. + +@item out-suspend (@pxref{SCM out-suspend}) +This function does not close the current output, but instead sets it aside +for resumption by the given name with @code{out-resume}. The current output +must have been pushed on the output queue with @code{out-push-new} +(@pxref{SCM out-push-new}). + +@item out-resume (@pxref{SCM out-resume}) +This will put a named file descriptor back onto the top of +stack so that it becomes the current output again. + +@item out-switch (@pxref{SCM out-switch}) +This closes the current output and creates a new file, +purging any preexisting one. This is a shortcut for "pop" +followed by "push", but this can also be done at the base level. + +@item out-move (@pxref{SCM out-move}) +Renames the current output file without closing it. +@end table + +There are also several functions for determining the output +status. @xref{AutoGen Functions}. + +@ignore + +* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +@end ignore + +@page +@node Augmenting AutoGen +@chapter Augmenting AutoGen Features +@cindex Augmenting AutoGen + +AutoGen was designed to be simple to enhance. You can do it by +providing shell commands, Guile/Scheme macros or callout functions +that can be invoked as a Guile macro. Here is how you do these. + +@menu +* shell commands:: Shell Output Commands +* guile macros:: Guile Macros +* guile callouts:: Guile Callout Functions +* AutoGen macros:: AutoGen Macros +@end menu + +@c === SECTION MARKER + +@node shell commands +@section Shell Output Commands + +Shell commands are run inside of a server process. This means that, +unlike @file{make}, context is kept from one command to the next. +Consequently, you can define a shell function in one place inside of +your template and invoke it in another. You may also store values +in shell variables for later reference. If you load functions from +a file containing shell functions, they will remain until AutoGen exits. + +If your shell script should determine that AutoGen should stop +processing, the recommended method for stopping AutoGen is: +@example +die "some error text" +@end example + +@noindent +That is a shell function added by AutoGen. It will send a SIGTERM +to autogen and exit from the "persistent" shell. + +@c === SECTION MARKER + +@node guile macros +@section Guile Macros + +Guile also maintains context from one command to the next. This means you may +define functions and variables in one place and reference them elsewhere. +If your Scheme script should determine that AutoGen should stop +processing, the recommended method for stopping AutoGen is: +@example +(error "some error text") +@end example + +@c === SECTION MARKER + +@node guile callouts +@section Guile Callout Functions + +Callout functions must be registered with Guile to work. This can +be accomplished either by putting your routines into a shared library +that contains a @code{void scm_init(void)} routine that registers +these routines, or by building them into AutoGen. + +To build them into AutoGen, you must place your routines in the source +directory and name the files @file{exp*.c}. You also must have a stylized +comment that @file{getdefs} can find that conforms to the following: + +@example +/*=gfunc <function-name> + * + * what: <short one-liner> + * general_use: + * string: <invocation-name-string> + * exparg: <name>, <description> [, ['optional'] [, 'list']] + * doc: A long description telling people how to use + * this function. +=*/ +SCM +ag_scm_<function-name>( SCM arg_name[, ...] ) +@{ <code> @} +@end example + +@table @samp +@item gfunc +You must have this exactly thus. + +@item <function-name> +This must follow C syntax for variable names + +@item <short one-liner> +This should be about a half a line long. +It is used as a subsection title in this document. + +@item general_use: +You must supply this unless you are an AutoGen maintainer and are writing +a function that queries or modifies the state of AutoGen. + +@item <invocation-name-string> +Normally, the @var{function-name} string will be transformed into +a reasonable invocation name. However, that is not always true. +If the result does not suit your needs, then supply an alternate string. + +@item exparg: +You must supply one for each argument to your function. +All optional arguments must be last. +The last of the optional arguments may be a list, if you choose. + +@item doc: +Please say something meaningful. + +@item [, ...] +Do not actually specify an ANSI ellipsis here. You must provide +for all the arguments you specified with @var{exparg}. +@end table + +See the Guile documentation for more details. +More information is also available in a large comment at the +beginning of the @file{agen5/snarf.tpl} template file. + +@c === SECTION MARKER + +@node AutoGen macros +@section AutoGen Macros + +There are two kinds@: those you define yourself and AutoGen native. +The user-defined macros may be defined in your templates, +@xref{DEFINE}. + +As for AutoGen native macros, do not add any. It is easy to do, but I +won't like it. The basic functions needed to accomplish looping over +and selecting blocks of text have proved to be sufficient over a period +of several years. New text transformations can be easily added via any +of the AutoGen extension methods, as discussed above. + +@ignore +END == AUGMENTING == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore + +@ignore +START == INSTALLATION == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore + +@page +@node Installation +@chapter Configuring and Installing + +@menu +* configuring:: Configuring AutoGen +* AutoGen CGI:: AutoGen as a CGI server +* signal names:: Signal Names +* installing:: Installing AutoGen +@end menu + +@c === SECTION MARKER + +@node configuring +@section Configuring AutoGen +@cindex configuring + +AutoGen is configured and built using Libtool, Automake and Autoconf. +Consequently, you can install it wherever you wish using the @samp{--prefix} +and other options. To the various configuration options supplied by these +tools, AutoGen adds a few of its own: + +@table @samp +@item --disable-shell +AutoGen is now capable of acting as a CGI forms server, @xref{AutoGen CGI}. +As such, it will gather its definitions using either @samp{GET} or +@samp{POST} methods. All you need to do is have a template named +@file{cgi.tpl} handy or specify a different one with a command line +option. + +However, doing this without disabling the server shell brings +considerable risk. If you were to pass user input to a script +that contained, say, the classic "@samp{`rm -rf /`}", you might have +a problem. This configuration option will cause shell template +commands to simply return the command string as the result. +No mistakes. Much safer. Strongly recommended. +The default is to have server shell scripting enabled. + +Disabling the shell will have some build side effects, too. + +@itemize @bullet +@item +Many of the make check tests will fail, since they assume +a working server shell. +@item +The getdefs and columns programs are not built. +The options are distributed as definition files and they +cannot be expanded with a shell-disabled AutoGen. +@item +Similarly, the documentation cannot be regenerated because +the documentation templates depend on subshell functionality. +@end itemize + +@item --enable-debug +Turning on AutoGen debugging enables very detailed inspection of +the input definitions and monitoring shell script processing. +These options are not particularly useful to anyone not directly +involved in maintaining AutoGen. If you do choose to enable AutoGen +debugging, be aware that the usage page was generated without these +options, so when the build process reaches the documentation rebuild, +there will be a failure. @samp{cd} into the @file{agen5} build +directory, @samp{make} the @samp{autogen.texi} file and all will +be well thereafter. + +@item --with-regex-header +@itemx --with-header-path +@itemx --with-regex-lib +These three work together to specify how to compile with and link to a +particular POSIX regular expression library. The value for +@file{--with-regex-header=value} must be the name of the relevant header file. +The AutoGen sources will attempt to include that source with a +@code{#include <value>} C preprocessing statement. The @var{path} from the +@option{--with-header-path=path} will be added to @code{CPPFLAGS} as +@option{-Ipath}. The @var{lib-specs} from @option{--with-regex-lib=lib-specs} +will be added to @code{LDFLAGS} without any adornment. +@end table + +@c === SECTION MARKER + +@page +@node AutoGen CGI +@section AutoGen as a CGI server + +AutoGen is now capable of acting as a CGI forms server. +It behaves as a CGI server if the definitions input is from stdin +and the environment variable @env{REQUEST_METHOD} is defined +and set to either "GET" or "POST". If set to anything else, +AutoGen will exit with a failure message. When set to one of those +values, the CGI data will be converted to AutoGen definitions +(@pxref{Definitions File}) and the template named "@file{cgi.tpl}" +will be processed. + +This works by including the name of the real template to process +in the form data and having the "@file{cgi.tpl}" template include +that template for processing. I do this for processing the form +@url{http://autogen.sourceforge.net/conftest.html}. The "@file{cgi.tpl}" +looks approximately like this: + +@example +<? AutoGen5 Template ?> +<? +IF (not (exist? "template")) ?><? + form-error ?><? + +ELIF (=* (get "template") "/") ?><? + form-error ?><? + +ELIF (define tpl-file (string-append "cgi-tpl/" + (get "template"))) + (access? tpl-file R_OK) ?><? + INCLUDE (. tpl-file) ?><? + +ELIF (set! tpl-file (string-append tpl-file ".tpl")) + (access? tpl-file R_OK) ?><? + INCLUDE (. tpl-file) ?><? + +ELSE ?><? + form-error ?><? +ENDIF ?> +@end example + +@noindent +This forces the template to be found in the "@file{cgi-tpl/}" +directory. Note also that there is no suffix specified in the +pseudo macro (@pxref{pseudo macro}). That tells AutoGen to emit +the output to @file{stdout}. + +The output is actually spooled until it is complete so that, +in the case of an error, the output can be discarded and a proper +error message can be written in its stead. + +@strong{Please also note} that it is advisable, @emph{especially} for network +accessible machines, to configure AutoGen (@pxref{configuring}) with +shell processing disabled (@option{--disable-shell}). That will make it +impossible for any referenced template to hand data to a subshell for +interpretation. + +@c === SECTION MARKER + +@node signal names +@section Signal Names +@cindex Signal Names + +When AutoGen is first built, it tries to use @code{psignal(3)}, +@code{sys_siglist}, @code{strsigno(3)} and @code{strsignal(3)} from the +host operating system. If your system does not supply these, the +AutoGen distribution will. However, it will use the distributed mapping +and this mapping is unlikely to match what your system uses. This can +be fixed. Once you have installed autogen, the mapping can be rebuilt +on the host operating system. To do so, you must perform the +following steps: + +@enumerate +@item +Build and install AutoGen in a place where it will be found in your +search path. +@item +@file{cd $@{top_srcdir@}/compat} +@item +@samp{autogen strsignal.def} +@item +Verify the results by examining the @file{strsignal.h} file produced. +@item +Re-build and re-install AutoGen. +@end enumerate + +If you have any problems or peculiarities that cause this process to +fail on your platform, please send me copies of the header files +containing the signal names and numbers, along with the full path names +of these files. I will endeavor to fix it. There is a shell script +inside of @file{strsignal.def} that tries to hunt down the information. + +@c === SECTION MARKER + +@node installing +@section Installing AutoGen +@cindex Installing + +There are several files that get installed. The number depend +whether or not both shared and archive libraries are to be +installed. The following assumes that everything is installed +relative to @env{$prefix}. You can, of course, use +@command{configure} to place these files where you wish. + +@strong{NB}@: AutoGen does not contain any compiled-in path names. +All support directories are located via option processing, +the environment variable @env{HOME} or finding the directory where +the executable came from. + +The installed files are: + +@enumerate +@item +The executables in @file{bin} (autogen, getdefs and columns). + +@item +The AutoOpts link libraries as @file{lib/libopts.*}. + +@item +An include file in @file{include/options.h}, needed for +Automated Option Processing (see next chapter). + +@item +Several template files and a scheme script in @file{share/autogen}, needed +for Automated Option Processing (@pxref{AutoOpts}), parsing definitions +written with scheme syntax (@pxref{Dynamic Text}), the templates for +producing documentation for your program (@pxref{documentation attributes}), +autoconf test macros, and AutoFSM. + +@item +Info-style help files as @file{info/autogen.info*}. +These files document AutoGen, the option processing +library AutoOpts, and several add-on components. + +@item +The three man pages for the three executables are installed in man/man1. +@end enumerate + +This program, library and supporting files can be installed +with three commands: + +@itemize @bullet +@item +<src-dir>/configure [ <configure-options> ] +@item +make +@item +make install +@end itemize + +However, you may wish to insert @samp{make check} +before the @samp{make install} command. + +If you do perform a @samp{make check} and there are any failures, you +will find the results in @file{<module>/test/FAILURES}. Needless to say, I +would be interested in seeing the contents of those files and any +associated messages. If you choose to go on and analyze one of these +failures, you will need to invoke the test scripts individually. You +may do so by specifying the test (or list of test) in the TESTS make +variable, thus: + +@example +gmake TESTS=test-name.test check +@end example + +I specify @command{gmake} because most makes will not let you override +internal definitions with command line arguments. @command{gmake} does. + +All of the AutoGen tests are written to honor the contents of the +@t{VERBOSE} environment variable. Normally, any commentary generated +during a test run is discarded unless the @t{VERBOSE} environment +variable is set. So, to see what is happening during the test, you +might invoke the following with @i{bash} or @i{ksh}: + +@example +VERBOSE=1 gmake TESTS="for.test forcomma.test" check +@end example + +@noindent +Or equivalently with @i{csh}: + +@example +env VERBOSE=1 gmake TESTS="for.test forcomma.test" check +@end example + +@ignore +END == INSTALLATION == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore + +@ignore +START == AUTOFSM == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore + +@c === SECTION MARKER + +@node AutoFSM +@section Automated Finite State Machine +@cindex AutoFSM +@cindex finite state machine + +The templates to generate a finite state machine in C or C++ is included +with AutoGen. The documentation is not. The documentation is in HTML +format for @uref{http://www.gnu.org/software/autogen/autofsm.html,viewing}, +or you can @uref{http://download.sourceforge.net/autogen/,download FSM}. + +@node AutoXDR +@section Combined RPC Marshalling +@cindex RPC +@cindex rpcgen +@cindex remote procedure call +@cindex AutoXDR +@cindex XDR + +The templates and NFSv4 definitions are not included with AutoGen in any way. +The folks that designed NFSv4 noticed that much time and bandwidth was +wasted sending queries and responses when many of them could be bundled. +The protocol bundles the data, but there is no support for it in rpcgen. +That means you have to write your own code to do that. Until now. +Download this and you will have a large, complex example of how to use +@code{AutoXDR} for generating the marshaling and unmarshaling of combined +RPC calls. There is a brief example +@uref{http://www.gnu.org/software/autogen/xdr/index.html,on the web}, but +you should @uref{http://download.sourceforge.net/autogen/,download AutoXDR}. + +@c === SECTION MARKER + +@node AutoEvents +@section Automated Event Management +@cindex AutoEvents + +Large software development projects invariably have a need to manage +the distribution and display of state information and state changes. +In other words, they need to manage their software events. Generally, +each such project invents its own way of accomplishing this and then +struggles to get all of its components to play the same way. It is a +difficult process and not always completely successful. This project +helps with that. + +AutoEvents completely separates the tasks of supplying the data +needed for a particular event from the methods used to manage the +distribution and display of that event. Consequently, the programmer +writing the code no longer has to worry about that part of the +problem. Likewise the persons responsible for designing the event +management and distribution no longer have to worry about getting +programmers to write conforming code. + +This is a work in progress. See my +@uref{http://www.gnu.org/software/autogen/autoevents.html,web page} +on the subject, if you are interested. +I have some useful things put together, but it is not ready +to call a product. + +@ignore +END == AUTOFSM == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore + +@c = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +@c +@c AUTOOPTS SECTIONS +@c +@c +@ignore +START == AUTOOPTS == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore + +All the features notwithstanding, some applications simply have +well-established command line interfaces. Even still, those programs +may use the configuration file parsing portion of the library. +See the ``AutoOpts Features'' and ``Configuration File Format'' sections. + +@menu +* Features:: AutoOpts Features +* Licensing:: AutoOpts Licensing +* Caveats:: Developer and User Notes +* Quick Start:: Quick Start +* Option Definitions:: Option Definitions +* AutoOpts API:: Programmatic Interface +* Multi-Threading:: Multi-Threading +* option descriptor:: Option Descriptor File +* Using AutoOpts:: Using AutoOpts +* Presetting Options:: Configuring your program +* Config File Format:: Configuration File Format +* shell options:: AutoOpts for Shell Scripts +* AutoInfo:: Automated Info Docs +* AutoMan pages:: Automated Man Pages +* getopt_long:: Using getopt(3C) +* i18n:: Internationalizing AutoOpts +* Naming Conflicts:: Naming Conflicts +* All Attribute Names:: All Attribute Names +* Option Define Names:: Option Definition Name Index +@end menu + +@c === SECTION MARKER + +@node Features +@section AutoOpts Features +@cindex features + +AutoOpts supports option processing; option state saving; and +program documentation with innumerable features. Here, we list +a few obvious ones and some important ones, but the full list is +really defined by all the attributes defined in the @ref{Option Definitions} +section. + +@enumerate +@item +POSIX-compliant short (flag) option processing. + +@item +GNU-style long options processing. Long options +are recognized without case sensitivity, and they may be abbreviated. + +@item +Environment variable initializations, @xref{environrc}. + +@item +Initialization from configuration files (aka RC or INI files), and +saving the option state back into one, @xref{loading rcfile}. + +@item +Config files may be partitioned. One config file may be used by several +programs by partitioning it with lines containing, +@code{[PROGRAM_NAME]} or @code{<?program-name>}, @xref{loading rcfile}. + +@item +Config files may contain AutoOpts directives. +@code{<?auto-options [[option-text]]>} +may be used to set @code{AutoOpts} option processing options. +Viz., @acronym{GNU} usage layout versus @code{AutoOpts} conventional layout, +and @code{misuse-usage} versus @code{no-misuse-usage}, @xref{usage attributes}. + +@item +Options may be marked as @code{@i{dis}-abled} with a disablement prefix. +Such options may default to either an enabled or a disabled state. You +may also provide an enablement prefix, too, e.g., @option{--allow-mumble} +and @option{--prevent-mumble} (@pxref{Common Attributes}). + +@item +Verify that required options are present between the minimum and maximum +number of times on the command line. Verify that conflicting options do not +appear together. Verify that options requiring the presence of other options +are, in fact, used in the presence of other options. +See @xref{Common Attributes}, and @xref{Option Conflict Attributes}. + +@item +There are several @ref{automatic options, automatically supported options}. +They will have short flags if any options have option flags and the flags +are not suppressed. The associated flag may be altered or suppressed by +specifying no value or an alternate character for @code{xxx-value;} in +the option definition file. @code{xxx} is the name of the option below: + +@table @samp +@item --help +@itemx --more-help +These are always available. @samp{--more-help} will pass the full usage +text through a pager. +@item --usage +@vindex usage-opt +This is added to the option list if @code{usage-opt} is specified. +It yields the abbreviated usage to @file{stdout}. +@item --version +This is added to the option list if @code{version = xxx;} is specified. +@item --load-opts +@itemx --save-opts +These are added to the option list if @code{homerc} is specified. Mostly. +If, @code{disable-save} is specified, then @option{--save-opts} is disabled. +@end table + +@item +Various forms of main procedures can be added to the output, +@xref{Generated main}. There are four basic forms: + +@enumerate a +@item +A program that processes the arguments and writes to standard out +portable shell commands containing the digested options. + +@item +A program that will generate portable shell commands to parse the defined +options. The expectation is that this result will be copied into a +shell script and used there. + +@item +A @code{for-each} main that will invoke a named function once for either +each non-option argument on the command line or, if there are none, +then once for each non-blank, non-comment input line read from stdin. + +@item +A main procedure of your own design. Its code can be supplied in the +option description template or by incorporating another template. +@end enumerate + +@item +There are several methods for handling option arguments. +@itemize @bullet +@item +nothing (@pxref{OPT_ARG}) option argument strings are globally available. +@item +user supplied (@pxref{Option Argument Handling}) +@item +stack option arguments (@pxref{Option Argument Handling}) +@item +integer numbers (@pxref{arg-type number}) +@item +true or false valued (@pxref{arg-type boolean}) +@item +enumerated list of names (@pxref{arg-type keyword}) +@item +an enumeration (membership) set (@pxref{arg-type set membership}) +@item +a list of name/value pairs (option @code{subopts}) +(@pxref{arg-type hierarchy}) +@item +a time duration or a specific time and date +@item +validated file name (@pxref{arg-type file name}) +@item +optional option argument (@pxref{arg-optional}) +@end itemize + +@item +The generated usage text can be emitted in either AutoOpts standard format +(maximizing the information about each option), or GNU-ish normal form. The +default form is selected by either specifying or not specifying the +@code{gnu-usage} attribute (@pxref{information attributes}). This can be +overridden by the user himself with the @env{AUTOOPTS_USAGE} environment +variable. If it exists and is set to the string @samp{gnu}, it will force +GNU-ish style format; if it is set to the string @samp{autoopts}, it will +force AutoOpts standard format; otherwise, it will have no effect. + +@item +The usage text and many other strings are stored in a single character array +(@pxref{SCM string-table-new,string table functions}). This reduces fixup +costs when loading the program or library. The downside is that if GCC +detects that any of these strings are used in a printf format, you may get the +warning, @code{embedded '\0' in format}. To eliminate the warning, you must +provide GCC with the @option{-Wno-format-contains-nul} option. + +@item +If you compile with @code{ENABLE_NLS} defined and @code{_()} defined to a +localization function (e.g. @code{gettext(3GNU)}), then the option processing +code will be localizable (@pxref{i18n}). Provided also that you do not define +the @code{no-xlate} attribute to @emph{anything} +(@pxref{presentation attributes}). + +You should also ensure that the @code{ATTRIBUTE_FORMAT_ARG()} gets +@code{#define}-ed to something useful. There is an autoconf macro +named @code{AG_COMPILE_FORMAT_ARG} in @file{ag_macros.m4} that will +set it appropriately for you. If you do not do this, then translated +formatting strings may trigger GCC compiler warnings. + +@item +Provides a callable routine to parse +a text string as if it were from one of the rc/ini/config files, +hereafter referred to as a configuration file. + +@item +By adding a @samp{doc} and @samp{arg-name} attributes to each option, +AutoGen will also be able to produce a man page and the @samp{invoking} +section of a texinfo document. + +@item +Intermingled option processing. AutoOpts options may be intermingled with +command line operands and options processed with other parsing techniques. +This is accomplished by setting the @code{allow-errors} +(@pxref{program attributes}) attribute. When processing reaches a point +where @code{optionProcess} (@pxref{libopts-optionProcess}) needs to be called +again, the current option can be set with @code{RESTART_OPT(n)} +(@pxref{RESTART_OPT}) before calling @code{optionProcess}. + +See: @xref{library attributes}. + +@item +Library suppliers can specify command line options that their +client programs will accept. They specify option definitions +that get @code{#include}-d into the client option definitions +and they specify an "anchor" option that has a callback and must be invoked. +That will give the library access to the option state for their options. + +@item +library options. An AutoOpt-ed library may export its options for use in +an AutoOpt-ed program. This is done by providing an option definition file +that client programs @code{#include} into their own option definitions. +See ``AutoOpt-ed Library for AutoOpt-ed Program'' (@pxref{lib and program}) +for more details. +@end enumerate + +@c === SECTION MARKER + +@node Licensing +@section AutoOpts Licensing +@cindex Licensing + +When AutoGen is installed, the AutoOpts project is installed with it. +AutoOpts includes various AutoGen templates and a pair of shared +libraries. These libraries may be used under the terms of version 3 +of the GNU Lesser General Public License (LGPL). + +One of these libraries (@code{libopts}) is needed by programs that are built +using AutoOpts generated code. This library is available as a separate +``tear-off'' source tarball. It is redistributable for use under either of +two licenses: The above mentioned GNU Lesser General Public License, and +the advertising-clause-free BSD license. Both of these license terms are +incorporated into appropriate COPYING files included with the @code{libopts} +source tarball. This source may be incorporated into your package with +the following simple commands: + +@example +rm -rf libopts libopts-* +gunzip -c `autoopts-config libsrc` | \ + tar -xvf - +mv libopts-*.*.* libopts +@end example + +View the @file{libopts/README} file for further integration information. + +@c === SECTION MARKER + +@page +@node Caveats +@section Developer and User Notes + +The formatting of the usage message can be controlled with the use of the +@env{AUTOOPTS_USAGE} environment variable. If it contains any of five +possible comma separated values, it will affect @file{libopts} behavior. +Any extraneous or conflicting data will cause its value to be ignored. + +If the program attributes @code{long-usage} and @code{short-usage} have been +specified (@pxref{usage attributes,Usage and Version Info Display}), these +strings are used for displaying full usage and abbreviated usage. +``Full usage'' is used when usage is requested, ``abbreviated usage'' +when a usage error is detected. If these strings are not provided, +the usage text is computed. + +The @env{AUTOOPTS_USAGE} environment variable may be set to the comma and/or +white space separated list of the following strings: + +@table @samp +@item compute +Ignore the provision of @code{long-usage} and @code{short-usage} attributes, +and compute the usage strings. This is useful, for example, if you wish to +regenerate the basic form of these strings and either tweak them or translate +them. The methods used to compute the usage text are not suitable for +translation. + +@item gnu +@cindex gnu +The format of the usage text will be displayed in GNU-normal form. +The default display for @option{--version} will be to include a note +on licensing terms. + +@item autoopts +@cindex autoopts +The format of the extended usage will be in AutoOpts' native layout. The +default version display will be one line of text with the last token the +version. @code{gnu} and @code{autoopts} conflict and may not be used +together. + +@item no-misuse-usage +@cindex no-misuse-usage +When an option error is made on the command line, the abbreviated usage text +will be suppressed. An error message and the method for getting full usage +information will be displayed. + +@item misuse-usage +@cindex misuse-usage +When an option error is made on the command line, the abbreviated usage text +will be shown. @code{misuse-usage} and @code{no-misuse-usage} conflict and +may not be used together. +@end table + +@code{misuse-usage} and @code{autoopts} are the defaults. +These defaults may be flipped to @code{no-misuse-usage} and @code{gnu} +by specifying @code{gnu-usage} and @code{no-misuse-usage} +program attributes, respectively, in the option definition file. + +@noindent +@i{Note for developers}: + +The templates used to implement AutoOpts depend heavily upon token pasting. +That mens that if you name an option, @code{debug}, for example, the generated +header will expect to be able to emit @code{#define} macros such as this: +@example +#define DESC(n) (autogenOptions.pOptDesc[INDEX_OPT_## n]) +@end example +and expect @code{DESC(DEBUG)} to expand correctly into +@code{(autogenOptions.pOptDesc[INDEX_OPT_DEBUG])}. +If @code{DEBUG} is @code{#defined} to something else, then +that something else will be in the above expansion. + +If you discover you are having strange problems like this, +you may wish to use some variation of the @code{guard-option-names} +@xref{program attributes}. + +@c === SECTION MARKER + +@page +@node Quick Start +@section Quick Start +@cindex example, simple AutoOpts + +Since it is generally easier to start with a simple example than it is +to look at the options that AutoGen uses itself, here is a very simple +AutoOpts example. You can copy this example out of the Info file and +into a source file to try it. You can then embellish it into what you +really need. For more extensive examples, you can also examine the help +output and option definitions for the commands @command{columns}, +@command{getdefs} and @command{autogen} itself. + +If you are looking for a more extensive example, +you may search the autogen sources for files named @file{*opts.def}. +@command{xml2ag} is ridiculous and @command{autogen} is very lengthy, +but @command{columns} and @command{getdefs} are not too difficult. +The @command{sharutils} sources are fairly reasonable, too. + +@menu +* quick ao problem:: Example option requirements +* quick ao def:: Example option definitions +* quick ao build:: Build the example options +* quick ao help:: Example option help text +* quick ao usage:: Using the example options +* quick ao docs:: Example option documentation +@end menu + +@node quick ao problem +@subsection Example option requirements + +For our simple example, assume you have a program named @command{check} +that takes two options: + +@enumerate +@item +A list of directories to check over for whatever it is @command{check} does. +You want this option available as a POSIX-style flag option +and a GNU long option. You want to allow as many of these +as the user wishes. +@item +An option to show or not show the definition tree being used. +Only one occurrence is to be allowed, specifying one or the other. +@end enumerate + +@node quick ao def +@subsection Example option definitions + +@noindent +First, specify your program attributes and its options to AutoOpts, +as with the following example. + +@example +@ignore +END == AUTOOPTS == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore + +@ignore +START == AUTOOPTS-MAIN == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore + +@node quick ao usage +@subsection Using the example options + +Normally, however, you would not use the @code{main} clause. Instead, +the file would be named something like @file{checkopt.def}, you would +compile @file{checkopt.c} the usual way, and link the object with the rest +of your program. + +The options are processed by calling @code{optionProcess} +(@pxref{libopts-optionProcess}): + +@example +main( int argc, char** argv ) +@{ + @{ + int optct = optionProcess( &checkOptions, argc, argv ); + argc -= optct; + argv += optct; + @} +@end example + +The options are tested and used as in the following fragment. +@code{ENABLED_OPT} is used instead of @code{HAVE_OPT} for the +@option{--show-defs} option because it is an enabled/disabled option type: + +@example + if ( ENABLED_OPT( SHOW_DEFS ) + && HAVE_OPT( CHECK_DIRS )) @{ + int dirct = STACKCT_OPT( CHECK_DIRS ); + char** dirs = STACKLST_OPT( CHECK_DIRS ); + while (dirct-- > 0) @{ + char* dir = *dirs++; + ... +@end example + +@node quick ao docs +@subsection Example option documentation + +The @code{doc} clauses are used in the flag stanzas for man pages and texinfo +invoking documentation. With the definition file described above, the two +following commands will produce the two documentation files @file{check.1} and +@file{invoke-check.texi}. The latter file will be generated as a chapter, +rather than a section or subsection. + +@example +autogen -Tagman-cmd check.def +autogen -DLEVEL=chapter -Tagtexi-cmd -binvoke-check.texi check.def +@end example + +@noindent +The result of which is left as an exercise for the reader. + +A lot of magic happens to make this happen. +The rest of this chapter will describe the myriad of option attributes +supported by AutoOpts. However, keep in mind that, in general, you won't +need much more than what was described in this "quick start" section. + +@node Option Definitions +@section Option Definitions +@cindex Option Definitions + +AutoOpts uses an AutoGen definitions file for the definitions of the +program options and overall configuration attributes. +The complete list of program and option attributes is quite extensive, +so if you are reading to understand how to use AutoOpts, I recommend +reading the "Quick Start" section (@pxref{Quick Start}) and paying +attention to the following: + +@enumerate +@item +@code{prog-name}, @code{prog-title}, and @code{argument}, program +attributes, @xref{program attributes}. +@item +@code{name} and @code{descrip} option attributes, @xref{Required Attributes}. +@item +@code{value} (flag character) and @code{min} (occurrence counts) +option attributes, @xref{Common Attributes}. +@item +@code{arg-type} from the option argument specification section, +@xref{Option Arguments}. +@item +Read the overall how to, @xref{Using AutoOpts}. +@item +Highly recommended, but not required, are the several "man" and +"info" documentation attributes, @xref{documentation attributes}. +@end enumerate + +Keep in mind that the majority are rarely used and can be safely +ignored. However, when you have special option processing requirements, +the flexibility is there. + +@menu +* program attributes:: Program Description Attributes +* library attributes:: Options for Library Code +* information attributes:: Program Information Attributes +* Generated main:: Generating main procedures +* option attributes:: Option Attributes +* Option Arguments:: Option Argument Specification +* Option Argument Handling:: Option Argument Handling +* Internationalizing Options:: Internationalizing Options +* documentation attributes:: Man and Info doc Attributes +* automatic options:: Automatically Supported Options +* standard options:: Library of Standard Options +@end menu + +@node program attributes +@subsection Program Description Attributes +@cindex program attributes + +The following global definitions are used to define attributes of the entire +program. These generally alter the configuration or global behavior of the +AutoOpts option parser. The first two are required of every program. The +third is required if there are to be any left over arguments (operands) +after option processing. The rest have been grouped below. Except as noted, +there may be only one copy of each of these definitions: + +@table @samp + +@item prog-name +@vindex prog-name +This attribute is required. Variable names derived from this name +are derived using @code{string->c_name!} (@pxref{SCM string->c-name!}). + +@item prog-title +@vindex prog-title +This attribute is required and may be any descriptive text. + +@item argument +@vindex argument +This attribute is required if your program uses operand arguments. +It specifies the syntax of the arguments that @strong{follow} the options. +It may not be empty, but if it is not supplied, then option processing +must consume all the arguments. If it is supplied and starts with an +open bracket (@code{[}), then there is no requirement on the presence or +absence of command line arguments following the options. Lastly, if it +is supplied and does not start with an open bracket, then option +processing must @strong{not} consume all of the command line arguments. + +@item config-header +@vindex config-header +If your build has a configuration header, it must be included before +anything else. Specifying the configuration header file name with this +attribute will cause that to happen. +@end table + +@menu +* usage attributes:: Usage and Version Info Display +* config attributes:: Program Configuration +* programming attributes:: Programming Details +* presentation attributes:: User Presentation Attributes +@end menu + +@c +@c = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +@c +@node usage attributes +@subsubsection Usage and Version Info Display + +These will affect the way usage is seen and whether or not version +information gets displayed. + +@table @samp +@item full-usage +@vindex full-usage +If this attribute is provided, it may specify the full length +usage text, or a variable name assignable to a @code{char const *} pointer, +or it may be empty. The meanings are determined by the length. +@itemize @bullet +@item +If not provided, the text will be computed as normal. +@item +If the length is zero, then the usage text will be derived from +the current settings and inserted as text into the generated .c file. +@item +If the length is 1 to 32 bytes, then it is presumed to be a variable +name that either points to or is an array of const chars. +@item +If it is longer than that, it is presumed to be the help text itself. +This text will be inserted into the generated .c file. +@end itemize + +This string should be readily translatable. Provision will be made +to translate it if this is provided, if the source code is compiled with +@code{ENABLE_NLS} defined, and @code{no-xlate} has not been set to the +value @emph{anything}. The untranslated text will be handed to +@code{dgettext("libopts", @i{txt})} and then @code{gettext(@i{txt})} +for translation, one paragraph at a time. + +To facilitate the creation and maintenance of this text, you can +force the string to be ignored and recomputed by specifying +@example +AUTOOPTS_USAGE=compute +@end example +@noindent +in the environment and requesting help or usage information. +See @xref{Caveats, Developer and User Notes}. + +@item short-usage +@vindex short-usage +If this attribute is provided, it is used to specify an abbreviated +version of the usage text. This text is constructed in the same way +as the @code{full-usage}, described above. + +@item gnu-usage +@vindex gnu-usage +AutoOpts normaly displays usage text in a format that provides more +information than the standard GNU layout, but that also means it is +not the standard GNU layout. This attribute changes the default to +GNU layout, with the @env{AUTOOPTS_USAGE} environment variable used +to request @code{autoopts} layout. +See @xref{Caveats, Developer and User Notes}. + +@item usage-opt +@vindex usage-opt +I apologize for too many confusing usages of usage. +This attribute specifies that @option{--usage} and/or @option{-u} be +supported. The help (usage) text displayed will be abbreviated +when compared to the default help text. + +@item no-misuse-usage +@vindex no-misuse-usage +When there is a command line syntax error, by default AutoOpts will +display the abbreviated usage text, rather than just a one line +``you goofed it, ask for usage'' message. You can change the default +behavior for your program by supplying this attribute. The user may +override this choice, again, with the @env{AUTOOPTS_USAGE} environment +variable. See @xref{Caveats, Developer and User Notes}. + +@item prog-group +@vindex prog-group +The version text in the @file{getopt.tpl} template will include this +text in parentheses after the program name, when this attribute is specified. +For example: +@example +mumble (stumble) 1.0 +@end example +@noindent +says that the @samp{mumble} program is version 1.0 and is part of the +@samp{stumble} group of programs. + +@item usage +@vindex usage +If your program has some cleanup work that must be done before exiting +on usage mode issues, or if you have to customize the usage message in +some way, specify this procedure and it will be called instead of the +default @code{optionUsage()} function. For example, if a program is +using the curses library and needs to invoke the usage display, then +you must arrange to call @code{endwin()} before invoking the library +function @code{optionUsage()}. This can be handled by specifying your +own usage function, thus: +@example +void +my_usage(tOptions * opts, int ex) +@{ + if (curses_window_active) + endwin(); + optionUsage(opts, ex); +@} +@end example + +@item version +@vindex version +Specifies the program version and activates the VERSION option, +@xref{automatic options}. +@end table + +@c +@c = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +@c +@node config attributes +@subsubsection Program Configuration + +Programs may be ``pre-configured'' before normal command line options +are processed (See @pxref{Immediate Action, Immediate Action Attributes}). +How configuration files and environment variables are handled get +specified with these attributes. + +@table @samp +@item disable-load +@itemx disable-save +@vindex disable-load +@vindex disable-save +Indicates that the command line usage of @option{--load-opts} and/or +@option{--save-opts} are disallowed. + +@item environrc +@vindex environrc +Indicates looking in the environment for values of variables named, +@env{PROGRAM_OPTNAME} or @env{PROGRAM}, where @env{PROGRAM} is the +upper cased @var{C-name} of the program and @samp{OPTNAME} is the +upper cased @var{C-name} of a specific option. The contents of +the @env{PROGRAM} variable, if found, are tokenized and processed. +The contents of @env{PROGRAM_OPTNAME} environment variables are taken +as the option argument to the option nameed @option{--optname}. + +@item homerc +@vindex homerc +Specifies that option settings may be loaded from and stored into +configuration files. Each instance of this attribute is either a directory +or a file using a specific path, a path based on an environment variable or +a path relative to installation directories. The method used depends on +the name. If the one entry is empty, it enables the loading and storing of +settings, but no specific files are searched for. Otherwise, a series of +configuration files are hunted down and, if found, loaded. + +If the first character of the @samp{homerc} value is not the dollar +character (@code{$}), then it is presumed to be a path name based on the +current directory. Otherwise, the method depends on the second character: + +@table @code +@item $ +The path is relative to the directory where the executable was found. +@item @@ +The path is relative to the package data directory, e.g. +@file{/usr/local/share/autogen}. +@item [a-zA-Z] +The path is derived from the named environment variable. +@end table + +Use as many as you like. The presence of this attribute +activates the @option{--save-opts} and @option{--load-opts} options. +However, saving into a file may be disabled with the @samp{disable-save}. +@xref{loading rcfile}. +See the @code{optionMakePath(3AGEN)} man page for excruciating details. + +@item rcfile +@vindex rcfile +Specifies the configuration file name. This is only useful if you +have provided at least one @code{homerc} attribute. +@example +default: .<prog-name>rc +@end example + +@item vendor-opt +@vindex vendor-opt +This option implements the @option{-W} vendor option command line option. + +For POSIX specified utilities, the options are constrained to the options +that are specified by POSIX. Extensions should be handled with @option{-W} +command line options, the short flag form. Long option name processing +must be disabled. In fact, the @code{long-opts} attribute must not be +provided, and some options must be specified without flag values. + +The @option{-W long-name} is processed by looking up the long option +name that follows it. It cannot be a short flag because that would +conflict with the POSIX flag name space. It will be processed as if +long options were accepted and @option{--long-name} were found on the +command line. +@end table + +@c +@c = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +@c +@node programming attributes +@subsubsection Programming Details + +These attributes affect some of the ways that the option data are +used and made available to the program. + +@table @samp +@item config-header +@vindex config-header +The contents of this attribute should be just the name of the configuration +file. A "#include" naming this file will be inserted at the top of the +generated header. + +@item exit-name +@itemx exit-desc +@vindex exit-name +@vindex exit-desc +These values should be defined as indexed values, thus: +@example +exit-name[0] = success; +exit-desc[0] = 'Successful program execution.'; +exit-name[1] = failure; +exit-desc[1] = 'The operation failed or command syntax was not valid.'; +@end example +By default, all programs have these effectively defined for them. +They may be overridden by explicitly defining any or all of these values. +Additional names and descriptions may be defined. +They will cause an enumeration to be emitted, like this one +for @command{getdefs}: +@example +typedef enum @{ + GETDEFS_EXIT_SUCCESS = 0, + GETDEFS_EXIT_FAILURE = 1 +@} getdefs_exit_code_t; +@end example +@noindent +which will be augmented by any @code{exit-name} definitions beyond @samp{1}. + +Some of the generated code will exit non-zero if there is an allocation error. +This exit will always be code @samp{1}, unless there is an exit named @samp{no_mem} +or @samp{nomem}. In that case, that value will be used. Additionally, if +there is such a value, and if @code{die-code} is specified, then a function +@code{nomem_err(size_t len, char const * what)} will be emitted as an inline +function for reporting out-of-memory conditions. + +@item usage-message +@vindex usage-message +This attribute will cause two procedures to be added to the code file: +@code{usage_message()} and @code{vusage_message()}, with any applicable prefix +(see @code{prefix}, below). They are declared in the +generated header, thus: +@example +noreturn extern void vusage_message(char const * fmt, va_list ap); +noreturn extern void usage_message(char const * fmt, ...); +@end example +@noindent +These functions print the message to @file{stderr} and invoke the usage +function with the exit code set to @code{1} (@code{EXIT_FAILURE}). + +@item die-code +@vindex die-code +This tells AutoOpts templates to emit code for @code{vdie()}, @code{die()}, +@code{fserr()}, and, possibly the @code{nomem_err()} functions. The latter is +emitted if an exit name of @samp{no-mem} or @samp{nomem} is specified. If the +@code{die-code} is assigned a text value, then that code will be inserted in +the @code{vdie} function immediately before it prints the death rattle +message. + +The profiles for these functions are: +@example +noreturn extern void vdie( int exit_code, char const * fmt, va_list); +noreturn extern void die( int exit_code, char const * fmt, ...); +noreturn extern void fserr(int exit_code, char const * op, char const * fname); +noreturn static inline void +nomem_err(size_t sz, char const * what) @{...@} +@end example + +@item export +@vindex export +This string is inserted into the .h interface file. Generally used for +global variables or @code{#include} directives required by +@code{flag-code} text and shared with other program text. +Do not specify your configuration header (@file{config.h}) in this +attribute or the @code{include} attribute. Instead, use +@code{config-header}, above. + +@item guard-option-names +@vindex guard-option-names +AutoOpts generates macros that presume that there are no @command{cpp} macros +with the same name as the option name. For example, if you have an option +named, @option{--debug}, then you must not use @code{#ifdef DEBUG} in your +code. If you specify this attribute, every option name will be guarded. If +the name is @code{#define}-d, then a warning will be issued and the name +undefined. If you do not specify this and there is a conflict, you will get +strange error messages. + +This attribute may be set to any of four recognized states: + +@itemize @bullet +@item +Not defined. AutoOpts will behave as described above. + +@item +Defined, but set to the empty string. Text will be emitted into the header +to undefine (@code{#undef}) any conflicting preprocessor macros. The code +will include compiler warnings (via @code{#warning}). Some compilers are +not ANSI-C-99 compliant yet and will error out on those warnings. You may +compile with @option{-DNO_OPTION_NAME_WARNINGS} to silence or mostly silence +them. + +@item +Defined and set to the string, @code{no-warning}. All of the needed +@code{#undef}s will be emitted, without any conflict checking @code{#warning} +directives emitted. + +@item +Defined and set to the string, @code{full-enum}. The option manipulation +preprocessor macros will not token paste the option names to the index +enumeration prefix. e.g. you will need to use @code{HAVE_OPT(INDEX_OPT_DEBUG)} +instead of @code{HAVE_OPT(DEBUG)}. +@end itemize + +@item include +@vindex include +This string is inserted into the .c file. Generally used for global +variables required only by @code{flag-code} program text. + +@item no-libopts +@vindex no-libopts +If you are going to handle your option processing with the @file{getopt.tpl} +template instead of using libopts, then specify this attribute. It will +suppress mention of @option{--more-help} in the generated documentation. +(@code{getopt_long} does not support @option{--more-help}.) + +@item prefix +@vindex prefix +This value is inserted into @strong{all} global names. This will +disambiguate them if more than one set of options are to be compiled +into a single program. +@end table + +@c +@c = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +@c +@node presentation attributes +@subsubsection User Presentation Attributes + +Attributes that affect the user's experience. + +@table @samp +@item allow-errors +@vindex allow-errors +The presence of this attribute indicates ignoring any command line +option errors. This may also be turned on and off by invoking the +macros @code{ERRSKIP_OPTERR} and @code{ERRSTOP_OPTERR} from the +generated interface file. + +@item long-opts +@vindex long-opts +@cindex named option mode +Presence indicates GNU-standard long option processing. Partial name +matches are accepted, if they are at least two characters long and the +partial match is unique. The matching is not case sensitive, and the +underscore, hyphen and carat characters are all equivalent (they match). + +If any options do not have an option value (flag character) specified, +and least one does specify such a value, then you must specify +@code{long-opts}. If none of your options specify an option value +(flag character) and you do not specify @code{long-opts}, then command +line arguments are processed in "named option mode". This means that: + +@itemize @bullet +@item +Every command line argument must be a long option. +@item +The flag markers @option{-} and @option{--} are completely optional. +@item +The @code{argument} program attribute is disallowed. +@item +One of the options may be specified as the default +(as long as it has a required option argument). +@end itemize + +@item no-xlate +@vindex no-xlate +Modifies when or whether option names get translated. If provided, +it must be assigned one of these values: +@table @samp +@item opt-cfg +to suppress option name translation for configuration file and and environment +variable processing. +@item opt +to suppress option name translation completely. The usage text will +always be translated if @code{ENABLE_NLS} is defined and you have +translations for that text. +@item anything +Specifies disabling all internationalization support for option code, completely. +@end table +See also the various @code{XLAT} interface entries in the +AutoOpts Programmatic Interface section (@pxref{AutoOpts API}). + +@item reorder-args +@vindex reorder-args +Normally, POSIX compliant commands do not allow for options to be interleaved +with operands. If this is necessary for historical reasons, there are two +approaches available: +@itemize @bullet +@item +Allow @code{optionProcess} to return the index of the operand like it normally +does and process the operand(s). When an operand is encountered that starts +with a hyphen, then set the AutoOpts current index with the @code{RESTART_OPT} +macro (see @pxref{RESTART_OPT}), and re-invoke @code{optionProcess}. This +will also allow you to process the operands in context. + +@item +Specify this attribute. AutoOpts will re-order the command arguments +so that the operands appear (in the original order) at the end of +the argument list. Differing configuration state is not possible +to detect after all options have been processed. +@end itemize + +@item resettable +@vindex resettable +Specifies that the @option{--reset-option} command line option is to be +supported. This makes it possible to suppress any setting that might be +found in a configuration file or environment variable. +@end table + +@node library attributes +@subsection Options for Library Code +@cindex library attributes + +Some libraries provide their own code for processing command line +options, and this may be used by programs that utilize AutoOpts. +You may also wish to write a library that gets configured with AutoOpts +options and config files. Such a library may either supply its own +configury routine and process its own options, or it may export its +option descriptions to programs that also use AutoOpts. This section +will describe how to do all of these different things. + +@menu +* lib and program:: AutoOpt-ed Library for AutoOpt-ed Program +* lib called:: AutoOpt-ed Library for Regular Program +* prog calls lib:: AutoOpt-ed Program Calls Regular Library +@end menu + +@node lib and program +@subsubsection AutoOpt-ed Library for AutoOpt-ed Program + +The library source code must provide an option definition file that consists +of only the attribute @code{library} +@vindex library +and @code{flag} entries. The @code{library} attribute does not need any +associated value, so it will generally appeary by itself on a line folowed +by a semi-colon. The first @code{flag} entry must contain the following +attributes: + +@table @samp +@item name +This name is used in the construction of a global pointer of type +@code{tOptDesc const*}. It is always required. +@item documentation +@vindex documentation +It tells @code{AutoOpts} that this option serves no normal purpose. +It will be used to add usage clarity and to locate option descriptors +in the library code. +@item descrip +This is a string that is inserted in the extended usage display +before the options specific to the current library. It is always required. +@item lib-name +@vindex lib-name +This should match the name of the library. This string is also used in +the construction of the option descriptor pointer name. In the end, it +looks like this: +@example +extern tOptDesc const* <<lib-name>>_<<name>>_optDesc_p; +@end example +@noindent +and is used in the macros generated for the library's @file{.h} file. +@end table + +In order to compile this @code{AutoOpts} using library, you must create a +special header that is not used by the client program. This is accomplished +by creating an option definition file that contains essentially exactly the +following: + +@example +AutoGen definitions options; +prog-name = does-not-matter; // but is always required +prog-title = 'also does not matter'; // also required +config-header = 'config.h'; // optional, but common +library; +#include library-options-only.def +@end example + +@noindent +and nothing else. AutoGen will produce only the @file{.h} file. +You may now compile your library, referencing just this @file{.h} file. +The macros it creates will utilize a global variable that will be defined +by the @code{AutoOpts}-using client program. That program will need to +have the following @code{#include} in @i{its} option definition file: + +@example +#include library-options-only.def +@end example + +@noindent +All the right things will magically happen so that the global variables +named @var{<<lib-name>>_<<name>>_optDesc_p} are initialized correctly. +For an example, please see the @code{AutoOpts} test script: +@file{autoopts/test/library.test}. + +@node lib called +@subsubsection AutoOpt-ed Library for Regular Program + +In this case, your library must provide an option processing function +to a calling program. This is accomplished by setting the @code{allow-errors} +global option attribute. Each time your option handling function is called, +you must determine where your scan is to resume and tell the AutoOpts library +by invoking: + +@example +RESTART_OPT(next_arg_index); +@end example + +@noindent +and then invoke @code{not_opt_index = optionProcess(...)}. +The @code{not_opt_index} value can be used to set @code{optind}, +if that is the global being used to scan the program argument array. + +In this method, do @strong{NOT} utilize the global @code{library} attribute. +Your library must specify its options as if it were a complete program. +You may choose to specify an alternate @code{usage()} function so that +usage for other parts of the option interface may be displayed as well. +See ``Program Information Attributes'' (@pxref{information attributes}). + +At the moment, there is no method for calling @code{optionUsage()} telling +it to produce just the information about the options and not the program +as a whole. Some later revision after somebody asks. + +@node prog calls lib +@subsubsection AutoOpt-ed Program Calls Regular Library + +As with providing an @code{AutoOpt}-ed library to a non-@code{AutoOpt}-ed +program, you must write the option description file as if you were writing +all the options for the program, but you should specify the +@code{allow-errors} global option attribute and you will likely want an +alternate @code{usage()} function (see ``Program Information Attributes'' +@pxref{information attributes}). In this case, though, when +@code{optionProcess()} returns, you need to test to see if there might be +library options. If there might be, then call the library's exported +routine for handling command line options, set the next-option-to-process +with the @code{RESTART_OPT()} macro, and recall @code{optionProcess()}. +Repeat until done. + +@node information attributes +@subsection Program Information Attributes +@cindex information attributes + +These attributes are used to define how and what information is displayed +to the user of the program. + +@table @samp +@item copyright +@vindex copyright +The @code{copyright} is a structured value containing three to five +values. If @code{copyright} is used, then the first three are required. + +@enumerate +@item +@vindex date +@file{date} - the list of applicable dates for the copyright. +@item +@vindex owner +@file{owner} - the name of the copyright holder. +@item +@vindex type +@file{type} - specifies the type of distribution license. +AutoOpts/AutoGen supports the text of the GNU Public License (@file{gpl}), +the GNU Lesser General Public License with Library extensions +(@file{lgpl}), the Modified Free BSD license (@file{mbsd}) and a few others. +Other licenses may be specified, but you must provide your own license file. +The list of license files provided by AutoOpts may be seen by typing: +@example +ls $(autoopts-config pkgdatadir)/*.lic +@end example +@item +@vindex text +@file{text} - the text of the copyright notice. This must be provided +if @file{type} is set to @file{NOTE}. +@item +@vindex author +@file{author} - in case the author name is to appear in the documentation +and is different from the copyright owner. +@item +@vindex eaddr +@file{eaddr} - email address for receiving praises and complaints. +Typically that of the author or copyright holder. +@end enumerate +@* +An example of this might be: +@example +copyright = @{ + date = "1992-2015"; + owner = "Bruce Korb"; + eaddr = 'bkorb@@gnu.org'; + type = GPL; +@}; +@end example + +@item detail +@vindex detail +This string is added to the usage output when the HELP option is +selected. + +@item explain +@vindex explain +Gives additional information whenever the usage routine is invoked. + +@item package +@vindex package +The name of the package the program belongs to. This will appear +parenthetically after the program name in the version and usage output, +e.g.: @code{autogen @i{(GNU autogen)} - The Automated Program Generator}. + +@item preserve-case +@vindex preserve-case +This attribute will not change anything except appearance. Normally, the +option names are all documented in lower case. However, if you specify this +attribute, then they will display in the case used in their specification. +Command line options will still be matched without case sensitivity. +This is useful for specifying option names in camel-case. + +@item prog-desc @strong{and} +@itemx opts-ptr +@vindex prog-desc +@vindex opts-ptr +These define global pointer variables that point to the program +descriptor and the first option descriptor for a library option. This +is intended for use by certain libraries that need command line and/or +initialization file option processing. These definitions have no effect +on the option template output, but are used for creating a library +interface file. Normally, the first "option" for a library will be a +documentation option that cannot be specified on the command line, but +is marked as @code{settable}. The library client program will invoke the +@code{SET_OPTION} macro which will invoke a handler function that will +finally set these global variables. + +@item usage +@vindex usage +Optionally names the usage procedure, if the library routine +@code{optionUsage()} does not work for you. If you specify +@code{my_usage} as the value of this attribute, for example, you will +use a procedure by that name for displaying usage. Of course, you will +need to provide that procedure and it must conform to this profile: +@example +void @i{my_usage}( tOptions* pOptions, int exitCode ) +@end example + +@item gnu-usage +@vindex gnu-usage +Normally, the default format produced by the @code{optionUsage} procedure +is @i{AutoOpts Standard}. By specifying this attribute, the default format +will be @i{GNU-ish style}. Either default may be overridden by the user with +the @env{AUTOOPTS_USAGE} environment variable. If it is set to @code{gnu} +or @code{autoopts}, it will alter the style appropriately. This attribute +will conflict with the @code{usage} attribute. + +@item reorder-args +@vindex reorder-args +Some applications traditionally require that the command operands be +intermixed with the command options. In order to handle that, the arguments +must be reordered. If you are writing such an application, specify this +global option. All of the options (and any associated option arguments) +will be brought to the beginning of the argument list. New applications +should not use this feature, if at all possible. This feature is +@i{disabled} if @env{POSIXLY_CORRECT} is defined in the environment. +@end table + +@node Generated main +@subsection Generating main procedures +@cindex main procedure + +When AutoOpts generates the code to parse the command line options, it has +the ability to produce any of several types of @code{main()} procedures. +This is done by specifying a global structured value for +@vindex main +@code{main}. The values that it contains are dependent on the value set for +the one value it must have: @code{main-type}. + +@vindex main-type +The recognized values for @code{main-type} are @code{guile}, +@code{shell-process}, @code{shell-parser}, @code{main}, @code{include}, +@code{invoke}, and @code{for-each}. + +@menu +* main guile:: guile: main and inner_main procedures +* main shell-process:: shell-process: emit Bourne shell results +* main shell-parser:: shell-parser: emit Bourne shell script +* main main:: main: user supplied main procedure +* main include:: include: code emitted from included template +* main invoke:: invoke: code emitted from AutoGen macro + +The @code{for-each} main procedure has a number of attributes that +must be specified: + +* main for-each:: for-each: perform function on each operand +* main-for-each-proc:: procedure to handle each argument +* main-for-each-type:: handler procedure type +* main-for-each-code:: code for handler procedure +* main-for-each-opts:: for-each main procedure options +@end menu + +@node main guile +@subsubsection guile: main and inner_main procedures + +When the @code{main-type} is specified to be @code{guile}, +a @code{main()} procedure is generated that calls @code{gh_enter()}, providing +it with a generated @code{inner_main()} to invoke. If you must perform +certain tasks before calling @code{gh_enter()}, you may specify such code +in the value for the +@vindex before-guile-boot +@code{before-guile-boot} attribute. + +The @code{inner_main()} procedure itself will process the command line +arguments (by calling @code{optionProcess()}, +@pxref{libopts-optionProcess}), and then either invoke the code +specified with the +@vindex guile-main +@code{guile-main} attribute, or else export the parsed options to Guile +symbols and invoke the @code{scm_shell()} function from the Guile library. +This latter will render the program nearly identical to the stock +@code{guile(1)} program. + +@node main shell-process +@subsubsection shell-process: emit Bourne shell results + +This will produce a @code{main()} procedure that parses the command line +options and emits to @file{stdout} Bourne shell commands that puts the +option state into environment variables. This can be used within a +shell script as follows: + +@example +unset OPTION_CT +eval "`opt_parser \"$@@\"`" +test $@{OPTION_CT@} -gt 0 && shift $@{OPTION_CT@} +@end example + +If the option parsing code detects an error or a request for usage or version, +it will emit a command to exit with an appropriate exit code to @file{stdout}. +This form of @code{main} will cause all messages, including requested usage +and version information, to be emitted to @file{stderr}. Otherwise, a numeric +value for @code{OPTION_CT} is guaranteed to be emitted, along with assignments +for all the options parsed, something along the lines of the following will be +written to @file{stdout} for evaluation: + +@example +OPTION_CT=4 +export OPTION_CT +MYPROG_SECOND='first' +export MYPROG_SECOND +MYPROG_ANOTHER=1 # 0x1 +export MYPROG_ANOTHER +@end example + +@noindent +If the arguments are to be reordered, however, then the resulting set +of operands will be emitted and @env{OPTION_CT} will be set to zero. +For example, the following would be appended to the above: + +@example +set -- 'operand1' 'operand2' 'operand3' +OPTION_CT=0 +@end example + +@noindent +@env{OPTION_CT} is set to zero since it is not necessary to shift +off any options. + +@node main shell-parser +@subsubsection shell-parser: emit Bourne shell script + +This will produce a @code{main()} procedure that emits a shell script +that will parse the command line options. That script can be emitted +to @file{stdout} or inserted or substituted into a pre-existing shell +script file. Improbable markers are used to identify previously inserted +parsing text: + +@example +# # # # # # # # # # -- do not modify this marker -- +@end example + +@noindent +The program is also pretty insistent upon starting its parsing script +on the second line. + +@node main main +@subsubsection main: user supplied main procedure + +You must supply a value for the @code{main-text} attribute. +You may also supply a value for +@vindex option-code +@code{option-code}. If you do, then the @code{optionProcess} invocation +will not be emitted into the code. AutoOpts will wrap the @code{main-text} +inside of: + +@example +int +main( int argc, char** argv ) +@{ + int res = <<success-exit-code>>; + @{ // replaced by option-code, if that exists + int ct = optionProcess( &<<prog-name>>Options, argc, argv); + argc -= ct; + argv += ct; + @} +<<main-text>> + return res; +@} +@end example + +@noindent +so you can most conveniently set the value with a @code{here string} +(@pxref{here-string}): + +@example +code = <<- _EndOfMainProc_ + <<your text goes here>> + _EndOfMainProc_; +@end example + +@node main include +@subsubsection include: code emitted from included template + +You must write a template to produce your main procedure. +You specify the name of the template with the @code{tpl} attribute +and it will be incorporated at the point where AutoOpts is ready +to emit the @code{main()} procedure. + +This can be very useful if, in your working environment, you have +many programs with highly similar @code{main()} procedures. All you need +to do is parameterize the variations and specify which variant is needed +within the @code{main} AutoOpts specification. Since you are coding +the template for this, the attributes needed for this variation would +be dictated by your template. + +Here is an example of an @code{include} variation: + +@example +main = @{ + main-type = include; + tpl = "main-template.tpl"; +@}; +@end example + +@node main invoke +@subsubsection invoke: code emitted from AutoGen macro + +You must write a template to produce your main procedure. That template +must contain a definition for the function specified with the @code{func} +attribute to this @code{main()} procedure specification. This +variation operates in much the same way as @code{include} +(@pxref{main include}) method. + +@node main for-each +@subsubsection for-each: perform function on each operand + +This produces a main procedure that invokes a procedure once for each operand +on the command line (non-option arguments), @strong{OR} once for each +non-blank, non-comment @code{stdin} input line. Leading and trailing white +space is trimmed from the input line and comment lines are lines that are +empty or begin with a comment character, defaulting to a hash ('#') character. + +@strong{NB}: +The @code{argument} program attribute (@pxref{program attributes}) +must begin with the @code{[} character, to indicate that there are +command operands, but that they are optional. + +@noindent +For an example of the produced main procedure, in the @file{autoopts/test} +build directory, type the following command and look at @file{main.c}: +@example +make verbose TESTS=main.test +@end example + +@node main-for-each-proc +@unnumberedsubsubsec procedure to handle each argument + +@vindex handler-proc +The @code{handler-proc} attribute is required. It is used to name the +procedure to call. That procedure is presumed to be external, but if +you provide the code for it, then the procedure is emitted as a static +procedure in the generated code. + +This procedure should return 0 on success, a cumulative error code on warning +and exit without returning on an unrecoverable error. As the cumulative +warning codes are @i{or}-ed together, the codes should be some sort of bit +mask in order to be ultimately decipherable (if you need to do that). + +If the called procedure needs to cause a fail-exit, it is expected to call +@code{exit(3)} directly. If you want to cause a warning exit code, then this +handler function should return a non-zero status. That value will be +@strong{OR}-ed into a result integer for computing the final exit code. E.g., +here is part of the emitted code: + +@example + int res = 0; + if (argc > 0) @{ + do @{ + res |= @var{my_handler}( *(argv++) ); + @} while (--argc > 0); + @} else @{ ... +@end example + +@node main-for-each-type +@unnumberedsubsubsec handler procedure type + +@vindex handler-type +If you do not supply the @code{handler-type} attribute, your handler +procedure must be the default type. The profile of the procedure must be: + +@example +int @var{my_handler}(char const * pz_entry); +@end example + +@noindent +However, if you do supply this attribute, you may set the value to any of +four alternate flavors: + +@table @samp +@item name-of-file +This is essentially the same as the default handler type, except that before +your procedure is invoked, the generated code has verified that the string +names an existing file. The profile is unchanged. + +@item file-X +Before calling your procedure, the file is f-opened according to the @code{X}, +where @code{X} may be any of the legal modes for @code{fopen(3C)}. In this +case, the profile for your procedure must be: + +@example +int @var{my_handler}(char const * pz_fname, FILE * entry_fp); +@end example + +@noindent +When processing inputs as file pointer stream files, there are several +ways of treating standard input. It may be an ordinary input file, +or it may contain a list of files to operate on. + +If the file handler type is more specifically set to @samp{file-r} and +a command line operand consists of a single hyphen, then @var{my_handler} +will be called with @code{entry_fp} set to @code{stdin} and the @code{pz_fname} +set to the translatable string, "standard input". Consequently, +in this case, if the input list is being read from @code{stdin}, a line +containing a hyphen by itself will be ignored. + +@item stdin-input +This attribute specifies that standard input is a data input file. +By default, @code{for-each} main procedures will read standard input for +operands if no operands appear on the command line. If there are operands +after the command line options, then standard input is typically ignored. +It can always be processed as an input data file, however, if a single bare +hyphen is put on the command line. + +@item text-of-file +@itemx some-text-of-file +Before calling your procedure, the contents of the file are read or mapped +into memory. (Excessively large files may cause problems.) The +@samp{some-text-of-file} disallows empty files. Both require regular files. +In this case, the profile for your procedure must be: + +@example +program_exit_code_t +@var{my_handler}(char const * fname, char * file_text, + size_t text_size); +@end example + +@noindent +Note that though the @code{file_text} is not @code{const}, any changes made to +it are not written back to the original file. It is merely a memory image of +the file contents. Also, the memory allocated to hold the text is +@code{text_size + 1} bytes long and the final byte is always @code{NUL}. The +file contents need not be text, as the data are read with the @code{read(2)} +system call. + +@code{file_text} is automatically freed, unless you specify a +@vindex handler-frees +@code{handler-frees} attribute. Then your code must @code{free(3)} the text. +@end table + +If you select one of these file type handlers, then on access or usage errors +the @code{PROGRAM_EXIT_FAILURE} exit code will, by default, be or-ed +into the final exit code. This can be changed by specifying the +global @code{file-fail-code} attribute and naming a different value. +That is, something other than @code{failure}. You may choose @code{success}, +in which case file access issues will not affect the exit code and the error +message will not be printed. + +@node main-for-each-code +@unnumberedsubsubsec code for handler procedure + +@vindex MYHANDLER-code +With the @code{MYHANDLER-code} attribute, you provide the code for +your handler procedure in the option definition file. Note that the +spelling of this attribute depends on the name provided with the +@code{handler-proc} attribute, so we represent it here with +@code{MYHANDLER} as a place holder. As an example, your @code{main()} +procedure specification might look something like this: + +@example +main = @{ + main-type = for-each; + handler-proc = @var{MYHANDLER}; + @var{MYHANDLER}-code = <<- EndOfMyCode + /* whatever you want to do */ + EndOfMyCode; +@}; +@end example + +@noindent +and instead of an emitted external reference, a procedure will be emitted +that looks like this: + +@example +static int +@var{MYHANDLER}( char const* pz_entry ) +@{ + int res = 0; + <<@var{MYHANDLER}-code goes here>> + return res; +@} +@end example + +@node main-for-each-opts +@unnumberedsubsubsec for-each main procedure options + +These attributes affect the main procedure and how it processes +each argument or input line. + +@table @samp +@item interleaved +@vindex interleaved +If this attribute is specified, then options and operands may be +interleaved. Arguments or input lines beginning with a hyphen will +cause it to be passed through to an option processing function and +will take effect for the remainder of the operands (or input lines) +processed. + +@item main-init +@vindex main-init +This is code that gets inserted after the options have been processed, but +before the handler procs get invoked. + +@item main-fini +@vindex main-fini +This is code that gets inserted after all the entries have been processed, +just before returning from @code{main()}. + +@item comment-char +@vindex comment-char +When reading operands from standard input, if you wish comment lines to +start with a character other than a hash (@code{#}) character, then +specify one character with this attribute. If string value is empty, +then only blank lines will be considered comments. +@end table + +@node option attributes +@subsection Option Attributes +@cindex option attributes + +For each option you wish to specify, you must have a block macro named +@code{flag} defined. There are two required attributes: @code{name} and +@code{descrip}. If any options do not have a @code{value} (traditional flag +character) attribute, then the @code{long-opts} program attribute must also +be defined. As a special exception, if no options have a @code{value} +@strong{and} @code{long-opts} is not defined @strong{and} @code{argument} is +not defined, then all arguments to the program are named options. In this +case, the @option{-} and @option{--} command line option markers are optional. + +@menu +* Required Attributes:: Required Attributes +* Common Attributes:: Common Option Attributes +* Immediate Action:: Immediate Action Attributes +* Option Conflict Attributes:: Option Conflict Attributes + +These option attributes do not fit well with the above categories. + +* opt-attr settable:: Program may set option +* opt-attr no-preset:: Option cannot be pre-configured +* opt-attr equivalence:: Option Equivalence Class +* opt-attr aliases:: Option Aliasing +* opt-attr default option:: Default Option +* opt-attr documentation:: Option Sectioning Comment +* opt-attr translators:: Translator Notes +@end menu + +@node Required Attributes +@subsubsection Required Attributes +@cindex Required Attributes + +Every option must have exactly one copy of both of these attributes. + +@table @samp +@item name +@vindex name +Long name for the option. Even if you are not accepting long options +and are only accepting flags, it must be provided. AutoOpts generates +private, named storage that requires this name. This name also causes +a @code{#define}-d name to be emitted. It must not conflict with any +other names you may be using in your program. + +For example, if your option name is, @code{debug} or @code{munged-up}, +you must not use the @code{#define} names @code{DEBUG} (or +@code{MUNGED_UP}) in your program for non-AutoOpts related purposes. +They are now used by AutoOpts. + +Sometimes (most especially under Windows), you may get a surprise. +For example, @code{INTERFACE} is apparently a user space name that +one should be free to use. Windows usurps this name. To solve this, +you must do one of the following: + +@enumerate +@item +Change the name of your option +@item +add the program attribute (@pxref{program attributes}): + +@example +export = '#undef INTERFACE'; +@end example +@item +add the program attribute: + +@example +guard-option-names; +@end example +@end enumerate + +@item descrip +@vindex descrip +Except for documentation options, a @strong{very} brief description of the +option. About 40 characters on one line, maximum, not counting any texinfo +markups. Texinfo markups are stripped before printing in the usage text. It +appears on the @code{usage()} output next to the option name. + +If, however, the option is a documentation option, it will appear on one or +more lines by itself. It is thus used to visually separate and comment upon +groups of options in the usage text. +@end table + +@node Common Attributes +@subsubsection Common Option Attributes +@cindex Common Option Attributes + +These option attributes are optional. Any that do appear in the +definition of a flag, may appear only once. + +@table @samp +@item value +@vindex value +The flag character to specify for traditional option flags, e.g., @option{-L}. + +@item max +@vindex max +Maximum occurrence count (invalid if @var{disable} present). +The default maximum is 1. @code{NOLIMIT} can be used for the value, +otherwise it must be a number or a @code{#define} that evaluates to a number. + +@item min +@vindex min +Minimum occurrence count. If present, then the option @strong{must} +appear on the command line. Do not define it with the value zero (0). + +@item must-set +@vindex must-set +If an option must be specified, but it need not be specified on +the command line, then specify this attribute for the option. + +@item deprecated +@vindex deprecated +There are two effects to this attribute: the usage text will not +show the option, and the generated documentation will mark it with: +@emph{NOTE: THIS OPTION IS DEPRECATED}. + +@item disable +@vindex disable +Prefix for disabling (inverting sense of) the option. Only useful +if long option names are being processed. When an option has this +attribute, the test @code{ENABLED_OPT(OPTNAME)} is false when either +of the following is true: +@itemize @bullet +@item +The option has not been specified and the @code{enable} attribute has +not been specified. +@item +The option has been specified with this disabling prefix. +@end itemize +To detect that the option has been specified with the disabling +prefix, you must use: +@example +HAVE_OPT(OPTNAME) && ! ENABLED_OPT(OPTNAME) +@end example + +@item enable +@vindex enable +Long-name prefix for enabling the option (invalid if @var{disable} +@strong{not} present). Only useful if long option names are being +processed. + +@item enabled +@vindex enabled +If default is for option being enabled. (Otherwise, the OPTST_DISABLED +bit is set at compile time.) Only useful if the option can be disabled. + +@item ifdef +@itemx ifndef +@itemx omitted-usage +@vindex ifdef +@vindex ifndef +@vindex omitted-usage +If an option is relevant on certain platforms or when certain features +are enabled or disabled, you can specify the compile time flag used +to indicate when the option should be compiled in or out. For example, +if you have a configurable feature, @code{mumble} that is indicated +with the compile time define, @code{WITH_MUMBLING}, then add: + +@example +ifdef = WITH_MUMBLING; +@end example + +@noindent +Take care when using these. There are several caveats: + +@itemize @bullet +@item +The case and spelling must match whatever is specified. +@item +Do not confuse these attributes with the AutoGen directives of the +same names, @xref{Directives}. These cause C preprocessing directives +to be inserted into the generated C text. +@item +Only one of @code{ifdef} and @code{ifndef} may apply to any one option. +@item +The @code{VALUE_OPT_} values are @code{#define}-d. If @code{WITH_MUMBLING} +is not defined, then the associated @code{VALUE_OPT_} value will not be +@code{#define}-d either. So, if you have an option named, @code{MUMBLING} +that is active only if @code{WITH_MUMBLING} is @code{#define}-d, then +@code{VALUE_OPT_MUMBLING} will be @code{#define}-d iff @code{WITH_MUMBLING} +is @code{#define}-d. Watch those switch statements. +@item +If you specify @code{omitted-usage}, then the option will be recognized +as disabled when it is configured out of the build, but will yield the +message, ``This option has been disabled.'' You may specify an alternate +message by giving @code{omitted-usage} a string value. e.g.: +@example +omitted-usage = 'you cannot do this'; +@end example +@end itemize + +@item no-command +@vindex no-command +This option specifies that the option is not allowed on the command line. +Such an option may not take a @code{value} (flag character) attribute. The +program must have the @code{homerc} (@pxref{program attributes}) option set. +@end table + +@node Immediate Action +@subsubsection Immediate Action Attributes +@cindex immediate action + +Certain options may need to be processed early. For example, in order to +suppress the processing of configuration files, it is necessary to process the +command line option @option{--no-load-opts} @strong{before} the config files +are processed. To accommodate this, certain options may have their enabled or +disabled forms marked for immediate processing. The consequence of this is +that they are processed ahead of all other options in the reverse of normal +order. + +Normally, the first options processed are the options specified in the first +@code{homerc} file, followed by then next @code{homerc} file through to the +end of config file processing. Next, environment variables are processed and +finally, the command line options. The later options override settings +processed earlier. That actually gives them higher priority. Command line +immediate action options actually have the lowest priority of all. They would +be used only if they are to have an effect on the processing of subsequent +options. + +@table @samp +@item immediate +@vindex immediate +Use this option attribute to specify that the enabled form of the option +is to be processed immediately. The @code{help} and @code{more-help} +options are so specified. They will also call @code{exit()} upon +completion, so they @strong{do} have an effect on the processing +of the remaining options :-). + +@item immed-disable +@vindex immed-disable +Use this option attribute to specify that the disabled form of the +option is to be processed immediately. The @code{load-opts} option is +so specified. The @option{--no-load-opts} command line option will +suppress the processing of config files and environment variables. +Contrariwise, the @option{--load-opts} command line option is +processed normally. That means that the options specified in that file +will be processed after all the @code{homerc} files and, in fact, after +options that precede it on the command line. + +@item also +If either the @code{immediate} or the @code{immed-disable} attributes +are set to the string, @code{also}, then the option will actually be +processed twice: first at the immediate processing phase and again +at the normal time. +@end table + +@node Option Conflict Attributes +@subsubsection Option Conflict Attributes +@cindex Option Conflict Attributes + +These attributes may be used as many times as you need. +They are used at the end of the option processing to verify +that the context within which each option is found does not +conflict with the presence or absence of other options. + +This is not a complete cover of all possible conflicts and +requirements, but it simple to implement and covers the +more common situations. + +@table @samp +@cindex flags-must +@item flags-must +one entry for every option that @strong{must} be present +when this option is present + +@cindex flags-cant +@item flags-cant +one entry for every option that @strong{cannot} be present +when this option is present +@end table + +@node opt-attr settable +@subsubsection Program may set option +@vindex settable +If the option can be set outside of option processing, specify +@code{settable}. If this attribute is defined, special macros for setting +this particular option will be inserted into the interface file. For example, +@code{TEMPL_DIRS} is a settable option for AutoGen, so a macro named +@code{SET_OPT_TEMPL_DIRS(a)} appears in the interface file. This attribute +interacts with the @var{documentation} attribute. + +@node opt-attr no-preset +@subsubsection Option cannot be pre-configured +@vindex no-preset +@cindex configuration file +If presetting this option is not allowed, specify @code{no-preset}. +(Thus, environment variables and values set in configuration files will be +ignored.) + +@node opt-attr equivalence +@subsubsection Option Equivalence Class +@vindex equivalence +Generally, when several options are mutually exclusive and basically serve the +purpose of selecting one of several processing modes, specify the +@code{equivalence} attribute. These options will be considered an +equivalence class. Sometimes, it is just easier to deal with them as such. +All members of the equivalence class must contain the same equivalenced-to +option, including the equivalenced-to option itself. Thus, it must be a class +member. + +For an option equivalence class, there is a single occurrence counter for +the class. It can be referenced with the interface macro, +@code{COUNT_OPT(BASE_OPTION)}, where @var{BASE_OPTION} is the equivalenced-to +option name. + +Also, please take careful note: since the options are mapped to the +equivalenced-to option descriptor, any option argument values are mapped to +that descriptor also. Be sure you know which ``equivalent option'' was +selected before getting an option argument value! + +During the presetting phase of option processing +(@pxref{Presetting Options}), equivalenced options may be specified. +However, if different equivalenced members are specified, only the last +instance will be recognized and the others will be discarded. A conflict +error is indicated only when multiple different members appear on the +command line itself. + +As an example of where equivalenced options might be useful, @code{cpio(1)} +has three options @option{-o}, @option{-i}, and @option{-p} that define the +operational mode of the program (@code{create}, @code{extract} and +@code{pass-through}, respectively). They form an equivalence class from +which one and only one member must appear on the command line. If +@code{cpio} were an AutoOpt-ed program, then each of these option +definitions would contain: + +@example +equivalence = create; +@end example + +and the program would be able to determine the operating mode +with code that worked something like this: + +@example +switch (WHICH_IDX_CREATE) @{ +case INDEX_OPT_CREATE: ... +case INDEX_OPT_EXTRACT: ... +case INDEX_OPT_PASS_THROUGH: ... +default: /* cannot happen */ +@} +@end example + +@node opt-attr aliases +@subsubsection Option Aliasing + +Sometimes, for backwards compatibility or tradition or just plain convenience, +it works better to define one option as a pure alias for another option. +For such situations, provide the following pieces of information: +@example +flag = @{ + name = @i{aliasing-option-name}; + value = @i{aliasing-flag-char}; // optional ! + aliases = @i{aliased-to-option}; +@}; +@end example +Do not provide anything else. The usage text for such an option will be: +@example + This is an alias for @i{aliased-to-option} +@end example + +@node opt-attr default option +@subsubsection Default Option +@vindex default +If your program processes its arguments in named option mode (See +@code{long-opts} in @ref{program attributes}), then you may select +@strong{one} of your options to be the default option. Do so by using +attribute @code{default} with one of the options. The option so specified +must have an @code{arg-type} (@pxref{Option Arguments}) specified, but not the +@code{arg-optional} (@pxref{arg-optional}) attribute. That is to say, the +option argument must be required. + +If you have done this, then any arguments that do not match an option name and +do not contain an equal sign (@code{=}) will be interpreted as an option +argument to the default option. + +@node opt-attr documentation +@subsubsection Option Sectioning Comment +This attribute means the option exists for the purpose of separating option +description text in the usage output and texi documentation. Without this +attribute, every option is a separate node in the texi docs. With this +attribute, the documentation options become texi doc nodes and the options are +collected under them. Choose the name attribute carefully because it will +appear in the texi documentation. + +Libraries may also choose to make it settable so that the library can +determine which command line option is the first one that pertains to the +library. + +@vindex documentation +If the @samp{documentation} attribute is present, then all other +attributes are disabled except @code{settable}, @code{call-proc} and +@code{flag-code}. @code{settable} must be and is only specified if +@code{call-proc}, @code{extract-code} or @code{flag-code} has been specified. +When present, the @code{descrip} attribute will be displayed only when the +@option{--help} option has been specified. It will be displayed flush to the +left hand margin and may consist of one or more lines of text, filled to 72 +columns. + +The name of the option will not be printed in the help text. It @i{will}, +however, be printed as section headers in the texi documentation. If the +attribute is given a non-empty value, this text will be reproduced in the man +page and texi doc immediately after the @code{descrip} text. + +@node opt-attr translators +@subsubsection Translator Notes +@vindex translators +If you need to give the translators a special note about a particular option, +please use the @code{translators} attribute. The attribute text will be +emitted into the generated @code{.c} text where the option related strings get +defined. To make a general comment about all of the option code, add comments +to an @code{include} attribute (@pxref{program attributes}). Do @strong{not} +use this attribute globally, or it will get emitted into every option +definition block. + +@node Option Arguments +@subsection Option Argument Specification +@cindex Option Arguments + +Command line options come in three flavors: options that do not +take arguments, those that do and those that may. Without an +"arg-type" attribute, AutoOpts will not process an argument to an +option. If "arg-type" is specified and "arg-optional" is also +specified, then the next command line token will be taken to +be an argument, unless it looks like the name of another option. + +If the argument type is specified to be anything other than "str[ing]", then +AutoOpts will specify a callback procedure to handle the argument. Some of +these procedures will be created and inserted into the generated @file{.c} +file, and others are already built into the @file{libopts} library. +Therefore, if you write your own callback procedure +(@pxref{Option Argument Handling}), then you must either not specify an +"arg-type" attribute, or else specify it to be of type "str[ing]". Your +callback function will be able to place its own restrictions on what that +string may contain or represent. + +Option argument handling attributes depend upon the value set for the +@vindex arg-type +@code{arg-type} attribute. It specifies the type of argument the option +will take. If not present, the option cannot take an argument. If present, +it must be an entry in the following table. The first three letters is +sufficient. + +@menu +* arg-type string:: Arg Type String +* arg-type number:: Arg Type Number +* arg-type boolean:: Arg Type Boolean +* arg-type keyword:: Arg Type Keyword +* arg-type set membership:: Arg Type Set Membership +* arg-type hierarchy:: Arg Type Hierarchical +* arg-type file name:: Arg Type File Name +* arg-type time-duration:: Arg Type Time Duration +* arg-type time-date:: Arg Type Time and Date + +Supporting attributes for particular argument types: + +* arg-keyword:: Keyword list +* arg-optional:: Option Argument Optional +* arg-default:: Default Option Argument Value +@end menu + +@node arg-type string +@subsubsection Arg Type String +@code{arg-type = string;} + +The argument may be any arbitrary string, though your program or option +callback procedure may place additional constraints upon it. + + +@node arg-type number +@subsubsection Arg Type Number +@code{arg-type = number;} + +The argument must be a correctly formed integer, without any trailing U's or +L's. AutoOpts contains a library procedure to convert the string to a number. +If you specify range checking with @code{arg-range} (see below), then AutoOpts +produces a special purpose procedure for this option. + +@table @samp +@item scaled +@vindex scaled +@code{scaled} marks the option so that suffixes of @samp{k}, @samp{K}, +@samp{m}, @samp{M}, @samp{g}, @samp{G}, @samp{t}, and @samp{T} will multiply +the given number by a power of 1000 or 1024. Lower case letters scale by a +power of 1000 and upper case scale by a power of 1024. + +@item arg-range +@vindex arg-range +@code{arg-range} is used to create a callback procedure for validating the +range of the option argument. It must match one of the range entries. Each +@code{arg-range} should consist of either an integer by itself or an integer +range. The integer range is specified by one or two integers separated by the +two character sequence, @code{->}. Be sure to quote the entire range string. +The definitions parser will not accept the range syntax as a single string +token. + +The generated procedure imposes the range constraints as follows: +@itemize @bullet +@item +A number by itself will match that one value. +@item +The high end of the range may not be @code{INT_MIN}, both for obvious +reasons and because that value is used to indicate a single-valued match. +@item +An omitted lower value implies a lower bound of INT_MIN. +@item +An omitted upper value implies a upper bound of INT_MAX. +@item +The argument value is required. It may not be optional. +@item +The value must match one of the entries. If it can match more than one, +then you have redundancies, but no harm will come of it. +@end itemize +@end table + + +@node arg-type boolean +@subsubsection Arg Type Boolean +@code{arg-type = boolean;} + +The argument will be interpreted and always yield either AG_TRUE or +AG_FALSE. False values are@: the empty string, the number zero, or a +string that starts with @code{f}, @code{F}, @code{n} or @code{N} +(representing False or No). Anything else will be interpreted as True. + + +@node arg-type keyword +@subsubsection Arg Type Keyword +@code{arg-type = keyword;} + +The argument must match a specified list of strings (@pxref{arg-keyword}). +Assuming you have named the option, @code{optn-name}, the strings will be +converted into an enumeration of type @code{te_Optn_Name} with the values +@code{OPTN_NAME_KEYWORD}.* If you have @strong{not} specified a default +value, the value @code{OPTN_NAME_UNDEFINED} will be inserted with the value +zero. The option will be initialized to that value. You may now use this +in your code as follows: + +@example +te_Optn_Name opt = OPT_VALUE_OPTN_NAME; +switch (opt) @{ +case OPTN_NAME_UNDEFINED: /* undefined things */ break; +case OPTN_NAME_KEYWORD: /* `keyword' things */ break; +default: /* utterly impossible */ ; +@} +@end example + +AutoOpts produces a special purpose procedure for this option. +You may not specify an alternate handling procedure. + +If you have need for the string name of the selected keyword, you +may obtain this with the macro, @code{OPT_OPTN_NAME_VAL2STR(val)}. +The value you pass would normally be @code{OPT_VALUE_OPTN_NAME}, +but anything with numeric value that is legal for @code{te_Optn_Name} +may be passed. Anything out of range will result in the string, +@samp{"*INVALID*"} being returned. The strings are read only. +It may be used as in: + +@example +te_Optn_Name opt = OPT_VALUE_OPTN_NAME; +printf( "you selected the %s keyword\n", + OPT_OPTN_NAME_VAL2STR(opt) ); +@end example + +* Note: you may replace the @code{OPTN_NAME} enumeration prefix with +another prefix by specifying a +@vindex prefix-enum +@code{prefix-enum} attribute. + +Finally, users may specify the argument either by name or by number. +Since the numeric equivalents change by having new entries inserted +into the keyword list, this would not be a recommended practice. +However, either @code{-1} or @code{~0} will always be equivalent to +specifying the last keyword. + +@node arg-type set membership +@subsubsection Arg Type Set Membership +@code{arg-type = set;} + +The argument must be a list of names each of which must match the strings +``@code{all}'', ``@code{none}'' or one of the keywords (@pxref{arg-keyword}) +specified for this option. @code{all} will turn on all membership bits and +@code{none} will turn them all off. Specifying one of the keywords will set +the corresponding set membership bit on (or off, if negated) . Literal +numbers may also be used and may, thereby, set or clear more than one bit. + +The membership result starts with the previous (or initialized) result. To +clear previous results, either start the membership string with @samp{none +} +or with the equals character (@samp{=}). To invert (bit flip) the final +result (regardless of whether the previous result is carried over or not), +start the string with a carat character (@samp{^}). If you wish to invert the +result and start without a carried over value, use one of the following: +@code{=^} or @code{^none+}. These are equivalent. + +The list of names or numbers must be separated by one of the following +characters: @samp{+-|!,} or whitespace. The comma is equivalent to +whitespace, except that only one may appear between two entries and it may not +appear in conjunction with the @var{or} bar (@samp{|}). The @samp{+|} leading +characters or unadorned name signify adding the next named bit to the mask, +and the @samp{-!} leading characters indicate removing it. + +The number of keywords allowed is constrained by the number of bits in a +pointer, as the bit set is kept in a @code{void *} pointer. + +If, for example, you specified @code{first} in your list of keywords, +then you can use the following code to test to see if either @code{first} +or @code{all} was specified: + +@example +uintptr_t opt = OPT_VALUE_OPTN_NAME; +if (opt & OPTN_NAME_FIRST) + /* OPTN_NAME_FIRST bit was set */ ; +@end example + +AutoOpts produces a special purpose procedure for this option. +To set multiple bits as the default (initial) value, you must +specify an initial numeric value (which might become inaccurate over +time), or else specify @code{arg-default} multiple times. Do not +specify a series of names conjoined with @code{+} symbols as the +value for any of the @code{arg-default} attributes. That works for +option parsing, but not for the option code generation. + +@node arg-type hierarchy +@subsubsection Arg Type Hierarchical +@code{arg-type = hierarchy;} +@* +@code{arg-type = nested;} + +This denotes an option with a structure-valued argument, a.k.a. +@code{subopts} in @code{getopts} terminology. The argument is parsed +and the values made available to the program via the find and +find next calls (@xref{libopts-optionFindValue}, +@xref{libopts-optionGetValue}, and +@pxref{libopts-optionFindNextValue}). + +@example +tOptionValue * val = optionGetValue(VALUE_OPT_OPTN_NAME, "name"); +while (val != NULL) @{ + process(val); + val = optionNextValue(VALUE_OPT_OPTN_NAME, val); + if (wrong_name(val, "name")) + break; +@} +@end example + + +@node arg-type file name +@subsubsection Arg Type File Name +@code{arg-type = file;} + +This argument type will have some validations on the argument and, +optionally, actually open the file. You must specify several additonal +attributes for the option: + +@table @samp +@item file-exists +@vindex file-exists +If not specified or empty, then the directory portion of the name is checked. +The directory must exist or the argument is rejected and the usage procedure +is invoked. + +Otherwise, both the directory as above and the full name is tested for +existence. If the value begins with the two letters @code{no}, then the file +must not pre-exist. Otherwise, the file is expected to exist. + +@item open-file +@vindex open-file +If not specified or empty, the file is left alone. +If the value begins with the four letters @code{desc}[@i{riptor}], then +@code{open(2)} is used and @code{optArg.argFd} is set. Otherwise, the +file is opened with @code{fopen} and @code{optArg.argFp} is set. + +@item file-mode +@vindex file-mode +If @code{open-file} is set and not empty, then you must specify the open mode. +Set the value to the flag bits or mode string as appropriate for the open +type. +@end table + + +@node arg-type time-duration +@subsubsection Arg Type Time Duration +@code{arg-type = time-duration;} + +The argument will be converted into a number of seconds. It may be +a multi-part number with different parts being multiplied into a seconds +value and added into the final result. Valid forms are in the table +below. Upper cased letters represent numbers that must be used in the +expressions. + +@table @samp +@item [[HH:]MM:]SS +@code{HH} is multiplied by @code{3600} and @code{MM} multiplied by @code{60} +before they are added to @code{SS}. This time specification may not be +followed by any other time specs. @code{HH} and @code{MM} are both optional, +though @code{HH} cannot be specified without @code{MM}. + +@item DAYS d +@code{DAYS} is multiplied by the number of seconds in a day. This value may +be followed by (and added to) values specified by @code{HH:MM:SS} or the +suffixed values below. If present, it must always be first. + +@item HRS h +@code{HRS} is multiplied by the number of seconds in an hour. This value may +be followed by (and added to) values specified by @code{MM:SS} or the +suffixed values below. + +@item MINS m +@code{MINS} is multiplied by the number of seconds in a minute. This value +may be followed by (and added to) a count of seconds. + +@item SECS s +This value can only be the last value in a time specification. The @code{s} +suffix is optional. +@end table + +@example + 5 d 1:10:05 ==> 5 days + 1 hour 10 minutes and 5 seconds + 5 d 1 h 10 m 5 ==> yields: 436205 seconds + 5d1h10m5s ==> same result -- spaces are optional. +@end example + +When saved into a config file, the value will be stored as a simple count +of seconds. There are actually more (many) accepted time duration strings. +The full documentation can be found with ISO-8601 documentation and the +more extedded documentation when @code{parse_duration()} becomes more widely +available. + + +@node arg-type time-date +@subsubsection Arg Type Time and Date +@code{arg-type = time-date;} + +The argument will be converted into the number of seconds since the epoch. +The conversion rules are very complicated, please see the +@file{getdate_r(3GNU)} man page. There are some additional restrictions: + +@enumerate +@item +Your project must be compiled with @code{PKGDATADIR} defined and naming a +valid directory. +@item +The @env{DATEMSK} environment variable will be set to the @file{datemsk} file +within that directory. +@end enumerate + +If that file is not accessible for any reason, the string will be +parsed as a time duration (@pxref{arg-type time-duration}) instead of a +specific date and time. + +@node arg-keyword +@subsubsection Keyword list +@vindex keyword +If the @code{arg-type} is @code{keyword} (@pxref{arg-type keyword}) or +@code{set-membership} (@pxref{arg-type set membership}), then you must specify +the list of keywords by a series of @code{keyword} entries. The interface +file will contain values for @env{@i{<OPTN_NAME>}_@i{<KEYWORD>}} for each +keyword entry. @code{keyword} option types will have an enumeration and +@code{set-membership} option types will have a set of unsigned bits +@code{#define}-d. + +If the @code{arg-type} is specifically @code{keyword}, you may also add +special handling code with a +@vindex extra-code +@code{extra-code} attribute. After @code{optionEnumerationVal} has +converted the input string into an enumeration, you may insert code to +process this enumeration value (@code{pOptDesc->optArg.argEnum}). + +@node arg-optional +@subsubsection Option Argument Optional +@vindex arg-optional +The @code{arg-optional} attribute indicates that the argument to the option is +optional (need not be specified on the command line). This is only valid if +the @var{arg-type} is @code{string} (@pxref{arg-type string}) or +@code{keyword} (@pxref{arg-type keyword}). If it is @code{keyword}, then this +attribute may also specify the default keyword to assume when the argument is +not supplied. If left empty, @var{arg-default} (@pxref{arg-default}) or the +zero-valued keyword will be used. + +The syntax rules for identifying the option argument are: +@itemize @bullet +@item +If the option is specified with a flag character and there is a character +following the flag character, then string following that flag character is the +option argument. +@item +If the flag character is the last character in an argument, then +the first character of the next argument is examined. If it is a hyphen, +then the option is presumed to not have an argument. Otherwise, the entire +next argument is the argument for the option. +@item +If the option is specified with a long option name and that name is ended with +an equal sign character (@code{=}), then everything after that character is the +option argument. +@item +If the long name is ended by the end of the argument, then the first character +of the next argument is examined, just as with the flag character ending an +argument string. +@end itemize + +This is overridden and the options are required if the libopts library +gets configured with @option{--disable-optional-args}. + +@node arg-default +@subsubsection Default Option Argument Value +@vindex arg-default +This specifies the default option argument value to be used when the option is +not specified or preset. You may specify multiple @code{arg-default} values +if the argument type is @code{set membership}. + +@node Option Argument Handling +@subsection Option Argument Handling +@cindex Option Argument Handling + +AutoOpts will either specify or automatically generate callback procedures +for options that take specialized arguments. The only option argument types +that are not specialized are plain string arguments and no argument at all. +For options that fall into one of those two categories, you may specify your +own callback function, as specified below. If you do this and if you +specify that options are resettable (@pxref{automatic options}), then your +option handling code @strong{must} look for the @samp{OPTST_RESET} bit in +the @code{fOptState} field of the option descriptor. + +If the option takes a string argument, then the @code{stack-arg} attribute can +be used to specify that the option is to be handled by the @code{libopts} +@code{stackOptArg()} and @code{unstackOptArg()} library procedures (see +below). In this case, you may not provide option handling code. + +Finally, @samp{documentation} options (@pxref{opt-attr documentation}) may +also be marked as @option{settable} (@pxref{opt-attr settable}) and have +special callback functions (either @samp{flag-code}, @samp{extract-code}, +or @samp{call-proc}). + +@table @samp +@item flag-code +@vindex flag-code +statements to execute when the option is encountered. This may be used in +conjunction with option argument types that cause AutoOpts to emit handler +code. If you do this, the @samp{flag-code} with index zero (0) is emitted +into the handler code @emph{before} the argument is handled, and the entry +with index one (1) is handled afterward. + +The generated procedure will be laid out something like this: + +@example +static void +doOpt<name>(tOptions* pOptions, tOptDesc* pOptDesc) +@{ +<flag-code[0]> +<AutoOpts defined handler code> +<flag-code[1]> +@} +@end example + +Only certain fields within the @code{tOptions} and @code{tOptDesc} +structures may be accessed. @xref{Option Processing Data}. When writing +this code, you must be very careful with the @code{pOptions} pointer. The +handler code is called with this pointer set to special values for handling +special situations. Your code must handle them. As an example, +look at @code{optionEnumerationVal} in @file{enum.c}. + +@item extract-code +@vindex extract-code +This is effectively identical to @code{flag-code}, except that the +source is kept in the output file instead of the definitions file +and you cannot use this in conjunction with options with arguments, +other than string arguments. + +A long comment is used to demarcate the code. You must not modify +that marker. @i{Before} regenerating the option code file, +the old file is renamed from MUMBLE.c to MUMBLE.c.save. The template +will be looking there for the text to copy into the new output file. + +@item call-proc +@vindex call-proc +external procedure to call when option is encountered. The calling +sequence must conform to the sequence defined above for the generated +procedure, @code{doOpt<name>}. It has the same restrictions +regarding the fields within the structures passed in as arguments. +@xref{Option Processing Data}. + +@item flag-proc +@vindex flag-proc +Name of another option whose @code{flag-code} can be executed +when this option is encountered. + +@item stack-arg +@vindex stack-arg +Call a special library routine to stack the option's arguments. Special +macros in the interface file are provided for determining how many of the +options were found (@code{STACKCT_OPT(NAME)}) and to obtain a pointer to a +list of pointers to the argument values (@code{STACKLST_OPT(NAME)}). +Obviously, for a stackable argument, the @code{max} attribute +(@pxref{Common Attributes}) needs to be set higher than @code{1}. + +If this stacked argument option has a disablement prefix, then the entire +stack of arguments will be cleared by specifying the option with that +disablement prefix. + +@item unstack-arg +@vindex unstack-arg +Call a special library routine to remove (@code{unstack}) strings +from a @code{stack-arg} option stack. This attribute must name +the option that is to be @code{unstacked}. Neither this option nor +the stacked argument option it references may be equivalenced to +another option. +@end table + +@node Internationalizing Options +@subsection Internationalizing Options +@cindex Internationalizing Options + +Normally, AutoOpts produces usage text that is difficult to translate. It is +pieced together on the fly using words and phrases scattered around here and +there, piecing together toe document. This does not translate well. + +Incorporated into this package are some ways around the problem. First, you +should specify the @code{full-usage} and @code{short-usage} program attributes +(@pxref{program attributes}). This will enable your translators to translate +the usage text as a whole. + +Your translators will also be able to translate long option names. The option +name translations will then become the names searched for both on the command +line and in configuration files. However, it will not affect the names of +environment variable names used to configure your program. + +If it is considered desireable to keep configuration files in the @code{C} +locale, then several macros are available to suppress or delay the +translations of option names at run time. These are all disabled if +@code{ENABLE_NLS} is not defined at compile time or if @code{no-xlate} has +been set to the value @emph{anything}. These macros @strong{must} +be invoked before the first invocation of @code{optionProcess}. + +@table @samp +@item OPT_NO_XLAT_CFG_NAMES; +@itemx OPT_XLAT_CFG_NAMES; +Disable (or enable) the translations of option names for configuration files. +If you enable translation for config files, then they will be translated for +command line options. + +@item OPT_NO_XLAT_OPT_NAMES; +@itemx OPT_XLAT_OPT_NAMES; +Disable (or enable) the translations of option names for command line +processing. If you disable the translation for command line processing, +you will also disable it for configuration file processing. Once translated, +the option names will remain translated. +@end table + +@node documentation attributes +@subsection Man and Info doc Attributes +@cindex documentation attributes + +AutoOpts includes AutoGen templates for producing abbreviated man pages +and for producing the invoking section of an info document. To take +advantage of these templates, you must add several attributes to your +option definitions. + +@menu +* per option attributes:: Per option documentation attributes +* global option attributes:: Global documentation attributes +@end menu + +@node per option attributes +@subsubsection Per option documentation attributes + +These attributes are sub-attributes (@i{sub-stanzas}) of the @code{flag} stanzas. + +@table @samp +@item arg-name +@vindex arg-name +If an option has an argument, the argument should have a name for +documentation purposes. It will default to @code{arg-type}, but +it will likely be clearer with something else like, @code{file-name} +instead of @code{string} (the type). + +@item doc +@vindex doc +First, every @code{flag} definition @emph{other than} @code{documentation} +definitions, must have a @code{doc} attribute defined. If the option takes +an argument, then it will need an @code{arg-name} attribute as well. The +@code{doc} text should be in plain sentences with minimal formatting. The +Texinfo commands @code{@@code}, and @code{@@var} will have its enclosed text +made into @strong{\fB} entries in the man page, and the @code{@@file} text +will be made into @strong{\fI} entries. The @code{arg-name} attribute is +used to display the option's argument in the man page. + +Options marked with the @code{documentation} attribute are for documenting +the usage text. All other options should have the @code{doc} attribute in +order to document the usage of the option in the generated man pages. + +Since these blocks of text are inserted into all output forms, +any markup text included in these blocks must be massaged for each +output format. By default, it is presumed to be @file{texi} format. +@end table + +@node global option attributes +@subsubsection Global documentation attributes +@table @samp +@item cmd-section +@vindex cmd-section +If your command is a game or a system management command, +specify this attribute with the value @code{5} or @code{8}, respectively. +The default is a user command (section 1). + +@item detail +@vindex detail +This attribute is used to add a very short explanation about what +a program is used for when the @code{title} attribute is insufficient. +If there is no @code{doc-section} stanza of type @code{DESCRIPTION}, then +this text is used for the man page DESCRIPTION section, too. + +@item addtogroup +@vindex addtogroup +This attribute tells the template that the generated code should be +surrounded with the following doxygen comments: +@example +/** @@file <header-or-code-file-name> + * @@addtogroup <value-of-addtogroup> + * @@@{ + */ +@end example +@noindent +and +@example +/** @@@} */ +@end example + +@item option-format +@vindex option-format +Specify the default markup style for the @code{doc} stanzas. +By default, it is @code{texi}, but @code{man} and @code{mdoc} may +also be selected. There are nine converter programs that do a partial +job of converting one form of markup into another. @command{texi2texi}, +@command{man2man} and @command{mdoc2mdoc} work pretty well. + +You may also post process the document by using @code{doc-sub} stanzas, +see below. + +@item option-info +@vindex option-info +This text will be inserted as a lead-in paragraph in the @code{OPTIONS} +section of the generated man page. + +@item doc-section +@vindex doc-section +This is a compound attribute that requires three @i{sub}attributes: + +@table @i +@item ds-format +This describes the format of the associated @code{ds-text} section. +@code{man}, @code{mdoc} and @code{texi} formats are supported. +Regardless of the chosen format, the formatting tags in the output +text will be converted to @code{man} macros for @code{man} pages, +@code{mdoc} macros for @code{mdoc} pages, and @code{texi} macros for +@code{texinfo} pages. + +@item ds-text +This is the descriptive text, written according to the rules for +@code{ds-format} documents. + +@item ds-type +This describes the section type. Basically, the title of the section +that will be added to all output documentation. There may be only one +@code{doc-section} for any given @code{ds-type}. If there are duplicates, +the results are undefined (it might work, it might not). + +There are five categories of @code{ds-type} sections. +They are those that the documentation templates would otherwise: +@enumerate +@item +always create itself, ignoring any @code{ds-type}s by this name. +These are marked, below, as @code{ao-only}. +@item +create, if none was provided. +These are marked, @code{alternate}. +@item +create, but augment if the @code{doc-section} was provided. +These are marked, @code{augments}. +@item +do nothing, but inserts them into the output in a prescribed order. +These are marked, @code{known} +@item +knows nothing about them. They will be alphabetized and inserted +after the list of leading sections and before the list of trailing +sections. These are not marked because I don't know their names. +@end enumerate + +Some of these are emitted by the documentation templates only if +certain conditions are met. If there are conditions, they are +explained below. If there are no conditions, then you will always +see the named section in the output. + +The output sections will appear in this order: +@table @samp +@item NAME +@code{ao-only}. +@item SYNOPSIS +@code{alternate}. +@item DESCRIPTION +@code{augments}. +@item OPTIONS +@code{ao-only}. +@item OPTION PRESETS +@code{ao-only}, if environment presets or configuration file processing +has been specified. +@item unknown +At this point, the unknown, alphabetized sections are inserted. +@item IMPLEMENTATION NOTES +@code{known} +@item ENVIRONMENT +@code{augments}, if environment presets have been specified. +@item FILES +@code{augments}, if configuration file processing has been specified. +@item EXAMPLES +@code{known} +@item EXIT STATUS +@code{augments}. +@item ERRORS +@code{known} +@item COMPATIBILITY +@code{known} +@item SEE ALSO +@code{known} +@item CONFORMING TO +@code{known} +@item HISTORY +@code{known} +@item AUTHORS +@code{alternate}, if the @code{copyright} stanza has either +an @code{author} or an @code{owner} attribute. +@item COPYRIGHT +@code{alternate}, if there is a @code{copyright} stanza. +@item BUGS +@code{augments}, if the @code{copyright} stanza has an +@code{eaddr} attribute. +@item NOTES +@code{augments}. +@end table +@end table + +@noindent +Here is an example of a @code{doc-section} for a @code{SEE ALSO} type. + +@example +doc-section = @{ + ds-type = 'SEE ALSO'; // or anything else + ds-format = 'man'; // or texi or mdoc format + ds-text = <<-_EOText_ + text relevant to this section type, + in the chosen format + _EOText_; +@}; +@end example + +@item doc-sub +@vindex doc-sub +This attribute will cause the resulting documentation to be post-processed. +This is normally with @command{sed}, see @code{doc-sub-cmd} below. +This attribute has several sub-attributes: + +@table @samp +@item sub-name +This is the name of an autogen text definition value, like @code{prog-name} +or @code{version}. In the @code{sub-text} field, occurrences of this +name preceded by two less than characters and followed by two greater +than characters will be replaced by the text value of the definition, +e.g. @samp{<<prog-name>>}. + +@item sub-text +The text that gets added to the command file for the post processing +program. + +@item sub-type +If this command only applies to certain types of output, specify +this with a regular expression that will match one of the valid +output format types, e.g. @samp{man|mdoc} will match those two kinds, +but not @code{texi} output. If omitted, it will always apply. +@end table + +For example, if you want to reference the program name in the @code{doc} +text for an option common to two programs, put @samp{#PROG#} into the +text. The following will replace all occrrences of @samp{#PROG#} +with the current value for @code{prog}: +@example +doc-sub = @{ + sub-name = prog-name; + sub-text = 's/#PROG#/<<prog-name>>/g'; +@}; +@end example + +@item doc-sub-cmd +@vindex doc-sub-cmd +A formatting string for constructing the post-processing command. +The first parameter is the name of the file with editing commands in it, +and the second is the file containing the unprocessed document. +The default value is: +@example +sed -f %s %s +@end example +@end table + +@node automatic options +@subsection Automatically Supported Options +@cindex automatic options + +AutoOpts provides automated support for several options. @code{help} and +@code{more-help} are always provided. The others are conditional upon +various global program attributes being defined @xref{program attributes}. + +Below are the option names and default flag values. The flags are activated +if and only if at least one user-defined option also uses a flag value. The +long names are supported as option names if @code{long-opts} has been +specified. These option flags may be deleted or changed to characters of your +choosing by specifying +@vindex more-help-value +@vindex usage-value +@vindex version-value +@vindex load-opts-value +@vindex reset-value +@code{xxx-value = "y";}, where @code{xxx} is one of the option names below and +@code{y} is either empty or the character of your choice. For example, to +change the help flag from @code{?} to @code{h}, specify +@vindex help-value +@code{help-value = "h";}; and to require that @code{save-opts} be specified +only with its long option name, specify +@vindex save-opts-value +@code{save-opts-value = "";}. + +Additionally, the procedure that prints out the program version may be +replaced by specifying @code{version-proc}. +@vindex version-proc +This procedure must be defined to be of external scope (non-static). +By default, the AutoOpts library provides @code{optionPrintVersion} +and it will be the specified callback function in the option +definition structure. + +With the exception of the @code{load-opts} option, none of these automatically +supported options will be recognized in configuration files or environment +variables. + +@table @samp +@item help -? +This option will immediately invoke the @code{USAGE()} procedure +and display the usage line, a description of each option with +its description and option usage information. This is followed +by the contents of the definition of the @code{detail} text macro. + +@item more-help -! +This option is identical to the @code{help} option, except that the +output is passed through a pager program. (@code{more} by default, or +the program identified by the @code{PAGER} environment variable.) + +@item usage -u +This option must be requested by specifying, @code{usage-opt} in the option +definition file. It will produce abbreviated help text to @file{stdout} and +exit with zero status (@code{EXIT_SUCCESS}). + +@item version -v + +This will print the program name, title and version. If it is not +followed by anything or is followed by the letter @code{v}, just the +program name and version will be printed. If followed by the letter +@code{c} and a value for @code{copyright} and @code{owner} have been +provided, then the copyright will be printed, too. If it is followed by +the letter @code{n}, then the full copyright notice (if available) will +be printed. The @code{version} attribute must be specified in the +option definition file. + +Because some target platforms discourage optional arguments to options, +the autoopts library can be compiled with @code{NO_OPTIONAL_OPT_ARGS} +defined. Alternatively, the @code{version-type} attribute can be added +to the option definitions and it can specify which flavor is preferred. +In either case, an argument to the @code{--version} option will then be +disallowed. + +@item load-opts -< +@cindex configuration file +This option will load options from the named file. They will be treated +exactly as if they were loaded from the normally found configuration files, +but will not be loaded until the option is actually processed. This can also +be used within another configuration file, causing them to nest. This is the +@strong{only} automatically supported option that can be activated inside of +config files or with environment variables. + +Specifying the negated form of the option (@option{--no-load-opts}) will +suppress the processing of configuration files and environment variables. + +This option is activated by specifying one or more @code{homerc} attributes. + +@item save-opts -> +@cindex configuration file +This option will cause the option state to be printed in the configuration +file format when option processing is done but not yet verified for +consistency. The program will terminate successfully without running when +this has completed. Note that for most shells you will have to quote or +escape the flag character to restrict special meanings to the shell. + +The output file will be the configuration file name (default or provided by +@code{rcfile}) in the last directory named in a @code{homerc} definition. + +This option may be set from within your program by invoking the +"@code{SET_OPT_SAVE_OPTS(@i{filename})}" macro (@pxref{SET_OPT_name}). +Invoking this macro will set the file name for saving the option processing +state, but the state will @strong{not} actually be saved. You must call +@code{optionSaveFile} to do that (@pxref{libopts-optionSaveFile}). +@strong{CAVEAT:} if, after invoking this macro, you call +@code{optionProcess}, the option processing state will be saved to this file +and @code{optionProcess} will not return. You may wish to invoke +@code{CLEAR_OPT( SAVE_OPTS )} (@pxref{CLEAR_OPT}) beforehand if you do need +to reinvoke @code{optionProcess}. + +This option is activated by specifying one or more @code{homerc} attributes. + +The method of saving the state may be altered by specifying flags before +the output file name. ``Flags'' are specified by placing a list of them +before the file name and separating them from the name with one or two +greater-than characters (``>''). There are three flags currently supported: + +@table @samp +@item default +If an option has a default value (has not been set), then the default value +is inserted as a comment. + +@item usage +Every option that can be processed from the configuration file will have a +comment that contains the usage string that gets printed with the @code{--help} text + +@item update +Instead of removing the old file and writing a new one, the output file is kept, +but any pre-existing segment labeled with @code{<?program prog-name>} is removed. +The new program segment is placed at the end of the file. This flag is implied if +the flags are separated from the file name with doubled greater-than characters. +In other words, @code{update,usage > @i{file-name}} and @code{usage >> @i{file-name}} +are identical. +@end table + +@item reset-option -R +This option takes the name of an option for the current program and resets its +state such that it is set back to its original, compile-time initialized +value. If the option state is subsequently stored (via @option{--save-opts}), +the named option will not appear in that file. + +This option is activated by specifying the @code{resettable} attribute. + +@strong{BEWARE}: If the @code{resettable} attribute is specified, all +option callbacks @strong{must} look for the @code{OPTST_RESET} bit in the +@code{fOptState} field of the option descriptor. If set, the @code{optCookie} +and @code{optArg} fields will be unchanged from their last setting. When the +callback returns, these fields will be set to their original values. If you +use this feature and you have allocated data hanging off of the cookie, you +need to deallocate it. +@end table + +@node standard options +@subsection Library of Standard Options +@cindex standard options + +AutoOpts has developed a set of standardized options. +You may incorporate these options in your program simply by @emph{first} +adding a @code{#define} for the options you want, and then the line, + +@example +#include stdoptions.def +@end example + +@noindent +in your option definitions. The supported options are specified thus: + +@example +#define DEBUG +#define DIRECTORY +#define DRY_RUN +#define INPUT +#define INTERACTIVE +#define OUTPUT +#define WARN + +#define SILENT +#define QUIET +#define BRIEF +#define VERBOSE +@end example + +By default, only the long form of the option will be available. +To specify the short (flag) form, suffix these names with @code{_FLAG}. +e.g., + +@example +#define DEBUG_FLAG +@end example + +@option{--silent}, @option{--quiet}, @option{--brief} and @option{--verbose} +are related in that they all indicate some level of diagnostic output. These +options are all designed to conflict with each other. Instead of four +different options, however, several levels can be incorporated by +@code{#define}-ing @code{VERBOSE_ENUM}. In conjunction with @code{VERBOSE}, +it incorporates the notion of @i{5} levels in an enumeration: @code{silent}, +@code{quiet}, @code{brief}, @code{informative} and @code{verbose}; with the +default being @code{brief}. + +@ignore +END == AUTOOPTS-MAIN == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore + +@ignore +START == AUTOOPTS-API == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore + +@c === SECTION MARKER + +@node AutoOpts API +@section Programmatic Interface +@cindex AutoOpts API + +The user interface for access to the argument information is completely +defined in the generated header file and in the portions of the +distributed file "options.h" that are marked "public". + +In the following macros, text marked @var{<NAME>} or @var{name} +is the name of the option @strong{in upper case} and +@strong{segmented with underscores @code{_}}. The macros and enumerations +defined in the options header (interface) file are used as follows: + +To see how these @code{#define} macros are used in a program, +the reader is referred to the several @file{opts.h} files +included with the AutoGen sources. + +@menu +* Option Processing Data:: Data for Option Processing +* CLEAR_OPT:: CLEAR_OPT( <NAME> ) - Clear Option Markings +* COUNT_OPT:: COUNT_OPT( <NAME> ) - Definition Count +* DESC:: DESC( <NAME> ) - Option Descriptor +* DISABLE_OPT_name:: DISABLE_OPT_name - Disable an option +* ENABLED_OPT:: ENABLED_OPT( <NAME> ) - Is Option Enabled? +* ERRSKIP_OPTERR:: ERRSKIP_OPTERR - Ignore Option Errors +* ERRSTOP_OPTERR:: ERRSTOP_OPTERR - Stop on Errors +* HAVE_OPT:: HAVE_OPT( <NAME> ) - Have this option? +* ISSEL_OPT:: ISSEL_OPT( <NAME> ) - Is Option Selected? +* ISUNUSED_OPT:: ISUNUSED_OPT( <NAME> ) - Never Specified? +* OPTION_CT:: OPTION_CT - Full Count of Options +* OPT_ARG:: OPT_ARG( <NAME> ) - Option Argument String +* OPT_NO_XLAT_CFG_NAMES:: OPT_NO_XLAT_CFG_NAMES - option name xlation +* OPT_NO_XLAT_OPT_NAMES:: OPT_NO_XLAT_OPT_NAMES - option name xlation +* OPT_VALUE_name:: OPT_VALUE_name - Option Argument Value +* OPT_XLAT_CFG_NAMES:: OPT_XLAT_CFG_NAMES - option name xlation +* OPT_XLAT_OPT_NAMES:: OPT_XLAT_OPT_NAMES - option name xlation +* RESTART_OPT:: RESTART_OPT( n ) - Resume Option Processing +* SET_OPT_name:: SET_OPT_name - Force an option to be set +* STACKCT_OPT:: STACKCT_OPT( <NAME> ) - Stacked Arg Count +* STACKLST_OPT:: STACKLST_OPT( <NAME> ) - Argument Stack +* START_OPT:: START_OPT - Restart Option Processing +* STATE_OPT:: STATE_OPT( <NAME> ) - Option State +* USAGE:: USAGE( exit-code ) - Usage invocation macro +* VALUE_OPT_name:: VALUE_OPT_name - Option Flag Value +* VERSION:: VERSION - Version and Full Version +* WHICH_IDX_name:: WHICH_IDX_name - Which Equivalenced Index +* WHICH_OPT_name:: WHICH_OPT_name - Which Equivalenced Option +* teOptIndex:: teOptIndex - Option Index and Enumeration +* OPTIONS_STRUCT_VERSION:: OPTIONS_STRUCT_VERSION - active version +* libopts procedures:: libopts External Procedures +@end menu + +@node Option Processing Data +@subsection Data for Option Processing +@cindex Option Processing Data + +This section describes the data that may be accessed from within the +option processing callback routines. The following fields may be used +in the following ways and may be used for read only. The first set is +addressed from the @code{tOptDesc*} pointer: + +@table @samp +@cindex optIndex +@item optIndex +@cindex optValue +@item optValue +These may be used by option procedures to determine which option they +are working on (in case they handle several options). + +@cindex optActualIndex +@item optActualIndex +@cindex optActualValue +@item optActualValue +These may be used by option procedures to determine which option was +used to set the current option. This may be different from the above if +the options are members of an equivalence class. + +@cindex optOccCt +@item optOccCt +If AutoOpts is processing command line arguments, then this value will contain +the current occurrence count. During the option preset phase (reading +configuration files and examining environment variables), the value is zero. + +@cindex fOptState +@item fOptState +The field may be tested for the following bit values +(prefix each name with @code{OPTST_}, e.g. @code{OPTST_INIT}): + +@table @samp +@item INIT +Initial compiled value. As a bit test, it will always yield FALSE. + +@item SET +The option was set via the @code{SET_OPT()} macro. + +@item PRESET +@cindex configuration file +The option was set via a configuration file. + +@item DEFINED +The option was set via a command line option. + +@item SET_MASK +This is a mask of flags that show the set state, one of the +above four values. + +@item EQUIVALENCE +This bit is set when the option was selected by an equivalenced option. + +@item DISABLED +This bit is set if the option is to be disabled. +(Meaning it was a long option prefixed by the disablement prefix, or +the option has not been specified yet and initializes as @code{disabled}.) +@end table + +As an example of how this might be used, in AutoGen I want to allow +template writers to specify that the template output can be left +in a writable or read-only state. To support this, there is a Guile +function named @code{set-writable} (@pxref{SCM set-writable}). +Also, I provide for command options @option{--writable} and +@option{--not-writable}. I give precedence to command line and RC +file options, thus: + +@example +switch (STATE_OPT( WRITABLE )) @{ +case OPTST_DEFINED: +case OPTST_PRESET: + fprintf(stderr, zOverrideWarn, pCurTemplate->pzFileName, + pCurMacro->lineNo); + break; + +default: + if (gh_boolean_p( set ) && (set == SCM_BOOL_F)) + CLEAR_OPT( WRITABLE ); + else + SET_OPT_WRITABLE; +@} +@end example + +@cindex pzLastArg +@item pzLastArg +Pointer to the latest argument string. BEWARE@: If the argument type +is numeric, an enumeration or a bit mask, then this will be the +argument @strong{value} and not a pointer to a string. +@end table + +The following two fields are addressed from the @code{tOptions*} pointer: + +@table @samp +@cindex pzProgName +@item pzProgName +Points to a NUL-terminated string containing the current program +name, as retrieved from the argument vector. + +@cindex pzProgPath +@item pzProgPath +Points to a NUL-terminated string containing the full path of +the current program, as retrieved from the argument vector. +(If available on your system.) + +@end table + +Note@: these fields get filled in during the first call to +@code{optionProcess()}. All other fields are private, for the exclusive +use of AutoOpts code and are subject to change. + +@node CLEAR_OPT +@subsection CLEAR_OPT( <NAME> ) - Clear Option Markings +@findex CLEAR_OPT + +Make as if the option had never been specified. +@code{HAVE_OPT(<NAME>)} will yield @code{FALSE} +after invoking this macro. + +@node COUNT_OPT +@subsection COUNT_OPT( <NAME> ) - Definition Count +@findex COUNT_OPT + +This macro will tell you how many times the option was +specified on the command line. It does not include counts +of preset options. + +@example +if (COUNT_OPT( NAME ) != desired-count) @{ + make-an-undesirable-message. +@} +@end example + +@node DESC +@subsection DESC( <NAME> ) - Option Descriptor +@findex DESC + +This macro is used internally by other AutoOpt macros. +It is not for general use. It is used to obtain the option description +corresponding to its @strong{UPPER CASED} option name argument. +This is primarily used in other macro definitions. + +@node DISABLE_OPT_name +@subsection DISABLE_OPT_name - Disable an option +@findex DISABLE_OPT_name + +This macro is emitted if it is both settable +and it can be disabled. If it cannot be disabled, it may +always be CLEAR-ed (see above). + +The form of the macro will actually depend on whether the +option is equivalenced to another, and/or has an assigned +handler procedure. Unlike the @code{SET_OPT} macro, +this macro does not allow an option argument. + +@example +DISABLE_OPT_NAME; +@end example + +@node ENABLED_OPT +@subsection ENABLED_OPT( <NAME> ) - Is Option Enabled? +@findex ENABLED_OPT + +Yields true if the option defaults to disabled and +@code{ISUNUSED_OPT()} would yield true. It also yields true if +the option has been specified with a disablement prefix, +disablement value or the @code{DISABLE_OPT_NAME} macro was invoked. + +@node ERRSKIP_OPTERR +@subsection ERRSKIP_OPTERR - Ignore Option Errors +@findex ERRSKIP_OPTERR + +When it is necessary to continue (return to caller) +on option errors, invoke this option. It is reversible. +@xref{ERRSTOP_OPTERR}. + +@node ERRSTOP_OPTERR +@subsection ERRSTOP_OPTERR - Stop on Errors +@findex ERRSTOP_OPTERR + +After invoking this macro, if @code{optionProcess()} +encounters an error, it will call @code{exit(1)} rather than return. +This is the default processing mode. It can be overridden by +specifying @code{allow-errors} in the definitions file, +or invoking the macro @xref{ERRSKIP_OPTERR}. + +@node HAVE_OPT +@subsection HAVE_OPT( <NAME> ) - Have this option? +@findex HAVE_OPT + +This macro yields true if the option has been specified +in any fashion at all. It is used thus: + +@example +if (HAVE_OPT( NAME )) @{ + <do-things-associated-with-opt-name>; +@} +@end example + +@node ISSEL_OPT +@subsection ISSEL_OPT( <NAME> ) - Is Option Selected? +@findex ISSEL_OPT + +This macro yields true if the option has been +specified either on the command line or via a SET/DISABLE macro. + +@node ISUNUSED_OPT +@subsection ISUNUSED_OPT( <NAME> ) - Never Specified? +@findex ISUNUSED_OPT + +This macro yields true if the option has +never been specified, or has been cleared via the +@code{CLEAR_OPT()} macro. + +@node OPTION_CT +@subsection OPTION_CT - Full Count of Options +@findex OPTION_CT + +The full count of all options, both those defined +and those generated automatically by AutoOpts. This is primarily +used to initialize the program option descriptor structure. + +@node OPT_ARG +@subsection OPT_ARG( <NAME> ) - Option Argument String +@findex OPT_ARG + +The option argument value as a pointer to string. Note that argument +values that have been specified as numbers are stored as numbers or +keywords. For such options, use instead the @code{OPT_VALUE_name} +define. It is used thus: + +@example +if (HAVE_OPT( NAME )) @{ + char* p = OPT_ARG( NAME ); + <do-things-with-opt-name-argument-string>; +@} +@end example + +@node OPT_NO_XLAT_CFG_NAMES +@subsection OPT_NO_XLAT_CFG_NAMES - option name xlation +@findex OPT_NO_XLAT_CFG_NAMES + +Invoking this macro will disable the translation of option names only while +processing configuration files and environment variables. This must be +invoked before the first call to @code{optionProcess}.. You need not invoke +this if your option definition file contains the attribute assignment, +@code{no-xlate = opt-cfg;}. + +@node OPT_NO_XLAT_OPT_NAMES +@subsection OPT_NO_XLAT_OPT_NAMES - option name xlation +@findex OPT_NO_XLAT_OPT_NAMES + +Invoking this macro will completely disable the translation of option names. +This must be invoked before the first call to @code{optionProcess}. You need +not invoke this if your option definition file contains the attribute +assignment, @code{no-xlate = opt;}. + +@node OPT_VALUE_name +@subsection OPT_VALUE_name - Option Argument Value +@findex OPT_VALUE_name + +This macro gets emitted only for options that take numeric, keyword or set +membership arguments. The macro yields a word-sized integer containing the +enumeration, bit set or numeric value for the option argument. + +@example +int opt_val = OPT_VALUE_name; +@end example + +@node OPT_XLAT_CFG_NAMES +@subsection OPT_XLAT_CFG_NAMES - option name xlation +@findex OPT_XLAT_CFG_NAMES + +If @code{ENABLE_NLS} is defined and @code{no-xlate} has been not set to the +value @emph{anything}, this macro will cause the translation of option names +to happen before starting the processing of configuration files and +environment variables. This will change the recognition of options within the +@code{$PROGRAMNAME} environment variable, but will not alter the names used +for setting options via @code{$PROGRAMNAME_name} environment variables. + +This must be invoked before the first call to @code{optionProcess}. You might +need to use this macro if your option definition file contains the attribute +assignment, @code{no-xlate = opt;} or @code{no-xlate = opt-cfg;}, and +you have determined in some way that you wish to override that. + +@node OPT_XLAT_OPT_NAMES +@subsection OPT_XLAT_OPT_NAMES - option name xlation +@findex OPT_XLAT_OPT_NAMES + +If @code{ENABLE_NLS} is defined and @code{no-xlate} has been not set to the +value @emph{anything}, translate the option names before processing the +command line options. Long option names may thus be localized. (If the names +were translated before configuration processing, they will not be +re-translated.) + +This must be invoked before the first call to @code{optionProcess}. You might +need to use this macro if your option definition file contains the attribute +assignment, @code{no-xlate = opt;} and you have determined in some way that +you wish to override that. + +@node RESTART_OPT +@subsection RESTART_OPT( n ) - Resume Option Processing +@findex RESTART_OPT + +If option processing has stopped (either because of an error +or something was encountered that looked like a program argument), +it can be resumed by providing this macro with the index @code{n} +of the next option to process and calling @code{optionProcess()} again. + +@example +int main(int argc, char ** argv) @{ + for (int ai = 0; ai < argc ;) @{ + restart: + ai = optionProcess(&progOptions, argc, argv); + for (; ai < argc; ai++) @{ + char * arg = arg[ai]; + if (*arg == '-') @{ + RESTART_OPT(ai); + goto restart; + @} + process(arg); + @} + @} +@} +@end example + +If you want a program to operate this way, you might consider specifying a +@code{for-each} main function +(@pxref{main for-each, for-each main procedure}) with the @code{interleaved} +attribute. It will allow you to process interleaved operands and options from +either the command line or when reading them from standard input. + +@node SET_OPT_name +@subsection SET_OPT_name - Force an option to be set +@findex SET_OPT_name + +This macro gets emitted only when the given +option has the @code{settable} attribute specified. + +The form of the macro will actually depend on whether the option is +equivalenced to another, has an option argument and/or has an assigned +handler procedure. If the option has an argument, then this macro will +too. Beware that the argument is not reallocated, so the value must not +be on the stack or deallocated in any other way for as long as the value +might get referenced. + +If you have supplied at least one @file{homerc} file +(@pxref{program attributes}), this macro will be emitted for the +@option{--save-opts} option. + +@example +SET_OPT_SAVE_OPTS( "filename" ); +@end example + +@noindent +@xref{automatic options}, for a discussion of the implications of using +this particular example. + +@node STACKCT_OPT +@subsection STACKCT_OPT( <NAME> ) - Stacked Arg Count +@findex STACKCT_OPT + +When the option handling attribute is specified +as @code{stack_arg}, this macro may be used to determine how +many of them actually got stacked. + +Do not use this on options that have not been stacked or has not been +specified (the @code{stack_arg} attribute must have been specified, +and @code{HAVE_OPT(<NAME>)} must yield TRUE). +Otherwise, you will likely seg fault. + +@example +if (HAVE_OPT( NAME )) @{ + int ct = STACKCT_OPT( NAME ); + char** pp = STACKLST_OPT( NAME ); + + do @{ + char* p = *pp++; + do-things-with-p; + @} while (--ct > 0); +@} +@end example + +@node STACKLST_OPT +@subsection STACKLST_OPT( <NAME> ) - Argument Stack +@findex STACKLST_OPT + +The address of the list of pointers to the +option arguments. The pointers are ordered by the order in +which they were encountered in the option presets and +command line processing. + +Do not use this on options that have not been stacked or has not been +specified (the @code{stack_arg} attribute must have been specified, +and @code{HAVE_OPT(<OPTION>)} must yield TRUE). +Otherwise, you will likely seg fault. + +@example +if (HAVE_OPT( NAME )) @{ + int ct = STACKCT_OPT( NAME ); + char** pp = STACKLST_OPT( NAME ); + + do @{ + char* p = *pp++; + do-things-with-p; + @} while (--ct > 0); +@} +@end example + +@node START_OPT +@subsection START_OPT - Restart Option Processing +@findex START_OPT + +This is just a shortcut for RESTART_OPT(1) (@xref{RESTART_OPT}.) + +@node STATE_OPT +@subsection STATE_OPT( <NAME> ) - Option State +@findex STATE_OPT + +If you need to know if an option was set because of presetting actions +(configuration file processing or environment variables), versus a command +line entry versus one of the SET/DISABLE macros, then use this macro. It +will yield one of four values: @code{OPTST_INIT}, @code{OPTST_SET}, +@code{OPTST_PRESET} or @code{OPTST_DEFINED}. It is used thus: + +@example +switch (STATE_OPT( NAME )) @{ + case OPTST_INIT: + not-preset, set or on the command line. (unless CLEAR-ed) + + case OPTST_SET: + option set via the SET_OPT_NAME() macro. + + case OPTST_PRESET: + option set via an configuration file or environment variable + + case OPTST_DEFINED: + option set via a command line option. + + default: + cannot happen :) +@} +@end example + +@node USAGE +@subsection USAGE( exit-code ) - Usage invocation macro +@findex USAGE + +This macro invokes the procedure registered to display +the usage text. Normally, this will be @code{optionUsage} from the +AutoOpts library, but you may select another procedure by specifying +@code{usage = "proc_name"} program attribute. This procedure must +take two arguments@: first, a pointer to the option descriptor, and +second the exit code. The macro supplies the option descriptor +automatically. This routine is expected to call @code{exit(3)} with +the provided exit code. + +The @code{optionUsage} routine also behaves differently depending +on the exit code: + +@table @code +@item EXIT_SUCCESS (the value zero) +It is assumed that full usage help has been requested. Consequently, more +information is provided than when displaying usage and exiting with a +non-zero exit code. Output will be sent to @file{stdout} and the program will +exit with a zero status code. + +@item EX_USAGE (64) +The abbreviated usage will be printed to @file{stdout} and the program will +exit with a zero status code. @code{EX_USAGE} may or may not be 64. If your +system provides @file{/usr/include/sysexits.h} that has a different value, +then that value will be used. + +@item any other value +The abbreviated usage will be printed to stderr and the program will +exit with the provided status code. +@end table + +@node VALUE_OPT_name +@subsection VALUE_OPT_name - Option Flag Value +@findex VALUE_OPT_name + +This is a #define for the flag character used to +specify an option on the command line. If @code{value} was not +specified for the option, then it is a unique number associated +with the option. @code{option value} refers to this value, +@code{option argument} refers to the (optional) argument to the +option. + +@example +switch (WHICH_OPT_OTHER_OPT) @{ +case VALUE_OPT_NAME: + this-option-was-really-opt-name; +case VALUE_OPT_OTHER_OPT: + this-option-was-really-other-opt; +@} +@end example + +@node VERSION +@subsection VERSION - Version and Full Version +@findex VERSION + +If the @code{version} attribute is defined for the program, +then a stringified version will be #defined as PROGRAM_VERSION and +PROGRAM_FULL_VERSION. PROGRAM_FULL_VERSION is used for printing +the program version in response to the version option. The version +option is automatically supplied in response to this attribute, too. + +You may access PROGRAM_VERSION via @code{programOptions.pzFullVersion}. + +@node WHICH_IDX_name +@subsection WHICH_IDX_name - Which Equivalenced Index +@findex WHICH_IDX_name + +This macro gets emitted only for equivalenced-to options. It is used to +obtain the index for the one of the several equivalence class members +set the equivalenced-to option. + +@example +switch (WHICH_IDX_OTHER_OPT) @{ +case INDEX_OPT_NAME: + this-option-was-really-opt-name; +case INDEX_OPT_OTHER_OPT: + this-option-was-really-other-opt; +@} +@end example + +@node WHICH_OPT_name +@subsection WHICH_OPT_name - Which Equivalenced Option +@findex WHICH_OPT_name + +This macro gets emitted only for equivalenced-to options. It is used to +obtain the value code for the one of the several equivalence class members +set the equivalenced-to option. + +@example +switch (WHICH_OPT_OTHER_OPT) @{ +case VALUE_OPT_NAME: + this-option-was-really-opt-name; +case VALUE_OPT_OTHER_OPT: + this-option-was-really-other-opt; +@} +@end example + +@node teOptIndex +@subsection teOptIndex - Option Index and Enumeration +@findex teOptIndex + +This enum defines the complete set of options, both +user specified and automatically provided. This can be used, +for example, to distinguish which of the equivalenced options +was actually used. + +@example +switch (pOptDesc->optActualIndex) @{ +case INDEX_OPT_FIRST: + stuff; +case INDEX_OPT_DIFFERENT: + different-stuff; +default: + unknown-things; +@} +@end example + +@node OPTIONS_STRUCT_VERSION +@subsection OPTIONS_STRUCT_VERSION - active version + +You will not actually need to reference this value, but you need to be +aware that it is there. It is the first value in the option descriptor +that you pass to @code{optionProcess}. It contains a magic number and +version information. Normally, you should be able to work with a more +recent option library than the one you compiled with. However, if the +library is changed incompatibly, then the library will detect the out of +date magic marker, explain the difficulty and exit. You will then need +to rebuild and recompile your option definitions. This has rarely been +necessary. + +@ignore +END == AUTOOPTS-API == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore + +@ignore +START == AUTOOPTS-DATA == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore + +@c === SECTION MARKER + +@node Multi-Threading +@section Multi-Threading + +AutoOpts was designed to configure a program for running. This generally +happens before much real work has been started. Consequently, it is +expected to be run before multi-threaded applications have started multiple +threads. However, this is not always the case. Some applications may +need to reset and reload their running configuration, and some may use +@code{SET_OPT_xxx()} macros during processing. If you need to dynamically +change your option configuration in your multi-threaded application, it is +your responsibility to prevent all threads from accessing the option +configuration state, except the one altering the configuration. + +The various accessor macros (@code{HAVE_OPT()}, etc.) do not modify state +and are safe to use in a multi-threaded application. It is safe as long +as no other thread is concurrently modifying state, of course. + +@c === SECTION MARKER + +@node option descriptor +@section Option Descriptor File +@cindex option descriptor + +This is the module that is to be compiled and linked with your program. +It contains internal data and procedures subject to change. Basically, +it contains a single global data structure containing all the +information provided in the option definitions, plus a number of static +strings and any callout procedures that are specified or required. You +should never have need for looking at this, except, perhaps, to examine +the code generated for implementing the @code{flag-code} construct. + +@c === SECTION MARKER + +@node Using AutoOpts +@section Using AutoOpts +@cindex using AutoOpts + +There are actually several levels of @code{using} autoopts. +Which you choose depends upon how you plan to distribute +(or not) your application. + +@menu +* local use:: local-only use +* binary not installed:: binary distro, AutoOpts not installed +* binary pre-installed:: binary distro, AutoOpts pre-installed +* source pre-installed:: source distro, AutoOpts pre-installed +* source not installed:: source distro, AutoOpts not installed +@end menu + +@node local use +@subsection local-only use + +To use AutoOpts in your application where you do not have to +worry about distribution issues, your issues are simple and few. + +@itemize @bullet +@item +Create a file @samp{myopts.def}, according to the documentation above. +It is probably easiest to start with the example in @ref{Quick Start} +and edit it into the form you need. + +@item +Run AutoGen to create the option interface file (@code{myopts.h}) +and the option descriptor code (@code{myopts.c}): + +@example +autogen myopts.def +@end example + +@item +In all your source files where you need to refer to option state, +@code{#include "myopts.h"}. +@item +In your main routine, code something along the lines of: + +@example +#define ARGC_MIN some-lower-limit +#define ARGC_MAX some-upper-limit +main( int argc, char** argv ) +@{ + @{ + int arg_ct = optionProcess( &myprogOptions, argc, argv ); + argc -= arg_ct; + if ((argc < ARGC_MIN) || (argc > ARGC_MAX)) @{ + fprintf( stderr, "%s ERROR: remaining args (%d) " + "out of range\n", myprogOptions.pzProgName, + argc ); + + USAGE( EXIT_FAILURE ); + @} + argv += arg_ct; + @} + if (HAVE_OPT(OPTN_NAME)) + respond_to_optn_name(); + ... +@} +@end example + +@item +Compile @samp{myopts.c} and link your program +with the following additional arguments: + +@example +`autoopts-config cflags ldflags` myopts.c +@end example +@end itemize + +@node binary not installed +@subsection binary distro, AutoOpts not installed + +If you will be distributing (or copying) your project to a system that +does not have AutoOpts installed, you will need to statically link the +AutoOpts library, @code{libopts} into your program. Get the link information +with @code{static-libs} instead of @code{ldflags}: + +@example +`autoopts-config static-libs` +@end example + +@node binary pre-installed +@subsection binary distro, AutoOpts pre-installed + +If you will be distributing (or copying) your project to a system that does +have AutoOpts (or only @code{libopts}) installed, you will still need to +ensure that the library is findable at program load time, or you will still +have to statically link. The former can be accomplished by linking your +project with @option{--rpath} or by setting the @env{LD_LIBRARY_PATH} +appropriately. Otherwise, @xref{binary not installed}. + +@node source pre-installed +@subsection source distro, AutoOpts pre-installed + +If you will be distributing your project to a system that will build +your product but it may not be pre-installed with AutoOpts, you will +need to do some configuration checking before you start the build. +Assuming you are willing to fail the build if AutoOpts has not been +installed, you will still need to do a little work. + +AutoOpts is distributed with a configuration check M4 script, +@file{autoopts.m4}. It will add an @code{autoconf} macro named, +@code{AG_PATH_AUTOOPTS}. Add this to your @file{configure.ac} script +and use the following substitution values: + +@table @code +@item AUTOGEN +the name of the autogen executable +@item AUTOGEN_TPLIB +the directory where AutoGen template library is stored +@item AUTOOPTS_CFLAGS +the compile time options needed to find the AutoOpts headers +@item AUTOOPTS_LIBS +the link options required to access the @code{libopts} library +@end table + +@node source not installed +@subsection source distro, AutoOpts not installed + +If you will be distributing your project to a system that will build +your product but it may not be pre-installed with AutoOpts, you may +wish to incorporate the sources for @code{libopts} in your project. +To do this, I recommend reading the tear-off libopts library +@file{README} that you can find in the @file{pkg/libopts} directory. +You can also examine an example package (blocksort) that incorporates +this tear off library in the autogen distribution directory. There is +also a web page that describes what you need to do: +@example +@url{http://autogen.sourceforge.net/blocksort.html} +@end example + +Alternatively, you can pull the @code{libopts} library sources into +a build directory and build it for installation along with your package. +This can be done approximately as follows: +@example +tar -xzvf `autoopts-config libsrc` +cd libopts-* +./bootstrap +configure +make +make install +@end example +That will install the library, but not the headers or anything else. + +@c === SECTION MARKER + +@node Presetting Options +@section Configuring your program +@cindex shell options + +AutoOpts supports the notion of @code{presetting} the value or state of an +option. The values may be obtained either from environment variables or from +configuration files (@file{rc} or @file{ini} files). In order to take +advantage of this, the AutoOpts client program must specify these features in +the option descriptor file (@pxref{program attributes}) with the @code{rcfile} +or @code{environrc} attributes. + +@menu +* loading rcfile:: configuration file presets +* saving rcfile:: Saving the presets into a configuration file +* sample rcfile:: Creating a sample configuration file +* environrc:: environment variable presets +* config example:: Config file only example +@end menu + +It is also possible to configure your program @i{without} using +the command line option parsing code. This is done by using +only the following four functions from the @file{libopts} library: + +@table @samp +@item configFileLoad +(@pxref{libopts-configFileLoad}) will parse the contents of a config +file and return a pointer to a structure representing the hierarchical +value. The values are sorted alphabetically by the value name and all +entries with the same name will retain their original order. +Insertion sort is used. + +@item optionGetValue +(@pxref{libopts-optionGetValue}) will find the first value within the +hierarchy with a name that matches the name passed in. + +@item optionNextValue +(@pxref{libopts-optionNextValue}) will return the next value that +follows the value passed in as an argument. If you wish to get all +the values for a particular name, you must take note when the name +changes. + +@item optionUnloadNested +(@pxref{libopts-optionUnloadNested}). The pointer passed in must be +of type, @code{OPARG_TYPE_HIERARCHY} (see the autoopts/options.h +header file). @code{configFileLoad} will return a @code{tOptionValue} +pointer of that type. This function will release all the associated +memory. @code{AutoOpts} generated code uses this function for its own +needs. Client code should only call this function with pointers +gotten from @code{configFileLoad}. +@end table + +@node loading rcfile +@subsection configuration file presets +@cindex rcfile + +Configuration files are enabled by specifying the program attribute +@code{homerc} (@pxref{program attributes}). Any option not marked +with the @code{no-preset} attribute may appear in a configuration file. +The files loaded are selected both by the @code{homerc} entries and, +optionally, via a command line option. The first component of the +@code{homerc} entry may be an environment variable such as @env{$HOME}, or +it may also be @samp{$$} (@strong{two} dollar sign characters) to specify +the directory of the executable. For example: + +@example +homerc = "$$/../share/autogen"; +@end example + +@noindent +will cause the AutoOpts library to look in the normal autogen datadir +relative to the current installation directory for autogen. + +The configuration files are processed in the order they are specified by +the @code{homerc} attribute, so that each new file will normally override +the settings of the previous files. This may be overridden by marking some +options for @code{immediate action} (@pxref{Immediate Action}). Any such +options are acted upon in @strong{reverse} order. The disabled +@code{load-opts} (@option{--no-load-opts}) option, for example, is an +immediate action option. Its presence in the last @code{homerc} file will +prevent the processing of any prior @code{homerc} files because its effect +is immediate. + +Configuration file processing can be completely suppressed by specifying +@option{--no-load-opts} on the command line, or @code{PROGRAM_LOAD_OPTS=no} in +the environment (if @code{environrc} has been specified). + +See the @code{Configuration File Format} section (@pxref{Config File Format}) +for details on the format of the file. + +@node saving rcfile +@subsection Saving the presets into a configuration file + +When configuration files are enabled for an application, the user is +also provided with an automatically supplied @option{--save-opts} option. +All of the known option state will be written to either the specified +output file or, if it is not specified, then to the last specified +@code{homerc} file. + +@node sample rcfile +@subsection Creating a sample configuration file +@cindex sample rcfile + +AutoOpts is shipped with a template named, @file{rc-sample.tpl}. +If your option definition file specifies the @code{homerc} attribute, +then you may invoke @file{autogen} thus: + +@example +autogen -Trc-sample <your-option-def-file> +@end example + +This will, by default, produce a sample file named, +@file{sample-<prog-name>rc}. It will be named differently if you specify your +configuration (rc) file name with the @code{rcfile} attribute. In that case, +the output file will be named, @file{sample-<rcfile-name>}. It will contain +all of the program options not marked as @code{no-preset}. It will also +include the text from the @code{doc} attribute. + +@ignore +END == AUTOOPTS-DATA == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore + +@ignore +START == AO-DATA1 == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore + +@node environrc +@subsection environment variable presets +@cindex environrc + +If the AutoOpts client program specifies @code{environrc} in its +option descriptor file, then environment variables will be used for +presetting option state. Variables will be looked for that are named, +@env{PROGRAM_OPTNAME} and @env{PROGRAM}. @env{PROGRAM} is the +upper cased @code{C-name} of the program, and @var{OPTNAME} is the +upper cased @code{C-name} of a specific option. (The @code{C-name}s +are the regular names with all special characters converted to +underscores (@code{_}).) + +Option specific environment variables are processed after (and thus +take precedence over) the contents of the @env{PROGRAM} environment +variable. The option argument string for these options takes on the +string value gotten from the environment. Consequently, you can only +have one instance of the @var{OPTNAME}. + +If a particular option may be disabled, then its disabled state is +indicated by setting the @env{PROGRAM_OPTNAME} value to the +disablement prefix. So, for example, if the disablement prefix were +@code{dont}, then you can disable the @code{optname} option by setting +the @env{PROGRAM_OPTNAME}' environment variable to @code{@i{dont}}. +@xref{Common Attributes}. + +The @env{PROGRAM} environment string is tokenized and parsed much +like a command line. Doubly quoted strings have backslash escapes +processed the same way they are processed in C program constant +strings. Singly quoted strings are pretty raw in that backslashes are +honored before other backslashes, apostrophes, newlines and cr/newline +pairs. The options must be introduced with hyphens in the same way as +the command line. + +Note that not all options may be preset. Options that are specified with the +@code{no-preset} attribute and the @option{--help}, @option{--more-help}, +and @option{--save-opts} auto-supported options may not be preset. + +@node config example +@subsection Config file only example +@cindex rcfile +@cindex Configuration File +@cindex Configuration File example + +If for some reason it is difficult or unworkable to integrate configuration +file processing with command line option parsing, the @code{libopts} +(@pxref{libopts procedures}) library can still be used to process +configuration files. Below is a @t{Hello, World!} greeting program that tries +to load a configuration file @file{hello.conf} to see if it should use an +alternate greeting or to personalize the salutation. +@ignore +END == AO-DATA1 == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore + +@ignore +START == AO-DATA2 == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore + +@c === SECTION MARKER + +@node Config File Format +@section Configuration File Format +@cindex Configuration File + +The configuration file is designed to associate names and values, much like +an AutoGen Definition File (@pxref{Definitions File}). Unfortunately, the +file formats are different. Specifically, AutoGen Definitions provide for +simpler methods for the precise control of a value string and provides for +dynamically computed content. Configuration files have some established +traditions in their layout. So, they are different, even though they do +both allow for a single name to be associated with multiple values and they +both allow for hierarchical values. + +@menu +* config name/string-value:: assigning a string value to a configurable +* config integer-values:: integer values +* config nested-values:: hierarchical values +* config directives:: configuration file directives +* config comments:: comments in the configuration file +@end menu + +@node config name/string-value +@subsection assigning a string value to a configurable + +The basic syntax is a name followed by a value on a single line. They are +separated from each other by either white space, a colon (@code{:}) or an +equal sign (@code{=}). The colon or equal sign may optionally be surrounded +by additional white space. If more than one value line is needed, a +backslash (@code{\}) may be used to continue the value. The backslash (but +not the newline) will be erased. Leading and trailing white space is always +stripped from the value. + +Fundamentally, it looks like this: + +@example +name value for that name +name = another \ + multi-line value \ + for that name. +name: a *third* value for @code{name} +@end example + +If you need more control over the content of the value, you may enclose the +value in XML style brackets: +@example +<name>value </name> +@end example +@noindent +Within these brackets you need not (must not) continue the value data with +backslashes. You may also select the string formation rules to use, just +add the attribute after the name, thus: @code{<name keep>}. + +@table @samp +@item keep +This mode will keep all text between the brackets and not strip any +white space. +@item uncooked +This mode strips leading and trailing white space, but not do any +quote processing. This is the default and need not be specified. +@item cooked +The text is trimmed of leading and trailing white space and XML encodings +are processed. These encodings are slightly expanded over the XML +specification. They are specified with an ampersand followed by a value +name or numeric value and then a semicolon: + +@table @samp +@item amp +@itemx lt +@itemx gt +@itemx quot +@itemx apos +@itemx #dd +@itemx #xHH + +These are all per fairly standad HTML and/or XML encodings. +Additionally: + +@item bs +The ASCII back space character. +@item ff +The ASCII form feed character. +@item ht +The ASCII horizontal (normal) tab character. +@item cr +The ASCII carriage return character. +@item vt +The ASCII vertical tab character. +@item bel +The ASCII alarm bell character. +@item nl +The ASCII new line character. +@item space +The ASCII space character. Normally not necessary, but if you want +to preserve leading or trailing space characters, then use this. +@end table +@end table + +And here is an example of an XML-styled value: + +@example +<name cooked> + This is&nl;&ht;another multi-line +&ht;string example. +</name> +@end example + +The string value associated with @code{name} will be exactly the text enclosed +in quotes with the encoded characters @code{cooked} as you would expect (three +text lines with the last line not ending with a newline, but ending with a +period). + +@node config integer-values +@subsection integer values + +A name can be specified as having an integer value. To do this, you +must use the XML-ish format and specify a @code{type} attribute for +the name: + +@example +<name type=integer> 1234 </name> +@end example + +Boolean, enumeration and set membership types will be added as time +allows. @code{type=string} is also supported, but also is the default. + +@node config nested-values +@subsection hierarchical values + +In order to specify a hierarchical value, you *must* use XML-styled +formatting, specifying a type that is shorter and easier to spell: + +@example +<structured-name type=nested> + [[....]] +</structured-name> +@end example + +@noindent +The ellipsis may be filled with any legal configuration file name/value +assignments. + +@node config directives +@subsection configuration file directives +@cindex autoopts directives + +The @code{<?} marker indicates an XML directive. +There is only one directive supported: program sectioning, +though two syntaxes are supported. + +If, for example, you have a collection of programs that work closely +together and, likely, have a common set of options, these programs may use a +single, sectioned, configuration file. The file may be sectioned in either +of two ways. The two ways may not be intermixed in a single configuration +file. All text before the first segmentation line is processed, then only +the segment that applies: + +@table @samp +@item <?auto-options ...> +The @code{...} ellipsis may contain AutoOpts option processing options. +Currently, that consists of one or both of: + +@table @code +@item gnu +@itemx autoopts +to indicate GNU-standard or AutoOpts-standard layout of usage and +version information, and/or + +@item misuse-usage +@itemx no-misuse-usage +to indicate whether the available options should be listed when +an invalid option appears on the command line. +@end table +@noindent +Anything else will be silently ignored. + +@item <?program prog-name> +The @code{<?} marker indicates an XML directive. +The file is partitioned by these lines and the options are processed +for the @code{prog-name} program only before the first @code{<?program} +directive and the program section with a matching program name. + +@item [PROG_NAME] +This is basically an alias for @code{<?program prog-name>}, except that +the program name must be upper cased and segmented only with underscores +and it is @strong{not} recognized as a program segment when updating +configuration files with the @code{--save-opts} option. In other words, +use this only for Windows compatibility. +@end table + +@noindent +Segmentation does not apply if the config file is being parsed with +the @code{configFileLoad(3AutoOpts)} function. + +@node config comments +@subsection comments in the configuration file + +Comments are lines beginning with a hash mark (@code{#}), +XML-style comments (@code{<!-- arbitrary text -->}), and +unrecognized XML directives. + +@example +# this is a comment +<!-- this is also + a comment --> +<?this is + a bad comment ;-> +@end example + +@c === SECTION MARKER + +@node shell options +@section AutoOpts for Shell Scripts +@cindex shell options +@cindex configuration file + +AutoOpts may be used with shell scripts either by automatically creating a +complete program that will process command line options and pass back +the results to the invoking shell by issuing shell variable assignment +commands, or it may be used to generate portable shell code that can +be inserted into your script. + +The functionality of these features, of course, is somewhat constrained +compared with the normal program facilities. Specifically, you cannot +invoke callout procedures with either of these methods. Additionally, +if you generate a shell script to do the parsing: + +@enumerate +@item +You cannot obtain options from configuration files. +@item +You cannot obtain options from environment variables. +@item +You cannot save the option state to an option file. +@item +Option conflict/requirement verification is disabled. +@end enumerate + +Both of these methods are enabled by running AutoGen on +the definitions file with the additional main procedure attribute: + +@example +main = @{ main-type = shell-process; @}; +@end example +@noindent +or: +@example +main = @{ main-type = shell-parser; @}; +@end example + +If you do not supply a @code{proc-to-call}, it will default to +@code{optionPutShell}. That will produce a program that will process the +options and generate shell text for the invoking shell to interpret +(@pxref{binary-parser}). If you supply the name, @code{optionParseShell}, +then you will have a program that will generate a shell script that can parse +the options (@pxref{script-parser}). If you supply a different procedure +name, you will have to provide that routine and it may do whatever you like. + +@menu +* binary-parser:: Parsing with an Executable +* script-parser:: Parsing with a Portable Script +@end menu + +@node binary-parser +@subsection Parsing with an Executable + +The following commands are approximately all that is needed +to build a shell script command line option parser from +an option definition file: + +@example +autogen -L <opt-template-dir> test-errors.def +cc -o test-errors -L <opt-lib-dir> -I <opt-include-dir> \ + -DTEST_PROGRAM_OPTS test-errors.c -lopts +@end example + +The resulting program can then be used within your shell script as follows: + +@example +eval `./test-errors "$@@"` +if [ -z "$@{OPTION_CT@}" ] ; then exit 1 ; fi +test $@{OPTION_CT@} -gt 0 && shift $@{OPTION_CT@} +@end example +@ignore +END == AO-DATA2 == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore + +@ignore +START == AUTOINFO == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore + +@c === SECTION MARKER + +@node AutoInfo +@section Automated Info Docs +@cindex AutoInfo + +AutoOpts provides two templates for producing @file{.texi} documentation. +@file{agtexi-cmd.tpl} for the invoking section, and @file{aginfo3.tpl} for +describing exported library functions and macros. + +For both types of documents, the documentation level is selected by +passing a @samp{-DLEVEL=<level-name>} argument to AutoGen when you build +the document. (See the example invocation below.) + +Two files will be produced, a @file{.texi} file and a @file{.menu} file. +You should include the text in the @file{.menu} file in a @file{@@menu} +list, either with @file{@@include}-ing it or just copying text. +The @file{.texi} file should be @file{@@include}-ed where the invoking +section belongs in your document. + +The @file{.texi} file will contain an introductory paragraph, a menu +and a subordinate section for the invocation usage and for each +documented option. The introductory paragraph is normally the boiler +plate text, along the lines of: + +@example +This chapter documents the @@file@{AutoOpts@} generated usage text +and option meanings for the @@file@{your-program@} program. +@end example + +@noindent +or: + +@example +These are the publicly exported procedures from the lib@i{name} library. +Any other functions mentioned in the @i{header} file are for the private use +of the library. +@end example + +@menu +* command-info:: @code{invoking} info docs +* library-info:: library info docs +@end menu + +@node command-info +@subsection @code{invoking} info docs + +Using the option definitions for an AutoOpt client program, the +@file{agtexi-cmd.tpl} template will produce texinfo text that documents the +invocation of your program. The text emitted is designed to be included +in the full texinfo document for your product. It is not a stand-alone +document. The usage text for the @ref{autogen usage}, +@ref{getdefs usage} and @ref{columns usage} programs, are included in +this document and are all generated using this template. + +If your program's option definitions include a +@samp{prog-info-descrip} section, then that text will replace the +boilerplate introductory paragraph. + +@noindent +These files are produced by invoking the following command: + +@example +autogen -L $@{prefix@}/share/autogen -Tagtexi-cmd.tpl \ + -DLEVEL=section your-opts.def +@end example + +@noindent +Where @file{$@{prefix@}} is the AutoGen installation prefix +and @file{your-opts.def} is the name of your product's option +definition file. + +@node library-info +@subsection library info docs + +The @command{texinfo} doc for libraries is derived from mostly the same +information as is used for producing man pages @xref{man3}. The main +difference is that there is only one output file and the individual +functions are referenced from a @code{texi} menu. There is also +a small difference in the global attributes used: + +@multitable @columnfractions .02 .23 .65 +@item @tab lib_description +@tab A description of the library. This text appears before the menu. +If not provided, the standard boilerplate version will be inserted. +@item +@item @tab see_also +@tab The @code{SEE ALSO} functionality is not supported for the +@file{texinfo} documentation, so any @code{see_also} attribute will be +ignored. +@end multitable + +@noindent +These files are produced by invoking the following commands: + +@example +getdefs linenum srcfile template=aginfo3.tpl output=libexport.def \ + <source-file-list> + +autogen -L $@{prefix@}/share/autogen -DLEVEL=section libexport.def +@end example + +@noindent +Where @file{$@{prefix@}} is the AutoGen installation prefix +and @file{libexport.def} is some name that suits you. + +An example of this can be seen in this document, @xref{libopts procedures}. + +@c === SECTION MARKER + +@node AutoMan pages +@section Automated Man Pages +@cindex AutoMan pages + +AutoOpts provides two templates for producing man pages. +The command (@file{man1}) pages are derived from the options definition +file, and the library (@file{man3}) pages are derived from +stylized comments (@pxref{getdefs Invocation}). + +Man pages include a date in the footer. By default, this is derived from +the current date. However, this may be overridden with the @code{MAN_PAGE_DATE} +environment variable. If set and not empty, its contents will be copied +into where the output of @code{date '+%d %b %Y'} would otherwise go. + +Man pages may be formatted as either traditional man pages or using @code{mdoc} formatting. +The format is selected by selecting the appropriate template. + +@menu +* man1:: command line man pages +* man3:: library man pages +@end menu + +@node man1 +@subsection command line man pages + +Man pages for commands are documented using the @file{agman-cmd.tpl} +and @file{agmdoc-cmd.tpl} templates. If the options specify pulling +information from @file{RC}/@file{ini}/@file{cfg} files, then you may use +the @file{rc-sample.tpl} template to produce an example config file for +your program. + +Using the option definitions for an AutoOpts client program, +the @samp{agman-cmd.tpl} template will produce an nroff document +suitable for use as a @samp{man(1)} page document for a command +line command. The description section of the document is either +the @samp{prog-man-descrip} text, if present, or the @samp{detail} +text. + +Each option in the option definitions file is fully documented +in its usage. This includes all the information documented +above for each option (@pxref{option attributes}), plus +the @samp{doc} attribute is appended. Since the @samp{doc} +text is presumed to be designed for @code{texinfo} documentation, +@code{sed} is used to convert some constructs from @code{texi} +to @code{nroff}-for-@code{man}-pages. Specifically, + +@example +convert @@code, @@var and @@samp into \fB...\fP phrases +convert @@file into \fI...\fP phrases +Remove the '@@' prefix from curly braces +Indent example regions +Delete the example commands +Replace @samp{end example} command with ".br" +Replace the @samp{@@*} command with ".br" +@end example + +@noindent +This document is produced by invoking the following command: + +@example +autogen -L $@{prefix@}/share/autogen -Tagman-cmd.tpl options.def +@end example + +@noindent +Where @file{$@{prefix@}} is the AutoGen installation prefix and +@file{options.def} is the name of your product's option definition file. +I do not use this very much, so any feedback or improvements would be +greatly appreciated. + +@node man3 +@subsection library man pages + +Man pages for libraries are documented using the @file{agman3.tpl} template. + +Two global definitions are required, and then +one library man page is produced for each @code{export_func} definition +that is found. It is generally convenient to place these definitions +as @file{getdefs} comments (@pxref{getdefs Invocation}) near the procedure +definition, but they may also be a separate AutoGen definitions file +(@pxref{Definitions File}). Each function will be cross referenced +with their sister functions in a @file{SEE ALSO} section. A global +@code{see_also} definition will be appended to this cross referencing text. + +@noindent +The two global definitions required are: + +@multitable @columnfractions .02 .15 .77 +@item @tab library +@tab This is the name of your library, without the @file{lib} prefix. +The AutoOpts library is named @file{libopts.so...}, so the @code{library} +attribute would have the value @code{opts}. +@item +@item @tab header +@tab Generally, using a library with a compiled program entails +@code{#include}-ing a header file. Name that header with this attribute. +In the case of AutoOpts, it is generated and will vary based on the +name of the option definition file. Consequently, @file{your-opts.h} is +specified. +@end multitable + +@noindent +The @code{export_func} definition should contain the following attributes: + +@multitable @columnfractions .02 .15 .77 +@item @tab name +@tab The name of the procedure the library user may call. +@item @tab what +@tab A brief sentence describing what the procedure does. +@item @tab doc +@tab A detailed description of what the procedure does. +It may ramble on for as long as necessary to properly describe it. +@item @tab err +@tab A short description of how errors are handled. +@item @tab ret_type +@tab The data type returned by the procedure. +Omit this for @code{void} procedures. +@item @tab ret_desc +@tab Describe what the returned value is, if needed. +@item @tab private +@tab If specified, the function will @strong{not} be documented. +This is used, for example, to produce external declarations for functions +that are not available for public use, but are used in the generated text. +@item +@item @tab arg +@tab This is a compound attribute that contains: +@end multitable +@multitable @columnfractions .02 .15 .15 .62 +@item @tab @tab arg_type +@tab The data type of the argument. +@item @tab @tab arg_name +@tab A short name for it. +@item @tab @tab arg_desc +@tab A brief description. +@end multitable + +@noindent +As a @file{getdefs} comment, this would appear something like this: + +@example +/*=--subblock=arg=arg_type,arg_name,arg_desc =*/ +/*=* + * library: opts + * header: your-opts.h +=*/ +/*=export_func optionProcess + * + * what: this is the main option processing routine + * arg: + tOptions* + pOpts + program options descriptor + + * arg: + int + argc + program arg count + + * arg: + char** + argv + program arg vector + + * ret_type: int + * ret_desc: the count of the arguments processed + * + * doc: This is what it does. + * err: When it can't, it does this. +=*/ +@end example + +@noindent +Note the @code{subblock} and @code{library} comments. +@code{subblock} is an embedded @file{getdefs} +option (@pxref{getdefs subblock}) that tells it how to parse the +@code{arg} attribute. The @code{library} and @code{header} entries +are global definitions that apply to all the documented functions. + +@c === SECTION MARKER + +@node getopt_long +@section Using getopt(3C) +@cindex getopt_long + +There is a template named, @file{getopt.tpl} that is distributed with +AutoOpts. Using that template instead of @file{options.tpl} will produce +completely independent source code that will parse command line options. It +will utilize either the standard @code{getopt(3C)} or the GNU +@code{getopt_long(3GNU)} function to drive the parsing. Which is used is +selected by the presence or absence of the @code{long-opts} program attribute. +It will save you from being dependent upon the @code{libopts} library @i{and} +it produces code ready for internationalization. However, it also carries +with it some limitations on the use of AutoOpts features and some requirements +on the build environment. + +@strong{PLEASE NOTE}: in processing the option definitions to produce +the usage text, it is necessary to compile some generated code in a +temporary directory. That means that all the include directories +needed to compile the code must be full path names and not relative +directory names. ``.'' is a relative directory name. To specify +``-I.'' in the @code{CFLAGS} environment variable, you must expand it. +For example, use: +@example +CFLAGS=-I`pwd` +@end example + +@menu +* getopt limitations:: getopt feature limitations +* getopt building:: getopt build requirements +@end menu + +@node getopt limitations +@subsection getopt feature limitations + +This list of limitations is relative to the full list of AutoOpts +supported features, @xref{Features}. + +@enumerate +@item +You cannot automatically take advantage of environment variable options or +automated parsing of configuration files (@code{rc} or @code{ini} files). +Consequently, the resulting code does not support @file{--load-opts} or +@file{--save-opts} options automatically. + +@item +You cannot use set membership, enumerated, range checked or stacked +argument type options. In fact, you cannot use anything that depends +upon the @code{libopts} library. You are constrained to options that +take @code{@code{string}} arguments, though you may handle the option +argument with a callback procedure. + +@item +Special disablement and/or enablement prefixes are not recognized. + +@item +Option coordination with external libraries will not work. + +@item +Every option must be @code{settable} because the emitted code +depends upon the @code{SET_OPT_XXX} macros having been defined. +Specify this as a global (program) attribute. + +@item +You must specify a main procedure attribute (@pxref{Generated main}). +The @file{getopt.tpl} template depends upon being able to compile the +traditional .c file into a program and get it to emit the usage text. + +@item +For the same reason, the traditional option parsing table code must be +emitted @b{before} the @file{getopt.tpl} template gets expanded. + +@item +The usage text is, therefore, statically defined. +@end enumerate + +@node getopt building +@subsection getopt build requirements + +You must supply some compile and link options via environment variables. + +@table @samp +@item srcdir +In case the option definition file lives in a different directory. +@item CFLAGS +Any special flags required to compile. The flags from +@code{autoopts-config cflags} will be included automatically. Since +the creation of the option parsing code includes creating a program +that prints out help text, if it is necessary to include files from +various directories to compile that program, you will need to specify +those directories with @option{-Idirpath} text in the @code{CFLAGS}. +Some experimentation may be necessary in that case. + +@strong{NOTE}: the @option{-Idirpath} text is only needed if your option +callback functions include code that require additional @code{#include} +directives. +@item LDFLAGS +Any special flags required to link. The flags from +@code{autoopts-config ldflags} will be included automatically. This +is required only if additional link flags for the help text emission +program might be needed. +@item CC +This is needed only if @code{@code{cc}} cannot be found in @env{$PATH} +(or it is not the one you want). +@end table + +To use this, set the exported environment variables and specify @code{getopt} +as the default template in your option definitions file +(@pxref{Identification}). You will have @i{four} new files. Assuming your +definitions were in a file named @file{myprog-opts.def} and your program name +was specified as @file{progname}, the resulting files would be created: +@file{myprog-opts.h}, @file{myprog-opts.c}, @file{getopt-progname.h} and +@file{getopt-progname.c}. You must compile and link both @file{.c} files into +your program. If there are link failures, then you are using AutoOpts +features that require the @file{libopts} library. You must remove these +features, @xref{getopt limitations}. + +These generated files depend upon configure defines to work correctly. +Therefore, you must specify a @code{config-header} attribute +(@pxref{programming attributes}) and ensure it has @code{#defines} for +either @code{HAVE_STDINT_H} or @code{HAVE_INTTYPES_H}; either +@code{HAVE_SYS_LIMITS_H} or @code{HAVE_LIMITS_H}; and +@code{HAVE_SYSEXITS_H}, if the @file{sysexits.h} header is available. +The required header files for these defines are, respectively, +the @file{/usr/include} files named: +@itemize @bullet +@item stdint.h +@item inttypes.h +@item sys/limits.h +@item limits.h +@item sysexits.h +@end itemize + +@noindent +The following header files must also exist on the build platform: +@itemize @bullet +@item sys/types.h +@item stdio.h +@item string.h +@item unistd.h -- or, for getopt_long: +@item getopt.h +@end itemize +@c === SECTION MARKER + +@node i18n +@section Internationalizing AutoOpts +@cindex Internationalizing AutoOpts + +The generated code for AutoOpts will enable and disable the translation of +AutoOpts run time messages. If @code{ENABLE_NLS} is defined at compile time +and @code{no-xlate} has been not set to the value @emph{anything}, then the +@code{_()} macro may be used to specify a translation function. If undefined, +it will default to @code{gettext(3GNU)}. This define will also enable a +callback function that @code{optionProcess} invokes at the beginning of option +processing. The AutoOpts @code{libopts} library will always check for this +@emph{compiled with NLS} flag, so @code{libopts} does not need to be specially +compiled. The strings returned by the translation function will be +@code{strdup(3)-ed} and kept. They will not be re-translated, even if the +locale changes, but they will also not be dependent upon reused or unmappable +memory. + +You should also ensure that the @code{ATTRIBUTE_FORMAT_ARG()} gets +@code{#define}-ed to something useful. There is an autoconf macro +named @code{AG_COMPILE_FORMAT_ARG} in @file{ag_macros.m4} that will +set it appropriately for you. If you do not do this, then translated +formatting strings may trigger GCC compiler warnings. + +To internationalize option processing, you should first internationalize your +program. Then, the option processing strings can be added to your translation +text by processing the AutoOpts-generated @file{my-opts.c} file and adding the +distributed @file{po/usage-txt.pot} file. (Also by extracting the strings +yourself from the @file{usage-txt.h} file.) When you call +@code{optionProcess}, all of the user visible AutoOpts strings will be passed +through the localization procedure established with the @code{_()} +preprocessing macro. + +All of this is @emph{dis}-abled if you specify the global attribute +@code{no-xlate} to @emph{anything}. + +@c === SECTION MARKER + +@node Naming Conflicts +@section Naming Conflicts +@cindex Naming Conflicts + +AutoOpts generates a header file that contains many C preprocessing macros and +several external names. For the most part, they begin with either @code{opt_} +or @code{option}, or else they end with @code{_opt}. If this happens to +conflict with other macros you are using, or if you are compiling multiple +option sets in the same compilation unit, the conflicts can be avoided. You +may specify an external name @code{prefix} (@pxref{program attributes}) for +all of the names generated for each set of option definitions. + +Among these macros, several take an option name as a macro argument. +Sometimes, this will inconveniently conflict. For example, if you specify an +option named, @code{debug}, the emitted code will presume that @code{DEBUG} is +not a preprocessing name. Or also, if you are building on a Windows platform, +you may find that MicroSoft has usurped a number of user space names in its +header files. Consequently, you will get a preprocessing error if you use, +for example, @code{HAVE_OPT(DEBUG)} or @code{HAVE_OPT(INTERNAL)} +(@pxref{HAVE_OPT}) in your code. You may trigger an obvious warning for such +conflicts by specifying the @code{guard-option-names} attribute +(@pxref{program attributes}). That emitted code will also @code{#undef}-ine +the conflicting name. + +@node All Attribute Names +@section All Attribute Names + +This is the list of all the option attributes used in the various +option processing templates. There are several flavors of attributes, +and these are not distinguished here. + +@itemize @bullet +@item +Valid, current attributes that you are encouraged to use. +@item +Internally generated attributes that you cannot use at all. +I need to prefix these with a distinguished prefix. e.g. @code{ao-} +@item +Valid attributes, but are deprecated. Alternates should be documented. +@end itemize + +This list is derived by running many example option definitions through the +option generation and man page templates and noting which attributes are +actually used. There may be a few that are used but not exercised in my +testing. If so, I need to ferret those out and test them, too. + +@example +addtogroup aliases allow_errors arg_default +arg_name arg_optional arg_range arg_type +argument author call_proc cmd_section +comment_char concept config_header copyright +date default deprecated descrip +detail die_code disable disable_load +disable_save doc doc_section doc_sub +doc_sub_cmd documentation ds_format ds_text +ds_type eaddr enable enabled +environrc equivalence exit_desc exit_name +explain export extract_code field +file_fail_code flag flag_code flag_proc +flags_cant flags_must full_usage gnu_usage +guard_option_names handler_proc handler_type help_type +help_value home_rc homerc ifdef +ifndef immed_disable immediate include +interleaved keyword lib_name library +load_opts_value long_opts main_fini main_init +main_type max min more_help_value +must_set name no_command no_libopts +no_misuse_usage no_preset no_xlate omit_texi +omitted_usage open_file opt_state option_format +option_info owner package prefix +prefix_enum preserve_case prog_descrip prog_info_descrip +prog_man_descrip prog_name prog_title rcfile +reorder_args reset_value resettable save_opts_value +scaled set_desc set_index settable +short_usage stack_arg stdin_input sub_name +sub_text sub_type test_main translators +type unshar_file_code unstack_arg usage +usage_message usage_opt usage_value value +vendor_opt version version_proc version_value +@end example + +@node Option Define Names +@section Option Definition Name Index +@printindex vr + +@ignore +END == AUTOINFO == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore + +@c = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +@c +@c TRAILER + +@c LocalWords: AutoGen texinfo Korb tpl bruce Exp texi autogen setfilename AG +@c LocalWords: settitle setchapternewpage dne dircategory direntry ifinfo gpl +@c LocalWords: AutoOpts snprintfv titlepage vskip pt filll sp dir xref cindex +@c LocalWords: AutoGen's noindent rc ini enum IDX const az upcase ENDFOR ESAC +@c LocalWords: optargs egcs inclhack sh fixincl autoconf endif var templ dirs +@c LocalWords: def txt cd STR str ifdef alist downcase sprintf arg lexer +@c LocalWords: srcfile linenum subblock defParse srcdir sed POSIX printf expr +@c LocalWords: stdout expr func gfunc tr findex exparg desc desc sep macfunc +@c LocalWords: ing getdefs libopts src ksh forcomma csh env Sourced autoopts +@c LocalWords: mkmerge builddir ADDON AutoGetopts getopt glibc argp perl awk +@c LocalWords: printindex cp fn diff --git a/doc/autogen.info b/doc/autogen.info new file mode 100644 index 0000000..33133c4 --- /dev/null +++ b/doc/autogen.info @@ -0,0 +1,523 @@ +This is autogen.info, produced by makeinfo version 6.5 from +autogen.texi. + +This manual is for GNU AutoGen version 5.18, updated August 2018. + + Copyright (C) 1992-2018 by Bruce Korb. + + Permission is granted to copy, distribute and/or modify this + document under the terms of the GNU Free Documentation License, + Version 1.2 or any later version published by the Free Software + Foundation; with no Invariant Sections, no Front-Cover Texts, and + no Back-Cover Texts. +INFO-DIR-SECTION GNU programming tools +START-INFO-DIR-ENTRY +* AutoGen: (autogen). The Automated Program Generator +END-INFO-DIR-ENTRY + + This file documents GNU AutoGen Version 5.18. + + AutoGen copyright (C) 1992-2018 Bruce Korb AutoOpts copyright (C) +1992-2018 Bruce Korb snprintfv copyright (C) 1999-2000 Gary V. Vaughan + + AutoGen 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. + + AutoGen is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +Public License for more details. + + You should have received a copy of the GNU General Public License +along with this program. If not, see <http://www.gnu.org/licenses/>. + + +Indirect: +autogen.info-1: 1430 +autogen.info-2: 303004 + +Tag Table: +(Indirect) +Node: Top1430 +Node: Introduction2868 +Node: Generalities4523 +Node: Example Usage7327 +Node: csh/zsh caveat12566 +Node: Testimonial13929 +Node: Definitions File16140 +Node: Identification18045 +Node: Definitions19332 +Node: def-list21055 +Node: double-quote-string21944 +Node: single-quote-string22813 +Node: simple-string23552 +Node: shell-generated24311 +Node: scheme-generated24996 +Node: here-string25393 +Node: concat-string27411 +Node: Index Assignments28394 +Node: Dynamic Text29855 +Node: Directives31030 +Node: Predefines36529 +Node: Comments38285 +Node: Example38700 +Node: Full Syntax39434 +Node: Alternate Definition53769 +Node: Template File55843 +Node: pseudo macro57472 +Node: naming values63171 +Node: expression syntax64452 +Node: apply code65687 +Node: basic expression68200 +Node: AutoGen Functions70493 +Node: SCM ag-fprintf75477 +Node: SCM ag-function?76258 +Node: SCM base-name76636 +Node: SCM chdir77015 +Node: SCM count77483 +Node: SCM def-file77966 +Node: SCM def-file-line78335 +Node: SCM dne79255 +Node: SCM emit80904 +Node: SCM emit-string-table81412 +Node: SCM error81860 +Node: SCM exist?82781 +Node: SCM find-file83553 +Node: SCM first-for?84095 +Node: SCM for-by84579 +Node: SCM for-from85012 +Node: SCM for-index85450 +Node: SCM for-sep85904 +Node: SCM for-to86447 +Node: SCM found-for?86875 +Node: SCM get87309 +Node: SCM get-c-name87799 +Node: SCM get-down-name88358 +Node: SCM get-up-name88984 +Node: SCM high-lim89600 +Node: SCM insert-file90297 +Node: SCM insert-suspended90667 +Node: SCM last-for?91110 +Node: SCM len91585 +Node: SCM low-lim92098 +Node: SCM make-header-guard92434 +Node: SCM make-tmp-dir94186 +Node: SCM match-value?94541 +Node: SCM max-file-time95444 +Node: SCM mk-gettextable95962 +Node: SCM out-delete96410 +Node: SCM out-depth96906 +Node: SCM out-emit-suspended97254 +Node: SCM out-line97670 +Node: SCM out-move98044 +Node: SCM out-name98527 +Node: SCM out-pop98983 +Node: SCM out-push-add99608 +Node: SCM out-push-new100018 +Node: SCM out-resume100636 +Node: SCM out-suspend101125 +Node: SCM out-switch101827 +Node: SCM output-file-next-line102406 +Node: SCM set-option103336 +Node: SCM set-writable103747 +Node: SCM stack104320 +Node: SCM stack-join104706 +Node: SCM suffix105227 +Node: SCM tpl-file105539 +Node: SCM tpl-file-line106031 +Node: SCM tpl-file-next-line107020 +Node: SCM warn107595 +Node: SCM autogen-version108080 +Node: SCM c-file-line-fmt108439 +Node: Common Functions108860 +Node: SCM agpl114213 +Node: SCM bsd114671 +Node: SCM c-string115148 +Node: SCM error-source-line115914 +Node: SCM extract116447 +Node: SCM format-arg-count119781 +Node: SCM fprintf120691 +Node: SCM gperf121241 +Node: SCM gperf-code121970 +Node: SCM gpl123160 +Node: SCM hide-email123625 +Node: SCM html-escape-encode124088 +Node: SCM in?124588 +Node: SCM join125026 +Node: SCM kr-string125538 +Node: SCM lgpl126105 +Node: SCM license126628 +Node: SCM license-description127175 +Node: SCM license-full127928 +Node: SCM license-info130082 +Node: SCM license-name131038 +Node: SCM make-gperf131398 +Node: SCM makefile-script132393 +Node: SCM max135174 +Node: SCM min135486 +Node: SCM prefix135789 +Node: SCM printf136682 +Node: SCM raw-shell-str137248 +Node: SCM shell137997 +Node: SCM shell-str139001 +Node: SCM shellf141925 +Node: SCM sprintf142373 +Node: SCM string-capitalize142756 +Node: SCM string-capitalize!143218 +Node: SCM *=*143559 +Node: SCM *==*144127 +Node: SCM string-downcase144533 +Node: SCM string-downcase!144944 +Node: SCM *~145305 +Node: SCM *~~145725 +Node: SCM *=146105 +Node: SCM *==146485 +Node: SCM ==146895 +Node: SCM ~147239 +Node: SCM =147708 +Node: SCM *~*148488 +Node: SCM *~~*148900 +Node: SCM ~~149294 +Node: SCM ~*149658 +Node: SCM ~~*150070 +Node: SCM =*150461 +Node: SCM ==*150847 +Node: SCM string-substitute151230 +Node: SCM string-table-add151992 +Node: SCM string-table-add-ref152794 +Node: SCM string-table-new153366 +Node: SCM string-table-size156081 +Node: SCM string->c-name!156503 +Node: SCM string->camelcase157034 +Node: SCM string-tr157528 +Node: SCM string-tr!158005 +Node: SCM string-upcase158664 +Node: SCM string-upcase!159071 +Node: SCM sub-shell-str159433 +Node: SCM sum159884 +Node: SCM time-string->number160217 +Node: SCM version-compare160849 +Node: native macros161791 +Node: AGMacro syntax164990 +Node: BREAK167131 +Node: CASE167487 +Node: COMMENT170195 +Node: CONTINUE170742 +Node: DEBUG171002 +Node: DEFINE171869 +Node: ELIF174100 +Node: ELSE174576 +Node: ENDDEF174949 +Node: ENDFOR175216 +Node: ENDIF175518 +Node: ENDWHILE175796 +Node: ESAC176090 +Node: EXPR176372 +Node: FOR176851 +Node: IF179887 +Node: INCLUDE180924 +Node: INVOKE181572 +Node: RETURN182572 +Node: SELECT183111 +Node: UNKNOWN183603 +Node: WHILE184132 +Node: shell command184895 +Node: guile command185526 +Node: output controls185949 +Node: Augmenting AutoGen187953 +Node: shell commands188503 +Node: guile macros189326 +Node: guile callouts189785 +Node: AutoGen macros191977 +Node: autogen Invocation192594 +Node: autogen usage194540 +Node: autogen input-select200309 +Ref: autogen templ-dirs200618 +Ref: autogen override-tpl201115 +Ref: autogen definitions201539 +Ref: autogen shell202221 +Ref: autogen no-fmemopen202836 +Ref: autogen equate203627 +Node: autogen out-handling203944 +Ref: autogen base-name204226 +Ref: autogen source-time205268 +Ref: autogen writable205759 +Node: autogen debug-tpl205992 +Ref: autogen loop-limit206386 +Ref: autogen timeout206786 +Ref: autogen trace207329 +Ref: autogen trace-out209312 +Ref: autogen show-defs209838 +Ref: autogen used-defines210230 +Ref: autogen core210958 +Node: autogen processing211479 +Ref: autogen skip-suffix211867 +Ref: autogen select-suffix212533 +Ref: autogen define213052 +Ref: autogen undefine214370 +Node: autogen dep-track214820 +Ref: autogen make-dep215094 +Node: autogen autoopts-opts218411 +Ref: autogen no-abort218668 +Node: autogen config218927 +Node: autogen exit status221995 +Node: autogen Examples223357 +Node: Installation224084 +Node: configuring224402 +Node: AutoGen CGI227248 +Node: signal names229692 +Node: installing230911 +Node: AutoOpts233694 +Node: Features235454 +Node: Licensing243393 +Node: Caveats244522 +Node: Quick Start247528 +Node: quick ao problem248699 +Node: quick ao def249313 +Node: quick ao build250563 +Node: quick ao help251164 +Node: quick ao usage251385 +Node: quick ao docs252485 +Node: Option Definitions253402 +Node: program attributes255328 +Node: usage attributes257229 +Node: config attributes261388 +Node: programming attributes264732 +Node: presentation attributes270315 +Node: library attributes273638 +Node: lib and program274515 +Node: lib called276935 +Node: prog calls lib278223 +Node: information attributes279101 +Node: Generated main283754 +Node: main guile285210 +Node: main shell-process286117 +Node: main shell-parser287642 +Node: main main288289 +Node: main include289221 +Node: main invoke290166 +Node: main for-each290654 +Node: main-for-each-proc291586 +Node: main-for-each-type292796 +Node: main-for-each-code296262 +Node: main-for-each-opts297240 +Node: option attributes298378 +Node: Required Attributes299765 +Node: Common Attributes303004 +Node: Immediate Action306911 +Node: Option Conflict Attributes309223 +Node: opt-attr settable310009 +Node: opt-attr no-preset310598 +Node: opt-attr equivalence310957 +Node: opt-attr aliases313181 +Node: opt-attr default option313853 +Node: opt-attr documentation314660 +Node: opt-attr translators316189 +Node: Option Arguments316802 +Node: arg-type string318932 +Node: arg-type number319233 +Node: arg-type boolean321135 +Node: arg-type keyword321583 +Node: arg-type set membership323549 +Node: arg-type hierarchy325940 +Node: arg-type file name326727 +Node: arg-type time-duration327975 +Node: arg-type time-date329929 +Node: arg-keyword330712 +Node: arg-optional331567 +Node: arg-default333223 +Node: Option Argument Handling333582 +Node: Internationalizing Options337810 +Node: documentation attributes339762 +Node: per option attributes340346 +Node: global option attributes341881 +Node: automatic options348917 +Node: standard options356133 +Node: AutoOpts API358461 +Node: Option Processing Data361358 +Node: CLEAR_OPT364966 +Node: COUNT_OPT365290 +Node: DESC365698 +Node: DISABLE_OPT_name366116 +Node: ENABLED_OPT366675 +Node: ERRSKIP_OPTERR367114 +Node: ERRSTOP_OPTERR367445 +Node: HAVE_OPT367899 +Node: ISSEL_OPT368271 +Node: ISUNUSED_OPT368579 +Node: OPTION_CT368889 +Node: OPT_ARG369245 +Node: OPT_NO_XLAT_CFG_NAMES369802 +Node: OPT_NO_XLAT_OPT_NAMES370337 +Node: OPT_VALUE_name370816 +Node: OPT_XLAT_CFG_NAMES371281 +Node: OPT_XLAT_OPT_NAMES372199 +Node: RESTART_OPT372959 +Node: SET_OPT_name374119 +Node: STACKCT_OPT375070 +Node: STACKLST_OPT375859 +Node: START_OPT376686 +Node: STATE_OPT376942 +Node: USAGE377903 +Node: VALUE_OPT_name379368 +Node: VERSION380028 +Node: WHICH_IDX_name380611 +Node: WHICH_OPT_name381175 +Node: teOptIndex381749 +Node: OPTIONS_STRUCT_VERSION382346 +Node: libopts procedures383139 +Node: libopts-ao_string_tokenize384834 +Node: libopts-configFileLoad386866 +Node: libopts-optionFileLoad388242 +Node: libopts-optionFindNextValue389874 +Node: libopts-optionFindValue391150 +Node: libopts-optionFree392268 +Node: libopts-optionGetValue392911 +Node: libopts-optionLoadLine394221 +Node: libopts-optionMemberList395716 +Node: libopts-optionNextValue396369 +Node: libopts-optionOnlyUsage397717 +Node: libopts-optionPrintVersion398434 +Node: libopts-optionPrintVersionAndReturn399037 +Node: libopts-optionProcess399818 +Node: libopts-optionRestore401645 +Node: libopts-optionSaveFile402531 +Node: libopts-optionSaveState403776 +Node: libopts-optionUnloadNested404984 +Node: libopts-optionVersion405628 +Node: libopts-strequate406194 +Node: libopts-streqvcmp406829 +Node: libopts-streqvmap407829 +Node: libopts-strneqvcmp408996 +Node: libopts-strtransform410110 +Node: Multi-Threading410859 +Node: option descriptor411858 +Node: Using AutoOpts412509 +Node: local use413119 +Node: binary not installed414769 +Node: binary pre-installed415270 +Node: source pre-installed415899 +Node: source not installed416958 +Node: Presetting Options418090 +Node: loading rcfile420353 +Node: saving rcfile422061 +Node: sample rcfile422570 +Node: environrc431737 +Node: config example433643 +Node: Config File Format435547 +Node: config name/string-value436593 +Node: config integer-values439444 +Node: config nested-values439949 +Node: config directives440436 +Node: config comments442431 +Node: shell options442861 +Node: binary-parser444680 +Node: script-parser447071 +Node: AutoInfo471404 +Node: command-info472849 +Node: library-info473894 +Node: AutoMan pages475160 +Node: man1476059 +Node: man3477801 +Node: getopt_long481111 +Node: getopt limitations482457 +Node: getopt building484048 +Node: i18n486676 +Node: Naming Conflicts488548 +Node: All Attribute Names489936 +Node: Option Define Names492935 +Node: Add-Ons505441 +Node: AutoFSM506519 +Node: AutoXDR506942 +Node: AutoEvents507772 +Node: Bit Maps509019 +Node: enums509986 +Node: enum-code512915 +Node: masks519381 +Node: columns Invocation521030 +Node: columns usage522811 +Node: columns dimensions526428 +Ref: columns width526672 +Ref: columns columns527121 +Ref: columns col-width527437 +Ref: columns tab-width527749 +Node: columns treatment527942 +Ref: columns spread528181 +Ref: columns fill528546 +Ref: columns indent529008 +Ref: columns first-indent529310 +Ref: columns format530033 +Ref: columns separation530340 +Ref: columns line-separation530596 +Ref: columns ending530842 +Node: columns ordering531005 +Ref: columns by-columns531254 +Ref: columns sort531561 +Node: columns input-text531897 +Ref: columns input532150 +Node: columns config532396 +Node: columns exit status535136 +Node: columns See Also535717 +Node: getdefs Invocation535992 +Node: getdefs usage538886 +Node: getdefs def-selection542179 +Ref: getdefs defs-to-get542475 +Ref: getdefs subblock542800 +Ref: getdefs listattr543743 +Node: getdefs enumerating544443 +Ref: getdefs ordering544703 +Ref: getdefs first-index545297 +Node: getdefs doc-insert545598 +Ref: getdefs filelist545845 +Ref: getdefs assign546218 +Ref: getdefs common-assign546567 +Ref: getdefs copy546912 +Ref: getdefs srcfile547236 +Ref: getdefs linenum547643 +Node: getdefs input-files548030 +Ref: getdefs input548285 +Node: getdefs doc-output548891 +Ref: getdefs output549139 +Ref: getdefs autogen549454 +Ref: getdefs template550020 +Ref: getdefs agarg550204 +Ref: getdefs base-name550615 +Node: getdefs config551096 +Node: getdefs exit status553319 +Node: getdefs See Also554034 +Node: xml2ag Invocation554309 +Node: xml2ag usage556196 +Node: xml2ag the-xml2ag-option560493 +Ref: xml2ag output560775 +Node: xml2ag autogen-options561007 +Ref: xml2ag templ-dirs561488 +Ref: xml2ag override-tpl561764 +Ref: xml2ag definitions561940 +Ref: xml2ag shell562097 +Ref: xml2ag no-fmemopen562282 +Ref: xml2ag equate562393 +Ref: xml2ag base-name562577 +Ref: xml2ag source-time562760 +Ref: xml2ag writable562880 +Ref: xml2ag loop-limit563097 +Ref: xml2ag timeout563263 +Ref: xml2ag trace563437 +Ref: xml2ag trace-out564019 +Ref: xml2ag show-defs564185 +Ref: xml2ag used-defines564307 +Ref: xml2ag core564424 +Ref: xml2ag skip-suffix564996 +Ref: xml2ag select-suffix565371 +Ref: xml2ag define565635 +Ref: xml2ag undefine565906 +Ref: xml2ag make-dep566181 +Node: xml2ag exit status566411 +Node: snprintfv566754 +Node: Future569268 +Node: Copying This Manual569607 +Node: Concept Index569893 +Node: Function Index591435 + +End Tag Table diff --git a/doc/autogen.info-1 b/doc/autogen.info-1 new file mode 100644 index 0000000..b111e17 --- /dev/null +++ b/doc/autogen.info-1 @@ -0,0 +1,7363 @@ +This is autogen.info, produced by makeinfo version 6.5 from +autogen.texi. + +This manual is for GNU AutoGen version 5.18, updated August 2018. + + Copyright (C) 1992-2018 by Bruce Korb. + + Permission is granted to copy, distribute and/or modify this + document under the terms of the GNU Free Documentation License, + Version 1.2 or any later version published by the Free Software + Foundation; with no Invariant Sections, no Front-Cover Texts, and + no Back-Cover Texts. +INFO-DIR-SECTION GNU programming tools +START-INFO-DIR-ENTRY +* AutoGen: (autogen). The Automated Program Generator +END-INFO-DIR-ENTRY + + This file documents GNU AutoGen Version 5.18. + + AutoGen copyright (C) 1992-2018 Bruce Korb AutoOpts copyright (C) +1992-2018 Bruce Korb snprintfv copyright (C) 1999-2000 Gary V. Vaughan + + AutoGen 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. + + AutoGen is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +Public License for more details. + + You should have received a copy of the GNU General Public License +along with this program. If not, see <http://www.gnu.org/licenses/>. + + +File: autogen.info, Node: Top, Next: Introduction, Up: (dir) + +The Automated Program Generator +******************************* + +This file documents AutoGen version 5.18. It is a tool designed for +generating program files that contain repetitive text with varied +substitutions. This document is very long because it is intended as a +reference document. For a quick start example, *Note Example Usage::. + + The AutoGen distribution includes the basic generator engine and +several add-on libraries and programs. Of the most general interest +would be Automated Option processing, *Note AutoOpts::, which also +includes stand-alone support for configuration file parsing, *Note +Features::. *Note Add-on packages for AutoGen: Add-Ons, section for +additional programs and libraries associated with AutoGen. + + This edition documents version 5.18, August 2018. + +* Menu: + +* Introduction:: AutoGen's Purpose +* Definitions File:: AutoGen Definitions File +* Template File:: AutoGen Template +* Augmenting AutoGen:: Augmenting AutoGen Features +* autogen Invocation:: Invoking AutoGen +* Installation:: Configuring and Installing +* AutoOpts:: Automated Option Processing +* Add-Ons:: Add-on packages for AutoGen +* Future:: Some ideas for the future. +* Copying This Manual:: Copying This Manual +* Concept Index:: General index +* Function Index:: Function index + + +File: autogen.info, Node: Introduction, Next: Definitions File, Up: Top + +1 Introduction +************** + +AutoGen is a tool designed for generating program files that contain +repetitive text with varied substitutions. Its goal is to simplify the +maintenance of programs that contain large amounts of repetitious text. +This is especially valuable if there are several blocks of such text +that must be kept synchronized in parallel tables. + + An obvious example is the problem of maintaining the code required +for processing program options and configuration settings. Processing +options requires a minimum of four different constructs be kept in +proper order in different places in your program. You need at least: + + 1. The flag character in the flag string, + 2. code to process the flag when it is encountered, + 3. a global state variable or two, and + 4. a line in the usage text. + +You will need more things besides this if you choose to implement long +option names, configuration (rc/ini) file processing, environment +variable settings and keep all the documentation for these up to date. +This can be done mechanically; with the proper templates and this +program. In fact, it has already been done and AutoGen itself uses it +*Note AutoOpts::. For a simple example of Automated Option processing, +*Note Quick Start::. For a full list of the Automated Option features, +*Note Features::. Be forewarned, though, the feature list is +ridiculously extensive. + +* Menu: + +* Generalities:: The Purpose of AutoGen +* Example Usage:: A Simple Example +* csh/zsh caveat:: csh/zsh caveat +* Testimonial:: A User's Perspective + + +File: autogen.info, Node: Generalities, Next: Example Usage, Up: Introduction + +1.1 The Purpose of AutoGen +========================== + +The idea of this program is to have a text file, a template if you will, +that contains the general text of the desired output file. That file +includes substitution expressions and sections of text that are +replicated under the control of separate definition files. + + AutoGen was designed with the following features: + + 1. The definitions are completely separate from the template. By + completely isolating the definitions from the template it greatly + increases the flexibility of the template implementation. A + secondary goal is that a template user only needs to specify those + data that are necessary to describe his application of a template. + + 2. Each datum in the definitions is named. Thus, the definitions can + be rearranged, augmented and become obsolete without it being + necessary to go back and clean up older definition files. Reduce + incompatibilities! + + 3. Every definition name defines an array of values, even when there + is only one entry. These arrays of values are used to control the + replication of sections of the template. + + 4. There are named collections of definitions. They form a nested + hierarchy. Associated values are collected and associated with a + group name. These associated data are used collectively in sets of + substitutions. + + 5. The template has special markers to indicate where substitutions + are required, much like the '${VAR}' construct in a shell 'here + doc'. These markers are not fixed strings. They are specified at + the start of each template. Template designers know best what fits + into their syntax and can avoid marker conflicts. + + We did this because it is burdensome and difficult to avoid + conflicts using either M4 tokenization or C preprocessor + substitution rules. It also makes it easier to specify expressions + that transform the value. Of course, our expressions are less + cryptic than the shell methods. + + 6. These same markers are used, in conjunction with enclosed keywords, + to indicate sections of text that are to be skipped and for + sections of text that are to be repeated. This is a major + improvement over using C preprocessing macros. With the C + preprocessor, you have no way of selecting output text because it + is an unvarying, mechanical substitution process. + + 7. Finally, we supply methods for carefully controlling the output. + Sometimes, it is just simply easier and clearer to compute some + text or a value in one context when its application needs to be + later. So, functions are available for saving text or values for + later use. + + +File: autogen.info, Node: Example Usage, Next: csh/zsh caveat, Prev: Generalities, Up: Introduction + +1.2 A Simple Example +==================== + +This is just one simple example that shows a few basic features. If you +are interested, you also may run "make check" with the 'VERBOSE' +environment variable set and see a number of other examples in the +'agen5/test' directory. + + Assume you have an enumeration of names and you wish to associate +some string with each name. Assume also, for the sake of this example, +that it is either too complex or too large to maintain easily by hand. +We will start by writing an abbreviated version of what the result is +supposed to be. We will use that to construct our output templates. + +In a header file, 'list.h', you define the enumeration and the global +array containing the associated strings: + + typedef enum { + IDX_ALPHA, + IDX_BETA, + IDX_OMEGA } list_enum; + + extern char const* az_name_list[ 3 ]; + +Then you also have 'list.c' that defines the actual strings: + + #include "list.h" + char const* az_name_list[] = { + "some alpha stuff", + "more beta stuff", + "final omega stuff" }; + +First, we will define the information that is unique for each +enumeration name/string pair. This would be placed in a file named, +'list.def', for example. + + autogen definitions list; + list = { list_element = alpha; + list_info = "some alpha stuff"; }; + list = { list_info = "more beta stuff"; + list_element = beta; }; + list = { list_element = omega; + list_info = "final omega stuff"; }; + + The 'autogen definitions list;' entry defines the file as an AutoGen +definition file that uses a template named 'list'. That is followed by +three 'list' entries that define the associations between the +enumeration names and the strings. The order of the differently named +elements inside of list is unimportant. They are reversed inside of the +'beta' entry and the output is unaffected. + + Now, to actually create the output, we need a template or two that +can be expanded into the files you want. In this program, we use a +single template that is capable of multiple output files. The +definitions above refer to a 'list' template, so it would normally be +named, 'list.tpl'. + + It looks something like this. (For a full description, *Note +Template File::.) + + [+ AutoGen5 template h c +] + [+ CASE (suffix) +][+ + == h +] + typedef enum {[+ + FOR list "," +] + IDX_[+ (string-upcase! (get "list_element")) +][+ + ENDFOR list +] } list_enum; + + extern char const* az_name_list[ [+ (count "list") +] ]; + [+ + + == c +] + #include "list.h" + char const* az_name_list[] = {[+ + FOR list "," +] + "[+list_info+]"[+ + ENDFOR list +] };[+ + + ESAC +] + + The '[+ AutoGen5 template h c +]' text tells AutoGen that this is an +AutoGen version 5 template file; that it is to be processed twice; that +the start macro marker is '[+'; and the end marker is '+]'. The +template will be processed first with a suffix value of 'h' and then +with 'c'. Normally, the suffix values are appended to the 'base-name' +to create the output file name. + + The '[+ == h +]' and '[+ == c +]' 'CASE' selection clauses select +different text for the two different passes. In this example, the +output is nearly disjoint and could have been put in two separate +templates. However, sometimes there are common sections and this is +just an example. + + The '[+FOR list "," +]' and '[+ ENDFOR list +]' clauses delimit a +block of text that will be repeated for every definition of 'list'. +Inside of that block, the definition name-value pairs that are members +of each 'list' are available for substitutions. + + The remainder of the macros are expressions. Some of these contain +special expression functions that are dependent on AutoGen named values; +others are simply Scheme expressions, the result of which will be +inserted into the output text. Other expressions are names of AutoGen +values. These values will be inserted into the output text. For +example, '[+list_info+]' will result in the value associated with the +name 'list_info' being inserted between the double quotes and +'(string-upcase! (get "list_element"))' will first "get" the value +associated with the name 'list_element', then change the case of all the +letters to upper case. The result will be inserted into the output +document. + + If you have compiled AutoGen, you can copy out the template and +definitions as described above and run 'autogen list.def'. This will +produce exactly the hypothesized desired output. + + One more point, too. Lets say you decided it was too much trouble to +figure out how to use AutoGen, so you created this enumeration and +string list with thousands of entries. Now, requirements have changed +and it has become necessary to map a string containing the enumeration +name into the enumeration number. With AutoGen, you just alter the +template to emit the table of names. It will be guaranteed to be in the +correct order, missing none of the entries. If you want to do that by +hand, well, good luck. + + +File: autogen.info, Node: csh/zsh caveat, Next: Testimonial, Prev: Example Usage, Up: Introduction + +1.3 csh/zsh caveat +================== + +AutoGen tries to use your normal shell so that you can supply shell code +in a manner you are accustomed to using. If, however, you use csh or +zsh, you cannot do this. Csh is sufficiently difficult to program that +it is unsupported. Zsh, though largely programmable, also has some +anomalies that make it incompatible with AutoGen usage. Therefore, when +invoking AutoGen from these environments, you must be certain to set the +SHELL environment variable to a Bourne-derived shell, e.g., sh, ksh or +bash. + + Any shell you choose for your own scripts need to follow these basic +requirements: + + 1. It handles 'trap ":" $sig' without output to standard out. This is + done when the server shell is first started. If your shell does + not handle this, then it may be able to by loading functions from + its start up files. + 2. At the beginning of each scriptlet, the command '\\cd $PWD' is + inserted. This ensures that 'cd' is not aliased to something + peculiar and each scriptlet starts life in the execution directory. + 3. At the end of each scriptlet, the command 'echo mumble' is + appended. The program you use as a shell must emit the single + argument 'mumble' on a line by itself. + + +File: autogen.info, Node: Testimonial, Prev: csh/zsh caveat, Up: Introduction + +1.4 A User's Perspective +======================== + +Alexandre wrote: +> +> I'd appreciate opinions from others about advantages/disadvantages of +> each of these macro packages. + + I am using AutoGen in my pet project, and find one of its best points +to be that it separates the operational data from the implementation. + + Indulge me for a few paragraphs, and all will be revealed: In the +manual, Bruce cites the example of maintaining command line flags inside +the source code; traditionally spreading usage information, flag names, +letters and processing across several functions (if not files). +Investing the time in writing a sort of boiler plate (a template in +AutoGen terminology) pays by moving all of the option details (usage, +flags names etc.) into a well structured table (a definition file if +you will), so that adding a new command line option becomes a simple +matter of adding a set of details to the table. + + So far so good! Of course, now that there is a template, writing all +of that tedious optargs processing and usage functions is no longer an +issue. Creating a table of the options needed for the new project and +running AutoGen generates all of the option processing code in C +automatically from just the tabular data. AutoGen in fact already ships +with such a template... AutoOpts. + + One final consequence of the good separation in the design of AutoGen +is that it is retargetable to a greater extent. The +egcs/gcc/fixinc/inclhack.def can equally be used (with different +templates) to create a shell script (inclhack.sh) or a c program +(fixincl.c). + + This is just the tip of the iceberg. AutoGen is far more powerful +than these examples might indicate, and has many other varied uses. I +am certain Bruce or I could supply you with many and varied examples, +and I would heartily recommend that you try it for your project and see +for yourself how it compares to m4. + + As an aside, I would be interested to see whether someone might be +persuaded to rationalise autoconf with AutoGen in place of m4... Ben, +are you listening? autoconf-3.0! 'kay? =)O| + +Sincerely, + Gary V. Vaughan + + +File: autogen.info, Node: Definitions File, Next: Template File, Prev: Introduction, Up: Top + +2 Definitions File +****************** + +This chapter describes the syntax and semantics of the AutoGen +definition file. In order to instantiate a template, you normally must +provide a definitions file that identifies itself and contains some +value definitions. Consequently, we keep it very simple. For +"advanced" users, there are preprocessing directives, sparse arrays, +named indexes and comments that may be used as well. + + The definitions file is used to associate values with names. Every +value is implicitly an array of values, even if there is only one value. +Values may be either simple strings or compound collections of +name-value pairs. An array may not contain both simple and compound +members. Fundamentally, it is as simple as: + + prog-name = "autogen"; + flag = { + name = templ_dirs; + value = L; + descrip = "Template search directory list"; + }; + + For purposes of commenting and controlling the processing of the +definitions, C-style comments and most C preprocessing directives are +honored. The major exception is that the '#if' directive is ignored, +along with all following text through the matching '#endif' directive. +The C preprocessor is not actually invoked, so C macro substitution is +*not* performed. + +* Menu: + +* Identification:: The Identification Definition +* Definitions:: Named Definitions +* Index Assignments:: Assigning an Index to a Definition +* Dynamic Text:: Dynamic Text +* Directives:: Controlling What Gets Processed +* Predefines:: Pre-defined Names +* Comments:: Commenting Your Definitions +* Example:: What it all looks like. +* Full Syntax:: Finite State Machine Grammar +* Alternate Definition:: Alternate Definition Forms + + +File: autogen.info, Node: Identification, Next: Definitions, Up: Definitions File + +2.1 The Identification Definition +================================= + +The first definition in this file is used to identify it as a AutoGen +file. It consists of the two keywords, 'autogen' and 'definitions' +followed by the default template name and a terminating semi-colon +(';'). That is: + + AutoGen Definitions TEMPLATE-NAME; + +Note that, other than the name TEMPLATE-NAME, the words 'AutoGen' and +'Definitions' are searched for without case sensitivity. Most lookups +in this program are case insensitive. + +Also, if the input contains more identification definitions, they will +be ignored. This is done so that you may include (*note Directives::) +other definition files without an identification conflict. + +AutoGen uses the name of the template to find the corresponding template +file. It searches for the file in the following way, stopping when it +finds the file: + + 1. It tries to open './TEMPLATE-NAME'. If it fails, + 2. it tries './TEMPLATE-NAME.tpl'. + 3. It searches for either of these files in the directories listed in + the templ-dirs command line option. + + If AutoGen fails to find the template file in one of these places, it +prints an error message and exits. + + +File: autogen.info, Node: Definitions, Next: Index Assignments, Prev: Identification, Up: Definitions File + +2.2 Named Definitions +===================== + +A name is a sequence of characters beginning with an alphabetic +character ('a' through 'z') followed by zero or more alpha-numeric +characters and/or separator characters: hyphen ('-'), underscore ('_') +or carat ('^'). Names are case insensitive. + + Any name may have multiple values associated with it. Every name may +be considered a sparse array of one or more elements. If there is more +than one value, the values my be accessed by indexing the value with +'[index]' or by iterating over them using the FOR (*note FOR::) AutoGen +macro on it, as described in the next chapter. Sparse arrays are +specified by specifying an index when defining an entry (*note Assigning +an Index to a Definition: Index Assignments.). + + There are two kinds of definitions, 'simple' and 'compound'. They +are defined thus (*note Full Syntax::): + + compound_name '=' '{' definition-list '}' ';' + + simple-name[2] '=' string ';' + + no^text^name ';' + +'simple-name' has the third index (index number 2) defined here. +'No^text^name' is a simple definition with a shorthand empty string +value. The string values for definitions may be specified in any of +several formation rules. + +* Menu: + +* def-list:: Definition List +* double-quote-string:: Double Quote String +* single-quote-string:: Single Quote String +* simple-string:: An Unquoted String +* shell-generated:: Shell Output String +* scheme-generated:: Scheme Result String +* here-string:: A Here String +* concat-string:: Concatenated Strings + + +File: autogen.info, Node: def-list, Next: double-quote-string, Up: Definitions + +2.2.1 Definition List +--------------------- + +'definition-list' is a list of definitions that may or may not contain +nested compound definitions. Any such definitions may *only* be +expanded within a 'FOR' block iterating over the containing compound +definition. *Note FOR::. + + Here is, again, the example definitions from the previous chapter, +with three additional name value pairs. Two with an empty value +assigned (FIRST and LAST), and a "global" GROUP_NAME. + + autogen definitions list; + group_name = example; + list = { list_element = alpha; first; + list_info = "some alpha stuff"; }; + list = { list_info = "more beta stuff"; + list_element = beta; }; + list = { list_element = omega; last; + list_info = "final omega stuff"; }; + + +File: autogen.info, Node: double-quote-string, Next: single-quote-string, Prev: def-list, Up: Definitions + +2.2.2 Double Quote String +------------------------- + +The string follows the C-style escaping, using the backslash to quote +(escape) the following character(s). Certain letters are translated to +various control codes (e.g. '\n', '\f', '\t', etc.). 'x' introduces a +two character hex code. '0' (the digit zero) introduces a one to three +character octal code (note: an octal byte followed by a digit must be +represented with three octal digits, thus: '"\0001"' yielding a NUL byte +followed by the ASCII digit 1). Any other character following the +backslash escape is simply inserted, without error, into the string +being formed. + + Like ANSI "C", a series of these strings, possibly intermixed with +single quote strings, will be concatenated together. + + +File: autogen.info, Node: single-quote-string, Next: simple-string, Prev: double-quote-string, Up: Definitions + +2.2.3 Single Quote String +------------------------- + +This is similar to the shell single-quote string. However, escapes '\' +are honored before another escape, single quotes ''' and hash characters +'#'. This latter is done specifically to disambiguate lines starting +with a hash character inside of a quoted string. In other words, + + fumble = ' + #endif + '; + + could be misinterpreted by the definitions scanner, whereas this +would not: + + fumble = ' + \#endif + '; + + + As with the double quote string, a series of these, even intermixed +with double quote strings, will be concatenated together. + + +File: autogen.info, Node: simple-string, Next: shell-generated, Prev: single-quote-string, Up: Definitions + +2.2.4 An Unquoted String +------------------------ + +A simple string that does not contain white space may be left unquoted. +The string must not contain any of the characters special to the +definition text (i.e., '"', '#', ''', '(', ')', ',', ';', '<', '=', '>', +'[', ']', '`', '{', or '}'). This list is subject to change, but it +will never contain underscore ('_'), period ('.'), slash ('/'), colon +(':'), hyphen ('-') or backslash ('\\'). Basically, if the string looks +like it is a normal DOS or UNIX file or variable name, and it is not one +of two keywords ('autogen' or 'definitions') then it is OK to not quote +it, otherwise you should. + + +File: autogen.info, Node: shell-generated, Next: scheme-generated, Prev: simple-string, Up: Definitions + +2.2.5 Shell Output String +------------------------- + +This is assembled according to the same rules as the double quote +string, except that there is no concatenation of strings and the +resulting string is written to a shell server process. The definition +takes on the value of the output string. + + NB The text is interpreted by a server shell. There may be left over +state from previous server shell processing. This scriptlet may also +leave state for subsequent processing. However, a 'cd' to the original +directory is always issued before the new command is issued. + + +File: autogen.info, Node: scheme-generated, Next: here-string, Prev: shell-generated, Up: Definitions + +2.2.6 Scheme Result String +-------------------------- + +A scheme result string must begin with an open parenthesis '('. The +scheme expression will be evaluated by Guile and the value will be the +result. The AutoGen expression functions are *dis*abled at this stage, +so do not use them. + + +File: autogen.info, Node: here-string, Next: concat-string, Prev: scheme-generated, Up: Definitions + +2.2.7 A Here String +------------------- + +A 'here string' is formed in much the same way as a shell here doc. It +is denoted with two less than characters('<<') and, optionally, a +hyphen. This is followed by optional horizontal white space and an +ending marker-identifier. This marker must follow the syntax rules for +identifiers. Unlike the shell version, however, you must not quote this +marker. + + The resulting string will start with the first character on the next +line and continue up to but not including the newline that precedes the +line that begins with the marker token. The characters are copied +directly into the result string. Mostly. + + If a hyphen follows the less than characters, then leading tabs will +be stripped and the terminating marker will be recognized even if +preceded by tabs. Also, if the first character on the line (after +removing tabs) is a backslash and the next character is a tab or space, +then the backslash will be removed as well. No other kind of processing +is done on this string. + + Here are three examples: + str1 = <<- STR_END + $quotes = " ' ` + STR_END; + + str2 = << STR_END + $quotes = " ' ` + STR_END; + STR_END; + + str3 = <<- STR_END + \ $quotes = " ' ` + STR_END; + The first string contains no new line characters. The first +character is the dollar sign, the last the back quote. + + The second string contains one new line character. The first +character is the tab character preceding the dollar sign. The last +character is the semicolon after the 'STR_END'. That 'STR_END' does not +end the string because it is not at the beginning of the line. In the +preceding case, the leading tab was stripped. + + The third string is almost identical to the first, except that the +first character is a tab. That is, it exactly matches the first line of +the second string. + + +File: autogen.info, Node: concat-string, Prev: here-string, Up: Definitions + +2.2.8 Concatenated Strings +-------------------------- + +If single or double quote characters are used, then you also have the +option, a la ANSI-C syntax, of implicitly concatenating a series of them +together, with intervening white space ignored. + + NB You *cannot* use directives to alter the string content. That is, + + str = "fumble" + #ifdef LATER + "stumble" + #endif + ; + +will result in a syntax error. The preprocessing directives are not +carried out by the C preprocessor. However, + + str = '"fumble\n" + #ifdef LATER + " stumble\n" + #endif + '; + +*Will* work. It will enclose the '#ifdef LATER' and '#endif' in the +string. But it may also wreak havoc with the definition processing +directives. The hash characters in the first column should be +disambiguated with an escape '\' or join them with previous lines: +'"fumble\n#ifdef LATER...'. + + +File: autogen.info, Node: Index Assignments, Next: Dynamic Text, Prev: Definitions, Up: Definitions File + +2.3 Assigning an Index to a Definition +====================================== + +In AutoGen, every name is implicitly an array of values. When assigning +values, they are usually implicitly assigned to the next highest slot. +They can also be specified explicitly: + + mumble[9] = stumble; + mumble[0] = grumble; + +If, subsequently, you assign a value to 'mumble' without an index, its +index will be '10', not '1'. If indexes are specified, they must not +cause conflicts. + + '#define'-d names may also be used for index values. This is +equivalent to the above: + + #define FIRST 0 + #define LAST 9 + mumble[LAST] = stumble; + mumble[FIRST] = grumble; + + All values in a range do *not* have to be filled in. If you leave +gaps, then you will have a sparse array. This is fine (*note FOR::). +You have your choice of iterating over all the defined values, or +iterating over a range of slots. This: + + [+ FOR mumble +][+ ENDFOR +] + +iterates over all and only the defined entries, whereas this: + + [+ FOR mumble (for-by 1) +][+ ENDFOR +] + +will iterate over all 10 "slots". Your template will likely have to +contain something like this: + + [+ IF (exist? (sprintf "mumble[%d]" (for-index))) +] + +or else "mumble" will have to be a compound value that, say, always +contains a "grumble" value: + + [+ IF (exist? "grumble") +] + + +File: autogen.info, Node: Dynamic Text, Next: Directives, Prev: Index Assignments, Up: Definitions File + +2.4 Dynamic Text +================ + +There are several methods for including dynamic content inside a +definitions file. Three of them are mentioned above (*note +shell-generated:: and *note scheme-generated::) in the discussion of +string formation rules. Another method uses the '#shell' processing +directive. It will be discussed in the next section (*note +Directives::). Guile/Scheme may also be used to yield to create +definitions. + + When the Scheme expression is preceded by a backslash and single +quote, then the expression is expected to be an alist of names and +values that will be used to create AutoGen definitions. + +This method can be be used as follows: + + \'( (name (value-expression)) + (name2 (another-expr)) ) + +This is entirely equivalent to: + + name = (value-expression); + name2 = (another-expr); + +Under the covers, the expression gets handed off to a Guile function +named 'alist->autogen-def' in an expression that looks like this: + + (alist->autogen-def + ( (name (value-expression)) (name2 (another-expr)) ) ) + + +File: autogen.info, Node: Directives, Next: Predefines, Prev: Dynamic Text, Up: Definitions File + +2.5 Controlling What Gets Processed +=================================== + +Definition processing directives can *only* be processed if the '#' +character is the first character on a line. Also, if you want a '#' as +the first character of a line in one of your string assignments, you +should either escape it by preceding it with a backslash '\', or by +embedding it in the string as in '"\n#"'. + + All of the normal C preprocessing directives are recognized, though +several are ignored. There is also an additional '#shell' - '#endshell' +pair. Another minor difference is that AutoGen directives must have the +hash character ('#') in column 1. Unrecognized directives produce an +error. + + The final tweak is that '#!' is treated as a comment line. Using +this feature, you can use: '#! /usr/local/bin/autogen' as the first line +of a definitions file, set the mode to executable and "run" the +definitions file as if it were a direct invocation of AutoGen. This was +done for its hack value. + + The AutoGen recognized directives are: +'#assert' + This directive is processed, but only if the expression begins with + either a back quote ('`') or an open parenthesis ('('). Text + within the back quotes are handed off to the shell for processing + and parenthesized text is handed off to Guile. Multiple line + expressions must be joined with backslashes. + + If the 'shell-script' or 'scheme-expr' do not yield 'true' valued + results, autogen will be aborted. If '<anything else>' or nothing + at all is provided, then this directive is ignored. + + The result is 'false' (and fails) if the result is empty, the + number zero, or a string that starts with the letters 'n' or 'f' + ("no" or "false"). + +'#define' + Will add the name to the define list as if it were a DEFINE program + argument. Its value will be the first non-whitespace token + following the name. Quotes are *not* processed. + + After the definitions file has been processed, any remaining + entries in the define list will be added to the environment. + +'#elif' + Marks a transition in the #if directive. Error when out of + context. #if blocks are always ignored. + +'#else' + This must follow an '#if', '#ifdef' or '#ifndef'. If it follows + the '#if', then it will be ignored. Otherwise, it will change the + processing state to the reverse of what it was. + +'#endif' + This must follow an '#if', '#ifdef' or '#ifndef'. In all cases, + this will resume normal processing of text. + +'#endmac' + Marks the end of the #macdef directive. Error when out of context. + +'#endshell' + Marks the end of the #shell directive. Error when out of context. + +'#error' + This directive will cause AutoGen to stop processing and exit with + a status of EXIT_FAILURE. + +'#ident' + Ignored directive. + +'#if' + '#if' expressions are not analyzed. *Everything* from here to the + matching '#endif' is skipped. + +'#ifdef' + The definitions that follow, up to the matching '#endif' will be + processed only if there is a corresponding '-Dname' command line + option or if a '#define' of that name has been previously + encountered. + +'#ifndef' + The definitions that follow, up to the matching '#endif' will be + processed only if the named value has *not* been defined. + +'#include' + This directive will insert definitions from another file into the + current collection. If the file name is adorned with double quotes + or angle brackets (as in a C program), then the include is ignored. + +'#let' + Ignored directive. + +'#line' + Alters the current line number and/or file name. You may wish to + use this directive if you extract definition source from other + files. 'getdefs' uses this mechanism so AutoGen will report the + correct file and approximate line number of any errors found in + extracted definitions. + +'#macdef' + This is a new AT&T research preprocessing directive. Basically, it + is a multi-line #define that may include other preprocessing + directives. Text between this line and a #endmac directive are + ignored. + +'#option' + This directive will pass the option name and associated text to the + AutoOpts optionLoadLine routine (*note libopts-optionLoadLine::). + The option text may span multiple lines by continuing them with a + backslash. The backslash/newline pair will be replaced with two + space characters. This directive may be used to set a search path + for locating template files For example, this: + + #option templ-dirs $ENVVAR/dirname + will direct autogen to use the 'ENVVAR' environment variable to + find a directory named 'dirname' that (may) contain templates. + Since these directories are searched in most recently supplied + first order, search directories supplied in this way will be + searched before any supplied on the command line. + +'#pragma' + Ignored directive. + +'#shell' + Invokes '$SHELL' or '/bin/sh' on a script that should generate + AutoGen definitions. It does this using the same server process + that handles the back-quoted '`' text. The block of text handed to + the shell is terminated with the #endshell directive. + + *CAUTION* let not your '$SHELL' be 'csh'. + +'#undef' + Will remove any entries from the define list that match the undef + name pattern. + + +File: autogen.info, Node: Predefines, Next: Comments, Prev: Directives, Up: Definitions File + +2.6 Pre-defined Names +===================== + +When AutoGen starts, it tries to determine several names from the +operating environment and put them into environment variables for use in +both '#ifdef' tests in the definitions files and in shell scripts with +environment variable tests. '__autogen__' is always defined. For other +names, AutoGen will first try to use the POSIX version of the +'sysinfo(2)' system call. Failing that, it will try for the POSIX +'uname(2)' call. If neither is available, then only "'__autogen__'" +will be inserted into the environment. In all cases, the associated +names are converted to lower case, surrounded by doubled underscores and +non-symbol characters are replaced with underscores. + + With Solaris on a sparc platform, 'sysinfo(2)' is available. The +following strings are used: + + * 'SI_SYSNAME' (e.g., "__sunos__") + * 'SI_HOSTNAME' (e.g., "__ellen__") + * 'SI_ARCHITECTURE' (e.g., "__sparc__") + * 'SI_HW_PROVIDER' (e.g., "__sun_microsystems__") + * 'SI_PLATFORM' (e.g., "__sun_ultra_5_10__") + * 'SI_MACHINE' (e.g., "__sun4u__") + + For Linux and other operating systems that only support the +'uname(2)' call, AutoGen will use these values: + + * 'sysname' (e.g., "__linux__") + * 'machine' (e.g., "__i586__") + * 'nodename' (e.g., "__bach__") + + By testing these pre-defines in my definitions, you can select pieces +of the definitions without resorting to writing shell scripts that parse +the output of 'uname(1)'. You can also segregate real C code from +autogen definitions by testing for "'__autogen__'". + + #ifdef __bach__ + location = home; + #else + location = work; + #endif + + +File: autogen.info, Node: Comments, Next: Example, Prev: Predefines, Up: Definitions File + +2.7 Commenting Your Definitions +=============================== + +The definitions file may contain C and C++ style comments. + + /* + * This is a comment. It continues for several lines and closes + * when the characters '*' and '/' appear together. + */ + // this comment is a single line comment + + +File: autogen.info, Node: Example, Next: Full Syntax, Prev: Comments, Up: Definitions File + +2.8 What it all looks like. +=========================== + +This is an extended example: + + autogen definitions 'template-name'; + /* + * This is a comment that describes what these + * definitions are all about. + */ + global = "value for a global text definition."; + + /* + * Include a standard set of definitions + */ + #include standards.def + + a_block = { + a_field; + a_subblock = { + sub_name = first; + sub_field = "sub value."; + }; + + #ifdef FEATURE + a_subblock = { + sub_name = second; + }; + #endif + + }; + + +File: autogen.info, Node: Full Syntax, Next: Alternate Definition, Prev: Example, Up: Definitions File + +2.9 Finite State Machine Grammar +================================ + +The preprocessing directives and comments are not part of the grammar. +They are handled by the scanner/lexer. The following was extracted +directly from the generated defParse-fsm.c source file. The "EVT:" is +the token seen, the "STATE:" is the current state and the entries in +this table describe the next state and the action to take. Invalid +transitions were removed from the table. + + dp_trans_table[ DP_STATE_CT ][ DP_EVENT_CT ] = { + + /* STATE 0: DP_ST_INIT */ + { { DP_ST_NEED_DEF, NULL }, /* EVT: AUTOGEN */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: DEFINITIONS */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: End-Of-File */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: VAR_NAME */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: OTHER_NAME */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: STRING */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: HERE_STRING */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: DELETE_ENT */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: NUMBER */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: ; */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: = */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: , */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: { */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: } */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: [ */ + { DP_ST_INVALID, dp_do_invalid } /* EVT: ] */ + + /* STATE 1: DP_ST_NEED_DEF */ + { { DP_ST_INVALID, dp_do_invalid }, /* EVT: AUTOGEN */ + { DP_ST_NEED_TPL, NULL }, /* EVT: DEFINITIONS */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: End-Of-File */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: VAR_NAME */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: OTHER_NAME */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: STRING */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: HERE_STRING */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: DELETE_ENT */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: NUMBER */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: ; */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: = */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: , */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: { */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: } */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: [ */ + { DP_ST_INVALID, dp_do_invalid } /* EVT: ] */ + + /* STATE 2: DP_ST_NEED_TPL */ + { { DP_ST_INVALID, dp_do_invalid }, /* EVT: AUTOGEN */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: DEFINITIONS */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: End-Of-File */ + { DP_ST_NEED_SEMI, dp_do_tpl_name }, /* EVT: VAR_NAME */ + { DP_ST_NEED_SEMI, dp_do_tpl_name }, /* EVT: OTHER_NAME */ + { DP_ST_NEED_SEMI, dp_do_tpl_name }, /* EVT: STRING */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: HERE_STRING */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: DELETE_ENT */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: NUMBER */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: ; */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: = */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: , */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: { */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: } */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: [ */ + { DP_ST_INVALID, dp_do_invalid } /* EVT: ] */ + + /* STATE 3: DP_ST_NEED_SEMI */ + { { DP_ST_INVALID, dp_do_invalid }, /* EVT: AUTOGEN */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: DEFINITIONS */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: End-Of-File */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: VAR_NAME */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: OTHER_NAME */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: STRING */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: HERE_STRING */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: DELETE_ENT */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: NUMBER */ + { DP_ST_NEED_NAME, NULL }, /* EVT: ; */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: = */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: , */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: { */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: } */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: [ */ + { DP_ST_INVALID, dp_do_invalid } /* EVT: ] */ + + /* STATE 4: DP_ST_NEED_NAME */ + { { DP_ST_NEED_DEF, NULL }, /* EVT: AUTOGEN */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: DEFINITIONS */ + { DP_ST_DONE, dp_do_need_name_end }, /* EVT: End-Of-File */ + { DP_ST_HAVE_NAME, dp_do_need_name_var_name }, /* EVT: VAR_NAME */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: OTHER_NAME */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: STRING */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: HERE_STRING */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: DELETE_ENT */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: NUMBER */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: ; */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: = */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: , */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: { */ + { DP_ST_HAVE_VALUE, dp_do_end_block }, /* EVT: } */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: [ */ + { DP_ST_INVALID, dp_do_invalid } /* EVT: ] */ + + /* STATE 5: DP_ST_HAVE_NAME */ + { { DP_ST_INVALID, dp_do_invalid }, /* EVT: AUTOGEN */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: DEFINITIONS */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: End-Of-File */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: VAR_NAME */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: OTHER_NAME */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: STRING */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: HERE_STRING */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: DELETE_ENT */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: NUMBER */ + { DP_ST_NEED_NAME, dp_do_empty_val }, /* EVT: ; */ + { DP_ST_NEED_VALUE, dp_do_have_name_lit_eq }, /* EVT: = */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: , */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: { */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: } */ + { DP_ST_NEED_IDX, NULL }, /* EVT: [ */ + { DP_ST_INVALID, dp_do_invalid } /* EVT: ] */ + + /* STATE 6: DP_ST_NEED_VALUE */ + { { DP_ST_INVALID, dp_do_invalid }, /* EVT: AUTOGEN */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: DEFINITIONS */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: End-Of-File */ + { DP_ST_HAVE_VALUE, dp_do_str_value }, /* EVT: VAR_NAME */ + { DP_ST_HAVE_VALUE, dp_do_str_value }, /* EVT: OTHER_NAME */ + { DP_ST_HAVE_VALUE, dp_do_str_value }, /* EVT: STRING */ + { DP_ST_HAVE_VALUE, dp_do_str_value }, /* EVT: HERE_STRING */ + { DP_ST_NEED_NAME, dp_do_need_value_delete_ent }, /* EVT: DELETE_ENT */ + { DP_ST_HAVE_VALUE, dp_do_str_value }, /* EVT: NUMBER */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: ; */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: = */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: , */ + { DP_ST_NEED_NAME, dp_do_start_block }, /* EVT: { */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: } */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: [ */ + { DP_ST_INVALID, dp_do_invalid } /* EVT: ] */ + + /* STATE 7: DP_ST_NEED_IDX */ + { { DP_ST_INVALID, dp_do_invalid }, /* EVT: AUTOGEN */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: DEFINITIONS */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: End-Of-File */ + { DP_ST_NEED_CBKT, dp_do_indexed_name }, /* EVT: VAR_NAME */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: OTHER_NAME */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: STRING */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: HERE_STRING */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: DELETE_ENT */ + { DP_ST_NEED_CBKT, dp_do_indexed_name }, /* EVT: NUMBER */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: ; */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: = */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: , */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: { */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: } */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: [ */ + { DP_ST_INVALID, dp_do_invalid } /* EVT: ] */ + + /* STATE 8: DP_ST_NEED_CBKT */ + { { DP_ST_INVALID, dp_do_invalid }, /* EVT: AUTOGEN */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: DEFINITIONS */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: End-Of-File */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: VAR_NAME */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: OTHER_NAME */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: STRING */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: HERE_STRING */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: DELETE_ENT */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: NUMBER */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: ; */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: = */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: , */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: { */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: } */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: [ */ + { DP_ST_INDX_NAME, NULL } /* EVT: ] */ + + /* STATE 9: DP_ST_INDX_NAME */ + { { DP_ST_INVALID, dp_do_invalid }, /* EVT: AUTOGEN */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: DEFINITIONS */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: End-Of-File */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: VAR_NAME */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: OTHER_NAME */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: STRING */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: HERE_STRING */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: DELETE_ENT */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: NUMBER */ + { DP_ST_NEED_NAME, dp_do_empty_val }, /* EVT: ; */ + { DP_ST_NEED_VALUE, NULL }, /* EVT: = */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: , */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: { */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: } */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: [ */ + { DP_ST_INVALID, dp_do_invalid } /* EVT: ] */ + + /* STATE 10: DP_ST_HAVE_VALUE */ + { { DP_ST_INVALID, dp_do_invalid }, /* EVT: AUTOGEN */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: DEFINITIONS */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: End-Of-File */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: VAR_NAME */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: OTHER_NAME */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: STRING */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: HERE_STRING */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: DELETE_ENT */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: NUMBER */ + { DP_ST_NEED_NAME, NULL }, /* EVT: ; */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: = */ + { DP_ST_NEED_VALUE, dp_do_next_val }, /* EVT: , */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: { */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: } */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: [ */ + { DP_ST_INVALID, dp_do_invalid } /* EVT: ] */ + + +File: autogen.info, Node: Alternate Definition, Prev: Full Syntax, Up: Definitions File + +2.10 Alternate Definition Forms +=============================== + +There are several methods for supplying data values for templates. + +'no definitions' + It is entirely possible to write a template that does not depend + upon external definitions. Such a template would likely have an + unvarying output, but be convenient nonetheless because of an + external library of either AutoGen or Scheme functions, or both. + This can be accommodated by providing the '--override-tpl' and + '--no-definitions' options on the command line. *Note autogen + Invocation::. + +'CGI' + AutoGen behaves as a CGI server if the definitions input is from + stdin and the environment variable 'REQUEST_METHOD' is defined and + set to either "GET" or "POST", *Note AutoGen CGI::. Obviously, all + the values are constrained to strings because there is no way to + represent nested values. + +'XML' + AutoGen comes with a program named, 'xml2ag'. Its output can + either be redirected to a file for later use, or the program can be + used as an AutoGen wrapper. *Note xml2ag Invocation::. + + The introductory template example (*note Example Usage::) can be + rewritten in XML as follows: + + <EXAMPLE template="list.tpl"> + <LIST list_element="alpha" + list_info="some alpha stuff"/> + <LIST list_info="more beta stuff" + list_element="beta"/> + <LIST list_element="omega" + list_info="final omega stuff"/> + </EXAMPLE> + + A more XML-normal form might look like this: + <EXAMPLE template="list.tpl"> + <LIST list_element="alpha">some alpha stuff</LIST> + <LIST list_element="beta" >more beta stuff</LIST> + <LIST list_element="omega">final omega stuff</LIST> + </EXAMPLE> + but you would have to change the template 'list-info' references + into 'text' references. + +'standard AutoGen definitions' + Of course. :-) + + +File: autogen.info, Node: Template File, Next: Augmenting AutoGen, Prev: Definitions File, Up: Top + +3 Template File +*************** + +The AutoGen template file defines the content of the output text. It is +composed of two parts. The first part consists of a pseudo macro +invocation and commentary. It is followed by the template proper. + + This pseudo macro is special. It is used to identify the file as a +AutoGen template file, fixing the starting and ending marks for the +macro invocations in the rest of the file, specifying the list of +suffixes to be generated by the template and, optionally, the shell to +use for processing shell commands embedded in the template. + + AutoGen-ing a file consists of copying text from the template to the +output file until a start macro marker is found. The text from the +start marker to the end marker constitutes the macro text. AutoGen +macros may cause sections of the template to be skipped or processed +several times. The process continues until the end of the template is +reached. The process is repeated once for each suffix specified in the +pseudo macro. + + This chapter describes the format of the AutoGen template macros and +the usage of the AutoGen native macros. Users may augment these by +defining their own macros, *Note DEFINE::. + +* Menu: + +* pseudo macro:: Format of the Pseudo Macro +* naming values:: Naming a value +* expression syntax:: Macro Expression Syntax +* AutoGen Functions:: AutoGen Scheme Functions +* Common Functions:: Common Scheme Functions +* native macros:: AutoGen Native Macros +* output controls:: Redirecting Output + + +File: autogen.info, Node: pseudo macro, Next: naming values, Up: Template File + +3.1 Format of the Pseudo Macro +============================== + +The pseudo macro is used to tell AutoGen how to process a template. It +tells autogen: + + 1. The start macro marker. It consists of punctuation characters used + to demarcate the start of a macro. It may be up to seven + characters long and must be the first non-whitespace characters in + the file. + + It is generally a good idea to use some sort of opening bracket in + the starting macro and closing bracket in the ending macro (e.g. + '{', '(', '[', or even '<' in the starting macro). It helps both + visually and with editors capable of finding a balancing + parenthesis. + + 2. That start marker must be immediately followed by the identifier + strings "AutoGen5" and then "template", though capitalization is + not important. + +The next several components may be intermingled: + + 3. Zero, one or more suffix specifications tell AutoGen how many times + to process the template file. No suffix specifications mean that + it is to be processed once and that the generated text is to be + written to 'stdout'. The current suffix for each pass can be + determined with the '(suffix)' scheme function (*note SCM + suffix::). + + The suffix specification consists of a sequence of POSIX compliant + file name characters and, optionally, an equal sign and a file name + formatting specification. That specification may be either an + ordinary sequence of file name characters with zero, one or two + "%s" formatting sequences in it, or else it may be a Scheme + expression that, when evaluated, produces such a string. The + Scheme result may not be empty. The two string arguments allowed + for that string are the base name of the definition file, and the + current suffix (that being the text to the left of the equal sign). + (Note: "POSIX compliant file name characters" consist of + alphanumerics plus the period ('.'), hyphen ('-') and underscore + ('_') characters.) + + If the suffix begins with one of these three latter characters and + a formatting string is not specified, then that character is + presumed to be the suffix separator. Otherwise, without a + specified format string, a single period will separate the suffix + from the base name in constructing the output file name. + + 4. Shell specification: to specify that the template was written + expecting a particular shell to run the shell commands. By + default, the shell used is the autoconf-ed 'CONFIG_SHELL'. This + will usually be '/bin/sh'. The shell is specified by a hash mark + ('#') followed by an exclamation mark ('!') followed by a full-path + file name (e.g. '/usr/xpg4/bin/sh' on Solaris): + [= Autogen5 Template c + #!/usr/xpg4/bin/sh + =] + + 5. Comments: blank lines, lines starting with a hash mark ('#') and + not specifying a shell, and edit mode markers (text between pairs + of '-*-' strings) are all treated as comments. + + 6. Some scheme expressions may be inserted in order to make + configuration changes before template processing begins. before + template processing begins means that there is no current output + file, no current suffix and, basically, none of the AutoGen + specific functions (*note AutoGen Functions::) may be invoked. + + The scheme expression can also be used, for example, to save a + pre-existing output file for later text extraction (*note SCM + extract::). + + (shellf "mv -f %1$s.c %1$s.sav" (base-name)) + +After these must come the end macro marker: + + 6. The punctuation characters used to demarcate the end of a macro. + Like the start marker, it must consist of seven or fewer + punctuation characters. + + The ending macro marker has a few constraints on its content. Some +of them are just advisory, though. There is no special check for +advisory restrictions. + + * It must not begin with a POSIX file name character (hyphen '-', + underscore '_' or period '.'), the backslash ('\') or open + parenthesis ('('). These are used to identify a suffix + specification, indicate Scheme code and trim white space. + + * If it begins with an equal sign, then it must be separated from any + suffix specification by white space. + + * The closing marker may not begin with an open parenthesis, as that + is used to enclose a scheme expression. + + * It cannot begin with a backslash, as that is used to indicate white + space trimming after the end macro mark. If, in the body of the + template, you put the backslash character ('\') before the end + macro mark, then any white space characters after the mark and + through the newline character are trimmed. + + * It is also helpful to avoid using the comment marker ('#'). It + might be seen as a comment within the pseudo macro. + + * You should avoid using any of the quote characters double, single + or back-quote. It won't confuse AutoGen, but it might well confuse + you and/or your editor. + + As an example, assume we want to use '[+' and '+]' as the start and +end macro markers, and we wish to produce a '.c' and a '.h' file, then +the pseudo macro might look something like this: + + [+ AutoGen5 template -*- Mode: emacs-mode-of-choice -*- + h=chk-%s.h + c + # make sure we don't use csh: + (setenv "SHELL" "/bin/sh") +] + + The template proper starts after the pseudo-macro. The starting +character is either the first non-whitespace character or the first +character after the newline that follows the end macro marker. + + +File: autogen.info, Node: naming values, Next: expression syntax, Prev: pseudo macro, Up: Template File + +3.2 Naming a value +================== + +When an AutoGen value is specified in a template, it is specified by +name. The name may be a simple name, or a compound name of several +components. Since each named value in AutoGen is implicitly an array of +one or more values, each component may have an index associated with it. + +It looks like this: + + comp-name-1 . comp-name-2 [ 2 ] + + Note that if there are multiple components to a name, each component +name is separated by a dot ('.'). Indexes follow a component name, +enclosed in square brackets ('[' and ']'). The index may be either an +integer or an integer-valued define name. The first component of the +name is searched for in the current definition level. If not found, +higher levels will be searched until either a value is found, or there +are no more definition levels. Subsequent components of the name must +be found within the context of the newly-current definition level. +Also, if the named value is prefixed by a dot ('.'), then the value +search is started in the current context only. Backtracking into other +definition levels is prevented. + + If someone rewrites this, I'll incorporate it. :-) + + +File: autogen.info, Node: expression syntax, Next: AutoGen Functions, Prev: naming values, Up: Template File + +3.3 Macro Expression Syntax +=========================== + +AutoGen has two types of expressions: full expressions and basic ones. +A full AutoGen expression can appear by itself, or as the argument to +certain AutoGen built-in macros: CASE, IF, ELIF, INCLUDE, INVOKE +(explicit invocation, *note INVOKE::), and WHILE. If it appears by +itself, the result is inserted into the output. If it is an argument to +one of these macros, the macro code will act on it sensibly. + + You are constrained to basic expressions only when passing arguments +to user defined macros, *Note DEFINE::. + + The syntax of a full AutoGen expression is: + + [[ <apply-code> ] <value-name> ] [ <basic-expr-1> [ <basic-expr-2> ]] + + How the expression is evaluated depends upon the presence or absence +of the apply code and value name. The "value name" is the name of an +AutoGen defined value, or not. If it does not name such a value, the +expression result is generally the empty string. All expressions must +contain either a VALUE-NAME or a BASIC-EXPR. + +* Menu: + +* apply code:: Apply Code +* basic expression:: Basic Expression + + +File: autogen.info, Node: apply code, Next: basic expression, Up: expression syntax + +3.3.1 Apply Code +---------------- + +The "apply code" selected determines the method of evaluating the +expression. There are five apply codes, including the non-use of an +apply code. + +'no apply code' + This is the most common expression type. Expressions of this sort + come in three flavors: + + '<value-name>' + The result is the value of VALUE-NAME, if defined. Otherwise + it is the empty string. + + '<basic-expr>' + The result of the basic expression is the result of the full + expression, *Note basic expression::. + + '<value-name> <basic-expr>' + If there is a defined value for VALUE-NAME, then the + BASIC-EXPR is evaluated. Otherwise, the result is the empty + string. + +'% <value-name> <basic-expr>' + If VALUE-NAME is defined, use BASIC-EXPR as a format string for + sprintf. Then, if the BASIC-EXPR is either a back-quoted string or + a parenthesized expression, then hand the result to the appropriate + interpreter for further evaluation. Otherwise, for single and + double quote strings, the result is the result of the sprintf + operation. Naturally, if VALUE-NAME is not defined, the result is + the empty string. + + For example, assume that 'fumble' had the string value, 'stumble': + [+ % fumble `printf '%%x\\n' $%s` +] + This would cause the shell to evaluate "'printf '%x\n' $stumble'". + Assuming that the shell variable 'stumble' had a numeric value, the + expression result would be that number, in hex. Note the need for + doubled percent characters and backslashes. + +'? <value-name> <basic-expr-1> <basic-expr-2>' + Two BASIC-EXPR-s are required. If the VALUE-NAME is defined, then + the first BASIC-EXPR-1 is evaluated, otherwise BASIC-EXPR-2 is. + +'- <value-name> <basic-expr>' + Evaluate BASIC-EXPR only if VALUE-NAME is not defined. + +'?% <value-name> <basic-expr-1> <basic-expr-2>' + This combines the functions of '?' and '%'. If VALUE-NAME is + defined, it behaves exactly like '%', above, using BASIC-EXPR-1. + If not defined, then BASIC-EXPR-2 is evaluated. + + For example, assume again that 'fumble' had the string value, + 'stumble': + [+ ?% fumble `cat $%s` `pwd` +] + This would cause the shell to evaluate "'cat $stumble'". If + 'fumble' were not defined, then the result would be the name of our + current directory. + + +File: autogen.info, Node: basic expression, Prev: apply code, Up: expression syntax + +3.3.2 Basic Expression +---------------------- + +A basic expression can have one of the following forms: + +''STRING'' + A single quoted string. Backslashes can be used to protect single + quotes ('''), hash characters ('#'), or backslashes ('\') in the + string. All other characters of STRING are output as-is when the + single quoted string is evaluated. Backslashes are processed + before the hash character for consistency with the definition + syntax. It is needed there to avoid preprocessing conflicts. + +'"STRING"' + A double quoted string. This is a cooked text string as in C, + except that they are not concatenated with adjacent strings. + Evaluating "'STRING'" will output STRING with all backslash + sequences interpreted. + +'`STRING`' + A back quoted string. When this expression is evaluated, STRING is + first interpreted as a cooked string (as in '"STRING"') and + evaluated as a shell expression by the AutoGen server shell. This + expression is replaced by the 'stdout' output of the shell. + +'(STRING)' + A parenthesized expression. It will be passed to the Guile + interpreter for evaluation and replaced by the resulting value. If + there is a Scheme error in this expression, Guile 1.4 and Guile 1.6 + will report the template line number where the error occurs. Guile + 1.7 has lost this capability. + + Guile has the capability of creating and manipulating variables + that can be referenced later on in the template processing. If you + define such a variable, it is invisible to AutoGen. To reference + its value, you must use a Guile expression. For example, + [+ (define my-var "some-string-value") +] + can have that string inserted later, but only as in: + [+ (. my-var) +] + + Additionally, other than in the '%' and '?%' expressions, the Guile + expressions may be introduced with the Guile comment character + (';') and you may put a series of Guile expressions within a single + macro. They will be implicitly evaluated as if they were arguments + to the '(begin ...)' expression. The result will be the result of + the last Guile expression evaluated. + + +File: autogen.info, Node: AutoGen Functions, Next: Common Functions, Prev: expression syntax, Up: Template File + +3.4 AutoGen Scheme Functions +============================ + +AutoGen uses Guile to interpret Scheme expressions within AutoGen +macros. All of the normal Guile functions are available, plus several +extensions (*note Common Functions::) have been added to augment the +repertoire of string manipulation functions and manage the state of +AutoGen processing. + + This section describes those functions that are specific to AutoGen. +Please take note that these AutoGen specific functions are not loaded +and thus not made available until after the command line options have +been processed and the AutoGen definitions have been loaded. They may, +of course, be used in Scheme functions that get defined at those times, +but they cannot be invoked. + +* Menu: + +* SCM ag-fprintf:: 'ag-fprintf' - format to autogen stream +* SCM ag-function?:: 'ag-function?' - test for function +* SCM base-name:: 'base-name' - base output name +* SCM chdir:: 'chdir' - Change current directory +* SCM count:: 'count' - definition count +* SCM def-file:: 'def-file' - definitions file name +* SCM def-file-line:: 'def-file-line' - get a definition file+line number +* SCM dne:: 'dne' - "Do Not Edit" warning +* SCM emit:: 'emit' - emit the text for each argument +* SCM emit-string-table:: 'emit-string-table' - output a string table +* SCM error:: 'error' - display message and exit +* SCM exist?:: 'exist?' - test for value name +* SCM find-file:: 'find-file' - locate a file in the search path +* SCM first-for?:: 'first-for?' - detect first iteration +* SCM for-by:: 'for-by' - set iteration step +* SCM for-from:: 'for-from' - set initial index +* SCM for-index:: 'for-index' - get current loop index +* SCM for-sep:: 'for-sep' - set loop separation string +* SCM for-to:: 'for-to' - set ending index +* SCM found-for?:: 'found-for?' - is current index in list? +* SCM get:: 'get' - get named value +* SCM get-c-name:: 'get-c-name' - get named value, mapped to C name syntax +* SCM get-down-name:: 'get-down-name' - get lower cased named value, mapped to C name syntax +* SCM get-up-name:: 'get-up-name' - get upper cased named value, mapped to C name syntax +* SCM high-lim:: 'high-lim' - get highest value index +* SCM insert-file:: 'insert-file' - insert the contents of a (list of) files. +* SCM insert-suspended:: 'insert-suspended' - insert a named suspension in current output +* SCM last-for?:: 'last-for?' - detect last iteration +* SCM len:: 'len' - get count of values +* SCM low-lim:: 'low-lim' - get lowest value index +* SCM make-header-guard:: 'make-header-guard' - make self-inclusion guard +* SCM make-tmp-dir:: 'make-tmp-dir' - create a temporary directory +* SCM match-value?:: 'match-value?' - test for matching value +* SCM max-file-time:: 'max-file-time' - get the maximum input file modification time +* SCM mk-gettextable:: 'mk-gettextable' - print a string in a gettext-able format +* SCM out-delete:: 'out-delete' - delete current output file +* SCM out-depth:: 'out-depth' - output file stack depth +* SCM out-emit-suspended:: 'out-emit-suspended' - emit the text of suspended output +* SCM out-line:: 'out-line' - output file line number +* SCM out-move:: 'out-move' - change name of output file +* SCM out-name:: 'out-name' - current output file name +* SCM out-pop:: 'out-pop' - close current output file +* SCM out-push-add:: 'out-push-add' - append output to file +* SCM out-push-new:: 'out-push-new' - purge and create output file +* SCM out-resume:: 'out-resume' - resume suspended output file +* SCM out-suspend:: 'out-suspend' - suspend current output file +* SCM out-switch:: 'out-switch' - close and create new output +* SCM output-file-next-line:: 'output-file-next-line' - print the file name and next line number +* SCM set-option:: 'set-option' - Set a command line option +* SCM set-writable:: 'set-writable' - Make the output file be writable +* SCM stack:: 'stack' - make list of AutoGen values +* SCM stack-join:: 'stack-join' - stack values then join them +* SCM suffix:: 'suffix' - get the current suffix +* SCM tpl-file:: 'tpl-file' - get the template file name +* SCM tpl-file-line:: 'tpl-file-line' - get the template file+line number +* SCM tpl-file-next-line:: 'tpl-file-next-line' - get the template file plus next line number +* SCM warn:: 'warn' - display warning message and continue +* SCM autogen-version:: 'autogen-version' - "5.18.16" +* SCM c-file-line-fmt:: format file info as, "'#line nn "file"'" + + +File: autogen.info, Node: SCM ag-fprintf, Next: SCM ag-function?, Up: AutoGen Functions + +3.4.1 'ag-fprintf' - format to autogen stream +--------------------------------------------- + +Usage: (ag-fprintf ag-diversion format [ format-arg ... ]) +Format a string using arguments from the alist. Write to a specified +AutoGen diversion. That may be either a specified suspended output +stream (*note SCM out-suspend::) or an index into the output stack +(*note SCM out-push-new::). '(ag-fprintf 0 ...)' is equivalent to +'(emit (sprintf ...))', and '(ag-fprintf 1 ...)' sends output to the +most recently suspended output stream. + + Arguments: +ag-diversion - AutoGen diversion name or number +format - formatting string +format-arg - Optional - list of arguments to formatting string + + +File: autogen.info, Node: SCM ag-function?, Next: SCM base-name, Prev: SCM ag-fprintf, Up: AutoGen Functions + +3.4.2 'ag-function?' - test for function +---------------------------------------- + +Usage: (ag-function? ag-name) +return SCM_BOOL_T if a specified name is a user-defined AutoGen macro, +otherwise return SCM_BOOL_F. + + Arguments: +ag-name - name of AutoGen macro + + +File: autogen.info, Node: SCM base-name, Next: SCM chdir, Prev: SCM ag-function?, Up: AutoGen Functions + +3.4.3 'base-name' - base output name +------------------------------------ + +Usage: (base-name) +Returns a string containing the base name of the output file(s). +Generally, this is also the base name of the definitions file. + + This Scheme function takes no arguments. + + +File: autogen.info, Node: SCM chdir, Next: SCM count, Prev: SCM base-name, Up: AutoGen Functions + +3.4.4 'chdir' - Change current directory +---------------------------------------- + +Usage: (chdir dir) +Sets the current directory for AutoGen. Shell commands will run from +this directory as well. This is a wrapper around the Guile native +function. It returns its directory name argument and fails the program +on failure. + + Arguments: +dir - new directory name + + +File: autogen.info, Node: SCM count, Next: SCM def-file, Prev: SCM chdir, Up: AutoGen Functions + +3.4.5 'count' - definition count +-------------------------------- + +Usage: (count ag-name) +Count the number of entries for a definition. The input argument must +be a string containing the name of the AutoGen values to be counted. If +there is no value associated with the name, the result is an SCM +immediate integer value of zero. + + Arguments: +ag-name - name of AutoGen value + + +File: autogen.info, Node: SCM def-file, Next: SCM def-file-line, Prev: SCM count, Up: AutoGen Functions + +3.4.6 'def-file' - definitions file name +---------------------------------------- + +Usage: (def-file) +Get the name of the definitions file. Returns the name of the source +file containing the AutoGen definitions. + + This Scheme function takes no arguments. + + +File: autogen.info, Node: SCM def-file-line, Next: SCM dne, Prev: SCM def-file, Up: AutoGen Functions + +3.4.7 'def-file-line' - get a definition file+line number +--------------------------------------------------------- + +Usage: (def-file-line ag-name [ msg-fmt ]) +Returns the file and line number of a AutoGen defined value, using +either the default format, "from %s line %d", or else the format you +supply. For example, if you want to insert a "C" language file-line +directive, you would supply the format "# %2$d \"%1$s\"", but that is +also already supplied with the scheme variable *Note SCM +c-file-line-fmt::. You may use it thus: + + (def-file-line "ag-def-name" c-file-line-fmt) + + It is also safe to use the formatting string, "%2$d". AutoGen uses +an argument vector version of printf: *Note snprintfv::. + + Arguments: +ag-name - name of AutoGen value +msg-fmt - Optional - formatting for line message + + +File: autogen.info, Node: SCM dne, Next: SCM emit, Prev: SCM def-file-line, Up: AutoGen Functions + +3.4.8 'dne' - "Do Not Edit" warning +----------------------------------- + +Usage: (dne prefix [ first_prefix ] [ optpfx ]) +Generate a "DO NOT EDIT" or "EDIT WITH CARE" warning string. Which +depends on whether or not the '--writable' command line option was set. + + The first argument may be an option: '-D' or '-d', causing the second +and (potentially) third arguments to be interpreted as the first and +second arguments. The only useful option is '-D': + +'-D' + will add date, timestamp and version information. +'-d' + is ignored, but still accepted for compatibility with older + versions of the "dne" function where emitting the date was the + default. + + If one of these options is specified, then the "prefix" and "first" +arguments are obtained from the following arguments. The presence (or +absence) of this option can be overridden with the environment variable, +'AUTOGEN_DNE_DATE'. The date is disabled if the value is empty or +starts with one of the characters, '0nNfF' - zero or the first letter of +"no" or "false". + + The 'prefix' argument is a per-line string prefix. The optional +second argument is a prefix for the first line only and, in read-only +mode, activates editor hints. + + -*- buffer-read-only: t -*- vi: set ro: + +The warning string also includes information about the template used to +construct the file and the definitions used in its instantiation. + + Arguments: +prefix - string for starting each output line +first_prefix - Optional - for the first output line +optpfx - Optional - shifted prefix + + +File: autogen.info, Node: SCM emit, Next: SCM emit-string-table, Prev: SCM dne, Up: AutoGen Functions + +3.4.9 'emit' - emit the text for each argument +---------------------------------------------- + +Usage: (emit alist ...) +Walk the tree of arguments, displaying the values of displayable SCM +types. EXCEPTION: if the first argument is a number, then that number +is used to index the output stack. "0" is the default, the current +output. + + Arguments: +alist - list of arguments to stringify and emit + + +File: autogen.info, Node: SCM emit-string-table, Next: SCM error, Prev: SCM emit, Up: AutoGen Functions + +3.4.10 'emit-string-table' - output a string table +-------------------------------------------------- + +Usage: (emit-string-table st-name) +Emit into the current output stream a 'static char const' array named +'st-name' that will have 'NUL' bytes between each inserted string. + + Arguments: +st-name - the name of the array of characters + + +File: autogen.info, Node: SCM error, Next: SCM exist?, Prev: SCM emit-string-table, Up: AutoGen Functions + +3.4.11 'error' - display message and exit +----------------------------------------- + +Usage: (error message) +The argument is a string that printed out as part of an error message. +The message is formed from the formatting string: + + DEFINITIONS ERROR in %s line %d for %s: %s\n + + The first three arguments to this format are provided by the routine +and are: The name of the template file, the line within the template +where the error was found, and the current output file name. + + After displaying the message, the current output file is removed and +autogen exits with the EXIT_FAILURE error code. IF, however, the +argument begins with the number 0 (zero), or the string is the empty +string, then processing continues with the next suffix. + + Arguments: +message - message to display before exiting + + +File: autogen.info, Node: SCM exist?, Next: SCM find-file, Prev: SCM error, Up: AutoGen Functions + +3.4.12 'exist?' - test for value name +------------------------------------- + +Usage: (exist? ag-name) +return SCM_BOOL_T iff a specified name has an AutoGen value. The name +may include indexes and/or member names. All but the last member name +must be an aggregate definition. For example: + (exist? "foo[3].bar.baz") + will yield true if all of the following is true: +There is a member value of either group or string type named 'baz' for +some group value 'bar' that is a member of the 'foo' group with index +'3'. There may be multiple entries of 'bar' within 'foo', only one +needs to contain a value for 'baz'. + + Arguments: +ag-name - name of AutoGen value + + +File: autogen.info, Node: SCM find-file, Next: SCM first-for?, Prev: SCM exist?, Up: AutoGen Functions + +3.4.13 'find-file' - locate a file in the search path +----------------------------------------------------- + +Usage: (find-file file-name [ suffix ]) +AutoGen has a search path that it uses to locate template and definition +files. This function will search the same list for 'file-name', both +with and without the '.suffix', if provided. + + Arguments: +file-name - name of file with text +suffix - Optional - file suffix to try, too + + +File: autogen.info, Node: SCM first-for?, Next: SCM for-by, Prev: SCM find-file, Up: AutoGen Functions + +3.4.14 'first-for?' - detect first iteration +-------------------------------------------- + +Usage: (first-for? [ for_var ]) +Returns 'SCM_BOOL_T' if the named FOR loop (or, if not named, the +current innermost loop) is on the first pass through the data. Outside +of any 'FOR' loop, it returns 'SCM_UNDEFINED', *note FOR::. + + Arguments: +for_var - Optional - which for loop + + +File: autogen.info, Node: SCM for-by, Next: SCM for-from, Prev: SCM first-for?, Up: AutoGen Functions + +3.4.15 'for-by' - set iteration step +------------------------------------ + +Usage: (for-by by) +This function records the "step by" information for an AutoGen FOR +function. Outside of the FOR macro itself, this function will emit an +error. *Note FOR::. + + Arguments: +by - the iteration increment for the AutoGen FOR macro + + +File: autogen.info, Node: SCM for-from, Next: SCM for-index, Prev: SCM for-by, Up: AutoGen Functions + +3.4.16 'for-from' - set initial index +------------------------------------- + +Usage: (for-from from) +This function records the initial index information for an AutoGen FOR +function. Outside of the FOR macro itself, this function will emit an +error. *Note FOR::. + + Arguments: +from - the initial index for the AutoGen FOR macro + + +File: autogen.info, Node: SCM for-index, Next: SCM for-sep, Prev: SCM for-from, Up: AutoGen Functions + +3.4.17 'for-index' - get current loop index +------------------------------------------- + +Usage: (for-index [ for_var ]) +Returns the current index for the named 'FOR' loop. If not named, then +the index for the innermost loop. Outside of any FOR loop, it returns +'SCM_UNDEFINED', *Note FOR::. + + Arguments: +for_var - Optional - which for loop + + +File: autogen.info, Node: SCM for-sep, Next: SCM for-to, Prev: SCM for-index, Up: AutoGen Functions + +3.4.18 'for-sep' - set loop separation string +--------------------------------------------- + +Usage: (for-sep separator) +This function records the separation string that is to be inserted +between each iteration of an AutoGen FOR function. This is often +nothing more than a comma. Outside of the FOR macro itself, this +function will emit an error. + + Arguments: +separator - the text to insert between the output of each FOR iteration + + +File: autogen.info, Node: SCM for-to, Next: SCM found-for?, Prev: SCM for-sep, Up: AutoGen Functions + +3.4.19 'for-to' - set ending index +---------------------------------- + +Usage: (for-to to) +This function records the terminating value information for an AutoGen +FOR function. Outside of the FOR macro itself, this function will emit +an error. *Note FOR::. + + Arguments: +to - the final index for the AutoGen FOR macro + + +File: autogen.info, Node: SCM found-for?, Next: SCM get, Prev: SCM for-to, Up: AutoGen Functions + +3.4.20 'found-for?' - is current index in list? +----------------------------------------------- + +Usage: (found-for? [ for_var ]) +Returns SCM_BOOL_T if the currently indexed value is present, otherwise +SCM_BOOL_F. Outside of any FOR loop, it returns SCM_UNDEFINED. *Note +FOR::. + + Arguments: +for_var - Optional - which for loop + + +File: autogen.info, Node: SCM get, Next: SCM get-c-name, Prev: SCM found-for?, Up: AutoGen Functions + +3.4.21 'get' - get named value +------------------------------ + +Usage: (get ag-name [ alt-val ]) +Get the first string value associated with the name. It will either +return the associated string value (if the name resolves), the alternate +value (if one is provided), or else the empty string. + + Arguments: +ag-name - name of AutoGen value +alt-val - Optional - value if not present + + +File: autogen.info, Node: SCM get-c-name, Next: SCM get-down-name, Prev: SCM get, Up: AutoGen Functions + +3.4.22 'get-c-name' - get named value, mapped to C name syntax +-------------------------------------------------------------- + +Usage: (get-c-name ag-name) +Get the first string value associated with the name. It will either +return the associated string value (if the name resolves), the alternate +value (if one is provided), or else the empty string. The result is +passed through "string->c-name!". + + Arguments: +ag-name - name of AutoGen value + + +File: autogen.info, Node: SCM get-down-name, Next: SCM get-up-name, Prev: SCM get-c-name, Up: AutoGen Functions + +3.4.23 'get-down-name' - get lower cased named value, mapped to C name syntax +----------------------------------------------------------------------------- + +Usage: (get-down-name ag-name) +Get the first string value associated with the name. It will either +return the associated string value (if the name resolves), the alternate +value (if one is provided), or else the empty string. The result is +passed through "string->c-name!" and "string->down-case!". + + Arguments: +ag-name - name of AutoGen value + + +File: autogen.info, Node: SCM get-up-name, Next: SCM high-lim, Prev: SCM get-down-name, Up: AutoGen Functions + +3.4.24 'get-up-name' - get upper cased named value, mapped to C name syntax +--------------------------------------------------------------------------- + +Usage: (get-up-name ag-name) +Get the first string value associated with the name. It will either +return the associated string value (if the name resolves), the alternate +value (if one is provided), or else the empty string. The result is +passed through "string->c-name!" and "string->up-case!". + + Arguments: +ag-name - name of AutoGen value + + +File: autogen.info, Node: SCM high-lim, Next: SCM insert-file, Prev: SCM get-up-name, Up: AutoGen Functions + +3.4.25 'high-lim' - get highest value index +------------------------------------------- + +Usage: (high-lim ag-name) +Returns the highest index associated with an array of definitions. This +is generally, but not necessarily, one less than the 'count' value. +(The indexes may be specified, rendering a non-zero based or sparse +array of values.) + + This is very useful for specifying the size of a zero-based array of +values where not all values are present. For example: + + tMyStruct myVals[ [+ (+ 1 (high-lim "my-val-list")) +] ]; + + Arguments: +ag-name - name of AutoGen value + + +File: autogen.info, Node: SCM insert-file, Next: SCM insert-suspended, Prev: SCM high-lim, Up: AutoGen Functions + +3.4.26 'insert-file' - insert the contents of a (list of) files. +---------------------------------------------------------------- + +Usage: (insert-file alist ...) +Insert the contents of one or more files. + + Arguments: +alist - list of files to emit + + +File: autogen.info, Node: SCM insert-suspended, Next: SCM last-for?, Prev: SCM insert-file, Up: AutoGen Functions + +3.4.27 'insert-suspended' - insert a named suspension in current output +----------------------------------------------------------------------- + +Usage: (insert-suspended susp-name) +Emit into the current output the output suspended under a given +diversion name. + + Arguments: +susp-name - the name of the suspended output + + +File: autogen.info, Node: SCM last-for?, Next: SCM len, Prev: SCM insert-suspended, Up: AutoGen Functions + +3.4.28 'last-for?' - detect last iteration +------------------------------------------ + +Usage: (last-for? [ for_var ]) +Returns SCM_BOOL_T if the named FOR loop (or, if not named, the current +innermost loop) is on the last pass through the data. Outside of any +FOR loop, it returns SCM_UNDEFINED. *Note FOR::. + + Arguments: +for_var - Optional - which for loop + + +File: autogen.info, Node: SCM len, Next: SCM low-lim, Prev: SCM last-for?, Up: AutoGen Functions + +3.4.29 'len' - get count of values +---------------------------------- + +Usage: (len ag-name) +If the named object is a group definition, then "len" is the same as +"count". Otherwise, if it is one or more text definitions, then it is +the sum of their string lengths. If it is a single text definition, +then it is equivalent to '(string-length (get "ag-name"))'. + + Arguments: +ag-name - name of AutoGen value + + +File: autogen.info, Node: SCM low-lim, Next: SCM make-header-guard, Prev: SCM len, Up: AutoGen Functions + +3.4.30 'low-lim' - get lowest value index +----------------------------------------- + +Usage: (low-lim ag-name) +Returns the lowest index associated with an array of definitions. + + Arguments: +ag-name - name of AutoGen value + + +File: autogen.info, Node: SCM make-header-guard, Next: SCM make-tmp-dir, Prev: SCM low-lim, Up: AutoGen Functions + +3.4.31 'make-header-guard' - make self-inclusion guard +------------------------------------------------------ + +Usage: (make-header-guard name) +This function will create a '#ifndef'/'#define' sequence for protecting +a header from multiple evaluation. It will also set the Scheme variable +'header-file' to the name of the file being protected and it will set +'header-guard' to the name of the '#define' being used to protect it. +It is expected that this will be used as follows: + [+ (make-header-guard "group_name") +] + ... + #endif /* [+ (. header-guard) +] */ + + #include "[+ (. header-file) +]" +The '#define' name is composed as follows: + + 1. The first element is the string argument and a separating + underscore. + 2. That is followed by the name of the header file with illegal + characters mapped to underscores. + 3. The end of the name is always, "'_GUARD'". + 4. Finally, the entire string is mapped to upper case. + + The final '#define' name is stored in an SCM symbol named +'header-guard'. Consequently, the concluding '#endif' for the file +should read something like: + + #endif /* [+ (. header-guard) +] */ + + The name of the header file (the current output file) is also stored +in an SCM symbol, 'header-file'. Therefore, if you are also generating +a C file that uses the previously generated header file, you can put +this into that generated file: + + #include "[+ (. header-file) +]" + + Obviously, if you are going to produce more than one header file from +a particular template, you will need to be careful how these SCM symbols +get handled. + + Arguments: +name - header group name + + +File: autogen.info, Node: SCM make-tmp-dir, Next: SCM match-value?, Prev: SCM make-header-guard, Up: AutoGen Functions + +3.4.32 'make-tmp-dir' - create a temporary directory +---------------------------------------------------- + +Usage: (make-tmp-dir) +Create a directory that will be cleaned up upon exit. + + This Scheme function takes no arguments. + + +File: autogen.info, Node: SCM match-value?, Next: SCM max-file-time, Prev: SCM make-tmp-dir, Up: AutoGen Functions + +3.4.33 'match-value?' - test for matching value +----------------------------------------------- + +Usage: (match-value? op ag-name test-str) +This function answers the question, "Is there an AutoGen value named +'ag-name' with a value that matches the pattern 'test-str' using the +match function 'op'?" Return SCM_BOOL_T iff at least one occurrence of +the specified name has such a value. The operator can be any function +that takes two string arguments and yields a boolean. It is expected +that you will use one of the string matching functions provided by +AutoGen. +The value name must follow the same rules as the 'ag-name' argument for +'exist?' (*note SCM exist?::). + + Arguments: +op - boolean result operator +ag-name - name of AutoGen value +test-str - string to test against + + +File: autogen.info, Node: SCM max-file-time, Next: SCM mk-gettextable, Prev: SCM match-value?, Up: AutoGen Functions + +3.4.34 'max-file-time' - get the maximum input file modification time +--------------------------------------------------------------------- + +Usage: (max-file-time) +returns the time stamp of the most recently modified sourc file as the +number of seconds since the epoch. If any input is dynamic (a shell +command), then it will be the current time. + + This Scheme function takes no arguments. + + +File: autogen.info, Node: SCM mk-gettextable, Next: SCM out-delete, Prev: SCM max-file-time, Up: AutoGen Functions + +3.4.35 'mk-gettextable' - print a string in a gettext-able format +----------------------------------------------------------------- + +Usage: (mk-gettextable string) +Returns SCM_UNDEFINED. The input text string is printed to the current +output as one puts() call per paragraph. + + Arguments: +string - a multi-paragraph string + + +File: autogen.info, Node: SCM out-delete, Next: SCM out-depth, Prev: SCM mk-gettextable, Up: AutoGen Functions + +3.4.36 'out-delete' - delete current output file +------------------------------------------------ + +Usage: (out-delete) +Remove the current output file. Cease processing the template for the +current suffix. It is an error if there are 'push'-ed output files. +Use the '(error "0")' scheme function instead. *Note output controls::. + + This Scheme function takes no arguments. + + +File: autogen.info, Node: SCM out-depth, Next: SCM out-emit-suspended, Prev: SCM out-delete, Up: AutoGen Functions + +3.4.37 'out-depth' - output file stack depth +-------------------------------------------- + +Usage: (out-depth) +Returns the depth of the output file stack. *Note output controls::. + + This Scheme function takes no arguments. + + +File: autogen.info, Node: SCM out-emit-suspended, Next: SCM out-line, Prev: SCM out-depth, Up: AutoGen Functions + +3.4.38 'out-emit-suspended' - emit the text of suspended output +--------------------------------------------------------------- + +Usage: (out-emit-suspended susp_nm) +This function is equivalent to '(begin (out-resume <name>) (out-pop +#t))' + + Arguments: +susp_nm - A name tag of suspended output + + +File: autogen.info, Node: SCM out-line, Next: SCM out-move, Prev: SCM out-emit-suspended, Up: AutoGen Functions + +3.4.39 'out-line' - output file line number +------------------------------------------- + +Usage: (out-line) +Returns the current line number of the output file. It rewinds and +reads the file to count newlines. + + This Scheme function takes no arguments. + + +File: autogen.info, Node: SCM out-move, Next: SCM out-name, Prev: SCM out-line, Up: AutoGen Functions + +3.4.40 'out-move' - change name of output file +---------------------------------------------- + +Usage: (out-move new-name) +Rename current output file. *Note output controls::. Please note: +changing the name will not save a temporary file from being deleted. It +may, however, be used on the root output file. + + Arguments: +new-name - new name for the current output file + + +File: autogen.info, Node: SCM out-name, Next: SCM out-pop, Prev: SCM out-move, Up: AutoGen Functions + +3.4.41 'out-name' - current output file name +-------------------------------------------- + +Usage: (out-name) +Returns the name of the current output file. If the current file is a +temporary, unnamed file, then it will scan up the chain until a real +output file name is found. *Note output controls::. + + This Scheme function takes no arguments. + + +File: autogen.info, Node: SCM out-pop, Next: SCM out-push-add, Prev: SCM out-name, Up: AutoGen Functions + +3.4.42 'out-pop' - close current output file +-------------------------------------------- + +Usage: (out-pop [ disp ]) +If there has been a 'push' on the output, then close that file and go +back to the previously open file. It is an error if there has not been +a 'push'. *Note output controls::. + + If there is no argument, no further action is taken. Otherwise, the +argument should be '#t' and the contents of the file are returned by the +function. + + Arguments: +disp - Optional - return contents of the file + + +File: autogen.info, Node: SCM out-push-add, Next: SCM out-push-new, Prev: SCM out-pop, Up: AutoGen Functions + +3.4.43 'out-push-add' - append output to file +--------------------------------------------- + +Usage: (out-push-add file-name) +Identical to 'push-new', except the contents are *not* purged, but +appended to. *Note output controls::. + + Arguments: +file-name - name of the file to append text to + + +File: autogen.info, Node: SCM out-push-new, Next: SCM out-resume, Prev: SCM out-push-add, Up: AutoGen Functions + +3.4.44 'out-push-new' - purge and create output file +---------------------------------------------------- + +Usage: (out-push-new [ file-name ]) +Leave the current output file open, but purge and create a new file that +will remain open until a 'pop' 'delete' or 'switch' closes it. The file +name is optional and, if omitted, the output will be sent to a temporary +file that will be deleted when it is closed. *Note output controls::. + + Arguments: +file-name - Optional - name of the file to create + + +File: autogen.info, Node: SCM out-resume, Next: SCM out-suspend, Prev: SCM out-push-new, Up: AutoGen Functions + +3.4.45 'out-resume' - resume suspended output file +-------------------------------------------------- + +Usage: (out-resume susp_nm) +If there has been a suspended output, then make that output descriptor +current again. That output must have been suspended with the same tag +name given to this routine as its argument. + + Arguments: +susp_nm - A name tag for reactivating + + +File: autogen.info, Node: SCM out-suspend, Next: SCM out-switch, Prev: SCM out-resume, Up: AutoGen Functions + +3.4.46 'out-suspend' - suspend current output file +-------------------------------------------------- + +Usage: (out-suspend suspName) +If there has been a 'push' on the output, then set aside the output +descriptor for later reactiviation with '(out-resume "xxx")'. The tag +name need not reflect the name of the output file. In fact, the output +file may be an anonymous temporary file. You may also change the tag +every time you suspend output to a file, because the tag names are +forgotten as soon as the file has been "resumed". + + Arguments: +suspName - A name tag for reactivating + + +File: autogen.info, Node: SCM out-switch, Next: SCM output-file-next-line, Prev: SCM out-suspend, Up: AutoGen Functions + +3.4.47 'out-switch' - close and create new output +------------------------------------------------- + +Usage: (out-switch file-name) +Switch output files - close current file and make the current file +pointer refer to the new file. This is equivalent to 'out-pop' followed +by 'out-push-new', except that you may not pop the base level output +file, but you may 'switch' it. *Note output controls::. + + Arguments: +file-name - name of the file to create + + +File: autogen.info, Node: SCM output-file-next-line, Next: SCM set-option, Prev: SCM out-switch, Up: AutoGen Functions + +3.4.48 'output-file-next-line' - print the file name and next line number +------------------------------------------------------------------------- + +Usage: (output-file-next-line [ line_off ] [ alt_fmt ]) +Returns a string with the current output file name and line number. The +default format is: # <line+1> "<output-file-name>" The argument may be +either a number indicating an offset from the current output line number +or an alternate formatting string. If both are provided, then the first +must be a numeric offset. + + Be careful that you are directing output to the final output file. +Otherwise, you will get the file name and line number of the temporary +file. That won't be what you want. + + Arguments: +line_off - Optional - offset to line number +alt_fmt - Optional - alternate format string + + +File: autogen.info, Node: SCM set-option, Next: SCM set-writable, Prev: SCM output-file-next-line, Up: AutoGen Functions + +3.4.49 'set-option' - Set a command line option +----------------------------------------------- + +Usage: (set-option opt) +The text argument must be an option name followed by any needed option +argument. Returns SCM_UNDEFINED. + + Arguments: +opt - AutoGen option name + its argument + + +File: autogen.info, Node: SCM set-writable, Next: SCM stack, Prev: SCM set-option, Up: AutoGen Functions + +3.4.50 'set-writable' - Make the output file be writable +-------------------------------------------------------- + +Usage: (set-writable [ set? ]) +This function will set the current output file to be writable (or not). +This is only effective if neither the '--writable' nor '--not-writable' +have been specified. This state is reset when the current suffix's +output is complete. + + Arguments: +set? - Optional - boolean arg, false to make output non-writable + + +File: autogen.info, Node: SCM stack, Next: SCM stack-join, Prev: SCM set-writable, Up: AutoGen Functions + +3.4.51 'stack' - make list of AutoGen values +-------------------------------------------- + +Usage: (stack ag-name) +Create a scheme list of all the strings that are associated with a name. +They must all be text values or we choke. + + Arguments: +ag-name - AutoGen value name + + +File: autogen.info, Node: SCM stack-join, Next: SCM suffix, Prev: SCM stack, Up: AutoGen Functions + +3.4.52 'stack-join' - stack values then join them +------------------------------------------------- + +Usage: (stack-join join ag-name) +This function will collect all the values named 'ag-name' (see the *note +stack function: SCM stack.) and join them separated by the 'join' string +(see the *note join function: SCM join.). + + Arguments: +join - string between each element +ag-name - name of autogen values to stack + + +File: autogen.info, Node: SCM suffix, Next: SCM tpl-file, Prev: SCM stack-join, Up: AutoGen Functions + +3.4.53 'suffix' - get the current suffix +---------------------------------------- + +Usage: (suffix) +Returns the current active suffix (*note pseudo macro::). + + This Scheme function takes no arguments. + + +File: autogen.info, Node: SCM tpl-file, Next: SCM tpl-file-line, Prev: SCM suffix, Up: AutoGen Functions + +3.4.54 'tpl-file' - get the template file name +---------------------------------------------- + +Usage: (tpl-file [ full_path ]) +Returns the name of the current template file. If '#t' is passed in as +an argument, then the template file is hunted for in the template search +path. Otherwise, just the unadorned name. + + Arguments: +full_path - Optional - include full path to file + + +File: autogen.info, Node: SCM tpl-file-line, Next: SCM tpl-file-next-line, Prev: SCM tpl-file, Up: AutoGen Functions + +3.4.55 'tpl-file-line' - get the template file+line number +---------------------------------------------------------- + +Usage: (tpl-file-line [ msg-fmt ]) +Returns the file and line number of the current template macro using +either the default format, "from %s line %d", or else the format you +supply. For example, if you want to insert a "C" language file-line +directive, you would supply the format "# %2$d \"%1$s\"", but that is +also already supplied with the scheme variable *Note SCM +c-file-line-fmt::. You may use it thus: + (tpl-file-line c-file-line-fmt) + + It is also safe to use the formatting string, "%2$d". AutoGen uses +an argument vector version of printf: *Note snprintfv::, and it does not +need to know the types of each argument in order to skip forward to the +second argument. + + Arguments: +msg-fmt - Optional - formatting for line message + + +File: autogen.info, Node: SCM tpl-file-next-line, Next: SCM warn, Prev: SCM tpl-file-line, Up: AutoGen Functions + +3.4.56 'tpl-file-next-line' - get the template file plus next line number +------------------------------------------------------------------------- + +Usage: (tpl-file-next-line [ msg-fmt ]) +This is almost the same as *Note SCM tpl-file-line::, except that the +line referenced is the next line, per C compiler conventions, and +consequently defaults to the format: # <line-no+1> "<file-name>" + + Arguments: +msg-fmt - Optional - formatting for line message + + +File: autogen.info, Node: SCM warn, Next: SCM autogen-version, Prev: SCM tpl-file-next-line, Up: AutoGen Functions + +3.4.57 'warn' - display warning message and continue +---------------------------------------------------- + +Usage: (warn message) +The argument is a string that printed out to stderr. The message is +formed from the formatting string: + + WARNING: %s\n + + The template processing resumes after printing the message. + + Arguments: +message - message to display + + +File: autogen.info, Node: SCM autogen-version, Next: SCM c-file-line-fmt, Prev: SCM warn, Up: AutoGen Functions + +3.4.58 'autogen-version' - autogen version number +------------------------------------------------- + +This is a symbol defining the current AutoGen version number string. It +was first defined in AutoGen-5.2.14. It is currently "5.18.16". + + +File: autogen.info, Node: SCM c-file-line-fmt, Prev: SCM autogen-version, Up: AutoGen Functions + +3.4.59 format file info as, "'#line nn "file"'" +----------------------------------------------- + +This is a symbol that can easily be used with the functions *Note SCM +tpl-file-line::, and *Note SCM def-file-line::. These will emit C +program '#line' directives pointing to template and definitions text, +respectively. + + +File: autogen.info, Node: Common Functions, Next: native macros, Prev: AutoGen Functions, Up: Template File + +3.5 Common Scheme Functions +=========================== + +This section describes a number of general purpose functions that make +the kind of string processing that AutoGen does a little easier. Unlike +the AutoGen specific functions (*note AutoGen Functions::), these +functions are available for direct use during definition load time. The +equality test (*note SCM =::) is "overloaded" to do string equivalence +comparisons. If you are looking for inequality, the Scheme/Lisp way of +spelling that is, "(not (= ...))". + +* Menu: + +* SCM agpl:: 'agpl' - GNU Affero General Public License +* SCM bsd:: 'bsd' - BSD Public License +* SCM c-string:: 'c-string' - emit string for ANSI C +* SCM error-source-line:: 'error-source-line' - display of file & line +* SCM extract:: 'extract' - extract text from another file +* SCM format-arg-count:: 'format-arg-count' - count the args to a format +* SCM fprintf:: 'fprintf' - format to a file +* SCM gperf:: 'gperf' - perform a perfect hash function +* SCM gperf-code:: 'gperf-code' - emit the source of the generated gperf program +* SCM gpl:: 'gpl' - GNU General Public License +* SCM hide-email:: 'hide-email' - convert eaddr to javascript +* SCM html-escape-encode:: 'html-escape-encode' - encode html special characters +* SCM in?:: 'in?' - test for string in list +* SCM join:: 'join' - join string list with separator +* SCM kr-string:: 'kr-string' - emit string for K&R C +* SCM lgpl:: 'lgpl' - GNU Library General Public License +* SCM license:: 'license' - an arbitrary license +* SCM license-description:: 'license-description' - Emit a license description +* SCM license-full:: 'license-full' - Emit the licensing information and description +* SCM license-info:: 'license-info' - Emit the licensing information and copyright years +* SCM license-name:: 'license-name' - Emit the name of the license +* SCM make-gperf:: 'make-gperf' - build a perfect hash function program +* SCM makefile-script:: 'makefile-script' - create makefile script +* SCM max:: 'max' - maximum value in list +* SCM min:: 'min' - minimum value in list +* SCM prefix:: 'prefix' - prefix lines with a string +* SCM printf:: 'printf' - format to stdout +* SCM raw-shell-str:: 'raw-shell-str' - single quote shell string +* SCM shell:: 'shell' - invoke a shell script +* SCM shell-str:: 'shell-str' - double quote shell string +* SCM shellf:: 'shellf' - format a string, run shell +* SCM sprintf:: 'sprintf' - format a string +* SCM string-capitalize:: 'string-capitalize' - capitalize a new string +* SCM string-capitalize!:: 'string-capitalize!' - capitalize a string +* SCM *=*:: 'string-contains-eqv?' - caseless substring +* SCM *==*:: 'string-contains?' - substring match +* SCM string-downcase:: 'string-downcase' - lower case a new string +* SCM string-downcase!:: 'string-downcase!' - make a string be lower case +* SCM *~:: 'string-end-eqv-match?' - caseless regex ending +* SCM *~~:: 'string-end-match?' - regex match end +* SCM *=:: 'string-ends-eqv?' - caseless string ending +* SCM *==:: 'string-ends-with?' - string ending +* SCM ==:: 'string-equals?' - string matching +* SCM ~:: 'string-eqv-match?' - caseless regex match +* SCM =:: 'string-eqv?' - caseless match +* SCM *~*:: 'string-has-eqv-match?' - caseless regex contains +* SCM *~~*:: 'string-has-match?' - contained regex match +* SCM ~~:: 'string-match?' - regex match +* SCM ~*:: 'string-start-eqv-match?' - caseless regex start +* SCM ~~*:: 'string-start-match?' - regex match start +* SCM =*:: 'string-starts-eqv?' - caseless string start +* SCM ==*:: 'string-starts-with?' - string starting +* SCM string-substitute:: 'string-substitute' - multiple global replacements +* SCM string-table-add:: 'string-table-add' - Add an entry to a string table +* SCM string-table-add-ref:: 'string-table-add-ref' - Add an entry to a string table, get reference +* SCM string-table-new:: 'string-table-new' - create a string table +* SCM string-table-size:: 'string-table-size' - print the current size of a string table +* SCM string->c-name!:: 'string->c-name!' - map non-name chars to underscore +* SCM string->camelcase:: 'string->camelcase' - make a string be CamelCase +* SCM string-tr:: 'string-tr' - convert characters with new result +* SCM string-tr!:: 'string-tr!' - convert characters +* SCM string-upcase:: 'string-upcase' - upper case a new string +* SCM string-upcase!:: 'string-upcase!' - make a string be upper case +* SCM sub-shell-str:: 'sub-shell-str' - back quoted (sub-)shell string +* SCM sum:: 'sum' - sum of values in list +* SCM time-string->number:: 'time-string->number' - duration string to seconds +* SCM version-compare:: 'version-compare' - compare two version numbers + + +File: autogen.info, Node: SCM agpl, Next: SCM bsd, Up: Common Functions + +3.5.1 'agpl' - GNU Affero General Public License +------------------------------------------------ + +Usage: (agpl prog-name prefix) +Emit a string that contains the GNU Affero General Public License. This +function is now deprecated. Please *Note SCM license-description::. + + Arguments: +prog-name - name of the program under the GPL +prefix - String for starting each output line + + +File: autogen.info, Node: SCM bsd, Next: SCM c-string, Prev: SCM agpl, Up: Common Functions + +3.5.2 'bsd' - BSD Public License +-------------------------------- + +Usage: (bsd prog_name owner prefix) +Emit a string that contains the Free BSD Public License. This function +is now deprecated. Please *Note SCM license-description::. + + Arguments: +prog_name - name of the program under the BSD +owner - Grantor of the BSD License +prefix - String for starting each output line + + +File: autogen.info, Node: SCM c-string, Next: SCM error-source-line, Prev: SCM bsd, Up: Common Functions + +3.5.3 'c-string' - emit string for ANSI C +----------------------------------------- + +Usage: (c-string string) +Reform a string so that, when printed, the C compiler will be able to +compile the data and construct a string that contains exactly what the +current string contains. Many non-printing characters are replaced with +escape sequences. Newlines are replaced with a backslash, an 'n', a +closing quote, a newline, seven spaces and another re-opening quote. +The compiler will implicitly concatenate them. The reader will see line +breaks. + + A K&R compiler will choke. Use 'kr-string' for that compiler. + + Arguments: +string - string to reformat + + +File: autogen.info, Node: SCM error-source-line, Next: SCM extract, Prev: SCM c-string, Up: Common Functions + +3.5.4 'error-source-line' - display of file & line +-------------------------------------------------- + +Usage: (error-source-line) +This function is only invoked just before Guile displays an error +message. It displays the file name and line number that triggered the +evaluation error. You should not need to invoke this routine directly. +Guile will do it automatically. + + This Scheme function takes no arguments. + + +File: autogen.info, Node: SCM extract, Next: SCM format-arg-count, Prev: SCM error-source-line, Up: Common Functions + +3.5.5 'extract' - extract text from another file +------------------------------------------------ + +Usage: (extract file-name marker-fmt [ caveat ] [ default ]) +This function is used to help construct output files that may contain +text that is carried from one version of the output to the next. + + The first two arguments are required, the second are optional: + + * The 'file-name' argument is used to name the file that contains the + demarcated text. + * The 'marker-fmt' is a formatting string that is used to construct + the starting and ending demarcation strings. The sprintf function + is given the 'marker-fmt' with two arguments. The first is either + "START" or "END". The second is either "DO NOT CHANGE THIS COMMENT" + or the optional 'caveat' argument. + * 'caveat' is presumed to be absent if it is the empty string ('""'). + If absent, "DO NOT CHANGE THIS COMMENT" is used as the second + string argument to the 'marker-fmt'. + * When a 'default' argument is supplied and no pre-existing text is + found, then this text will be inserted between the START and END + markers. + +The resulting strings are presumed to be unique within the subject file. +As a simplified example: + + [+ (extract "fname" "// %s - SOMETHING - %s" "" + "example default") +] +will result in the following text being inserted into the output: + + // START - SOMETHING - DO NOT CHANGE THIS COMMENT + example default + // END - SOMETHING - DO NOT CHANGE THIS COMMENT + +The "'example default'" string can then be carried forward to the next +generation of the output, *provided* the output is not named "'fname'" +and the old output is renamed to "'fname'" before AutoGen-eration +begins. + +*NB:* + You can set aside previously generated source files inside the + pseudo macro with a Guile/scheme function, extract the text you + want to keep with this extract function. Just remember you should + delete it at the end, too. Here is an example from my Finite State + Machine generator: + + [+ AutoGen5 Template -*- Mode: text -*- + h=%s-fsm.h c=%s-fsm.c + (shellf + "test -f %1$s-fsm.h && mv -f %1$s-fsm.h .fsm.head + test -f %1$s-fsm.c && mv -f %1$s-fsm.c .fsm.code" (base-name)) + +] + + This code will move the two previously produced output files to + files named ".fsm.head" and ".fsm.code". At the end of the 'c' + output processing, I delete them. + +*also NB:* + This function presumes that the output file ought to be editable so + that the code between the 'START' and 'END' marks can be edited by + the template user. Consequently, when the '(extract ...)' function + is invoked, if the 'writable' option has not been specified, then + it will be set at that point. If this is not the desired behavior, + the '--not-writable' command line option will override this. Also, + you may use the guile function '(chmod "file" mode-value)' to + override whatever AutoGen is using for the result mode. + + Arguments: +file-name - name of file with text +marker-fmt - format for marker text +caveat - Optional - warn about changing marker +default - Optional - default initial text + + +File: autogen.info, Node: SCM format-arg-count, Next: SCM fprintf, Prev: SCM extract, Up: Common Functions + +3.5.6 'format-arg-count' - count the args to a format +----------------------------------------------------- + +Usage: (format-arg-count format) +Sometimes, it is useful to simply be able to figure out how many +arguments are required by a format string. For example, if you are +extracting a format string for the purpose of generating a macro to +invoke a printf-like function, you can run the formatting string through +this function to determine how many arguments to provide for in the +macro. e.g. for this extraction text: + + /*=fumble bumble + * fmt: 'stumble %s: %d\n' + =*/ + +You may wish to generate a macro: + + #define BUMBLE(a1,a2) printf_like(something,(a1),(a2)) + +You can do this by knowing that the format needs two arguments. + + Arguments: +format - formatting string + + +File: autogen.info, Node: SCM fprintf, Next: SCM gperf, Prev: SCM format-arg-count, Up: Common Functions + +3.5.7 'fprintf' - format to a file +---------------------------------- + +Usage: (fprintf port format [ format-arg ... ]) +Format a string using arguments from the alist. Write to a specified +port. The result will NOT appear in your output. Use this to print +information messages to a template user. + + Arguments: +port - Guile-scheme output port +format - formatting string +format-arg - Optional - list of arguments to formatting string + + +File: autogen.info, Node: SCM gperf, Next: SCM gperf-code, Prev: SCM fprintf, Up: Common Functions + +3.5.8 'gperf' - perform a perfect hash function +----------------------------------------------- + +Usage: (gperf name str) +Perform the perfect hash on the input string. This is only useful if +you have previously created a gperf program with the 'make-gperf' +function *Note SCM make-gperf::. The 'name' you supply here must match +the name used to create the program and the string to hash must be one +of the strings supplied in the 'make-gperf' string list. The result +will be a perfect hash index. + + See the documentation for 'gperf(1GNU)' for more details. + + Arguments: +name - name of hash list +str - string to hash + + +File: autogen.info, Node: SCM gperf-code, Next: SCM gpl, Prev: SCM gperf, Up: Common Functions + +3.5.9 'gperf-code' - emit the source of the generated gperf program +------------------------------------------------------------------- + +Usage: (gperf-code st-name) +Returns the contents of the emitted code, suitable for inclusion in +another program. The interface contains the following elements: + +'struct <st-name>_index' + containg the fields: '{char const * name, int const id; };' + +'<st-name>_hash()' + This is the hashing function with local only scope (static). + +'<st-name>_find()' + This is the searching and validation function. The first argument + is the string to look up, the second is its length. It returns a + pointer to the corresponding '<st-name>_index' entry. + + Use this in your template as follows where "<st-name>" was set to be +"'lookup'": + + [+ (make-gperf "lookup" (join "\n" (stack "name_list"))) + (gperf-code "lookup") +] + void my_fun(char * str) { + struct lookup_index * li = lookup_find(str, strlen(str)); + if (li != NULL) printf("%s yields %d\n", str, li->idx); + + Arguments: +st-name - the name of the gperf hash list + + +File: autogen.info, Node: SCM gpl, Next: SCM hide-email, Prev: SCM gperf-code, Up: Common Functions + +3.5.10 'gpl' - GNU General Public License +----------------------------------------- + +Usage: (gpl prog-name prefix) +Emit a string that contains the GNU General Public License. This +function is now deprecated. Please *Note SCM license-description::. + + Arguments: +prog-name - name of the program under the GPL +prefix - String for starting each output line + + +File: autogen.info, Node: SCM hide-email, Next: SCM html-escape-encode, Prev: SCM gpl, Up: Common Functions + +3.5.11 'hide-email' - convert eaddr to javascript +------------------------------------------------- + +Usage: (hide-email display eaddr) +Hides an email address as a java scriptlett. The 'mailto:' tag and the +email address are coded bytes rather than plain text. They are also +broken up. + + Arguments: +display - display text +eaddr - email address + + +File: autogen.info, Node: SCM html-escape-encode, Next: SCM in?, Prev: SCM hide-email, Up: Common Functions + +3.5.12 'html-escape-encode' - encode html special characters +------------------------------------------------------------ + +Usage: (html-escape-encode str) +This function will replace replace the characters ''&'', ''<'' and ''>'' +characters with the HTML/XML escape-encoded strings ('"&"', +'"<"', and '">"', respectively). + + Arguments: +str - string to make substitutions in + + +File: autogen.info, Node: SCM in?, Next: SCM join, Prev: SCM html-escape-encode, Up: Common Functions + +3.5.13 'in?' - test for string in list +-------------------------------------- + +Usage: (in? test-string string-list ...) +Return SCM_BOOL_T if the first argument string is found in one of the +entries in the second (list-of-strings) argument. + + Arguments: +test-string - string to look for +string-list - list of strings to check + + +File: autogen.info, Node: SCM join, Next: SCM kr-string, Prev: SCM in?, Up: Common Functions + +3.5.14 'join' - join string list with separator +----------------------------------------------- + +Usage: (join separator list ...) +With the first argument as the separator string, joins together an +a-list of strings into one long string. The list may contain nested +lists, partly because you cannot always control that. + + Arguments: +separator - string to insert between entries +list - list of strings to join + + +File: autogen.info, Node: SCM kr-string, Next: SCM lgpl, Prev: SCM join, Up: Common Functions + +3.5.15 'kr-string' - emit string for K&R C +------------------------------------------ + +Usage: (kr-string string) +Reform a string so that, when printed, a K&R C compiler will be able to +compile the data and construct a string that contains exactly what the +current string contains. Many non-printing characters are replaced with +escape sequences. New-lines are replaced with a backslash-n-backslash +and newline sequence, + + Arguments: +string - string to reformat + + +File: autogen.info, Node: SCM lgpl, Next: SCM license, Prev: SCM kr-string, Up: Common Functions + +3.5.16 'lgpl' - GNU Library General Public License +-------------------------------------------------- + +Usage: (lgpl prog_name owner prefix) +Emit a string that contains the GNU Library General Public License. +This function is now deprecated. Please *Note SCM +license-description::. + + Arguments: +prog_name - name of the program under the LGPL +owner - Grantor of the LGPL +prefix - String for starting each output line + + +File: autogen.info, Node: SCM license, Next: SCM license-description, Prev: SCM lgpl, Up: Common Functions + +3.5.17 'license' - an arbitrary license +--------------------------------------- + +Usage: (license lic_name prog_name owner prefix) +Emit a string that contains the named license. This function is now +deprecated. Please *Note SCM license-description::. + + Arguments: +lic_name - file name of the license +prog_name - name of the licensed program or library +owner - Grantor of the License +prefix - String for starting each output line + + +File: autogen.info, Node: SCM license-description, Next: SCM license-full, Prev: SCM license, Up: Common Functions + +3.5.18 'license-description' - Emit a license description +--------------------------------------------------------- + +Usage: (license-description license prog-name prefix [ owner ]) +Emit a string that contains a detailed license description, with +substitutions for program name, copyright holder and a per-line prefix. +This is the text typically used as part of a source file header. For +more details, *Note the license-full command: SCM license-full. + + Arguments: +license - name of license type +prog-name - name of the program under the GPL +prefix - String for starting each output line +owner - Optional - owner of the program + + +File: autogen.info, Node: SCM license-full, Next: SCM license-info, Prev: SCM license-description, Up: Common Functions + +3.5.19 'license-full' - Emit the licensing information and description +---------------------------------------------------------------------- + +Usage: (license-full license prog-name prefix [ owner ] [ years ]) +Emit all the text that 'license-info' and 'license-description' would +emit (*note 'license-info': SCM license-info, and *note +'license-description': SCM license-description.), with all the same +substitutions. + + All of these depend upon the existence of a license file named after +the 'license' argument with a '.lic' suffix. That file should contain +three blocks of text, each separated by two or more consecutive newline +characters (at least one completely blank line). + + The first section describes copyright attribution and the name of the +usage licence. For GNU software, this should be the text that is to be +displayed with the program version. Four text markers can be replaced: +<PFX>, <program>, <years> and <owner>. + + The second section is a short description of the terms of the +license. This is typically the kind of text that gets displayed in the +header of source files. Only the <PFX>, <owner> and <program> markers +are substituted. + + The third section is strictly the name of the license. No marker +substitutions are performed. + + <PFX>Copyright (C) <years> <owner>, all rights reserved. + <PFX> + <PFX>This is free software. It is licensed for use, + <PFX>modification and redistribution under the terms + <PFX>of the GNU General Public License, version 3 or later + <PFX> <http://gnu.org/licenses/gpl.html> + + <PFX><program> is free software: you can redistribute it + <PFX>and/or modify it under the terms of the GNU General + <PFX>Public License as published by the Free Software ... + + the GNU General Public License, version 3 or later + + Arguments: +license - name of license type +prog-name - name of the program under the GPL +prefix - String for starting each output line +owner - Optional - owner of the program +years - Optional - copyright years + + +File: autogen.info, Node: SCM license-info, Next: SCM license-name, Prev: SCM license-full, Up: Common Functions + +3.5.20 'license-info' - Emit the licensing information and copyright years +-------------------------------------------------------------------------- + +Usage: (license-info license prog-name prefix [ owner ] [ years ]) +Emit a string that contains the licensing description, with some +substitutions for program name, copyright holder, a list of years when +the source was modified, and a per-line prefix. This text typically +includes a brief license description and is often printed out when a +program starts running or as part of the '--version' output. For more +details, *Note the license-full command: SCM license-full. + + Arguments: +license - name of license type +prog-name - name of the program under the GPL +prefix - String for starting each output line +owner - Optional - owner of the program +years - Optional - copyright years + + +File: autogen.info, Node: SCM license-name, Next: SCM make-gperf, Prev: SCM license-info, Up: Common Functions + +3.5.21 'license-name' - Emit the name of the license +---------------------------------------------------- + +Usage: (license-name license) +Emit a string that contains the full name of the license. + + Arguments: +license - name of license type + + +File: autogen.info, Node: SCM make-gperf, Next: SCM makefile-script, Prev: SCM license-name, Up: Common Functions + +3.5.22 'make-gperf' - build a perfect hash function program +----------------------------------------------------------- + +Usage: (make-gperf name strings ...) +Build a program to perform perfect hashes of a known list of input +strings. This function produces no output, but prepares a program +named, 'gperf_<name>' for use by the gperf function *Note SCM gperf::. + + This program will be obliterated as AutoGen exits. However, you may +incorporate the generated hashing function into your C program with +commands something like the following: + + [+ (shellf "sed '/^int main(/,$d;/^#line/d' ${gpdir}/%s.c" + name ) +] + + where 'name' matches the name provided to this 'make-perf' function. +'gpdir' is the variable used to store the name of the temporary +directory used to stash all the files. + + Arguments: +name - name of hash list +strings - list of strings to hash + + +File: autogen.info, Node: SCM makefile-script, Next: SCM max, Prev: SCM make-gperf, Up: Common Functions + +3.5.23 'makefile-script' - create makefile script +------------------------------------------------- + +Usage: (makefile-script text) +This function will take ordinary shell script text and reformat it so +that it will work properly inside of a makefile shell script. Not every +shell construct can be supported; the intent is to have most ordinary +scripts work without much, if any, alteration. + + The following transformations are performed on the source text: + + 1. Trailing whitespace on each line is stripped. + + 2. Except for the last line, the string, " ; \\" is appended to the + end of every line that does not end with certain special characters + or keywords. Note that this will mutilate multi-line quoted + strings, but 'make' renders it impossible to use multi-line + constructs anyway. + + 3. If the line ends with a backslash, it is left alone. + + 4. If the line ends with a semi-colon, conjunction operator, pipe + (vertical bar) or one of the keywords "then", "else" or "in", then + a space and a backslash is added, but no semi-colon. + + 5. The dollar sign character is doubled, unless it immediately + precedes an opening parenthesis or the single character make macros + '*', '<', '@', '?' or '%'. Other single character make macros + that do not have enclosing parentheses will fail. For shell usage + of the "$@", "$?" and "$*" macros, you must enclose them with + curly braces, e.g., "${?}". The ksh construct '$(<command>)' will + not work. Though some 'make's accept '${var}' constructs, this + function will assume it is for shell interpretation and double the + dollar character. You must use '$(var)' for all 'make' + substitutions. + + 6. Double dollar signs are replaced by four before the next character + is examined. + + 7. Every line is prefixed with a tab, unless the first line already + starts with a tab. + + 8. The newline character on the last line, if present, is suppressed. + + 9. Blank lines are stripped. + + 10. Lines starting with "@ifdef", "@ifndef", "@else" and "@endif" are + presumed to be autoconf "sed" expression tags. These lines will be + emitted as-is, with no tab prefix and no line splicing backslash. + These lines can then be processed at configure time with + 'AC_CONFIG_FILES' sed expressions, similar to: + + sed "/^@ifdef foo/d;/^@endif foo/d;/^@ifndef foo/,/^@endif foo/d" + +This function is intended to be used approximately as follows: + + $(TARGET) : $(DEPENDENCIES) + <+ (out-push-new) +> + ....mostly arbitrary shell script text.... + <+ (makefile-script (out-pop #t)) +> + + Arguments: +text - the text of the script + + +File: autogen.info, Node: SCM max, Next: SCM min, Prev: SCM makefile-script, Up: Common Functions + +3.5.24 'max' - maximum value in list +------------------------------------ + +Usage: (max list ...) +Return the maximum value in the list + + Arguments: +list - list of values. Strings are converted to numbers + + +File: autogen.info, Node: SCM min, Next: SCM prefix, Prev: SCM max, Up: Common Functions + +3.5.25 'min' - minimum value in list +------------------------------------ + +Usage: (min list ...) +Return the minimum value in the list + + Arguments: +list - list of values. Strings are converted to numbers + + +File: autogen.info, Node: SCM prefix, Next: SCM printf, Prev: SCM min, Up: Common Functions + +3.5.26 'prefix' - prefix lines with a string +-------------------------------------------- + +Usage: (prefix prefix text) +Prefix every line in the second string with the first string. This +includes empty lines. Trailing white space will be removed so if the +prefix is all horizontal white space, then it will be removed from +otherwise blank lines. Also, if the last character is a newline, then +*two* prefixes will be inserted into the result text. + + For example, if the first string is "# " and the second contains: + "two\nlines\n" +The result string will contain: + # two + # lines + # + + The last line will be incomplete: no newline and no space after the +hash character, either. + + Arguments: +prefix - string to insert at start of each line +text - multi-line block of text + + +File: autogen.info, Node: SCM printf, Next: SCM raw-shell-str, Prev: SCM prefix, Up: Common Functions + +3.5.27 'printf' - format to stdout +---------------------------------- + +Usage: (printf format [ format-arg ... ]) +Format a string using arguments from the alist. Write to the standard +out port. The result will NOT appear in your output. Use this to print +information messages to a template user. Use "(sprintf ...)" to add +text to your document. + + Arguments: +format - formatting string +format-arg - Optional - list of arguments to formatting string + + +File: autogen.info, Node: SCM raw-shell-str, Next: SCM shell, Prev: SCM printf, Up: Common Functions + +3.5.28 'raw-shell-str' - single quote shell string +-------------------------------------------------- + +Usage: (raw-shell-str string) +Convert the text of the string into a singly quoted string that a normal +shell will process into the original string. (It will not do macro +expansion later, either.) Contained single quotes become tripled, with +the middle quote escaped with a backslash. Normal shells will +reconstitute the original string. + + *Notice*: some shells will not correctly handle unusual non-printing +characters. This routine works for most reasonably conventional ASCII +strings. + + Arguments: +string - string to transform + + +File: autogen.info, Node: SCM shell, Next: SCM shell-str, Prev: SCM raw-shell-str, Up: Common Functions + +3.5.29 'shell' - invoke a shell script +-------------------------------------- + +Usage: (shell command ...) +Generate a string by writing the value to a server shell and reading the +output back in. The template programmer is responsible for ensuring +that it completes within 10 seconds. If it does not, the server will be +killed, the output tossed and a new server started. + + Please note: This is the same server process used by the '#shell' +definitions directive and backquoted '`' definitions. There may be left +over state from previous shell expressions and the '`' processing in the +declarations. However, a 'cd' to the original directory is always +issued before the new command is issued. + + Also note: When initializing, autogen will set the environment +variable "AGexe" to the full path of the autogen executable. + + Arguments: +command - shell command - the result is from stdout + + +File: autogen.info, Node: SCM shell-str, Next: SCM shellf, Prev: SCM shell, Up: Common Functions + +3.5.30 'shell-str' - double quote shell string +---------------------------------------------- + +Usage: (shell-str string) +Convert the text of the string into a double quoted string that a normal +shell will process into the original string, almost. It will add the +escape character '\\' before two special characters to accomplish this: +the backslash '\\' and double quote '"'. + + *Notice*: some shells will not correctly handle unusual non-printing +characters. This routine works for most reasonably conventional ASCII +strings. + + *WARNING*: +This function omits the extra backslash in front of a backslash, +however, if it is followed by either a backquote or a dollar sign. It +must do this because otherwise it would be impossible to protect the +dollar sign or backquote from shell evaluation. Consequently, it is not +possible to render the strings "\\$" or "\\'". The lesser of two evils. + + All others characters are copied directly into the output. + + The 'sub-shell-str' variation of this routine behaves identically, +except that the extra backslash is omitted in front of '"' instead of +'`'. You have to think about it. I'm open to suggestions. + + Meanwhile, the best way to document is with a detailed output +example. If the backslashes make it through the text processing +correctly, below you will see what happens with three example strings. +The first example string contains a list of quoted 'foo's, the second is +the same with a single backslash before the quote characters and the +last is with two backslash escapes. Below each is the result of the +'raw-shell-str', 'shell-str' and 'sub-shell-str' functions. + + foo[0] ''foo'' 'foo' "foo" `foo` $foo + raw-shell-str -> \'\''foo'\'\'' '\''foo'\'' "foo" `foo` $foo' + shell-str -> "''foo'' 'foo' \"foo\" `foo` $foo" + sub-shell-str -> `''foo'' 'foo' "foo" \`foo\` $foo` + + foo[1] \'bar\' \"bar\" \`bar\` \$bar + raw-shell-str -> '\'\''bar\'\'' \"bar\" \`bar\` \$bar' + shell-str -> "\\'bar\\' \\\"bar\\\" \`bar\` \$bar" + sub-shell-str -> `\\'bar\\' \"bar\" \\\`bar\\\` \$bar` + + foo[2] \\'BAZ\\' \\"BAZ\\" \\`BAZ\\` \\$BAZ + raw-shell-str -> '\\'\''BAZ\\'\'' \\"BAZ\\" \\`BAZ\\` \\$BAZ' + shell-str -> "\\\\'BAZ\\\\' \\\\\"BAZ\\\\\" \\\`BAZ\\\` \\\$BAZ" + sub-shell-str -> `\\\\'BAZ\\\\' \\\"BAZ\\\" \\\\\`BAZ\\\\\` \\\$BAZ` + + There should be four, three, five and three backslashes for the four +examples on the last line, respectively. The next to last line should +have four, five, three and three backslashes. If this was not +accurately reproduced, take a look at the agen5/test/shell.test test. +Notice the backslashes in front of the dollar signs. It goes from zero +to one to three for the "cooked" string examples. + + Arguments: +string - string to transform + + +File: autogen.info, Node: SCM shellf, Next: SCM sprintf, Prev: SCM shell-str, Up: Common Functions + +3.5.31 'shellf' - format a string, run shell +-------------------------------------------- + +Usage: (shellf format [ format-arg ... ]) +Format a string using arguments from the alist, then send the result to +the shell for interpretation. + + Arguments: +format - formatting string +format-arg - Optional - list of arguments to formatting string + + +File: autogen.info, Node: SCM sprintf, Next: SCM string-capitalize, Prev: SCM shellf, Up: Common Functions + +3.5.32 'sprintf' - format a string +---------------------------------- + +Usage: (sprintf format [ format-arg ... ]) +Format a string using arguments from the alist. + + Arguments: +format - formatting string +format-arg - Optional - list of arguments to formatting string + + +File: autogen.info, Node: SCM string-capitalize, Next: SCM string-capitalize!, Prev: SCM sprintf, Up: Common Functions + +3.5.33 'string-capitalize' - capitalize a new string +---------------------------------------------------- + +Usage: (string-capitalize str) +Create a new SCM string containing the same text as the original, only +all the first letter of each word is upper cased and all other letters +are made lower case. + + Arguments: +str - input string + + +File: autogen.info, Node: SCM string-capitalize!, Next: SCM *=*, Prev: SCM string-capitalize, Up: Common Functions + +3.5.34 'string-capitalize!' - capitalize a string +------------------------------------------------- + +Usage: (string-capitalize! str) +capitalize all the words in an SCM string. + + Arguments: +str - input/output string + + +File: autogen.info, Node: SCM *=*, Next: SCM *==*, Prev: SCM string-capitalize!, Up: Common Functions + +3.5.35 'string-contains-eqv?' - caseless substring +-------------------------------------------------- + +Usage: (*=* text match) +string-contains-eqv?: Test to see if a string contains an equivalent +string. 'equivalent' means the strings match, but without regard to +character case and certain characters are considered 'equivalent'. +Viz., '-', '_' and '^' are equivalent. + + Arguments: +text - text to test for pattern +match - pattern/substring to search for + + +File: autogen.info, Node: SCM *==*, Next: SCM string-downcase, Prev: SCM *=*, Up: Common Functions + +3.5.36 'string-contains?' - substring match +------------------------------------------- + +Usage: (*==* text match) +string-contains?: Test to see if a string contains a substring. +"strstr(3)" will find an address. + + Arguments: +text - text to test for pattern +match - pattern/substring to search for + + +File: autogen.info, Node: SCM string-downcase, Next: SCM string-downcase!, Prev: SCM *==*, Up: Common Functions + +3.5.37 'string-downcase' - lower case a new string +-------------------------------------------------- + +Usage: (string-downcase str) +Create a new SCM string containing the same text as the original, only +all the upper case letters are changed to lower case. + + Arguments: +str - input string + + +File: autogen.info, Node: SCM string-downcase!, Next: SCM *~, Prev: SCM string-downcase, Up: Common Functions + +3.5.38 'string-downcase!' - make a string be lower case +------------------------------------------------------- + +Usage: (string-downcase! str) +Change to lower case all the characters in an SCM string. + + Arguments: +str - input/output string + + +File: autogen.info, Node: SCM *~, Next: SCM *~~, Prev: SCM string-downcase!, Up: Common Functions + +3.5.39 'string-end-eqv-match?' - caseless regex ending +------------------------------------------------------ + +Usage: (*~ text match) +string-end-eqv-match?: Test to see if a string ends with a pattern. +Case is not significant. + + Arguments: +text - text to test for pattern +match - pattern/substring to search for + + +File: autogen.info, Node: SCM *~~, Next: SCM *=, Prev: SCM *~, Up: Common Functions + +3.5.40 'string-end-match?' - regex match end +-------------------------------------------- + +Usage: (*~~ text match) +string-end-match?: Test to see if a string ends with a pattern. Case is +significant. + + Arguments: +text - text to test for pattern +match - pattern/substring to search for + + +File: autogen.info, Node: SCM *=, Next: SCM *==, Prev: SCM *~~, Up: Common Functions + +3.5.41 'string-ends-eqv?' - caseless string ending +-------------------------------------------------- + +Usage: (*= text match) +string-ends-eqv?: Test to see if a string ends with an equivalent +string. + + Arguments: +text - text to test for pattern +match - pattern/substring to search for + + +File: autogen.info, Node: SCM *==, Next: SCM ==, Prev: SCM *=, Up: Common Functions + +3.5.42 'string-ends-with?' - string ending +------------------------------------------ + +Usage: (*== text match) +string-ends-with?: Test to see if a string ends with a substring. +strcmp(3) returns zero for comparing the string ends. + + Arguments: +text - text to test for pattern +match - pattern/substring to search for + + +File: autogen.info, Node: SCM ==, Next: SCM ~, Prev: SCM *==, Up: Common Functions + +3.5.43 'string-equals?' - string matching +----------------------------------------- + +Usage: (== text match) +string-equals?: Test to see if two strings exactly match. + + Arguments: +text - text to test for pattern +match - pattern/substring to search for + + +File: autogen.info, Node: SCM ~, Next: SCM =, Prev: SCM ==, Up: Common Functions + +3.5.44 'string-eqv-match?' - caseless regex match +------------------------------------------------- + +Usage: (~ text match) +string-eqv-match?: Test to see if a string fully matches a pattern. +Case is not significant, but any character equivalences must be +expressed in your regular expression. + + Arguments: +text - text to test for pattern +match - pattern/substring to search for + + +File: autogen.info, Node: SCM =, Next: SCM *~*, Prev: SCM ~, Up: Common Functions + +3.5.45 'string-eqv?' - caseless match +------------------------------------- + +Usage: (= text match) +string-eqv?: Test to see if two strings are equivalent. 'equivalent' +means the strings match, but without regard to character case and +certain characters are considered 'equivalent'. Viz., '-', '_' and '^' +are equivalent. If the arguments are not strings, then the result of +the numeric comparison is returned. + + This is an overloaded operation. If the arguments are both numbers, +then the query is passed through to 'scm_num_eq_p()', otherwise the +result depends on the SCMs being strictly equal. + + Arguments: +text - text to test for pattern +match - pattern/substring to search for + + +File: autogen.info, Node: SCM *~*, Next: SCM *~~*, Prev: SCM =, Up: Common Functions + +3.5.46 'string-has-eqv-match?' - caseless regex contains +-------------------------------------------------------- + +Usage: (*~* text match) +string-has-eqv-match?: Test to see if a string contains a pattern. Case +is not significant. + + Arguments: +text - text to test for pattern +match - pattern/substring to search for + + +File: autogen.info, Node: SCM *~~*, Next: SCM ~~, Prev: SCM *~*, Up: Common Functions + +3.5.47 'string-has-match?' - contained regex match +-------------------------------------------------- + +Usage: (*~~* text match) +string-has-match?: Test to see if a string contains a pattern. Case is +significant. + + Arguments: +text - text to test for pattern +match - pattern/substring to search for + + +File: autogen.info, Node: SCM ~~, Next: SCM ~*, Prev: SCM *~~*, Up: Common Functions + +3.5.48 'string-match?' - regex match +------------------------------------ + +Usage: (~~ text match) +string-match?: Test to see if a string fully matches a pattern. Case is +significant. + + Arguments: +text - text to test for pattern +match - pattern/substring to search for + + +File: autogen.info, Node: SCM ~*, Next: SCM ~~*, Prev: SCM ~~, Up: Common Functions + +3.5.49 'string-start-eqv-match?' - caseless regex start +------------------------------------------------------- + +Usage: (~* text match) +string-start-eqv-match?: Test to see if a string starts with a pattern. +Case is not significant. + + Arguments: +text - text to test for pattern +match - pattern/substring to search for + + +File: autogen.info, Node: SCM ~~*, Next: SCM =*, Prev: SCM ~*, Up: Common Functions + +3.5.50 'string-start-match?' - regex match start +------------------------------------------------ + +Usage: (~~* text match) +string-start-match?: Test to see if a string starts with a pattern. +Case is significant. + + Arguments: +text - text to test for pattern +match - pattern/substring to search for + + +File: autogen.info, Node: SCM =*, Next: SCM ==*, Prev: SCM ~~*, Up: Common Functions + +3.5.51 'string-starts-eqv?' - caseless string start +--------------------------------------------------- + +Usage: (=* text match) +string-starts-eqv?: Test to see if a string starts with an equivalent +string. + + Arguments: +text - text to test for pattern +match - pattern/substring to search for + + +File: autogen.info, Node: SCM ==*, Next: SCM string-substitute, Prev: SCM =*, Up: Common Functions + +3.5.52 'string-starts-with?' - string starting +---------------------------------------------- + +Usage: (==* text match) +string-starts-with?: Test to see if a string starts with a substring. + + Arguments: +text - text to test for pattern +match - pattern/substring to search for + + +File: autogen.info, Node: SCM string-substitute, Next: SCM string-table-add, Prev: SCM ==*, Up: Common Functions + +3.5.53 'string-substitute' - multiple global replacements +--------------------------------------------------------- + +Usage: (string-substitute source match repl) +'match' and 'repl' may be either a single string or a list of strings. +Either way, they must have the same structure and number of elements. +For example, to replace all amphersands, less than and greater than +characters, do something like this: + + (string-substitute source + (list "&" "<" ">") + (list "&" "<" ">")) + + Arguments: +source - string to transform +match - substring or substring list to be replaced +repl - replacement strings or substrings + + +File: autogen.info, Node: SCM string-table-add, Next: SCM string-table-add-ref, Prev: SCM string-substitute, Up: Common Functions + +3.5.54 'string-table-add' - Add an entry to a string table +---------------------------------------------------------- + +Usage: (string-table-add st-name str-val) +Check for a duplicate string and, if none, then insert a new string into +the string table. In all cases, returns the character index of the +beginning of the string in the table. + + The returned index can be used in expressions like: + string_array + <returned-value> +that will yield the address of the first byte of the inserted string. +See the 'strtable.test' AutoGen test for a usage example. + + Arguments: +st-name - the name of the array of characters +str-val - the (possibly) new value to add + + +File: autogen.info, Node: SCM string-table-add-ref, Next: SCM string-table-new, Prev: SCM string-table-add, Up: Common Functions + +3.5.55 'string-table-add-ref' - Add an entry to a string table, get reference +----------------------------------------------------------------------------- + +Usage: (string-table-add-ref st-name str-val) +Identical to string-table-add, except the value returned is the string +"st-name" '+' and the index returned by string-table-add. + + Arguments: +st-name - the name of the array of characters +str-val - the (possibly) new value to add + + +File: autogen.info, Node: SCM string-table-new, Next: SCM string-table-size, Prev: SCM string-table-add-ref, Up: Common Functions + +3.5.56 'string-table-new' - create a string table +------------------------------------------------- + +Usage: (string-table-new st-name) +This function will create an array of characters. The companion +functions, (*Note SCM string-table-add::, *Note SCM +string-table-add-ref::, and *note SCM emit-string-table::) will insert +text and emit the populated table. + + With these functions, it should be much easier to construct +structures containing string offsets instead of string pointers. That +can be very useful when transmitting, storing or sharing data with +different address spaces. + +Here is a brief example copied from the strtable.test test: + + [+ (string-table-new "scribble") + (out-push-new) ;; redirect output to temporary + (define ct 1) +][+ + + FOR str IN that was the week that was +][+ + (set! ct (+ ct 1)) + +] + [+ (string-table-add-ref "scribble" (get "str")) +],[+ + ENDFOR +] + [+ (out-suspend "main") + (emit-string-table "scribble") + (ag-fprintf 0 "\nchar const *ap[%d] = {" ct) + (out-resume "main") + (out-pop #t) ;; now dump out the redirected output +] + NULL }; + +Some explanation: + +I added the '(out-push-new)' because the string table text is diverted +into an output stream named, "scribble" and I want to have the string +table emitted before the string table references. The string table +references are also emitted inside the 'FOR' loop. So, when the loop is +done, the current output is suspended under the name, "main" and the +"scribble" table is then emitted into the primary output. +('emit-string-table' inserts its output directly into the current output +stream. It does not need to be the last function in an AutoGen macro +block.) Next I 'ag-fprintf' the array-of-pointer declaration directly +into the current output. Finally I restore the "main" output stream and +'(out-pop #t)'-it into the main output stream. + + Here is the result. Note that duplicate strings are not repeated in +the string table: + + static char const scribble[18] = + "that\0" "was\0" "the\0" "week\0"; + + char const *ap[7] = { + scribble+0, + scribble+5, + scribble+9, + scribble+13, + scribble+0, + scribble+5, + NULL }; + + These functions use the global name space 'stt-*' in addition to the +function names. + + If you utilize this in your programming, it is recommended that you +prevent printf format usage warnings with the GCC option +'-Wno-format-contains-nul' + + Arguments: +st-name - the name of the array of characters + + +File: autogen.info, Node: SCM string-table-size, Next: SCM string->c-name!, Prev: SCM string-table-new, Up: Common Functions + +3.5.57 'string-table-size' - print the current size of a string table +--------------------------------------------------------------------- + +Usage: (string-table-size st-name) +Returns the current byte count of the string table. + + Arguments: +st-name - the name of the array of characters + + +File: autogen.info, Node: SCM string->c-name!, Next: SCM string->camelcase, Prev: SCM string-table-size, Up: Common Functions + +3.5.58 'string->c-name!' - map non-name chars to underscore +----------------------------------------------------------- + +Usage: (string->c-name! str) +Change all the graphic characters that are invalid in a C name token +into underscores. Whitespace characters are ignored. Any other +character type (i.e. non-graphic and non-white) will cause a failure. + + Arguments: +str - input/output string + + +File: autogen.info, Node: SCM string->camelcase, Next: SCM string-tr, Prev: SCM string->c-name!, Up: Common Functions + +3.5.59 'string->camelcase' - make a string be CamelCase +------------------------------------------------------- + +Usage: (string->camelcase str) +Capitalize the first letter of each block of letters and numbers, and +stripping out characters that are not alphanumerics. For example, +"alpha-beta0gamma" becomes "AlphaBeta0gamma". + + Arguments: +str - input/output string + + +File: autogen.info, Node: SCM string-tr, Next: SCM string-tr!, Prev: SCM string->camelcase, Up: Common Functions + +3.5.60 'string-tr' - convert characters with new result +------------------------------------------------------- + +Usage: (string-tr source match translation) +This is identical to 'string-tr!', except that it does not over-write +the previous value. + + Arguments: +source - string to transform +match - characters to be converted +translation - conversion list + + +File: autogen.info, Node: SCM string-tr!, Next: SCM string-upcase, Prev: SCM string-tr, Up: Common Functions + +3.5.61 'string-tr!' - convert characters +---------------------------------------- + +Usage: (string-tr! source match translation) +This is the same as the 'tr(1)' program, except the string to transform +is the first argument. The second and third arguments are used to +construct mapping arrays for the transformation of the first argument. + + It is too bad this little program has so many different and +incompatible implementations! + + Arguments: +source - string to transform +match - characters to be converted +translation - conversion list + + +File: autogen.info, Node: SCM string-upcase, Next: SCM string-upcase!, Prev: SCM string-tr!, Up: Common Functions + +3.5.62 'string-upcase' - upper case a new string +------------------------------------------------ + +Usage: (string-upcase str) +Create a new SCM string containing the same text as the original, only +all the lower case letters are changed to upper case. + + Arguments: +str - input string + + +File: autogen.info, Node: SCM string-upcase!, Next: SCM sub-shell-str, Prev: SCM string-upcase, Up: Common Functions + +3.5.63 'string-upcase!' - make a string be upper case +----------------------------------------------------- + +Usage: (string-upcase! str) +Change to upper case all the characters in an SCM string. + + Arguments: +str - input/output string + + +File: autogen.info, Node: SCM sub-shell-str, Next: SCM sum, Prev: SCM string-upcase!, Up: Common Functions + +3.5.64 'sub-shell-str' - back quoted (sub-)shell string +------------------------------------------------------- + +Usage: (sub-shell-str string) +This function is substantially identical to 'shell-str', except that the +quoting character is '`' and the "leave the escape alone" character is +'"'. + + Arguments: +string - string to transform + + +File: autogen.info, Node: SCM sum, Next: SCM time-string->number, Prev: SCM sub-shell-str, Up: Common Functions + +3.5.65 'sum' - sum of values in list +------------------------------------ + +Usage: (sum list ...) +Compute the sum of the list of expressions. + + Arguments: +list - list of values. Strings are converted to numbers + + +File: autogen.info, Node: SCM time-string->number, Next: SCM version-compare, Prev: SCM sum, Up: Common Functions + +3.5.66 'time-string->number' - duration string to seconds +--------------------------------------------------------- + +Usage: (time-string->number time_spec) +Convert the argument string to a time period in seconds. The string may +use multiple parts consisting of days, hours minutes and seconds. These +are indicated with a suffix of 'd', 'h', 'm' and 's' respectively. +Hours, minutes and seconds may also be represented with 'HH:MM:SS' or, +without hours, as 'MM:SS'. + + Arguments: +time_spec - string to parse + + +File: autogen.info, Node: SCM version-compare, Prev: SCM time-string->number, Up: Common Functions + +3.5.67 'version-compare' - compare two version numbers +------------------------------------------------------ + +Usage: (version-compare op v1 v2) +Converts v1 and v2 strings into 64 bit values and returns the result of +running 'op' on those values. It assumes that the version is a 1 to 4 +part dot-separated series of numbers. Suffixes like, "5pre4" or +"5-pre4" will be interpreted as two numbers. The first number ("5" in +this case) will be decremented and the number after the "pre" will be +added to 0xC000. (Unless your platform is unable to support 64 bit +integer arithmetic. Then it will be added to 0xC0.) Consequently, +these yield true: + (version-compare > "5.8.5" "5.8.5-pre4") + (version-compare > "5.8.5-pre10" "5.8.5-pre4") + + Arguments: +op - comparison operator +v1 - first version +v2 - compared-to version + + +File: autogen.info, Node: native macros, Next: output controls, Prev: Common Functions, Up: Template File + +3.6 AutoGen Native Macros +========================= + +This section describes the various AutoGen natively defined macros. +Unlike the Scheme functions, some of these macros are "block macros" +with a scope that extends through a terminating macro. Block macros +must not overlap. That is to say, a block macro started within the +scope of an encompassing block macro must have its matching end macro +appear before the encompassing block macro is either ended or +subdivided. + + The block macros are these: + +'CASE' + This macro has scope through the 'ESAC' macro. The scope is + subdivided by 'SELECT' macros. You must have at least one 'SELECT' + macro. + +'DEFINE' + This macro has scope through the 'ENDDEF' macro. The defined user + macro can never be a block macro. This macro is extracted from the + template before the template is processed. Consequently, you + cannot select a definition based on context. You can, however, + place them all at the end of the file. + +'FOR' + This macro has scope through the 'ENDFOR' macro. + +'IF' + This macro has scope through the 'ENDIF' macro. The scope may be + subdivided by 'ELIF' and 'ELSE' macros. Obviously, there may be + only one 'ELSE' macro and it must be the last of these + subdivisions. + +'INCLUDE' + This macro has the scope of the included file. It is a block macro + in the sense that the included file must not contain any incomplete + block macros. + +'WHILE' + This macro has scope through the 'ENDWHILE' macro. +* Menu: + +* AGMacro syntax:: AutoGen Macro Syntax +* BREAK:: BREAK - Leave a FOR or WHILE macro +* CASE:: CASE - Select one of several template blocks +* COMMENT:: COMMENT - A block of comment to be ignored +* CONTINUE:: CONTINUE - Skip to end of a FOR or WHILE macro. +* DEBUG:: DEBUG - Print debug message to trace output +* DEFINE:: DEFINE - Define a user AutoGen macro +* ELIF:: ELIF - Alternate Conditional Template Block +* ELSE:: ELSE - Alternate Template Block +* ENDDEF:: ENDDEF - Ends a macro definition. +* ENDFOR:: ENDFOR - Terminates the 'FOR' function template block +* ENDIF:: ENDIF - Terminate the 'IF' Template Block +* ENDWHILE:: ENDWHILE - Terminate the 'WHILE' Template Block +* ESAC:: ESAC - Terminate the 'CASE' Template Block +* EXPR:: EXPR - Evaluate and emit an Expression +* FOR:: FOR - Emit a template block multiple times +* IF:: IF - Conditionally Emit a Template Block +* INCLUDE:: INCLUDE - Read in and emit a template block +* INVOKE:: INVOKE - Invoke a User Defined Macro +* RETURN:: RETURN - Leave an INVOKE-d (DEFINE) macro +* SELECT:: SELECT - Selection block for CASE function +* UNKNOWN:: UNKNOWN - Either a user macro or a value name. +* WHILE:: WHILE - Conditionally loop over a Template Block +* shell command:: Inserting text from a shell script +* guile command:: Inserting text from a scheme script + + +File: autogen.info, Node: AGMacro syntax, Next: BREAK, Up: native macros + +3.6.1 AutoGen Macro Syntax +-------------------------- + +The general syntax is: + + [ { <native-macro-name> | <user-defined-name> } ] [ <arg> ... ] + +The syntax for '<arg>' depends on the particular macro, but is generally +a full expression (*note expression syntax::). Here are the exceptions +to that general rule: + + 1. 'INVOKE' macros, implicit or explicit, must be followed by a list + of name/string value pairs. The string values are simple + expressions, as described above. + + That is, the 'INVOKE' syntax is one of these two: + <user-macro-name> [ <name> [ = <expression> ] ... ] + + INVOKE <name-expression> [ <name> [ = <expression> ] ... ] + + 2. AutoGen FOR macros must be in one of three forms: + + FOR <name> [ <separator-string> ] + + FOR <name> (...Scheme expression list) + + FOR <name> IN <string-entry> [ ... ] + where: + '<name>' + must be a simple name. + '<separator-string>' + is inserted between copies of the enclosed block. Do not try + to use "IN" as your separator string. It won't work. + '<string-entry>' + is an entry in a list of strings. "'<name>'" is assigned each + value from the "'IN'" list before expanding the 'FOR' block. + '(...Scheme expression list)' + is expected to contain one or more of the 'for-from', + 'for-to', 'for-by', and 'for-sep' functions. (*Note FOR::, + and *note AutoGen Functions::) + + The first two forms iterate over the 'FOR' block if '<name>' is + found in the AutoGen values. The last form will create the AutoGen + value named '<name>'. + + 3. AutoGen 'DEFINE' macros must be followed by a simple name. + Anything after that is ignored. Consequently, that "comment space" + may be used to document any named values the macro expects to have + set up as arguments. *Note DEFINE::. + + 4. The AutoGen 'COMMENT', 'ELSE', 'ESAC' and the 'END*' macros take no + arguments and ignore everything after the macro name (e.g. see + *note COMMENT::) + + +File: autogen.info, Node: BREAK, Next: CASE, Prev: AGMacro syntax, Up: native macros + +3.6.2 BREAK - Leave a FOR or WHILE macro +---------------------------------------- + +This will unwind the loop context and resume after ENDFOR/ENDWHILE. Note +that unless this happens to be the last iteration anyway, the +(last-for?) function will never yield "#t". + + +File: autogen.info, Node: CASE, Next: COMMENT, Prev: BREAK, Up: native macros + +3.6.3 CASE - Select one of several template blocks +-------------------------------------------------- + +The arguments are evaluated and converted to a string, if necessary. A +simple name will be interpreted as an AutoGen value name and its value +will be used by the 'SELECT' macros (see the example below and the +expression evaluation function, *note EXPR::). The scope of the macro +is up to the matching 'ESAC' macro. Within the scope of a 'CASE', this +string is matched against case selection macros. There are sixteen +match macros that are derived from four different ways matches may be +performed, plus an "always true", "true if the AutoGen value was found", +and "true if no AutoGen value was found" matches. The codes for the +nineteen match macros are formed as follows: + + 1. Must the match start matching from the beginning of the string? If + not, then the match macro code starts with an asterisk ('*'). + 2. Must the match finish matching at the end of the string? If not, + then the match macro code ends with an asterisk ('*'). + 3. Is the match a pattern match or a string comparison? If a + comparison, use an equal sign ('='). If a pattern match, use a + tilde ('~'). + 4. Is the match case sensitive? If alphabetic case is important, + double the tilde or equal sign. + 5. Do you need a default match when none of the others match? Use a + single asterisk ('*'). + 6. Do you need to distinguish between an empty string value and a + value that was not found? Use the non-existence test ('!E') before + testing a full match against an empty string ('== '''). There is + also an existence test ('+E'), more for symmetry than for practical + use. + +For example: + + [+ CASE <full-expression> +] + [+ ~~* "[Tt]est" +]reg exp must match at start, not at end + [+ == "TeSt" +]a full-string, case sensitive compare + [+ = "TEST" +]a full-string, case insensitive compare + [+ !E +]not exists - matches if no AutoGen value found + [+ == "" +]expression yielded a zero-length string + [+ +E +]exists - matches if there is any value result + [+ * +]always match - no testing + [+ ESAC +] + + '<full-expression>' (*note expression syntax::) may be any +expression, including the use of apply-codes and value-names. If the +expression yields a number, it is converted to a decimal string. + + These case selection codes have also been implemented as Scheme +expression functions using the same codes. They are documented in this +texi doc as "string-*?" predicates (*note Common Functions::). + + +File: autogen.info, Node: COMMENT, Next: CONTINUE, Prev: CASE, Up: native macros + +3.6.4 COMMENT - A block of comment to be ignored +------------------------------------------------ + +This function can be specified by the user, but there will never be a +situation where it will be invoked at emit time. The macro is actually +removed from the internal representation. + + If the native macro name code is '#', then the entire macro function +is treated as a comment and ignored. + + [+ # say what you want, but no '+' before any ']' chars +] + + +File: autogen.info, Node: CONTINUE, Next: DEBUG, Prev: COMMENT, Up: native macros + +3.6.5 CONTINUE - Skip to end of a FOR or WHILE macro. +----------------------------------------------------- + +This will skip the remainder of the loop and start the next. + + +File: autogen.info, Node: DEBUG, Next: DEFINE, Prev: CONTINUE, Up: native macros + +3.6.6 DEBUG - Print debug message to trace output +------------------------------------------------- + +If the tracing level is at "debug-message" or above (*note autogen +trace::), this macro prints a debug message to trace output. This +message is not evaluated. This macro can also be used to set useful +debugger breakpoints. By inserting [+DEBUG n+] into your template, you +can set a debugger breakpoint on the #n case element below (in the +AutoGen source) and step through the processing of interesting parts of +your template. + + To be useful, you have to have access to the source tree where +autogen was built and the template being processed. The definitions are +also helpful, but not crucial. Please contact the author if you think +you might actually want to use this. + + +File: autogen.info, Node: DEFINE, Next: ELIF, Prev: DEBUG, Up: native macros + +3.6.7 DEFINE - Define a user AutoGen macro +------------------------------------------ + +This function will define a new macro. You must provide a name for the +macro. You do not specify any arguments, though the invocation may +specify a set of name/value pairs that are to be active during the +processing of the macro. + + [+ define foo +] + ... macro body with macro functions ... + [+ enddef +] + ... [+ foo bar='raw text' baz=<<text expression>> +] + + Once the macro has been defined, this new macro can be invoked by +specifying the macro name as the first token after the start macro +marker. Alternatively, you may make the invocation explicitly invoke a +defined macro by specifying 'INVOKE' (*note INVOKE::) in the macro +invocation. If you do that, the macro name can be computed with an +expression that gets evaluated every time the INVOKE macro is +encountered. + + Any remaining text in the macro invocation will be used to create new +name/value pairs that only persist for the duration of the processing of +the macro. The expressions are evaluated the same way basic expressions +are evaluated. *Note expression syntax::. + + The resulting definitions are handled much like regular definitions, +except: + + 1. The values may not be compound. That is, they may not contain + nested name/value pairs. + 2. The bindings go away when the macro is complete. + 3. The name/value pairs are separated by whitespace instead of + semi-colons. + 4. Sequences of strings are not concatenated. + + *NB:* The macro is extracted from the template as the template is + scanned. You cannot conditionally define a macro by enclosing it + in an 'IF'/'ENDIF' (*note IF::) macro pair. If you need to + dynamically select the format of a 'DEFINE'd macro, then put the + flavors into separate template files that simply define macros. + 'INCLUDE' (*note INCLUDE::) the appropriate template when you have + computed which you need. + + Due to this, it is acceptable and even a good idea to place all the +'DEFINE' macros at the end of the template. That puts the main body of +the template at the beginning of the file. + + +File: autogen.info, Node: ELIF, Next: ELSE, Prev: DEFINE, Up: native macros + +3.6.8 ELIF - Alternate Conditional Template Block +------------------------------------------------- + +This macro must only appear after an 'IF' function, and before any +associated 'ELSE' or 'ENDIF' functions. It denotes the start of an +alternate template block for the 'IF' function. Its expression argument +is evaluated as are the arguments to 'IF'. For a complete description +*Note IF::. + + +File: autogen.info, Node: ELSE, Next: ENDDEF, Prev: ELIF, Up: native macros + +3.6.9 ELSE - Alternate Template Block +------------------------------------- + +This macro must only appear after an 'IF' function, and before the +associated 'ENDIF' function. It denotes the start of an alternate +template block for the 'IF' function. For a complete description *Note +IF::. + + +File: autogen.info, Node: ENDDEF, Next: ENDFOR, Prev: ELSE, Up: native macros + +3.6.10 ENDDEF - Ends a macro definition. +---------------------------------------- + +This macro ends the 'DEFINE' function template block. For a complete +description *Note DEFINE::. + + +File: autogen.info, Node: ENDFOR, Next: ENDIF, Prev: ENDDEF, Up: native macros + +3.6.11 ENDFOR - Terminates the 'FOR' function template block +------------------------------------------------------------ + +This macro ends the 'FOR' function template block. For a complete +description *Note FOR::. + + +File: autogen.info, Node: ENDIF, Next: ENDWHILE, Prev: ENDFOR, Up: native macros + +3.6.12 ENDIF - Terminate the 'IF' Template Block +------------------------------------------------ + +This macro ends the 'IF' function template block. For a complete +description *Note IF::. + + +File: autogen.info, Node: ENDWHILE, Next: ESAC, Prev: ENDIF, Up: native macros + +3.6.13 ENDWHILE - Terminate the 'WHILE' Template Block +------------------------------------------------------ + +This macro ends the 'WHILE' function template block. For a complete +description *Note WHILE::. + + +File: autogen.info, Node: ESAC, Next: EXPR, Prev: ENDWHILE, Up: native macros + +3.6.14 ESAC - Terminate the 'CASE' Template Block +------------------------------------------------- + +This macro ends the 'CASE' function template block. For a complete +description, *Note CASE::. + + +File: autogen.info, Node: EXPR, Next: FOR, Prev: ESAC, Up: native macros + +3.6.15 EXPR - Evaluate and emit an Expression +--------------------------------------------- + +This macro does not have a name to cause it to be invoked explicitly, +though if a macro starts with one of the apply codes or one of the +simple expression markers, then an expression macro is inferred. The +result of the expression evaluation (*note expression syntax::) is +written to the current output. + + +File: autogen.info, Node: FOR, Next: IF, Prev: EXPR, Up: native macros + +3.6.16 FOR - Emit a template block multiple times +------------------------------------------------- + +This macro has a slight variation on the standard syntax: + FOR <value-name> [ <separator-string> ] + + FOR <value-name> (...Scheme expression list) + + FOR <value-name> IN "string" [ ... ] + + Other than for the last form, the first macro argument must be the +name of an AutoGen value. If there is no value associated with the +name, the 'FOR' template block is skipped entirely. The scope of the +'FOR' macro extends to the corresponding 'ENDFOR' macro. The last form +will create an array of string values named '<value-name>' that only +exists within the context of this 'FOR' loop. With this form, in order +to use a 'separator-string', you must code it into the end of the +template block using the '(last-for?)' predicate function (*note SCM +last-for?::). + + If there are any arguments after the 'value-name', the initial +characters are used to determine the form. If the first character is +either a semi-colon (';') or an opening parenthesis ('('), then it is +presumed to be a Scheme expression containing the FOR macro specific +functions 'for-from', 'for-by', 'for-to', and/or 'for-sep'. *Note +AutoGen Functions::. If it consists of an ''i'' an ''n'' and separated +by white space from more text, then the 'FOR x IN' form is processed. +Otherwise, the remaining text is presumed to be a string for inserting +between each iteration of the loop. This string will be emitted one +time less than the number of iterations of the loop. That is, it is +emitted after each loop, excepting for the last iteration. + + If the from/by/to functions are invoked, they will specify which +copies of the named value are to be processed. If there is no copy of +the named value associated with a particular index, the 'FOR' template +block will be instantiated anyway. The template must use 'found-for?' +(*note SCM found-for?::) or other methods for detecting missing +definitions and emitting default text. In this fashion, you can insert +entries from a sparse or non-zero based array into a dense, zero based +array. + + *NB:* the 'for-from', 'for-to', 'for-by' and 'for-sep' functions are +disabled outside of the context of the 'FOR' macro. Likewise, the +'first-for?', 'last-for?' 'for-index', and 'found-for?' functions are +disabled outside of the range of a 'FOR' block. + + *Also:* the '<value-name>' must be a single level name, not a +compound name (*note naming values::). + + [+FOR var (for-from 0) (for-to <number>) (for-sep ",") +] + ... text with various substitutions ...[+ + ENDFOR var+] + +this will repeat the '... text with various substitutions ...' +<number>+1 times. Each repetition, except for the last, will have a +comma ',' after it. + + [+FOR var ",\n" +] + ... text with various substitutions ...[+ + ENDFOR var +] + +This will do the same thing, but only for the index values of 'var' that +have actually been defined. + + +File: autogen.info, Node: IF, Next: INCLUDE, Prev: FOR, Up: native macros + +3.6.17 IF - Conditionally Emit a Template Block +----------------------------------------------- + +Conditional block. Its arguments are evaluated (*note EXPR::) and if +the result is non-zero or a string with one or more bytes, then the +condition is true and the text from that point until a matched 'ELIF', +'ELSE' or 'ENDIF' is emitted. 'ELIF' introduces a conditional +alternative if the 'IF' clause evaluated FALSE and 'ELSE' introduces an +unconditional alternative. + + [+IF <full-expression> +] + emit things that are for the true condition[+ + + ELIF <full-expression-2> +] + emit things that are true maybe[+ + + ELSE "This may be a comment" +] + emit this if all but else fails[+ + + ENDIF "This may *also* be a comment" +] + +'<full-expression>' may be any expression described in the 'EXPR' +expression function, including the use of apply-codes and value-names. +If the expression yields an empty string, it is interpreted as false. + + +File: autogen.info, Node: INCLUDE, Next: INVOKE, Prev: IF, Up: native macros + +3.6.18 INCLUDE - Read in and emit a template block +-------------------------------------------------- + +The entire contents of the named file is inserted at this point. The +contents of the file are processed for macro expansion. The arguments +are eval-ed, so you may compute the name of the file to be included. +The included file must not contain any incomplete function blocks. +Function blocks are template text beginning with any of the macro +functions 'CASE', 'DEFINE', 'FOR', 'IF' and 'WHILE'; extending through +their respective terminating macro functions. + + +File: autogen.info, Node: INVOKE, Next: RETURN, Prev: INCLUDE, Up: native macros + +3.6.19 INVOKE - Invoke a User Defined Macro +------------------------------------------- + +User defined macros may be invoked explicitly or implicitly. If you +invoke one implicitly, the macro must begin with the name of the defined +macro. Consequently, this may *not* be a computed value. If you +explicitly invoke a user defined macro, the macro begins with the macro +name 'INVOKE' followed by a basic expression that must yield a known +user defined macro. A macro name _must_ be found, or AutoGen will issue +a diagnostic and exit. + + Arguments are passed to the invoked macro by name. The text +following the macro name must consist of a series of names each of which +is followed by an equal sign ('=') and a basic expression that yields a +string. + + The string values may contain template macros that are parsed the +first time the macro is processed and evaluated again every time the +macro is evaluated. + + +File: autogen.info, Node: RETURN, Next: SELECT, Prev: INVOKE, Up: native macros + +3.6.20 RETURN - Leave an INVOKE-d (DEFINE) macro +------------------------------------------------ + +This will unwind looping constructs inside of a DEFINE-d macro and +return to the invocation point. The output files and diversions are +left alone. This means it is unwise to start diversions in a DEFINEd +macro and RETURN from it before you have handled the diversion. Unless +you are careful. Here is some rope for you. Please be careful using +it. + + +File: autogen.info, Node: SELECT, Next: UNKNOWN, Prev: RETURN, Up: native macros + +3.6.21 SELECT - Selection block for CASE function +------------------------------------------------- + +This macro selects a block of text by matching an expression against the +sample text expression evaluated in the 'CASE' macro. *Note CASE::. + + You do not specify a 'SELECT' macro with the word "select". Instead, +you must use one of the 19 match operators described in the 'CASE' macro +description. + + +File: autogen.info, Node: UNKNOWN, Next: WHILE, Prev: SELECT, Up: native macros + +3.6.22 UNKNOWN - Either a user macro or a value name. +----------------------------------------------------- + +The macro text has started with a name not known to AutoGen. If, at run +time, it turns out to be the name of a defined macro, then that macro is +invoked. If it is not, then it is a conditional expression that is +evaluated only if the name is defined at the time the macro is invoked. + + You may not specify 'UNKNOWN' explicitly. + + +File: autogen.info, Node: WHILE, Next: shell command, Prev: UNKNOWN, Up: native macros + +3.6.23 WHILE - Conditionally loop over a Template Block +------------------------------------------------------- + +Conditionally repeated block. Its arguments are evaluated (*note +EXPR::) and as long as the result is non-zero or a string with one or +more bytes, then the condition is true and the text from that point +until a matched 'ENDWHILE' is emitted. + + [+WHILE <full-expression> +] + emit things that are for the true condition[+ + + ENDWHILE +] + +'<full-expression>' may be any expression described in the 'EXPR' +expression function, including the use of apply-codes and value-names. +If the expression yields an empty string, it is interpreted as false. + + +File: autogen.info, Node: shell command, Next: guile command, Prev: WHILE, Up: native macros + +3.6.24 Inserting text from a shell script +----------------------------------------- + +If the text between the start and end macro markers starts with an +opening curly brace (''{'') or is surrounded by back quotes (''`''), +then the text is handed off to the server shell for evaluation. The +output to standard out is inserted into the document. If the text +starts with the curly brace, all the text is passed off as is to the +shell. If surrounded by back quotes, then the string is "cooked" before +being handed off to the shell. + + +File: autogen.info, Node: guile command, Prev: shell command, Up: native macros + +3.6.25 Inserting text from a scheme script +------------------------------------------ + +If the text between the start and end macro markers starts with a +semi-colon or an opening parenthesis, all the text is handed off to the +Guile/scheme processor. If the last result is text or a number, it is +added (as text) to the output document. + + +File: autogen.info, Node: output controls, Prev: native macros, Up: Template File + +3.7 Redirecting Output +====================== + +AutoGen provides a means for redirecting the template output to +different files or, in 'M4' parlance, to various diversions. It is +accomplished by providing a set of Scheme functions named 'out-*' (*note +AutoGen Functions::). + +'out-push-new (*note SCM out-push-new::)' + This allows you to logically "push" output files onto a stack. If + you supply a string name, then a file by that name is created to + hold the output. If you do not supply a name, then the text is + written to a scratch pad and retrieved by passing a '#t' argument + to the 'out-pop' (*note SCM out-pop::) function. + +'out-pop (*note SCM out-pop::)' + This function closes the current output file and resumes output to + the next one in the stack. At least one output must have been + pushed onto the output stack with the 'out-push-new' (*note SCM + out-push-new::) function. If '#t' is passed in as an argument, + then the entire contents of the diversion (or file) is returned. + +'out-suspend (*note SCM out-suspend::)' + This function does not close the current output, but instead sets + it aside for resumption by the given name with 'out-resume'. The + current output must have been pushed on the output queue with + 'out-push-new' (*note SCM out-push-new::). + +'out-resume (*note SCM out-resume::)' + This will put a named file descriptor back onto the top of stack so + that it becomes the current output again. + +'out-switch (*note SCM out-switch::)' + This closes the current output and creates a new file, purging any + preexisting one. This is a shortcut for "pop" followed by "push", + but this can also be done at the base level. + +'out-move (*note SCM out-move::)' + Renames the current output file without closing it. + + There are also several functions for determining the output status. +*Note AutoGen Functions::. + + +File: autogen.info, Node: Augmenting AutoGen, Next: autogen Invocation, Prev: Template File, Up: Top + +4 Augmenting AutoGen Features +***************************** + +AutoGen was designed to be simple to enhance. You can do it by +providing shell commands, Guile/Scheme macros or callout functions that +can be invoked as a Guile macro. Here is how you do these. + +* Menu: + +* shell commands:: Shell Output Commands +* guile macros:: Guile Macros +* guile callouts:: Guile Callout Functions +* AutoGen macros:: AutoGen Macros + + +File: autogen.info, Node: shell commands, Next: guile macros, Up: Augmenting AutoGen + +4.1 Shell Output Commands +========================= + +Shell commands are run inside of a server process. This means that, +unlike 'make', context is kept from one command to the next. +Consequently, you can define a shell function in one place inside of +your template and invoke it in another. You may also store values in +shell variables for later reference. If you load functions from a file +containing shell functions, they will remain until AutoGen exits. + + If your shell script should determine that AutoGen should stop +processing, the recommended method for stopping AutoGen is: + die "some error text" + +That is a shell function added by AutoGen. It will send a SIGTERM to +autogen and exit from the "persistent" shell. + + +File: autogen.info, Node: guile macros, Next: guile callouts, Prev: shell commands, Up: Augmenting AutoGen + +4.2 Guile Macros +================ + +Guile also maintains context from one command to the next. This means +you may define functions and variables in one place and reference them +elsewhere. If your Scheme script should determine that AutoGen should +stop processing, the recommended method for stopping AutoGen is: + (error "some error text") + + +File: autogen.info, Node: guile callouts, Next: AutoGen macros, Prev: guile macros, Up: Augmenting AutoGen + +4.3 Guile Callout Functions +=========================== + +Callout functions must be registered with Guile to work. This can be +accomplished either by putting your routines into a shared library that +contains a 'void scm_init(void)' routine that registers these routines, +or by building them into AutoGen. + + To build them into AutoGen, you must place your routines in the +source directory and name the files 'exp*.c'. You also must have a +stylized comment that 'getdefs' can find that conforms to the following: + + /*=gfunc <function-name> + * + * what: <short one-liner> + * general_use: + * string: <invocation-name-string> + * exparg: <name>, <description> [, ['optional'] [, 'list']] + * doc: A long description telling people how to use + * this function. + =*/ + SCM + ag_scm_<function-name>( SCM arg_name[, ...] ) + { <code> } + +'gfunc' + You must have this exactly thus. + +'<function-name>' + This must follow C syntax for variable names + +'<short one-liner>' + This should be about a half a line long. It is used as a + subsection title in this document. + +'general_use:' + You must supply this unless you are an AutoGen maintainer and are + writing a function that queries or modifies the state of AutoGen. + +'<invocation-name-string>' + Normally, the FUNCTION-NAME string will be transformed into a + reasonable invocation name. However, that is not always true. If + the result does not suit your needs, then supply an alternate + string. + +'exparg:' + You must supply one for each argument to your function. All + optional arguments must be last. The last of the optional + arguments may be a list, if you choose. + +'doc:' + Please say something meaningful. + +'[, ...]' + Do not actually specify an ANSI ellipsis here. You must provide + for all the arguments you specified with EXPARG. + + See the Guile documentation for more details. More information is +also available in a large comment at the beginning of the +'agen5/snarf.tpl' template file. + + +File: autogen.info, Node: AutoGen macros, Prev: guile callouts, Up: Augmenting AutoGen + +4.4 AutoGen Macros +================== + +There are two kinds those you define yourself and AutoGen native. The +user-defined macros may be defined in your templates, *Note DEFINE::. + + As for AutoGen native macros, do not add any. It is easy to do, but +I won't like it. The basic functions needed to accomplish looping over +and selecting blocks of text have proved to be sufficient over a period +of several years. New text transformations can be easily added via any +of the AutoGen extension methods, as discussed above. + + +File: autogen.info, Node: autogen Invocation, Next: Installation, Prev: Augmenting AutoGen, Up: Top + +5 Invoking autogen +****************** + +AutoGen creates text files from templates using external definitions. + + 'AutoGen' is designed for generating program files that contain +repetitive text with varied substitutions. The goal is to simplify the +maintenance of programs that contain large amounts of repetitious text. +This is especially valuable if there are several blocks of such text +that must be kept synchronized. + + One common example is the problem of maintaining the code required +for processing program options. Processing options requires a minimum +of four different constructs be kept in proper order in different places +in your program. You need at least: The flag character in the flag +string, code to process the flag when it is encountered, a global state +variable or two, and a line in the usage text. You will need more +things besides this if you choose to implement long option names, +configuration file processing, environment variables and so on. + + All of this can be done mechanically; with the proper templates and +this program. + + This chapter was generated by *AutoGen*, using the 'agtexi-cmd' +template and the option descriptions for the 'autogen' program. This +software is released under the GNU General Public License, version 3 or +later. + +* Menu: + +* autogen usage:: autogen help/usage ('--help') +* autogen input-select:: input-select options +* autogen out-handling:: out-handling options +* autogen debug-tpl:: debug-tpl options +* autogen processing:: processing options +* autogen dep-track:: dep-track options +* autogen autoopts-opts:: autoopts-opts options +* autogen config:: presetting/configuring autogen +* autogen exit status:: exit status +* autogen Examples:: Examples + + +File: autogen.info, Node: autogen usage, Next: autogen input-select, Up: autogen Invocation + +5.1 autogen help/usage ('--help') +================================= + +This is the automatically generated usage text for autogen. + + The text printed is the same whether selected with the 'help' option +('--help') or the 'more-help' option ('--more-help'). 'more-help' will +print the usage text by passing it through a pager program. 'more-help' +is disabled on platforms without a working 'fork(2)' function. The +'PAGER' environment variable is used to select the program, defaulting +to 'more'. Both will exit with a status code of 0. + + autogen (GNU AutoGen) - The Automated Program Generator - Ver. 5.18.15.001 + Usage: autogen [ -<flag> [<val>] | --<name>[{=| }<val>] ]... [ <def-file> ] + + The following options select definitions, templates and scheme functions + to use: + + Flg Arg Option-Name Description + -L Str templ-dirs Search for templates in DIR + - may appear multiple times + -T Str override-tpl Use TPL-FILE for the template + - may not be preset + Str definitions Read definitions from FILE + - disabled as '--no-definitions' + - enabled by default + - may not be preset + Str shell name or path name of shell to use + -m no no-fmemopen Do not use in-mem streams + Str equate characters considered equivalent + + The following options modify how output is handled: + + Flg Arg Option-Name Description + -b Str base-name Specify NAME as the base name for output + - may not be preset + no source-time set mod times to latest source + - disabled as '--no-source-time' + no writable Allow output files to be writable + - disabled as '--not-writable' + + The following options are often useful while debugging new templates: + + Flg Arg Option-Name Description + Num loop-limit Limit on increment loops + - is scalable with a suffix: k/K/m/M/g/G/t/T + - it must lie in one of the ranges: + -1 exactly, or + 1 to 16777216 + -t Num timeout Limit server shell operations to SECONDS + - it must be in the range: + 0 to 3600 + KWd trace tracing level of detail + Str trace-out tracing output file or filter + --- show-defs This option has been disabled + no used-defines Show the definitions used + - may not be preset + -C no core Leave a core dump on a failure exit + + These options can be used to control what gets processed in the + definitions files and template files: + + Flg Arg Option-Name Description + -s Str skip-suffix Skip the file with this SUFFIX + - prohibits the option 'select-suffix' + - may not be preset + - may appear multiple times + -o Str select-suffix specify this output suffix + - may not be preset + - may appear multiple times + -D Str define name to add to definition list + - may appear multiple times + -U Str undefine definition list removal pattern + - an alternate for 'define' + + This option is used to automate dependency tracking: + + Flg Arg Option-Name Description + -M opt make-dep emit make dependency file + - may not be preset + - may appear multiple times + + help, version, option and error handling: + + Flg Arg Option-Name Description + no no-abort Do not abort on errors + + Version, usage and configuration options: + + Flg Arg Option-Name Description + -R Str reset-option reset an option's state + -v opt version output version information and exit + -? no help display extended usage information and exit + -! no more-help extended usage information passed thru pager + -u no usage abbreviated usage to stdout + -> opt save-opts save the option state to a config file + -< Str load-opts load options from a config file + - disabled as '--no-load-opts' + - may appear multiple times + + Options are specified by doubled hyphens and their name or by a single + hyphen and the flag character. + AutoGen creates text files from templates using external definitions. + + The following option preset mechanisms are supported: + - reading file $HOME + - reading file ./.autogenrc + - examining environment variables named AUTOGEN_* + + The valid "trace" option keywords are: + nothing debug-message server-shell templates block-macros + expressions everything + or an integer from 0 through 6 + AutoGen is a tool designed for generating program files that contain + repetitive text with varied substitutions. + + Please send bug reports to: <autogen-users@lists.sourceforge.net> + + +File: autogen.info, Node: autogen input-select, Next: autogen out-handling, Prev: autogen usage, Up: autogen Invocation + +5.2 input-select options +======================== + +The following options select definitions, templates and scheme functions +to use. + +templ-dirs option (-L). +----------------------- + +This is the "search for templates in 'dir'" option. This option takes a +string argument 'DIR'. + +This option has some usage constraints. It: + * may appear an unlimited number of times. + + Add a directory to the list of directories 'autogen' searches when +opening a template, either as the primary template or an included one. +The last entry has the highest priority in the search list. That is to +say, they are searched in reverse order. + +override-tpl option (-T). +------------------------- + +This is the "use 'tpl-file' for the template" option. This option takes +a string argument 'TPL-FILE'. + +This option has some usage constraints. It: + * may not be preset with environment variables or configuration + (rc/ini) files. + + Definition files specify the standard template that is to be +expanded. This option will override that name and expand a different +template. + +definitions option. +------------------- + +This is the "read definitions from 'file'" option. This option takes a +string argument 'FILE'. + +This option has some usage constraints. It: + * can be disabled with -no-definitions. + * It is enabled by default. + * may not be preset with environment variables or configuration + (rc/ini) files. + + Use this argument to specify the input definitions file with a +command line option. If you do not specify this option, then there must +be a command line argument that specifies the file, even if only to +specify stdin with a hyphen ('-'). Specify, '--no-definitions' when you +wish to process a template without any active AutoGen definitions. + +shell option. +------------- + +This is the "name or path name of shell to use" option. This option +takes a string argument 'shell'. + +This option has some usage constraints. It: + * must be compiled in by defining 'SHELL_ENABLED' during the + compilation. + + By default, when AutoGen is built, the configuration is probed for a +reasonable Bourne-like shell to use for shell script processing. If a +particular template needs an alternate shell, it must be specified with +this option on the command line, with an environment variable ('SHELL') +or in the configuration/initialization file. + +no-fmemopen option (-m). +------------------------ + +This is the "do not use in-mem streams" option. If the local C library +supports "'fopencookie(3GNU)'", or "'funopen(3BSD)'" then AutoGen +prefers to use in-memory stream buffer opens instead of anonymous files. +This may lead to problems if there is a shortage of virtual memory. If, +for a particular application, you run out of memory, then specify this +option. This is unlikely in a modern 64-bit virtual memory environment. + + On platforms without these functions, the option is accepted but +ignored. 'fmemopen(POSIX)' is not adequate because its string buffer is +not reallocatable. 'open_memstream(POSIX)' is also not adequate because +the stream is only opened for output. AutoGen needs a reallocatable +buffer available for both reading and writing. + +equate option. +-------------- + +This is the "characters considered equivalent" option. This option +takes a string argument 'char-list'. This option will alter the list of +characters considered equivalent. The default are the three characters, +"_-^". (The last is conventional on a Tandem/HP-NonStop, and I used to +do a lot of work on Tandems.) + + +File: autogen.info, Node: autogen out-handling, Next: autogen debug-tpl, Prev: autogen input-select, Up: autogen Invocation + +5.3 out-handling options +======================== + +The following options modify how output is handled. + +base-name option (-b). +---------------------- + +This is the "specify 'name' as the base name for output" option. This +option takes a string argument 'NAME'. + +This option has some usage constraints. It: + * may not be preset with environment variables or configuration + (rc/ini) files. + + A template may specify the exact name of the output file. Normally, +it does not. Instead, the name is composed of the base name of the +definitions file with suffixes appended. This option will override the +base name derived from the definitions file name. This is required if +there is no definitions file and advisable if definitions are being read +from stdin. If the definitions are being read from standard in, the +base name defaults to 'stdin'. Any leading directory components in the +name will be silently removed. If you wish the output file to appear in +a particular directory, it is recommended that you "cd" into that +directory first, or use directory names in the format specification for +the output suffix lists, *Note pseudo macro::. + +source-time option. +------------------- + +This is the "set mod times to latest source" option. + +This option has some usage constraints. It: + * can be disabled with -no-source-time. + + If you stamp your output files with the 'DNE' macro output, then your +output files will always be different, even if the content has not +really changed. If you use this option, then the modification time of +the output files will change only if the input files change. This will +help reduce unneeded builds. + +writable option. +---------------- + +This is the "allow output files to be writable" option. + +This option has some usage constraints. It: + * can be disabled with -not-writable. + + This option will leave output files writable. Normally, output files +are read-only. + + +File: autogen.info, Node: autogen debug-tpl, Next: autogen processing, Prev: autogen out-handling, Up: autogen Invocation + +5.4 debug-tpl options +===================== + +The following options are often useful while debugging new templates. +They specify limits that prevent the template from taking overly long or +producing more output than expected. + +loop-limit option. +------------------ + +This is the "limit on increment loops" option. This option takes a +number argument 'lim'. This option prevents runaway loops. For +example, if you accidentally specify, "FOR x (for-from 1) (for-to -1) +(for-by 1)", it will take a long time to finish. If you do have more +than 256 entries in tables, you will need to specify a new limit with +this option. + +timeout option (-t). +-------------------- + +This is the "limit server shell operations to 'seconds'" option. This +option takes a number argument 'SECONDS'. + +This option has some usage constraints. It: + * must be compiled in by defining 'SHELL_ENABLED' during the + compilation. + + AutoGen works with a shell server process. Most normal commands will +complete in less than 10 seconds. If, however, your commands need more +time than this, use this option. + + The valid range is 0 to 3600 seconds (1 hour). Zero will disable the +server time limit. + +trace option. +------------- + +This is the "tracing level of detail" option. This option takes a +keyword argument 'level'. + +This option has some usage constraints. It: + * This option takes a keyword as its argument. The argument sets an + enumeration value that can be tested by comparing the option value + macro (OPT_VALUE_TRACE). The available keywords are: + nothing debug-message server-shell + templates block-macros expressions + everything + + or their numeric equivalent. + + This option will cause AutoGen to display a trace of its template +processing. There are six levels, each level including messages from +the previous levels: + +'nothing' + Does no tracing at all (default) + +'debug-message' + Print messages from the "DEBUG" AutoGen macro (*note DEBUG::). + +'server-shell' + Traces all input and output to the server shell. This includes a + shell "independent" initialization script about 30 lines long. Its + output is discarded and not inserted into any template. + +'templates' + Traces the invocation of 'DEFINE'd macros and 'INCLUDE's + +'block-macros' + Traces all block macros. The above, plus 'IF', 'FOR', 'CASE' and + 'WHILE'. + +'expressions' + Displays the results of expression evaluations. + +'everything' + Displays the invocation of every AutoGen macro, even 'TEXT' macros + (i.e. the text outside of macro quotes). Additionally, if you + rebuild the "expr.ini" file with debugging enabled, then all calls + to AutoGen defined scheme functions will also get logged: + cd ${top_builddir}/agen5 + DEBUG_ENABLED=true bash bootstrap.dir expr.ini + make CFLAGS='-g -DDEBUG_ENABLED=1' + + Be aware that you cannot rebuild this source in this way without + first having installed the 'autogen' executable in your search + path. Because of this, "expr.ini" is in the distributed source + list, and not in the dependencies. + +trace-out option. +----------------- + +This is the "tracing output file or filter" option. This option takes a +string argument 'file'. The output specified may be a file name, a file +that is appended to, or, if the option argument begins with the 'pipe' +operator ('|'), a command that will receive the tracing output as +standard in. For example, '--traceout='| less'' will run the trace +output through the 'less' program. Appending to a file is specified by +preceding the file name with two greater-than characters ('>>'). + +show-defs option. +----------------- + +This is the "show the definition tree" option. + +This option has some usage constraints. It: + * must be compiled in by defining 'DEBUG_ENABLED' during the + compilation. + * may not be preset with environment variables or configuration + (rc/ini) files. + + This will print out the complete definition tree before processing +the template. + +used-defines option. +-------------------- + +This is the "show the definitions used" option. + +This option has some usage constraints. It: + * may not be preset with environment variables or configuration + (rc/ini) files. + + This will print out the names of definition values searched for +during the processing of the template, whether actually found or not. +There may be other referenced definitions in a template in portions of +the template not evaluated. Some of the names listed may be computed +names and others AutoGen macro arguments. This is not a means for +producing a definitive, all-encompassing list of all and only the values +used from a definition file. This is intended as an aid to template +documentation only. + +core option (-C). +----------------- + +This is the "leave a core dump on a failure exit" option. + +This option has some usage constraints. It: + * must be compiled in by defining 'HAVE_SYS_RESOURCE_H' during the + compilation. + + Many systems default to a zero sized core limit. If the system has +the sys/resource.h header and if this option is supplied, then in the +failure exit path, autogen will attempt to set the soft core limit to +whatever the hard core limit is. If that does not work, then an +administrator must raise the hard core size limit. + + +File: autogen.info, Node: autogen processing, Next: autogen dep-track, Prev: autogen debug-tpl, Up: autogen Invocation + +5.5 processing options +====================== + +These options can be used to control what gets processed in the +definitions files and template files. They specify which outputs and +parts of outputs to produce. + +skip-suffix option (-s). +------------------------ + +This is the "skip the file with this 'suffix'" option. This option +takes a string argument 'SUFFIX'. + +This option has some usage constraints. It: + * may appear an unlimited number of times. + * may not be preset with environment variables or configuration + (rc/ini) files. + * must not appear in combination with any of the following options: + select-suffix. + + Occasionally, it may not be desirable to produce all of the output +files specified in the template. (For example, only the '.h' header +file, but not the '.c' program text.) To do this specify +'--skip-suffix=c' on the command line. + +select-suffix option (-o). +-------------------------- + +This is the "specify this output suffix" option. This option takes a +string argument 'SUFFIX'. + +This option has some usage constraints. It: + * may appear an unlimited number of times. + * may not be preset with environment variables or configuration + (rc/ini) files. + + If you wish to override the suffix specifications in the template, +you can use one or more copies of this option. See the suffix +specification in the *note pseudo macro:: section of the info doc. + +define option (-D). +------------------- + +This is the "name to add to definition list" option. This option takes +a string argument 'value'. + +This option has some usage constraints. It: + * may appear an unlimited number of times. + + The AutoGen define names are used for the following purposes: + + 1. Sections of the AutoGen definitions may be enabled or disabled by + using C-style #ifdef and #ifndef directives. + 2. When defining a value for a name, you may specify the index for a + particular value. That index may be a literal value, a define + option or a value #define-d in the definitions themselves. + 3. The name of a file may be prefixed with '$NAME/'. The '$NAME' part + of the name string will be replaced with the define-d value for + 'NAME'. + 4. When AutoGen is finished loading the definitions, the defined + values are exported to the environment with, 'putenv(3)'. These + values can then be used in shell scripts with '${NAME}' references + and in templates with '(getenv "NAME")'. + 5. While processing a template, you may specify an index to retrieve a + specific value. That index may also be a define-d value. + + It is entirely equivalent to place this name in the exported +environment. Internally, that is what AutoGen actually does with this +option. + +undefine option (-U). +--------------------- + +This is the "definition list removal pattern" option. This option takes +a string argument 'name-pat'. + +This option has some usage constraints. It: + * may appear an unlimited number of times. + * may not be preset with environment variables or configuration + (rc/ini) files. + + Similar to 'C', AutoGen uses '#ifdef/#ifndef' preprocessing +directives. This option will cause the matching names to be removed +from the list of defined values. + + +File: autogen.info, Node: autogen dep-track, Next: autogen autoopts-opts, Prev: autogen processing, Up: autogen Invocation + +5.6 dep-track options +===================== + +This option is used to automate dependency tracking. + +make-dep option (-M). +--------------------- + +This is the "emit make dependency file" option. This option takes an +optional string argument 'type'. + +This option has some usage constraints. It: + * may appear an unlimited number of times. + * may not be preset with environment variables or configuration + (rc/ini) files. + + This option behaves fairly closely to the way the '-M' series of +options work with the gcc compiler, except that instead of just emitting +the predecessor dependencies, this also emits the successor dependencies +(output target files). By default, the output dependency information +will be placed in '<base-name>.d', but may also be specified with +'-MF<file>'. The time stamp on this file will be manipulated so that it +will be one second older than the oldest primary output file. + + The target in this dependency file will normally be the dependency +file name, but may also be overridden with '-MT<targ-name>'. AutoGen +will not alter the contents of that file, but it may create it and it +will adjust the modification time to match the start time. + + *NB:* these second letters are part of the option argument, so '-MF +<file>' must have the space character quoted or omitted, and '-M "F +<file>"' is acceptable because the 'F' is part of the option argument. + + '-M' may be followed by any of the letters M, F, P, T, Q, D, or G. +However, only F, Q, T and P are meaningful. All but F have somewhat +different meanings. '-MT<name>' is interpreted as meaning '<name>' is a +sentinel file that will depend on all inputs (templates and definition +files) and all the output files will depend on this sentinel file. It +is suitable for use as a real make target. Q is treated identically to +T, except dollar characters ('$') are doubled. P causes a special clean +(clobber) phoney rule to be inserted into the make file fragment. An +empty rule is always created for building the list of targets. + + This is the recommended usage: + -MFwhatever-you-like.dep -MTyour-sentinel-file -MP + and then in your 'Makefile', make the 'autogen' rule: + -include whatever-you-like.dep + clean_targets += clean-your-sentinel-file + + your-sentinel-file: + autogen -MT$@ -MF$*.d ..... + + local-clean : + rm -f $(clean_targets) + + The modification time on the dependency file is adjusted to be one +second before the earliest time stamp of any other output file. +Consequently, it is suitable for use as the sentinel file testifying to +the fact the program was successfully run. ('-include' is the GNU make +way of specifying "include it if it exists". Your make must support +that feature or your bootstrap process must create the file.) + + All of this may also be specified using the 'DEPENDENCIES_OUTPUT' or +'AUTOGEN_MAKE_DEP' environment variables. If defined, dependency +information will be output. If defined with white space free text that +is something other than 'true', 'false', 'yes', 'no', '0' or '1', then +the string is taken to be an output file name. If it contains a string +of white space characters, the first token is as above and the second +token is taken to be the target (sentinel) file as '-MT' in the +paragraphs above. 'DEPENDENCIES_OUTPUT' will be ignored if there are +multiple sequences of white space characters or if its contents are, +specifically, 'false', 'no' or '0'. + + +File: autogen.info, Node: autogen autoopts-opts, Next: autogen config, Prev: autogen dep-track, Up: autogen Invocation + +5.7 autoopts-opts options +========================= + +help, version, option and error handling. + +no-abort option. +---------------- + +This is the "do not abort on errors" option. By default, 'AutoGen' will +abort on an error leaving behind a core image. That is sometimes +inconvenient. If present on the command line or in the environment, +AutoGen will call 'exit(1)' instead of 'abort()'. + + +File: autogen.info, Node: autogen config, Next: autogen exit status, Prev: autogen autoopts-opts, Up: autogen Invocation + +5.8 presetting/configuring autogen +================================== + +Any option that is not marked as not presettable may be preset by +loading values from configuration ("rc" or "ini") files, and values from +environment variables named 'AUTOGEN' and 'AUTOGEN_<OPTION_NAME>'. +'<OPTION_NAME>' must be one of the options listed above in upper case +and segmented with underscores. The 'AUTOGEN' variable will be +tokenized and parsed like the command line. The remaining variables are +tested for existence and their values are treated like option arguments. + +'libopts' will search in 2 places for configuration files: + * $HOME + * $PWD + The environment variables 'HOME', and 'PWD' are expanded and replaced +when 'autogen' runs. For any of these that are plain files, they are +simply processed. For any that are directories, then a file named +'.autogenrc' is searched for within that directory and processed. + + Configuration files may be in a wide variety of formats. The basic +format is an option name followed by a value (argument) on the same +line. Values may be separated from the option name with a colon, equal +sign or simply white space. Values may be continued across multiple +lines by escaping the newline with a backslash. + + Multiple programs may also share the same initialization file. +Common options are collected at the top, followed by program specific +segments. The segments are separated by lines like: + [AUTOGEN] +or by + <?program autogen> +Do not mix these styles within one configuration file. + + Compound values and carefully constructed string values may also be +specified using XML syntax: + <option-name> + <sub-opt>...<...>...</sub-opt> + </option-name> +yielding an 'option-name.sub-opt' string value of + "...<...>..." + 'AutoOpts' does not track suboptions. You simply note that it is a +hierarchicly valued option. 'AutoOpts' does provide a means for +searching the associated name/value pair list (see: optionFindValue). + + The command line options relating to configuration and/or usage help +are: + +version (-v) +------------ + +Print the program version to standard out, optionally with licensing +information, then exit 0. The optional argument specifies how much +licensing detail to provide. The default is to print just the version. +The licensing information may be selected with an option argument. Only +the first letter of the argument is examined: + +'version' + Only print the version. This is the default. +'copyright' + Name the copyright usage licensing terms. +'verbose' + Print the full copyright usage licensing terms. + +usage (-u) +---------- + +Print abbreviated usage to standard out, then exit 0. + +reset-option (-R) +----------------- + +Resets the specified option to the compiled-in initial state. This will +undo anything that may have been set by configuration files. The option +argument may be either the option flag character or its long name. + + +File: autogen.info, Node: autogen exit status, Next: autogen Examples, Prev: autogen config, Up: autogen Invocation + +5.9 autogen exit status +======================= + +One of the following exit values will be returned: +'0 (EXIT_SUCCESS)' + Successful program execution. +'1 (EXIT_OPTION_ERROR)' + The command options were misconfigured. +'2 (EXIT_BAD_TEMPLATE)' + An error was encountered processing the template. +'3 (EXIT_BAD_DEFINITIONS)' + The definitions could not be deciphered. +'4 (EXIT_LOAD_ERROR)' + An error was encountered during the load phase. +'5 (EXIT_FS_ERROR)' + a file system error stopped the program. +'6 (EXIT_NO_MEM)' + Insufficient memory to operate. +'128 (EXIT_SIGNAL)' + 'autogen' exited due to catching a signal. If your template + includes string formatting, a number argument to a "%s" formatting + element will trigger a segmentation fault. Autogen will catch the + seg fault signal and exit with 'AUTOGEN_EXIT_SIGNAL(5)'. + Alternatively, AutoGen may have been interrupted with a 'kill(2)' + signal. + + Subtract 128 from the actual exit code to detect the signal number. +'66 (EX_NOINPUT)' + A specified configuration file could not be loaded. +'70 (EX_SOFTWARE)' + libopts had an internal operational error. Please report it to + autogen-users@lists.sourceforge.net. Thank you. + + +File: autogen.info, Node: autogen Examples, Prev: autogen exit status, Up: autogen Invocation + +5.10 autogen Examples +===================== + +Here is how the man page is produced: + autogen -Tagman-cmd.tpl -MFman-dep -MTstamp-man opts.def + + This command produced this man page from the AutoGen option +definition file. It overrides the template specified in 'opts.def' +(normally 'options.tpl') and uses 'agman-cmd.tpl'. It also sets the +make file dependency output to 'man-dep' and the sentinel file (time +stamp file) to 'man-stamp'. The base of the file name is derived from +the defined 'prog-name'. + + The texi invocation document is produced via: + autogen -Tagtexi-cmd.tpl -MFtexi-dep -MTtexi-stamp opts.def + + +File: autogen.info, Node: Installation, Next: AutoOpts, Prev: autogen Invocation, Up: Top + +6 Configuring and Installing +**************************** + +* Menu: + +* configuring:: Configuring AutoGen +* AutoGen CGI:: AutoGen as a CGI server +* signal names:: Signal Names +* installing:: Installing AutoGen + + +File: autogen.info, Node: configuring, Next: AutoGen CGI, Up: Installation + +6.1 Configuring AutoGen +======================= + +AutoGen is configured and built using Libtool, Automake and Autoconf. +Consequently, you can install it wherever you wish using the '--prefix' +and other options. To the various configuration options supplied by +these tools, AutoGen adds a few of its own: + +'--disable-shell' + AutoGen is now capable of acting as a CGI forms server, *Note + AutoGen CGI::. As such, it will gather its definitions using + either 'GET' or 'POST' methods. All you need to do is have a + template named 'cgi.tpl' handy or specify a different one with a + command line option. + + However, doing this without disabling the server shell brings + considerable risk. If you were to pass user input to a script that + contained, say, the classic "'`rm -rf /`'", you might have a + problem. This configuration option will cause shell template + commands to simply return the command string as the result. No + mistakes. Much safer. Strongly recommended. The default is to + have server shell scripting enabled. + + Disabling the shell will have some build side effects, too. + + * Many of the make check tests will fail, since they assume a + working server shell. + * The getdefs and columns programs are not built. The options + are distributed as definition files and they cannot be + expanded with a shell-disabled AutoGen. + * Similarly, the documentation cannot be regenerated because the + documentation templates depend on subshell functionality. + +'--enable-debug' + Turning on AutoGen debugging enables very detailed inspection of + the input definitions and monitoring shell script processing. + These options are not particularly useful to anyone not directly + involved in maintaining AutoGen. If you do choose to enable + AutoGen debugging, be aware that the usage page was generated + without these options, so when the build process reaches the + documentation rebuild, there will be a failure. 'cd' into the + 'agen5' build directory, 'make' the 'autogen.texi' file and all + will be well thereafter. + +'--with-regex-header' +'--with-header-path' +'--with-regex-lib' + These three work together to specify how to compile with and link + to a particular POSIX regular expression library. The value for + '--with-regex-header=value' must be the name of the relevant header + file. The AutoGen sources will attempt to include that source with + a '#include <value>' C preprocessing statement. The PATH from the + '--with-header-path=path' will be added to 'CPPFLAGS' as '-Ipath'. + The LIB-SPECS from '--with-regex-lib=lib-specs' will be added to + 'LDFLAGS' without any adornment. + + +File: autogen.info, Node: AutoGen CGI, Next: signal names, Prev: configuring, Up: Installation + +6.2 AutoGen as a CGI server +=========================== + +AutoGen is now capable of acting as a CGI forms server. It behaves as a +CGI server if the definitions input is from stdin and the environment +variable 'REQUEST_METHOD' is defined and set to either "GET" or "POST". +If set to anything else, AutoGen will exit with a failure message. When +set to one of those values, the CGI data will be converted to AutoGen +definitions (*note Definitions File::) and the template named +"'cgi.tpl'" will be processed. + + This works by including the name of the real template to process in +the form data and having the "'cgi.tpl'" template include that template +for processing. I do this for processing the form +<http://autogen.sourceforge.net/conftest.html>. The "'cgi.tpl'" looks +approximately like this: + + <? AutoGen5 Template ?> + <? + IF (not (exist? "template")) ?><? + form-error ?><? + + ELIF (=* (get "template") "/") ?><? + form-error ?><? + + ELIF (define tpl-file (string-append "cgi-tpl/" + (get "template"))) + (access? tpl-file R_OK) ?><? + INCLUDE (. tpl-file) ?><? + + ELIF (set! tpl-file (string-append tpl-file ".tpl")) + (access? tpl-file R_OK) ?><? + INCLUDE (. tpl-file) ?><? + + ELSE ?><? + form-error ?><? + ENDIF ?> + +This forces the template to be found in the "'cgi-tpl/'" directory. +Note also that there is no suffix specified in the pseudo macro (*note +pseudo macro::). That tells AutoGen to emit the output to 'stdout'. + + The output is actually spooled until it is complete so that, in the +case of an error, the output can be discarded and a proper error message +can be written in its stead. + + *Please also note* that it is advisable, _especially_ for network +accessible machines, to configure AutoGen (*note configuring::) with +shell processing disabled ('--disable-shell'). That will make it +impossible for any referenced template to hand data to a subshell for +interpretation. + + +File: autogen.info, Node: signal names, Next: installing, Prev: AutoGen CGI, Up: Installation + +6.3 Signal Names +================ + +When AutoGen is first built, it tries to use 'psignal(3)', +'sys_siglist', 'strsigno(3)' and 'strsignal(3)' from the host operating +system. If your system does not supply these, the AutoGen distribution +will. However, it will use the distributed mapping and this mapping is +unlikely to match what your system uses. This can be fixed. Once you +have installed autogen, the mapping can be rebuilt on the host operating +system. To do so, you must perform the following steps: + + 1. Build and install AutoGen in a place where it will be found in your + search path. + 2. 'cd ${top_srcdir}/compat' + 3. 'autogen strsignal.def' + 4. Verify the results by examining the 'strsignal.h' file produced. + 5. Re-build and re-install AutoGen. + + If you have any problems or peculiarities that cause this process to +fail on your platform, please send me copies of the header files +containing the signal names and numbers, along with the full path names +of these files. I will endeavor to fix it. There is a shell script +inside of 'strsignal.def' that tries to hunt down the information. + + +File: autogen.info, Node: installing, Prev: signal names, Up: Installation + +6.4 Installing AutoGen +====================== + +There are several files that get installed. The number depend whether +or not both shared and archive libraries are to be installed. The +following assumes that everything is installed relative to '$prefix'. +You can, of course, use 'configure' to place these files where you wish. + + *NB* AutoGen does not contain any compiled-in path names. All +support directories are located via option processing, the environment +variable 'HOME' or finding the directory where the executable came from. + + The installed files are: + + 1. The executables in 'bin' (autogen, getdefs and columns). + + 2. The AutoOpts link libraries as 'lib/libopts.*'. + + 3. An include file in 'include/options.h', needed for Automated Option + Processing (see next chapter). + + 4. Several template files and a scheme script in 'share/autogen', + needed for Automated Option Processing (*note AutoOpts::), parsing + definitions written with scheme syntax (*note Dynamic Text::), the + templates for producing documentation for your program (*note + documentation attributes::), autoconf test macros, and AutoFSM. + + 5. Info-style help files as 'info/autogen.info*'. These files + document AutoGen, the option processing library AutoOpts, and + several add-on components. + + 6. The three man pages for the three executables are installed in + man/man1. + + This program, library and supporting files can be installed with +three commands: + + * <src-dir>/configure [ <configure-options> ] + * make + * make install + + However, you may wish to insert 'make check' before the 'make +install' command. + + If you do perform a 'make check' and there are any failures, you will +find the results in '<module>/test/FAILURES'. Needless to say, I would +be interested in seeing the contents of those files and any associated +messages. If you choose to go on and analyze one of these failures, you +will need to invoke the test scripts individually. You may do so by +specifying the test (or list of test) in the TESTS make variable, thus: + + gmake TESTS=test-name.test check + + I specify 'gmake' because most makes will not let you override +internal definitions with command line arguments. 'gmake' does. + + All of the AutoGen tests are written to honor the contents of the +VERBOSE environment variable. Normally, any commentary generated during +a test run is discarded unless the VERBOSE environment variable is set. +So, to see what is happening during the test, you might invoke the +following with bash or ksh: + + VERBOSE=1 gmake TESTS="for.test forcomma.test" check + +Or equivalently with csh: + + env VERBOSE=1 gmake TESTS="for.test forcomma.test" check + + +File: autogen.info, Node: AutoOpts, Next: Add-Ons, Prev: Installation, Up: Top + +7 Automated Option Processing +***************************** + +AutoOpts 42.1 is bundled with AutoGen. It is a tool that virtually +eliminates the hassle of processing options and keeping man pages, info +docs and usage text up to date. This package allows you to specify +several program attributes, thousands of option types and many option +attributes. From this, it then produces all the code necessary to parse +and handle the command line and configuration file options, and the +documentation that should go with your program as well. + + All the features notwithstanding, some applications simply have +well-established command line interfaces. Even still, those programs +may use the configuration file parsing portion of the library. See the +"AutoOpts Features" and "Configuration File Format" sections. + +* Menu: + +* Features:: AutoOpts Features +* Licensing:: AutoOpts Licensing +* Caveats:: Developer and User Notes +* Quick Start:: Quick Start +* Option Definitions:: Option Definitions +* AutoOpts API:: Programmatic Interface +* Multi-Threading:: Multi-Threading +* option descriptor:: Option Descriptor File +* Using AutoOpts:: Using AutoOpts +* Presetting Options:: Configuring your program +* Config File Format:: Configuration File Format +* shell options:: AutoOpts for Shell Scripts +* AutoInfo:: Automated Info Docs +* AutoMan pages:: Automated Man Pages +* getopt_long:: Using getopt(3C) +* i18n:: Internationalizing AutoOpts +* Naming Conflicts:: Naming Conflicts +* All Attribute Names:: All Attribute Names +* Option Define Names:: Option Definition Name Index + + +File: autogen.info, Node: Features, Next: Licensing, Up: AutoOpts + +7.1 AutoOpts Features +===================== + +AutoOpts supports option processing; option state saving; and program +documentation with innumerable features. Here, we list a few obvious +ones and some important ones, but the full list is really defined by all +the attributes defined in the *note Option Definitions:: section. + + 1. POSIX-compliant short (flag) option processing. + + 2. GNU-style long options processing. Long options are recognized + without case sensitivity, and they may be abbreviated. + + 3. Environment variable initializations, *Note environrc::. + + 4. Initialization from configuration files (aka RC or INI files), and + saving the option state back into one, *Note loading rcfile::. + + 5. Config files may be partitioned. One config file may be used by + several programs by partitioning it with lines containing, + '[PROGRAM_NAME]' or '<?program-name>', *Note loading rcfile::. + + 6. Config files may contain AutoOpts directives. '<?auto-options + [[option-text]]>' may be used to set 'AutoOpts' option processing + options. Viz., GNU usage layout versus 'AutoOpts' conventional + layout, and 'misuse-usage' versus 'no-misuse-usage', *Note usage + attributes::. + + 7. Options may be marked as 'dis-abled' with a disablement prefix. + Such options may default to either an enabled or a disabled state. + You may also provide an enablement prefix, too, e.g., + '--allow-mumble' and '--prevent-mumble' (*note Common + Attributes::). + + 8. Verify that required options are present between the minimum and + maximum number of times on the command line. Verify that + conflicting options do not appear together. Verify that options + requiring the presence of other options are, in fact, used in the + presence of other options. See *Note Common Attributes::, and + *Note Option Conflict Attributes::. + + 9. There are several *note automatically supported options: automatic + options. They will have short flags if any options have option + flags and the flags are not suppressed. The associated flag may be + altered or suppressed by specifying no value or an alternate + character for 'xxx-value;' in the option definition file. 'xxx' is + the name of the option below: + + '--help' + '--more-help' + These are always available. '--more-help' will pass the full + usage text through a pager. + '--usage' + This is added to the option list if 'usage-opt' is specified. + It yields the abbreviated usage to 'stdout'. + '--version' + This is added to the option list if 'version = xxx;' is + specified. + '--load-opts' + '--save-opts' + These are added to the option list if 'homerc' is specified. + Mostly. If, 'disable-save' is specified, then '--save-opts' + is disabled. + + 10. Various forms of main procedures can be added to the output, *Note + Generated main::. There are four basic forms: + + a. A program that processes the arguments and writes to standard + out portable shell commands containing the digested options. + + b. A program that will generate portable shell commands to parse + the defined options. The expectation is that this result will + be copied into a shell script and used there. + + c. A 'for-each' main that will invoke a named function once for + either each non-option argument on the command line or, if + there are none, then once for each non-blank, non-comment + input line read from stdin. + + d. A main procedure of your own design. Its code can be supplied + in the option description template or by incorporating another + template. + + 11. There are several methods for handling option arguments. + * nothing (*note OPT_ARG::) option argument strings are globally + available. + * user supplied (*note Option Argument Handling::) + * stack option arguments (*note Option Argument Handling::) + * integer numbers (*note arg-type number::) + * true or false valued (*note arg-type boolean::) + * enumerated list of names (*note arg-type keyword::) + * an enumeration (membership) set (*note arg-type set + membership::) + * a list of name/value pairs (option 'subopts') (*note arg-type + hierarchy::) + * a time duration or a specific time and date + * validated file name (*note arg-type file name::) + * optional option argument (*note arg-optional::) + + 12. The generated usage text can be emitted in either AutoOpts + standard format (maximizing the information about each option), or + GNU-ish normal form. The default form is selected by either + specifying or not specifying the 'gnu-usage' attribute (*note + information attributes::). This can be overridden by the user + himself with the 'AUTOOPTS_USAGE' environment variable. If it + exists and is set to the string 'gnu', it will force GNU-ish style + format; if it is set to the string 'autoopts', it will force + AutoOpts standard format; otherwise, it will have no effect. + + 13. The usage text and many other strings are stored in a single + character array (*note string table functions: SCM + string-table-new.). This reduces fixup costs when loading the + program or library. The downside is that if GCC detects that any + of these strings are used in a printf format, you may get the + warning, 'embedded '\0' in format'. To eliminate the warning, you + must provide GCC with the '-Wno-format-contains-nul' option. + + 14. If you compile with 'ENABLE_NLS' defined and '_()' defined to a + localization function (e.g. 'gettext(3GNU)'), then the option + processing code will be localizable (*note i18n::). Provided also + that you do not define the 'no-xlate' attribute to _anything_ + (*note presentation attributes::). + + You should also ensure that the 'ATTRIBUTE_FORMAT_ARG()' gets + '#define'-ed to something useful. There is an autoconf macro named + 'AG_COMPILE_FORMAT_ARG' in 'ag_macros.m4' that will set it + appropriately for you. If you do not do this, then translated + formatting strings may trigger GCC compiler warnings. + + 15. Provides a callable routine to parse a text string as if it were + from one of the rc/ini/config files, hereafter referred to as a + configuration file. + + 16. By adding a 'doc' and 'arg-name' attributes to each option, + AutoGen will also be able to produce a man page and the 'invoking' + section of a texinfo document. + + 17. Intermingled option processing. AutoOpts options may be + intermingled with command line operands and options processed with + other parsing techniques. This is accomplished by setting the + 'allow-errors' (*note program attributes::) attribute. When + processing reaches a point where 'optionProcess' (*note + libopts-optionProcess::) needs to be called again, the current + option can be set with 'RESTART_OPT(n)' (*note RESTART_OPT::) + before calling 'optionProcess'. + + See: *Note library attributes::. + + 18. Library suppliers can specify command line options that their + client programs will accept. They specify option definitions that + get '#include'-d into the client option definitions and they + specify an "anchor" option that has a callback and must be invoked. + That will give the library access to the option state for their + options. + + 19. library options. An AutoOpt-ed library may export its options for + use in an AutoOpt-ed program. This is done by providing an option + definition file that client programs '#include' into their own + option definitions. See "AutoOpt-ed Library for AutoOpt-ed + Program" (*note lib and program::) for more details. + + +File: autogen.info, Node: Licensing, Next: Caveats, Prev: Features, Up: AutoOpts + +7.2 AutoOpts Licensing +====================== + +When AutoGen is installed, the AutoOpts project is installed with it. +AutoOpts includes various AutoGen templates and a pair of shared +libraries. These libraries may be used under the terms of version 3 of +the GNU Lesser General Public License (LGPL). + + One of these libraries ('libopts') is needed by programs that are +built using AutoOpts generated code. This library is available as a +separate "tear-off" source tarball. It is redistributable for use under +either of two licenses: The above mentioned GNU Lesser General Public +License, and the advertising-clause-free BSD license. Both of these +license terms are incorporated into appropriate COPYING files included +with the 'libopts' source tarball. This source may be incorporated into +your package with the following simple commands: + + rm -rf libopts libopts-* + gunzip -c `autoopts-config libsrc` | \ + tar -xvf - + mv libopts-*.*.* libopts + + View the 'libopts/README' file for further integration information. + + +File: autogen.info, Node: Caveats, Next: Quick Start, Prev: Licensing, Up: AutoOpts + +7.3 Developer and User Notes +============================ + +The formatting of the usage message can be controlled with the use of +the 'AUTOOPTS_USAGE' environment variable. If it contains any of five +possible comma separated values, it will affect 'libopts' behavior. Any +extraneous or conflicting data will cause its value to be ignored. + + If the program attributes 'long-usage' and 'short-usage' have been +specified (*note Usage and Version Info Display: usage attributes.), +these strings are used for displaying full usage and abbreviated usage. +"Full usage" is used when usage is requested, "abbreviated usage" when a +usage error is detected. If these strings are not provided, the usage +text is computed. + + The 'AUTOOPTS_USAGE' environment variable may be set to the comma +and/or white space separated list of the following strings: + +'compute' + Ignore the provision of 'long-usage' and 'short-usage' attributes, + and compute the usage strings. This is useful, for example, if you + wish to regenerate the basic form of these strings and either tweak + them or translate them. The methods used to compute the usage text + are not suitable for translation. + +'gnu' + The format of the usage text will be displayed in GNU-normal form. + The default display for '--version' will be to include a note on + licensing terms. + +'autoopts' + The format of the extended usage will be in AutoOpts' native + layout. The default version display will be one line of text with + the last token the version. 'gnu' and 'autoopts' conflict and may + not be used together. + +'no-misuse-usage' + When an option error is made on the command line, the abbreviated + usage text will be suppressed. An error message and the method for + getting full usage information will be displayed. + +'misuse-usage' + When an option error is made on the command line, the abbreviated + usage text will be shown. 'misuse-usage' and 'no-misuse-usage' + conflict and may not be used together. + + 'misuse-usage' and 'autoopts' are the defaults. These defaults may +be flipped to 'no-misuse-usage' and 'gnu' by specifying 'gnu-usage' and +'no-misuse-usage' program attributes, respectively, in the option +definition file. + +Note for developers: + + The templates used to implement AutoOpts depend heavily upon token +pasting. That mens that if you name an option, 'debug', for example, +the generated header will expect to be able to emit '#define' macros +such as this: + #define DESC(n) (autogenOptions.pOptDesc[INDEX_OPT_## n]) + and expect 'DESC(DEBUG)' to expand correctly into +'(autogenOptions.pOptDesc[INDEX_OPT_DEBUG])'. If 'DEBUG' is '#defined' +to something else, then that something else will be in the above +expansion. + + If you discover you are having strange problems like this, you may +wish to use some variation of the 'guard-option-names' *Note program +attributes::. + + +File: autogen.info, Node: Quick Start, Next: Option Definitions, Prev: Caveats, Up: AutoOpts + +7.4 Quick Start +=============== + +Since it is generally easier to start with a simple example than it is +to look at the options that AutoGen uses itself, here is a very simple +AutoOpts example. You can copy this example out of the Info file and +into a source file to try it. You can then embellish it into what you +really need. For more extensive examples, you can also examine the help +output and option definitions for the commands 'columns', 'getdefs' and +'autogen' itself. + + If you are looking for a more extensive example, you may search the +autogen sources for files named '*opts.def'. 'xml2ag' is ridiculous and +'autogen' is very lengthy, but 'columns' and 'getdefs' are not too +difficult. The 'sharutils' sources are fairly reasonable, too. + +* Menu: + +* quick ao problem:: Example option requirements +* quick ao def:: Example option definitions +* quick ao build:: Build the example options +* quick ao help:: Example option help text +* quick ao usage:: Using the example options +* quick ao docs:: Example option documentation + + +File: autogen.info, Node: quick ao problem, Next: quick ao def, Up: Quick Start + +7.4.1 Example option requirements +--------------------------------- + +For our simple example, assume you have a program named 'check' that +takes two options: + + 1. A list of directories to check over for whatever it is 'check' + does. You want this option available as a POSIX-style flag option + and a GNU long option. You want to allow as many of these as the + user wishes. + 2. An option to show or not show the definition tree being used. Only + one occurrence is to be allowed, specifying one or the other. + + +File: autogen.info, Node: quick ao def, Next: quick ao build, Prev: quick ao problem, Up: Quick Start + +7.4.2 Example option definitions +-------------------------------- + +First, specify your program attributes and its options to AutoOpts, as +with the following example. + + AutoGen Definitions options; + prog-name = check; + prog-title = "Checkout Automated Options"; + long-opts; + gnu-usage; /* GNU style preferred to default */ + + main = { main-type = shell-process; }; + + flag = { + name = check-dirs; + value = L; /* flag style option character */ + arg-type = string; /* option argument indication */ + max = NOLIMIT; /* occurrence limit (none) */ + stack-arg; /* save opt args in a stack */ + descrip = "Checkout directory list"; + doc = 'name of each directory that is to be "checked out".'; + }; + + flag = { + name = show_defs; + descrip = "Show the definition tree"; + disable = dont; /* mark as enable/disable type */ + /* option. Disable as `dont-' */ + doc = 'disable, if you do not want to see the tree.'; + }; + + +File: autogen.info, Node: quick ao build, Next: quick ao help, Prev: quick ao def, Up: Quick Start + +7.4.3 Build the example options +------------------------------- + +This program will produce a program that digests its options and writes +the values as shell script code to stdout. Run the following short +script to produce this program: + base=check + BASE=`echo $base | tr '[a-z-]' '[A-Z_]'` + cflags="-DTEST_${BASE} `autoopts-config cflags`" + ldflags="`autoopts-config ldflags`" + autogen ${base}.def + cc -o ${base} -g ${cflags} ${base}.c ${ldflags} + ./${base} --help + + +File: autogen.info, Node: quick ao help, Next: quick ao usage, Prev: quick ao build, Up: Quick Start + +7.4.4 Example option help text +------------------------------ + +Running the build commands yields: + + + exit 0 + + +File: autogen.info, Node: quick ao usage, Next: quick ao docs, Prev: quick ao help, Up: Quick Start + +7.4.5 Using the example options +------------------------------- + +Normally, however, you would not use the 'main' clause. Instead, the +file would be named something like 'checkopt.def', you would compile +'checkopt.c' the usual way, and link the object with the rest of your +program. + + The options are processed by calling 'optionProcess' (*note +libopts-optionProcess::): + + main( int argc, char** argv ) + { + { + int optct = optionProcess( &checkOptions, argc, argv ); + argc -= optct; + argv += optct; + } + + The options are tested and used as in the following fragment. +'ENABLED_OPT' is used instead of 'HAVE_OPT' for the '--show-defs' option +because it is an enabled/disabled option type: + + if ( ENABLED_OPT( SHOW_DEFS ) + && HAVE_OPT( CHECK_DIRS )) { + int dirct = STACKCT_OPT( CHECK_DIRS ); + char** dirs = STACKLST_OPT( CHECK_DIRS ); + while (dirct-- > 0) { + char* dir = *dirs++; + ... + + +File: autogen.info, Node: quick ao docs, Prev: quick ao usage, Up: Quick Start + +7.4.6 Example option documentation +---------------------------------- + +The 'doc' clauses are used in the flag stanzas for man pages and texinfo +invoking documentation. With the definition file described above, the +two following commands will produce the two documentation files +'check.1' and 'invoke-check.texi'. The latter file will be generated as +a chapter, rather than a section or subsection. + + autogen -Tagman-cmd check.def + autogen -DLEVEL=chapter -Tagtexi-cmd -binvoke-check.texi check.def + +The result of which is left as an exercise for the reader. + + A lot of magic happens to make this happen. The rest of this chapter +will describe the myriad of option attributes supported by AutoOpts. +However, keep in mind that, in general, you won't need much more than +what was described in this "quick start" section. + + +File: autogen.info, Node: Option Definitions, Next: AutoOpts API, Prev: Quick Start, Up: AutoOpts + +7.5 Option Definitions +====================== + +AutoOpts uses an AutoGen definitions file for the definitions of the +program options and overall configuration attributes. The complete list +of program and option attributes is quite extensive, so if you are +reading to understand how to use AutoOpts, I recommend reading the +"Quick Start" section (*note Quick Start::) and paying attention to the +following: + + 1. 'prog-name', 'prog-title', and 'argument', program attributes, + *Note program attributes::. + 2. 'name' and 'descrip' option attributes, *Note Required + Attributes::. + 3. 'value' (flag character) and 'min' (occurrence counts) option + attributes, *Note Common Attributes::. + 4. 'arg-type' from the option argument specification section, *Note + Option Arguments::. + 5. Read the overall how to, *Note Using AutoOpts::. + 6. Highly recommended, but not required, are the several "man" and + "info" documentation attributes, *Note documentation attributes::. + + Keep in mind that the majority are rarely used and can be safely +ignored. However, when you have special option processing requirements, +the flexibility is there. + +* Menu: + +* program attributes:: Program Description Attributes +* library attributes:: Options for Library Code +* information attributes:: Program Information Attributes +* Generated main:: Generating main procedures +* option attributes:: Option Attributes +* Option Arguments:: Option Argument Specification +* Option Argument Handling:: Option Argument Handling +* Internationalizing Options:: Internationalizing Options +* documentation attributes:: Man and Info doc Attributes +* automatic options:: Automatically Supported Options +* standard options:: Library of Standard Options + + +File: autogen.info, Node: program attributes, Next: library attributes, Up: Option Definitions + +7.5.1 Program Description Attributes +------------------------------------ + +The following global definitions are used to define attributes of the +entire program. These generally alter the configuration or global +behavior of the AutoOpts option parser. The first two are required of +every program. The third is required if there are to be any left over +arguments (operands) after option processing. The rest have been +grouped below. Except as noted, there may be only one copy of each of +these definitions: + +'prog-name' + This attribute is required. Variable names derived from this name + are derived using 'string->c_name!' (*note SCM string->c-name!::). + +'prog-title' + This attribute is required and may be any descriptive text. + +'argument' + This attribute is required if your program uses operand arguments. + It specifies the syntax of the arguments that *follow* the options. + It may not be empty, but if it is not supplied, then option + processing must consume all the arguments. If it is supplied and + starts with an open bracket ('['), then there is no requirement on + the presence or absence of command line arguments following the + options. Lastly, if it is supplied and does not start with an open + bracket, then option processing must *not* consume all of the + command line arguments. + +'config-header' + If your build has a configuration header, it must be included + before anything else. Specifying the configuration header file + name with this attribute will cause that to happen. + +* Menu: + +* usage attributes:: Usage and Version Info Display +* config attributes:: Program Configuration +* programming attributes:: Programming Details +* presentation attributes:: User Presentation Attributes + + +File: autogen.info, Node: usage attributes, Next: config attributes, Up: program attributes + +7.5.1.1 Usage and Version Info Display +...................................... + +These will affect the way usage is seen and whether or not version +information gets displayed. + +'full-usage' + If this attribute is provided, it may specify the full length usage + text, or a variable name assignable to a 'char const *' pointer, or + it may be empty. The meanings are determined by the length. + * If not provided, the text will be computed as normal. + * If the length is zero, then the usage text will be derived + from the current settings and inserted as text into the + generated .c file. + * If the length is 1 to 32 bytes, then it is presumed to be a + variable name that either points to or is an array of const + chars. + * If it is longer than that, it is presumed to be the help text + itself. This text will be inserted into the generated .c + file. + + This string should be readily translatable. Provision will be made + to translate it if this is provided, if the source code is compiled + with 'ENABLE_NLS' defined, and 'no-xlate' has not been set to the + value _anything_. The untranslated text will be handed to + 'dgettext("libopts", txt)' and then 'gettext(txt)' for translation, + one paragraph at a time. + + To facilitate the creation and maintenance of this text, you can + force the string to be ignored and recomputed by specifying + AUTOOPTS_USAGE=compute + in the environment and requesting help or usage information. See + *Note Developer and User Notes: Caveats. + +'short-usage' + If this attribute is provided, it is used to specify an abbreviated + version of the usage text. This text is constructed in the same + way as the 'full-usage', described above. + +'gnu-usage' + AutoOpts normaly displays usage text in a format that provides more + information than the standard GNU layout, but that also means it is + not the standard GNU layout. This attribute changes the default to + GNU layout, with the 'AUTOOPTS_USAGE' environment variable used to + request 'autoopts' layout. See *Note Developer and User Notes: + Caveats. + +'usage-opt' + I apologize for too many confusing usages of usage. This attribute + specifies that '--usage' and/or '-u' be supported. The help + (usage) text displayed will be abbreviated when compared to the + default help text. + +'no-misuse-usage' + When there is a command line syntax error, by default AutoOpts will + display the abbreviated usage text, rather than just a one line + "you goofed it, ask for usage" message. You can change the default + behavior for your program by supplying this attribute. The user + may override this choice, again, with the 'AUTOOPTS_USAGE' + environment variable. See *Note Developer and User Notes: Caveats. + +'prog-group' + The version text in the 'getopt.tpl' template will include this + text in parentheses after the program name, when this attribute is + specified. For example: + mumble (stumble) 1.0 + says that the 'mumble' program is version 1.0 and is part of the + 'stumble' group of programs. + +'usage' + If your program has some cleanup work that must be done before + exiting on usage mode issues, or if you have to customize the usage + message in some way, specify this procedure and it will be called + instead of the default 'optionUsage()' function. For example, if a + program is using the curses library and needs to invoke the usage + display, then you must arrange to call 'endwin()' before invoking + the library function 'optionUsage()'. This can be handled by + specifying your own usage function, thus: + void + my_usage(tOptions * opts, int ex) + { + if (curses_window_active) + endwin(); + optionUsage(opts, ex); + } + +'version' + Specifies the program version and activates the VERSION option, + *Note automatic options::. + + +File: autogen.info, Node: config attributes, Next: programming attributes, Prev: usage attributes, Up: program attributes + +7.5.1.2 Program Configuration +............................. + +Programs may be "pre-configured" before normal command line options are +processed (See *note Immediate Action Attributes: Immediate Action.). +How configuration files and environment variables are handled get +specified with these attributes. + +'disable-load' +'disable-save' + Indicates that the command line usage of '--load-opts' and/or + '--save-opts' are disallowed. + +'environrc' + Indicates looking in the environment for values of variables named, + 'PROGRAM_OPTNAME' or 'PROGRAM', where 'PROGRAM' is the upper cased + C-NAME of the program and 'OPTNAME' is the upper cased C-NAME of a + specific option. The contents of the 'PROGRAM' variable, if found, + are tokenized and processed. The contents of 'PROGRAM_OPTNAME' + environment variables are taken as the option argument to the + option nameed '--optname'. + +'homerc' + Specifies that option settings may be loaded from and stored into + configuration files. Each instance of this attribute is either a + directory or a file using a specific path, a path based on an + environment variable or a path relative to installation + directories. The method used depends on the name. If the one + entry is empty, it enables the loading and storing of settings, but + no specific files are searched for. Otherwise, a series of + configuration files are hunted down and, if found, loaded. + + If the first character of the 'homerc' value is not the dollar + character ('$'), then it is presumed to be a path name based on the + current directory. Otherwise, the method depends on the second + character: + + '$' + The path is relative to the directory where the executable was + found. + '@' + The path is relative to the package data directory, e.g. + '/usr/local/share/autogen'. + '[a-zA-Z]' + The path is derived from the named environment variable. + + Use as many as you like. The presence of this attribute activates + the '--save-opts' and '--load-opts' options. However, saving into + a file may be disabled with the 'disable-save'. *Note loading + rcfile::. See the 'optionMakePath(3AGEN)' man page for + excruciating details. + +'rcfile' + Specifies the configuration file name. This is only useful if you + have provided at least one 'homerc' attribute. + default: .<prog-name>rc + +'vendor-opt' + This option implements the '-W' vendor option command line option. + + For POSIX specified utilities, the options are constrained to the + options that are specified by POSIX. Extensions should be handled + with '-W' command line options, the short flag form. Long option + name processing must be disabled. In fact, the 'long-opts' + attribute must not be provided, and some options must be specified + without flag values. + + The '-W long-name' is processed by looking up the long option name + that follows it. It cannot be a short flag because that would + conflict with the POSIX flag name space. It will be processed as + if long options were accepted and '--long-name' were found on the + command line. + + +File: autogen.info, Node: programming attributes, Next: presentation attributes, Prev: config attributes, Up: program attributes + +7.5.1.3 Programming Details +........................... + +These attributes affect some of the ways that the option data are used +and made available to the program. + +'config-header' + The contents of this attribute should be just the name of the + configuration file. A "#include" naming this file will be inserted + at the top of the generated header. + +'exit-name' +'exit-desc' + These values should be defined as indexed values, thus: + exit-name[0] = success; + exit-desc[0] = 'Successful program execution.'; + exit-name[1] = failure; + exit-desc[1] = 'The operation failed or command syntax was not valid.'; + By default, all programs have these effectively defined for them. + They may be overridden by explicitly defining any or all of these + values. Additional names and descriptions may be defined. They + will cause an enumeration to be emitted, like this one for + 'getdefs': + typedef enum { + GETDEFS_EXIT_SUCCESS = 0, + GETDEFS_EXIT_FAILURE = 1 + } getdefs_exit_code_t; + which will be augmented by any 'exit-name' definitions beyond '1'. + + Some of the generated code will exit non-zero if there is an + allocation error. This exit will always be code '1', unless there + is an exit named 'no_mem' or 'nomem'. In that case, that value + will be used. Additionally, if there is such a value, and if + 'die-code' is specified, then a function 'nomem_err(size_t len, + char const * what)' will be emitted as an inline function for + reporting out-of-memory conditions. + +'usage-message' + This attribute will cause two procedures to be added to the code + file: 'usage_message()' and 'vusage_message()', with any applicable + prefix (see 'prefix', below). They are declared in the generated + header, thus: + noreturn extern void vusage_message(char const * fmt, va_list ap); + noreturn extern void usage_message(char const * fmt, ...); + These functions print the message to 'stderr' and invoke the usage + function with the exit code set to '1' ('EXIT_FAILURE'). + +'die-code' + This tells AutoOpts templates to emit code for 'vdie()', 'die()', + 'fserr()', and, possibly the 'nomem_err()' functions. The latter + is emitted if an exit name of 'no-mem' or 'nomem' is specified. If + the 'die-code' is assigned a text value, then that code will be + inserted in the 'vdie' function immediately before it prints the + death rattle message. + + The profiles for these functions are: + noreturn extern void vdie( int exit_code, char const * fmt, va_list); + noreturn extern void die( int exit_code, char const * fmt, ...); + noreturn extern void fserr(int exit_code, char const * op, char const * fname); + noreturn static inline void + nomem_err(size_t sz, char const * what) {...} + +'export' + This string is inserted into the .h interface file. Generally used + for global variables or '#include' directives required by + 'flag-code' text and shared with other program text. Do not + specify your configuration header ('config.h') in this attribute or + the 'include' attribute. Instead, use 'config-header', above. + +'guard-option-names' + AutoOpts generates macros that presume that there are no 'cpp' + macros with the same name as the option name. For example, if you + have an option named, '--debug', then you must not use '#ifdef + DEBUG' in your code. If you specify this attribute, every option + name will be guarded. If the name is '#define'-d, then a warning + will be issued and the name undefined. If you do not specify this + and there is a conflict, you will get strange error messages. + + This attribute may be set to any of four recognized states: + + * Not defined. AutoOpts will behave as described above. + + * Defined, but set to the empty string. Text will be emitted + into the header to undefine ('#undef') any conflicting + preprocessor macros. The code will include compiler warnings + (via '#warning'). Some compilers are not ANSI-C-99 compliant + yet and will error out on those warnings. You may compile + with '-DNO_OPTION_NAME_WARNINGS' to silence or mostly silence + them. + + * Defined and set to the string, 'no-warning'. All of the + needed '#undef's will be emitted, without any conflict + checking '#warning' directives emitted. + + * Defined and set to the string, 'full-enum'. The option + manipulation preprocessor macros will not token paste the + option names to the index enumeration prefix. e.g. you will + need to use 'HAVE_OPT(INDEX_OPT_DEBUG)' instead of + 'HAVE_OPT(DEBUG)'. + +'include' + This string is inserted into the .c file. Generally used for + global variables required only by 'flag-code' program text. + +'no-libopts' + If you are going to handle your option processing with the + 'getopt.tpl' template instead of using libopts, then specify this + attribute. It will suppress mention of '--more-help' in the + generated documentation. ('getopt_long' does not support + '--more-help'.) + +'prefix' + This value is inserted into *all* global names. This will + disambiguate them if more than one set of options are to be + compiled into a single program. + + +File: autogen.info, Node: presentation attributes, Prev: programming attributes, Up: program attributes + +7.5.1.4 User Presentation Attributes +.................................... + +Attributes that affect the user's experience. + +'allow-errors' + The presence of this attribute indicates ignoring any command line + option errors. This may also be turned on and off by invoking the + macros 'ERRSKIP_OPTERR' and 'ERRSTOP_OPTERR' from the generated + interface file. + +'long-opts' + Presence indicates GNU-standard long option processing. Partial + name matches are accepted, if they are at least two characters long + and the partial match is unique. The matching is not case + sensitive, and the underscore, hyphen and carat characters are all + equivalent (they match). + + If any options do not have an option value (flag character) + specified, and least one does specify such a value, then you must + specify 'long-opts'. If none of your options specify an option + value (flag character) and you do not specify 'long-opts', then + command line arguments are processed in "named option mode". This + means that: + + * Every command line argument must be a long option. + * The flag markers '-' and '--' are completely optional. + * The 'argument' program attribute is disallowed. + * One of the options may be specified as the default (as long as + it has a required option argument). + +'no-xlate' + Modifies when or whether option names get translated. If provided, + it must be assigned one of these values: + 'opt-cfg' + to suppress option name translation for configuration file and + and environment variable processing. + 'opt' + to suppress option name translation completely. The usage + text will always be translated if 'ENABLE_NLS' is defined and + you have translations for that text. + 'anything' + Specifies disabling all internationalization support for + option code, completely. + See also the various 'XLAT' interface entries in the AutoOpts + Programmatic Interface section (*note AutoOpts API::). + +'reorder-args' + Normally, POSIX compliant commands do not allow for options to be + interleaved with operands. If this is necessary for historical + reasons, there are two approaches available: + * Allow 'optionProcess' to return the index of the operand like + it normally does and process the operand(s). When an operand + is encountered that starts with a hyphen, then set the + AutoOpts current index with the 'RESTART_OPT' macro (see *note + RESTART_OPT::), and re-invoke 'optionProcess'. This will also + allow you to process the operands in context. + + * Specify this attribute. AutoOpts will re-order the command + arguments so that the operands appear (in the original order) + at the end of the argument list. Differing configuration + state is not possible to detect after all options have been + processed. + +'resettable' + Specifies that the '--reset-option' command line option is to be + supported. This makes it possible to suppress any setting that + might be found in a configuration file or environment variable. + + +File: autogen.info, Node: library attributes, Next: information attributes, Prev: program attributes, Up: Option Definitions + +7.5.2 Options for Library Code +------------------------------ + +Some libraries provide their own code for processing command line +options, and this may be used by programs that utilize AutoOpts. You +may also wish to write a library that gets configured with AutoOpts +options and config files. Such a library may either supply its own +configury routine and process its own options, or it may export its +option descriptions to programs that also use AutoOpts. This section +will describe how to do all of these different things. + +* Menu: + +* lib and program:: AutoOpt-ed Library for AutoOpt-ed Program +* lib called:: AutoOpt-ed Library for Regular Program +* prog calls lib:: AutoOpt-ed Program Calls Regular Library + + +File: autogen.info, Node: lib and program, Next: lib called, Up: library attributes + +7.5.2.1 AutoOpt-ed Library for AutoOpt-ed Program +................................................. + +The library source code must provide an option definition file that +consists of only the attribute 'library' and 'flag' entries. The +'library' attribute does not need any associated value, so it will +generally appeary by itself on a line folowed by a semi-colon. The +first 'flag' entry must contain the following attributes: + +'name' + This name is used in the construction of a global pointer of type + 'tOptDesc const*'. It is always required. +'documentation' + It tells 'AutoOpts' that this option serves no normal purpose. It + will be used to add usage clarity and to locate option descriptors + in the library code. +'descrip' + This is a string that is inserted in the extended usage display + before the options specific to the current library. It is always + required. +'lib-name' + This should match the name of the library. This string is also + used in the construction of the option descriptor pointer name. In + the end, it looks like this: + extern tOptDesc const* <<lib-name>>_<<name>>_optDesc_p; + and is used in the macros generated for the library's '.h' file. + + In order to compile this 'AutoOpts' using library, you must create a +special header that is not used by the client program. This is +accomplished by creating an option definition file that contains +essentially exactly the following: + + AutoGen definitions options; + prog-name = does-not-matter; // but is always required + prog-title = 'also does not matter'; // also required + config-header = 'config.h'; // optional, but common + library; + #include library-options-only.def + +and nothing else. AutoGen will produce only the '.h' file. You may now +compile your library, referencing just this '.h' file. The macros it +creates will utilize a global variable that will be defined by the +'AutoOpts'-using client program. That program will need to have the +following '#include' in its option definition file: + + #include library-options-only.def + +All the right things will magically happen so that the global variables +named <<LIB-NAME>>_<<NAME>>_OPTDESC_P are initialized correctly. For an +example, please see the 'AutoOpts' test script: +'autoopts/test/library.test'. + + +File: autogen.info, Node: lib called, Next: prog calls lib, Prev: lib and program, Up: library attributes + +7.5.2.2 AutoOpt-ed Library for Regular Program +.............................................. + +In this case, your library must provide an option processing function to +a calling program. This is accomplished by setting the 'allow-errors' +global option attribute. Each time your option handling function is +called, you must determine where your scan is to resume and tell the +AutoOpts library by invoking: + + RESTART_OPT(next_arg_index); + +and then invoke 'not_opt_index = optionProcess(...)'. The +'not_opt_index' value can be used to set 'optind', if that is the global +being used to scan the program argument array. + + In this method, do *NOT* utilize the global 'library' attribute. +Your library must specify its options as if it were a complete program. +You may choose to specify an alternate 'usage()' function so that usage +for other parts of the option interface may be displayed as well. See +"Program Information Attributes" (*note information attributes::). + + At the moment, there is no method for calling 'optionUsage()' telling +it to produce just the information about the options and not the program +as a whole. Some later revision after somebody asks. + + +File: autogen.info, Node: prog calls lib, Prev: lib called, Up: library attributes + +7.5.2.3 AutoOpt-ed Program Calls Regular Library +................................................ + +As with providing an 'AutoOpt'-ed library to a non-'AutoOpt'-ed program, +you must write the option description file as if you were writing all +the options for the program, but you should specify the 'allow-errors' +global option attribute and you will likely want an alternate 'usage()' +function (see "Program Information Attributes" *note information +attributes::). In this case, though, when 'optionProcess()' returns, +you need to test to see if there might be library options. If there +might be, then call the library's exported routine for handling command +line options, set the next-option-to-process with the 'RESTART_OPT()' +macro, and recall 'optionProcess()'. Repeat until done. + + +File: autogen.info, Node: information attributes, Next: Generated main, Prev: library attributes, Up: Option Definitions + +7.5.3 Program Information Attributes +------------------------------------ + +These attributes are used to define how and what information is +displayed to the user of the program. + +'copyright' + The 'copyright' is a structured value containing three to five + values. If 'copyright' is used, then the first three are required. + + 1. 'date' - the list of applicable dates for the copyright. + 2. 'owner' - the name of the copyright holder. + 3. 'type' - specifies the type of distribution license. + AutoOpts/AutoGen supports the text of the GNU Public License + ('gpl'), the GNU Lesser General Public License with Library + extensions ('lgpl'), the Modified Free BSD license ('mbsd') + and a few others. Other licenses may be specified, but you + must provide your own license file. The list of license files + provided by AutoOpts may be seen by typing: + ls $(autoopts-config pkgdatadir)/*.lic + 4. 'text' - the text of the copyright notice. This must be + provided if 'type' is set to 'NOTE'. + 5. 'author' - in case the author name is to appear in the + documentation and is different from the copyright owner. + 6. 'eaddr' - email address for receiving praises and complaints. + Typically that of the author or copyright holder. + + An example of this might be: + copyright = { + date = "1992-2015"; + owner = "Bruce Korb"; + eaddr = 'bkorb@gnu.org'; + type = GPL; + }; + +'detail' + This string is added to the usage output when the HELP option is + selected. + +'explain' + Gives additional information whenever the usage routine is invoked. + +'package' + The name of the package the program belongs to. This will appear + parenthetically after the program name in the version and usage + output, e.g.: 'autogen (GNU autogen) - The Automated Program + Generator'. + +'preserve-case' + This attribute will not change anything except appearance. + Normally, the option names are all documented in lower case. + However, if you specify this attribute, then they will display in + the case used in their specification. Command line options will + still be matched without case sensitivity. This is useful for + specifying option names in camel-case. + +'prog-desc *and*' +'opts-ptr' + These define global pointer variables that point to the program + descriptor and the first option descriptor for a library option. + This is intended for use by certain libraries that need command + line and/or initialization file option processing. These + definitions have no effect on the option template output, but are + used for creating a library interface file. Normally, the first + "option" for a library will be a documentation option that cannot + be specified on the command line, but is marked as 'settable'. The + library client program will invoke the 'SET_OPTION' macro which + will invoke a handler function that will finally set these global + variables. + +'usage' + Optionally names the usage procedure, if the library routine + 'optionUsage()' does not work for you. If you specify 'my_usage' + as the value of this attribute, for example, you will use a + procedure by that name for displaying usage. Of course, you will + need to provide that procedure and it must conform to this profile: + void my_usage( tOptions* pOptions, int exitCode ) + +'gnu-usage' + Normally, the default format produced by the 'optionUsage' + procedure is AutoOpts Standard. By specifying this attribute, the + default format will be GNU-ish style. Either default may be + overridden by the user with the 'AUTOOPTS_USAGE' environment + variable. If it is set to 'gnu' or 'autoopts', it will alter the + style appropriately. This attribute will conflict with the 'usage' + attribute. + +'reorder-args' + Some applications traditionally require that the command operands + be intermixed with the command options. In order to handle that, + the arguments must be reordered. If you are writing such an + application, specify this global option. All of the options (and + any associated option arguments) will be brought to the beginning + of the argument list. New applications should not use this + feature, if at all possible. This feature is disabled if + 'POSIXLY_CORRECT' is defined in the environment. + + +File: autogen.info, Node: Generated main, Next: option attributes, Prev: information attributes, Up: Option Definitions + +7.5.4 Generating main procedures +-------------------------------- + +When AutoOpts generates the code to parse the command line options, it +has the ability to produce any of several types of 'main()' procedures. +This is done by specifying a global structured value for 'main'. The +values that it contains are dependent on the value set for the one value +it must have: 'main-type'. + + The recognized values for 'main-type' are 'guile', 'shell-process', +'shell-parser', 'main', 'include', 'invoke', and 'for-each'. + +* Menu: + +* main guile:: guile: main and inner_main procedures +* main shell-process:: shell-process: emit Bourne shell results +* main shell-parser:: shell-parser: emit Bourne shell script +* main main:: main: user supplied main procedure +* main include:: include: code emitted from included template +* main invoke:: invoke: code emitted from AutoGen macro + +The 'for-each' main procedure has a number of attributes that +must be specified: + +* main for-each:: for-each: perform function on each operand +* main-for-each-proc:: procedure to handle each argument +* main-for-each-type:: handler procedure type +* main-for-each-code:: code for handler procedure +* main-for-each-opts:: for-each main procedure options + + +File: autogen.info, Node: main guile, Next: main shell-process, Up: Generated main + +7.5.4.1 guile: main and inner_main procedures +............................................. + +When the 'main-type' is specified to be 'guile', a 'main()' procedure is +generated that calls 'gh_enter()', providing it with a generated +'inner_main()' to invoke. If you must perform certain tasks before +calling 'gh_enter()', you may specify such code in the value for the +'before-guile-boot' attribute. + + The 'inner_main()' procedure itself will process the command line +arguments (by calling 'optionProcess()', *note libopts-optionProcess::), +and then either invoke the code specified with the 'guile-main' +attribute, or else export the parsed options to Guile symbols and invoke +the 'scm_shell()' function from the Guile library. This latter will +render the program nearly identical to the stock 'guile(1)' program. + + +File: autogen.info, Node: main shell-process, Next: main shell-parser, Prev: main guile, Up: Generated main + +7.5.4.2 shell-process: emit Bourne shell results +................................................ + +This will produce a 'main()' procedure that parses the command line +options and emits to 'stdout' Bourne shell commands that puts the option +state into environment variables. This can be used within a shell +script as follows: + + unset OPTION_CT + eval "`opt_parser \"$@\"`" + test ${OPTION_CT} -gt 0 && shift ${OPTION_CT} + + If the option parsing code detects an error or a request for usage or +version, it will emit a command to exit with an appropriate exit code to +'stdout'. This form of 'main' will cause all messages, including +requested usage and version information, to be emitted to 'stderr'. +Otherwise, a numeric value for 'OPTION_CT' is guaranteed to be emitted, +along with assignments for all the options parsed, something along the +lines of the following will be written to 'stdout' for evaluation: + + OPTION_CT=4 + export OPTION_CT + MYPROG_SECOND='first' + export MYPROG_SECOND + MYPROG_ANOTHER=1 # 0x1 + export MYPROG_ANOTHER + +If the arguments are to be reordered, however, then the resulting set of +operands will be emitted and 'OPTION_CT' will be set to zero. For +example, the following would be appended to the above: + + set -- 'operand1' 'operand2' 'operand3' + OPTION_CT=0 + +'OPTION_CT' is set to zero since it is not necessary to shift off any +options. + + +File: autogen.info, Node: main shell-parser, Next: main main, Prev: main shell-process, Up: Generated main + +7.5.4.3 shell-parser: emit Bourne shell script +.............................................. + +This will produce a 'main()' procedure that emits a shell script that +will parse the command line options. That script can be emitted to +'stdout' or inserted or substituted into a pre-existing shell script +file. Improbable markers are used to identify previously inserted +parsing text: + + # # # # # # # # # # -- do not modify this marker -- + +The program is also pretty insistent upon starting its parsing script on +the second line. + + +File: autogen.info, Node: main main, Next: main include, Prev: main shell-parser, Up: Generated main + +7.5.4.4 main: user supplied main procedure +.......................................... + +You must supply a value for the 'main-text' attribute. You may also +supply a value for 'option-code'. If you do, then the 'optionProcess' +invocation will not be emitted into the code. AutoOpts will wrap the +'main-text' inside of: + + int + main( int argc, char** argv ) + { + int res = <<success-exit-code>>; + { // replaced by option-code, if that exists + int ct = optionProcess( &<<prog-name>>Options, argc, argv); + argc -= ct; + argv += ct; + } + <<main-text>> + return res; + } + +so you can most conveniently set the value with a 'here string' (*note +here-string::): + + code = <<- _EndOfMainProc_ + <<your text goes here>> + _EndOfMainProc_; + + +File: autogen.info, Node: main include, Next: main invoke, Prev: main main, Up: Generated main + +7.5.4.5 include: code emitted from included template +.................................................... + +You must write a template to produce your main procedure. You specify +the name of the template with the 'tpl' attribute and it will be +incorporated at the point where AutoOpts is ready to emit the 'main()' +procedure. + + This can be very useful if, in your working environment, you have +many programs with highly similar 'main()' procedures. All you need to +do is parameterize the variations and specify which variant is needed +within the 'main' AutoOpts specification. Since you are coding the +template for this, the attributes needed for this variation would be +dictated by your template. + + Here is an example of an 'include' variation: + + main = { + main-type = include; + tpl = "main-template.tpl"; + }; + + +File: autogen.info, Node: main invoke, Next: main for-each, Prev: main include, Up: Generated main + +7.5.4.6 invoke: code emitted from AutoGen macro +............................................... + +You must write a template to produce your main procedure. That template +must contain a definition for the function specified with the 'func' +attribute to this 'main()' procedure specification. This variation +operates in much the same way as 'include' (*note main include::) +method. + + +File: autogen.info, Node: main for-each, Next: main-for-each-proc, Prev: main invoke, Up: Generated main + +7.5.4.7 for-each: perform function on each operand +.................................................. + +This produces a main procedure that invokes a procedure once for each +operand on the command line (non-option arguments), *OR* once for each +non-blank, non-comment 'stdin' input line. Leading and trailing white +space is trimmed from the input line and comment lines are lines that +are empty or begin with a comment character, defaulting to a hash ('#') +character. + + *NB*: The 'argument' program attribute (*note program attributes::) +must begin with the '[' character, to indicate that there are command +operands, but that they are optional. + +For an example of the produced main procedure, in the 'autoopts/test' +build directory, type the following command and look at 'main.c': + make verbose TESTS=main.test + + +File: autogen.info, Node: main-for-each-proc, Next: main-for-each-type, Prev: main for-each, Up: Generated main + +procedure to handle each argument +................................. + +The 'handler-proc' attribute is required. It is used to name the +procedure to call. That procedure is presumed to be external, but if +you provide the code for it, then the procedure is emitted as a static +procedure in the generated code. + + This procedure should return 0 on success, a cumulative error code on +warning and exit without returning on an unrecoverable error. As the +cumulative warning codes are or-ed together, the codes should be some +sort of bit mask in order to be ultimately decipherable (if you need to +do that). + + If the called procedure needs to cause a fail-exit, it is expected to +call 'exit(3)' directly. If you want to cause a warning exit code, then +this handler function should return a non-zero status. That value will +be *OR*-ed into a result integer for computing the final exit code. +E.g., here is part of the emitted code: + + int res = 0; + if (argc > 0) { + do { + res |= MY_HANDLER( *(argv++) ); + } while (--argc > 0); + } else { ... + + +File: autogen.info, Node: main-for-each-type, Next: main-for-each-code, Prev: main-for-each-proc, Up: Generated main + +handler procedure type +...................... + +If you do not supply the 'handler-type' attribute, your handler +procedure must be the default type. The profile of the procedure must +be: + + int MY_HANDLER(char const * pz_entry); + +However, if you do supply this attribute, you may set the value to any +of four alternate flavors: + +'name-of-file' + This is essentially the same as the default handler type, except + that before your procedure is invoked, the generated code has + verified that the string names an existing file. The profile is + unchanged. + +'file-X' + Before calling your procedure, the file is f-opened according to + the 'X', where 'X' may be any of the legal modes for 'fopen(3C)'. + In this case, the profile for your procedure must be: + + int MY_HANDLER(char const * pz_fname, FILE * entry_fp); + + When processing inputs as file pointer stream files, there are + several ways of treating standard input. It may be an ordinary + input file, or it may contain a list of files to operate on. + + If the file handler type is more specifically set to 'file-r' and a + command line operand consists of a single hyphen, then MY_HANDLER + will be called with 'entry_fp' set to 'stdin' and the 'pz_fname' + set to the translatable string, "standard input". Consequently, in + this case, if the input list is being read from 'stdin', a line + containing a hyphen by itself will be ignored. + +'stdin-input' + This attribute specifies that standard input is a data input file. + By default, 'for-each' main procedures will read standard input for + operands if no operands appear on the command line. If there are + operands after the command line options, then standard input is + typically ignored. It can always be processed as an input data + file, however, if a single bare hyphen is put on the command line. + +'text-of-file' +'some-text-of-file' + Before calling your procedure, the contents of the file are read or + mapped into memory. (Excessively large files may cause problems.) + The 'some-text-of-file' disallows empty files. Both require + regular files. In this case, the profile for your procedure must + be: + + program_exit_code_t + MY_HANDLER(char const * fname, char * file_text, + size_t text_size); + + Note that though the 'file_text' is not 'const', any changes made + to it are not written back to the original file. It is merely a + memory image of the file contents. Also, the memory allocated to + hold the text is 'text_size + 1' bytes long and the final byte is + always 'NUL'. The file contents need not be text, as the data are + read with the 'read(2)' system call. + + 'file_text' is automatically freed, unless you specify a + 'handler-frees' attribute. Then your code must 'free(3)' the text. + + If you select one of these file type handlers, then on access or +usage errors the 'PROGRAM_EXIT_FAILURE' exit code will, by default, be +or-ed into the final exit code. This can be changed by specifying the +global 'file-fail-code' attribute and naming a different value. That +is, something other than 'failure'. You may choose 'success', in which +case file access issues will not affect the exit code and the error +message will not be printed. + + +File: autogen.info, Node: main-for-each-code, Next: main-for-each-opts, Prev: main-for-each-type, Up: Generated main + +code for handler procedure +.......................... + +With the 'MYHANDLER-code' attribute, you provide the code for your +handler procedure in the option definition file. Note that the spelling +of this attribute depends on the name provided with the 'handler-proc' +attribute, so we represent it here with 'MYHANDLER' as a place holder. +As an example, your 'main()' procedure specification might look +something like this: + + main = { + main-type = for-each; + handler-proc = MYHANDLER; + MYHANDLER-code = <<- EndOfMyCode + /* whatever you want to do */ + EndOfMyCode; + }; + +and instead of an emitted external reference, a procedure will be +emitted that looks like this: + + static int + MYHANDLER( char const* pz_entry ) + { + int res = 0; + <<MYHANDLER-code goes here>> + return res; + } + + +File: autogen.info, Node: main-for-each-opts, Prev: main-for-each-code, Up: Generated main + +for-each main procedure options +............................... + +These attributes affect the main procedure and how it processes each +argument or input line. + +'interleaved' + If this attribute is specified, then options and operands may be + interleaved. Arguments or input lines beginning with a hyphen will + cause it to be passed through to an option processing function and + will take effect for the remainder of the operands (or input lines) + processed. + +'main-init' + This is code that gets inserted after the options have been + processed, but before the handler procs get invoked. + +'main-fini' + This is code that gets inserted after all the entries have been + processed, just before returning from 'main()'. + +'comment-char' + When reading operands from standard input, if you wish comment + lines to start with a character other than a hash ('#') character, + then specify one character with this attribute. If string value is + empty, then only blank lines will be considered comments. + + +File: autogen.info, Node: option attributes, Next: Option Arguments, Prev: Generated main, Up: Option Definitions + +7.5.5 Option Attributes +----------------------- + +For each option you wish to specify, you must have a block macro named +'flag' defined. There are two required attributes: 'name' and +'descrip'. If any options do not have a 'value' (traditional flag +character) attribute, then the 'long-opts' program attribute must also +be defined. As a special exception, if no options have a 'value' *and* +'long-opts' is not defined *and* 'argument' is not defined, then all +arguments to the program are named options. In this case, the '-' and +'--' command line option markers are optional. + +* Menu: + +* Required Attributes:: Required Attributes +* Common Attributes:: Common Option Attributes +* Immediate Action:: Immediate Action Attributes +* Option Conflict Attributes:: Option Conflict Attributes + +These option attributes do not fit well with the above categories. + +* opt-attr settable:: Program may set option +* opt-attr no-preset:: Option cannot be pre-configured +* opt-attr equivalence:: Option Equivalence Class +* opt-attr aliases:: Option Aliasing +* opt-attr default option:: Default Option +* opt-attr documentation:: Option Sectioning Comment +* opt-attr translators:: Translator Notes + + +File: autogen.info, Node: Required Attributes, Next: Common Attributes, Up: option attributes + +7.5.5.1 Required Attributes +........................... + +Every option must have exactly one copy of both of these attributes. + +'name' + Long name for the option. Even if you are not accepting long + options and are only accepting flags, it must be provided. + AutoOpts generates private, named storage that requires this name. + This name also causes a '#define'-d name to be emitted. It must + not conflict with any other names you may be using in your program. + + For example, if your option name is, 'debug' or 'munged-up', you + must not use the '#define' names 'DEBUG' (or 'MUNGED_UP') in your + program for non-AutoOpts related purposes. They are now used by + AutoOpts. + + Sometimes (most especially under Windows), you may get a surprise. + For example, 'INTERFACE' is apparently a user space name that one + should be free to use. Windows usurps this name. To solve this, + you must do one of the following: + + 1. Change the name of your option + 2. add the program attribute (*note program attributes::): + + export = '#undef INTERFACE'; + 3. add the program attribute: + + guard-option-names; + +'descrip' + Except for documentation options, a *very* brief description of the + option. About 40 characters on one line, maximum, not counting any + texinfo markups. Texinfo markups are stripped before printing in + the usage text. It appears on the 'usage()' output next to the + option name. + + If, however, the option is a documentation option, it will appear + on one or more lines by itself. It is thus used to visually + separate and comment upon groups of options in the usage text. + diff --git a/doc/autogen.info-2 b/doc/autogen.info-2 new file mode 100644 index 0000000..cf68422 --- /dev/null +++ b/doc/autogen.info-2 @@ -0,0 +1,7358 @@ +This is autogen.info, produced by makeinfo version 6.5 from +autogen.texi. + +This manual is for GNU AutoGen version 5.18, updated August 2018. + + Copyright (C) 1992-2018 by Bruce Korb. + + Permission is granted to copy, distribute and/or modify this + document under the terms of the GNU Free Documentation License, + Version 1.2 or any later version published by the Free Software + Foundation; with no Invariant Sections, no Front-Cover Texts, and + no Back-Cover Texts. +INFO-DIR-SECTION GNU programming tools +START-INFO-DIR-ENTRY +* AutoGen: (autogen). The Automated Program Generator +END-INFO-DIR-ENTRY + + This file documents GNU AutoGen Version 5.18. + + AutoGen copyright (C) 1992-2018 Bruce Korb AutoOpts copyright (C) +1992-2018 Bruce Korb snprintfv copyright (C) 1999-2000 Gary V. Vaughan + + AutoGen 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. + + AutoGen is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +Public License for more details. + + You should have received a copy of the GNU General Public License +along with this program. If not, see <http://www.gnu.org/licenses/>. + + +File: autogen.info, Node: Common Attributes, Next: Immediate Action, Prev: Required Attributes, Up: option attributes + +7.5.5.2 Common Option Attributes +................................ + +These option attributes are optional. Any that do appear in the +definition of a flag, may appear only once. + +'value' + The flag character to specify for traditional option flags, e.g., + '-L'. + +'max' + Maximum occurrence count (invalid if DISABLE present). The default + maximum is 1. 'NOLIMIT' can be used for the value, otherwise it + must be a number or a '#define' that evaluates to a number. + +'min' + Minimum occurrence count. If present, then the option *must* + appear on the command line. Do not define it with the value zero + (0). + +'must-set' + If an option must be specified, but it need not be specified on the + command line, then specify this attribute for the option. + +'deprecated' + There are two effects to this attribute: the usage text will not + show the option, and the generated documentation will mark it with: + _NOTE: THIS OPTION IS DEPRECATED_. + +'disable' + Prefix for disabling (inverting sense of) the option. Only useful + if long option names are being processed. When an option has this + attribute, the test 'ENABLED_OPT(OPTNAME)' is false when either of + the following is true: + * The option has not been specified and the 'enable' attribute + has not been specified. + * The option has been specified with this disabling prefix. + To detect that the option has been specified with the disabling + prefix, you must use: + HAVE_OPT(OPTNAME) && ! ENABLED_OPT(OPTNAME) + +'enable' + Long-name prefix for enabling the option (invalid if DISABLE *not* + present). Only useful if long option names are being processed. + +'enabled' + If default is for option being enabled. (Otherwise, the + OPTST_DISABLED bit is set at compile time.) Only useful if the + option can be disabled. + +'ifdef' +'ifndef' +'omitted-usage' + If an option is relevant on certain platforms or when certain + features are enabled or disabled, you can specify the compile time + flag used to indicate when the option should be compiled in or out. + For example, if you have a configurable feature, 'mumble' that is + indicated with the compile time define, 'WITH_MUMBLING', then add: + + ifdef = WITH_MUMBLING; + + Take care when using these. There are several caveats: + + * The case and spelling must match whatever is specified. + * Do not confuse these attributes with the AutoGen directives of + the same names, *Note Directives::. These cause C + preprocessing directives to be inserted into the generated C + text. + * Only one of 'ifdef' and 'ifndef' may apply to any one option. + * The 'VALUE_OPT_' values are '#define'-d. If 'WITH_MUMBLING' + is not defined, then the associated 'VALUE_OPT_' value will + not be '#define'-d either. So, if you have an option named, + 'MUMBLING' that is active only if 'WITH_MUMBLING' is + '#define'-d, then 'VALUE_OPT_MUMBLING' will be '#define'-d iff + 'WITH_MUMBLING' is '#define'-d. Watch those switch + statements. + * If you specify 'omitted-usage', then the option will be + recognized as disabled when it is configured out of the build, + but will yield the message, "This option has been disabled." + You may specify an alternate message by giving 'omitted-usage' + a string value. e.g.: + omitted-usage = 'you cannot do this'; + +'no-command' + This option specifies that the option is not allowed on the command + line. Such an option may not take a 'value' (flag character) + attribute. The program must have the 'homerc' (*note program + attributes::) option set. + + +File: autogen.info, Node: Immediate Action, Next: Option Conflict Attributes, Prev: Common Attributes, Up: option attributes + +7.5.5.3 Immediate Action Attributes +................................... + +Certain options may need to be processed early. For example, in order +to suppress the processing of configuration files, it is necessary to +process the command line option '--no-load-opts' *before* the config +files are processed. To accommodate this, certain options may have +their enabled or disabled forms marked for immediate processing. The +consequence of this is that they are processed ahead of all other +options in the reverse of normal order. + + Normally, the first options processed are the options specified in +the first 'homerc' file, followed by then next 'homerc' file through to +the end of config file processing. Next, environment variables are +processed and finally, the command line options. The later options +override settings processed earlier. That actually gives them higher +priority. Command line immediate action options actually have the +lowest priority of all. They would be used only if they are to have an +effect on the processing of subsequent options. + +'immediate' + Use this option attribute to specify that the enabled form of the + option is to be processed immediately. The 'help' and 'more-help' + options are so specified. They will also call 'exit()' upon + completion, so they *do* have an effect on the processing of the + remaining options :-). + +'immed-disable' + Use this option attribute to specify that the disabled form of the + option is to be processed immediately. The 'load-opts' option is + so specified. The '--no-load-opts' command line option will + suppress the processing of config files and environment variables. + Contrariwise, the '--load-opts' command line option is processed + normally. That means that the options specified in that file will + be processed after all the 'homerc' files and, in fact, after + options that precede it on the command line. + +'also' + If either the 'immediate' or the 'immed-disable' attributes are set + to the string, 'also', then the option will actually be processed + twice: first at the immediate processing phase and again at the + normal time. + + +File: autogen.info, Node: Option Conflict Attributes, Next: opt-attr settable, Prev: Immediate Action, Up: option attributes + +7.5.5.4 Option Conflict Attributes +.................................. + +These attributes may be used as many times as you need. They are used +at the end of the option processing to verify that the context within +which each option is found does not conflict with the presence or +absence of other options. + + This is not a complete cover of all possible conflicts and +requirements, but it simple to implement and covers the more common +situations. + +'flags-must' + one entry for every option that *must* be present when this option + is present + +'flags-cant' + one entry for every option that *cannot* be present when this + option is present + + +File: autogen.info, Node: opt-attr settable, Next: opt-attr no-preset, Prev: Option Conflict Attributes, Up: option attributes + +7.5.5.5 Program may set option +.............................. + +If the option can be set outside of option processing, specify +'settable'. If this attribute is defined, special macros for setting +this particular option will be inserted into the interface file. For +example, 'TEMPL_DIRS' is a settable option for AutoGen, so a macro named +'SET_OPT_TEMPL_DIRS(a)' appears in the interface file. This attribute +interacts with the DOCUMENTATION attribute. + + +File: autogen.info, Node: opt-attr no-preset, Next: opt-attr equivalence, Prev: opt-attr settable, Up: option attributes + +7.5.5.6 Option cannot be pre-configured +....................................... + +If presetting this option is not allowed, specify 'no-preset'. (Thus, +environment variables and values set in configuration files will be +ignored.) + + +File: autogen.info, Node: opt-attr equivalence, Next: opt-attr aliases, Prev: opt-attr no-preset, Up: option attributes + +7.5.5.7 Option Equivalence Class +................................ + +Generally, when several options are mutually exclusive and basically +serve the purpose of selecting one of several processing modes, specify +the 'equivalence' attribute. These options will be considered an +equivalence class. Sometimes, it is just easier to deal with them as +such. All members of the equivalence class must contain the same +equivalenced-to option, including the equivalenced-to option itself. +Thus, it must be a class member. + + For an option equivalence class, there is a single occurrence counter +for the class. It can be referenced with the interface macro, +'COUNT_OPT(BASE_OPTION)', where BASE_OPTION is the equivalenced-to +option name. + + Also, please take careful note: since the options are mapped to the +equivalenced-to option descriptor, any option argument values are mapped +to that descriptor also. Be sure you know which "equivalent option" was +selected before getting an option argument value! + + During the presetting phase of option processing (*note Presetting +Options::), equivalenced options may be specified. However, if +different equivalenced members are specified, only the last instance +will be recognized and the others will be discarded. A conflict error +is indicated only when multiple different members appear on the command +line itself. + + As an example of where equivalenced options might be useful, +'cpio(1)' has three options '-o', '-i', and '-p' that define the +operational mode of the program ('create', 'extract' and 'pass-through', +respectively). They form an equivalence class from which one and only +one member must appear on the command line. If 'cpio' were an +AutoOpt-ed program, then each of these option definitions would contain: + + equivalence = create; + + and the program would be able to determine the operating mode with +code that worked something like this: + + switch (WHICH_IDX_CREATE) { + case INDEX_OPT_CREATE: ... + case INDEX_OPT_EXTRACT: ... + case INDEX_OPT_PASS_THROUGH: ... + default: /* cannot happen */ + } + + +File: autogen.info, Node: opt-attr aliases, Next: opt-attr default option, Prev: opt-attr equivalence, Up: option attributes + +7.5.5.8 Option Aliasing +....................... + +Sometimes, for backwards compatibility or tradition or just plain +convenience, it works better to define one option as a pure alias for +another option. For such situations, provide the following pieces of +information: + flag = { + name = aliasing-option-name; + value = aliasing-flag-char; // optional ! + aliases = aliased-to-option; + }; + Do not provide anything else. The usage text for such an option will +be: + This is an alias for aliased-to-option + + +File: autogen.info, Node: opt-attr default option, Next: opt-attr documentation, Prev: opt-attr aliases, Up: option attributes + +7.5.5.9 Default Option +...................... + +If your program processes its arguments in named option mode (See +'long-opts' in *note program attributes::), then you may select *one* of +your options to be the default option. Do so by using attribute +'default' with one of the options. The option so specified must have an +'arg-type' (*note Option Arguments::) specified, but not the +'arg-optional' (*note arg-optional::) attribute. That is to say, the +option argument must be required. + + If you have done this, then any arguments that do not match an option +name and do not contain an equal sign ('=') will be interpreted as an +option argument to the default option. + + +File: autogen.info, Node: opt-attr documentation, Next: opt-attr translators, Prev: opt-attr default option, Up: option attributes + +7.5.5.10 Option Sectioning Comment +.................................. + +This attribute means the option exists for the purpose of separating +option description text in the usage output and texi documentation. +Without this attribute, every option is a separate node in the texi +docs. With this attribute, the documentation options become texi doc +nodes and the options are collected under them. Choose the name +attribute carefully because it will appear in the texi documentation. + + Libraries may also choose to make it settable so that the library can +determine which command line option is the first one that pertains to +the library. + + If the 'documentation' attribute is present, then all other +attributes are disabled except 'settable', 'call-proc' and 'flag-code'. +'settable' must be and is only specified if 'call-proc', 'extract-code' +or 'flag-code' has been specified. When present, the 'descrip' +attribute will be displayed only when the '--help' option has been +specified. It will be displayed flush to the left hand margin and may +consist of one or more lines of text, filled to 72 columns. + + The name of the option will not be printed in the help text. It +will, however, be printed as section headers in the texi documentation. +If the attribute is given a non-empty value, this text will be +reproduced in the man page and texi doc immediately after the 'descrip' +text. + + +File: autogen.info, Node: opt-attr translators, Prev: opt-attr documentation, Up: option attributes + +7.5.5.11 Translator Notes +......................... + +If you need to give the translators a special note about a particular +option, please use the 'translators' attribute. The attribute text will +be emitted into the generated '.c' text where the option related strings +get defined. To make a general comment about all of the option code, +add comments to an 'include' attribute (*note program attributes::). Do +*not* use this attribute globally, or it will get emitted into every +option definition block. + + +File: autogen.info, Node: Option Arguments, Next: Option Argument Handling, Prev: option attributes, Up: Option Definitions + +7.5.6 Option Argument Specification +----------------------------------- + +Command line options come in three flavors: options that do not take +arguments, those that do and those that may. Without an "arg-type" +attribute, AutoOpts will not process an argument to an option. If +"arg-type" is specified and "arg-optional" is also specified, then the +next command line token will be taken to be an argument, unless it looks +like the name of another option. + + If the argument type is specified to be anything other than +"str[ing]", then AutoOpts will specify a callback procedure to handle +the argument. Some of these procedures will be created and inserted +into the generated '.c' file, and others are already built into the +'libopts' library. Therefore, if you write your own callback procedure +(*note Option Argument Handling::), then you must either not specify an +"arg-type" attribute, or else specify it to be of type "str[ing]". Your +callback function will be able to place its own restrictions on what +that string may contain or represent. + + Option argument handling attributes depend upon the value set for the +'arg-type' attribute. It specifies the type of argument the option will +take. If not present, the option cannot take an argument. If present, +it must be an entry in the following table. The first three letters is +sufficient. + +* Menu: + +* arg-type string:: Arg Type String +* arg-type number:: Arg Type Number +* arg-type boolean:: Arg Type Boolean +* arg-type keyword:: Arg Type Keyword +* arg-type set membership:: Arg Type Set Membership +* arg-type hierarchy:: Arg Type Hierarchical +* arg-type file name:: Arg Type File Name +* arg-type time-duration:: Arg Type Time Duration +* arg-type time-date:: Arg Type Time and Date + +Supporting attributes for particular argument types: + +* arg-keyword:: Keyword list +* arg-optional:: Option Argument Optional +* arg-default:: Default Option Argument Value + + +File: autogen.info, Node: arg-type string, Next: arg-type number, Up: Option Arguments + +7.5.6.1 Arg Type String +....................... + +'arg-type = string;' + + The argument may be any arbitrary string, though your program or +option callback procedure may place additional constraints upon it. + + +File: autogen.info, Node: arg-type number, Next: arg-type boolean, Prev: arg-type string, Up: Option Arguments + +7.5.6.2 Arg Type Number +....................... + +'arg-type = number;' + + The argument must be a correctly formed integer, without any trailing +U's or L's. AutoOpts contains a library procedure to convert the string +to a number. If you specify range checking with 'arg-range' (see +below), then AutoOpts produces a special purpose procedure for this +option. + +'scaled' + 'scaled' marks the option so that suffixes of 'k', 'K', 'm', 'M', + 'g', 'G', 't', and 'T' will multiply the given number by a power of + 1000 or 1024. Lower case letters scale by a power of 1000 and + upper case scale by a power of 1024. + +'arg-range' + 'arg-range' is used to create a callback procedure for validating + the range of the option argument. It must match one of the range + entries. Each 'arg-range' should consist of either an integer by + itself or an integer range. The integer range is specified by one + or two integers separated by the two character sequence, '->'. Be + sure to quote the entire range string. The definitions parser will + not accept the range syntax as a single string token. + + The generated procedure imposes the range constraints as follows: + * A number by itself will match that one value. + * The high end of the range may not be 'INT_MIN', both for + obvious reasons and because that value is used to indicate a + single-valued match. + * An omitted lower value implies a lower bound of INT_MIN. + * An omitted upper value implies a upper bound of INT_MAX. + * The argument value is required. It may not be optional. + * The value must match one of the entries. If it can match more + than one, then you have redundancies, but no harm will come of + it. + + +File: autogen.info, Node: arg-type boolean, Next: arg-type keyword, Prev: arg-type number, Up: Option Arguments + +7.5.6.3 Arg Type Boolean +........................ + +'arg-type = boolean;' + + The argument will be interpreted and always yield either AG_TRUE or +AG_FALSE. False values are the empty string, the number zero, or a +string that starts with 'f', 'F', 'n' or 'N' (representing False or No). +Anything else will be interpreted as True. + + +File: autogen.info, Node: arg-type keyword, Next: arg-type set membership, Prev: arg-type boolean, Up: Option Arguments + +7.5.6.4 Arg Type Keyword +........................ + +'arg-type = keyword;' + + The argument must match a specified list of strings (*note +arg-keyword::). Assuming you have named the option, 'optn-name', the +strings will be converted into an enumeration of type 'te_Optn_Name' +with the values 'OPTN_NAME_KEYWORD'.* If you have *not* specified a +default value, the value 'OPTN_NAME_UNDEFINED' will be inserted with the +value zero. The option will be initialized to that value. You may now +use this in your code as follows: + + te_Optn_Name opt = OPT_VALUE_OPTN_NAME; + switch (opt) { + case OPTN_NAME_UNDEFINED: /* undefined things */ break; + case OPTN_NAME_KEYWORD: /* `keyword' things */ break; + default: /* utterly impossible */ ; + } + + AutoOpts produces a special purpose procedure for this option. You +may not specify an alternate handling procedure. + + If you have need for the string name of the selected keyword, you may +obtain this with the macro, 'OPT_OPTN_NAME_VAL2STR(val)'. The value you +pass would normally be 'OPT_VALUE_OPTN_NAME', but anything with numeric +value that is legal for 'te_Optn_Name' may be passed. Anything out of +range will result in the string, '"*INVALID*"' being returned. The +strings are read only. It may be used as in: + + te_Optn_Name opt = OPT_VALUE_OPTN_NAME; + printf( "you selected the %s keyword\n", + OPT_OPTN_NAME_VAL2STR(opt) ); + + * Note: you may replace the 'OPTN_NAME' enumeration prefix with +another prefix by specifying a 'prefix-enum' attribute. + + Finally, users may specify the argument either by name or by number. +Since the numeric equivalents change by having new entries inserted into +the keyword list, this would not be a recommended practice. However, +either '-1' or '~0' will always be equivalent to specifying the last +keyword. + + +File: autogen.info, Node: arg-type set membership, Next: arg-type hierarchy, Prev: arg-type keyword, Up: Option Arguments + +7.5.6.5 Arg Type Set Membership +............................... + +'arg-type = set;' + + The argument must be a list of names each of which must match the +strings "'all'", "'none'" or one of the keywords (*note arg-keyword::) +specified for this option. 'all' will turn on all membership bits and +'none' will turn them all off. Specifying one of the keywords will set +the corresponding set membership bit on (or off, if negated) . Literal +numbers may also be used and may, thereby, set or clear more than one +bit. + + The membership result starts with the previous (or initialized) +result. To clear previous results, either start the membership string +with 'none +' or with the equals character ('='). To invert (bit flip) +the final result (regardless of whether the previous result is carried +over or not), start the string with a carat character ('^'). If you +wish to invert the result and start without a carried over value, use +one of the following: '=^' or '^none+'. These are equivalent. + + The list of names or numbers must be separated by one of the +following characters: '+-|!,' or whitespace. The comma is equivalent to +whitespace, except that only one may appear between two entries and it +may not appear in conjunction with the OR bar ('|'). The '+|' leading +characters or unadorned name signify adding the next named bit to the +mask, and the '-!' leading characters indicate removing it. + + The number of keywords allowed is constrained by the number of bits +in a pointer, as the bit set is kept in a 'void *' pointer. + + If, for example, you specified 'first' in your list of keywords, then +you can use the following code to test to see if either 'first' or 'all' +was specified: + + uintptr_t opt = OPT_VALUE_OPTN_NAME; + if (opt & OPTN_NAME_FIRST) + /* OPTN_NAME_FIRST bit was set */ ; + + AutoOpts produces a special purpose procedure for this option. To +set multiple bits as the default (initial) value, you must specify an +initial numeric value (which might become inaccurate over time), or else +specify 'arg-default' multiple times. Do not specify a series of names +conjoined with '+' symbols as the value for any of the 'arg-default' +attributes. That works for option parsing, but not for the option code +generation. + + +File: autogen.info, Node: arg-type hierarchy, Next: arg-type file name, Prev: arg-type set membership, Up: Option Arguments + +7.5.6.6 Arg Type Hierarchical +............................. + +'arg-type = hierarchy;' +'arg-type = nested;' + + This denotes an option with a structure-valued argument, a.k.a. +'subopts' in 'getopts' terminology. The argument is parsed and the +values made available to the program via the find and find next calls +(*Note libopts-optionFindValue::, *Note libopts-optionGetValue::, and +*note libopts-optionFindNextValue::). + + tOptionValue * val = optionGetValue(VALUE_OPT_OPTN_NAME, "name"); + while (val != NULL) { + process(val); + val = optionNextValue(VALUE_OPT_OPTN_NAME, val); + if (wrong_name(val, "name")) + break; + } + + +File: autogen.info, Node: arg-type file name, Next: arg-type time-duration, Prev: arg-type hierarchy, Up: Option Arguments + +7.5.6.7 Arg Type File Name +.......................... + +'arg-type = file;' + + This argument type will have some validations on the argument and, +optionally, actually open the file. You must specify several additonal +attributes for the option: + +'file-exists' + If not specified or empty, then the directory portion of the name + is checked. The directory must exist or the argument is rejected + and the usage procedure is invoked. + + Otherwise, both the directory as above and the full name is tested + for existence. If the value begins with the two letters 'no', then + the file must not pre-exist. Otherwise, the file is expected to + exist. + +'open-file' + If not specified or empty, the file is left alone. If the value + begins with the four letters 'desc'[riptor], then 'open(2)' is used + and 'optArg.argFd' is set. Otherwise, the file is opened with + 'fopen' and 'optArg.argFp' is set. + +'file-mode' + If 'open-file' is set and not empty, then you must specify the open + mode. Set the value to the flag bits or mode string as appropriate + for the open type. + + +File: autogen.info, Node: arg-type time-duration, Next: arg-type time-date, Prev: arg-type file name, Up: Option Arguments + +7.5.6.8 Arg Type Time Duration +.............................. + +'arg-type = time-duration;' + + The argument will be converted into a number of seconds. It may be a +multi-part number with different parts being multiplied into a seconds +value and added into the final result. Valid forms are in the table +below. Upper cased letters represent numbers that must be used in the +expressions. + +'[[HH:]MM:]SS' + 'HH' is multiplied by '3600' and 'MM' multiplied by '60' before + they are added to 'SS'. This time specification may not be + followed by any other time specs. 'HH' and 'MM' are both optional, + though 'HH' cannot be specified without 'MM'. + +'DAYS d' + 'DAYS' is multiplied by the number of seconds in a day. This value + may be followed by (and added to) values specified by 'HH:MM:SS' or + the suffixed values below. If present, it must always be first. + +'HRS h' + 'HRS' is multiplied by the number of seconds in an hour. This + value may be followed by (and added to) values specified by 'MM:SS' + or the suffixed values below. + +'MINS m' + 'MINS' is multiplied by the number of seconds in a minute. This + value may be followed by (and added to) a count of seconds. + +'SECS s' + This value can only be the last value in a time specification. The + 's' suffix is optional. + + 5 d 1:10:05 ==> 5 days + 1 hour 10 minutes and 5 seconds + 5 d 1 h 10 m 5 ==> yields: 436205 seconds + 5d1h10m5s ==> same result -- spaces are optional. + + When saved into a config file, the value will be stored as a simple +count of seconds. There are actually more (many) accepted time duration +strings. The full documentation can be found with ISO-8601 +documentation and the more extedded documentation when +'parse_duration()' becomes more widely available. + + +File: autogen.info, Node: arg-type time-date, Next: arg-keyword, Prev: arg-type time-duration, Up: Option Arguments + +7.5.6.9 Arg Type Time and Date +.............................. + +'arg-type = time-date;' + + The argument will be converted into the number of seconds since the +epoch. The conversion rules are very complicated, please see the +'getdate_r(3GNU)' man page. There are some additional restrictions: + + 1. Your project must be compiled with 'PKGDATADIR' defined and naming + a valid directory. + 2. The 'DATEMSK' environment variable will be set to the 'datemsk' + file within that directory. + + If that file is not accessible for any reason, the string will be +parsed as a time duration (*note arg-type time-duration::) instead of a +specific date and time. + + +File: autogen.info, Node: arg-keyword, Next: arg-optional, Prev: arg-type time-date, Up: Option Arguments + +7.5.6.10 Keyword list +..................... + +If the 'arg-type' is 'keyword' (*note arg-type keyword::) or +'set-membership' (*note arg-type set membership::), then you must +specify the list of keywords by a series of 'keyword' entries. The +interface file will contain values for '<OPTN_NAME>_<KEYWORD>' for each +keyword entry. 'keyword' option types will have an enumeration and +'set-membership' option types will have a set of unsigned bits +'#define'-d. + + If the 'arg-type' is specifically 'keyword', you may also add special +handling code with a 'extra-code' attribute. After +'optionEnumerationVal' has converted the input string into an +enumeration, you may insert code to process this enumeration value +('pOptDesc->optArg.argEnum'). + + +File: autogen.info, Node: arg-optional, Next: arg-default, Prev: arg-keyword, Up: Option Arguments + +7.5.6.11 Option Argument Optional +................................. + +The 'arg-optional' attribute indicates that the argument to the option +is optional (need not be specified on the command line). This is only +valid if the ARG-TYPE is 'string' (*note arg-type string::) or 'keyword' +(*note arg-type keyword::). If it is 'keyword', then this attribute may +also specify the default keyword to assume when the argument is not +supplied. If left empty, ARG-DEFAULT (*note arg-default::) or the +zero-valued keyword will be used. + + The syntax rules for identifying the option argument are: + * If the option is specified with a flag character and there is a + character following the flag character, then string following that + flag character is the option argument. + * If the flag character is the last character in an argument, then + the first character of the next argument is examined. If it is a + hyphen, then the option is presumed to not have an argument. + Otherwise, the entire next argument is the argument for the option. + * If the option is specified with a long option name and that name is + ended with an equal sign character ('='), then everything after + that character is the option argument. + * If the long name is ended by the end of the argument, then the + first character of the next argument is examined, just as with the + flag character ending an argument string. + + This is overridden and the options are required if the libopts +library gets configured with '--disable-optional-args'. + + +File: autogen.info, Node: arg-default, Prev: arg-optional, Up: Option Arguments + +7.5.6.12 Default Option Argument Value +...................................... + +This specifies the default option argument value to be used when the +option is not specified or preset. You may specify multiple +'arg-default' values if the argument type is 'set membership'. + + +File: autogen.info, Node: Option Argument Handling, Next: Internationalizing Options, Prev: Option Arguments, Up: Option Definitions + +7.5.7 Option Argument Handling +------------------------------ + +AutoOpts will either specify or automatically generate callback +procedures for options that take specialized arguments. The only option +argument types that are not specialized are plain string arguments and +no argument at all. For options that fall into one of those two +categories, you may specify your own callback function, as specified +below. If you do this and if you specify that options are resettable +(*note automatic options::), then your option handling code *must* look +for the 'OPTST_RESET' bit in the 'fOptState' field of the option +descriptor. + + If the option takes a string argument, then the 'stack-arg' attribute +can be used to specify that the option is to be handled by the 'libopts' +'stackOptArg()' and 'unstackOptArg()' library procedures (see below). +In this case, you may not provide option handling code. + + Finally, 'documentation' options (*note opt-attr documentation::) may +also be marked as 'settable' (*note opt-attr settable::) and have +special callback functions (either 'flag-code', 'extract-code', or +'call-proc'). + +'flag-code' + statements to execute when the option is encountered. This may be + used in conjunction with option argument types that cause AutoOpts + to emit handler code. If you do this, the 'flag-code' with index + zero (0) is emitted into the handler code _before_ the argument is + handled, and the entry with index one (1) is handled afterward. + + The generated procedure will be laid out something like this: + + static void + doOpt<name>(tOptions* pOptions, tOptDesc* pOptDesc) + { + <flag-code[0]> + <AutoOpts defined handler code> + <flag-code[1]> + } + + Only certain fields within the 'tOptions' and 'tOptDesc' structures + may be accessed. *Note Option Processing Data::. When writing + this code, you must be very careful with the 'pOptions' pointer. + The handler code is called with this pointer set to special values + for handling special situations. Your code must handle them. As + an example, look at 'optionEnumerationVal' in 'enum.c'. + +'extract-code' + This is effectively identical to 'flag-code', except that the + source is kept in the output file instead of the definitions file + and you cannot use this in conjunction with options with arguments, + other than string arguments. + + A long comment is used to demarcate the code. You must not modify + that marker. Before regenerating the option code file, the old + file is renamed from MUMBLE.c to MUMBLE.c.save. The template will + be looking there for the text to copy into the new output file. + +'call-proc' + external procedure to call when option is encountered. The calling + sequence must conform to the sequence defined above for the + generated procedure, 'doOpt<name>'. It has the same restrictions + regarding the fields within the structures passed in as arguments. + *Note Option Processing Data::. + +'flag-proc' + Name of another option whose 'flag-code' can be executed when this + option is encountered. + +'stack-arg' + Call a special library routine to stack the option's arguments. + Special macros in the interface file are provided for determining + how many of the options were found ('STACKCT_OPT(NAME)') and to + obtain a pointer to a list of pointers to the argument values + ('STACKLST_OPT(NAME)'). Obviously, for a stackable argument, the + 'max' attribute (*note Common Attributes::) needs to be set higher + than '1'. + + If this stacked argument option has a disablement prefix, then the + entire stack of arguments will be cleared by specifying the option + with that disablement prefix. + +'unstack-arg' + Call a special library routine to remove ('unstack') strings from a + 'stack-arg' option stack. This attribute must name the option that + is to be 'unstacked'. Neither this option nor the stacked argument + option it references may be equivalenced to another option. + + +File: autogen.info, Node: Internationalizing Options, Next: documentation attributes, Prev: Option Argument Handling, Up: Option Definitions + +7.5.8 Internationalizing Options +-------------------------------- + +Normally, AutoOpts produces usage text that is difficult to translate. +It is pieced together on the fly using words and phrases scattered +around here and there, piecing together toe document. This does not +translate well. + + Incorporated into this package are some ways around the problem. +First, you should specify the 'full-usage' and 'short-usage' program +attributes (*note program attributes::). This will enable your +translators to translate the usage text as a whole. + + Your translators will also be able to translate long option names. +The option name translations will then become the names searched for +both on the command line and in configuration files. However, it will +not affect the names of environment variable names used to configure +your program. + + If it is considered desireable to keep configuration files in the 'C' +locale, then several macros are available to suppress or delay the +translations of option names at run time. These are all disabled if +'ENABLE_NLS' is not defined at compile time or if 'no-xlate' has been +set to the value _anything_. These macros *must* be invoked before the +first invocation of 'optionProcess'. + +'OPT_NO_XLAT_CFG_NAMES;' +'OPT_XLAT_CFG_NAMES;' + Disable (or enable) the translations of option names for + configuration files. If you enable translation for config files, + then they will be translated for command line options. + +'OPT_NO_XLAT_OPT_NAMES;' +'OPT_XLAT_OPT_NAMES;' + Disable (or enable) the translations of option names for command + line processing. If you disable the translation for command line + processing, you will also disable it for configuration file + processing. Once translated, the option names will remain + translated. + + +File: autogen.info, Node: documentation attributes, Next: automatic options, Prev: Internationalizing Options, Up: Option Definitions + +7.5.9 Man and Info doc Attributes +--------------------------------- + +AutoOpts includes AutoGen templates for producing abbreviated man pages +and for producing the invoking section of an info document. To take +advantage of these templates, you must add several attributes to your +option definitions. + +* Menu: + +* per option attributes:: Per option documentation attributes +* global option attributes:: Global documentation attributes + + +File: autogen.info, Node: per option attributes, Next: global option attributes, Up: documentation attributes + +7.5.9.1 Per option documentation attributes +........................................... + +These attributes are sub-attributes (sub-stanzas) of the 'flag' stanzas. + +'arg-name' + If an option has an argument, the argument should have a name for + documentation purposes. It will default to 'arg-type', but it will + likely be clearer with something else like, 'file-name' instead of + 'string' (the type). + +'doc' + First, every 'flag' definition _other than_ 'documentation' + definitions, must have a 'doc' attribute defined. If the option + takes an argument, then it will need an 'arg-name' attribute as + well. The 'doc' text should be in plain sentences with minimal + formatting. The Texinfo commands '@code', and '@var' will have its + enclosed text made into *\fB* entries in the man page, and the + '@file' text will be made into *\fI* entries. The 'arg-name' + attribute is used to display the option's argument in the man page. + + Options marked with the 'documentation' attribute are for + documenting the usage text. All other options should have the + 'doc' attribute in order to document the usage of the option in the + generated man pages. + + Since these blocks of text are inserted into all output forms, any + markup text included in these blocks must be massaged for each + output format. By default, it is presumed to be 'texi' format. + + +File: autogen.info, Node: global option attributes, Prev: per option attributes, Up: documentation attributes + +7.5.9.2 Global documentation attributes +....................................... + +'cmd-section' + If your command is a game or a system management command, specify + this attribute with the value '5' or '8', respectively. The + default is a user command (section 1). + +'detail' + This attribute is used to add a very short explanation about what a + program is used for when the 'title' attribute is insufficient. If + there is no 'doc-section' stanza of type 'DESCRIPTION', then this + text is used for the man page DESCRIPTION section, too. + +'addtogroup' + This attribute tells the template that the generated code should be + surrounded with the following doxygen comments: + /** @file <header-or-code-file-name> + * @addtogroup <value-of-addtogroup> + * @{ + */ + and + /** @} */ + +'option-format' + Specify the default markup style for the 'doc' stanzas. By + default, it is 'texi', but 'man' and 'mdoc' may also be selected. + There are nine converter programs that do a partial job of + converting one form of markup into another. 'texi2texi', 'man2man' + and 'mdoc2mdoc' work pretty well. + + You may also post process the document by using 'doc-sub' stanzas, + see below. + +'option-info' + This text will be inserted as a lead-in paragraph in the 'OPTIONS' + section of the generated man page. + +'doc-section' + This is a compound attribute that requires three subattributes: + + ds-format + This describes the format of the associated 'ds-text' section. + 'man', 'mdoc' and 'texi' formats are supported. Regardless of + the chosen format, the formatting tags in the output text will + be converted to 'man' macros for 'man' pages, 'mdoc' macros + for 'mdoc' pages, and 'texi' macros for 'texinfo' pages. + + ds-text + This is the descriptive text, written according to the rules + for 'ds-format' documents. + + ds-type + This describes the section type. Basically, the title of the + section that will be added to all output documentation. There + may be only one 'doc-section' for any given 'ds-type'. If + there are duplicates, the results are undefined (it might + work, it might not). + + There are five categories of 'ds-type' sections. They are + those that the documentation templates would otherwise: + 1. always create itself, ignoring any 'ds-type's by this + name. These are marked, below, as 'ao-only'. + 2. create, if none was provided. These are marked, + 'alternate'. + 3. create, but augment if the 'doc-section' was provided. + These are marked, 'augments'. + 4. do nothing, but inserts them into the output in a + prescribed order. These are marked, 'known' + 5. knows nothing about them. They will be alphabetized and + inserted after the list of leading sections and before + the list of trailing sections. These are not marked + because I don't know their names. + + Some of these are emitted by the documentation templates only + if certain conditions are met. If there are conditions, they + are explained below. If there are no conditions, then you + will always see the named section in the output. + + The output sections will appear in this order: + 'NAME' + 'ao-only'. + 'SYNOPSIS' + 'alternate'. + 'DESCRIPTION' + 'augments'. + 'OPTIONS' + 'ao-only'. + 'OPTION PRESETS' + 'ao-only', if environment presets or configuration file + processing has been specified. + 'unknown' + At this point, the unknown, alphabetized sections are + inserted. + 'IMPLEMENTATION NOTES' + 'known' + 'ENVIRONMENT' + 'augments', if environment presets have been specified. + 'FILES' + 'augments', if configuration file processing has been + specified. + 'EXAMPLES' + 'known' + 'EXIT STATUS' + 'augments'. + 'ERRORS' + 'known' + 'COMPATIBILITY' + 'known' + 'SEE ALSO' + 'known' + 'CONFORMING TO' + 'known' + 'HISTORY' + 'known' + 'AUTHORS' + 'alternate', if the 'copyright' stanza has either an + 'author' or an 'owner' attribute. + 'COPYRIGHT' + 'alternate', if there is a 'copyright' stanza. + 'BUGS' + 'augments', if the 'copyright' stanza has an 'eaddr' + attribute. + 'NOTES' + 'augments'. + + Here is an example of a 'doc-section' for a 'SEE ALSO' type. + + doc-section = { + ds-type = 'SEE ALSO'; // or anything else + ds-format = 'man'; // or texi or mdoc format + ds-text = <<-_EOText_ + text relevant to this section type, + in the chosen format + _EOText_; + }; + +'doc-sub' + This attribute will cause the resulting documentation to be + post-processed. This is normally with 'sed', see 'doc-sub-cmd' + below. This attribute has several sub-attributes: + + 'sub-name' + This is the name of an autogen text definition value, like + 'prog-name' or 'version'. In the 'sub-text' field, + occurrences of this name preceded by two less than characters + and followed by two greater than characters will be replaced + by the text value of the definition, e.g. '<<prog-name>>'. + + 'sub-text' + The text that gets added to the command file for the post + processing program. + + 'sub-type' + If this command only applies to certain types of output, + specify this with a regular expression that will match one of + the valid output format types, e.g. 'man|mdoc' will match + those two kinds, but not 'texi' output. If omitted, it will + always apply. + + For example, if you want to reference the program name in the 'doc' + text for an option common to two programs, put '#PROG#' into the + text. The following will replace all occrrences of '#PROG#' with + the current value for 'prog': + doc-sub = { + sub-name = prog-name; + sub-text = 's/#PROG#/<<prog-name>>/g'; + }; + +'doc-sub-cmd' + A formatting string for constructing the post-processing command. + The first parameter is the name of the file with editing commands + in it, and the second is the file containing the unprocessed + document. The default value is: + sed -f %s %s + + +File: autogen.info, Node: automatic options, Next: standard options, Prev: documentation attributes, Up: Option Definitions + +7.5.10 Automatically Supported Options +-------------------------------------- + +AutoOpts provides automated support for several options. 'help' and +'more-help' are always provided. The others are conditional upon +various global program attributes being defined *Note program +attributes::. + + Below are the option names and default flag values. The flags are +activated if and only if at least one user-defined option also uses a +flag value. The long names are supported as option names if 'long-opts' +has been specified. These option flags may be deleted or changed to +characters of your choosing by specifying 'xxx-value = "y";', where +'xxx' is one of the option names below and 'y' is either empty or the +character of your choice. For example, to change the help flag from '?' +to 'h', specify 'help-value = "h";'; and to require that 'save-opts' be +specified only with its long option name, specify 'save-opts-value = +"";'. + + Additionally, the procedure that prints out the program version may +be replaced by specifying 'version-proc'. This procedure must be +defined to be of external scope (non-static). By default, the AutoOpts +library provides 'optionPrintVersion' and it will be the specified +callback function in the option definition structure. + + With the exception of the 'load-opts' option, none of these +automatically supported options will be recognized in configuration +files or environment variables. + +'help -?' + This option will immediately invoke the 'USAGE()' procedure and + display the usage line, a description of each option with its + description and option usage information. This is followed by the + contents of the definition of the 'detail' text macro. + +'more-help -!' + This option is identical to the 'help' option, except that the + output is passed through a pager program. ('more' by default, or + the program identified by the 'PAGER' environment variable.) + +'usage -u' + This option must be requested by specifying, 'usage-opt' in the + option definition file. It will produce abbreviated help text to + 'stdout' and exit with zero status ('EXIT_SUCCESS'). + +'version -v' + + This will print the program name, title and version. If it is not + followed by anything or is followed by the letter 'v', just the + program name and version will be printed. If followed by the + letter 'c' and a value for 'copyright' and 'owner' have been + provided, then the copyright will be printed, too. If it is + followed by the letter 'n', then the full copyright notice (if + available) will be printed. The 'version' attribute must be + specified in the option definition file. + + Because some target platforms discourage optional arguments to + options, the autoopts library can be compiled with + 'NO_OPTIONAL_OPT_ARGS' defined. Alternatively, the 'version-type' + attribute can be added to the option definitions and it can specify + which flavor is preferred. In either case, an argument to the + '--version' option will then be disallowed. + +'load-opts -<' + This option will load options from the named file. They will be + treated exactly as if they were loaded from the normally found + configuration files, but will not be loaded until the option is + actually processed. This can also be used within another + configuration file, causing them to nest. This is the *only* + automatically supported option that can be activated inside of + config files or with environment variables. + + Specifying the negated form of the option ('--no-load-opts') will + suppress the processing of configuration files and environment + variables. + + This option is activated by specifying one or more 'homerc' + attributes. + +'save-opts ->' + This option will cause the option state to be printed in the + configuration file format when option processing is done but not + yet verified for consistency. The program will terminate + successfully without running when this has completed. Note that + for most shells you will have to quote or escape the flag character + to restrict special meanings to the shell. + + The output file will be the configuration file name (default or + provided by 'rcfile') in the last directory named in a 'homerc' + definition. + + This option may be set from within your program by invoking the + "'SET_OPT_SAVE_OPTS(filename)'" macro (*note SET_OPT_name::). + Invoking this macro will set the file name for saving the option + processing state, but the state will *not* actually be saved. You + must call 'optionSaveFile' to do that (*note + libopts-optionSaveFile::). *CAVEAT:* if, after invoking this + macro, you call 'optionProcess', the option processing state will + be saved to this file and 'optionProcess' will not return. You may + wish to invoke 'CLEAR_OPT( SAVE_OPTS )' (*note CLEAR_OPT::) + beforehand if you do need to reinvoke 'optionProcess'. + + This option is activated by specifying one or more 'homerc' + attributes. + + The method of saving the state may be altered by specifying flags + before the output file name. "Flags" are specified by placing a + list of them before the file name and separating them from the name + with one or two greater-than characters (">"). There are three + flags currently supported: + + 'default' + If an option has a default value (has not been set), then the + default value is inserted as a comment. + + 'usage' + Every option that can be processed from the configuration file + will have a comment that contains the usage string that gets + printed with the '--help' text + + 'update' + Instead of removing the old file and writing a new one, the + output file is kept, but any pre-existing segment labeled with + '<?program prog-name>' is removed. The new program segment is + placed at the end of the file. This flag is implied if the + flags are separated from the file name with doubled + greater-than characters. In other words, 'update,usage > + file-name' and 'usage >> file-name' are identical. + +'reset-option -R' + This option takes the name of an option for the current program and + resets its state such that it is set back to its original, + compile-time initialized value. If the option state is + subsequently stored (via '--save-opts'), the named option will not + appear in that file. + + This option is activated by specifying the 'resettable' attribute. + + *BEWARE*: If the 'resettable' attribute is specified, all option + callbacks *must* look for the 'OPTST_RESET' bit in the 'fOptState' + field of the option descriptor. If set, the 'optCookie' and + 'optArg' fields will be unchanged from their last setting. When + the callback returns, these fields will be set to their original + values. If you use this feature and you have allocated data + hanging off of the cookie, you need to deallocate it. + + +File: autogen.info, Node: standard options, Prev: automatic options, Up: Option Definitions + +7.5.11 Library of Standard Options +---------------------------------- + +AutoOpts has developed a set of standardized options. You may +incorporate these options in your program simply by _first_ adding a +'#define' for the options you want, and then the line, + + #include stdoptions.def + +in your option definitions. The supported options are specified thus: + + #define DEBUG + #define DIRECTORY + #define DRY_RUN + #define INPUT + #define INTERACTIVE + #define OUTPUT + #define WARN + + #define SILENT + #define QUIET + #define BRIEF + #define VERBOSE + + By default, only the long form of the option will be available. To +specify the short (flag) form, suffix these names with '_FLAG'. e.g., + + #define DEBUG_FLAG + + '--silent', '--quiet', '--brief' and '--verbose' are related in that +they all indicate some level of diagnostic output. These options are +all designed to conflict with each other. Instead of four different +options, however, several levels can be incorporated by '#define'-ing +'VERBOSE_ENUM'. In conjunction with 'VERBOSE', it incorporates the +notion of 5 levels in an enumeration: 'silent', 'quiet', 'brief', +'informative' and 'verbose'; with the default being 'brief'. + + Here is an example program that uses the following set of +definitions: + + AutoGen Definitions options; + + prog-name = default-test; + prog-title = 'Default Option Example'; + homerc = '$$/../share/default-test', '$HOME', '.'; + environrc; + long-opts; + gnu-usage; + usage-opt; + version = '1.0'; + main = { + main-type = shell-process; + }; + #define DEBUG_FLAG + #define WARN_FLAG + #define WARN_LEVEL + #define VERBOSE_FLAG + #define VERBOSE_ENUM + #define DRY_RUN_FLAG + #define OUTPUT_FLAG + #define INPUT_FLAG + #define DIRECTORY_FLAG + #define INTERACTIVE_FLAG + #include stdoptions.def + +Running a few simple commands on that definition file: + + autogen default-test.def + copts="-DTEST_DEFAULT_TEST_OPTS `autoopts-config cflags`" + lopts="`autoopts-config ldflags`" + cc -o default-test ${copts} default-test.c ${lopts} + +Yields a program which, when run with '--help', prints out: + + + exit 0 + + +File: autogen.info, Node: AutoOpts API, Next: Multi-Threading, Prev: Option Definitions, Up: AutoOpts + +7.6 Programmatic Interface +========================== + +The user interface for access to the argument information is completely +defined in the generated header file and in the portions of the +distributed file "options.h" that are marked "public". + + In the following macros, text marked <NAME> or NAME is the name of +the option *in upper case* and *segmented with underscores '_'*. The +macros and enumerations defined in the options header (interface) file +are used as follows: + + To see how these '#define' macros are used in a program, the reader +is referred to the several 'opts.h' files included with the AutoGen +sources. + +* Menu: + +* Option Processing Data:: Data for Option Processing +* CLEAR_OPT:: CLEAR_OPT( <NAME> ) - Clear Option Markings +* COUNT_OPT:: COUNT_OPT( <NAME> ) - Definition Count +* DESC:: DESC( <NAME> ) - Option Descriptor +* DISABLE_OPT_name:: DISABLE_OPT_name - Disable an option +* ENABLED_OPT:: ENABLED_OPT( <NAME> ) - Is Option Enabled? +* ERRSKIP_OPTERR:: ERRSKIP_OPTERR - Ignore Option Errors +* ERRSTOP_OPTERR:: ERRSTOP_OPTERR - Stop on Errors +* HAVE_OPT:: HAVE_OPT( <NAME> ) - Have this option? +* ISSEL_OPT:: ISSEL_OPT( <NAME> ) - Is Option Selected? +* ISUNUSED_OPT:: ISUNUSED_OPT( <NAME> ) - Never Specified? +* OPTION_CT:: OPTION_CT - Full Count of Options +* OPT_ARG:: OPT_ARG( <NAME> ) - Option Argument String +* OPT_NO_XLAT_CFG_NAMES:: OPT_NO_XLAT_CFG_NAMES - option name xlation +* OPT_NO_XLAT_OPT_NAMES:: OPT_NO_XLAT_OPT_NAMES - option name xlation +* OPT_VALUE_name:: OPT_VALUE_name - Option Argument Value +* OPT_XLAT_CFG_NAMES:: OPT_XLAT_CFG_NAMES - option name xlation +* OPT_XLAT_OPT_NAMES:: OPT_XLAT_OPT_NAMES - option name xlation +* RESTART_OPT:: RESTART_OPT( n ) - Resume Option Processing +* SET_OPT_name:: SET_OPT_name - Force an option to be set +* STACKCT_OPT:: STACKCT_OPT( <NAME> ) - Stacked Arg Count +* STACKLST_OPT:: STACKLST_OPT( <NAME> ) - Argument Stack +* START_OPT:: START_OPT - Restart Option Processing +* STATE_OPT:: STATE_OPT( <NAME> ) - Option State +* USAGE:: USAGE( exit-code ) - Usage invocation macro +* VALUE_OPT_name:: VALUE_OPT_name - Option Flag Value +* VERSION:: VERSION - Version and Full Version +* WHICH_IDX_name:: WHICH_IDX_name - Which Equivalenced Index +* WHICH_OPT_name:: WHICH_OPT_name - Which Equivalenced Option +* teOptIndex:: teOptIndex - Option Index and Enumeration +* OPTIONS_STRUCT_VERSION:: OPTIONS_STRUCT_VERSION - active version +* libopts procedures:: libopts External Procedures + + +File: autogen.info, Node: Option Processing Data, Next: CLEAR_OPT, Up: AutoOpts API + +7.6.1 Data for Option Processing +-------------------------------- + +This section describes the data that may be accessed from within the +option processing callback routines. The following fields may be used +in the following ways and may be used for read only. The first set is +addressed from the 'tOptDesc*' pointer: + +'optIndex' +'optValue' + These may be used by option procedures to determine which option + they are working on (in case they handle several options). + +'optActualIndex' +'optActualValue' + These may be used by option procedures to determine which option + was used to set the current option. This may be different from the + above if the options are members of an equivalence class. + +'optOccCt' + If AutoOpts is processing command line arguments, then this value + will contain the current occurrence count. During the option + preset phase (reading configuration files and examining environment + variables), the value is zero. + +'fOptState' + The field may be tested for the following bit values (prefix each + name with 'OPTST_', e.g. 'OPTST_INIT'): + + 'INIT' + Initial compiled value. As a bit test, it will always yield + FALSE. + + 'SET' + The option was set via the 'SET_OPT()' macro. + + 'PRESET' + The option was set via a configuration file. + + 'DEFINED' + The option was set via a command line option. + + 'SET_MASK' + This is a mask of flags that show the set state, one of the + above four values. + + 'EQUIVALENCE' + This bit is set when the option was selected by an + equivalenced option. + + 'DISABLED' + This bit is set if the option is to be disabled. (Meaning it + was a long option prefixed by the disablement prefix, or the + option has not been specified yet and initializes as + 'disabled'.) + + As an example of how this might be used, in AutoGen I want to allow + template writers to specify that the template output can be left in + a writable or read-only state. To support this, there is a Guile + function named 'set-writable' (*note SCM set-writable::). Also, I + provide for command options '--writable' and '--not-writable'. I + give precedence to command line and RC file options, thus: + + switch (STATE_OPT( WRITABLE )) { + case OPTST_DEFINED: + case OPTST_PRESET: + fprintf(stderr, zOverrideWarn, pCurTemplate->pzFileName, + pCurMacro->lineNo); + break; + + default: + if (gh_boolean_p( set ) && (set == SCM_BOOL_F)) + CLEAR_OPT( WRITABLE ); + else + SET_OPT_WRITABLE; + } + +'pzLastArg' + Pointer to the latest argument string. BEWARE If the argument type + is numeric, an enumeration or a bit mask, then this will be the + argument *value* and not a pointer to a string. + + The following two fields are addressed from the 'tOptions*' pointer: + +'pzProgName' + Points to a NUL-terminated string containing the current program + name, as retrieved from the argument vector. + +'pzProgPath' + Points to a NUL-terminated string containing the full path of the + current program, as retrieved from the argument vector. (If + available on your system.) + + Note these fields get filled in during the first call to +'optionProcess()'. All other fields are private, for the exclusive use +of AutoOpts code and are subject to change. + + +File: autogen.info, Node: CLEAR_OPT, Next: COUNT_OPT, Prev: Option Processing Data, Up: AutoOpts API + +7.6.2 CLEAR_OPT( <NAME> ) - Clear Option Markings +------------------------------------------------- + +Make as if the option had never been specified. 'HAVE_OPT(<NAME>)' will +yield 'FALSE' after invoking this macro. + + +File: autogen.info, Node: COUNT_OPT, Next: DESC, Prev: CLEAR_OPT, Up: AutoOpts API + +7.6.3 COUNT_OPT( <NAME> ) - Definition Count +-------------------------------------------- + +This macro will tell you how many times the option was specified on the +command line. It does not include counts of preset options. + + if (COUNT_OPT( NAME ) != desired-count) { + make-an-undesirable-message. + } + + +File: autogen.info, Node: DESC, Next: DISABLE_OPT_name, Prev: COUNT_OPT, Up: AutoOpts API + +7.6.4 DESC( <NAME> ) - Option Descriptor +---------------------------------------- + +This macro is used internally by other AutoOpt macros. It is not for +general use. It is used to obtain the option description corresponding +to its *UPPER CASED* option name argument. This is primarily used in +other macro definitions. + + +File: autogen.info, Node: DISABLE_OPT_name, Next: ENABLED_OPT, Prev: DESC, Up: AutoOpts API + +7.6.5 DISABLE_OPT_name - Disable an option +------------------------------------------ + +This macro is emitted if it is both settable and it can be disabled. If +it cannot be disabled, it may always be CLEAR-ed (see above). + + The form of the macro will actually depend on whether the option is +equivalenced to another, and/or has an assigned handler procedure. +Unlike the 'SET_OPT' macro, this macro does not allow an option +argument. + + DISABLE_OPT_NAME; + + +File: autogen.info, Node: ENABLED_OPT, Next: ERRSKIP_OPTERR, Prev: DISABLE_OPT_name, Up: AutoOpts API + +7.6.6 ENABLED_OPT( <NAME> ) - Is Option Enabled? +------------------------------------------------ + +Yields true if the option defaults to disabled and 'ISUNUSED_OPT()' +would yield true. It also yields true if the option has been specified +with a disablement prefix, disablement value or the 'DISABLE_OPT_NAME' +macro was invoked. + + +File: autogen.info, Node: ERRSKIP_OPTERR, Next: ERRSTOP_OPTERR, Prev: ENABLED_OPT, Up: AutoOpts API + +7.6.7 ERRSKIP_OPTERR - Ignore Option Errors +------------------------------------------- + +When it is necessary to continue (return to caller) on option errors, +invoke this option. It is reversible. *Note ERRSTOP_OPTERR::. + + +File: autogen.info, Node: ERRSTOP_OPTERR, Next: HAVE_OPT, Prev: ERRSKIP_OPTERR, Up: AutoOpts API + +7.6.8 ERRSTOP_OPTERR - Stop on Errors +------------------------------------- + +After invoking this macro, if 'optionProcess()' encounters an error, it +will call 'exit(1)' rather than return. This is the default processing +mode. It can be overridden by specifying 'allow-errors' in the +definitions file, or invoking the macro *Note ERRSKIP_OPTERR::. + + +File: autogen.info, Node: HAVE_OPT, Next: ISSEL_OPT, Prev: ERRSTOP_OPTERR, Up: AutoOpts API + +7.6.9 HAVE_OPT( <NAME> ) - Have this option? +-------------------------------------------- + +This macro yields true if the option has been specified in any fashion +at all. It is used thus: + + if (HAVE_OPT( NAME )) { + <do-things-associated-with-opt-name>; + } + + +File: autogen.info, Node: ISSEL_OPT, Next: ISUNUSED_OPT, Prev: HAVE_OPT, Up: AutoOpts API + +7.6.10 ISSEL_OPT( <NAME> ) - Is Option Selected? +------------------------------------------------ + +This macro yields true if the option has been specified either on the +command line or via a SET/DISABLE macro. + + +File: autogen.info, Node: ISUNUSED_OPT, Next: OPTION_CT, Prev: ISSEL_OPT, Up: AutoOpts API + +7.6.11 ISUNUSED_OPT( <NAME> ) - Never Specified? +------------------------------------------------ + +This macro yields true if the option has never been specified, or has +been cleared via the 'CLEAR_OPT()' macro. + + +File: autogen.info, Node: OPTION_CT, Next: OPT_ARG, Prev: ISUNUSED_OPT, Up: AutoOpts API + +7.6.12 OPTION_CT - Full Count of Options +---------------------------------------- + +The full count of all options, both those defined and those generated +automatically by AutoOpts. This is primarily used to initialize the +program option descriptor structure. + + +File: autogen.info, Node: OPT_ARG, Next: OPT_NO_XLAT_CFG_NAMES, Prev: OPTION_CT, Up: AutoOpts API + +7.6.13 OPT_ARG( <NAME> ) - Option Argument String +------------------------------------------------- + +The option argument value as a pointer to string. Note that argument +values that have been specified as numbers are stored as numbers or +keywords. For such options, use instead the 'OPT_VALUE_name' define. +It is used thus: + + if (HAVE_OPT( NAME )) { + char* p = OPT_ARG( NAME ); + <do-things-with-opt-name-argument-string>; + } + + +File: autogen.info, Node: OPT_NO_XLAT_CFG_NAMES, Next: OPT_NO_XLAT_OPT_NAMES, Prev: OPT_ARG, Up: AutoOpts API + +7.6.14 OPT_NO_XLAT_CFG_NAMES - option name xlation +-------------------------------------------------- + +Invoking this macro will disable the translation of option names only +while processing configuration files and environment variables. This +must be invoked before the first call to 'optionProcess'.. You need not +invoke this if your option definition file contains the attribute +assignment, 'no-xlate = opt-cfg;'. + + +File: autogen.info, Node: OPT_NO_XLAT_OPT_NAMES, Next: OPT_VALUE_name, Prev: OPT_NO_XLAT_CFG_NAMES, Up: AutoOpts API + +7.6.15 OPT_NO_XLAT_OPT_NAMES - option name xlation +-------------------------------------------------- + +Invoking this macro will completely disable the translation of option +names. This must be invoked before the first call to 'optionProcess'. +You need not invoke this if your option definition file contains the +attribute assignment, 'no-xlate = opt;'. + + +File: autogen.info, Node: OPT_VALUE_name, Next: OPT_XLAT_CFG_NAMES, Prev: OPT_NO_XLAT_OPT_NAMES, Up: AutoOpts API + +7.6.16 OPT_VALUE_name - Option Argument Value +--------------------------------------------- + +This macro gets emitted only for options that take numeric, keyword or +set membership arguments. The macro yields a word-sized integer +containing the enumeration, bit set or numeric value for the option +argument. + + int opt_val = OPT_VALUE_name; + + +File: autogen.info, Node: OPT_XLAT_CFG_NAMES, Next: OPT_XLAT_OPT_NAMES, Prev: OPT_VALUE_name, Up: AutoOpts API + +7.6.17 OPT_XLAT_CFG_NAMES - option name xlation +----------------------------------------------- + +If 'ENABLE_NLS' is defined and 'no-xlate' has been not set to the value +_anything_, this macro will cause the translation of option names to +happen before starting the processing of configuration files and +environment variables. This will change the recognition of options +within the '$PROGRAMNAME' environment variable, but will not alter the +names used for setting options via '$PROGRAMNAME_name' environment +variables. + + This must be invoked before the first call to 'optionProcess'. You +might need to use this macro if your option definition file contains the +attribute assignment, 'no-xlate = opt;' or 'no-xlate = opt-cfg;', and +you have determined in some way that you wish to override that. + + +File: autogen.info, Node: OPT_XLAT_OPT_NAMES, Next: RESTART_OPT, Prev: OPT_XLAT_CFG_NAMES, Up: AutoOpts API + +7.6.18 OPT_XLAT_OPT_NAMES - option name xlation +----------------------------------------------- + +If 'ENABLE_NLS' is defined and 'no-xlate' has been not set to the value +_anything_, translate the option names before processing the command +line options. Long option names may thus be localized. (If the names +were translated before configuration processing, they will not be +re-translated.) + + This must be invoked before the first call to 'optionProcess'. You +might need to use this macro if your option definition file contains the +attribute assignment, 'no-xlate = opt;' and you have determined in some +way that you wish to override that. + + +File: autogen.info, Node: RESTART_OPT, Next: SET_OPT_name, Prev: OPT_XLAT_OPT_NAMES, Up: AutoOpts API + +7.6.19 RESTART_OPT( n ) - Resume Option Processing +-------------------------------------------------- + +If option processing has stopped (either because of an error or +something was encountered that looked like a program argument), it can +be resumed by providing this macro with the index 'n' of the next option +to process and calling 'optionProcess()' again. + + int main(int argc, char ** argv) { + for (int ai = 0; ai < argc ;) { + restart: + ai = optionProcess(&progOptions, argc, argv); + for (; ai < argc; ai++) { + char * arg = arg[ai]; + if (*arg == '-') { + RESTART_OPT(ai); + goto restart; + } + process(arg); + } + } + } + + If you want a program to operate this way, you might consider +specifying a 'for-each' main function (*note for-each main procedure: +main for-each.) with the 'interleaved' attribute. It will allow you to +process interleaved operands and options from either the command line or +when reading them from standard input. + + +File: autogen.info, Node: SET_OPT_name, Next: STACKCT_OPT, Prev: RESTART_OPT, Up: AutoOpts API + +7.6.20 SET_OPT_name - Force an option to be set +----------------------------------------------- + +This macro gets emitted only when the given option has the 'settable' +attribute specified. + + The form of the macro will actually depend on whether the option is +equivalenced to another, has an option argument and/or has an assigned +handler procedure. If the option has an argument, then this macro will +too. Beware that the argument is not reallocated, so the value must not +be on the stack or deallocated in any other way for as long as the value +might get referenced. + + If you have supplied at least one 'homerc' file (*note program +attributes::), this macro will be emitted for the '--save-opts' option. + + SET_OPT_SAVE_OPTS( "filename" ); + +*Note automatic options::, for a discussion of the implications of using +this particular example. + + +File: autogen.info, Node: STACKCT_OPT, Next: STACKLST_OPT, Prev: SET_OPT_name, Up: AutoOpts API + +7.6.21 STACKCT_OPT( <NAME> ) - Stacked Arg Count +------------------------------------------------ + +When the option handling attribute is specified as 'stack_arg', this +macro may be used to determine how many of them actually got stacked. + + Do not use this on options that have not been stacked or has not been +specified (the 'stack_arg' attribute must have been specified, and +'HAVE_OPT(<NAME>)' must yield TRUE). Otherwise, you will likely seg +fault. + + if (HAVE_OPT( NAME )) { + int ct = STACKCT_OPT( NAME ); + char** pp = STACKLST_OPT( NAME ); + + do { + char* p = *pp++; + do-things-with-p; + } while (--ct > 0); + } + + +File: autogen.info, Node: STACKLST_OPT, Next: START_OPT, Prev: STACKCT_OPT, Up: AutoOpts API + +7.6.22 STACKLST_OPT( <NAME> ) - Argument Stack +---------------------------------------------- + +The address of the list of pointers to the option arguments. The +pointers are ordered by the order in which they were encountered in the +option presets and command line processing. + + Do not use this on options that have not been stacked or has not been +specified (the 'stack_arg' attribute must have been specified, and +'HAVE_OPT(<OPTION>)' must yield TRUE). Otherwise, you will likely seg +fault. + + if (HAVE_OPT( NAME )) { + int ct = STACKCT_OPT( NAME ); + char** pp = STACKLST_OPT( NAME ); + + do { + char* p = *pp++; + do-things-with-p; + } while (--ct > 0); + } + + +File: autogen.info, Node: START_OPT, Next: STATE_OPT, Prev: STACKLST_OPT, Up: AutoOpts API + +7.6.23 START_OPT - Restart Option Processing +-------------------------------------------- + +This is just a shortcut for RESTART_OPT(1) (*Note RESTART_OPT::.) + + +File: autogen.info, Node: STATE_OPT, Next: USAGE, Prev: START_OPT, Up: AutoOpts API + +7.6.24 STATE_OPT( <NAME> ) - Option State +----------------------------------------- + +If you need to know if an option was set because of presetting actions +(configuration file processing or environment variables), versus a +command line entry versus one of the SET/DISABLE macros, then use this +macro. It will yield one of four values: 'OPTST_INIT', 'OPTST_SET', +'OPTST_PRESET' or 'OPTST_DEFINED'. It is used thus: + + switch (STATE_OPT( NAME )) { + case OPTST_INIT: + not-preset, set or on the command line. (unless CLEAR-ed) + + case OPTST_SET: + option set via the SET_OPT_NAME() macro. + + case OPTST_PRESET: + option set via an configuration file or environment variable + + case OPTST_DEFINED: + option set via a command line option. + + default: + cannot happen :) + } + + +File: autogen.info, Node: USAGE, Next: VALUE_OPT_name, Prev: STATE_OPT, Up: AutoOpts API + +7.6.25 USAGE( exit-code ) - Usage invocation macro +-------------------------------------------------- + +This macro invokes the procedure registered to display the usage text. +Normally, this will be 'optionUsage' from the AutoOpts library, but you +may select another procedure by specifying 'usage = "proc_name"' program +attribute. This procedure must take two arguments first, a pointer to +the option descriptor, and second the exit code. The macro supplies the +option descriptor automatically. This routine is expected to call +'exit(3)' with the provided exit code. + + The 'optionUsage' routine also behaves differently depending on the +exit code: + +'EXIT_SUCCESS (the value zero)' + It is assumed that full usage help has been requested. + Consequently, more information is provided than when displaying + usage and exiting with a non-zero exit code. Output will be sent + to 'stdout' and the program will exit with a zero status code. + +'EX_USAGE (64)' + The abbreviated usage will be printed to 'stdout' and the program + will exit with a zero status code. 'EX_USAGE' may or may not be + 64. If your system provides '/usr/include/sysexits.h' that has a + different value, then that value will be used. + +'any other value' + The abbreviated usage will be printed to stderr and the program + will exit with the provided status code. + + +File: autogen.info, Node: VALUE_OPT_name, Next: VERSION, Prev: USAGE, Up: AutoOpts API + +7.6.26 VALUE_OPT_name - Option Flag Value +----------------------------------------- + +This is a #define for the flag character used to specify an option on +the command line. If 'value' was not specified for the option, then it +is a unique number associated with the option. 'option value' refers to +this value, 'option argument' refers to the (optional) argument to the +option. + + switch (WHICH_OPT_OTHER_OPT) { + case VALUE_OPT_NAME: + this-option-was-really-opt-name; + case VALUE_OPT_OTHER_OPT: + this-option-was-really-other-opt; + } + + +File: autogen.info, Node: VERSION, Next: WHICH_IDX_name, Prev: VALUE_OPT_name, Up: AutoOpts API + +7.6.27 VERSION - Version and Full Version +----------------------------------------- + +If the 'version' attribute is defined for the program, then a +stringified version will be #defined as PROGRAM_VERSION and +PROGRAM_FULL_VERSION. PROGRAM_FULL_VERSION is used for printing the +program version in response to the version option. The version option +is automatically supplied in response to this attribute, too. + + You may access PROGRAM_VERSION via 'programOptions.pzFullVersion'. + + +File: autogen.info, Node: WHICH_IDX_name, Next: WHICH_OPT_name, Prev: VERSION, Up: AutoOpts API + +7.6.28 WHICH_IDX_name - Which Equivalenced Index +------------------------------------------------ + +This macro gets emitted only for equivalenced-to options. It is used to +obtain the index for the one of the several equivalence class members +set the equivalenced-to option. + + switch (WHICH_IDX_OTHER_OPT) { + case INDEX_OPT_NAME: + this-option-was-really-opt-name; + case INDEX_OPT_OTHER_OPT: + this-option-was-really-other-opt; + } + + +File: autogen.info, Node: WHICH_OPT_name, Next: teOptIndex, Prev: WHICH_IDX_name, Up: AutoOpts API + +7.6.29 WHICH_OPT_name - Which Equivalenced Option +------------------------------------------------- + +This macro gets emitted only for equivalenced-to options. It is used to +obtain the value code for the one of the several equivalence class +members set the equivalenced-to option. + + switch (WHICH_OPT_OTHER_OPT) { + case VALUE_OPT_NAME: + this-option-was-really-opt-name; + case VALUE_OPT_OTHER_OPT: + this-option-was-really-other-opt; + } + + +File: autogen.info, Node: teOptIndex, Next: OPTIONS_STRUCT_VERSION, Prev: WHICH_OPT_name, Up: AutoOpts API + +7.6.30 teOptIndex - Option Index and Enumeration +------------------------------------------------ + +This enum defines the complete set of options, both user specified and +automatically provided. This can be used, for example, to distinguish +which of the equivalenced options was actually used. + + switch (pOptDesc->optActualIndex) { + case INDEX_OPT_FIRST: + stuff; + case INDEX_OPT_DIFFERENT: + different-stuff; + default: + unknown-things; + } + + +File: autogen.info, Node: OPTIONS_STRUCT_VERSION, Next: libopts procedures, Prev: teOptIndex, Up: AutoOpts API + +7.6.31 OPTIONS_STRUCT_VERSION - active version +---------------------------------------------- + +You will not actually need to reference this value, but you need to be +aware that it is there. It is the first value in the option descriptor +that you pass to 'optionProcess'. It contains a magic number and +version information. Normally, you should be able to work with a more +recent option library than the one you compiled with. However, if the +library is changed incompatibly, then the library will detect the out of +date magic marker, explain the difficulty and exit. You will then need +to rebuild and recompile your option definitions. This has rarely been +necessary. + + +File: autogen.info, Node: libopts procedures, Prev: OPTIONS_STRUCT_VERSION, Up: AutoOpts API + +7.6.32 libopts External Procedures +---------------------------------- + +These are the routines that libopts users may call directly from their +code. There are several other routines that can be called by code +generated by the libopts option templates, but they are not to be called +from any other user code. The 'options.h' header is fairly clear about +this, too. + +* Menu: + +* libopts-ao_string_tokenize:: ao_string_tokenize +* libopts-configFileLoad:: configFileLoad +* libopts-optionFileLoad:: optionFileLoad +* libopts-optionFindNextValue:: optionFindNextValue +* libopts-optionFindValue:: optionFindValue +* libopts-optionFree:: optionFree +* libopts-optionGetValue:: optionGetValue +* libopts-optionLoadLine:: optionLoadLine +* libopts-optionMemberList:: optionMemberList +* libopts-optionNextValue:: optionNextValue +* libopts-optionOnlyUsage:: optionOnlyUsage +* libopts-optionPrintVersion:: optionPrintVersion +* libopts-optionPrintVersionAndReturn:: optionPrintVersionAndReturn +* libopts-optionProcess:: optionProcess +* libopts-optionRestore:: optionRestore +* libopts-optionSaveFile:: optionSaveFile +* libopts-optionSaveState:: optionSaveState +* libopts-optionUnloadNested:: optionUnloadNested +* libopts-optionVersion:: optionVersion +* libopts-strequate:: strequate +* libopts-streqvcmp:: streqvcmp +* libopts-streqvmap:: streqvmap +* libopts-strneqvcmp:: strneqvcmp +* libopts-strtransform:: strtransform + + This subsection was automatically generated by AutoGen using +extracted information and the aginfo3.tpl template. + + +File: autogen.info, Node: libopts-ao_string_tokenize, Next: libopts-configFileLoad, Up: libopts procedures + +7.6.32.1 ao_string_tokenize +........................... + +tokenize an input string + +Usage: + token_list_t * res = ao_string_tokenize( string ); +Where the arguments are: + Name Type Description + --- --- --------- + string 'char const string to be tokenized + *' + returns token_list_t pointer to a structure that lists each + * token + + This function will convert one input string into a list of strings. +The list of strings is derived by separating the input based on white +space separation. However, if the input contains either single or +double quote characters, then the text after that character up to a +matching quote will become the string in the list. + + The returned pointer should be deallocated with 'free(3C)' when are +done using the data. The data are placed in a single block of allocated +memory. Do not deallocate individual token/strings. + + The structure pointed to will contain at least these two fields: +'tkn_ct' + The number of tokens found in the input string. +'tok_list' + An array of 'tkn_ct + 1' pointers to substring tokens, with the + last pointer set to NULL. + + There are two types of quoted strings: single quoted (''') and double +quoted ('"'). Singly quoted strings are fairly raw in that escape +characters ('\\') are simply another character, except when preceding +the following characters: + \\ double backslashes reduce to one + ' incorporates the single quote into the string + \n suppresses both the backslash and newline character + + Double quote strings are formed according to the rules of string +constants in ANSI-C programs. + + NULL is returned and 'errno' will be set to indicate the problem: + * 'EINVAL' - There was an unterminated quoted string. + * 'ENOENT' - The input string was empty. + * 'ENOMEM' - There is not enough memory. + + +File: autogen.info, Node: libopts-configFileLoad, Next: libopts-optionFileLoad, Prev: libopts-ao_string_tokenize, Up: libopts procedures + +7.6.32.2 configFileLoad +....................... + +parse a configuration file + +Usage: + const tOptionValue * res = configFileLoad( fname ); +Where the arguments are: + Name Type Description + --- --- --------- + fname 'char const the file to load + *' + returns const An allocated, compound value structure + tOptionValue + * + + This routine will load a named configuration file and parse the text +as a hierarchically valued option. The option descriptor created from +an option definition file is not used via this interface. The returned +value is "named" with the input file name and is of type +"'OPARG_TYPE_HIERARCHY'". It may be used in calls to +'optionGetValue()', 'optionNextValue()' and 'optionUnloadNested()'. + + If the file cannot be loaded or processed, 'NULL' is returned and +ERRNO is set. It may be set by a call to either 'open(2)' 'mmap(2)' or +other file system calls, or it may be: + * 'ENOENT' - the file was not found. + * 'ENOMSG' - the file was empty. + * 'EINVAL' - the file contents are invalid - not properly formed. + * 'ENOMEM' - not enough memory to allocate the needed structures. + + +File: autogen.info, Node: libopts-optionFileLoad, Next: libopts-optionFindNextValue, Prev: libopts-configFileLoad, Up: libopts procedures + +7.6.32.3 optionFileLoad +....................... + +Load the locatable config files, in order + +Usage: + int res = optionFileLoad( opts, prog ); +Where the arguments are: + Name Type Description + --- --- --------- + opts 'tOptions *' program options descriptor + + prog 'char const program name + *' + returns int 0 -> SUCCESS, -1 -> FAILURE + + This function looks in all the specified directories for a +configuration file ("rc" file or "ini" file) and processes any found +twice. The first time through, they are processed in reverse order +(last file first). At that time, only "immediate action" configurables +are processed. For example, if the last named file specifies not +processing any more configuration files, then no more configuration +files will be processed. Such an option in the *first* named directory +will have no effect. + + Once the immediate action configurables have been handled, then the +directories are handled in normal, forward order. In that way, later +config files can override the settings of earlier config files. + + See the AutoOpts documentation for a thorough discussion of the +config file format. + + Configuration files not found or not decipherable are simply ignored. + + Returns the value, "-1" if the program options descriptor is out of +date or indecipherable. Otherwise, the value "0" will always be +returned. + + +File: autogen.info, Node: libopts-optionFindNextValue, Next: libopts-optionFindValue, Prev: libopts-optionFileLoad, Up: libopts procedures + +7.6.32.4 optionFindNextValue +............................ + +find a hierarcicaly valued option instance + +Usage: + const tOptionValue * res = optionFindNextValue( odesc, pPrevVal, name, value ); +Where the arguments are: + Name Type Description + --- --- --------- + odesc 'const an option with a nested arg type + tOptDesc *' + pPrevVal 'const the last entry + tOptionValue + *' + name 'char const name of value to find + *' + value 'char const the matching value + *' + returns const a compound value structure + tOptionValue + * + + This routine will find the next entry in a nested value option or +configurable. It will search through the list and return the next entry +that matches the criteria. + + The returned result is NULL and errno is set: + * 'EINVAL' - the 'pOptValue' does not point to a valid hierarchical + option value. + * 'ENOENT' - no entry matched the given name. + + +File: autogen.info, Node: libopts-optionFindValue, Next: libopts-optionFree, Prev: libopts-optionFindNextValue, Up: libopts procedures + +7.6.32.5 optionFindValue +........................ + +find a hierarcicaly valued option instance + +Usage: + const tOptionValue * res = optionFindValue( odesc, name, val ); +Where the arguments are: + Name Type Description + --- --- --------- + odesc 'const an option with a nested arg type + tOptDesc *' + name 'char const name of value to find + *' + val 'char const the matching value + *' + returns const a compound value structure + tOptionValue + * + + This routine will find an entry in a nested value option or +configurable. It will search through the list and return a matching +entry. + + The returned result is NULL and errno is set: + * 'EINVAL' - the 'pOptValue' does not point to a valid hierarchical + option value. + * 'ENOENT' - no entry matched the given name. + + +File: autogen.info, Node: libopts-optionFree, Next: libopts-optionGetValue, Prev: libopts-optionFindValue, Up: libopts procedures + +7.6.32.6 optionFree +................... + +free allocated option processing memory + +Usage: + optionFree( pOpts ); +Where the arguments are: + Name Type Description + --- --- --------- + pOpts 'tOptions *' program options descriptor + + AutoOpts sometimes allocates memory and puts pointers to it in the +option state structures. This routine deallocates all such memory. + + As long as memory has not been corrupted, this routine is always +successful. + + +File: autogen.info, Node: libopts-optionGetValue, Next: libopts-optionLoadLine, Prev: libopts-optionFree, Up: libopts procedures + +7.6.32.7 optionGetValue +....................... + +get a specific value from a hierarcical list + +Usage: + const tOptionValue * res = optionGetValue( pOptValue, valueName ); +Where the arguments are: + Name Type Description + --- --- --------- + pOptValue 'const a hierarchcal value + tOptionValue + *' + valueName 'char const name of value to get + *' + returns const a compound value structure + tOptionValue + * + + This routine will find an entry in a nested value option or +configurable. If "valueName" is NULL, then the first entry is returned. +Otherwise, the first entry with a name that exactly matches the argument +will be returned. If there is no matching value, NULL is returned and +errno is set to ENOENT. If the provided option value is not a +hierarchical value, NULL is also returned and errno is set to EINVAL. + + The returned result is NULL and errno is set: + * 'EINVAL' - the 'pOptValue' does not point to a valid hierarchical + option value. + * 'ENOENT' - no entry matched the given name. + + +File: autogen.info, Node: libopts-optionLoadLine, Next: libopts-optionMemberList, Prev: libopts-optionGetValue, Up: libopts procedures + +7.6.32.8 optionLoadLine +....................... + +process a string for an option name and value + +Usage: + optionLoadLine( opts, line ); +Where the arguments are: + Name Type Description + --- --- --------- + opts 'tOptions *' program options descriptor + + line 'char const NUL-terminated text + *' + + This is a client program callable routine for setting options from, +for example, the contents of a file that they read in. Only one option +may appear in the text. It will be treated as a normal (non-preset) +option. + + When passed a pointer to the option struct and a string, it will find +the option named by the first token on the string and set the option +argument to the remainder of the string. The caller must NUL terminate +the string. The caller need not skip over any introductory hyphens. +Any embedded new lines will be included in the option argument. If the +input looks like one or more quoted strings, then the input will be +"cooked". The "cooking" is identical to the string formation used in +AutoGen definition files (*note basic expression::), except that you may +not use backquotes. + + Invalid options are silently ignored. Invalid option arguments will +cause a warning to print, but the function should return. + + +File: autogen.info, Node: libopts-optionMemberList, Next: libopts-optionNextValue, Prev: libopts-optionLoadLine, Up: libopts procedures + +7.6.32.9 optionMemberList +......................... + +Get the list of members of a bit mask set + +Usage: + char * res = optionMemberList( od ); +Where the arguments are: + Name Type Description + --- --- --------- + od 'tOptDesc *' the set membership option description + returns char * the names of the set bits + + This converts the OPT_VALUE_name mask value to a allocated string. +It is the caller's responsibility to free the string. + + +File: autogen.info, Node: libopts-optionNextValue, Next: libopts-optionOnlyUsage, Prev: libopts-optionMemberList, Up: libopts procedures + +7.6.32.10 optionNextValue +......................... + +get the next value from a hierarchical list + +Usage: + const tOptionValue * res = optionNextValue( pOptValue, pOldValue ); +Where the arguments are: + Name Type Description + --- --- --------- + pOptValue 'const a hierarchcal list value + tOptionValue + *' + pOldValue 'const a value from this list + tOptionValue + *' + returns const a compound value structure + tOptionValue + * + + This routine will return the next entry after the entry passed in. +At the end of the list, NULL will be returned. If the entry is not +found on the list, NULL will be returned and "ERRNO" will be set to +EINVAL. The "POLDVALUE" must have been gotten from a prior call to this +routine or to "'opitonGetValue()'". + + The returned result is NULL and errno is set: + * 'EINVAL' - the 'pOptValue' does not point to a valid hierarchical + option value or 'pOldValue' does not point to a member of that + option value. + * 'ENOENT' - the supplied 'pOldValue' pointed to the last entry. + + +File: autogen.info, Node: libopts-optionOnlyUsage, Next: libopts-optionPrintVersion, Prev: libopts-optionNextValue, Up: libopts procedures + +7.6.32.11 optionOnlyUsage +......................... + +Print usage text for just the options + +Usage: + optionOnlyUsage( pOpts, ex_code ); +Where the arguments are: + Name Type Description + --- --- --------- + pOpts 'tOptions *' program options descriptor + + ex_code 'int' exit code for calling exit(3) + + This routine will print only the usage for each option. This +function may be used when the emitted usage must incorporate information +not available to AutoOpts. + + +File: autogen.info, Node: libopts-optionPrintVersion, Next: libopts-optionPrintVersionAndReturn, Prev: libopts-optionOnlyUsage, Up: libopts procedures + +7.6.32.12 optionPrintVersion +............................ + +Print the program version + +Usage: + optionPrintVersion( opts, od ); +Where the arguments are: + Name Type Description + --- --- --------- + opts 'tOptions *' program options descriptor + + od 'tOptDesc *' the descriptor for this arg + + This routine will print the version to stdout. + + +File: autogen.info, Node: libopts-optionPrintVersionAndReturn, Next: libopts-optionProcess, Prev: libopts-optionPrintVersion, Up: libopts procedures + +7.6.32.13 optionPrintVersionAndReturn +..................................... + +Print the program version + +Usage: + optionPrintVersionAndReturn( opts, od ); +Where the arguments are: + Name Type Description + --- --- --------- + opts 'tOptions *' program options descriptor + + od 'tOptDesc *' the descriptor for this arg + + This routine will print the version to stdout and return instead of +exiting. Please see the source for the 'print_ver' funtion for details +on selecting how verbose to be after this function returns. + + +File: autogen.info, Node: libopts-optionProcess, Next: libopts-optionRestore, Prev: libopts-optionPrintVersionAndReturn, Up: libopts procedures + +7.6.32.14 optionProcess +....................... + +this is the main option processing routine + +Usage: + int res = optionProcess( opts, a_ct, a_v ); +Where the arguments are: + Name Type Description + --- --- --------- + opts 'tOptions *' program options descriptor + + a_ct 'int' program arg count + + a_v 'char **' program arg vector + returns int the count of the arguments processed + + This is the main entry point for processing options. It is intended +that this procedure be called once at the beginning of the execution of +a program. Depending on options selected earlier, it is sometimes +necessary to stop and restart option processing, or to select completely +different sets of options. This can be done easily, but you generally +do not want to do this. + + The number of arguments processed always includes the program name. +If one of the arguments is "-", then it is counted and the processing +stops. If an error was encountered and errors are to be tolerated, then +the returned value is the index of the argument causing the error. A +hyphen by itself ("-") will also cause processing to stop and will _not_ +be counted among the processed arguments. A hyphen by itself is treated +as an operand. Encountering an operand stops option processing. + + Errors will cause diagnostics to be printed. 'exit(3)' may or may +not be called. It depends upon whether or not the options were +generated with the "allow-errors" attribute, or if the ERRSKIP_OPTERR or +ERRSTOP_OPTERR macros were invoked. + + +File: autogen.info, Node: libopts-optionRestore, Next: libopts-optionSaveFile, Prev: libopts-optionProcess, Up: libopts procedures + +7.6.32.15 optionRestore +....................... + +restore option state from memory copy + +Usage: + optionRestore( pOpts ); +Where the arguments are: + Name Type Description + --- --- --------- + pOpts 'tOptions *' program options descriptor + + Copy back the option state from saved memory. The allocated memory +is left intact, so this routine can be called repeatedly without having +to call optionSaveState again. If you are restoring a state that was +saved before the first call to optionProcess(3AO), then you may change +the contents of the argc/argv parameters to optionProcess. + + If you have not called 'optionSaveState' before, a diagnostic is +printed to 'stderr' and exit is called. + + +File: autogen.info, Node: libopts-optionSaveFile, Next: libopts-optionSaveState, Prev: libopts-optionRestore, Up: libopts procedures + +7.6.32.16 optionSaveFile +........................ + +saves the option state to a file + +Usage: + optionSaveFile( opts ); +Where the arguments are: + Name Type Description + --- --- --------- + opts 'tOptions *' program options descriptor + + This routine will save the state of option processing to a file. The +name of that file can be specified with the argument to the +'--save-opts' option, or by appending the 'rcfile' attribute to the last +'homerc' attribute. If no 'rcfile' attribute was specified, it will +default to '.programnamerc'. If you wish to specify another file, you +should invoke the 'SET_OPT_SAVE_OPTS(filename)' macro. + + The recommend usage is as follows: + optionProcess(&progOptions, argc, argv); + if (i_want_a_non_standard_place_for_this) + SET_OPT_SAVE_OPTS("myfilename"); + optionSaveFile(&progOptions); + + If no 'homerc' file was specified, this routine will silently return +and do nothing. If the output file cannot be created or updated, a +message will be printed to 'stderr' and the routine will return. + + +File: autogen.info, Node: libopts-optionSaveState, Next: libopts-optionUnloadNested, Prev: libopts-optionSaveFile, Up: libopts procedures + +7.6.32.17 optionSaveState +......................... + +saves the option state to memory + +Usage: + optionSaveState( pOpts ); +Where the arguments are: + Name Type Description + --- --- --------- + pOpts 'tOptions *' program options descriptor + + This routine will allocate enough memory to save the current option +processing state. If this routine has been called before, that memory +will be reused. You may only save one copy of the option state. This +routine may be called before optionProcess(3AO). If you do call it +before the first call to optionProcess, then you may also change the +contents of argc/argv after you call optionRestore(3AO) + + In fact, more strongly put: it is safest to only use this function +before having processed any options. In particular, the saving and +restoring of stacked string arguments and hierarchical values is +disabled. The values are not saved. + + If it fails to allocate the memory, it will print a message to stderr +and exit. Otherwise, it will always succeed. + + +File: autogen.info, Node: libopts-optionUnloadNested, Next: libopts-optionVersion, Prev: libopts-optionSaveState, Up: libopts procedures + +7.6.32.18 optionUnloadNested +............................ + +Deallocate the memory for a nested value + +Usage: + optionUnloadNested( pOptVal ); +Where the arguments are: + Name Type Description + --- --- --------- + pOptVal 'tOptionValue the hierarchical value + const *' + + A nested value needs to be deallocated. The pointer passed in should +have been gotten from a call to 'configFileLoad()' (See *note +libopts-configFileLoad::). + + +File: autogen.info, Node: libopts-optionVersion, Next: libopts-strequate, Prev: libopts-optionUnloadNested, Up: libopts procedures + +7.6.32.19 optionVersion +....................... + +return the compiled AutoOpts version number + +Usage: + char const * res = optionVersion(); +Where the arguments are: + Name Type Description + --- --- --------- + returns char const * the version string in constant memory + + Returns the full version string compiled into the library. The +returned string cannot be modified. + + +File: autogen.info, Node: libopts-strequate, Next: libopts-streqvcmp, Prev: libopts-optionVersion, Up: libopts procedures + +7.6.32.20 strequate +................... + +map a list of characters to the same value + +Usage: + strequate( ch_list ); +Where the arguments are: + Name Type Description + --- --- --------- + ch_list 'char const characters to equivalence + *' + + Each character in the input string get mapped to the first character +in the string. This function name is mapped to option_strequate so as +to not conflict with the POSIX name space. + + none. + + +File: autogen.info, Node: libopts-streqvcmp, Next: libopts-streqvmap, Prev: libopts-strequate, Up: libopts procedures + +7.6.32.21 streqvcmp +................... + +compare two strings with an equivalence mapping + +Usage: + int res = streqvcmp( str1, str2 ); +Where the arguments are: + Name Type Description + --- --- --------- + str1 'char const first string + *' + str2 'char const second string + *' + returns int the difference between two differing + characters + + Using a character mapping, two strings are compared for +"equivalence". Each input character is mapped to a comparison character +and the mapped-to characters are compared for the two NUL terminated +input strings. This function name is mapped to option_streqvcmp so as +to not conflict with the POSIX name space. + + none checked. Caller responsible for seg faults. + + +File: autogen.info, Node: libopts-streqvmap, Next: libopts-strneqvcmp, Prev: libopts-streqvcmp, Up: libopts procedures + +7.6.32.22 streqvmap +................... + +Set the character mappings for the streqv functions + +Usage: + streqvmap( from, to, ct ); +Where the arguments are: + Name Type Description + --- --- --------- + from 'char' Input character + + to 'char' Mapped-to character + + ct 'int' compare length + + Set the character mapping. If the count ('ct') is set to zero, then +the map is cleared by setting all entries in the map to their index +value. Otherwise, the "'From'" character is mapped to the "'To'" +character. If 'ct' is greater than 1, then 'From' and 'To' are +incremented and the process repeated until 'ct' entries have been set. +For example, + streqvmap('a', 'A', 26); +will alter the mapping so that all English lower case letters will map +to upper case. + + This function name is mapped to option_streqvmap so as to not +conflict with the POSIX name space. + + none. + + +File: autogen.info, Node: libopts-strneqvcmp, Next: libopts-strtransform, Prev: libopts-streqvmap, Up: libopts procedures + +7.6.32.23 strneqvcmp +.................... + +compare two strings with an equivalence mapping + +Usage: + int res = strneqvcmp( str1, str2, ct ); +Where the arguments are: + Name Type Description + --- --- --------- + str1 'char const first string + *' + str2 'char const second string + *' + ct 'int' compare length + returns int the difference between two differing + characters + + Using a character mapping, two strings are compared for +"equivalence". Each input character is mapped to a comparison character +and the mapped-to characters are compared for the two NUL terminated +input strings. The comparison is limited to 'ct' bytes. This function +name is mapped to option_strneqvcmp so as to not conflict with the POSIX +name space. + + none checked. Caller responsible for seg faults. + + +File: autogen.info, Node: libopts-strtransform, Prev: libopts-strneqvcmp, Up: libopts procedures + +7.6.32.24 strtransform +...................... + +convert a string into its mapped-to value + +Usage: + strtransform( dest, src ); +Where the arguments are: + Name Type Description + --- --- --------- + dest 'char *' output string + + src 'char const input string + *' + + Each character in the input string is mapped and the mapped-to +character is put into the output. This function name is mapped to +option_strtransform so as to not conflict with the POSIX name space. + + The source and destination may be the same. + + none. + + +File: autogen.info, Node: Multi-Threading, Next: option descriptor, Prev: AutoOpts API, Up: AutoOpts + +7.7 Multi-Threading +=================== + +AutoOpts was designed to configure a program for running. This +generally happens before much real work has been started. Consequently, +it is expected to be run before multi-threaded applications have started +multiple threads. However, this is not always the case. Some +applications may need to reset and reload their running configuration, +and some may use 'SET_OPT_xxx()' macros during processing. If you need +to dynamically change your option configuration in your multi-threaded +application, it is your responsibility to prevent all threads from +accessing the option configuration state, except the one altering the +configuration. + + The various accessor macros ('HAVE_OPT()', etc.) do not modify state +and are safe to use in a multi-threaded application. It is safe as long +as no other thread is concurrently modifying state, of course. + + +File: autogen.info, Node: option descriptor, Next: Using AutoOpts, Prev: Multi-Threading, Up: AutoOpts + +7.8 Option Descriptor File +========================== + +This is the module that is to be compiled and linked with your program. +It contains internal data and procedures subject to change. Basically, +it contains a single global data structure containing all the +information provided in the option definitions, plus a number of static +strings and any callout procedures that are specified or required. You +should never have need for looking at this, except, perhaps, to examine +the code generated for implementing the 'flag-code' construct. + + +File: autogen.info, Node: Using AutoOpts, Next: Presetting Options, Prev: option descriptor, Up: AutoOpts + +7.9 Using AutoOpts +================== + +There are actually several levels of 'using' autoopts. Which you choose +depends upon how you plan to distribute (or not) your application. + +* Menu: + +* local use:: local-only use +* binary not installed:: binary distro, AutoOpts not installed +* binary pre-installed:: binary distro, AutoOpts pre-installed +* source pre-installed:: source distro, AutoOpts pre-installed +* source not installed:: source distro, AutoOpts not installed + + +File: autogen.info, Node: local use, Next: binary not installed, Up: Using AutoOpts + +7.9.1 local-only use +-------------------- + +To use AutoOpts in your application where you do not have to worry about +distribution issues, your issues are simple and few. + + * Create a file 'myopts.def', according to the documentation above. + It is probably easiest to start with the example in *note Quick + Start:: and edit it into the form you need. + + * Run AutoGen to create the option interface file ('myopts.h') and + the option descriptor code ('myopts.c'): + + autogen myopts.def + + * In all your source files where you need to refer to option state, + '#include "myopts.h"'. + * In your main routine, code something along the lines of: + + #define ARGC_MIN some-lower-limit + #define ARGC_MAX some-upper-limit + main( int argc, char** argv ) + { + { + int arg_ct = optionProcess( &myprogOptions, argc, argv ); + argc -= arg_ct; + if ((argc < ARGC_MIN) || (argc > ARGC_MAX)) { + fprintf( stderr, "%s ERROR: remaining args (%d) " + "out of range\n", myprogOptions.pzProgName, + argc ); + + USAGE( EXIT_FAILURE ); + } + argv += arg_ct; + } + if (HAVE_OPT(OPTN_NAME)) + respond_to_optn_name(); + ... + } + + * Compile 'myopts.c' and link your program with the following + additional arguments: + + `autoopts-config cflags ldflags` myopts.c + + +File: autogen.info, Node: binary not installed, Next: binary pre-installed, Prev: local use, Up: Using AutoOpts + +7.9.2 binary distro, AutoOpts not installed +------------------------------------------- + +If you will be distributing (or copying) your project to a system that +does not have AutoOpts installed, you will need to statically link the +AutoOpts library, 'libopts' into your program. Get the link information +with 'static-libs' instead of 'ldflags': + + `autoopts-config static-libs` + + +File: autogen.info, Node: binary pre-installed, Next: source pre-installed, Prev: binary not installed, Up: Using AutoOpts + +7.9.3 binary distro, AutoOpts pre-installed +------------------------------------------- + +If you will be distributing (or copying) your project to a system that +does have AutoOpts (or only 'libopts') installed, you will still need to +ensure that the library is findable at program load time, or you will +still have to statically link. The former can be accomplished by +linking your project with '--rpath' or by setting the 'LD_LIBRARY_PATH' +appropriately. Otherwise, *Note binary not installed::. + + +File: autogen.info, Node: source pre-installed, Next: source not installed, Prev: binary pre-installed, Up: Using AutoOpts + +7.9.4 source distro, AutoOpts pre-installed +------------------------------------------- + +If you will be distributing your project to a system that will build +your product but it may not be pre-installed with AutoOpts, you will +need to do some configuration checking before you start the build. +Assuming you are willing to fail the build if AutoOpts has not been +installed, you will still need to do a little work. + + AutoOpts is distributed with a configuration check M4 script, +'autoopts.m4'. It will add an 'autoconf' macro named, +'AG_PATH_AUTOOPTS'. Add this to your 'configure.ac' script and use the +following substitution values: + +'AUTOGEN' + the name of the autogen executable +'AUTOGEN_TPLIB' + the directory where AutoGen template library is stored +'AUTOOPTS_CFLAGS' + the compile time options needed to find the AutoOpts headers +'AUTOOPTS_LIBS' + the link options required to access the 'libopts' library + + +File: autogen.info, Node: source not installed, Prev: source pre-installed, Up: Using AutoOpts + +7.9.5 source distro, AutoOpts not installed +------------------------------------------- + +If you will be distributing your project to a system that will build +your product but it may not be pre-installed with AutoOpts, you may wish +to incorporate the sources for 'libopts' in your project. To do this, I +recommend reading the tear-off libopts library 'README' that you can +find in the 'pkg/libopts' directory. You can also examine an example +package (blocksort) that incorporates this tear off library in the +autogen distribution directory. There is also a web page that describes +what you need to do: + <http://autogen.sourceforge.net/blocksort.html> + + Alternatively, you can pull the 'libopts' library sources into a +build directory and build it for installation along with your package. +This can be done approximately as follows: + tar -xzvf `autoopts-config libsrc` + cd libopts-* + ./bootstrap + configure + make + make install + That will install the library, but not the headers or anything else. + + +File: autogen.info, Node: Presetting Options, Next: Config File Format, Prev: Using AutoOpts, Up: AutoOpts + +7.10 Configuring your program +============================= + +AutoOpts supports the notion of 'presetting' the value or state of an +option. The values may be obtained either from environment variables or +from configuration files ('rc' or 'ini' files). In order to take +advantage of this, the AutoOpts client program must specify these +features in the option descriptor file (*note program attributes::) with +the 'rcfile' or 'environrc' attributes. + +* Menu: + +* loading rcfile:: configuration file presets +* saving rcfile:: Saving the presets into a configuration file +* sample rcfile:: Creating a sample configuration file +* environrc:: environment variable presets +* config example:: Config file only example + + It is also possible to configure your program without using the +command line option parsing code. This is done by using only the +following four functions from the 'libopts' library: + +'configFileLoad' + (*note libopts-configFileLoad::) will parse the contents of a + config file and return a pointer to a structure representing the + hierarchical value. The values are sorted alphabetically by the + value name and all entries with the same name will retain their + original order. Insertion sort is used. + +'optionGetValue' + (*note libopts-optionGetValue::) will find the first value within + the hierarchy with a name that matches the name passed in. + +'optionNextValue' + (*note libopts-optionNextValue::) will return the next value that + follows the value passed in as an argument. If you wish to get all + the values for a particular name, you must take note when the name + changes. + +'optionUnloadNested' + (*note libopts-optionUnloadNested::). The pointer passed in must + be of type, 'OPARG_TYPE_HIERARCHY' (see the autoopts/options.h + header file). 'configFileLoad' will return a 'tOptionValue' + pointer of that type. This function will release all the + associated memory. 'AutoOpts' generated code uses this function + for its own needs. Client code should only call this function with + pointers gotten from 'configFileLoad'. + + +File: autogen.info, Node: loading rcfile, Next: saving rcfile, Up: Presetting Options + +7.10.1 configuration file presets +--------------------------------- + +Configuration files are enabled by specifying the program attribute +'homerc' (*note program attributes::). Any option not marked with the +'no-preset' attribute may appear in a configuration file. The files +loaded are selected both by the 'homerc' entries and, optionally, via a +command line option. The first component of the 'homerc' entry may be +an environment variable such as '$HOME', or it may also be '$$' (*two* +dollar sign characters) to specify the directory of the executable. For +example: + + homerc = "$$/../share/autogen"; + +will cause the AutoOpts library to look in the normal autogen datadir +relative to the current installation directory for autogen. + + The configuration files are processed in the order they are specified +by the 'homerc' attribute, so that each new file will normally override +the settings of the previous files. This may be overridden by marking +some options for 'immediate action' (*note Immediate Action::). Any +such options are acted upon in *reverse* order. The disabled +'load-opts' ('--no-load-opts') option, for example, is an immediate +action option. Its presence in the last 'homerc' file will prevent the +processing of any prior 'homerc' files because its effect is immediate. + + Configuration file processing can be completely suppressed by +specifying '--no-load-opts' on the command line, or +'PROGRAM_LOAD_OPTS=no' in the environment (if 'environrc' has been +specified). + + See the 'Configuration File Format' section (*note Config File +Format::) for details on the format of the file. + + +File: autogen.info, Node: saving rcfile, Next: sample rcfile, Prev: loading rcfile, Up: Presetting Options + +7.10.2 Saving the presets into a configuration file +--------------------------------------------------- + +When configuration files are enabled for an application, the user is +also provided with an automatically supplied '--save-opts' option. All +of the known option state will be written to either the specified output +file or, if it is not specified, then to the last specified 'homerc' +file. + + +File: autogen.info, Node: sample rcfile, Next: environrc, Prev: saving rcfile, Up: Presetting Options + +7.10.3 Creating a sample configuration file +------------------------------------------- + +AutoOpts is shipped with a template named, 'rc-sample.tpl'. If your +option definition file specifies the 'homerc' attribute, then you may +invoke 'autogen' thus: + + autogen -Trc-sample <your-option-def-file> + + This will, by default, produce a sample file named, +'sample-<prog-name>rc'. It will be named differently if you specify +your configuration (rc) file name with the 'rcfile' attribute. In that +case, the output file will be named, 'sample-<rcfile-name>'. It will +contain all of the program options not marked as 'no-preset'. It will +also include the text from the 'doc' attribute. + +Doing so with getdefs' option definitions yields this sample-getdefsrc +file. I tend to be wordy in my 'doc' attributes: + + # getdefs sample configuration file + ## This source file is copyrighted and licensed under the following terms: + # + # Copyright (C) 1999-2018 Bruce Korb, all rights reserved. + # This is free software. It is licensed for use, modification and + # redistribution under the terms of the GNU General Public License, + # version 3 or later <http://gnu.org/licenses/gpl.html> + # + # getdefs 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. + # + # getdefs is distributed in the hope that it will be useful, but + # WITHOUT ANY WARRANTY; without even the implied warranty of + # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + # See the GNU General Public License for more details. + # + # You should have received a copy of the GNU General Public License along + # with this program. If not, see <http://www.gnu.org/licenses/>. + + # defs_to_get -- Regexp to look for after the "/*=" + # + # + # + # + # If you want definitions only from a particular category, or even + # with names matching particular patterns, then specify this regular + # expression for the text that must follow the @code{/*=}. + # Example: + # + #defs_to_get reg-ex + + # subblock -- subblock definition names + # + # + # + # + # This option is used to create shorthand entries for nested definitions. + # For example, with: + # @table @r + # @item using subblock thus + # @code{--subblock=arg=argname,type,null} + # @item and defining an @code{arg} thus + # @code{arg: this, char *} + # @item will then expand to: + # @code{arg = @{ argname = this; type = "char *"; @};} + # @end table + # The "this, char *" string is separated at the commas, with the + # white space removed. You may use characters other than commas by + # starting the value string with a punctuation character other than + # a single or double quote character. You may also omit intermediate + # values by placing the commas next to each other with no intervening + # white space. For example, "+mumble++yes+" will expand to: + # @* + # @code{arg = @{ argname = mumble; null = "yes"; @};}. + # Example: + # + #subblock sub-def + + # listattr -- attribute with list of values + # + # + # + # + # This option is used to create shorthand entries for definitions + # that generally appear several times. That is, they tend to be + # a list of values. For example, with: + # @* + # @code{listattr=foo} defined, the text: + # @* + # @code{foo: this, is, a, multi-list} will then expand to: + # @* + # @code{foo = 'this', 'is', 'a', 'multi-list';} + # @* + # The texts are separated by the commas, with the + # white space removed. You may use characters other than commas by + # starting the value string with a punctuation character other than + # a single or double quote character. + # Example: + # + #listattr def + + # ordering -- Alphabetize or use named file + # + # + # + # + # By default, ordering is alphabetical by the entry name. Use, + # @code{no-ordering} if order is unimportant. Use @code{ordering} + # with no argument to order without case sensitivity. Use + # @code{ordering=<file-name>} if chronological order is important. + # getdefs will maintain the text content of @code{file-name}. + # @code{file-name} need not exist. + # Example: + # + #ordering file-name + + # first_index -- The first index to apply to groups + # + # This configuration value takes an integer number as its argument. + # + # + # By default, the first occurrence of a named definition will have an + # index of zero. Sometimes, that needs to be a reserved value. Provide + # this option to specify a different starting point. + # Example: + # + #first_index 0 + + # filelist -- Insert source file names into defs + # + # + # + # + # Inserts the name of each input file into the output definitions. + # If no argument is supplied, the format will be: + # @example + # infile = '%s'; + # @end example + # If an argument is supplied, that string will be used for the entry + # name instead of @var{infile}. + # Example: + # + #filelist file + + # assign -- Global assignments + # + # + # + # + # The argument to each copy of this option will be inserted into + # the output definitions, with only a semicolon attached. + # Example: + # + #assign ag-def + + # common_assign -- Assignments common to all blocks + # + # + # + # + # The argument to each copy of this option will be inserted into + # each output definition, with only a semicolon attached. + # Example: + # + #common_assign ag-def + + # copy -- File(s) to copy into definitions + # + # + # + # + # The content of each file named by these options will be inserted into + # the output definitions. + # Example: + # + #copy file + + # srcfile -- Insert source file name into each def + # + # + # + # + # Inserts the name of the input file where a definition was found + # into the output definition. + # If no argument is supplied, the format will be: + # @example + # srcfile = '%s'; + # @end example + # If an argument is supplied, that string will be used for the entry + # name instead of @var{srcfile}. + # Example: + # + #srcfile file + + # linenum -- Insert source line number into each def + # + # + # + # + # Inserts the line number in the input file where a definition + # was found into the output definition. + # If no argument is supplied, the format will be: + # @example + # linenum = '%s'; + # @end example + # If an argument is supplied, that string will be used for the entry + # name instead of @var{linenum}. + # Example: + # + #linenum def-name + + # input -- Input file to search for defs + # + # + # + # + # All files that are to be searched for definitions must be named on + # the command line or read from @code{stdin}. If there is only one + # @code{input} option and it is the string, "-", then the input file + # list is read from @code{stdin}. If a command line argument is not + # an option name and does not contain an assignment operator + # (@code{=}), then it defaults to being an input file name. + # At least one input file must be specified. + # Example: + # + #input src-file + + # output -- Output file to open + # + # + # + # + # If you are not sending the output to an AutoGen process, + # you may name an output file instead. + # Example: + # + #output file + + # autogen -- Invoke AutoGen with defs + # + # + # + # + # This is the default output mode. Specifying @code{no-autogen} is + # equivalent to @code{output=-}. If you supply an argument to this + # option, that program will be started as if it were AutoGen and + # its standard in will be set to the output definitions of this program. + # Example: + # + #autogen ag-cmd + + # template -- Template Name + # + # + # + # + # Specifies the template name to be used for generating the final output. + # Example: + # + #template file + + # agarg -- AutoGen Argument + # + # + # + # + # This is a pass-through argument. It allows you to specify any + # arbitrary argument to be passed to AutoGen. + # Example: + # + #agarg ag-opt + + # base_name -- Base name for output file(s) + # + # + # + # + # When output is going to AutoGen, a base name must either be supplied + # or derived. If this option is not supplied, then it is taken from + # the @code{template} option. If that is not provided either, then + # it is set to the base name of the current directory. + # Example: + # + #base_name name + + +File: autogen.info, Node: environrc, Next: config example, Prev: sample rcfile, Up: Presetting Options + +7.10.4 environment variable presets +----------------------------------- + +If the AutoOpts client program specifies 'environrc' in its option +descriptor file, then environment variables will be used for presetting +option state. Variables will be looked for that are named, +'PROGRAM_OPTNAME' and 'PROGRAM'. 'PROGRAM' is the upper cased 'C-name' +of the program, and OPTNAME is the upper cased 'C-name' of a specific +option. (The 'C-name's are the regular names with all special +characters converted to underscores ('_').) + + Option specific environment variables are processed after (and thus +take precedence over) the contents of the 'PROGRAM' environment +variable. The option argument string for these options takes on the +string value gotten from the environment. Consequently, you can only +have one instance of the OPTNAME. + + If a particular option may be disabled, then its disabled state is +indicated by setting the 'PROGRAM_OPTNAME' value to the disablement +prefix. So, for example, if the disablement prefix were 'dont', then +you can disable the 'optname' option by setting the 'PROGRAM_OPTNAME'' +environment variable to 'dont'. *Note Common Attributes::. + + The 'PROGRAM' environment string is tokenized and parsed much like a +command line. Doubly quoted strings have backslash escapes processed +the same way they are processed in C program constant strings. Singly +quoted strings are pretty raw in that backslashes are honored before +other backslashes, apostrophes, newlines and cr/newline pairs. The +options must be introduced with hyphens in the same way as the command +line. + + Note that not all options may be preset. Options that are specified +with the 'no-preset' attribute and the '--help', '--more-help', and +'--save-opts' auto-supported options may not be preset. + + +File: autogen.info, Node: config example, Prev: environrc, Up: Presetting Options + +7.10.5 Config file only example +------------------------------- + +If for some reason it is difficult or unworkable to integrate +configuration file processing with command line option parsing, the +'libopts' (*note libopts procedures::) library can still be used to +process configuration files. Below is a Hello, World! greeting program +that tries to load a configuration file 'hello.conf' to see if it should +use an alternate greeting or to personalize the salutation. + #include <config.h> + #include <sys/types.h> + #include <stdio.h> + #include <pwd.h> + #include <string.h> + #ifdef HAVE_UNISTD_H + #include <unistd.h> + #endif + #include <autoopts/options.h> + int main(int argc, char ** argv) { + char const * greeting = "Hello"; + char const * greeted = "World"; + tOptionValue const * pOV = configFileLoad("hello.conf"); + + if (pOV != NULL) { + const tOptionValue* pGetV = optionGetValue(pOV, "greeting"); + + if ( (pGetV != NULL) + && (pGetV->valType == OPARG_TYPE_STRING)) + greeting = strdup(pGetV->v.strVal); + + pGetV = optionGetValue(pOV, "personalize"); + if (pGetV != NULL) { + struct passwd * pwe = getpwuid(getuid()); + if (pwe != NULL) + greeted = strdup(pwe->pw_gecos); + } + + optionUnloadNested(pOV); /* deallocate config data */ + } + printf("%s, %s!\n", greeting, greeted); + return 0; + } + +With that text in a file named "hello.c", this short script: + + cc -o hello hello.c `autoopts-config cflags ldflags` + ./hello + echo 'greeting Buzz off' > hello.conf + ./hello + echo personalize > hello.conf + ./hello + +will produce the following output: + + Hello, World! + Buzz off, World! + Hello, Bruce Korb,,,! + + +File: autogen.info, Node: Config File Format, Next: shell options, Prev: Presetting Options, Up: AutoOpts + +7.11 Configuration File Format +============================== + +The configuration file is designed to associate names and values, much +like an AutoGen Definition File (*note Definitions File::). +Unfortunately, the file formats are different. Specifically, AutoGen +Definitions provide for simpler methods for the precise control of a +value string and provides for dynamically computed content. +Configuration files have some established traditions in their layout. +So, they are different, even though they do both allow for a single name +to be associated with multiple values and they both allow for +hierarchical values. + +* Menu: + +* config name/string-value:: assigning a string value to a configurable +* config integer-values:: integer values +* config nested-values:: hierarchical values +* config directives:: configuration file directives +* config comments:: comments in the configuration file + + +File: autogen.info, Node: config name/string-value, Next: config integer-values, Up: Config File Format + +7.11.1 assigning a string value to a configurable +------------------------------------------------- + +The basic syntax is a name followed by a value on a single line. They +are separated from each other by either white space, a colon (':') or an +equal sign ('='). The colon or equal sign may optionally be surrounded +by additional white space. If more than one value line is needed, a +backslash ('\') may be used to continue the value. The backslash (but +not the newline) will be erased. Leading and trailing white space is +always stripped from the value. + + Fundamentally, it looks like this: + + name value for that name + name = another \ + multi-line value \ + for that name. + name: a *third* value for name + + If you need more control over the content of the value, you may +enclose the value in XML style brackets: + <name>value </name> +Within these brackets you need not (must not) continue the value data +with backslashes. You may also select the string formation rules to +use, just add the attribute after the name, thus: '<name keep>'. + +'keep' + This mode will keep all text between the brackets and not strip any + white space. +'uncooked' + This mode strips leading and trailing white space, but not do any + quote processing. This is the default and need not be specified. +'cooked' + The text is trimmed of leading and trailing white space and XML + encodings are processed. These encodings are slightly expanded + over the XML specification. They are specified with an ampersand + followed by a value name or numeric value and then a semicolon: + + 'amp' + 'lt' + 'gt' + 'quot' + 'apos' + '#dd' + '#xHH' + + These are all per fairly standad HTML and/or XML encodings. + Additionally: + + 'bs' + The ASCII back space character. + 'ff' + The ASCII form feed character. + 'ht' + The ASCII horizontal (normal) tab character. + 'cr' + The ASCII carriage return character. + 'vt' + The ASCII vertical tab character. + 'bel' + The ASCII alarm bell character. + 'nl' + The ASCII new line character. + 'space' + The ASCII space character. Normally not necessary, but if you + want to preserve leading or trailing space characters, then + use this. + + And here is an example of an XML-styled value: + + <name cooked> + This is&nl;&ht;another multi-line + &ht;string example. + </name> + + The string value associated with 'name' will be exactly the text +enclosed in quotes with the encoded characters 'cooked' as you would +expect (three text lines with the last line not ending with a newline, +but ending with a period). + + +File: autogen.info, Node: config integer-values, Next: config nested-values, Prev: config name/string-value, Up: Config File Format + +7.11.2 integer values +--------------------- + +A name can be specified as having an integer value. To do this, you +must use the XML-ish format and specify a 'type' attribute for the name: + + <name type=integer> 1234 </name> + + Boolean, enumeration and set membership types will be added as time +allows. 'type=string' is also supported, but also is the default. + + +File: autogen.info, Node: config nested-values, Next: config directives, Prev: config integer-values, Up: Config File Format + +7.11.3 hierarchical values +-------------------------- + +In order to specify a hierarchical value, you *must* use XML-styled +formatting, specifying a type that is shorter and easier to spell: + + <structured-name type=nested> + [[....]] + </structured-name> + +The ellipsis may be filled with any legal configuration file name/value +assignments. + + +File: autogen.info, Node: config directives, Next: config comments, Prev: config nested-values, Up: Config File Format + +7.11.4 configuration file directives +------------------------------------ + +The '<?' marker indicates an XML directive. There is only one directive +supported: program sectioning, though two syntaxes are supported. + + If, for example, you have a collection of programs that work closely +together and, likely, have a common set of options, these programs may +use a single, sectioned, configuration file. The file may be sectioned +in either of two ways. The two ways may not be intermixed in a single +configuration file. All text before the first segmentation line is +processed, then only the segment that applies: + +'<?auto-options ...>' + The '...' ellipsis may contain AutoOpts option processing options. + Currently, that consists of one or both of: + + 'gnu' + 'autoopts' + to indicate GNU-standard or AutoOpts-standard layout of usage + and version information, and/or + + 'misuse-usage' + 'no-misuse-usage' + to indicate whether the available options should be listed + when an invalid option appears on the command line. + Anything else will be silently ignored. + +'<?program prog-name>' + The '<?' marker indicates an XML directive. The file is + partitioned by these lines and the options are processed for the + 'prog-name' program only before the first '<?program' directive and + the program section with a matching program name. + +'[PROG_NAME]' + This is basically an alias for '<?program prog-name>', except that + the program name must be upper cased and segmented only with + underscores and it is *not* recognized as a program segment when + updating configuration files with the '--save-opts' option. In + other words, use this only for Windows compatibility. + +Segmentation does not apply if the config file is being parsed with the +'configFileLoad(3AutoOpts)' function. + + +File: autogen.info, Node: config comments, Prev: config directives, Up: Config File Format + +7.11.5 comments in the configuration file +----------------------------------------- + +Comments are lines beginning with a hash mark ('#'), XML-style comments +('<!-- arbitrary text -->'), and unrecognized XML directives. + + # this is a comment + <!-- this is also + a comment --> + <?this is + a bad comment ;-> + + +File: autogen.info, Node: shell options, Next: AutoInfo, Prev: Config File Format, Up: AutoOpts + +7.12 AutoOpts for Shell Scripts +=============================== + +AutoOpts may be used with shell scripts either by automatically creating +a complete program that will process command line options and pass back +the results to the invoking shell by issuing shell variable assignment +commands, or it may be used to generate portable shell code that can be +inserted into your script. + + The functionality of these features, of course, is somewhat +constrained compared with the normal program facilities. Specifically, +you cannot invoke callout procedures with either of these methods. +Additionally, if you generate a shell script to do the parsing: + + 1. You cannot obtain options from configuration files. + 2. You cannot obtain options from environment variables. + 3. You cannot save the option state to an option file. + 4. Option conflict/requirement verification is disabled. + + Both of these methods are enabled by running AutoGen on the +definitions file with the additional main procedure attribute: + + main = { main-type = shell-process; }; +or: + main = { main-type = shell-parser; }; + + If you do not supply a 'proc-to-call', it will default to +'optionPutShell'. That will produce a program that will process the +options and generate shell text for the invoking shell to interpret +(*note binary-parser::). If you supply the name, 'optionParseShell', +then you will have a program that will generate a shell script that can +parse the options (*note script-parser::). If you supply a different +procedure name, you will have to provide that routine and it may do +whatever you like. + +* Menu: + +* binary-parser:: Parsing with an Executable +* script-parser:: Parsing with a Portable Script + + +File: autogen.info, Node: binary-parser, Next: script-parser, Up: shell options + +7.12.1 Parsing with an Executable +--------------------------------- + +The following commands are approximately all that is needed to build a +shell script command line option parser from an option definition file: + + autogen -L <opt-template-dir> test-errors.def + cc -o test-errors -L <opt-lib-dir> -I <opt-include-dir> \ + -DTEST_PROGRAM_OPTS test-errors.c -lopts + + The resulting program can then be used within your shell script as +follows: + + eval `./test-errors "$@"` + if [ -z "${OPTION_CT}" ] ; then exit 1 ; fi + test ${OPTION_CT} -gt 0 && shift ${OPTION_CT} + + Here is the usage output example from AutoOpts error handling tests. +The option definition has argument reordering enabled: + + test_errors - Test AutoOpts for errors + Usage: errors [ -<flag> [<val>] | --<name>[{=| }<val>] ]... arg ... + Flg Arg Option-Name Description + -o no option The option option descrip + -s Str second The second option descrip + - may appear up to 10 times + -i --- ignored we have dumped this + -X no another Another option descrip + - may appear up to 5 times + -? no help display extended usage information and exit + -! no more-help extended usage information passed thru pager + -> opt save-opts save the option state to a config file + -< Str load-opts load options from a config file + - disabled as '--no-load-opts' + - may appear multiple times + + Options are specified by doubled hyphens and their name or by a single + hyphen and the flag character. + Operands and options may be intermixed. They will be reordered. + + The following option preset mechanisms are supported: + - reading file errorsRC + + Using the invocation, + test-errors operand1 -s first operand2 -X -- -s operand3 + you get the following output for your shell script to evaluate: + + OPTION_CT=4 + export OPTION_CT + TEST_ERRORS_SECOND='first' + export TEST_ERRORS_SECOND + TEST_ERRORS_ANOTHER=1 # 0x1 + export TEST_ERRORS_ANOTHER + set -- 'operand1' 'operand2' '-s' 'operand3' + OPTION_CT=0 + + +File: autogen.info, Node: script-parser, Prev: binary-parser, Up: shell options + +7.12.2 Parsing with a Portable Script +------------------------------------- + +If you had used 'test-main = optionParseShell' instead, then you can, at +this point, merely run the program and it will write the parsing script +to standard out. You may also provide this program with command line +options to specify the shell script file to create or edit, and you may +specify the shell program to use on the first shell script line. That +program's usage text would look something like the following and the +script parser itself would be very verbose: + + genshellopt - Generate Shell Option Processing Script - Ver. 1 + Usage: genshellopt [ -<flag> [<val>] | --<name>[{=| }<val>] ]... + Flg Arg Option-Name Description + -o Str script Output Script File + -s Str shell Shell name (follows "#!" magic) + - disabled as '--no-shell' + - enabled by default + -v opt version output version information and exit + -? no help display extended usage information and exit + -! no more-help extended usage information passed thru pager + + Options are specified by doubled hyphens and their name or by a single + hyphen and the flag character. + Note that 'shell' is only useful if the output file does not already exist. + If it does, then the shell name and optional first argument will be + extracted from the script file. + If the script file already exists and contains Automated Option Processing + text, the second line of the file through the ending tag will be replaced + by the newly generated text. The first '#!' line will be regenerated. + + Please send bug reports to: <autogen-users@lists.sourceforge.net> + + = = = = = = = = + + This incarnation of genshell will produce + a shell script to parse the options for getdefs: + + getdefs (GNU AutoGen) - AutoGen Definition Extraction Tool - Ver. 1.5 + Usage: getdefs [ <option-name>[{=| }<val>] ]... + Arg Option-Name Description + Str defs-to-get Regexp to look for after the "/*=" + Str subblock subblock definition names + Str listattr attribute with list of values + opt ordering Alphabetize or use named file + Num first-index The first index to apply to groups + opt filelist Insert source file names into defs + Str assign Global assignments + Str common-assign Assignments common to all blocks + Str copy File(s) to copy into definitions + opt srcfile Insert source file name into each def + opt linenum Insert source line number into each def + Str input Input file to search for defs + Str output Output file to open + opt autogen Invoke AutoGen with defs + Str template Template Name + Str agarg AutoGen Argument + Str base-name Base name for output file(s) + +Resulting in the following script: + #! /bin/sh + # # # # # # # # # # -- do not modify this marker -- + # + # DO NOT EDIT THIS SECTION + OF /u/bkorb/tools/ag/autogen-bld/doc/ag-texi-32340.d/.ag-5GQlKL/genshellopt.sh + # + # From here to the next `-- do not modify this marker --', + # the text has been generated Sunday August 26, 2018 at 10:46:02 AM PDT + # From the GETDEFS option definitions + # + GETDEFS_LONGUSAGE_TEXT='getdefs error: invalid option descriptor for version + getdefs (GNU AutoGen) - AutoGen Definition Extraction Tool - Ver. 1.5 + Usage: getdefs [ <option-name>[{=| }<val>] ]... + + Specify which definitions are of interest and what to say about them: + + Arg Option-Name Description + Str defs-to-get Regexp to look for after the "/*=" + Str subblock subblock definition names + - may appear multiple times + Str listattr attribute with list of values + - may appear multiple times + + specify how to number the definitions: + + Arg Option-Name Description + opt ordering Alphabetize or use named file + - disabled as '\''--no-ordering'\'' + - enabled by default + Num first-index The first index to apply to groups + + Definition insertion options: + + Arg Option-Name Description + opt filelist Insert source file names into defs + Str assign Global assignments + - may appear multiple times + Str common-assign Assignments common to all blocks + - may appear multiple times + Str copy File(s) to copy into definitions + - may appear multiple times + opt srcfile Insert source file name into each def + opt linenum Insert source line number into each def + + specify which files to search for markers: + + Arg Option-Name Description + Str input Input file to search for defs + - may appear multiple times + - default option for unnamed options + + Definition output disposition options:: + + Arg Option-Name Description + Str output Output file to open + - an alternate for '\''autogen'\'' + opt autogen Invoke AutoGen with defs + - disabled as '\''--no-autogen'\'' + - enabled by default + Str template Template Name + Str agarg AutoGen Argument + - prohibits the option '\''output'\'' + - may appear multiple times + Str base-name Base name for output file(s) + - prohibits the option '\''output'\'' + + Version, usage and configuration options: + + Arg Option-Name Description + ' + + GETDEFS_USAGE_TEXT='getdefs (GNU AutoGen) - AutoGen Definition Extraction Tool - Ver. 1.5 + Usage: getdefs [ <option-name>[{=| }<val>] ]... + Arg Option-Name Description + Str defs-to-get Regexp to look for after the "/*=" + Str subblock subblock definition names + Str listattr attribute with list of values + opt ordering Alphabetize or use named file + Num first-index The first index to apply to groups + opt filelist Insert source file names into defs + Str assign Global assignments + Str common-assign Assignments common to all blocks + Str copy File(s) to copy into definitions + opt srcfile Insert source file name into each def + opt linenum Insert source line number into each def + Str input Input file to search for defs + Str output Output file to open + opt autogen Invoke AutoGen with defs + Str template Template Name + Str agarg AutoGen Argument + Str base-name Base name for output file(s) + getdefs error: invalid option descriptor for version' + + + GETDEFS_DEFS_TO_GET=${GETDEFS_DEFS_TO_GET} + GETDEFS_DEFS_TO_GET_set=false + export GETDEFS_DEFS_TO_GET + + if test -z "${GETDEFS_SUBBLOCK}" + then + GETDEFS_SUBBLOCK_CT=0 + export GETDEFS_SUBBLOCK_CT + else + GETDEFS_SUBBLOCK_CT=1 + GETDEFS_SUBBLOCK_1=${GETDEFS_SUBBLOCK} + export GETDEFS_SUBBLOCK_CT GETDEFS_SUBBLOCK_1 + fi + + if test -z "${GETDEFS_LISTATTR}" + then + GETDEFS_LISTATTR_CT=0 + export GETDEFS_LISTATTR_CT + else + GETDEFS_LISTATTR_CT=1 + GETDEFS_LISTATTR_1=${GETDEFS_LISTATTR} + export GETDEFS_LISTATTR_CT GETDEFS_LISTATTR_1 + fi + + GETDEFS_ORDERING=${GETDEFS_ORDERING} + GETDEFS_ORDERING_set=false + export GETDEFS_ORDERING + + GETDEFS_FIRST_INDEX=${GETDEFS_FIRST_INDEX-'0'} + GETDEFS_FIRST_INDEX_set=false + export GETDEFS_FIRST_INDEX + + GETDEFS_FILELIST=${GETDEFS_FILELIST} + GETDEFS_FILELIST_set=false + export GETDEFS_FILELIST + + if test -z "${GETDEFS_ASSIGN}" + then + GETDEFS_ASSIGN_CT=0 + export GETDEFS_ASSIGN_CT + else + GETDEFS_ASSIGN_CT=1 + GETDEFS_ASSIGN_1=${GETDEFS_ASSIGN} + export GETDEFS_ASSIGN_CT GETDEFS_ASSIGN_1 + fi + + if test -z "${GETDEFS_COMMON_ASSIGN}" + then + GETDEFS_COMMON_ASSIGN_CT=0 + export GETDEFS_COMMON_ASSIGN_CT + else + GETDEFS_COMMON_ASSIGN_CT=1 + GETDEFS_COMMON_ASSIGN_1=${GETDEFS_COMMON_ASSIGN} + export GETDEFS_COMMON_ASSIGN_CT GETDEFS_COMMON_ASSIGN_1 + fi + + if test -z "${GETDEFS_COPY}" + then + GETDEFS_COPY_CT=0 + export GETDEFS_COPY_CT + else + GETDEFS_COPY_CT=1 + GETDEFS_COPY_1=${GETDEFS_COPY} + export GETDEFS_COPY_CT GETDEFS_COPY_1 + fi + + GETDEFS_SRCFILE=${GETDEFS_SRCFILE} + GETDEFS_SRCFILE_set=false + export GETDEFS_SRCFILE + + GETDEFS_LINENUM=${GETDEFS_LINENUM} + GETDEFS_LINENUM_set=false + export GETDEFS_LINENUM + + if test -z "${GETDEFS_INPUT}" + then + GETDEFS_INPUT_CT=0 + export GETDEFS_INPUT_CT + else + GETDEFS_INPUT_CT=1 + GETDEFS_INPUT_1=${GETDEFS_INPUT} + export GETDEFS_INPUT_CT GETDEFS_INPUT_1 + fi + + GETDEFS_OUTPUT=${GETDEFS_OUTPUT} + GETDEFS_OUTPUT_set=false + export GETDEFS_OUTPUT + + GETDEFS_AUTOGEN=${GETDEFS_AUTOGEN} + GETDEFS_AUTOGEN_set=false + export GETDEFS_AUTOGEN + + GETDEFS_TEMPLATE=${GETDEFS_TEMPLATE} + GETDEFS_TEMPLATE_set=false + export GETDEFS_TEMPLATE + + if test -z "${GETDEFS_AGARG}" + then + GETDEFS_AGARG_CT=0 + export GETDEFS_AGARG_CT + else + GETDEFS_AGARG_CT=1 + GETDEFS_AGARG_1=${GETDEFS_AGARG} + export GETDEFS_AGARG_CT GETDEFS_AGARG_1 + fi + + GETDEFS_BASE_NAME=${GETDEFS_BASE_NAME} + GETDEFS_BASE_NAME_set=false + export GETDEFS_BASE_NAME + + ARG_COUNT=$# + OPT_ARG=$1 + while [ $# -gt 0 ] + do + OPT_ELEMENT='' + OPT_ARG_VAL='' + OPT_ARG=${1} + OPT_CODE=`echo "X${OPT_ARG}"|sed 's/^X-*//'` + shift + OPT_ARG=$1 + case "${OPT_CODE}" in *=* ) + OPT_ARG_VAL=`echo "${OPT_CODE}"|sed 's/^[^=]*=//'` + OPT_CODE=`echo "${OPT_CODE}"|sed 's/=.*$//'` ;; esac + case "${OPT_CODE}" in + 'de' | \ + 'def' | \ + 'defs' | \ + 'defs-' | \ + 'defs-t' | \ + 'defs-to' | \ + 'defs-to-' | \ + 'defs-to-g' | \ + 'defs-to-ge' | \ + 'defs-to-get' ) + if [ -n "${GETDEFS_DEFS_TO_GET}" ] && ${GETDEFS_DEFS_TO_GET_set} ; then + echo 'Error: duplicate DEFS_TO_GET option' + echo "$GETDEFS_USAGE_TEXT" + exit 1 + fi >&2 + GETDEFS_DEFS_TO_GET_set=true + OPT_NAME='DEFS_TO_GET' + OPT_ARG_NEEDED=YES + ;; + + 'su' | \ + 'sub' | \ + 'subb' | \ + 'subbl' | \ + 'subblo' | \ + 'subbloc' | \ + 'subblock' ) + GETDEFS_SUBBLOCK_CT=`expr ${GETDEFS_SUBBLOCK_CT} + 1` + OPT_ELEMENT="_${GETDEFS_SUBBLOCK_CT}" + OPT_NAME='SUBBLOCK' + OPT_ARG_NEEDED=YES + ;; + + 'li' | \ + 'lis' | \ + 'list' | \ + 'lista' | \ + 'listat' | \ + 'listatt' | \ + 'listattr' ) + GETDEFS_LISTATTR_CT=`expr ${GETDEFS_LISTATTR_CT} + 1` + OPT_ELEMENT="_${GETDEFS_LISTATTR_CT}" + OPT_NAME='LISTATTR' + OPT_ARG_NEEDED=YES + ;; + + 'or' | \ + 'ord' | \ + 'orde' | \ + 'order' | \ + 'orderi' | \ + 'orderin' | \ + 'ordering' ) + if [ -n "${GETDEFS_ORDERING}" ] && ${GETDEFS_ORDERING_set} ; then + echo 'Error: duplicate ORDERING option' + echo "$GETDEFS_USAGE_TEXT" + exit 1 + fi >&2 + GETDEFS_ORDERING_set=true + OPT_NAME='ORDERING' + eval GETDEFS_ORDERING${OPT_ELEMENT}=true + export GETDEFS_ORDERING${OPT_ELEMENT} + OPT_ARG_NEEDED=OK + ;; + + 'no-' | \ + 'no-o' | \ + 'no-or' | \ + 'no-ord' | \ + 'no-orde' | \ + 'no-order' | \ + 'no-orderi' | \ + 'no-orderin' | \ + 'no-ordering' ) + if [ -n "${GETDEFS_ORDERING}" ] && ${GETDEFS_ORDERING_set} ; then + echo 'Error: duplicate ORDERING option' + echo "$GETDEFS_USAGE_TEXT" + exit 1 + fi >&2 + GETDEFS_ORDERING_set=true + GETDEFS_ORDERING='no' + export GETDEFS_ORDERING + OPT_NAME='ORDERING' + OPT_ARG_NEEDED=NO + ;; + + 'fi' | \ + 'fir' | \ + 'firs' | \ + 'first' | \ + 'first-' | \ + 'first-i' | \ + 'first-in' | \ + 'first-ind' | \ + 'first-inde' | \ + 'first-index' ) + if [ -n "${GETDEFS_FIRST_INDEX}" ] && ${GETDEFS_FIRST_INDEX_set} ; then + echo 'Error: duplicate FIRST_INDEX option' + echo "$GETDEFS_USAGE_TEXT" + exit 1 + fi >&2 + GETDEFS_FIRST_INDEX_set=true + OPT_NAME='FIRST_INDEX' + OPT_ARG_NEEDED=YES + ;; + + 'fi' | \ + 'fil' | \ + 'file' | \ + 'filel' | \ + 'fileli' | \ + 'filelis' | \ + 'filelist' ) + if [ -n "${GETDEFS_FILELIST}" ] && ${GETDEFS_FILELIST_set} ; then + echo 'Error: duplicate FILELIST option' + echo "$GETDEFS_USAGE_TEXT" + exit 1 + fi >&2 + GETDEFS_FILELIST_set=true + OPT_NAME='FILELIST' + eval GETDEFS_FILELIST${OPT_ELEMENT}=true + export GETDEFS_FILELIST${OPT_ELEMENT} + OPT_ARG_NEEDED=OK + ;; + + 'as' | \ + 'ass' | \ + 'assi' | \ + 'assig' | \ + 'assign' ) + GETDEFS_ASSIGN_CT=`expr ${GETDEFS_ASSIGN_CT} + 1` + OPT_ELEMENT="_${GETDEFS_ASSIGN_CT}" + OPT_NAME='ASSIGN' + OPT_ARG_NEEDED=YES + ;; + + 'co' | \ + 'com' | \ + 'comm' | \ + 'commo' | \ + 'common' | \ + 'common-' | \ + 'common-a' | \ + 'common-as' | \ + 'common-ass' | \ + 'common-assi' | \ + 'common-assig' | \ + 'common-assign' ) + GETDEFS_COMMON_ASSIGN_CT=`expr ${GETDEFS_COMMON_ASSIGN_CT} + 1` + OPT_ELEMENT="_${GETDEFS_COMMON_ASSIGN_CT}" + OPT_NAME='COMMON_ASSIGN' + OPT_ARG_NEEDED=YES + ;; + + 'co' | \ + 'cop' | \ + 'copy' ) + GETDEFS_COPY_CT=`expr ${GETDEFS_COPY_CT} + 1` + OPT_ELEMENT="_${GETDEFS_COPY_CT}" + OPT_NAME='COPY' + OPT_ARG_NEEDED=YES + ;; + + 'sr' | \ + 'src' | \ + 'srcf' | \ + 'srcfi' | \ + 'srcfil' | \ + 'srcfile' ) + if [ -n "${GETDEFS_SRCFILE}" ] && ${GETDEFS_SRCFILE_set} ; then + echo 'Error: duplicate SRCFILE option' + echo "$GETDEFS_USAGE_TEXT" + exit 1 + fi >&2 + GETDEFS_SRCFILE_set=true + OPT_NAME='SRCFILE' + eval GETDEFS_SRCFILE${OPT_ELEMENT}=true + export GETDEFS_SRCFILE${OPT_ELEMENT} + OPT_ARG_NEEDED=OK + ;; + + 'li' | \ + 'lin' | \ + 'line' | \ + 'linen' | \ + 'linenu' | \ + 'linenum' ) + if [ -n "${GETDEFS_LINENUM}" ] && ${GETDEFS_LINENUM_set} ; then + echo 'Error: duplicate LINENUM option' + echo "$GETDEFS_USAGE_TEXT" + exit 1 + fi >&2 + GETDEFS_LINENUM_set=true + OPT_NAME='LINENUM' + eval GETDEFS_LINENUM${OPT_ELEMENT}=true + export GETDEFS_LINENUM${OPT_ELEMENT} + OPT_ARG_NEEDED=OK + ;; + + 'in' | \ + 'inp' | \ + 'inpu' | \ + 'input' ) + GETDEFS_INPUT_CT=`expr ${GETDEFS_INPUT_CT} + 1` + OPT_ELEMENT="_${GETDEFS_INPUT_CT}" + OPT_NAME='INPUT' + OPT_ARG_NEEDED=YES + ;; + + 'ou' | \ + 'out' | \ + 'outp' | \ + 'outpu' | \ + 'output' ) + if [ -n "${GETDEFS_OUTPUT}" ] && ${GETDEFS_OUTPUT_set} ; then + echo 'Error: duplicate OUTPUT option' + echo "$GETDEFS_USAGE_TEXT" + exit 1 + fi >&2 + GETDEFS_OUTPUT_set=true + OPT_NAME='OUTPUT' + OPT_ARG_NEEDED=YES + ;; + + 'au' | \ + 'aut' | \ + 'auto' | \ + 'autog' | \ + 'autoge' | \ + 'autogen' ) + if [ -n "${GETDEFS_AUTOGEN}" ] && ${GETDEFS_AUTOGEN_set} ; then + echo 'Error: duplicate AUTOGEN option' + echo "$GETDEFS_USAGE_TEXT" + exit 1 + fi >&2 + GETDEFS_AUTOGEN_set=true + OPT_NAME='AUTOGEN' + eval GETDEFS_AUTOGEN${OPT_ELEMENT}=true + export GETDEFS_AUTOGEN${OPT_ELEMENT} + OPT_ARG_NEEDED=OK + ;; + + 'no-' | \ + 'no-a' | \ + 'no-au' | \ + 'no-aut' | \ + 'no-auto' | \ + 'no-autog' | \ + 'no-autoge' | \ + 'no-autogen' ) + if [ -n "${GETDEFS_AUTOGEN}" ] && ${GETDEFS_AUTOGEN_set} ; then + echo 'Error: duplicate AUTOGEN option' + echo "$GETDEFS_USAGE_TEXT" + exit 1 + fi >&2 + GETDEFS_AUTOGEN_set=true + GETDEFS_AUTOGEN='no' + export GETDEFS_AUTOGEN + OPT_NAME='AUTOGEN' + OPT_ARG_NEEDED=NO + ;; + + 'te' | \ + 'tem' | \ + 'temp' | \ + 'templ' | \ + 'templa' | \ + 'templat' | \ + 'template' ) + if [ -n "${GETDEFS_TEMPLATE}" ] && ${GETDEFS_TEMPLATE_set} ; then + echo 'Error: duplicate TEMPLATE option' + echo "$GETDEFS_USAGE_TEXT" + exit 1 + fi >&2 + GETDEFS_TEMPLATE_set=true + OPT_NAME='TEMPLATE' + OPT_ARG_NEEDED=YES + ;; + + 'ag' | \ + 'aga' | \ + 'agar' | \ + 'agarg' ) + GETDEFS_AGARG_CT=`expr ${GETDEFS_AGARG_CT} + 1` + OPT_ELEMENT="_${GETDEFS_AGARG_CT}" + OPT_NAME='AGARG' + OPT_ARG_NEEDED=YES + ;; + + 'ba' | \ + 'bas' | \ + 'base' | \ + 'base-' | \ + 'base-n' | \ + 'base-na' | \ + 'base-nam' | \ + 'base-name' ) + if [ -n "${GETDEFS_BASE_NAME}" ] && ${GETDEFS_BASE_NAME_set} ; then + echo 'Error: duplicate BASE_NAME option' + echo "$GETDEFS_USAGE_TEXT" + exit 1 + fi >&2 + GETDEFS_BASE_NAME_set=true + OPT_NAME='BASE_NAME' + OPT_ARG_NEEDED=YES + ;; + + 've' | \ + 'ver' | \ + 'vers' | \ + 'versi' | \ + 'versio' | \ + 'version' ) + echo "$GETDEFS_LONGUSAGE_TEXT" + exit 0 + ;; + + 'he' | \ + 'hel' | \ + 'help' ) + echo "$GETDEFS_LONGUSAGE_TEXT" + exit 0 + ;; + + 'mo' | \ + 'mor' | \ + 'more' | \ + 'more-' | \ + 'more-h' | \ + 'more-he' | \ + 'more-hel' | \ + 'more-help' ) + echo "$GETDEFS_LONGUSAGE_TEXT" | ${PAGER-more} + exit 0 + ;; + + 'sa' | \ + 'sav' | \ + 'save' | \ + 'save-' | \ + 'save-o' | \ + 'save-op' | \ + 'save-opt' | \ + 'save-opts' ) + echo 'Warning: Cannot save options files' >&2 + OPT_ARG_NEEDED=OK + ;; + + 'lo' | \ + 'loa' | \ + 'load' | \ + 'load-' | \ + 'load-o' | \ + 'load-op' | \ + 'load-opt' | \ + 'load-opts' ) + echo 'Warning: Cannot load options files' >&2 + OPT_ARG_NEEDED=YES + ;; + + 'no-' | \ + 'no-l' | \ + 'no-lo' | \ + 'no-loa' | \ + 'no-load' | \ + 'no-load-' | \ + 'no-load-o' | \ + 'no-load-op' | \ + 'no-load-opt' | \ + 'no-load-opts' ) + echo 'Warning: Cannot suppress the loading of options files' >&2 + OPT_ARG_NEEDED=NO + ;; + + * ) + echo Unknown option: "${OPT_CODE}" >&2 + echo "$GETDEFS_USAGE_TEXT" >&2 + exit 1 + ;; + esac + case "${OPT_ARG_NEEDED}" in + NO ) + OPT_ARG_VAL='' + ;; + YES ) + if [ -z "${OPT_ARG_VAL}" ] + then + if [ $# -eq 0 ] + then + echo No argument provided for ${OPT_NAME} option + echo "$GETDEFS_USAGE_TEXT" + exit 1 + fi >&2 + OPT_ARG_VAL=${OPT_ARG} + shift + OPT_ARG=$1 + fi + ;; + OK ) + if [ -z "${OPT_ARG_VAL}" ] && [ $# -gt 0 ] + then + case "${OPT_ARG}" in -* ) ;; * ) + OPT_ARG_VAL=${OPT_ARG} + shift + OPT_ARG=$1 ;; esac + fi + ;; + esac + if [ -n "${OPT_ARG_VAL}" ] + then + eval GETDEFS_${OPT_NAME}${OPT_ELEMENT}="'${OPT_ARG_VAL}'" + export GETDEFS_${OPT_NAME}${OPT_ELEMENT} + fi + done + OPTION_COUNT=`expr $ARG_COUNT - $#` + OPERAND_COUNT=$# + unset OPT_PROCESS || : + unset OPT_ELEMENT || : + unset OPT_ARG || : + unset OPT_ARG_NEEDED || : + unset OPT_NAME || : + unset OPT_CODE || : + unset OPT_ARG_VAL || : + + # # # # # # # # # # + # + # END OF AUTOMATED OPTION PROCESSING + # + # # # # # # # # # # -- do not modify this marker -- + + env | grep '^GETDEFS_' + + +File: autogen.info, Node: AutoInfo, Next: AutoMan pages, Prev: shell options, Up: AutoOpts + +7.13 Automated Info Docs +======================== + +AutoOpts provides two templates for producing '.texi' documentation. +'agtexi-cmd.tpl' for the invoking section, and 'aginfo3.tpl' for +describing exported library functions and macros. + + For both types of documents, the documentation level is selected by +passing a '-DLEVEL=<level-name>' argument to AutoGen when you build the +document. (See the example invocation below.) + + Two files will be produced, a '.texi' file and a '.menu' file. You +should include the text in the '.menu' file in a '@menu' list, either +with '@include'-ing it or just copying text. The '.texi' file should be +'@include'-ed where the invoking section belongs in your document. + + The '.texi' file will contain an introductory paragraph, a menu and a +subordinate section for the invocation usage and for each documented +option. The introductory paragraph is normally the boiler plate text, +along the lines of: + + This chapter documents the @file{AutoOpts} generated usage text + and option meanings for the @file{your-program} program. + +or: + + These are the publicly exported procedures from the libname library. + Any other functions mentioned in the header file are for the private use + of the library. + +* Menu: + +* command-info:: 'invoking' info docs +* library-info:: library info docs + + +File: autogen.info, Node: command-info, Next: library-info, Up: AutoInfo + +7.13.1 'invoking' info docs +--------------------------- + +Using the option definitions for an AutoOpt client program, the +'agtexi-cmd.tpl' template will produce texinfo text that documents the +invocation of your program. The text emitted is designed to be included +in the full texinfo document for your product. It is not a stand-alone +document. The usage text for the *note autogen usage::, *note getdefs +usage:: and *note columns usage:: programs, are included in this +document and are all generated using this template. + + If your program's option definitions include a 'prog-info-descrip' +section, then that text will replace the boilerplate introductory +paragraph. + +These files are produced by invoking the following command: + + autogen -L ${prefix}/share/autogen -Tagtexi-cmd.tpl \ + -DLEVEL=section your-opts.def + +Where '${prefix}' is the AutoGen installation prefix and 'your-opts.def' +is the name of your product's option definition file. + + +File: autogen.info, Node: library-info, Prev: command-info, Up: AutoInfo + +7.13.2 library info docs +------------------------ + +The 'texinfo' doc for libraries is derived from mostly the same +information as is used for producing man pages *Note man3::. The main +difference is that there is only one output file and the individual +functions are referenced from a 'texi' menu. There is also a small +difference in the global attributes used: + + lib_description A description of the library. This text + appears before the menu. If not provided, + the standard boilerplate version will be + inserted. + see_also The 'SEE ALSO' functionality is not supported + for the 'texinfo' documentation, so any + 'see_also' attribute will be ignored. + +These files are produced by invoking the following commands: + + getdefs linenum srcfile template=aginfo3.tpl output=libexport.def \ + <source-file-list> + + autogen -L ${prefix}/share/autogen -DLEVEL=section libexport.def + +Where '${prefix}' is the AutoGen installation prefix and 'libexport.def' +is some name that suits you. + + An example of this can be seen in this document, *Note libopts +procedures::. + + +File: autogen.info, Node: AutoMan pages, Next: getopt_long, Prev: AutoInfo, Up: AutoOpts + +7.14 Automated Man Pages +======================== + +AutoOpts provides two templates for producing man pages. The command +('man1') pages are derived from the options definition file, and the +library ('man3') pages are derived from stylized comments (*note getdefs +Invocation::). + + Man pages include a date in the footer. By default, this is derived +from the current date. However, this may be overridden with the +'MAN_PAGE_DATE' environment variable. If set and not empty, its +contents will be copied into where the output of 'date '+%d %b %Y'' +would otherwise go. + + Man pages may be formatted as either traditional man pages or using +'mdoc' formatting. The format is selected by selecting the appropriate +template. + +* Menu: + +* man1:: command line man pages +* man3:: library man pages + + +File: autogen.info, Node: man1, Next: man3, Up: AutoMan pages + +7.14.1 command line man pages +----------------------------- + +Man pages for commands are documented using the 'agman-cmd.tpl' and +'agmdoc-cmd.tpl' templates. If the options specify pulling information +from 'RC'/'ini'/'cfg' files, then you may use the 'rc-sample.tpl' +template to produce an example config file for your program. + + Using the option definitions for an AutoOpts client program, the +'agman-cmd.tpl' template will produce an nroff document suitable for use +as a 'man(1)' page document for a command line command. The description +section of the document is either the 'prog-man-descrip' text, if +present, or the 'detail' text. + + Each option in the option definitions file is fully documented in its +usage. This includes all the information documented above for each +option (*note option attributes::), plus the 'doc' attribute is +appended. Since the 'doc' text is presumed to be designed for 'texinfo' +documentation, 'sed' is used to convert some constructs from 'texi' to +'nroff'-for-'man'-pages. Specifically, + + convert @code, @var and @samp into \fB...\fP phrases + convert @file into \fI...\fP phrases + Remove the '@' prefix from curly braces + Indent example regions + Delete the example commands + Replace 'end example' command with ".br" + Replace the '@*' command with ".br" + +This document is produced by invoking the following command: + + autogen -L ${prefix}/share/autogen -Tagman-cmd.tpl options.def + +Where '${prefix}' is the AutoGen installation prefix and 'options.def' +is the name of your product's option definition file. I do not use this +very much, so any feedback or improvements would be greatly appreciated. + + +File: autogen.info, Node: man3, Prev: man1, Up: AutoMan pages + +7.14.2 library man pages +------------------------ + +Man pages for libraries are documented using the 'agman3.tpl' template. + + Two global definitions are required, and then one library man page is +produced for each 'export_func' definition that is found. It is +generally convenient to place these definitions as 'getdefs' comments +(*note getdefs Invocation::) near the procedure definition, but they may +also be a separate AutoGen definitions file (*note Definitions File::). +Each function will be cross referenced with their sister functions in a +'SEE ALSO' section. A global 'see_also' definition will be appended to +this cross referencing text. + +The two global definitions required are: + + library This is the name of your library, without the 'lib' + prefix. The AutoOpts library is named + 'libopts.so...', so the 'library' attribute would + have the value 'opts'. + header Generally, using a library with a compiled program + entails '#include'-ing a header file. Name that + header with this attribute. In the case of AutoOpts, + it is generated and will vary based on the name of + the option definition file. Consequently, + 'your-opts.h' is specified. + +The 'export_func' definition should contain the following attributes: + + name The name of the procedure the library user may call. + what A brief sentence describing what the procedure does. + doc A detailed description of what the procedure does. + It may ramble on for as long as necessary to properly + describe it. + err A short description of how errors are handled. + ret_type The data type returned by the procedure. Omit this + for 'void' procedures. + ret_desc Describe what the returned value is, if needed. + private If specified, the function will *not* be documented. + This is used, for example, to produce external + declarations for functions that are not available for + public use, but are used in the generated text. + arg This is a compound attribute that contains: + arg_type The data type of the argument. + arg_name A short name for it. + arg_desc A brief description. + +As a 'getdefs' comment, this would appear something like this: + + /*=--subblock=arg=arg_type,arg_name,arg_desc =*/ + /*=* + * library: opts + * header: your-opts.h + =*/ + /*=export_func optionProcess + * + * what: this is the main option processing routine + * arg: + tOptions* + pOpts + program options descriptor + + * arg: + int + argc + program arg count + + * arg: + char** + argv + program arg vector + + * ret_type: int + * ret_desc: the count of the arguments processed + * + * doc: This is what it does. + * err: When it can't, it does this. + =*/ + +Note the 'subblock' and 'library' comments. 'subblock' is an embedded +'getdefs' option (*note getdefs subblock::) that tells it how to parse +the 'arg' attribute. The 'library' and 'header' entries are global +definitions that apply to all the documented functions. + + +File: autogen.info, Node: getopt_long, Next: i18n, Prev: AutoMan pages, Up: AutoOpts + +7.15 Using getopt(3C) +===================== + +There is a template named, 'getopt.tpl' that is distributed with +AutoOpts. Using that template instead of 'options.tpl' will produce +completely independent source code that will parse command line options. +It will utilize either the standard 'getopt(3C)' or the GNU +'getopt_long(3GNU)' function to drive the parsing. Which is used is +selected by the presence or absence of the 'long-opts' program +attribute. It will save you from being dependent upon the 'libopts' +library and it produces code ready for internationalization. However, +it also carries with it some limitations on the use of AutoOpts features +and some requirements on the build environment. + + *PLEASE NOTE*: in processing the option definitions to produce the +usage text, it is necessary to compile some generated code in a +temporary directory. That means that all the include directories needed +to compile the code must be full path names and not relative directory +names. "." is a relative directory name. To specify "-I." in the +'CFLAGS' environment variable, you must expand it. For example, use: + CFLAGS=-I`pwd` + +* Menu: + +* getopt limitations:: getopt feature limitations +* getopt building:: getopt build requirements + + +File: autogen.info, Node: getopt limitations, Next: getopt building, Up: getopt_long + +7.15.1 getopt feature limitations +--------------------------------- + +This list of limitations is relative to the full list of AutoOpts +supported features, *Note Features::. + + 1. You cannot automatically take advantage of environment variable + options or automated parsing of configuration files ('rc' or 'ini' + files). Consequently, the resulting code does not support + '--load-opts' or '--save-opts' options automatically. + + 2. You cannot use set membership, enumerated, range checked or stacked + argument type options. In fact, you cannot use anything that + depends upon the 'libopts' library. You are constrained to options + that take 'string' arguments, though you may handle the option + argument with a callback procedure. + + 3. Special disablement and/or enablement prefixes are not recognized. + + 4. Option coordination with external libraries will not work. + + 5. Every option must be 'settable' because the emitted code depends + upon the 'SET_OPT_XXX' macros having been defined. Specify this as + a global (program) attribute. + + 6. You must specify a main procedure attribute (*note Generated + main::). The 'getopt.tpl' template depends upon being able to + compile the traditional .c file into a program and get it to emit + the usage text. + + 7. For the same reason, the traditional option parsing table code must + be emitted before the 'getopt.tpl' template gets expanded. + + 8. The usage text is, therefore, statically defined. + + +File: autogen.info, Node: getopt building, Prev: getopt limitations, Up: getopt_long + +7.15.2 getopt build requirements +-------------------------------- + +You must supply some compile and link options via environment variables. + +'srcdir' + In case the option definition file lives in a different directory. +'CFLAGS' + Any special flags required to compile. The flags from + 'autoopts-config cflags' will be included automatically. Since the + creation of the option parsing code includes creating a program + that prints out help text, if it is necessary to include files from + various directories to compile that program, you will need to + specify those directories with '-Idirpath' text in the 'CFLAGS'. + Some experimentation may be necessary in that case. + + *NOTE*: the '-Idirpath' text is only needed if your option callback + functions include code that require additional '#include' + directives. +'LDFLAGS' + Any special flags required to link. The flags from + 'autoopts-config ldflags' will be included automatically. This is + required only if additional link flags for the help text emission + program might be needed. +'CC' + This is needed only if 'cc' cannot be found in '$PATH' (or it is + not the one you want). + + To use this, set the exported environment variables and specify +'getopt' as the default template in your option definitions file (*note +Identification::). You will have four new files. Assuming your +definitions were in a file named 'myprog-opts.def' and your program name +was specified as 'progname', the resulting files would be created: +'myprog-opts.h', 'myprog-opts.c', 'getopt-progname.h' and +'getopt-progname.c'. You must compile and link both '.c' files into +your program. If there are link failures, then you are using AutoOpts +features that require the 'libopts' library. You must remove these +features, *Note getopt limitations::. + + These generated files depend upon configure defines to work +correctly. Therefore, you must specify a 'config-header' attribute +(*note programming attributes::) and ensure it has '#defines' for either +'HAVE_STDINT_H' or 'HAVE_INTTYPES_H'; either 'HAVE_SYS_LIMITS_H' or +'HAVE_LIMITS_H'; and 'HAVE_SYSEXITS_H', if the 'sysexits.h' header is +available. The required header files for these defines are, +respectively, the '/usr/include' files named: + * stdint.h + * inttypes.h + * sys/limits.h + * limits.h + * sysexits.h + +The following header files must also exist on the build platform: + * sys/types.h + * stdio.h + * string.h + * unistd.h - or, for getopt_long: + * getopt.h + + +File: autogen.info, Node: i18n, Next: Naming Conflicts, Prev: getopt_long, Up: AutoOpts + +7.16 Internationalizing AutoOpts +================================ + +The generated code for AutoOpts will enable and disable the translation +of AutoOpts run time messages. If 'ENABLE_NLS' is defined at compile +time and 'no-xlate' has been not set to the value _anything_, then the +'_()' macro may be used to specify a translation function. If +undefined, it will default to 'gettext(3GNU)'. This define will also +enable a callback function that 'optionProcess' invokes at the beginning +of option processing. The AutoOpts 'libopts' library will always check +for this _compiled with NLS_ flag, so 'libopts' does not need to be +specially compiled. The strings returned by the translation function +will be 'strdup(3)-ed' and kept. They will not be re-translated, even +if the locale changes, but they will also not be dependent upon reused +or unmappable memory. + + You should also ensure that the 'ATTRIBUTE_FORMAT_ARG()' gets +'#define'-ed to something useful. There is an autoconf macro named +'AG_COMPILE_FORMAT_ARG' in 'ag_macros.m4' that will set it appropriately +for you. If you do not do this, then translated formatting strings may +trigger GCC compiler warnings. + + To internationalize option processing, you should first +internationalize your program. Then, the option processing strings can +be added to your translation text by processing the AutoOpts-generated +'my-opts.c' file and adding the distributed 'po/usage-txt.pot' file. +(Also by extracting the strings yourself from the 'usage-txt.h' file.) +When you call 'optionProcess', all of the user visible AutoOpts strings +will be passed through the localization procedure established with the +'_()' preprocessing macro. + + All of this is _dis_-abled if you specify the global attribute +'no-xlate' to _anything_. + + +File: autogen.info, Node: Naming Conflicts, Next: All Attribute Names, Prev: i18n, Up: AutoOpts + +7.17 Naming Conflicts +===================== + +AutoOpts generates a header file that contains many C preprocessing +macros and several external names. For the most part, they begin with +either 'opt_' or 'option', or else they end with '_opt'. If this +happens to conflict with other macros you are using, or if you are +compiling multiple option sets in the same compilation unit, the +conflicts can be avoided. You may specify an external name 'prefix' +(*note program attributes::) for all of the names generated for each set +of option definitions. + + Among these macros, several take an option name as a macro argument. +Sometimes, this will inconveniently conflict. For example, if you +specify an option named, 'debug', the emitted code will presume that +'DEBUG' is not a preprocessing name. Or also, if you are building on a +Windows platform, you may find that MicroSoft has usurped a number of +user space names in its header files. Consequently, you will get a +preprocessing error if you use, for example, 'HAVE_OPT(DEBUG)' or +'HAVE_OPT(INTERNAL)' (*note HAVE_OPT::) in your code. You may trigger +an obvious warning for such conflicts by specifying the +'guard-option-names' attribute (*note program attributes::). That +emitted code will also '#undef'-ine the conflicting name. + + +File: autogen.info, Node: All Attribute Names, Next: Option Define Names, Prev: Naming Conflicts, Up: AutoOpts + +7.18 All Attribute Names +======================== + +This is the list of all the option attributes used in the various option +processing templates. There are several flavors of attributes, and +these are not distinguished here. + + * Valid, current attributes that you are encouraged to use. + * Internally generated attributes that you cannot use at all. I need + to prefix these with a distinguished prefix. e.g. 'ao-' + * Valid attributes, but are deprecated. Alternates should be + documented. + + This list is derived by running many example option definitions +through the option generation and man page templates and noting which +attributes are actually used. There may be a few that are used but not +exercised in my testing. If so, I need to ferret those out and test +them, too. + + addtogroup aliases allow_errors arg_default + arg_name arg_optional arg_range arg_type + argument author call_proc cmd_section + comment_char concept config_header copyright + date default deprecated descrip + detail die_code disable disable_load + disable_save doc doc_section doc_sub + doc_sub_cmd documentation ds_format ds_text + ds_type eaddr enable enabled + environrc equivalence exit_desc exit_name + explain export extract_code field + file_fail_code flag flag_code flag_proc + flags_cant flags_must full_usage gnu_usage + guard_option_names handler_proc handler_type help_type + help_value home_rc homerc ifdef + ifndef immed_disable immediate include + interleaved keyword lib_name library + load_opts_value long_opts main_fini main_init + main_type max min more_help_value + must_set name no_command no_libopts + no_misuse_usage no_preset no_xlate omit_texi + omitted_usage open_file opt_state option_format + option_info owner package prefix + prefix_enum preserve_case prog_descrip prog_info_descrip + prog_man_descrip prog_name prog_title rcfile + reorder_args reset_value resettable save_opts_value + scaled set_desc set_index settable + short_usage stack_arg stdin_input sub_name + sub_text sub_type test_main translators + type unshar_file_code unstack_arg usage + usage_message usage_opt usage_value value + vendor_opt version version_proc version_value + + +File: autogen.info, Node: Option Define Names, Prev: All Attribute Names, Up: AutoOpts + +7.19 Option Definition Name Index +================================= + +�[index�] +* Menu: + +* addtogroup: global option attributes. + (line 18) +* allow-errors: presentation attributes. + (line 9) +* arg-default: arg-default. (line 6) +* arg-name: per option attributes. + (line 9) +* arg-optional: arg-optional. (line 6) +* arg-range: arg-type number. (line 21) +* arg-type: Option Arguments. (line 24) +* argument: program attributes. (line 22) +* author: information attributes. + (line 25) +* before-guile-boot: main guile. (line 9) +* call-proc: Option Argument Handling. + (line 62) +* cmd-section: global option attributes. + (line 7) +* comment-char: main-for-each-opts. (line 25) +* config-header: program attributes. (line 33) +* config-header <1>: programming attributes. + (line 10) +* copyright: information attributes. + (line 10) +* date: information attributes. + (line 13) +* default: opt-attr default option. + (line 6) +* deprecated: Common Attributes. (line 28) +* descrip: Required Attributes. (line 34) +* detail: information attributes. + (line 39) +* detail <1>: global option attributes. + (line 12) +* die-code: programming attributes. + (line 51) +* disable: Common Attributes. (line 33) +* disable-load: config attributes. (line 13) +* disable-save: config attributes. (line 13) +* doc: per option attributes. + (line 15) +* doc-section: global option attributes. + (line 42) +* doc-sub: global option attributes. + (line 141) +* doc-sub-cmd: global option attributes. + (line 173) +* documentation: lib and program. (line 16) +* documentation <1>: opt-attr documentation. + (line 17) +* eaddr: information attributes. + (line 27) +* enable: Common Attributes. (line 45) +* enabled: Common Attributes. (line 49) +* environrc: config attributes. (line 17) +* equivalence: opt-attr equivalence. + (line 6) +* exit-desc: programming attributes. + (line 16) +* exit-name: programming attributes. + (line 16) +* explain: information attributes. + (line 43) +* export: programming attributes. + (line 66) +* extra-code: arg-keyword. (line 15) +* extract-code: Option Argument Handling. + (line 51) +* file-exists: arg-type file name. (line 13) +* file-mode: arg-type file name. (line 29) +* flag-code: Option Argument Handling. + (line 27) +* flag-proc: Option Argument Handling. + (line 69) +* full-usage: usage attributes. (line 10) +* gnu-usage: usage attributes. (line 43) +* gnu-usage <1>: information attributes. + (line 82) +* guard-option-names: programming attributes. + (line 73) +* guile-main: main guile. (line 14) +* handler-frees: main-for-each-type. (line 66) +* handler-proc: main-for-each-proc. (line 6) +* handler-type: main-for-each-type. (line 6) +* help-value: automatic options. (line 18) +* homerc: config attributes. (line 26) +* ifdef: Common Attributes. (line 56) +* ifndef: Common Attributes. (line 56) +* immed-disable: Immediate Action. (line 31) +* immediate: Immediate Action. (line 24) +* include: programming attributes. + (line 104) +* interleaved: main-for-each-opts. (line 10) +* keyword: arg-keyword. (line 6) +* lib-name: lib and program. (line 24) +* library: lib and program. (line 7) +* load-opts-value: automatic options. (line 15) +* long-opts: presentation attributes. + (line 15) +* main: Generated main. (line 8) +* main-fini: main-for-each-opts. (line 21) +* main-init: main-for-each-opts. (line 17) +* main-type: Generated main. (line 12) +* max: Common Attributes. (line 14) +* min: Common Attributes. (line 19) +* more-help-value: automatic options. (line 15) +* must-set: Common Attributes. (line 24) +* MYHANDLER-code: main-for-each-code. (line 6) +* name: Required Attributes. (line 9) +* no-command: Common Attributes. (line 87) +* no-libopts: programming attributes. + (line 108) +* no-misuse-usage: usage attributes. (line 57) +* no-preset: opt-attr no-preset. (line 6) +* no-xlate: presentation attributes. + (line 35) +* omitted-usage: Common Attributes. (line 56) +* open-file: arg-type file name. (line 23) +* option-code: main main. (line 7) +* option-format: global option attributes. + (line 28) +* option-info: global option attributes. + (line 38) +* opts-ptr: information attributes. + (line 61) +* owner: information attributes. + (line 14) +* package: information attributes. + (line 46) +* prefix: programming attributes. + (line 115) +* prefix-enum: arg-type keyword. (line 38) +* preserve-case: information attributes. + (line 52) +* prog-desc: information attributes. + (line 61) +* prog-group: usage attributes. (line 65) +* prog-name: program attributes. (line 15) +* prog-title: program attributes. (line 19) +* rcfile: config attributes. (line 56) +* reorder-args: presentation attributes. + (line 51) +* reorder-args <1>: information attributes. + (line 91) +* reset-value: automatic options. (line 15) +* resettable: presentation attributes. + (line 68) +* save-opts-value: automatic options. (line 19) +* scaled: arg-type number. (line 15) +* settable: opt-attr settable. (line 6) +* short-usage: usage attributes. (line 38) +* stack-arg: Option Argument Handling. + (line 73) +* text: information attributes. + (line 23) +* translators: opt-attr translators. + (line 6) +* type: information attributes. + (line 15) +* unstack-arg: Option Argument Handling. + (line 86) +* usage: usage attributes. (line 73) +* usage <1>: information attributes. + (line 74) +* usage-message: programming attributes. + (line 41) +* usage-opt: Features. (line 56) +* usage-opt <1>: usage attributes. (line 51) +* usage-value: automatic options. (line 15) +* value: Common Attributes. (line 10) +* vendor-opt: config attributes. (line 61) +* version: usage attributes. (line 90) +* version-proc: automatic options. (line 23) +* version-value: automatic options. (line 15) + + +File: autogen.info, Node: Add-Ons, Next: Future, Prev: AutoOpts, Up: Top + +8 Add-on packages for AutoGen +***************************** + +This chapter includes several programs that either work closely with +AutoGen (extracting definitions or providing special formatting +functions), or leverage off of AutoGen technology. There is also a +formatting library that helps make AutoGen possible. + + AutoOpts ought to appear in this list as well, but since it is the +primary reason why many people would even look into AutoGen at all, I +decided to leave it in the list of chapters. + +* Menu: + +* AutoFSM:: Automated Finite State Machine. +* AutoXDR:: Combined RPC Marshalling. +* AutoEvents:: Automated Event Management. +* Bit Maps:: Bit Maps and Enumerations. +* columns Invocation:: Invoking columns. +* getdefs Invocation:: Invoking getdefs. +* xml2ag Invocation:: Invoking xml2ag. +* snprintfv:: The extensible format printing library. + + +File: autogen.info, Node: AutoFSM, Next: AutoXDR, Up: Add-Ons + +8.1 Automated Finite State Machine +================================== + +The templates to generate a finite state machine in C or C++ is included +with AutoGen. The documentation is not. The documentation is in HTML +format for viewing (http://www.gnu.org/software/autogen/autofsm.html), +or you can download FSM (http://download.sourceforge.net/autogen/). + + +File: autogen.info, Node: AutoXDR, Next: AutoEvents, Prev: AutoFSM, Up: Add-Ons + +8.2 Combined RPC Marshalling +============================ + +The templates and NFSv4 definitions are not included with AutoGen in any +way. The folks that designed NFSv4 noticed that much time and bandwidth +was wasted sending queries and responses when many of them could be +bundled. The protocol bundles the data, but there is no support for it +in rpcgen. That means you have to write your own code to do that. +Until now. Download this and you will have a large, complex example of +how to use 'AutoXDR' for generating the marshaling and unmarshaling of +combined RPC calls. There is a brief example on the web +(http://www.gnu.org/software/autogen/xdr/index.html), but you should +download AutoXDR (http://download.sourceforge.net/autogen/). + + +File: autogen.info, Node: AutoEvents, Next: Bit Maps, Prev: AutoXDR, Up: Add-Ons + +8.3 Automated Event Management +============================== + +Large software development projects invariably have a need to manage the +distribution and display of state information and state changes. In +other words, they need to manage their software events. Generally, each +such project invents its own way of accomplishing this and then +struggles to get all of its components to play the same way. It is a +difficult process and not always completely successful. This project +helps with that. + + AutoEvents completely separates the tasks of supplying the data +needed for a particular event from the methods used to manage the +distribution and display of that event. Consequently, the programmer +writing the code no longer has to worry about that part of the problem. +Likewise the persons responsible for designing the event management and +distribution no longer have to worry about getting programmers to write +conforming code. + + This is a work in progress. See my web page +(http://www.gnu.org/software/autogen/autoevents.html) on the subject, if +you are interested. I have some useful things put together, but it is +not ready to call a product. + + +File: autogen.info, Node: Bit Maps, Next: columns Invocation, Prev: AutoEvents, Up: Add-Ons + +8.4 Bit Maps and Enumerations +============================= + +AutoGen provides two templates for managing enumerations and bit maps +(flag words). They produce an enumeration of the enum or '#define's for +the bit maps, plus conversion functions for converting a string into one +of these values or converting one of these values into a human readable +string. Finally, for enumerations, you may specify one or more sets of +dispatching functions that will be selected by identifying a keyword +prefix of a string (*note the dispatch attribute in Strings to Enums and +Back: enum-code.). + + There is a separate project that produces a GDB add-on that will add +these capabilities into GDB for bit masks. (GDB does just fine with +enumerations.) + +* Menu: + +* enums:: Enumerations +* enum-code:: Strings to Enums and Back +* masks:: Bit Maps and Masks + + +File: autogen.info, Node: enums, Next: enum-code, Up: Bit Maps + +8.4.1 Enumerations +------------------ + +'str2enum.tpl' + + Produce an enumeration for a list of input "cmd"s (names). +Optionally, produce functions to: + + * convert a string to an enumeration + * convert an enumeration value into a string + * invoke a function based on the first token name found in a string + + The header file produced will contain the enumeration and +declarations for the optional procedures. The code ('.c') file will +contain these optional procedures, but can be omitted if the 'no-code' +attribute is specified. + + The following attributes are recognized with the 'str2enum' template: + +'cmd' + You must provide a series of these attributes: they specify the + list of names used in the enumeration. Specific values for the + names may be specified by specifying a numeric index for these + attributes. e.g. 'cmd[5] = mumble;' will cause + FOO_CMD_MUMBLE = 5 + to be inserted into the enumeration. Do not specify a value of + "invalid", unless you specify the 'invalid-name' attribute. (In + that case, do not specify a 'cmd' value that matches the + 'invalid-name' value.) + +'prefix' + This specifies the first segment of each enumeration name. If not + specified, the first segment of the enumeration definition file + name will be used. e.g. 'foo-bar.def' will default to a 'FOO' + prefix. + +'type' + Normally, there is a second constant segment following the prefix. + If not specified, it will be 'CMD', so if both 'prefix' and 'type' + were to default from 'foo-bar.def', you will have enumeration + values prefixed with 'FOO_CMD_'. If specified as the empty string, + there will be no "type" component to the name and the default + constant prefix will thus be 'FOO_'. + +'base-name' + This specifies the base name of the output files, enumeration type + and the translation functions. The default is to use the + 'basename(3)' of the definition file. e.g. 'foo-bar.def' results + in a 'base-name' of 'foo-bar'. + +'invalid-val' + The default invalid value is zero. Sometimes, it is useful for + zero to be valid. If so, you can specify ~0 or the empty string to + be invalid. The empty string will cause the enumeration count + (maximum value plus 1) to be the invalid value. + +'invalid-name' + By default, the invalid value is emitted into the enumeration as + 'FOO_INVALID_CMD'. Specifying this attribute will replace + 'INVALID' with whatever you place in this attribute. + +'add-on-text' + Additional text to insert into the code or header file. + + 'ao-file' + Which file to insert the text into. There are four choices, + only two of which are relevant for the 'str2enum' template: + "enum-header", "enum-code", "mask-header" or "mask-code". + + 'ao-text' + The text to insert. + + +File: autogen.info, Node: enum-code, Next: masks, Prev: enums, Up: Bit Maps + +8.4.2 Strings to Enums and Back +------------------------------- + +A continuation of the attributes for the 'str2enum.tpl' template. + +'no-code' + Do not emit any string to enumeration or enumeration to string code + at all. If this is specified, the remainder of the attributes have + no effect. + +'no-name' + Do not emit the enumeration to name function. + +'no-case' + When looking up a string, the case of the input string is ignored. + +'alias' + A single punctuation character can be interpreted as a command. + The first character of this attribute is the aliased character and + the remainder the aliased-to command. e.g. "#comment" makes '#' + an alias for the 'comment' command. "#comment" must still be + listed in the 'cmd' attributes. + +'length' + Specify how lengths are to be handled. Under the covers, + 'gperf(1)' is used to map a string to an enumeration value. The + code it produces requires the string length to be passed in. You + may pass in the length yourself, or the generated code may figure + it out, or you may ask for that length to be returned back after + being figured out. + + You have four choices with the 'length' attribute: + + * Do not specify it. You will need to provide the length. + * Specify "provided". You will need to provide the length. + * Specify "returned". You must pass a pointer to a size_t + object. If the name is found, the length will be put there. + * Specify an empty string. The generated code will compute the + length and that computed length will not be returned. The + length parameter may be omitted. If the input strings contain + only enumeration names, then this would be sufficient. + * Specifying anything else is undefined. + +'partial' + Normally, a name must fully match to be found successfully. This + attribute causes the generated code to look for partial matches if + the full match 'gperf' function fails. Partial matches must be at + least two characters long. + +'undef-str' + by default, the display string for an undefined value is "* + UNDEFINED *". Use this to change that. + +'equate' + A series of punctuation characters considered equivalent. + Typically, "-_" but sometimes (Tandem) "-_^". Do not use '#' in + the list of characters. + +'dispatch' + A lookup procedure will call a dispatch function for the procedure + named after the keyword identified at the start of a string. Other + than as specially noted below, for every named "cmd", must have a + handling function, plus another function to handle errors, with + "invalid" (or the 'invalid-name' value) as the 'cmd' name. + Multiple 'dispatch' definitions will produce multiple dispatching + functions, each with (potentially) unique argument lists and return + types. + + You may also use 'add-on-text' to "#define" one function to + another, thus allowing one function to handle multiple keywords or + commands. The 'd-nam' and 'd-ret' attributes are required. The + 'd-arg', 'd-omit' and 'd-only' attributes are optional: + + 'd-nam' + This must be a printf format string with one formatting + element: '%s'. The '%s' will be replaced by each 'cmd' name. + The '%s' will be stripped and the result will be combined with + the base name to construct the dispatch procedure name. + + 'd-ret' + The return type of the dispatched function, even if "void". + + 'd-arg' + If there are additional arguments that are to be passed + through to the dispatched function, specify this as though it + were part of the procedure header. (It will be glued into the + dispatching function as is and sedded into what is needed for + the dispatched function.) + + 'd-omit' + Instead of providing handling functions for all of the 'cmd' + names, the invalid function will be called for omitted command + codes. + + 'd-only' + You need only provide functions for the names listed by + 'd-only', plus the "invalid" name. All other command values + will trigger calls to the invalid handling function. Note + that the invalid call can distinguish from a command that + could not be found by examining the value of its first ('id') + argument. + + The handler functions will have the command enumeration as its + first first argument, a pointer to a constant string that will be + the character after the parsed command (keyword) name, plus any + 'd-arg' arguments that follow that. + + As an example, a file 'samp-chk.def' containing this: + AutoGen Definitions str2enum; + cmd = one, two; invalid-name = oops; + dispatch = { d-nam = 'hdl_%s_cmd'; d-ret = void; }; + will produce a header containing: + typedef enum { + SAMP_OOPS_CMD = 0, + SAMP_CMD_ONE = 1, + SAMP_CMD_TWO = 2, + SAMP_COUNT_CMD + } samp_chk_enum_t; + + extern samp_chk_enum_t + find_samp_chk_cmd(char const * str, size_t len); + + typedef void(samp_chk_handler_t)( + samp_chk_enum_t id, char const * str); + + samp_chk_handler_t + hdl_oops_cmd, hdl_one_cmd, hdl_two_cmd; + + extern void + disp_samp_chk(char * str, size_t len); + + extern char const * + samp_chk_name(samp_chk_enum_t id); + + * 'find_samp_chk_cmd' will look up a 'len' byte 'str' and return + the corresponding 'samp_chk_enum_t' value. That value is + 'SAMP_OOPS_CMD' if the string is not "one" or "two". + * 'samp_chk_handler_t' is the type of the callback procedures. + Three must be provided for the dispatching function to call: + 'hdl_oops_cmd', 'hdl_one_cmd' and 'hdl_two_cmd'. + 'hdl_oops_cmd' will receive calls when the string does not + match. + * 'disp_samp_chk' this function will call the handler function + and return whatever the handler returns. In this case, it is + void. + * 'samp_chk_name' will return a string corresponding to the + enumeration value argument. If the value is not valid, "* + UNDEFINED *" (or the value of 'undef-str') is used. + + +File: autogen.info, Node: masks, Prev: enum-code, Up: Bit Maps + +8.4.3 Bit Maps and Masks +------------------------ + +'str2mask.tpl' + + This template leverages highly off of enumerations (*note enums::). +It will produce a header file with bit masks defined for each bit +specified with a 'cmd' attribute. 63 is the highest legal bit number +because this template has not been extended to cope with multiple word +masks. (Patches would be welcome.) + + There are a few constraints on the names allowed: + + * names are constrained to alphanumerics and the underscore + * aliases are not allowed + * dispatch procedures are not allowed + + 'no-code' and 'no-name' are honored. 'dispatch' is not. The lookup +function will examine each token in an input string, determine which bit +is specified and add it into a result. The names may be prefixed with a +hyphen (-) or tilde (~) to remove the bit(s) from the cumulative result. +If the string begins with a plus (+), hyphen or tilde, a "base value" +parameter is used for the starting mask, otherwise the conversion starts +with zero. + + Beyond the enumeration attributes that are used (or ignored), the +'str2mask' template accepts a 'mask' attribute. It takes a few +"subattributes": + +'m-name' + a special name for a sub-collection of the mask bits + +'m-bit' + The name of each previously defined bit(s). If the desired + previously defined value is a mask, that 'm-name' must be suffixed + with "-mask". + +'m-invert' + When all done collecting the bits, x-or the value with the mask of + all the bits in the collection. + +A mask of all bits in the collection is always generated. + + +File: autogen.info, Node: columns Invocation, Next: getdefs Invocation, Prev: Bit Maps, Up: Add-Ons + +8.5 Invoking columns +==================== + +This program was designed for the purpose of generating compact, +columnized tables. It will read a list of text items from standard in +or a specified input file and produce a columnized listing of all the +non-blank lines. Leading white space on each line is preserved, but +trailing white space is stripped. Methods of applying per-entry and +per-line embellishments are provided. See the formatting and separation +arguments below. + + This program is used by AutoGen to help clean up and organize its +output. + + See 'autogen/agen5/fsm.tpl' and the generated output 'pseudo-fsm.h'. + + This function was not implemented as an expression function because +either it would have to be many expression functions, or a provision +would have to be added to provide options to expression functions. +Maybe not a bad idea, but it is not being implemented at the moment. + + A side benefit is that you can use it outside of 'autogen' to +columnize input, a la the 'ls' command. + + This section was generated by *AutoGen*, using the 'agtexi-cmd' +template and the option descriptions for the 'columns' program. This +software is released under the GNU General Public License, version 3 or +later. + +* Menu: + +* columns usage:: columns help/usage ('--help') +* columns dimensions:: dimensions options +* columns treatment:: treatment options +* columns ordering:: ordering options +* columns input-text:: input-text options +* columns config:: presetting/configuring columns +* columns exit status:: exit status +* columns See Also:: See Also + + +File: autogen.info, Node: columns usage, Next: columns dimensions, Up: columns Invocation + +8.5.1 columns help/usage ('--help') +----------------------------------- + +This is the automatically generated usage text for columns. + + The text printed is the same whether selected with the 'help' option +('--help') or the 'more-help' option ('--more-help'). 'more-help' will +print the usage text by passing it through a pager program. 'more-help' +is disabled on platforms without a working 'fork(2)' function. The +'PAGER' environment variable is used to select the program, defaulting +to 'more'. Both will exit with a status code of 0. + + columns (GNU AutoGen) - Columnize Input Text - Ver. 1.2 + Usage: columns [ -<flag> [<val>] | --<name>[{=| }<val>] ]... + + Specify the output dimensions: + + Flg Arg Option-Name Description + -W Num width Maximum Line Width + - it must be in the range: + 16 to 4095 + -c Num columns Desired number of columns + - it must be in the range: + 1 to 2048 + -w Num col-width Set width of each column + - it must be in the range: + 1 to 2048 + Num tab-width tab width + + Specify how to lay out the text: + + Flg Arg Option-Name Description + Num spread maximum spread added to column width + - it must be in the range: + 1 to 1024 + no fill Fill lines with input + - prohibits these options: + spread + col-width + by-columns + -I Str indent Line prefix or indentation + Str first-indent First line prefix + - requires the option 'indent' + -f Str format Formatting string for each input + -S Str separation Separation string - follows all but last + Str line-separation string at end of all lines but last + Str ending string at end of last line + + Specify the ordering of the entries: + + Flg Arg Option-Name Description + no by-columns Print entries in column order + -s opt sort Sort input text + + Redirecting stdin to an alternate file: + + Flg Arg Option-Name Description + -i Str input Input file (if not stdin) + + Version, usage and configuration options: + + Flg Arg Option-Name Description + -v opt version output version information and exit + -? no help display extended usage information and exit + -! no more-help extended usage information passed thru pager + -> opt save-opts save the option state to a config file + -< Str load-opts load options from a config file + - disabled as '--no-load-opts' + - may appear multiple times + + Options are specified by doubled hyphens and their name or by a single + hyphen and the flag character. + + The following option preset mechanisms are supported: + - reading file ./.columnsrc + - reading file $HOME/.columnsrc + - examining environment variables named COLUMNS_* + + Please send bug reports to: <autogen-users@lists.sourceforge.net> + + +File: autogen.info, Node: columns dimensions, Next: columns treatment, Prev: columns usage, Up: columns Invocation + +8.5.2 dimensions options +------------------------ + +Specify the output dimensions. + +width option (-W). +.................. + +This is the "maximum line width" option. This option takes a number +argument 'num'. This option specifies the full width of the output +line, including any start-of-line indentation. The output will fill +each line as completely as possible, unless the column width has been +explicitly specified. If the maximum width is less than the length of +the widest input, you will get a single column of output. + +columns option (-c). +.................... + +This is the "desired number of columns" option. This option takes a +number argument 'count'. Use this option to specify exactly how many +columns to produce. If that many columns will not fit within +LINE_WIDTH, then the count will be reduced to the number that fit. + +col-width option (-w). +...................... + +This is the "set width of each column" option. This option takes a +number argument 'num'. Use this option to specify exactly how many +characters are to be allocated for each column. If it is narrower than +the widest entry, it will be over-ridden with the required width. + +tab-width option. +................. + +This is the "tab width" option. This option takes a number argument +'num'. If an indentation string contains tabs, then this value is used +to compute the ending column of the prefix string. + + +File: autogen.info, Node: columns treatment, Next: columns ordering, Prev: columns dimensions, Up: columns Invocation + +8.5.3 treatment options +----------------------- + +Specify how to lay out the text. + +spread option. +.............. + +This is the "maximum spread added to column width" option. This option +takes a number argument 'num'. Use this option to specify exactly how +many characters may be added to each column. It allows you to prevent +columns from becoming too far apart. Without this option, 'columns' +will attempt to widen columns to fill the full width. + +fill option. +............ + +This is the "fill lines with input" option. + +This option has some usage constraints. It: + * must not appear in combination with any of the following options: + spread, col_width, by_columns. + + Instead of columnizing the input text, fill the output lines with the +input lines. Blank lines on input will cause a blank line in the +output, unless the output is sorted. With sorted output, blank lines +are ignored. + +indent option (-I). +................... + +This is the "line prefix or indentation" option. This option takes a +string argument 'l-pfx'. If a number, then this many spaces will be +inserted at the start of every line. Otherwise, it is a line prefix +that will be inserted at the start of every line. + +first-indent option. +.................... + +This is the "first line prefix" option. This option takes a string +argument 'l-pfx'. + +This option has some usage constraints. It: + * must appear in combination with the following options: indent. + + If a number, then this many spaces will be inserted at the start of +the first line. Otherwise, it is a line prefix that will be inserted at +the start of that line. If its length exceeds "indent", then it will be +emitted on a line by itself, suffixed by any line separation string. +For example: + + $ columns --first='#define TABLE' -c 2 -I4 --line=' \' <<_EOF_ + one + two + three + four + _EOF_ + #define TABLE \ + one two \ + three four + +format option (-f). +................... + +This is the "formatting string for each input" option. This option +takes a string argument 'fmt-str'. If you need to reformat each input +text, the argument to this option is interpreted as an 'sprintf(3)' +format that is used to produce each output entry. + +separation option (-S). +....................... + +This is the "separation string - follows all but last" option. This +option takes a string argument 'sep-str'. Use this option if, for +example, you wish a comma to appear after each entry except the last. + +line-separation option. +....................... + +This is the "string at end of all lines but last" option. This option +takes a string argument 'sep-str'. Use this option if, for example, you +wish a backslash to appear at the end of every line, except the last. + +ending option. +.............. + +This is the "string at end of last line" option. This option takes a +string argument 'end-str'. This option puts the specified string at the +end of the output. + + +File: autogen.info, Node: columns ordering, Next: columns input-text, Prev: columns treatment, Up: columns Invocation + +8.5.4 ordering options +---------------------- + +Specify the ordering of the entries. + +by-columns option. +.................. + +This is the "print entries in column order" option. Normally, the +entries are printed out in order by rows and then columns. This option +will cause the entries to be ordered within columns. The final column, +instead of the final row, may be shorter than the others. + +sort option (-s). +................. + +This is the "sort input text" option. This option takes an optional +string argument 'key-pat'. Causes the input text to be sorted. If an +argument is supplied, it is presumed to be a pattern and the sort is +based upon the matched text. If the pattern starts with or consists of +an asterisk ('*'), then the sort is case insensitive. + + +File: autogen.info, Node: columns input-text, Next: columns config, Prev: columns ordering, Up: columns Invocation + +8.5.5 input-text options +------------------------ + +Redirecting stdin to an alternate file. + +input option (-i). +.................. + +This is the "input file (if not stdin)" option. This option takes a +string argument 'file'. This program normally runs as a 'filter', +reading from standard input, columnizing and writing to standard out. +This option redirects input to a file. + + +File: autogen.info, Node: columns config, Next: columns exit status, Prev: columns input-text, Up: columns Invocation + +8.5.6 presetting/configuring columns +------------------------------------ + +Any option that is not marked as not presettable may be preset by +loading values from configuration ("rc" or "ini") files, and values from +environment variables named 'COLUMNS' and 'COLUMNS_<OPTION_NAME>'. +'<OPTION_NAME>' must be one of the options listed above in upper case +and segmented with underscores. The 'COLUMNS' variable will be +tokenized and parsed like the command line. The remaining variables are +tested for existence and their values are treated like option arguments. + +'libopts' will search in 2 places for configuration files: + * $PWD + * $HOME + The environment variables 'PWD', and 'HOME' are expanded and replaced +when 'columns' runs. For any of these that are plain files, they are +simply processed. For any that are directories, then a file named +'.columnsrc' is searched for within that directory and processed. + + Configuration files may be in a wide variety of formats. The basic +format is an option name followed by a value (argument) on the same +line. Values may be separated from the option name with a colon, equal +sign or simply white space. Values may be continued across multiple +lines by escaping the newline with a backslash. + + Multiple programs may also share the same initialization file. +Common options are collected at the top, followed by program specific +segments. The segments are separated by lines like: + [COLUMNS] +or by + <?program columns> +Do not mix these styles within one configuration file. + + Compound values and carefully constructed string values may also be +specified using XML syntax: + <option-name> + <sub-opt>...<...>...</sub-opt> + </option-name> +yielding an 'option-name.sub-opt' string value of + "...<...>..." + 'AutoOpts' does not track suboptions. You simply note that it is a +hierarchicly valued option. 'AutoOpts' does provide a means for +searching the associated name/value pair list (see: optionFindValue). + + The command line options relating to configuration and/or usage help +are: + +version (-v) +............ + +Print the program version to standard out, optionally with licensing +information, then exit 0. The optional argument specifies how much +licensing detail to provide. The default is to print just the version. +The licensing information may be selected with an option argument. Only +the first letter of the argument is examined: + +'version' + Only print the version. This is the default. +'copyright' + Name the copyright usage licensing terms. +'verbose' + Print the full copyright usage licensing terms. + + +File: autogen.info, Node: columns exit status, Next: columns See Also, Prev: columns config, Up: columns Invocation + +8.5.7 columns exit status +------------------------- + +One of the following exit values will be returned: +'0 (EXIT_SUCCESS)' + Successful program execution. +'1 (EXIT_FAILURE)' + The operation failed or the command syntax was not valid. +'66 (EX_NOINPUT)' + A specified configuration file could not be loaded. +'70 (EX_SOFTWARE)' + libopts had an internal operational error. Please report it to + autogen-users@lists.sourceforge.net. Thank you. + + +File: autogen.info, Node: columns See Also, Prev: columns exit status, Up: columns Invocation + +8.5.8 columns See Also +---------------------- + +This program is documented more fully in the Columns section of the +Add-On chapter in the 'AutoGen' Info system documentation. + + +File: autogen.info, Node: getdefs Invocation, Next: xml2ag Invocation, Prev: columns Invocation, Up: Add-Ons + +8.6 Invoking getdefs +==================== + +If no 'input' argument is provided or is set to simply "-", and if +'stdin' is not a 'tty', then the list of input files will be read from +'stdin'. This program extracts AutoGen definitions from a list of +source files. Definitions are delimited by '/*=<entry-type> +<entry-name>\n' and '=*/\n'. From that, this program creates a +definition of the following form: + + #line nnn "source-file-name" + entry_type = { + name = entry_name; + ... + }; + + 1. The ellipsis '...' is filled in by text found between the two + delimiters. Each line of text is stripped of anything before the + first asterisk, then leading asterisks, then any leading or + trailing white space. + + 2. If what is left starts with what looks like a name followed by a + colon, then it is interpreted as a name followed by a value. + + 3. If the first character of the value is either a single or double + quote, then you are responsible for quoting the text as it gets + inserted into the output definitions. So, if you want whitespace + at the beginnings of the lines of text, you must do something like + this: + + * mumble: + * " this is some\n" + * " indented text." + + 4. If the '<entry-name>' is followed by a comma, the word 'ifdef' (or + 'ifndef') and a name 'if_name', then the above entry will be under + 'ifdef' control. + + /*=group entry_name, ifdef FOO + * attr: attribute value + =*/ + + Will produce the following: + + #ifdef FOO + #line nnn "source-file-name" + group = { + name = entry_name; + attr = 'attribute value'; + }; + #endif + + 5. If you use of the 'subblock' option, you can specify a nested + value, *Note getdefs subblock::. That is, this text: + + * arg: int, this, what-it-is + + with the '--subblock=arg=type,name,doc' option would yield: + + arg = { type = int; name = this; doc = what-it-is; }; + + This section was generated by *AutoGen*, using the 'agtexi-cmd' +template and the option descriptions for the 'getdefs' program. This +software is released under the GNU General Public License, version 3 or +later. + +* Menu: + +* getdefs usage:: getdefs help/usage ('help') +* getdefs def-selection:: def-selection options +* getdefs enumerating:: enumerating options +* getdefs doc-insert:: doc-insert options +* getdefs input-files:: input-files options +* getdefs doc-output:: doc-output options +* getdefs config:: presetting/configuring getdefs +* getdefs exit status:: exit status +* getdefs See Also:: See Also + + +File: autogen.info, Node: getdefs usage, Next: getdefs def-selection, Up: getdefs Invocation + +8.6.1 getdefs help/usage ('help') +--------------------------------- + +This is the automatically generated usage text for getdefs. + + The text printed is the same whether selected with the 'help' option +('help') or the 'more-help' option ('more-help'). 'more-help' will +print the usage text by passing it through a pager program. 'more-help' +is disabled on platforms without a working 'fork(2)' function. The +'PAGER' environment variable is used to select the program, defaulting +to 'more'. Both will exit with a status code of 0. + + getdefs error: invalid option descriptor for version + getdefs (GNU AutoGen) - AutoGen Definition Extraction Tool - Ver. 1.5 + Usage: getdefs [ <option-name>[{=| }<val>] ]... + + Specify which definitions are of interest and what to say about them: + + Arg Option-Name Description + Str defs-to-get Regexp to look for after the "/*=" + Str subblock subblock definition names + - may appear multiple times + Str listattr attribute with list of values + - may appear multiple times + + specify how to number the definitions: + + Arg Option-Name Description + opt ordering Alphabetize or use named file + - disabled as '--no-ordering' + - enabled by default + Num first-index The first index to apply to groups + + Definition insertion options: + + Arg Option-Name Description + opt filelist Insert source file names into defs + Str assign Global assignments + - may appear multiple times + Str common-assign Assignments common to all blocks + - may appear multiple times + Str copy File(s) to copy into definitions + - may appear multiple times + opt srcfile Insert source file name into each def + opt linenum Insert source line number into each def + + specify which files to search for markers: + + Arg Option-Name Description + Str input Input file to search for defs + - may appear multiple times + - default option for unnamed options + + Definition output disposition options:: + + Arg Option-Name Description + Str output Output file to open + - an alternate for 'autogen' + opt autogen Invoke AutoGen with defs + - disabled as '--no-autogen' + - enabled by default + Str template Template Name + Str agarg AutoGen Argument + - prohibits the option 'output' + - may appear multiple times + Str base-name Base name for output file(s) + - prohibits the option 'output' + + Version, usage and configuration options: + + Arg Option-Name Description + + +File: autogen.info, Node: getdefs def-selection, Next: getdefs enumerating, Prev: getdefs usage, Up: getdefs Invocation + +8.6.2 def-selection options +--------------------------- + +Specify which definitions are of interest and what to say about them. + +defs-to-get option. +................... + +This is the "regexp to look for after the "/*="" option. This option +takes a string argument 'reg-ex'. If you want definitions only from a +particular category, or even with names matching particular patterns, +then specify this regular expression for the text that must follow the +'/*='. + +subblock option. +................ + +This is the "subblock definition names" option. This option takes a +string argument 'sub-def'. + +This option has some usage constraints. It: + * may appear an unlimited number of times. + + This option is used to create shorthand entries for nested +definitions. For example, with: +using subblock thus + '--subblock=arg=argname,type,null' +and defining an 'arg' thus + 'arg: this, char *' +will then expand to: + 'arg = { argname = this; type = "char *"; };' + The "this, char *" string is separated at the commas, with the white +space removed. You may use characters other than commas by starting the +value string with a punctuation character other than a single or double +quote character. You may also omit intermediate values by placing the +commas next to each other with no intervening white space. For example, +"+mumble++yes+" will expand to: +'arg = { argname = mumble; null = "yes"; };'. + +listattr option. +................ + +This is the "attribute with list of values" option. This option takes a +string argument 'def'. + +This option has some usage constraints. It: + * may appear an unlimited number of times. + + This option is used to create shorthand entries for definitions that +generally appear several times. That is, they tend to be a list of +values. For example, with: +'listattr=foo' defined, the text: +'foo: this, is, a, multi-list' will then expand to: +'foo = 'this', 'is', 'a', 'multi-list';' +The texts are separated by the commas, with the white space removed. +You may use characters other than commas by starting the value string +with a punctuation character other than a single or double quote +character. + + +File: autogen.info, Node: getdefs enumerating, Next: getdefs doc-insert, Prev: getdefs def-selection, Up: getdefs Invocation + +8.6.3 enumerating options +------------------------- + +specify how to number the definitions. + +ordering option. +................ + +This is the "alphabetize or use named file" option. This option takes +an optional string argument 'file-name'. + +This option has some usage constraints. It: + * can be disabled with -no-ordering. + * It is enabled by default. + + By default, ordering is alphabetical by the entry name. Use, +'no-ordering' if order is unimportant. Use 'ordering' with no argument +to order without case sensitivity. Use 'ordering=<file-name>' if +chronological order is important. getdefs will maintain the text +content of 'file-name'. 'file-name' need not exist. + +first-index option. +................... + +This is the "the first index to apply to groups" option. This option +takes a number argument 'first-index'. By default, the first occurrence +of a named definition will have an index of zero. Sometimes, that needs +to be a reserved value. Provide this option to specify a different +starting point. + + +File: autogen.info, Node: getdefs doc-insert, Next: getdefs input-files, Prev: getdefs enumerating, Up: getdefs Invocation + +8.6.4 doc-insert options +------------------------ + +Definition insertion options. + +filelist option. +................ + +This is the "insert source file names into defs" option. This option +takes an optional string argument 'file'. Inserts the name of each +input file into the output definitions. If no argument is supplied, the +format will be: + infile = '%s'; + If an argument is supplied, that string will be used for the entry +name instead of INFILE. + +assign option. +.............. + +This is the "global assignments" option. This option takes a string +argument 'ag-def'. + +This option has some usage constraints. It: + * may appear an unlimited number of times. + + The argument to each copy of this option will be inserted into the +output definitions, with only a semicolon attached. + +common-assign option. +..................... + +This is the "assignments common to all blocks" option. This option +takes a string argument 'ag-def'. + +This option has some usage constraints. It: + * may appear an unlimited number of times. + + The argument to each copy of this option will be inserted into each +output definition, with only a semicolon attached. + +copy option. +............ + +This is the "file(s) to copy into definitions" option. This option +takes a string argument 'file'. + +This option has some usage constraints. It: + * may appear an unlimited number of times. + + The content of each file named by these options will be inserted into +the output definitions. + +srcfile option. +............... + +This is the "insert source file name into each def" option. This option +takes an optional string argument 'file'. Inserts the name of the input +file where a definition was found into the output definition. If no +argument is supplied, the format will be: + srcfile = '%s'; + If an argument is supplied, that string will be used for the entry +name instead of SRCFILE. + +linenum option. +............... + +This is the "insert source line number into each def" option. This +option takes an optional string argument 'def-name'. Inserts the line +number in the input file where a definition was found into the output +definition. If no argument is supplied, the format will be: + linenum = '%s'; + If an argument is supplied, that string will be used for the entry +name instead of LINENUM. + + +File: autogen.info, Node: getdefs input-files, Next: getdefs doc-output, Prev: getdefs doc-insert, Up: getdefs Invocation + +8.6.5 input-files options +------------------------- + +specify which files to search for markers. + +input option. +............. + +This is the "input file to search for defs" option. This option takes a +string argument 'src-file'. + +This option has some usage constraints. It: + * may appear an unlimited number of times. + + All files that are to be searched for definitions must be named on +the command line or read from 'stdin'. If there is only one 'input' +option and it is the string, "-", then the input file list is read from +'stdin'. If a command line argument is not an option name and does not +contain an assignment operator ('='), then it defaults to being an input +file name. At least one input file must be specified. + + +File: autogen.info, Node: getdefs doc-output, Next: getdefs config, Prev: getdefs input-files, Up: getdefs Invocation + +8.6.6 doc-output options +------------------------ + +Definition output disposition options:. + +output option. +.............. + +This is the "output file to open" option. This option takes a string +argument 'file'. + +This option has some usage constraints. It: + * is a member of the autogen class of options. + + If you are not sending the output to an AutoGen process, you may name +an output file instead. + +autogen option. +............... + +This is the "invoke autogen with defs" option. This option takes an +optional string argument 'ag-cmd'. + +This option has some usage constraints. It: + * can be disabled with -no-autogen. + * It is enabled by default. + * is a member of the autogen class of options. + + This is the default output mode. Specifying 'no-autogen' is +equivalent to 'output=-'. If you supply an argument to this option, +that program will be started as if it were AutoGen and its standard in +will be set to the output definitions of this program. + +template option. +................ + +This is the "template name" option. This option takes a string argument +'file'. Specifies the template name to be used for generating the final +output. + +agarg option. +............. + +This is the "autogen argument" option. This option takes a string +argument 'ag-opt'. + +This option has some usage constraints. It: + * may appear an unlimited number of times. + * must not appear in combination with any of the following options: + output. + + This is a pass-through argument. It allows you to specify any +arbitrary argument to be passed to AutoGen. + +base-name option. +................. + +This is the "base name for output file(s)" option. This option takes a +string argument 'name'. + +This option has some usage constraints. It: + * must not appear in combination with any of the following options: + output. + + When output is going to AutoGen, a base name must either be supplied +or derived. If this option is not supplied, then it is taken from the +'template' option. If that is not provided either, then it is set to +the base name of the current directory. + + +File: autogen.info, Node: getdefs config, Next: getdefs exit status, Prev: getdefs doc-output, Up: getdefs Invocation + +8.6.7 presetting/configuring getdefs +------------------------------------ + +Any option that is not marked as not presettable may be preset by +loading values from configuration ("rc" or "ini") files. + +'libopts' will search in '/dev/null' for configuration (option) data. +If this is a plain file, it is simply processed. If it is a directory, +then a file named '.getdefsrc' is searched for within that directory. + + Configuration files may be in a wide variety of formats. The basic +format is an option name followed by a value (argument) on the same +line. Values may be separated from the option name with a colon, equal +sign or simply white space. Values may be continued across multiple +lines by escaping the newline with a backslash. + + Multiple programs may also share the same initialization file. +Common options are collected at the top, followed by program specific +segments. The segments are separated by lines like: + [GETDEFS] +or by + <?program getdefs> +Do not mix these styles within one configuration file. + + Compound values and carefully constructed string values may also be +specified using XML syntax: + <option-name> + <sub-opt>...<...>...</sub-opt> + </option-name> +yielding an 'option-name.sub-opt' string value of + "...<...>..." + 'AutoOpts' does not track suboptions. You simply note that it is a +hierarchicly valued option. 'AutoOpts' does provide a means for +searching the associated name/value pair list (see: optionFindValue). + + The command line options relating to configuration and/or usage help +are: + +version +....... + +Print the program version to standard out, optionally with licensing +information, then exit 0. The optional argument specifies how much +licensing detail to provide. The default is to print just the version. +The licensing information may be selected with an option argument. Only +the first letter of the argument is examined: + +'version' + Only print the version. This is the default. +'copyright' + Name the copyright usage licensing terms. +'verbose' + Print the full copyright usage licensing terms. + + +File: autogen.info, Node: getdefs exit status, Next: getdefs See Also, Prev: getdefs config, Up: getdefs Invocation + +8.6.8 getdefs exit status +------------------------- + +One of the following exit values will be returned: +'0 (EXIT_SUCCESS)' + Successful program execution. +'1 (EXIT_FAILURE)' + The operation failed or the command syntax was not valid. +'2 (EXIT_INVALID_INPUT)' + An input file was specified that is not a file +'3 (EXIT_NO_MEM)' + Insufficient memory for operation +'66 (EX_NOINPUT)' + A specified configuration file could not be loaded. +'70 (EX_SOFTWARE)' + libopts had an internal operational error. Please report it to + autogen-users@lists.sourceforge.net. Thank you. + + +File: autogen.info, Node: getdefs See Also, Prev: getdefs exit status, Up: getdefs Invocation + +8.6.9 getdefs See Also +---------------------- + +This program is documented more fully in the Getdefs section of the +Add-On chapter in the 'AutoGen' Info system documentation. + + +File: autogen.info, Node: xml2ag Invocation, Next: snprintfv, Prev: getdefs Invocation, Up: Add-Ons + +8.7 Invoking xml2ag +=================== + +This program will convert any arbitrary XML file into equivalent AutoGen +definitions, and invoke AutoGen. The template used will be derived from +either: + * The *-override-tpl* command line option + * A top level XML attribute named, "'template'" +One or the other *must* be provided, or the program will exit with a +failure message. + + The _base-name_ for the output will similarly be either: + * The *-base-name* command line option. + * The base name of the '.xml' file. + + The definitions derived from XML generally have an extra layer of +definition. Specifically, this XML input: + <mumble attr="foo"> + mumble-1 + <grumble> + grumble, grumble, grumble. + </grumble>mumble, mumble + </mumble> + Will get converted into this: + mumble = { + grumble = { + text = 'grumble, grumble, grumble'; + }; + text = 'mumble-1'; + text = 'mumble, mumble'; + }; + Please notice that some information is lost. AutoGen cannot tell +that "grumble" used to lie between the mumble texts. Also please note +that you cannot assign: + grumble = 'grumble, grumble, grumble.'; + because if another "grumble" has an attribute or multiple texts, it +becomes impossible to have the definitions be the same type (compound or +text values). + + This section was generated by *AutoGen*, using the 'agtexi-cmd' +template and the option descriptions for the 'xml2ag' program. This +software is released under the GNU General Public License, version 3 or +later. + +* Menu: + +* xml2ag usage:: xml2ag help/usage ('--help') +* xml2ag the-xml2ag-option:: the-xml2ag-option options +* xml2ag autogen-options:: autogen-options options +* xml2ag exit status:: exit status + + +File: autogen.info, Node: xml2ag usage, Next: xml2ag the-xml2ag-option, Up: xml2ag Invocation + +8.7.1 xml2ag help/usage ('--help') +---------------------------------- + +This is the automatically generated usage text for xml2ag. + + The text printed is the same whether selected with the 'help' option +('--help') or the 'more-help' option ('--more-help'). 'more-help' will +print the usage text by passing it through a pager program. 'more-help' +is disabled on platforms without a working 'fork(2)' function. The +'PAGER' environment variable is used to select the program, defaulting +to 'more'. Both will exit with a status code of 0. + + xml2ag (GNU AutoGen) - XML to AutoGen Definiton Converter - Ver. 5.18.16 + Usage: xml2ag [ -<flag> [<val>] | --<name>[{=| }<val>] ]... [ <def-file> ] + + All other options are derived from autogen: + + Flg Arg Option-Name Description + -O Str output Output file in lieu of AutoGen processing + + All other options: + + Flg Arg Option-Name Description + -L Str templ-dirs Search for templates in DIR + - may appear multiple times + -T Str override-tpl Use TPL-FILE for the template + Str definitions Read definitions from FILE + Str shell name or path name of shell to use + -m no no-fmemopen Do not use in-mem streams + Str equate characters considered equivalent + -b Str base-name Specify NAME as the base name for output + no source-time set mod times to latest source + no writable Allow output files to be writable + - disabled as '--not-writable' + Num loop-limit Limit on increment loops + - is scalable with a suffix: k/K/m/M/g/G/t/T + - it must lie in one of the ranges: + -1 exactly, or + 1 to 16777216 + -t Num timeout Limit server shell operations to SECONDS + - it must be in the range: + 0 to 3600 + KWd trace tracing level of detail + Str trace-out tracing output file or filter + no show-defs Show the definition tree + no used-defines Show the definitions used + -C no core Leave a core dump on a failure exit + -s Str skip-suffix Skip the file with this SUFFIX + - prohibits the option 'select-suffix' + - may appear multiple times + -o Str select-suffix specify this output suffix + - may appear multiple times + -D Str define name to add to definition list + - may appear multiple times + -U Str undefine definition list removal pattern + - an alternate for 'define' + -M opt make-dep emit make dependency file + - may appear multiple times + + Version, usage and configuration options: + + Flg Arg Option-Name Description + -v opt version output version information and exit + -? no help display extended usage information and exit + -! no more-help extended usage information passed thru pager + + Options are specified by doubled hyphens and their name or by a single + hyphen and the flag character. + This program will convert any arbitrary XML file into equivalent AutoGen + definitions, and invoke AutoGen. + + The valid "trace" option keywords are: + nothing debug-message server-shell templates block-macros + expressions everything + or an integer from 0 through 6 + The template will be derived from either: * the ``--override-tpl'' command + line option * a top level XML attribute named, "template" + + The ``base-name'' for the output will similarly be either: * the + ``--base-name'' command line option * the base name of the .xml file + + Please send bug reports to: <autogen-users@lists.sourceforge.net> + + +File: autogen.info, Node: xml2ag the-xml2ag-option, Next: xml2ag autogen-options, Prev: xml2ag usage, Up: xml2ag Invocation + +8.7.2 the-xml2ag-option options +------------------------------- + +All other options are derived from autogen. + +output option (-O). +................... + +This is the "output file in lieu of autogen processing" option. This +option takes a string argument 'file'. By default, the output is handed +to an AutoGen for processing. However, you may save the definitions to +a file instead. + + +File: autogen.info, Node: xml2ag autogen-options, Next: xml2ag exit status, Prev: xml2ag the-xml2ag-option, Up: xml2ag Invocation + +8.7.3 autogen-options options +----------------------------- + +All other options. These options are mostly just passed throug to +'autogen'. The one exception is '--override-tpl' which replaces the +default template in the output definitions. It does not get passed +through on the command line. + +templ-dirs option (-L). +....................... + +This is the "search for templates in 'dir'" option. This option takes a +string argument 'DIR'. + +This option has some usage constraints. It: + * may appear an unlimited number of times. + + Pass-through AutoGen argument + +override-tpl option (-T). +......................... + +This is the "use 'tpl-file' for the template" option. This option takes +a string argument 'TPL-FILE'. Pass-through AutoGen argument + +definitions option. +................... + +This is the "read definitions from 'file'" option. This option takes a +string argument 'FILE'. Pass-through AutoGen argument + +shell option. +............. + +This is the "name or path name of shell to use" option. This option +takes a string argument 'shell'. Pass-through AutoGen argument + +no-fmemopen option (-m). +........................ + +This is the "do not use in-mem streams" option. Pass-through AutoGen +argument + +equate option. +.............. + +This is the "characters considered equivalent" option. This option +takes a string argument 'char-list'. Pass-through AutoGen argument + +base-name option (-b). +...................... + +This is the "specify 'name' as the base name for output" option. This +option takes a string argument 'NAME'. Pass-through AutoGen argument + +source-time option. +................... + +This is the "set mod times to latest source" option. Pass-through +AutoGen argument + +writable option. +................ + +This is the "allow output files to be writable" option. + +This option has some usage constraints. It: + * can be disabled with -not-writable. + + Pass-through AutoGen argument + +loop-limit option. +.................. + +This is the "limit on increment loops" option. This option takes a +number argument 'lim'. Pass-through AutoGen argument + +timeout option (-t). +.................... + +This is the "limit server shell operations to 'seconds'" option. This +option takes a number argument 'SECONDS'. Pass-through AutoGen argument + +trace option. +............. + +This is the "tracing level of detail" option. This option takes a +keyword argument 'level'. + +This option has some usage constraints. It: + * This option takes a keyword as its argument. The argument sets an + enumeration value that can be tested by comparing the option value + macro (OPT_VALUE_TRACE). The available keywords are: + nothing debug-message server-shell + templates block-macros expressions + everything + + or their numeric equivalent. + + Pass-through AutoGen argument + +trace-out option. +................. + +This is the "tracing output file or filter" option. This option takes a +string argument 'file'. Pass-through AutoGen argument + +show-defs option. +................. + +This is the "show the definition tree" option. Pass-through AutoGen +argument + +used-defines option. +.................... + +This is the "show the definitions used" option. Pass-through AutoGen +argument + +core option (-C). +................. + +This is the "leave a core dump on a failure exit" option. + +This option has some usage constraints. It: + * must be compiled in by defining 'HAVE_SYS_RESOURCE_H' during the + compilation. + + Many systems default to a zero sized core limit. If the system has +the sys/resource.h header and if this option is supplied, then in the +failure exit path, autogen will attempt to set the soft core limit to +whatever the hard core limit is. If that does not work, then an +administrator must raise the hard core size limit. + +skip-suffix option (-s). +........................ + +This is the "skip the file with this 'suffix'" option. This option +takes a string argument 'SUFFIX'. + +This option has some usage constraints. It: + * may appear an unlimited number of times. + * must not appear in combination with any of the following options: + select-suffix. + + Pass-through AutoGen argument + +select-suffix option (-o). +.......................... + +This is the "specify this output suffix" option. This option takes a +string argument 'SUFFIX'. + +This option has some usage constraints. It: + * may appear an unlimited number of times. + + Pass-through AutoGen argument + +define option (-D). +................... + +This is the "name to add to definition list" option. This option takes +a string argument 'value'. + +This option has some usage constraints. It: + * may appear an unlimited number of times. + + Pass-through AutoGen argument + +undefine option (-U). +..................... + +This is the "definition list removal pattern" option. This option takes +a string argument 'name-pat'. + +This option has some usage constraints. It: + * may appear an unlimited number of times. + + Pass-through AutoGen argument + +make-dep option (-M). +..................... + +This is the "emit make dependency file" option. This option takes an +optional string argument 'type'. + +This option has some usage constraints. It: + * may appear an unlimited number of times. + + Pass-through AutoGen argument + + +File: autogen.info, Node: xml2ag exit status, Prev: xml2ag autogen-options, Up: xml2ag Invocation + +8.7.4 xml2ag exit status +------------------------ + +One of the following exit values will be returned: +'0 (EXIT_SUCCESS)' + Successful program execution. +'1 (EXIT_FAILURE)' + The operation failed or the command syntax was not valid. + + +File: autogen.info, Node: snprintfv, Prev: xml2ag Invocation, Up: Add-Ons + +8.8 Replacement for Stdio Formatting Library +============================================ + +Using the 'printf' formatting routines in a portable fashion has always +been a pain, and this package has been way more pain than anyone ever +imagined. Hopefully, with this release of snprintfv, the pain is now +over for all time. + + The issues with portable usage are these: + + 1. Argument number specifiers are often either not implemented or are + buggy. Even GNU libc, version 1 got it wrong. + + 2. ANSI/ISO "forgot" to provide a mechanism for computing argument + lists for vararg procedures. + + 3. The argument array version of printf ('printfv()') is not generally + available, does not work with the native printf, and does not have + a working argument number specifier in the format specification. + (Last I knew, anyway.) + + 4. You cannot fake varargs by calling 'vprintf()' with an array of + arguments, because ANSI does not require such an implementation and + some vendors play funny tricks because they are allowed to. + + These four issues made it impossible for AutoGen to ship without its +own implementation of the 'printf' formatting routines. Since we were +forced to do this, we decided to make the formatting routines both +better and more complete :-). We addressed these issues and added the +following features to the common printf API: + + 5. The formatted output can be written to + + * a string allocated by the formatting function ('asprintf()'). + * a file descriptor instead of a file stream ('dprintf()'). + * a user specified stream ('stream_printf()'). + + 6. The formatting functions can be augmented with your own functions. + These functions are allowed to consume more than one character from + the format, but must commence with a unique character. For + example, + + "%{struct stat}\n" + + might be used with '{' registered to a procedure that would look up + "struct stat" in a symbol table and do appropriate things, + consuming the format string through the '}' character. + + Gary V. Vaughan was generous enough to supply this implementation. +Many thanks!! + + For further details, the reader is referred to the snprintfv +documentation. These functions are also available in the template +processing as 'sprintf' (*note SCM sprintf::), 'printf' (*note SCM +printf::), 'fprintf' (*note SCM fprintf::), and 'shellf' (*note SCM +shellf::). + + +File: autogen.info, Node: Future, Next: Copying This Manual, Prev: Add-Ons, Up: Top + +9 Some ideas for the future. +**************************** + +Here are some things that might happen in the distant future. + + * Fix up current tools that contain miserably complex perl, shell, + sed, awk and m4 scripts to instead use this tool. + + +File: autogen.info, Node: Copying This Manual, Next: Concept Index, Prev: Future, Up: Top + +Appendix A Copying This Manual +****************************** + +You may copy this manual under the terms of the FDL (the GNU Free +Documentation License (http://gnu.org/licenses/fdl.texi)). + + +File: autogen.info, Node: Concept Index, Next: Function Index, Prev: Copying This Manual, Up: Top + +Concept Index +************* + +�[index�] +* Menu: + +* .: naming values. (line 23) +* .def file: Definitions File. (line 6) +* .tpl file: Template File. (line 6) +* Alternate Definition: Alternate Definition. + (line 6) +* assert: Directives. (line 26) +* assert directive: Directives. (line 26) +* Augmenting AutoGen: Augmenting AutoGen. (line 6) +* AutoEvents: AutoEvents. (line 6) +* AutoFSM: AutoFSM. (line 6) +* autogen: autogen Invocation. (line 6) +* AutoGen Definition Extraction Tool: getdefs Invocation. (line 6) +* autogen help: autogen usage. (line 6) +* autogen-base-name: autogen out-handling. + (line 11) +* autogen-core: autogen debug-tpl. (line 138) +* autogen-define: autogen processing. (line 46) +* autogen-definitions: autogen input-select. + (line 40) +* autogen-equate: autogen input-select. + (line 90) +* autogen-loop-limit: autogen debug-tpl. (line 13) +* autogen-make-dep: autogen dep-track. (line 11) +* autogen-no-abort: autogen autoopts-opts. + (line 11) +* autogen-no-fmemopen: autogen input-select. + (line 74) +* autogen-override-tpl: autogen input-select. + (line 26) +* autogen-select-suffix: autogen processing. (line 31) +* autogen-shell: autogen input-select. + (line 58) +* autogen-show-defs: autogen debug-tpl. (line 106) +* autogen-skip-suffix: autogen processing. (line 13) +* autogen-source-time: autogen out-handling. + (line 33) +* autogen-templ-dirs: autogen input-select. + (line 12) +* autogen-timeout: autogen debug-tpl. (line 23) +* autogen-trace: autogen debug-tpl. (line 40) +* autogen-trace-out: autogen debug-tpl. (line 95) +* autogen-undefine: autogen processing. (line 76) +* autogen-used-defines: autogen debug-tpl. (line 120) +* autogen-writable: autogen out-handling. + (line 47) +* AutoInfo: AutoInfo. (line 6) +* AutoMan pages: AutoMan pages. (line 6) +* automatic options: automatic options. (line 6) +* autoopts: AutoOpts. (line 6) +* autoopts <1>: Caveats. (line 34) +* AutoOpts API: AutoOpts API. (line 6) +* autoopts directives: config directives. (line 6) +* AutoXDR: AutoXDR. (line 6) +* backtrack: naming values. (line 24) +* Columnize Input Text: columns Invocation. (line 6) +* columns: columns Invocation. (line 6) +* columns help: columns usage. (line 6) +* columns-by-columns: columns ordering. (line 11) +* columns-col-width: columns dimensions. (line 29) +* columns-columns: columns dimensions. (line 21) +* columns-ending: columns treatment. (line 89) +* columns-fill: columns treatment. (line 20) +* columns-first-indent: columns treatment. (line 42) +* columns-format: columns treatment. (line 67) +* columns-indent: columns treatment. (line 34) +* columns-input: columns input-text. (line 11) +* columns-line-separation: columns treatment. (line 82) +* columns-separation: columns treatment. (line 75) +* columns-sort: columns ordering. (line 19) +* columns-spread: columns treatment. (line 11) +* columns-tab-width: columns dimensions. (line 37) +* columns-width: columns dimensions. (line 11) +* comments: Comments. (line 6) +* Common Option Attributes: Common Attributes. (line 6) +* compound definitions: Definitions. (line 43) +* concat-string: concat-string. (line 6) +* conditional emit: IF. (line 6) +* conditional emit <1>: WHILE. (line 6) +* configuration file: opt-attr no-preset. (line 6) +* configuration file <1>: automatic options. (line 67) +* configuration file <2>: automatic options. (line 83) +* configuration file <3>: Option Processing Data. + (line 40) +* Configuration File: config example. (line 6) +* Configuration File <1>: Config File Format. (line 6) +* configuration file <4>: shell options. (line 6) +* Configuration File example: config example. (line 6) +* configuring: configuring. (line 6) +* define: Directives. (line 41) +* define directive: Directives. (line 41) +* define macro: DEFINE. (line 6) +* Definition Index: Index Assignments. (line 6) +* definitions: Definitions. (line 6) +* definitions file: Definitions File. (line 6) +* design goals: Generalities. (line 11) +* directives: Directives. (line 6) +* diversion: output controls. (line 6) +* documentation attributes: documentation attributes. + (line 6) +* Dynamic Definition Text: Dynamic Text. (line 6) +* elif: Directives. (line 49) +* elif directive: Directives. (line 49) +* else: Directives. (line 53) +* else directive: Directives. (line 53) +* endif: Directives. (line 58) +* endif directive: Directives. (line 58) +* endmac: Directives. (line 62) +* endmac directive: Directives. (line 62) +* endshell: Directives. (line 65) +* endshell directive: Directives. (line 65) +* environrc: environrc. (line 6) +* error: Directives. (line 68) +* error directive: Directives. (line 68) +* example, simple AutoGen: Example Usage. (line 6) +* example, simple AutoOpts: Quick Start. (line 6) +* expression syntax: expression syntax. (line 6) +* features: Features. (line 6) +* finite state machine: AutoFSM. (line 6) +* flags-cant: Option Conflict Attributes. + (line 19) +* flags-must: Option Conflict Attributes. + (line 15) +* fOptState: Option Processing Data. + (line 28) +* for loop: FOR. (line 6) +* futures: Future. (line 6) +* getdefs: getdefs Invocation. (line 6) +* getdefs help: getdefs usage. (line 6) +* getdefs-agarg: getdefs doc-output. (line 46) +* getdefs-assign: getdefs doc-insert. (line 22) +* getdefs-autogen: getdefs doc-output. (line 23) +* getdefs-base-name: getdefs doc-output. (line 60) +* getdefs-common-assign: getdefs doc-insert. (line 34) +* getdefs-copy: getdefs doc-insert. (line 46) +* getdefs-defs-to-get: getdefs def-selection. + (line 11) +* getdefs-filelist: getdefs doc-insert. (line 11) +* getdefs-first-index: getdefs enumerating. (line 27) +* getdefs-input: getdefs input-files. (line 11) +* getdefs-linenum: getdefs doc-insert. (line 69) +* getdefs-listattr: getdefs def-selection. + (line 45) +* getdefs-ordering: getdefs enumerating. (line 11) +* getdefs-output: getdefs doc-output. (line 11) +* getdefs-srcfile: getdefs doc-insert. (line 58) +* getdefs-subblock: getdefs def-selection. + (line 20) +* getdefs-template: getdefs doc-output. (line 39) +* getopt_long: getopt_long. (line 6) +* gnu: Caveats. (line 29) +* here-string: here-string. (line 6) +* ident: Directives. (line 72) +* ident directive: Directives. (line 72) +* identification: Identification. (line 6) +* if: Directives. (line 75) +* if directive: Directives. (line 75) +* if test: IF. (line 6) +* ifdef: Directives. (line 79) +* ifdef directive: Directives. (line 79) +* ifndef: Directives. (line 85) +* ifndef directive: Directives. (line 85) +* immediate action: Immediate Action. (line 6) +* include: Directives. (line 89) +* include directive: Directives. (line 89) +* information attributes: information attributes. + (line 6) +* Installing: installing. (line 6) +* Internationalizing AutoOpts: i18n. (line 6) +* Internationalizing Options: Internationalizing Options. + (line 6) +* Introduction: Introduction. (line 6) +* let: Directives. (line 94) +* let directive: Directives. (line 94) +* library attributes: library attributes. (line 6) +* Licensing: Licensing. (line 6) +* line: Directives. (line 97) +* line directive: Directives. (line 97) +* looping, for: FOR. (line 6) +* m4: Testimonial. (line 41) +* macdef: Directives. (line 104) +* macdef directive: Directives. (line 104) +* macro syntax: AGMacro syntax. (line 6) +* macro, pseudo: Template File. (line 10) +* main procedure: Generated main. (line 6) +* misuse-usage: Caveats. (line 45) +* named option mode: presentation attributes. + (line 15) +* Naming Conflicts: Naming Conflicts. (line 6) +* naming values: naming values. (line 6) +* native macros: native macros. (line 6) +* no-misuse-usage: Caveats. (line 40) +* optActualIndex: Option Processing Data. + (line 16) +* optActualValue: Option Processing Data. + (line 17) +* optIndex: Option Processing Data. + (line 11) +* option: Directives. (line 110) +* Option Argument Handling: Option Argument Handling. + (line 6) +* Option Arguments: Option Arguments. (line 6) +* option attributes: option attributes. (line 6) +* Option Conflict Attributes: Option Conflict Attributes. + (line 6) +* Option Definitions: Option Definitions. (line 6) +* option descriptor: option descriptor. (line 6) +* option directive: Directives. (line 110) +* Option Processing Data: Option Processing Data. + (line 6) +* optOccCt: Option Processing Data. + (line 22) +* optValue: Option Processing Data. + (line 12) +* pragma: Directives. (line 125) +* pragma directive: Directives. (line 125) +* predefines: Predefines. (line 6) +* program attributes: program attributes. (line 6) +* pseudo macro: Template File. (line 10) +* pseudo macro <1>: pseudo macro. (line 6) +* pzLastArg: Option Processing Data. + (line 80) +* pzProgName: Option Processing Data. + (line 87) +* pzProgPath: Option Processing Data. + (line 91) +* rcfile: loading rcfile. (line 6) +* rcfile <1>: config example. (line 6) +* Redirecting Output: output controls. (line 6) +* remote procedure call: AutoXDR. (line 6) +* Required Attributes: Required Attributes. (line 6) +* RPC: AutoXDR. (line 6) +* rpcgen: AutoXDR. (line 6) +* sample rcfile: sample rcfile. (line 6) +* shell: Directives. (line 128) +* shell directive: Directives. (line 128) +* shell options: Presetting Options. (line 6) +* shell options <1>: shell options. (line 6) +* shell-generated string: shell-generated. (line 6) +* Signal Names: signal names. (line 6) +* simple definitions: Definitions. (line 44) +* standard options: standard options. (line 6) +* string, double quote: double-quote-string. (line 6) +* string, shell output: shell-generated. (line 6) +* string, single quote: single-quote-string. (line 6) +* template file: Identification. (line 21) +* template file <1>: Template File. (line 6) +* The Automated Program Generator: autogen Invocation. (line 6) +* undef: Directives. (line 136) +* undef directive: Directives. (line 136) +* using AutoOpts: Using AutoOpts. (line 6) +* while test: WHILE. (line 6) +* XDR: AutoXDR. (line 6) +* XML to AutoGen Definiton Converter: xml2ag Invocation. (line 6) +* xml2ag: xml2ag Invocation. (line 6) +* xml2ag help: xml2ag usage. (line 6) +* xml2ag-base-name: xml2ag autogen-options. + (line 55) +* xml2ag-core: xml2ag autogen-options. + (line 125) +* xml2ag-define: xml2ag autogen-options. + (line 164) +* xml2ag-definitions: xml2ag autogen-options. + (line 31) +* xml2ag-equate: xml2ag autogen-options. + (line 49) +* xml2ag-loop-limit: xml2ag autogen-options. + (line 77) +* xml2ag-make-dep: xml2ag autogen-options. + (line 186) +* xml2ag-no-fmemopen: xml2ag autogen-options. + (line 43) +* xml2ag-output: xml2ag the-xml2ag-option. + (line 11) +* xml2ag-override-tpl: xml2ag autogen-options. + (line 25) +* xml2ag-select-suffix: xml2ag autogen-options. + (line 153) +* xml2ag-shell: xml2ag autogen-options. + (line 37) +* xml2ag-show-defs: xml2ag autogen-options. + (line 113) +* xml2ag-skip-suffix: xml2ag autogen-options. + (line 140) +* xml2ag-source-time: xml2ag autogen-options. + (line 61) +* xml2ag-templ-dirs: xml2ag autogen-options. + (line 14) +* xml2ag-timeout: xml2ag autogen-options. + (line 83) +* xml2ag-trace: xml2ag autogen-options. + (line 89) +* xml2ag-trace-out: xml2ag autogen-options. + (line 107) +* xml2ag-undefine: xml2ag autogen-options. + (line 175) +* xml2ag-used-defines: xml2ag autogen-options. + (line 119) +* xml2ag-writable: xml2ag autogen-options. + (line 67) + + +File: autogen.info, Node: Function Index, Prev: Concept Index, Up: Top + +Function Index +************** + +�[index�] +* Menu: + +* *=: SCM *=. (line 6) +* *=*: SCM *=*. (line 6) +* *==: SCM *==. (line 6) +* *==*: SCM *==*. (line 6) +* *~: SCM *~. (line 6) +* *~*: SCM *~*. (line 6) +* *~~: SCM *~~. (line 6) +* *~~*: SCM *~~*. (line 6) +* =: SCM =. (line 6) +* =*: SCM =*. (line 6) +* ==: SCM ==. (line 6) +* ==*: SCM ==*. (line 6) +* ~: SCM ~. (line 6) +* ~*: SCM ~*. (line 6) +* ~~: SCM ~~. (line 6) +* ~~*: SCM ~~*. (line 6) +* ag-fprintf: SCM ag-fprintf. (line 6) +* ag-function?: SCM ag-function?. (line 6) +* agpl: SCM agpl. (line 6) +* ao_string_tokenize: libopts-ao_string_tokenize. + (line 6) +* autogen-version: SCM autogen-version. (line 6) +* base-name: SCM base-name. (line 6) +* BREAK: BREAK. (line 6) +* bsd: SCM bsd. (line 6) +* c-file-line-fmt: SCM c-file-line-fmt. (line 6) +* c-string: SCM c-string. (line 6) +* CASE: CASE. (line 6) +* chdir: SCM chdir. (line 6) +* CLEAR_OPT: CLEAR_OPT. (line 6) +* COMMENT: COMMENT. (line 6) +* configFileLoad: libopts-configFileLoad. + (line 6) +* CONTINUE: CONTINUE. (line 6) +* count: SCM count. (line 6) +* COUNT_OPT: COUNT_OPT. (line 6) +* DEBUG: DEBUG. (line 6) +* def-file: SCM def-file. (line 6) +* def-file-line: SCM def-file-line. (line 6) +* DEFINE: DEFINE. (line 6) +* DESC: DESC. (line 6) +* DISABLE_OPT_name: DISABLE_OPT_name. (line 6) +* dne: SCM dne. (line 6) +* ELIF: ELIF. (line 6) +* ELSE: ELSE. (line 6) +* emit: SCM emit. (line 6) +* emit-string-table: SCM emit-string-table. (line 6) +* ENABLED_OPT: ENABLED_OPT. (line 6) +* ENDDEF: ENDDEF. (line 6) +* ENDFOR: ENDFOR. (line 6) +* ENDIF: ENDIF. (line 6) +* ENDWHILE: ENDWHILE. (line 6) +* error: SCM error. (line 6) +* error-source-line: SCM error-source-line. (line 6) +* ERRSKIP_OPTERR: ERRSKIP_OPTERR. (line 6) +* ERRSTOP_OPTERR: ERRSTOP_OPTERR. (line 6) +* ESAC: ESAC. (line 6) +* exist?: SCM exist?. (line 6) +* EXPR: EXPR. (line 6) +* extract: SCM extract. (line 6) +* find-file: SCM find-file. (line 6) +* first-for?: SCM first-for?. (line 6) +* FOR: FOR. (line 6) +* for-by: SCM for-by. (line 6) +* for-from: SCM for-from. (line 6) +* for-index: SCM for-index. (line 6) +* for-sep: SCM for-sep. (line 6) +* for-to: SCM for-to. (line 6) +* format-arg-count: SCM format-arg-count. (line 6) +* found-for?: SCM found-for?. (line 6) +* fprintf: SCM fprintf. (line 6) +* get: SCM get. (line 6) +* get-c-name: SCM get-c-name. (line 6) +* get-down-name: SCM get-down-name. (line 6) +* get-up-name: SCM get-up-name. (line 6) +* gperf: SCM gperf. (line 6) +* gperf-code: SCM gperf-code. (line 6) +* gpl: SCM gpl. (line 6) +* HAVE_OPT: HAVE_OPT. (line 6) +* hide-email: SCM hide-email. (line 6) +* high-lim: SCM high-lim. (line 6) +* html-escape-encode: SCM html-escape-encode. + (line 6) +* IF: IF. (line 6) +* in?: SCM in?. (line 6) +* INCLUDE: INCLUDE. (line 6) +* insert-file: SCM insert-file. (line 6) +* insert-suspended: SCM insert-suspended. (line 6) +* INVOKE: INVOKE. (line 6) +* ISSEL_OPT: ISSEL_OPT. (line 6) +* ISUNUSED_OPT: ISUNUSED_OPT. (line 6) +* join: SCM join. (line 6) +* kr-string: SCM kr-string. (line 6) +* last-for?: SCM last-for?. (line 6) +* len: SCM len. (line 6) +* lgpl: SCM lgpl. (line 6) +* license: SCM license. (line 6) +* license-description: SCM license-description. + (line 6) +* license-full: SCM license-full. (line 6) +* license-info: SCM license-info. (line 6) +* license-name: SCM license-name. (line 6) +* low-lim: SCM low-lim. (line 6) +* make-gperf: SCM make-gperf. (line 6) +* make-header-guard: SCM make-header-guard. (line 6) +* make-tmp-dir: SCM make-tmp-dir. (line 6) +* makefile-script: SCM makefile-script. (line 6) +* match-value?: SCM match-value?. (line 6) +* max: SCM max. (line 6) +* max-file-time: SCM max-file-time. (line 6) +* min: SCM min. (line 6) +* mk-gettextable: SCM mk-gettextable. (line 6) +* optionFileLoad: libopts-optionFileLoad. + (line 6) +* optionFindNextValue: libopts-optionFindNextValue. + (line 6) +* optionFindValue: libopts-optionFindValue. + (line 6) +* optionFree: libopts-optionFree. (line 6) +* optionGetValue: libopts-optionGetValue. + (line 6) +* optionLoadLine: libopts-optionLoadLine. + (line 6) +* optionMemberList: libopts-optionMemberList. + (line 6) +* optionNextValue: libopts-optionNextValue. + (line 6) +* optionOnlyUsage: libopts-optionOnlyUsage. + (line 6) +* optionPrintVersion: libopts-optionPrintVersion. + (line 6) +* optionPrintVersionAndReturn: libopts-optionPrintVersionAndReturn. + (line 6) +* optionProcess: libopts-optionProcess. (line 6) +* optionRestore: libopts-optionRestore. (line 6) +* optionSaveFile: libopts-optionSaveFile. + (line 6) +* optionSaveState: libopts-optionSaveState. + (line 6) +* optionUnloadNested: libopts-optionUnloadNested. + (line 6) +* optionVersion: libopts-optionVersion. (line 6) +* OPTION_CT: OPTION_CT. (line 6) +* OPT_ARG: OPT_ARG. (line 6) +* OPT_NO_XLAT_CFG_NAMES: OPT_NO_XLAT_CFG_NAMES. (line 6) +* OPT_NO_XLAT_OPT_NAMES: OPT_NO_XLAT_OPT_NAMES. (line 6) +* OPT_VALUE_name: OPT_VALUE_name. (line 6) +* OPT_XLAT_CFG_NAMES: OPT_XLAT_CFG_NAMES. (line 6) +* OPT_XLAT_OPT_NAMES: OPT_XLAT_OPT_NAMES. (line 6) +* out-delete: SCM out-delete. (line 6) +* out-depth: SCM out-depth. (line 6) +* out-emit-suspended: SCM out-emit-suspended. + (line 6) +* out-line: SCM out-line. (line 6) +* out-move: SCM out-move. (line 6) +* out-name: SCM out-name. (line 6) +* out-pop: SCM out-pop. (line 6) +* out-push-add: SCM out-push-add. (line 6) +* out-push-new: SCM out-push-new. (line 6) +* out-resume: SCM out-resume. (line 6) +* out-suspend: SCM out-suspend. (line 6) +* out-switch: SCM out-switch. (line 6) +* output-file-next-line: SCM output-file-next-line. + (line 6) +* prefix: SCM prefix. (line 6) +* printf: SCM printf. (line 6) +* raw-shell-str: SCM raw-shell-str. (line 6) +* RESTART_OPT: RESTART_OPT. (line 6) +* RETURN: RETURN. (line 6) +* SELECT: SELECT. (line 6) +* set-option: SCM set-option. (line 6) +* set-writable: SCM set-writable. (line 6) +* SET_OPT_name: SET_OPT_name. (line 6) +* shell: SCM shell. (line 6) +* shell-str: SCM shell-str. (line 6) +* shellf: SCM shellf. (line 6) +* sprintf: SCM sprintf. (line 6) +* stack: SCM stack. (line 6) +* stack-join: SCM stack-join. (line 6) +* STACKCT_OPT: STACKCT_OPT. (line 6) +* STACKLST_OPT: STACKLST_OPT. (line 6) +* START_OPT: START_OPT. (line 6) +* STATE_OPT: STATE_OPT. (line 6) +* strequate: libopts-strequate. (line 6) +* streqvcmp: libopts-streqvcmp. (line 6) +* streqvmap: libopts-streqvmap. (line 6) +* string->c-name!: SCM string->c-name!. (line 6) +* string->camelcase: SCM string->camelcase. (line 6) +* string-capitalize: SCM string-capitalize. (line 6) +* string-capitalize!: SCM string-capitalize!. + (line 6) +* string-contains-eqv?: SCM *=*. (line 6) +* string-contains?: SCM *==*. (line 6) +* string-downcase: SCM string-downcase. (line 6) +* string-downcase!: SCM string-downcase!. (line 6) +* string-end-eqv-match?: SCM *~. (line 6) +* string-end-match?: SCM *~~. (line 6) +* string-ends-eqv?: SCM *=. (line 6) +* string-ends-with?: SCM *==. (line 6) +* string-equals?: SCM ==. (line 6) +* string-eqv-match?: SCM ~. (line 6) +* string-eqv?: SCM =. (line 6) +* string-has-eqv-match?: SCM *~*. (line 6) +* string-has-match?: SCM *~~*. (line 6) +* string-match?: SCM ~~. (line 6) +* string-start-eqv-match?: SCM ~*. (line 6) +* string-start-match?: SCM ~~*. (line 6) +* string-starts-eqv?: SCM =*. (line 6) +* string-starts-with?: SCM ==*. (line 6) +* string-substitute: SCM string-substitute. (line 6) +* string-table-add: SCM string-table-add. (line 6) +* string-table-add-ref: SCM string-table-add-ref. + (line 6) +* string-table-new: SCM string-table-new. (line 6) +* string-table-size: SCM string-table-size. (line 6) +* string-tr: SCM string-tr. (line 6) +* string-tr!: SCM string-tr!. (line 6) +* string-upcase: SCM string-upcase. (line 6) +* string-upcase!: SCM string-upcase!. (line 6) +* strneqvcmp: libopts-strneqvcmp. (line 6) +* strtransform: libopts-strtransform. (line 6) +* sub-shell-str: SCM sub-shell-str. (line 6) +* suffix: SCM suffix. (line 6) +* sum: SCM sum. (line 6) +* teOptIndex: teOptIndex. (line 6) +* time-string->number: SCM time-string->number. + (line 6) +* tpl-file: SCM tpl-file. (line 6) +* tpl-file-line: SCM tpl-file-line. (line 6) +* tpl-file-next-line: SCM tpl-file-next-line. + (line 6) +* UNKNOWN: UNKNOWN. (line 6) +* USAGE: USAGE. (line 6) +* VALUE_OPT_name: VALUE_OPT_name. (line 6) +* VERSION: VERSION. (line 6) +* version-compare: SCM version-compare. (line 6) +* warn: SCM warn. (line 6) +* WHICH_IDX_name: WHICH_IDX_name. (line 6) +* WHICH_OPT_name: WHICH_OPT_name. (line 6) +* WHILE: WHILE. (line 6) + diff --git a/doc/autogen.texi b/doc/autogen.texi new file mode 100644 index 0000000..e6f2a83 --- /dev/null +++ b/doc/autogen.texi @@ -0,0 +1,7 @@ +\input texinfo +@ignore +\internalpagesizes{46\baselineskip}{6in}{-.25in}{-.25in}{\bindingoffset}{36pt}% +@end ignore +@c %**start of header +@setfilename autogen.info +@include agdoc.texi diff --git a/doc/bitmaps.texi b/doc/bitmaps.texi new file mode 100644 index 0000000..b3b5592 --- /dev/null +++ b/doc/bitmaps.texi @@ -0,0 +1,348 @@ +@ignore + +This file is part of AutoGen. +AutoGen is free software. +AutoGen is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + +AutoGen 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. + +AutoGen is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program. If not, see <http://www.gnu.org/licenses/>. + +This file has the following md5sum: + +43b91e8ca915626ed3818ffb1b71248b COPYING.gplv3 + +@end ignore +@node Bit Maps +@section Bit Maps and Enumerations + +AutoGen provides two templates for managing enumerations and bit maps +(flag words). They produce an enumeration of the enum or @code{#define}s +for the bit maps, plus conversion functions for converting a string into +one of these values or converting one of these values into a human readable +string. Finally, for enumerations, you may specify one or more sets of +dispatching functions that will be selected by identifying a keyword +prefix of a string (@pxref{enum-code, the @i{dispatch} attribute in +Strings to Enums and Back}). + +There is a separate project that produces a GDB add-on that +will add these capabilities into GDB for bit masks. (GDB does just fine +with enumerations.) + +@menu +* enums:: Enumerations +* enum-code:: Strings to Enums and Back +* masks:: Bit Maps and Masks +@end menu + +@node enums +@subsection Enumerations + +@file{str2enum.tpl} + +Produce an enumeration for a list of input ``cmd''s (names). +Optionally, produce functions to: + +@itemize @bullet +@item +convert a string to an enumeration +@item +convert an enumeration value into a string +@item +invoke a function based on the first token name found in a string +@end itemize + +The header file produced will contain the enumeration and declarations +for the optional procedures. The code (@file{.c}) file will contain +these optional procedures, but can be omitted if the @code{no-code} +attribute is specified. + +The following attributes are recognized with the @code{str2enum} template: + +@table @samp +@item cmd +You must provide a series of these attributes: they specify the list of +names used in the enumeration. Specific values for the names may be +specified by specifying a numeric index for these attributes. +e.g. @code{cmd[5] = mumble;} will cause +@example +FOO_CMD_MUMBLE = 5 +@end example +@noindent +to be inserted into the enumeration. +Do not specify a value of ``@t{invalid}'', unless you specify the +@code{invalid-name} attribute. (In that case, do not specify a +@code{cmd} value that matches the @code{invalid-name} value.) + +@item prefix +This specifies the first segment of each enumeration name. +If not specified, the first segment of the enumeration definition file name +will be used. e.g. @file{foo-bar.def} will default to a @code{FOO} prefix. + +@item type +Normally, there is a second constant segment following the prefix. If not +specified, it will be @code{CMD}, so if both @code{prefix} and @code{type} +were to default from @file{foo-bar.def}, you will have enumeration values +prefixed with @code{FOO_CMD_}. If specified as the empty string, there will +be no ``type'' component to the name and the default constant prefix will +thus be @code{FOO_}. + +@item base-name +This specifies the base name of the output files, enumeration type and the +translation functions. The default is to use the @code{basename(3)} of +the definition file. e.g. @file{foo-bar.def} results in a @code{base-name} +of @code{foo-bar}. + +@item invalid-val +The default invalid value is zero. Sometimes, it is useful for zero to be +valid. If so, you can specify @t{~0} or the empty string to be invalid. +The empty string will cause the enumeration count (maximum value plus 1) to +be the invalid value. + +@item invalid-name +By default, the invalid value is emitted into the enumeration as +@code{FOO_INVALID_CMD}. Specifying this attribute will replace +@code{INVALID} with whatever you place in this attribute. + +@item add-on-text +Additional text to insert into the code or header file. + +@table @samp +@item ao-file +Which file to insert the text into. There are four choices, +only two of which are relevant for the @file{str2enum} template: +``@t{enum-header}'', ``@t{enum-code}'', ``@t{mask-header}'' or ``@t{mask-code}''. + +@item ao-text +The text to insert. +@end table +@end table + +@c +@c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +@c +@node enum-code +@subsection Strings to Enums and Back + +A continuation of the attributes for the @file{str2enum.tpl} template. + +@table @samp +@item no-code +Do not emit any string to enumeration or enumeration to string code at all. +If this is specified, the remainder of the attributes have no effect. + +@item no-name +Do not emit the enumeration to name function. + +@item no-case +When looking up a string, the case of the input string is ignored. + +@item alias +A single punctuation character can be interpreted as a command. The first +character of this attribute is the aliased character and the remainder the +aliased-to command. e.g. ``@t{#comment}'' makes '@t{#}' an alias for the +@command{comment} command. ``@t{#comment}'' must still be listed in the +@code{cmd} attributes. + +@item length +Specify how lengths are to be handled. Under the covers, @command{gperf(1)} +is used to map a string to an enumeration value. The code it produces +requires the string length to be passed in. You may pass in the length +yourself, or the generated code may figure it out, or you may ask for that +length to be returned back after being figured out. + +You have four choices with the @code{length} attribute: + +@itemize @bullet +@item +Do not specify it. You will need to provide the length. +@item +Specify ``@t{provided}''. You will need to provide the length. +@item +Specify ``@t{returned}''. You must pass a pointer to a @t{size_t} object. +If the name is found, the length will be put there. +@item +Specify an empty string. The generated code will compute the length and +that computed length will not be returned. The length parameter may be +omitted. If the input strings contain only enumeration names, then this +would be sufficient. +@item +Specifying anything else is undefined. +@end itemize + +@item partial +Normally, a name must fully match to be found successfully. This attribute +causes the generated code to look for partial matches if the full match +@command{gperf} function fails. Partial matches must be at least two +characters long. + +@item undef-str +by default, the display string for an undefined value is +``@t{* UNDEFINED *}''. Use this to change that. + +@item equate +A series of punctuation characters considered equivalent. +Typically, ``@t{-_}'' but sometimes (Tandem) ``@t{-_^}''. +Do not use '@t{#}' in the list of characters. + +@item dispatch +A lookup procedure will call a dispatch function for the procedure named +after the keyword identified at the start of a string. Other than as +specially noted below, for every named ``cmd'', must have a handling +function, plus another function to handle errors, with ``invalid'' (or the +@code{invalid-name} value) as the @code{cmd} name. Multiple @code{dispatch} +definitions will produce multiple dispatching functions, each with +(potentially) unique argument lists and return types. + +You may also use @code{add-on-text} to ``@t{#define}'' one function to +another, thus allowing one function to handle multiple keywords or commands. +The @code{d-nam} and @code{d-ret} attributes are required. The @code{d-arg}, +@code{d-omit} and @code{d-only} attributes are optional: + +@table @samp +@item d-nam +This must be a printf format string with one formatting element: @code{%s}. +The @code{%s} will be replaced by each @code{cmd} name. The @code{%s} will +be stripped and the result will be combined with the base name to construct +the dispatch procedure name. + +@item d-ret +The return type of the dispatched function, even if ``@t{void}''. + +@item d-arg +If there are additional arguments that are to be passed through to the +dispatched function, specify this as though it were part of the procedure +header. (It will be glued into the dispatching function as is and sedded +into what is needed for the dispatched function.) + +@item d-omit +Instead of providing handling functions for all of the @code{cmd} names, +the invalid function will be called for omitted command codes. + +@item d-only +You need only provide functions for the names listed by @code{d-only}, plus +the ``invalid'' name. All other command values will trigger calls to +the invalid handling function. Note that the invalid call can distinguish +from a command that could not be found by examining the value of its +first (@code{id}) argument. +@end table + +The handler functions will have the command enumeration as its first first +argument, a pointer to a constant string that will be the character +@i{after} the parsed command (keyword) name, plus any @code{d-arg} arguments +that follow that. + +@noindent +As an example, a file @file{samp-chk.def} containing this: +@example +AutoGen Definitions str2enum; +cmd = one, two; invalid-name = oops; +dispatch = @{ d-nam = 'hdl_%s_cmd'; d-ret = void; @}; +@end example +@noindent +will produce a header containing: +@example +typedef enum @{ + SAMP_OOPS_CMD = 0, + SAMP_CMD_ONE = 1, + SAMP_CMD_TWO = 2, + SAMP_COUNT_CMD +@} samp_chk_enum_t; + +extern samp_chk_enum_t +find_samp_chk_cmd(char const * str, size_t len); + +typedef void(samp_chk_handler_t)( + samp_chk_enum_t id, char const * str); + +samp_chk_handler_t + hdl_oops_cmd, hdl_one_cmd, hdl_two_cmd; + +extern void +disp_samp_chk(char * str, size_t len); + +extern char const * +samp_chk_name(samp_chk_enum_t id); +@end example + +@itemize @bullet +@item +@code{find_samp_chk_cmd} will look up a @code{len} byte @code{str} and +return the corresponding @code{samp_chk_enum_t} value. That value is +@code{SAMP_OOPS_CMD} if the string is not ``one'' or ``two''. +@item +@code{samp_chk_handler_t} is the type of the callback procedures. +Three must be provided for the dispatching function to call: +@code{hdl_oops_cmd}, @code{hdl_one_cmd} and @code{hdl_two_cmd}. +@code{hdl_oops_cmd} will receive calls when the string does not match. +@item +@code{disp_samp_chk} this function will call the handler function +and return whatever the handler returns. In this case, it is void. +@item +@code{samp_chk_name} will return a string corresponding to the enumeration +value argument. If the value is not valid, ``* UNDEFINED *'' (or the +value of @code{undef-str}) is used. +@end itemize +@end table + +@c +@c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +@c +@node masks +@subsection Bit Maps and Masks + +@file{str2mask.tpl} + +This template leverages highly off of enumerations (@pxref{enums}). It will +produce a header file with bit masks defined for each bit specified with a +@code{cmd} attribute. 63 is the highest legal bit number because this +template has not been extended to cope with multiple word masks. (Patches +would be welcome.) + +There are a few constraints on the names allowed: + +@itemize @bullet +@item +names are constrained to alphanumerics and the underscore +@item +aliases are not allowed +@item +dispatch procedures are not allowed +@end itemize + +@code{no-code} and @code{no-name} are honored. @code{dispatch} is not. The +lookup function will examine each token in an input string, determine which +bit is specified and add it into a result. The names may be prefixed with a +hyphen (@t{-}) or tilde (@t{~}) to remove the bit(s) from the cumulative +result. If the string begins with a plus (@t{+}), hyphen or tilde, a ``base +value'' parameter is used for the starting mask, otherwise the conversion +starts with zero. + +Beyond the enumeration attributes that are used (or ignored), the +@file{str2mask} template accepts a @code{mask} attribute. It takes a few +``subattributes'': + +@table @samp +@item m-name +a special name for a sub-collection of the mask bits + +@item m-bit +The name of each previously defined bit(s). If the desired previously +defined value is a mask, that @code{m-name} must be suffixed with ``@t{-mask}''. + +@item m-invert +When all done collecting the bits, x-or the value with the mask +of all the bits in the collection. +@end table + +@noindent +A mask of all bits in the collection is always generated. diff --git a/doc/fdl.texi b/doc/fdl.texi new file mode 100644 index 0000000..cb71f05 --- /dev/null +++ b/doc/fdl.texi @@ -0,0 +1,505 @@ +@c The GNU Free Documentation License. +@center Version 1.3, 3 November 2008 + +@c This file is intended to be included within another document, +@c hence no sectioning command or @node. + +@display +Copyright @copyright{} 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc. +@uref{http://fsf.org/} + +Everyone is permitted to copy and distribute verbatim copies +of this license document, but changing it is not allowed. +@end display + +@enumerate 0 +@item +PREAMBLE + +The purpose of this License is to make a manual, textbook, or other +functional and useful document @dfn{free} in the sense of freedom: to +assure everyone the effective freedom to copy and redistribute it, +with or without modifying it, either commercially or noncommercially. +Secondarily, this License preserves for the author and publisher a way +to get credit for their work, while not being considered responsible +for modifications made by others. + +This License is a kind of ``copyleft'', which means that derivative +works of the document must themselves be free in the same sense. It +complements the GNU General Public License, which is a copyleft +license designed for free software. + +We have designed this License in order to use it for manuals for free +software, because free software needs free documentation: a free +program should come with manuals providing the same freedoms that the +software does. But this License is not limited to software manuals; +it can be used for any textual work, regardless of subject matter or +whether it is published as a printed book. We recommend this License +principally for works whose purpose is instruction or reference. + +@item +APPLICABILITY AND DEFINITIONS + +This License applies to any manual or other work, in any medium, that +contains a notice placed by the copyright holder saying it can be +distributed under the terms of this License. Such a notice grants a +world-wide, royalty-free license, unlimited in duration, to use that +work under the conditions stated herein. The ``Document'', below, +refers to any such manual or work. Any member of the public is a +licensee, and is addressed as ``you''. You accept the license if you +copy, modify or distribute the work in a way requiring permission +under copyright law. + +A ``Modified Version'' of the Document means any work containing the +Document or a portion of it, either copied verbatim, or with +modifications and/or translated into another language. + +A ``Secondary Section'' is a named appendix or a front-matter section +of the Document that deals exclusively with the relationship of the +publishers or authors of the Document to the Document's overall +subject (or to related matters) and contains nothing that could fall +directly within that overall subject. (Thus, if the Document is in +part a textbook of mathematics, a Secondary Section may not explain +any mathematics.) The relationship could be a matter of historical +connection with the subject or with related matters, or of legal, +commercial, philosophical, ethical or political position regarding +them. + +The ``Invariant Sections'' are certain Secondary Sections whose titles +are designated, as being those of Invariant Sections, in the notice +that says that the Document is released under this License. If a +section does not fit the above definition of Secondary then it is not +allowed to be designated as Invariant. The Document may contain zero +Invariant Sections. If the Document does not identify any Invariant +Sections then there are none. + +The ``Cover Texts'' are certain short passages of text that are listed, +as Front-Cover Texts or Back-Cover Texts, in the notice that says that +the Document is released under this License. A Front-Cover Text may +be at most 5 words, and a Back-Cover Text may be at most 25 words. + +A ``Transparent'' copy of the Document means a machine-readable copy, +represented in a format whose specification is available to the +general public, that is suitable for revising the document +straightforwardly with generic text editors or (for images composed of +pixels) generic paint programs or (for drawings) some widely available +drawing editor, and that is suitable for input to text formatters or +for automatic translation to a variety of formats suitable for input +to text formatters. A copy made in an otherwise Transparent file +format whose markup, or absence of markup, has been arranged to thwart +or discourage subsequent modification by readers is not Transparent. +An image format is not Transparent if used for any substantial amount +of text. A copy that is not ``Transparent'' is called ``Opaque''. + +Examples of suitable formats for Transparent copies include plain +ASCII without markup, Texinfo input format, La@TeX{} input +format, SGML or XML using a publicly available +DTD, and standard-conforming simple HTML, +PostScript or PDF designed for human modification. Examples +of transparent image formats include PNG, XCF and +JPG. Opaque formats include proprietary formats that can be +read and edited only by proprietary word processors, SGML or +XML for which the DTD and/or processing tools are +not generally available, and the machine-generated HTML, +PostScript or PDF produced by some word processors for +output purposes only. + +The ``Title Page'' means, for a printed book, the title page itself, +plus such following pages as are needed to hold, legibly, the material +this License requires to appear in the title page. For works in +formats which do not have any title page as such, ``Title Page'' means +the text near the most prominent appearance of the work's title, +preceding the beginning of the body of the text. + +The ``publisher'' means any person or entity that distributes copies +of the Document to the public. + +A section ``Entitled XYZ'' means a named subunit of the Document whose +title either is precisely XYZ or contains XYZ in parentheses following +text that translates XYZ in another language. (Here XYZ stands for a +specific section name mentioned below, such as ``Acknowledgements'', +``Dedications'', ``Endorsements'', or ``History''.) To ``Preserve the Title'' +of such a section when you modify the Document means that it remains a +section ``Entitled XYZ'' according to this definition. + +The Document may include Warranty Disclaimers next to the notice which +states that this License applies to the Document. These Warranty +Disclaimers are considered to be included by reference in this +License, but only as regards disclaiming warranties: any other +implication that these Warranty Disclaimers may have is void and has +no effect on the meaning of this License. + +@item +VERBATIM COPYING + +You may copy and distribute the Document in any medium, either +commercially or noncommercially, provided that this License, the +copyright notices, and the license notice saying this License applies +to the Document are reproduced in all copies, and that you add no other +conditions whatsoever to those of this License. You may not use +technical measures to obstruct or control the reading or further +copying of the copies you make or distribute. However, you may accept +compensation in exchange for copies. If you distribute a large enough +number of copies you must also follow the conditions in section 3. + +You may also lend copies, under the same conditions stated above, and +you may publicly display copies. + +@item +COPYING IN QUANTITY + +If you publish printed copies (or copies in media that commonly have +printed covers) of the Document, numbering more than 100, and the +Document's license notice requires Cover Texts, you must enclose the +copies in covers that carry, clearly and legibly, all these Cover +Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on +the back cover. Both covers must also clearly and legibly identify +you as the publisher of these copies. The front cover must present +the full title with all words of the title equally prominent and +visible. You may add other material on the covers in addition. +Copying with changes limited to the covers, as long as they preserve +the title of the Document and satisfy these conditions, can be treated +as verbatim copying in other respects. + +If the required texts for either cover are too voluminous to fit +legibly, you should put the first ones listed (as many as fit +reasonably) on the actual cover, and continue the rest onto adjacent +pages. + +If you publish or distribute Opaque copies of the Document numbering +more than 100, you must either include a machine-readable Transparent +copy along with each Opaque copy, or state in or with each Opaque copy +a computer-network location from which the general network-using +public has access to download using public-standard network protocols +a complete Transparent copy of the Document, free of added material. +If you use the latter option, you must take reasonably prudent steps, +when you begin distribution of Opaque copies in quantity, to ensure +that this Transparent copy will remain thus accessible at the stated +location until at least one year after the last time you distribute an +Opaque copy (directly or through your agents or retailers) of that +edition to the public. + +It is requested, but not required, that you contact the authors of the +Document well before redistributing any large number of copies, to give +them a chance to provide you with an updated version of the Document. + +@item +MODIFICATIONS + +You may copy and distribute a Modified Version of the Document under +the conditions of sections 2 and 3 above, provided that you release +the Modified Version under precisely this License, with the Modified +Version filling the role of the Document, thus licensing distribution +and modification of the Modified Version to whoever possesses a copy +of it. In addition, you must do these things in the Modified Version: + +@enumerate A +@item +Use in the Title Page (and on the covers, if any) a title distinct +from that of the Document, and from those of previous versions +(which should, if there were any, be listed in the History section +of the Document). You may use the same title as a previous version +if the original publisher of that version gives permission. + +@item +List on the Title Page, as authors, one or more persons or entities +responsible for authorship of the modifications in the Modified +Version, together with at least five of the principal authors of the +Document (all of its principal authors, if it has fewer than five), +unless they release you from this requirement. + +@item +State on the Title page the name of the publisher of the +Modified Version, as the publisher. + +@item +Preserve all the copyright notices of the Document. + +@item +Add an appropriate copyright notice for your modifications +adjacent to the other copyright notices. + +@item +Include, immediately after the copyright notices, a license notice +giving the public permission to use the Modified Version under the +terms of this License, in the form shown in the Addendum below. + +@item +Preserve in that license notice the full lists of Invariant Sections +and required Cover Texts given in the Document's license notice. + +@item +Include an unaltered copy of this License. + +@item +Preserve the section Entitled ``History'', Preserve its Title, and add +to it an item stating at least the title, year, new authors, and +publisher of the Modified Version as given on the Title Page. If +there is no section Entitled ``History'' in the Document, create one +stating the title, year, authors, and publisher of the Document as +given on its Title Page, then add an item describing the Modified +Version as stated in the previous sentence. + +@item +Preserve the network location, if any, given in the Document for +public access to a Transparent copy of the Document, and likewise +the network locations given in the Document for previous versions +it was based on. These may be placed in the ``History'' section. +You may omit a network location for a work that was published at +least four years before the Document itself, or if the original +publisher of the version it refers to gives permission. + +@item +For any section Entitled ``Acknowledgements'' or ``Dedications'', Preserve +the Title of the section, and preserve in the section all the +substance and tone of each of the contributor acknowledgements and/or +dedications given therein. + +@item +Preserve all the Invariant Sections of the Document, +unaltered in their text and in their titles. Section numbers +or the equivalent are not considered part of the section titles. + +@item +Delete any section Entitled ``Endorsements''. Such a section +may not be included in the Modified Version. + +@item +Do not retitle any existing section to be Entitled ``Endorsements'' or +to conflict in title with any Invariant Section. + +@item +Preserve any Warranty Disclaimers. +@end enumerate + +If the Modified Version includes new front-matter sections or +appendices that qualify as Secondary Sections and contain no material +copied from the Document, you may at your option designate some or all +of these sections as invariant. To do this, add their titles to the +list of Invariant Sections in the Modified Version's license notice. +These titles must be distinct from any other section titles. + +You may add a section Entitled ``Endorsements'', provided it contains +nothing but endorsements of your Modified Version by various +parties---for example, statements of peer review or that the text has +been approved by an organization as the authoritative definition of a +standard. + +You may add a passage of up to five words as a Front-Cover Text, and a +passage of up to 25 words as a Back-Cover Text, to the end of the list +of Cover Texts in the Modified Version. Only one passage of +Front-Cover Text and one of Back-Cover Text may be added by (or +through arrangements made by) any one entity. If the Document already +includes a cover text for the same cover, previously added by you or +by arrangement made by the same entity you are acting on behalf of, +you may not add another; but you may replace the old one, on explicit +permission from the previous publisher that added the old one. + +The author(s) and publisher(s) of the Document do not by this License +give permission to use their names for publicity for or to assert or +imply endorsement of any Modified Version. + +@item +COMBINING DOCUMENTS + +You may combine the Document with other documents released under this +License, under the terms defined in section 4 above for modified +versions, provided that you include in the combination all of the +Invariant Sections of all of the original documents, unmodified, and +list them all as Invariant Sections of your combined work in its +license notice, and that you preserve all their Warranty Disclaimers. + +The combined work need only contain one copy of this License, and +multiple identical Invariant Sections may be replaced with a single +copy. If there are multiple Invariant Sections with the same name but +different contents, make the title of each such section unique by +adding at the end of it, in parentheses, the name of the original +author or publisher of that section if known, or else a unique number. +Make the same adjustment to the section titles in the list of +Invariant Sections in the license notice of the combined work. + +In the combination, you must combine any sections Entitled ``History'' +in the various original documents, forming one section Entitled +``History''; likewise combine any sections Entitled ``Acknowledgements'', +and any sections Entitled ``Dedications''. You must delete all +sections Entitled ``Endorsements.'' + +@item +COLLECTIONS OF DOCUMENTS + +You may make a collection consisting of the Document and other documents +released under this License, and replace the individual copies of this +License in the various documents with a single copy that is included in +the collection, provided that you follow the rules of this License for +verbatim copying of each of the documents in all other respects. + +You may extract a single document from such a collection, and distribute +it individually under this License, provided you insert a copy of this +License into the extracted document, and follow this License in all +other respects regarding verbatim copying of that document. + +@item +AGGREGATION WITH INDEPENDENT WORKS + +A compilation of the Document or its derivatives with other separate +and independent documents or works, in or on a volume of a storage or +distribution medium, is called an ``aggregate'' if the copyright +resulting from the compilation is not used to limit the legal rights +of the compilation's users beyond what the individual works permit. +When the Document is included in an aggregate, this License does not +apply to the other works in the aggregate which are not themselves +derivative works of the Document. + +If the Cover Text requirement of section 3 is applicable to these +copies of the Document, then if the Document is less than one half of +the entire aggregate, the Document's Cover Texts may be placed on +covers that bracket the Document within the aggregate, or the +electronic equivalent of covers if the Document is in electronic form. +Otherwise they must appear on printed covers that bracket the whole +aggregate. + +@item +TRANSLATION + +Translation is considered a kind of modification, so you may +distribute translations of the Document under the terms of section 4. +Replacing Invariant Sections with translations requires special +permission from their copyright holders, but you may include +translations of some or all Invariant Sections in addition to the +original versions of these Invariant Sections. You may include a +translation of this License, and all the license notices in the +Document, and any Warranty Disclaimers, provided that you also include +the original English version of this License and the original versions +of those notices and disclaimers. In case of a disagreement between +the translation and the original version of this License or a notice +or disclaimer, the original version will prevail. + +If a section in the Document is Entitled ``Acknowledgements'', +``Dedications'', or ``History'', the requirement (section 4) to Preserve +its Title (section 1) will typically require changing the actual +title. + +@item +TERMINATION + +You may not copy, modify, sublicense, or distribute the Document +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense, or distribute it is void, and +will automatically terminate your rights under this License. + +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, receipt of a copy of some or all of the same material does +not give you any rights to use it. + +@item +FUTURE REVISIONS OF THIS LICENSE + +The Free Software Foundation may publish new, revised versions +of the GNU Free Documentation 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. See +@uref{http://www.gnu.org/copyleft/}. + +Each version of the License is given a distinguishing version number. +If the Document specifies that a particular numbered version of this +License ``or any later version'' applies to it, you have the option of +following the terms and conditions either of that specified version or +of any later version that has been published (not as a draft) by the +Free Software Foundation. If the Document does not specify a version +number of this License, you may choose any version ever published (not +as a draft) by the Free Software Foundation. If the Document +specifies that a proxy can decide which future versions of this +License can be used, that proxy's public statement of acceptance of a +version permanently authorizes you to choose that version for the +Document. + +@item +RELICENSING + +``Massive Multiauthor Collaboration Site'' (or ``MMC Site'') means any +World Wide Web server that publishes copyrightable works and also +provides prominent facilities for anybody to edit those works. A +public wiki that anybody can edit is an example of such a server. A +``Massive Multiauthor Collaboration'' (or ``MMC'') contained in the +site means any set of copyrightable works thus published on the MMC +site. + +``CC-BY-SA'' means the Creative Commons Attribution-Share Alike 3.0 +license published by Creative Commons Corporation, a not-for-profit +corporation with a principal place of business in San Francisco, +California, as well as future copyleft versions of that license +published by that same organization. + +``Incorporate'' means to publish or republish a Document, in whole or +in part, as part of another Document. + +An MMC is ``eligible for relicensing'' if it is licensed under this +License, and if all works that were first published under this License +somewhere other than this MMC, and subsequently incorporated in whole +or in part into the MMC, (1) had no cover texts or invariant sections, +and (2) were thus incorporated prior to November 1, 2008. + +The operator of an MMC Site may republish an MMC contained in the site +under CC-BY-SA on the same site at any time before August 1, 2009, +provided the MMC is eligible for relicensing. + +@end enumerate + +@page +@heading ADDENDUM: How to use this License for your documents + +To use this License in a document you have written, include a copy of +the License in the document and put the following copyright and +license notices just after the title page: + +@smallexample +@group + Copyright (C) @var{year} @var{your name}. + Permission is granted to copy, distribute and/or modify this document + under the terms of the GNU Free Documentation License, Version 1.3 + or any later version published by the Free Software Foundation; + with no Invariant Sections, no Front-Cover Texts, and no Back-Cover + Texts. A copy of the license is included in the section entitled ``GNU + Free Documentation License''. +@end group +@end smallexample + +If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts, +replace the ``with@dots{}Texts.''@: line with this: + +@smallexample +@group + with the Invariant Sections being @var{list their titles}, with + the Front-Cover Texts being @var{list}, and with the Back-Cover Texts + being @var{list}. +@end group +@end smallexample + +If you have Invariant Sections without Cover Texts, or some other +combination of the three, merge those two alternatives to suit the +situation. + +If your document contains nontrivial examples of program code, we +recommend releasing these examples in parallel under your choice of +free software license, such as the GNU General Public License, +to permit their use in free software. + +@c Local Variables: +@c ispell-local-pdict: "ispell-dict" +@c End: diff --git a/doc/gendocs_template b/doc/gendocs_template new file mode 100644 index 0000000..daf3bd2 --- /dev/null +++ b/doc/gendocs_template @@ -0,0 +1,91 @@ +<!--#include virtual="/server/header.html" --> +<!-- Parent-Version: 1.77 --> +<title>%%TITLE%% - GNU Project - Free Software Foundation + +

%%TITLE%%

+ +
Free Software Foundation
+
last updated %%DATE%%
+ +

This manual (%%PACKAGE%%) is available in the following formats:

+ + + +

You can buy printed copies of +some manuals (among other items) from the Free Software Foundation; +this helps support FSF activities.

+ +

(This page generated by the %%SCRIPTNAME%% +script.)

+ + + + + + + + diff --git a/doc/invoke-autogen.texi b/doc/invoke-autogen.texi new file mode 100644 index 0000000..b33c1ad --- /dev/null +++ b/doc/invoke-autogen.texi @@ -0,0 +1,859 @@ +@node autogen Invocation +@chapter Invoking autogen +@pindex autogen +@cindex The Automated Program Generator +@ignore +# -*- buffer-read-only: t -*- vi: set ro: +# +# DO NOT EDIT THIS FILE (invoke-autogen.texi) +# +# It has been AutoGen-ed +# From the definitions /u/bkorb/tools/ag/autogen-bld/agen5/opts.def +# and the template file agtexi-cmd.tpl +@end ignore + +AutoGen creates text files from templates using external definitions. + +@code{AutoGen} is designed for generating program files that contain +repetitive text with varied substitutions. The goal is to simplify the +maintenance of programs that contain large amounts of repetitious text. +This is especially valuable if there are several blocks of such text +that must be kept synchronized. + +One common example is the problem of maintaining the code required for +processing program options. Processing options requires a minimum of +four different constructs be kept in proper order in different places +in your program. You need at least: The flag character in the flag +string, code to process the flag when it is encountered, a global +state variable or two, and a line in the usage text. +You will need more things besides this if you choose to implement +long option names, configuration file processing, environment variables +and so on. + +All of this can be done mechanically; with the proper templates +and this program. + + +This chapter was generated by @strong{AutoGen}, +using the @code{agtexi-cmd} template and the option descriptions for the @code{autogen} program. +This software is released under the GNU General Public License, version 3 or later. + +@menu +* autogen usage:: autogen help/usage (@option{--help}) +* autogen input-select:: input-select options +* autogen out-handling:: out-handling options +* autogen debug-tpl:: debug-tpl options +* autogen processing:: processing options +* autogen dep-track:: dep-track options +* autogen autoopts-opts:: autoopts-opts options +* autogen config:: presetting/configuring autogen +* autogen exit status:: exit status +* autogen Examples:: Examples +@end menu + +@node autogen usage +@section autogen help/usage (@option{--help}) +@cindex autogen help + +This is the automatically generated usage text for autogen. + +The text printed is the same whether selected with the @code{help} option +(@option{--help}) or the @code{more-help} option (@option{--more-help}). @code{more-help} will print +the usage text by passing it through a pager program. +@code{more-help} is disabled on platforms without a working +@code{fork(2)} function. The @code{PAGER} environment variable is +used to select the program, defaulting to @file{more}. Both will exit +with a status code of 0. + +@exampleindent 0 +@example +autogen (GNU AutoGen) - The Automated Program Generator - Ver. 5.18.15.001 +Usage: autogen [ - [] | --[@{=| @}] ]... [ ] + +The following options select definitions, templates and scheme functions +to use: + + Flg Arg Option-Name Description + -L Str templ-dirs Search for templates in DIR + - may appear multiple times + -T Str override-tpl Use TPL-FILE for the template + - may not be preset + Str definitions Read definitions from FILE + - disabled as '--no-definitions' + - enabled by default + - may not be preset + Str shell name or path name of shell to use + -m no no-fmemopen Do not use in-mem streams + Str equate characters considered equivalent + +The following options modify how output is handled: + + Flg Arg Option-Name Description + -b Str base-name Specify NAME as the base name for output + - may not be preset + no source-time set mod times to latest source + - disabled as '--no-source-time' + no writable Allow output files to be writable + - disabled as '--not-writable' + +The following options are often useful while debugging new templates: + + Flg Arg Option-Name Description + Num loop-limit Limit on increment loops + - is scalable with a suffix: k/K/m/M/g/G/t/T + - it must lie in one of the ranges: + -1 exactly, or + 1 to 16777216 + -t Num timeout Limit server shell operations to SECONDS + - it must be in the range: + 0 to 3600 + KWd trace tracing level of detail + Str trace-out tracing output file or filter + --- show-defs This option has been disabled + no used-defines Show the definitions used + - may not be preset + -C no core Leave a core dump on a failure exit + +These options can be used to control what gets processed in the +definitions files and template files: + + Flg Arg Option-Name Description + -s Str skip-suffix Skip the file with this SUFFIX + - prohibits the option 'select-suffix' + - may not be preset + - may appear multiple times + -o Str select-suffix specify this output suffix + - may not be preset + - may appear multiple times + -D Str define name to add to definition list + - may appear multiple times + -U Str undefine definition list removal pattern + - an alternate for 'define' + +This option is used to automate dependency tracking: + + Flg Arg Option-Name Description + -M opt make-dep emit make dependency file + - may not be preset + - may appear multiple times + +help, version, option and error handling: + + Flg Arg Option-Name Description + no no-abort Do not abort on errors + +Version, usage and configuration options: + + Flg Arg Option-Name Description + -R Str reset-option reset an option's state + -v opt version output version information and exit + -? no help display extended usage information and exit + -! no more-help extended usage information passed thru pager + -u no usage abbreviated usage to stdout + -> opt save-opts save the option state to a config file + -< Str load-opts load options from a config file + - disabled as '--no-load-opts' + - may appear multiple times + +Options are specified by doubled hyphens and their name or by a single +hyphen and the flag character. +AutoGen creates text files from templates using external definitions. + +The following option preset mechanisms are supported: + - reading file $HOME + - reading file ./.autogenrc + - examining environment variables named AUTOGEN_* + +The valid "trace" option keywords are: + nothing debug-message server-shell templates block-macros + expressions everything + or an integer from 0 through 6 +AutoGen is a tool designed for generating program files that contain +repetitive text with varied substitutions. + +Please send bug reports to: +@end example +@exampleindent 4 + +@node autogen input-select +@section input-select options +The following options select definitions, templates and scheme functions to use. +@subheading templ-dirs option (-L). +@anchor{autogen templ-dirs} +@cindex autogen-templ-dirs + +This is the ``search for templates in @file{dir}'' option. +This option takes a string argument @file{DIR}. + +@noindent +This option has some usage constraints. It: +@itemize @bullet +@item +may appear an unlimited number of times. +@end itemize + +Add a directory to the list of directories @command{autogen} searches when +opening a template, either as the primary template or an included one. +The last entry has the highest priority in the search list. That is +to say, they are searched in reverse order. +@subheading override-tpl option (-T). +@anchor{autogen override-tpl} +@cindex autogen-override-tpl + +This is the ``use @file{tpl-file} for the template'' option. +This option takes a string argument @file{TPL-FILE}. + +@noindent +This option has some usage constraints. It: +@itemize @bullet +@item +may not be preset with environment variables or configuration (rc/ini) files. +@end itemize + +Definition files specify the standard template that is to be expanded. +This option will override that name and expand a different template. +@subheading definitions option. +@anchor{autogen definitions} +@cindex autogen-definitions + +This is the ``read definitions from @file{file}'' option. +This option takes a string argument @file{FILE}. + +@noindent +This option has some usage constraints. It: +@itemize @bullet +@item +can be disabled with --no-definitions. +@item +It is enabled by default. +@item +may not be preset with environment variables or configuration (rc/ini) files. +@end itemize + +Use this argument to specify the input definitions file with a +command line option. If you do not specify this option, then +there must be a command line argument that specifies the file, +even if only to specify stdin with a hyphen (@code{-}). +Specify, @code{--no-definitions} when you wish to process +a template without any active AutoGen definitions. +@subheading shell option. +@anchor{autogen shell} +@cindex autogen-shell + +This is the ``name or path name of shell to use'' option. +This option takes a string argument @file{shell}. + +@noindent +This option has some usage constraints. It: +@itemize @bullet +@item +must be compiled in by defining @code{SHELL_ENABLED} during the compilation. +@end itemize + +By default, when AutoGen is built, the configuration is probed for a +reasonable Bourne-like shell to use for shell script processing. If +a particular template needs an alternate shell, it must be specified +with this option on the command line, with an environment variable +(@code{SHELL}) or in the configuration/initialization file. +@subheading no-fmemopen option (-m). +@anchor{autogen no-fmemopen} +@cindex autogen-no-fmemopen + +This is the ``do not use in-mem streams'' option. +If the local C library supports "@code{fopencookie(3GNU)}", or +"@code{funopen(3BSD)}" then AutoGen prefers to use in-memory stream +buffer opens instead of anonymous files. This may lead to problems +if there is a shortage of virtual memory. If, for a particular +application, you run out of memory, then specify this option. +This is unlikely in a modern 64-bit virtual memory environment. + +On platforms without these functions, the option is accepted +but ignored. @code{fmemopen(POSIX)} is not adequate because +its string buffer is not reallocatable. @code{open_memstream(POSIX)} +is @i{also} not adequate because the stream is only opened for +output. AutoGen needs a reallocatable buffer available for both +reading and writing. +@subheading equate option. +@anchor{autogen equate} +@cindex autogen-equate + +This is the ``characters considered equivalent'' option. +This option takes a string argument @file{char-list}. +This option will alter the list of characters considered equivalent. +The default are the three characters, "_-^". (The last is conventional +on a Tandem/HP-NonStop, and I used to do a lot of work on Tandems.) +@node autogen out-handling +@section out-handling options +The following options modify how output is handled. +@subheading base-name option (-b). +@anchor{autogen base-name} +@cindex autogen-base-name + +This is the ``specify @code{name} as the base name for output'' option. +This option takes a string argument @file{NAME}. + +@noindent +This option has some usage constraints. It: +@itemize @bullet +@item +may not be preset with environment variables or configuration (rc/ini) files. +@end itemize + +A template may specify the exact name of the output file. Normally, +it does not. Instead, the name is composed of the base name of the +definitions file with suffixes appended. This option will override the +base name derived from the definitions file name. This is required if +there is no definitions file and advisable if definitions are being +read from stdin. If the definitions are being read from standard in, +the base name defaults to @file{stdin}. Any leading directory components +in the name will be silently removed. If you wish the output file to +appear in a particular directory, it is recommended that you "cd" into +that directory first, or use directory names in the format specification +for the output suffix lists, @xref{pseudo macro}. +@subheading source-time option. +@anchor{autogen source-time} +@cindex autogen-source-time + +This is the ``set mod times to latest source'' option. + +@noindent +This option has some usage constraints. It: +@itemize @bullet +@item +can be disabled with --no-source-time. +@end itemize + +If you stamp your output files with the @code{DNE} macro output, then +your output files will always be different, even if the content has +not really changed. If you use this option, then the modification +time of the output files will change only if the input files change. +This will help reduce unneeded builds. +@subheading writable option. +@anchor{autogen writable} +@cindex autogen-writable + +This is the ``allow output files to be writable'' option. + +@noindent +This option has some usage constraints. It: +@itemize @bullet +@item +can be disabled with --not-writable. +@end itemize + +This option will leave output files writable. +Normally, output files are read-only. +@node autogen debug-tpl +@section debug-tpl options +The following options are often useful while debugging new templates. +They specify limits that prevent the template from taking overly long +or producing more output than expected. +@subheading loop-limit option. +@anchor{autogen loop-limit} +@cindex autogen-loop-limit + +This is the ``limit on increment loops'' option. +This option takes a number argument @file{lim}. +This option prevents runaway loops. For example, if you accidentally +specify, "FOR x (for-from 1) (for-to -1) (for-by 1)", it will take a +long time to finish. If you do have more than 256 entries in tables, +you will need to specify a new limit with this option. +@subheading timeout option (-t). +@anchor{autogen timeout} +@cindex autogen-timeout + +This is the ``limit server shell operations to @code{seconds}'' option. +This option takes a number argument @file{SECONDS}. + +@noindent +This option has some usage constraints. It: +@itemize @bullet +@item +must be compiled in by defining @code{SHELL_ENABLED} during the compilation. +@end itemize + +AutoGen works with a shell server process. Most normal commands will +complete in less than 10 seconds. If, however, your commands need more +time than this, use this option. + +The valid range is 0 to 3600 seconds (1 hour). +Zero will disable the server time limit. +@subheading trace option. +@anchor{autogen trace} +@cindex autogen-trace + +This is the ``tracing level of detail'' option. +This option takes a keyword argument @file{level}. + +@noindent +This option has some usage constraints. It: +@itemize @bullet +@item +This option takes a keyword as its argument. +The argument sets an enumeration value that can be tested by comparing the option value macro (OPT_VALUE_TRACE). +The available keywords are: +@example + nothing debug-message server-shell + templates block-macros expressions + everything +@end example + +or their numeric equivalent. +@end itemize + +This option will cause AutoGen to display a trace of its template +processing. There are six levels, each level including messages from +the previous levels: + +@table @samp +@item nothing +Does no tracing at all (default) + +@item debug-message +Print messages from the "DEBUG" AutoGen macro (@pxref{DEBUG}). + +@item server-shell +Traces all input and output to the server shell. This includes a shell +"independent" initialization script about 30 lines long. Its output is +discarded and not inserted into any template. + +@item templates +Traces the invocation of @code{DEFINE}d macros and @code{INCLUDE}s + +@item block-macros +Traces all block macros. The above, plus @code{IF}, @code{FOR}, +@code{CASE} and @code{WHILE}. + +@item expressions +Displays the results of expression evaluations. + +@item everything +Displays the invocation of every AutoGen macro, even @code{TEXT} macros +(i.e. the text outside of macro quotes). Additionally, if you rebuild +the ``expr.ini'' file with debugging enabled, then all calls to +AutoGen defined scheme functions will also get logged: +@* +@example +cd $@{top_builddir@}/agen5 +DEBUG_ENABLED=true bash bootstrap.dir expr.ini +make CFLAGS='-g -DDEBUG_ENABLED=1' +@end example + +Be aware that you cannot rebuild this source in this way without first +having installed the @code{autogen} executable in your search path. +Because of this, "expr.ini" is in the distributed source list, and +not in the dependencies. +@end table +@subheading trace-out option. +@anchor{autogen trace-out} +@cindex autogen-trace-out + +This is the ``tracing output file or filter'' option. +This option takes a string argument @file{file}. +The output specified may be a file name, a file that is appended to, +or, if the option argument begins with the @code{pipe} operator +(@code{|}), a command that will receive the tracing output as standard +in. For example, @code{--traceout='| less'} will run the trace output +through the @code{less} program. Appending to a file is specified by +preceding the file name with two greater-than characters (@code{>>}). +@subheading show-defs option. +@anchor{autogen show-defs} +@cindex autogen-show-defs + +This is the ``show the definition tree'' option. + +@noindent +This option has some usage constraints. It: +@itemize @bullet +@item +must be compiled in by defining @code{DEBUG_ENABLED} during the compilation. +@item +may not be preset with environment variables or configuration (rc/ini) files. +@end itemize + +This will print out the complete definition tree before processing +the template. +@subheading used-defines option. +@anchor{autogen used-defines} +@cindex autogen-used-defines + +This is the ``show the definitions used'' option. + +@noindent +This option has some usage constraints. It: +@itemize @bullet +@item +may not be preset with environment variables or configuration (rc/ini) files. +@end itemize + +This will print out the names of definition values searched for +during the processing of the template, whether actually found or +not. There may be other referenced definitions in a template in +portions of the template not evaluated. Some of the names listed +may be computed names and others AutoGen macro arguments. This is +not a means for producing a definitive, all-encompassing list of all +and only the values used from a definition file. This is intended +as an aid to template documentation only. +@subheading core option (-C). +@anchor{autogen core} +@cindex autogen-core + +This is the ``leave a core dump on a failure exit'' option. + +@noindent +This option has some usage constraints. It: +@itemize @bullet +@item +must be compiled in by defining @code{HAVE_SYS_RESOURCE_H} during the compilation. +@end itemize + +Many systems default to a zero sized core limit. If the system +has the sys/resource.h header and if this option is supplied, +then in the failure exit path, autogen will attempt to set the +soft core limit to whatever the hard core limit is. If that +does not work, then an administrator must raise the hard core +size limit. +@node autogen processing +@section processing options +These options can be used to control what gets processed +in the definitions files and template files. +They specify which outputs and parts of outputs to produce. +@subheading skip-suffix option (-s). +@anchor{autogen skip-suffix} +@cindex autogen-skip-suffix + +This is the ``skip the file with this @file{suffix}'' option. +This option takes a string argument @file{SUFFIX}. + +@noindent +This option has some usage constraints. It: +@itemize @bullet +@item +may appear an unlimited number of times. +@item +may not be preset with environment variables or configuration (rc/ini) files. +@item +must not appear in combination with any of the following options: +select-suffix. +@end itemize + +Occasionally, it may not be desirable to produce all of the output +files specified in the template. (For example, only the @file{.h} +header file, but not the @file{.c} program text.) To do this +specify @code{--skip-suffix=c} on the command line. +@subheading select-suffix option (-o). +@anchor{autogen select-suffix} +@cindex autogen-select-suffix + +This is the ``specify this output suffix'' option. +This option takes a string argument @file{SUFFIX}. + +@noindent +This option has some usage constraints. It: +@itemize @bullet +@item +may appear an unlimited number of times. +@item +may not be preset with environment variables or configuration (rc/ini) files. +@end itemize + +If you wish to override the suffix specifications in the template, +you can use one or more copies of this option. See the suffix +specification in the @ref{pseudo macro} section of the info doc. +@subheading define option (-D). +@anchor{autogen define} +@cindex autogen-define + +This is the ``name to add to definition list'' option. +This option takes a string argument @file{value}. + +@noindent +This option has some usage constraints. It: +@itemize @bullet +@item +may appear an unlimited number of times. +@end itemize + +The AutoGen define names are used for the following purposes: + +@enumerate +@item +Sections of the AutoGen definitions may be enabled or disabled +by using C-style #ifdef and #ifndef directives. +@item +When defining a value for a name, you may specify the index +for a particular value. That index may be a literal value, +a define option or a value #define-d in the definitions themselves. +@item +The name of a file may be prefixed with @code{$NAME/}. +The @code{$NAME} part of the name string will be replaced with +the define-d value for @code{NAME}. +@item +When AutoGen is finished loading the definitions, the defined values +are exported to the environment with, @code{putenv(3)}. +These values can then be used in shell scripts with @code{$@{NAME@}} +references and in templates with @code{(getenv "NAME")}. +@item +While processing a template, you may specify an index to retrieve +a specific value. That index may also be a define-d value. +@end enumerate + +It is entirely equivalent to place this name in the exported environment. +Internally, that is what AutoGen actually does with this option. +@subheading undefine option (-U). +@anchor{autogen undefine} +@cindex autogen-undefine + +This is the ``definition list removal pattern'' option. +This option takes a string argument @file{name-pat}. + +@noindent +This option has some usage constraints. It: +@itemize @bullet +@item +may appear an unlimited number of times. +@item +may not be preset with environment variables or configuration (rc/ini) files. +@end itemize + +Similar to 'C', AutoGen uses @code{#ifdef/#ifndef} preprocessing +directives. This option will cause the matching names to be +removed from the list of defined values. +@node autogen dep-track +@section dep-track options +This option is used to automate dependency tracking. +@subheading make-dep option (-M). +@anchor{autogen make-dep} +@cindex autogen-make-dep + +This is the ``emit make dependency file'' option. +This option takes an optional string argument @file{type}. + +@noindent +This option has some usage constraints. It: +@itemize @bullet +@item +may appear an unlimited number of times. +@item +may not be preset with environment variables or configuration (rc/ini) files. +@end itemize + + +This option behaves fairly closely to the way the @code{-M} series of +options work with the gcc compiler, except that instead of just +emitting the predecessor dependencies, this also emits the successor +dependencies (output target files). By default, the output dependency +information will be placed in @code{.d}, but may also be +specified with @code{-MF}. The time stamp on this file will be +manipulated so that it will be one second older than the oldest +primary output file. + +The target in this dependency file will normally be the dependency +file name, but may also be overridden with @code{-MT}. +AutoGen will not alter the contents of that file, but it may create +it and it will adjust the modification time to match the start time. + +@strong{NB:} these second letters are part of the option argument, so +@code{-MF } must have the space character quoted or omitted, and +@code{-M "F "} is acceptable because the @code{F} is part of the +option argument. + +@code{-M} may be followed by any of the letters M, F, P, T, Q, D, or G. +However, only F, Q, T and P are meaningful. All but F have somewhat +different meanings. @code{-MT} is interpreted as meaning +@code{} is a sentinel file that will depend on all inputs +(templates and definition files) and all the output files will depend +on this sentinel file. It is suitable for use as a real make target. +Q is treated identically to T, except dollar characters ('$') are +doubled. P causes a special clean (clobber) phoney rule to be inserted +into the make file fragment. An empty rule is always created for +building the list of targets. + +This is the recommended usage: +@example + -MFwhatever-you-like.dep -MTyour-sentinel-file -MP +@end example +and then in your @code{Makefile}, make the @file{autogen} rule: +@example + -include whatever-you-like.dep + clean_targets += clean-your-sentinel-file + + your-sentinel-file: + autogen -MT$@@ -MF$*.d ..... + + local-clean : + rm -f $(clean_targets) +@end example + +The modification time on the dependency file is adjusted to be one +second before the earliest time stamp of any other output file. +Consequently, it is suitable for use as the sentinel file testifying +to the fact the program was successfully run. (@code{-include} is +the GNU make way of specifying "include it if it exists". Your make +must support that feature or your bootstrap process must create the +file.) + +All of this may also be specified using the @code{DEPENDENCIES_OUTPUT} +or @code{AUTOGEN_MAKE_DEP} environment variables. If defined, +dependency information will be output. If defined with white space +free text that is something other than @code{true}, @code{false}, +@code{yes}, @code{no}, @code{0} or @code{1}, then the string is taken +to be an output file name. If it contains a string of white space +characters, the first token is as above and the second token is taken +to be the target (sentinel) file as @code{-MT} in the paragraphs +above. @code{DEPENDENCIES_OUTPUT} will be ignored if there are +multiple sequences of white space characters or if its contents are, +specifically, @code{false}, @code{no} or @code{0}. +@node autogen autoopts-opts +@section autoopts-opts options +help, version, option and error handling. +@subheading no-abort option. +@anchor{autogen no-abort} +@cindex autogen-no-abort + +This is the ``do not abort on errors'' option. +By default, @code{AutoGen} will abort on an error leaving behind a core image. +That is sometimes inconvenient. If present on the command line or in +the environment, AutoGen will call @code{exit(1)} instead of @code{abort()}. + + +@node autogen config +@section presetting/configuring autogen + +Any option that is not marked as @i{not presettable} may be preset by +loading values from configuration ("rc" or "ini") files, and values from environment variables named @code{AUTOGEN} and @code{AUTOGEN_}. @code{} must be one of +the options listed above in upper case and segmented with underscores. +The @code{AUTOGEN} variable will be tokenized and parsed like +the command line. The remaining variables are tested for existence and their +values are treated like option arguments. + + +@noindent +@code{libopts} will search in 2 places for configuration files: +@itemize @bullet +@item +$HOME +@item +$PWD +@end itemize +The environment variables @code{HOME}, and @code{PWD} +are expanded and replaced when @file{autogen} runs. +For any of these that are plain files, they are simply processed. +For any that are directories, then a file named @file{.autogenrc} is searched for +within that directory and processed. + +Configuration files may be in a wide variety of formats. +The basic format is an option name followed by a value (argument) on the +same line. Values may be separated from the option name with a colon, +equal sign or simply white space. Values may be continued across multiple +lines by escaping the newline with a backslash. + +Multiple programs may also share the same initialization file. +Common options are collected at the top, followed by program specific +segments. The segments are separated by lines like: +@example +[AUTOGEN] +@end example +@noindent +or by +@example + +@end example +@noindent +Do not mix these styles within one configuration file. + +Compound values and carefully constructed string values may also be +specified using XML syntax: +@example + + ...<...>... + +@end example +@noindent +yielding an @code{option-name.sub-opt} string value of +@example +"...<...>..." +@end example +@code{AutoOpts} does not track suboptions. You simply note that it is a +hierarchicly valued option. @code{AutoOpts} does provide a means for searching +the associated name/value pair list (see: optionFindValue). + +The command line options relating to configuration and/or usage help are: + +@subheading version (-v) + +Print the program version to standard out, optionally with licensing +information, then exit 0. The optional argument specifies how much licensing +detail to provide. The default is to print just the version. The licensing information may be selected with an option argument. +Only the first letter of the argument is examined: + +@table @samp +@item version +Only print the version. This is the default. +@item copyright +Name the copyright usage licensing terms. +@item verbose +Print the full copyright usage licensing terms. +@end table + +@subheading usage (-u) + +Print abbreviated usage to standard out, then exit 0. + +@subheading reset-option (-R) + +Resets the specified option to the compiled-in initial state. +This will undo anything that may have been set by configuration files. +The option argument may be either the option flag character or its long name. + +@node autogen exit status +@section autogen exit status + +One of the following exit values will be returned: +@table @samp +@item 0 (EXIT_SUCCESS) +Successful program execution. +@item 1 (EXIT_OPTION_ERROR) +The command options were misconfigured. +@item 2 (EXIT_BAD_TEMPLATE) +An error was encountered processing the template. +@item 3 (EXIT_BAD_DEFINITIONS) +The definitions could not be deciphered. +@item 4 (EXIT_LOAD_ERROR) +An error was encountered during the load phase. +@item 5 (EXIT_FS_ERROR) +a file system error stopped the program. +@item 6 (EXIT_NO_MEM) +Insufficient memory to operate. +@item 128 (EXIT_SIGNAL) +@command{autogen} exited due to catching a signal. If your template includes +string formatting, a number argument to a "%s" formatting element will +trigger a segmentation fault. Autogen will catch the seg fault signal +and exit with @code{AUTOGEN_EXIT_SIGNAL(5)}. Alternatively, AutoGen +may have been interrupted with a @code{kill(2)} signal. + +Subtract 128 from the actual exit code to detect the signal number. +@item 66 (EX_NOINPUT) +A specified configuration file could not be loaded. +@item 70 (EX_SOFTWARE) +libopts had an internal operational error. Please report +it to autogen-users@@lists.sourceforge.net. Thank you. +@end table +@node autogen Examples +@section autogen Examples +Here is how the man page is produced: +@example +autogen -Tagman-cmd.tpl -MFman-dep -MTstamp-man opts.def +@end example + +This command produced this man page from the AutoGen option definition +file. It overrides the template specified in @file{opts.def} (normally +@file{options.tpl}) and uses @file{agman-cmd.tpl}. It also sets the +make file dependency output to @file{man-dep} and the sentinel file +(time stamp file) to @file{man-stamp}. The base of the file name is +derived from the defined @code{prog-name}. + +The texi invocation document is produced via: +@example +autogen -Tagtexi-cmd.tpl -MFtexi-dep -MTtexi-stamp opts.def +@end example diff --git a/doc/invoke-bitmaps.texi b/doc/invoke-bitmaps.texi new file mode 100644 index 0000000..b3b5592 --- /dev/null +++ b/doc/invoke-bitmaps.texi @@ -0,0 +1,348 @@ +@ignore + +This file is part of AutoGen. +AutoGen is free software. +AutoGen is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + +AutoGen 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. + +AutoGen is distributed in the hope that 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 file has the following md5sum: + +43b91e8ca915626ed3818ffb1b71248b COPYING.gplv3 + +@end ignore +@node Bit Maps +@section Bit Maps and Enumerations + +AutoGen provides two templates for managing enumerations and bit maps +(flag words). They produce an enumeration of the enum or @code{#define}s +for the bit maps, plus conversion functions for converting a string into +one of these values or converting one of these values into a human readable +string. Finally, for enumerations, you may specify one or more sets of +dispatching functions that will be selected by identifying a keyword +prefix of a string (@pxref{enum-code, the @i{dispatch} attribute in +Strings to Enums and Back}). + +There is a separate project that produces a GDB add-on that +will add these capabilities into GDB for bit masks. (GDB does just fine +with enumerations.) + +@menu +* enums:: Enumerations +* enum-code:: Strings to Enums and Back +* masks:: Bit Maps and Masks +@end menu + +@node enums +@subsection Enumerations + +@file{str2enum.tpl} + +Produce an enumeration for a list of input ``cmd''s (names). +Optionally, produce functions to: + +@itemize @bullet +@item +convert a string to an enumeration +@item +convert an enumeration value into a string +@item +invoke a function based on the first token name found in a string +@end itemize + +The header file produced will contain the enumeration and declarations +for the optional procedures. The code (@file{.c}) file will contain +these optional procedures, but can be omitted if the @code{no-code} +attribute is specified. + +The following attributes are recognized with the @code{str2enum} template: + +@table @samp +@item cmd +You must provide a series of these attributes: they specify the list of +names used in the enumeration. Specific values for the names may be +specified by specifying a numeric index for these attributes. +e.g. @code{cmd[5] = mumble;} will cause +@example +FOO_CMD_MUMBLE = 5 +@end example +@noindent +to be inserted into the enumeration. +Do not specify a value of ``@t{invalid}'', unless you specify the +@code{invalid-name} attribute. (In that case, do not specify a +@code{cmd} value that matches the @code{invalid-name} value.) + +@item prefix +This specifies the first segment of each enumeration name. +If not specified, the first segment of the enumeration definition file name +will be used. e.g. @file{foo-bar.def} will default to a @code{FOO} prefix. + +@item type +Normally, there is a second constant segment following the prefix. If not +specified, it will be @code{CMD}, so if both @code{prefix} and @code{type} +were to default from @file{foo-bar.def}, you will have enumeration values +prefixed with @code{FOO_CMD_}. If specified as the empty string, there will +be no ``type'' component to the name and the default constant prefix will +thus be @code{FOO_}. + +@item base-name +This specifies the base name of the output files, enumeration type and the +translation functions. The default is to use the @code{basename(3)} of +the definition file. e.g. @file{foo-bar.def} results in a @code{base-name} +of @code{foo-bar}. + +@item invalid-val +The default invalid value is zero. Sometimes, it is useful for zero to be +valid. If so, you can specify @t{~0} or the empty string to be invalid. +The empty string will cause the enumeration count (maximum value plus 1) to +be the invalid value. + +@item invalid-name +By default, the invalid value is emitted into the enumeration as +@code{FOO_INVALID_CMD}. Specifying this attribute will replace +@code{INVALID} with whatever you place in this attribute. + +@item add-on-text +Additional text to insert into the code or header file. + +@table @samp +@item ao-file +Which file to insert the text into. There are four choices, +only two of which are relevant for the @file{str2enum} template: +``@t{enum-header}'', ``@t{enum-code}'', ``@t{mask-header}'' or ``@t{mask-code}''. + +@item ao-text +The text to insert. +@end table +@end table + +@c +@c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +@c +@node enum-code +@subsection Strings to Enums and Back + +A continuation of the attributes for the @file{str2enum.tpl} template. + +@table @samp +@item no-code +Do not emit any string to enumeration or enumeration to string code at all. +If this is specified, the remainder of the attributes have no effect. + +@item no-name +Do not emit the enumeration to name function. + +@item no-case +When looking up a string, the case of the input string is ignored. + +@item alias +A single punctuation character can be interpreted as a command. The first +character of this attribute is the aliased character and the remainder the +aliased-to command. e.g. ``@t{#comment}'' makes '@t{#}' an alias for the +@command{comment} command. ``@t{#comment}'' must still be listed in the +@code{cmd} attributes. + +@item length +Specify how lengths are to be handled. Under the covers, @command{gperf(1)} +is used to map a string to an enumeration value. The code it produces +requires the string length to be passed in. You may pass in the length +yourself, or the generated code may figure it out, or you may ask for that +length to be returned back after being figured out. + +You have four choices with the @code{length} attribute: + +@itemize @bullet +@item +Do not specify it. You will need to provide the length. +@item +Specify ``@t{provided}''. You will need to provide the length. +@item +Specify ``@t{returned}''. You must pass a pointer to a @t{size_t} object. +If the name is found, the length will be put there. +@item +Specify an empty string. The generated code will compute the length and +that computed length will not be returned. The length parameter may be +omitted. If the input strings contain only enumeration names, then this +would be sufficient. +@item +Specifying anything else is undefined. +@end itemize + +@item partial +Normally, a name must fully match to be found successfully. This attribute +causes the generated code to look for partial matches if the full match +@command{gperf} function fails. Partial matches must be at least two +characters long. + +@item undef-str +by default, the display string for an undefined value is +``@t{* UNDEFINED *}''. Use this to change that. + +@item equate +A series of punctuation characters considered equivalent. +Typically, ``@t{-_}'' but sometimes (Tandem) ``@t{-_^}''. +Do not use '@t{#}' in the list of characters. + +@item dispatch +A lookup procedure will call a dispatch function for the procedure named +after the keyword identified at the start of a string. Other than as +specially noted below, for every named ``cmd'', must have a handling +function, plus another function to handle errors, with ``invalid'' (or the +@code{invalid-name} value) as the @code{cmd} name. Multiple @code{dispatch} +definitions will produce multiple dispatching functions, each with +(potentially) unique argument lists and return types. + +You may also use @code{add-on-text} to ``@t{#define}'' one function to +another, thus allowing one function to handle multiple keywords or commands. +The @code{d-nam} and @code{d-ret} attributes are required. The @code{d-arg}, +@code{d-omit} and @code{d-only} attributes are optional: + +@table @samp +@item d-nam +This must be a printf format string with one formatting element: @code{%s}. +The @code{%s} will be replaced by each @code{cmd} name. The @code{%s} will +be stripped and the result will be combined with the base name to construct +the dispatch procedure name. + +@item d-ret +The return type of the dispatched function, even if ``@t{void}''. + +@item d-arg +If there are additional arguments that are to be passed through to the +dispatched function, specify this as though it were part of the procedure +header. (It will be glued into the dispatching function as is and sedded +into what is needed for the dispatched function.) + +@item d-omit +Instead of providing handling functions for all of the @code{cmd} names, +the invalid function will be called for omitted command codes. + +@item d-only +You need only provide functions for the names listed by @code{d-only}, plus +the ``invalid'' name. All other command values will trigger calls to +the invalid handling function. Note that the invalid call can distinguish +from a command that could not be found by examining the value of its +first (@code{id}) argument. +@end table + +The handler functions will have the command enumeration as its first first +argument, a pointer to a constant string that will be the character +@i{after} the parsed command (keyword) name, plus any @code{d-arg} arguments +that follow that. + +@noindent +As an example, a file @file{samp-chk.def} containing this: +@example +AutoGen Definitions str2enum; +cmd = one, two; invalid-name = oops; +dispatch = @{ d-nam = 'hdl_%s_cmd'; d-ret = void; @}; +@end example +@noindent +will produce a header containing: +@example +typedef enum @{ + SAMP_OOPS_CMD = 0, + SAMP_CMD_ONE = 1, + SAMP_CMD_TWO = 2, + SAMP_COUNT_CMD +@} samp_chk_enum_t; + +extern samp_chk_enum_t +find_samp_chk_cmd(char const * str, size_t len); + +typedef void(samp_chk_handler_t)( + samp_chk_enum_t id, char const * str); + +samp_chk_handler_t + hdl_oops_cmd, hdl_one_cmd, hdl_two_cmd; + +extern void +disp_samp_chk(char * str, size_t len); + +extern char const * +samp_chk_name(samp_chk_enum_t id); +@end example + +@itemize @bullet +@item +@code{find_samp_chk_cmd} will look up a @code{len} byte @code{str} and +return the corresponding @code{samp_chk_enum_t} value. That value is +@code{SAMP_OOPS_CMD} if the string is not ``one'' or ``two''. +@item +@code{samp_chk_handler_t} is the type of the callback procedures. +Three must be provided for the dispatching function to call: +@code{hdl_oops_cmd}, @code{hdl_one_cmd} and @code{hdl_two_cmd}. +@code{hdl_oops_cmd} will receive calls when the string does not match. +@item +@code{disp_samp_chk} this function will call the handler function +and return whatever the handler returns. In this case, it is void. +@item +@code{samp_chk_name} will return a string corresponding to the enumeration +value argument. If the value is not valid, ``* UNDEFINED *'' (or the +value of @code{undef-str}) is used. +@end itemize +@end table + +@c +@c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +@c +@node masks +@subsection Bit Maps and Masks + +@file{str2mask.tpl} + +This template leverages highly off of enumerations (@pxref{enums}). It will +produce a header file with bit masks defined for each bit specified with a +@code{cmd} attribute. 63 is the highest legal bit number because this +template has not been extended to cope with multiple word masks. (Patches +would be welcome.) + +There are a few constraints on the names allowed: + +@itemize @bullet +@item +names are constrained to alphanumerics and the underscore +@item +aliases are not allowed +@item +dispatch procedures are not allowed +@end itemize + +@code{no-code} and @code{no-name} are honored. @code{dispatch} is not. The +lookup function will examine each token in an input string, determine which +bit is specified and add it into a result. The names may be prefixed with a +hyphen (@t{-}) or tilde (@t{~}) to remove the bit(s) from the cumulative +result. If the string begins with a plus (@t{+}), hyphen or tilde, a ``base +value'' parameter is used for the starting mask, otherwise the conversion +starts with zero. + +Beyond the enumeration attributes that are used (or ignored), the +@file{str2mask} template accepts a @code{mask} attribute. It takes a few +``subattributes'': + +@table @samp +@item m-name +a special name for a sub-collection of the mask bits + +@item m-bit +The name of each previously defined bit(s). If the desired previously +defined value is a mask, that @code{m-name} must be suffixed with ``@t{-mask}''. + +@item m-invert +When all done collecting the bits, x-or the value with the mask +of all the bits in the collection. +@end table + +@noindent +A mask of all bits in the collection is always generated. diff --git a/doc/invoke-columns.texi b/doc/invoke-columns.texi new file mode 100644 index 0000000..a426832 --- /dev/null +++ b/doc/invoke-columns.texi @@ -0,0 +1,415 @@ +@node columns Invocation +@section Invoking columns +@pindex columns +@cindex Columnize Input Text +@ignore +# -*- buffer-read-only: t -*- vi: set ro: +# +# DO NOT EDIT THIS FILE (invoke-columns.texi) +# +# It has been AutoGen-ed +# From the definitions ./opts.def +# and the template file agtexi-cmd.tpl +@end ignore +This program was designed for the purpose of generating compact, +columnized tables. It will read a list of text items from standard +in or a specified input file and produce a columnized listing of +all the non-blank lines. Leading white space on each line is +preserved, but trailing white space is stripped. Methods of +applying per-entry and per-line embellishments are provided. +See the formatting and separation arguments below. + +This program is used by AutoGen to help clean up and organize +its output. + +See @file{autogen/agen5/fsm.tpl} and the generated output +@file{pseudo-fsm.h}. + +This function was not implemented as an expression function because +either it would have to be many expression functions, or a provision +would have to be added to provide options to expression functions. +Maybe not a bad idea, but it is not being implemented at the moment. + +A side benefit is that you can use it outside of @code{autogen} to +columnize input, a la the @code{ls} command. + +This section was generated by @strong{AutoGen}, +using the @code{agtexi-cmd} template and the option descriptions for the @code{columns} program. +This software is released under the GNU General Public License, version 3 or later. + +@menu +* columns usage:: columns help/usage (@option{--help}) +* columns dimensions:: dimensions options +* columns treatment:: treatment options +* columns ordering:: ordering options +* columns input-text:: input-text options +* columns config:: presetting/configuring columns +* columns exit status:: exit status +* columns See Also:: See Also +@end menu + +@node columns usage +@subsection columns help/usage (@option{--help}) +@cindex columns help + +This is the automatically generated usage text for columns. + +The text printed is the same whether selected with the @code{help} option +(@option{--help}) or the @code{more-help} option (@option{--more-help}). @code{more-help} will print +the usage text by passing it through a pager program. +@code{more-help} is disabled on platforms without a working +@code{fork(2)} function. The @code{PAGER} environment variable is +used to select the program, defaulting to @file{more}. Both will exit +with a status code of 0. + +@exampleindent 0 +@example +columns (GNU AutoGen) - Columnize Input Text - Ver. 1.2 +Usage: columns [ - [] | --[@{=| @}] ]... + +Specify the output dimensions: + + Flg Arg Option-Name Description + -W Num width Maximum Line Width + - it must be in the range: + 16 to 4095 + -c Num columns Desired number of columns + - it must be in the range: + 1 to 2048 + -w Num col-width Set width of each column + - it must be in the range: + 1 to 2048 + Num tab-width tab width + +Specify how to lay out the text: + + Flg Arg Option-Name Description + Num spread maximum spread added to column width + - it must be in the range: + 1 to 1024 + no fill Fill lines with input + - prohibits these options: + spread + col-width + by-columns + -I Str indent Line prefix or indentation + Str first-indent First line prefix + - requires the option 'indent' + -f Str format Formatting string for each input + -S Str separation Separation string - follows all but last + Str line-separation string at end of all lines but last + Str ending string at end of last line + +Specify the ordering of the entries: + + Flg Arg Option-Name Description + no by-columns Print entries in column order + -s opt sort Sort input text + +Redirecting stdin to an alternate file: + + Flg Arg Option-Name Description + -i Str input Input file (if not stdin) + +Version, usage and configuration options: + + Flg Arg Option-Name Description + -v opt version output version information and exit + -? no help display extended usage information and exit + -! no more-help extended usage information passed thru pager + -> opt save-opts save the option state to a config file + -< Str load-opts load options from a config file + - disabled as '--no-load-opts' + - may appear multiple times + +Options are specified by doubled hyphens and their name or by a single +hyphen and the flag character. + +The following option preset mechanisms are supported: + - reading file ./.columnsrc + - reading file $HOME/.columnsrc + - examining environment variables named COLUMNS_* + +Please send bug reports to: +@end example +@exampleindent 4 + +@node columns dimensions +@subsection dimensions options +Specify the output dimensions. +@subsubheading width option (-W). +@anchor{columns width} +@cindex columns-width + +This is the ``maximum line width'' option. +This option takes a number argument @file{num}. +This option specifies the full width of the output line, +including any start-of-line indentation. The output will fill +each line as completely as possible, unless the column width has +been explicitly specified. If the maximum width is less than +the length of the widest input, you will get a single column +of output. +@subsubheading columns option (-c). +@anchor{columns columns} +@cindex columns-columns + +This is the ``desired number of columns'' option. +This option takes a number argument @file{count}. +Use this option to specify exactly how many columns to produce. +If that many columns will not fit within @var{line_width}, then +the count will be reduced to the number that fit. +@subsubheading col-width option (-w). +@anchor{columns col-width} +@cindex columns-col-width + +This is the ``set width of each column'' option. +This option takes a number argument @file{num}. +Use this option to specify exactly how many characters are to be +allocated for each column. If it is narrower than the widest entry, +it will be over-ridden with the required width. +@subsubheading tab-width option. +@anchor{columns tab-width} +@cindex columns-tab-width + +This is the ``tab width'' option. +This option takes a number argument @file{num}. +If an indentation string contains tabs, then this value is used to +compute the ending column of the prefix string. +@node columns treatment +@subsection treatment options +Specify how to lay out the text. +@subsubheading spread option. +@anchor{columns spread} +@cindex columns-spread + +This is the ``maximum spread added to column width'' option. +This option takes a number argument @file{num}. +Use this option to specify exactly how many characters may be +added to each column. It allows you to prevent columns from +becoming too far apart. Without this option, @file{columns} +will attempt to widen columns to fill the full width. +@subsubheading fill option. +@anchor{columns fill} +@cindex columns-fill + +This is the ``fill lines with input'' option. + +@noindent +This option has some usage constraints. It: +@itemize @bullet +@item +must not appear in combination with any of the following options: +spread, col_width, by_columns. +@end itemize + +Instead of columnizing the input text, fill the output lines +with the input lines. Blank lines on input will cause a +blank line in the output, unless the output is sorted. +With sorted output, blank lines are ignored. +@subsubheading indent option (-I). +@anchor{columns indent} +@cindex columns-indent + +This is the ``line prefix or indentation'' option. +This option takes a string argument @file{l-pfx}. +If a number, then this many spaces will be inserted at the start of +every line. Otherwise, it is a line prefix that will be inserted +at the start of every line. +@subsubheading first-indent option. +@anchor{columns first-indent} +@cindex columns-first-indent + +This is the ``first line prefix'' option. +This option takes a string argument @file{l-pfx}. + +@noindent +This option has some usage constraints. It: +@itemize @bullet +@item +must appear in combination with the following options: +indent. +@end itemize + +If a number, then this many spaces will be inserted at the start of +the first line. Otherwise, it is a line prefix that will be inserted +at the start of that line. If its length exceeds "indent", then it +will be emitted on a line by itself, suffixed by any line separation +string. For example: + +@example +$ columns --first='#define TABLE' -c 2 -I4 --line=' \' <<_EOF_ +one +two +three +four +_EOF_ +#define TABLE \ + one two \ + three four +@end example +@subsubheading format option (-f). +@anchor{columns format} +@cindex columns-format + +This is the ``formatting string for each input'' option. +This option takes a string argument @file{fmt-str}. +If you need to reformat each input text, the argument to this +option is interpreted as an @code{sprintf(3)} format that is used +to produce each output entry. +@subsubheading separation option (-S). +@anchor{columns separation} +@cindex columns-separation + +This is the ``separation string - follows all but last'' option. +This option takes a string argument @file{sep-str}. +Use this option if, for example, you wish a comma to appear after +each entry except the last. +@subsubheading line-separation option. +@anchor{columns line-separation} +@cindex columns-line-separation + +This is the ``string at end of all lines but last'' option. +This option takes a string argument @file{sep-str}. +Use this option if, for example, you wish a backslash to appear at +the end of every line, except the last. +@subsubheading ending option. +@anchor{columns ending} +@cindex columns-ending + +This is the ``string at end of last line'' option. +This option takes a string argument @file{end-str}. +This option puts the specified string at the end of the output. +@node columns ordering +@subsection ordering options +Specify the ordering of the entries. +@subsubheading by-columns option. +@anchor{columns by-columns} +@cindex columns-by-columns + +This is the ``print entries in column order'' option. +Normally, the entries are printed out in order by rows and then columns. +This option will cause the entries to be ordered within columns. +The final column, instead of the final row, may be shorter than the +others. +@subsubheading sort option (-s). +@anchor{columns sort} +@cindex columns-sort + +This is the ``sort input text'' option. +This option takes an optional string argument @file{key-pat}. +Causes the input text to be sorted. If an argument is supplied, +it is presumed to be a pattern and the sort is based upon the +matched text. If the pattern starts with or consists of +an asterisk (@code{*}), then the sort is case insensitive. +@node columns input-text +@subsection input-text options +Redirecting stdin to an alternate file. +@subsubheading input option (-i). +@anchor{columns input} +@cindex columns-input + +This is the ``input file (if not stdin)'' option. +This option takes a string argument @file{file}. +This program normally runs as a @code{filter}, reading from standard +input, columnizing and writing to standard out. This option redirects +input to a file. + + +@node columns config +@subsection presetting/configuring columns + +Any option that is not marked as @i{not presettable} may be preset by +loading values from configuration ("rc" or "ini") files, and values from environment variables named @code{COLUMNS} and @code{COLUMNS_}. @code{} must be one of +the options listed above in upper case and segmented with underscores. +The @code{COLUMNS} variable will be tokenized and parsed like +the command line. The remaining variables are tested for existence and their +values are treated like option arguments. + + +@noindent +@code{libopts} will search in 2 places for configuration files: +@itemize @bullet +@item +$PWD +@item +$HOME +@end itemize +The environment variables @code{PWD}, and @code{HOME} +are expanded and replaced when @file{columns} runs. +For any of these that are plain files, they are simply processed. +For any that are directories, then a file named @file{.columnsrc} is searched for +within that directory and processed. + +Configuration files may be in a wide variety of formats. +The basic format is an option name followed by a value (argument) on the +same line. Values may be separated from the option name with a colon, +equal sign or simply white space. Values may be continued across multiple +lines by escaping the newline with a backslash. + +Multiple programs may also share the same initialization file. +Common options are collected at the top, followed by program specific +segments. The segments are separated by lines like: +@example +[COLUMNS] +@end example +@noindent +or by +@example + +@end example +@noindent +Do not mix these styles within one configuration file. + +Compound values and carefully constructed string values may also be +specified using XML syntax: +@example + + ...<...>... + +@end example +@noindent +yielding an @code{option-name.sub-opt} string value of +@example +"...<...>..." +@end example +@code{AutoOpts} does not track suboptions. You simply note that it is a +hierarchicly valued option. @code{AutoOpts} does provide a means for searching +the associated name/value pair list (see: optionFindValue). + +The command line options relating to configuration and/or usage help are: + +@subsubheading version (-v) + +Print the program version to standard out, optionally with licensing +information, then exit 0. The optional argument specifies how much licensing +detail to provide. The default is to print just the version. The licensing information may be selected with an option argument. +Only the first letter of the argument is examined: + +@table @samp +@item version +Only print the version. This is the default. +@item copyright +Name the copyright usage licensing terms. +@item verbose +Print the full copyright usage licensing terms. +@end table + +@node columns exit status +@subsection columns exit status + +One of the following exit values will be returned: +@table @samp +@item 0 (EXIT_SUCCESS) +Successful program execution. +@item 1 (EXIT_FAILURE) +The operation failed or the command syntax was not valid. +@item 66 (EX_NOINPUT) +A specified configuration file could not be loaded. +@item 70 (EX_SOFTWARE) +libopts had an internal operational error. Please report +it to autogen-users@@lists.sourceforge.net. Thank you. +@end table +@node columns See Also +@subsection columns See Also +This program is documented more fully in the Columns section +of the Add-On chapter in the @code{AutoGen} Info system documentation. diff --git a/doc/invoke-getdefs.texi b/doc/invoke-getdefs.texi new file mode 100644 index 0000000..60e42e8 --- /dev/null +++ b/doc/invoke-getdefs.texi @@ -0,0 +1,583 @@ +@node getdefs Invocation +@section Invoking getdefs +@pindex getdefs +@cindex AutoGen Definition Extraction Tool +@ignore +# -*- buffer-read-only: t -*- vi: set ro: +# +# DO NOT EDIT THIS FILE (invoke-getdefs.texi) +# +# It has been AutoGen-ed +# From the definitions ./opts.def +# and the template file agtexi-cmd +@end ignore + +If no @code{input} argument is provided or is set to simply "-", and if +@code{stdin} is not a @code{tty}, then the list of input files will be +read from @code{stdin}. +This program extracts AutoGen definitions from a list of source files. +Definitions are delimited by @code{/*= \n} and +@code{=*/\n}. From that, this program creates a definition of the following +form: + +@example + #line nnn "source-file-name" + entry_type = @{ + name = entry_name; + ... + @}; +@end example + +@enumerate +@item +The ellipsis @code{...} is filled in by text found between the two +delimiters. Each line of text is stripped of anything before the first +asterisk, then leading asterisks, then any leading or trailing white space. + +@item +If what is left starts with what looks like a name followed by a colon, then +it is interpreted as a name followed by a value. + +@item +If the first character of the value is either a single or double quote, then +you are responsible for quoting the text as it gets inserted into the output +definitions. So, if you want whitespace at the beginnings of the lines of +text, you must do something like this: + +@example + * mumble: + * " this is some\n" + * " indented text." +@end example + +@item +If the @code{} is followed by a comma, the word @code{ifdef} (or +@code{ifndef}) and a name @code{if_name}, then the above entry will be under +@code{ifdef} control. + +@example +/*=group entry_name, ifdef FOO + * attr: attribute value +=*/ +@end example + +Will produce the following: + +@example +#ifdef FOO +#line nnn "source-file-name" +group = @{ + name = entry_name; + attr = 'attribute value'; +@}; +#endif +@end example + +@item +If you use of the @code{subblock} option, you can specify a nested +value, @xref{getdefs subblock}. That is, this text: + +@example + * arg: int, this, what-it-is +@end example + +with the @code{--subblock=arg=type,name,doc} option would yield: + +@example +arg = @{ type = int; name = this; doc = what-it-is; @}; +@end example +@end enumerate + +This section was generated by @strong{AutoGen}, +using the @code{agtexi-cmd} template and the option descriptions for the @code{getdefs} program. +This software is released under the GNU General Public License, version 3 or later. + +@menu +* getdefs usage:: getdefs help/usage (@option{help}) +* getdefs def-selection:: def-selection options +* getdefs enumerating:: enumerating options +* getdefs doc-insert:: doc-insert options +* getdefs input-files:: input-files options +* getdefs doc-output:: doc-output options +* getdefs config:: presetting/configuring getdefs +* getdefs exit status:: exit status +* getdefs See Also:: See Also +@end menu + +@node getdefs usage +@subsection getdefs help/usage (@option{help}) +@cindex getdefs help + +This is the automatically generated usage text for getdefs. + +The text printed is the same whether selected with the @code{help} option +(@option{help}) or the @code{more-help} option (@option{more-help}). @code{more-help} will print +the usage text by passing it through a pager program. +@code{more-help} is disabled on platforms without a working +@code{fork(2)} function. The @code{PAGER} environment variable is +used to select the program, defaulting to @file{more}. Both will exit +with a status code of 0. + +@exampleindent 0 +@example +getdefs error: invalid option descriptor for version +getdefs (GNU AutoGen) - AutoGen Definition Extraction Tool - Ver. 1.5 +Usage: getdefs [ [@{=| @}] ]... + +Specify which definitions are of interest and what to say about them: + + Arg Option-Name Description + Str defs-to-get Regexp to look for after the "/*=" + Str subblock subblock definition names + - may appear multiple times + Str listattr attribute with list of values + - may appear multiple times + +specify how to number the definitions: + + Arg Option-Name Description + opt ordering Alphabetize or use named file + - disabled as '--no-ordering' + - enabled by default + Num first-index The first index to apply to groups + +Definition insertion options: + + Arg Option-Name Description + opt filelist Insert source file names into defs + Str assign Global assignments + - may appear multiple times + Str common-assign Assignments common to all blocks + - may appear multiple times + Str copy File(s) to copy into definitions + - may appear multiple times + opt srcfile Insert source file name into each def + opt linenum Insert source line number into each def + +specify which files to search for markers: + + Arg Option-Name Description + Str input Input file to search for defs + - may appear multiple times + - default option for unnamed options + +Definition output disposition options:: + + Arg Option-Name Description + Str output Output file to open + - an alternate for 'autogen' + opt autogen Invoke AutoGen with defs + - disabled as '--no-autogen' + - enabled by default + Str template Template Name + Str agarg AutoGen Argument + - prohibits the option 'output' + - may appear multiple times + Str base-name Base name for output file(s) + - prohibits the option 'output' + +Version, usage and configuration options: + + Arg Option-Name Description +@end example +@exampleindent 4 + +@node getdefs def-selection +@subsection def-selection options +Specify which definitions are of interest and what to say about them. +@subsubheading defs-to-get option. +@anchor{getdefs defs-to-get} +@cindex getdefs-defs-to-get + +This is the ``regexp to look for after the "/*="'' option. +This option takes a string argument @file{reg-ex}. +If you want definitions only from a particular category, or even +with names matching particular patterns, then specify this regular +expression for the text that must follow the @code{/*=}. +@subsubheading subblock option. +@anchor{getdefs subblock} +@cindex getdefs-subblock + +This is the ``subblock definition names'' option. +This option takes a string argument @file{sub-def}. + +@noindent +This option has some usage constraints. It: +@itemize @bullet +@item +may appear an unlimited number of times. +@end itemize + +This option is used to create shorthand entries for nested definitions. +For example, with: +@table @r +@item using subblock thus +@code{--subblock=arg=argname,type,null} +@item and defining an @code{arg} thus +@code{arg: this, char *} +@item will then expand to: +@code{arg = @{ argname = this; type = "char *"; @};} +@end table +The "this, char *" string is separated at the commas, with the +white space removed. You may use characters other than commas by +starting the value string with a punctuation character other than +a single or double quote character. You may also omit intermediate +values by placing the commas next to each other with no intervening +white space. For example, "+mumble++yes+" will expand to: +@* +@code{arg = @{ argname = mumble; null = "yes"; @};}. +@subsubheading listattr option. +@anchor{getdefs listattr} +@cindex getdefs-listattr + +This is the ``attribute with list of values'' option. +This option takes a string argument @file{def}. + +@noindent +This option has some usage constraints. It: +@itemize @bullet +@item +may appear an unlimited number of times. +@end itemize + +This option is used to create shorthand entries for definitions +that generally appear several times. That is, they tend to be +a list of values. For example, with: +@* +@code{listattr=foo} defined, the text: +@* +@code{foo: this, is, a, multi-list} will then expand to: +@* +@code{foo = 'this', 'is', 'a', 'multi-list';} +@* +The texts are separated by the commas, with the +white space removed. You may use characters other than commas by +starting the value string with a punctuation character other than +a single or double quote character. +@node getdefs enumerating +@subsection enumerating options +specify how to number the definitions. +@subsubheading ordering option. +@anchor{getdefs ordering} +@cindex getdefs-ordering + +This is the ``alphabetize or use named file'' option. +This option takes an optional string argument @file{file-name}. + +@noindent +This option has some usage constraints. It: +@itemize @bullet +@item +can be disabled with --no-ordering. +@item +It is enabled by default. +@end itemize + +By default, ordering is alphabetical by the entry name. Use, +@code{no-ordering} if order is unimportant. Use @code{ordering} +with no argument to order without case sensitivity. Use +@code{ordering=} if chronological order is important. +getdefs will maintain the text content of @code{file-name}. +@code{file-name} need not exist. +@subsubheading first-index option. +@anchor{getdefs first-index} +@cindex getdefs-first-index + +This is the ``the first index to apply to groups'' option. +This option takes a number argument @file{first-index}. +By default, the first occurrence of a named definition will have an +index of zero. Sometimes, that needs to be a reserved value. Provide +this option to specify a different starting point. +@node getdefs doc-insert +@subsection doc-insert options +Definition insertion options. +@subsubheading filelist option. +@anchor{getdefs filelist} +@cindex getdefs-filelist + +This is the ``insert source file names into defs'' option. +This option takes an optional string argument @file{file}. +Inserts the name of each input file into the output definitions. +If no argument is supplied, the format will be: +@example +infile = '%s'; +@end example +If an argument is supplied, that string will be used for the entry +name instead of @var{infile}. +@subsubheading assign option. +@anchor{getdefs assign} +@cindex getdefs-assign + +This is the ``global assignments'' option. +This option takes a string argument @file{ag-def}. + +@noindent +This option has some usage constraints. It: +@itemize @bullet +@item +may appear an unlimited number of times. +@end itemize + +The argument to each copy of this option will be inserted into +the output definitions, with only a semicolon attached. +@subsubheading common-assign option. +@anchor{getdefs common-assign} +@cindex getdefs-common-assign + +This is the ``assignments common to all blocks'' option. +This option takes a string argument @file{ag-def}. + +@noindent +This option has some usage constraints. It: +@itemize @bullet +@item +may appear an unlimited number of times. +@end itemize + +The argument to each copy of this option will be inserted into +each output definition, with only a semicolon attached. +@subsubheading copy option. +@anchor{getdefs copy} +@cindex getdefs-copy + +This is the ``file(s) to copy into definitions'' option. +This option takes a string argument @file{file}. + +@noindent +This option has some usage constraints. It: +@itemize @bullet +@item +may appear an unlimited number of times. +@end itemize + +The content of each file named by these options will be inserted into +the output definitions. +@subsubheading srcfile option. +@anchor{getdefs srcfile} +@cindex getdefs-srcfile + +This is the ``insert source file name into each def'' option. +This option takes an optional string argument @file{file}. +Inserts the name of the input file where a definition was found +into the output definition. +If no argument is supplied, the format will be: +@example +srcfile = '%s'; +@end example +If an argument is supplied, that string will be used for the entry +name instead of @var{srcfile}. +@subsubheading linenum option. +@anchor{getdefs linenum} +@cindex getdefs-linenum + +This is the ``insert source line number into each def'' option. +This option takes an optional string argument @file{def-name}. +Inserts the line number in the input file where a definition +was found into the output definition. +If no argument is supplied, the format will be: +@example +linenum = '%s'; +@end example +If an argument is supplied, that string will be used for the entry +name instead of @var{linenum}. +@node getdefs input-files +@subsection input-files options +specify which files to search for markers. +@subsubheading input option. +@anchor{getdefs input} +@cindex getdefs-input + +This is the ``input file to search for defs'' option. +This option takes a string argument @file{src-file}. + +@noindent +This option has some usage constraints. It: +@itemize @bullet +@item +may appear an unlimited number of times. +@end itemize + +All files that are to be searched for definitions must be named on +the command line or read from @code{stdin}. If there is only one +@code{input} option and it is the string, "-", then the input file +list is read from @code{stdin}. If a command line argument is not +an option name and does not contain an assignment operator +(@code{=}), then it defaults to being an input file name. +At least one input file must be specified. +@node getdefs doc-output +@subsection doc-output options +Definition output disposition options:. +@subsubheading output option. +@anchor{getdefs output} +@cindex getdefs-output + +This is the ``output file to open'' option. +This option takes a string argument @file{file}. + +@noindent +This option has some usage constraints. It: +@itemize @bullet +@item +is a member of the autogen class of options. +@end itemize + +If you are not sending the output to an AutoGen process, +you may name an output file instead. +@subsubheading autogen option. +@anchor{getdefs autogen} +@cindex getdefs-autogen + +This is the ``invoke autogen with defs'' option. +This option takes an optional string argument @file{ag-cmd}. + +@noindent +This option has some usage constraints. It: +@itemize @bullet +@item +can be disabled with --no-autogen. +@item +It is enabled by default. +@item +is a member of the autogen class of options. +@end itemize + +This is the default output mode. Specifying @code{no-autogen} is +equivalent to @code{output=-}. If you supply an argument to this +option, that program will be started as if it were AutoGen and +its standard in will be set to the output definitions of this program. +@subsubheading template option. +@anchor{getdefs template} +@cindex getdefs-template + +This is the ``template name'' option. +This option takes a string argument @file{file}. +Specifies the template name to be used for generating the final output. +@subsubheading agarg option. +@anchor{getdefs agarg} +@cindex getdefs-agarg + +This is the ``autogen argument'' option. +This option takes a string argument @file{ag-opt}. + +@noindent +This option has some usage constraints. It: +@itemize @bullet +@item +may appear an unlimited number of times. +@item +must not appear in combination with any of the following options: +output. +@end itemize + +This is a pass-through argument. It allows you to specify any +arbitrary argument to be passed to AutoGen. +@subsubheading base-name option. +@anchor{getdefs base-name} +@cindex getdefs-base-name + +This is the ``base name for output file(s)'' option. +This option takes a string argument @file{name}. + +@noindent +This option has some usage constraints. It: +@itemize @bullet +@item +must not appear in combination with any of the following options: +output. +@end itemize + +When output is going to AutoGen, a base name must either be supplied +or derived. If this option is not supplied, then it is taken from +the @code{template} option. If that is not provided either, then +it is set to the base name of the current directory. + + +@node getdefs config +@subsection presetting/configuring getdefs + +Any option that is not marked as @i{not presettable} may be preset by +loading values from configuration ("rc" or "ini") files. + + +@noindent +@code{libopts} will search in @file{/dev/null} for configuration (option) data. +If this is a plain file, it is simply processed. +If it is a directory, then a file named @file{.getdefsrc} is searched for within that directory. + +Configuration files may be in a wide variety of formats. +The basic format is an option name followed by a value (argument) on the +same line. Values may be separated from the option name with a colon, +equal sign or simply white space. Values may be continued across multiple +lines by escaping the newline with a backslash. + +Multiple programs may also share the same initialization file. +Common options are collected at the top, followed by program specific +segments. The segments are separated by lines like: +@example +[GETDEFS] +@end example +@noindent +or by +@example + +@end example +@noindent +Do not mix these styles within one configuration file. + +Compound values and carefully constructed string values may also be +specified using XML syntax: +@example + + ...<...>... + +@end example +@noindent +yielding an @code{option-name.sub-opt} string value of +@example +"...<...>..." +@end example +@code{AutoOpts} does not track suboptions. You simply note that it is a +hierarchicly valued option. @code{AutoOpts} does provide a means for searching +the associated name/value pair list (see: optionFindValue). + +The command line options relating to configuration and/or usage help are: + +@subsubheading version + +Print the program version to standard out, optionally with licensing +information, then exit 0. The optional argument specifies how much licensing +detail to provide. The default is to print just the version. The licensing information may be selected with an option argument. +Only the first letter of the argument is examined: + +@table @samp +@item version +Only print the version. This is the default. +@item copyright +Name the copyright usage licensing terms. +@item verbose +Print the full copyright usage licensing terms. +@end table + +@node getdefs exit status +@subsection getdefs exit status + +One of the following exit values will be returned: +@table @samp +@item 0 (EXIT_SUCCESS) +Successful program execution. +@item 1 (EXIT_FAILURE) +The operation failed or the command syntax was not valid. +@item 2 (EXIT_INVALID_INPUT) +An input file was specified that is not a file +@item 3 (EXIT_NO_MEM) +Insufficient memory for operation +@item 66 (EX_NOINPUT) +A specified configuration file could not be loaded. +@item 70 (EX_SOFTWARE) +libopts had an internal operational error. Please report +it to autogen-users@@lists.sourceforge.net. Thank you. +@end table +@node getdefs See Also +@subsection getdefs See Also +This program is documented more fully in the Getdefs section +of the Add-On chapter in the @code{AutoGen} Info system documentation. diff --git a/doc/invoke-snprintfv.texi b/doc/invoke-snprintfv.texi new file mode 100644 index 0000000..380641c --- /dev/null +++ b/doc/invoke-snprintfv.texi @@ -0,0 +1,74 @@ +@node snprintfv +@section Replacement for Stdio Formatting Library + + Using the `printf' formatting routines in a portable fashion has +always been a pain, and this package has been way more pain than anyone +ever imagined. Hopefully, with this release of snprintfv, the pain is +now over for all time. + + The issues with portable usage are these: + +@enumerate +@item +Argument number specifiers are often either not implemented or are +buggy. Even GNU libc, version 1 got it wrong. + +@item +ANSI/ISO "forgot" to provide a mechanism for computing argument +lists for vararg procedures. + +@item +The argument array version of printf (`printfv()') is not +generally available, does not work with the native printf, and +does not have a working argument number specifier in the format +specification. (Last I knew, anyway.) + +@item +You cannot fake varargs by calling `vprintf()' with an array of +arguments, because ANSI does not require such an implementation +and some vendors play funny tricks because they are allowed to. +@end enumerate + + These four issues made it impossible for AutoGen to ship without its +own implementation of the `printf' formatting routines. Since we were +forced to do this, we decided to make the formatting routines both +better and more complete :-). We addressed these issues and added the +following features to the common printf API: + +@enumerate 5 +@item +The formatted output can be written to + +@itemize @bullet +@item +a string allocated by the formatting function (`asprintf()'). +@item +a file descriptor instead of a file stream (`dprintf()'). +@item +a user specified stream (`stream_printf()'). +@end itemize + +@item +The formatting functions can be augmented with your own functions. +These functions are allowed to consume more than one character +from the format, but must commence with a unique character. For +example, + +@example +"%@{struct stat@}\n" +@end example + +might be used with '@{' registered to a procedure that would look +up "struct stat" in a symbol table and do appropriate things, +consuming the format string through the '@}' character. +@end enumerate + + Gary V. Vaughan was generous enough to supply this implementation. +Many thanks!! + + For further details, the reader is referred to the snprintfv +documentation. These functions are also available in the template +processing as@: `sprintf' (@pxref{SCM sprintf}), `printf' +(@pxref{SCM printf}), `fprintf' (@pxref{SCM fprintf}), and `shellf' +(@pxref{SCM shellf}). + diff --git a/doc/invoke-xml2ag.texi b/doc/invoke-xml2ag.texi new file mode 100644 index 0000000..eebfaa0 --- /dev/null +++ b/doc/invoke-xml2ag.texi @@ -0,0 +1,423 @@ +@node xml2ag Invocation +@section Invoking xml2ag +@pindex xml2ag +@cindex XML to AutoGen Definiton Converter +@ignore +# -*- buffer-read-only: t -*- vi: set ro: +# +# DO NOT EDIT THIS FILE (invoke-xml2ag.texi) +# +# It has been AutoGen-ed +# From the definitions ./xmlopts.def +# and the template file agtexi-cmd +@end ignore + +This program will convert any arbitrary XML file into equivalent +AutoGen definitions, and invoke AutoGen. +The template used will be derived from either: +@itemize @bullet +@item +The @strong{--override-tpl} command line option +@item +A top level XML attribute named, "@code{template}" +@end itemize +@noindent +One or the other @strong{must} be provided, or the program will +exit with a failure message. + +The @emph{base-name} for the output will similarly be either: +@itemize @bullet +@item +The @strong{--base-name} command line option. +@item +The base name of the @file{.xml} file. +@end itemize + +The definitions derived from XML generally have an extra layer +of definition. Specifically, this XML input: +@example + + mumble-1 + + grumble, grumble, grumble. +mumble, mumble + +@end example +Will get converted into this: +@example +mumble = @{ + grumble = @{ + text = 'grumble, grumble, grumble'; + @}; + text = 'mumble-1'; + text = 'mumble, mumble'; +@}; +@end example +Please notice that some information is lost. AutoGen cannot tell that +"grumble" used to lie between the mumble texts. Also please note that +you cannot assign: +@example +grumble = 'grumble, grumble, grumble.'; +@end example +because if another "grumble" has an attribute or multiple texts, +it becomes impossible to have the definitions be the same type +(compound or text values). + +This section was generated by @strong{AutoGen}, +using the @code{agtexi-cmd} template and the option descriptions for the @code{xml2ag} program. +This software is released under the GNU General Public License, version 3 or later. + +@menu +* xml2ag usage:: xml2ag help/usage (@option{--help}) +* xml2ag the-xml2ag-option:: the-xml2ag-option options +* xml2ag autogen-options:: autogen-options options +* xml2ag exit status:: exit status +@end menu + +@node xml2ag usage +@subsection xml2ag help/usage (@option{--help}) +@cindex xml2ag help + +This is the automatically generated usage text for xml2ag. + +The text printed is the same whether selected with the @code{help} option +(@option{--help}) or the @code{more-help} option (@option{--more-help}). @code{more-help} will print +the usage text by passing it through a pager program. +@code{more-help} is disabled on platforms without a working +@code{fork(2)} function. The @code{PAGER} environment variable is +used to select the program, defaulting to @file{more}. Both will exit +with a status code of 0. + +@exampleindent 0 +@example +xml2ag (GNU AutoGen) - XML to AutoGen Definiton Converter - Ver. 5.18.16 +Usage: xml2ag [ - [] | --[@{=| @}] ]... [ ] + +All other options are derived from autogen: + + Flg Arg Option-Name Description + -O Str output Output file in lieu of AutoGen processing + +All other options: + + Flg Arg Option-Name Description + -L Str templ-dirs Search for templates in DIR + - may appear multiple times + -T Str override-tpl Use TPL-FILE for the template + Str definitions Read definitions from FILE + Str shell name or path name of shell to use + -m no no-fmemopen Do not use in-mem streams + Str equate characters considered equivalent + -b Str base-name Specify NAME as the base name for output + no source-time set mod times to latest source + no writable Allow output files to be writable + - disabled as '--not-writable' + Num loop-limit Limit on increment loops + - is scalable with a suffix: k/K/m/M/g/G/t/T + - it must lie in one of the ranges: + -1 exactly, or + 1 to 16777216 + -t Num timeout Limit server shell operations to SECONDS + - it must be in the range: + 0 to 3600 + KWd trace tracing level of detail + Str trace-out tracing output file or filter + no show-defs Show the definition tree + no used-defines Show the definitions used + -C no core Leave a core dump on a failure exit + -s Str skip-suffix Skip the file with this SUFFIX + - prohibits the option 'select-suffix' + - may appear multiple times + -o Str select-suffix specify this output suffix + - may appear multiple times + -D Str define name to add to definition list + - may appear multiple times + -U Str undefine definition list removal pattern + - an alternate for 'define' + -M opt make-dep emit make dependency file + - may appear multiple times + +Version, usage and configuration options: + + Flg Arg Option-Name Description + -v opt version output version information and exit + -? no help display extended usage information and exit + -! no more-help extended usage information passed thru pager + +Options are specified by doubled hyphens and their name or by a single +hyphen and the flag character. +This program will convert any arbitrary XML file into equivalent AutoGen +definitions, and invoke AutoGen. + +The valid "trace" option keywords are: + nothing debug-message server-shell templates block-macros + expressions everything + or an integer from 0 through 6 +The template will be derived from either: * the ``--override-tpl'' command +line option * a top level XML attribute named, "template" + +The ``base-name'' for the output will similarly be either: * the +``--base-name'' command line option * the base name of the .xml file + +Please send bug reports to: +@end example +@exampleindent 4 + +@node xml2ag the-xml2ag-option +@subsection the-xml2ag-option options +All other options are derived from autogen. +@subsubheading output option (-O). +@anchor{xml2ag output} +@cindex xml2ag-output + +This is the ``output file in lieu of autogen processing'' option. +This option takes a string argument @file{file}. +By default, the output is handed to an AutoGen for processing. +However, you may save the definitions to a file instead. +@node xml2ag autogen-options +@subsection autogen-options options +All other options. +These options are @i{mostly} just passed throug to @code{autogen}. +The one exception is @code{--override-tpl} which replaces the +default template in the output definitions. It does not get passed +through on the command line. +@subsubheading templ-dirs option (-L). +@anchor{xml2ag templ-dirs} +@cindex xml2ag-templ-dirs + +This is the ``search for templates in @file{dir}'' option. +This option takes a string argument @file{DIR}. + +@noindent +This option has some usage constraints. It: +@itemize @bullet +@item +may appear an unlimited number of times. +@end itemize + +Pass-through AutoGen argument +@subsubheading override-tpl option (-T). +@anchor{xml2ag override-tpl} +@cindex xml2ag-override-tpl + +This is the ``use @file{tpl-file} for the template'' option. +This option takes a string argument @file{TPL-FILE}. +Pass-through AutoGen argument +@subsubheading definitions option. +@anchor{xml2ag definitions} +@cindex xml2ag-definitions + +This is the ``read definitions from @file{file}'' option. +This option takes a string argument @file{FILE}. +Pass-through AutoGen argument +@subsubheading shell option. +@anchor{xml2ag shell} +@cindex xml2ag-shell + +This is the ``name or path name of shell to use'' option. +This option takes a string argument @file{shell}. +Pass-through AutoGen argument +@subsubheading no-fmemopen option (-m). +@anchor{xml2ag no-fmemopen} +@cindex xml2ag-no-fmemopen + +This is the ``do not use in-mem streams'' option. +Pass-through AutoGen argument +@subsubheading equate option. +@anchor{xml2ag equate} +@cindex xml2ag-equate + +This is the ``characters considered equivalent'' option. +This option takes a string argument @file{char-list}. +Pass-through AutoGen argument +@subsubheading base-name option (-b). +@anchor{xml2ag base-name} +@cindex xml2ag-base-name + +This is the ``specify @code{name} as the base name for output'' option. +This option takes a string argument @file{NAME}. +Pass-through AutoGen argument +@subsubheading source-time option. +@anchor{xml2ag source-time} +@cindex xml2ag-source-time + +This is the ``set mod times to latest source'' option. +Pass-through AutoGen argument +@subsubheading writable option. +@anchor{xml2ag writable} +@cindex xml2ag-writable + +This is the ``allow output files to be writable'' option. + +@noindent +This option has some usage constraints. It: +@itemize @bullet +@item +can be disabled with --not-writable. +@end itemize + +Pass-through AutoGen argument +@subsubheading loop-limit option. +@anchor{xml2ag loop-limit} +@cindex xml2ag-loop-limit + +This is the ``limit on increment loops'' option. +This option takes a number argument @file{lim}. +Pass-through AutoGen argument +@subsubheading timeout option (-t). +@anchor{xml2ag timeout} +@cindex xml2ag-timeout + +This is the ``limit server shell operations to @code{seconds}'' option. +This option takes a number argument @file{SECONDS}. +Pass-through AutoGen argument +@subsubheading trace option. +@anchor{xml2ag trace} +@cindex xml2ag-trace + +This is the ``tracing level of detail'' option. +This option takes a keyword argument @file{level}. + +@noindent +This option has some usage constraints. It: +@itemize @bullet +@item +This option takes a keyword as its argument. +The argument sets an enumeration value that can be tested by comparing the option value macro (OPT_VALUE_TRACE). +The available keywords are: +@example + nothing debug-message server-shell + templates block-macros expressions + everything +@end example + +or their numeric equivalent. +@end itemize + +Pass-through AutoGen argument +@subsubheading trace-out option. +@anchor{xml2ag trace-out} +@cindex xml2ag-trace-out + +This is the ``tracing output file or filter'' option. +This option takes a string argument @file{file}. +Pass-through AutoGen argument +@subsubheading show-defs option. +@anchor{xml2ag show-defs} +@cindex xml2ag-show-defs + +This is the ``show the definition tree'' option. +Pass-through AutoGen argument +@subsubheading used-defines option. +@anchor{xml2ag used-defines} +@cindex xml2ag-used-defines + +This is the ``show the definitions used'' option. +Pass-through AutoGen argument +@subsubheading core option (-C). +@anchor{xml2ag core} +@cindex xml2ag-core + +This is the ``leave a core dump on a failure exit'' option. + +@noindent +This option has some usage constraints. It: +@itemize @bullet +@item +must be compiled in by defining @code{HAVE_SYS_RESOURCE_H} during the compilation. +@end itemize + +Many systems default to a zero sized core limit. If the system +has the sys/resource.h header and if this option is supplied, +then in the failure exit path, autogen will attempt to set the +soft core limit to whatever the hard core limit is. If that +does not work, then an administrator must raise the hard core +size limit. +@subsubheading skip-suffix option (-s). +@anchor{xml2ag skip-suffix} +@cindex xml2ag-skip-suffix + +This is the ``skip the file with this @file{suffix}'' option. +This option takes a string argument @file{SUFFIX}. + +@noindent +This option has some usage constraints. It: +@itemize @bullet +@item +may appear an unlimited number of times. +@item +must not appear in combination with any of the following options: +select-suffix. +@end itemize + +Pass-through AutoGen argument +@subsubheading select-suffix option (-o). +@anchor{xml2ag select-suffix} +@cindex xml2ag-select-suffix + +This is the ``specify this output suffix'' option. +This option takes a string argument @file{SUFFIX}. + +@noindent +This option has some usage constraints. It: +@itemize @bullet +@item +may appear an unlimited number of times. +@end itemize + +Pass-through AutoGen argument +@subsubheading define option (-D). +@anchor{xml2ag define} +@cindex xml2ag-define + +This is the ``name to add to definition list'' option. +This option takes a string argument @file{value}. + +@noindent +This option has some usage constraints. It: +@itemize @bullet +@item +may appear an unlimited number of times. +@end itemize + +Pass-through AutoGen argument +@subsubheading undefine option (-U). +@anchor{xml2ag undefine} +@cindex xml2ag-undefine + +This is the ``definition list removal pattern'' option. +This option takes a string argument @file{name-pat}. + +@noindent +This option has some usage constraints. It: +@itemize @bullet +@item +may appear an unlimited number of times. +@end itemize + +Pass-through AutoGen argument +@subsubheading make-dep option (-M). +@anchor{xml2ag make-dep} +@cindex xml2ag-make-dep + +This is the ``emit make dependency file'' option. +This option takes an optional string argument @file{type}. + +@noindent +This option has some usage constraints. It: +@itemize @bullet +@item +may appear an unlimited number of times. +@end itemize + +Pass-through AutoGen argument +@node xml2ag exit status +@subsection xml2ag exit status + +One of the following exit values will be returned: +@table @samp +@item 0 (EXIT_SUCCESS) +Successful program execution. +@item 1 (EXIT_FAILURE) +The operation failed or the command syntax was not valid. +@end table diff --git a/doc/libopts.texi b/doc/libopts.texi new file mode 100644 index 0000000..ff3a741 --- /dev/null +++ b/doc/libopts.texi @@ -0,0 +1,927 @@ +@node libopts procedures +@subsection libopts External Procedures + +These are the routines that libopts users may call directly from their +code. There are several other routines that can be called by code +generated by the libopts option templates, but they are not to be +called from any other user code. The @file{options.h} header is +fairly clear about this, too. + +@menu +* libopts-ao_string_tokenize:: ao_string_tokenize +* libopts-configFileLoad:: configFileLoad +* libopts-optionFileLoad:: optionFileLoad +* libopts-optionFindNextValue:: optionFindNextValue +* libopts-optionFindValue:: optionFindValue +* libopts-optionFree:: optionFree +* libopts-optionGetValue:: optionGetValue +* libopts-optionLoadLine:: optionLoadLine +* libopts-optionMemberList:: optionMemberList +* libopts-optionNextValue:: optionNextValue +* libopts-optionOnlyUsage:: optionOnlyUsage +* libopts-optionPrintVersion:: optionPrintVersion +* libopts-optionPrintVersionAndReturn:: optionPrintVersionAndReturn +* libopts-optionProcess:: optionProcess +* libopts-optionRestore:: optionRestore +* libopts-optionSaveFile:: optionSaveFile +* libopts-optionSaveState:: optionSaveState +* libopts-optionUnloadNested:: optionUnloadNested +* libopts-optionVersion:: optionVersion +* libopts-strequate:: strequate +* libopts-streqvcmp:: streqvcmp +* libopts-streqvmap:: streqvmap +* libopts-strneqvcmp:: strneqvcmp +* libopts-strtransform:: strtransform +@end menu + +This subsection was automatically generated by AutoGen +using extracted information and the aginfo3.tpl template. + +@node libopts-ao_string_tokenize +@subsubsection ao_string_tokenize +@findex ao_string_tokenize + +tokenize an input string + +@noindent +Usage: +@example +token_list_t * res = ao_string_tokenize( string ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab string @tab @code{char const *} +@tab string to be tokenized +@item @tab returns @tab token_list_t * +@tab pointer to a structure that lists each token +@end multitable + +This function will convert one input string into a list of strings. +The list of strings is derived by separating the input based on +white space separation. However, if the input contains either single +or double quote characters, then the text after that character up to +a matching quote will become the string in the list. + +The returned pointer should be deallocated with @code{free(3C)} when +are done using the data. The data are placed in a single block of +allocated memory. Do not deallocate individual token/strings. + +The structure pointed to will contain at least these two fields: +@table @samp +@item tkn_ct +The number of tokens found in the input string. +@item tok_list +An array of @code{tkn_ct + 1} pointers to substring tokens, with +the last pointer set to NULL. +@end table + +There are two types of quoted strings: single quoted (@code{'}) and +double quoted (@code{"}). Singly quoted strings are fairly raw in that +escape characters (@code{\\}) are simply another character, except when +preceding the following characters: +@example +@code{\\} double backslashes reduce to one +@code{'} incorporates the single quote into the string +@code{\n} suppresses both the backslash and newline character +@end example + +Double quote strings are formed according to the rules of string +constants in ANSI-C programs. + +NULL is returned and @code{errno} will be set to indicate the problem: +@itemize @bullet +@item +@code{EINVAL} - There was an unterminated quoted string. +@item +@code{ENOENT} - The input string was empty. +@item +@code{ENOMEM} - There is not enough memory. +@end itemize + + +@node libopts-configFileLoad +@subsubsection configFileLoad +@findex configFileLoad + +parse a configuration file + +@noindent +Usage: +@example +const tOptionValue * res = configFileLoad( fname ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab fname @tab @code{char const *} +@tab the file to load +@item @tab returns @tab const tOptionValue * +@tab An allocated, compound value structure +@end multitable + +This routine will load a named configuration file and parse the +text as a hierarchically valued option. The option descriptor +created from an option definition file is not used via this interface. +The returned value is "named" with the input file name and is of +type "@code{OPARG_TYPE_HIERARCHY}". It may be used in calls to +@code{optionGetValue()}, @code{optionNextValue()} and +@code{optionUnloadNested()}. + +If the file cannot be loaded or processed, @code{NULL} is returned and +@var{errno} is set. It may be set by a call to either @code{open(2)} +@code{mmap(2)} or other file system calls, or it may be: +@itemize @bullet +@item +@code{ENOENT} - the file was not found. +@item +@code{ENOMSG} - the file was empty. +@item +@code{EINVAL} - the file contents are invalid -- not properly formed. +@item +@code{ENOMEM} - not enough memory to allocate the needed structures. +@end itemize + + +@node libopts-optionFileLoad +@subsubsection optionFileLoad +@findex optionFileLoad + +Load the locatable config files, in order + +@noindent +Usage: +@example +int res = optionFileLoad( opts, prog ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab opts @tab @code{tOptions *} +@tab program options descriptor + +@item @tab prog @tab @code{char const *} +@tab program name +@item @tab returns @tab int +@tab 0 -> SUCCESS, -1 -> FAILURE +@end multitable + +This function looks in all the specified directories for a configuration +file ("rc" file or "ini" file) and processes any found twice. The first +time through, they are processed in reverse order (last file first). At +that time, only "immediate action" configurables are processed. For +example, if the last named file specifies not processing any more +configuration files, then no more configuration files will be processed. +Such an option in the @strong{first} named directory will have no effect. + +Once the immediate action configurables have been handled, then the +directories are handled in normal, forward order. In that way, later +config files can override the settings of earlier config files. + +See the AutoOpts documentation for a thorough discussion of the +config file format. + +Configuration files not found or not decipherable are simply ignored. + +Returns the value, "-1" if the program options descriptor +is out of date or indecipherable. Otherwise, the value "0" will +always be returned. + + +@node libopts-optionFindNextValue +@subsubsection optionFindNextValue +@findex optionFindNextValue + +find a hierarcicaly valued option instance + +@noindent +Usage: +@example +const tOptionValue * res = optionFindNextValue( odesc, pPrevVal, name, value ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab odesc @tab @code{const tOptDesc *} +@tab an option with a nested arg type + +@item @tab pPrevVal @tab @code{const tOptionValue *} +@tab the last entry + +@item @tab name @tab @code{char const *} +@tab name of value to find + +@item @tab value @tab @code{char const *} +@tab the matching value +@item @tab returns @tab const tOptionValue * +@tab a compound value structure +@end multitable + +This routine will find the next entry in a nested value option or +configurable. It will search through the list and return the next entry +that matches the criteria. + +The returned result is NULL and errno is set: +@itemize @bullet +@item +@code{EINVAL} - the @code{pOptValue} does not point to a valid +hierarchical option value. +@item +@code{ENOENT} - no entry matched the given name. +@end itemize + + +@node libopts-optionFindValue +@subsubsection optionFindValue +@findex optionFindValue + +find a hierarcicaly valued option instance + +@noindent +Usage: +@example +const tOptionValue * res = optionFindValue( odesc, name, val ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab odesc @tab @code{const tOptDesc *} +@tab an option with a nested arg type + +@item @tab name @tab @code{char const *} +@tab name of value to find + +@item @tab val @tab @code{char const *} +@tab the matching value +@item @tab returns @tab const tOptionValue * +@tab a compound value structure +@end multitable + +This routine will find an entry in a nested value option or configurable. +It will search through the list and return a matching entry. + +The returned result is NULL and errno is set: +@itemize @bullet +@item +@code{EINVAL} - the @code{pOptValue} does not point to a valid +hierarchical option value. +@item +@code{ENOENT} - no entry matched the given name. +@end itemize + + +@node libopts-optionFree +@subsubsection optionFree +@findex optionFree + +free allocated option processing memory + +@noindent +Usage: +@example +optionFree( pOpts ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab pOpts @tab @code{tOptions *} +@tab program options descriptor +@end multitable + +AutoOpts sometimes allocates memory and puts pointers to it in the +option state structures. This routine deallocates all such memory. + +As long as memory has not been corrupted, +this routine is always successful. + + +@node libopts-optionGetValue +@subsubsection optionGetValue +@findex optionGetValue + +get a specific value from a hierarcical list + +@noindent +Usage: +@example +const tOptionValue * res = optionGetValue( pOptValue, valueName ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab pOptValue @tab @code{const tOptionValue *} +@tab a hierarchcal value + +@item @tab valueName @tab @code{char const *} +@tab name of value to get +@item @tab returns @tab const tOptionValue * +@tab a compound value structure +@end multitable + +This routine will find an entry in a nested value option or configurable. +If "valueName" is NULL, then the first entry is returned. Otherwise, +the first entry with a name that exactly matches the argument will be +returned. If there is no matching value, NULL is returned and errno is +set to ENOENT. If the provided option value is not a hierarchical value, +NULL is also returned and errno is set to EINVAL. + +The returned result is NULL and errno is set: +@itemize @bullet +@item +@code{EINVAL} - the @code{pOptValue} does not point to a valid +hierarchical option value. +@item +@code{ENOENT} - no entry matched the given name. +@end itemize + + +@node libopts-optionLoadLine +@subsubsection optionLoadLine +@findex optionLoadLine + +process a string for an option name and value + +@noindent +Usage: +@example +optionLoadLine( opts, line ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab opts @tab @code{tOptions *} +@tab program options descriptor + +@item @tab line @tab @code{char const *} +@tab NUL-terminated text +@end multitable + +This is a client program callable routine for setting options from, for +example, the contents of a file that they read in. Only one option may +appear in the text. It will be treated as a normal (non-preset) option. + +When passed a pointer to the option struct and a string, it will find +the option named by the first token on the string and set the option +argument to the remainder of the string. The caller must NUL terminate +the string. The caller need not skip over any introductory hyphens. +Any embedded new lines will be included in the option +argument. If the input looks like one or more quoted strings, then the +input will be "cooked". The "cooking" is identical to the string +formation used in AutoGen definition files (@pxref{basic expression}), +except that you may not use backquotes. + +Invalid options are silently ignored. Invalid option arguments +will cause a warning to print, but the function should return. + + +@node libopts-optionMemberList +@subsubsection optionMemberList +@findex optionMemberList + +Get the list of members of a bit mask set + +@noindent +Usage: +@example +char * res = optionMemberList( od ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab od @tab @code{tOptDesc *} +@tab the set membership option description +@item @tab returns @tab char * +@tab the names of the set bits +@end multitable + +This converts the OPT_VALUE_name mask value to a allocated string. +It is the caller's responsibility to free the string. + + +@node libopts-optionNextValue +@subsubsection optionNextValue +@findex optionNextValue + +get the next value from a hierarchical list + +@noindent +Usage: +@example +const tOptionValue * res = optionNextValue( pOptValue, pOldValue ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab pOptValue @tab @code{const tOptionValue *} +@tab a hierarchcal list value + +@item @tab pOldValue @tab @code{const tOptionValue *} +@tab a value from this list +@item @tab returns @tab const tOptionValue * +@tab a compound value structure +@end multitable + +This routine will return the next entry after the entry passed in. At the +end of the list, NULL will be returned. If the entry is not found on the +list, NULL will be returned and "@var{errno}" will be set to EINVAL. +The "@var{pOldValue}" must have been gotten from a prior call to this +routine or to "@code{opitonGetValue()}". + +The returned result is NULL and errno is set: +@itemize @bullet +@item +@code{EINVAL} - the @code{pOptValue} does not point to a valid +hierarchical option value or @code{pOldValue} does not point to a +member of that option value. +@item +@code{ENOENT} - the supplied @code{pOldValue} pointed to the last entry. +@end itemize + + +@node libopts-optionOnlyUsage +@subsubsection optionOnlyUsage +@findex optionOnlyUsage + +Print usage text for just the options + +@noindent +Usage: +@example +optionOnlyUsage( pOpts, ex_code ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab pOpts @tab @code{tOptions *} +@tab program options descriptor + +@item @tab ex_code @tab @code{int} +@tab exit code for calling exit(3) +@end multitable + +This routine will print only the usage for each option. +This function may be used when the emitted usage must incorporate +information not available to AutoOpts. + + +@node libopts-optionPrintVersion +@subsubsection optionPrintVersion +@findex optionPrintVersion + +Print the program version + +@noindent +Usage: +@example +optionPrintVersion( opts, od ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab opts @tab @code{tOptions *} +@tab program options descriptor + +@item @tab od @tab @code{tOptDesc *} +@tab the descriptor for this arg +@end multitable + +This routine will print the version to stdout. + + +@node libopts-optionPrintVersionAndReturn +@subsubsection optionPrintVersionAndReturn +@findex optionPrintVersionAndReturn + +Print the program version + +@noindent +Usage: +@example +optionPrintVersionAndReturn( opts, od ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab opts @tab @code{tOptions *} +@tab program options descriptor + +@item @tab od @tab @code{tOptDesc *} +@tab the descriptor for this arg +@end multitable + +This routine will print the version to stdout and return +instead of exiting. Please see the source for the +@code{print_ver} funtion for details on selecting how +verbose to be after this function returns. + + +@node libopts-optionProcess +@subsubsection optionProcess +@findex optionProcess + +this is the main option processing routine + +@noindent +Usage: +@example +int res = optionProcess( opts, a_ct, a_v ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab opts @tab @code{tOptions *} +@tab program options descriptor + +@item @tab a_ct @tab @code{int} +@tab program arg count + +@item @tab a_v @tab @code{char **} +@tab program arg vector +@item @tab returns @tab int +@tab the count of the arguments processed +@end multitable + +This is the main entry point for processing options. It is intended +that this procedure be called once at the beginning of the execution of +a program. Depending on options selected earlier, it is sometimes +necessary to stop and restart option processing, or to select completely +different sets of options. This can be done easily, but you generally +do not want to do this. + +The number of arguments processed always includes the program name. +If one of the arguments is "--", then it is counted and the processing +stops. If an error was encountered and errors are to be tolerated, then +the returned value is the index of the argument causing the error. +A hyphen by itself ("-") will also cause processing to stop and will +@emph{not} be counted among the processed arguments. A hyphen by itself +is treated as an operand. Encountering an operand stops option +processing. + +Errors will cause diagnostics to be printed. @code{exit(3)} may +or may not be called. It depends upon whether or not the options +were generated with the "allow-errors" attribute, or if the +ERRSKIP_OPTERR or ERRSTOP_OPTERR macros were invoked. + + +@node libopts-optionRestore +@subsubsection optionRestore +@findex optionRestore + +restore option state from memory copy + +@noindent +Usage: +@example +optionRestore( pOpts ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab pOpts @tab @code{tOptions *} +@tab program options descriptor +@end multitable + +Copy back the option state from saved memory. +The allocated memory is left intact, so this routine can be +called repeatedly without having to call optionSaveState again. +If you are restoring a state that was saved before the first call +to optionProcess(3AO), then you may change the contents of the +argc/argv parameters to optionProcess. + +If you have not called @code{optionSaveState} before, a diagnostic is +printed to @code{stderr} and exit is called. + + +@node libopts-optionSaveFile +@subsubsection optionSaveFile +@findex optionSaveFile + +saves the option state to a file + +@noindent +Usage: +@example +optionSaveFile( opts ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab opts @tab @code{tOptions *} +@tab program options descriptor +@end multitable + +This routine will save the state of option processing to a file. The name +of that file can be specified with the argument to the @code{--save-opts} +option, or by appending the @code{rcfile} attribute to the last +@code{homerc} attribute. If no @code{rcfile} attribute was specified, it +will default to @code{.@i{programname}rc}. If you wish to specify another +file, you should invoke the @code{SET_OPT_SAVE_OPTS(@i{filename})} macro. + +The recommend usage is as follows: +@example +optionProcess(&progOptions, argc, argv); +if (i_want_a_non_standard_place_for_this) +SET_OPT_SAVE_OPTS("myfilename"); +optionSaveFile(&progOptions); +@end example + +If no @code{homerc} file was specified, this routine will silently return +and do nothing. If the output file cannot be created or updated, a message +will be printed to @code{stderr} and the routine will return. + + +@node libopts-optionSaveState +@subsubsection optionSaveState +@findex optionSaveState + +saves the option state to memory + +@noindent +Usage: +@example +optionSaveState( pOpts ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab pOpts @tab @code{tOptions *} +@tab program options descriptor +@end multitable + +This routine will allocate enough memory to save the current option +processing state. If this routine has been called before, that memory +will be reused. You may only save one copy of the option state. This +routine may be called before optionProcess(3AO). If you do call it +before the first call to optionProcess, then you may also change the +contents of argc/argv after you call optionRestore(3AO) + +In fact, more strongly put: it is safest to only use this function +before having processed any options. In particular, the saving and +restoring of stacked string arguments and hierarchical values is +disabled. The values are not saved. + +If it fails to allocate the memory, +it will print a message to stderr and exit. +Otherwise, it will always succeed. + + +@node libopts-optionUnloadNested +@subsubsection optionUnloadNested +@findex optionUnloadNested + +Deallocate the memory for a nested value + +@noindent +Usage: +@example +optionUnloadNested( pOptVal ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab pOptVal @tab @code{tOptionValue const *} +@tab the hierarchical value +@end multitable + +A nested value needs to be deallocated. The pointer passed in should +have been gotten from a call to @code{configFileLoad()} (See +@pxref{libopts-configFileLoad}). + + +@node libopts-optionVersion +@subsubsection optionVersion +@findex optionVersion + +return the compiled AutoOpts version number + +@noindent +Usage: +@example +char const * res = optionVersion(); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab returns @tab char const * +@tab the version string in constant memory +@end multitable + +Returns the full version string compiled into the library. +The returned string cannot be modified. + + +@node libopts-strequate +@subsubsection strequate +@findex strequate + +map a list of characters to the same value + +@noindent +Usage: +@example +strequate( ch_list ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab ch_list @tab @code{char const *} +@tab characters to equivalence +@end multitable + +Each character in the input string get mapped to the first character +in the string. +This function name is mapped to option_strequate so as to not conflict +with the POSIX name space. + +none. + + +@node libopts-streqvcmp +@subsubsection streqvcmp +@findex streqvcmp + +compare two strings with an equivalence mapping + +@noindent +Usage: +@example +int res = streqvcmp( str1, str2 ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab str1 @tab @code{char const *} +@tab first string + +@item @tab str2 @tab @code{char const *} +@tab second string +@item @tab returns @tab int +@tab the difference between two differing characters +@end multitable + +Using a character mapping, two strings are compared for "equivalence". +Each input character is mapped to a comparison character and the +mapped-to characters are compared for the two NUL terminated input strings. +This function name is mapped to option_streqvcmp so as to not conflict +with the POSIX name space. + +none checked. Caller responsible for seg faults. + + +@node libopts-streqvmap +@subsubsection streqvmap +@findex streqvmap + +Set the character mappings for the streqv functions + +@noindent +Usage: +@example +streqvmap( from, to, ct ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab from @tab @code{char} +@tab Input character + +@item @tab to @tab @code{char} +@tab Mapped-to character + +@item @tab ct @tab @code{int} +@tab compare length +@end multitable + +Set the character mapping. If the count (@code{ct}) is set to zero, then +the map is cleared by setting all entries in the map to their index +value. Otherwise, the "@code{From}" character is mapped to the "@code{To}" +character. If @code{ct} is greater than 1, then @code{From} and @code{To} +are incremented and the process repeated until @code{ct} entries have been +set. For example, +@example +streqvmap('a', 'A', 26); +@end example +@noindent +will alter the mapping so that all English lower case letters +will map to upper case. + +This function name is mapped to option_streqvmap so as to not conflict +with the POSIX name space. + +none. + + +@node libopts-strneqvcmp +@subsubsection strneqvcmp +@findex strneqvcmp + +compare two strings with an equivalence mapping + +@noindent +Usage: +@example +int res = strneqvcmp( str1, str2, ct ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab str1 @tab @code{char const *} +@tab first string + +@item @tab str2 @tab @code{char const *} +@tab second string + +@item @tab ct @tab @code{int} +@tab compare length +@item @tab returns @tab int +@tab the difference between two differing characters +@end multitable + +Using a character mapping, two strings are compared for "equivalence". +Each input character is mapped to a comparison character and the +mapped-to characters are compared for the two NUL terminated input strings. +The comparison is limited to @code{ct} bytes. +This function name is mapped to option_strneqvcmp so as to not conflict +with the POSIX name space. + +none checked. Caller responsible for seg faults. + + +@node libopts-strtransform +@subsubsection strtransform +@findex strtransform + +convert a string into its mapped-to value + +@noindent +Usage: +@example +strtransform( dest, src ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab dest @tab @code{char *} +@tab output string + +@item @tab src @tab @code{char const *} +@tab input string +@end multitable + +Each character in the input string is mapped and the mapped-to +character is put into the output. +This function name is mapped to option_strtransform so as to not conflict +with the POSIX name space. + +The source and destination may be the same. + +none. + diff --git a/doc/mk-agen-texi.sh b/doc/mk-agen-texi.sh new file mode 100755 index 0000000..764349a --- /dev/null +++ b/doc/mk-agen-texi.sh @@ -0,0 +1,315 @@ +#! /bin/sh + +## This file is part of AutoGen. +## +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen 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. +## +## AutoGen is distributed in the hope that 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 . + +PS4='+mtx=${FUNCNAME:-=}-$LINENO> ' +exec 2> ${0%.sh}.log + +set -x + +typeset -r prog=$(basename "$0" .sh) +typeset -r progdir=$(\cd $(dirname "$0") && pwd -P) +typeset -r program=${progdir}/$(basename "$0") +typeset -r progpid=$$ + +builddir=`pwd` +. ${top_builddir:-..}/config/shdefs + +die() +{ + exec 1> ${TMPDIR}/err-report.txt 2>&1 + echo "mk-agen-texi FAILED: $*" + echo + cat ${LOG_FILE} + exec 2>&8 1>&2 8>&- + cat ${TMPDIR}/err-report.txt + trap : EXIT + echo leaving ${TMPDIR} in place + kill -TERM ${progpid} + exit 1 +} + +set_config_values() +{ + TMPDIR=`pwd`/ag-texi-$$.d + rm -rf ag-texi-*.d + mkdir ${TMPDIR} || die "cannot make ${TMPDIR} directory" + export TMPDIR + + case "$-" in + *x* ) trap "echo 'saved tmp dir: ${TMPDIR}';chmod 777 ${TMPDIR}" EXIT + VERBOSE=true ;; + * ) trap "rm -rf ${TMPDIR}" EXIT + VERBOSE=false ;; + esac + + LOG_FILE=${TMPDIR}/texi.log + + exec 8>&2 2> ${LOG_FILE} + + nl=' +' ht=' ' + . ${top_builddir}/config/shdefs + : ${MAKE=`which make`} + : ${srcdir=`pwd`} + srcdir=`cd ${srcdir} >/dev/null ; pwd` + INCLUDES="${DEFS} "` + + for d in ${top_srcdir} ${top_builddir} \ + ${top_builddir}/autoopts ${top_srcdir}/autoopts + do + (\cd ${d} && pwd) 2>/dev/null + done | \ + sort -u | \ + sed s/^/-I/ ` + + CFLAGS="${INCLUDES} "`echo ${CFLAGS} | \ + ${SED:-sed} -e "s/-Werror[^ ${ht}]*//g;s/-Wextra//g"` + + LIBS=-L` + test -d ${top_builddir}/autoopts/.libs \ + && echo ${top_builddir}/autoopts/.libs \ + || echo ${top_builddir}/autoopts + `" $LIBS" + + export CC CFLAGS LIBS MAKE LOG_FILE TMPDIR +} + +setup_exports() +{ + # Now auto-export variables: + # + set -a + + PATH=${top_builddir}/columns:${PATH} + timer=`expr ${AG_TIMEOUT} '*' 5` + d=`find ${top_builddir}/autoopts -type f -name libopts.a -print` + test -f "$d" || die "Cannot locate libopts.a" + LIBS="$d ${LIBS}" + + eval `${EGREP} '^AG_[A-Z_]*' ${top_srcdir}/VERSION` + + AGsrc=${top_srcdir}/agen5 + OPTIONS_DEF=${AGsrc}/opts.def + GETDEF_SRC=`${FGREP} -l '/*=' ${AGsrc}/*.[ch] ${AGsrc}/*.scm` + + for d in "${top_builddir}" "${top_srcdir}" + do test -f "$d/agen5/invoke-autogen.texi" || continue + AGEN_TEXI=${d}/agen5/invoke-autogen.texi + break + done + DOC_TEXT=${top_srcdir}/doc/autogen-texi.txt + + ADDON_TEXI=" + ${top_srcdir}/doc/bitmaps.texi + ${top_builddir}/columns/invoke-columns.texi + ${top_builddir}/getdefs/invoke-getdefs.texi + ${top_builddir}/xml2ag/invoke-xml2ag.texi + ${top_srcdir}/doc/snprintfv.texi" + + DOC_INCLUDES=" + ${AGsrc}/defParse-fsm.c + ${AGsrc}/opts.h + ${top_builddir}/autoopts/libopts.texi + ${top_srcdir}/doc/autogen-intro.texi + ${AGEN_TEXI}" + + DOC_TEMPLATE=${top_builddir}/doc/auto_gen.tpl + + DOC_DEPENDS=` + echo ${DOC_TEMPLATE} ${OPTIONS_DEF} ${ADDON_MENU} ${ADDON_TEXI} \ + ${DOC_INCLUDES} ${GETDEF_SRC} ${DOC_TEXT}` + + set +a +} + +# We have our executables and texi's. Collect the definitions: +# +run_getdefs() +{ + gd_cfg=${TMPDIR}/getdefs.cfg + exec 3> ${gd_cfg} + cat >&3 <<- EOCat + output ${TMPDIR}/${GEN_BASE}.def + copy ${OPTIONS_DEF} + srcfile + linenum + template auto_gen.tpl + assign ag-texi = invoke-autogen.texi + subblock exparg = arg_name,arg_desc,arg_optional,arg_list + EOCat + + tf=invoke-autogen.texi + test -f ${tf} || ln -s ${AGEN_TEXI} ${tf} + + for f in ${ADDON_TEXI} + do + tf=`basename ${f}` + case "$tf" in + invoke-* ) : ;; + * ) tf=invoke-$tf ;; + esac + test -f ${tf} || ln -s ${f} ${tf} + echo "assign addon-texi = ${tf}" + done >&3 + + for f in ${GETDEF_SRC} + do + echo "input " ${f} + done >&3 + exec 3>&- + echo + ${GDexe} load-opt=${gd_cfg} >&8 + ${GDexe} load-opt=${gd_cfg} || die cannot run ${GDexe} +} + +sanity_check() +{ + # Make sure the executables are there + # + test -x ${AGexe} || (cd `dirname ${AGexe}` ; ${MAKE}) || exit 0 + test -x ${GDexe} || (cd `dirname ${GDexe}` ; ${MAKE}) || exit 0 + test -x ${CLexe} || (cd `dirname ${CLexe}` ; ${MAKE}) || exit 0 + PATH="`dirname ${AGexe}`:`dirname ${CLexe}`:$PATH" + + # See to it that the .texi files have been generated, too. + # + for f in ${ADDON_TEXI} ${AGEN_TEXI} \ + ${top_builddir}/autoopts/libopts.texi + do + test -f "${f}" || ( + cd `dirname "${f}"` + ${MAKE} `basename "${f}"` >&2 + test $? -ne 0 && die MAKE of ${f} failed. + ) + done + + # Make sure we have all our sources and generate the doc + # + for f in ${DOC_DEPENDS} + do test -f "${f}" || die cannot find doc file: ${f} + test -f `basename $f` || ln -s "${f}" . + done +} + +build_agdoc() { + # Validate everything: + # + set_config_values + setup_exports + sanity_check + run_getdefs + + { + sh -c set | sed '/^BASH/d' + } >&2 + { + cat <<- _EOF_ + timeout ${timer} + templ-dirs ${srcdir} + templ-dirs ${top_srcdir}/autoopts/tpl + base-name ${GEN_BASE} + make-dep F ${GEN_BASE}.dep + make-dep P + _EOF_ + ${VERBOSE} && { + echo 'trace every' + echo "trace-out >>${TMPDIR}/ag.log" + export VERBOSE + } + } > ${TMPDIR}/ag.ini + + opts="--load-opts=${TMPDIR}/ag.ini" + cmd=`echo ${AGexe} ${opts} ${TMPDIR}/${GEN_BASE}.def` + echo "${PS4:-+} " ${cmd} >&8 + + timeout ${timer}s ${cmd} || { + head -n999999 ${TMPDIR}/ag.ini ${TMPDIR}/*.log + die could not regenerate doc + } >&2 + + test -f ${GEN_BASE}.texi || die "MISSING: ${GEN_BASE}.texi" + + exec 2>&8 8>&- +} + +build_gnudocs() +{ + local sedcmd='/^@author @email/ { + s/.*{// + s/}.*// + s/@@*/@/g + p + q + }' + + case "X$-" in + *x* ) local dashx=-x ;; + * ) local dashx= ;; + esac + + title=`sed -n 's/^@title *//p' agdoc.texi` + email=--email' '`sed -n "$sedcmd" agdoc.texi` + opts="--texi2html ${email}" + PS4='+gd=${FUNCNAME:-=}-$LINENO> ' ${SHELL} ${dashx} \ + ${top_srcdir}/config/gendocs.sh $opts autogen "$title" +} + +mk_autogen_texi() { + tfile=autogen.texi + page_style=\ +'\internalpagesizes{46\baselineskip}{6in}{-.25in}{-.25in}{\bindingoffset}{36pt}%' + + cat > ${tfile}$$ <<- _EOF_ + \\input texinfo + @ignore + ${page_style} + @end ignore + @c %**start of header + @setfilename ${tfile%.texi}.info + @include ${GEN_BASE}.texi + _EOF_ + + if test -f ${tfile} && cmp -s ${tfile} ${tfile}$$ + then rm -f ${tfile}$$ + else mv -f ${tfile}$$ ${tfile} + fi +} + +PS4='+agt=${FUNCNAME:-=}-$LINENO> ' +set -x +GEN_BASE=agdoc +test "X$1" = X--force && { + rm -f agdoc.texi + shift +} +test -f agdoc.texi || build_agdoc +mk_autogen_texi + +case "$1" in +gnudocs | gnudoc ) build_gnudocs ;; +* ) +esac + +exit 0 + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## sh-basic-offset: 2 +## End: diff --git a/doc/snprintfv.texi b/doc/snprintfv.texi new file mode 100644 index 0000000..380641c --- /dev/null +++ b/doc/snprintfv.texi @@ -0,0 +1,74 @@ +@node snprintfv +@section Replacement for Stdio Formatting Library + + Using the `printf' formatting routines in a portable fashion has +always been a pain, and this package has been way more pain than anyone +ever imagined. Hopefully, with this release of snprintfv, the pain is +now over for all time. + + The issues with portable usage are these: + +@enumerate +@item +Argument number specifiers are often either not implemented or are +buggy. Even GNU libc, version 1 got it wrong. + +@item +ANSI/ISO "forgot" to provide a mechanism for computing argument +lists for vararg procedures. + +@item +The argument array version of printf (`printfv()') is not +generally available, does not work with the native printf, and +does not have a working argument number specifier in the format +specification. (Last I knew, anyway.) + +@item +You cannot fake varargs by calling `vprintf()' with an array of +arguments, because ANSI does not require such an implementation +and some vendors play funny tricks because they are allowed to. +@end enumerate + + These four issues made it impossible for AutoGen to ship without its +own implementation of the `printf' formatting routines. Since we were +forced to do this, we decided to make the formatting routines both +better and more complete :-). We addressed these issues and added the +following features to the common printf API: + +@enumerate 5 +@item +The formatted output can be written to + +@itemize @bullet +@item +a string allocated by the formatting function (`asprintf()'). +@item +a file descriptor instead of a file stream (`dprintf()'). +@item +a user specified stream (`stream_printf()'). +@end itemize + +@item +The formatting functions can be augmented with your own functions. +These functions are allowed to consume more than one character +from the format, but must commence with a unique character. For +example, + +@example +"%@{struct stat@}\n" +@end example + +might be used with '@{' registered to a procedure that would look +up "struct stat" in a symbol table and do appropriate things, +consuming the format string through the '@}' character. +@end enumerate + + Gary V. Vaughan was generous enough to supply this implementation. +Many thanks!! + + For further details, the reader is referred to the snprintfv +documentation. These functions are also available in the template +processing as@: `sprintf' (@pxref{SCM sprintf}), `printf' +(@pxref{SCM printf}), `fprintf' (@pxref{SCM fprintf}), and `shellf' +(@pxref{SCM shellf}). + diff --git a/getdefs/Makefile.am b/getdefs/Makefile.am new file mode 100644 index 0000000..4322223 --- /dev/null +++ b/getdefs/Makefile.am @@ -0,0 +1,102 @@ +## -*- Mode: Makefile -*- +## --------------------------------------------------------------------- +## Makefile.am -- process this file with automake to produce Makefile.in +## +## Author: Bruce Korb +## +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen 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. +## +## AutoGen is distributed in the hope that 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 . +## --------------------------------------------------------------------- +TARG = getdefs + +bin_PROGRAMS = getdefs +getdefs_LDFLAGS = -no-install +gdsrcs = getdefs.h proto.h gdemit.c gdinit.c getdefs.c +getdefs_SOURCES = proto.h +BUILT_SOURCES = gd.c +nodist_getdefs_SOURCES = $(BUILT_SOURCES) + +SUBDIRS = test +EXTRA_DIST = opts.def $(gdsrcs) +AG_ENV = top_builddir="$(top_builddir)" top_srcdir="$(top_srcdir)" \ + VERBOSE="$(V)" +RUN_AG = $(AG_ENV) $(SHELL) "${top_srcdir}/build-aux/run-ag.sh" + +all : gen +gen : $(BUILT_SOURCES) $(DOCFILES) + +if AMDEP +DEPFL_OPTS = $(DEPDIR)/opts-dep.mk +DEPFL_TEXI = $(DEPDIR)/info-dep.mk +DEPFL_MAN = $(DEPDIR)/man-dep.mk + +$(DEPFL_OPTS) : + $(RUN_AG) "$@" +include $(DEPFL_OPTS) + +$(DEPFL_MAN) : + $(RUN_AG) "$@" +include $(DEPFL_MAN) + +$(DEPFL_INFO) : + $(RUN_AG) "$@" +include $(DEPFL_INFO) +else +DEPFL_OPTS = $@ +DEPFL_TEXI = $@ +DEPFL_MAN = $@ +endif + +AGARG_OPTS = -MF$(DEPFL_OPTS) -MT$@ -MP +AGARG_TEXI = -MF$(DEPFL_TEXI) -MT$@ -MP -Tagtexi-cmd +AGARG_MAN = -MF$(DEPFL_MAN) -MT$@ -MP -Tagman-cmd + +getdefs_LDADD = $(top_builddir)/autoopts/libopts.la +man_MANS = $(TARG).1 +TEXI_FILES = $(TARG).texi $(TARG).menu +DOCFILES = $(TEXI_FILES) $(man_MANS) +DISTCLEANFILES = $(DOCFILES) $(nodist_getdefs_SOURCES) *-stamp +AM_CPPFLAGS = @INCLIST@ +AM_CFLAGS = @WARN_CFLAGS@ + +gd.c : $(gdsrcs) + exec > $@ ; \ + echo '#undef PKGDATADIR' ; \ + echo '#define PKGDATADIR "$(pkgdatadir)"' ; \ + echo ; echo '#define DEFINING 1' ; \ + echo '#include "autoopts/project.h"' ; \ + for f in opts.c $(gdsrcs) ; \ + do echo "#include \"$$f\"" ; done + +$(getdefs_OBJECTS) opts.h opts.c : stamp-opts +stamp-opts : opts.def + $(RUN_AG) $(AGARG_OPTS) $(srcdir)/opts.def + +$(man_MANS) : stamp-man +stamp-man : $(TARG)$(EXEEXT) + $(RUN_AG) $(AGARG_MAN) $(srcdir)/opts.def + +$(TEXI_FILES) : stamp-doc +stamp-doc : $(TARG)$(EXEEXT) + $(RUN_AG) $(AGARG_TEXI) -DLEVEL=section $(srcdir)/opts.def + +.NOTPARALLEL: + +.PHONY : local-maintainer-clean stamp-man +local-maintainer-clean : clean-stamp-opts clean-stamp-doc clean-stamp-man + rm -f *~ + +# end of getdefs/Makefile.am diff --git a/getdefs/Makefile.in b/getdefs/Makefile.in new file mode 100644 index 0000000..f6423b4 --- /dev/null +++ b/getdefs/Makefile.in @@ -0,0 +1,976 @@ +# Makefile.in generated by automake 1.16.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2018 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +bin_PROGRAMS = getdefs$(EXEEXT) +subdir = getdefs +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/config/ag_macros.m4 \ + $(top_srcdir)/config/asm-underscore.m4 \ + $(top_srcdir)/config/extensions.m4 \ + $(top_srcdir)/config/guile.m4 \ + $(top_srcdir)/config/host-cpu-c-abi.m4 \ + $(top_srcdir)/config/lib-ld.m4 \ + $(top_srcdir)/config/lib-link.m4 \ + $(top_srcdir)/config/lib-prefix.m4 \ + $(top_srcdir)/config/libopts.m4 \ + $(top_srcdir)/config/libtool.m4 \ + $(top_srcdir)/config/ltoptions.m4 \ + $(top_srcdir)/config/ltsugar.m4 \ + $(top_srcdir)/config/ltversion.m4 \ + $(top_srcdir)/config/lt~obsolete.m4 \ + $(top_srcdir)/config/onceonly.m4 $(top_srcdir)/config/pkg.m4 \ + $(top_srcdir)/config/snprintfv.m4 \ + $(top_srcdir)/config/stdnoreturn.m4 \ + $(top_srcdir)/config/unlocked-io.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" +PROGRAMS = $(bin_PROGRAMS) +am_getdefs_OBJECTS = +am__objects_1 = gd.$(OBJEXT) +nodist_getdefs_OBJECTS = $(am__objects_1) +getdefs_OBJECTS = $(am_getdefs_OBJECTS) $(nodist_getdefs_OBJECTS) +getdefs_DEPENDENCIES = $(top_builddir)/autoopts/libopts.la +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +getdefs_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(getdefs_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/config/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/gd.Po +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(getdefs_SOURCES) $(nodist_getdefs_SOURCES) +DIST_SOURCES = $(getdefs_SOURCES) +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +man1dir = $(mandir)/man1 +NROFF = nroff +MANS = $(man_MANS) +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ + distdir distdir-am +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = $(SUBDIRS) +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/config/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +ACLOCAL = @ACLOCAL@ +AGEN5_TESTS = @AGEN5_TESTS@ +AG_LDFLAGS = @AG_LDFLAGS@ +AG_MAJOR_VERSION = @AG_MAJOR_VERSION@ +AG_MINOR_VERSION = @AG_MINOR_VERSION@ +AG_STATIC_AUTOGEN = @AG_STATIC_AUTOGEN@ +AG_TIMEOUT = @AG_TIMEOUT@ +AG_VERSION = @AG_VERSION@ +AG_XML2 = @AG_XML2@ +AGexe = @AGexe@ +AGnam = @AGnam@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AO_AGE = @AO_AGE@ +AO_CURRENT = @AO_CURRENT@ +AO_REVISION = @AO_REVISION@ +AO_TEMPLATE_VERSION = @AO_TEMPLATE_VERSION@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CLexe = @CLexe@ +CLnam = @CLnam@ +CONFIG_SHELL = @CONFIG_SHELL@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEBUG_ENABLED = @DEBUG_ENABLED@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +DYNAMIC_AG = @DYNAMIC_AG@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ENABLE_STATIC = @ENABLE_STATIC@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GDexe = @GDexe@ +GDnam = @GDnam@ +GO_AGE = @GO_AGE@ +GO_CURRENT = @GO_CURRENT@ +GO_REVISION = @GO_REVISION@ +GREP = @GREP@ +GUILE_CFLAGS = @GUILE_CFLAGS@ +GUILE_EFFECTIVE_VERSION = @GUILE_EFFECTIVE_VERSION@ +GUILE_LDFLAGS = @GUILE_LDFLAGS@ +GUILE_LIBS = @GUILE_LIBS@ +GUILE_LTLIBS = @GUILE_LTLIBS@ +HOST_CPU = @HOST_CPU@ +HOST_CPU_C_ABI = @HOST_CPU_C_ABI@ +INCLIST = @INCLIST@ +INCSNPRINTFV = @INCSNPRINTFV@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSNPRINTFV = @LIBSNPRINTFV@ +LIBTOOL = @LIBTOOL@ +LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ +LIBXML2_LIBS = @LIBXML2_LIBS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +M4_SRC = @M4_SRC@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPTS_TESTDIR = @OPTS_TESTDIR@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POSIX_SHELL = @POSIX_SHELL@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STDNORETURN_H = @STDNORETURN_H@ +STRIP = @STRIP@ +TEXI2HTML = @TEXI2HTML@ +VERSION = @VERSION@ +WARN_CFLAGS = @WARN_CFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_aux_dir = @ac_aux_dir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +TARG = getdefs +getdefs_LDFLAGS = -no-install +gdsrcs = getdefs.h proto.h gdemit.c gdinit.c getdefs.c +getdefs_SOURCES = proto.h +BUILT_SOURCES = gd.c +nodist_getdefs_SOURCES = $(BUILT_SOURCES) +SUBDIRS = test +EXTRA_DIST = opts.def $(gdsrcs) +AG_ENV = top_builddir="$(top_builddir)" top_srcdir="$(top_srcdir)" \ + VERBOSE="$(V)" + +RUN_AG = $(AG_ENV) $(SHELL) "${top_srcdir}/build-aux/run-ag.sh" +@AMDEP_FALSE@DEPFL_OPTS = $@ +@AMDEP_TRUE@DEPFL_OPTS = $(DEPDIR)/opts-dep.mk +@AMDEP_FALSE@DEPFL_TEXI = $@ +@AMDEP_TRUE@DEPFL_TEXI = $(DEPDIR)/info-dep.mk +@AMDEP_FALSE@DEPFL_MAN = $@ +@AMDEP_TRUE@DEPFL_MAN = $(DEPDIR)/man-dep.mk +AGARG_OPTS = -MF$(DEPFL_OPTS) -MT$@ -MP +AGARG_TEXI = -MF$(DEPFL_TEXI) -MT$@ -MP -Tagtexi-cmd +AGARG_MAN = -MF$(DEPFL_MAN) -MT$@ -MP -Tagman-cmd +getdefs_LDADD = $(top_builddir)/autoopts/libopts.la +man_MANS = $(TARG).1 +TEXI_FILES = $(TARG).texi $(TARG).menu +DOCFILES = $(TEXI_FILES) $(man_MANS) +DISTCLEANFILES = $(DOCFILES) $(nodist_getdefs_SOURCES) *-stamp +AM_CPPFLAGS = @INCLIST@ +AM_CFLAGS = @WARN_CFLAGS@ +all: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) all-recursive + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu getdefs/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu getdefs/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ + fi; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p \ + || test -f $$p1 \ + ; then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' \ + -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' \ + `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(bindir)" && rm -f $$files + +clean-binPROGRAMS: + @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list + +getdefs$(EXEEXT): $(getdefs_OBJECTS) $(getdefs_DEPENDENCIES) $(EXTRA_getdefs_DEPENDENCIES) + @rm -f getdefs$(EXEEXT) + $(AM_V_CCLD)$(getdefs_LINK) $(getdefs_OBJECTS) $(getdefs_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gd.Po@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-man1: $(man_MANS) + @$(NORMAL_INSTALL) + @list1=''; \ + list2='$(man_MANS)'; \ + test -n "$(man1dir)" \ + && test -n "`echo $$list1$$list2`" \ + || exit 0; \ + echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \ + { for i in $$list1; do echo "$$i"; done; \ + if test -n "$$list2"; then \ + for i in $$list2; do echo "$$i"; done \ + | sed -n '/\.1[a-z]*$$/p'; \ + fi; \ + } | while read p; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; echo "$$p"; \ + done | \ + sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ + sed 'N;N;s,\n, ,g' | { \ + list=; while read file base inst; do \ + if test "$$base" = "$$inst"; then list="$$list $$file"; else \ + echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ + $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ + fi; \ + done; \ + for i in $$list; do echo "$$i"; done | $(am__base_list) | \ + while read files; do \ + test -z "$$files" || { \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ + done; } + +uninstall-man1: + @$(NORMAL_UNINSTALL) + @list=''; test -n "$(man1dir)" || exit 0; \ + files=`{ for i in $$list; do echo "$$i"; done; \ + l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ + sed -n '/\.1[a-z]*$$/p'; \ + } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ + dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir) + +# This directory's subdirectories are mostly independent; you can cd +# into them and run 'make' without going through this Makefile. +# To change the values of 'make' variables: instead of editing Makefiles, +# (1) if the variable is set in 'config.status', edit 'config.status' +# (which will cause the Makefiles to be regenerated when you run 'make'); +# (2) otherwise, pass the desired values on the 'make' command line. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-recursive + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-recursive + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) check-recursive +all-am: Makefile $(PROGRAMS) $(MANS) +installdirs: installdirs-recursive +installdirs-am: + for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) +clean: clean-recursive + +clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am + +distclean: distclean-recursive + -rm -f ./$(DEPDIR)/gd.Po + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: install-man + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: install-binPROGRAMS + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: install-man1 + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f ./$(DEPDIR)/gd.Po + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: uninstall-binPROGRAMS uninstall-man + +uninstall-man: uninstall-man1 + +.MAKE: $(am__recursive_targets) all check install install-am \ + install-strip + +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ + am--depfiles check check-am clean clean-binPROGRAMS \ + clean-generic clean-libtool cscopelist-am ctags ctags-am \ + distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-binPROGRAMS \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-man1 \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + installdirs-am maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-binPROGRAMS uninstall-man \ + uninstall-man1 + +.PRECIOUS: Makefile + + +all : gen +gen : $(BUILT_SOURCES) $(DOCFILES) + +@AMDEP_TRUE@$(DEPFL_OPTS) : +@AMDEP_TRUE@ $(RUN_AG) "$@" +@AMDEP_TRUE@include $(DEPFL_OPTS) + +@AMDEP_TRUE@$(DEPFL_MAN) : +@AMDEP_TRUE@ $(RUN_AG) "$@" +@AMDEP_TRUE@include $(DEPFL_MAN) + +@AMDEP_TRUE@$(DEPFL_INFO) : +@AMDEP_TRUE@ $(RUN_AG) "$@" +@AMDEP_TRUE@include $(DEPFL_INFO) + +gd.c : $(gdsrcs) + exec > $@ ; \ + echo '#undef PKGDATADIR' ; \ + echo '#define PKGDATADIR "$(pkgdatadir)"' ; \ + echo ; echo '#define DEFINING 1' ; \ + echo '#include "autoopts/project.h"' ; \ + for f in opts.c $(gdsrcs) ; \ + do echo "#include \"$$f\"" ; done + +$(getdefs_OBJECTS) opts.h opts.c : stamp-opts +stamp-opts : opts.def + $(RUN_AG) $(AGARG_OPTS) $(srcdir)/opts.def + +$(man_MANS) : stamp-man +stamp-man : $(TARG)$(EXEEXT) + $(RUN_AG) $(AGARG_MAN) $(srcdir)/opts.def + +$(TEXI_FILES) : stamp-doc +stamp-doc : $(TARG)$(EXEEXT) + $(RUN_AG) $(AGARG_TEXI) -DLEVEL=section $(srcdir)/opts.def + +.NOTPARALLEL: + +.PHONY : local-maintainer-clean stamp-man +local-maintainer-clean : clean-stamp-opts clean-stamp-doc clean-stamp-man + rm -f *~ + +# end of getdefs/Makefile.am + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/getdefs/gdemit.c b/getdefs/gdemit.c new file mode 100644 index 0000000..6d991d7 --- /dev/null +++ b/getdefs/gdemit.c @@ -0,0 +1,586 @@ + +/** + * @file gdemit.c + * @addtogroup columns + * @{ + */ +/* + * getdefs Copyright (C) 1999-2018 by Bruce Korb - all rights reserved + * + * Author: Bruce Korb + * This file is part of AutoGen. + * AutoGen Copyright (C) 1992-2017 by Bruce Korb - all rights reserved + * + * AutoGen 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. + * + * AutoGen is distributed in the hope that 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 . + */ + +/* + * compress_def + * + * Compress the definition text. Each input line has some prefix + * stuff to ensure it is a comment as seen by the normal processor + * of the file. In "C", the entire block is surrounded by the + * '/'-'*' and '*'-'/' pairs. In shell, every line would start + * with a hash character ('#'). Etc. To make life easy, we require + * that every line be prefixed with something that matches the + * pattern: + * + * "^[^*]*\*+" + * + * and any line that does not is ignored. So, here we strip off + * that prefix before we go ahead and try to parse it. + */ +static void +compress_def(char * pz) +{ + char * pzStrt = pz; + char * pzDest = pz; + char * pzSrc = pz; + int nlCt = 0; + + /* + * Search until we find a line that contains an asterisk + * and is followed by something other than whitespace. + */ + nlCt = 0; + + skip_leading_space: + while (isspace( *pzSrc )) { + if (*(pzSrc++) == '\n') { + nlCt++; + for (;;) { + switch (*(pzSrc++)) { + case '*': + while (*pzSrc == '*') pzSrc++; + goto skip_leading_space; + + case NUL: + *pzStrt = NUL; + return; + + case '\n': + nlCt++; + } + } + } + } + + if (*pzSrc == NUL) { + *pzStrt = NUL; + return; + } + + /* + * FOR as long as we still have more text, ... + */ + for (;;) { + /* + * IF we passed over one or more newlines while looking for + * an asterisk, then insert one extra newline into the output + */ + if (nlCt > 0) { + *pzDest++ = '\n'; + nlCt = 0; + } + + /* + * FOR all the data on the current input line, ... + */ + for (;;) { + /* + * Move the source to destination until we find + * either a new-line or a NUL. + */ + switch (*pzDest++ = *pzSrc++) { + case '\n': + if (*pzSrc != NUL) + goto lineDone; + /* FALLTHROUGH */ + + case NUL: + pzDest--; + goto compressDone; + + default: + ; + } + } lineDone:; + + /* + * Trim trailing white space off the end of the line. + */ + if ((pzDest[-2] == ' ') || (pzDest[-2] == '\t')) { + do { + pzDest--; + } while ((pzDest[-2] == ' ') || (pzDest[-2] == '\t')); + pzDest[-1] = '\n'; + } + + /* + * We found a new-line. Skip forward to an asterisk. + */ + foundNewline: + while (*pzSrc != '*') { + if (*pzSrc == NUL) + goto compressDone; + if (*pzSrc == '\n') + nlCt++; + pzSrc++; + } + + /* + * Skip over the asterisk we found and all the ones that follow + */ + while (*pzSrc == '*') pzSrc++; + while (isspace( *pzSrc )) { + /* + * IF we stumble into another newline, + * THEN we go back to look for an asterisk. + */ + if (*pzSrc == '\n') + goto foundNewline; + pzSrc++; + } + } compressDone:; + + /* + * Trim off all the trailing white space, including newlines + */ + while ((pzDest > pzStrt) && isspace( pzDest[-1] )) pzDest--; + *pzDest = NUL; +} + + +/* + * emitDefinition + */ +MOD_LOCAL char * +emitDefinition(char * pzDef, char * pzOut) +{ + char sep_char; + char zEntryName[ MAXNAMELEN ]; + + /* + * Indent attribute definitions four spaces + */ + { + char * p = zEntryName; + *pzOut++ = ' '; *pzOut++ = ' '; *pzOut++ = ' '; *pzOut++ = ' '; + + while (AG_NAME_CHAR(*pzDef)) + *p++ = *pzOut++ = *pzDef++; + + if (p >= zEntryName + sizeof(zEntryName)) + die(GETDEFS_EXIT_USAGE_ERROR, "names are constrained to %d bytes\n", + MAXNAMELEN); + + *p = NUL; + } + + /* + * Strip the prefixes from all the definition lines + * (viz., the "^.*\*" text, except that it is a shortest match + * instead of longest match). Skip the ':' before starting. + */ + compress_def(++pzDef); + + if (HAVE_OPT( SUBBLOCK )) { + int ct = STACKCT_OPT( SUBBLOCK ); + char const ** ppz = STACKLST_OPT( SUBBLOCK ); + + do { + char const * pz = *ppz++; + if (strcmp(pz, zEntryName) == 0) + return emit_subblock(pz, pzDef, pzOut); + } while (--ct > 0); + } + + if (HAVE_OPT( LISTATTR )) { + int ct = STACKCT_OPT( LISTATTR ); + char const ** ppz = STACKLST_OPT( LISTATTR ); + + do { + if (strcmp(*ppz++, zEntryName) == 0) + return list_attrib(pzDef, pzOut); + } while (--ct > 0); + } + + if (isspace(*pzDef)) + sep_char = *pzDef++; + else sep_char = ' '; + + switch (*pzDef) { + case NUL: + *pzOut++ = ';'; *pzOut++ = '\n'; + break; + + case '"': + case '\'': + case '{': + /* + * Quoted entries or subblocks do their own stringification + * sprintf is safe because we are copying strings around + * and *always* making the result smaller than the original + */ + pzOut += sprintf(pzOut, " =%c%s;\n", sep_char, pzDef); + break; + + default: + *pzOut++ = ' '; *pzOut++ = '='; *pzOut++ = sep_char; + *pzOut++ = '\''; + + for (;;) { + switch (*pzOut++ = *pzDef++) { + case '\\': + *pzOut++ = '\\'; + break; + + case '\'': + pzOut[-1] = '\\'; + *pzOut++ = '\''; + break; + + case NUL: + goto unquotedDone; + } + } unquotedDone:; + pzOut[-1] = '\''; *pzOut++ = ';'; *pzOut++ = '\n'; + break; + } + return pzOut; +} + + +/* + * list_attrib + */ +static char * +list_attrib(char * pzText, char * pzOut) +{ + static char const zStart[] = " = "; + + uint_t sepChar = ','; + int FirstAttr = 1; + + strcpy(pzOut, zStart); + pzOut += sizeof(zStart) - 1; + + /* + * See if there is an alternate separator character. + * It must be a punctuation character that is not also + * a quote character. + */ + if (ispunct(*pzText) && (*pzText != '"') && (*pzText != '\'')) + sepChar = (uint_t)*(pzText++); + while (isspace(*pzText)) pzText++; + + /* + * Loop for as long as we have text entries + */ + while (*pzText != NUL) { + + if (FirstAttr) + FirstAttr = 0; + else + *(pzOut++) = ','; + + /* + * If the first thing we find is the separator char, + * then emit the empty string. + */ + if ((uint_t)*pzText == sepChar) { + *(pzOut++) = '\''; *(pzOut++) = '\''; + pzText++; + continue; + } + + /* + * Emit whatever we have. The call will consume any trailing + * separator character. + */ + pzOut = subblock_str(&pzText, sepChar, pzOut); + } + + /* + * IF there were no definitions, THEN emit an empty one + */ + if (FirstAttr) + pzOut -= sizeof(zStart) - 1; + + *(pzOut++) = ';'; + *(pzOut++) = '\n'; + + return pzOut; +} + + +/* + * The text is quoted, so copy it as is, ensuring that escaped + * characters are not used to end the quoted text. + */ +static char * +emit_quote(char ** ppzText, char * pzOut) +{ + char * pzText = *ppzText; + char svch = (*pzOut++ = *pzText++); + + for (;;) { + switch (*pzOut++ = *pzText++) { + + case '\\': + if ((*pzOut++ = *pzText++) != NUL) + break; + /* FALLTHROUGH */ + + case NUL: + pzText--; + pzOut[-1] = svch; + svch = NUL; + /* FALLTHROUGH */ + + case '"': + case '\'': + if (pzOut[-1] == svch) + goto quoteDone; + + break; + } + } + +quoteDone: + *ppzText = pzText; + return pzOut; +} + +static void +next_def_entry(char ** txt_pp, char const ** def_pp) +{ + char const * p = *def_pp; + (*txt_pp)++; + for (;;) { + switch (*++p) { + case ' ': p++; /* FALLTHROUGH */ + case NUL: + *def_pp = p; + return; + } + } +} + +static void +emit_attribute(char const ** def_pp, char ** out_pp) +{ + static char const pfx[] = "\n "; + + char * out = *out_pp; + char const * def = *def_pp; + + memcpy(out, pfx, sizeof(pfx) - 1); + out += sizeof(pfx) - 1; + + for (;;) { + *out++ = *def++; + switch (*def) { + case ' ': def++; /* FALLTHROUGH */ + case NUL: + goto leave_emit_attribute; + } + } + + leave_emit_attribute: + + *out++ = ';'; + *out_pp = out; + *def_pp = def; +} + +/* + * emit_subblock + */ +static char * +emit_subblock(char const * pzDefList, char * pzText, char * pzOut) +{ + static char const zStart[] = " = {"; + static char const zEnd[] = "\n };\n"; + + uint_t sepChar = ','; + int FirstAttr = 1; + + /* + * Advance past subblock name to the entry name list + */ + pzDefList += strlen(pzDefList) + 1; + strcpy(pzOut, zStart); + pzOut += sizeof(zStart) - 1; + + /* + * See if there is an alternate separator character. + * It must be a punctuation character that is not also + * a quote character. + */ + if (ispunct(*pzText) && (*pzText != '"') && (*pzText != '\'')) + sepChar = (uint_t)*(pzText++); + + /* + * Loop for as long as we have text entries and subblock + * attribute names, ... + */ + do { + /* + * IF the first character is the separator, + * THEN this entry is skipped. + */ + if ((uint_t)*pzText == sepChar) { + next_def_entry(&pzText, &pzDefList); + continue; + } + + /* + * Skip leading white space in the attribute and check for done. + */ + while (isspace(*pzText)) pzText++; + if (*pzText == NUL) { + /* + * IF there were no definitions, THEN emit one anyway + */ + if (FirstAttr) + emit_attribute(&pzDefList, &pzOut); + + break; + } + + /* + * Copy out the attribute name + */ + emit_attribute(&pzDefList, &pzOut); + FirstAttr = 0; + + /* + * IF there are no data for this attribute, + * THEN we leave the definition empty. + */ + if ((uint_t)*pzText == sepChar) { + pzText++; + continue; + } + + /* + * Copy out the assignment operator and emit the string + */ + pzOut[-1] = ' '; *pzOut++ = '='; *pzOut++ = ' '; + pzOut = subblock_str(&pzText, sepChar, pzOut); + *pzOut++ = ';'; + + } while (isalpha(*pzDefList)); + + memcpy(pzOut, zEnd, sizeof(zEnd)); + return pzOut + sizeof(zEnd) - 1; +} + + +/* + * Emit a string in a fashion that autogen will be able to + * correctly reconstruct it. + */ +static char * +subblock_str(char ** ppzText, uint_t sepChar, char * pzOut) +{ + char * pzText = *ppzText; + char * pcComma; + char * pcEnd; + + /* + * Skip leading space + */ + while (isspace(*pzText)) pzText++; + + /* + * IF the text is already quoted, + * THEN call the quoted text emitting routine + */ + if ((*pzText == '"') || (*pzText == '\'')) { + pzOut = emit_quote(&pzText, pzOut); + + /* + * Make sure we strip off trailing white space and any + * separation character. + */ + while (isspace(*pzText)) pzText++; + if ((uint_t)*pzText == sepChar) { + pzText++; + while (isspace(*pzText)) pzText++; + } + *ppzText = pzText; + return pzOut; + } + + /* + * Look for the character that separates this entry text + * from the entry text for the next attribute. Leave 'pcComma' + * pointing to the character _before_ the character where we + * are to resume our text scan. (i.e. at the comma, or the + * last character in the string) + */ + pcComma = strchr(pzText, (int)sepChar); + if (pcComma == (char *)NULL) { + pcEnd = pzText + strlen(pzText); + pcComma = pcEnd-1; + } else { + pcEnd = pcComma; + } + + /* + * Clean off trailing white space. + */ + while ((pcEnd > pzText) && isspace(pcEnd[-1])) pcEnd--; + + /* + * Copy the text, surrounded by single quotes + */ + *pzOut++ = '\''; + { + char svch = *pcEnd; + *pcEnd = NUL; + for (;;) { + char ch = *pzText++; + switch (ch) { + case '\'': + *pzOut++ = '\\'; + /* FALLTHROUGH */ + default: + *pzOut++ = ch; + break; + case NUL: + goto copyDone; + } + } copyDone: ; + + pzText = pcComma+1; + *pcEnd = svch; + } + + *pzOut++ = '\''; + while (isspace(*pzText)) pzText++; + *ppzText = pzText; + return pzOut; +} + +/** @} + * + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of getdefs/gdemit.c */ diff --git a/getdefs/gdinit.c b/getdefs/gdinit.c new file mode 100644 index 0000000..0ad9c9a --- /dev/null +++ b/getdefs/gdinit.c @@ -0,0 +1,456 @@ + +/** + * @file gdinit.c + * @addtogroup columns + * @{ + */ +/* + * getdefs Copyright (C) 1999-2018 by Bruce Korb - all rights reserved + * + * Author: Bruce Korb + * This file is part of AutoGen. + * AutoGen Copyright (C) 1992-2017 by Bruce Korb - all rights reserved + * + * AutoGen 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. + * + * AutoGen is distributed in the hope that 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 . + */ + +MOD_LOCAL char const zNoList[] = "ERROR: block attr must have name list:\n\t%s\n"; + +/* + * compressOptionText + */ +static char * +compressOptionText(char * pzS, char * pzE) +{ + char * pzR = pzS; /* result */ + char * pzD = pzS; /* destination */ + + for (;;) { + char ch; + + if (pzS >= pzE) + break; + + ch = (*(pzD++) = *(pzS++)); + + /* + * IF At end of line, skip to next '*' + */ + if (ch == '\n') { + while (*pzS != '*') { + pzS++; + if (pzS >= pzE) + goto compressDone; + } + } + } compressDone:; + + { + size_t len = (size_t)(pzD - pzR); + pzD = malloc(len + 1); + if (pzD == NULL) + nomem_err(len + 1, "new option string"); + + memcpy(pzD, pzR, len); + pzD[ len ] = NUL; + } + + /* + * Blank out trailing data. + */ + while (pzS < pzE) *(pzS++) = ' '; + return pzD; +} + + +/* + * fixupSubblockString + */ +static char * +fixupSubblockString(char const * pzSrc) +{ + char * pzString; + char * pzDest; + char * pzCopy; + + pzString = strdup(pzSrc); + + /* + * Make sure we find the '=' separator + */ + { + char * p = strchr(pzString, '='); + if (p == NULL) + die(GETDEFS_EXIT_INVALID_INPUT, zNoList, pzString); + + /* + * Trim the name + */ + pzDest = p++; + while ((pzDest > pzString) && IS_HORIZ_WHITE_CHAR(pzDest[-1])) pzDest--; + *(pzDest++) = NUL; + + /* + * Make sure at least one attribute name is defined + */ + while (IS_WHITESPACE_CHAR(*p)) p++; + if (*p == NUL) + die(GETDEFS_EXIT_INVALID_INPUT, zNoList, pzString); + + pzCopy = p; + } + + for (;;) { + /* + * Attribute names must start with an alpha + */ + if (! IS_ALPHABETIC_CHAR(*pzCopy)) { + fprintf(stderr, "ERROR: attribute names must start " + "with an alphabetic character:\n\t%s\n", + pzString); + USAGE(EXIT_FAILURE); + } + + /* + * Copy the name. + */ + while (IS_OPTION_NAME_CHAR(*pzCopy)) + *pzDest++ = *pzCopy++; + + /* + * Skip over one comma (optional) and any white space. + * If there is a newline, it must be after the comma. + */ + while (IS_HORIZ_WHITE_CHAR(*pzCopy)) pzCopy++; + if (*pzCopy == ',') + pzCopy++; + + while (IS_WHITESPACE_CHAR(*pzCopy)) pzCopy++; + if (*pzCopy == NUL) + break; + /* + * The final string contains only one space between attributes + */ + *pzDest++ = ' '; + } + + *pzDest = NUL; + + return pzString; +} + + +/* + * loadStdin + * + * The input file list is from stdin. + * + * We make some simplifying assumptions: + * *ALL* input lines are less than 4096 bytes. If this is not true, + * we may strip some white space in the middle of a line and presume + * a comment begins in the middle of a line or we only comment out + * the first 4096 bytes of a comment line. So, rather than all these + * problems, we just choke on it. + */ +static void +loadStdin(void) +{ + char z[ 4096 ]; + int ct = 0; + char const ** ppz = STACKLST_OPT(INPUT); + + if (isatty(STDIN_FILENO)) { + fputs("getdefs error: no inputs were specified and stdin is a tty\n", + stderr); + USAGE(EXIT_FAILURE); + } + + while (fgets(z, (int)sizeof(z), stdin) != NULL) { + char * pz = z + strlen(z); + + if (pz[-1] != '\n') { + static char const zErr[] = + "getdefs error: input line not newline terminated\n"; + fputs(zErr, stderr); + exit(EXIT_FAILURE); + } + + while ((pz > z) && isspace(pz[-1])) pz--; + *pz = '\0'; + pz = z; + while (isspace(*pz)) pz++; + if ((*pz == '\0') || (*pz == '#')) continue; + if (access(pz, R_OK) != 0) continue; + + if (ct++ == 0) + *ppz = strdup(z); /* replace the "-" */ + else + SET_OPT_INPUT(strdup(z)); /* if 'strdup' fails, we die later */ + } +} + + +/* + * processEmbeddedOptions + * + * This routine processes the text contained within "/\*==--" + * and "=\*\/" as a single option. If that option is the SUBBLOCK + * option, it will need to be massaged for use. + */ +MOD_LOCAL void +processEmbeddedOptions(char * pzText) +{ + static char const zStStr[] = "/*=--"; + static char const zEndSt[] = "=*/"; + + for (;;) { + char * pzStart = strstr(pzText, zStStr); + char * pzEnd; + int sblct = 0; + + if (pzStart == NULL) + return; + + if (HAVE_OPT(SUBBLOCK)) + sblct = STACKCT_OPT(SUBBLOCK); + + pzEnd = strstr(pzStart, zEndSt); + if (pzEnd == NULL) + return; + + pzStart = compressOptionText(pzStart + sizeof(zStStr)-1, pzEnd); + + optionLoadLine(&getdefsOptions, pzStart); + + if (HAVE_OPT(SUBBLOCK) && (sblct != STACKCT_OPT(SUBBLOCK))) { + char const ** ppz = STACKLST_OPT(SUBBLOCK); + ppz[ sblct ] = fixupSubblockString(ppz[sblct]); + } + pzText = pzEnd + sizeof(zEndSt); + } +} + +/** + * set up the regular expression we search for + */ +static void +set_define_re(void) +{ + static char const default_pat[] = + "/\\*=(\\*|" + "([a-z][a-z0-9_]*(\\[[0-9]+\\]){0,1}|\\*)[ \t]+[a-z])"; + static char const pat_wrapper[] = "/\\*=(%s)"; + + char const * def_pat; + bool free_pat = false; + + /* + * Our default pattern is to accept all names following + * the '/' '*' '=' character sequence. We ignore case. + */ + if ((! HAVE_OPT(DEFS_TO_GET)) || (*OPT_ARG(DEFS_TO_GET) == NUL)) { + def_pat = default_pat; + + } else if (strncmp(OPT_ARG(DEFS_TO_GET), default_pat, 4) == 0) { + def_pat = OPT_ARG(DEFS_TO_GET); + + } else { + char const * pz = OPT_ARG(DEFS_TO_GET); + size_t len = strlen((char *)pz) + 16; + char * bf = malloc(len); + + if (bf == NULL) + nomem_err(len, "definition pattern"); + + /* + * IF a pattern has been supplied, enclose it with + * the '/' '*' '=' part of the pattern. + */ + snprintf(bf, len, pat_wrapper, pz); + def_pat = bf; + free_pat = true; + } + + /* + * Compile the regular expression that we are to search for + * to find each new definition in the source files. + */ + { + char zRER[MAXNAMELEN]; + static char const regex_err[] = + "Regex error %d (%s): Cannot compile reg expr:\n\t%s\n"; + + int rerr = regcomp(&define_re, def_pat, REG_EXTENDED | REG_ICASE); + if (rerr != 0) { + regerror(rerr, &define_re, zRER, sizeof(zRER)); + die(GETDEFS_EXIT_INVALID_INPUT, regex_err, rerr, zRER, def_pat); + } + + if (free_pat) + free(VOIDP(def_pat)); + + rerr = regcomp(&attrib_re, zAttribRe, REG_EXTENDED | REG_ICASE); + if (rerr != 0) { + regerror(rerr, &attrib_re, zRER, sizeof(zRER)); + die(GETDEFS_EXIT_INVALID_INPUT, regex_err, rerr, zRER, zAttribRe); + } + } +} + +/** + * Make sure each of the input files is findable. + * Also, while we are at it, compute the output file mod time + * based on the mod time of the most recent file. + */ +static void +set_modtime(void) +{ + int ct = STACKCT_OPT(INPUT); + char const ** ppz = STACKLST_OPT(INPUT); + struct stat stb; + + if ((ct == 1) && (strcmp(*ppz, "-") == 0)) { + /* + * Read the list of input files from stdin. + */ + loadStdin(); + ct = STACKCT_OPT( INPUT); + ppz = STACKLST_OPT(INPUT); + } + + do { + if (stat(*ppz++, &stb) != 0) + break; + + if (! S_ISREG(stb.st_mode)) { + errno = EINVAL; + break; + } + + if (++(stb.st_mtime) > modtime) + modtime = stb.st_mtime; + } while (--ct > 0); + + if (ct > 0) + fserr(GETDEFS_EXIT_INVALID_INPUT, "stat", ppz[-1]); +} + +/** + * validate_opts + * + * - Sanity check the options + * - massage the SUBBLOCK options into something + * more easily used during the source text processing. + * - compile the regular expressions + * - make sure we can find all the input files and their mod times + * - Set up our entry ordering database (if specified) + * - Make sure we have valid strings for SRCFILE and LINENUM + * (if we are to use these things). + * - Initialize the user name characters array. + */ +static void +validate_opts(void) +{ + set_define_re(); + + /* + * Prepare each sub-block entry so we can parse easily later. + */ + if (HAVE_OPT(SUBBLOCK)) { + int ct = STACKCT_OPT( SUBBLOCK); + char const ** ppz = STACKLST_OPT(SUBBLOCK); + + /* + * FOR each SUBBLOCK argument, + * DO condense each name list to be a list of names + * separated by a single space and NUL terminated. + */ + do { + *ppz = fixupSubblockString(*ppz); + ppz++; + } while (--ct > 0); + } + + if (! HAVE_OPT(INPUT)) + SET_OPT_INPUT("-"); + + set_modtime(); + + /* + * IF the output is to have order AND it is to be based on a file, + * THEN load the contents of that file. + * IF we cannot load the file, + * THEN it must be new or empty. Allocate several K to start. + */ + if ( HAVE_OPT(ORDERING) + && (OPT_ARG(ORDERING) != NULL)) { + static char const preamble[] = + "# -*- buffer-read-only: t -*- vi: set ro:\n" + "#\n# DO NOT EDIT THIS FILE - it is auto-edited by getdefs\n"; + + pzIndexText = loadFile(OPT_ARG(ORDERING)); + if (pzIndexText == NULL) { + pzIndexText = pzEndIndex = pzIndexEOF = malloc((size_t)0x4000); + indexAlloc = 0x4000; + pzEndIndex += sprintf(pzEndIndex, "%s", preamble); + } else { + pzEndIndex = pzIndexEOF = pzIndexText + strlen(pzIndexText); + indexAlloc = (size_t)(pzEndIndex - pzIndexText) + 1; + } + + /* + * We map the name entries to a connonical form. + * By default, everything is mapped to lower case already. + * This call will map these three characters to '_'. + */ + strequate("_-^"); + } + + { + char const * pz = OPT_ARG(SRCFILE); + if ((pz == NULL) || (*pz == NUL)) + OPT_ARG(SRCFILE) = "srcfile"; + + pz = OPT_ARG(LINENUM); + if ((pz == NULL) || (*pz == NUL)) + OPT_ARG(LINENUM) = "linenum"; + } + + { + static char const ag_nm_chars[] = + "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "0123456789" "_-^"; + static char const usr_nm_chars[] = ":.$%*!~<>&@"; + + char const * p = ag_nm_chars; + + while (*p) + zUserNameCh[(unsigned char)(*p++)] = 3; + + p = usr_nm_chars; + while (*p) + zUserNameCh[(unsigned char)(*p++)] = 1; + } +} + + +/** @} + * + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of getdefs/gdinit.c */ diff --git a/getdefs/getdefs.c b/getdefs/getdefs.c new file mode 100644 index 0000000..3124cb0 --- /dev/null +++ b/getdefs/getdefs.c @@ -0,0 +1,1162 @@ + +/** + * @file getdefs.c + * @addtogroup getdefs + * @{ + */ +/* + * getdefs Copyright (C) 1999-2018 by Bruce Korb - all rights reserved + * + * Author: Bruce Korb + * + * This file is part of AutoGen. + * AutoGen Copyright (C) 1992-2017 by Bruce Korb - all rights reserved + * + * AutoGen 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. + * + * AutoGen is distributed in the hope that 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 . + */ + +MOD_LOCAL char const zBogusDef[] = "Bogus definition:\n%s\n"; + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * Forward procedure pointers + */ +typedef int (compar_func)(const void *, const void *); +MOD_LOCAL compar_func compar_text, compar_defname; + +#ifndef HAVE_STRSIGNAL +# include "compat/strsignal.c" +#endif + +#ifndef HAVE_CHMOD +# include "compat/chmod.c" +#endif + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * Main + */ +int +main(int argc, char ** argv) +{ + FILE * outFp; + + optionProcess(&getdefsOptions, argc, argv); + validate_opts(); + + outFp = startAutogen(); + + doPreamble(outFp); + + /* + * Process each input file + */ + { + int ct = STACKCT_OPT(INPUT); + char const ** ppz = STACKLST_OPT(INPUT); + + do { + processFile(*ppz++); + } while (--ct > 0); + } + + /* + * IF we don't have an ordering file, but we do have a "first index", + * THEN alphabetize by definition name. + */ + if ((pzIndexText == NULL) && HAVE_OPT(FIRST_INDEX)) { + qsort(VOIDP(papzBlocks), blkUseCt, sizeof(char *), compar_defname); + set_first_idx(); + } + + else if (ENABLED_OPT(ORDERING) && (blkUseCt > 1)) + qsort(VOIDP(papzBlocks), blkUseCt, sizeof(char *), &compar_text); + + printEntries(outFp); +#ifdef HAVE_FCHMOD + fchmod(fileno(outFp), S_IRUSR|S_IRGRP|S_IROTH); +#endif + fclose(outFp); + + /* + * IF output is to a file + * THEN set the permissions and modification times + */ + if ( (WHICH_IDX_AUTOGEN == INDEX_OPT_OUTPUT) + && (outFp != stdout) ) { + struct utimbuf tbuf; + tbuf.actime = time((time_t *)NULL); + tbuf.modtime = modtime + 1; + utime(OPT_ARG(OUTPUT), &tbuf); +#ifndef HAVE_CHMOD + chmod(OPT_ARG(OUTPUT), S_IRUSR|S_IRGRP|S_IROTH); +#endif + } + + /* + * IF we are keeping a database of indexes + * AND we have augmented the contents, + * THEN append the new entries to the file. + */ + if ((pzIndexText != NULL) && (pzEndIndex != pzIndexEOF)) + update_db(); + + if (agPid != -1) + return awaitAutogen(); + + return EXIT_SUCCESS; +} + + +/* + * assignIndex + */ +static char * +assignIndex(char * pzOut, char * pzDef) +{ + char * pzMatch; + size_t len = strlen(pzDef); + int idx; + + /* + * Make the source text all lower case and map + * '-', '^' and '_' characters to '_'. + */ + strtransform(pzDef, pzDef); + + /* + * IF there is already an entry, + * THEN put the index into the output. + */ + pzMatch = strstr(pzIndexText, pzDef); + if (pzMatch != NULL) { + pzMatch += len; + while (isspace(*pzMatch)) pzMatch++; + while ((*pzOut++ = *pzMatch++) != ']') ; + return pzOut; + } + + /* + * We have a new entry. Make sure we have room for it + * in our in-memory string + */ + if (((size_t)(pzEndIndex - pzIndexText) + len + 64 ) > indexAlloc) { + char * pz; + indexAlloc += 0x1FFF; + indexAlloc &= (unsigned long)~0x0FFFUL; + pz = (char *)realloc(VOIDP(pzIndexText), indexAlloc); + if (pz == NULL) { + fputs("Realloc of index text failed\n", stderr); + exit(EXIT_FAILURE); + } + + /* + * IF the allocation moved, + * THEN adjust all our pointers. + */ + if (pz != pzIndexText) { + pzIndexEOF = pz + (pzIndexEOF - pzIndexText); + pzEndIndex = pz + (pzEndIndex - pzIndexText); + pzIndexText = pz; + } + } + + /* + * IF there are no data in our text database, + * THEN use default index. + */ + if (pzEndIndex == pzIndexText) + idx = (int)OPT_VALUE_FIRST_INDEX; + else do { + char * pz = strrchr(pzDef, ' '); + *pz = NUL; + len = strlen(pzDef); + + /* + * Find the last entry for the current category of entries + */ + pzMatch = strstr(pzIndexText, pzDef); + if (pzMatch == NULL) { + /* + * No entries for this category. Use default index. + */ + idx = (int)OPT_VALUE_FIRST_INDEX; + *pz = ' '; + break; + } + + for (;;) { + char * pzn = strstr(pzMatch + len, pzDef); + if (pzn == NULL) + break; + pzMatch = pzn; + } + + /* + * Skip forward to the '[' character and convert the + * number that follows to a long. + */ + *pz = ' '; + pzMatch = strchr(pzMatch + len, '['); + idx = (int)strtol(pzMatch+1, (char **)NULL, 0)+1; + } while (false); + + /* + * Add the new entry to our text database and + * place a copy of the value into our output. + */ + pzEndIndex += sprintf(pzEndIndex, "%-40s [%d]\n", pzDef, idx); + pzOut += sprintf(pzOut, "[%d]", idx); + + return pzOut; +} + + +/* + * awaitAutogen + */ +static int +awaitAutogen(void) +{ + int status; + waitpid(agPid, &status, 0); + if (WIFEXITED(status)) { + status = WEXITSTATUS(status); + if (status != EXIT_SUCCESS) { + fprintf(stderr, "ERROR: %s exited with status %d\n", + pzAutogen, status); + } + return status; + } + + if (WIFSIGNALED( status )) { + status = WTERMSIG( status ); + fprintf(stderr, "ERROR: %s exited due to %d signal (%s)\n", + pzAutogen, status, strsignal(status)); + } + else + fprintf(stderr, "ERROR: %s exited due to unknown reason %d\n", + pzAutogen, status); + + return EXIT_FAILURE; +} + + +/* + * buildDefinition + */ +static void +buildDefinition(char * pzDef, char const * pzFile, int line, char * pzOut) +{ + static char const zSrcFile[] = " %s = '%s';\n"; + static char const zLineNum[] = " %s = '%d';\n"; + + bool these_are_global_defs; + tSuccess preamble; + int re_res; + char * pzNextDef = NULL; + regmatch_t match[2]; + + if (*pzDef == '*') { + these_are_global_defs = true; + strcpy(pzOut, zGlobal); + pzOut += sizeof(zGlobal)-1; + pzOut += sprintf(pzOut, zLineId, line, pzFile); + + pzDef = strchr(pzDef, '\n'); + preamble = PROBLEM; + + } else { + these_are_global_defs = false; + preamble = buildPreamble(&pzDef, &pzOut, pzFile, line); + if (FAILED(preamble)) { + *pzOut = NUL; + return; + } + } + + /* + * FOR each attribute for this entry, ... + */ + for (;;) { + /* + * Find the next attribute regular expression + */ + re_res = regexec(&attrib_re, pzDef, COUNT(match), match, 0); + switch (re_res) { + case 0: + /* + * NUL-terminate the current attribute. + * Set the "next" pointer to the start of the next attribute name. + */ + pzDef[ match[0].rm_so ] = NUL; + if (pzNextDef != NULL) + pzOut = emitDefinition(pzNextDef, pzOut); + pzNextDef = pzDef = pzDef + match[1].rm_so; + break; + + case REG_NOMATCH: + /* + * No more attributes. + */ + if (pzNextDef == NULL) { + *pzOut++ = '\n'; *pzOut++ = '#'; + sprintf(pzOut, zNoData, pzFile, line); + fputs(pzOut, stderr); + pzOut += strlen(pzOut); + return; + } + + pzOut = emitDefinition(pzNextDef, pzOut); + goto eachAttrDone; + break; + + default: + { + char zRER[ MAXNAMELEN ]; + static char const zErr[] = "error %d (%s) finding '%s' in\n%s\n\n"; + regerror(re_res, &attrib_re, zRER, sizeof(zRER)); + *pzOut++ = '\n'; + *pzOut++ = '#'; + sprintf(pzOut, zErr, re_res, zRER, zAttribRe, pzDef); + fprintf(stderr, "getdefs: %s", zErr); + return; + } + } + } eachAttrDone:; + + if (these_are_global_defs) { + *pzOut = NUL; + return; + } + + if (HAVE_OPT(COMMON_ASSIGN)) { + int ct = STACKCT_OPT(COMMON_ASSIGN); + char const ** ppz = STACKLST_OPT(COMMON_ASSIGN); + do { + pzOut += sprintf(pzOut, " %s;\n", *ppz++); + } while (--ct > 0); + } + + if (HAVE_OPT(SRCFILE)) + pzOut += sprintf(pzOut, zSrcFile, OPT_ARG(SRCFILE), pzFile); + + if (HAVE_OPT(LINENUM)) + pzOut += sprintf(pzOut, zLineNum, OPT_ARG(LINENUM), line); + + /* + * IF the preamble had a problem, it is because it could not + * emit the final "#endif\n" directive. Do that now. + */ + if (HADGLITCH(preamble)) + strcpy(pzOut, "};\n#endif\n"); + else strcpy(pzOut, "};\n"); +} + + +/* + * buildPreamble + */ +static tSuccess +buildPreamble(char ** ppzDef, char ** ppzOut, char const * fname, int line) +{ + char * pzDef = *ppzDef; + char * pzOut = *ppzOut; + + char def_bf[ MAXNAMELEN ]; + char name_bf[ MAXNAMELEN ]; + char * def_str = def_bf; + char * pzIfText = NULL; + + /* + * Copy out the name of the entry type + */ + *def_str++ = '`'; + while (isalnum(*pzDef) || (*pzDef == '_') || (*pzDef == '.') + || (*pzDef == '[') || (*pzDef == ']')) + *def_str++ = *pzDef++; + + *def_str = NUL; + + pzDef += (int)strspn(pzDef, "* \t"); + + /* + * Copy out the name for this entry of the above entry type. + */ + { + char * name_str = name_bf; + while (isalnum(*pzDef) || (*pzDef == '_')) + *name_str++ = *pzDef++; + *name_str = NUL; + } + + if ( (def_bf[1] == NUL) + || (name_bf[0] == NUL) ) { + fprintf(stderr, zNoData, fname, line); + return FAILURE; + } + + pzDef += (int)strspn(pzDef, " \t"); + + /* + * IF these names are followed by a comma and an "if" clause, + * THEN we emit the definition with "#if..."/"#endif" around it + */ + if (*pzDef == ',') { + pzDef++; + pzDef += strspn(pzDef, " \t"); + if ((pzDef[0] == 'i') && (pzDef[1] == 'f')) + pzIfText = pzDef; + } + + pzDef = strchr(pzDef, '\n'); + if (pzDef == NULL) { + fprintf(stderr, zNoData, fname, line); + return FAILURE; + } + + *pzDef = NUL; + + /* + * Now start the output. First, the "#line" directive, + * then any "#ifdef..." line and finally put the + * entry type name into the output. + */ + pzOut += sprintf(pzOut, zLineId, line, fname); + if (pzIfText != NULL) + pzOut += sprintf(pzOut, "#%s\n", pzIfText); + { + char * pz = def_bf+1; + while (*pz != NUL) + *pzOut++ = *pz++; + } + + /* + * IF we are indexing the entries, + * THEN build the string by which we are indexing + * and insert the index into the output. + */ + if (pzIndexText != NULL) { + sprintf(def_str, " %s'", name_bf); + pzOut = assignIndex(pzOut, def_bf); + } + + /* + * Now insert the name with a consistent name string prefix + * that we use to locate the sort key later. + */ + pzOut += sprintf(pzOut, "%s%s';\n", zNameTag, name_bf); + *ppzOut = pzOut; + *ppzDef = pzDef; + *pzDef = '\n'; /* restore the newline. Used in pattern match */ + + /* + * Returning "PROBLEM" means the caller must emit the "#endif\n" + * at the end of the definition. + */ + return (pzIfText != NULL) ? PROBLEM : SUCCESS; +} + + +/* + * compar_defname + */ +static int +compar_defname(const void * p1, const void * p2) +{ + char const * pzS1 = *(char const * const *)p1; + char const * pz1 = strstr(pzS1, zNameTag); + char const * pzS2 = *(char const * const *)p2; + char const * pz2 = strstr(pzS2, zNameTag); + + if (pz1 == NULL) { + if (strncmp(*(char const * const *)p1, zGlobal, sizeof(zGlobal)-1) == 0) + return -1; + + die(GETDEFS_EXIT_USAGE_ERROR, zBogusDef, *(char const * const *)p1); + } + + if (pz2 == NULL) { + if (strncmp(*(char const * const *)p2, zGlobal, sizeof(zGlobal)-1) == 0) + return 1; + + die(GETDEFS_EXIT_USAGE_ERROR, zBogusDef, *(char const * const *)p2); + } + + /* + * Back up to the name of the definition + */ + while ((pz1 > pzS1) && (*--pz1 != '\n')) ; + while ((pz2 > pzS2) && (*--pz2 != '\n')) ; + + return strcmp(pz1, pz2); +} + + +/* + * compar_text + * + * merely returns the relative ordering of two input strings. + * The arguments are pointers to pointers to NUL-terminated strings. + * IF the definiton was mal-formed, an error message was printed + * earlier. When we get here, we wil fail to find the "zNameTag" + * string and EXIT_FAILURE. + */ +static int +compar_text(const void * p1, const void * p2) +{ + char * pz1 = strstr(*(char const * const *)p1, zNameTag); + char * pe1; + char * pz2 = strstr(*(char const * const *)p2, zNameTag); + char * pe2; + int res; + + if (pz1 == NULL) { + if (strncmp(*(char const * const *)p1, zGlobal, sizeof(zGlobal)-1) == 0) + return -1; + + die(GETDEFS_EXIT_USAGE_ERROR, zBogusDef, *(char const * const *)p1); + } + + if (pz2 == NULL) { + if (strncmp(*(char const * const *)p2, zGlobal, sizeof(zGlobal)-1) == 0) + return 1; + + die(GETDEFS_EXIT_USAGE_ERROR, zBogusDef, *(char const * const *)p2); + } + + pz1 += sizeof(zNameTag)-1; + pe1 = strchr(pz1, '\''); + + if (pe1 == NULL) + die(GETDEFS_EXIT_USAGE_ERROR, zBogusDef, *(char const * const *)p1); + + pz2 += sizeof(zNameTag)-1; + pe2 = strchr(pz2, '\''); + + if (pe2 == NULL) + die(GETDEFS_EXIT_USAGE_ERROR, zBogusDef, *(char const * const *)p2); + + *pe1 = *pe2 = NUL; + + /* + * We know ordering is enabled because we only get called when + * it is enabled. If the option was also specified, then + * we sort without case sensitivity (and we compare '-', '_' + * and '^' as being equal as well). Otherwise, we do a + * strict string comparison. + */ + if (HAVE_OPT(ORDERING)) + res = streqvcmp(pz1, pz2); + else res = strcmp(pz1, pz2); + *pe1 = *pe2 = '\''; + return res; +} + + +/* + * doPreamble + */ +static void +doPreamble(FILE * outFp) +{ + /* + * Emit the "autogen definitions xxx;" line + */ + fprintf(outFp, zAgDef, OPT_ARG(TEMPLATE)); + + if (HAVE_OPT(FILELIST)) { + static char const zFmt[] = "%-12s = '%s';\n"; + char const * pzName = OPT_ARG(FILELIST); + + if ((pzName == NULL) || (*pzName == NUL)) + pzName = "infile"; + + if (HAVE_OPT(INPUT)) { + int ct = STACKCT_OPT(INPUT); + char const ** ppz = STACKLST_OPT(INPUT); + + do { + fprintf(outFp, zFmt, pzName, *ppz++); + } while (--ct > 0); + } + + if (HAVE_OPT(COPY)) { + int ct = STACKCT_OPT(COPY); + char const ** ppz = STACKLST_OPT(COPY); + + do { + fprintf(outFp, zFmt, pzName, *ppz++); + } while (--ct > 0); + } + fputc('\n', outFp); + } + + /* + * IF there are COPY files to be included, + * THEN emit the '#include' directives + */ + if (HAVE_OPT(COPY)) { + int ct = STACKCT_OPT(COPY); + char const ** ppz = STACKLST_OPT(COPY); + do { + fprintf(outFp, "#include %s\n", *ppz++); + } while (--ct > 0); + fputc('\n', outFp); + } + + /* + * IF there are global assignments, then emit them + * (these do not get sorted, so we write directly now.) + */ + if (HAVE_OPT(ASSIGN)) { + int ct = STACKCT_OPT(ASSIGN); + char const ** ppz = STACKLST_OPT(ASSIGN); + do { + fprintf(outFp, "%s;\n", *ppz++); + } while (--ct > 0); + fputc('\n', outFp); + } +} + + +/* + * loadFile + */ +static char * +loadFile(char const * pzFname) +{ + FILE * fp = fopen(pzFname, "r" FOPEN_BINARY_FLAG); + int res; + char * pzText; + char * pzRead; + size_t rdsz; + + if (fp == (FILE *)NULL) + return NULL; + /* + * Find out how much data we need to read. + * And make sure we are reading a regular file. + */ + { + struct stat stb; + res = fstat(fileno(fp), &stb); + if (res != 0) + fserr(GETDEFS_EXIT_INVALID_INPUT, "fstat", pzFname); + + if (! S_ISREG(stb.st_mode)) { + errno = EINVAL; + fserr(GETDEFS_EXIT_INVALID_INPUT, "fstat", pzFname); + } + + rdsz = (size_t)stb.st_size; + if (rdsz < 16) + die(GETDEFS_EXIT_USAGE_ERROR, + "Error file %s only contains %d bytes.\n" + "\tit cannot contain autogen definitions\n", + pzFname, (int)rdsz); + } + + /* + * Allocate the space we need for the ENTIRE file. + */ + pzRead = pzText = (char *)malloc(rdsz + 1); + if (pzText == NULL) + die(GETDEFS_EXIT_USAGE_ERROR, "Error: could not allocate %d bytes\n", + (int)rdsz + 1); + + /* + * Read as much as we can get until we have read the file. + */ + do { + size_t rdct = fread(VOIDP(pzRead), (size_t)1, rdsz, fp); + + if (rdct == 0) + fserr(GETDEFS_EXIT_INVALID_INPUT, "fread", pzFname); + + pzRead += rdct; + rdsz -= rdct; + } while (rdsz > 0); + + *pzRead = NUL; + fclose(fp); + return pzText; +} + + +/* + * printEntries + */ +static void +printEntries(FILE * fp) +{ + size_t ct = blkUseCt; + char ** ppz = papzBlocks; + + if (ct == 0) + exit(EXIT_FAILURE); + + for (;;) { + char * pz = *(ppz++); + fputs(pz, fp); + free(VOIDP(pz)); + if (--ct == 0) + break; + fputc('\n', fp); + } + free(VOIDP(papzBlocks)); +} + + +/* + * processFile + */ +static void +processFile(char const * fname) +{ + char * pzText = loadFile(fname); /* full text */ + char * pzScan; /* Scanning Pointer */ + char * pzDef; /* Def block start */ + char * pzNext; /* start next search */ + char * pzDta; /* data value */ + int lineNo = 1; + char * pzOut; + regmatch_t matches[MAX_SUBMATCH+1]; + + if (pzText == NULL) { + errno = ENOMEM; + fserr(GETDEFS_EXIT_INVALID_INPUT, "open+read", fname); + } + + processEmbeddedOptions(pzText); + pzNext = pzText; + + while (pzScan = pzNext, + regexec(&define_re, pzScan, COUNT(matches), matches, 0) == 0) { + + static char const zNoEnd[] = + "Error: definition in %s at line %d has no end\n"; + static char const zNoSubexp[] = + "Warning: entry type not found on line %d in %s:\n\t%s\n"; + + int linesInDef = 0; + + /* + * Make sure there is a subexpression match!! + */ + if (matches[1].rm_so == -1) { + char * pz = NULL; + char ch = NUL; + + pzDef = pzScan + matches[0].rm_so; + if (strlen(pzDef) > 30) { + pz = pzDef + 30; + ch = *pz; + *pz = NUL; + } + + fprintf(stderr, zNoSubexp, lineNo, fname, pzDef); + if (pz != NULL) + *pz = ch; + continue; + } + + pzDef = pzScan + matches[0].rm_so + sizeof("/*=") - 1; + pzNext = strstr(pzDef, "=*/"); + if (pzNext == NULL) + die(GETDEFS_EXIT_USAGE_ERROR, zNoEnd, fname, lineNo); + + *pzNext = NUL; + pzNext += 3; + /* + * Count the number of lines skipped to the start of the def. + */ + for (;;) { + pzScan = strchr(pzScan, '\n'); + if (pzScan++ == NULL) + break; + if (pzScan >= pzDef) + break; + lineNo++; + } + + pzOut = pzDta = (char *)malloc(2 * strlen(pzDef) + 8000); + + /* + * Count the number of lines in the definition itself. + * It will find and stop on the "=* /\n" line. + */ + pzScan = pzDef; + for (;;) { + pzScan = strchr(pzScan, '\n'); + if (pzScan++ == NULL) + break; + linesInDef++; + } + + /* + * OK. We are done figuring out where the boundaries of the + * definition are and where we will resume our processing. + */ + buildDefinition(pzDef, fname, lineNo, pzOut); + pzDta = (char *)realloc(VOIDP(pzDta), strlen(pzDta) + 1); + lineNo += linesInDef; + + if (++blkUseCt > blkAllocCt) { + blkAllocCt += 32; + papzBlocks = (char **)realloc(VOIDP(papzBlocks), + blkAllocCt * sizeof(char *)); + if (papzBlocks == (char **)NULL) + die(GETDEFS_EXIT_USAGE_ERROR, "Realloc error for %d pointers\n", + (int)blkAllocCt); + } + papzBlocks[ blkUseCt-1 ] = pzDta; + } + + free(VOIDP(pzText)); +} + + +/* + * set_first_idx + * + * Go through all our different kinds of defines. On the first occurrence + * of each different name, check for an index value. If not supplied, + * then insert ''[OPT_VALUE_FIRST_INDEX]'' after the object name. + */ +static void +set_first_idx(void) +{ + char zNm[ 128 ] = { NUL }; + size_t nmLn = 1; + int ct = (int)blkUseCt; + char ** ppz = papzBlocks; + + if (ct == 0) + exit(EXIT_FAILURE); + + for (; --ct >= 0; ppz++) { + char * pzOld = *ppz; + int changed = (strneqvcmp(pzOld, zNm, (int)nmLn) != 0); + char * pzNew; + + /* + * IF the name still matches, then check the following character. + * If it is whitespace or an open bracket, then + * it's the old type. Continue to the next entry. + */ + if (! changed) { + if (isspace(pzOld[ nmLn ]) || (pzOld[nmLn] == '[')) + continue; + } + + pzNew = zNm; + nmLn = 0; + while (isalnum(*pzOld) + || (*pzOld == '_') || (*pzOld == '-') || (*pzOld == '^')) { + nmLn++; + *(pzNew++) = *(pzOld++); + } + *pzNew = NUL; + + /* + * IF the source has specified its own index, then do not + * supply our own new one. + */ + if (*pzOld != '[') { + pzNew = (char *)malloc(strlen(pzOld) + nmLn + 10); + sprintf(pzNew, "%s[%d]%s", zNm, + (int)OPT_VALUE_FIRST_INDEX, pzOld); + free(VOIDP(*ppz)); + *ppz = pzNew; + } + } +} + +static FILE * +open_ag_file(char ** pzBase) +{ + switch (WHICH_IDX_AUTOGEN) { + case INDEX_OPT_OUTPUT: + { + static char const zFileFmt[] = " * %s\n"; + FILE * fp; + + if (*pzBase != NULL) + free(*pzBase); + + if (strcmp(OPT_ARG(OUTPUT), "-") == 0) + return stdout; + + unlink(OPT_ARG(OUTPUT)); + fp = fopen(OPT_ARG(OUTPUT), "w" FOPEN_BINARY_FLAG); + fprintf(fp, zDne, OPT_ARG(OUTPUT)); + + if (HAVE_OPT(INPUT)) { + int ct = STACKCT_OPT(INPUT); + char const ** ppz = STACKLST_OPT(INPUT); + do { + fprintf(fp, zFileFmt, *ppz++); + } while (--ct > 0); + } + + fputs(" */\n", fp); + return fp; + } + + case INDEX_OPT_AUTOGEN: + if (! ENABLED_OPT(AUTOGEN)) { + if (*pzBase != NULL) + free(*pzBase); + + return stdout; + } + + if ( ( OPT_ARG(AUTOGEN) != NULL) + && (*OPT_ARG(AUTOGEN) != NUL )) + pzAutogen = OPT_ARG(AUTOGEN); + + break; + } + + return NULL; +} + +static FILE * +open_ag_proc_pipe(char ** pzBase) +{ + FILE * agFp; + + int pfd[2]; + + if (pipe(pfd) != 0) + fserr(GETDEFS_EXIT_FAILURE, "pipe", "(2)"); + + agPid = fork(); + + switch (agPid) { + case 0: + /* + * We are the child. Close the write end of the pipe + * and force STDIN to become the read end. + */ + close(pfd[1]); + if (dup2(pfd[0], STDIN_FILENO) != 0) + fserr(GETDEFS_EXIT_FAILURE, "dup2", "STDIN_FILENO"); + break; + + case -1: + fserr(GETDEFS_EXIT_FAILURE, "fork", "(2)"); + /* FALLTHROUGH */ /* NOTREACHED */ + + default: + /* + * We are the parent. Close the read end of the pipe + * and get a FILE * pointer for the write file descriptor + */ + close(pfd[0]); + agFp = fdopen(pfd[1], "w" FOPEN_BINARY_FLAG); + if (agFp == (FILE *)NULL) + fserr(GETDEFS_EXIT_FAILURE, "fdopen", "pipe"); + free(*pzBase); + return agFp; + } + + return NULL; +} + +static void +exec_autogen(char ** pzBase) +{ + char const ** paparg; + char const ** pparg; + int argCt = 5; + + /* + * IF we don't have template search directories, + * THEN allocate the default arg counter of pointers and + * set the program name into it. + * ELSE insert each one into the arg list. + */ + if (! HAVE_OPT(AGARG)) { + paparg = pparg = malloc((size_t)argCt * sizeof(char *)); + *pparg++ = pzAutogen; + + } else { + int ct = STACKCT_OPT(AGARG); + char const ** ppz = STACKLST_OPT(AGARG); + + argCt += ct; + paparg = pparg = malloc((size_t)argCt * sizeof(char *)); + *pparg++ = pzAutogen; + + do { + *pparg++ = *ppz++; + } while (--ct > 0); + } + + *pparg++ = *pzBase; + *pparg++ = "--"; + *pparg++ = "-"; + *pparg++ = NULL; + +#ifdef DEBUG + fputc('\n', stderr); + pparg = paparg; + for (;;) { + fputs(*pparg++, stderr); + if (*pparg == NULL) + break; + fputc(' ', stderr); + } + fputc('\n', stderr); + fputc('\n', stderr); +#endif + + execvp(pzAutogen, (char **)VOIDP(paparg)); + die(GETDEFS_EXIT_FAILURE, "exec of %s %s %s %s\n", + paparg[0], paparg[1], paparg[2], paparg[3]); +} + +/* + * startAutogen + */ +static FILE * +startAutogen(void) +{ + char * pz; + FILE * agFp; + char * pzBase = NULL; + + /* + * Compute the base name. + * + * If an argument was specified, use that without question. + * IF a definition pattern is supplied, and it looks like + * a normal name, then use that. + * If neither of these work, then use the current directory name. + */ + if (HAVE_OPT(BASE_NAME)) { + pzBase = malloc(strlen(OPT_ARG(BASE_NAME)) + 3); + strcpy(pzBase, "-b"); + strcpy(pzBase+2, OPT_ARG(BASE_NAME)); + } + else { + /* + * IF we have a definition name pattern, + * THEN copy the leading part that consists of name-like characters. + */ + if (HAVE_OPT(DEFS_TO_GET)) { + char const * pzS = OPT_ARG(DEFS_TO_GET); + pzBase = malloc(strlen(pzS) + 3); + strcpy(pzBase, "-b"); + + pz = pzBase + 2; + while (isalnum(*pzS) || (*pzS == '_')) + *pz++ = *pzS++; + if (pz == pzBase + 2) { + free(pzBase); + pzBase = NULL; + } + else + *pz = NUL; + } + + /* + * IF no pattern or it does not look like a name, ... + */ + if (pzBase == NULL) { + char zSrch[ MAXPATHLEN ]; + if (getcwd(zSrch, sizeof(zSrch)) == NULL) + fserr(GETDEFS_EXIT_FAILURE, "getcwd", "."); + + pz = strrchr(zSrch, '/'); + if (pz == NULL) + pz = zSrch; + else pz++; + pzBase = malloc(strlen(pz) + 3); + strcpy(pzBase, "-b"); + strcpy(pzBase+2, pz); + } + } + + /* + * For our template name, we take the argument (if supplied). + * If not, then whatever we decided our base name was will also + * be our template name. + */ + if (! HAVE_OPT(TEMPLATE)) + SET_OPT_TEMPLATE(strdup(pzBase+2)); + + /* + * Now, what kind of output have we? + * If it is a file, open it up and return. + * If it is an alternate autogen program, + * then set it to whatever the argument said it was. + * If the option was not supplied, we default to + * whatever we set the "pzAutogen" pointer to above. + */ + if (HAVE_OPT(AUTOGEN)) { + agFp = open_ag_file(&pzBase); + if (agFp != NULL) + return agFp; + } + + agFp = open_ag_proc_pipe(&pzBase); + if (agFp != NULL) + return agFp; + + exec_autogen(&pzBase); + return (FILE *)NULL; +} + + +/* + * update_db + */ +static void +update_db(void) +{ + FILE * fp; + + if (chmod(OPT_ARG(ORDERING), 0666) == 0) { + fp = fopen(OPT_ARG(ORDERING), "a" FOPEN_BINARY_FLAG); + + } else { + unlink(OPT_ARG(ORDERING)); + fp = fopen(OPT_ARG(ORDERING), "w" FOPEN_BINARY_FLAG); + pzIndexEOF = pzIndexText; + } + + if (fp == (FILE *)NULL) + fserr(GETDEFS_EXIT_FAILURE, "fopen-w+", OPT_ARG(ORDERING)); + + fwrite(pzIndexEOF, (size_t)(pzEndIndex - pzIndexEOF), (size_t)1, fp); +#ifdef HAVE_FCHMOD + fchmod(fileno(fp), 0444); + fclose(fp); +#else + fclose(fp); + chmod(OPT_ARG(ORDERING), 0444); +#endif +} + +/** @} + * + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of getdefs/getdefs.c */ diff --git a/getdefs/getdefs.h b/getdefs/getdefs.h new file mode 100644 index 0000000..2c184ff --- /dev/null +++ b/getdefs/getdefs.h @@ -0,0 +1,125 @@ + +/** + * @file getdefs.h + * @group columns + * @{ + */ +/* -*- Mode: C -*- + * + * getdefs Copyright (C) 1999-2018 by Bruce Korb - all rights reserved + * + * Author: Bruce Korb + * + * This file is part of AutoGen. + * AutoGen Copyright (C) 1992-2017 by Bruce Korb - all rights reserved + * + * AutoGen 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. + * + * AutoGen is distributed in the hope that 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 . + */ + +#ifndef GETDEFS_HEADER +#define GETDEFS_HEADER + +#include +#include +#include + +#include REGEX_HEADER +#include "ag-char-map.h" +#include "opts.h" + +#define EXPORT +#define MAXNAMELEN 256 +#define MAX_SUBMATCH 1 +#define COUNT(a) (sizeof(a)/sizeof(a[0])) +#define MARK_CHAR ':' + +#define AG_NAME_CHAR(c) (zUserNameCh[(unsigned char)(c)] & 2) +#define USER_NAME_CH(c) (zUserNameCh[(unsigned char)(c)] & 1) +char zUserNameCh[ 256 ] = { '\0' }; + +/* + * Index database string pointers. + */ +char * pzIndexText = NULL; /* all the text */ +char * pzEndIndex = NULL; /* end of current */ +char * pzIndexEOF = NULL; /* end of file */ +size_t indexAlloc = 0; /* allocation size */ + +/* + * Name of program to process output (normally ``autogen'') + */ +char const * pzAutogen = "autogen"; + +/* + * const global strings + */ +#define DEF_STRING(n,s) char const n[] = s +DEF_STRING( zGlobal, "\n/* GLOBALDEFS */\n" ); +DEF_STRING( zLineId, "\n#line %d \"%s\"\n" ); +DEF_STRING( zMallocErr, "Error: could not allocate %d bytes for %s\n" ); +DEF_STRING( zAttribRe, "\n[^*\n]*\\*[ \t]*([a-z][a-z0-9_-]*):"); +DEF_STRING( zNameTag, " = {\n name = '" ); +DEF_STRING( zMemberLine, " member = " ); +DEF_STRING( zNoData, "error no data for definition in file %s line %d\n" ); +DEF_STRING( zAgDef, "autogen definitions %s;\n"); +DEF_STRING( zDne, + "/* -*- buffer-read-only: t -*- vi: set ro:\n *\n" + " *\n * DO NOT EDIT THIS FILE (%s)\n *\n" + " * It has been extracted by getdefs from the following files:\n" + " *\n" ); + +/* + * ptr to zero (NUL) terminated definition pattern string. + * + * The pattern we look for starts with the three characters + * '/', '*' and '=' and is followed by two names: + * the name of a group and the name of the entry within the group. + * + * The patterns we accept for output may specify a particular group, + * certain members within certain groups or all members of all groups + */ +regex_t define_re; +regex_t attrib_re; + +/* + * The output file pointer. It may be "stdout". + * It gets closed when we are done. + */ +FILE * evtFp = (FILE *)NULL; + +/* + * The output file modification time. Only used if we + * have specified a real file for output (not stdout). + */ +time_t modtime = 0; + +/* + * The array of pointers to the output blocks. + * We build them first, then sort them, then print them out. + */ +char ** papzBlocks = (char **)NULL; +size_t blkUseCt = 0; +size_t blkAllocCt = 0; +pid_t agPid = -1; + +#endif /* GETDEFS_HEADER */ + +/** @} + * + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of getdefs/getdefs.h */ diff --git a/getdefs/opts.def b/getdefs/opts.def new file mode 100644 index 0000000..045e888 --- /dev/null +++ b/getdefs/opts.def @@ -0,0 +1,479 @@ +/* -*- Mode: conf -*- */ + +AutoGen definitions options; +addtogroup = getdefs; + +/* opts.def: option definitons for getdefs + * + * This file is part of AutoGen. + * AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoGen 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. + * + * AutoGen is distributed in the hope that 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 . + */ + +copyright = { + date = "1999-2018"; + type = gpl; + owner = "Bruce Korb"; + eaddr = 'autogen-users@lists.sourceforge.net'; +}; + +prog-name = "getdefs"; +prog-title = "AutoGen Definition Extraction Tool"; +package = 'GNU AutoGen'; +version = "1.5"; version-type = copyright; +homerc = /dev/null; +no-xlate = anything; +die-code; + +explain = <<- EndExplanation + If no @code{input} argument is provided or is set to simply "-", and if + @code{stdin} is not a @code{tty}, then the list of input files will be + read from @code{stdin}. + EndExplanation; +guard-option-names; + +flag = { + name = def-selection; + documentation; + descrip = 'Specify which definitions are of interest and ' + 'what to say about them'; +}; + +flag = { + name = "defs_to_get"; + arg-type = string; + arg-name = reg-ex; + descrip = 'Regexp to look for after the "/*="'; + doc = <<- _EOF_ + If you want definitions only from a particular category, or even + with names matching particular patterns, then specify this regular + expression for the text that must follow the @code{/*=}. + _EOF_; // */ +}; + +flag = { + name = subblock; + arg-type = string; + arg-name = sub-def; + max = NOLIMIT; + stack_arg; + descrip = "subblock definition names"; + doc = <<- _EOF_ + This option is used to create shorthand entries for nested definitions. + For example, with: + @table @r + @item using subblock thus + @code{--subblock=arg=argname,type,null} + @item and defining an @code{arg} thus + @code{arg: this, char *} + @item will then expand to: + @code{arg = @{ argname = this; type = "char *"; @};} + @end table + The "this, char *" string is separated at the commas, with the + white space removed. You may use characters other than commas by + starting the value string with a punctuation character other than + a single or double quote character. You may also omit intermediate + values by placing the commas next to each other with no intervening + white space. For example, "+mumble++yes+" will expand to: + @* + @code{arg = @{ argname = mumble; null = "yes"; @};}. + _EOF_; +}; + +flag = { + name = listattr; + arg-type = string; + arg-name = def; + max = NOLIMIT; + stack_arg; + descrip = "attribute with list of values"; + doc = <<- _EOF_ + This option is used to create shorthand entries for definitions + that generally appear several times. That is, they tend to be + a list of values. For example, with: + @* + @code{listattr=foo} defined, the text: + @* + @code{foo: this, is, a, multi-list} will then expand to: + @* + @code{foo = 'this', 'is', 'a', 'multi-list';} + @* + The texts are separated by the commas, with the + white space removed. You may use characters other than commas by + starting the value string with a punctuation character other than + a single or double quote character. + _EOF_; +}; + +flag = { + name = enumerating; + documentation; + descrip = 'specify how to number the definitions'; +}; + +flag = { + name = ordering; + arg-type = string; + arg-optional; + arg-name = file-name; + disable = no; + enabled; + descrip = "Alphabetize or use named file"; + doc = <<- _EOF_ + By default, ordering is alphabetical by the entry name. Use, + @code{no-ordering} if order is unimportant. Use @code{ordering} + with no argument to order without case sensitivity. Use + @code{ordering=} if chronological order is important. + getdefs will maintain the text content of @code{file-name}. + @code{file-name} need not exist. + _EOF_; +}; + +flag = { + name = first_index; + arg_type = number; + arg-default = 0; + arg-name = first-index; + descrip = "The first index to apply to groups"; + doc = <<- _EOF_ + By default, the first occurrence of a named definition will have an + index of zero. Sometimes, that needs to be a reserved value. Provide + this option to specify a different starting point. + _EOF_; +}; + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * Definition Insertion Options: + */ +flag = { + name = doc_insert; + descrip = "Definition insertion options"; + documentation; +}; + +flag = { + name = filelist; + arg-type = string; + arg-optional; + arg-name = file; + descrip = "Insert source file names into defs"; + doc = <<- _EOF_ + Inserts the name of each input file into the output definitions. + If no argument is supplied, the format will be: + @example + infile = '%s'; + @end example + If an argument is supplied, that string will be used for the entry + name instead of @var{infile}. + _EOF_; +}; + +flag = { + name = assign; + arg-type = string; + arg-name = ag-def; + max = NOLIMIT; + stack_arg; + descrip = "Global assignments"; + doc = <<- _EOF_ + The argument to each copy of this option will be inserted into + the output definitions, with only a semicolon attached. + _EOF_; + +}; + +flag = { + name = common_assign; + arg-type = string; + arg-name = ag-def; + max = NOLIMIT; + stack_arg; + descrip = "Assignments common to all blocks"; + doc = <<- _EOF_ + The argument to each copy of this option will be inserted into + each output definition, with only a semicolon attached. + _EOF_; + +}; + +flag = { + name = copy; + arg-type = string; + arg-name = file; + max = NOLIMIT; + stack_arg; + descrip = "File(s) to copy into definitions"; + doc = <<- _EOF_ + The content of each file named by these options will be inserted into + the output definitions. + _EOF_; + +}; + +flag = { + name = srcfile; + arg-type = string; + arg-optional; + arg-name = file; + descrip = "Insert source file name into each def"; + doc = <<- _EOF_ + Inserts the name of the input file where a definition was found + into the output definition. + If no argument is supplied, the format will be: + @example + srcfile = '%s'; + @end example + If an argument is supplied, that string will be used for the entry + name instead of @var{srcfile}. + _EOF_; + +}; + +flag = { + name = linenum; + arg-type = string; + arg-optional; + arg-name = def-name; + descrip = "Insert source line number into each def"; + doc = <<- _EOF_ + Inserts the line number in the input file where a definition + was found into the output definition. + If no argument is supplied, the format will be: + @example + linenum = '%s'; + @end example + If an argument is supplied, that string will be used for the entry + name instead of @var{linenum}. + _EOF_; + +}; + +flag = { + name = input-files; + documentation; + descrip = 'specify which files to search for markers'; +}; + +flag = { + name = input; + arg-type = string; + arg-name = src-file; + max = NOLIMIT; + settable; + stack_arg; + default; + descrip = "Input file to search for defs"; + + doc = <<- _EOF_ + All files that are to be searched for definitions must be named on + the command line or read from @code{stdin}. If there is only one + @code{input} option and it is the string, "-", then the input file + list is read from @code{stdin}. If a command line argument is not + an option name and does not contain an assignment operator + (@code{=}), then it defaults to being an input file name. + At least one input file must be specified. + _EOF_; +}; + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * Definition Output Disposition Options: + */ +flag = { + name = doc_output; + descrip = "Definition output disposition options:"; + documentation; +}; + +flag = { + name = output; + equivalence = "autogen"; + arg-type = string; + arg-name = file; + descrip = "Output file to open"; + doc = <<- _EOF_ + If you are not sending the output to an AutoGen process, + you may name an output file instead. + _EOF_; + +}; + +flag = { + name = "autogen"; + equivalence = "autogen"; + arg-type = string; + arg-optional; + arg-name = ag-cmd; + disable = "no"; + enabled; + descrip = "Invoke AutoGen with defs"; + doc = <<- _EOF_ + This is the default output mode. Specifying @code{no-autogen} is + equivalent to @code{output=-}. If you supply an argument to this + option, that program will be started as if it were AutoGen and + its standard in will be set to the output definitions of this program. + _EOF_; + +}; + +flag = { + name = template; + arg-type = string; + arg-name = file; + settable; + descrip = "Template Name"; + doc = + "Specifies the template name to be used for generating the final output."; +}; + +flag = { + name = agarg; + arg-type = string; + arg-name = ag-opt; + max = NOLIMIT; + stack_arg; + descrip = "AutoGen Argument"; + flags_cant = output; + doc = <<- _EOF_ + This is a pass-through argument. It allows you to specify any + arbitrary argument to be passed to AutoGen. + _EOF_; + +}; + +flag = { + name = base_name; + arg-type = string; + arg-name = name; + descrip = "Base name for output file(s)"; + flags_cant = output; + doc = <<- _EOF_ + When output is going to AutoGen, a base name must either be supplied + or derived. If this option is not supplied, then it is taken from + the @code{template} option. If that is not provided either, then + it is set to the base name of the current directory. + _EOF_; + +}; + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * Program Documentation + */ + +exit-name[2] = invalid-input; +exit-desc[2] = 'An input file was specified that is not a file'; + +exit-name[3] = no-mem; +exit-desc[3] = 'Insufficient memory for operation'; + +/* * * * * MAN PAGE DESCRIPTION * * * * * * * * * * * * * * * * * * * */ + +doc-section = { + ds-type = "SEE ALSO"; + ds-format = texi; + ds-text = <<- _EndOfMan_ + This program is documented more fully in the Getdefs section + of the Add-On chapter in the @code{AutoGen} Info system documentation. + _EndOfMan_; +}; + +/* * * * * DOC DESCRIPTION * * * * * * * * * * * * * * * * * * * */ + +option-doc-format = texi; + +detail = <<- _EOF_ + This program extracts AutoGen definitions from a list of source files. + Definitions are delimited by @code{/*= \n} and + @code{=*/\n}. + _EOF_; + +prog-descrip = <<_EOF_ +This program extracts AutoGen definitions from a list of source files. +Definitions are delimited by @code{/*= \n} and +@code{=*/\n}. From that, this program creates a definition of the following +form: + +@example + #line nnn "source-file-name" + entry_type = @{ + name = entry_name; + ... + @}; +@end example + +@enumerate +@item +The ellipsis @code{...} is filled in by text found between the two +delimiters. Each line of text is stripped of anything before the first +asterisk, then leading asterisks, then any leading or trailing white space. + +@item +If what is left starts with what looks like a name followed by a colon, then +it is interpreted as a name followed by a value. + +@item +If the first character of the value is either a single or double quote, then +you are responsible for quoting the text as it gets inserted into the output +definitions. So, if you want whitespace at the beginnings of the lines of +text, you must do something like this: + +@example + * mumble: + * " this is some\n" + * " indented text." +@end example + +@item +If the @code{} is followed by a comma, the word @code{ifdef} (or +@code{ifndef}) and a name @code{if_name}, then the above entry will be under +@code{ifdef} control. + +@example +/*=group entry_name, ifdef FOO + * attr: attribute value +=*/ +@end example + +Will produce the following: + +@example +#ifdef FOO +#line nnn "source-file-name" +group = @{ + name = entry_name; + attr = 'attribute value'; +@}; +#endif +@end example + +@item +If you use of the @code{subblock} option, you can specify a nested +value, @xref{getdefs subblock}. That is, this text: + +@example + * arg: int, this, what-it-is +@end example + +with the @code{--subblock=arg=type,name,doc} option would yield: + +@example +arg = @{ type = int; name = this; doc = what-it-is; @}; +@end example +@end enumerate +_EOF_; + +/* end of opts.def */ diff --git a/getdefs/proto.h b/getdefs/proto.h new file mode 100644 index 0000000..1c8505b --- /dev/null +++ b/getdefs/proto.h @@ -0,0 +1,85 @@ +/* -*- buffer-read-only: t -*- vi: set ro: + * + * Prototypes for getdefs + * Generated Sun Aug 26 10:44:48 PDT 2018 + */ +#ifndef GETDEFS_PROTO_H_GUARD +#define GETDEFS_PROTO_H_GUARD 1 + + +/* + * Static declarations from gdemit.c + */ +static void +compress_def(char * pz); + +static char * +list_attrib(char * pzText, char * pzOut); + +static char * +emit_quote(char ** ppzText, char * pzOut); + +static void +next_def_entry(char ** txt_pp, char const ** def_pp); + +static void +emit_attribute(char const ** def_pp, char ** out_pp); + +static char * +emit_subblock(char const * pzDefList, char * pzText, char * pzOut); + +static char * +subblock_str(char ** ppzText, uint_t sepChar, char * pzOut); + +/* + * Static declarations from getdefs.c + */ +static char * +assignIndex(char * pzOut, char * pzDef); + +static int +awaitAutogen(void); + +static void +buildDefinition(char * pzDef, char const * pzFile, int line, char * pzOut); + +static tSuccess +buildPreamble(char ** ppzDef, char ** ppzOut, char const * fname, int line); + +static int +compar_defname(const void * p1, const void * p2); + +static int +compar_text(const void * p1, const void * p2); + +static void +doPreamble(FILE * outFp); + +static char * +loadFile(char const * pzFname); + +static void +printEntries(FILE * fp); + +static void +processFile(char const * fname); + +static void +set_first_idx(void); + +static FILE * +open_ag_file(char ** pzBase); + +static FILE * +open_ag_proc_pipe(char ** pzBase); + +static void +exec_autogen(char ** pzBase); + +static FILE * +startAutogen(void); + +static void +update_db(void); + +#endif /* GETDEFS_PROTO_H_GUARD */ diff --git a/getdefs/test/Makefile.am b/getdefs/test/Makefile.am new file mode 100644 index 0000000..cceea6d --- /dev/null +++ b/getdefs/test/Makefile.am @@ -0,0 +1,47 @@ +## -*- Mode: Makefile -*- +## +## Makefile.am -- process this file with automake to produce Makefile.in +## +## Author: Bruce Korb +## +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen 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. +## +## AutoGen is distributed in the hope that 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 . + +TESTS = cfg.test index.test option.test subblock.test +EXTRA_DIST = defs $(TESTS) + +TESTS_ENVIRONMENT = top_srcdir=$(top_srcdir) \ + srcdir=$(srcdir) top_builddir=$(top_builddir) \ + GDexe=$(GDexe) AGexe=$(AGexe) CLexe=$(CLexe) + +distclean-local: + -rm -rf *-testd FAILURES defs + +$(TESTS) : defs + +defs : ${top_builddir}/autoopts/test/defs + $(TESTS_ENVIRONMENT) $(SHELL) \ + $(top_srcdir)/config/install-defs.sh \ + $(top_builddir)/autoopts/test/defs + +${top_builddir}/autoopts/test/defs : + cd ${top_builddir}/autoopts/test ; $(MAKE) defs + +verbose : defs + rm -rf FAILURES *-testd ; \ + VERBOSE=true $(MAKE) check TESTS="$(TESTS)" + +# end of Makefile.am diff --git a/getdefs/test/Makefile.in b/getdefs/test/Makefile.in new file mode 100644 index 0000000..e9c1948 --- /dev/null +++ b/getdefs/test/Makefile.in @@ -0,0 +1,894 @@ +# Makefile.in generated by automake 1.16.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2018 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +subdir = getdefs/test +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/config/ag_macros.m4 \ + $(top_srcdir)/config/asm-underscore.m4 \ + $(top_srcdir)/config/extensions.m4 \ + $(top_srcdir)/config/guile.m4 \ + $(top_srcdir)/config/host-cpu-c-abi.m4 \ + $(top_srcdir)/config/lib-ld.m4 \ + $(top_srcdir)/config/lib-link.m4 \ + $(top_srcdir)/config/lib-prefix.m4 \ + $(top_srcdir)/config/libopts.m4 \ + $(top_srcdir)/config/libtool.m4 \ + $(top_srcdir)/config/ltoptions.m4 \ + $(top_srcdir)/config/ltsugar.m4 \ + $(top_srcdir)/config/ltversion.m4 \ + $(top_srcdir)/config/lt~obsolete.m4 \ + $(top_srcdir)/config/onceonly.m4 $(top_srcdir)/config/pkg.m4 \ + $(top_srcdir)/config/snprintfv.m4 \ + $(top_srcdir)/config/stdnoreturn.m4 \ + $(top_srcdir)/config/unlocked-io.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +am__tty_colors_dummy = \ + mgn= red= grn= lgn= blu= brg= std=; \ + am__color_tests=no +am__tty_colors = { \ + $(am__tty_colors_dummy); \ + if test "X$(AM_COLOR_TESTS)" = Xno; then \ + am__color_tests=no; \ + elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ + am__color_tests=yes; \ + elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ + am__color_tests=yes; \ + fi; \ + if test $$am__color_tests = yes; then \ + red=''; \ + grn=''; \ + lgn=''; \ + blu=''; \ + mgn=''; \ + brg=''; \ + std=''; \ + fi; \ +} +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__recheck_rx = ^[ ]*:recheck:[ ]* +am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* +am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* +# A command that, given a newline-separated list of test names on the +# standard input, print the name of the tests that are to be re-run +# upon "make recheck". +am__list_recheck_tests = $(AWK) '{ \ + recheck = 1; \ + while ((rc = (getline line < ($$0 ".trs"))) != 0) \ + { \ + if (rc < 0) \ + { \ + if ((getline line2 < ($$0 ".log")) < 0) \ + recheck = 0; \ + break; \ + } \ + else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \ + { \ + recheck = 0; \ + break; \ + } \ + else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \ + { \ + break; \ + } \ + }; \ + if (recheck) \ + print $$0; \ + close ($$0 ".trs"); \ + close ($$0 ".log"); \ +}' +# A command that, given a newline-separated list of test names on the +# standard input, create the global log from their .trs and .log files. +am__create_global_log = $(AWK) ' \ +function fatal(msg) \ +{ \ + print "fatal: making $@: " msg | "cat >&2"; \ + exit 1; \ +} \ +function rst_section(header) \ +{ \ + print header; \ + len = length(header); \ + for (i = 1; i <= len; i = i + 1) \ + printf "="; \ + printf "\n\n"; \ +} \ +{ \ + copy_in_global_log = 1; \ + global_test_result = "RUN"; \ + while ((rc = (getline line < ($$0 ".trs"))) != 0) \ + { \ + if (rc < 0) \ + fatal("failed to read from " $$0 ".trs"); \ + if (line ~ /$(am__global_test_result_rx)/) \ + { \ + sub("$(am__global_test_result_rx)", "", line); \ + sub("[ ]*$$", "", line); \ + global_test_result = line; \ + } \ + else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \ + copy_in_global_log = 0; \ + }; \ + if (copy_in_global_log) \ + { \ + rst_section(global_test_result ": " $$0); \ + while ((rc = (getline line < ($$0 ".log"))) != 0) \ + { \ + if (rc < 0) \ + fatal("failed to read from " $$0 ".log"); \ + print line; \ + }; \ + printf "\n"; \ + }; \ + close ($$0 ".trs"); \ + close ($$0 ".log"); \ +}' +# Restructured Text title. +am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; } +# Solaris 10 'make', and several other traditional 'make' implementations, +# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it +# by disabling -e (using the XSI extension "set +e") if it's set. +am__sh_e_setup = case $$- in *e*) set +e;; esac +# Default flags passed to test drivers. +am__common_driver_flags = \ + --color-tests "$$am__color_tests" \ + --enable-hard-errors "$$am__enable_hard_errors" \ + --expect-failure "$$am__expect_failure" +# To be inserted before the command running the test. Creates the +# directory for the log if needed. Stores in $dir the directory +# containing $f, in $tst the test, in $log the log. Executes the +# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and +# passes TESTS_ENVIRONMENT. Set up options for the wrapper that +# will run the test scripts (or their associated LOG_COMPILER, if +# thy have one). +am__check_pre = \ +$(am__sh_e_setup); \ +$(am__vpath_adj_setup) $(am__vpath_adj) \ +$(am__tty_colors); \ +srcdir=$(srcdir); export srcdir; \ +case "$@" in \ + */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \ + *) am__odir=.;; \ +esac; \ +test "x$$am__odir" = x"." || test -d "$$am__odir" \ + || $(MKDIR_P) "$$am__odir" || exit $$?; \ +if test -f "./$$f"; then dir=./; \ +elif test -f "$$f"; then dir=; \ +else dir="$(srcdir)/"; fi; \ +tst=$$dir$$f; log='$@'; \ +if test -n '$(DISABLE_HARD_ERRORS)'; then \ + am__enable_hard_errors=no; \ +else \ + am__enable_hard_errors=yes; \ +fi; \ +case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ + am__expect_failure=yes;; \ + *) \ + am__expect_failure=no;; \ +esac; \ +$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT) +# A shell command to get the names of the tests scripts with any registered +# extension removed (i.e., equivalently, the names of the test logs, with +# the '.log' extension removed). The result is saved in the shell variable +# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly, +# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)", +# since that might cause problem with VPATH rewrites for suffix-less tests. +# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'. +am__set_TESTS_bases = \ + bases='$(TEST_LOGS)'; \ + bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ + bases=`echo $$bases` +RECHECK_LOGS = $(TEST_LOGS) +AM_RECURSIVE_TARGETS = check recheck +TEST_SUITE_LOG = test-suite.log +TEST_EXTENSIONS = @EXEEXT@ .test +am__test_logs1 = $(TESTS:=.log) +am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) +TEST_LOGS = $(am__test_logs2:.test.log=.log) +TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/config/test-driver +TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ + $(TEST_LOG_FLAGS) +am__set_b = \ + case '$@' in \ + */*) \ + case '$*' in \ + */*) b='$*';; \ + *) b=`echo '$@' | sed 's/\.log$$//'`; \ + esac;; \ + *) \ + b='$*';; \ + esac +am__DIST_COMMON = $(srcdir)/Makefile.in \ + $(top_srcdir)/config/test-driver +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AGEN5_TESTS = @AGEN5_TESTS@ +AG_LDFLAGS = @AG_LDFLAGS@ +AG_MAJOR_VERSION = @AG_MAJOR_VERSION@ +AG_MINOR_VERSION = @AG_MINOR_VERSION@ +AG_STATIC_AUTOGEN = @AG_STATIC_AUTOGEN@ +AG_TIMEOUT = @AG_TIMEOUT@ +AG_VERSION = @AG_VERSION@ +AG_XML2 = @AG_XML2@ +AGexe = @AGexe@ +AGnam = @AGnam@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AO_AGE = @AO_AGE@ +AO_CURRENT = @AO_CURRENT@ +AO_REVISION = @AO_REVISION@ +AO_TEMPLATE_VERSION = @AO_TEMPLATE_VERSION@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CLexe = @CLexe@ +CLnam = @CLnam@ +CONFIG_SHELL = @CONFIG_SHELL@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEBUG_ENABLED = @DEBUG_ENABLED@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +DYNAMIC_AG = @DYNAMIC_AG@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ENABLE_STATIC = @ENABLE_STATIC@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GDexe = @GDexe@ +GDnam = @GDnam@ +GO_AGE = @GO_AGE@ +GO_CURRENT = @GO_CURRENT@ +GO_REVISION = @GO_REVISION@ +GREP = @GREP@ +GUILE_CFLAGS = @GUILE_CFLAGS@ +GUILE_EFFECTIVE_VERSION = @GUILE_EFFECTIVE_VERSION@ +GUILE_LDFLAGS = @GUILE_LDFLAGS@ +GUILE_LIBS = @GUILE_LIBS@ +GUILE_LTLIBS = @GUILE_LTLIBS@ +HOST_CPU = @HOST_CPU@ +HOST_CPU_C_ABI = @HOST_CPU_C_ABI@ +INCLIST = @INCLIST@ +INCSNPRINTFV = @INCSNPRINTFV@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSNPRINTFV = @LIBSNPRINTFV@ +LIBTOOL = @LIBTOOL@ +LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ +LIBXML2_LIBS = @LIBXML2_LIBS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +M4_SRC = @M4_SRC@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPTS_TESTDIR = @OPTS_TESTDIR@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POSIX_SHELL = @POSIX_SHELL@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STDNORETURN_H = @STDNORETURN_H@ +STRIP = @STRIP@ +TEXI2HTML = @TEXI2HTML@ +VERSION = @VERSION@ +WARN_CFLAGS = @WARN_CFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_aux_dir = @ac_aux_dir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +TESTS = cfg.test index.test option.test subblock.test +EXTRA_DIST = defs $(TESTS) +TESTS_ENVIRONMENT = top_srcdir=$(top_srcdir) \ + srcdir=$(srcdir) top_builddir=$(top_builddir) \ + GDexe=$(GDexe) AGexe=$(AGexe) CLexe=$(CLexe) + +all: all-am + +.SUFFIXES: +.SUFFIXES: .log .test .test$(EXEEXT) .trs +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu getdefs/test/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu getdefs/test/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +tags TAGS: + +ctags CTAGS: + +cscope cscopelist: + + +# Recover from deleted '.trs' file; this should ensure that +# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create +# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells +# to avoid problems with "make -n". +.log.trs: + rm -f $< $@ + $(MAKE) $(AM_MAKEFLAGS) $< + +# Leading 'am--fnord' is there to ensure the list of targets does not +# expand to empty, as could happen e.g. with make check TESTS=''. +am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) +am--force-recheck: + @: + +$(TEST_SUITE_LOG): $(TEST_LOGS) + @$(am__set_TESTS_bases); \ + am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ + redo_bases=`for i in $$bases; do \ + am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \ + done`; \ + if test -n "$$redo_bases"; then \ + redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \ + redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \ + if $(am__make_dryrun); then :; else \ + rm -f $$redo_logs && rm -f $$redo_results || exit 1; \ + fi; \ + fi; \ + if test -n "$$am__remaking_logs"; then \ + echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ + "recursion detected" >&2; \ + elif test -n "$$redo_logs"; then \ + am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ + fi; \ + if $(am__make_dryrun); then :; else \ + st=0; \ + errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \ + for i in $$redo_bases; do \ + test -f $$i.trs && test -r $$i.trs \ + || { echo "$$errmsg $$i.trs" >&2; st=1; }; \ + test -f $$i.log && test -r $$i.log \ + || { echo "$$errmsg $$i.log" >&2; st=1; }; \ + done; \ + test $$st -eq 0 || exit 1; \ + fi + @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \ + ws='[ ]'; \ + results=`for b in $$bases; do echo $$b.trs; done`; \ + test -n "$$results" || results=/dev/null; \ + all=` grep "^$$ws*:test-result:" $$results | wc -l`; \ + pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \ + fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \ + skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \ + xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \ + xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \ + error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \ + if test `expr $$fail + $$xpass + $$error` -eq 0; then \ + success=true; \ + else \ + success=false; \ + fi; \ + br='==================='; br=$$br$$br$$br$$br; \ + result_count () \ + { \ + if test x"$$1" = x"--maybe-color"; then \ + maybe_colorize=yes; \ + elif test x"$$1" = x"--no-color"; then \ + maybe_colorize=no; \ + else \ + echo "$@: invalid 'result_count' usage" >&2; exit 4; \ + fi; \ + shift; \ + desc=$$1 count=$$2; \ + if test $$maybe_colorize = yes && test $$count -gt 0; then \ + color_start=$$3 color_end=$$std; \ + else \ + color_start= color_end=; \ + fi; \ + echo "$${color_start}# $$desc $$count$${color_end}"; \ + }; \ + create_testsuite_report () \ + { \ + result_count $$1 "TOTAL:" $$all "$$brg"; \ + result_count $$1 "PASS: " $$pass "$$grn"; \ + result_count $$1 "SKIP: " $$skip "$$blu"; \ + result_count $$1 "XFAIL:" $$xfail "$$lgn"; \ + result_count $$1 "FAIL: " $$fail "$$red"; \ + result_count $$1 "XPASS:" $$xpass "$$red"; \ + result_count $$1 "ERROR:" $$error "$$mgn"; \ + }; \ + { \ + echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ + $(am__rst_title); \ + create_testsuite_report --no-color; \ + echo; \ + echo ".. contents:: :depth: 2"; \ + echo; \ + for b in $$bases; do echo $$b; done \ + | $(am__create_global_log); \ + } >$(TEST_SUITE_LOG).tmp || exit 1; \ + mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ + if $$success; then \ + col="$$grn"; \ + else \ + col="$$red"; \ + test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ + fi; \ + echo "$${col}$$br$${std}"; \ + echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}"; \ + echo "$${col}$$br$${std}"; \ + create_testsuite_report --maybe-color; \ + echo "$$col$$br$$std"; \ + if $$success; then :; else \ + echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \ + if test -n "$(PACKAGE_BUGREPORT)"; then \ + echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ + fi; \ + echo "$$col$$br$$std"; \ + fi; \ + $$success || exit 1 + +check-TESTS: + @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list + @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list + @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + @set +e; $(am__set_TESTS_bases); \ + log_list=`for i in $$bases; do echo $$i.log; done`; \ + trs_list=`for i in $$bases; do echo $$i.trs; done`; \ + log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ + $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ + exit $$?; +recheck: all + @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + @set +e; $(am__set_TESTS_bases); \ + bases=`for i in $$bases; do echo $$i; done \ + | $(am__list_recheck_tests)` || exit 1; \ + log_list=`for i in $$bases; do echo $$i.log; done`; \ + log_list=`echo $$log_list`; \ + $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \ + am__force_recheck=am--force-recheck \ + TEST_LOGS="$$log_list"; \ + exit $$? +.test.log: + @p='$<'; \ + $(am__set_b); \ + $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +@am__EXEEXT_TRUE@.test$(EXEEXT).log: +@am__EXEEXT_TRUE@ @p='$<'; \ +@am__EXEEXT_TRUE@ $(am__set_b); \ +@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ +@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ +@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ +@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) check-TESTS +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) + -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) + -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-local + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: check-am install-am install-strip + +.PHONY: all all-am check check-TESTS check-am clean clean-generic \ + clean-libtool cscopelist-am ctags-am distclean \ + distclean-generic distclean-libtool distclean-local distdir \ + dvi dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am recheck tags-am \ + uninstall uninstall-am + +.PRECIOUS: Makefile + + +distclean-local: + -rm -rf *-testd FAILURES defs + +$(TESTS) : defs + +defs : ${top_builddir}/autoopts/test/defs + $(TESTS_ENVIRONMENT) $(SHELL) \ + $(top_srcdir)/config/install-defs.sh \ + $(top_builddir)/autoopts/test/defs + +${top_builddir}/autoopts/test/defs : + cd ${top_builddir}/autoopts/test ; $(MAKE) defs + +verbose : defs + rm -rf FAILURES *-testd ; \ + VERBOSE=true $(MAKE) check TESTS="$(TESTS)" + +# end of Makefile.am + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/getdefs/test/cfg.test b/getdefs/test/cfg.test new file mode 100755 index 0000000..932bceb --- /dev/null +++ b/getdefs/test/cfg.test @@ -0,0 +1,108 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# cfg.test --- test config file processing +# +# Author: Bruce Korb +# +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen 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. +## +## AutoGen is distributed in the hope that 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 . + +. ./defs + +# Create the files we need in the test environment +cat > ${testname}.c <<- _EOSource_ + + /*=* global + * + * test: subblock + * doc: we want to see + * just what happens + =*/ + + /*=gfunc in_p + * + * exparg: test-string , string to look for + + arg-name + arg-desc + arg-opt + arg-list + + * exparg: @ string-list @ list of strings to check,, @@ list + * + * opt: 1 + * doc: + * Return SCM_BOOL_T if the first argument is duplicated + * in the second (list) argument. + =*/ + SCM + ag_scm_in_p( SCM obj, SCM list ) + { + } + _EOSource_ + +cat > ${testname}.cfg <<- _EOCfg_ + output ${testname}.out + common-assign stumble = grumble + assign mumble = stumble ; mumble = grumble + template test${testname} + subblock exparg=arg_name,arg_desc,arg_optional,arg_list + _EOCfg_ + +cat > ${testname}.test <<- _EOTestOut_ + /* -*- buffer-read-only: t -*- vi: set ro: + * + * + * DO NOT EDIT THIS FILE (cfg.out) + * + * It has been extracted by getdefs from the following files: + * + * cfg.c + */ + autogen definitions testcfg; + mumble = stumble ; mumble = grumble; + + + /* GLOBALDEFS */ + + #line 2 "cfg.c" + test = 'subblock'; + doc = 'we want to see + just what happens'; + + + #line 9 "cfg.c" + gfunc = { + name = 'in_p'; + exparg = { + arg_name = 'test-string'; + arg_desc = 'string to look for'; + }; + exparg = { + arg_name = 'string-list'; + arg_desc = 'list of strings to check,,'; + arg_list = 'list'; + }; + opt = '1'; + doc = + 'Return SCM_BOOL_T if the first argument is duplicated + in the second (list) argument.'; + stumble = grumble; + }; + _EOTestOut_ + +set -x +${GDexe} load=${testname}.cfg ${testname}.c || \ + failure running ${GDexe} +cmp -s ${testname}.test ${testname}.out || \ + failure "`diff ${testname}.test ${testname}.out`" + +# end of cfg.test diff --git a/getdefs/test/defs b/getdefs/test/defs new file mode 100644 index 0000000..5057fac --- /dev/null +++ b/getdefs/test/defs @@ -0,0 +1,392 @@ +#! /bin/echo this_file_should_be_sourced,_not_executed +# -*- Mode: Shell-script -*- +# +# defs --- define the environment for autogen tests. +# +# Author: Bruce Korb +# +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# +# C O N F I G U R E D V A L U E S +# +# Make sure srcdir is an absolute path. Supply the variable +# if it does not exist. We want to be able to run the tests +# stand-alone!! +# +cfg_vals() +{ + case `uname -s` in + SunOS ) + if test "X$BASH_VERSION" = X + then + # On Solaris, make certain we do not use /bin/sh + sh=`which bash` + test "X$sh" = X && sh=/usr/xpg4/bin/sh + BASH_VERSION=not-good-enough + export BASH_VERSION + exec $sh "$0" "$@" + fi + ;; + esac + + set -a + TESTS='' + builddir=`pwd` + progpid=$$ + : ${top_builddir=/u/bkorb/tools/ag/autogen-bld} + top_builddir=`cd ${top_builddir} >/dev/null ; pwd` + : ${top_srcdir=/u/bkorb/tools/ag/autogen-bld} + top_srcdir=`cd ${top_srcdir} >/dev/null ; pwd` + : ${srcdir=/u/bkorb/tools/ag/autogen-bld/getdefs/test} + srcdir=`cd $srcdir >/dev/null && pwd` + . ${top_builddir}/config/shdefs "${builddir}/` + echo $0|${SED:-sed} 's@.*/@@'`" + progname=`echo "$1" | ${SED} 's,^.*/,,'` + testname=`echo "$progname" | ${SED} 's,\..*$,,'` + testsubdir=${testname}-testd + tstdir=${builddir}/${testsubdir} + PS4=">${testname}-\${FUNCNAME}> " + test_name=`echo ${testname} | ${SED} 's/-/_/g'` + ( exec 2>/dev/null; ulimit -c unlimited ) && \ + ulimit -c unlimited + + CFLAGS="${CFLAGS} ${DEFS}" + : ${PAGER=more} + + stdopts=${top_srcdir}/autoopts/test/stdopts.def + test_main=yes + use_flags=true + sed_omit_license="/-\*- buffer-read-only:/,/^ \*\//d" + TERM='' + set +a + + ( + test_local() { + local local_works=yes + } + test_local + ) || eval 'local() { : ; }' + + vars=`set | ${SED} -n '/^\(LANG\|LC_[A-Z_]*\)=/s/=.*//p'` 2>/dev/null + unset AUTOOPTS_USAGE $vars CONTENT_LENGTH REQUEST_METHOD QUERY_STRING +} + +# If only the "rm(1)" command could be relied upon.... +# +purge() +{ + rm -rf ${*} 2>/dev/null + bad='' + for f + do test -f ${f} -o -d ${f} && bad="${bad} ${f}" + done + test -z "$bad" && return 0 + + # NFS "busy" files and MS-DOS fs sometimes fail. + # + set -- $bad + test "x${RANDOM}" = "x${RANDOM}" && RANDOM=`expr 0${RANDOM} + 1 2>/dev/null` + + f=zzPURGE-${1}-${RANDOM}-${progpid} + if test $# -gt 1 + then mkdir "${f}" + mv $* "${f}/." + else mv $1 "${f}" + fi +} + +init_tests() +{ + exec 8>&2 + BASH_XTRACEFD=8 + + TMPDIR="${tstdir}/${testname}-tmpd" + mkdir -p ${TMPDIR} + CFLAGS=`echo ${CFLAGS} | \ + ${SED} "s/-Werror[^ ${ht}]*//g;s/-Wextra//g"` + + lo_dir=${top_builddir}/autoopts + lo_lib=`find ${lo_dir} -type f -name "*libopts.${OBJEXT}" | head -n1` + test -f "$lo_lib" || { + lo_lib=`find ${lo_dir} -type f -name "*libopts.lo" | head -n1` + test -f "$lo_lib" || die "no libopts lib" + } + lo_dir=${lo_lib%/*} + test "X${LD_LIBRARY_PATH}" = X || \ + LD_LIBRARY_PATH=:${LD_LIBRARY_PATH} + LD_LIBRARY_PATH=${lo_dir}:${LIBGUILE_PATH}${LD_LIBRARY_PATH} + + case ${AG_VERSION} in + *pre* ) GUILE_WARN_DEPRECATED=detailed ;; + * ) GUILE_WARN_DEPRECATED=no ;; + esac + + case "$LIB" in + *-lgen* ) : ;; + * ) + for f in /usr/lib*/libgen.so /lib*/libgen.so + do + test -f $f && { + LIB="${LIB} -lgen" + break + } + done + ;; + esac + LIB="${lo_lib} ${LIB}" + + AG_L=run_ag\ ao + agl_opts="-L${top_builddir}/autoopts/tpl" + test "L${top_builddir}" = "L${top_srcdir}" || \ + agl_opts="$agl_opts -L${top_srcdir}/autoopts/tpl" + export TMPDIR PATH LD_LIBRARY_PATH \ + GUILE_WARN_DEPRECATED LIB AG_L agl_opts \ + CC LIBGUILE AG_VERSION +} + +be_silent() +{ + setx=: + msg=echo + VERBOSE=false + purge ${testsubdir} + + run_ag() + { + local opts= + opts='' + shift + + case " $* " in + *' -L'* ) : ;; + * ) opts="${agl_opts}" ;; + esac + + ${AGexe} ${opts} "$@" + } + + init_tests +} + +be_verbose() +{ + set -x + setx='set -x' + msg=: + VERBOSE=true + test -d ${testsubdir} || mkdir ${testsubdir} || exit 1 + + run_ag() + { + local opts= tfile=${testname}-aglog-${1}-${progpid}.log + ${verb_ok:-true} && { + case " $* " in + *' --trace'* ) : ;; + * ) + opts="--trace=every --trace-out=>>${tfile}" + ;; + esac + AUTOGEN_TRACE=every + AUTOGEN_TRACE_OUT=">>`pwd`/${tfile}" + export AUTOGEN_TRACE_OUT AUTOGEN_TRACE + } + shift + + case " $* " in + *' -L'* ) : ;; + * ) opts="${opts} ${agl_opts}" ;; + esac + + MALLOC_CHECK_=3 ${AGexe} ${opts} "$@" + } + + init_tests +} + +cfg_inc() +{ + test_src=$srcdir/${testname}.test + cd ${testsubdir} || { + echo "Cannot make or change into ${testsubdir}" + exit 1 + } + + dirs=` + for f in ${top_builddir} ${top_srcdir} + do + for d in . autoopts agen5 + do + cd $f/$d + pwd >&9 + cd - + done 9>&1 1>/dev/null + done | sort -u | ${SED} 's/^/-I/'` + + INC=`echo ${dirs} ${CPPFLAGS}` + + : "=== Running $progname for ${testname} using ${SHELL} ===" + chmod +w * > /dev/null 2>&1 || : + ${VERBOSE} && SHELLX="${SHELL} -x" || SHELLX="${SHELL}" +} + +# # # # +# +# "clean_help" -- remove variable parts so results can be compared +# +nl=' +' +ht=' ' +basic_help_clean="/^Packaged by/d +/^Report .* bugs to/d +/[Pp]lease send bug reports/d +/^exit [0-9]/d +/^[ ${ht}]*\$/d" +TR=`command -v tr` +test -x "$TR" || die "cannot run tests without 'tr' program" + +export nl ht basic_help_clean TR +readonly nl ht basic_help_clean TR + +clean_help() { + test -z "$sedcmd" && \ + s=${basic_help_clean} || \ + s="${sedcmd}${nl}${basic_help_clean}" + + ${SED} "${s}" ${1+"$@"} +} + +compile() +{ + ${setx} + test "X${Csrc}" = "X" && Csrc="${testname}" + test "X${Cexe}" = "X" && Cexe="${Csrc}" + test "X${Dnam}" = "X" && Dnam="${testname}" + + d=`echo TEST_TEST_${Dnam}_OPTS | ${TR} '[a-z]-' '[A-Z]_'` + cc_cmd="${CC} ${CFLAGS} -D$d ${INC} -o ${Cexe} ${Csrc}.c ${LIB}" + eval ${cc_cmd} || \ + failure cannot compile ${Csrc}.c + if test $# -gt 0 + then + ( set +xe + exec 2>&1 + ./${Cexe} ${*} ${dosed} + ) || failure cannot obtain help output for ${Csrc} + fi > ${Cexe}.RAW-HELP + clean_help ${Cexe}.RAW-HELP > ${Csrc}.help + Csrc='' Cexe='' Dnam='' +} + +cleanup() +{ + kill -9 $THUMPER_PID + trap '' 15 + ${setx} + ${VERBOSE} || { + cd ${builddir} + purge ${testsubdir} + } + ${msg} ${testname} done + exit 0 +} + +# A standard failure function +# +failure() +{ + kill -9 $THUMPER_PID + trap '' 15 + set -x + cd ${tstdir}/.. + if test -d FAILURES + then test -d "FAILURES/${testsubdir}" && \ + purge "FAILURES/${testsubdir}" + else mkdir FAILURES + fi + + mv "${testsubdir}" "FAILURES/${testsubdir}" + test -f "${testname}.log" && { + mv "${testname}.log" "FAILURES/${testsubdir}/amtest-${testname}.log" + ln -s "FAILURES/${testsubdir}/amtest-${testname}.log" "${testname}.log" + } + echo FAILURE: "$*" + exit 1 +} + +thumper() +{ + exec > /dev/null 2>&1 /dev/null ; pwd` + cd / + rpid=${progpid} + test -z "${kill_delay}" && kill_delay=3 + kill_delay=`expr $kill_delay '*' $AG_TIMEOUT` + while test ${kill_delay} -gt 0 + do sleep 1 + ps -p ${rpid} || exit 0 + kill_delay=`expr $kill_delay - 1` + done + kill -15 ${rpid} + sleep 1 + ps -p ${rpid} || exit + test -d "$bdir" && { + test -d ${bdir}/FAILURES || \ + mkdir ${bdir}/FAILURES + mv -f "${tstdir}" "${bdir}/FAILURES/." + } + kill -9 ${rpid} +} + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + +cfg_vals $0 + +case "${VERBOSE}" in +'' | [Nn]* | 0 | [Ff]* ) + be_silent ;; + +[Yy]* | [0-9] | [Tt]* ) + be_verbose ;; + +* ) + case "$-" in + *x* ) be_verbose ;; + * ) be_silent ;; + esac +esac + +thumper & +THUMPER_PID=$! +cfg_inc + +trap "failure 'test ${testname} killed on timeout'" 15 + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## sh-basic-offset: 2 +## End: + +# defs.in ends here diff --git a/getdefs/test/index.test b/getdefs/test/index.test new file mode 100755 index 0000000..c382b9e --- /dev/null +++ b/getdefs/test/index.test @@ -0,0 +1,122 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# +# index.test --- test the subblock parameter to getdefs +# +# Author: Bruce Korb +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen 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. +## +## AutoGen is distributed in the hope that 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 . + +# Common definitions + +. ./defs + +# Create the files we need in the test environment +cat > ${testname}.c < ${testname}.test <<_EOF_ +/* -*- buffer-read-only: t -*- vi: set ro: + * + * + * DO NOT EDIT THIS FILE (index.out) + * + * It has been extracted by getdefs from the following files: + * + * index.c + */ +autogen definitions index-testd; + +#line 14 "index.c" +gfunc[2] = { + name = 'in_p'; + exparg = { + arg_name = 'test-string'; + arg_desc = 'string to look for'; + }; + exparg = { + arg_name = 'string-list'; + arg_desc = 'list of strings to check,,'; + arg_list = 'list'; + }; + opt = '1'; + doc = 'Return SCM_BOOL_T if the first argument is duplicated +in the second (list) argument.'; + foo = 'bar','','baz'; +}; + + +#line 4 "index.c" +gfunc = { + name = 'xtract'; + what = 'extract text from another file'; + general_use; + exparg = { + arg_name = 'file-name'; + arg_desc = 'name of file with text'; + }; + exparg = { + arg_name = 'marker-fmt'; + arg_desc = 'format for marker text'; + }; + exparg = { + arg_name = 'caveat'; + arg_desc = 'warn about changing marker'; + arg_optional = 'opt'; + }; + exparg = { + arg_name = 'default'; + arg_desc = 'default initial text'; + arg_optional = 'opt'; + }; +}; +_EOF_ + +set -x +${GDexe} output=$testname.out $testname.c || \ + failure running ${GDexe} +cmp -s $testname.test $testname.out || \ + failure "`diff $testname.test $testname.out`" + +# end of index.test diff --git a/getdefs/test/option.test b/getdefs/test/option.test new file mode 100755 index 0000000..33d9621 --- /dev/null +++ b/getdefs/test/option.test @@ -0,0 +1,100 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# +# option.test --- test option extraction +# +# Author: Bruce Korb +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen 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. +## +## AutoGen is distributed in the hope that 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 . + +# Common definitions + +. ./defs + +# Create the files we need in the test environment +cat > ${testname}.c < ${testname}.test <<_EOF_ +/* -*- buffer-read-only: t -*- vi: set ro: + * + * + * DO NOT EDIT THIS FILE (option.out) + * + * It has been extracted by getdefs from the following files: + * + * option.c + */ +autogen definitions option-testd; + +/* GLOBALDEFS */ + +#line 2 "option.c" + test = 'subblock'; + doc = 'we want to see +just what happens'; + + +#line 11 "option.c" +gfunc = { + name = 'in_p'; + exparg = { + arg_name = 'test-string'; + arg_desc = 'string to look for'; + }; + exparg = { + arg_name = 'string-list'; + arg_desc = 'list of strings to check,,'; + arg_list = 'list'; + }; + opt = '1'; + doc = +'Return SCM_BOOL_T if the first argument is duplicated +in the second (list) argument.'; +}; +_EOF_ +set -x +${GDexe} output=${testname}.out ${testname}.c || \ + failure running ${GDexe} +cmp -s ${testname}.test ${testname}.out || \ + failure "`diff ${testname}.test ${testname}.out`" + +# end of option.test diff --git a/getdefs/test/subblock.test b/getdefs/test/subblock.test new file mode 100755 index 0000000..d4fab2d --- /dev/null +++ b/getdefs/test/subblock.test @@ -0,0 +1,98 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# +# subblock.test --- test the subblock parameter to getdefs +# +# Author: Bruce Korb +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen 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. +## +## AutoGen is distributed in the hope that 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 . + +# Common definitions + +. ./defs + + +# Create the files we need in the test environment +cat > $testname.c < $testname.test <<_EOF_ +/* -*- buffer-read-only: t -*- vi: set ro: + * + * + * DO NOT EDIT THIS FILE (subblock.out) + * + * It has been extracted by getdefs from the following files: + * + * subblock.c + */ +autogen definitions subblock-testd; + +/* GLOBALDEFS */ + +#line 2 "subblock.c" + test = 'subblock'; + doc = 'we want to see +just what happens'; + + +#line 9 "subblock.c" +gfunc = { + name = 'in_p'; + exparg = { + arg_name = 'test-string'; + arg_desc = 'string to look for'; + }; + exparg = { + arg_name = 'string-list'; + arg_desc = 'list of strings to check,,'; + arg_list = 'list'; + }; + opt = '1'; + doc = 'Return SCM_BOOL_T if the first argument is duplicated +in the second (list) argument.'; +}; +_EOF_ + +${GDexe} subblock=exparg=arg_name,arg_desc,arg_optional,arg_list \ + output=$testname.out $testname.c || \ + failure running ${GDexe} +cmp -s $testname.test $testname.out || \ + failure "`diff $testname.test $testname.out`" + +# end of subblock.test diff --git a/pkg/Makefile.am b/pkg/Makefile.am new file mode 100644 index 0000000..0e2a807 --- /dev/null +++ b/pkg/Makefile.am @@ -0,0 +1,51 @@ +## -*- Mode: Makefile -*- +## Makefile.am --- process this file with automake to produce Makefile.in +## +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2017 by Bruce Korb - all rights reserved +## +## AutoGen 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. +## +## AutoGen is distributed in the hope that 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 . + +DISTCLEANFILES = autogen.lsm +LIBOPTS_FILES = \ + libopts/libopts-add.m4 libopts/mklibsrc.sh libopts/README \ + libopts/COPYING.mbsd libopts/COPYING.lgplv3 libopts/stdnoreturn.mk \ + libopts/COPYING.gplv3 + +TPL_FILES = lsm.tpl spec.tpl gnudir.tpl gnudoc.tpl +PKG_FILES = mkpkg.linux mkpkg.sh mkpkg.sun pkg-env.in +EXTRA_DIST = $(TPL_FILES) $(LIBOPTS_FILES) $(PKG_FILES) +DOCENV = MAKE="$(MAKE)" + +all : $(DISTCLEANFILES) + +autogen.lsm : $(top_srcdir)/VERSION lsm.tpl + top_builddir=$(top_builddir) top_srcdir=$(top_srcdir) \ + $(AGexe) -L$(top_srcdir)/autoopts -T $(srcdir)/lsm.tpl \ + $(top_srcdir)/agen5/opts.def + +autogen.spec : $(top_srcdir)/VERSION spec.tpl + top_builddir=$(top_builddir) top_srcdir=$(top_srcdir) \ + $(AGexe) -T $(srcdir)/spec.tpl $(top_srcdir)/agen5/opts.def + +package : + pkgtype=$(pkgtype) \ + DESTDIR=`cd $(top_builddir) > /dev/null ; pwd`/stage-pkg \ + $(DOCENV) $(POSIX_SHELL) $(srcdir)/mkpkg.sh + +pkg : package + +.NOTPARALLEL: + +## pkg/Makefile.am ends here diff --git a/pkg/Makefile.in b/pkg/Makefile.in new file mode 100644 index 0000000..7ad0924 --- /dev/null +++ b/pkg/Makefile.in @@ -0,0 +1,537 @@ +# Makefile.in generated by automake 1.16.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2018 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +subdir = pkg +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/config/ag_macros.m4 \ + $(top_srcdir)/config/asm-underscore.m4 \ + $(top_srcdir)/config/extensions.m4 \ + $(top_srcdir)/config/guile.m4 \ + $(top_srcdir)/config/host-cpu-c-abi.m4 \ + $(top_srcdir)/config/lib-ld.m4 \ + $(top_srcdir)/config/lib-link.m4 \ + $(top_srcdir)/config/lib-prefix.m4 \ + $(top_srcdir)/config/libopts.m4 \ + $(top_srcdir)/config/libtool.m4 \ + $(top_srcdir)/config/ltoptions.m4 \ + $(top_srcdir)/config/ltsugar.m4 \ + $(top_srcdir)/config/ltversion.m4 \ + $(top_srcdir)/config/lt~obsolete.m4 \ + $(top_srcdir)/config/onceonly.m4 $(top_srcdir)/config/pkg.m4 \ + $(top_srcdir)/config/snprintfv.m4 \ + $(top_srcdir)/config/stdnoreturn.m4 \ + $(top_srcdir)/config/unlocked-io.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = pkg-env +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/pkg-env.in +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AGEN5_TESTS = @AGEN5_TESTS@ +AG_LDFLAGS = @AG_LDFLAGS@ +AG_MAJOR_VERSION = @AG_MAJOR_VERSION@ +AG_MINOR_VERSION = @AG_MINOR_VERSION@ +AG_STATIC_AUTOGEN = @AG_STATIC_AUTOGEN@ +AG_TIMEOUT = @AG_TIMEOUT@ +AG_VERSION = @AG_VERSION@ +AG_XML2 = @AG_XML2@ +AGexe = @AGexe@ +AGnam = @AGnam@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AO_AGE = @AO_AGE@ +AO_CURRENT = @AO_CURRENT@ +AO_REVISION = @AO_REVISION@ +AO_TEMPLATE_VERSION = @AO_TEMPLATE_VERSION@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CLexe = @CLexe@ +CLnam = @CLnam@ +CONFIG_SHELL = @CONFIG_SHELL@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEBUG_ENABLED = @DEBUG_ENABLED@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +DYNAMIC_AG = @DYNAMIC_AG@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ENABLE_STATIC = @ENABLE_STATIC@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GDexe = @GDexe@ +GDnam = @GDnam@ +GO_AGE = @GO_AGE@ +GO_CURRENT = @GO_CURRENT@ +GO_REVISION = @GO_REVISION@ +GREP = @GREP@ +GUILE_CFLAGS = @GUILE_CFLAGS@ +GUILE_EFFECTIVE_VERSION = @GUILE_EFFECTIVE_VERSION@ +GUILE_LDFLAGS = @GUILE_LDFLAGS@ +GUILE_LIBS = @GUILE_LIBS@ +GUILE_LTLIBS = @GUILE_LTLIBS@ +HOST_CPU = @HOST_CPU@ +HOST_CPU_C_ABI = @HOST_CPU_C_ABI@ +INCLIST = @INCLIST@ +INCSNPRINTFV = @INCSNPRINTFV@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSNPRINTFV = @LIBSNPRINTFV@ +LIBTOOL = @LIBTOOL@ +LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ +LIBXML2_LIBS = @LIBXML2_LIBS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +M4_SRC = @M4_SRC@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPTS_TESTDIR = @OPTS_TESTDIR@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POSIX_SHELL = @POSIX_SHELL@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STDNORETURN_H = @STDNORETURN_H@ +STRIP = @STRIP@ +TEXI2HTML = @TEXI2HTML@ +VERSION = @VERSION@ +WARN_CFLAGS = @WARN_CFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_aux_dir = @ac_aux_dir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +DISTCLEANFILES = autogen.lsm +LIBOPTS_FILES = \ + libopts/libopts-add.m4 libopts/mklibsrc.sh libopts/README \ + libopts/COPYING.mbsd libopts/COPYING.lgplv3 libopts/stdnoreturn.mk \ + libopts/COPYING.gplv3 + +TPL_FILES = lsm.tpl spec.tpl gnudir.tpl gnudoc.tpl +PKG_FILES = mkpkg.linux mkpkg.sh mkpkg.sun pkg-env.in +EXTRA_DIST = $(TPL_FILES) $(LIBOPTS_FILES) $(PKG_FILES) +DOCENV = MAKE="$(MAKE)" +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu pkg/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu pkg/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +pkg-env: $(top_builddir)/config.status $(srcdir)/pkg-env.in + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +tags TAGS: + +ctags CTAGS: + +cscope cscopelist: + + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: all all-am check check-am clean clean-generic clean-libtool \ + cscopelist-am ctags-am distclean distclean-generic \ + distclean-libtool distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + + +all : $(DISTCLEANFILES) + +autogen.lsm : $(top_srcdir)/VERSION lsm.tpl + top_builddir=$(top_builddir) top_srcdir=$(top_srcdir) \ + $(AGexe) -L$(top_srcdir)/autoopts -T $(srcdir)/lsm.tpl \ + $(top_srcdir)/agen5/opts.def + +autogen.spec : $(top_srcdir)/VERSION spec.tpl + top_builddir=$(top_builddir) top_srcdir=$(top_srcdir) \ + $(AGexe) -T $(srcdir)/spec.tpl $(top_srcdir)/agen5/opts.def + +package : + pkgtype=$(pkgtype) \ + DESTDIR=`cd $(top_builddir) > /dev/null ; pwd`/stage-pkg \ + $(DOCENV) $(POSIX_SHELL) $(srcdir)/mkpkg.sh + +pkg : package + +.NOTPARALLEL: + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/pkg/gnudir.tpl b/pkg/gnudir.tpl new file mode 100644 index 0000000..8dc6f3a --- /dev/null +++ b/pkg/gnudir.tpl @@ -0,0 +1,142 @@ +%%comments: +Copyright (C) 2001-2018 by Bruce Korb - all rights reserved + +Permission is granted to copy, distribute and/or modify this document +under the terms of the GNU Free Documentation License, Version 1.1 or +any later version published by the Free Software Foundation; with no +Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. +A copy of the license is included in the file COPYING. + +%%name: Autogen + +%%short-description: Automated program and text generation + +%%full-description: Autogen is a tool designed for generating program +files that contain repetitive text with varied substitutions. its +goal is to simplify the maintenance of programs that have large +amounts of repetitive text. This is particularly valuable +if there are several blocks of such text that must be kept +synchronized. The follwing programs and libraries are also included: + +

AutoOpts- This is a link library that can be redistributed with any +project. It completely automates the process of parsing command line +options, configuration files, environment variables, usage text, man +pages, and the invoking section of an info doc. It currently produces +option processing code for C, C++, Guile inner-main programs and shell +scripts. + +

AutoFSM- Where it is possible to determine a state transition type +(token code) largely without reference to the current state, this +template will produce a transition table and prototype finite state +machine. If you must know current state to determine the transition +type, this is not useful. + +

getdefs- Extracts AutoGen definitions from stylized commentes +embedded in source code. + +

columns- tabularizes lists for improved output appearance. +See also ls(1). + +

AutoXDR- is an affiliated download. +NFSv4 specifies that its remote procedure calls be batched. Using +an enhanced XDR specification and the AutoXDR templates, AutoGen +generates all the grunge code for marshalling and unmarshalling +the arguments on both sides of the RPC request. + +%%category: software development, program build automation + +%%license: GPL, LGPL, BSD, public domain + +%%license verified by: Janet Casey + +%%license verified on: 2001-01-31 + +%%maintainer: Bruce Korb + +%%updated: 2005-02-01 + +%%keywords: RPC, rpcgen, NFSv4, finite state machine, FSM, Guile, M4 + +%%interface: Command line + +%%programs: autogen, getdefs, columns + +%%libraries: AutoOpts, AutoXDR, AutoFSM + +%%GNU: yes + +%%web-page: http://www.gnu.org/software/autogen + +%%support: + +%%doc: Developer's reference manual available from +http://www.gnu.org/manual/autogen/autogen.html + +%%developers: Bruce Korb , Gary V. Vaughan + +%%contributors: + +%%sponsors: + +%%source-tarball: ftp://ftp.gnu.org/pub/gnu/autogen/autogen-5.3.2.tar.gz + +%%source-info: http://prdownloads.sourceforge.net/autogen/ + +%%source-template: + +%%debian: http://packages.debian.org/unstable/devel/autogen.html + +%%rpm: + +%%repository: cvs.AutoGen.sourceforge.net:/cvsroot/AutoGen + +%%related: Guile + +%%source-language: C, Guile, Bourne shell + +%%supported-languages: + +%%use-requirements: Guile, Bourne-like shell, POSIX environment + +%%build-prerequisites: Guile, ANSI C, Bourne-like shell, POSIX environment + +%%weak-prerequisites: + +%%source-prerequisites: + +%%version: 5.3.2 stable released 2002-02-25 + +%%announce-list: + +%%announce-news: + +%%help-list: + +%%help-news: + +%%irc-help-channel: + +%%dev-list: + +%%dev-news: + +%%irc-dev-channel: + +%%bug-list: + +%%bug-database: + +%%Entry Written By: Janet Casey + + + + + + + + + + + + + diff --git a/pkg/gnudoc.tpl b/pkg/gnudoc.tpl new file mode 100644 index 0000000..f74662c --- /dev/null +++ b/pkg/gnudoc.tpl @@ -0,0 +1,142 @@ +[= AutoGen5 Template -*- Mode: html -*- + +html =][= +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen 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. +## +## AutoGen is distributed in the hope that 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 . + +=] + +[=(dne " == " " +[= title =] - GNU Project - Free Software Foundation (FSF) + + + +

[= project =] version [= version =] - Table of Contents

+ +
Free Software Foundation
+
last updated [=`date '+%B %e, %Y'`=]
+ +

The manual for the [= project =] project is available in the following formats:

[= + +(define fnam "") +(define fsiz 0) + +(define (compute-size dir sfx) + (begin + (set! fnam (string-append dir "/" package sfx)) + (set! fsiz (if (access? fnam R_OK) (stat:size (stat fnam)) 0 )) + (shellf "fsiz='%d' + if test ${fsiz} -lt 4096 + then echo ${fsiz} + else + fsiz=`expr ${fsiz} / 1024` + if test ${fsiz} -lt 2048 + then echo ${fsiz}K + else + fsiz=`expr ${fsiz} / 1024` + echo ${fsiz}M + fi + fi" fsiz) +) ) + +=] + + +

(This page generated by the autogen program in conjunction with a fairly simple template.)

+ + + + + diff --git a/pkg/libopts/COPYING.gplv3 b/pkg/libopts/COPYING.gplv3 new file mode 100644 index 0000000..7718bd1 --- /dev/null +++ b/pkg/libopts/COPYING.gplv3 @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + 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) by Bruce Korb - all rights reserved + + 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) by Bruce Korb - all rights reserved + 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/pkg/libopts/COPYING.lgplv3 b/pkg/libopts/COPYING.lgplv3 new file mode 100644 index 0000000..f7b8c63 --- /dev/null +++ b/pkg/libopts/COPYING.lgplv3 @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + 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. + + 0. Additional Definitions. + + 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. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + 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. + + 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". + + 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. + + 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. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + 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: + + 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 + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + 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) 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. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + 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. diff --git a/pkg/libopts/COPYING.mbsd b/pkg/libopts/COPYING.mbsd new file mode 100644 index 0000000..b74eb00 --- /dev/null +++ b/pkg/libopts/COPYING.mbsd @@ -0,0 +1,27 @@ +Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + 3. The name of the author may not be used to endorse or promote + products derived from this software without specific prior + written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. diff --git a/pkg/libopts/README b/pkg/libopts/README new file mode 100644 index 0000000..5c8b9d7 --- /dev/null +++ b/pkg/libopts/README @@ -0,0 +1,122 @@ + THIS TARBALL IS NOT A FULL DISTRIBUTION. + +The contents of this tarball is designed to be incorporated into +software packages that utilize the AutoOpts option automation package +and are intended to be installed on systems that may not have libopts +installed. It is redistributable under the terms of either the LGPL +(see COPYING.lgpl) or under the terms of the advertising clause free BSD +license (see COPYING.mbsd). + +Usage Instructions for autoconf/automake/libtoolized projects: + +1. Install the unrolled tarball into your package source tree, + copying ``libopts.m4'' to your autoconf macro directory. + + In your bootstrap (pre-configure) script, you can do this: + + rm -rf libopts libopts-* + gunzip -c `autoopts-config libsrc` | tar -xvf - + mv -f libopts-*.*.* libopts + cp -fp libopts/m4/*.m4 m4/. + + I tend to put my configure auxiliary files in "m4". + Whatever directory you choose, if it is not ".", then + be sure to tell autoconf about it with: + + AC_CONFIG_AUX_DIR(m4) + + This is one macro where you *MUST* remember to *NOT* quote + the argument. If you do, automake will get lost. + +2. Add an invocation of either LIBOPTS_CHECK or LIBOPTS_CHECK_NOBUILD + to your configure.ac file. See LIBOPTS_CHECK: below for details. + +3. Add the following to your top level ``Makefile.am'' file: + + if NEED_LIBOPTS + SUBDIRS += $(LIBOPTS_DIR) + endif + + where ``<...>'' can be whatever other files or directories you may + need. The SUBDIRS must be properly ordered. *PLEASE NOTE* it is + crucial that the SUBDIRS be set under the control of an automake + conditional. To work correctly, automake has to know the range of + possible values of SUBDIRS. It's a magical name with magical + properties. ``NEED_LIBOPTS'' will be correctly set by the + ``LIBOPTS_CHECK'' macro, above. + +4. Add ``$(LIBOPTS_CFLAGS)'' to relevant compiler flags and + ``$(LIBOPTS_LDADD)'' to relevant link options whereever + you need them in your build tree. + +5. Make sure your object files explicitly depend upon the + generated options header file. e.g.: + + $(prog_OBJECTS) : prog-opts.h + prog-opts.h : prog-opts.c + prog-opts.c : prog-opts.def + autogen prog-opts.def + +6. *OPTIONAL* -- + If you are creating man pages and texi documentation from + the program options, you will need these rules somewhere, too: + + man_MANS = prog.1 + prog.1 : prog-opts.def + autogen -Tagman-cmd.tpl -bprog prog-opts.def + + invoke-prog.texi : prog-opts.def + autogen -Tagtexi-cmd.tpl prog-opts.def + +If your package does not utilize the auto* tools, then you +will need to hand craft the rules for building the library. + +LIBOPTS_CHECK: + +The arguments to both macro are a relative path to the directory with +the libopts source code. It is optional and defaults to "libopts". +These macros work as follows: + +1. LIBOPTS_CHECK([libopts/rel/path/optional]) + + Adds two command-line options to the generated configure script, + --enable-local-libopts and --disable-libopts-install. AC_SUBST's + LIBOPTS_CFLAGS, LIBOPTS_LDADD, and LIBOPTS_DIR for use in + Makefile.am files. Adds Automake conditional NEED_LIBOPTS which + will be true when the local copy of libopts should be built. Uses + AC_CONFIG_FILES([$libopts-dir/Makefile]) to cause the local libopts + into the package build. If the optional relative path to libopts is + not provided, it defaults to simply "libopts". + +2. LIBOPTS_CHECK_NOBUILD([libopts/rel/path/optional]) + + This variant of LIBOPTS_CHECK is useful when multiple configure.ac + files in a package make use of a single libopts tearoff. In that + case, only one of the configure.ac files should build libopts and + others should simply use it. Consider this package arrangment: + + all-tools/ + configure.ac + common-tools/ + configure.ac + libopts/ + + The parent package all-tools contains a subpackage common-tools + which can be torn off and used independently. Programs configured + by both configure.ac files link against the common-tools/libopts + tearoff, when not using the system's libopts. The top-level + configure.ac uses LIBOPTS_CHECK_NOBUILD([common-tools/libopts]), + while common-tools/configure.ac uses LIBOPTS_CHECK. The difference + is LIBOPTS_CHECK_NOBUILD will never build the libopts tearoff, + leaving that to the subpackage configure.ac's LIBOPTS_CHECK. + Specifically, LIBOPTS_CHECK_NOBUILD always results in the + NEED_LIBOPTS Automake conditional being false, and does not invoke + AC_CONFIG_FILES(path-to-libopts/Makefile). + +LICENSING: + +This material is Copyright (C) 1992-2018 by Bruce Korb. You are +licensed to use this under the terms of either the GNU Lesser General +Public License (see: COPYING.lgpl), or, at your option, the modified +Berkeley Software Distribution License (see: COPYING.mbsd). Both of +these files should be included with this tarball. diff --git a/pkg/libopts/libopts-add.m4 b/pkg/libopts/libopts-add.m4 new file mode 100644 index 0000000..4e11ec8 --- /dev/null +++ b/pkg/libopts/libopts-add.m4 @@ -0,0 +1,138 @@ + +dnl @synopsis LIBOPTS_CHECK +dnl +dnl If autoopts-config works, add the linking information to LIBS. +dnl Otherwise, add ``libopts-${ao_rev}'' to SUBDIRS and run all +dnl the config tests that the library needs. Invoke the +dnl "INVOKE_LIBOPTS_MACROS" macro iff we are building libopts. +dnl +dnl This file is part of AutoGen. +dnl AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +dnl +dnl AutoGen is free software: you can redistribute it and/or modify it +dnl under the terms of the GNU General Public License as published by the +dnl Free Software Foundation, either version 3 of the License, or +dnl (at your option) any later version. +dnl +dnl AutoGen is distributed in the hope that it will be useful, but +dnl WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +dnl See the GNU General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License along +dnl with this program. If not, see . +dnl +dnl Default to system libopts +dnl +AC_DEFUN([LIBOPTS_CHECK_COMMON],[ + AC_REQUIRE([INVOKE_LIBOPTS_MACROS_FIRST]) + [NEED_LIBOPTS_DIR=''] + m4_pushdef([AO_Libopts_Dir], + [ifelse($1, , [libopts], [$1])]) + AC_ARG_ENABLE([local-libopts], + AC_HELP_STRING([--enable-local-libopts], + [Use the supplied libopts tearoff code]),[ + if test x$enableval = xyes ; then + AC_MSG_NOTICE([Using supplied libopts tearoff]) + LIBOPTS_CFLAGS='-I$(top_srcdir)/AO_Libopts_Dir' + NEED_LIBOPTS_DIR=true + LIBOPTS_LDADD='$(top_builddir)/AO_Libopts_Dir/libopts.la' + fi]) + + AC_ARG_ENABLE([libopts-install], + AC_HELP_STRING([--enable-libopts-install], + [Install libopts with client installation])) + AM_CONDITIONAL([INSTALL_LIBOPTS],[test "X${enable_libopts_install}" = Xyes]) + + [if test -z "${NEED_LIBOPTS_DIR}" ; then] + AC_MSG_CHECKING([whether autoopts-config can be found]) + AC_ARG_WITH([autoopts-config], + AC_HELP_STRING([--with-autoopts-config], + [specify the config-info script]), + [lo_cv_with_autoopts_config=${with_autoopts_config}], + AC_CACHE_CHECK([whether autoopts-config is specified], + [lo_cv_with_autoopts_config], + [if autoopts-config --help 2>/dev/null 1>&2 + then lo_cv_with_autoopts_config=autoopts-config + elif libopts-config --help 2>/dev/null 1>&2 + then lo_cv_with_autoopts_config=libopts-config + else lo_cv_with_autoopts_config=no ; fi]) + ) # end of AC_ARG_WITH + + AC_CACHE_VAL([lo_cv_test_autoopts],[ + if test -z "${lo_cv_with_autoopts_config}" \ + -o X"${lo_cv_with_autoopts_config}" = Xno + then + if autoopts-config --help 2>/dev/null 1>&2 + then lo_cv_with_autoopts_config=autoopts-config + elif libopts-config --help 2>/dev/null 1>&2 + then lo_cv_with_autoopts_config=libopts-config + else lo_cv_with_autoopts_config=false ; fi + fi + lo_cv_test_autoopts=` + ${lo_cv_with_autoopts_config} --libs` 2> /dev/null + if test $? -ne 0 -o -z "${lo_cv_test_autoopts}" + then lo_cv_test_autoopts=no ; fi + ]) # end of CACHE_VAL + AC_MSG_RESULT([${lo_cv_test_autoopts}]) + + [if test "X${lo_cv_test_autoopts}" != Xno + then + LIBOPTS_LDADD="${lo_cv_test_autoopts}" + LIBOPTS_CFLAGS="`${lo_cv_with_autoopts_config} --cflags`" + else + LIBOPTS_LDADD='$(top_builddir)/]AO_Libopts_Dir[/libopts.la' + LIBOPTS_CFLAGS='-I$(top_srcdir)/]AO_Libopts_Dir[' + NEED_LIBOPTS_DIR=true + fi + fi # end of if test -z "${NEED_LIBOPTS_DIR}" + if test -n "${LIBOPTS_BUILD_BLOCKED}" ; then + NEED_LIBOPTS_DIR='' + fi] + AM_CONDITIONAL([NEED_LIBOPTS], [test -n "${NEED_LIBOPTS_DIR}"]) + AC_SUBST(LIBOPTS_LDADD) + AC_SUBST(LIBOPTS_CFLAGS) + AC_SUBST(LIBOPTS_DIR, AO_Libopts_Dir) + m4_popdef([AO_Libopts_Dir]) +[# end of AC_DEFUN of LIBOPTS_CHECK_COMMON] +]) +dnl +dnl AC_CONFIG_FILES conditionalization requires using AM_COND_IF, however +dnl AM_COND_IF is new to Automake 1.11. To use it on new Automake without +dnl requiring same, a fallback implementation for older Automake is provided. +dnl Note that disabling of AC_CONFIG_FILES requires Automake 1.11, this code +dnl is correct only in terms of m4sh generated script. +dnl +m4_ifndef([AM_COND_IF], + [AC_DEFUN([AM_COND_IF], [ + if test -z "$$1_TRUE"; then : + m4_n([$2])[]dnl + m4_ifval([$3],[ + else + $3 + ])dnl + fi[]dnl + ])dnl +]) +dnl +AC_DEFUN([LIBOPTS_CHECK_NOBUILD], [ + m4_pushdef([AO_Libopts_Dir], + [ifelse($1, , [libopts], [$1])]) + LIBOPTS_BUILD_BLOCKED=true + LIBOPTS_CHECK_COMMON(AO_Libopts_Dir) + m4_popdef([AO_Libopts_Dir])dnl +# end of AC_DEFUN of LIBOPTS_CHECK_NOBUILD +]) +dnl +AC_DEFUN([LIBOPTS_CHECK], [ + m4_pushdef([AO_Libopts_Dir], + [ifelse($1, , [libopts], [$1])]) + LIBOPTS_BUILD_BLOCKED='' + LIBOPTS_CHECK_COMMON(AO_Libopts_Dir) + AM_COND_IF([NEED_LIBOPTS], [ + INVOKE_LIBOPTS_MACROS + ]) + AC_CONFIG_FILES(AO_Libopts_Dir/Makefile) + m4_popdef([AO_Libopts_Dir])dnl +# end of AC_DEFUN of LIBOPTS_CHECK +]) diff --git a/pkg/libopts/mklibsrc.sh b/pkg/libopts/mklibsrc.sh new file mode 100644 index 0000000..0cad4dc --- /dev/null +++ b/pkg/libopts/mklibsrc.sh @@ -0,0 +1,149 @@ +#! /bin/echo thils-file-should-not-be-directly-executed +## -*- Mode: shell-script -*- +## +## mklibsrc.sh -- make the libopts tear-off library source tarball +## +## This file is called via $(POSIX_SHELL) in autoopts/Makefile +## +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen 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. +## +## AutoGen is distributed in the hope that 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 . + +test ${#CDPATH} -gt 0 && CDPATH='' +test -d "${top_builddir}" && test -d "${top_srcdir}" || { + echo top_builddir and top_srcdir must specify a directory >&2 + exit 1 +} +top_builddir=`cd $top_builddir ; pwd` +top_srcdir=`cd $top_srcdir ; pwd` + +test -x ${top_builddir}/agen5/autogen || exit 0 +test -x ${top_builddir}/columns/columns || exit 0 + +ao_rev=${AO_CURRENT}.${AO_REVISION}.${AO_AGE} +tag=libopts-${ao_rev} + +cd ${top_builddir}/pkg +[ ! -d ${tag} ] || rm -rf ${tag} +mkdir ${tag} ${tag}/compat ${tag}/autoopts ${tag}/m4 +tagd=`pwd`/${tag} + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# +# WORKING IN SOURCE DIRECTORY +# +cd ${top_builddir}/autoopts +files='libopts.c gettext.h parse-duration.c parse-duration.h + stdnoreturn.in.h _Noreturn.h '$( + fgrep '#include' libopts.c | \ + sed -e 's,"$,,;s,#.*",,' ) + +for f in ${files} intprops.h verify.h +do + test -f ${f} && + cp -f ${f} ${tagd}/${f} && continue + + test -f ${top_srcdir}/autoopts/${f} && + cp -f ${top_srcdir}/autoopts/${f} ${tagd}/${f} && continue + + test -f ${top_srcdir}/${f} && + cp -f ${top_srcdir}/${f} ${tagd}/${f} && continue + + die "could not locate ${f} to copy into tarball" +done + +cp -f ${top_srcdir}/pkg/libopts/COPYING.* ${tagd}/. + +cd ${top_srcdir}/compat +cp windows-config.h compat.h pathfind.c snprintf.c strdup.c strchr.c \ + ../config/snippet/_Noreturn.h ${tagd}/compat/. +# +# END WORK IN SOURCE DIRECTORY +# +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + +cd ${tagd} + +cp ${top_srcdir}/config/libopts*.m4 ${top_srcdir}/config/stdnoret*.m4 m4/. +chmod u+w m4/libopts.m4 +cat ${top_srcdir}/pkg/libopts/libopts-add.m4 >> m4/libopts.m4 +test ! -f Makefile.am || rm -f Makefile.am + +sed s,'\${tag}',"${tag}",g ${top_srcdir}/pkg/libopts/README > README + +touch MakeDefs.inc + +vers=${AO_CURRENT}:${AO_REVISION}:${AO_AGE} +{ + cat <<- EOMakefile + ## LIBOPTS Makefile + MAINTAINERCLEANFILES = Makefile.in + if INSTALL_LIBOPTS + lib_LTLIBRARIES = libopts.la + else + noinst_LTLIBRARIES = libopts.la + endif + libopts_la_SOURCES = libopts.c + libopts_la_CPPFLAGS = -I\$(srcdir) + libopts_la_LDFLAGS = -version-info ${AM_LDFLAGS} ${vers} + EXTRA_DIST = + BUILT_SOURCES = + MOSTLYCLEANFILES = + + libopts.c: \$(BUILT_SOURCES) + @: do-nothing rule to avoid default SCCS get + + EOMakefile + + printf '\n# Makefile fragment from gnulib-s stdnoreturn module:\n#\n' + sed '/^#/d;/^$/d;s/top_srcdir/srcdir/' \ + ${top_srcdir}/pkg/libopts/stdnoreturn.mk + sed '1,/^Makefile.am:/d;/^[A-Z][a-z0-9-]*:/,$d' \ + ${top_srcdir}/pkg/libopts/_Noreturn + + printf '\nEXTRA_DIST += \\\n' + find $(ls -A) -type f \ + | env LC_COLLATE=C sort \ + | egrep -v '^(libopts\.c|Makefile\.am)$' \ + | ${CLexe} -I4 --spread=1 --line-sep=" \\" +} > Makefile.am + +gz='gzip --best -n' +sfx=tar.gz + +cd .. +echo ! cd `pwd` +echo ! tar cvf ${tag}.${sfx} ${tag} + +# If we have a SOURCE_DATE_EPOCH *and* tar supports a sort option, +# then add some fancy options to make tar output repeatable. +# +rbopts="" +[ -z "$SOURCE_DATE_EPOCH" ] \ + || ! tar --help|grep -q sort= \ + || rbopts="--sort=name --format=gnu --clamp-mtime --mtime @$SOURCE_DATE_EPOCH" + +tar cvf - $rbopts ${tag} | \ + $gz > ${top_builddir}/autoopts/${tag}.${sfx} +rm -rf ${tag} + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## sh-basic-offset: 2 +## End: + +## end of mklibsrc.sh diff --git a/pkg/libopts/stdnoreturn.mk b/pkg/libopts/stdnoreturn.mk new file mode 100644 index 0000000..ba5a80a --- /dev/null +++ b/pkg/libopts/stdnoreturn.mk @@ -0,0 +1,30 @@ + +# Because this Makefile snippet defines a variable used by other +# gnulib Makefile snippets, it must be present in all makefiles that +# need it. This is ensured by the applicability 'all' defined above. + +_NORETURN_H=$(srcdir)/_Noreturn.h + +EXTRA_DIST += _Noreturn.h + + +BUILT_SOURCES += $(STDNORETURN_H) + +# We need the following in order to create when the system +# doesn't have one that works. +if GL_GENERATE_STDNORETURN_H +stdnoreturn.h: stdnoreturn.in.h $(top_builddir)/config.status $(_NORETURN_H) + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ + sed -e '/definition of _Noreturn/r $(_NORETURN_H)' \ + < $(srcdir)/stdnoreturn.in.h; \ + } > $@-t && \ + mv $@-t $@ +else +stdnoreturn.h: $(top_builddir)/config.status + rm -f $@ +endif +MOSTLYCLEANFILES += stdnoreturn.h stdnoreturn.h-t + +EXTRA_DIST += stdnoreturn.in.h + diff --git a/pkg/lsm.tpl b/pkg/lsm.tpl new file mode 100644 index 0000000..7d4d973 --- /dev/null +++ b/pkg/lsm.tpl @@ -0,0 +1,68 @@ +[= AutoGen5 template + +lsm=autogen.lsm + +## +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen 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. +## +## AutoGen is distributed in the hope that 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 . +=] +Begin4 +Title: AutoGen + +Version: [=version=] + +Entered-date: [=`date +%Y-%m-%d`=] + +Description: AutoGen - [=prog_title=] + + AutoGen is a tool for automatically generating + arbitrary text files that contain repetitive text + with varying substitutions. This is particularly + useful if you have several types of repetitive + text that all need to be kept in sync with each + other. The goal is to try to simplify the process + of maintaining repetitive program text. + +Keywords: macro, m4, preprocessor, source generator, + command line option parser + +Author: bkorb@gnu.org (Bruce Korb) + +Maintained-by: bkorb@gnu.org (Bruce Korb) + +Primary-site: sunsite.unc.edu /pub/Linux/devel + [= ` +cd $top_builddir +set -- autogen*.gz +if [ $# -gt 1 ] +then shift \`expr $# - 1\` ; fi +if [ ! -f $1 ] +then ct=1151 +else ct="\`expr \\\\( \\\`wc -c < $1\\\` + 1023 \\\\) / 1024\`" +fi +echo ${ct}K $1 +` =] + 1K autogen.lsm + +Alternate-site: ftp://ftp.gnu.org/pub/autogen + +Original-site: http://autogen.sourceforge.net + +Platforms: gunzip, Guile and ANSI-C + +Copying-policy: GPL and LGPL + +End diff --git a/pkg/mkpkg.linux b/pkg/mkpkg.linux new file mode 100644 index 0000000..3743dad --- /dev/null +++ b/pkg/mkpkg.linux @@ -0,0 +1,91 @@ +#! /bin/sh + +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen 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. +## +## AutoGen is distributed in the hope that 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 . + +case "${VERBOSE}" in +"" | f* | F* | n* | N* ) + VERBOSE=false ;; +*) VERBOSE=true ; set -x ;; +esac +export VERBOSE + +eval "`egrep '^AG_' ${top_srcdir}/VERSION`" > /dev/null + +## Set directories in case they are relative paths +## +builddir=`pwd` +top_srcdir=`cd ${top_srcdir} > /dev/null ; pwd` +srcdir=`cd ${srcdir} > /dev/null ; pwd` + +cd ${top_builddir} +top_builddir=`pwd` + +rm -rf ./AGPKG +mkdir AGPKG +cd AGPKG +HOME=`pwd` + +mkdir -p BUILD SOURCES SPECS RPMS SRPMS + +[ -f ../autogen-${AG_VERSION}.tar.gz ] || ( + cd .. + ${MAKE} dist || exit 1 +) || exit 1 + +ln ../autogen-${AG_VERSION}.tar.gz SOURCES/. +printf "\n\nPACKAGING RPM FOR LINUX\n\n" + +cd ${builddir} +AG_VERSION=`echo ${AG_VERSION} | sed 's,\.,-,g'` +specfile=autogen-${AG_VERSION}.spec +agargs="-L ${srcdir} -L ${top_srcdir}/autoopts" +agargs="${agargs} -T spec.tpl -b autogen-${AG_VERSION} --writable" +${AGexe} ${agargs} ${top_srcdir}/agen5/opts.def || exit 1 + +cd ${HOME} + +echo "%_tmppath ${top_builddir}/AGPKG/BUILD +%_topdir $PWD" > .rpmmacros + +cat > .rpmrc <<- _EOF_ + + optflags: i386 -O3 -march=i486 -mcpu=i686 + optflags: i486 -O3 -march=i486 + optflags: i586 -O3 -march=i586 -mcpu=i686 -fmessage-length=0 + optflags: i686 -O3 -march=i686 -mcpu=i686 + optflags: athlon -O3 -march=athlon + optflags: ia64 -O3 + optflags: x86_64 -O3 + optflags: amd64 -O3 + optflags: ia32e -O3 + + _EOF_ + +RPM_OPT_FLAGS=-O3 rpmbuild -ba ${builddir}/${specfile} || exit 1 +ln `find . -type f -name '*.rpm'` ${builddir}/. +cd ${builddir} +rm -rf ${HOME} +${VERBOSE} || ls -l *.rpm +: + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## sh-basic-offset: 2 +## End: +## end of mkpkg.linux diff --git a/pkg/mkpkg.sh b/pkg/mkpkg.sh new file mode 100644 index 0000000..ff3527d --- /dev/null +++ b/pkg/mkpkg.sh @@ -0,0 +1,45 @@ +#! /bin/sh + +## mkpkg.sh -- create a native package +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen 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. +## +## AutoGen is distributed in the hope that 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 . + +test -f pkg-env && . pkg-env + +if test -z "${pkgtype}" +then + pkgtype=`sh ${top_srcdir}/config/config.guess | \ + sed 's,-[^-]*$,,;s,.*-,,'` +fi + +if test ! -f ${srcdir}/mkpkg.${pkgtype} +then + pkgtype=`uname -s | tr '[A-Z]' '[a-z]'` + test -f ${srcdir}/mkpkg.${pkgtype} || { + echo "No mkpkg script for ${pkgtype}" >&2 + exit 1 + } +fi + +. ${srcdir}/mkpkg.${pkgtype} + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## sh-basic-offset: 2 +## End: +## mkpkg.sh ends here diff --git a/pkg/mkpkg.sun b/pkg/mkpkg.sun new file mode 100644 index 0000000..5b33413 --- /dev/null +++ b/pkg/mkpkg.sun @@ -0,0 +1,150 @@ +#! /bin/sh + +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen 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. +## +## AutoGen is distributed in the hope that 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 . + +case "${VERBOSE}" in +"" | f* | F* | n* | N* ) + VERBOSE=false ;; +*) VERBOSE=true ; set -x ;; +esac +export VERBOSE + +set -e +pkgsrc=`pwd` +agdir=`cd ../agen5 > /dev/null 2>&1 ; pwd` + +[ ! -d ${DESTDIR} ] || rm -rf ${DESTDIR} || exit 1 +mkdir ${DESTDIR} || exit 1 +DESTDIR=`cd ${DESTDIR} > /dev/null && pwd` || exit 1 + +cd ${top_builddir} +${MAKE} install DESTDIR=${DESTDIR} + +cd ${DESTDIR} + +if [ ! -d reloc ] +then + mkdir reloc + case "${prefix}" in + /* ) : ;; + * ) prefix="/${prefix}" ;; + esac + mv .${prefix}/* reloc/. || exit 1 + p=${prefix} + while [ -n "$p" ] + do rmdir .${p} + p=`echo "$p" | sed 's,/[^/]*$,,'` + done +fi + +cp -f ${top_srcdir}/COPYING ./copyright + +pkgdst=`pwd` +[ -f prototype ] && rm -f prototype +exec 4> prototype +cat >&4 <<- EOF + # Prototype file for AutoGen + # + # derived by scanning the `pwd` directory + + i copyright + i pkginfo + i prototype + i checkinstall + ! default 0755 root sys + + # pt tp ???? obj-name + EOF + +cd reloc + +find * -type d | \ +while read d +do + case "$d" in + *autogen* ) mod="0775 root sys" ;; + * ) mod="? ? ?" ;; + esac + + echo " 1 d none ${d} ${mod}" +done >&4 + +echo "! default 0644 root sys" >&4 + +find * -type f | \ +while read f +do + if [ -x "$f" ] + then mod=0755 + else mod=0644 ; fi + echo " 1 f none ${f} $mod root sys" +done >&4 + +find * -type l | \ +while read l +do + f=`ls -l $l | sed 's,.* -> ,,'` + echo " 1 s none ${l}=${f}" +done >&4 + +exec 4>&- +cd ${pkgdst} + +cat > checkinstall <<- EOF + PATH=${PATH}:${prefix}/bin + guile-config compile > /dev/null 2>&1 && exit 0 + guile -c '(quit "bye")' && exit 0 + echo "The guile library does not seem to be present." + echo "I have searched the PATH ${PATH}" + echo "If it is, please ensure it is in the search path and retry." + exit 1 + EOF + +[ -f pkginfo.tpl ] && rm -f pkginfo.tpl +cat > pkginfo.tpl <<- EOF + [= AutoGen5 Template info=pkginfo =] + PKG="GNUagen" + NAME="AutoGen - [=prog-title=]" + VERSION="[= version =]" + BASEDIR="${prefix}" + DESC="AutoGen - [=prog-title=]" + VENDOR="[= copyright.owner =] http://autogen.sf.net" + ARCH="sparc" + CATEGORY="Development" + EMAIL="[= copyright.eaddr =]" + CONTACT="[= copyright.owner =]" + CLASSES=none + PSTAMP="[= version =] `date '+%Y-%m-%d %H:%M:%S'`" + EOF + +cd ${agdir} +${AGexe} --writable -L${pkgdst} -Tpkginfo.tpl ${top_srcdir}/agen5/opts.def +mv -f pkginfo ${pkgdst}/. +cd ${pkgdst} +rm -f pkginfo.tpl +cd .. +rm -rf GNUagen* +pkgmk -d. -r ${pkgdst}/reloc,${pkgdst} -f ${pkgdst}/prototype +pkgtrans -s . GNUagen.pkg GNUagen +gzip --best GNUagen.pkg +rm -rf ${pkgdst} + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## End: +## end of mkpkg.sun diff --git a/pkg/pkg-env.in b/pkg/pkg-env.in new file mode 100644 index 0000000..4fcbaac --- /dev/null +++ b/pkg/pkg-env.in @@ -0,0 +1,45 @@ +#! /bin/echo this_file_must_be_sourced,_not_executed + +## pkg-env.in -- create a native package +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen 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. +## +## AutoGen is distributed in the hope that 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 . + +set -a + +prefix="@prefix@" +builddir="@abs_builddir@" +srcdir="@abs_srcdir@" +top_builddir="@abs_top_builddir@" +top_srcdir="@abs_top_srcdir@" +PACKAGE="@PACKAGE@" +PACKAGE_BUGREPORT="@PACKAGE_BUGREPORT@" +PACKAGE_NAME="@PACKAGE_NAME@" +PACKAGE_STRING="@PACKAGE_STRING@" +PACKAGE_TARNAME="@PACKAGE_TARNAME@" +PACKAGE_VERSION="@PACKAGE_VERSION@" +. ${top_srcdir}/VERSION +AGexe="@AGexe@" +CLexe="@CLexe@" + +set +a + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## sh-basic-offset: 2 +## End: +## pkg-env.in ends here diff --git a/pkg/spec.tpl b/pkg/spec.tpl new file mode 100644 index 0000000..ec444b8 --- /dev/null +++ b/pkg/spec.tpl @@ -0,0 +1,149 @@ +[= AutoGen5 Template spec =] +[= # + * This file is part of AutoGen. + * AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoGen 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. + * + * AutoGen is distributed in the hope that 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 . +\=] +Summary: AutoGen - [=prog-title=] +Name: [= prog-name =] +Version: [= version =] +Vendor: [= copyright.owner =] http://www.gnu.org/software/autogen +Release: [=`echo $AG_MAJOR_VERSION`=] +License: GPL +Group: Development/Tools +Source: ftp://ftp.gnu.org/gnu/autogen/rel[= version =]/autogen-[= version + =].tar.gz +BuildRoot: %{_tmppath}/%{name}-root + +%description +AutoGen is a tool designed for generating program files that contain +repetitive text with varied substitutions. Its goal is to simplify the +maintenance of programs that contain large amounts of repetitious text. +This is especially valuable if there are several blocks of such text +that must be kept synchronized in parallel tables. + +Some parts are released under different licensing: + +libopts LGPL This is a tear-off, redistributable option processing library +autofsm BSD This is a template for producing finite state machine programs + +The Copyright itself is privately held by Bruce Korb. +Copyright (C) [= copyright.date =] by [= copyright.owner + =]. All rights reserved. Licensed under GPL, [=# + =]version 2 or later. +%prep +%setup -q +chmod -R +rw * + +%build +%configure +make CFLAGS="$RPM_OPT_FLAGS" + +if [ `id -u` -eq 0 ] && grep -E -q '^nobody:' /etc/passwd +then + echo "switching to user nobody to run 'make check'" + chown -R nobody . + su -s /bin/bash -c "umask 002; make check || touch FAIL" nobody + test -f FAIL && exit 1 || : +else + make check +fi + +%install +[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf ${RPM_BUILD_ROOT} +mkdir -p ${RPM_BUILD_ROOT} +make install DESTDIR=${RPM_BUILD_ROOT} + +# IF we have a valid file list OR the build root is _the_ root, +# THEN skip the file list generation. +# +if test -s autogen-filelist -o ${#RPM_BUILD_ROOT} -le 1 +then : ; else + ( cd ${RPM_BUILD_ROOT} + rm -f usr/share/info/dir + find . -type f -o -type l | grep -v 'usr/share/doc' + ) | sed -e 's@^\./@/@' \ + -e'/usr\/share\/info/s,$,.gz,' \ + -e'/usr\/share\/man/s,$,.gz,' \ + | sort \ + > autogen-filelist +fi + +%post +/sbin/ldconfig +/sbin/install-info --info-dir=%{_infodir} %{_infodir}/autogen.info* + +%preun +/sbin/install-info --delete --info-dir=%{_infodir} %{_infodir}/autogen.info* + +%postun -p /sbin/ldconfig + +%clean +rm -rf ${RPM_BUILD_ROOT} + +%files -f autogen-filelist +%defattr(-,root,root) + +%doc[=` +for f in AUTHORS TODO COPYING NEWS THANKS README +do test -f ${top_builddir}/$f -o -f ${top_srcdir}/$f && printf " $f" ; done +`=] + +%changelog +[= + +;; Run the following script at spec creation time to insert the +;; "regenerated" change log entry +;; +(out-push-new) + +=] +test -z "${LOGNAME}" && { + LOGNAME=`logname` 2>/dev/null + case "${LOGNAME}" in + *"no login name" ) + LOGNAME=`id | sed 's,).*,,;s,^.*(,,'` ;; + esac +} +name=`grep ^${LOGNAME}: /etc/passwd | \ + sed 's,:/.*,,;s,.*:,,'` 2>/dev/null +date=`date '+%a %b %e %Y'` +domain=`dnsdomainname` 2>/dev/null + +echo \* ${date} ${name} \<${LOGNAME}@${domain}\> Regenerated +[= + +(shell (out-pop #t)) + +=] +* Sun May 6 2012 Install only existing files to doc directory. +- Omit NOTES and VERSION. +* Fri Dec 31 2004 Bruce Korb Restored the file list +* Wed Oct 27 2004 Ed Swierk fixed up for Fedora +* Tue Dec 16 2003 Richard Zidlicky 5.5.7pre5-5 +- fix %%doc +- add post/pre scriptlets +- change default prefix +* Sat Mar 15 2003 Bruce Korb +- Rework as a template to automatically produce a properly configured RPM +* Fri Aug 9 2002 Bruce Korb +- Pull stuff from Thomas Steudten's version of this file[= #' + +## Local Variables: +## mode: shell-script +## minor-mode: rpm +## indent-tabs-mode: nil +## End: +## end of spec.tpl =] diff --git a/snprintfv/AUTHORS b/snprintfv/AUTHORS new file mode 100644 index 0000000..d17456b --- /dev/null +++ b/snprintfv/AUTHORS @@ -0,0 +1,8 @@ +Authors of libsnprintfv. See individual files for their licenses. + +Gary V. Vaughan : + Designed, implemented and maintained libsnprintfv up to the 0.98h release. + +Paolo Bonzini and +Bruce Korb : + Are currently maintaining libsnprintfv (starting from Summer 2002). diff --git a/snprintfv/Makefile.am b/snprintfv/Makefile.am new file mode 100644 index 0000000..f86f008 --- /dev/null +++ b/snprintfv/Makefile.am @@ -0,0 +1,47 @@ +## -*- Mode: Makefile -*- +## --------------------------------------------------------------------- +## Makefile.am -- process this file with automake to produce Makefile.in +## Copyright (C) 1998, 1999, 2000, 2002 Gary V. Vaughan +## Originally by Gary V. Vaughan, 1998 +## This file is part of Snprintfv +## +## Snprintfv 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. +## +## Snprintfv 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 . +## +## As a special exception to the GNU General Public License, if you +## distribute this file as part of a program that also links with and +## uses the libopts library from AutoGen, you may include it under +## the same distribution terms used by the libopts library. + +## Code: + +AM_CPPFLAGS = -I$(top_srcdir) +noinst_HEADERS = mem.h filament.h stream.h printf.h compat.h +dist_noinst_DATA = filament.stamp stream.stamp printf.stamp +noinst_LTLIBRARIES = libsnprintfv.la +libsnprintfv_la_LDFLAGS = -no-undefined +CSRC = filament.c format.c printf.c mem.c stream.c custom.c + +nodist_libsnprintfv_la_SOURCES = snv.c + +# These files are the raw sources used to generate similarly named +# header files after extracting the prototypes from the sources +# +EXTRA_DIST = filament.in printf.in stream.in $(CSRC) + +snv.c : $(CSRC) + for f in $(CSRC) ; do echo "#include \"$$f\"" ; done > $@ + +.NOTPARALLEL: + +# Makefile.am ends here diff --git a/snprintfv/Makefile.in b/snprintfv/Makefile.in new file mode 100644 index 0000000..4139804 --- /dev/null +++ b/snprintfv/Makefile.in @@ -0,0 +1,686 @@ +# Makefile.in generated by automake 1.16.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2018 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + + + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +subdir = snprintfv +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/config/ag_macros.m4 \ + $(top_srcdir)/config/asm-underscore.m4 \ + $(top_srcdir)/config/extensions.m4 \ + $(top_srcdir)/config/guile.m4 \ + $(top_srcdir)/config/host-cpu-c-abi.m4 \ + $(top_srcdir)/config/lib-ld.m4 \ + $(top_srcdir)/config/lib-link.m4 \ + $(top_srcdir)/config/lib-prefix.m4 \ + $(top_srcdir)/config/libopts.m4 \ + $(top_srcdir)/config/libtool.m4 \ + $(top_srcdir)/config/ltoptions.m4 \ + $(top_srcdir)/config/ltsugar.m4 \ + $(top_srcdir)/config/ltversion.m4 \ + $(top_srcdir)/config/lt~obsolete.m4 \ + $(top_srcdir)/config/onceonly.m4 $(top_srcdir)/config/pkg.m4 \ + $(top_srcdir)/config/snprintfv.m4 \ + $(top_srcdir)/config/stdnoreturn.m4 \ + $(top_srcdir)/config/unlocked-io.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(dist_noinst_DATA) \ + $(noinst_HEADERS) $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LTLIBRARIES = $(noinst_LTLIBRARIES) +libsnprintfv_la_LIBADD = +nodist_libsnprintfv_la_OBJECTS = snv.lo +libsnprintfv_la_OBJECTS = $(nodist_libsnprintfv_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +libsnprintfv_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(AM_CFLAGS) $(CFLAGS) $(libsnprintfv_la_LDFLAGS) $(LDFLAGS) \ + -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/config/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/snv.Plo +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(nodist_libsnprintfv_la_SOURCES) +DIST_SOURCES = +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +DATA = $(dist_noinst_DATA) +HEADERS = $(noinst_HEADERS) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/config/depcomp \ + AUTHORS README THANKS +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AGEN5_TESTS = @AGEN5_TESTS@ +AG_LDFLAGS = @AG_LDFLAGS@ +AG_MAJOR_VERSION = @AG_MAJOR_VERSION@ +AG_MINOR_VERSION = @AG_MINOR_VERSION@ +AG_STATIC_AUTOGEN = @AG_STATIC_AUTOGEN@ +AG_TIMEOUT = @AG_TIMEOUT@ +AG_VERSION = @AG_VERSION@ +AG_XML2 = @AG_XML2@ +AGexe = @AGexe@ +AGnam = @AGnam@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AO_AGE = @AO_AGE@ +AO_CURRENT = @AO_CURRENT@ +AO_REVISION = @AO_REVISION@ +AO_TEMPLATE_VERSION = @AO_TEMPLATE_VERSION@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CLexe = @CLexe@ +CLnam = @CLnam@ +CONFIG_SHELL = @CONFIG_SHELL@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEBUG_ENABLED = @DEBUG_ENABLED@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +DYNAMIC_AG = @DYNAMIC_AG@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ENABLE_STATIC = @ENABLE_STATIC@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GDexe = @GDexe@ +GDnam = @GDnam@ +GO_AGE = @GO_AGE@ +GO_CURRENT = @GO_CURRENT@ +GO_REVISION = @GO_REVISION@ +GREP = @GREP@ +GUILE_CFLAGS = @GUILE_CFLAGS@ +GUILE_EFFECTIVE_VERSION = @GUILE_EFFECTIVE_VERSION@ +GUILE_LDFLAGS = @GUILE_LDFLAGS@ +GUILE_LIBS = @GUILE_LIBS@ +GUILE_LTLIBS = @GUILE_LTLIBS@ +HOST_CPU = @HOST_CPU@ +HOST_CPU_C_ABI = @HOST_CPU_C_ABI@ +INCLIST = @INCLIST@ +INCSNPRINTFV = @INCSNPRINTFV@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSNPRINTFV = @LIBSNPRINTFV@ +LIBTOOL = @LIBTOOL@ +LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ +LIBXML2_LIBS = @LIBXML2_LIBS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +M4_SRC = @M4_SRC@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPTS_TESTDIR = @OPTS_TESTDIR@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POSIX_SHELL = @POSIX_SHELL@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STDNORETURN_H = @STDNORETURN_H@ +STRIP = @STRIP@ +TEXI2HTML = @TEXI2HTML@ +VERSION = @VERSION@ +WARN_CFLAGS = @WARN_CFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_aux_dir = @ac_aux_dir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +AM_CPPFLAGS = -I$(top_srcdir) +noinst_HEADERS = mem.h filament.h stream.h printf.h compat.h +dist_noinst_DATA = filament.stamp stream.stamp printf.stamp +noinst_LTLIBRARIES = libsnprintfv.la +libsnprintfv_la_LDFLAGS = -no-undefined +CSRC = filament.c format.c printf.c mem.c stream.c custom.c +nodist_libsnprintfv_la_SOURCES = snv.c + +# These files are the raw sources used to generate similarly named +# header files after extracting the prototypes from the sources +# +EXTRA_DIST = filament.in printf.in stream.in $(CSRC) +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu snprintfv/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu snprintfv/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +libsnprintfv.la: $(libsnprintfv_la_OBJECTS) $(libsnprintfv_la_DEPENDENCIES) $(EXTRA_libsnprintfv_la_DEPENDENCIES) + $(AM_V_CCLD)$(libsnprintfv_la_LINK) $(libsnprintfv_la_OBJECTS) $(libsnprintfv_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/snv.Plo@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) $(DATA) $(HEADERS) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/snv.Plo + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/snv.Plo + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-libtool clean-noinstLTLIBRARIES \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + + +snv.c : $(CSRC) + for f in $(CSRC) ; do echo "#include \"$$f\"" ; done > $@ + +.NOTPARALLEL: + +# Makefile.am ends here + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/snprintfv/README b/snprintfv/README new file mode 100644 index 0000000..9251106 --- /dev/null +++ b/snprintfv/README @@ -0,0 +1,30 @@ +This is libsnprintfv, a portable, extensible reimplementation of the +POSIX format printing API. libsnprintfv provides all the features +which should be present in a POSIX format printing implementation, +but which often are not, such as guaranteed return of number of +characters printed and support for %n$ format specifiers. + +In addition the the POSIX features, libsnprintfv also provides some +extensions to the API, and a GNU glibc-2 compatible printf custom +format specifier, all of which you can use with impunity if you link +with libsnprintfv, rather than worrying about whether the target C +library provides the extensions. See the info manual for details of +the API calls available, and an explanation of how to write custom +specifier handlers. + +The latest version of libsnprintfv is available from the author's +homepage: http://www.oranda.demon.co.uk. + +libsnprintfv is written in a very portable K&R compatible style, and +should build anywhere that provides a reasonable C compiler and runtime. +See the file INSTALL for instructions on how to build and install +libsnprintfv. + +See the file NEWS for a description of user visible changes to +libsnprintfv between releases. + +See the file TODO for a list of outstanding work. + +If you have any suggestions or bug reports, please send email to the +author at . + diff --git a/snprintfv/THANKS b/snprintfv/THANKS new file mode 100644 index 0000000..0480bbe --- /dev/null +++ b/snprintfv/THANKS @@ -0,0 +1,13 @@ +libsnprintfv would not be what it is without the invaluable help of +these people: + +Everybody who was kind enough to spend time testing libsnprintfv, +use it in their packages and report bugs. + +The following people made especially gracious contributions of their +time and energy in helping to track down bugs, port to new systems, +and generally assist in the maintainership process: + +Bruce Korb +Kaveh R. Ghazi +Robert Lipe diff --git a/snprintfv/compat.h b/snprintfv/compat.h new file mode 100644 index 0000000..e3fa52f --- /dev/null +++ b/snprintfv/compat.h @@ -0,0 +1,329 @@ +/* -*- Mode: C -*- + * -------------------------------------------------------------------- + * compat.h.in --- verbose but portable cpp defines for snprintfv + * Copyright (C) 1999 Gary V. Vaughan + * Originally by Gary V. Vaughan, 1999 + * This file is part of Snprintfv + * + * Snprintfv 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. + * + * Snprintfv 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 . + * + * As a special exception to the GNU General Public License, if you + * distribute this file as part of a program that also links with and + * uses the libopts library from AutoGen, you may include it under + * the same distribution terms used by the libopts library. + * + * Code: */ + +#ifndef SNPRINTFV_COMPAT_H +#define SNPRINTFV_COMPAT_H 1 + +#define _GNU_SOURCE 1 /* for strsignal in GNU's libc */ +#define __USE_GNU 1 // likewise +#define __EXTENSIONS__ 1 /* and another way to call for it */ + +#ifdef __cplusplus +#define SNV_START_EXTERN_C extern "C" { +SNV_START_EXTERN_C +#define SNV_END_EXTERN_C } +#else +#define SNV_END_EXTERN_C +#endif /* __cplusplus */ + +#define NO_FLOAT_PRINTING + +#ifdef HAVE_SYS_TYPES_H +# include +#endif + +#include + +#ifdef HAVE_STDLIB_H +# include +#endif + +#ifdef HAVE_ERRNO_H +# include +# ifndef errno + /* Some sytems #define this! */ + extern int errno; +# endif +#endif + +#if defined( HAVE_LIMITS_H ) +# include + +#elif defined( HAVE_SYS_LIMITS_H ) +# include + +#elif defined( HAVE_VALUES_H ) +# ifndef MAXINT +# include +# endif /* MAXINT */ +#endif + +#if defined( HAVE_STRING_H ) +# include + +#elif defined( HAVE_STRINGS_H ) +# include +#endif + +#if defined( HAVE_MEMORY_H ) +# include +#endif + +#if defined( HAVE_INTTYPES_H ) +# include + +#elif defined( HAVE_STDINT_H ) +# include +#endif + +#ifndef HAVE_UINTMAX_T +# if defined( HAVE_LONG_LONG ) + typedef long long intmax_t; + typedef unsigned long long uintmax_t; +# else + typedef long intmax_t; + typedef unsigned long uintmax_t; +# endif +#endif + +#if defined( HAVE_STDARG_H ) +# include +# ifndef VA_START +# define VA_START(a, f) va_start(a, f) +# define VA_END(a) va_end(a) +# endif /* VA_START */ +# define SNV_USING_STDARG_H +#elif defined( HAVE_VARARGS_H ) +# include +# ifndef VA_START +# define VA_START(a, f) va_start(a) +# define VA_END(a) va_end(a) +# endif /* VA_START */ +# undef SNV_USING_STDARG_H +#else +# include "must-have-stdarg-or-varargs" +#endif + +#if HAVE_RUNETYPE_H +# include +#endif + +#ifdef HAVE_WCHAR_H +# include +#endif + +#ifdef HAVE_WCHAR_T +typedef wchar_t snv_wchar_t; +#else +typedef int snv_wchar_t; +#endif + +#ifdef HAVE_WINT_T +typedef wint_t snv_wint_t; +#else +typedef int snv_wint_t; +#endif + +/* inline and const keywords are (mostly) handled by config.h */ +#ifdef __GNUC__ + +# define GCC_VERSION (__GNUC__ * 10000 \ + + __GNUC_MINOR__ * 100 \ + + __GNUC_PATCHLEVEL__) + +# if GCC_VERSION > 40400 +# pragma GCC diagnostic ignored "-Wextra" +# pragma GCC diagnostic ignored "-Wconversion" +# pragma GCC diagnostic ignored "-Wsign-conversion" +# pragma GCC diagnostic ignored "-Wstrict-overflow" +# endif + +# ifndef const +# define const __const +# endif +# ifndef inline +# define inline __inline +# endif +# ifndef signed +# define signed __signed +# endif + +#else +# define GCC_VERSION 0 +# ifndef __STDC__ +# undef signed +# define signed +# endif +#endif + +#ifdef __STDC__ +# define _SNV_STR(x) #x + typedef void *snv_pointer; + typedef const void *snv_constpointer; +#else +# define _SNV_STR(x) "x" + typedef char *snv_pointer; + typedef char *snv_constpointer; +#endif + +#if defined(HAVE_FPUTC_UNLOCKED) && defined(HAVE_FLOCKFILE) +# define SNV_FPUTC_UNLOCKED fputc_unlocked +# define SNV_PUTC_UNLOCKED putc_unlocked +# define SNV_WITH_LOCKED_FP(fp, tmp_var) \ + for (flockfile (fp), tmp_var = 1; \ + tmp_var--; funlockfile (fp)) +#else +# define SNV_FPUTC_UNLOCKED fputc +# define SNV_PUTC_UNLOCKED putc +# define SNV_WITH_LOCKED_FP(fp, tmp_var) \ + for (tmp_var = 1; tmp_var--; ) +#endif + +/* + * Define macros for storing integers inside pointers. + * Be aware that it is only safe to use these macros to store `int' + * values in `char*' (or `void*') words, and then extract them later. + * Although it will work the other way round on many common + * architectures, it is not portable to assume a `char*' can be + * stored in an `int' and extracted later without loss of the msb's + */ +#define SNV_POINTER_TO_LONG(p) ((long)(p)) +#define SNV_POINTER_TO_ULONG(p) ((unsigned long)(p)) +#define SNV_LONG_TO_POINTER(i) ((snv_pointer)(long)(i)) +#define SNV_ULONG_TO_POINTER(u) ((snv_pointer)(unsigned long)(u)) + +#ifdef HAVE_STDBOOL_H +#include +#else +typedef enum { + false = 0, + true = 1 +} bool; +#endif + +#ifdef __CYGWIN32__ +# ifndef __CYGWIN__ +# define __CYGWIN__ +# endif +#endif +#ifdef __CYGWIN__ +# ifndef _WIN32 +# define _WIN32 +# endif +#endif + +#ifndef PARAMS +# define PARAMS(args) args +#endif + +#undef SNV_STMT_START +#undef SNV_STMT_END +#if defined (__GNUC__) && !defined (__STRICT_ANSI__) && !defined (__cplusplus) +# define SNV_STMT_START (void)( +# define SNV_STMT_END ) + +#elif (defined (sun) || defined (__sun__)) +# define SNV_STMT_START if (1) +# define SNV_STMT_END else (void)0 + +#else +# define SNV_STMT_START do +# define SNV_STMT_END while (false) +#endif + +#ifdef _WIN32 +# ifdef DLL_EXPORT +# define SNV_SCOPE extern __declspec(dllexport) +# else +# ifdef LIBSNPRINTFV_DLL_IMPORT +# define SNV_SCOPE extern __declspec(dllimport) +# endif +# endif +#endif +#ifndef SNV_SCOPE +# define SNV_SCOPE extern +#endif + +#undef SNV_GNUC_PRINTF +#undef SNV_GNUC_NORETURN +#if GCC_VERSION > 20400 +# define SNV_GNUC_PRINTF( args, format_idx, arg_idx ) \ + args __attribute__((format (printf, format_idx, arg_idx))) +# define SNV_GNUC_NORETURN \ + __attribute__((__noreturn__)) +# define SNV_ASSERT_FCN " (", __PRETTY_FUNCTION__, ")" +#else /* GCC_VERSION */ +# define SNV_GNUC_PRINTF( args, format_idx, arg_idx ) args +# define SNV_GNUC_NORETURN +# define SNV_ASSERT_FCN "", "", "" +#endif /* GCC_VERSION */ + +#define SNV_ASSERT_FMT "file %s: line %d%s%s%s: assertion \"%s\" failed.\n" + +#define snv_assert(expr) snv_fassert(stderr, expr) +#define snv_fassert(stream, expr) SNV_STMT_START { \ + if (!(expr)) { \ + fprintf (stream, SNV_ASSERT_FMT, __FILE__, __LINE__, \ + SNV_ASSERT_FCN, _SNV_STR(expr)); \ + exit(EXIT_FAILURE); \ + }; } SNV_STMT_END + +#define return_if_fail(expr) freturn_if_fail(stderr, expr) +#define freturn_if_fail(expr) SNV_STMT_START { \ + if (!(expr)) { \ + fprintf (stream, SNV_ASSERT_FMT, __FILE__, __LINE__, \ + SNV_ASSERT_FCN, _SNV_STR(expr)); \ + return; \ + }; } SNV_STMT_END + +#define return_val_if_fail(expr, val) freturn_val_if_fail(stderr, expr, val) +#define freturn_val_if_fail(stream, expr, val) SNV_STMT_START { \ + if (!(expr)) { \ + fprintf (stream, SNV_ASSERT_FMT, __FILE__, __LINE__, \ + SNV_ASSERT_FCN, _SNV_STR(expr)); \ + return val; \ + }; } SNV_STMT_END + +#ifndef MAX +#define MAX(a,b) ((a) > (b) ? (a) : (b)) +#endif + +#ifndef MIN +#define MIN(a,b) ((a) < (b) ? (a) : (b)) +#endif + +#ifndef ABS +#define ABS(a) ((a) < 0 ? -(a) : (a)) +#endif + +typedef SNV_LONG_DOUBLE snv_long_double; + +#ifndef HAVE_STRTOUL +extern unsigned long +strtoul( const char *nptrm, char **endptr, register int base ); +#endif + +SNV_END_EXTERN_C +#endif /* SNPRINTFV_COMPAT_H */ + +/* + * Local Variables: + * mode: C + * c-file-style: "gnu" + * indent-tabs-mode: nil + * End: + * end of snprintfv/compat.h */ diff --git a/snprintfv/custom.c b/snprintfv/custom.c new file mode 100644 index 0000000..b50a78b --- /dev/null +++ b/snprintfv/custom.c @@ -0,0 +1,181 @@ +/* -*- Mode: C -*- */ + +/* custom.c --- printf clone for argv arrays + * Copyright (C) 2003 Gary V. Vaughan + * Originally by Paolo Bonzini, 2002 + * This file is part of Snprintfv + * + * Snprintfv 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. + * + * Snprintfv 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 . + * + * As a special exception to the GNU General Public License, if you + * distribute this file as part of a program that also links with and + * uses the libopts library from AutoGen, you may include it under + * the same distribution terms used by the libopts library. + */ + +/* Code: */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#ifdef WITH_DMALLOC +# include +#endif + +#include + +#if HAVE_RUNETYPE_H +# include +#endif + +#ifdef HAVE_WCHAR_H +# include +#endif + +#include "printf.h" + + + +/** + * printf_generic_info: + * @pinfo: the current state information for the format + * string parser. + * @n: the number of available slots in the @argtypes array + * @argtypes: the pointer to the first slot to be filled by the + * function + * + * An example implementation of a %printf_arginfo_function, which + * takes the basic type from the type given in the %spec_entry + * and adds flags depending on what was parsed (e.g. %PA_FLAG_SHORT + * is %pparser->is_short and so on). + * + * Return value: + * Always 1. + */ +int +printf_generic_info (struct printf_info *const pinfo, size_t n, int *argtypes) +{ + int type = pinfo->type; + + if (!n) + return 1; + + if ((type & PA_TYPE_MASK) == PA_POINTER) + type |= PA_FLAG_UNSIGNED; + + if (pinfo->is_char) + type = PA_CHAR; + + if (pinfo->is_short) + type |= PA_FLAG_SHORT; + + if (pinfo->is_long) + type |= PA_FLAG_LONG; + + if (pinfo->is_long_double) + type |= PA_FLAG_LONG_LONG; + + argtypes[0] = type; + return 1; +} + + +/** + * printf_generic: + * @stream: the stream (possibly a struct printfv_stream appropriately + * cast) on which to write output. + * @pinfo: the current state information for the format string parser. + * @args: the pointer to the first argument to be read by the handler + * + * An example implementation of a %printf_function, used to provide easy + * access to justification, width and precision options. + * + * Return value: + * The number of characters output. + **/ +int +printf_generic (STREAM *stream, struct printf_info *const pinfo, union printf_arg const *args) +{ + int len = 0, count_or_errorcode = SNV_OK; + char *p = NULL; + + /* Used to interface to the custom function. */ + STREAM *out; + Filament *fil; + printf_function *user_func = (printf_function *) pinfo->extra; + + return_val_if_fail (pinfo != NULL, SNV_ERROR); + + /* Read these now to advance the argument pointer appropriately */ + if (pinfo->prec == -1) + pinfo->prec = 0; + + /* Check for valid pre-state. */ + if (pinfo->prec <= -1) + { + PRINTF_ERROR (pinfo, "invalid flags"); + return -1; + } + + /* Print to a stream using a user-supplied function. */ + fil = filnew (NULL, (size_t)0); + out = stream_new (fil, SNV_UNLIMITED, NULL, snv_filputc); + user_func (out, pinfo, args); + stream_delete (out); + len = (int)fillen (fil); + p = fildelete (fil); + + /* Left pad to the width if the supplied argument is less than + the width specifier. */ + if (p != NULL && pinfo->prec && pinfo->prec < len) + len = pinfo->prec; + + if ((len < pinfo->width) && !pinfo->left) + { + int padwidth = pinfo->width - len; + while ((count_or_errorcode >= 0) && (count_or_errorcode < padwidth)) + SNV_EMIT (pinfo->pad, stream, count_or_errorcode); + } + + /* Fill the buffer with as many characters from the format argument + * as possible without overflowing or exceeding the precision. + */ + if ((count_or_errorcode >= 0) && (p != NULL)) + { + int mark = count_or_errorcode; + while ((count_or_errorcode >= 0) && *p != '\0' + && ((pinfo->prec == 0) || (count_or_errorcode - mark < len))) + SNV_EMIT (*p++, stream, count_or_errorcode); + } + + /* Right pad to the width if we still didn't reach the specified + * width and the left justify flag was set. + */ + if ((count_or_errorcode < pinfo->width) && pinfo->left) + while ((count_or_errorcode >= 0) + && (count_or_errorcode < pinfo->width)) + SNV_EMIT (pinfo->pad, stream, count_or_errorcode); + + /* Return the number of characters emitted. */ + return count_or_errorcode; +} + +/* + * Local Variables: + * mode: C + * c-file-style: "gnu" + * indent-tabs-mode: nil + * End: + * end of snprintfv/custom.c */ diff --git a/snprintfv/filament.c b/snprintfv/filament.c new file mode 100644 index 0000000..4f6af29 --- /dev/null +++ b/snprintfv/filament.c @@ -0,0 +1,231 @@ +/* -*- Mode: C -*- */ + +/* filament.c --- a bit like a string, but different =)O| + * Copyright (C) 1999 Gary V. Vaughan + * Originally by Gary V. Vaughan, 1999 + * This file is part of Snprintfv + * + * Snprintfv 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. + * + * Snprintfv 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 . + * + * As a special exception to the GNU General Public License, if you + * distribute this file as part of a program that also links with and + * uses the libopts library from AutoGen, you may include it under + * the same distribution terms used by the libopts library. + */ + +/* Commentary: + * + * Try to exploit usage patterns to optimise string handling, and + * as a happy consequence handle NUL's embedded in strings properly. + * + * o Since finding the length of a (long) string is time consuming and + * requires careful coding to cache the result in local scope: We + * keep count of the length of a Filament all the time, so finding the + * length is O(1) at the expense of a little bookkeeping while + * manipulating the Filament contents. + * + * o Constantly resizing a block of memory to hold a string is memory + * efficient, but slow: Filaments are only ever expanded in size, + * doubling at each step to minimise the number of times the block + * needs to be reallocated and the contents copied (this problem is + * especially poignant for very large strings). + * + * o Most strings tend to be either relatively small and short-lived, + * or else long-lived but growing in asymptotically in size: To + * care for the former case, Filaments start off with a modest static + * buffer for the string contents to avoid any mallocations (except + * the initial one to get the structure!); the latter case is handled + * gracefully by the resizing algorithm in the previous point. + * + * o Extracting a C-style NUL terminated string from the Filament is + * an extremely common operation: We ensure there is always a + * terminating NUL character after the last character in the string + * so that the conversion can be performed quickly. + * + * In summary, Filaments are good where you need to do a lot of length + * calculations with your strings and/or gradually append more text + * onto existing strings. Filaments are also an easy way to get 8-bit + * clean strings is a more lightweight approach isn't required. + * + * They probably don't buy much if you need to do insertions and partial + * deletions, but optimising for that is a whole other problem! + */ + +/* Code: */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#ifdef WITH_DMALLOC +# include +#endif + +#include "mem.h" +#include "filament.h" + + + +/** + * filnew: constructor + * @init: address of the first byte to copy into the new object. + * @len: the number of bytes to copy into the new object. + * + * Create a new Filament object, initialised to hold a copy of the + * first @len bytes starting at address @init. If @init is NULL, or + * @len is 0 (or less), then the initialised Filament will return the + * empty string, "", if its value is queried. + * + * Return value: + * A newly created Filament object is returned. + **/ +Filament * +filnew (const char *const init, size_t len) +{ + Filament *new; + + new = snv_new (Filament, 1); + + new->value = new->buffer; + new->length = 0; + new->size = FILAMENT_BUFSIZ; + + return (init || len) ? filinit (new, init, len) : new; +} + +/** + * filinit: + * @fil: The Filament object to initialise. + * @init: address of the first byte to copy into the new object. + * @len: the number of bytes to copy into the new object. + * + * Initialise a Filament object to hold a copy of the first @len bytes + * starting at address @init. If @init is NULL, or @len is 0 (or less), + * then the Filament will be reset to hold the empty string, "". + * + * Return value: + * The initialised Filament object is returned. + **/ +Filament * +filinit (Filament *fil, const char *const init, size_t len) +{ + if (init == NULL || len < 1) + { + /* Recycle any dynamic memory assigned to the previous + contents of @fil, and point back into the static buffer. */ + if (fil->value != fil->buffer) + snv_delete (fil->value); + + fil->value = fil->buffer; + fil->length = 0; + fil->size = FILAMENT_BUFSIZ; + } + else + { + if (len < FILAMENT_BUFSIZ) + { + /* We have initialisation data which will easily fit into + the static buffer: recycle any memory already assigned + and initialise in the static buffer. */ + if (fil->value != fil->buffer) + { + snv_delete (fil->value); + fil->value = fil->buffer; + fil->size = FILAMENT_BUFSIZ; + } + } + else + { + /* If we get to here then we never try to shrink the already + allocated dynamic buffer (if any), we just leave it in + place all ready to expand into later... */ + fil_maybe_extend (fil, len, false); + } + + snv_assert (len < fil->size); + + fil->length = len; + memcpy (fil->value, init, len); + } + + return fil; +} + +/** + * fildelete: destructor + * @fil: The Filament object for recycling. + * + * The memory being used by @fil is recycled. + * + * Return value: + * The original contents of @fil are converted to a null terminated + * string which is returned, either to be freed itself or else used + * as a normal C string. The entire Filament contents are copied into + * this string including any embedded nulls. + **/ +char * +fildelete (Filament *fil) +{ + char *value; + + if (fil->value == fil->buffer) + { + value = memcpy (snv_new (char, 1 + fil->length), + fil->buffer, 1 + fil->length); + value[fil->length] = '\0'; + } + else + value = filval (fil); + + snv_delete (fil); + + return value; +} + +/** + * _fil_extend: + * @fil: The Filament object which may need more string space. + * @len: The length of the data to be stored in @fil. + * @copy: whether to copy data from the static buffer on reallocation. + * + * This function will will assign a bigger block of memory to @fil + * considering the space left in @fil and @len, the length required + * for the prospective contents. + */ +void +_fil_extend (Filament *fil, size_t len, bool copy) +{ + /* Usually we will simply double the amount of space previously + allocated, but if the extra data is larger than the current + size it *still* won't fit, so in that case we allocate enough + room plus some we leave the current free space to expand into. */ + fil->size += MAX (len, fil->size); + + if (fil->value == fil->buffer) + { + fil->value = snv_new (char, fil->size); + if (copy) + memcpy (fil->value, fil->buffer, fil->length); + } + else + fil->value = snv_renew (char, fil->value, fil->size); +} + +/* + * Local Variables: + * mode: C + * c-file-style: "gnu" + * indent-tabs-mode: nil + * End: + * end of snprintfv/filament.c */ diff --git a/snprintfv/filament.h b/snprintfv/filament.h new file mode 100644 index 0000000..d00aefc --- /dev/null +++ b/snprintfv/filament.h @@ -0,0 +1,256 @@ +/* -*- Mode: C -*- */ + +/* filament.h --- a bit like a string but different =)O| + * Copyright (C) 1998, 1999, 2000, 2002 Gary V. Vaughan + * Originally by Gary V. Vaughan, 1998 + * This file is part of Snprintfv + * + * Snprintfv 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. + * + * Snprintfv 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 . + * + * As a special exception to the GNU General Public License, if you + * distribute this file as part of a program that also links with and + * uses the libopts library from AutoGen, you may include it under + * the same distribution terms used by the libopts library. + */ + +/* Code: */ + +#ifndef FILAMENT_H +#define FILAMENT_H 1 + +#include + +#ifdef __cplusplus +extern "C" +{ +#if 0 +/* This brace is so that emacs can still indent properly: */ } +#endif +#endif /* __cplusplus */ + +#define FILAMENT_BUFSIZ (512 - sizeof(char *) - (2 * sizeof(size_t))) + +/** + * Filament: + * Opaque data type used to hold 8-bit clean dynamic strings which know + * their own length and resize themselves to avoid buffer overruns. + **/ +typedef struct filament Filament; + +struct filament +{ + char *value; /* pointer to the start of the string */ + size_t length; /* length of the string */ + size_t size; /* total memory allocated */ + char buffer[FILAMENT_BUFSIZ]; /* usually string == &buffer[0] */ +}; + +/** + * filnew: constructor + * @init: address of the first byte to copy into the new object. + * @len: the number of bytes to copy into the new object. + * + * Create a new Filament object, initialised to hold a copy of the + * first @len bytes starting at address @init. If @init is NULL, or + * @len is 0 (or less), then the initialised Filament will return the + * empty string, "", if its value is queried. + * + * Return value: + * A newly created Filament object is returned. + **/ +extern Filament * +filnew (const char *const init, size_t len); + +/** + * filinit: + * @fil: The Filament object to initialise. + * @init: address of the first byte to copy into the new object. + * @len: the number of bytes to copy into the new object. + * + * Initialise a Filament object to hold a copy of the first @len bytes + * starting at address @init. If @init is NULL, or @len is 0 (or less), + * then the Filament will be reset to hold the empty string, "". + * + * Return value: + * The initialised Filament object is returned. + **/ +extern Filament * +filinit (Filament *fil, const char *const init, size_t len); + +/** + * fildelete: destructor + * @fil: The Filament object for recycling. + * + * The memory being used by @fil is recycled. + * + * Return value: + * The original contents of @fil are converted to a null terminated + * string which is returned, either to be freed itself or else used + * as a normal C string. The entire Filament contents are copied into + * this string including any embedded nulls. + **/ +extern char * +fildelete (Filament *fil); + +/** + * _fil_extend: + * @fil: The Filament object which may need more string space. + * @len: The length of the data to be stored in @fil. + * @copy: whether to copy data from the static buffer on reallocation. + * + * This function will will assign a bigger block of memory to @fil + * considering the space left in @fil and @len, the length required + * for the prospective contents. + */ +extern void +_fil_extend (Filament *fil, size_t len, bool copy); + +#line 60 "filament.in" + +/* Save the overhead of a function call in the great majority of cases. */ +#define fil_maybe_extend(fil, len, copy) \ + (((len)>=(fil)->size) ? _fil_extend((fil), (len), (copy)) : (void)0) + +/** + * filval: + * @fil: The Filament object being queried. + * + * Return value: + * A pointer to the null terminated string held by the Filament + * object is returned. Since the @fil may contain embedded nulls, it + * is not entirely safe to use the strfoo() API to examine the contents + * of the return value. + **/ +SNV_INLINE char * +filval (Filament *fil) +{ + /* Because we have been careful to ensure there is always at least + one spare byte of allocated memory, it is safe to set it here. */ + fil->value[fil->length] = '\0'; + return (char *) (fil->value); +} + +/** + * fillen: + * @fil: The Filament object being queried. + * + * Return value: + * The length of @fil, including any embedded nulls, but excluding the + * terminating null, is returned. + **/ +SNV_INLINE size_t +fillen (Filament *fil) +{ + return fil->length; +} + +/** + * filelt: + * @fil: The Filament being queried. + * @n: A zero based index into @fil. + * + * This function looks for the @n'th element of @fil. + * + * Return value: + * If @n is an index inside the Filament @fil, then the character stored + * at that index cast to an int is returned, otherwise @n is outside + * this range and -1 is returned. + **/ +SNV_INLINE int +filelt (Filament *fil, ssize_t n) +{ + if ((n >= 0) && (n < (ssize_t)fil->length)) + return (int) fil->value[n]; + else + return -1; +} + +/** + * filncat: + * @fil: The destination Filament of the concatenation. + * @str: The address of the source bytes for concatenation. + * @n: The number of bytes to be copied from @str. + * + * @n bytes starting with the byte at address @str are destructively + * concatenated to @fil. If necessary, @fil is dynamically reallocated + * to make room for this operation. + * + * Return value: + * A pointer to the (not null terminated) string which is the result + * of this concatenation is returned. + **/ +SNV_INLINE char * +filncat (Filament *fil, const char *str, size_t n) +{ + fil_maybe_extend (fil, n + fil->length, true); + memcpy (fil->value + fil->length, str, n); + fil->length += n; + return fil->value; +} + +/** + * filcat: + * @fil: The destination Filament of the concatenation. + * @str: The address of the source bytes for concatenation. + * + * The bytes starting at address @str upto and including the first null + * byte encountered are destructively concatenated to @fil. If + * necessary @fil is dynamically reallocated to make room for this + * operation. + * + * Return value: + * A pointer to the (not null terminated) string which is the result + * of this concatenation is returned. + **/ +SNV_INLINE char * +filcat (Filament *fil, const char *str) +{ + size_t length = strlen (str); + return filncat (fil, str, length); +} + +/** + * filccat: + * @fil: The destination Filament of the concatenation. + * @c: The character to append to @fil. + * + * @c is destructively concatenated to @fil. If necessary, @fil is + * dynamically reallocated to make room for this operation. When used + * repeatedly this function is less efficient than %filncat, + * since it must check whether to extend the filament before each + * character is appended. + * + * Return value: + * A pointer to the (not null terminated) string which is the result + * of this concatenation is returned. + **/ +SNV_INLINE char * +filccat (Filament *fil, int c) +{ + fil_maybe_extend (fil, 1 + fil->length, true); + fil->value[fil->length++] = (char)(c & 0xFF); + return fil->value; +} + +#ifdef __cplusplus +#if 0 +/* This brace is so that emacs can still indent properly: */ +{ +#endif +} +#endif /* __cplusplus */ + +#endif /* FILAMENT_H */ + +/* filament.h ends here */ diff --git a/snprintfv/filament.in b/snprintfv/filament.in new file mode 100644 index 0000000..a21a574 --- /dev/null +++ b/snprintfv/filament.in @@ -0,0 +1,196 @@ +/* -*- Mode: C -*- */ + +/* filament.h --- a bit like a string but different =)O| + * Copyright (C) 1998, 1999, 2000, 2002 Gary V. Vaughan + * Originally by Gary V. Vaughan, 1998 + * This file is part of Snprintfv + * + * Snprintfv 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. + * + * Snprintfv 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 . + * + * As a special exception to the GNU General Public License, if you + * distribute this file as part of a program that also links with and + * uses the libopts library from AutoGen, you may include it under + * the same distribution terms used by the libopts library. + */ + +/* Code: */ + +#ifndef FILAMENT_H +#define FILAMENT_H 1 + +#include + +#ifdef __cplusplus +extern "C" +{ +#if 0 +/* This brace is so that emacs can still indent properly: */ } +#endif +#endif /* __cplusplus */ + +#define FILAMENT_BUFSIZ (512 - sizeof(char *) - (2 * sizeof(size_t))) + +/** + * Filament: + * Opaque data type used to hold 8-bit clean dynamic strings which know + * their own length and resize themselves to avoid buffer overruns. + **/ +typedef struct filament Filament; + +struct filament +{ + char *value; /* pointer to the start of the string */ + size_t length; /* length of the string */ + size_t size; /* total memory allocated */ + char buffer[FILAMENT_BUFSIZ]; /* usually string == &buffer[0] */ +}; + +@protos filament.c + +/* Save the overhead of a function call in the great majority of cases. */ +#define fil_maybe_extend(fil, len, copy) \ + (((len)>=(fil)->size) ? _fil_extend((fil), (len), (copy)) : (void)0) + +/** + * filval: + * @fil: The Filament object being queried. + * + * Return value: + * A pointer to the null terminated string held by the Filament + * object is returned. Since the @fil may contain embedded nulls, it + * is not entirely safe to use the strfoo() API to examine the contents + * of the return value. + **/ +SNV_INLINE char * +filval (Filament *fil) +{ + /* Because we have been careful to ensure there is always at least + one spare byte of allocated memory, it is safe to set it here. */ + fil->value[fil->length] = '\0'; + return (char *) (fil->value); +} + +/** + * fillen: + * @fil: The Filament object being queried. + * + * Return value: + * The length of @fil, including any embedded nulls, but excluding the + * terminating null, is returned. + **/ +SNV_INLINE size_t +fillen (Filament *fil) +{ + return fil->length; +} + +/** + * filelt: + * @fil: The Filament being queried. + * @n: A zero based index into @fil. + * + * This function looks for the @n'th element of @fil. + * + * Return value: + * If @n is an index inside the Filament @fil, then the character stored + * at that index cast to an int is returned, otherwise @n is outside + * this range and -1 is returned. + **/ +SNV_INLINE int +filelt (Filament *fil, ssize_t n) +{ + if ((n >= 0) && (n < (ssize_t)fil->length)) + return (int) fil->value[n]; + else + return -1; +} + +/** + * filncat: + * @fil: The destination Filament of the concatenation. + * @str: The address of the source bytes for concatenation. + * @n: The number of bytes to be copied from @str. + * + * @n bytes starting with the byte at address @str are destructively + * concatenated to @fil. If necessary, @fil is dynamically reallocated + * to make room for this operation. + * + * Return value: + * A pointer to the (not null terminated) string which is the result + * of this concatenation is returned. + **/ +SNV_INLINE char * +filncat (Filament *fil, const char *str, size_t n) +{ + fil_maybe_extend (fil, n + fil->length, true); + memcpy (fil->value + fil->length, str, n); + fil->length += n; + return fil->value; +} + +/** + * filcat: + * @fil: The destination Filament of the concatenation. + * @str: The address of the source bytes for concatenation. + * + * The bytes starting at address @str upto and including the first null + * byte encountered are destructively concatenated to @fil. If + * necessary @fil is dynamically reallocated to make room for this + * operation. + * + * Return value: + * A pointer to the (not null terminated) string which is the result + * of this concatenation is returned. + **/ +SNV_INLINE char * +filcat (Filament *fil, const char *str) +{ + size_t length = strlen (str); + return filncat (fil, str, length); +} + +/** + * filccat: + * @fil: The destination Filament of the concatenation. + * @c: The character to append to @fil. + * + * @c is destructively concatenated to @fil. If necessary, @fil is + * dynamically reallocated to make room for this operation. When used + * repeatedly this function is less efficient than %filncat, + * since it must check whether to extend the filament before each + * character is appended. + * + * Return value: + * A pointer to the (not null terminated) string which is the result + * of this concatenation is returned. + **/ +SNV_INLINE char * +filccat (Filament *fil, int c) +{ + fil_maybe_extend (fil, 1 + fil->length, true); + fil->value[fil->length++] = (char)(c & 0xFF); + return fil->value; +} + +#ifdef __cplusplus +#if 0 +/* This brace is so that emacs can still indent properly: */ +{ +#endif +} +#endif /* __cplusplus */ + +#endif /* FILAMENT_H */ + +/* filament.h ends here */ diff --git a/snprintfv/filament.stamp b/snprintfv/filament.stamp new file mode 100644 index 0000000..e69de29 diff --git a/snprintfv/format.c b/snprintfv/format.c new file mode 100644 index 0000000..e684bdf --- /dev/null +++ b/snprintfv/format.c @@ -0,0 +1,1282 @@ +/* -*- Mode: C -*- */ + +/* format.c --- printf clone for argv arrays + * Copyright (C) 1998, 1999, 2000, 2002 Gary V. Vaughan + * Originally by Gary V. Vaughan, 1998 + * This file is part of Snprintfv + * + * Snprintfv 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. + * + * Snprintfv 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 . + * + * As a special exception to the GNU General Public License, if you + * distribute this file as part of a program that also links with and + * uses the libopts library from AutoGen, you may include it under + * the same distribution terms used by the libopts library. + */ + +/* Code: */ + +#include "compat.h" + +#ifdef HAVE_LIMITS_H +#include +#else +#include +#endif + +#ifdef WITH_DMALLOC +# include +#endif + +#include +#include +#include + +#if HAVE_RUNETYPE_H +# include +#endif + +#ifdef HAVE_WCHAR_H +# include +#endif + +#include "printf.h" + +#ifndef NO_FLOAT_PRINTING +# ifdef HAVE_LONG_DOUBLE +# ifndef HAVE_ISNANL +# define isnanl(x) ((x) != (x)) +# endif +# ifndef HAVE_ISINFL +# define isinfl(x) isnanl ((x) - (x)) +# endif +# ifndef HAVE_MODFL +static snv_long_double modfl (long double x, long double *exp); +# endif +# ifndef HAVE_COPYSIGNL +static snv_long_double copysignl (long double x, long double y); +# endif +# else +# ifdef HAVE_ISNAN +# define isnanl isnan +# else +# define isnanl(x) ((x) != (x)) +# endif +# ifdef HAVE_ISINF +# define isinfl isinf +# else +# define isinfl(x) isnanl ((x) - (x)) +# endif +# ifdef HAVE_COPYSIGN +# define copysignl copysign +# else +# define copysign(x, y) (((x) < 0.0 ^ (y) < 0.0) ? (x) * -1.0 : (x)); +# endif +# define modfl modf +# endif +#endif + + +static uintmax_t +fetch_uintmax (struct printf_info *pinfo, union printf_arg const *arg) +{ + if (pinfo->is_long_double) + return (uintmax_t) arg->pa_u_long_long_int; + + if (pinfo->is_long) + return (uintmax_t) arg->pa_u_long_int; + + if (pinfo->is_short) + return (uintmax_t) arg->pa_u_short_int; + + if (pinfo->is_char) + return (uintmax_t) arg->pa_char; + + return (uintmax_t) arg->pa_u_int; +} + +static intmax_t +fetch_intmax (struct printf_info *pinfo, union printf_arg const *arg) +{ + if (pinfo->is_long_double) + return (intmax_t) (signed long long) arg->pa_long_long_int; + + if (pinfo->is_long) + return (intmax_t) (signed long) arg->pa_long_int; + + if (pinfo->is_short) + return (intmax_t) (signed short) arg->pa_short_int; + + if (pinfo->is_char) + return (intmax_t) (signed char) arg->pa_char; + + return (intmax_t) (signed int) arg->pa_int; +} + +#ifndef NO_FLOAT_PRINTING +static snv_long_double +fetch_double (struct printf_info *pinfo, union printf_arg const *arg) +{ + if (pinfo->is_long_double) + return (snv_long_double) arg->pa_long_double; + else + return (snv_long_double) (arg->pa_double); +} +#endif + + +#ifndef NO_FLOAT_PRINTING + +/* These two routines are cleaned up version of the code in libio 2.95.3 + (actually I got it from the Attic, not from the released tarball). + The changes were mainly to share code between %f and %g (libio did + share some code between %e and %g), and to share code between the + %e and %f when invoked by %g. Support from infinities and NaNs comes + from the old snprintfv code. */ + +typedef struct { + int pfs_prec; + int fmtch; + int expcnt; + int gformat; + char * scan_back_pz; + char * out_pz; + char * start_pz; + char * pfs_end; + snv_long_double fract; + snv_long_double integer; + snv_long_double tmp; +} print_float_status_t; + +static char * +print_float_round (snv_long_double fract, int *exp, char *start, char *end, + char ch, int *signp) +{ + snv_long_double tmp; + if (fract) + (void) modfl (fract * 10, &tmp); + else + tmp = ch - '0'; + + if (tmp > 4) + for (;; --end) + { + if (*end == '.') + --end; + if (end == start) + { + if (exp) /* e/E; increment exponent */ + ++end, ++*exp; + + *end = '1'; + break; + } + if (++*end <= '9') + break; + *end = '0'; + } + + /* ``"%.3f", (double)-0.0004'' gives you a negative 0. */ + else if (*signp == '-') + for (;; --end) + { + if (*end == '.') + --end; + if (*end != '0') + break; + if (end == start) + *signp = 0; + } + return (start); +} + +static void +fiddle_precision (print_float_status_t * pfs) +{ + /* %e/%f/%#g add 0's for precision, others trim 0's */ + if (pfs->gformat && !pinfo->alt) + { + while (pfs->out_pz > pfs->start_pz && *--pfs->out_pz == '0'); + if (*pfs->out_pz != '.') + ++pfs->out_pz; + } + else + for (; pfs->pfs_prec--; *pfs->out_pz++ = '0'); +} + +static void +do_fformat (print_float_status_t * pfs) +{ + /* reverse integer into beginning of buffer */ + if (pfs->expcnt) + for (; ++pfs->scn_bk_pz < pfs->pfs_end; *pfs->out_pz++ = *pfs->scn_bk_pz); + else + *pfs->out_pz++ = '0'; + + /* If precision required or alternate flag set, add in a + decimal point. */ + if (pinfo->prec || pinfo->alt) + *pfs->out_pz++ = '.'; + + /* if requires more precision and some fraction left */ + if (pfs->fract) + { + if (pfs->pfs_prec) + { + /* For %g, if no integer part, don't count initial + zeros as significant digits. */ + do + { + pfs->fract = modfl (pfs->fract * 10, &pfs->tmp); + *pfs->out_pz++ = '0' + ((int) pfs->tmp); + } + while (!pfs->tmp && !pfs->expcnt && pfs->gformat); + + while (--pfs->pfs_prec && pfs->fract) + { + pfs->fract = modfl (pfs->fract * 10, &pfs->tmp); + *pfs->out_pz++ = '0' + ((int) pfs->tmp); + } + } + + if (pfs->fract) + pfs->start_pz = + print_float_round (pfs->fract, (int *) NULL, pfs->start_pz, + pfs->out_pz - 1, (char) 0, signp); + } + + fiddle_precision (pfp); +} + +static void +do_eformat (print_float_status_t * pfs) +{ + if (pfs->expcnt) + { + *pfs->out_pz++ = *++pfs->scn_bk_pz; + if (pinfo->prec || pinfo->alt) + *pfs->out_pz++ = '.'; + + /* if requires more precision and some integer left */ + for (; pfs->pfs_prec && ++pfs->scn_bk_pz < pfs->pfs_end; --pfs->pfs_prec) + *pfs->out_pz++ = *pfs->scn_bk_pz; + + /* if done precision and more of the integer component, + round using it; adjust fract so we don'pfs->out_pz re-round + later. */ + if (!pfs->pfs_prec && ++pfs->scn_bk_pz < pfs->pfs_end) + { + pfs->fract = 0; + pfs->start_pz = print_float_round ( + (snv_long_double) 0, &pfs->expcnt, pfs->start_pz, pfs->out_pz - 1, + *pfs->scn_bk_pz, signp); + } + + /* adjust expcnt for digit in front of decimal */ + --pfs->expcnt; + } + + /* until first fractional digit, decrement exponent */ + else if (pfs->fract) + { + /* adjust expcnt for digit in front of decimal */ + for (pfs->expcnt = -1;; --pfs->expcnt) + { + pfs->fract = modfl (pfs->fract * 10, &pfs->tmp); + if (pfs->tmp) + break; + } + *pfs->out_pz++ = '0' + ((int) pfs->tmp); + if (pinfo->prec || pinfo->alt) + *pfs->out_pz++ = '.'; + } + + else + { + *pfs->out_pz++ = '0'; + if (pinfo->prec || pinfo->alt) + *pfs->out_pz++ = '.'; + } + + /* if requires more precision and some fraction left */ + if (pfs->fract) + { + if (pfs->pfs_prec) + do + { + pfs->fract = modfl (pfs->fract * 10, &pfs->tmp); + *pfs->out_pz++ = '0' + ((int) pfs->tmp); + } + while (--pfs->pfs_prec && pfs->fract); + + if (pfs->fract) + pfs->start_pz = print_float_round ( + pfs->fract, &pfs->expcnt, pfs->start_pz, pfs->out_pz - 1, + (char) 0, signp); + } + + fiddle_precision (pfp); + + if (pfs.fmtch != 'e' && pfs.fmtch != 'E') + return; + + { + char expbuf[10]; + *pfs.out_pz++ = pfs.fmtch; + if (pfs.expcnt < 0) + { + pfs.expcnt = -pfs.expcnt; + *pfs.out_pz++ = '-'; + } + else + *pfs.out_pz++ = '+'; + + pfs.scn_bk_pz = expbuf; + do + *pfs.scn_bk_pz++ = '0' + (pfs.expcnt % 10); + while ((pfs.expcnt /= 10) > 9); + *pfs.scn_bk_pz++ = '0' + pfs.expcnt; + while (pfs.scn_bk_pz > expbuf) + *pfs.out_pz++ = *--pfs.scn_bk_pz; + } +} + +static void +do_gformat (print_float_status_t * pfs) +{ + pfs->gformat = 1; + + /* a precision of 0 is treated as a precision of 1. */ + if (!pfs->pfs_prec) + pinfo->prec = ++pfs->pfs_prec; + + /* ``The style used depends on the value converted; style e + will be used only if the exponent resulting from the + conversion is less than -4 or greater than the precision.'' + -- ANSI X3J11 */ + if ( (pfs->expcnt > pfs->pfs_prec) + || (!pfs->expcnt && pfs->fract && pfs->fract < .0001L)) + { + /* g/G format counts "significant digits, not digits of + precision; for the e/E format, this just causes an + off-by-one problem, i.e. g/G considers the digit + before the decimal point significant and e/E doesn't + count it as precision. */ + --pfs->pfs_prec; + pfs->fmtch -= 2; /* G->E, g->e */ + do_eformat (pfs); + } + else + { + /* Decrement precision */ + if (fnum != 0.0L) + pfs->pfs_prec -= (pfs->pfs_end - pfs->scn_bk_pz) - 1; + else + pfs->pfs_prec--; + + do_fformat (pfs); + } +} + +static int +print_float (struct printf_info *pinfo, char *startp, char *endp, int *signp, + snv_long_double fnum) +{ + print_float_status_t pfs = { + .pfs_prec = pinfo->prec, + .pfs_end = endp, + .fmtch = pinfo->spec, + .out_pz = startp, + .start_pz = startp, + .gformat = 0 + }; + + *signp = 0; + + /* Do the special cases: nans, infinities, zero, and negative numbers. */ + if (isnanl (fnum)) + { + /* Not-a-numbers are printed as a simple string. */ + *pfs.out_pz++ = pfs.fmtch < 'a' ? 'N' : 'n'; + *pfs.out_pz++ = pfs.fmtch < 'a' ? 'A' : 'a'; + *pfs.out_pz++ = pfs.fmtch < 'a' ? 'N' : 'n'; + return pfs.out_pz - pfs.start_pz; + } + + /* Zero and infinity also can have a sign in front of them. */ + if (copysignl (1.0, fnum) < 0.0) + { + fnum = -1.0 * fnum; + *signp = '-'; + } + + if (isinfl (fnum)) + { + /* Infinities are printed as a simple string. */ + *pfs.out_pz++ = pfs.fmtch < 'a' ? 'I' : 'i'; + *pfs.out_pz++ = pfs.fmtch < 'a' ? 'N' : 'n'; + *pfs.out_pz++ = pfs.fmtch < 'a' ? 'F' : 'f'; + goto set_signp; + } + + pfs.expcnt = 0; + pfs.fract = modfl (fnum, &pfs.integer); + + /* get an extra slot for rounding. */ + *pfs.out_pz++ = '0'; + + /* get integer portion of number; put into the end of the buffer; the + .01 is added for modfl (356.0 / 10, &integer) returning .59999999... */ + for (pfs.scn_bk_pz = pfs.pfs_end - 1; + pfs.scn_bk_pz >= pfs.start_pz && pfs.integer; + ++pfs.expcnt) + { + pfs.tmp = modfl (pfs.integer / 10, &pfs.integer); + *pfs.scn_bk_pz-- = '0' + ((int) ((pfs.tmp + .01L) * 10)); + } + + switch (pfs.fmtch) + { + case 'g': + case 'G': + do_gformat (&pfs); + break; + + case 'f': + case 'F': + do_fformat (&pfs); + break; + + case 'e': + case 'E': + do_eformat (&pfs); + break; + + default: + abort (); + } + +set_signp: + if (!*signp) + { + if (pinfo->showsign) + *signp = '+'; + else if (pinfo->space) + *signp = ' '; + } + + return (pfs.out_pz - pfs.start_pz); +} +#endif + + +static int +printf_flag_info (struct printf_info *const pinfo, size_t n, int *argtypes) +{ + return_val_if_fail (pinfo != NULL, SNV_ERROR); + (void)n; + (void)argtypes; + + if (!(pinfo->state & (SNV_STATE_BEGIN | SNV_STATE_FLAG))) + { + PRINTF_ERROR (pinfo, "invalid specifier"); + return -1; + } + + pinfo->state = SNV_STATE_FLAG; + + while (pinfo->state & SNV_STATE_FLAG) + { + switch (*pinfo->format) + { + case '#': + pinfo->alt = true; + pinfo->format++; + break; + + case '0': + if (!pinfo->left) + pinfo->pad = '0'; + pinfo->format++; + break; + + case '-': + pinfo->pad = ' '; + pinfo->left = true; + pinfo->format++; + break; + + case ' ': + pinfo->space = true; + pinfo->format++; + break; + + case '+': + pinfo->showsign = true; + pinfo->format++; + break; + + case '\'': + pinfo->group = true; + pinfo->format++; + break; + + default: + pinfo->state = ~(SNV_STATE_BEGIN | SNV_STATE_FLAG); + break; + } + } + + pinfo->format--; + + /* Return the number of characters emitted. */ + return 0; +} + +/* This function has considerably more freedom than the others in + playing with pinfo; in particular, it modifies argindex and can + return completely bogus values whose only purpose is to extend + the argtypes vector so that it has enough items for the positional + parameter of the width (in the *n$ case). It also expects that + argtypes = (base of argtypes vector) + pinfo->argindex. + + This is messy, suggestion for simplifying it are gladly accepted. */ +static int +printf_numeric_param_info (struct printf_info *const pinfo, size_t n, int *argtypes) +{ + const char *pEnd = NULL; + int found = 0, allowed_states, new_state; + unsigned int position = 0, skipped_args = 0; + long value; + + return_val_if_fail (pinfo != NULL, SNV_ERROR); + + /* If we are looking at a ``.'', then this is a precision parameter. */ + if (*pinfo->format == '.') + { + pinfo->format++; + found |= 1; + } + + /* First we might have a ``*''. */ + if (*pinfo->format == '*') + { + pinfo->format++; + found |= 2; + } + + /* Parse the number. */ + for (pEnd = pinfo->format, value = 0; *pEnd >= '0' && *pEnd <= '9'; pEnd++) + value = value * 10 + (*pEnd - '0'); + + if (pEnd > pinfo->format) + { + pinfo->format = pEnd; + found |= 4; + } + + if (value > INT_MAX) + { + PRINTF_ERROR (pinfo, "out of range"); + return -1; + } + + /* And finally a dollar sign. */ + if (*pinfo->format == '$') + { + if (value <= 0) + { + PRINTF_ERROR (pinfo, "invalid position specifier"); + return -1; + } + + position = (unsigned int)value; + pinfo->format++; + found |= 8; + } + + switch (found & 14) + { + /* We found a * specification */ + case 2: + if (pinfo->args) + value = pinfo->args[pinfo->argindex].pa_int; + if (n) + argtypes[0] = PA_INT; + pinfo->argindex++; + skipped_args = 1; + found ^= 6; + break; + + /* We found a *n$ specification */ + case 14: + if ((unsigned int)n + (unsigned int)pinfo->argindex > (position - 1)) + argtypes[(unsigned)position - 1 - (unsigned)pinfo->argindex] = PA_INT; + + /* Else there is not enough space, reallocate and retry please... + ... but we must say how much to skip. */ + if (position >= (unsigned)pinfo->argindex) + skipped_args = position - (unsigned)pinfo->argindex; + + if (pinfo->args) + value = pinfo->args[position - 1].pa_int; + found ^= 10; + break; + } + + switch (found) + { + /* We must have read a width specification. */ + case 4: + allowed_states = SNV_STATE_BEGIN | SNV_STATE_WIDTH; + new_state = ~(SNV_STATE_BEGIN | SNV_STATE_FLAG | SNV_STATE_WIDTH); + + /* How awful... */ + if (value < 0) + { + pinfo->pad = ' '; + pinfo->left = true; + value = -value; + } + + pinfo->width = (int)value; + break; + + /* We must have read a precision specification. */ + case 5: + allowed_states = SNV_STATE_PRECISION | SNV_STATE_BEGIN; + new_state = SNV_STATE_MODIFIER | SNV_STATE_SPECIFIER; + pinfo->prec = (int)value; + break; + + /* We must have read a position specification. */ + case 12: + allowed_states = SNV_STATE_BEGIN; + new_state = ~SNV_STATE_BEGIN; + pinfo->dollar = (int)position; + break; + + /* We must have read something bogus. */ + default: + PRINTF_ERROR (pinfo, "invalid specifier"); + return -1; + } + + if (!(pinfo->state & allowed_states)) + { + PRINTF_ERROR (pinfo, "invalid specifier"); + return -1; + } + + pinfo->state = new_state; + pinfo->format--; + return (int)skipped_args; +} + +static int +printf_modifier_info (struct printf_info *const pinfo, size_t n, int *argtypes) +{ + return_val_if_fail (pinfo != NULL, SNV_ERROR); + (void)n; + (void)argtypes; + + /* Check for valid pre-state. */ + if (!(pinfo->state & (SNV_STATE_BEGIN | SNV_STATE_MODIFIER))) + { + PRINTF_ERROR (pinfo, "out of range"); + return -1; + } + + while (pinfo->state != SNV_STATE_SPECIFIER) + { + switch (*pinfo->format) + { + case 'h': + if (*++pinfo->format != 'h') + { + pinfo->is_short = true; + break; + } + + pinfo->is_char = true; + pinfo->format++; + break; + + case 'z': + if (sizeof (size_t) > sizeof (char *)) + pinfo->is_long_double = true; + else + pinfo->is_long = true; + + pinfo->format++; + break; + + case 't': + if (sizeof (ptrdiff_t) > sizeof (char *)) + pinfo->is_long_double = true; + else + pinfo->is_long = true; + + pinfo->format++; + break; + + case 'l': + if (*++pinfo->format != 'l') + { + pinfo->is_long = true; + break; + } + /*FALLTHROUGH*/ + + case 'j': + case 'q': + case 'L': + pinfo->is_long_double = true; + pinfo->format++; + break; + + default: + pinfo->state = SNV_STATE_SPECIFIER; + pinfo->format--; + break; + } + } + + /* Return the number of characters emitted. */ + return 0; +} + + +static int +printf_char (STREAM *stream, struct printf_info *const pinfo, union printf_arg const *args) +{ + int count_or_errorcode = SNV_OK; + unsigned char ch = '\0'; + + return_val_if_fail (pinfo != NULL, SNV_ERROR); + + /* Check for valid pre-state. */ + if (pinfo->prec != -1 + || pinfo->is_char || pinfo->is_short || pinfo->is_long + || pinfo->is_long_double || pinfo->pad == '0' + || pinfo->alt || pinfo->space || pinfo->showsign) + { + PRINTF_ERROR (pinfo, "invalid flags"); + return -1; + } + + /* Extract the correct argument from the arg vector. */ + ch = args->pa_char; + + /* Left pad to the width if the supplied argument is less than + the width specifier. */ + if ((pinfo->width > 1) && !pinfo->left) + { + int padwidth = pinfo->width - 1; + + while ((count_or_errorcode >= 0) && (count_or_errorcode < padwidth)) + SNV_EMIT (pinfo->pad, stream, count_or_errorcode); + } + + /* Emit the character argument. */ + SNV_EMIT (ch, stream, count_or_errorcode); + + /* Right pad to the width if we still didn't reach the specified + width and the left justify flag was set. */ + if ((count_or_errorcode < pinfo->width) && pinfo->left) + while ((count_or_errorcode >= 0) + && (count_or_errorcode < pinfo->width)) + SNV_EMIT (pinfo->pad, stream, count_or_errorcode); + + /* Return the number of characters emitted. */ + return count_or_errorcode; +} + +#ifndef NO_FLOAT_PRINTING + +static int +printf_float (STREAM *stream, + struct printf_info *const pinfo, + union printf_arg const *args) +{ + snv_long_double value = 0.0; + int sign, len, count_or_errorcode = SNV_OK; +#ifdef HAVE_LONG_DOUBLE + char buffer[LDBL_MAX_10_EXP * 2 + 20], *p = buffer; +#else + char buffer[DBL_MAX_10_EXP * 2 + 20], *p = buffer; +#endif + + return_val_if_fail (pinfo != NULL, SNV_ERROR); + + /* Check for valid pre-state */ + if (pinfo->prec == -1) + pinfo->prec = SNV_POINTER_TO_LONG (pinfo->extra); + + /* Check for valid pre-state. */ + if (pinfo->prec <= -1 + || pinfo->is_char || pinfo->is_short || pinfo->is_long) + { + PRINTF_ERROR (pinfo, "invalid flags"); + return -1; + } + + /* Extract the correct argument from the arg vector. */ + value = fetch_double (pinfo, args); + + /* Convert the number into a string. */ + len = print_float (pinfo, buffer, buffer + sizeof (buffer), &sign, value); + if (*buffer == '0') + p++, len--; + + /* Compute the size of the padding. */ + pinfo->width -= len; + if (sign) + pinfo->width--; + + /* Left pad to the remaining width if the supplied argument is less + than the width specifier, and the padding character is ' '. */ + if (pinfo->pad == ' ' && !pinfo->left) + while ((count_or_errorcode >= 0) && (pinfo->width-- > 0)) + SNV_EMIT (pinfo->pad, stream, count_or_errorcode); + + /* Display any sign character. */ + if (count_or_errorcode >= 0 && sign) + SNV_EMIT (sign, stream, count_or_errorcode); + + /* Left pad to the remaining width if the supplied argument is less + than the width specifier, and the padding character is not ' '. */ + if (pinfo->pad != ' ' && !pinfo->left) + while ((count_or_errorcode >= 0) && (pinfo->width-- > 0)) + SNV_EMIT (pinfo->pad, stream, count_or_errorcode); + + /* Fill the stream buffer with as many characters from the number + buffer as possible without overflowing. */ + while ((count_or_errorcode >= 0) && (len-- > 0)) + SNV_EMIT (*p++, stream, count_or_errorcode); + + /* Right pad to the width if we still didn't reach the specified + width and the left justify flag was set. */ + if (pinfo->left) + while ((count_or_errorcode >= 0) && (pinfo->width-- > 0)) + SNV_EMIT (pinfo->pad, stream, count_or_errorcode); + + /* Return the number of characters emitted. */ + return count_or_errorcode; +} +#endif + +static int +printf_count (STREAM *stream, struct printf_info *const pinfo, union printf_arg const *args) +{ + (void)stream; + + if (pinfo->is_char) + *(char *) (args->pa_pointer) = (char)pinfo->count; + + else if (pinfo->is_short) + *(short *) (args->pa_pointer) = (short)pinfo->count; + + else if (pinfo->is_long) + *(long *) (args->pa_pointer) = (long)pinfo->count; + + else if (pinfo->is_long_double) + *(intmax_t *) (args->pa_pointer) = (intmax_t)pinfo->count; + + else + *(int *) (args->pa_pointer) = (int)pinfo->count; + + return 0; +} + +static int +printf_integer (STREAM *stream, struct printf_info *const pinfo, union printf_arg const *args) +{ + static const char digits_lower[] = "0123456789abcdefghijklmnopqrstuvwxyz"; + static const char digits_upper[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + const char *digits; + + unsigned base = (unsigned int)SNV_POINTER_TO_ULONG (pinfo->extra); + uintmax_t value = 0L; + int type, count_or_errorcode = SNV_OK; + char buffer[256], *p, *end; + bool is_negative = false; + + return_val_if_fail (pinfo != NULL, SNV_ERROR); + + /* Check for valid pre-state. */ + if (!(pinfo->state & (SNV_STATE_BEGIN | SNV_STATE_SPECIFIER))) + { + PRINTF_ERROR (pinfo, "out of range"); + return -1; + } + + /* Upper or lower-case hex conversion? */ + digits = ((pinfo->spec >= 'a') && (pinfo->spec <= 'z')) + ? digits_lower : digits_upper; + + if (pinfo->prec == -1) + pinfo->prec = 0; + + /* Check for valid pre-state. */ + if (pinfo->prec < 0) + { + PRINTF_ERROR (pinfo, "invalid precision"); + return -1; + } + + type = pinfo->type; + + /* Extract the correct argument from the arg vector. */ + if (type & PA_FLAG_UNSIGNED) + { + value = fetch_uintmax (pinfo, args); + is_negative = false; + pinfo->showsign = pinfo->space = false; + } + else + { + intmax_t svalue = 0L; + svalue = fetch_intmax (pinfo, args); + is_negative = (svalue < 0); + value = (uintmax_t) ABS (svalue); + } + + /* Convert the number into a string. */ + p = end = &buffer[sizeof (buffer) - 1]; + + if (value == 0) + *p-- = '0'; + + else + while (value > 0) + { + *p-- = digits[value % base]; + value /= base; + } + + pinfo->width -= (int)(end - p); + pinfo->prec -= (int)(end - p); + + /* Octal numbers have a leading zero in alterate form. */ + if (pinfo->alt && base == 8) + { + *p-- = '0'; + --pinfo->width; + } + + /* Left pad with zeros to make up the precision. */ + if (pinfo->prec > 0) + { + pinfo->width -= pinfo->prec; + while (pinfo->prec-- > 0) + *p-- = '0'; + } + + /* Reserve room for leading `0x' for hexadecimal. */ + if (pinfo->alt && base == 16) + pinfo->width -= 2; + + /* Reserve room for a sign character. */ + if (is_negative || pinfo->showsign || pinfo->space) + --pinfo->width; + + /* Left pad to the remaining width if the supplied argument is less + * than the width specifier, and the padding character is ' '. + */ + if (pinfo->pad == ' ' && !pinfo->left) + while ((count_or_errorcode >= 0) && (pinfo->width-- > 0)) + SNV_EMIT (pinfo->pad, stream, count_or_errorcode); + + /* Display any sign character. */ + if (count_or_errorcode >= 0) + { + if (is_negative) + SNV_EMIT ('-', stream, count_or_errorcode); + else if (pinfo->showsign) + SNV_EMIT ('+', stream, count_or_errorcode); + else if (pinfo->space) + SNV_EMIT (' ', stream, count_or_errorcode); + } + + /* Display `0x' for alternate hexadecimal specifier. */ + if ((count_or_errorcode >= 0) && (base == 16) && pinfo->alt) + { + SNV_EMIT ('0', stream, count_or_errorcode); + SNV_EMIT (digits['X' - 'A' + 10], stream, count_or_errorcode); + } + + /* Left pad to the remaining width if the supplied argument is less + * than the width specifier, and the padding character is not ' '. + */ + if (pinfo->pad != ' ' && !pinfo->left) + while ((count_or_errorcode >= 0) && (pinfo->width-- > 0)) + SNV_EMIT (pinfo->pad, stream, count_or_errorcode); + + /* Fill the stream buffer with as many characters from the number + * buffer as possible without overflowing. + */ + while ((count_or_errorcode >= 0) && (++p < &buffer[sizeof (buffer)])) + SNV_EMIT (*p, stream, count_or_errorcode); + + /* Right pad to the width if we still didn't reach the specified + * width and the left justify flag was set. + */ + if (pinfo->left) + while ((count_or_errorcode >= 0) && (pinfo->width-- > 0)) + SNV_EMIT (pinfo->pad, stream, count_or_errorcode); + + /* Return the number of characters emitted. */ + return count_or_errorcode; +} + +static int +printf_pointer (STREAM *stream, struct printf_info *const pinfo, union printf_arg const *args) +{ + int count_or_errorcode = SNV_OK; + + return_val_if_fail (pinfo != NULL, SNV_ERROR); + + /* Read these now to advance the argument pointer appropriately */ + if (pinfo->prec == -1) + pinfo->prec = 0; + + /* Check for valid pre-state. */ + if (pinfo->prec <= -1 + || pinfo->is_char || pinfo->is_short || pinfo->is_long + || pinfo->is_long_double) + { + PRINTF_ERROR (pinfo, "invalid flags"); + return -1; + } + + /* Always print 0x. */ + pinfo->alt = 1; + pinfo->is_long = sizeof(long) == sizeof (char *); + pinfo->is_long_double = sizeof(intmax_t) == sizeof (char *); + + /* Use the standard routine for numbers for the printing call, + if the pointer is not NULL. */ + + if (args->pa_pointer != NULL) + return printf_integer (stream, pinfo, args); + + /* Print a NULL pointer as (nil), appropriately padded. */ + if ((pinfo->width > 5) && !pinfo->left) + { + int padwidth = pinfo->width - 5; + while ((count_or_errorcode >= 0) && (count_or_errorcode < padwidth)) + SNV_EMIT (pinfo->pad, stream, count_or_errorcode); + } + + SNV_EMIT ('(', stream, count_or_errorcode); + SNV_EMIT ('n', stream, count_or_errorcode); + SNV_EMIT ('i', stream, count_or_errorcode); + SNV_EMIT ('l', stream, count_or_errorcode); + SNV_EMIT (')', stream, count_or_errorcode); + + if ((pinfo->width > 5) && pinfo->left) + while ((count_or_errorcode >= 0) + && (count_or_errorcode < pinfo->width)) + SNV_EMIT (pinfo->pad, stream, count_or_errorcode); + + return count_or_errorcode; +} + +static int +printf_string (STREAM *stream, struct printf_info *const pinfo, union printf_arg const *args) +{ + size_t len = 0; + int count_or_errorcode = SNV_OK; + const char *p = NULL; + + return_val_if_fail (pinfo != NULL, SNV_ERROR); + + /* Read these now to advance the argument pointer appropriately */ + if (pinfo->prec == -1) + pinfo->prec = 0; + + /* Check for valid pre-state. */ + if (pinfo->prec <= -1 + || pinfo->is_char || pinfo->is_short || pinfo->is_long + || pinfo->is_long_double) + { + PRINTF_ERROR (pinfo, "invalid flags"); + return -1; + } + + /* Extract the correct argument from the arg vector. */ + p = args->pa_string; + + /* Left pad to the width if the supplied argument is less than + the width specifier. */ + if (p != NULL) + { + len = strlen (p); + if (pinfo->prec && ((size_t)pinfo->prec < len)) + len = (size_t)pinfo->prec; + } + + if ((len < (size_t)pinfo->width) && !pinfo->left) + { + int padwidth = pinfo->width - (int)len; + while ((count_or_errorcode >= 0) && (count_or_errorcode < padwidth)) + SNV_EMIT (pinfo->pad, stream, count_or_errorcode); + } + + /* Fill the buffer with as many characters from the format argument + as possible without overflowing or exceeding the precision. */ + if ((count_or_errorcode >= 0) && (p != NULL)) + { + int mark = (int)count_or_errorcode; + while ( (*p != '\0') + && ( (pinfo->prec == 0) + || (count_or_errorcode - mark < (int)len))) + SNV_EMIT (*p++, stream, count_or_errorcode); + } + + /* Right pad to the width if we still didn't reach the specified + width and the left justify flag was set. */ + if ((count_or_errorcode < pinfo->width) && pinfo->left) + while ((count_or_errorcode >= 0) + && (count_or_errorcode < pinfo->width)) + SNV_EMIT (pinfo->pad, stream, count_or_errorcode); + + /* Return the number of characters emitted. */ + return count_or_errorcode; +} + + + +/* replacements for modfl and copysignl follow. */ + +#if !defined NO_FLOAT_PRINTING && defined HAVE_LONG_DOUBLE +# ifndef HAVE_MODFL +static long double modfl (long double x, long double *exp) +{ + /* To compute the integer part of a positive integer (in this case + abs(X)), sum a big enough integer to the absolute value, so that + the precision of the floating point number is exactly 1. Then + we round towards zero. + + The code in the two branches is the same but it considers -x + if x is negative. */ + + long double z; + if (x < 0.0L) + { + z = 1.0L / LDBL_EPSILON - x - 1.0 / LDBL_EPSILON; + if (z + x > 0.0L) + z = z - 1.0L; + + return (*exp = -z) + x; + } + else + { + z = 1.0L / LDBL_EPSILON + x - 1.0 / LDBL_EPSILON; + if (z > x) + z = z - 1.0L; + + return x - (*exp = z); + } +} +# endif /* !HAVE_MODFL */ + +# ifndef HAVE_COPYSIGNL +long double +copysignl (long double x, long double y) +{ +# ifdef HAVE_COPYSIGN + return x * (long double) copysign (1.0, x * y); +# else /* !HAVE_COPYSIGN */ + /* If we do not have copysign, assume zero is unsigned (too risky to + assume we have infinities, which would allow to test with + (x < 0.0 && 1.0 / x < 0.0). */ + return (x < 0.0 ^ y < 0.0) ? x * -1.0 : x; +# endif /* !HAVE_COPYSIGN */ +} +# endif /* !HAVE_COPYSIGNL */ +#endif /* !NO_FLOAT_PRINTING && HAVE_LONG_DOUBLE) */ + + + +/* This is where the parsing of FORMAT strings is handled: + + Each of these functions should inspect PPARSER for parser + state information; update PPARSER as necessary based on + the state discovered; possibly put some characters in STREAM, in + which case that number of characters must be returned. If the + handler detects that parsing (of the current specifier) is complete, + then it must set pinfo->state to SNV_STATE_END. The library will then + copy characters from the format string to STREAM until another unescaped + SNV_CHAR_SPEC is detected when the handlers will be called again. */ + +spec_entry snv_default_spec_table[] = { + /* ch type function */ + {' ', 0, 0, NULL, printf_flag_info, NULL}, + {'#', 0, 0, NULL, printf_flag_info, NULL}, + {'+', 0, 0, NULL, printf_flag_info, NULL}, + {'-', 0, 0, NULL, printf_flag_info, NULL}, + {'\'', 0, 0, NULL, printf_flag_info, NULL}, + {'*', 0, PA_INT, NULL, printf_numeric_param_info, NULL}, + {'$', 0, 0, NULL, printf_numeric_param_info, NULL}, + {'.', 0, 0, NULL, printf_numeric_param_info, NULL}, + {'0', 0, 0, NULL, printf_flag_info, NULL}, + {'1', 0, 0, NULL, printf_numeric_param_info, NULL}, + {'2', 0, 0, NULL, printf_numeric_param_info, NULL}, + {'3', 0, 0, NULL, printf_numeric_param_info, NULL}, + {'4', 0, 0, NULL, printf_numeric_param_info, NULL}, + {'5', 0, 0, NULL, printf_numeric_param_info, NULL}, + {'6', 0, 0, NULL, printf_numeric_param_info, NULL}, + {'7', 0, 0, NULL, printf_numeric_param_info, NULL}, + {'8', 0, 0, NULL, printf_numeric_param_info, NULL}, + {'9', 0, 0, NULL, printf_numeric_param_info, NULL}, + {'c', 0, PA_CHAR, printf_char, NULL, NULL}, + {'d', 0, PA_INT, printf_integer, printf_generic_info, (snv_pointer) 10}, +#ifndef NO_FLOAT_PRINTING + {'e', 0, PA_DOUBLE, printf_float, printf_generic_info, (snv_pointer) 6}, + {'E', 0, PA_DOUBLE, printf_float, printf_generic_info, (snv_pointer) 6}, + {'f', 0, PA_DOUBLE, printf_float, printf_generic_info, (snv_pointer) 6}, + {'F', 0, PA_DOUBLE, printf_float, printf_generic_info, (snv_pointer) 6}, + {'g', 0, PA_DOUBLE, printf_float, printf_generic_info, (snv_pointer) 6}, + {'G', 0, PA_DOUBLE, printf_float, printf_generic_info, (snv_pointer) 6}, +#endif + {'h', 0, 0, NULL, printf_modifier_info, NULL}, + {'i', 0, PA_INT, printf_integer, printf_generic_info, (snv_pointer) 10}, + {'j', 0, 0, NULL, printf_modifier_info, NULL}, + {'l', 0, 0, NULL, printf_modifier_info, NULL}, + {'L', 0, 0, NULL, printf_modifier_info, NULL}, + {'n', 0, PA_INT | PA_FLAG_PTR, printf_count, printf_generic_info, NULL}, + {'o', 0, PA_INT | PA_FLAG_UNSIGNED, + printf_integer, printf_generic_info, (snv_pointer) 8}, + {'p', 0, PA_POINTER, printf_pointer, NULL, (snv_pointer) 16}, + {'q', 0, 0, NULL, printf_modifier_info, NULL}, + {'s', 0, PA_STRING, printf_string, NULL, NULL}, + {'t', 0, 0, NULL, printf_modifier_info, NULL}, + {'u', 0, PA_INT | PA_FLAG_UNSIGNED, + printf_integer, printf_generic_info, (snv_pointer) 10}, + {'x', 0, PA_INT | PA_FLAG_UNSIGNED, + printf_integer, printf_generic_info, (snv_pointer) 16}, + {'X', 0, PA_INT | PA_FLAG_UNSIGNED, + printf_integer, printf_generic_info, (snv_pointer) 16}, + {'z', 0, 0, NULL, printf_modifier_info, NULL}, + {'\0', 0, PA_LAST, NULL, NULL, NULL} +}; + +/* + * Local Variables: + * mode: C + * c-file-style: "gnu" + * indent-tabs-mode: nil + * End: + * end of snprintfv/format.c */ diff --git a/snprintfv/mem.c b/snprintfv/mem.c new file mode 100644 index 0000000..1c345f5 --- /dev/null +++ b/snprintfv/mem.c @@ -0,0 +1,81 @@ +/* -*- Mode: C -*- */ + +/* mem.c --- memory management routines + * Copyright (C) 2002 Gary V. Vaughan + * Originally by Paolo Bonzini, 2002 + * This file is part of Snprintfv + * + * Snprintfv 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. + * + * Snprintfv 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 . + * + * As a special exception to the GNU General Public License, if you + * distribute this file as part of a program that also links with and + * uses the libopts library from AutoGen, you may include it under + * the same distribution terms used by the libopts library. + */ + +/* Code: */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#ifdef HAVE_DMALLOC +# include +#endif + +#include "mem.h" + + +/* We deliberately don't prototype the malloc functions; they are cast + to match the function pointers we expose to avoid compiler warnings + from mismatched prototypes (if we find a host implementation. + + Not also that if this file is compiled -DWITH_DMALLOC, the inclusion + in mem.h will cause the malloc references below to be redirected + correctly. */ +malloc_proc_t* snv_malloc = (malloc_proc_t*)malloc; +realloc_proc_t* snv_realloc = (realloc_proc_t*)realloc; +free_proc_t* snv_free = (free_proc_t*)free; + +/* Unportable memory management functions are reimplemented tout court. */ +snv_pointer +snv_xrealloc (snv_pointer old, size_t count) +{ + if (count < 1) + { + snv_free (old); + return NULL; + } + if (!old) + return snv_malloc (count); + else + return snv_realloc (old, count); +} + +char * +snv_strdup (const char *str) +{ + size_t len = strlen (str); + char *result = snv_malloc (len + 1); + memcpy (result, str, len + 1); + return result; +} + +/* + * Local Variables: + * mode: C + * c-file-style: "gnu" + * indent-tabs-mode: nil + * End: + * end of snprintfv/mem.c */ diff --git a/snprintfv/mem.h b/snprintfv/mem.h new file mode 100644 index 0000000..44aa88c --- /dev/null +++ b/snprintfv/mem.h @@ -0,0 +1,119 @@ +/* -*- Mode: C -*- */ + +/* mem.h --- memory handling macros + * Copyright (C) 1999 Gary V. Vaughan + * Originally by Gary V. Vaughan, 1999 + * This file is part of Snprintfv + * + * Snprintfv 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. + * + * Snprintfv 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 . + * + * As a special exception to the GNU General Public License, if you + * distribute this file as part of a program that also links with and + * uses the libopts library from AutoGen, you may include it under + * the same distribution terms used by the libopts library. + */ + +/* Code: */ + +#ifndef SNPRINTFV_MEM_H +#define SNPRINTFV_MEM_H 1 + +#include + +#ifdef WITH_DMALLOC +# include +#endif + +#ifdef _WIN32 +# ifdef DLL_EXPORT +# define SNV_SCOPE extern __declspec(dllexport) +# else +# ifdef LIBSNPRINTFV_DLL_IMPORT +# define SNV_SCOPE extern __declspec(dllimport) +# endif +# endif +#else +# define SNV_SCOPE extern +#endif + +/* This is the API we use throughout libsnprintfv. */ +#define snv_new(type, count) \ + ((type*)snv_malloc(sizeof(type) * (size_t)(count))) +#define snv_renew(type, ptr, count) \ + ((type*)snv_xrealloc((ptr), sizeof(type) * (size_t)(count))) +#define snv_delete(old) snv_free(old) + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +typedef void* (malloc_proc_t )(size_t); +typedef void* (realloc_proc_t)(snv_pointer, size_t); +typedef void* (free_proc_t )(snv_pointer); + +/* These function pointers are exposed through the API incase a user + of this library needs to map our memory management routines to + their own (e.g. xmalloc). */ + +/** + * snv_malloc: + * @count: The number of bytes to allocate. + * + * Allocates a fresh block of memory whose size is @count bytes. + * + * Return value: + * The pointer to the newly-allocated memory area. + */ +SNV_SCOPE malloc_proc_t *snv_malloc; + +/** + * snv_realloc: + * @old: The pointer to the block whose size must be changed. + * @count: The number of bytes to allocate. + * + * Reallocates a fresh block of memory pointed to by @old + * so that its size becomes @count bytes. + * + * Return value: + * The pointer to the newly-allocated memory area, possibly + * the same as @old. + */ +SNV_SCOPE realloc_proc_t *snv_realloc; + +/** + * snv_free: + * @old: The pointer to the block that must freed. + * + * Frees a block of memory pointed to by @old. + */ +SNV_SCOPE free_proc_t *snv_free; + +/* And these are reimplemented tout court because they are + not fully portable. */ +extern realloc_proc_t snv_xrealloc; +extern char* snv_strdup (const char *str); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* SNPRINTFV_MEM_H */ + +/* + * Local Variables: + * mode: C + * c-file-style: "gnu" + * indent-tabs-mode: nil + * End: + * end of snprintfv/mem.h */ diff --git a/snprintfv/printf.c b/snprintfv/printf.c new file mode 100644 index 0000000..01fd750 --- /dev/null +++ b/snprintfv/printf.c @@ -0,0 +1,1572 @@ +/* -*- Mode: C -*- */ + +/* printf.c --- printf clone for argv arrays + * Copyright (C) 1998, 1999, 2000, 2002 Gary V. Vaughan + * Originally by Gary V. Vaughan, 1998 + * This file is part of Snprintfv + * + * Snprintfv 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. + * + * Snprintfv 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 . + * + * As a special exception to the GNU General Public License, if you + * distribute this file as part of a program that also links with and + * uses the libopts library from AutoGen, you may include it under + * the same distribution terms used by the libopts library. + */ + +/* Code: */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include /* for the write(2) call */ + +#ifdef HAVE_ASSERT_H +# include +#else +# define assert(_e) +#endif + +#define COMPILING_PRINTF_C +#include "printf.h" + +#ifdef WITH_DMALLOC +#include +#endif + +#include "filament.h" +#include "stream.h" +#include "mem.h" + +#ifdef SNV_LIBRARY_BUILD +# include "dl.h" +#else + +# ifndef HAVE_STRTOUL +# include "strtoul.c" +# endif +#endif /* SNV_LIBRARY_BUILD */ + +#define EOS '\0' +#define SNV_CHAR_SPEC '%' +#define SNV_ESC_SPEC '\\' + +/* Functions to manage mapping of spec chars to handlers. */ +SNV_INLINE unsigned spec_hash (unsigned spec); +SNV_INLINE void spec_init (void); +SNV_INLINE spec_entry *spec_lookup (unsigned spec); +static void spec_insert (spec_entry * pentry); +static int do_printfv (STREAM *stream, const char *format, + union printf_arg const args[]); + +/* FIXME: We are assuming an ASCII character set where all the + printable characters are between SPACE and DEL. */ +#define ASCII_DEL (int)'\177' +#define ASCII_SPACE (int)' ' + +#define IS_MODIFIER(spec) (!((spec)->fmt)) + +/* TODO: This is not thread-safe. Change the API to pass the spec_table + in as the first parameter to the functions which use it? */ +static spec_entry *spec_table[ASCII_DEL - ASCII_SPACE]; + +/* TODO: This is not thread-safe as well. */ +static char *printf_last_error; + +SNV_INLINE unsigned +spec_hash (unsigned spec) +{ + return (spec & ASCII_DEL) - ASCII_SPACE; +} + +/* Register all of the functions in INIT_SPEC_TABLE. */ +static void +spec_init (void) +{ + static bool is_init = false; + + if (!is_init) + { + extern spec_entry snv_default_spec_table[]; + unsigned ix; + + memset (spec_table, 0, sizeof (spec_table)); + for (ix = 0; snv_default_spec_table[ix].spec_key != EOS; ix++) + { + unsigned hash = spec_hash (snv_default_spec_table[ix].spec_key); + spec_table[hash] = snv_default_spec_table + ix; + } + + is_init = true; + } +} + +/* Insert PENTRY, a new handler, into SPEC_TABLE. */ +SNV_INLINE void +spec_insert (spec_entry *pentry) +{ + unsigned hash = spec_hash (pentry->spec_key); + spec_init (); + spec_table[hash] = pentry; +} + +/* Lookup and return the SPEC_TABLE entry for SPEC. */ +SNV_INLINE spec_entry * +spec_lookup (unsigned spec) +{ + unsigned hash = spec_hash (spec); + spec_init (); + return spec_table[hash]; +} + +/** + * register_printf_function: printf.h + * @spec: the character which will trigger @func, cast to an unsigned int. + * @fmt: the handler function to actually print the arguments to the specifier + * @arg: the handler function to tell %printf about the types of the arguments + * to the specifier + * + * Register the pair made of @fmt and @arg, so that it is called + * when @spec is encountered in a format string. + * + * Return value: + * Returns %NULL if @func was not successfully registered, a + * %spec_entry with the information on the function if it was. + **/ +spec_entry * +register_printf_function (unsigned spec, printf_function *fmt, + printf_arginfo_function *arg) +{ + spec_entry *new, *old; + old = spec_lookup (spec); + if (old && IS_MODIFIER (old)) + return NULL; + + if (!fmt || !spec) + return NULL; + + new = snv_new (spec_entry, 1); + new->spec_key = spec; + new->fmt = fmt; + new->arg = arg; + new->user = NULL; + + spec_insert (new); + + return new; +} + +static int +call_argtype_function ( + struct printf_info *const pinfo, + int **argtypes, + spec_entry *spec) +{ + int n; + int argindex = (pinfo->dollar && !IS_MODIFIER (spec)) + ? pinfo->dollar - 1 + : pinfo->argindex; + + int save_argindex = pinfo->argindex; + int save_state = pinfo->state; + char const *save_format = pinfo->format; + + if (!spec->arg) + { + n = 1; + if (pinfo->argc <= argindex) + { + /* + * "argtypes" points to a pointer of an array of int values. + * Here, we ensure that there are "argindex + 1" entries in + * that array. + */ + *argtypes = snv_renew (int, *argtypes, (argindex + 1)); + + /* + * IF there are more entries that follow the current argument + * index, then we will clobber all the entries that follow. + * The size of these entries is the size of the array elements, + * not the size of the pointer to the array elements. + */ + if (pinfo->argc < argindex) + memset(*argtypes + pinfo->argc, PA_UNKNOWN, + (size_t)(argindex - pinfo->argc) * sizeof(**argtypes)); + + pinfo->argc = argindex + 1; + } + + (*argtypes) [argindex] = spec->type; + } + + else + { + pinfo->spec = (unsigned)*(pinfo->format); + pinfo->extra = spec->user; + pinfo->type = spec->type; + + if (pinfo->argc > argindex) + n = spec->arg(pinfo, (size_t) (pinfo->argc - argindex), + *argtypes + argindex); + else + n = spec->arg(pinfo, (size_t)0, NULL); + + if (n < 0) + return n; + if (argindex + n > pinfo->argc) + { + int new_ct = argindex + n; + *argtypes = snv_renew (int, *argtypes, new_ct); + memset(*argtypes + pinfo->argc, PA_UNKNOWN, + (size_t)(new_ct - pinfo->argc) * sizeof(**argtypes)); + pinfo->argc = argindex + n; + /* Call again... */ + pinfo->argindex = save_argindex; + pinfo->format = save_format; + pinfo->state = save_state; + pinfo->spec = (unsigned)*(pinfo->format); + pinfo->extra = spec->user; + pinfo->type = spec->type; + n = spec->arg(pinfo, (size_t)n, *argtypes + argindex); + } + } + + if (!pinfo->dollar || !IS_MODIFIER (spec)) + pinfo->argindex += n; + + return n; +} + + +/** + * printf_strerror: printf.h + * + * Communicate information on the last error in a printf + * format string. + * + * Return value: + * A string describing the last error which occurred during the + * parsing of a printf format string. It is the responsibility + * of the caller to free the string. + */ +char * +printf_strerror (void) +{ + return snv_strdup(printf_last_error); +} + +/* (re)initialise the memory used by PPARSER. */ +static inline void +parser_init ( + struct printf_info *pinfo, + const char *format, + const union printf_arg *args) +{ + memset (pinfo, 0, sizeof (struct printf_info)); + pinfo->format = format; + pinfo->args = args; +} + +static inline struct printf_info * +parser_reset (struct printf_info *pinfo) +{ + pinfo->is_long_double = pinfo->is_char = pinfo->is_short = + pinfo->is_long = 0; + pinfo->alt = 0; + pinfo->left = 0; + pinfo->showsign = 0; + pinfo->group = 0; + pinfo->wide = 0; + pinfo->spec = 0; + pinfo->width = 0; + pinfo->space = 0; + pinfo->state = SNV_STATE_BEGIN; + pinfo->prec = -1; + pinfo->dollar = 0; + pinfo->pad = ' '; + + return pinfo; +} + + +/** + * printf_error: printf.h + * @pinfo: pointer to the current parser state. + * @file: file where error was detected. + * @line: line where error was detected. + * @func1: " (" if function is supplied by compiler. + * @func2: function where error was detected, if supplied by compiler. + * @func3: ")" if function is supplied by compiler. + * @error_message: new error message to append to @pinfo. + * + * The contents of @error_message are appended to the @pinfo internal + * error string, so it is safe to pass static strings or recycle the + * original when this function returns. + * + * Return value: + * The address of the full accumulated error message in @pinfo is + * returned. + **/ +char * +printf_error (struct printf_info *pinfo, const char *file, int line, + const char *func1, const char *func2, const char *func3, + const char *error_message) +{ + int i; + char *result; + if (pinfo->error == NULL) + pinfo->error = filnew (NULL, (size_t)0); + else + filccat (pinfo->error, '\n'); + + /* Cannot use printf because a bug in it might trigger another + printf_error! */ + result = filcat (pinfo->error, "file "); + filcat (pinfo->error, file); + filcat (pinfo->error, ": line "); + for (i = 10; i <= line; i *= 10); + for (i /= 10; i >= 1; i /= 10) + filccat (pinfo->error, '0' + (line / i) % 10); + + filcat (pinfo->error, func1); + filcat (pinfo->error, func2); + filcat (pinfo->error, func3); + filcat (pinfo->error, ": "); + filcat (pinfo->error, error_message); + return result; +} + + + +/** + * parse_printf_format: printf.h + * @format: a % delimited format string. + * @n: the size of the @argtypes vector + * @argtypes: a vector of ints, to be filled with the argument types from @format + * + * Returns information about the number and types of + * arguments expected by the template string @format. + * The argument @n specifies the number of elements in the array + * @argtypes. This is the maximum number of elements that + * the function will try to write. + * + * Return value: + * The total number of arguments required by @format. If this + * number is greater than @n, then the information returned + * describes only the first @n arguments. If you want information + * about additional arguments, allocate a bigger array and call + * this function again. If there is an error, then %SNV_ERROR + * is returned instead. + **/ +size_t +parse_printf_format (const char *format, int n, int *argtypes) +{ + struct printf_info info; + + return_val_if_fail (format != NULL, (size_t)-1); + + parser_init (&info, format, NULL); + + while (*info.format != EOS) + { + int ch = (int) *info.format++; + spec_entry *spec; + int status; + int argindex; + + if (ch != SNV_CHAR_SPEC) + continue; + + if (*info.format == SNV_CHAR_SPEC) + { + /* An escaped CHAR_SPEC: ignore it (by falling through). */ + ++info.format; + continue; + } + + /* We found the start of a format specifier! */ + parser_reset (&info); + do + { + /* Until we fill the stream (or get some other + exception) or one of the handlers tells us + we have reached the end of the specifier... */ + + /* ...lookup the handler associated with the char + we are looking at in the format string... */ + spec = spec_lookup ((unsigned)*(info.format)); + if (spec == NULL) + { + PRINTF_ERROR (&info, "unregistered specifier"); + goto error; + } + + if (!IS_MODIFIER (spec) && + !(info.state & (SNV_STATE_BEGIN | SNV_STATE_SPECIFIER))) + { + PRINTF_ERROR (&info, "invalid combination of flags"); + goto error; + } + + argindex = info.dollar && !IS_MODIFIER (spec) + ? info.dollar - 1 : info.argindex; + + /* ...and call the relevant handler. */ + if (spec->arg) + { + info.spec = (unsigned)*(info.format); + info.extra = spec->user; + info.type = spec->type; + status = (*spec->arg) (&info, (size_t) (n - argindex), + argtypes + argindex); + } + else + { + status = 1; + if (n > argindex) + argtypes[argindex] = spec->type; + } + + if (status < 0) + goto error; + + info.argc = MAX (info.argc, argindex + status); + if (!info.dollar || !IS_MODIFIER (spec)) + info.argindex += status; + + info.format++; + } + while (IS_MODIFIER (spec)); + + continue; + + error: + /* Get here on error */ + info.argc = -1; + break; + } + + if (printf_last_error) + snv_delete (printf_last_error); + + if (info.error) + printf_last_error = fildelete (info.error); + else + printf_last_error = NULL; + + return (size_t)info.argc; +} + +static int +do_printfv (STREAM *stream, const char *format, union printf_arg const args[]) +{ + struct printf_info info; + + /* This is the parser driver. + + Here we scan through the format string and move bytes into the + stream and call handlers based on the parser state. */ + + parser_init (&info, format, args); + + /* Keep going until the format string runs out! */ + while (*info.format != EOS) + { + int ch = (int) *info.format++; + + switch (ch) + { + case SNV_CHAR_SPEC: + if (*info.format != SNV_CHAR_SPEC) + { + /* We found the start of a format specifier! */ + spec_entry *spec; + int status; + int argindex; + + parser_reset (&info); + do + { + /* Until we fill the stream (or get some other + exception) or one of the handlers tells us + we have reached the end of the specifier... */ + + /* ...lookup the handler associated with the char + we are looking at in the format string... */ + spec = spec_lookup ((unsigned)*(info.format)); + if (spec == NULL) + { + PRINTF_ERROR (&info, "unregistered specifier"); + goto error; + } + + if (!IS_MODIFIER (spec) && + !(info.state & (SNV_STATE_BEGIN | SNV_STATE_SPECIFIER))) + { + PRINTF_ERROR (&info, "invalid combination of flags"); + goto error; + } + + /* ...and call the relevant handler. */ + info.spec = (unsigned)*(info.format); + info.extra = spec->user; + info.type = spec->type; + + status = spec->arg ? (*spec->arg) (&info, (size_t)0, NULL) : 1; + + if (status < 0) + goto error; + + argindex = info.dollar && !IS_MODIFIER (spec) + ? info.dollar - 1 : info.argindex; + + info.format++; + info.argc = MAX (info.argc, argindex + status); + if (!info.dollar && !IS_MODIFIER (spec)) + info.argindex += status; + } + while (info.count >= 0 && IS_MODIFIER (spec)); + + status = (*spec->fmt) (stream, &info, args + argindex); + + if (status < 0) + goto error; + + info.count += status; + continue; + } + + /* An escaped CHAR_SPEC: ignore it (by falling through). */ + ++info.format; + + /*FALLTHROUGH*/ + + default: + /* Just a character: copy it. */ + SNV_EMIT (ch, stream, info.count); + continue; + } + + error: + /* Get here on error */ + info.count = -1; + break; + } + + if (printf_last_error) + snv_delete (printf_last_error); + + if (info.error) + printf_last_error = fildelete (info.error); + else + printf_last_error = NULL; + + return info.count; +} + +/** + * stream_printfv: printf.h + * @stream: an initialised stream structure. + * @format: a % delimited format string. + * @args: a vector of argument addresses to match @format. + * + * Format the elements of @args according to @format, and write + * the results to @stream. If @stream is %NULL, only count the + * number of characters needed to output the format. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +int +stream_printfv (STREAM *stream, const char *format, snv_constpointer const *ap) +{ + union printf_arg *args; + struct printf_info info; + int count_or_errorcode; + int *argtypes = NULL; + + return_val_if_fail (format != NULL, SNV_ERROR); + + parser_init (&info, format, NULL); + + /* Keep going until the format string runs out! */ + while (*info.format != EOS) + { + int ch = (int) *info.format++; + + switch (ch) + { + case SNV_CHAR_SPEC: + if (*info.format != SNV_CHAR_SPEC) + { + /* We found the start of a format specifier! */ + spec_entry *spec; + + parser_reset (&info); + do + { + /* Until we fill the stream (or get some other + exception) or one of the handlers tells us + we have reached the end of the specifier... */ + + /* ...lookup the handler associated with the char + we are looking at in the format string... */ + spec = spec_lookup ((unsigned)*(info.format)); + if (spec == NULL) + { + PRINTF_ERROR (&info, "unregistered specifier"); + goto error; + } + + if (!IS_MODIFIER (spec) && + !(info.state & (SNV_STATE_BEGIN | SNV_STATE_SPECIFIER))) + { + PRINTF_ERROR (&info, "invalid combination of flags"); + goto error; + } + + /* ...and call the relevant handler. */ + if (call_argtype_function (&info, &argtypes, spec) < 0) + goto error; + + info.format++; + } + while (info.count >= 0 && IS_MODIFIER (spec)); + continue; + } + + /* An escaped CHAR_SPEC: ignore it (by falling through). */ + ++info.format; + + /*FALLTHROUGH*/ + + default: /* Just a character: ignore it. */ + continue; + } + + error: + /* Get here on error */ + info.argc = -1; + break; + } + + if (info.argc == 0) + { + args = NULL; + } + else + { + int idx; + + assert(argtypes != NULL); + args = snv_new (union printf_arg, info.argc); + + /* We scanned the format string to find the type of the arguments, + so we can now cast it and store it correctly. */ + for (idx = 0; idx < info.argc; idx++) + { + int tp = argtypes[idx]; + if ((tp & PA_TYPE_MASK) == PA_TYPE_MASK) + { + if (idx + 1 == info.argc) + { + info.argc--; + break; + } + continue; /* Ignore it. We allow skipping args, but the + * user is responsible for ensuring a void* sized + * spacer in the argument list. + */ + } + + switch (tp & ~PA_FLAG_UNSIGNED) + { + case PA_CHAR: + args[idx].pa_char = (unsigned char)*(const long int *)(ap + idx); + break; + + case PA_WCHAR: + args[idx].pa_wchar = + (snv_wchar_t) *(const long int *)(ap + idx); + break; + + case PA_INT|PA_FLAG_SHORT: + args[idx].pa_short_int = + (short int) *(const long int *)(ap + idx); + break; + + case PA_INT: + args[idx].pa_int = (int) *(const long int *)(ap + idx); + break; + + case PA_INT|PA_FLAG_LONG: + args[idx].pa_long_int = *(const long int *)(ap + idx); + break; + + case PA_INT|PA_FLAG_LONG_LONG: + args[idx].pa_long_long_int = **(const intmax_t **)(ap + idx); + break; + + case PA_FLOAT: + args[idx].pa_float = **(const float **)(ap + idx); + break; + + case PA_DOUBLE|PA_FLAG_LONG_DOUBLE: +#ifdef HAVE_LONG_DOUBLE + args[idx].pa_long_double = **(const long double **)(ap + idx); + break; +#endif + /* else fall through */ + + case PA_DOUBLE: + args[idx].pa_double = **(const double **)(ap + idx); + break; + + /* Note that pointer types are dereferenced just once! */ + case PA_STRING: + args[idx].pa_string = *(const char **)(ap + idx); + break; + + case PA_WSTRING: + args[idx].pa_wstring = *(const snv_wchar_t **)(ap + idx); + break; + + case PA_POINTER: + args[idx].pa_pointer = *(snv_constpointer *)(ap + idx); + break; + + default: + if (argtypes[idx] & PA_FLAG_PTR) + args[idx].pa_pointer = *(snv_constpointer *)(ap + idx); + else + args[idx].pa_long_double = 0.0; + break; + } + } + } + + if (printf_last_error) + snv_delete (printf_last_error); + + if (info.error) + printf_last_error = fildelete (info.error); + else + printf_last_error = NULL; + + count_or_errorcode = do_printfv (stream, format, args); + + snv_delete (argtypes); + if (info.argc > 0) + snv_delete (args); + + return count_or_errorcode; +} + + +/** + * stream_vprintf: printf.h + * @stream: an initialised stream structure. + * @format: a % delimited format string. + * @ap: a varargs/stdargs va_list. + * + * Format the elements of @ap according to @format, and write + * the results to @stream. If @stream is %NULL, only count the + * number of characters needed to output the format. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +int +stream_vprintf (STREAM *stream, const char *format, va_list ap) +{ + union printf_arg *args = NULL; + struct printf_info info; + int count_or_errorcode; + int *argtypes = NULL; + + return_val_if_fail (format != NULL, SNV_ERROR); + + parser_init (&info, format, NULL); + + /* Keep going until the format string runs out! */ + while (*info.format != EOS) + { + int ch = (int) *info.format++; + + switch (ch) + { + case SNV_CHAR_SPEC: + if (*info.format != SNV_CHAR_SPEC) + { + /* We found the start of a format specifier! */ + spec_entry *spec; + + parser_reset (&info); + do + { + /* Until we fill the stream (or get some other + exception) or one of the handlers tells us + we have reached the end of the specifier... */ + /* ...lookup the handler associated with the char + we are looking at in the format string... */ + spec = spec_lookup ((unsigned)*(info.format)); + if (spec == NULL) + { + PRINTF_ERROR (&info, "unregistered specifier"); + goto error; + } + + if (!IS_MODIFIER (spec) && + !(info.state & (SNV_STATE_BEGIN | SNV_STATE_SPECIFIER))) + { + PRINTF_ERROR (&info, "invalid combination of flags"); + goto error; + } + + /* ...and call the relevant handler. */ + if (call_argtype_function (&info, &argtypes, spec) < 0) + goto error; + + info.format++; + } + while (info.count >= 0 && IS_MODIFIER (spec)); + continue; + } + /* An escaped CHAR_SPEC: ignore it (by falling through). */ + ++info.format; + + /*FALLTHROUGH*/ + + default: /* Just a character: ignore it. */ + continue; + } + + error: + /* Get here on error */ + info.argc = -1; + break; + } + + if (info.argc > 0) + { + int idx; + + assert(argtypes != NULL); + args = snv_new (union printf_arg, info.argc); + + /* Scan the format string to find the type of the argument + so we can cast it and store it correctly. + + Note that according to the ISO C standards, standard + type promotion takes place on any variadic arguments as + they are aligned on the call stack, and so it is these + promoted types that we must extract with the va_arg() + macro, or the alignment gets all messed up. + + Thanks to Robert Lipe for explaining all + this to me. */ + for (idx = 0; idx < info.argc; idx++) + switch (argtypes[idx] & ~PA_FLAG_UNSIGNED) + { + case PA_CHAR: + args[idx].pa_char = (unsigned char)va_arg (ap, int); /* Promoted */ + break; + + case PA_WCHAR: + args[idx].pa_wchar = (snv_wchar_t)va_arg (ap, snv_wint_t); + break; + + case PA_INT|PA_FLAG_SHORT: + args[idx].pa_short_int = (short int)va_arg (ap, int); + break; + + case PA_INT: + args[idx].pa_int = va_arg (ap, int); + break; + + case PA_INT|PA_FLAG_LONG: + args[idx].pa_long_int = va_arg (ap, long int); + break; + + case PA_INT|PA_FLAG_LONG_LONG: + args[idx].pa_long_long_int = va_arg (ap, intmax_t); + break; + + case PA_FLOAT: + args[idx].pa_float = (float)va_arg (ap, double); /* Promoted. */ + break; + + case PA_DOUBLE|PA_FLAG_LONG_DOUBLE: + args[idx].pa_long_double = va_arg (ap, long double); + break; + + case PA_DOUBLE: + args[idx].pa_double = va_arg (ap, double); + break; + + case PA_STRING: + args[idx].pa_string = va_arg (ap, const char *); + break; + + case PA_WSTRING: + args[idx].pa_wstring = va_arg (ap, const snv_wchar_t *); + break; + + case PA_POINTER: + args[idx].pa_pointer = va_arg (ap, void *); + break; + + default: + if (argtypes[idx] & PA_FLAG_PTR) + args[idx].pa_pointer = va_arg (ap, void *); + else + args[idx].pa_long_double = 0.0; + break; + } + } + + if (printf_last_error) + snv_delete (printf_last_error); + + if (info.error) + printf_last_error = fildelete (info.error); + else + printf_last_error = NULL; + + count_or_errorcode = do_printfv (stream, format, args); + + snv_delete (argtypes); + snv_delete (args); + return count_or_errorcode; +} + +/** + * stream_printf: printf.h + * @stream: an initialised stream structure. + * @format: a % delimited format string. + * @va_alist: a varargs/stdargs va_list. + * + * Format the elements of @va_alist according to @format, and write + * the results to @stream. If @stream is %NULL, only count the + * number of characters needed to output the format. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +int +stream_printf (STREAM * stream, const char *format, ...) +{ + int count_or_errorcode; + va_list ap; + + va_start (ap, format); + count_or_errorcode = stream_vprintf (stream, format, ap); + va_end (ap); + + return count_or_errorcode; +} + + +/* Finally... the main API implementation: */ + +/** + * snv_fdputc: printf.h + * @ch: A single character to be added to @stream. + * @stream: The stream in which to write @ch. + * + * A StreamPut function for use in putting characters + * into STREAMs holding a file descriptor. + * + * Return value: + * The value of @ch that has been put in @stream, or -1 in case of + * an error (errno will be set to indicate the type of error). + **/ +int +snv_fdputc (int ch, STREAM *stream) +{ + static char buf[1] = { 0 }; + buf[0] = (char) ch; + return + write ((int) SNV_POINTER_TO_LONG (stream_details (stream)), buf, (size_t) 1) + ? ch : -1; +} + +/** + * snv_dprintf: printf.h + * @fd: an open file descriptor. + * @format: a % delimited format string. + * @va_alist: a varargs/stdargs va_list. + * + * Format the elements of @va_alist according to @format, and write + * the results to the file descriptor @fd. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +int +snv_dprintf (int fd, const char *format, ...) +{ + int count_or_errorcode; + va_list ap; + + va_start (ap, format); + count_or_errorcode = snv_vdprintf (fd, format, ap); + va_end (ap); + + return count_or_errorcode; +} + +/** + * snv_vdprintf: printf.h + * @fd: an open file descriptor. + * @format: a % delimited format string. + * @ap: a varargs/stdargs va_list. + * + * Format the elements of @ap according to @format, and write + * the results to the file descriptor @fd. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +int +snv_vdprintf (int fd, const char *format, va_list ap) +{ + int result; + STREAM *out = stream_new (SNV_LONG_TO_POINTER (fd), + SNV_UNLIMITED, NULL, snv_fdputc); + + result = stream_vprintf (out, format, ap); + stream_delete (out); + return result; +} + +/** + * snv_dprintfv: printf.h + * @fd: an open file descriptor. + * @format: a % delimited format string. + * @args: a vector of argument addresses to match @format. + * + * Format the elements of @args according to @format, and write + * the results to file descriptor @fd. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +int +snv_dprintfv (int fd, const char *format, snv_constpointer const args[]) +{ + int result; + STREAM *out = stream_new (SNV_LONG_TO_POINTER (fd), + SNV_UNLIMITED, NULL, snv_fdputc); + + result = stream_printfv (out, format, args); + stream_delete (out); + return result; +} + + +/** + * snv_fileputc: printf.h + * @ch: A single character to be added to @stream. + * @stream: The stream in which to write @ch. + * + * A StreamPut function for use in putting characters + * into STREAMs holding a FILE*. + * + * Return value: + * The value of @ch that has been put in @stream. + **/ +int +snv_fileputc (int ch, STREAM *stream) +{ + FILE *fp = (FILE *) stream_details (stream); + return putc (ch, fp); +} + +static int +snv_fileputc_unlocked (int ch, STREAM *stream) +{ + FILE *fp = (FILE *) stream_details (stream); + return SNV_PUTC_UNLOCKED (ch, fp); +} + +/** + * snv_printf: printf.h + * @format: a % delimited format string. + * @va_alist: a varargs/stdargs va_list. + * + * Format the elements of @va_alist according to @format, and write + * the results to the standard output stream. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +int +snv_printf (const char *format, ...) +{ + int count_or_errorcode; + va_list ap; + + va_start (ap, format); + count_or_errorcode = snv_vprintf (format, ap); + va_end (ap); + + return count_or_errorcode; +} + +/** + * snv_vprintf: printf.h + * @format: a % delimited format string. + * @ap: a varargs/stdargs va_list. + * + * Format the elements of @ap according to @format, and write + * the results to the standard output stream. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +int +snv_vprintf (const char *format, va_list ap) +{ + int result; + STREAM *out = stream_new (stdout, SNV_UNLIMITED, NULL, snv_fileputc_unlocked); + int tmp; + + SNV_WITH_LOCKED_FP (stdout, tmp) + result = stream_vprintf (out, format, ap); + + stream_delete (out); + return result; +} + +/** + * snv_printfv: printf.h + * @format: a % delimited format string. + * @args: a vector of argument addresses to match @format. + * + * Format the elements of @args according to the string @format, + * and write the result to the standard output stream. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +int +snv_printfv (const char *format, snv_constpointer const args[]) +{ + int result; + STREAM *out = stream_new (stdout, SNV_UNLIMITED, NULL, snv_fileputc_unlocked); + int tmp; + + SNV_WITH_LOCKED_FP (stdout, tmp) + result = stream_printfv (out, format, args); + stream_delete (out); + return result; +} + +/** + * snv_fprintf: printf.h + * @file: a stdio.h FILE* stream. + * @format: a % delimited format string. + * @va_alist: a varargs/stdargs va_list. + * + * Format the elements of @va_alist according to @format, and write + * the results to the @file stream. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +int +snv_fprintf (FILE * file, const char *format, ...) +{ + int count_or_errorcode; + va_list ap; + + va_start (ap, format); + count_or_errorcode = snv_vfprintf (file, format, ap); + va_end (ap); + + return count_or_errorcode; +} + +/** + * snv_vfprintf: printf.h + * @file: a stdio.h FILE* stream. + * @format: a % delimited format string. + * @ap: a varargs/stdargs va_list. + * + * Format the elements of @ap according to @format, and write + * the results to the @file stream. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +int +snv_vfprintf (FILE *file, const char *format, va_list ap) +{ + int result; + STREAM *out = stream_new (file, SNV_UNLIMITED, NULL, snv_fileputc_unlocked); + int tmp; + + SNV_WITH_LOCKED_FP (file, tmp) + result = stream_vprintf (out, format, ap); + stream_delete (out); + return result; +} + +/** + * snv_fprintfv: printf.h + * @file: a stdio.h FILE* stream. + * @format: a % delimited format string. + * @args: a vector of argument addresses to match @format. + * + * Format the elements of @args according to @format, and write + * the results to @file. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +int +snv_fprintfv (FILE *file, const char *format, snv_constpointer const args[]) +{ + int result; + STREAM *out = stream_new (file, SNV_UNLIMITED, NULL, snv_fileputc_unlocked); + int tmp; + + SNV_WITH_LOCKED_FP (file, tmp) + result = stream_printfv (out, format, args); + + stream_delete (out); + return result; +} + + +/** + * snv_bufputc: printf.h + * @ch: A single character to be added to @stream. + * @stream: The stream in which to write @ch. + * + * A StreamPut function for use in putting characters + * into STREAMs holding a char buffer. + * + * Return value: + * The value of @ch that has been put in @stream. + **/ +int +snv_bufputc (int ch, STREAM * stream) +{ + char **ppbuffer = (char **) stream_details (stream); + **ppbuffer = (char) ch; + (*ppbuffer)++; + return ch; +} + +/** + * snv_sprintf: printf.h + * @buffer: a preallocated char* buffer. + * @format: a % delimited format string. + * @va_alist: a varargs/stdargs va_list. + * + * Format the elements of @va_alist according to @format, and write + * the results to the string @buffer. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +int +snv_sprintf (char buffer[], const char *format, ...) +{ + int count_or_errorcode; + va_list ap; + + va_start (ap, format); + count_or_errorcode = snv_vsprintf (buffer, format, ap); + va_end (ap); + + return count_or_errorcode; +} + +/** + * snv_vsprintf: printf.h + * @buffer: a preallocated char* buffer. + * @format: a % delimited format string. + * @ap: a varargs/stdargs va_list. + * + * Format the elements of @ap according to @format, and write + * the results to the string @buffer. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +int +snv_vsprintf (char buffer[], const char *format, va_list ap) +{ + int count_or_errorcode; + STREAM *out = stream_new (&buffer, SNV_UNLIMITED, NULL, snv_bufputc); + count_or_errorcode = stream_vprintf (out, format, ap); + + /* Terminate with an EOS without incrementing the counter. */ + stream_put (EOS, out); + + stream_delete (out); + return count_or_errorcode; +} + +/** + * snv_sprintfv: printf.h + * @buffer: a preallocated char* buffer. + * @format: a % delimited format string. + * @args: a vector of argument addresses to match @format. + * + * Format the elements of @args according to @format, and write + * the results to the string @buffer. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +int +snv_sprintfv (char buffer[], const char *format, snv_constpointer const args[]) +{ + int count_or_errorcode; + STREAM *out = stream_new (&buffer, SNV_UNLIMITED, NULL, snv_bufputc); + count_or_errorcode = stream_printfv (out, format, args); + + /* Terminate with an EOS without incrementing the counter. */ + stream_put (EOS, out); + + stream_delete (out); + return count_or_errorcode; +} + +/** + * snv_snprintf: printf.h + * @buffer: a preallocated char* buffer. + * @limit: the maximum number of characters to write into @buffer. + * @format: a % delimited format string. + * @va_alist: a varargs/stdargs va_list. + * + * Format the elements of @va_alist according to @format, and write + * the results to the string @buffer, truncating the formatted string + * if it reaches @limit characters in length. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +int +snv_snprintf (char buffer[], unsigned long limit, const char *format, ...) +{ + int count_or_errorcode; + va_list ap; + + va_start (ap, format); + count_or_errorcode = snv_vsnprintf (buffer, limit, format, ap); + va_end (ap); + + return count_or_errorcode; +} + +/** + * snv_vsnprintf: printf.h + * @buffer: a preallocated char* buffer. + * @limit: the maximum number of characters to write into @buffer. + * @format: a % delimited format string. + * @ap: a varargs/stdargs va_list. + * + * Format the elements of @ap according to @format, and write + * the results to the string @buffer, truncating the formatted string + * if it reaches @limit characters in length. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +int +snv_vsnprintf (char buffer[], unsigned long limit, const char *format, va_list ap) +{ + int count_or_errorcode; + STREAM *out = stream_new (&buffer, limit - 1, NULL, snv_bufputc); + count_or_errorcode = stream_vprintf (out, format, ap); + *buffer = EOS; + + stream_delete (out); + return count_or_errorcode; +} + +/** + * snv_snprintfv: printf.h + * @buffer: a preallocated char* buffer. + * @limit: the maximum number of characters to write into @buffer. + * @format: a % delimited format string. + * @args: a vector of argument addresses to match @format. + * + * Format the elements of @args according to @format, and write + * the results to the string @buffer, truncating the formatted string + * if it reaches @limit characters in length. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +int +snv_snprintfv (char buffer[], unsigned long limit, const char *format, + snv_constpointer const args[]) +{ + int count_or_errorcode; + STREAM *out = stream_new (&buffer, limit - 1, NULL, snv_bufputc); + count_or_errorcode = stream_printfv (out, format, args); + *buffer = EOS; + + stream_delete (out); + return count_or_errorcode; +} + + +/** + * snv_filputc: printf.h + * @ch: A single character to be added to @stream. + * @stream: The stream in which to write @ch. + * + * A StreamPut function for use in putting characters + * into STREAMs holding a Filament*. + * + * Return value: + * The value of @ch that has been put in @stream. + **/ +int +snv_filputc (int ch, STREAM * stream) +{ + return filccat ((Filament *) stream_details (stream), ch), ch; +} + +/** + * snv_asprintf: printf.h + * @result: the address of a char * variable. + * @format: a % delimited format string. + * @va_alist: a varargs/stdargs va_list. + * + * Format the elements of @va_alist according to @format, and write + * the results to an internally allocated buffer whose address is + * stored in @result (and should be freed by the caller) unless + * there is an error. + * + * Yes, this interface is cumbersome and totally useless. It would + * have been better to simply return the allocated address, but + * it turns out that somebody wasn't thinking much when adding + * asprintf to libiberty a few years ago. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +int +snv_asprintf (char **result, const char *format, ...) +{ + int count; + va_list ap; + + va_start (ap, format); + count = snv_vasprintf (result, format, ap); + va_end (ap); + + return count; +} + +/** + * snv_vasprintf: printf.h + * @result: the address of a char * variable. + * @format: a % delimited format string. + * @ap: a varargs/stdargs va_list. + * + * Format the elements of @ap according to @format, and write + * the results to an internally allocated buffer whose address is + * stored in @result (and should be freed by the caller) unless + * there is an error. + * + * Above moaning for asprintf applies here too. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +int +snv_vasprintf (char **result, const char *format, va_list ap) +{ + int count_or_errorcode; + char *base; + Filament *fil = filnew (NULL, (size_t)0); + STREAM *out = stream_new (fil, SNV_UNLIMITED, NULL, snv_filputc); + count_or_errorcode = stream_vprintf (out, format, ap); + + base = fildelete (fil); + stream_delete (out); + + *result = (count_or_errorcode < 0) ? NULL : base; + return count_or_errorcode; +} + +/** + * snv_asprintfv: printf.h + * @result: the address of a char * variable. + * @format: a % delimited format string. + * @args: a vector of argument addresses to match @format. + * + * Format the elements of @args according to @format, and write + * the results to an internally allocated buffer whose address is + * stored in @result (and should be freed by the caller) unless + * there is an error. + * + * Above moaning for asprintf applies here too. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +int +snv_asprintfv (char **result, const char *format, snv_constpointer const args[]) +{ + int count_or_errorcode; + char *base; + Filament *fil = filnew (NULL, (size_t)0); + STREAM *out = stream_new (fil, SNV_UNLIMITED, NULL, snv_filputc); + count_or_errorcode = stream_printfv (out, format, args); + + base = fildelete (fil); + stream_delete (out); + + *result = (count_or_errorcode < 0) ? NULL : base; + return count_or_errorcode; +} + +/* + * Local Variables: + * mode: C + * c-file-style: "gnu" + * indent-tabs-mode: nil + * End: + * end of snprintfv/printfv.c */ diff --git a/snprintfv/printf.h b/snprintfv/printf.h new file mode 100644 index 0000000..784ec46 --- /dev/null +++ b/snprintfv/printf.h @@ -0,0 +1,845 @@ +/* -*- Mode: C -*- */ + +/* printf.in --- printf clone for argv arrays + * Copyright (C) 1998, 1999, 2000, 2002 Gary V. Vaughan + * Originally by Gary V. Vaughan, 1998 + * This file is part of Snprintfv + * + * Snprintfv 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. + * + * Snprintfv 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 . + * + * As a special exception to the GNU General Public License, if you + * distribute this file as part of a program that also links with and + * uses the libopts library from AutoGen, you may include it under + * the same distribution terms used by the libopts library. + */ + +/* Code: */ + +#ifndef SNPRINTFV_SNPRINTFV_H +#define SNPRINTFV_SNPRINTFV_H 1 + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* The type of each element in the table of printf specifiers. */ +struct spec_entry; + +typedef enum +{ + SNV_ERROR = -1, + SNV_OK +} +snv_status; + +/* Basic states required by the parser. On initialisation the parser + will be in SNV_STATE_BEGIN, and tokens will be parsed by the registered + functions until the parser reached SNV_STATE_END. */ +#define SNV_STATE_BEGIN 1 +#define SNV_STATE_END 0 + +/* States needed to support: + %[$][|\*][.|\*] */ +#define SNV_STATE_FLAG (1 << 1) +#define SNV_STATE_WIDTH (1 << 2) +#define SNV_STATE_PRECISION (1 << 3) +#define SNV_STATE_MODIFIER (1 << 4) +#define SNV_STATE_SPECIFIER (1 << 5) + +/* First state available to the user */ +#define SNV_STATE_USER_FIRST (1 << 8) + +/* Mask for states available to the user */ +#define SNV_STATE_USER_MASK ~(SNV_STATE_USER_FIRST - 1) + +typedef struct printf_info +{ + int count; /* accumulated count, or SNV_ERROR */ + int state; /* one of the defines above */ + Filament *error; /* accumulated error details */ + + const char *format; /* pointer to format string */ + int argc; /* number of arguments used by format */ + int argindex; /* number of non-dollar arguments used so far */ + + int dollar; /* standard parser state, as in glibc */ + int prec; /* from this field on, as in glibc */ + int width; + + snv_pointer extra; + int type; + + char spec; + char pad; + unsigned is_long_double:1; + unsigned is_char:1; + unsigned is_short:1; + unsigned is_long:1; + unsigned alt:1; + unsigned space:1; + unsigned left:1; + unsigned showsign:1; + unsigned group:1; + unsigned wide:1; + + const union printf_arg *args; +} printf_info; + +/** + * printf_arg: + * @pa_char: an unsigned %char + * @pa_wchar: a %wchar_t + * @pa_short_int: a %short integer + * @pa_int: an %int + * @pa_long_int: a %long integer + * @pa_long_long_int: the widest signed integer type in use on the host + * @pa_u_short_int: an unsigned %short integer + * @pa_u_int: an unsigned %int + * @pa_u_long_int: an unsigned %long integer + * @pa_u_long_long_int: the widest unsigned integer type in use on the host + * @pa_float: a %float + * @pa_double: a %double + * @pa_long_double: a long %double, or a simple %double if it is the widest floating-point type in use on the host + * @pa_string: a %const pointer to %char + * @pa_wstring: a %const pointer to %wchar_t + * @pa_pointer: a generic pointer + * + * The various kinds of arguments that can be passed to printf. + */ +typedef union printf_arg +{ + unsigned char pa_char; + snv_wchar_t pa_wchar; + short int pa_short_int; + int pa_int; + long int pa_long_int; + intmax_t pa_long_long_int; + unsigned short int pa_u_short_int; + unsigned int pa_u_int; + unsigned long int pa_u_long_int; + uintmax_t pa_u_long_long_int; + float pa_float; + double pa_double; + long double pa_long_double; + const char *pa_string; + const snv_wchar_t *pa_wstring; + snv_constpointer pa_pointer; +} printf_arg; + +/** + * PRINTF_ERROR: + * @pi: A pointer to the current state for the parser + * @str: The error message + * + * Append an error that will be returned by printf_strerror. + */ +#define PRINTF_ERROR(pi, str) \ + printf_error(pi, __FILE__, __LINE__, SNV_ASSERT_FCN, str); + +typedef int printf_function (STREAM *stream, struct printf_info *pparser, + union printf_arg const * args); + +typedef int printf_arginfo_function (struct printf_info *pparser, size_t n, + int *argtypes); + +/** + * spec_entry: + * @spec: the specifier character that was matched + * @type: when @arg is NULL, the type of the only argument to the specifier + * @fmt: the handler function to actually print the arguments to the specifier + * @arg: the handler function to tell %printf about the types of the arguments to the specifier + * @user: the user data for the specifier, accessible to the handler function + * + * This is returned by register_printf_function. + */ +typedef struct spec_entry +{ + unsigned int spec_key; + int unused; /* for binary compatibility */ + int type; + printf_function *fmt; + printf_arginfo_function *arg; + snv_pointer user; +} +spec_entry; + +/** + * register_callback_function: printf.h + * @spec: the character which will trigger the functions, cast to an unsigned int. + * @fmt: the handler function to actually print the arguments to the specifier + * @arg: the handler function to tell %printf about the types of the arguments to the specifier + * + * Register the pair made of @fmt and @arg, so that it is called + * when @spec is encountered in a format string. If you create + * a shared library with an entry point named + * %snv_register_printf_funcs, and put the library in the + * search path given by the environment library %LTDL_LIBRARY_PATH, + * that entry point will be called when %libsnprintfv is initialized, + * passing a pointer to this kind of function (actually, a pointer + * to %register_printf_function) to it. This functionality is only + * present when the library is installed, not when it is built as + * a convenience library. + * + * Return value: + * Returns %NULL if @func was not successfully registered, a + * %spec_entry with the information on the function if it was. + **/ +typedef spec_entry *register_callback_function (unsigned spec, printf_function *func, printf_arginfo_function *arginfo); + +/* Codes to determine basic types. + + These values cover all the standard format specifications. + Users can add new values after PA_LAST for their own types. */ + +enum +{ + PA_INT, /* int */ + PA_CHAR, /* int, cast to char */ + PA_WCHAR, /* wide char */ + PA_STRING, /* const char *, a '\0'-terminated string */ + PA_WSTRING, /* const wchar_t *, wide character string */ + PA_POINTER, /* void * */ + PA_FLOAT, /* float */ + PA_DOUBLE, /* double */ + PA_LAST, + PA_UNKNOWN = -1 +}; + +/* Flag bits that can be set in a type. */ +#define PA_TYPE_MASK 0x00ff +#define PA_FLAG_MASK ~SNV_TYPE_MASK + +#define PA_FLAG_LONG_LONG (1 << 8) +#define PA_FLAG_LONG_DOUBLE PA_FLAG_LONG_LONG +#define PA_FLAG_LONG (1 << 9) +#define PA_FLAG_SHORT (1 << 10) +#define PA_FLAG_UNSIGNED (1 << 11) +#define PA_FLAG_CHAR (1 << 12) +#define PA_FLAG_PTR (1 << 13) + +/** + * SNV_EMIT: + * @ch: the character to be printed + * @stream: the stream on which to print + * @count: a variable to be updated with the count of printed + * characters + * + * Maintain the count while putting @ch in @stream, also be careful about + * handling %NULL stream if the handler is being called purely to count + * output size. + **/ +#define SNV_EMIT(ch, stream, count) \ + SNV_STMT_START { \ + if ((stream)) \ + { \ + if ((count) >= 0) \ + { \ + int m_status = stream_put((unsigned char) (ch), (stream)); \ + (count) = m_status < 0 ? m_status : (count) + m_status; \ + } \ + } \ + else \ + { \ + (void)(ch); \ + (count)++; \ + } \ + } SNV_STMT_END + +#line 266 "printf.in" +/** + * printf_generic_info: + * @pinfo: the current state information for the format + * string parser. + * @n: the number of available slots in the @argtypes array + * @argtypes: the pointer to the first slot to be filled by the + * function + * + * An example implementation of a %printf_arginfo_function, which + * takes the basic type from the type given in the %spec_entry + * and adds flags depending on what was parsed (e.g. %PA_FLAG_SHORT + * is %pparser->is_short and so on). + * + * Return value: + * Always 1. + */ +extern int +printf_generic_info (struct printf_info *const pinfo, size_t n, int *argtypes); + +/** + * printf_generic: + * @stream: the stream (possibly a struct printfv_stream appropriately + * cast) on which to write output. + * @pinfo: the current state information for the format string parser. + * @args: the pointer to the first argument to be read by the handler + * + * An example implementation of a %printf_function, used to provide easy + * access to justification, width and precision options. + * + * Return value: + * The number of characters output. + **/ +extern int +printf_generic (STREAM *stream, struct printf_info *const pinfo, union printf_arg const *args); + +#line 267 "printf.in" +/** + * register_printf_function: printf.h + * @spec: the character which will trigger @func, cast to an unsigned int. + * @fmt: the handler function to actually print the arguments to the specifier + * @arg: the handler function to tell %printf about the types of the arguments + * to the specifier + * + * Register the pair made of @fmt and @arg, so that it is called + * when @spec is encountered in a format string. + * + * Return value: + * Returns %NULL if @func was not successfully registered, a + * %spec_entry with the information on the function if it was. + **/ +extern spec_entry * +register_printf_function (unsigned spec, printf_function *fmt, + printf_arginfo_function *arg); + +/** + * printf_strerror: printf.h + * + * Communicate information on the last error in a printf + * format string. + * + * Return value: + * A string describing the last error which occurred during the + * parsing of a printf format string. It is the responsibility + * of the caller to free the string. + */ +extern char * +printf_strerror (void); + +/** + * printf_error: printf.h + * @pinfo: pointer to the current parser state. + * @file: file where error was detected. + * @line: line where error was detected. + * @func1: " (" if function is supplied by compiler. + * @func2: function where error was detected, if supplied by compiler. + * @func3: ")" if function is supplied by compiler. + * @error_message: new error message to append to @pinfo. + * + * The contents of @error_message are appended to the @pinfo internal + * error string, so it is safe to pass static strings or recycle the + * original when this function returns. + * + * Return value: + * The address of the full accumulated error message in @pinfo is + * returned. + **/ +extern char * +printf_error (struct printf_info *pinfo, const char *file, int line, + const char *func1, const char *func2, const char *func3, + const char *error_message); + +/** + * parse_printf_format: printf.h + * @format: a % delimited format string. + * @n: the size of the @argtypes vector + * @argtypes: a vector of ints, to be filled with the argument types from @format + * + * Returns information about the number and types of + * arguments expected by the template string @format. + * The argument @n specifies the number of elements in the array + * @argtypes. This is the maximum number of elements that + * the function will try to write. + * + * Return value: + * The total number of arguments required by @format. If this + * number is greater than @n, then the information returned + * describes only the first @n arguments. If you want information + * about additional arguments, allocate a bigger array and call + * this function again. If there is an error, then %SNV_ERROR + * is returned instead. + **/ +extern size_t +parse_printf_format (const char *format, int n, int *argtypes); + +/** + * stream_printfv: printf.h + * @stream: an initialised stream structure. + * @format: a % delimited format string. + * @args: a vector of argument addresses to match @format. + * + * Format the elements of @args according to @format, and write + * the results to @stream. If @stream is %NULL, only count the + * number of characters needed to output the format. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +extern int +stream_printfv (STREAM *stream, const char *format, snv_constpointer const *ap); + +/** + * stream_vprintf: printf.h + * @stream: an initialised stream structure. + * @format: a % delimited format string. + * @ap: a varargs/stdargs va_list. + * + * Format the elements of @ap according to @format, and write + * the results to @stream. If @stream is %NULL, only count the + * number of characters needed to output the format. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +extern int +stream_vprintf (STREAM *stream, const char *format, va_list ap); + +/** + * stream_printf: printf.h + * @stream: an initialised stream structure. + * @format: a % delimited format string. + * @va_alist: a varargs/stdargs va_list. + * + * Format the elements of @va_alist according to @format, and write + * the results to @stream. If @stream is %NULL, only count the + * number of characters needed to output the format. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +extern int +stream_printf (STREAM * stream, const char *format, ...); + +/** + * snv_fdputc: printf.h + * @ch: A single character to be added to @stream. + * @stream: The stream in which to write @ch. + * + * A StreamPut function for use in putting characters + * into STREAMs holding a file descriptor. + * + * Return value: + * The value of @ch that has been put in @stream, or -1 in case of + * an error (errno will be set to indicate the type of error). + **/ +extern int +snv_fdputc (int ch, STREAM *stream); + +/** + * snv_dprintf: printf.h + * @fd: an open file descriptor. + * @format: a % delimited format string. + * @va_alist: a varargs/stdargs va_list. + * + * Format the elements of @va_alist according to @format, and write + * the results to the file descriptor @fd. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +extern int +snv_dprintf (int fd, const char *format, ...); + +/** + * snv_vdprintf: printf.h + * @fd: an open file descriptor. + * @format: a % delimited format string. + * @ap: a varargs/stdargs va_list. + * + * Format the elements of @ap according to @format, and write + * the results to the file descriptor @fd. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +extern int +snv_vdprintf (int fd, const char *format, va_list ap); + +/** + * snv_dprintfv: printf.h + * @fd: an open file descriptor. + * @format: a % delimited format string. + * @args: a vector of argument addresses to match @format. + * + * Format the elements of @args according to @format, and write + * the results to file descriptor @fd. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +extern int +snv_dprintfv (int fd, const char *format, snv_constpointer const args[]); + +/** + * snv_fileputc: printf.h + * @ch: A single character to be added to @stream. + * @stream: The stream in which to write @ch. + * + * A StreamPut function for use in putting characters + * into STREAMs holding a FILE*. + * + * Return value: + * The value of @ch that has been put in @stream. + **/ +extern int +snv_fileputc (int ch, STREAM *stream); + +/** + * snv_printf: printf.h + * @format: a % delimited format string. + * @va_alist: a varargs/stdargs va_list. + * + * Format the elements of @va_alist according to @format, and write + * the results to the standard output stream. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +extern int +snv_printf (const char *format, ...); + +/** + * snv_vprintf: printf.h + * @format: a % delimited format string. + * @ap: a varargs/stdargs va_list. + * + * Format the elements of @ap according to @format, and write + * the results to the standard output stream. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +extern int +snv_vprintf (const char *format, va_list ap); + +/** + * snv_printfv: printf.h + * @format: a % delimited format string. + * @args: a vector of argument addresses to match @format. + * + * Format the elements of @args according to the string @format, + * and write the result to the standard output stream. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +extern int +snv_printfv (const char *format, snv_constpointer const args[]); + +/** + * snv_fprintf: printf.h + * @file: a stdio.h FILE* stream. + * @format: a % delimited format string. + * @va_alist: a varargs/stdargs va_list. + * + * Format the elements of @va_alist according to @format, and write + * the results to the @file stream. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +extern int +snv_fprintf (FILE * file, const char *format, ...); + +/** + * snv_vfprintf: printf.h + * @file: a stdio.h FILE* stream. + * @format: a % delimited format string. + * @ap: a varargs/stdargs va_list. + * + * Format the elements of @ap according to @format, and write + * the results to the @file stream. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +extern int +snv_vfprintf (FILE *file, const char *format, va_list ap); + +/** + * snv_fprintfv: printf.h + * @file: a stdio.h FILE* stream. + * @format: a % delimited format string. + * @args: a vector of argument addresses to match @format. + * + * Format the elements of @args according to @format, and write + * the results to @file. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +extern int +snv_fprintfv (FILE *file, const char *format, snv_constpointer const args[]); + +/** + * snv_bufputc: printf.h + * @ch: A single character to be added to @stream. + * @stream: The stream in which to write @ch. + * + * A StreamPut function for use in putting characters + * into STREAMs holding a char buffer. + * + * Return value: + * The value of @ch that has been put in @stream. + **/ +extern int +snv_bufputc (int ch, STREAM * stream); + +/** + * snv_sprintf: printf.h + * @buffer: a preallocated char* buffer. + * @format: a % delimited format string. + * @va_alist: a varargs/stdargs va_list. + * + * Format the elements of @va_alist according to @format, and write + * the results to the string @buffer. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +extern int +snv_sprintf (char buffer[], const char *format, ...); + +/** + * snv_vsprintf: printf.h + * @buffer: a preallocated char* buffer. + * @format: a % delimited format string. + * @ap: a varargs/stdargs va_list. + * + * Format the elements of @ap according to @format, and write + * the results to the string @buffer. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +extern int +snv_vsprintf (char buffer[], const char *format, va_list ap); + +/** + * snv_sprintfv: printf.h + * @buffer: a preallocated char* buffer. + * @format: a % delimited format string. + * @args: a vector of argument addresses to match @format. + * + * Format the elements of @args according to @format, and write + * the results to the string @buffer. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +extern int +snv_sprintfv (char buffer[], const char *format, snv_constpointer const args[]); + +/** + * snv_snprintf: printf.h + * @buffer: a preallocated char* buffer. + * @limit: the maximum number of characters to write into @buffer. + * @format: a % delimited format string. + * @va_alist: a varargs/stdargs va_list. + * + * Format the elements of @va_alist according to @format, and write + * the results to the string @buffer, truncating the formatted string + * if it reaches @limit characters in length. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +extern int +snv_snprintf (char buffer[], unsigned long limit, const char *format, ...); + +/** + * snv_vsnprintf: printf.h + * @buffer: a preallocated char* buffer. + * @limit: the maximum number of characters to write into @buffer. + * @format: a % delimited format string. + * @ap: a varargs/stdargs va_list. + * + * Format the elements of @ap according to @format, and write + * the results to the string @buffer, truncating the formatted string + * if it reaches @limit characters in length. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +extern int +snv_vsnprintf (char buffer[], unsigned long limit, const char *format, va_list ap); + +/** + * snv_snprintfv: printf.h + * @buffer: a preallocated char* buffer. + * @limit: the maximum number of characters to write into @buffer. + * @format: a % delimited format string. + * @args: a vector of argument addresses to match @format. + * + * Format the elements of @args according to @format, and write + * the results to the string @buffer, truncating the formatted string + * if it reaches @limit characters in length. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +extern int +snv_snprintfv (char buffer[], unsigned long limit, const char *format, + snv_constpointer const args[]); + +/** + * snv_filputc: printf.h + * @ch: A single character to be added to @stream. + * @stream: The stream in which to write @ch. + * + * A StreamPut function for use in putting characters + * into STREAMs holding a Filament*. + * + * Return value: + * The value of @ch that has been put in @stream. + **/ +extern int +snv_filputc (int ch, STREAM * stream); + +/** + * snv_asprintf: printf.h + * @result: the address of a char * variable. + * @format: a % delimited format string. + * @va_alist: a varargs/stdargs va_list. + * + * Format the elements of @va_alist according to @format, and write + * the results to an internally allocated buffer whose address is + * stored in @result (and should be freed by the caller) unless + * there is an error. + * + * Yes, this interface is cumbersome and totally useless. It would + * have been better to simply return the allocated address, but + * it turns out that somebody wasn't thinking much when adding + * asprintf to libiberty a few years ago. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +extern int +snv_asprintf (char **result, const char *format, ...); + +/** + * snv_vasprintf: printf.h + * @result: the address of a char * variable. + * @format: a % delimited format string. + * @ap: a varargs/stdargs va_list. + * + * Format the elements of @ap according to @format, and write + * the results to an internally allocated buffer whose address is + * stored in @result (and should be freed by the caller) unless + * there is an error. + * + * Above moaning for asprintf applies here too. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +extern int +snv_vasprintf (char **result, const char *format, va_list ap); + +/** + * snv_asprintfv: printf.h + * @result: the address of a char * variable. + * @format: a % delimited format string. + * @args: a vector of argument addresses to match @format. + * + * Format the elements of @args according to @format, and write + * the results to an internally allocated buffer whose address is + * stored in @result (and should be freed by the caller) unless + * there is an error. + * + * Above moaning for asprintf applies here too. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +extern int +snv_asprintfv (char **result, const char *format, snv_constpointer const args[]); + +#line 268 "printf.in" + +/* If you don't want to use snprintfv functions for *all* of your string + formatting API, then define COMPILING_SNPRINTFV_C and use the snv_ + prefix for the entry points below. */ +#ifndef COMPILING_PRINTF_C +#undef printf +#undef vprintf +#undef dprintf +#undef vdprintf +#undef fprintf +#undef vfprintf +#undef sprintf +#undef vsprintf +#undef snprintf +#undef vsnprintf +#undef asprintf +#undef vasprintf +#undef asprintfv +#undef dprintfv +#undef fprintfv +#undef sprintfv +#undef printfv +#undef snprintfv + +#define printf snv_printf +#define vprintf snv_vprintf +#define dprintf snv_dprintf +#define vdprintf snv_vdprintf +#define fprintf snv_fprintf +#define vfprintf snv_vfprintf +#define sprintf snv_sprintf +#define vsprintf snv_vsprintf +#define snprintf snv_snprintf +#define vsnprintf snv_vsnprintf +#define asprintf snv_asprintf +#define vasprintf snv_vasprintf +#define asprintfv snv_asprintfv +#define dprintfv snv_dprintfv +#define fprintfv snv_fprintfv +#define sprintfv snv_sprintfv +#define printfv snv_printfv +#define snprintfv snv_snprintfv +#endif /* !COMPILING_SNPRINTFV_C */ +#ifdef __cplusplus +} +#endif + +#endif /* SNPRINTFV_SNPRINTFV_H */ + +/* snprintfv.h ends here */ diff --git a/snprintfv/printf.in b/snprintfv/printf.in new file mode 100644 index 0000000..8fef02c --- /dev/null +++ b/snprintfv/printf.in @@ -0,0 +1,317 @@ +/* -*- Mode: C -*- */ + +/* printf.in --- printf clone for argv arrays + * Copyright (C) 1998, 1999, 2000, 2002 Gary V. Vaughan + * Originally by Gary V. Vaughan, 1998 + * This file is part of Snprintfv + * + * Snprintfv 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. + * + * Snprintfv 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 . + * + * As a special exception to the GNU General Public License, if you + * distribute this file as part of a program that also links with and + * uses the libopts library from AutoGen, you may include it under + * the same distribution terms used by the libopts library. + */ + +/* Code: */ + +#ifndef SNPRINTFV_SNPRINTFV_H +#define SNPRINTFV_SNPRINTFV_H 1 + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* The type of each element in the table of printf specifiers. */ +struct spec_entry; + +typedef enum +{ + SNV_ERROR = -1, + SNV_OK +} +snv_status; + +/* Basic states required by the parser. On initialisation the parser + will be in SNV_STATE_BEGIN, and tokens will be parsed by the registered + functions until the parser reached SNV_STATE_END. */ +#define SNV_STATE_BEGIN 1 +#define SNV_STATE_END 0 + +/* States needed to support: + %[$][|\*][.|\*] */ +#define SNV_STATE_FLAG (1 << 1) +#define SNV_STATE_WIDTH (1 << 2) +#define SNV_STATE_PRECISION (1 << 3) +#define SNV_STATE_MODIFIER (1 << 4) +#define SNV_STATE_SPECIFIER (1 << 5) + +/* First state available to the user */ +#define SNV_STATE_USER_FIRST (1 << 8) + +/* Mask for states available to the user */ +#define SNV_STATE_USER_MASK ~(SNV_STATE_USER_FIRST - 1) + +typedef struct printf_info +{ + int count; /* accumulated count, or SNV_ERROR */ + int state; /* one of the defines above */ + Filament *error; /* accumulated error details */ + + const char *format; /* pointer to format string */ + int argc; /* number of arguments used by format */ + int argindex; /* number of non-dollar arguments used so far */ + + int dollar; /* standard parser state, as in glibc */ + int prec; /* from this field on, as in glibc */ + int width; + + snv_pointer extra; + int type; + + char spec; + char pad; + unsigned is_long_double:1; + unsigned is_char:1; + unsigned is_short:1; + unsigned is_long:1; + unsigned alt:1; + unsigned space:1; + unsigned left:1; + unsigned showsign:1; + unsigned group:1; + unsigned wide:1; + + const union printf_arg *args; +} printf_info; + +/** + * printf_arg: + * @pa_char: an unsigned %char + * @pa_wchar: a %wchar_t + * @pa_short_int: a %short integer + * @pa_int: an %int + * @pa_long_int: a %long integer + * @pa_long_long_int: the widest signed integer type in use on the host + * @pa_u_short_int: an unsigned %short integer + * @pa_u_int: an unsigned %int + * @pa_u_long_int: an unsigned %long integer + * @pa_u_long_long_int: the widest unsigned integer type in use on the host + * @pa_float: a %float + * @pa_double: a %double + * @pa_long_double: a long %double, or a simple %double if it is the widest floating-point type in use on the host + * @pa_string: a %const pointer to %char + * @pa_wstring: a %const pointer to %wchar_t + * @pa_pointer: a generic pointer + * + * The various kinds of arguments that can be passed to printf. + */ +typedef union printf_arg +{ + unsigned char pa_char; + snv_wchar_t pa_wchar; + short int pa_short_int; + int pa_int; + long int pa_long_int; + intmax_t pa_long_long_int; + unsigned short int pa_u_short_int; + unsigned int pa_u_int; + unsigned long int pa_u_long_int; + uintmax_t pa_u_long_long_int; + float pa_float; + double pa_double; + long double pa_long_double; + const char *pa_string; + const snv_wchar_t *pa_wstring; + snv_constpointer pa_pointer; +} printf_arg; + +/** + * PRINTF_ERROR: + * @pi: A pointer to the current state for the parser + * @str: The error message + * + * Append an error that will be returned by printf_strerror. + */ +#define PRINTF_ERROR(pi, str) \ + printf_error(pi, __FILE__, __LINE__, SNV_ASSERT_FCN, str); + +typedef int printf_function (STREAM *stream, struct printf_info *pparser, + union printf_arg const * args); + +typedef int printf_arginfo_function (struct printf_info *pparser, size_t n, + int *argtypes); + +/** + * spec_entry: + * @spec: the specifier character that was matched + * @type: when @arg is NULL, the type of the only argument to the specifier + * @fmt: the handler function to actually print the arguments to the specifier + * @arg: the handler function to tell %printf about the types of the arguments to the specifier + * @user: the user data for the specifier, accessible to the handler function + * + * This is returned by register_printf_function. + */ +typedef struct spec_entry +{ + unsigned int spec_key; + int unused; /* for binary compatibility */ + int type; + printf_function *fmt; + printf_arginfo_function *arg; + snv_pointer user; +} +spec_entry; + +/** + * register_callback_function: printf.h + * @spec: the character which will trigger the functions, cast to an unsigned int. + * @fmt: the handler function to actually print the arguments to the specifier + * @arg: the handler function to tell %printf about the types of the arguments to the specifier + * + * Register the pair made of @fmt and @arg, so that it is called + * when @spec is encountered in a format string. If you create + * a shared library with an entry point named + * %snv_register_printf_funcs, and put the library in the + * search path given by the environment library %LTDL_LIBRARY_PATH, + * that entry point will be called when %libsnprintfv is initialized, + * passing a pointer to this kind of function (actually, a pointer + * to %register_printf_function) to it. This functionality is only + * present when the library is installed, not when it is built as + * a convenience library. + * + * Return value: + * Returns %NULL if @func was not successfully registered, a + * %spec_entry with the information on the function if it was. + **/ +typedef spec_entry *register_callback_function (unsigned spec, printf_function *func, printf_arginfo_function *arginfo); + +/* Codes to determine basic types. + + These values cover all the standard format specifications. + Users can add new values after PA_LAST for their own types. */ + +enum +{ + PA_INT, /* int */ + PA_CHAR, /* int, cast to char */ + PA_WCHAR, /* wide char */ + PA_STRING, /* const char *, a '\0'-terminated string */ + PA_WSTRING, /* const wchar_t *, wide character string */ + PA_POINTER, /* void * */ + PA_FLOAT, /* float */ + PA_DOUBLE, /* double */ + PA_LAST, + PA_UNKNOWN = -1 +}; + +/* Flag bits that can be set in a type. */ +#define PA_TYPE_MASK 0x00ff +#define PA_FLAG_MASK ~SNV_TYPE_MASK + +#define PA_FLAG_LONG_LONG (1 << 8) +#define PA_FLAG_LONG_DOUBLE PA_FLAG_LONG_LONG +#define PA_FLAG_LONG (1 << 9) +#define PA_FLAG_SHORT (1 << 10) +#define PA_FLAG_UNSIGNED (1 << 11) +#define PA_FLAG_CHAR (1 << 12) +#define PA_FLAG_PTR (1 << 13) + +/** + * SNV_EMIT: + * @ch: the character to be printed + * @stream: the stream on which to print + * @count: a variable to be updated with the count of printed + * characters + * + * Maintain the count while putting @ch in @stream, also be careful about + * handling %NULL stream if the handler is being called purely to count + * output size. + **/ +#define SNV_EMIT(ch, stream, count) \ + SNV_STMT_START { \ + if ((stream)) \ + { \ + if ((count) >= 0) \ + { \ + int m_status = stream_put((unsigned char) (ch), (stream)); \ + (count) = m_status < 0 ? m_status : (count) + m_status; \ + } \ + } \ + else \ + { \ + (void)(ch); \ + (count)++; \ + } \ + } SNV_STMT_END + +@protos format.c +@protos custom.c +@protos printf.c + +/* If you don't want to use snprintfv functions for *all* of your string + formatting API, then define COMPILING_SNPRINTFV_C and use the snv_ + prefix for the entry points below. */ +#ifndef COMPILING_PRINTF_C +#undef printf +#undef vprintf +#undef dprintf +#undef vdprintf +#undef fprintf +#undef vfprintf +#undef sprintf +#undef vsprintf +#undef snprintf +#undef vsnprintf +#undef asprintf +#undef vasprintf +#undef asprintfv +#undef dprintfv +#undef fprintfv +#undef sprintfv +#undef printfv +#undef snprintfv + +#define printf snv_printf +#define vprintf snv_vprintf +#define dprintf snv_dprintf +#define vdprintf snv_vdprintf +#define fprintf snv_fprintf +#define vfprintf snv_vfprintf +#define sprintf snv_sprintf +#define vsprintf snv_vsprintf +#define snprintf snv_snprintf +#define vsnprintf snv_vsnprintf +#define asprintf snv_asprintf +#define vasprintf snv_vasprintf +#define asprintfv snv_asprintfv +#define dprintfv snv_dprintfv +#define fprintfv snv_fprintfv +#define sprintfv snv_sprintfv +#define printfv snv_printfv +#define snprintfv snv_snprintfv +#endif /* !COMPILING_SNPRINTFV_C */ +#ifdef __cplusplus +} +#endif + +#endif /* SNPRINTFV_SNPRINTFV_H */ + +/* snprintfv.h ends here */ diff --git a/snprintfv/printf.stamp b/snprintfv/printf.stamp new file mode 100644 index 0000000..e69de29 diff --git a/snprintfv/stream.c b/snprintfv/stream.c new file mode 100644 index 0000000..17a441f --- /dev/null +++ b/snprintfv/stream.c @@ -0,0 +1,225 @@ +/* -*- Mode: C -*- */ + +/* stream.c --- customizable stream routines + * Copyright (C) 1998, 1999, 2000, 2002, 2003 Gary V. Vaughan + * Originally by Gary V. Vaughan, 1998 + * This file is part of Snprintfv + * + * Snprintfv 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. + * + * Snprintfv 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 . + * + * As a special exception to the GNU General Public License, if you + * distribute this file as part of a program that also links with and + * uses the libopts library from AutoGen, you may include it under + * the same distribution terms used by the libopts library. + */ + +/* Code: */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#ifdef WITH_DMALLOC +# include +#endif + +#include "compat.h" +#include "stream.h" +#include "mem.h" + +struct stream +{ + snv_pointer stream; + unsigned long limit; + + StreamGet get_func; + StreamPut put_func; +}; + +static int +stream_not_readable (STREAM *stream) +{ + (void)stream; + return -1; +} + +static int +stream_not_writable (int ch, STREAM *stream) +{ + (void)stream; + (void)ch; + return -1; +} + +/** + * stream_new: constructor + * @dets: user supplied stream details to be passed into the various funcs. + * @limit: the maximum number of consecutive bytes to fit in @dets. + * @get_func: function to get a character from @dets stream. + * @put_func: function to put a character in @dets stream. + * + * Allocate and initialize a new %STREAM data type. The @get_func + * and @put_func can be NULL if you intend to create a non-readable + * or non-writable stream, respectively. + * + * Return value: + * The address of the newly allocated and initialised stream is returned. + **/ +STREAM * +stream_new (snv_pointer dets, unsigned long limit, StreamGet get_func, StreamPut put_func) +{ + STREAM *new = snv_new (STREAM, 1); + + new->stream = dets; + new->limit = limit; + + new->get_func = get_func ? get_func : stream_not_readable; + new->put_func = put_func ? put_func : stream_not_writable; + + return new; +} + + +/** + * stream_delete: destructor + * @stream: The stream pending deletion + * + * The memory associated with @stream is recycled. + + * Return value: + * The %dets supplied by the user when the stream was created are + * returned for handling by the calling function. + **/ +snv_pointer +stream_delete (STREAM *stream) +{ + snv_pointer dets = stream->stream; + snv_delete (stream); + return dets; +} + +/** + * stream_details: + * @stream: the stream being queried. + * + * The finalization function specified when @stream was created (if any) + * is called, and then the memory associated with @stream is recycled. + * It is the responsibility of the finalization function to recycle, or + * otherwise manage, any memory associated with the user supplied %dets. + * Return value: + * This function returns the stream details associated with @stream + * when it was originally created. + **/ +snv_pointer +stream_details (STREAM *stream) +{ + return stream ? stream->stream : NULL; +} + +/** + * stream_put: + * @ch: A single character to be placed in @stream. + * @stream: The stream to be written to. + * + * This function will @ch in @stream if that stream's output limit will + * not be exceeded. + * + * Return value: + * If @stream is full, return 1. Otherwise, if any other error occurs, + * that error code is returned unchanged. This is of course dependant + * on what the handler function uses to indicate an error. If the stream + * is not full and the stream's writing function succeeds, 1 (the number of + * characters emitted!) is returned. + **/ +int +stream_put (int ch, STREAM *stream) +{ + int ch_or_errorcode; + + if (!stream) + return -1; + + if (stream->limit < 1) + return 1; + + stream->limit -= 1; + ch_or_errorcode = (*stream->put_func) ((unsigned char) ch, stream); + + return (ch_or_errorcode < 0) ? ch_or_errorcode : 1; +} + +/** + * stream_puts: + * @s: A string to be placed in @stream. + * @stream: The stream to be written to. + * + * This function will @ch in @stream if that stream's output limit will + * not be exceeded. + * + * Return value: + * If any other error occurs, that error code is returned unchanged. + * This is of course dependant on what the handler function uses to + * indicate an error. If the stream becomes full, the remaining + * characters are not printed. If the stream's writing function + * always succeeds, the number of characters emitted or skipped is + * returned. + **/ +int +stream_puts (char *s, STREAM *stream) +{ + int ch_or_errorcode; + int num; + + if (!stream) + return -1; + + for (num = 0; *s; num++, s++) + { + if (stream->limit < 1) + return (int)((size_t)num + strlen (s)); + + stream->limit -= 1; + ch_or_errorcode = (*stream->put_func) ((unsigned char) *s, stream); + + if (ch_or_errorcode < 0) + return ch_or_errorcode; + } + + return num; +} + +/** + * stream_get: + * @stream: The stream to be read from. + * + * This function will try to read a single character from @stream. + * + * Return value: + * If an error occurs or the end of @stream is reached, -1 is returned. + * Under normal circumstances the value if the character read (cast to + * an int) is returned. + **/ +int +stream_get (STREAM *stream) +{ + return (*stream->get_func) (stream); +} + +/* + * Local Variables: + * mode: C + * c-file-style: "gnu" + * indent-tabs-mode: nil + * End: + * end of snprintfv/stream.c */ diff --git a/snprintfv/stream.h b/snprintfv/stream.h new file mode 100644 index 0000000..e4a5cd1 --- /dev/null +++ b/snprintfv/stream.h @@ -0,0 +1,191 @@ +/* -*- Mode: C -*- */ + +/* stream.h --- customizable stream routines + * Copyright (C) 1998, 1999, 2000, 2002 Gary V. Vaughan + * Originally by Gary V. Vaughan, 1998 + * This file is part of Snprintfv + * + * Snprintfv 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. + * + * Snprintfv 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 . + * + * As a special exception to the GNU General Public License, if you + * distribute this file as part of a program that also links with and + * uses the libopts library from AutoGen, you may include it under + * the same distribution terms used by the libopts library. + */ + +/* Code: */ + +#ifndef STREAM_H +#define STREAM_H 1 + +#define STREAM_READABLE (1 << 0) +#define STREAM_WRITABLE (1 << 1) + +/** + * SNV_UNLIMITED: + * Used to denote that there is no upper limit to the number of characters + * that can safely be written to a stream. + **/ +#define SNV_UNLIMITED (~0UL) + +#ifdef __cplusplus +extern "C" +{ +#if 0 +/* This brace is so that emacs can still indent properly: */ } +#endif +#endif /* __cplusplus */ + +/** + * STREAM: + * Data type used to pass details of streams between functions, + * much like stdio's %FILE, but more flexible. A %STREAM can be uni- or + * bi-directional depending on how it is initialised. + **/ +typedef struct stream STREAM; + +/** + * StreamPut: + * @ch: The character to write to @stream cast to an int. + * @stream: The stream being written to. + * + * Type of the function to put a character in a writeable stream. + * + * Return value: + * The function should return the character written to the + * stream, cast to an int if it was written successfully, or + * else %EOF, if the write failed. + **/ +typedef int (*StreamPut) (int ch, STREAM * stream); + +/** + * StreamGet: + * @stream: The stream being read from. + * + * Type of the function to get a character from a readable stream. + * + * Return value: + * The function should return the character read from the + * stream, cast to an int if it was read successfully, or + * else %EOF, if the read failed. + **/ +typedef int (*StreamGet) (STREAM * stream); + + +/** + * stream_new: constructor + * @dets: user supplied stream details to be passed into the various funcs. + * @limit: the maximum number of consecutive bytes to fit in @dets. + * @get_func: function to get a character from @dets stream. + * @put_func: function to put a character in @dets stream. + * + * Allocate and initialize a new %STREAM data type. The @get_func + * and @put_func can be NULL if you intend to create a non-readable + * or non-writable stream, respectively. + * + * Return value: + * The address of the newly allocated and initialised stream is returned. + **/ +extern STREAM * +stream_new (snv_pointer dets, unsigned long limit, StreamGet get_func, StreamPut put_func); + +/** + * stream_delete: destructor + * @stream: The stream pending deletion + * + * The memory associated with @stream is recycled. + + * Return value: + * The %dets supplied by the user when the stream was created are + * returned for handling by the calling function. + **/ +extern snv_pointer +stream_delete (STREAM *stream); + +/** + * stream_details: + * @stream: the stream being queried. + * + * The finalization function specified when @stream was created (if any) + * is called, and then the memory associated with @stream is recycled. + * It is the responsibility of the finalization function to recycle, or + * otherwise manage, any memory associated with the user supplied %dets. + * Return value: + * This function returns the stream details associated with @stream + * when it was originally created. + **/ +extern snv_pointer +stream_details (STREAM *stream); + +/** + * stream_put: + * @ch: A single character to be placed in @stream. + * @stream: The stream to be written to. + * + * This function will @ch in @stream if that stream's output limit will + * not be exceeded. + * + * Return value: + * If @stream is full, return 1. Otherwise, if any other error occurs, + * that error code is returned unchanged. This is of course dependant + * on what the handler function uses to indicate an error. If the stream + * is not full and the stream's writing function succeeds, 1 (the number of + * characters emitted!) is returned. + **/ +extern int +stream_put (int ch, STREAM *stream); + +/** + * stream_puts: + * @s: A string to be placed in @stream. + * @stream: The stream to be written to. + * + * This function will @ch in @stream if that stream's output limit will + * not be exceeded. + * + * Return value: + * If any other error occurs, that error code is returned unchanged. + * This is of course dependant on what the handler function uses to + * indicate an error. If the stream becomes full, the remaining + * characters are not printed. If the stream's writing function + * always succeeds, the number of characters emitted or skipped is + * returned. + **/ +extern int +stream_puts (char *s, STREAM *stream); + +/** + * stream_get: + * @stream: The stream to be read from. + * + * This function will try to read a single character from @stream. + * + * Return value: + * If an error occurs or the end of @stream is reached, -1 is returned. + * Under normal circumstances the value if the character read (cast to + * an int) is returned. + **/ +extern int +stream_get (STREAM *stream); + +#line 87 "stream.in" +#ifdef __cplusplus +#if 0 +/* This brace is so that emacs can still indent properly: */ +{ +#endif +} +#endif /* __cplusplus */ + +#endif /* STREAM_H */ diff --git a/snprintfv/stream.in b/snprintfv/stream.in new file mode 100644 index 0000000..41be8f2 --- /dev/null +++ b/snprintfv/stream.in @@ -0,0 +1,95 @@ +/* -*- Mode: C -*- */ + +/* stream.h --- customizable stream routines + * Copyright (C) 1998, 1999, 2000, 2002 Gary V. Vaughan + * Originally by Gary V. Vaughan, 1998 + * This file is part of Snprintfv + * + * Snprintfv 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. + * + * Snprintfv 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 . + * + * As a special exception to the GNU General Public License, if you + * distribute this file as part of a program that also links with and + * uses the libopts library from AutoGen, you may include it under + * the same distribution terms used by the libopts library. + */ + +/* Code: */ + +#ifndef STREAM_H +#define STREAM_H 1 + +#define STREAM_READABLE (1 << 0) +#define STREAM_WRITABLE (1 << 1) + +/** + * SNV_UNLIMITED: + * Used to denote that there is no upper limit to the number of characters + * that can safely be written to a stream. + **/ +#define SNV_UNLIMITED (~0UL) + +#ifdef __cplusplus +extern "C" +{ +#if 0 +/* This brace is so that emacs can still indent properly: */ } +#endif +#endif /* __cplusplus */ + +/** + * STREAM: + * Data type used to pass details of streams between functions, + * much like stdio's %FILE, but more flexible. A %STREAM can be uni- or + * bi-directional depending on how it is initialised. + **/ +typedef struct stream STREAM; + +/** + * StreamPut: + * @ch: The character to write to @stream cast to an int. + * @stream: The stream being written to. + * + * Type of the function to put a character in a writeable stream. + * + * Return value: + * The function should return the character written to the + * stream, cast to an int if it was written successfully, or + * else %EOF, if the write failed. + **/ +typedef int (*StreamPut) (int ch, STREAM * stream); + +/** + * StreamGet: + * @stream: The stream being read from. + * + * Type of the function to get a character from a readable stream. + * + * Return value: + * The function should return the character read from the + * stream, cast to an int if it was read successfully, or + * else %EOF, if the read failed. + **/ +typedef int (*StreamGet) (STREAM * stream); + + +@protos stream.c +#ifdef __cplusplus +#if 0 +/* This brace is so that emacs can still indent properly: */ +{ +#endif +} +#endif /* __cplusplus */ + +#endif /* STREAM_H */ diff --git a/snprintfv/stream.stamp b/snprintfv/stream.stamp new file mode 100644 index 0000000..e69de29 diff --git a/xml2ag/Makefile.am b/xml2ag/Makefile.am new file mode 100644 index 0000000..d2d05d2 --- /dev/null +++ b/xml2ag/Makefile.am @@ -0,0 +1,111 @@ +## -*- Mode: Makefile -*- +## --------------------------------------------------------------------- +## Makefile.am -- process this file with automake to produce Makefile.in +## +## Author: Bruce Korb +## +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen 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. +## +## AutoGen is distributed in the hope that 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 . +## +TARG = xml2ag + +bin_PROGRAMS = xml2ag +csrcs = xml2ag.c +gsrcs = xmlopts.c fork.c +BUILT_SOURCES = x.c +nodist_xml2ag_SOURCES = $(BUILT_SOURCES) +SUBDIRS = test +EXTRA_DIST = xmlopts.def fork.tpl $(gsrcs) $(csrcs) +xml2ag_LDADD = $(top_builddir)/autoopts/libopts.la $(LIBXML2_LIBS) +man_MANS = $(TARG).1 +TEXI_FILES = invoke-$(TARG).texi invoke-$(TARG).menu +DOCFILES = $(TEXI_FILES) $(man_MANS) +DISTCLEANFILES = $(DOCFILES) $(nodist_xml2ag_SOURCES) stamp-* +AM_CPPFLAGS = @INCLIST@ $(LIBXML2_CFLAGS) +AM_CFLAGS = @WARN_CFLAGS@ +AG_ENV = top_builddir="$(top_builddir)" top_srcdir="$(top_srcdir)" \ + VERBOSE="$(V)" +RUN_AG = $(AG_ENV) $(SHELL) "${top_srcdir}/build-aux/run-ag.sh" +DOC_TIMEOUT = -DLEVEL=section --timeout=`expr $(AG_TIMEOUT) '*' 3` + +all : gen +gen : $(gsrcs) $(DOCFILES) + +if AMDEP +DEPFL_OPTS = $(DEPDIR)/opts-dep.mk +DEPFL_MAN = $(DEPDIR)/man-dep.mk +DEPFL_TEXI = $(DEPDIR)/texi-dep.mk +DEPFL_FORK = $(DEPDIR)/fork-dep.mk + +$(DEPFL_OPTS) : + $(RUN_AG) "$@" + +$(DEPFL_MAN) : + $(RUN_AG) "$@" + +$(DEPFL_TEXI) : + $(RUN_AG) "$@" + +$(DEPFL_FORK) : + $(RUN_AG) "$@" + +include $(DEPDIR)/opts-dep.mk +include $(DEPDIR)/man-dep.mk +include $(DEPDIR)/texi-dep.mk +include $(DEPDIR)/fork-dep.mk +else +DEPFL_OPTS = $@ +DEPFL_MAN = $@ +DEPFL_TEXI = $@ +DEPFL_FORK = $@ +endif + +AGARG_OPTS = -MF$(DEPFL_OPTS) -MT$@ -MP +AGARG_MAN = -MF$(DEPFL_MAN) -MT$@ -MP -Tagman-cmd +AGARG_TEXI = -MF$(DEPFL_TEXI) -MT$@ -MP -Tagtexi-cmd $(DOC_TIMEOUT) +AGARG_FORK = -MF$(DEPFL_FORK) -MT$@ -MP -L$(srcdir) -Tfork.tpl + +$(getdefs_OBJECTS) xmlopts.c xmlopts.h : stamp-opts +stamp-opts : xmlopts.def + $(RUN_AG) $(AGARG_OPTS) "$(srcdir)/xmlopts.def" + +$(TARG).1 : stamp-man +stamp-man : xmlopts.def $(TARG)$(EXEEXT) ../columns/columns$(EXEEXT) + $(RUN_AG) $(AGARG_MAN) "$(srcdir)/xmlopts.def" + +invoke-$(TARG).texi invoke-$(TARG).menu : stamp-texi +stamp-texi : xmlopts.def $(TARG)$(EXEEXT) ../columns/columns$(EXEEXT) + $(RUN_AG) $(AGARG_TEXI) "$(srcdir)/xmlopts.def" + +fork.c : stamp-fork +stamp-fork : fork.tpl xmlopts.def $(CLexe) + $(RUN_AG) $(AGARG_FORK) "$(srcdir)/xmlopts.def" + +$(CLexe) : + cd ../columns ; $(MAKE) $(CLnam) + +x.c : $(gsrcs) $(csrcs) + exec > $@ ; \ + echo '#undef PKGDATADIR' ; \ + echo '#define PKGDATADIR "$(pkgdatadir)"' ; \ + echo ; echo '#define DEFINING 1' ; \ + echo '#include "autoopts/project.h"' ; \ + for f in $(gsrcs) $(csrcs) ; \ + do echo "#include \"$$f\"" ; done + +.NOTPARALLEL: + +# end of Makefile.am diff --git a/xml2ag/Makefile.in b/xml2ag/Makefile.in new file mode 100644 index 0000000..5b85e95 --- /dev/null +++ b/xml2ag/Makefile.in @@ -0,0 +1,985 @@ +# Makefile.in generated by automake 1.16.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2018 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +bin_PROGRAMS = xml2ag$(EXEEXT) +subdir = xml2ag +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/config/ag_macros.m4 \ + $(top_srcdir)/config/asm-underscore.m4 \ + $(top_srcdir)/config/extensions.m4 \ + $(top_srcdir)/config/guile.m4 \ + $(top_srcdir)/config/host-cpu-c-abi.m4 \ + $(top_srcdir)/config/lib-ld.m4 \ + $(top_srcdir)/config/lib-link.m4 \ + $(top_srcdir)/config/lib-prefix.m4 \ + $(top_srcdir)/config/libopts.m4 \ + $(top_srcdir)/config/libtool.m4 \ + $(top_srcdir)/config/ltoptions.m4 \ + $(top_srcdir)/config/ltsugar.m4 \ + $(top_srcdir)/config/ltversion.m4 \ + $(top_srcdir)/config/lt~obsolete.m4 \ + $(top_srcdir)/config/onceonly.m4 $(top_srcdir)/config/pkg.m4 \ + $(top_srcdir)/config/snprintfv.m4 \ + $(top_srcdir)/config/stdnoreturn.m4 \ + $(top_srcdir)/config/unlocked-io.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" +PROGRAMS = $(bin_PROGRAMS) +am__objects_1 = x.$(OBJEXT) +nodist_xml2ag_OBJECTS = $(am__objects_1) +xml2ag_OBJECTS = $(nodist_xml2ag_OBJECTS) +am__DEPENDENCIES_1 = +xml2ag_DEPENDENCIES = $(top_builddir)/autoopts/libopts.la \ + $(am__DEPENDENCIES_1) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/config/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/x.Po +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(nodist_xml2ag_SOURCES) +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +man1dir = $(mandir)/man1 +NROFF = nroff +MANS = $(man_MANS) +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ + distdir distdir-am +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = $(SUBDIRS) +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/config/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +ACLOCAL = @ACLOCAL@ +AGEN5_TESTS = @AGEN5_TESTS@ +AG_LDFLAGS = @AG_LDFLAGS@ +AG_MAJOR_VERSION = @AG_MAJOR_VERSION@ +AG_MINOR_VERSION = @AG_MINOR_VERSION@ +AG_STATIC_AUTOGEN = @AG_STATIC_AUTOGEN@ +AG_TIMEOUT = @AG_TIMEOUT@ +AG_VERSION = @AG_VERSION@ +AG_XML2 = @AG_XML2@ +AGexe = @AGexe@ +AGnam = @AGnam@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AO_AGE = @AO_AGE@ +AO_CURRENT = @AO_CURRENT@ +AO_REVISION = @AO_REVISION@ +AO_TEMPLATE_VERSION = @AO_TEMPLATE_VERSION@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CLexe = @CLexe@ +CLnam = @CLnam@ +CONFIG_SHELL = @CONFIG_SHELL@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEBUG_ENABLED = @DEBUG_ENABLED@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +DYNAMIC_AG = @DYNAMIC_AG@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ENABLE_STATIC = @ENABLE_STATIC@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GDexe = @GDexe@ +GDnam = @GDnam@ +GO_AGE = @GO_AGE@ +GO_CURRENT = @GO_CURRENT@ +GO_REVISION = @GO_REVISION@ +GREP = @GREP@ +GUILE_CFLAGS = @GUILE_CFLAGS@ +GUILE_EFFECTIVE_VERSION = @GUILE_EFFECTIVE_VERSION@ +GUILE_LDFLAGS = @GUILE_LDFLAGS@ +GUILE_LIBS = @GUILE_LIBS@ +GUILE_LTLIBS = @GUILE_LTLIBS@ +HOST_CPU = @HOST_CPU@ +HOST_CPU_C_ABI = @HOST_CPU_C_ABI@ +INCLIST = @INCLIST@ +INCSNPRINTFV = @INCSNPRINTFV@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSNPRINTFV = @LIBSNPRINTFV@ +LIBTOOL = @LIBTOOL@ +LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ +LIBXML2_LIBS = @LIBXML2_LIBS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +M4_SRC = @M4_SRC@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPTS_TESTDIR = @OPTS_TESTDIR@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POSIX_SHELL = @POSIX_SHELL@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STDNORETURN_H = @STDNORETURN_H@ +STRIP = @STRIP@ +TEXI2HTML = @TEXI2HTML@ +VERSION = @VERSION@ +WARN_CFLAGS = @WARN_CFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_aux_dir = @ac_aux_dir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +TARG = xml2ag +csrcs = xml2ag.c +gsrcs = xmlopts.c fork.c +BUILT_SOURCES = x.c +nodist_xml2ag_SOURCES = $(BUILT_SOURCES) +SUBDIRS = test +EXTRA_DIST = xmlopts.def fork.tpl $(gsrcs) $(csrcs) +xml2ag_LDADD = $(top_builddir)/autoopts/libopts.la $(LIBXML2_LIBS) +man_MANS = $(TARG).1 +TEXI_FILES = invoke-$(TARG).texi invoke-$(TARG).menu +DOCFILES = $(TEXI_FILES) $(man_MANS) +DISTCLEANFILES = $(DOCFILES) $(nodist_xml2ag_SOURCES) stamp-* +AM_CPPFLAGS = @INCLIST@ $(LIBXML2_CFLAGS) +AM_CFLAGS = @WARN_CFLAGS@ +AG_ENV = top_builddir="$(top_builddir)" top_srcdir="$(top_srcdir)" \ + VERBOSE="$(V)" + +RUN_AG = $(AG_ENV) $(SHELL) "${top_srcdir}/build-aux/run-ag.sh" +DOC_TIMEOUT = -DLEVEL=section --timeout=`expr $(AG_TIMEOUT) '*' 3` +@AMDEP_FALSE@DEPFL_OPTS = $@ +@AMDEP_TRUE@DEPFL_OPTS = $(DEPDIR)/opts-dep.mk +@AMDEP_FALSE@DEPFL_MAN = $@ +@AMDEP_TRUE@DEPFL_MAN = $(DEPDIR)/man-dep.mk +@AMDEP_FALSE@DEPFL_TEXI = $@ +@AMDEP_TRUE@DEPFL_TEXI = $(DEPDIR)/texi-dep.mk +@AMDEP_FALSE@DEPFL_FORK = $@ +@AMDEP_TRUE@DEPFL_FORK = $(DEPDIR)/fork-dep.mk +AGARG_OPTS = -MF$(DEPFL_OPTS) -MT$@ -MP +AGARG_MAN = -MF$(DEPFL_MAN) -MT$@ -MP -Tagman-cmd +AGARG_TEXI = -MF$(DEPFL_TEXI) -MT$@ -MP -Tagtexi-cmd $(DOC_TIMEOUT) +AGARG_FORK = -MF$(DEPFL_FORK) -MT$@ -MP -L$(srcdir) -Tfork.tpl +all: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) all-recursive + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu xml2ag/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu xml2ag/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ + fi; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p \ + || test -f $$p1 \ + ; then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' \ + -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' \ + `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(bindir)" && rm -f $$files + +clean-binPROGRAMS: + @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list + +xml2ag$(EXEEXT): $(xml2ag_OBJECTS) $(xml2ag_DEPENDENCIES) $(EXTRA_xml2ag_DEPENDENCIES) + @rm -f xml2ag$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(xml2ag_OBJECTS) $(xml2ag_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/x.Po@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-man1: $(man_MANS) + @$(NORMAL_INSTALL) + @list1=''; \ + list2='$(man_MANS)'; \ + test -n "$(man1dir)" \ + && test -n "`echo $$list1$$list2`" \ + || exit 0; \ + echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \ + { for i in $$list1; do echo "$$i"; done; \ + if test -n "$$list2"; then \ + for i in $$list2; do echo "$$i"; done \ + | sed -n '/\.1[a-z]*$$/p'; \ + fi; \ + } | while read p; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; echo "$$p"; \ + done | \ + sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ + sed 'N;N;s,\n, ,g' | { \ + list=; while read file base inst; do \ + if test "$$base" = "$$inst"; then list="$$list $$file"; else \ + echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ + $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ + fi; \ + done; \ + for i in $$list; do echo "$$i"; done | $(am__base_list) | \ + while read files; do \ + test -z "$$files" || { \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ + done; } + +uninstall-man1: + @$(NORMAL_UNINSTALL) + @list=''; test -n "$(man1dir)" || exit 0; \ + files=`{ for i in $$list; do echo "$$i"; done; \ + l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ + sed -n '/\.1[a-z]*$$/p'; \ + } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ + dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir) + +# This directory's subdirectories are mostly independent; you can cd +# into them and run 'make' without going through this Makefile. +# To change the values of 'make' variables: instead of editing Makefiles, +# (1) if the variable is set in 'config.status', edit 'config.status' +# (which will cause the Makefiles to be regenerated when you run 'make'); +# (2) otherwise, pass the desired values on the 'make' command line. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-recursive + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-recursive + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) check-recursive +all-am: Makefile $(PROGRAMS) $(MANS) +installdirs: installdirs-recursive +installdirs-am: + for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) +clean: clean-recursive + +clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am + +distclean: distclean-recursive + -rm -f ./$(DEPDIR)/x.Po + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: install-man + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: install-binPROGRAMS + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: install-man1 + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f ./$(DEPDIR)/x.Po + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: uninstall-binPROGRAMS uninstall-man + +uninstall-man: uninstall-man1 + +.MAKE: $(am__recursive_targets) all check install install-am \ + install-strip + +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ + am--depfiles check check-am clean clean-binPROGRAMS \ + clean-generic clean-libtool cscopelist-am ctags ctags-am \ + distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-binPROGRAMS \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-man1 \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + installdirs-am maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-binPROGRAMS uninstall-man \ + uninstall-man1 + +.PRECIOUS: Makefile + + +all : gen +gen : $(gsrcs) $(DOCFILES) + +@AMDEP_TRUE@$(DEPFL_OPTS) : +@AMDEP_TRUE@ $(RUN_AG) "$@" + +@AMDEP_TRUE@$(DEPFL_MAN) : +@AMDEP_TRUE@ $(RUN_AG) "$@" + +@AMDEP_TRUE@$(DEPFL_TEXI) : +@AMDEP_TRUE@ $(RUN_AG) "$@" + +@AMDEP_TRUE@$(DEPFL_FORK) : +@AMDEP_TRUE@ $(RUN_AG) "$@" + +@AMDEP_TRUE@include $(DEPDIR)/opts-dep.mk +@AMDEP_TRUE@include $(DEPDIR)/man-dep.mk +@AMDEP_TRUE@include $(DEPDIR)/texi-dep.mk +@AMDEP_TRUE@include $(DEPDIR)/fork-dep.mk + +$(getdefs_OBJECTS) xmlopts.c xmlopts.h : stamp-opts +stamp-opts : xmlopts.def + $(RUN_AG) $(AGARG_OPTS) "$(srcdir)/xmlopts.def" + +$(TARG).1 : stamp-man +stamp-man : xmlopts.def $(TARG)$(EXEEXT) ../columns/columns$(EXEEXT) + $(RUN_AG) $(AGARG_MAN) "$(srcdir)/xmlopts.def" + +invoke-$(TARG).texi invoke-$(TARG).menu : stamp-texi +stamp-texi : xmlopts.def $(TARG)$(EXEEXT) ../columns/columns$(EXEEXT) + $(RUN_AG) $(AGARG_TEXI) "$(srcdir)/xmlopts.def" + +fork.c : stamp-fork +stamp-fork : fork.tpl xmlopts.def $(CLexe) + $(RUN_AG) $(AGARG_FORK) "$(srcdir)/xmlopts.def" + +$(CLexe) : + cd ../columns ; $(MAKE) $(CLnam) + +x.c : $(gsrcs) $(csrcs) + exec > $@ ; \ + echo '#undef PKGDATADIR' ; \ + echo '#define PKGDATADIR "$(pkgdatadir)"' ; \ + echo ; echo '#define DEFINING 1' ; \ + echo '#include "autoopts/project.h"' ; \ + for f in $(gsrcs) $(csrcs) ; \ + do echo "#include \"$$f\"" ; done + +.NOTPARALLEL: + +# end of Makefile.am + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/xml2ag/fork.c b/xml2ag/fork.c new file mode 100644 index 0000000..6f43785 --- /dev/null +++ b/xml2ag/fork.c @@ -0,0 +1,315 @@ +/* -*- buffer-read-only: t -*- vi: set ro: + * + * DO NOT EDIT THIS FILE (fork.c) + * + * It has been AutoGen-ed + * From the definitions ./xmlopts.def + * and the template file fork.tpl + * + * This module will fire up autogen and have it read definitions + * from its standard-in. + */ + +static char const fs_err_fmt[] = "%s fs ERROR %d (%s) on %s\n"; + +/** + * increase size of argument vector. Allocation will always be a + * multiple of 8 times sizeof(void *). + */ +static void +get_argv_space(void) +{ + static void * av = NULL; //!< static arg vector + int act = (int)xml2agOptions.origArgCt; //!< current count + + /* + * First time through, use "malloc" not "realloc". + */ + if (av == NULL) { + size_t csz = act * sizeof(void *); //! current size + /* + * "act" will always be one less than a multiple of 8 and + * at least one larger than before. After first time through, + * each call will increment by 8. + */ + act = (act + 10) & ~0x0007; + av = malloc(act-- * sizeof(void *)); + if (av == NULL) + goto no_memory; + memcpy(av, xml2agOptions.origArgVect, csz); + + } else { + act += 8; + av = realloc(av, (act + 1) * sizeof(void *)); + if (av == NULL) + goto no_memory; + } + + xml2agOptions.origArgCt = act; + xml2agOptions.origArgVect = av; + return; + + no_memory: + fprintf(stderr, "No memory for %d args\n", act+1); + exit(EXIT_FAILURE); +} + +static void +add_arg(char const * arg, int ix) +{ + if (ix >= (int)xml2agOptions.origArgCt) + get_argv_space(); + + xml2agOptions.origArgVect[ix] = VOIDP(arg); +} + +static int +become_child(int * fd, char const * in_file) +{ + if (pipe(fd) != 0) { + fprintf(stderr, fs_err_fmt, xml2agOptions.pzProgName, + errno, strerror( errno ), "pipe(2)"); + exit(EXIT_FAILURE); + } + + fflush(stdout); + fflush(stdin); + + switch (fork()) { + case -1: + fprintf(stderr, fs_err_fmt, xml2agOptions.pzProgName, + errno, strerror( errno ), "fork(2)"); + exit(EXIT_FAILURE); + + case 0: + fclose(stdin); + if (dup2(fd[0], STDIN_FILENO) != STDIN_FILENO) { + fprintf(stderr, fs_err_fmt, xml2agOptions.pzProgName, + errno, strerror( errno ), "dup2(2) w/ STDIN_FILENO"); + exit(EXIT_FAILURE); + } + close(fd[1]); + break; + + default: + errno = 0; + ag_pipe_fp = fdopen(fd[1], "w"); + if (ag_pipe_fp == NULL) { + fprintf(stderr, fs_err_fmt, xml2agOptions.pzProgName, + errno, strerror( errno ), "fdopen(2) w/ pipe[1]"); + exit(EXIT_FAILURE); + } + close(fd[0]); + return 0; + } + + if (! HAVE_OPT( BASE_NAME )) { + if (in_file == NULL) + in_file = "stdin"; + else { + char * pz = strrchr(in_file, '.'); + if (pz != NULL) { + in_file = pz = strdup(in_file); + pz = strrchr(pz, '.'); + *pz = '\0'; + } + } + SET_OPT_BASE_NAME(in_file); + } + + return 1; +} + +void +fork_ag(char const * in_file) +{ + int fd[2]; + + if (! become_child(fd, in_file)) + return; // parent process returns + + get_argv_space(); + + { + static char const zAg[] = "autogen"; + char * pzArg; + int ix = 1; + + { + char * pz = malloc(strlen( xml2agOptions.pzProgPath ) + 7); + char * p = strrchr(xml2agOptions.pzProgPath, '/'); + + if (p == NULL) { + strcpy(pz, zAg); + } else { + size_t len = (size_t)(p - xml2agOptions.pzProgPath) + 1; + memcpy(pz, xml2agOptions.pzProgPath, len); + strcpy(pz + len, zAg); + } + + add_arg(pz, 0); + } + + if (HAVE_OPT(TEMPL_DIRS)) { + int optCt = STACKCT_OPT(TEMPL_DIRS); + char const ** ppOA = STACKLST_OPT(TEMPL_DIRS); + do { + char const * pA = *(ppOA++); + pzArg = malloc(14 + strlen(pA)); + sprintf(pzArg, "--templ-dirs=%s", pA); + add_arg(pzArg, ix++); + } while (--optCt > 0); + } + + if (HAVE_OPT(DEFINITIONS)) { + pzArg = malloc(15 + strlen( OPT_ARG( DEFINITIONS ))); + sprintf(pzArg, "--definitions=%s", OPT_ARG( DEFINITIONS )); + add_arg(pzArg, ix++); + } + + if (HAVE_OPT(SHELL)) { + pzArg = malloc(9 + strlen( OPT_ARG( SHELL ))); + sprintf(pzArg, "--shell=%s", OPT_ARG( SHELL )); + add_arg(pzArg, ix++); + } + + if (HAVE_OPT(NO_FMEMOPEN)) { + add_arg("--no-fmemopen", ix++); + } + + if (HAVE_OPT(EQUATE)) { + pzArg = malloc(10 + strlen( OPT_ARG( EQUATE ))); + sprintf(pzArg, "--equate=%s", OPT_ARG( EQUATE )); + add_arg(pzArg, ix++); + } + + if (HAVE_OPT(BASE_NAME)) { + pzArg = malloc(13 + strlen( OPT_ARG( BASE_NAME ))); + sprintf(pzArg, "--base-name=%s", OPT_ARG( BASE_NAME )); + add_arg(pzArg, ix++); + } + + if (HAVE_OPT(SOURCE_TIME)) { + add_arg("--source-time", ix++); + } + + if (HAVE_OPT(WRITABLE)) { + add_arg("--writable", ix++); + } + + if (HAVE_OPT(LOOP_LIMIT)) { + pzArg = malloc((size_t)26); + sprintf(pzArg, "--loop-limit=%d", (int)OPT_VALUE_LOOP_LIMIT); + add_arg(pzArg, ix++); + } + + if (HAVE_OPT(TIMEOUT)) { + pzArg = malloc((size_t)23); + sprintf(pzArg, "--timeout=%d", (int)OPT_VALUE_TIMEOUT); + add_arg(pzArg, ix++); + } + + if (HAVE_OPT(TRACE)) { + static char const * kwlist[] = { + "nothing", "debug-message", "server-shell", + "templates", "block-macros", "expressions", + "everything" }; + pzArg = malloc(9 + strlen( kwlist[ OPT_VALUE_TRACE ] )); + sprintf(pzArg, "--trace=%s", kwlist[ OPT_VALUE_TRACE ]); + add_arg(pzArg, ix++); + } + + if (HAVE_OPT(TRACE_OUT)) { + pzArg = malloc(13 + strlen( OPT_ARG( TRACE_OUT ))); + sprintf(pzArg, "--trace-out=%s", OPT_ARG( TRACE_OUT )); + add_arg(pzArg, ix++); + } + + if (HAVE_OPT(SHOW_DEFS)) { + add_arg("--show-defs", ix++); + } + + if (HAVE_OPT(USED_DEFINES)) { + add_arg("--used-defines", ix++); + } + + if (HAVE_OPT(CORE)) { + add_arg("--core", ix++); + } + + if (HAVE_OPT(SKIP_SUFFIX)) { + int optCt = STACKCT_OPT(SKIP_SUFFIX); + char const ** ppOA = STACKLST_OPT(SKIP_SUFFIX); + do { + char const * pA = *(ppOA++); + pzArg = malloc(15 + strlen(pA)); + sprintf(pzArg, "--skip-suffix=%s", pA); + add_arg(pzArg, ix++); + } while (--optCt > 0); + } + + if (HAVE_OPT(SELECT_SUFFIX)) { + int optCt = STACKCT_OPT(SELECT_SUFFIX); + char const ** ppOA = STACKLST_OPT(SELECT_SUFFIX); + do { + char const * pA = *(ppOA++); + pzArg = malloc(17 + strlen(pA)); + sprintf(pzArg, "--select-suffix=%s", pA); + add_arg(pzArg, ix++); + } while (--optCt > 0); + } + + if (HAVE_OPT(DEFINE)) { + int optCt = STACKCT_OPT(DEFINE); + char const ** ppOA = STACKLST_OPT(DEFINE); + do { + char const * pA = *(ppOA++); + pzArg = malloc(10 + strlen(pA)); + sprintf(pzArg, "--define=%s", pA); + add_arg(pzArg, ix++); + } while (--optCt > 0); + } + + if (HAVE_OPT(UNDEFINE)) { + int optCt = STACKCT_OPT(UNDEFINE); + char const ** ppOA = STACKLST_OPT(UNDEFINE); + do { + char const * pA = *(ppOA++); + pzArg = malloc(12 + strlen(pA)); + sprintf(pzArg, "--undefine=%s", pA); + add_arg(pzArg, ix++); + } while (--optCt > 0); + } + + if (HAVE_OPT(MAKE_DEP)) { + int optCt = STACKCT_OPT(MAKE_DEP); + char const ** ppOA = STACKLST_OPT(MAKE_DEP); + do { + char const * pA = *(ppOA++); + pzArg = malloc(12 + strlen(pA)); + sprintf(pzArg, "--make-dep=%s", pA); + add_arg(pzArg, ix++); + } while (--optCt > 0); + } + + xml2agOptions.origArgVect[ix] = NULL; + execvp(xml2agOptions.origArgVect[0], xml2agOptions.origArgVect); + + /* + * IF the first try fails, it may be because xml2ag and autogen have + * different paths. Try again with just plain "autogen" and let + * the OS search "PATH" for the program. + */ + execvp(zAg, xml2agOptions.origArgVect); + fprintf(stderr, fs_err_fmt, xml2agOptions.pzProgName, + errno, strerror(errno), "execvp(2)"); + exit(EXIT_FAILURE); + } +} + +/* + * Local Variables: + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of fork.c */ diff --git a/xml2ag/fork.tpl b/xml2ag/fork.tpl new file mode 100644 index 0000000..737a843 --- /dev/null +++ b/xml2ag/fork.tpl @@ -0,0 +1,259 @@ +[= AutoGen5 Template c=fork.c -*- Mode: C -*- =] +[= # + * fork.tpl: template for passing arguments to autogen forked process. + * + * This file is part of AutoGen. + * AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoGen 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. + * + * AutoGen is distributed in the hope that 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 . + =][= + +(define up-c-name (lambda (ag-name) + (string-upcase! (string->c-name! (get ag-name))) )) + +(dne " * " "/* ")=] + * + * This module will fire up autogen and have it read definitions + * from its standard-in. + */ + +static char const fs_err_fmt[] = "%s fs ERROR %d (%s) on %s\n"; + +/** + * increase size of argument vector. Allocation will always be a + * multiple of 8 times sizeof(void *). + */ +static void +get_argv_space(void) +{ + static void * av = NULL; //!< static arg vector + int act = (int)xml2agOptions.origArgCt; //!< current count + + /* + * First time through, use "malloc" not "realloc". + */ + if (av == NULL) { + size_t csz = act * sizeof(void *); //! current size + /* + * "act" will always be one less than a multiple of 8 and + * at least one larger than before. After first time through, + * each call will increment by 8. + */ + act = (act + 10) & ~0x0007; + av = malloc(act-- * sizeof(void *)); + if (av == NULL) + goto no_memory; + memcpy(av, xml2agOptions.origArgVect, csz); + + } else { + act += 8; + av = realloc(av, (act + 1) * sizeof(void *)); + if (av == NULL) + goto no_memory; + } + + xml2agOptions.origArgCt = act; + xml2agOptions.origArgVect = av; + return; + + no_memory: + fprintf(stderr, "No memory for %d args\n", act+1); + exit(EXIT_FAILURE); +} + +static void +add_arg(char const * arg, int ix) +{ + if (ix >= (int)xml2agOptions.origArgCt) + get_argv_space(); + + xml2agOptions.origArgVect[ix] = VOIDP(arg); +} + +static int +become_child(int * fd, char const * in_file) +{ + if (pipe(fd) != 0) { + fprintf(stderr, fs_err_fmt, xml2agOptions.pzProgName, + errno, strerror( errno ), "pipe(2)"); + exit(EXIT_FAILURE); + } + + fflush(stdout); + fflush(stdin); + + switch (fork()) { + case -1: + fprintf(stderr, fs_err_fmt, xml2agOptions.pzProgName, + errno, strerror( errno ), "fork(2)"); + exit(EXIT_FAILURE); + + case 0: + fclose(stdin); + if (dup2(fd[0], STDIN_FILENO) != STDIN_FILENO) { + fprintf(stderr, fs_err_fmt, xml2agOptions.pzProgName, + errno, strerror( errno ), "dup2(2) w/ STDIN_FILENO"); + exit(EXIT_FAILURE); + } + close(fd[1]); + break; + + default: + errno = 0; + ag_pipe_fp = fdopen(fd[1], "w"); + if (ag_pipe_fp == NULL) { + fprintf(stderr, fs_err_fmt, xml2agOptions.pzProgName, + errno, strerror( errno ), "fdopen(2) w/ pipe[1]"); + exit(EXIT_FAILURE); + } + close(fd[0]); + return 0; + } + + if (! HAVE_OPT( BASE_NAME )) { + if (in_file == NULL) + in_file = "stdin"; + else { + char * pz = strrchr(in_file, '.'); + if (pz != NULL) { + in_file = pz = strdup(in_file); + pz = strrchr(pz, '.'); + *pz = '\0'; + } + } + SET_OPT_BASE_NAME(in_file); + } + + return 1; +} + +void +fork_ag(char const * in_file) +{ + int fd[2]; + + if (! become_child(fd, in_file)) + return; // parent process returns + + get_argv_space(); + + { + static char const zAg[] = "autogen"; + char * pzArg; + int ix = 1; + + { + char * pz = malloc(strlen( xml2agOptions.pzProgPath ) + 7); + char * p = strrchr(xml2agOptions.pzProgPath, '/'); + + if (p == NULL) { + strcpy(pz, zAg); + } else { + size_t len = (size_t)(p - xml2agOptions.pzProgPath) + 1; + memcpy(pz, xml2agOptions.pzProgPath, len); + strcpy(pz + len, zAg); + } + + add_arg(pz, 0); + }[= + + FOR flag =][= + IF (define opt-name (up-c-name "name")) + + (and + (not (~~ opt-name "OVERRIDE_TPL|OUTPUT")) + (not (exist? "documentation")) + ) =][= + + INVOKE handle-option =][= + ENDIF (not override) =][= + ENDFOR =] + + xml2agOptions.origArgVect[ix] = NULL; + execvp(xml2agOptions.origArgVect[0], xml2agOptions.origArgVect); + + /* + * IF the first try fails, it may be because xml2ag and autogen have + * different paths. Try again with just plain "autogen" and let + * the OS search "PATH" for the program. + */ + execvp(zAg, xml2agOptions.origArgVect); + fprintf(stderr, fs_err_fmt, xml2agOptions.pzProgName, + errno, strerror(errno), "execvp(2)"); + exit(EXIT_FAILURE); + } +} + +/* + * Local Variables: + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of [= (out-name) =] */ +[= + +DEFINE handle-option =] + + if (HAVE_OPT([=(. opt-name)=])) {[= + + CASE arg-type =][= + + ==* key =] + static char const * kwlist[] = { +[=(shellf "${CLexe:-columns} -I16 -f'\"%%s\"' -S, --spread=2 <<_EOF_\n%s\n_EOF_" + (join "\n" (stack "keyword")) )=] }; + pzArg = malloc([= (+ 4 (string-length (get "name"))) + =] + strlen( kwlist[ OPT_VALUE_[=(. opt-name)=] ] )); + sprintf(pzArg, "--[=name=]=%s", kwlist[ OPT_VALUE_[= + (. opt-name)=] ]); + add_arg(pzArg, ix++);[= + + ==* num =] + pzArg = malloc((size_t)[= (+ 16 (string-length (get "name"))) =]); + sprintf(pzArg, "--[=name=]=%d", (int)OPT_VALUE_[=(. opt-name)=]); + add_arg(pzArg, ix++);[= + + ==* bool =] + static char z[] = "--[=name=]=false"; + if (OPT_VALUE_[=(. opt-name)=]) + strcpy(z + [= (+ 3 (string-length (get "name"))) =], "true"); + add_arg(z, ix++);[= + + ==* str =][= + IF (exist? "max") =] + int optCt = STACKCT_OPT([=(. opt-name)=]); + char const ** ppOA = STACKLST_OPT([=(. opt-name)=]); + do { + char const * pA = *(ppOA++); + pzArg = malloc([= (+ 4 (string-length (get "name"))) + =] + strlen(pA)); + sprintf(pzArg, "--[=name=]=%s", pA); + add_arg(pzArg, ix++); + } while (--optCt > 0);[= + ELSE !exists-max =] + pzArg = malloc([= (+ 4 (string-length (get "name"))) + =] + strlen( OPT_ARG( [=(. opt-name)=] ))); + sprintf(pzArg, "--[=name=]=%s", OPT_ARG( [=(. opt-name)=] )); + add_arg(pzArg, ix++);[= + ENDIF exists-max =][= + + == "" =] + add_arg("--[=name=]", ix++);[= + + ESAC arg-type =] + }[= + +ENDDEF handle-option + +end of fork.tpl \=] diff --git a/xml2ag/test/Makefile.am b/xml2ag/test/Makefile.am new file mode 100644 index 0000000..88a3f53 --- /dev/null +++ b/xml2ag/test/Makefile.am @@ -0,0 +1,40 @@ +## -*- Mode: Makefile -*- +## +## Makefile.am -- process this file with automake to produce Makefile.in +## +## Author: Bruce Korb +## +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen 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. +## +## AutoGen is distributed in the hope that 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 . + +TESTS = convert.test +EXTRA_DIST = $(TESTS) + +TESTS_ENVIRONMENT = \ + X2Aexe=`\cd $(top_builddir)/xml2ag ; pwd`/xml2ag$(EXEEXT) \ + srcdir=$(srcdir) top_srcdir=$(top_srcdir) + +distclean-local: + -rm -rf testdir FAILURES + +check : perm-stamp + +$(TESTS) : perm-stamp + +perm-stamp : + cd $(srcdir) ; chmod +x *.test + +# end of Makefile.am diff --git a/xml2ag/test/Makefile.in b/xml2ag/test/Makefile.in new file mode 100644 index 0000000..139c702 --- /dev/null +++ b/xml2ag/test/Makefile.in @@ -0,0 +1,887 @@ +# Makefile.in generated by automake 1.16.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2018 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +subdir = xml2ag/test +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/config/ag_macros.m4 \ + $(top_srcdir)/config/asm-underscore.m4 \ + $(top_srcdir)/config/extensions.m4 \ + $(top_srcdir)/config/guile.m4 \ + $(top_srcdir)/config/host-cpu-c-abi.m4 \ + $(top_srcdir)/config/lib-ld.m4 \ + $(top_srcdir)/config/lib-link.m4 \ + $(top_srcdir)/config/lib-prefix.m4 \ + $(top_srcdir)/config/libopts.m4 \ + $(top_srcdir)/config/libtool.m4 \ + $(top_srcdir)/config/ltoptions.m4 \ + $(top_srcdir)/config/ltsugar.m4 \ + $(top_srcdir)/config/ltversion.m4 \ + $(top_srcdir)/config/lt~obsolete.m4 \ + $(top_srcdir)/config/onceonly.m4 $(top_srcdir)/config/pkg.m4 \ + $(top_srcdir)/config/snprintfv.m4 \ + $(top_srcdir)/config/stdnoreturn.m4 \ + $(top_srcdir)/config/unlocked-io.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +am__tty_colors_dummy = \ + mgn= red= grn= lgn= blu= brg= std=; \ + am__color_tests=no +am__tty_colors = { \ + $(am__tty_colors_dummy); \ + if test "X$(AM_COLOR_TESTS)" = Xno; then \ + am__color_tests=no; \ + elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ + am__color_tests=yes; \ + elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ + am__color_tests=yes; \ + fi; \ + if test $$am__color_tests = yes; then \ + red=''; \ + grn=''; \ + lgn=''; \ + blu=''; \ + mgn=''; \ + brg=''; \ + std=''; \ + fi; \ +} +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__recheck_rx = ^[ ]*:recheck:[ ]* +am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* +am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* +# A command that, given a newline-separated list of test names on the +# standard input, print the name of the tests that are to be re-run +# upon "make recheck". +am__list_recheck_tests = $(AWK) '{ \ + recheck = 1; \ + while ((rc = (getline line < ($$0 ".trs"))) != 0) \ + { \ + if (rc < 0) \ + { \ + if ((getline line2 < ($$0 ".log")) < 0) \ + recheck = 0; \ + break; \ + } \ + else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \ + { \ + recheck = 0; \ + break; \ + } \ + else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \ + { \ + break; \ + } \ + }; \ + if (recheck) \ + print $$0; \ + close ($$0 ".trs"); \ + close ($$0 ".log"); \ +}' +# A command that, given a newline-separated list of test names on the +# standard input, create the global log from their .trs and .log files. +am__create_global_log = $(AWK) ' \ +function fatal(msg) \ +{ \ + print "fatal: making $@: " msg | "cat >&2"; \ + exit 1; \ +} \ +function rst_section(header) \ +{ \ + print header; \ + len = length(header); \ + for (i = 1; i <= len; i = i + 1) \ + printf "="; \ + printf "\n\n"; \ +} \ +{ \ + copy_in_global_log = 1; \ + global_test_result = "RUN"; \ + while ((rc = (getline line < ($$0 ".trs"))) != 0) \ + { \ + if (rc < 0) \ + fatal("failed to read from " $$0 ".trs"); \ + if (line ~ /$(am__global_test_result_rx)/) \ + { \ + sub("$(am__global_test_result_rx)", "", line); \ + sub("[ ]*$$", "", line); \ + global_test_result = line; \ + } \ + else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \ + copy_in_global_log = 0; \ + }; \ + if (copy_in_global_log) \ + { \ + rst_section(global_test_result ": " $$0); \ + while ((rc = (getline line < ($$0 ".log"))) != 0) \ + { \ + if (rc < 0) \ + fatal("failed to read from " $$0 ".log"); \ + print line; \ + }; \ + printf "\n"; \ + }; \ + close ($$0 ".trs"); \ + close ($$0 ".log"); \ +}' +# Restructured Text title. +am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; } +# Solaris 10 'make', and several other traditional 'make' implementations, +# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it +# by disabling -e (using the XSI extension "set +e") if it's set. +am__sh_e_setup = case $$- in *e*) set +e;; esac +# Default flags passed to test drivers. +am__common_driver_flags = \ + --color-tests "$$am__color_tests" \ + --enable-hard-errors "$$am__enable_hard_errors" \ + --expect-failure "$$am__expect_failure" +# To be inserted before the command running the test. Creates the +# directory for the log if needed. Stores in $dir the directory +# containing $f, in $tst the test, in $log the log. Executes the +# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and +# passes TESTS_ENVIRONMENT. Set up options for the wrapper that +# will run the test scripts (or their associated LOG_COMPILER, if +# thy have one). +am__check_pre = \ +$(am__sh_e_setup); \ +$(am__vpath_adj_setup) $(am__vpath_adj) \ +$(am__tty_colors); \ +srcdir=$(srcdir); export srcdir; \ +case "$@" in \ + */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \ + *) am__odir=.;; \ +esac; \ +test "x$$am__odir" = x"." || test -d "$$am__odir" \ + || $(MKDIR_P) "$$am__odir" || exit $$?; \ +if test -f "./$$f"; then dir=./; \ +elif test -f "$$f"; then dir=; \ +else dir="$(srcdir)/"; fi; \ +tst=$$dir$$f; log='$@'; \ +if test -n '$(DISABLE_HARD_ERRORS)'; then \ + am__enable_hard_errors=no; \ +else \ + am__enable_hard_errors=yes; \ +fi; \ +case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ + am__expect_failure=yes;; \ + *) \ + am__expect_failure=no;; \ +esac; \ +$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT) +# A shell command to get the names of the tests scripts with any registered +# extension removed (i.e., equivalently, the names of the test logs, with +# the '.log' extension removed). The result is saved in the shell variable +# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly, +# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)", +# since that might cause problem with VPATH rewrites for suffix-less tests. +# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'. +am__set_TESTS_bases = \ + bases='$(TEST_LOGS)'; \ + bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ + bases=`echo $$bases` +RECHECK_LOGS = $(TEST_LOGS) +AM_RECURSIVE_TARGETS = check recheck +TEST_SUITE_LOG = test-suite.log +TEST_EXTENSIONS = @EXEEXT@ .test +am__test_logs1 = $(TESTS:=.log) +am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) +TEST_LOGS = $(am__test_logs2:.test.log=.log) +TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/config/test-driver +TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ + $(TEST_LOG_FLAGS) +am__set_b = \ + case '$@' in \ + */*) \ + case '$*' in \ + */*) b='$*';; \ + *) b=`echo '$@' | sed 's/\.log$$//'`; \ + esac;; \ + *) \ + b='$*';; \ + esac +am__DIST_COMMON = $(srcdir)/Makefile.in \ + $(top_srcdir)/config/test-driver +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AGEN5_TESTS = @AGEN5_TESTS@ +AG_LDFLAGS = @AG_LDFLAGS@ +AG_MAJOR_VERSION = @AG_MAJOR_VERSION@ +AG_MINOR_VERSION = @AG_MINOR_VERSION@ +AG_STATIC_AUTOGEN = @AG_STATIC_AUTOGEN@ +AG_TIMEOUT = @AG_TIMEOUT@ +AG_VERSION = @AG_VERSION@ +AG_XML2 = @AG_XML2@ +AGexe = @AGexe@ +AGnam = @AGnam@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AO_AGE = @AO_AGE@ +AO_CURRENT = @AO_CURRENT@ +AO_REVISION = @AO_REVISION@ +AO_TEMPLATE_VERSION = @AO_TEMPLATE_VERSION@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CLexe = @CLexe@ +CLnam = @CLnam@ +CONFIG_SHELL = @CONFIG_SHELL@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEBUG_ENABLED = @DEBUG_ENABLED@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +DYNAMIC_AG = @DYNAMIC_AG@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ENABLE_STATIC = @ENABLE_STATIC@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GDexe = @GDexe@ +GDnam = @GDnam@ +GO_AGE = @GO_AGE@ +GO_CURRENT = @GO_CURRENT@ +GO_REVISION = @GO_REVISION@ +GREP = @GREP@ +GUILE_CFLAGS = @GUILE_CFLAGS@ +GUILE_EFFECTIVE_VERSION = @GUILE_EFFECTIVE_VERSION@ +GUILE_LDFLAGS = @GUILE_LDFLAGS@ +GUILE_LIBS = @GUILE_LIBS@ +GUILE_LTLIBS = @GUILE_LTLIBS@ +HOST_CPU = @HOST_CPU@ +HOST_CPU_C_ABI = @HOST_CPU_C_ABI@ +INCLIST = @INCLIST@ +INCSNPRINTFV = @INCSNPRINTFV@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSNPRINTFV = @LIBSNPRINTFV@ +LIBTOOL = @LIBTOOL@ +LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ +LIBXML2_LIBS = @LIBXML2_LIBS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +M4_SRC = @M4_SRC@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPTS_TESTDIR = @OPTS_TESTDIR@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POSIX_SHELL = @POSIX_SHELL@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STDNORETURN_H = @STDNORETURN_H@ +STRIP = @STRIP@ +TEXI2HTML = @TEXI2HTML@ +VERSION = @VERSION@ +WARN_CFLAGS = @WARN_CFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_aux_dir = @ac_aux_dir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +TESTS = convert.test +EXTRA_DIST = $(TESTS) +TESTS_ENVIRONMENT = \ + X2Aexe=`\cd $(top_builddir)/xml2ag ; pwd`/xml2ag$(EXEEXT) \ + srcdir=$(srcdir) top_srcdir=$(top_srcdir) + +all: all-am + +.SUFFIXES: +.SUFFIXES: .log .test .test$(EXEEXT) .trs +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu xml2ag/test/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu xml2ag/test/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +tags TAGS: + +ctags CTAGS: + +cscope cscopelist: + + +# Recover from deleted '.trs' file; this should ensure that +# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create +# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells +# to avoid problems with "make -n". +.log.trs: + rm -f $< $@ + $(MAKE) $(AM_MAKEFLAGS) $< + +# Leading 'am--fnord' is there to ensure the list of targets does not +# expand to empty, as could happen e.g. with make check TESTS=''. +am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) +am--force-recheck: + @: + +$(TEST_SUITE_LOG): $(TEST_LOGS) + @$(am__set_TESTS_bases); \ + am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ + redo_bases=`for i in $$bases; do \ + am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \ + done`; \ + if test -n "$$redo_bases"; then \ + redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \ + redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \ + if $(am__make_dryrun); then :; else \ + rm -f $$redo_logs && rm -f $$redo_results || exit 1; \ + fi; \ + fi; \ + if test -n "$$am__remaking_logs"; then \ + echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ + "recursion detected" >&2; \ + elif test -n "$$redo_logs"; then \ + am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ + fi; \ + if $(am__make_dryrun); then :; else \ + st=0; \ + errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \ + for i in $$redo_bases; do \ + test -f $$i.trs && test -r $$i.trs \ + || { echo "$$errmsg $$i.trs" >&2; st=1; }; \ + test -f $$i.log && test -r $$i.log \ + || { echo "$$errmsg $$i.log" >&2; st=1; }; \ + done; \ + test $$st -eq 0 || exit 1; \ + fi + @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \ + ws='[ ]'; \ + results=`for b in $$bases; do echo $$b.trs; done`; \ + test -n "$$results" || results=/dev/null; \ + all=` grep "^$$ws*:test-result:" $$results | wc -l`; \ + pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \ + fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \ + skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \ + xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \ + xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \ + error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \ + if test `expr $$fail + $$xpass + $$error` -eq 0; then \ + success=true; \ + else \ + success=false; \ + fi; \ + br='==================='; br=$$br$$br$$br$$br; \ + result_count () \ + { \ + if test x"$$1" = x"--maybe-color"; then \ + maybe_colorize=yes; \ + elif test x"$$1" = x"--no-color"; then \ + maybe_colorize=no; \ + else \ + echo "$@: invalid 'result_count' usage" >&2; exit 4; \ + fi; \ + shift; \ + desc=$$1 count=$$2; \ + if test $$maybe_colorize = yes && test $$count -gt 0; then \ + color_start=$$3 color_end=$$std; \ + else \ + color_start= color_end=; \ + fi; \ + echo "$${color_start}# $$desc $$count$${color_end}"; \ + }; \ + create_testsuite_report () \ + { \ + result_count $$1 "TOTAL:" $$all "$$brg"; \ + result_count $$1 "PASS: " $$pass "$$grn"; \ + result_count $$1 "SKIP: " $$skip "$$blu"; \ + result_count $$1 "XFAIL:" $$xfail "$$lgn"; \ + result_count $$1 "FAIL: " $$fail "$$red"; \ + result_count $$1 "XPASS:" $$xpass "$$red"; \ + result_count $$1 "ERROR:" $$error "$$mgn"; \ + }; \ + { \ + echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ + $(am__rst_title); \ + create_testsuite_report --no-color; \ + echo; \ + echo ".. contents:: :depth: 2"; \ + echo; \ + for b in $$bases; do echo $$b; done \ + | $(am__create_global_log); \ + } >$(TEST_SUITE_LOG).tmp || exit 1; \ + mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ + if $$success; then \ + col="$$grn"; \ + else \ + col="$$red"; \ + test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ + fi; \ + echo "$${col}$$br$${std}"; \ + echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}"; \ + echo "$${col}$$br$${std}"; \ + create_testsuite_report --maybe-color; \ + echo "$$col$$br$$std"; \ + if $$success; then :; else \ + echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \ + if test -n "$(PACKAGE_BUGREPORT)"; then \ + echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ + fi; \ + echo "$$col$$br$$std"; \ + fi; \ + $$success || exit 1 + +check-TESTS: + @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list + @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list + @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + @set +e; $(am__set_TESTS_bases); \ + log_list=`for i in $$bases; do echo $$i.log; done`; \ + trs_list=`for i in $$bases; do echo $$i.trs; done`; \ + log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ + $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ + exit $$?; +recheck: all + @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + @set +e; $(am__set_TESTS_bases); \ + bases=`for i in $$bases; do echo $$i; done \ + | $(am__list_recheck_tests)` || exit 1; \ + log_list=`for i in $$bases; do echo $$i.log; done`; \ + log_list=`echo $$log_list`; \ + $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \ + am__force_recheck=am--force-recheck \ + TEST_LOGS="$$log_list"; \ + exit $$? +.test.log: + @p='$<'; \ + $(am__set_b); \ + $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +@am__EXEEXT_TRUE@.test$(EXEEXT).log: +@am__EXEEXT_TRUE@ @p='$<'; \ +@am__EXEEXT_TRUE@ $(am__set_b); \ +@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ +@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ +@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ +@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) check-TESTS +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) + -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) + -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-local + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: check-am install-am install-strip + +.PHONY: all all-am check check-TESTS check-am clean clean-generic \ + clean-libtool cscopelist-am ctags-am distclean \ + distclean-generic distclean-libtool distclean-local distdir \ + dvi dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am recheck tags-am \ + uninstall uninstall-am + +.PRECIOUS: Makefile + + +distclean-local: + -rm -rf testdir FAILURES + +check : perm-stamp + +$(TESTS) : perm-stamp + +perm-stamp : + cd $(srcdir) ; chmod +x *.test + +# end of Makefile.am + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/xml2ag/test/convert.test b/xml2ag/test/convert.test new file mode 100755 index 0000000..36a6734 --- /dev/null +++ b/xml2ag/test/convert.test @@ -0,0 +1,101 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# ---------------------------------------------------------------------- +# convert.test --- test XML -> AutoGen conversion +# +## Author: Bruce Korb +## +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen 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. +## +## AutoGen is distributed in the hope that 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 . + +case "X${VERBOSE}" in +X | X[nNfF]* ) VERBOSE=false ;; +* ) set -x ; VERBOSE=true ;; +esac + +# A standard failure function +failure() +{ + cd ${testsubdir} + test -d ../FAILURES || mkdir ../FAILURES + l=`echo *` + ( \cd ../FAILURES ; rm -f $l ) + mv -f * ../FAILURES + echo "$*" + exit 1 +} + +srcdir=`pwd` +testname=convert +[ -d testdir ] || mkdir testdir +cd testdir +testsubdir=`pwd` + +${X2Aexe} -O ${testname}.out <<'_EndOfXML_' + + + + + <stumble around the 'XML'.> + + mumble-1 + + mumble-2 + + grumble & "grumble" & grumble. + + mumble, mumble + + + +_EndOfXML_ + +cat > ${testname}.samp <<'_EndOfSample_' +/* Parsed from stdin */ +AutoGen Definitions sample.tpl; +XML-version = '1.0'; +XML-standalone = 'true'; +template = 'sample.tpl'; +mumble = { + content = ''; + attr = 'foo'; + grumble = { + content = ''; + text = ''; + }; + text = 'mumble-1'; + /* This is just a + /* multi-line comment * / */ + text = 'mumble-2'; + grumble = { + content = ''; + text = 'grumble & "grumble" & grumble.'; + }; + text = 'mumble, mumble'; +}; +stumble = { + content = ''; + upon = 'rough going'; +}; +_EndOfSample_ + +cmp -s ${testname}.samp ${testname}.out || \ + failure "`diff -u ${testname}.samp ${testname}.out`" + +${VERBOSE} || { cd ${srcdir} ; rm -rf ${testsubdir} ; } + +# end of convert.test diff --git a/xml2ag/xml2ag.c b/xml2ag/xml2ag.c new file mode 100644 index 0000000..867a4b1 --- /dev/null +++ b/xml2ag/xml2ag.c @@ -0,0 +1,462 @@ + +/** + * @file xml2ag.c + * + * This is the main routine for xml2ag. + * + * @group xml2ag + * @{ + */ +/* + * xml2ag Copyright (C) 2002-2018 by Bruce Korb - all rights reserved + * This file is part of AutoGen. + * AutoGen Copyright (C) 1992-2017 by Bruce Korb - all rights reserved + * + * AutoGen 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. + * + * AutoGen is distributed in the hope that 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 . + */ + +static char const zConflict[] = + "the file name operand conflicts with the definitions option.\n"; + +static char const zTextFmt[] = + "text = '%s';\n"; + +static char const * typeName[] = { + "0 - inval", + "ELEMENT_NODE", + "ATTRIBUTE_NODE", + "TEXT_NODE", + "CDATA_SECTION_NODE", + "ENTITY_REF_NODE", + "ENTITY_NODE", + "PI_NODE", + "COMMENT_NODE", + "DOCUMENT_NODE", + "DOCUMENT_TYPE_NODE", + "DOCUMENT_FRAG_NODE", + "NOTATION_NODE", + "HTML_DOCUMENT_NODE", + "DTD_NODE", + "ELEMENT_DECL", + "ATTRIBUTE_DECL", + "ENTITY_DECL", + "NAMESPACE_DECL", + "XINCLUDE_START", + "XINCLUDE_END", + "DOCB_DOCUMENT_NODE" }; + +int level = 0; +FILE * ag_pipe_fp; + +#define CHUNK_SZ 4096 + +#define TRIM(s,psz) trim( (char const *)(s), (size_t *)(psz) ) + +extern void fork_ag(char const * pzInput); +static char * loadFile(FILE * fp, size_t * pzSize); +static xmlNodePtr printHeader(xmlDocPtr pDoc); +static void printAttrs(xmlAttrPtr pAttr); +static void printChildren(xmlNodePtr pNode); + +int +main(int argc, char ** argv) +{ + xmlDocPtr pDoc; + char const * pzFile = NULL; + + { + int ct = optionProcess( &xml2agOptions, argc, argv ); + argc -= ct; + argv += ct; + + switch (argc) { + case 1: + if (strcmp( *argv, "-" ) != 0) { + if (HAVE_OPT( DEFINITIONS )) { + fprintf(stderr, zConflict); + USAGE( EXIT_FAILURE ); + } + pzFile = *argv; + break; + } + /* FALLTHROUGH */ + case 0: + if ( HAVE_OPT( DEFINITIONS ) + && (strcmp( OPT_ARG( DEFINITIONS ), "-" ) != 0) ) + + pzFile = OPT_ARG( DEFINITIONS ); + break; + + default: + fprintf(stderr, "only one argument allowed\n"); + return EXIT_FAILURE; + } + } + + if (! HAVE_OPT( OUTPUT )) + fork_ag(pzFile); + else + ag_pipe_fp = stdout; + + if (pzFile != NULL) { + fprintf(ag_pipe_fp, "/* Parsing file %s */\n", pzFile); + pDoc = xmlParseFile( pzFile ); + } + else { + size_t sz; + char * pz = loadFile( stdin, &sz ); + pDoc = xmlParseMemory( pz, (int)sz ); + fprintf(ag_pipe_fp, "/* Parsed from stdin */\n"); + } + + { + static char const z_not_doc[] = + "/* type %d doc is not DOCUMENT or HTML_DOCUMENT */\n"; + + xmlNodePtr pRoot = printHeader( pDoc ); + printAttrs( pRoot->properties ); + switch (pDoc->type) { + case XML_DOCUMENT_NODE: + case XML_HTML_DOCUMENT_NODE: + printChildren( pRoot->children ); + break; + default: + fprintf(ag_pipe_fp, z_not_doc, pDoc->type); + } + } + + xmlCleanupParser(); + return 0; +} + + +static char * +loadFile(FILE * fp, size_t * pzSize) +{ + size_t asz = CHUNK_SZ; + size_t usz = 0; + char * mem = malloc( asz ); + + for (;;) { + + if ((usz + CHUNK_SZ) > asz) { + asz += CHUNK_SZ; + mem = realloc( mem, asz ); + } + + if (mem == NULL) { + fprintf(stderr, "Cannot allocate %d byte bufer\n", (int)asz); + exit( EXIT_FAILURE ); + } + + { + size_t rdct = fread(mem + usz, (size_t)1, (size_t)CHUNK_SZ, fp); + usz += rdct; + if (rdct < CHUNK_SZ) + break; + } + } + + *pzSize = usz; + return mem; +} + + +static void +emitIndentation( void ) +{ + int indent = level * 2; + while (--indent >= 0) fputc( ' ', ag_pipe_fp ); +} + + +static char * +trim(char const * pzSrc, size_t * pSz) +{ + static char zNil[1] = ""; + static char * pzData = NULL; + static size_t dataLen = 0; + size_t strSize; + + if (pzSrc == NULL) { + if (pSz != NULL) *pSz = 0; + return zNil; + } + + /* + * Trim leading and trailing white space. + */ + while (isspace( *pzSrc )) pzSrc++; + + { + char const * pzEnd = pzSrc + strlen( pzSrc ); + while ((pzEnd > pzSrc) && isspace( pzEnd[-1] )) pzEnd--; + + if (pzEnd <= pzSrc) { + if (pSz != NULL) *pSz = 0; + return zNil; + } + strSize = (size_t)(pzEnd - pzSrc); + } + + /* + * Count the extra backslashes required and ensure our buffer is + * big enough to hold the newly formed string. + */ + { + char const * pz = pzSrc; + for (;;) { + pz += strcspn( pz, "'\\" ); + if (*(pz++) == NUL) + break; + strSize++; + } + } + + if (dataLen <= strSize) { + size_t sz = (strSize + 0x1000) & ~0x0FFFUL; + if (pzData == NULL) + pzData = malloc( sz ); + else pzData = realloc( pzData, sz ); + if (pzData == NULL) { + fprintf(stderr, "ENOMEM allocating 0x%X bytes", (unsigned)sz); + exit( EXIT_FAILURE ); + } + dataLen = sz; + } + + /* + * Copy the data, adding backslashes in front of + * single quotes and backslashes. + */ + { + char * pzDest = pzData; + for (;;) { + switch (*(pzDest++) = *(pzSrc++)) { + case '\'': pzDest[-1] = '\\'; *(pzDest++) = '\''; break; + case '\\': *(pzDest++) = '\\'; break; + case NUL: goto set_size; + } + if (pzDest == pzData + strSize) + break; + } + + *pzDest = '\0'; + } + + set_size: + if (pSz != NULL) *pSz = strSize; + return pzData; +} + +static xmlNodePtr +printHeader(xmlDocPtr pDoc) +{ + static char const def_hdr[] = "AutoGen Definitions %s%s;\n"; + static char const xml_fmt[] = "XML-%s = '%s';\n"; + + char const * suffx = ".tpl"; + + xmlNodePtr root_node = xmlDocGetRootElement( pDoc ); + xmlChar * tmp_tpl = NULL; + xmlChar * tpl_nm; + + if (root_node == NULL) { + fprintf(stderr, "Root node not found\n"); + exit( EXIT_FAILURE ); + } + + if (HAVE_OPT( OVERRIDE_TPL )) { + if (strchr( OPT_ARG( OVERRIDE_TPL ), '.' ) != NULL) + suffx = ""; + tpl_nm = (xmlChar *)VOIDP(OPT_ARG( OVERRIDE_TPL )); + } + else { + tmp_tpl = xmlGetProp(root_node, (xmlChar *)VOIDP("template")); + if (tmp_tpl == NULL) { + fprintf(stderr, "No template was specified.\n"); + exit( EXIT_FAILURE ); + } + + tpl_nm = tmp_tpl; + if (strchr( (char *)tpl_nm, '.' ) != NULL) + suffx = ""; + } + + fprintf(ag_pipe_fp, def_hdr, tpl_nm, suffx); + if (tmp_tpl != NULL) + free(tmp_tpl); + + if (pDoc->name != NULL) + fprintf(ag_pipe_fp, xml_fmt, "name", TRIM(pDoc->name, NULL)); + + if (pDoc->version != NULL) + fprintf(ag_pipe_fp, xml_fmt, "version", TRIM(pDoc->version, NULL)); + + if (pDoc->encoding != NULL) + fprintf(ag_pipe_fp, xml_fmt, "encoding", TRIM(pDoc->encoding, NULL)); + + if (pDoc->URL != NULL) + fprintf(ag_pipe_fp, xml_fmt, "URL", TRIM(pDoc->URL, NULL)); + + if (pDoc->standalone) + fprintf(ag_pipe_fp, xml_fmt, "standalone", "true"); + + return root_node; +} + +static void +printAttrs(xmlAttrPtr pAttr) +{ + while (pAttr != NULL) { + char * pzCont = (char *)pAttr->children->content; + + emitIndentation(); + fputs( (char *)VOIDP(pAttr->name), ag_pipe_fp ); + fputs( " = ", ag_pipe_fp ); + if (pAttr->children->children == NULL) + fprintf(ag_pipe_fp, "'%s';\n", TRIM(pzCont, NULL)); + else { + fputs( "{\n", ag_pipe_fp ); + level++; + if (pzCont != NULL) { + emitIndentation(); + fprintf(ag_pipe_fp, zTextFmt, TRIM(pzCont, NULL)); + } + printChildren( pAttr->children->children ); + level--; + emitIndentation(); + fputs( "};\n", ag_pipe_fp ); + } + + pAttr = pAttr->next; + } +} + + +static void +printNode(xmlNodePtr pNode) +{ + switch (pNode->type) { + case XML_ELEMENT_NODE: + { + size_t sz; + char * pzTxt; + emitIndentation(); + fputs( (char *)VOIDP(pNode->name), ag_pipe_fp ); + pzTxt = TRIM(pNode->content, &sz); + + if ( (pNode->properties == NULL) + && (pNode->children == NULL)) { + + if (sz == 0) + fputs( ";\n", ag_pipe_fp ); + else fprintf(ag_pipe_fp, " = '%s';\n", pzTxt); + break; + } + + fputs( " = {\n", ag_pipe_fp ); + level++; + emitIndentation(); + fprintf(ag_pipe_fp, "content = '%s';\n", pzTxt); + printAttrs( pNode->properties ); + printChildren( pNode->children ); + level--; + emitIndentation(); + fputs( "};\n", ag_pipe_fp ); + break; + } + + case XML_ATTRIBUTE_NODE: + fputs( "Misplaced attribute\n", ag_pipe_fp ); + exit( EXIT_FAILURE ); + + case XML_TEXT_NODE: + { + size_t sz; + char * pzTxt = TRIM(pNode->content, &sz); + if (sz == 0) + break; + emitIndentation(); + fprintf(ag_pipe_fp, zTextFmt, pzTxt); + break; + } + + case XML_COMMENT_NODE: + { + size_t sz; + char * pzTxt = TRIM(pNode->content, &sz); + if (sz == 0) + break; + + emitIndentation(); + fputs( "/* ", ag_pipe_fp ); + for (;;) { + char * pz = strstr( pzTxt, "*/" ); + if (pz == NULL) + break; + fwrite(pzTxt, (size_t)((pz - pzTxt) + 1), (size_t)1, ag_pipe_fp); + pzTxt = pz+1; + fputc( ' ', ag_pipe_fp ); + } + fprintf(ag_pipe_fp, "%s */\n", pzTxt); + break; + } + + case XML_CDATA_SECTION_NODE: + case XML_ENTITY_REF_NODE: + case XML_ENTITY_NODE: + case XML_PI_NODE: + + case XML_DOCUMENT_NODE: + case XML_HTML_DOCUMENT_NODE: + case XML_DOCUMENT_TYPE_NODE: + case XML_DOCUMENT_FRAG_NODE: + case XML_NOTATION_NODE: + case XML_DTD_NODE: + case XML_ELEMENT_DECL: + case XML_ATTRIBUTE_DECL: + case XML_ENTITY_DECL: + case XML_NAMESPACE_DECL: + case XML_XINCLUDE_START: + case XML_XINCLUDE_END: + emitIndentation(); + fprintf(ag_pipe_fp, "/* Unsupported XML node type: %s */\n", + typeName[ pNode->type ]); + break; + + default: + emitIndentation(); + fprintf(ag_pipe_fp, "/* Unknown XML node type %d */\n", pNode->type); + break; + } +} + + +static void +printChildren(xmlNodePtr pNode) +{ + while (pNode != NULL) { + printNode( pNode ); + pNode = pNode->next; + } +} + +/* + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of xml2ag/xml2ag.c */ diff --git a/xml2ag/xmlopts.c b/xml2ag/xmlopts.c new file mode 100644 index 0000000..e65317b --- /dev/null +++ b/xml2ag/xmlopts.c @@ -0,0 +1,1118 @@ +/* -*- buffer-read-only: t -*- vi: set ro: + * + * DO NOT EDIT THIS FILE (xmlopts.c) + * + * It has been AutoGen-ed + * From the definitions ./xmlopts.def + * and the template file options + * + * Generated from AutoOpts 42:1:17 templates. + * + * AutoOpts is a copyrighted work. This source file is not encumbered + * by AutoOpts licensing, but is provided under the licensing terms chosen + * by the xml2ag author or copyright holder. AutoOpts is + * licensed under the terms of the LGPL. The redistributable library + * (``libopts'') is licensed under the terms of either the LGPL or, at the + * users discretion, the BSD license. See the AutoOpts and/or libopts sources + * for details. + * + * The xml2ag program is copyrighted and licensed + * under the following terms: + * + * Copyright (C) 1992-2018 Bruce Korb, all rights reserved. + * This is free software. It is licensed for use, modification and + * redistribution under the terms of the GNU General Public License, + * version 3 or later + * + * xml2ag 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. + * + * xml2ag is distributed in the hope that 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 . + */ +/** \file xmlopts.c + * \addtogroup xml2ag + * @{ + */ + +#ifndef __doxygen__ +#define OPTION_CODE_COMPILE 1 +#include "xmlopts.h" +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif +extern FILE * option_usage_fp; +#define zCopyright (xml2ag_opt_strs+0) +#define zLicenseDescrip (xml2ag_opt_strs+271) + +/* + * global included definitions + */ + + +#ifndef NULL +# define NULL 0 +#endif + +/** + * static const strings for xml2ag options + */ +static char const xml2ag_opt_strs[2872] = +/* 0 */ "xml2ag (GNU AutoGen) 5.18.16\n" + "Copyright (C) 1992-2018 Bruce Korb, all rights reserved.\n" + "This is free software. It is licensed for use, modification and\n" + "redistribution under the terms of the GNU General Public License,\n" + "version 3 or later \n\0" +/* 271 */ "xml2ag is free software: you can redistribute it and/or modify it under the\n" + "terms of the GNU General Public License as published by the Free Software\n" + "Foundation, either version 3 of the License, or (at your option) any later\n" + "version.\n\n" + "xml2ag is distributed in the hope that it will be useful, but WITHOUT ANY\n" + "WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\n" + "FOR A PARTICULAR PURPOSE. See the GNU General Public License for more\n" + "details.\n\n" + "You should have received a copy of the GNU General Public License along\n" + "with this program. If not, see .\n\0" +/* 872 */ "All other options are derived from autogen:\0" +/* 916 */ "Output file in lieu of AutoGen processing\0" +/* 958 */ "OUTPUT\0" +/* 965 */ "output\0" +/* 972 */ "All other options:\0" +/* 991 */ "Search for templates in DIR\0" +/* 1019 */ "TEMPL_DIRS\0" +/* 1030 */ "templ-dirs\0" +/* 1041 */ "Use TPL-FILE for the template\0" +/* 1071 */ "OVERRIDE_TPL\0" +/* 1084 */ "override-tpl\0" +/* 1097 */ "Read definitions from FILE\0" +/* 1124 */ "DEFINITIONS\0" +/* 1136 */ "definitions\0" +/* 1148 */ "name or path name of shell to use\0" +/* 1182 */ "SHELL\0" +/* 1188 */ "shell\0" +/* 1194 */ "Do not use in-mem streams\0" +/* 1220 */ "NO_FMEMOPEN\0" +/* 1232 */ "no-fmemopen\0" +/* 1244 */ "characters considered equivalent\0" +/* 1277 */ "EQUATE\0" +/* 1284 */ "equate\0" +/* 1291 */ "Specify NAME as the base name for output\0" +/* 1332 */ "BASE_NAME\0" +/* 1342 */ "base-name\0" +/* 1352 */ "set mod times to latest source\0" +/* 1383 */ "SOURCE_TIME\0" +/* 1395 */ "source-time\0" +/* 1407 */ "Allow output files to be writable\0" +/* 1441 */ "WRITABLE\0" +/* 1450 */ "not-writable\0" +/* 1463 */ "not\0" +/* 1467 */ "Limit on increment loops\0" +/* 1492 */ "LOOP_LIMIT\0" +/* 1503 */ "loop-limit\0" +/* 1514 */ "Limit server shell operations to SECONDS\0" +/* 1555 */ "TIMEOUT\0" +/* 1563 */ "timeout\0" +/* 1571 */ "tracing level of detail\0" +/* 1595 */ "TRACE\0" +/* 1601 */ "trace\0" +/* 1607 */ "tracing output file or filter\0" +/* 1637 */ "TRACE_OUT\0" +/* 1647 */ "trace-out\0" +/* 1657 */ "Show the definition tree\0" +/* 1682 */ "SHOW_DEFS\0" +/* 1692 */ "show-defs\0" +/* 1702 */ "Show the definitions used\0" +/* 1728 */ "USED_DEFINES\0" +/* 1741 */ "used-defines\0" +/* 1754 */ "Leave a core dump on a failure exit\0" +/* 1790 */ "CORE\0" +/* 1795 */ "core\0" +/* 1800 */ "Skip the file with this SUFFIX\0" +/* 1831 */ "SKIP_SUFFIX\0" +/* 1843 */ "skip-suffix\0" +/* 1855 */ "specify this output suffix\0" +/* 1882 */ "SELECT_SUFFIX\0" +/* 1896 */ "select-suffix\0" +/* 1910 */ "name to add to definition list\0" +/* 1941 */ "DEFINE\0" +/* 1948 */ "define\0" +/* 1955 */ "definition list removal pattern\0" +/* 1987 */ "UNDEFINE\0" +/* 1996 */ "undefine\0" +/* 2005 */ "emit make dependency file\0" +/* 2031 */ "MAKE_DEP\0" +/* 2040 */ "make-dep\0" +/* 2049 */ "display extended usage information and exit\0" +/* 2093 */ "help\0" +/* 2098 */ "extended usage information passed thru pager\0" +/* 2143 */ "more-help\0" +/* 2153 */ "output version information and exit\0" +/* 2189 */ "version\0" +/* 2197 */ "XML2AG\0" +/* 2204 */ "xml2ag (GNU AutoGen) - XML to AutoGen Definiton Converter - Ver. 5.18.16\n" + "Usage: %s [ - [] | --[{=| }] ]... [ ]\n\0" +/* 2350 */ "autogen-users@lists.sourceforge.net\0" +/* 2386 */ "This program will convert any arbitrary XML file into equivalent AutoGen\n" + "definitions, and invoke AutoGen.\n\0" +/* 2493 */ "The template will be derived from either: * the ``--override-tpl'' command\n" + "line option * a top level XML attribute named, \"template\"\n\n" + "The ``base-name'' for the output will similarly be either: * the\n" + "``--base-name'' command line option * the base name of the .xml file\n\0" +/* 2762 */ "xml2ag (GNU AutoGen) 5.18.16\0" +/* 2791 */ "nothing\0" +/* 2799 */ "debug-message\0" +/* 2813 */ "server-shell\0" +/* 2826 */ "templates\0" +/* 2836 */ "block-macros\0" +/* 2849 */ "expressions\0" +/* 2861 */ "everything"; + +/** + * the-xml2ag-option option description: + */ +/** the-xml2ag-option option separation text */ +#define THE_XML2AG_OPTION_DESC (xml2ag_opt_strs+872) +#define THE_XML2AG_OPTION_FLAGS (OPTST_DOCUMENT | OPTST_NO_INIT) + +/** + * output option description: + */ +/** Descriptive text for the output option */ +#define OUTPUT_DESC (xml2ag_opt_strs+916) +/** Upper-cased name for the output option */ +#define OUTPUT_NAME (xml2ag_opt_strs+958) +/** Name string for the output option */ +#define OUTPUT_name (xml2ag_opt_strs+965) +/** Compiled in flag settings for the output option */ +#define OUTPUT_FLAGS (OPTST_DISABLED \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING)) + +/** + * autogen-options option description: + */ +/** autogen-options option separation text */ +#define AUTOGEN_OPTIONS_DESC (xml2ag_opt_strs+972) +#define AUTOGEN_OPTIONS_FLAGS (OPTST_DOCUMENT | OPTST_NO_INIT) + +/** + * templ-dirs option description: + */ +/* TRANSLATORS: the option argument is a file name */ +/** Descriptive text for the templ-dirs option */ +#define TEMPL_DIRS_DESC (xml2ag_opt_strs+991) +/** Upper-cased name for the templ-dirs option */ +#define TEMPL_DIRS_NAME (xml2ag_opt_strs+1019) +/** Name string for the templ-dirs option */ +#define TEMPL_DIRS_name (xml2ag_opt_strs+1030) +/** Compiled in flag settings for the templ-dirs option */ +#define TEMPL_DIRS_FLAGS (OPTST_DISABLED | OPTST_STACKED \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING)) + +/** + * override-tpl option description: + */ +/** Descriptive text for the override-tpl option */ +#define OVERRIDE_TPL_DESC (xml2ag_opt_strs+1041) +/** Upper-cased name for the override-tpl option */ +#define OVERRIDE_TPL_NAME (xml2ag_opt_strs+1071) +/** Name string for the override-tpl option */ +#define OVERRIDE_TPL_name (xml2ag_opt_strs+1084) +/** Compiled in flag settings for the override-tpl option */ +#define OVERRIDE_TPL_FLAGS (OPTST_DISABLED \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING)) + +/** + * definitions option description: + */ +/** Descriptive text for the definitions option */ +#define DEFINITIONS_DESC (xml2ag_opt_strs+1097) +/** Upper-cased name for the definitions option */ +#define DEFINITIONS_NAME (xml2ag_opt_strs+1124) +/** Name string for the definitions option */ +#define DEFINITIONS_name (xml2ag_opt_strs+1136) +/** Compiled in flag settings for the definitions option */ +#define DEFINITIONS_FLAGS (OPTST_DISABLED \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING)) + +/** + * shell option description: + */ +/** Descriptive text for the shell option */ +#define SHELL_DESC (xml2ag_opt_strs+1148) +/** Upper-cased name for the shell option */ +#define SHELL_NAME (xml2ag_opt_strs+1182) +/** Name string for the shell option */ +#define SHELL_name (xml2ag_opt_strs+1188) +/** Compiled in flag settings for the shell option */ +#define SHELL_FLAGS (OPTST_DISABLED \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING)) + +/** + * no-fmemopen option description: + */ +/** Descriptive text for the no-fmemopen option */ +#define NO_FMEMOPEN_DESC (xml2ag_opt_strs+1194) +/** Upper-cased name for the no-fmemopen option */ +#define NO_FMEMOPEN_NAME (xml2ag_opt_strs+1220) +/** Name string for the no-fmemopen option */ +#define NO_FMEMOPEN_name (xml2ag_opt_strs+1232) +/** Compiled in flag settings for the no-fmemopen option */ +#define NO_FMEMOPEN_FLAGS (OPTST_DISABLED) + +/** + * equate option description: + */ +/** Descriptive text for the equate option */ +#define EQUATE_DESC (xml2ag_opt_strs+1244) +/** Upper-cased name for the equate option */ +#define EQUATE_NAME (xml2ag_opt_strs+1277) +/** Name string for the equate option */ +#define EQUATE_name (xml2ag_opt_strs+1284) +/** Compiled in flag settings for the equate option */ +#define EQUATE_FLAGS (OPTST_DISABLED \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING)) + +/** + * base-name option description: + */ +/** Descriptive text for the base-name option */ +#define BASE_NAME_DESC (xml2ag_opt_strs+1291) +/** Upper-cased name for the base-name option */ +#define BASE_NAME_NAME (xml2ag_opt_strs+1332) +/** Name string for the base-name option */ +#define BASE_NAME_name (xml2ag_opt_strs+1342) +/** Compiled in flag settings for the base-name option */ +#define BASE_NAME_FLAGS (OPTST_DISABLED \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING)) + +/** + * source-time option description: + */ +/** Descriptive text for the source-time option */ +#define SOURCE_TIME_DESC (xml2ag_opt_strs+1352) +/** Upper-cased name for the source-time option */ +#define SOURCE_TIME_NAME (xml2ag_opt_strs+1383) +/** Name string for the source-time option */ +#define SOURCE_TIME_name (xml2ag_opt_strs+1395) +/** Compiled in flag settings for the source-time option */ +#define SOURCE_TIME_FLAGS (OPTST_DISABLED) + +/** + * writable option description: + */ +/** Descriptive text for the writable option */ +#define WRITABLE_DESC (xml2ag_opt_strs+1407) +/** Upper-cased name for the writable option */ +#define WRITABLE_NAME (xml2ag_opt_strs+1441) +/** disablement name for the writable option */ +#define NOT_WRITABLE_name (xml2ag_opt_strs+1450) +/** disablement prefix for the writable option */ +#define NOT_WRITABLE_PFX (xml2ag_opt_strs+1463) +/** Name string for the writable option */ +#define WRITABLE_name (NOT_WRITABLE_name + 4) +/** Compiled in flag settings for the writable option */ +#define WRITABLE_FLAGS (OPTST_DISABLED) + +/** + * loop-limit option description: + */ +/** Descriptive text for the loop-limit option */ +#define LOOP_LIMIT_DESC (xml2ag_opt_strs+1467) +/** Upper-cased name for the loop-limit option */ +#define LOOP_LIMIT_NAME (xml2ag_opt_strs+1492) +/** Name string for the loop-limit option */ +#define LOOP_LIMIT_name (xml2ag_opt_strs+1503) +/** The compiled in default value for the loop-limit option argument */ +#define LOOP_LIMIT_DFT_ARG ((char const*)256) +/** Compiled in flag settings for the loop-limit option */ +#define LOOP_LIMIT_FLAGS (OPTST_DISABLED \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_NUMERIC) \ + | OPTST_SCALED_NUM) + +/** + * timeout option description: + */ +/** Descriptive text for the timeout option */ +#define TIMEOUT_DESC (xml2ag_opt_strs+1514) +/** Upper-cased name for the timeout option */ +#define TIMEOUT_NAME (xml2ag_opt_strs+1555) +/** Name string for the timeout option */ +#define TIMEOUT_name (xml2ag_opt_strs+1563) +/** Compiled in flag settings for the timeout option */ +#define TIMEOUT_FLAGS (OPTST_DISABLED \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_NUMERIC)) + +/** + * trace option description: + */ +/** Descriptive text for the trace option */ +#define TRACE_DESC (xml2ag_opt_strs+1571) +/** Upper-cased name for the trace option */ +#define TRACE_NAME (xml2ag_opt_strs+1595) +/** Name string for the trace option */ +#define TRACE_name (xml2ag_opt_strs+1601) +/** The compiled in default value for the trace option argument */ +#define TRACE_DFT_ARG ((char const*)TRACE_NOTHING) +/** Compiled in flag settings for the trace option */ +#define TRACE_FLAGS (OPTST_DISABLED \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_ENUMERATION)) + +/** + * trace-out option description: + */ +/** Descriptive text for the trace-out option */ +#define TRACE_OUT_DESC (xml2ag_opt_strs+1607) +/** Upper-cased name for the trace-out option */ +#define TRACE_OUT_NAME (xml2ag_opt_strs+1637) +/** Name string for the trace-out option */ +#define TRACE_OUT_name (xml2ag_opt_strs+1647) +/** Compiled in flag settings for the trace-out option */ +#define TRACE_OUT_FLAGS (OPTST_DISABLED \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING)) + +/** + * show-defs option description: + */ +/** Descriptive text for the show-defs option */ +#define SHOW_DEFS_DESC (xml2ag_opt_strs+1657) +/** Upper-cased name for the show-defs option */ +#define SHOW_DEFS_NAME (xml2ag_opt_strs+1682) +/** Name string for the show-defs option */ +#define SHOW_DEFS_name (xml2ag_opt_strs+1692) +/** Compiled in flag settings for the show-defs option */ +#define SHOW_DEFS_FLAGS (OPTST_DISABLED) + +/** + * used-defines option description: + */ +/** Descriptive text for the used-defines option */ +#define USED_DEFINES_DESC (xml2ag_opt_strs+1702) +/** Upper-cased name for the used-defines option */ +#define USED_DEFINES_NAME (xml2ag_opt_strs+1728) +/** Name string for the used-defines option */ +#define USED_DEFINES_name (xml2ag_opt_strs+1741) +/** Compiled in flag settings for the used-defines option */ +#define USED_DEFINES_FLAGS (OPTST_DISABLED) + +/** + * core option description: + */ +#ifdef HAVE_SYS_RESOURCE_H +/** Descriptive text for the core option */ +#define CORE_DESC (xml2ag_opt_strs+1754) +/** Upper-cased name for the core option */ +#define CORE_NAME (xml2ag_opt_strs+1790) +/** Name string for the core option */ +#define CORE_name (xml2ag_opt_strs+1795) +/** Compiled in flag settings for the core option */ +#define CORE_FLAGS (OPTST_DISABLED) + +#else /* disable core */ +#define CORE_FLAGS (OPTST_OMITTED | OPTST_NO_INIT) +#define CORE_NAME NULL +#define CORE_DESC NULL +#define CORE_name NULL +#endif /* HAVE_SYS_RESOURCE_H */ + +/** + * skip-suffix option description with + * "Must also have options" and "Incompatible options": + */ +/** Descriptive text for the skip-suffix option */ +#define SKIP_SUFFIX_DESC (xml2ag_opt_strs+1800) +/** Upper-cased name for the skip-suffix option */ +#define SKIP_SUFFIX_NAME (xml2ag_opt_strs+1831) +/** Name string for the skip-suffix option */ +#define SKIP_SUFFIX_name (xml2ag_opt_strs+1843) +/** Other options that appear in conjunction with the skip-suffix option */ +static int const aSkip_SuffixCantList[] = { + INDEX_OPT_SELECT_SUFFIX, NO_EQUIVALENT }; +/** Compiled in flag settings for the skip-suffix option */ +#define SKIP_SUFFIX_FLAGS (OPTST_DISABLED | OPTST_STACKED \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING)) + +/** + * select-suffix option description: + */ +/** Descriptive text for the select-suffix option */ +#define SELECT_SUFFIX_DESC (xml2ag_opt_strs+1855) +/** Upper-cased name for the select-suffix option */ +#define SELECT_SUFFIX_NAME (xml2ag_opt_strs+1882) +/** Name string for the select-suffix option */ +#define SELECT_SUFFIX_name (xml2ag_opt_strs+1896) +/** Compiled in flag settings for the select-suffix option */ +#define SELECT_SUFFIX_FLAGS (OPTST_DISABLED | OPTST_STACKED \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING)) + +/** + * define option description: + */ +/** Descriptive text for the define option */ +#define DEFINE_DESC (xml2ag_opt_strs+1910) +/** Upper-cased name for the define option */ +#define DEFINE_NAME (xml2ag_opt_strs+1941) +/** Name string for the define option */ +#define DEFINE_name (xml2ag_opt_strs+1948) +/** Compiled in flag settings for the define option */ +#define DEFINE_FLAGS (OPTST_DISABLED | OPTST_STACKED \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING)) + +/** + * undefine option description: + */ +/** Descriptive text for the undefine option */ +#define UNDEFINE_DESC (xml2ag_opt_strs+1955) +/** Upper-cased name for the undefine option */ +#define UNDEFINE_NAME (xml2ag_opt_strs+1987) +/** Name string for the undefine option */ +#define UNDEFINE_name (xml2ag_opt_strs+1996) +/** Compiled in flag settings for the undefine option */ +#define UNDEFINE_FLAGS (OPTST_DISABLED \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING)) + +/** + * make-dep option description: + */ +/** Descriptive text for the make-dep option */ +#define MAKE_DEP_DESC (xml2ag_opt_strs+2005) +/** Upper-cased name for the make-dep option */ +#define MAKE_DEP_NAME (xml2ag_opt_strs+2031) +/** Name string for the make-dep option */ +#define MAKE_DEP_name (xml2ag_opt_strs+2040) +/** Compiled in flag settings for the make-dep option */ +#define MAKE_DEP_FLAGS (OPTST_DISABLED \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING) | OPTST_ARG_OPTIONAL) + +/* + * Help/More_Help/Version option descriptions: + */ +#define HELP_DESC (xml2ag_opt_strs+2049) +#define HELP_name (xml2ag_opt_strs+2093) +#ifdef HAVE_WORKING_FORK +#define MORE_HELP_DESC (xml2ag_opt_strs+2098) +#define MORE_HELP_name (xml2ag_opt_strs+2143) +#define MORE_HELP_FLAGS (OPTST_IMM | OPTST_NO_INIT) +#else +#define MORE_HELP_DESC HELP_DESC +#define MORE_HELP_name HELP_name +#define MORE_HELP_FLAGS (OPTST_OMITTED | OPTST_NO_INIT) +#endif +#ifdef NO_OPTIONAL_OPT_ARGS +# define VER_FLAGS (OPTST_IMM | OPTST_NO_INIT) +#else +# define VER_FLAGS (OPTST_SET_ARGTYPE(OPARG_TYPE_STRING) | \ + OPTST_ARG_OPTIONAL | OPTST_IMM | OPTST_NO_INIT) +#endif +#define VER_DESC (xml2ag_opt_strs+2153) +#define VER_name (xml2ag_opt_strs+2189) +/** + * Declare option callback procedures + */ +extern tOptProc + optionBooleanVal, optionNestedVal, optionNumericVal, + optionPagedUsage, optionPrintVersion, optionResetOpt, + optionStackArg, optionTimeDate, optionTimeVal, + optionUnstackArg, optionVendorOption; +static tOptProc + doOptLoop_Limit, doOptOutput, doOptTimeout, doOptTrace, doUsageOpt; +#define VER_PROC optionPrintVersion + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/** + * Define the xml2ag Option Descriptions. + * This is an array of OPTION_CT entries, one for each + * option that the xml2ag program responds to. + */ +static tOptDesc optDesc[OPTION_CT] = { + { /* entry idx, value */ 0, 0, + /* equiv idx, value */ 0, 0, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 0, 0, + /* opt state flags */ THE_XML2AG_OPTION_FLAGS, 0, + /* last opt argumnt */ { NULL }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ NULL, + /* desc, NAME, name */ THE_XML2AG_OPTION_DESC, NULL, NULL, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 1, VALUE_OPT_OUTPUT, + /* equiv idx, value */ 1, VALUE_OPT_OUTPUT, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ OUTPUT_FLAGS, 0, + /* last opt argumnt */ { NULL }, /* --output */ + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ doOptOutput, + /* desc, NAME, name */ OUTPUT_DESC, OUTPUT_NAME, OUTPUT_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 0, 0, + /* equiv idx, value */ 0, 0, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 0, 0, + /* opt state flags */ AUTOGEN_OPTIONS_FLAGS, 0, + /* last opt argumnt */ { NULL }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ NULL, + /* desc, NAME, name */ AUTOGEN_OPTIONS_DESC, NULL, NULL, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 3, VALUE_OPT_TEMPL_DIRS, + /* equiv idx, value */ 3, VALUE_OPT_TEMPL_DIRS, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, NOLIMIT, 0, + /* opt state flags */ TEMPL_DIRS_FLAGS, 0, + /* last opt argumnt */ { NULL }, /* --templ-dirs */ + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ optionStackArg, + /* desc, NAME, name */ TEMPL_DIRS_DESC, TEMPL_DIRS_NAME, TEMPL_DIRS_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 4, VALUE_OPT_OVERRIDE_TPL, + /* equiv idx, value */ 4, VALUE_OPT_OVERRIDE_TPL, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ OVERRIDE_TPL_FLAGS, 0, + /* last opt argumnt */ { NULL }, /* --override-tpl */ + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ NULL, + /* desc, NAME, name */ OVERRIDE_TPL_DESC, OVERRIDE_TPL_NAME, OVERRIDE_TPL_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 5, VALUE_OPT_DEFINITIONS, + /* equiv idx, value */ 5, VALUE_OPT_DEFINITIONS, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ DEFINITIONS_FLAGS, 0, + /* last opt argumnt */ { NULL }, /* --definitions */ + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ NULL, + /* desc, NAME, name */ DEFINITIONS_DESC, DEFINITIONS_NAME, DEFINITIONS_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 6, VALUE_OPT_SHELL, + /* equiv idx, value */ 6, VALUE_OPT_SHELL, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ SHELL_FLAGS, 0, + /* last opt argumnt */ { NULL }, /* --shell */ + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ NULL, + /* desc, NAME, name */ SHELL_DESC, SHELL_NAME, SHELL_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 7, VALUE_OPT_NO_FMEMOPEN, + /* equiv idx, value */ 7, VALUE_OPT_NO_FMEMOPEN, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ NO_FMEMOPEN_FLAGS, 0, + /* last opt argumnt */ { NULL }, /* --no-fmemopen */ + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ NULL, + /* desc, NAME, name */ NO_FMEMOPEN_DESC, NO_FMEMOPEN_NAME, NO_FMEMOPEN_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 8, VALUE_OPT_EQUATE, + /* equiv idx, value */ 8, VALUE_OPT_EQUATE, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ EQUATE_FLAGS, 0, + /* last opt argumnt */ { NULL }, /* --equate */ + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ NULL, + /* desc, NAME, name */ EQUATE_DESC, EQUATE_NAME, EQUATE_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 9, VALUE_OPT_BASE_NAME, + /* equiv idx, value */ 9, VALUE_OPT_BASE_NAME, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ BASE_NAME_FLAGS, 0, + /* last opt argumnt */ { NULL }, /* --base-name */ + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ NULL, + /* desc, NAME, name */ BASE_NAME_DESC, BASE_NAME_NAME, BASE_NAME_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 10, VALUE_OPT_SOURCE_TIME, + /* equiv idx, value */ 10, VALUE_OPT_SOURCE_TIME, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ SOURCE_TIME_FLAGS, 0, + /* last opt argumnt */ { NULL }, /* --source-time */ + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ NULL, + /* desc, NAME, name */ SOURCE_TIME_DESC, SOURCE_TIME_NAME, SOURCE_TIME_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 11, VALUE_OPT_WRITABLE, + /* equiv idx, value */ 11, VALUE_OPT_WRITABLE, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ WRITABLE_FLAGS, 0, + /* last opt argumnt */ { NULL }, /* --writable */ + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ NULL, + /* desc, NAME, name */ WRITABLE_DESC, WRITABLE_NAME, WRITABLE_name, + /* disablement strs */ NOT_WRITABLE_name, NOT_WRITABLE_PFX }, + + { /* entry idx, value */ 12, VALUE_OPT_LOOP_LIMIT, + /* equiv idx, value */ 12, VALUE_OPT_LOOP_LIMIT, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ LOOP_LIMIT_FLAGS, 0, + /* last opt argumnt */ { LOOP_LIMIT_DFT_ARG }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ doOptLoop_Limit, + /* desc, NAME, name */ LOOP_LIMIT_DESC, LOOP_LIMIT_NAME, LOOP_LIMIT_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 13, VALUE_OPT_TIMEOUT, + /* equiv idx, value */ 13, VALUE_OPT_TIMEOUT, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ TIMEOUT_FLAGS, 0, + /* last opt argumnt */ { NULL }, /* --timeout */ + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ doOptTimeout, + /* desc, NAME, name */ TIMEOUT_DESC, TIMEOUT_NAME, TIMEOUT_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 14, VALUE_OPT_TRACE, + /* equiv idx, value */ 14, VALUE_OPT_TRACE, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ TRACE_FLAGS, 0, + /* last opt argumnt */ { TRACE_DFT_ARG }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ doOptTrace, + /* desc, NAME, name */ TRACE_DESC, TRACE_NAME, TRACE_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 15, VALUE_OPT_TRACE_OUT, + /* equiv idx, value */ 15, VALUE_OPT_TRACE_OUT, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ TRACE_OUT_FLAGS, 0, + /* last opt argumnt */ { NULL }, /* --trace-out */ + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ NULL, + /* desc, NAME, name */ TRACE_OUT_DESC, TRACE_OUT_NAME, TRACE_OUT_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 16, VALUE_OPT_SHOW_DEFS, + /* equiv idx, value */ 16, VALUE_OPT_SHOW_DEFS, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ SHOW_DEFS_FLAGS, 0, + /* last opt argumnt */ { NULL }, /* --show-defs */ + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ NULL, + /* desc, NAME, name */ SHOW_DEFS_DESC, SHOW_DEFS_NAME, SHOW_DEFS_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 17, VALUE_OPT_USED_DEFINES, + /* equiv idx, value */ 17, VALUE_OPT_USED_DEFINES, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ USED_DEFINES_FLAGS, 0, + /* last opt argumnt */ { NULL }, /* --used-defines */ + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ NULL, + /* desc, NAME, name */ USED_DEFINES_DESC, USED_DEFINES_NAME, USED_DEFINES_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 18, VALUE_OPT_CORE, + /* equiv idx, value */ 18, VALUE_OPT_CORE, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ CORE_FLAGS, 0, + /* last opt argumnt */ { NULL }, /* --core */ + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ NULL, + /* desc, NAME, name */ CORE_DESC, CORE_NAME, CORE_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 19, VALUE_OPT_SKIP_SUFFIX, + /* equiv idx, value */ 19, VALUE_OPT_SKIP_SUFFIX, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, NOLIMIT, 0, + /* opt state flags */ SKIP_SUFFIX_FLAGS, 0, + /* last opt argumnt */ { NULL }, /* --skip-suffix */ + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, aSkip_SuffixCantList, + /* option proc */ optionStackArg, + /* desc, NAME, name */ SKIP_SUFFIX_DESC, SKIP_SUFFIX_NAME, SKIP_SUFFIX_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 20, VALUE_OPT_SELECT_SUFFIX, + /* equiv idx, value */ 20, VALUE_OPT_SELECT_SUFFIX, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, NOLIMIT, 0, + /* opt state flags */ SELECT_SUFFIX_FLAGS, 0, + /* last opt argumnt */ { NULL }, /* --select-suffix */ + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ optionStackArg, + /* desc, NAME, name */ SELECT_SUFFIX_DESC, SELECT_SUFFIX_NAME, SELECT_SUFFIX_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 21, VALUE_OPT_DEFINE, + /* equiv idx, value */ 21, VALUE_OPT_DEFINE, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, NOLIMIT, 0, + /* opt state flags */ DEFINE_FLAGS, 0, + /* last opt argumnt */ { NULL }, /* --define */ + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ optionStackArg, + /* desc, NAME, name */ DEFINE_DESC, DEFINE_NAME, DEFINE_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 22, VALUE_OPT_UNDEFINE, + /* equiv idx, value */ NOLIMIT, NOLIMIT, + /* equivalenced to */ INDEX_OPT_DEFINE, + /* min, max, act ct */ 0, NOLIMIT, 0, + /* opt state flags */ UNDEFINE_FLAGS, 0, + /* last opt argumnt */ { NULL }, /* --undefine */ + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ optionUnstackArg, + /* desc, NAME, name */ UNDEFINE_DESC, UNDEFINE_NAME, UNDEFINE_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 23, VALUE_OPT_MAKE_DEP, + /* equiv idx, value */ 23, VALUE_OPT_MAKE_DEP, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, NOLIMIT, 0, + /* opt state flags */ MAKE_DEP_FLAGS, 0, + /* last opt argumnt */ { NULL }, /* --make-dep */ + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ NULL, + /* desc, NAME, name */ MAKE_DEP_DESC, MAKE_DEP_NAME, MAKE_DEP_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ INDEX_OPT_VERSION, VALUE_OPT_VERSION, + /* equiv idx value */ NO_EQUIVALENT, VALUE_OPT_VERSION, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ VER_FLAGS, AOUSE_VERSION, + /* last opt argumnt */ { NULL }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ VER_PROC, + /* desc, NAME, name */ VER_DESC, NULL, VER_name, + /* disablement strs */ NULL, NULL }, + + + + { /* entry idx, value */ INDEX_OPT_HELP, VALUE_OPT_HELP, + /* equiv idx value */ NO_EQUIVALENT, VALUE_OPT_HELP, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ OPTST_IMM | OPTST_NO_INIT, AOUSE_HELP, + /* last opt argumnt */ { NULL }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ doUsageOpt, + /* desc, NAME, name */ HELP_DESC, NULL, HELP_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ INDEX_OPT_MORE_HELP, VALUE_OPT_MORE_HELP, + /* equiv idx value */ NO_EQUIVALENT, VALUE_OPT_MORE_HELP, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ MORE_HELP_FLAGS, AOUSE_MORE_HELP, + /* last opt argumnt */ { NULL }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ optionPagedUsage, + /* desc, NAME, name */ MORE_HELP_DESC, NULL, MORE_HELP_name, + /* disablement strs */ NULL, NULL } +}; + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/** Reference to the upper cased version of xml2ag. */ +#define zPROGNAME (xml2ag_opt_strs+2197) +/** Reference to the title line for xml2ag usage. */ +#define zUsageTitle (xml2ag_opt_strs+2204) +/** There is no xml2ag configuration file. */ +#define zRcName NULL +/** There are no directories to search for xml2ag config files. */ +#define apzHomeList NULL +/** The xml2ag program bug email address. */ +#define zBugsAddr (xml2ag_opt_strs+2350) +/** Clarification/explanation of what xml2ag does. */ +#define zExplain (xml2ag_opt_strs+2386) +/** Extra detail explaining what xml2ag does. */ +#define zDetail (xml2ag_opt_strs+2493) +/** The full version string for xml2ag. */ +#define zFullVersion (xml2ag_opt_strs+2762) +/* extracted from optcode.tlib near line 342 */ + +#define OPTPROC_BASE OPTPROC_NONE +#define translate_option_strings NULL + +#define xml2ag_full_usage (NULL) +#define xml2ag_short_usage (NULL) + +#endif /* not defined __doxygen__ */ + +/* + * Create the static procedure(s) declared above. + */ +/** + * The callout function that invokes the optionUsage function. + * + * @param[in] opts the AutoOpts option description structure + * @param[in] od the descriptor for the "help" (usage) option. + * @noreturn + */ +static void +doUsageOpt(tOptions * opts, tOptDesc * od) +{ + int ex_code; + ex_code = XML2AG_EXIT_SUCCESS; + optionUsage(&xml2agOptions, ex_code); + /* NOTREACHED */ + exit(XML2AG_EXIT_FAILURE); + (void)opts; + (void)od; +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/** + * Code to handle the output option. + * By default, the output is handed to an AutoGen for processing. + * However, you may save the definitions to a file instead. + * @param[in] pOptions the xml2ag options data structure + * @param[in,out] pOptDesc the option descriptor for this option. + */ +static void +doOptOutput(tOptions* pOptions, tOptDesc* pOptDesc) +{ + /* + * Be sure the flag-code[0] handles special values for the options pointer + * viz. (poptions <= OPTPROC_EMIT_LIMIT) *and also* the special flag bit + * ((poptdesc->fOptState & OPTST_RESET) != 0) telling the option to + * reset its state. + */ + /* extracted from xmlopts.def, line 70 */ + if (strcmp(pOptDesc->optArg.argString, "-") == 0) + return; + + if (freopen(pOptDesc->optArg.argString, "w", stdout) == NULL) { + fprintf(stderr, "Error %d (%s) opening `%s' for output", + errno, strerror(errno), pOptDesc->optArg.argString); + exit(EXIT_FAILURE); + } + (void)pOptions; +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/** + * Code to handle the loop-limit option. + * Pass-through AutoGen argument + * @param[in] pOptions the xml2ag options data structure + * @param[in,out] pOptDesc the option descriptor for this option. + */ +static void +doOptLoop_Limit(tOptions* pOptions, tOptDesc* pOptDesc) +{ + static struct {long rmin, rmax;} const rng[2] = { + { -1, LONG_MIN }, { 1, 0x1000000 } }; + int ix; + + if (pOptions <= OPTPROC_EMIT_LIMIT) + goto emit_ranges; + optionNumericVal(pOptions, pOptDesc); + + for (ix = 0; ix < 2; ix++) { + if (pOptDesc->optArg.argInt < rng[ix].rmin) + continue; /* ranges need not be ordered. */ + if (pOptDesc->optArg.argInt == rng[ix].rmin) + return; + if (rng[ix].rmax == LONG_MIN) + continue; + if (pOptDesc->optArg.argInt <= rng[ix].rmax) + return; + } + + option_usage_fp = stderr; + + emit_ranges: +optionShowRange(pOptions, pOptDesc, VOIDP(rng), 2); +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/** + * Code to handle the timeout option. + * Pass-through AutoGen argument + * @param[in] pOptions the xml2ag options data structure + * @param[in,out] pOptDesc the option descriptor for this option. + */ +static void +doOptTimeout(tOptions* pOptions, tOptDesc* pOptDesc) +{ + static struct {long rmin, rmax;} const rng[1] = { + { 0, 3600 } }; + int ix; + + if (pOptions <= OPTPROC_EMIT_LIMIT) + goto emit_ranges; + optionNumericVal(pOptions, pOptDesc); + + for (ix = 0; ix < 1; ix++) { + if (pOptDesc->optArg.argInt < rng[ix].rmin) + continue; /* ranges need not be ordered. */ + if (pOptDesc->optArg.argInt == rng[ix].rmin) + return; + if (rng[ix].rmax == LONG_MIN) + continue; + if (pOptDesc->optArg.argInt <= rng[ix].rmax) + return; + } + + option_usage_fp = stderr; + + emit_ranges: +optionShowRange(pOptions, pOptDesc, VOIDP(rng), 1); +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/** + * Code to handle the trace option. + * Pass-through AutoGen argument + * @param[in] pOptions the xml2ag options data structure + * @param[in,out] pOptDesc the option descriptor for this option. + */ +static void +doOptTrace(tOptions* pOptions, tOptDesc* pOptDesc) +{ + +/* extracted from optmain.tlib near line 945 */ + static char const * const names[7] = { + xml2ag_opt_strs+2791, xml2ag_opt_strs+2799, xml2ag_opt_strs+2813, + xml2ag_opt_strs+2826, xml2ag_opt_strs+2836, xml2ag_opt_strs+2849, + xml2ag_opt_strs+2861 }; + + if (pOptions <= OPTPROC_EMIT_LIMIT) { + (void) optionEnumerationVal(pOptions, pOptDesc, names, 7); + return; /* protect AutoOpts client code from internal callbacks */ + } + + pOptDesc->optArg.argEnum = + optionEnumerationVal(pOptions, pOptDesc, names, 7); +} +/* extracted from optmain.tlib near line 1250 */ + +/** + * The directory containing the data associated with xml2ag. + */ +#ifndef PKGDATADIR +# define PKGDATADIR "" +#endif + +/** + * Information about the person or institution that packaged xml2ag + * for the current distribution. + */ +#ifndef WITH_PACKAGER +# define xml2ag_packager_info NULL +#else +/** Packager information for xml2ag. */ +static char const xml2ag_packager_info[] = + "Packaged by " WITH_PACKAGER + +# ifdef WITH_PACKAGER_VERSION + " ("WITH_PACKAGER_VERSION")" +# endif + +# ifdef WITH_PACKAGER_BUG_REPORTS + "\nReport xml2ag bugs to " WITH_PACKAGER_BUG_REPORTS +# endif + "\n"; +#endif +#ifndef __doxygen__ + +#endif /* __doxygen__ */ +/** + * The option definitions for xml2ag. The one structure that + * binds them all. + */ +tOptions xml2agOptions = { + OPTIONS_STRUCT_VERSION, + 0, NULL, /* original argc + argv */ + ( OPTPROC_BASE + + OPTPROC_ERRSTOP + + OPTPROC_SHORTOPT + + OPTPROC_LONGOPT + + OPTPROC_NO_REQ_OPT + + OPTPROC_NEGATIONS ), + 0, NULL, /* current option index, current option */ + NULL, NULL, zPROGNAME, + zRcName, zCopyright, zLicenseDescrip, + zFullVersion, apzHomeList, zUsageTitle, + zExplain, zDetail, optDesc, + zBugsAddr, /* address to send bugs to */ + NULL, NULL, /* extensions/saved state */ + optionUsage, /* usage procedure */ + translate_option_strings, /* translation procedure */ + /* + * Indexes to special options + */ + { INDEX_OPT_MORE_HELP, /* more-help option index */ + NO_EQUIVALENT, /* save option index */ + NO_EQUIVALENT, /* '-#' option index */ + NO_EQUIVALENT /* index of default opt */ + }, + 27 /* full option count */, 24 /* user option count */, + xml2ag_full_usage, xml2ag_short_usage, + NULL, NULL, + PKGDATADIR, xml2ag_packager_info +}; + +#ifdef __cplusplus +} +#endif +/** @} */ +/* xmlopts.c ends here */ diff --git a/xml2ag/xmlopts.def b/xml2ag/xmlopts.def new file mode 100644 index 0000000..b2e6a9c --- /dev/null +++ b/xml2ag/xmlopts.def @@ -0,0 +1,180 @@ +/* -*- Mode: conf -*- */ + +autogen definitions options; +addtogroup = xml2ag; + +/* xmlopts.def: option definitions for xml2ag + * + * This file is part of AutoGen. + * AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoGen 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. + * + * AutoGen is distributed in the hope that 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 . + */ +export = <<- EOExport + #include + #include + + #ifndef __USE_POSIX + # define __USE_POSIX /* for glib's pedantic needs */ + #endif + #ifndef __USE_XOPEN_EXTENDED + # define __USE_XOPEN_EXTENDED /* ditto */ + #endif + #include + #include + #include + #include + #include + #include + #include + #include + + #include + #include + + extern FILE * ag_pipe_fp; + #ifndef NUL + # define NUL '\0' + #endif + extern void fork_ag(char const * pzInput); + EOExport; + +flag = { + name = the-xml2ag-option; + documentation; + descrip = 'All other options are derived from autogen'; +}; + +flag = { + name = output; + value = O; + arg-type = string; + arg-name = file; + descrip = "Output file in lieu of AutoGen processing"; + doc = + "By default, the output is handed to an AutoGen for processing.\n" + "However, you may save the definitions to a file instead."; + + flag_code = <<- FLAG_CODE_END + if (strcmp(pOptDesc->optArg.argString, "-") == 0) + return; + + if (freopen(pOptDesc->optArg.argString, "w", stdout) == NULL) { + fprintf(stderr, "Error %d (%s) opening `%s' for output", + errno, strerror(errno), pOptDesc->optArg.argString); + exit(EXIT_FAILURE); + } + FLAG_CODE_END ; +}; + +flag = { + name = autogen-options; + documentation = <<- _EODoc_ + These options are @i{mostly} just passed throug to @code{autogen}. + The one exception is @code{--override-tpl} which replaces the + default template in the output definitions. It does not get passed + through on the command line. + _EODoc_; + + descrip = 'All other options'; +}; + +#define XML2AG +#option templ-dir $top_srcdir/agen5 +#option templ-dir $top_srcdir/autoopts +#include opts.def + +explain = <<- END_EXPLAIN + This program will convert any arbitrary XML file into equivalent + AutoGen definitions, and invoke AutoGen. + END_EXPLAIN ; + +detail = <<- END_DETAIL + The template will be derived from either: + * the ``--override-tpl'' command line option + * a top level XML attribute named, "template" + + The ``base-name'' for the output will similarly be either: + * the ``--base-name'' command line option + * the base name of the .xml file + END_DETAIL ; + +prog-man-descrip = <<- END_DETAIL + The template will be derived from either: + .br + * the \fB--override-tpl\fP command line option + .br + * a top level XML attribute named, "template" + .br + One or the other \fBmust\fP be provided, or the program will + exit with a failure message. + .sp 1 + The ``base-name'' for the output will similarly be either: + .br + * the \fB--base-name\fP command line option + .br + * the base name of the .xml file + END_DETAIL ; + +prog-info-descrip = <<- END_DETAIL + The template used will be derived from either: + @itemize @bullet + @item + The @strong{--override-tpl} command line option + @item + A top level XML attribute named, "@code{template}" + @end itemize + @noindent + One or the other @strong{must} be provided, or the program will + exit with a failure message. + + The @emph{base-name} for the output will similarly be either: + @itemize @bullet + @item + The @strong{--base-name} command line option. + @item + The base name of the @file{.xml} file. + @end itemize + + The definitions derived from XML generally have an extra layer + of definition. Specifically, this XML input: + @example + + mumble-1 + + grumble, grumble, grumble. + mumble, mumble + + @end example + Will get converted into this: + @example + mumble = @{ + grumble = @{ + text = 'grumble, grumble, grumble'; + @}; + text = 'mumble-1'; + text = 'mumble, mumble'; + @}; + @end example + Please notice that some information is lost. AutoGen cannot tell that + "grumble" used to lie between the mumble texts. Also please note that + you cannot assign: + @example + grumble = 'grumble, grumble, grumble.'; + @end example + because if another "grumble" has an attribute or multiple texts, + it becomes impossible to have the definitions be the same type + (compound or text values). + END_DETAIL ; +/* end of xmlopts.def */