Index: ext/libicpf/AUTHORS =================================================================== diff -u -N --- ext/libicpf/AUTHORS (revision 0) +++ ext/libicpf/AUTHORS (revision e17c80d36eaa0430313e7d1058aa7a301d1510af) @@ -0,0 +1 @@ +Józef Starosczyk Index: ext/libicpf/COPYING =================================================================== diff -u -N --- ext/libicpf/COPYING (revision 0) +++ ext/libicpf/COPYING (revision e17c80d36eaa0430313e7d1058aa7a301d1510af) @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) 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 +this service 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 make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. 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. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute 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 and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the 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 a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, 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. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE 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. + + 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 +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision 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, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This 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 Library General +Public License instead of this License. Index: ext/libicpf/COPYING.LIB =================================================================== diff -u -N --- ext/libicpf/COPYING.LIB (revision 0) +++ ext/libicpf/COPYING.LIB (revision e17c80d36eaa0430313e7d1058aa7a301d1510af) @@ -0,0 +1,481 @@ + GNU LIBRARY GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1991 Free Software Foundation, Inc. + 59 Temple Place - Suite 330 + Boston, MA 02111-1307, USA. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the library GPL. It is + numbered 2 because it goes with version 2 of the ordinary GPL.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Library General Public License, applies to some +specially designated Free Software Foundation software, and to any +other libraries whose authors decide to use it. You can use it for +your libraries, 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 +this service 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 make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if +you distribute copies of the library, or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link a program with the library, you must provide +complete object files to the recipients so that they can relink them +with the library, after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + Our method of protecting your rights has two steps: (1) copyright +the library, and (2) offer you this license which gives you legal +permission to copy, distribute and/or modify the library. + + Also, for each distributor's protection, we want to make certain +that everyone understands that there is no warranty for this free +library. If the library is modified by someone else and passed on, we +want its recipients to know that what they have is not the original +version, so that any problems introduced by others will not reflect on +the original authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that companies distributing free +software will individually obtain patent licenses, thus in effect +transforming the program into proprietary software. To prevent this, +we have made it clear that any patent must be licensed for everyone's +free use or not licensed at all. + + Most GNU software, including some libraries, is covered by the ordinary +GNU General Public License, which was designed for utility programs. This +license, the GNU Library General Public License, applies to certain +designated libraries. This license is quite different from the ordinary +one; be sure to read it in full, and don't assume that anything in it is +the same as in the ordinary license. + + The reason we have a separate public license for some libraries is that +they blur the distinction we usually make between modifying or adding to a +program and simply using it. Linking a program with a library, without +changing the library, is in some sense simply using the library, and is +analogous to running a utility program or application program. However, in +a textual and legal sense, the linked executable is a combined work, a +derivative of the original library, and the ordinary General Public License +treats it as such. + + Because of this blurred distinction, using the ordinary General +Public License for libraries did not effectively promote software +sharing, because most developers did not use the libraries. We +concluded that weaker conditions might promote sharing better. + + However, unrestricted linking of non-free programs would deprive the +users of those programs of all benefit from the free status of the +libraries themselves. This Library General Public License is intended to +permit developers of non-free programs to use free libraries, while +preserving your freedom as a user of such programs to change the free +libraries that are incorporated in them. (We have not seen how to achieve +this as regards changes in header files, but we have achieved it as regards +changes in the actual functions of the Library.) The hope is that this +will lead to faster development of free libraries. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, while the latter only +works together with the library. + + Note that it is possible for a library to be covered by the ordinary +General Public License rather than by this special one. + + GNU LIBRARY GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library which +contains a notice placed by the copyright holder or other authorized +party saying it may be distributed under the terms of this Library +General Public License (also called "this License"). Each licensee is +addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also compile or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + c) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + d) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the source code distributed need not include anything that is normally +distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Library General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! Index: ext/libicpf/ChangeLog =================================================================== diff -u -N --- ext/libicpf/ChangeLog (revision 0) +++ ext/libicpf/ChangeLog (revision e17c80d36eaa0430313e7d1058aa7a301d1510af) @@ -0,0 +1 @@ \ No newline at end of file Index: ext/libicpf/Doxyfile =================================================================== diff -u -N --- ext/libicpf/Doxyfile (revision 0) +++ ext/libicpf/Doxyfile (revision e17c80d36eaa0430313e7d1058aa7a301d1510af) @@ -0,0 +1,275 @@ +# Doxyfile 1.4.1-KDevelop + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- +PROJECT_NAME = libicpf +PROJECT_NUMBER = 0.1 +OUTPUT_DIRECTORY = +CREATE_SUBDIRS = NO +OUTPUT_LANGUAGE = English +USE_WINDOWS_ENCODING = NO +BRIEF_MEMBER_DESC = YES +REPEAT_BRIEF = YES +ABBREVIATE_BRIEF = "The $name class" \ + "The $name widget" \ + "The $name file" \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the +ALWAYS_DETAILED_SEC = NO +INLINE_INHERITED_MEMB = NO +FULL_PATH_NAMES = YES +STRIP_FROM_PATH = /home/ixen/ +STRIP_FROM_INC_PATH = +SHORT_NAMES = NO +JAVADOC_AUTOBRIEF = NO +MULTILINE_CPP_IS_BRIEF = NO +DETAILS_AT_TOP = YES +INHERIT_DOCS = YES +DISTRIBUTE_GROUP_DOC = NO +TAB_SIZE = 8 +ALIASES = +OPTIMIZE_OUTPUT_FOR_C = NO +OPTIMIZE_OUTPUT_JAVA = NO +SUBGROUPING = YES +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- +EXTRACT_ALL = NO +EXTRACT_PRIVATE = NO +EXTRACT_STATIC = NO +EXTRACT_LOCAL_CLASSES = YES +EXTRACT_LOCAL_METHODS = NO +HIDE_UNDOC_MEMBERS = NO +HIDE_UNDOC_CLASSES = NO +HIDE_FRIEND_COMPOUNDS = NO +HIDE_IN_BODY_DOCS = NO +INTERNAL_DOCS = NO +CASE_SENSE_NAMES = YES +HIDE_SCOPE_NAMES = NO +SHOW_INCLUDE_FILES = YES +INLINE_INFO = YES +SORT_MEMBER_DOCS = YES +SORT_BRIEF_DOCS = NO +SORT_BY_SCOPE_NAME = NO +GENERATE_TODOLIST = YES +GENERATE_TESTLIST = YES +GENERATE_BUGLIST = YES +GENERATE_DEPRECATEDLIST= YES +ENABLED_SECTIONS = +MAX_INITIALIZER_LINES = 30 +SHOW_USED_FILES = YES +SHOW_DIRECTORIES = YES +FILE_VERSION_FILTER = +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- +QUIET = NO +WARNINGS = YES +WARN_IF_UNDOCUMENTED = YES +WARN_IF_DOC_ERROR = YES +WARN_NO_PARAMDOC = NO +WARN_FORMAT = "$file:$line: $text" +WARN_LOGFILE = +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- +INPUT = src +FILE_PATTERNS = *.c \ + *.cc \ + *.cxx \ + *.cpp \ + *.c++ \ + *.java \ + *.ii \ + *.ixx \ + *.ipp \ + *.i++ \ + *.inl \ + *.h \ + *.hh \ + *.hxx \ + *.hpp \ + *.h++ \ + *.idl \ + *.odl \ + *.cs \ + *.php \ + *.php3 \ + *.inc \ + *.m \ + *.mm \ + *.C \ + *.CC \ + *.C++ \ + *.II \ + *.I++ \ + *.H \ + *.HH \ + *.H++ \ + *.CS \ + *.PHP \ + *.PHP3 \ + *.M \ + *.MM \ + *.C \ + *.H \ + *.tlh \ + *.diff \ + *.patch \ + *.moc \ + *.xpm \ + *.dox +RECURSIVE = YES +EXCLUDE = +EXCLUDE_SYMLINKS = NO +EXCLUDE_PATTERNS = +EXAMPLE_PATH = +EXAMPLE_PATTERNS = * +EXAMPLE_RECURSIVE = NO +IMAGE_PATH = +INPUT_FILTER = +FILTER_PATTERNS = +FILTER_SOURCE_FILES = NO +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- +SOURCE_BROWSER = NO +INLINE_SOURCES = NO +STRIP_CODE_COMMENTS = YES +REFERENCED_BY_RELATION = YES +REFERENCES_RELATION = YES +VERBATIM_HEADERS = YES +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- +ALPHABETICAL_INDEX = YES +COLS_IN_ALPHA_INDEX = 5 +IGNORE_PREFIX = +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- +GENERATE_HTML = YES +HTML_OUTPUT = html +HTML_FILE_EXTENSION = .html +HTML_HEADER = +HTML_FOOTER = +HTML_STYLESHEET = +HTML_ALIGN_MEMBERS = YES +GENERATE_HTMLHELP = NO +CHM_FILE = +HHC_LOCATION = +GENERATE_CHI = NO +BINARY_TOC = NO +TOC_EXPAND = NO +DISABLE_INDEX = NO +ENUM_VALUES_PER_LINE = 4 +GENERATE_TREEVIEW = NO +TREEVIEW_WIDTH = 250 +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- +GENERATE_LATEX = NO +LATEX_OUTPUT = latex +LATEX_CMD_NAME = latex +MAKEINDEX_CMD_NAME = makeindex +COMPACT_LATEX = NO +PAPER_TYPE = a4wide +EXTRA_PACKAGES = +LATEX_HEADER = +PDF_HYPERLINKS = NO +USE_PDFLATEX = NO +LATEX_BATCHMODE = NO +LATEX_HIDE_INDICES = NO +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- +GENERATE_RTF = NO +RTF_OUTPUT = rtf +COMPACT_RTF = NO +RTF_HYPERLINKS = NO +RTF_STYLESHEET_FILE = +RTF_EXTENSIONS_FILE = +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- +GENERATE_MAN = NO +MAN_OUTPUT = man +MAN_EXTENSION = .3 +MAN_LINKS = NO +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- +GENERATE_XML = NO +XML_OUTPUT = xml +XML_SCHEMA = +XML_DTD = +XML_PROGRAMLISTING = YES +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- +GENERATE_AUTOGEN_DEF = NO +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- +GENERATE_PERLMOD = NO +PERLMOD_LATEX = NO +PERLMOD_PRETTY = YES +PERLMOD_MAKEVAR_PREFIX = +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- +ENABLE_PREPROCESSING = YES +MACRO_EXPANSION = NO +EXPAND_ONLY_PREDEF = NO +SEARCH_INCLUDES = YES +INCLUDE_PATH = +INCLUDE_FILE_PATTERNS = +PREDEFINED = +EXPAND_AS_DEFINED = +SKIP_FUNCTION_MACROS = YES +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- +TAGFILES = +GENERATE_TAGFILE = libicpf.tag +ALLEXTERNALS = NO +EXTERNAL_GROUPS = YES +PERL_PATH = /usr/bin/perl +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- +CLASS_DIAGRAMS = YES +HIDE_UNDOC_RELATIONS = YES +HAVE_DOT = YES +CLASS_GRAPH = YES +COLLABORATION_GRAPH = YES +GROUP_GRAPHS = YES +UML_LOOK = NO +TEMPLATE_RELATIONS = YES +INCLUDE_GRAPH = YES +INCLUDED_BY_GRAPH = YES +CALL_GRAPH = NO +GRAPHICAL_HIERARCHY = YES +DIRECTORY_GRAPH = YES +DOT_IMAGE_FORMAT = png +DOT_PATH = /usr/bin +DOTFILE_DIRS = /usr/share/graphviz/graphs/directed/ \ + /usr/share/graphviz/graphs/undirected/ +MAX_DOT_GRAPH_WIDTH = 1024 +MAX_DOT_GRAPH_HEIGHT = 1024 +MAX_DOT_GRAPH_DEPTH = 1000 +DOT_TRANSPARENT = NO +DOT_MULTI_TARGETS = NO +GENERATE_LEGEND = YES +DOT_CLEANUP = YES +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- +SEARCHENGINE = NO Index: ext/libicpf/INSTALL =================================================================== diff -u -N --- ext/libicpf/INSTALL (revision 0) +++ ext/libicpf/INSTALL (revision e17c80d36eaa0430313e7d1058aa7a301d1510af) @@ -0,0 +1,167 @@ +Basic Installation +================== + + These are generic installation instructions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, a file +`config.cache' that saves the results of its tests to speed up +reconfiguring, and a file `config.log' containing compiler output +(useful mainly for debugging `configure'). + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If at some point `config.cache' +contains results you don't want to keep, you may remove or edit it. + + The file `configure.in' is used to create `configure' by a program +called `autoconf'. You only need `configure.in' if you want to change +it or regenerate `configure' using a newer version of `autoconf'. + +The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. If you're + using `csh' on an old version of System V, you might need to type + `sh ./configure' instead to prevent `csh' from trying to execute + `configure' itself. + + Running `configure' takes a while. While running, it prints some + messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Type `make install' to install the programs and any data files and + documentation. + + 4. You can remove the program binaries and object files from the + source code directory by typing `make clean'. + +Compilers and Options +===================== + + Some systems require unusual options for compilation or linking that +the `configure' script does not know about. You can give `configure' +initial values for variables by setting them in the environment. Using +a Bourne-compatible shell, you can do that on the command line like +this: + CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure + +Or on systems that have the `env' program, you can do it like this: + env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure + +Compiling For Multiple Architectures +==================================== + + You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you must use a version of `make' that +supports the `VPATH' variable, such as GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. + + If you have to use a `make' that does not supports the `VPATH' +variable, you have to compile the package for one architecture at a time +in the source code directory. After you have installed the package for +one architecture, use `make distclean' before reconfiguring for another +architecture. + +Installation Names +================== + + By default, `make install' will install the package's files in +`/usr/local/bin', `/usr/local/man', etc. You can specify an +installation prefix other than `/usr/local' by giving `configure' the +option `--prefix=PATH'. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +give `configure' the option `--exec-prefix=PATH', the package will use +PATH as the prefix for installing programs and libraries. +Documentation and other data files will still use the regular prefix. + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + +Optional Features +================= + + Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + +Specifying the System Type +========================== + + There may be some features `configure' can not figure out +automatically, but needs to determine by the type of host the package +will run on. Usually `configure' can figure that out, but if it prints +a message saying it can not guess the host type, give it the +`--host=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name with three fields: + CPU-COMPANY-SYSTEM + +See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the host type. + + If you are building compiler tools for cross-compiling, you can also +use the `--target=TYPE' option to select the type of system they will +produce code for and the `--build=TYPE' option to select the type of +system on which you are compiling the package. + +Sharing Defaults +================ + + If you want to set default values for `configure' scripts to share, +you can create a site shell script called `config.site' that gives +default values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Operation Controls +================== + + `configure' recognizes the following options to control how it +operates. + +`--cache-file=FILE' + Use and save the results of the tests in FILE instead of + `./config.cache'. Set FILE to `/dev/null' to disable caching, for + debugging `configure'. + +`--help' + Print a summary of the options to `configure', and exit. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`--version' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`configure' also accepts some other, not widely useful, options. + Index: ext/libicpf/Makefile.am =================================================================== diff -u -N --- ext/libicpf/Makefile.am (revision 0) +++ ext/libicpf/Makefile.am (revision e17c80d36eaa0430313e7d1058aa7a301d1510af) @@ -0,0 +1,5 @@ +# not a GNU package. You can remove this line, if +# have all needed files, that a GNU package needs +AUTOMAKE_OPTIONS = foreign 1.4 + +SUBDIRS = src Index: ext/libicpf/Makefile.cvs =================================================================== diff -u -N --- ext/libicpf/Makefile.cvs (revision 0) +++ ext/libicpf/Makefile.cvs (revision e17c80d36eaa0430313e7d1058aa7a301d1510af) @@ -0,0 +1,8 @@ +default: all + +all: + aclocal + autoheader + automake + autoconf + Index: ext/libicpf/NEWS =================================================================== diff -u -N --- ext/libicpf/NEWS (revision 0) +++ ext/libicpf/NEWS (revision e17c80d36eaa0430313e7d1058aa7a301d1510af) @@ -0,0 +1 @@ + \ No newline at end of file Index: ext/libicpf/README =================================================================== diff -u -N --- ext/libicpf/README (revision 0) +++ ext/libicpf/README (revision e17c80d36eaa0430313e7d1058aa7a301d1510af) @@ -0,0 +1 @@ + Index: ext/libicpf/TODO =================================================================== diff -u -N --- ext/libicpf/TODO (revision 0) +++ ext/libicpf/TODO (revision e17c80d36eaa0430313e7d1058aa7a301d1510af) @@ -0,0 +1 @@ \ No newline at end of file Index: ext/libicpf/config.guess =================================================================== diff -u -N --- ext/libicpf/config.guess (revision 0) +++ ext/libicpf/config.guess (revision e17c80d36eaa0430313e7d1058aa7a301d1510af) @@ -0,0 +1,1363 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002 Free Software Foundation, Inc. + +timestamp='2002-10-21' + +# 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 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# 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 Per Bothner . +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# The plan is that this can be called by configure scripts if you +# don't specify an explicit build system type. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -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 (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +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 0 ;; + --version | -v ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # 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. + +# This shell variable is my proudest work .. or something. --bje + +set_cc_for_build='tmpdir=${TMPDIR-/tmp}/config-guess-$$ ; +(old=`umask` && umask 077 && mkdir $tmpdir && umask $old && unset old) + || (echo "$me: cannot create $tmpdir" >&2 && exit 1) ; +dummy=$tmpdir/dummy ; +files="$dummy.c $dummy.o $dummy.rel $dummy" ; +trap '"'"'rm -f $files; rmdir $tmpdir; exit 1'"'"' 1 2 15 ; +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 ; + rm -f $files ; + 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 ; +unset files' + +# 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 + +# 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 tupples: *-*-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=`(/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 ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep __ELF__ >/dev/null + 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 + # The OS release + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit 0 ;; + amiga:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + arc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + hp300:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mac68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + macppc:OpenBSD:*:*) + echo powerpc-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme88k:OpenBSD:*:*) + echo m88k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvmeppc:OpenBSD:*:*) + echo powerpc-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + pmax:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sgi:OpenBSD:*:*) + echo mipseb-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sun3:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + wgrisc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + *:OpenBSD:*:*) + echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + alpha:OSF1:*:*) + if test $UNAME_RELEASE = "V4.0"; then + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + fi + # 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. + eval $set_cc_for_build + cat <$dummy.s + .data +\$Lformat: + .byte 37,100,45,37,120,10,0 # "%d-%x\n" + + .text + .globl main + .align 4 + .ent main +main: + .frame \$30,16,\$26,0 + ldgp \$29,0(\$27) + .prologue 1 + .long 0x47e03d80 # implver \$0 + lda \$2,-1 + .long 0x47e20c21 # amask \$2,\$1 + lda \$16,\$Lformat + mov \$0,\$17 + not \$1,\$18 + jsr \$26,printf + ldgp \$29,0(\$26) + mov 0,\$16 + jsr \$26,exit + .end main +EOF + $CC_FOR_BUILD -o $dummy $dummy.s 2>/dev/null + if test "$?" = 0 ; then + case `$dummy` in + 0-0) + UNAME_MACHINE="alpha" + ;; + 1-0) + UNAME_MACHINE="alphaev5" + ;; + 1-1) + UNAME_MACHINE="alphaev56" + ;; + 1-101) + UNAME_MACHINE="alphapca56" + ;; + 2-303) + UNAME_MACHINE="alphaev6" + ;; + 2-307) + UNAME_MACHINE="alphaev67" + ;; + 2-1307) + UNAME_MACHINE="alphaev68" + ;; + 3-1307) + UNAME_MACHINE="alphaev7" + ;; + esac + fi + rm -f $dummy.s $dummy && rmdir $tmpdir + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + exit 0 ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit 0 ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit 0 ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit 0;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit 0 ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit 0 ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit 0 ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit 0;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit 0;; + 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 0 ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit 0 ;; + DRS?6000:UNIX_SV:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7 && exit 0 ;; + esac ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + i86pc:SunOS:5.*:*) + echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + 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 0 ;; + 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 0 ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit 0 ;; + 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 0 ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit 0 ;; + # 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 0 ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit 0 ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit 0 ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit 0 ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit 0 ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit 0 ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit 0 ;; + 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 \ + && $dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ + && rm -f $dummy.c $dummy && rmdir $tmpdir && exit 0 + rm -f $dummy.c $dummy && rmdir $tmpdir + echo mips-mips-riscos${UNAME_RELEASE} + exit 0 ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit 0 ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit 0 ;; + Night_Hawk:*:*:PowerMAX_OS) + echo powerpc-harris-powermax + exit 0 ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit 0 ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit 0 ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit 0 ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit 0 ;; + 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 0 ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit 0 ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit 0 ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit 0 ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit 0 ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit 0 ;; + ????????: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 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit 0 ;; + 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 0 ;; + *: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 + $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && rm -f $dummy.c $dummy && rmdir $tmpdir && exit 0 + rm -f $dummy.c $dummy && rmdir $tmpdir + echo rs6000-ibm-aix3.2.5 + 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 0 ;; + *:AIX:*:[45]) + 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/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit 0 ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit 0 ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit 0 ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit 0 ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit 0 ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit 0 ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit 0 ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit 0 ;; + 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` + if test -z "$HP_ARCH"; then HP_ARCH=hppa; fi + rm -f $dummy.c $dummy && rmdir $tmpdir + fi ;; + esac + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit 0 ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit 0 ;; + 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 && $dummy && rm -f $dummy.c $dummy && rmdir $tmpdir && exit 0 + rm -f $dummy.c $dummy && rmdir $tmpdir + echo unknown-hitachi-hiuxwe2 + exit 0 ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit 0 ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit 0 ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit 0 ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit 0 ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit 0 ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit 0 ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit 0 ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit 0 ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit 0 ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit 0 ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit 0 ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + 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 0 ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*T3D:*:*:*) + echo alpha-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + 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 0 ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit 0 ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:FreeBSD:*:*) + # Determine whether the default compiler uses glibc. + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + #if __GLIBC__ >= 2 + LIBC=gnu + #else + LIBC= + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` + rm -f $dummy.c && rmdir $tmpdir + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`${LIBC:+-$LIBC} + exit 0 ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit 0 ;; + i*:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit 0 ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit 0 ;; + x86:Interix*:3*) + echo i386-pc-interix3 + exit 0 ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i386-pc-interix + exit 0 ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit 0 ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit 0 ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + *:GNU:*:*) + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit 0 ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit 0 ;; + arm*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + mips:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips + #undef mipsel + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mipsel + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` + rm -f $dummy.c && rmdir $tmpdir + test x"${CPU}" != x && echo "${CPU}-pc-linux-gnu" && exit 0 + ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu + exit 0 ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit 0 ;; + 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 ld.so.1 >/dev/null + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit 0 ;; + 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-gnu ;; + PA8*) echo hppa2.0-unknown-linux-gnu ;; + *) echo hppa-unknown-linux-gnu ;; + esac + exit 0 ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit 0 ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit 0 ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + x86_64:Linux:*:*) + echo x86_64-unknown-linux-gnu + exit 0 ;; + i*86:Linux:*:*) + # The BFD linker knows what the default object file format is, so + # first see if it will tell us. cd to the root directory to prevent + # problems with other programs or directories called `ld' in the path. + # Set LC_ALL=C to ensure ld outputs messages in English. + ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ + | sed -ne '/supported targets:/!d + s/[ ][ ]*/ /g + s/.*supported targets: *// + s/ .*// + p'` + case "$ld_supported_targets" in + elf32-i386) + TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" + ;; + a.out-i386-linux) + echo "${UNAME_MACHINE}-pc-linux-gnuaout" + exit 0 ;; + coff-i386) + echo "${UNAME_MACHINE}-pc-linux-gnucoff" + exit 0 ;; + "") + # Either a pre-BFD a.out linker (linux-gnuoldld) or + # one that does not give us useful --help. + echo "${UNAME_MACHINE}-pc-linux-gnuoldld" + exit 0 ;; + esac + # Determine whether the default compiler is a.out or elf + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + #ifdef __ELF__ + # ifdef __GLIBC__ + # if __GLIBC__ >= 2 + LIBC=gnu + # else + LIBC=gnulibc1 + # endif + # else + LIBC=gnulibc1 + # endif + #else + #ifdef __INTEL_COMPILER + LIBC=gnu + #else + LIBC=gnuaout + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` + rm -f $dummy.c && rmdir $tmpdir + test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0 + test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0 + ;; + 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 0 ;; + 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 0 ;; + i*86:*:4.*:* | i*86:SYSTEM_V: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 0 ;; + i*86:*:5:[78]*) + 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 0 ;; + 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 0 ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit 0 ;; + 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 i386. + echo i386-pc-msdosdjgpp + exit 0 ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit 0 ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit 0 ;; + 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 0 ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit 0 ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit 0 ;; + M68*:*:R3V[567]*:*) + test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; + 3[34]??:*: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) + 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 0 + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4 && exit 0 ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit 0 ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit 0 ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + *: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 0 ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit 0 ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit 0 ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit 0 ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit 0 ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit 0 ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit 0 ;; + 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 0 ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit 0 ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit 0 ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit 0 ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit 0 ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit 0 ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit 0 ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Darwin:*:*) + echo `uname -p`-apple-darwin${UNAME_RELEASE} + exit 0 ;; + *: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 0 ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit 0 ;; + NSR-[DGKLNPTVW]:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit 0 ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit 0 ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit 0 ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit 0 ;; + *: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 0 ;; + 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 0 ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit 0 ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit 0 ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit 0 ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit 0 ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit 0 ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit 0 ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit 0 ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit 0 ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +eval $set_cc_for_build +cat >$dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && $dummy && rm -f $dummy.c $dummy && rmdir $tmpdir && exit 0 +rm -f $dummy.c $dummy && rmdir $tmpdir + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit 0 ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + c34*) + echo c34-convex-bsd + exit 0 ;; + c38*) + echo c38-convex-bsd + exit 0 ;; + c4*) + echo c4-convex-bsd + exit 0 ;; + esac +fi + +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +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` +/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 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: Index: ext/libicpf/config.sub =================================================================== diff -u -N --- ext/libicpf/config.sub (revision 0) +++ ext/libicpf/config.sub (revision e17c80d36eaa0430313e7d1058aa7a301d1510af) @@ -0,0 +1,1470 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002 Free Software Foundation, Inc. + +timestamp='2002-09-05' + +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# 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 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. + +# 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. + +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# 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. + +# 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 + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -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 (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +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 0 ;; + --version | -v ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # 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 0;; + + * ) + 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* | freebsd*-gnu* | storm-chaos* | os2-emx* | windows32-* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + 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) + os= + basic_machine=$1 + ;; + -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 + ;; + -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/'` + ;; + -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*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -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 \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ + | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | i370 | i860 | i960 | ia64 \ + | ip2k \ + | m32r | m68000 | m68k | m88k | mcore \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64vr | mips64vrel \ + | mips64orion | mips64orionel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mipsisa32 | mipsisa32el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | ns16k | ns32k \ + | openrisc | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ + | pyramid \ + | sh | sh[1234] | sh3e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \ + | strongarm \ + | tahoe | thumb | tic80 | tron \ + | v850 | v850e \ + | we32k \ + | x86 | xscale | xstormy16 | xtensa \ + | z8k) + basic_machine=$basic_machine-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12) + # Motorola 68HC11/12. + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + + # 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-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* \ + | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* \ + | clipper-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* \ + | m32r-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | mcore-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipstx39 | mipstx39el \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ + | pyramid-* \ + | romp-* | rs6000-* \ + | sh-* | sh[1234]-* | sh3e-* | sh[34]eb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \ + | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \ + | tahoe-* | thumb-* | tic30-* | tic4x-* | tic54x-* | tic80-* | tron-* \ + | v850-* | v850e-* | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \ + | xtensa-* \ + | ymp-* \ + | z8k-*) + ;; + # 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-unknown + 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 + ;; + 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 + ;; + 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 + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + 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 + ;; + crds | unos) + basic_machine=m68k-crds + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + 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 + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + 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 + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? + 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 + ;; + i386-vsta | 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 + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + 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 + ;; + mmix*) + basic_machine=mmix-knuth + os=-mmixware + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + 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 + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + or32 | or32-*) + basic_machine=or32-unknown + os=-coff + ;; + 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 + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2) + basic_machine=i686-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-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc) basic_machine=powerpc-unknown + ;; + ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + 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 | ppc64-le | powerpc64-little) + 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 + ;; + 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 + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sparclite-wrs | 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 + ;; + 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 + ;; + t3d) + basic_machine=alpha-cray + os=-unicos + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tic4x | c4x*) + basic_machine=tic4x-unknown + os=-coff + ;; + tic54x | c54x*) + basic_machine=tic54x-unknown + os=-coff + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + 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 + ;; + windows32) + basic_machine=i386-pc + os=-windows32-msvcrt + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + 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 + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh3 | sh4 | sh3eb | sh4eb | sh[1234]le | sh3ele) + basic_machine=sh-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparc | sparcv9 | sparcv9b) + basic_machine=sparc-sun + ;; + 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. + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First 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* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \ + | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* \ + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* | -powermax*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto*) + os=-nto-qnx + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -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 + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -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 + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -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 + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + # 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 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + m68*-cisco) + os=-aout + ;; + 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 + ;; + *-be) + os=-beos + ;; + *-ibm) + os=-aix + ;; + *-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 + ;; + *-next) + os=-nextstep3 + ;; + *-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 + ;; + -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 + ;; + -ptx*) + vendor=sequent + ;; + -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 0 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: Index: ext/libicpf/configure.ac =================================================================== diff -u -N --- ext/libicpf/configure.ac (revision 0) +++ ext/libicpf/configure.ac (revision e17c80d36eaa0430313e7d1058aa7a301d1510af) @@ -0,0 +1,46 @@ +AC_INIT(libicpf, 0.1alpha, ixen2@o2.pl) +AC_CONFIG_SRCDIR([config.h.in]) +AC_CONFIG_HEADER([config.h]) +AM_INIT_AUTOMAKE(libicpf, 0.1alpha) + +# Programs +AC_PROG_CXX +AC_PROG_CC +AC_PROG_CPP +AC_PROG_AWK +AC_PROG_INSTALL +AC_PROG_LN_S +AC_PROG_MAKE_SET +AC_PROG_RANLIB +AC_PROG_LIBTOOL + +# libraries +AC_CHECK_LIB([dl], [dlopen]) +AC_CHECK_LIB([pthread], [pthread_mutex_init]) + +# header files +AC_HEADER_DIRENT +AC_HEADER_STDC +AC_CHECK_HEADERS([fcntl.h stdlib.h string.h unistd.h utime.h wchar.h pthread.h]) + +# typedefs, structs, ... +AC_HEADER_STDBOOL +AC_C_CONST +AC_TYPE_UID_T +AC_C_INLINE +AC_TYPE_OFF_T +AC_TYPE_SIZE_T + +# library functions +AC_FUNC_CHOWN +AC_FUNC_CLOSEDIR_VOID +AC_FUNC_LSTAT +AC_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK +AC_FUNC_UTIME_NULL +AC_FUNC_VPRINTF +AC_CHECK_FUNCS([ftruncate memmove memset strchr strtoul utime]) + +AC_CONFIG_FILES([Makefile + src/Makefile]) + +AC_OUTPUT Index: ext/libicpf/depcomp =================================================================== diff -u -N --- ext/libicpf/depcomp (revision 0) +++ ext/libicpf/depcomp (revision e17c80d36eaa0430313e7d1058aa7a301d1510af) @@ -0,0 +1,441 @@ +#! /bin/sh + +# depcomp - compile a program generating dependencies as side-effects +# Copyright 1999, 2000 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# 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 . + +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 +# `libtool' can also be set to `yes' or `no'. + +depfile=${depfile-`echo "$object" | sed 's,\([^/]*\)$,.deps/\1,;s/\.\([^.]*\)$/.P\1/'`} +tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} + +rm -f "$tmpdepfile" + +# 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 + +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. + "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + mv "$tmpdepfile" "$depfile" + ;; + +gcc) +## 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). +## - 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 -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz +## 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. + tr ' ' ' +' < "$tmpdepfile" | +## 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. +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -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 -eq 0; then : + else + 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 ' ' ' +' < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ + tr ' +' ' ' >> $depfile + echo >> $depfile + + # The second pass generates a dummy entry for each header file. + tr ' ' ' +' < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ + >> $depfile + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +aix) + # The C for AIX Compiler uses -M and outputs the dependencies + # in a .u file. 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. + stripped=`echo "$object" | sed -e 's,^.*/,,' -e 's/\(.*\)\..*$/\1/'` + tmpdepfile="$stripped.u" + outname="$stripped.o" + if test "$libtool" = yes; then + "$@" -Wc,-M + else + "$@" -M + fi + + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + + if test -f "$tmpdepfile"; then + # Each line is of the form `foo.o: dependent.h'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile" + sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile" + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +icc) + # Must come before tru64. + + # Intel's C compiler understands `-MD -MF file'. However + # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c + # will fill foo.d with something like + # foo.o: sub/foo.c + # foo.o: sub/foo.h + # which is wrong. We want: + # sub/foo.o: sub/foo.c + # sub/foo.o: sub/foo.h + # sub/foo.c: + # sub/foo.h: + + "$@" -MD -MF "$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each line is of the form `foo.o: dependent.h'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed -e "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" + sed -e "s,^[^:]*: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile" + rm -f "$tmpdepfile" + ;; + +tru64) + # The Tru64 AIX 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. + + tmpdepfile1="$object.d" + tmpdepfile2=`echo "$object" | sed -e 's/.o$/.d/'` + if test "$libtool" = yes; then + "$@" -Wc,-MD + else + "$@" -MD + fi + + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" + exit $stat + fi + + if test -f "$tmpdepfile1"; then + tmpdepfile="$tmpdepfile1" + else + tmpdepfile="$tmpdepfile2" + fi + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" + # That's a space and a tab in the []. + sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" + else + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +#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 proprocessed file to stdout, regardless of -o, + # because we must use -o when running libtool. + test -z "$dashmflag" && dashmflag=-M + ( IFS=" " + case " $* " in + *" --mode=compile "*) # this is libtool, let us make it quiet + for arg + do # cycle over the arguments + case "$arg" in + "--mode=compile") + # insert --quiet before "--mode=compile" + set fnord "$@" --quiet + shift # fnord + ;; + esac + set fnord "$@" "$arg" + shift # fnord + shift # "$arg" + done + ;; + esac + "$@" $dashmflag | sed 's:^[^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" + ) & + proc=$! + "$@" + stat=$? + wait "$proc" + if test "$stat" != 0; then exit $stat; fi + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + tr ' ' ' +' < "$tmpdepfile" | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + 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) + # X makedepend + ( + shift + cleared=no + for arg in "$@"; do + case $cleared in no) + set ""; shift + cleared=yes + esac + case "$arg" in + -D*|-I*) + set fnord "$@" "$arg"; shift;; + -*) + ;; + *) + set fnord "$@" "$arg"; shift;; + esac + done + obj_suffix="`echo $object | sed 's/^.*\././'`" + touch "$tmpdepfile" + ${MAKEDEPEND-makedepend} 2>/dev/null -o"$obj_suffix" -f"$tmpdepfile" "$@" + ) & + proc=$! + "$@" + stat=$? + wait "$proc" + if test "$stat" != 0; then exit $stat; fi + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + tail +3 "$tmpdepfile" | tr ' ' ' +' | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + 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 proprocessed file to stdout, regardless of -o, + # because we must use -o when running libtool. + ( IFS=" " + case " $* " in + *" --mode=compile "*) + for arg + do # cycle over the arguments + case $arg in + "--mode=compile") + # insert --quiet before "--mode=compile" + set fnord "$@" --quiet + shift # fnord + ;; + esac + set fnord "$@" "$arg" + shift # fnord + shift # "$arg" + done + ;; + esac + "$@" -E | + sed -n '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | + sed '$ s: \\$::' > "$tmpdepfile" + ) & + proc=$! + "$@" + stat=$? + wait "$proc" + if test "$stat" != 0; then exit $stat; fi + 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 proprocessed file to stdout, regardless of -o, + # because we must use -o when running libtool. + ( IFS=" " + case " $* " in + *" --mode=compile "*) + for arg + do # cycle over the arguments + case $arg in + "--mode=compile") + # insert --quiet before "--mode=compile" + set fnord "$@" --quiet + shift # fnord + ;; + esac + set fnord "$@" "$arg" + shift # fnord + shift # "$arg" + done + ;; + esac + "$@" -E | + sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile" + ) & + proc=$! + "$@" + stat=$? + wait "$proc" + if test "$stat" != 0; then exit $stat; fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" + echo " " >> "$depfile" + . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +none) + exec "$@" + ;; + +*) + echo "Unknown depmode $depmode" 1>&2 + exit 1 + ;; +esac + +exit 0 Index: ext/libicpf/install-sh =================================================================== diff -u -N --- ext/libicpf/install-sh (revision 0) +++ ext/libicpf/install-sh (revision e17c80d36eaa0430313e7d1058aa7a301d1510af) @@ -0,0 +1,276 @@ +#!/bin/sh +# +# install - install a program, script, or datafile +# This comes from X11R5 (mit/util/scripts/install.sh). +# +# Copyright 1991 by the Massachusetts Institute of Technology +# +# Permission to use, copy, modify, distribute, and sell this software and its +# documentation for any purpose is hereby granted without fee, provided that +# the above copyright notice appear in all copies and that both that +# copyright notice and this permission notice appear in supporting +# documentation, and that the name of M.I.T. not be used in advertising or +# publicity pertaining to distribution of the software without specific, +# written prior permission. M.I.T. makes no representations about the +# suitability of this software for any purpose. It is provided "as is" +# without express or implied warranty. +# +# 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. It can only install one file at a time, a restriction +# shared with many OS's install programs. + + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +transformbasename="" +transform_arg="" +instcmd="$mvprog" +chmodcmd="$chmodprog 0755" +chowncmd="" +chgrpcmd="" +stripcmd="" +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src="" +dst="" +dir_arg="" + +while [ x"$1" != x ]; do + case $1 in + -c) instcmd=$cpprog + shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + -s) stripcmd=$stripprog + shift + continue;; + + -t=*) transformarg=`echo $1 | sed 's/-t=//'` + shift + continue;; + + -b=*) transformbasename=`echo $1 | sed 's/-b=//'` + shift + continue;; + + *) if [ x"$src" = x ] + then + src=$1 + else + # this colon is to work around a 386BSD /bin/sh bug + : + dst=$1 + fi + shift + continue;; + esac +done + +if [ x"$src" = x ] +then + echo "$0: no input file specified" >&2 + exit 1 +else + : +fi + +if [ x"$dir_arg" != x ]; then + dst=$src + src="" + + if [ -d "$dst" ]; then + instcmd=: + chmodcmd="" + else + instcmd=$mkdirprog + fi +else + +# Waiting for this to be detected by the "$instcmd $src $dsttmp" command +# might cause directories to be created, which would be especially bad +# if $src (and thus $dsttmp) contains '*'. + + if [ -f "$src" ] || [ -d "$src" ] + then + : + else + echo "$0: $src does not exist" >&2 + exit 1 + fi + + if [ x"$dst" = x ] + then + echo "$0: no destination specified" >&2 + exit 1 + else + : + fi + +# If destination is a directory, append the input filename; if your system +# does not like double slashes in filenames, you may need to add some logic + + if [ -d "$dst" ] + then + dst=$dst/`basename "$src"` + else + : + fi +fi + +## this sed command emulates the dirname command +dstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` + +# Make sure that the destination directory exists. +# this part is taken from Noah Friedman's mkinstalldirs script + +# Skip lots of stat calls in the usual case. +if [ ! -d "$dstdir" ]; then +defaultIFS=' + ' +IFS="${IFS-$defaultIFS}" + +oIFS=$IFS +# Some sh's can't handle IFS=/ for some reason. +IFS='%' +set - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'` +IFS=$oIFS + +pathcomp='' + +while [ $# -ne 0 ] ; do + pathcomp=$pathcomp$1 + shift + + if [ ! -d "$pathcomp" ] ; + then + $mkdirprog "$pathcomp" + else + : + fi + + pathcomp=$pathcomp/ +done +fi + +if [ x"$dir_arg" != x ] +then + $doit $instcmd "$dst" && + + if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dst"; else : ; fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dst"; else : ; fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dst"; else : ; fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dst"; else : ; fi +else + +# If we're going to rename the final executable, determine the name now. + + if [ x"$transformarg" = x ] + then + dstfile=`basename "$dst"` + else + dstfile=`basename "$dst" $transformbasename | + sed $transformarg`$transformbasename + fi + +# don't allow the sed command to completely eliminate the filename + + if [ x"$dstfile" = x ] + then + dstfile=`basename "$dst"` + else + : + fi + +# Make a couple of temp file names in the proper directory. + + dsttmp=$dstdir/#inst.$$# + rmtmp=$dstdir/#rm.$$# + +# Trap to clean up temp files at exit. + + trap 'status=$?; rm -f "$dsttmp" "$rmtmp" && exit $status' 0 + trap '(exit $?); exit' 1 2 13 15 + +# Move or copy the file name to the temp name + + $doit $instcmd "$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 $instcmd $src $dsttmp" command. + + if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dsttmp"; else :;fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dsttmp"; else :;fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dsttmp"; else :;fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dsttmp"; else :;fi && + +# 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. + +{ + if [ -f "$dstdir/$dstfile" ] + then + $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null || + $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null || + { + echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2 + (exit 1); exit + } + else + : + fi +} && + +# Now rename the file to the real destination. + + $doit $mvcmd "$dsttmp" "$dstdir/$dstfile" + +fi && + +# The final little trick to "correctly" pass the exit status to the exit trap. + +{ + (exit 0); exit +} Index: ext/libicpf/libicpf.kdevelop =================================================================== diff -u -N --- ext/libicpf/libicpf.kdevelop (revision 0) +++ ext/libicpf/libicpf.kdevelop (revision e17c80d36eaa0430313e7d1058aa7a301d1510af) @@ -0,0 +1,213 @@ + + + + Józef Starosczyk + ixen2@o2.pl + 0.1 + KDevAutoProject + C++ + + C++ + Code + + . + false + + + kdevrbdebugger + kdevfilelist + kdevfileselector + kdevbookmarks + + + kdevcvsservice + + + + src/libicpf.la + debug + + + + true + executable + + + + + / + + true + + + + + optimized + kdevgccoptions + kdevgppoptions + kdevg77options + -O2 -g0 + + + --enable-debug=full + debug + kdevgccoptions + kdevgppoptions + kdevg77options + -O0 -g3 + + + + + + + + + false + 1 + false + + 0 + + + + + ada + ada_bugs_gcc + bash + bash_bugs + clanlib + w3c-dom-level2-html + fortran_bugs_gcc + gnome1 + gnustep + gtk + gtk_bugs + haskell + haskell_bugs_ghc + java_bugs_gcc + java_bugs_sun + kde2book + opengl + pascal_bugs_fp + php + php_bugs + perl + perl_bugs + python + python_bugs + qt-kdev3 + ruby + ruby_bugs + sdl + w3c-svg + sw + w3c-uaag10 + wxwidgets_bugs + + + Guide to the Qt Translation Tools + Qt Assistant Manual + Qt Designer Manual + Qt Reference Documentation + qmake User Guide + + + KDE Libraries (Doxygen) + + + + + + + + + + + + + + false + false + + + *.o,*.lo,CVS + true + false + + + + true + true + true + true + -C + + + + + true + true + true + false + true + true + true + 50 + 50 + 250 + + + + set + m_,_ + theValue + true + true + + + + + .h + .cpp + + + + + + + + + + + true + true + false + + + true + true + 10 + + + + + Kolekcja dokumentacji programu Doxygen + html/index.html + + + + + + + + + VisualBoyAdvance + + + false + false + -f0 + -1 + + Index: ext/libicpf/libicpf.sln =================================================================== diff -u -N --- ext/libicpf/libicpf.sln (revision 0) +++ ext/libicpf/libicpf.sln (revision e17c80d36eaa0430313e7d1058aa7a301d1510af) @@ -0,0 +1,21 @@ +Microsoft Visual Studio Solution File, Format Version 8.00 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libicpf", "libicpf.vcproj", "{5510B933-046F-4F75-8B46-5E8279C8CCDE}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfiguration) = preSolution + Debug = Debug + Release = Release + EndGlobalSection + GlobalSection(ProjectConfiguration) = postSolution + {5510B933-046F-4F75-8B46-5E8279C8CCDE}.Debug.ActiveCfg = Debug|Win32 + {5510B933-046F-4F75-8B46-5E8279C8CCDE}.Debug.Build.0 = Debug|Win32 + {5510B933-046F-4F75-8B46-5E8279C8CCDE}.Release.ActiveCfg = Release|Win32 + {5510B933-046F-4F75-8B46-5E8279C8CCDE}.Release.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + EndGlobalSection + GlobalSection(ExtensibilityAddIns) = postSolution + EndGlobalSection +EndGlobal Index: ext/libicpf/libicpf.vcproj =================================================================== diff -u -N --- ext/libicpf/libicpf.vcproj (revision 0) +++ ext/libicpf/libicpf.vcproj (revision e17c80d36eaa0430313e7d1058aa7a301d1510af) @@ -0,0 +1,239 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: ext/libicpf/ltmain.sh =================================================================== diff -u -N --- ext/libicpf/ltmain.sh (revision 0) +++ ext/libicpf/ltmain.sh (revision e17c80d36eaa0430313e7d1058aa7a301d1510af) @@ -0,0 +1,6343 @@ +# ltmain.sh - Provide generalized library-building support services. +# NOTE: Changing this file will not affect anything until you rerun configure. +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003 +# Free Software Foundation, Inc. +# Originally by Gordon Matzigkeit , 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 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# 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. + +# Check that we have a working $echo. +if test "X$1" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift +elif test "X$1" = X--fallback-echo; then + # Avoid inline document here, it may be left over + : +elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then + # Yippee, $echo works! + : +else + # Restart under the correct shell, and then maybe $echo will work. + exec $SHELL "$0" --no-reexec ${1+"$@"} +fi + +if test "X$1" = X--fallback-echo; then + # used as fallback echo + shift + cat <&2 + $echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 + exit 1 +fi + +# Global variables. +mode=$default_mode +nonopt= +prev= +prevopt= +run= +show="$echo" +show_help= +execute_dlfiles= +lo2o="s/\\.lo\$/.${objext}/" +o2lo="s/\\.${objext}\$/.lo/" + +##################################### +# Shell function definitions: +# This seems to be the best place for them + +# 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. +win32_libid () { + 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 + if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | \ + grep -E 'file format pe-i386(.*architecture: i386)?' >/dev/null ; then + win32_nmres=`eval $NM -f posix -A $1 | \ + sed -n -e '1,100{/ I /{x;/import/!{s/^/import/;h;p;};x;};}'` + if test "X$win32_nmres" = "Ximport" ; then + win32_libid_type="x86 archive import" + else + win32_libid_type="x86 archive static" + fi + 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 +} + +# End of Shell function definitions +##################################### + +# Parse our command line options once, thoroughly. +while test "$#" -gt 0 +do + arg="$1" + shift + + case $arg in + -*=*) optarg=`$echo "X$arg" | $Xsed -e 's/[-_a-zA-Z0-9]*=//'` ;; + *) optarg= ;; + esac + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + case $prev in + execute_dlfiles) + execute_dlfiles="$execute_dlfiles $arg" + ;; + tag) + tagname="$arg" + + # Check whether tagname contains only valid characters + case $tagname in + *[!-_A-Za-z0-9,/]*) + $echo "$progname: invalid tag name: $tagname" 1>&2 + exit 1 + ;; + esac + + case $tagname in + CC) + # Don't test for the "default" C tag, as we know, it's there, but + # not specially marked. + ;; + *) + if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "$0" > /dev/null; then + taglist="$taglist $tagname" + # Evaluate the configuration. + eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$tagname'$/,/^# ### END LIBTOOL TAG CONFIG: '$tagname'$/p' < $0`" + else + $echo "$progname: ignoring unknown tag $tagname" 1>&2 + fi + ;; + esac + ;; + *) + eval "$prev=\$arg" + ;; + esac + + prev= + prevopt= + continue + fi + + # Have we seen a non-optional argument yet? + case $arg in + --help) + show_help=yes + ;; + + --version) + $echo "$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP" + $echo + $echo "Copyright (C) 2003 Free Software Foundation, Inc." + $echo "This is free software; see the source for copying conditions. There is NO" + $echo "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + exit 0 + ;; + + --config) + ${SED} -e '1,/^# ### BEGIN LIBTOOL CONFIG/d' -e '/^# ### END LIBTOOL CONFIG/,$d' $0 + # Now print the configurations for the tags. + for tagname in $taglist; do + ${SED} -n -e "/^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$/,/^# ### END LIBTOOL TAG CONFIG: $tagname$/p" < "$0" + done + exit 0 + ;; + + --debug) + $echo "$progname: enabling shell trace mode" + set -x + ;; + + --dry-run | -n) + run=: + ;; + + --features) + $echo "host: $host" + if test "$build_libtool_libs" = yes; then + $echo "enable shared libraries" + else + $echo "disable shared libraries" + fi + if test "$build_old_libs" = yes; then + $echo "enable static libraries" + else + $echo "disable static libraries" + fi + exit 0 + ;; + + --finish) mode="finish" ;; + + --mode) prevopt="--mode" prev=mode ;; + --mode=*) mode="$optarg" ;; + + --preserve-dup-deps) duplicate_deps="yes" ;; + + --quiet | --silent) + show=: + ;; + + --tag) prevopt="--tag" prev=tag ;; + --tag=*) + set tag "$optarg" ${1+"$@"} + shift + prev=tag + ;; + + -dlopen) + prevopt="-dlopen" + prev=execute_dlfiles + ;; + + -*) + $echo "$modename: unrecognized option \`$arg'" 1>&2 + $echo "$help" 1>&2 + exit 1 + ;; + + *) + nonopt="$arg" + break + ;; + esac +done + +if test -n "$prevopt"; then + $echo "$modename: option \`$prevopt' requires an argument" 1>&2 + $echo "$help" 1>&2 + exit 1 +fi + +# 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= + +if test -z "$show_help"; then + + # Infer the operation mode. + if test -z "$mode"; then + $echo "*** Warning: inferring the mode of operation is deprecated." 1>&2 + $echo "*** Future versions of Libtool will require -mode=MODE be specified." 1>&2 + case $nonopt in + *cc | cc* | *++ | gcc* | *-gcc* | g++* | xlc*) + mode=link + for arg + do + case $arg in + -c) + mode=compile + break + ;; + esac + done + ;; + *db | *dbx | *strace | *truss) + mode=execute + ;; + *install*|cp|mv) + mode=install + ;; + *rm) + mode=uninstall + ;; + *) + # If we have no mode, but dlfiles were specified, then do execute mode. + test -n "$execute_dlfiles" && mode=execute + + # Just use the default operation mode. + if test -z "$mode"; then + if test -n "$nonopt"; then + $echo "$modename: warning: cannot infer operation mode from \`$nonopt'" 1>&2 + else + $echo "$modename: warning: cannot infer operation mode without MODE-ARGS" 1>&2 + fi + fi + ;; + esac + fi + + # Only execute mode is allowed to have -dlopen flags. + if test -n "$execute_dlfiles" && test "$mode" != execute; then + $echo "$modename: unrecognized option \`-dlopen'" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + # Change the help message to a mode-specific one. + generic_help="$help" + help="Try \`$modename --help --mode=$mode' for more information." + + # These modes are in order of execution frequency so that they run quickly. + case $mode in + # libtool compile mode + compile) + modename="$modename: compile" + # Get the compilation command and the source file. + base_compile= + srcfile="$nonopt" # always keep a non-empty value in "srcfile" + suppress_output= + arg_mode=normal + libobj= + + 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) + if test -n "$libobj" ; then + $echo "$modename: you cannot specify \`-o' more than once" 1>&2 + exit 1 + fi + arg_mode=target + continue + ;; + + -static) + build_old_libs=yes + continue + ;; + + -prefer-pic) + pic_mode=yes + continue + ;; + + -prefer-non-pic) + pic_mode=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,*) + args=`$echo "X$arg" | $Xsed -e "s/^-Wc,//"` + lastarg= + save_ifs="$IFS"; IFS=',' + for arg in $args; do + IFS="$save_ifs" + + # Double-quote args containing other shell metacharacters. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + lastarg="$lastarg $arg" + done + IFS="$save_ifs" + lastarg=`$echo "X$lastarg" | $Xsed -e "s/^ //"` + + # Add the arguments to base_compile. + base_compile="$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. + lastarg=`$echo "X$lastarg" | $Xsed -e "$sed_quote_subst"` + + case $lastarg in + # Double-quote args containing other shell metacharacters. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + lastarg="\"$lastarg\"" + ;; + esac + + base_compile="$base_compile $lastarg" + done # for arg + + case $arg_mode in + arg) + $echo "$modename: you must specify an argument for -Xcompile" + exit 1 + ;; + target) + $echo "$modename: you must specify a target with \`-o'" 1>&2 + exit 1 + ;; + *) + # Get the name of the library object. + [ -z "$libobj" ] && libobj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%'` + ;; + esac + + # Recognize several different file suffixes. + # If the user specifies -o file.o, it is replaced with file.lo + xform='[cCFSifmso]' + case $libobj in + *.ada) xform=ada ;; + *.adb) xform=adb ;; + *.ads) xform=ads ;; + *.asm) xform=asm ;; + *.c++) xform=c++ ;; + *.cc) xform=cc ;; + *.ii) xform=ii ;; + *.class) xform=class ;; + *.cpp) xform=cpp ;; + *.cxx) xform=cxx ;; + *.f90) xform=f90 ;; + *.for) xform=for ;; + *.java) xform=java ;; + esac + + libobj=`$echo "X$libobj" | $Xsed -e "s/\.$xform$/.lo/"` + + case $libobj in + *.lo) obj=`$echo "X$libobj" | $Xsed -e "$lo2o"` ;; + *) + $echo "$modename: cannot determine name of library object from \`$libobj'" 1>&2 + exit 1 + ;; + esac + + # 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. + if test -n "$available_tags" && test -z "$tagname"; then + case $base_compile 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 "* | " `$echo $CC` "* | "`$echo $CC` "*) ;; + # 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$" < "$0" > /dev/null; then + # Evaluate the configuration. + eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $0`" + case "$base_compile " in + "$CC "* | " $CC "* | "`$echo $CC` "* | " `$echo $CC` "*) + # 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 + $echo "$modename: unable to infer tagged configuration" + $echo "$modename: specify a tag with \`--tag'" 1>&2 + exit 1 +# else +# $echo "$modename: using $tagname tagged configuration" + fi + ;; + esac + fi + + objname=`$echo "X$obj" | $Xsed -e 's%^.*/%%'` + xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$obj"; then + xdir= + else + xdir=$xdir/ + fi + lobj=${xdir}$objdir/$objname + + if test -z "$base_compile"; then + $echo "$modename: you must specify a compilation command" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + # Delete any leftover library objects. + if test "$build_old_libs" = yes; then + removelist="$obj $lobj $libobj ${libobj}T" + else + removelist="$lobj $libobj ${libobj}T" + fi + + $run $rm $removelist + trap "$run $rm $removelist; exit 1" 1 2 15 + + # On Cygwin there's no "real" PIC flag so we must build both object types + case $host_os in + cygwin* | mingw* | pw32* | os2*) + pic_mode=default + ;; + esac + if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; 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 "$compiler_c_o" = no; then + output_obj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\.[^.]*$%%'`.${objext} + lockfile="$output_obj.lock" + removelist="$removelist $output_obj $lockfile" + trap "$run $rm $removelist; exit 1" 1 2 15 + 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 "$need_locks" = yes; then + until $run ln "$0" "$lockfile" 2>/dev/null; do + $show "Waiting for $lockfile to be removed" + sleep 2 + done + elif test "$need_locks" = warn; 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." + + $run $rm $removelist + exit 1 + fi + $echo $srcfile > "$lockfile" + fi + + if test -n "$fix_srcfile_path"; then + eval srcfile=\"$fix_srcfile_path\" + fi + + $run $rm "$libobj" "${libobj}T" + + # Create a libtool object file (analogous to a ".la" file), + # but don't create it if we're doing a dry run. + test -z "$run" && cat > ${libobj}T </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." + + $run $rm $removelist + exit 1 + 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 + $show "$mv $output_obj $lobj" + if $run $mv $output_obj $lobj; then : + else + error=$? + $run $rm $removelist + exit $error + fi + fi + + # Append the name of the PIC object to the libtool object file. + test -z "$run" && cat >> ${libobj}T <> ${libobj}T </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." + + $run $rm $removelist + exit 1 + fi + + # Just move the object if needed + if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then + $show "$mv $output_obj $obj" + if $run $mv $output_obj $obj; then : + else + error=$? + $run $rm $removelist + exit $error + fi + fi + + # Append the name of the non-PIC object the libtool object file. + # Only append if the libtool object file exists. + test -z "$run" && cat >> ${libobj}T <> ${libobj}T <&2 + fi + if test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + else + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + fi + build_libtool_libs=no + build_old_libs=yes + prefer_static_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" + base_compile="$base_compile $arg" + shift + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + qarg=\"`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`\" ### testsuite: skip nested quoting test + ;; + *) qarg=$arg ;; + esac + libtool_args="$libtool_args $qarg" + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + case $prev in + output) + compile_command="$compile_command @OUTPUT@" + finalize_command="$finalize_command @OUTPUT@" + ;; + esac + + case $prev in + dlfiles|dlprefiles) + if test "$preload" = no; then + # Add the symbol object into the linking commands. + compile_command="$compile_command @SYMFILE@" + finalize_command="$finalize_command @SYMFILE@" + preload=yes + fi + case $arg in + *.la | *.lo) ;; # We handle these cases below. + force) + if test "$dlself" = no; then + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + self) + if test "$prev" = dlprefiles; then + dlself=yes + elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then + dlself=yes + else + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + *) + if test "$prev" = dlfiles; then + dlfiles="$dlfiles $arg" + else + dlprefiles="$dlprefiles $arg" + fi + prev= + continue + ;; + esac + ;; + expsyms) + export_symbols="$arg" + if test ! -f "$arg"; then + $echo "$modename: symbol file \`$arg' does not exist" + exit 1 + fi + prev= + continue + ;; + expsyms_regex) + export_symbols_regex="$arg" + prev= + continue + ;; + inst_prefix) + inst_prefix_dir="$arg" + prev= + continue + ;; + release) + release="-$arg" + prev= + continue + ;; + objectlist) + if test -f "$arg"; then + save_arg=$arg + moreargs= + for fil in `cat $save_arg` + do +# moreargs="$moreargs $fil" + arg=$fil + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if (${SED} -e '2q' $arg | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + pic_object= + non_pic_object= + + # Read the .lo file + # If there is no directory component, then add one. + case $arg in + */* | *\\*) . $arg ;; + *) . ./$arg ;; + esac + + if test -z "$pic_object" || \ + test -z "$non_pic_object" || + test "$pic_object" = none && \ + test "$non_pic_object" = none; then + $echo "$modename: cannot find name of object for \`$arg'" 1>&2 + exit 1 + fi + + # Extract subdirectory from the argument. + xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$arg"; then + xdir= + else + xdir="$xdir/" + fi + + if test "$pic_object" != none; then + # Prepend the subdirectory the object is found in. + pic_object="$xdir$pic_object" + + if test "$prev" = dlfiles; then + if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + dlfiles="$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 "$prev" = dlprefiles; then + # Preload the old-style object. + dlprefiles="$dlprefiles $pic_object" + prev= + fi + + # A PIC object. + libobjs="$libobjs $pic_object" + arg="$pic_object" + fi + + # Non-PIC object. + if test "$non_pic_object" != none; then + # Prepend the subdirectory the object is found in. + non_pic_object="$xdir$non_pic_object" + + # A standard non-PIC object + non_pic_objects="$non_pic_objects $non_pic_object" + if test -z "$pic_object" || test "$pic_object" = none ; then + arg="$non_pic_object" + fi + fi + else + # Only an error if not doing a dry-run. + if test -z "$run"; then + $echo "$modename: \`$arg' is not a valid libtool object" 1>&2 + exit 1 + else + # Dry-run case. + + # Extract subdirectory from the argument. + xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$arg"; then + xdir= + else + xdir="$xdir/" + fi + + pic_object=`$echo "X${xdir}${objdir}/${arg}" | $Xsed -e "$lo2o"` + non_pic_object=`$echo "X${xdir}${arg}" | $Xsed -e "$lo2o"` + libobjs="$libobjs $pic_object" + non_pic_objects="$non_pic_objects $non_pic_object" + fi + fi + done + else + $echo "$modename: link input file \`$save_arg' does not exist" + exit 1 + fi + arg=$save_arg + prev= + continue + ;; + rpath | xrpath) + # We need an absolute path. + case $arg in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + $echo "$modename: only absolute run-paths are allowed" 1>&2 + exit 1 + ;; + esac + if test "$prev" = rpath; then + case "$rpath " in + *" $arg "*) ;; + *) rpath="$rpath $arg" ;; + esac + else + case "$xrpath " in + *" $arg "*) ;; + *) xrpath="$xrpath $arg" ;; + esac + fi + prev= + continue + ;; + xcompiler) + compiler_flags="$compiler_flags $qarg" + prev= + compile_command="$compile_command $qarg" + finalize_command="$finalize_command $qarg" + continue + ;; + xlinker) + linker_flags="$linker_flags $qarg" + compiler_flags="$compiler_flags $wl$qarg" + prev= + compile_command="$compile_command $wl$qarg" + finalize_command="$finalize_command $wl$qarg" + continue + ;; + xcclinker) + linker_flags="$linker_flags $qarg" + compiler_flags="$compiler_flags $qarg" + prev= + compile_command="$compile_command $qarg" + finalize_command="$finalize_command $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 + compile_command="$compile_command $link_static_flag" + finalize_command="$finalize_command $link_static_flag" + fi + continue + ;; + + -allow-undefined) + # FIXME: remove this flag sometime in the future. + $echo "$modename: \`-allow-undefined' is deprecated because it is the default" 1>&2 + continue + ;; + + -avoid-version) + avoid_version=yes + 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 + $echo "$modename: more than one -exported-symbols argument is not allowed" + exit 1 + fi + if test "X$arg" = "X-export-symbols"; then + prev=expsyms + else + prev=expsyms_regex + fi + 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*) + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + ;; + esac + continue + ;; + + -L*) + dir=`$echo "X$arg" | $Xsed -e 's/^-L//'` + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + absdir=`cd "$dir" && pwd` + if test -z "$absdir"; then + $echo "$modename: cannot determine absolute directory name of \`$dir'" 1>&2 + exit 1 + fi + dir="$absdir" + ;; + esac + case "$deplibs " in + *" -L$dir "*) ;; + *) + deplibs="$deplibs -L$dir" + lib_search_path="$lib_search_path $dir" + ;; + esac + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) + case :$dllsearchpath: in + *":$dir:"*) ;; + *) dllsearchpath="$dllsearchpath:$dir";; + esac + ;; + esac + continue + ;; + + -l*) + if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then + case $host in + *-*-cygwin* | *-*-pw32* | *-*-beos*) + # These systems don't actually have a C or math library (as such) + continue + ;; + *-*-freebsd*-gnu*) + # prevent being parsed by the freebsd regexp below + ;; + *-*-mingw* | *-*-os2*) + # These systems don't actually have a C library (as such) + test "X$arg" = "X-lc" && continue + ;; + *-*-openbsd* | *-*-freebsd*) + # Do not include libc due to us having libc/libc_r. + test "X$arg" = "X-lc" && continue + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C and math libraries are in the System framework + deplibs="$deplibs -framework System" + continue + esac + elif test "X$arg" = "X-lc_r"; then + case $host in + *-*-freebsd*-gnu*) + # prevent being parsed by the freebsd regexp below + ;; + *-*-openbsd*) + # Do not include libc_r directly, use -pthread flag. + continue + ;; + esac + fi + deplibs="$deplibs $arg" + continue + ;; + + -module) + module=yes + continue + ;; + + # gcc -m* arguments should be passed to the linker via $compiler_flags + # in order to pass architecture information to the linker + # (e.g. 32 vs 64-bit). This may also be accomplished via -Wl,-mfoo + # but this is not reliable with gcc because gcc may use -mfoo to + # select a different linker, different libraries, etc, while + # -Wl,-mfoo simply passes -mfoo to the linker. + -m*) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + if test "$with_gcc" = "yes" ; then + compiler_flags="$compiler_flags $arg" + fi + continue + ;; + + -shrext) + prev=shrext + continue + ;; + + -no-fast-install) + fast_install=no + continue + ;; + + -no-install) + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) + # The PATH hackery in wrapper scripts is required on Windows + # in order for the loader to find any dlls it needs. + $echo "$modename: warning: \`-no-install' is ignored for $host" 1>&2 + $echo "$modename: warning: assuming \`-no-fast-install' instead" 1>&2 + fast_install=no + ;; + *) no_install=yes ;; + esac + continue + ;; + + -no-undefined) + allow_undefined=no + continue + ;; + + -objectlist) + prev=objectlist + continue + ;; + + -o) prev=output ;; + + -release) + prev=release + continue + ;; + + -rpath) + prev=rpath + continue + ;; + + -R) + prev=xrpath + continue + ;; + + -R*) + dir=`$echo "X$arg" | $Xsed -e 's/^-R//'` + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + $echo "$modename: only absolute run-paths are allowed" 1>&2 + exit 1 + ;; + esac + case "$xrpath " in + *" $dir "*) ;; + *) xrpath="$xrpath $dir" ;; + esac + continue + ;; + + -static) + # 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 + ;; + + -Wc,*) + args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wc,//'` + arg= + save_ifs="$IFS"; IFS=',' + for flag in $args; do + IFS="$save_ifs" + case $flag in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + flag="\"$flag\"" + ;; + esac + arg="$arg $wl$flag" + compiler_flags="$compiler_flags $flag" + done + IFS="$save_ifs" + arg=`$echo "X$arg" | $Xsed -e "s/^ //"` + ;; + + -Wl,*) + args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wl,//'` + arg= + save_ifs="$IFS"; IFS=',' + for flag in $args; do + IFS="$save_ifs" + case $flag in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + flag="\"$flag\"" + ;; + esac + arg="$arg $wl$flag" + compiler_flags="$compiler_flags $wl$flag" + linker_flags="$linker_flags $flag" + done + IFS="$save_ifs" + arg=`$echo "X$arg" | $Xsed -e "s/^ //"` + ;; + + -Xcompiler) + prev=xcompiler + continue + ;; + + -Xlinker) + prev=xlinker + continue + ;; + + -XCClinker) + prev=xcclinker + continue + ;; + + # Some other compiler flag. + -* | +*) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + add_flags="$add_flags $arg" + ;; + + *.$objext) + # A standard object. + objs="$objs $arg" + ;; + + *.lo) + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if (${SED} -e '2q' $arg | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + pic_object= + non_pic_object= + + # Read the .lo file + # If there is no directory component, then add one. + case $arg in + */* | *\\*) . $arg ;; + *) . ./$arg ;; + esac + + if test -z "$pic_object" || \ + test -z "$non_pic_object" || + test "$pic_object" = none && \ + test "$non_pic_object" = none; then + $echo "$modename: cannot find name of object for \`$arg'" 1>&2 + exit 1 + fi + + # Extract subdirectory from the argument. + xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$arg"; then + xdir= + else + xdir="$xdir/" + fi + + if test "$pic_object" != none; then + # Prepend the subdirectory the object is found in. + pic_object="$xdir$pic_object" + + if test "$prev" = dlfiles; then + if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + dlfiles="$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 "$prev" = dlprefiles; then + # Preload the old-style object. + dlprefiles="$dlprefiles $pic_object" + prev= + fi + + # A PIC object. + libobjs="$libobjs $pic_object" + arg="$pic_object" + fi + + # Non-PIC object. + if test "$non_pic_object" != none; then + # Prepend the subdirectory the object is found in. + non_pic_object="$xdir$non_pic_object" + + # A standard non-PIC object + non_pic_objects="$non_pic_objects $non_pic_object" + if test -z "$pic_object" || test "$pic_object" = none ; then + arg="$non_pic_object" + fi + fi + else + # Only an error if not doing a dry-run. + if test -z "$run"; then + $echo "$modename: \`$arg' is not a valid libtool object" 1>&2 + exit 1 + else + # Dry-run case. + + # Extract subdirectory from the argument. + xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$arg"; then + xdir= + else + xdir="$xdir/" + fi + + pic_object=`$echo "X${xdir}${objdir}/${arg}" | $Xsed -e "$lo2o"` + non_pic_object=`$echo "X${xdir}${arg}" | $Xsed -e "$lo2o"` + libobjs="$libobjs $pic_object" + non_pic_objects="$non_pic_objects $non_pic_object" + fi + fi + ;; + + *.$libext) + # An archive. + deplibs="$deplibs $arg" + old_deplibs="$old_deplibs $arg" + continue + ;; + + *.la) + # A libtool-controlled library. + + if test "$prev" = dlfiles; then + # This library was specified with -dlopen. + dlfiles="$dlfiles $arg" + prev= + elif test "$prev" = dlprefiles; then + # The library was specified with -dlpreopen. + dlprefiles="$dlprefiles $arg" + prev= + else + deplibs="$deplibs $arg" + 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. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + add_flags="$add_flags $arg" + ;; + esac # arg + + # Now actually substitute the argument into the commands. + if test -n "$arg"; then + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + fi + done # argument parsing loop + + if test -n "$prev"; then + $echo "$modename: the \`$prevarg' option requires an argument" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + # 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 link + # command doesn't match the default compiler. + if test -n "$available_tags" && test -z "$tagname"; then + case $base_compile 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 "* | "`$echo $CC` "* | " `$echo $CC` "*) ;; + # 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$" < "$0" > /dev/null; then + # Evaluate the configuration. + eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $0`" + case $base_compile in + "$CC "* | " $CC "* | "`$echo $CC` "* | " `$echo $CC` "*) + # The compiler in $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 + $echo "$modename: unable to infer tagged configuration" + $echo "$modename: specify a tag with \`--tag'" 1>&2 + exit 1 +# else +# $echo "$modename: using $tagname tagged configuration" + fi + ;; + esac + fi + + if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then + eval arg=\"$export_dynamic_flag_spec\" + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + fi + + oldlibs= + # calculate the name of the file, without its directory + outputname=`$echo "X$output" | $Xsed -e 's%^.*/%%'` + libobjs_save="$libobjs" + + if test -n "$shlibpath_var"; then + # get the directories listed in $shlibpath_var + eval shlib_search_path=\`\$echo \"X\${$shlibpath_var}\" \| \$Xsed -e \'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\" + + output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'` + if test "X$output_objdir" = "X$output"; then + output_objdir="$objdir" + else + output_objdir="$output_objdir/$objdir" + fi + # Create the object directory. + if test ! -d "$output_objdir"; then + $show "$mkdir $output_objdir" + $run $mkdir $output_objdir + status=$? + if test "$status" -ne 0 && test ! -d "$output_objdir"; then + exit $status + fi + fi + + # Determine the type of output + case $output in + "") + $echo "$modename: you must specify an output file" 1>&2 + $echo "$help" 1>&2 + exit 1 + ;; + *.$libext) linkmode=oldlib ;; + *.lo | *.$objext) linkmode=obj ;; + *.la) linkmode=lib ;; + *) linkmode=prog ;; # Anything else should be a program. + esac + + case $host in + *cygwin* | *mingw* | *pw32*) + # don't eliminate duplcations in $postdeps and $predeps + duplicate_compiler_generated_deps=yes + ;; + *) + duplicate_compiler_generated_deps=$duplicate_deps + ;; + 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 test "X$duplicate_deps" = "Xyes" ; then + case "$libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + libs="$libs $deplib" + done + + if test "$linkmode" = lib; 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 test "X$duplicate_compiler_generated_deps" = "Xyes" ; then + for pre_post_dep in $predeps $postdeps; do + case "$pre_post_deps " in + *" $pre_post_dep "*) specialdeplibs="$specialdeplibs $pre_post_deps" ;; + esac + pre_post_deps="$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 link" + for file in $dlfiles $dlprefiles; do + case $file in + *.la) ;; + *) + $echo "$modename: libraries can \`-dlopen' only libtool libraries: $file" 1>&2 + exit 1 + ;; + esac + done + ;; + prog) + compile_deplibs= + finalize_deplibs= + alldeplibs=no + newdlfiles= + newdlprefiles= + passes="conv scan dlopen dlpreopen link" + ;; + *) passes="conv" + ;; + esac + for pass in $passes; do + if test "$linkmode,$pass" = "lib,link" || + test "$linkmode,$pass" = "prog,scan"; then + libs="$deplibs" + deplibs= + fi + if test "$linkmode" = prog; then + case $pass in + dlopen) libs="$dlfiles" ;; + dlpreopen) libs="$dlprefiles" ;; + link) libs="$deplibs %DEPLIBS% $dependency_libs" ;; + esac + fi + if test "$pass" = dlopen; then + # Collect dlpreopened libraries + save_deplibs="$deplibs" + deplibs= + fi + for deplib in $libs; do + lib= + found=no + case $deplib in + -l*) + if test "$linkmode" != lib && test "$linkmode" != prog; then + $echo "$modename: warning: \`-l' is ignored for archives/objects" 1>&2 + continue + fi + if test "$pass" = conv && test "$allow_undefined" = yes; then + deplibs="$deplib $deplibs" + continue + fi + name=`$echo "X$deplib" | $Xsed -e 's/^-l//'` + for searchdir in $newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path; do + for search_ext in .la $shrext .so .a; do + # Search the libtool library + lib="$searchdir/lib${name}${search_ext}" + if test -f "$lib"; then + if test "$search_ext" = ".la"; then + found=yes + else + found=no + fi + break 2 + fi + done + done + if test "$found" != yes; then + # deplib doesn't seem to be a libtool library + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" + fi + continue + else # 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 "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $deplib "*) + if (${SED} -e '2q' $lib | + grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + library_names= + old_library= + case $lib in + */* | *\\*) . $lib ;; + *) . ./$lib ;; + esac + for l in $old_library $library_names; do + ll="$l" + done + if test "X$ll" = "X$old_library" ; then # only static version available + found=no + ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'` + test "X$ladir" = "X$lib" && ladir="." + lib=$ladir/$old_library + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" + fi + continue + fi + fi + ;; + *) ;; + esac + fi + fi + ;; # -l + -L*) + case $linkmode in + lib) + deplibs="$deplib $deplibs" + test "$pass" = conv && continue + newdependency_libs="$deplib $newdependency_libs" + newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'` + ;; + prog) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + continue + fi + if test "$pass" = scan; then + deplibs="$deplib $deplibs" + newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'` + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + ;; + *) + $echo "$modename: warning: \`-L' is ignored for archives/objects" 1>&2 + ;; + esac # linkmode + continue + ;; # -L + -R*) + if test "$pass" = link; then + dir=`$echo "X$deplib" | $Xsed -e 's/^-R//'` + # Make sure the xrpath contains only unique directories. + case "$xrpath " in + *" $dir "*) ;; + *) xrpath="$xrpath $dir" ;; + esac + fi + deplibs="$deplib $deplibs" + continue + ;; + *.la) lib="$deplib" ;; + *.$libext) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + continue + fi + case $linkmode in + lib) + if test "$deplibs_check_method" != pass_all; then + $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 used here." + else + $echo + $echo "*** Warning: Linking the shared library $output against the" + $echo "*** static library $deplib is not portable!" + deplibs="$deplib $deplibs" + fi + continue + ;; + prog) + if test "$pass" != link; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + continue + ;; + esac # linkmode + ;; # *.$libext + *.lo | *.$objext) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + elif test "$linkmode" = prog; then + if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then + # If there is no dlopen support or we're linking statically, + # we need to preload. + newdlprefiles="$newdlprefiles $deplib" + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + newdlfiles="$newdlfiles $deplib" + fi + fi + continue + ;; + %DEPLIBS%) + alldeplibs=yes + continue + ;; + esac # case $deplib + if test "$found" = yes || test -f "$lib"; then : + else + $echo "$modename: cannot find the library \`$lib'" 1>&2 + exit 1 + fi + + # Check to see that this really is a libtool archive. + if (${SED} -e '2q' $lib | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : + else + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + exit 1 + fi + + ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'` + test "X$ladir" = "X$lib" && ladir="." + + dlname= + dlopen= + dlpreopen= + libdir= + library_names= + old_library= + # If the library was installed with an old release of libtool, + # it will not redefine variables installed, or shouldnotlink + installed=yes + shouldnotlink=no + + # Read the .la file + case $lib in + */* | *\\*) . $lib ;; + *) . ./$lib ;; + esac + + if test "$linkmode,$pass" = "lib,link" || + test "$linkmode,$pass" = "prog,scan" || + { test "$linkmode" != prog && test "$linkmode" != lib; }; then + test -n "$dlopen" && dlfiles="$dlfiles $dlopen" + test -n "$dlpreopen" && dlprefiles="$dlprefiles $dlpreopen" + fi + + if test "$pass" = conv; then + # Only check for convenience libraries + deplibs="$lib $deplibs" + tmp_libs= + for deplib in $dependency_libs; do + #echo "Adding $deplib to \$deplibs" + deplibs="$deplib $deplibs" + if test "X$duplicate_deps" = "Xyes" ; then + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + tmp_libs="$tmp_libs $deplib" + done + if test -z "$libdir"; then + if test -z "$old_library"; then + $echo "$modename: cannot find name of link library for \`$lib'" 1>&2 + exit 1 + fi + # It is a libtool convenience library, so add in its objects. + convenience="$convenience $ladir/$objdir/$old_library" + old_convenience="$old_convenience $ladir/$objdir/$old_library" + elif test "$linkmode" != prog && test "$linkmode" != lib; then + $echo "$modename: \`$lib' is not a convenience library" 1>&2 + exit 1 + fi + continue + fi # $pass = conv + + + # Get the name of the library we link against. + linklib= + for l in $old_library $library_names; do + linklib="$l" + done + if test -z "$linklib"; then + $echo "$modename: cannot find name of link library for \`$lib'" 1>&2 + exit 1 + fi + + # This library was specified with -dlopen. + if test "$pass" = dlopen; then + if test -z "$libdir"; then + $echo "$modename: cannot -dlopen a convenience library: \`$lib'" 1>&2 + exit 1 + fi + if test -z "$dlname" || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; 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. + dlprefiles="$dlprefiles $lib $dependency_libs" + else + newdlfiles="$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 + $echo "$modename: warning: cannot determine absolute directory name of \`$ladir'" 1>&2 + $echo "$modename: passing it literally to the linker, although it might fail" 1>&2 + abs_ladir="$ladir" + fi + ;; + esac + laname=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` + + # Find the relevant object directory and library name. + if test "X$installed" = Xyes; then + if test ! -f "$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then + $echo "$modename: warning: library \`$lib' was moved." 1>&2 + dir="$ladir" + absdir="$abs_ladir" + libdir="$abs_ladir" + else + dir="$libdir" + absdir="$libdir" + fi + else + dir="$ladir/$objdir" + absdir="$abs_ladir/$objdir" + # Remove this search path later + notinst_path="$notinst_path $abs_ladir" + fi # $installed = yes + name=`$echo "X$laname" | $Xsed -e 's/\.la$//' -e 's/^lib//'` + + # This library was specified with -dlpreopen. + if test "$pass" = dlpreopen; then + if test -z "$libdir"; then + $echo "$modename: cannot -dlpreopen a convenience library: \`$lib'" 1>&2 + exit 1 + fi + # Prefer using a static library (so that no silly _DYNAMIC symbols + # are required to link). + if test -n "$old_library"; then + newdlprefiles="$newdlprefiles $dir/$old_library" + # Otherwise, use the dlname, so that lt_dlopen finds it. + elif test -n "$dlname"; then + newdlprefiles="$newdlprefiles $dir/$dlname" + else + newdlprefiles="$newdlprefiles $dir/$linklib" + fi + fi # $pass = dlpreopen + + if test -z "$libdir"; then + # Link the convenience library + if test "$linkmode" = lib; then + deplibs="$dir/$old_library $deplibs" + elif test "$linkmode,$pass" = "prog,link"; 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 "$linkmode" = prog && test "$pass" != link; then + newlib_search_path="$newlib_search_path $ladir" + deplibs="$lib $deplibs" + + linkalldeplibs=no + if test "$link_all_deplibs" != no || test -z "$library_names" || + test "$build_libtool_libs" = no; then + linkalldeplibs=yes + fi + + tmp_libs= + for deplib in $dependency_libs; do + case $deplib in + -L*) newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`;; ### testsuite: skip nested quoting test + esac + # Need to link against all dependency_libs? + if test "$linkalldeplibs" = yes; then + deplibs="$deplib $deplibs" + else + # Need to hardcode shared library paths + # or/and link against static libraries + newdependency_libs="$deplib $newdependency_libs" + fi + if test "X$duplicate_deps" = "Xyes" ; then + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + tmp_libs="$tmp_libs $deplib" + done # for deplib + continue + fi # $linkmode = prog... + + if test "$linkmode,$pass" = "prog,link"; then + if test -n "$library_names" && + { test "$prefer_static_libs" = no || test -z "$old_library"; }; then + # We need to hardcode the library path + if test -n "$shlibpath_var"; then + # Make sure the rpath contains only unique directories. + case "$temp_rpath " in + *" $dir "*) ;; + *" $absdir "*) ;; + *) temp_rpath="$temp_rpath $dir" ;; + 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 "*) ;; + *) compile_rpath="$compile_rpath $absdir" + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" + esac + ;; + esac + fi # $linkmode,$pass = prog,link... + + if test "$alldeplibs" = yes && + { test "$deplibs_check_method" = pass_all || + { test "$build_libtool_libs" = yes && + 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 + if test -n "$library_names" && + { test "$prefer_static_libs" = no || test -z "$old_library"; }; then + if test "$installed" = no; then + notinst_deplibs="$notinst_deplibs $lib" + need_relink=yes + fi + # This is a shared library + + # Warn about portability, can't link against -module's on some systems (darwin) + if test "$shouldnotlink" = yes && test "$pass" = link ; then + $echo + if test "$linkmode" = prog; 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 "$linkmode" = lib && + test "$hardcode_into_libs" = yes; 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 "*) ;; + *) compile_rpath="$compile_rpath $absdir" + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" + esac + ;; + esac + fi + + if test -n "$old_archive_from_expsyms_cmds"; then + # figure out the soname + set dummy $library_names + realname="$2" + shift; 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*) + major=`expr $current - $age` + versuffix="-$major" + ;; + esac + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + + # Make a new name for the extract_expsyms_cmds to use + soroot="$soname" + soname=`$echo $soroot | ${SED} -e 's/^.*\///'` + newlib="libimp-`$echo $soname | ${SED} 's/^lib//;s/\.dll$//'`.a" + + # If the library has no export list, then create one now + if test -f "$output_objdir/$soname-def"; then : + else + $show "extracting exported symbol list from \`$soname'" + save_ifs="$IFS"; IFS='~' + eval cmds=\"$extract_expsyms_cmds\" + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + fi + + # Create $newlib + if test -f "$output_objdir/$newlib"; then :; else + $show "generating import library for \`$soname'" + save_ifs="$IFS"; IFS='~' + eval cmds=\"$old_archive_from_expsyms_cmds\" + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + 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 "$linkmode" = prog || test "$mode" != relink; then + add_shlibpath= + add_dir= + add= + lib_linked=yes + case $hardcode_action in + immediate | unsupported) + if test "$hardcode_direct" = no; then + add="$dir/$linklib" + case $host in + *-*-sco3.2v5* ) add_dir="-L$dir" ;; + *-*-darwin* ) + # if the lib is a module then we can not link against it, someone + # is ignoring the new warnings I added + if /usr/bin/file -L $add 2> /dev/null | grep "bundle" >/dev/null ; 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 + fi + esac + elif test "$hardcode_minus_L" = no; then + case $host in + *-*-sunos*) add_shlibpath="$dir" ;; + esac + add_dir="-L$dir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = no; then + add_shlibpath="$dir" + add="-l$name" + else + lib_linked=no + fi + ;; + relink) + if test "$hardcode_direct" = yes; then + add="$dir/$linklib" + elif test "$hardcode_minus_L" = yes; then + add_dir="-L$dir" + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case "$libdir" in + [\\/]*) + add_dir="-L$inst_prefix_dir$libdir $add_dir" + ;; + esac + fi + add="-l$name" + elif test "$hardcode_shlibpath_var" = yes; then + add_shlibpath="$dir" + add="-l$name" + else + lib_linked=no + fi + ;; + *) lib_linked=no ;; + esac + + if test "$lib_linked" != yes; then + $echo "$modename: configuration error: unsupported hardcode properties" + exit 1 + fi + + if test -n "$add_shlibpath"; then + case :$compile_shlibpath: in + *":$add_shlibpath:"*) ;; + *) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;; + esac + fi + if test "$linkmode" = prog; 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 "$hardcode_direct" != yes && \ + test "$hardcode_minus_L" != yes && \ + test "$hardcode_shlibpath_var" = yes; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; + esac + fi + fi + fi + + if test "$linkmode" = prog || test "$mode" = relink; then + add_shlibpath= + add_dir= + add= + # Finalize command for both is simple: just hardcode it. + if test "$hardcode_direct" = yes; then + add="$libdir/$linklib" + elif test "$hardcode_minus_L" = yes; then + add_dir="-L$libdir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = yes; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; + esac + add="-l$name" + elif test "$hardcode_automatic" = yes; 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 + [\\/]*) + add_dir="-L$inst_prefix_dir$libdir $add_dir" + ;; + esac + fi + add="-l$name" + fi + + if test "$linkmode" = prog; 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 "$linkmode" = prog; 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 "$hardcode_direct" != unsupported; 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 "$build_libtool_libs" = yes; then + # Not a shared library + if test "$deplibs_check_method" != pass_all; 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 can not 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 "$module" = yes; 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 "$build_old_libs" = no; then + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + else + convenience="$convenience $dir/$old_library" + old_convenience="$old_convenience $dir/$old_library" + deplibs="$dir/$old_library $deplibs" + link_static=yes + fi + fi # link shared/static library? + + if test "$linkmode" = lib; then + #if test -n "$dependency_libs" && + # { test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes || + # test "$link_static" = yes; }; then + # Extract -R from dependency_libs + temp_deplibs= + for libdir in $dependency_libs; do + case $libdir in + -R*) temp_xrpath=`$echo "X$libdir" | $Xsed -e 's/^-R//'` + case " $xrpath " in + *" $temp_xrpath "*) ;; + *) xrpath="$xrpath $temp_xrpath";; + esac;; + *) temp_deplibs="$temp_deplibs $libdir";; + esac + done + dependency_libs="$temp_deplibs" + #fi + + newlib_search_path="$newlib_search_path $absdir" + # Link against this library + test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" + # ... and its dependency_libs + tmp_libs= + for deplib in $dependency_libs; do + newdependency_libs="$deplib $newdependency_libs" + if test "X$duplicate_deps" = "Xyes" ; then + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + tmp_libs="$tmp_libs $deplib" + done + + if test "$link_all_deplibs" != no; then + # Add the search paths of all dependency libraries + for deplib in $dependency_libs; do + case $deplib in + -L*) path="$deplib" ;; + *.la) + dir=`$echo "X$deplib" | $Xsed -e 's%/[^/]*$%%'` + test "X$dir" = "X$deplib" && dir="." + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;; + *) + absdir=`cd "$dir" && pwd` + if test -z "$absdir"; then + $echo "$modename: warning: cannot determine absolute directory name of \`$dir'" 1>&2 + absdir="$dir" + fi + ;; + esac + if grep "^installed=no" $deplib > /dev/null; then + path="$absdir/$objdir" + else + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + if test -z "$libdir"; then + $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2 + exit 1 + fi + if test "$absdir" != "$libdir"; then + # Sure, some shells/systems don't implement the -ef. + # Those will have to live with the warning. + test "$absdir" -ef "$libdir" > /dev/null 2>&1 || + $echo "$modename: warning: \`$deplib' seems to be moved" 1>&2 + fi + path="$absdir" + fi + depdepl= + case $host in + *-*-darwin*) + # we do not want to link against static libs, but need to link against shared + 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 "$path/$depdepl" ; then + depdepl="$path/$depdepl" + fi + # do not add paths which are already there + case " $newlib_search_path " in + *" $path "*) ;; + *) newlib_search_path="$newlib_search_path $path";; + esac + path="" + fi + ;; + *) + path="-L$path" + ;; + esac + + ;; + -l*) + case $host in + *-*-darwin*) + # Again, we only want to link against shared libraries + eval tmp_libs=`$echo "X$deplib" | $Xsed -e "s,^\-l,,"` + for tmp in $newlib_search_path ; do + if test -f "$tmp/lib$tmp_libs.dylib" ; then + eval depdepl="$tmp/lib$tmp_libs.dylib" + break + fi + done + path="" + ;; + *) continue ;; + esac + ;; + *) continue ;; + esac + case " $deplibs " in + *" $depdepl "*) ;; + *) deplibs="$deplibs $depdepl" ;; + esac + case " $deplibs " in + *" $path "*) ;; + *) deplibs="$deplibs $path" ;; + esac + done + fi # link_all_deplibs != no + fi # linkmode = lib + done # for deplib in $libs + dependency_libs="$newdependency_libs" + if test "$pass" = dlpreopen; then + # Link the dlpreopened libraries before other libraries + for deplib in $save_deplibs; do + deplibs="$deplib $deplibs" + done + fi + if test "$pass" != dlopen; then + if test "$pass" != conv; then + # 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 "*) ;; + *) lib_search_path="$lib_search_path $dir" ;; + esac + done + newlib_search_path= + fi + + if test "$linkmode,$pass" != "prog,link"; then + vars="deplibs" + else + vars="compile_deplibs finalize_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 "*) ;; + *) tmp_libs="$tmp_libs $deplib" ;; + esac + ;; + *) tmp_libs="$tmp_libs $deplib" ;; + esac + done + eval $var=\"$tmp_libs\" + done # for var + fi + # 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 + tmp_libs="$tmp_libs $i" + fi + done + dependency_libs=$tmp_libs + done # for pass + if test "$linkmode" = prog; then + dlfiles="$newdlfiles" + dlprefiles="$newdlprefiles" + fi + + case $linkmode in + oldlib) + if test -n "$deplibs"; then + $echo "$modename: warning: \`-l' and \`-L' are ignored for archives" 1>&2 + fi + + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + $echo "$modename: warning: \`-dlopen' is ignored for archives" 1>&2 + fi + + if test -n "$rpath"; then + $echo "$modename: warning: \`-rpath' is ignored for archives" 1>&2 + fi + + if test -n "$xrpath"; then + $echo "$modename: warning: \`-R' is ignored for archives" 1>&2 + fi + + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info/-version-number' is ignored for archives" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for archives" 1>&2 + fi + + if test -n "$export_symbols" || test -n "$export_symbols_regex"; then + $echo "$modename: warning: \`-export-symbols' is ignored for archives" 1>&2 + fi + + # Now set the variables for building old libraries. + build_libtool_libs=no + oldlibs="$output" + objs="$objs$old_deplibs" + ;; + + lib) + # Make sure we only generate libraries of the form `libNAME.la'. + case $outputname in + lib*) + name=`$echo "X$outputname" | $Xsed -e 's/\.la$//' -e 's/^lib//'` + eval shared_ext=\"$shrext\" + eval libname=\"$libname_spec\" + ;; + *) + if test "$module" = no; then + $echo "$modename: libtool library \`$output' must begin with \`lib'" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + if test "$need_lib_prefix" != no; then + # Add the "lib" prefix for modules if required + name=`$echo "X$outputname" | $Xsed -e 's/\.la$//'` + eval shared_ext=\"$shrext\" + eval libname=\"$libname_spec\" + else + libname=`$echo "X$outputname" | $Xsed -e 's/\.la$//'` + fi + ;; + esac + + if test -n "$objs"; then + if test "$deplibs_check_method" != pass_all; then + $echo "$modename: cannot build libtool library \`$output' from non-libtool objects on this host:$objs" 2>&1 + exit 1 + else + $echo + $echo "*** Warning: Linking the shared library $output against the non-libtool" + $echo "*** objects $objs is not portable!" + libobjs="$libobjs $objs" + fi + fi + + if test "$dlself" != no; then + $echo "$modename: warning: \`-dlopen self' is ignored for libtool libraries" 1>&2 + fi + + set dummy $rpath + if test "$#" -gt 2; then + $echo "$modename: warning: ignoring multiple \`-rpath's for a libtool library" 1>&2 + fi + install_libdir="$2" + + oldlibs= + if test -z "$rpath"; then + if test "$build_libtool_libs" = yes; 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 + + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info/-version-number' is ignored for convenience libraries" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for convenience libraries" 1>&2 + fi + else + + # Parse the version information argument. + save_ifs="$IFS"; IFS=':' + set dummy $vinfo 0 0 0 + IFS="$save_ifs" + + if test -n "$8"; then + $echo "$modename: too many parameters to \`-version-info'" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + # 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="$2" + number_minor="$3" + number_revision="$4" + # + # 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 + # which has an extra 1 added just for fun + # + case $version_type in + darwin|linux|osf|windows) + current=`expr $number_major + $number_minor` + age="$number_minor" + revision="$number_revision" + ;; + freebsd-aout|freebsd-elf|sunos) + current="$number_major" + revision="$number_minor" + age="0" + ;; + irix|nonstopux) + current=`expr $number_major + $number_minor - 1` + age="$number_minor" + revision="$number_minor" + ;; + esac + ;; + no) + current="$2" + revision="$3" + age="$4" + ;; + 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]) ;; + *) + $echo "$modename: CURRENT \`$current' is not a nonnegative integer" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit 1 + ;; + esac + + case $revision in + 0 | [1-9] | [1-9][0-9] | [1-9][0-9][0-9]) ;; + *) + $echo "$modename: REVISION \`$revision' is not a nonnegative integer" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit 1 + ;; + esac + + case $age in + 0 | [1-9] | [1-9][0-9] | [1-9][0-9][0-9]) ;; + *) + $echo "$modename: AGE \`$age' is not a nonnegative integer" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit 1 + ;; + esac + + if test "$age" -gt "$current"; then + $echo "$modename: AGE \`$age' is greater than the current interface number \`$current'" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit 1 + 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 + major=.`expr $current - $age` + versuffix="$major.$age.$revision" + # Darwin ld doesn't like 0 for these options... + minor_current=`expr $current + 1` + verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" + ;; + + freebsd-aout) + major=".$current" + versuffix=".$current.$revision"; + ;; + + freebsd-elf) + major=".$current" + versuffix=".$current"; + ;; + + irix | nonstopux) + major=`expr $current - $age + 1` + + 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 "$loop" -ne 0; do + iface=`expr $revision - $loop` + loop=`expr $loop - 1` + verstring="$verstring_prefix$major.$iface:$verstring" + done + + # Before this point, $major must not contain `.'. + major=.$major + versuffix="$major.$revision" + ;; + + linux) + major=.`expr $current - $age` + versuffix="$major.$age.$revision" + ;; + + osf) + major=.`expr $current - $age` + versuffix=".$current.$age.$revision" + verstring="$current.$age.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$age + while test "$loop" -ne 0; do + iface=`expr $current - $loop` + loop=`expr $loop - 1` + verstring="$verstring:${iface}.0" + done + + # Make executables depend on our current version. + verstring="$verstring:${current}.0" + ;; + + sunos) + major=".$current" + versuffix=".$current.$revision" + ;; + + windows) + # Use '-' rather than '.', since we only want one + # extension on DOS 8.3 filesystems. + major=`expr $current - $age` + versuffix="-$major" + ;; + + *) + $echo "$modename: unknown library version type \`$version_type'" 1>&2 + $echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 + exit 1 + ;; + 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 "$need_version" = no; then + versuffix= + else + versuffix=".0.0" + fi + fi + + # Remove version info from name if versioning should be avoided + if test "$avoid_version" = yes && test "$need_version" = no; then + major= + versuffix= + verstring="" + fi + + # Check to see if the archive will have undefined symbols. + if test "$allow_undefined" = yes; then + if test "$allow_undefined_flag" = unsupported; then + $echo "$modename: warning: undefined symbols not allowed in $host shared libraries" 1>&2 + build_libtool_libs=no + build_old_libs=yes + fi + else + # Don't allow undefined symbols. + allow_undefined_flag="$no_undefined_flag" + fi + fi + + if test "$mode" != relink; 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) + ;; + $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*) + removelist="$removelist $p" + ;; + *) ;; + esac + done + if test -n "$removelist"; then + $show "${rm}r $removelist" + $run ${rm}r $removelist + fi + fi + + # Now set the variables for building old libraries. + if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then + oldlibs="$oldlibs $output_objdir/$libname.$libext" + + # Transform .lo files to .o files. + oldobjs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP` + fi + + # Eliminate all temporary directories. + for path in $notinst_path; do + lib_search_path=`$echo "$lib_search_path " | ${SED} -e 's% $path % %g'` + deplibs=`$echo "$deplibs " | ${SED} -e 's% -L$path % %g'` + dependency_libs=`$echo "$dependency_libs " | ${SED} -e '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 + temp_xrpath="$temp_xrpath -R$libdir" + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" ;; + esac + done + if true || test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; 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 "*) ;; + *) dlfiles="$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 "*) ;; + *) dlprefiles="$dlprefiles $lib" ;; + esac + done + + if test "$build_libtool_libs" = yes; then + if test -n "$rpath"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos*) + # these systems don't actually have a c library (as such)! + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C library is in the System framework + deplibs="$deplibs -framework System" + ;; + *-*-netbsd*) + # Don't link with libc until the a.out ld.so is fixed. + ;; + *-*-freebsd*-gnu*) + # Prevent $arg from being parsed by the freebsd regexp below. + if test "$build_libtool_need_lc" = "yes"; then + deplibs="$deplibs -lc" + fi + ;; + *-*-openbsd* | *-*-freebsd*) + # Do not include libc due to us having libc/libc_r. + test "X$arg" = "X-lc" && continue + ;; + *) + # Add libc to deplibs on all other systems if necessary. + if test "$build_libtool_need_lc" = "yes"; then + deplibs="$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. + $rm conftest.c + cat > conftest.c </dev/null` + 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 "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";; + esac + done + if eval $file_magic_cmd \"\$potlib\" 2>/dev/null \ + | ${SED} 10q \ + | $EGREP "$file_magic_regex" > /dev/null; then + newdeplibs="$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 + else + # Add a -L argument. + newdeplibs="$newdeplibs $a_deplib" + fi + done # Gone through all deplibs. + ;; + match_pattern*) + set dummy $deplibs_check_method + match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"` + for a_deplib in $deplibs; do + name="`expr $a_deplib : '-l\(.*\)'`" + # If $name is empty we are operating on a -L argument. + if test -n "$name" && test "$name" != "0"; then + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $a_deplib "*) + newdeplibs="$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 + newdeplibs="$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 + else + # Add a -L argument. + newdeplibs="$newdeplibs $a_deplib" + fi + done # Gone through all deplibs. + ;; + none | unknown | *) + newdeplibs="" + tmp_deplibs=`$echo "X $deplibs" | $Xsed -e 's/ -lc$//' \ + -e 's/ -[LR][^ ]*//g'` + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + for i in $predeps $postdeps ; do + # can't use Xsed below, because $i might contain '/' + tmp_deplibs=`$echo "X $tmp_deplibs" | ${SED} -e "1s,^X,," -e "s,$i,,"` + done + fi + if $echo "X $tmp_deplibs" | $Xsed -e 's/[ ]//g' \ + | grep . >/dev/null; then + $echo + if test "X$deplibs_check_method" = "Xnone"; 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 + fi + ;; + 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 is the System framework + newdeplibs=`$echo "X $newdeplibs" | $Xsed -e 's/ -lc / -framework System /'` + ;; + esac + + if test "$droppeddeps" = yes; then + if test "$module" = yes; 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 "$build_old_libs" = no; 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 "$allow_undefined" = no; 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 "$build_old_libs" = no; 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 + + # 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 "$build_libtool_libs" = yes; then + if test "$hardcode_into_libs" = yes; then + # Hardcode the library paths + hardcode_libdirs= + dep_rpath= + rpath="$finalize_rpath" + test "$mode" != relink && test "$fast_install" = no && rpath="$compile_rpath$rpath" + for libdir in $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"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + dep_rpath="$dep_rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) perm_rpath="$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" + if test -n "$hardcode_libdir_flag_spec_ld"; then + eval dep_rpath=\"$hardcode_libdir_flag_spec_ld\" + else + eval dep_rpath=\"$hardcode_libdir_flag_spec\" + fi + fi + if test -n "$runpath_var" && test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + rpath="$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 "$mode" != relink && 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\" + eval library_names=\"$library_names_spec\" + set dummy $library_names + realname="$2" + shift; 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" + for link + do + linknames="$linknames $link" + done + + # Use standard objects if they are pic + test -z "$pic_flag" && libobjs=`$echo "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then + $show "generating symbol list for \`$libname.la'" + export_symbols="$output_objdir/$libname.exp" + $run $rm $export_symbols + eval cmds=\"$export_symbols_cmds\" + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + if len=`expr "X$cmd" : ".*"` && + test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then + $show "$cmd" + $run eval "$cmd" || exit $? + skipped_export=false + else + # The command line is too long to execute in one step. + $show "using reloadable object file for export list..." + skipped_export=: + fi + done + IFS="$save_ifs" + if test -n "$export_symbols_regex"; then + $show "$EGREP -e \"$export_symbols_regex\" \"$export_symbols\" > \"${export_symbols}T\"" + $run eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + $show "$mv \"${export_symbols}T\" \"$export_symbols\"" + $run eval '$mv "${export_symbols}T" "$export_symbols"' + fi + fi + fi + + if test -n "$export_symbols" && test -n "$include_expsyms"; then + $run eval '$echo "X$include_expsyms" | $SP2NL >> "$export_symbols"' + fi + + tmp_deplibs= + for test_deplib in $deplibs; do + case " $convenience " in + *" $test_deplib "*) ;; + *) + tmp_deplibs="$tmp_deplibs $test_deplib" + ;; + esac + done + deplibs="$tmp_deplibs" + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + else + gentop="$output_objdir/${outputname}x" + $show "${rm}r $gentop" + $run ${rm}r "$gentop" + $show "$mkdir $gentop" + $run $mkdir "$gentop" + status=$? + if test "$status" -ne 0 && test ! -d "$gentop"; then + exit $status + fi + generated="$generated $gentop" + + for xlib in $convenience; do + # Extract the objects. + case $xlib in + [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;; + *) xabs=`pwd`"/$xlib" ;; + esac + xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'` + xdir="$gentop/$xlib" + + $show "${rm}r $xdir" + $run ${rm}r "$xdir" + $show "$mkdir $xdir" + $run $mkdir "$xdir" + status=$? + if test "$status" -ne 0 && test ! -d "$xdir"; then + exit $status + fi + # We will extract separately just the conflicting names and we will no + # longer touch any unique names. It is faster to leave these extract + # automatically by $AR in one run. + $show "(cd $xdir && $AR x $xabs)" + $run eval "(cd \$xdir && $AR x \$xabs)" || exit $? + if ($AR t "$xabs" | sort | sort -uc >/dev/null 2>&1); then + : + else + $echo "$modename: warning: object name conflicts; renaming object files" 1>&2 + $echo "$modename: warning: to ensure that they will not overwrite" 1>&2 + $AR t "$xabs" | sort | uniq -cd | while read -r count name + do + i=1 + while test "$i" -le "$count" + do + # Put our $i before any first dot (extension) + # Never overwrite any file + name_to="$name" + while test "X$name_to" = "X$name" || test -f "$xdir/$name_to" + do + name_to=`$echo "X$name_to" | $Xsed -e "s/\([^.]*\)/\1-$i/"` + done + $show "(cd $xdir && $AR xN $i $xabs '$name' && $mv '$name' '$name_to')" + $run eval "(cd \$xdir && $AR xN $i \$xabs '$name' && $mv '$name' '$name_to')" || exit $? + i=`expr $i + 1` + done + done + fi + + libobjs="$libobjs "`find $xdir -name \*.$objext -print -o -name \*.lo -print | $NL2SP` + done + fi + fi + + if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then + eval flag=\"$thread_safe_flag_spec\" + linker_flags="$linker_flags $flag" + fi + + # Make a backup of the uninstalled library when relinking + if test "$mode" = relink; then + $run eval '(cd $output_objdir && $rm ${realname}U && $mv $realname ${realname}U)' || exit $? + fi + + # Add all flags from the command line. We here create a library, + # but those flags were only added to compile_command and + # finalize_command, which are only used when creating executables. + # So do it by hand here. + compiler_flags="$compiler_flags $add_flags" + # Only add it to commands which use CC, instead of LD, i.e. + # only to $compiler_flags + #linker_flags="$linker_flags $add_flags" + + # Do each of the archive commands. + if test "$module" = yes && test -n "$module_cmds" ; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + eval cmds=\"$module_expsym_cmds\" + else + eval cmds=\"$module_cmds\" + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + eval cmds=\"$archive_expsym_cmds\" + else + eval cmds=\"$archive_cmds\" + fi + fi + + if test "X$skipped_export" != "X:" && len=`expr "X$cmds" : ".*"` && + test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then + : + else + # The command line is too long to link in one step, link piecewise. + $echo "creating reloadable object files..." + + # 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 + + # Clear the reloadable object creation command queue and + # initialize k to one. + test_cmds= + concat_cmds= + objlist= + delfiles= + last_robj= + k=1 + output=$output_objdir/$save_output-${k}.$objext + # Loop over the list of objects to be linked. + for obj in $save_libobjs + do + eval test_cmds=\"$reload_cmds $objlist $last_robj\" + if test "X$objlist" = X || + { len=`expr "X$test_cmds" : ".*"` && + test "$len" -le "$max_cmd_len"; }; then + objlist="$objlist $obj" + else + # The command $test_cmds is almost too long, add a + # command to the queue. + if test "$k" -eq 1 ; then + # The first file doesn't have a previous command to add. + eval concat_cmds=\"$reload_cmds $objlist $last_robj\" + else + # All subsequent reloadable object files will link in + # the last one created. + eval concat_cmds=\"\$concat_cmds~$reload_cmds $objlist $last_robj\" + fi + last_robj=$output_objdir/$save_output-${k}.$objext + k=`expr $k + 1` + output=$output_objdir/$save_output-${k}.$objext + objlist=$obj + len=1 + 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~ + eval concat_cmds=\"\${concat_cmds}$reload_cmds $objlist $last_robj\" + + if ${skipped_export-false}; then + $show "generating symbol list for \`$libname.la'" + export_symbols="$output_objdir/$libname.exp" + $run $rm $export_symbols + libobjs=$output + # Append the command to create the export file. + eval concat_cmds=\"\$concat_cmds~$export_symbols_cmds\" + fi + + # Set up a command to remove the reloadale object files + # after they are used. + i=0 + while test "$i" -lt "$k" + do + i=`expr $i + 1` + delfiles="$delfiles $output_objdir/$save_output-${i}.$objext" + done + + $echo "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" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + + 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\" + fi + # Expand the library linking commands again to reset the + # value of $libobjs for piecewise linking. + + # Do each of the archive commands. + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + eval cmds=\"$archive_expsym_cmds\" + else + eval cmds=\"$archive_cmds\" + fi + + # Append the command to remove the reloadable object files + # to the just-reset $cmds. + eval cmds=\"\$cmds~$rm $delfiles\" + fi + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + + # Restore the uninstalled library and exit + if test "$mode" = relink; then + $run eval '(cd $output_objdir && $rm ${realname}T && $mv $realname ${realname}T && $mv "$realname"U $realname)' || exit $? + exit 0 + fi + + # Create links to the real library. + for linkname in $linknames; do + if test "$realname" != "$linkname"; then + $show "(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)" + $run 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 "$module" = yes || test "$export_dynamic" = yes; then + # On all known operating systems, these are identical. + dlname="$soname" + fi + fi + ;; + + obj) + if test -n "$deplibs"; then + $echo "$modename: warning: \`-l' and \`-L' are ignored for objects" 1>&2 + fi + + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + $echo "$modename: warning: \`-dlopen' is ignored for objects" 1>&2 + fi + + if test -n "$rpath"; then + $echo "$modename: warning: \`-rpath' is ignored for objects" 1>&2 + fi + + if test -n "$xrpath"; then + $echo "$modename: warning: \`-R' is ignored for objects" 1>&2 + fi + + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info' is ignored for objects" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for objects" 1>&2 + fi + + case $output in + *.lo) + if test -n "$objs$old_deplibs"; then + $echo "$modename: cannot build library object \`$output' from non-libtool objects" 1>&2 + exit 1 + fi + libobj="$output" + obj=`$echo "X$output" | $Xsed -e "$lo2o"` + ;; + *) + libobj= + obj="$output" + ;; + esac + + # Delete the old objects. + $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= + # reload_cmds runs $LD directly, so let us get rid of + # -Wl from whole_archive_flag_spec + wl= + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec"; then + eval reload_conv_objs=\"\$reload_objs $whole_archive_flag_spec\" + else + gentop="$output_objdir/${obj}x" + $show "${rm}r $gentop" + $run ${rm}r "$gentop" + $show "$mkdir $gentop" + $run $mkdir "$gentop" + status=$? + if test "$status" -ne 0 && test ! -d "$gentop"; then + exit $status + fi + generated="$generated $gentop" + + for xlib in $convenience; do + # Extract the objects. + case $xlib in + [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;; + *) xabs=`pwd`"/$xlib" ;; + esac + xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'` + xdir="$gentop/$xlib" + + $show "${rm}r $xdir" + $run ${rm}r "$xdir" + $show "$mkdir $xdir" + $run $mkdir "$xdir" + status=$? + if test "$status" -ne 0 && test ! -d "$xdir"; then + exit $status + fi + # We will extract separately just the conflicting names and we will no + # longer touch any unique names. It is faster to leave these extract + # automatically by $AR in one run. + $show "(cd $xdir && $AR x $xabs)" + $run eval "(cd \$xdir && $AR x \$xabs)" || exit $? + if ($AR t "$xabs" | sort | sort -uc >/dev/null 2>&1); then + : + else + $echo "$modename: warning: object name conflicts; renaming object files" 1>&2 + $echo "$modename: warning: to ensure that they will not overwrite" 1>&2 + $AR t "$xabs" | sort | uniq -cd | while read -r count name + do + i=1 + while test "$i" -le "$count" + do + # Put our $i before any first dot (extension) + # Never overwrite any file + name_to="$name" + while test "X$name_to" = "X$name" || test -f "$xdir/$name_to" + do + name_to=`$echo "X$name_to" | $Xsed -e "s/\([^.]*\)/\1-$i/"` + done + $show "(cd $xdir && $AR xN $i $xabs '$name' && $mv '$name' '$name_to')" + $run eval "(cd \$xdir && $AR xN $i \$xabs '$name' && $mv '$name' '$name_to')" || exit $? + i=`expr $i + 1` + done + done + fi + + reload_conv_objs="$reload_objs "`find $xdir -name \*.$objext -print -o -name \*.lo -print | $NL2SP` + done + fi + fi + + # Create the old-style object. + reload_objs="$objs$old_deplibs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test + + output="$obj" + eval cmds=\"$reload_cmds\" + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + + # Exit if we aren't doing a library object file. + if test -z "$libobj"; then + if test -n "$gentop"; then + $show "${rm}r $gentop" + $run ${rm}r $gentop + fi + + exit 0 + fi + + if test "$build_libtool_libs" != yes; then + if test -n "$gentop"; then + $show "${rm}r $gentop" + $run ${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" + # $run eval "echo timestamp > $libobj" || exit $? + exit 0 + fi + + if test -n "$pic_flag" || test "$pic_mode" != default; then + # Only do commands if we really have different PIC objects. + reload_objs="$libobjs $reload_conv_objs" + output="$libobj" + eval cmds=\"$reload_cmds\" + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + fi + + if test -n "$gentop"; then + $show "${rm}r $gentop" + $run ${rm}r $gentop + fi + + exit 0 + ;; + + prog) + case $host in + *cygwin*) output=`$echo $output | ${SED} -e 's,.exe$,,;s,$,.exe,'` ;; + esac + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info' is ignored for programs" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for programs" 1>&2 + fi + + if test "$preload" = yes; then + if test "$dlopen_support" = unknown && test "$dlopen_self" = unknown && + test "$dlopen_self_static" = unknown; then + $echo "$modename: warning: \`AC_LIBTOOL_DLOPEN' not used. Assuming no dlopen support." + fi + fi + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library is the System framework + compile_deplibs=`$echo "X $compile_deplibs" | $Xsed -e 's/ -lc / -framework System /'` + finalize_deplibs=`$echo "X $finalize_deplibs" | $Xsed -e 's/ -lc / -framework System /'` + ;; + esac + + case $host in + *darwin*) + # Don't allow lazy linking, it breaks C++ global constructors + if test "$tagname" = CXX ; then + compile_command="$compile_command ${wl}-bind_at_load" + finalize_command="$finalize_command ${wl}-bind_at_load" + fi + ;; + esac + + compile_command="$compile_command $compile_deplibs" + finalize_command="$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 "*) ;; + *) finalize_rpath="$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"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + rpath="$rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) perm_rpath="$perm_rpath $libdir" ;; + esac + fi + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) + case :$dllsearchpath: in + *":$libdir:"*) ;; + *) dllsearchpath="$dllsearchpath:$libdir";; + 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"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + rpath="$rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$finalize_perm_rpath " in + *" $libdir "*) ;; + *) finalize_perm_rpath="$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 "$build_old_libs" = yes; then + # Transform all the library objects into standard objects. + compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + fi + + dlsyms= + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + if test -n "$NM" && test -n "$global_symbol_pipe"; then + dlsyms="${outputname}S.c" + else + $echo "$modename: not configured to extract global symbols from dlpreopened files" 1>&2 + fi + fi + + if test -n "$dlsyms"; then + case $dlsyms in + "") ;; + *.c) + # Discover the nlist of each of the dlfiles. + nlist="$output_objdir/${outputname}.nm" + + $show "$rm $nlist ${nlist}S ${nlist}T" + $run $rm "$nlist" "${nlist}S" "${nlist}T" + + # Parse the name list into a source file. + $show "creating $output_objdir/$dlsyms" + + test -z "$run" && $echo > "$output_objdir/$dlsyms" "\ +/* $dlsyms - symbol resolution table for \`$outputname' dlsym emulation. */ +/* Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP */ + +#ifdef __cplusplus +extern \"C\" { +#endif + +/* Prevent the only kind of declaration conflicts we can make. */ +#define lt_preloaded_symbols some_other_symbol + +/* External symbol declarations for the compiler. */\ +" + + if test "$dlself" = yes; then + $show "generating symbol list for \`$output'" + + test -z "$run" && $echo ': @PROGRAM@ ' > "$nlist" + + # Add our own program objects to the symbol list. + progfiles=`$echo "X$objs$old_deplibs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + for arg in $progfiles; do + $show "extracting global C symbols from \`$arg'" + $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" + done + + if test -n "$exclude_expsyms"; then + $run eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' + $run eval '$mv "$nlist"T "$nlist"' + fi + + if test -n "$export_symbols_regex"; then + $run eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' + $run eval '$mv "$nlist"T "$nlist"' + fi + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + export_symbols="$output_objdir/$output.exp" + $run $rm $export_symbols + $run eval "${SED} -n -e '/^: @PROGRAM@$/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' + else + $run eval "${SED} -e 's/\([][.*^$]\)/\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$output.exp"' + $run eval 'grep -f "$output_objdir/$output.exp" < "$nlist" > "$nlist"T' + $run eval 'mv "$nlist"T "$nlist"' + fi + fi + + for arg in $dlprefiles; do + $show "extracting global C symbols from \`$arg'" + name=`$echo "$arg" | ${SED} -e 's%^.*/%%'` + $run eval '$echo ": $name " >> "$nlist"' + $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" + done + + if test -z "$run"; then + # 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 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/$dlsyms"' + else + $echo '/* NONE */' >> "$output_objdir/$dlsyms" + fi + + $echo >> "$output_objdir/$dlsyms" "\ + +#undef lt_preloaded_symbols + +#if defined (__STDC__) && __STDC__ +# define lt_ptr void * +#else +# define lt_ptr char * +# define const +#endif + +/* The mapping between symbol names and symbols. */ +const struct { + const char *name; + lt_ptr address; +} +lt_preloaded_symbols[] = +{\ +" + + eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$dlsyms" + + $echo >> "$output_objdir/$dlsyms" "\ + {0, (lt_ptr) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif\ +" + fi + + pic_flag_for_symtable= + 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*) + case "$compile_command " in + *" -static "*) ;; + *) pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND";; + esac;; + *-*-hpux*) + case "$compile_command " in + *" -static "*) ;; + *) pic_flag_for_symtable=" $pic_flag";; + esac + esac + + # Now compile the dynamic symbol file. + $show "(cd $output_objdir && $LTCC -c$no_builtin_flag$pic_flag_for_symtable \"$dlsyms\")" + $run eval '(cd $output_objdir && $LTCC -c$no_builtin_flag$pic_flag_for_symtable "$dlsyms")' || exit $? + + # Clean up the generated files. + $show "$rm $output_objdir/$dlsyms $nlist ${nlist}S ${nlist}T" + $run $rm "$output_objdir/$dlsyms" "$nlist" "${nlist}S" "${nlist}T" + + # Transform the symbol file into the correct name. + compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"` + finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"` + ;; + *) + $echo "$modename: unknown suffix for \`$dlsyms'" 1>&2 + exit 1 + ;; + 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 "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"` + finalize_command=`$echo "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"` + fi + + # AIX runtime linking requires linking programs with -Wl,-brtl and libs with -Wl,-G + # Also add -bnolibpath to the beginning of the link line, to clear the hardcoded runpath. + # Otherwise, things like the -L path to libgcc.a are accidentally hardcoded by ld. + # This does not apply on AIX for ia64, which uses a SysV linker. + case "$host" in + ia64-*-aix5*) ;; + *-*-aix4* | *-*-aix5*) + compile_command=`$echo "X$compile_command $wl-brtl" | $Xsed -e "s/\$CC/\$CC $wl-bnolibpath/1"` + finalize_command=`$echo "X$finalize_command $wl-brtl" | $Xsed -e "s/\$CC/\$CC $wl-bnolibpath/1"` ;; + esac + + if test "$need_relink" = no || test "$build_libtool_libs" != yes; then + # Replace the output file specification. + compile_command=`$echo "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` + link_command="$compile_command$compile_rpath" + + # We have no uninstalled library dependencies, so finalize right now. + $show "$link_command" + $run eval "$link_command" + status=$? + + # Delete the generated files. + if test -n "$dlsyms"; then + $show "$rm $output_objdir/${outputname}S.${objext}" + $run $rm "$output_objdir/${outputname}S.${objext}" + fi + + exit $status + fi + + if test -n "$shlibpath_var"; then + # We should set the shlibpath_var + rpath= + for dir in $temp_rpath; do + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) + # Absolute path. + rpath="$rpath$dir:" + ;; + *) + # Relative path: add a thisdir entry. + rpath="$rpath\$thisdir/$dir:" + ;; + esac + done + temp_rpath="$rpath" + fi + + 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 + rpath="$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 + rpath="$rpath$dir:" + done + finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + fi + + if test "$no_install" = yes; 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 "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` + # Delete the old output file. + $run $rm $output + # Link the executable and exit + $show "$link_command" + $run eval "$link_command" || exit $? + exit 0 + fi + + if test "$hardcode_action" = relink; then + # Fast installation is not supported + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + + $echo "$modename: warning: this platform does not like uninstalled shared libraries" 1>&2 + $echo "$modename: \`$output' will be relinked during installation" 1>&2 + else + if test "$fast_install" != no; then + link_command="$finalize_var$compile_command$finalize_rpath" + if test "$fast_install" = yes; then + relink_command=`$echo "X$compile_var$compile_command$compile_rpath" | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g'` + else + # fast_install is set to needless + relink_command= + fi + else + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + fi + fi + + # Replace the output file specification. + link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` + + # Delete the old output files. + $run $rm $output $output_objdir/$outputname $output_objdir/lt-$outputname + + $show "$link_command" + $run eval "$link_command" || exit $? + + # Now create the wrapper script. + $show "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}\" || 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 + var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"` + relink_command="$var=\"$var_value\"; export $var; $relink_command" + fi + done + relink_command="(cd `pwd`; $relink_command)" + relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"` + fi + + # Quote $echo for shipping. + if test "X$echo" = "X$SHELL $0 --fallback-echo"; then + case $0 in + [\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $0 --fallback-echo";; + *) qecho="$SHELL `pwd`/$0 --fallback-echo";; + esac + qecho=`$echo "X$qecho" | $Xsed -e "$sed_quote_subst"` + else + qecho=`$echo "X$echo" | $Xsed -e "$sed_quote_subst"` + fi + + # Only actually do things if our run command is non-null. + if test -z "$run"; then + # win32 will think the script is a binary if it has + # a .exe suffix, so we strip it off here. + case $output in + *.exe) output=`$echo $output|${SED} 's,.exe$,,'` ;; + esac + # test for cygwin because mv fails w/o .exe extensions + case $host in + *cygwin*) + exeext=.exe + outputname=`$echo $outputname|${SED} 's,.exe$,,'` ;; + *) exeext= ;; + esac + case $host in + *cygwin* | *mingw* ) + cwrappersource=`$echo ${objdir}/lt-${output}.c` + cwrapper=`$echo ${output}.exe` + $rm $cwrappersource $cwrapper + trap "$rm $cwrappersource $cwrapper; exit 1" 1 2 15 + + cat > $cwrappersource <> $cwrappersource<<"EOF" +#include +#include +#include +#include +#include +#include + +#if defined(PATH_MAX) +# define LT_PATHMAX PATH_MAX +#elif defined(MAXPATHLEN) +# define LT_PATHMAX MAXPATHLEN +#else +# define LT_PATHMAX 1024 +#endif + +#ifndef DIR_SEPARATOR +#define DIR_SEPARATOR '/' +#endif + +#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \ + defined (__OS2__) +#define HAVE_DOS_BASED_FILE_SYSTEM +#ifndef DIR_SEPARATOR_2 +#define DIR_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 */ + +#define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) +#define XFREE(stale) do { \ + if (stale) { free ((void *) stale); stale = 0; } \ +} while (0) + +const char *program_name = NULL; + +void * xmalloc (size_t num); +char * xstrdup (const char *string); +char * basename (const char *name); +char * fnqualify(const char *path); +char * strendzap(char *str, const char *pat); +void lt_fatal (const char *message, ...); + +int +main (int argc, char *argv[]) +{ + char **newargz; + int i; + + program_name = (char *) xstrdup ((char *) basename (argv[0])); + newargz = XMALLOC(char *, argc+2); +EOF + + cat >> $cwrappersource <> $cwrappersource <<"EOF" + newargz[1] = fnqualify(argv[0]); + /* we know the script has the same name, without the .exe */ + /* so make sure newargz[1] doesn't end in .exe */ + strendzap(newargz[1],".exe"); + for (i = 1; i < argc; i++) + newargz[i+1] = xstrdup(argv[i]); + newargz[argc+1] = NULL; +EOF + + cat >> $cwrappersource <> $cwrappersource <<"EOF" +} + +void * +xmalloc (size_t num) +{ + void * p = (void *) malloc (num); + if (!p) + lt_fatal ("Memory exhausted"); + + return p; +} + +char * +xstrdup (const char *string) +{ + return string ? strcpy ((char *) xmalloc (strlen (string) + 1), string) : NULL +; +} + +char * +basename (const char *name) +{ + const char *base; + +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + /* Skip over the disk name in MSDOS pathnames. */ + if (isalpha (name[0]) && name[1] == ':') + name += 2; +#endif + + for (base = name; *name; name++) + if (IS_DIR_SEPARATOR (*name)) + base = name + 1; + return (char *) base; +} + +char * +fnqualify(const char *path) +{ + size_t size; + char *p; + char tmp[LT_PATHMAX + 1]; + + assert(path != NULL); + + /* Is it qualified already? */ +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + if (isalpha (path[0]) && path[1] == ':') + return xstrdup (path); +#endif + if (IS_DIR_SEPARATOR (path[0])) + return xstrdup (path); + + /* prepend the current directory */ + /* doesn't handle '~' */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal ("getcwd failed"); + size = strlen(tmp) + 1 + strlen(path) + 1; /* +2 for '/' and '\0' */ + p = XMALLOC(char, size); + sprintf(p, "%s%c%s", tmp, DIR_SEPARATOR, path); + return p; +} + +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 (strcmp(str, pat) == 0) + *str = '\0'; + } + return str; +} + +static void +lt_error_core (int exit_status, const char * mode, + const char * message, va_list ap) +{ + fprintf (stderr, "%s: %s: ", program_name, mode); + vfprintf (stderr, message, ap); + fprintf (stderr, ".\n"); + + if (exit_status >= 0) + exit (exit_status); +} + +void +lt_fatal (const char *message, ...) +{ + va_list ap; + va_start (ap, message); + lt_error_core (EXIT_FAILURE, "FATAL", message, ap); + va_end (ap); +} +EOF + # we should really use a build-platform specific compiler + # here, but OTOH, the wrappers (shell script and this C one) + # are only useful if you want to execute the "real" binary. + # Since the "real" binary is built for $host, then this + # wrapper might as well be built for $host, too. + $run $LTCC -s -o $cwrapper $cwrappersource + ;; + esac + $rm $output + trap "$rm $output; exit 1" 1 2 15 + + $echo > $output "\ +#! $SHELL + +# $output - temporary wrapper script for $objdir/$outputname +# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP +# +# 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. +Xsed='${SED} -e 1s/^X//' +sed_quote_subst='$sed_quote_subst' + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +if test \"\${CDPATH+set}\" = set; then CDPATH=:; export CDPATH; fi + +relink_command=\"$relink_command\" + +# This environment variable determines our operation mode. +if test \"\$libtool_install_magic\" = \"$magic\"; then + # install mode needs the following variable: + 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 + echo=\"$qecho\" + file=\"\$0\" + # Make sure echo works. + if test \"X\$1\" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift + elif test \"X\`(\$echo '\t') 2>/dev/null\`\" = 'X\t'; then + # Yippee, \$echo works! + : + else + # Restart under the correct shell, and then maybe \$echo will work. + exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"} + fi + fi\ +" + $echo >> $output "\ + + # Find the directory that this script lives in. + thisdir=\`\$echo \"X\$file\" | \$Xsed -e '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 \"X\$file\" | \$Xsed -e '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 \"X\$file\" | \$Xsed -e 's%^.*/%%'\` + file=\`ls -ld \"\$thisdir/\$file\" | ${SED} -n 's/.*-> //p'\` + done + + # Try to get the absolute directory name. + absdir=\`cd \"\$thisdir\" && pwd\` + test -n \"\$absdir\" && thisdir=\"\$absdir\" +" + + if test "$fast_install" = yes; then + $echo >> $output "\ + 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 >> $output "\ + + # 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 >> $output "\ + program='$outputname' + progdir=\"\$thisdir/$objdir\" +" + fi + + $echo >> $output "\ + + if test -f \"\$progdir/\$program\"; then" + + # Export our shlibpath_var if we have one. + if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then + $echo >> $output "\ + # 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 \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\` + + export $shlibpath_var +" + fi + + # fixup the dll searchpath if we need to. + if test -n "$dllsearchpath"; then + $echo >> $output "\ + # Add the dll search path components to the executable PATH + PATH=$dllsearchpath:\$PATH +" + fi + + $echo >> $output "\ + if test \"\$libtool_execute_magic\" != \"$magic\"; then + # Run the actual program with our arguments. +" + case $host in + # Backslashes separate directories on plain windows + *-*-mingw | *-*-os2*) + $echo >> $output "\ + exec \$progdir\\\\\$program \${1+\"\$@\"} +" + ;; + + *) + $echo >> $output "\ + exec \$progdir/\$program \${1+\"\$@\"} +" + ;; + esac + $echo >> $output "\ + \$echo \"\$0: cannot exec \$program \${1+\"\$@\"}\" + exit 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\ +" + chmod +x $output + fi + exit 0 + ;; + esac + + # See if we need to build an old-fashioned archive. + for oldlib in $oldlibs; do + + if test "$build_libtool_libs" = convenience; then + oldobjs="$libobjs_save" + addlibs="$convenience" + build_libtool_libs=no + else + if test "$build_libtool_libs" = module; then + oldobjs="$libobjs_save" + build_libtool_libs=no + else + oldobjs="$old_deplibs $non_pic_objects" + fi + addlibs="$old_convenience" + fi + + if test -n "$addlibs"; then + gentop="$output_objdir/${outputname}x" + $show "${rm}r $gentop" + $run ${rm}r "$gentop" + $show "$mkdir $gentop" + $run $mkdir "$gentop" + status=$? + if test "$status" -ne 0 && test ! -d "$gentop"; then + exit $status + fi + generated="$generated $gentop" + + # Add in members from convenience archives. + for xlib in $addlibs; do + # Extract the objects. + case $xlib in + [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;; + *) xabs=`pwd`"/$xlib" ;; + esac + xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'` + xdir="$gentop/$xlib" + + $show "${rm}r $xdir" + $run ${rm}r "$xdir" + $show "$mkdir $xdir" + $run $mkdir "$xdir" + status=$? + if test "$status" -ne 0 && test ! -d "$xdir"; then + exit $status + fi + # We will extract separately just the conflicting names and we will no + # longer touch any unique names. It is faster to leave these extract + # automatically by $AR in one run. + $show "(cd $xdir && $AR x $xabs)" + $run eval "(cd \$xdir && $AR x \$xabs)" || exit $? + if ($AR t "$xabs" | sort | sort -uc >/dev/null 2>&1); then + : + else + $echo "$modename: warning: object name conflicts; renaming object files" 1>&2 + $echo "$modename: warning: to ensure that they will not overwrite" 1>&2 + $AR t "$xabs" | sort | uniq -cd | while read -r count name + do + i=1 + while test "$i" -le "$count" + do + # Put our $i before any first dot (extension) + # Never overwrite any file + name_to="$name" + while test "X$name_to" = "X$name" || test -f "$xdir/$name_to" + do + name_to=`$echo "X$name_to" | $Xsed -e "s/\([^.]*\)/\1-$i/"` + done + $show "(cd $xdir && $AR xN $i $xabs '$name' && $mv '$name' '$name_to')" + $run eval "(cd \$xdir && $AR xN $i \$xabs '$name' && $mv '$name' '$name_to')" || exit $? + i=`expr $i + 1` + done + done + fi + + oldobjs="$oldobjs "`find $xdir -name \*.${objext} -print -o -name \*.lo -print | $NL2SP` + done + fi + + compiler_flags="$compiler_flags $add_flags" + + # Do each command in the archive commands. + if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then + eval cmds=\"$old_archive_from_new_cmds\" + else + eval cmds=\"$old_archive_cmds\" + + if len=`expr "X$cmds" : ".*"` && + test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then + : + else + # the command line is too long to link in one step, link in parts + $echo "using piecewise archive linking..." + save_RANLIB=$RANLIB + RANLIB=: + objlist= + concat_cmds= + save_oldobjs=$oldobjs + # GNU ar 2.10+ was changed to match POSIX; thus no paths are + # encoded into archives. This makes 'ar r' malfunction in + # this piecewise linking case whenever conflicting object + # names appear in distinct ar calls; check, warn and compensate. + if (for obj in $save_oldobjs + do + $echo "X$obj" | $Xsed -e 's%^.*/%%' + done | sort | sort -uc >/dev/null 2>&1); then + : + else + $echo "$modename: warning: object name conflicts; overriding AR_FLAGS to 'cq'" 1>&2 + $echo "$modename: warning: to ensure that POSIX-compatible ar will work" 1>&2 + AR_FLAGS=cq + fi + # Is there a better way of finding the last object in the list? + for obj in $save_oldobjs + do + last_oldobj=$obj + done + for obj in $save_oldobjs + do + oldobjs="$objlist $obj" + objlist="$objlist $obj" + eval test_cmds=\"$old_archive_cmds\" + if len=`expr "X$test_cmds" : ".*"` && + test "$len" -le "$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= + fi + done + RANLIB=$save_RANLIB + oldobjs=$objlist + if test "X$oldobjs" = "X" ; then + eval cmds=\"\$concat_cmds\" + else + eval cmds=\"\$concat_cmds~$old_archive_cmds\" + fi + fi + fi + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + done + + if test -n "$generated"; then + $show "${rm}r$generated" + $run ${rm}r$generated + fi + + # Now create the libtool archive. + case $output in + *.la) + old_library= + test "$build_old_libs" = yes && old_library="$libname.$libext" + $show "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}\" || 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 + var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"` + relink_command="$var=\"$var_value\"; export $var; $relink_command" + fi + done + # Quote the link command for shipping. + relink_command="(cd `pwd`; $SHELL $0 --mode=relink $libtool_args @inst_prefix_dir@)" + relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"` + if test "$hardcode_automatic" = yes ; then + relink_command= + fi + # Only create the output if not a dry run. + if test -z "$run"; then + for installed in no yes; do + if test "$installed" = yes; 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) + name=`$echo "X$deplib" | $Xsed -e 's%^.*/%%'` + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + if test -z "$libdir"; then + $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2 + exit 1 + fi + newdependency_libs="$newdependency_libs $libdir/$name" + ;; + *) newdependency_libs="$newdependency_libs $deplib" ;; + esac + done + dependency_libs="$newdependency_libs" + newdlfiles= + for lib in $dlfiles; do + name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + if test -z "$libdir"; then + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + exit 1 + fi + newdlfiles="$newdlfiles $libdir/$name" + done + dlfiles="$newdlfiles" + newdlprefiles= + for lib in $dlprefiles; do + name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + if test -z "$libdir"; then + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + exit 1 + fi + newdlprefiles="$newdlprefiles $libdir/$name" + done + dlprefiles="$newdlprefiles" + fi + $rm $output + # place dlname in correct position for cygwin + tdlname=$dlname + case $host,$output,$installed,$module,$dlname in + *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;; + esac + $echo > $output "\ +# $outputname - a libtool library file +# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP +# +# 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' + +# Libraries that this one depends upon. +dependency_libs='$dependency_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 "$installed" = no && test "$need_relink" = yes && test "$fast_install" = no; then + $echo >> $output "\ +relink_command=\"$relink_command\"" + fi + done + fi + + # Do a symbolic link so that the libtool archive can be found in + # LD_LIBRARY_PATH before the program is installed. + $show "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)" + $run eval '(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)' || exit $? + ;; + esac + exit 0 + ;; + + # libtool install mode + install) + modename="$modename: install" + + # There may be an optional sh(1) argument at the beginning of + # install_prog (especially on Windows NT). + if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || + # Allow the use of GNU shtool's install command. + $echo "X$nonopt" | $Xsed | grep shtool > /dev/null; then + # Aesthetically quote it. + arg=`$echo "X$nonopt" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) + arg="\"$arg\"" + ;; + esac + install_prog="$arg " + arg="$1" + shift + else + install_prog= + arg="$nonopt" + fi + + # The real first argument should be the name of the installation program. + # Aesthetically quote it. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) + arg="\"$arg\"" + ;; + esac + install_prog="$install_prog$arg" + + # We need to accept at least all the BSD install flags. + dest= + files= + opts= + prev= + install_type= + isdir=no + stripme= + for arg + do + if test -n "$dest"; then + files="$files $dest" + dest="$arg" + continue + fi + + case $arg in + -d) isdir=yes ;; + -f) prev="-f" ;; + -g) prev="-g" ;; + -m) prev="-m" ;; + -o) prev="-o" ;; + -s) + stripme=" -s" + continue + ;; + -*) ;; + + *) + # If the previous option needed an argument, then skip it. + if test -n "$prev"; then + prev= + else + dest="$arg" + continue + fi + ;; + esac + + # Aesthetically quote the argument. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) + arg="\"$arg\"" + ;; + esac + install_prog="$install_prog $arg" + done + + if test -z "$install_prog"; then + $echo "$modename: you must specify an install program" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + if test -n "$prev"; then + $echo "$modename: the \`$prev' option requires an argument" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + if test -z "$files"; then + if test -z "$dest"; then + $echo "$modename: no file or destination specified" 1>&2 + else + $echo "$modename: you must specify a destination" 1>&2 + fi + $echo "$help" 1>&2 + exit 1 + fi + + # Strip any trailing slash from the destination. + dest=`$echo "X$dest" | $Xsed -e 's%/$%%'` + + # Check to see that the destination is a directory. + test -d "$dest" && isdir=yes + if test "$isdir" = yes; then + destdir="$dest" + destname= + else + destdir=`$echo "X$dest" | $Xsed -e 's%/[^/]*$%%'` + test "X$destdir" = "X$dest" && destdir=. + destname=`$echo "X$dest" | $Xsed -e 's%^.*/%%'` + + # Not a directory, so check to see that there is only one file specified. + set dummy $files + if test "$#" -gt 2; then + $echo "$modename: \`$dest' is not a directory" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + fi + case $destdir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + for file in $files; do + case $file in + *.lo) ;; + *) + $echo "$modename: \`$destdir' must be an absolute directory name" 1>&2 + $echo "$help" 1>&2 + exit 1 + ;; + 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. + staticlibs="$staticlibs $file" + ;; + + *.la) + # Check to see that this really is a libtool archive. + if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : + else + $echo "$modename: \`$file' is not a valid libtool archive" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + library_names= + old_library= + relink_command= + # If there is no directory component, then add one. + case $file in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + # Add the libdir to current_libdirs if it is the destination. + if test "X$destdir" = "X$libdir"; then + case "$current_libdirs " in + *" $libdir "*) ;; + *) current_libdirs="$current_libdirs $libdir" ;; + esac + else + # Note the libdir as a future libdir. + case "$future_libdirs " in + *" $libdir "*) ;; + *) future_libdirs="$future_libdirs $libdir" ;; + esac + fi + + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`/ + test "X$dir" = "X$file/" && dir= + dir="$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 "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. + if test "$inst_prefix_dir" = "$destdir"; then + $echo "$modename: error: cannot install \`$file' to a directory not ending in $libdir" 1>&2 + exit 1 + fi + + 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 + + $echo "$modename: warning: relinking \`$file'" 1>&2 + $show "$relink_command" + if $run eval "$relink_command"; then : + else + $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2 + exit 1 + fi + fi + + # See the names of the shared library. + set dummy $library_names + if test -n "$2"; then + realname="$2" + shift + shift + + srcname="$realname" + test -n "$relink_command" && srcname="$realname"T + + # Install the shared library and build the symlinks. + $show "$install_prog $dir/$srcname $destdir/$realname" + $run eval "$install_prog $dir/$srcname $destdir/$realname" || exit $? + if test -n "$stripme" && test -n "$striplib"; then + $show "$striplib $destdir/$realname" + $run eval "$striplib $destdir/$realname" || exit $? + fi + + if test "$#" -gt 0; then + # Delete the old symlinks, and create new ones. + for linkname + do + if test "$linkname" != "$realname"; then + $show "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)" + $run eval "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)" + fi + done + fi + + # Do each command in the postinstall commands. + lib="$destdir/$realname" + eval cmds=\"$postinstall_cmds\" + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + fi + + # Install the pseudo-library for information purposes. + name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + instname="$dir/$name"i + $show "$install_prog $instname $destdir/$name" + $run eval "$install_prog $instname $destdir/$name" || exit $? + + # Maybe install the static library, too. + test -n "$old_library" && staticlibs="$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 + destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + destfile="$destdir/$destfile" + fi + + # Deduce the name of the destination old-style object file. + case $destfile in + *.lo) + staticdest=`$echo "X$destfile" | $Xsed -e "$lo2o"` + ;; + *.$objext) + staticdest="$destfile" + destfile= + ;; + *) + $echo "$modename: cannot copy a libtool object to \`$destfile'" 1>&2 + $echo "$help" 1>&2 + exit 1 + ;; + esac + + # Install the libtool object if requested. + if test -n "$destfile"; then + $show "$install_prog $file $destfile" + $run eval "$install_prog $file $destfile" || exit $? + fi + + # Install the old object if enabled. + if test "$build_old_libs" = yes; then + # Deduce the name of the old-style object file. + staticobj=`$echo "X$file" | $Xsed -e "$lo2o"` + + $show "$install_prog $staticobj $staticdest" + $run eval "$install_prog \$staticobj \$staticdest" || exit $? + fi + exit 0 + ;; + + *) + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + 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 + file=`$echo $file|${SED} 's,.exe$,,'` + stripped_ext=".exe" + fi + ;; + esac + + # Do a test to see if this is really a libtool program. + case $host in + *cygwin*|*mingw*) + wrapper=`$echo $file | ${SED} -e 's,.exe$,,'` + ;; + *) + wrapper=$file + ;; + esac + if (${SED} -e '4q' $wrapper | grep "^# Generated by .*$PACKAGE")>/dev/null 2>&1; then + notinst_deplibs= + relink_command= + + # To insure that "foo" is sourced, and not "foo.exe", + # finese the cygwin/MSYS system by explicitly sourcing "foo." + # which disallows the automatic-append-.exe behavior. + case $build in + *cygwin* | *mingw*) wrapperdot=${wrapper}. ;; + *) wrapperdot=${wrapper} ;; + esac + # If there is no directory component, then add one. + case $file in + */* | *\\*) . ${wrapperdot} ;; + *) . ./${wrapperdot} ;; + esac + + # Check the variables that should have been set. + if test -z "$notinst_deplibs"; then + $echo "$modename: invalid libtool wrapper script \`$wrapper'" 1>&2 + exit 1 + fi + + finalize=yes + for lib in $notinst_deplibs; do + # Check to see that each library is installed. + libdir= + if test -f "$lib"; then + # If there is no directory component, then add one. + case $lib in + */* | *\\*) . $lib ;; + *) . ./$lib ;; + esac + fi + libfile="$libdir/"`$echo "X$lib" | $Xsed -e 's%^.*/%%g'` ### testsuite: skip nested quoting test + if test -n "$libdir" && test ! -f "$libfile"; then + $echo "$modename: warning: \`$lib' has not been installed in \`$libdir'" 1>&2 + finalize=no + fi + done + + relink_command= + # To insure that "foo" is sourced, and not "foo.exe", + # finese the cygwin/MSYS system by explicitly sourcing "foo." + # which disallows the automatic-append-.exe behavior. + case $build in + *cygwin* | *mingw*) wrapperdot=${wrapper}. ;; + *) wrapperdot=${wrapper} ;; + esac + # If there is no directory component, then add one. + case $file in + */* | *\\*) . ${wrapperdot} ;; + *) . ./${wrapperdot} ;; + esac + + outputname= + if test "$fast_install" = no && test -n "$relink_command"; then + if test "$finalize" = yes && test -z "$run"; then + tmpdir="/tmp" + test -n "$TMPDIR" && tmpdir="$TMPDIR" + tmpdir="$tmpdir/libtool-$$" + if $mkdir -p "$tmpdir" && chmod 700 "$tmpdir"; then : + else + $echo "$modename: error: cannot create temporary directory \`$tmpdir'" 1>&2 + continue + fi + file=`$echo "X$file$stripped_ext" | $Xsed -e 's%^.*/%%'` + outputname="$tmpdir/$file" + # Replace the output file specification. + relink_command=`$echo "X$relink_command" | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g'` + + $show "$relink_command" + if $run eval "$relink_command"; then : + else + $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2 + ${rm}r "$tmpdir" + continue + fi + file="$outputname" + else + $echo "$modename: warning: cannot relink \`$file'" 1>&2 + fi + else + # Install the binary that we compiled earlier. + file=`$echo "X$file$stripped_ext" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"` + fi + fi + + # remove .exe since cygwin /usr/bin/install will append another + # one anyways + case $install_prog,$host in + */usr/bin/install*,*cygwin*) + case $file:$destfile in + *.exe:*.exe) + # this is ok + ;; + *.exe:*) + destfile=$destfile.exe + ;; + *:*.exe) + destfile=`$echo $destfile | ${SED} -e 's,.exe$,,'` + ;; + esac + ;; + esac + $show "$install_prog$stripme $file $destfile" + $run eval "$install_prog\$stripme \$file \$destfile" || exit $? + test -n "$outputname" && ${rm}r "$tmpdir" + ;; + esac + done + + for file in $staticlibs; do + name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + + # Set up the ranlib parameters. + oldlib="$destdir/$name" + + $show "$install_prog $file $oldlib" + $run eval "$install_prog \$file \$oldlib" || exit $? + + if test -n "$stripme" && test -n "$striplib"; then + $show "$old_striplib $oldlib" + $run eval "$old_striplib $oldlib" || exit $? + fi + + # Do each command in the postinstall commands. + eval cmds=\"$old_postinstall_cmds\" + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + done + + if test -n "$future_libdirs"; then + $echo "$modename: warning: remember to run \`$progname --finish$future_libdirs'" 1>&2 + fi + + if test -n "$current_libdirs"; then + # Maybe just do a dry run. + test -n "$run" && current_libdirs=" -n$current_libdirs" + exec_cmd='$SHELL $0 --finish$current_libdirs' + else + exit 0 + fi + ;; + + # libtool finish mode + finish) + modename="$modename: finish" + libdirs="$nonopt" + admincmds= + + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then + for dir + do + libdirs="$libdirs $dir" + done + + for libdir in $libdirs; do + if test -n "$finish_cmds"; then + # Do each command in the finish commands. + eval cmds=\"$finish_cmds\" + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || admincmds="$admincmds + $cmd" + done + IFS="$save_ifs" + fi + if test -n "$finish_eval"; then + # Do the single finish_eval. + eval cmds=\"$finish_eval\" + $run eval "$cmds" || admincmds="$admincmds + $cmds" + fi + done + fi + + # Exit here if they wanted silent mode. + exit 0 + + $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" + $echo "more information, such as the ld(1) and ld.so(8) manual pages." + $echo "----------------------------------------------------------------------" + exit 0 + ;; + + # libtool execute mode + execute) + modename="$modename: execute" + + # The first argument is the command name. + cmd="$nonopt" + if test -z "$cmd"; then + $echo "$modename: you must specify a COMMAND" 1>&2 + $echo "$help" + exit 1 + fi + + # Handle -dlopen flags immediately. + for file in $execute_dlfiles; do + if test ! -f "$file"; then + $echo "$modename: \`$file' is not a file" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + dir= + case $file in + *.la) + # Check to see that this really is a libtool archive. + if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : + else + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + # Read the libtool library. + dlname= + library_names= + + # If there is no directory component, then add one. + case $file in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + # Skip this library if it cannot be dlopened. + if test -z "$dlname"; then + # Warn if it was a shared library. + test -n "$library_names" && $echo "$modename: warning: \`$file' was not linked with \`-export-dynamic'" + continue + fi + + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` + test "X$dir" = "X$file" && dir=. + + if test -f "$dir/$objdir/$dlname"; then + dir="$dir/$objdir" + else + $echo "$modename: cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" 1>&2 + exit 1 + fi + ;; + + *.lo) + # Just add the directory containing the .lo file. + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` + test "X$dir" = "X$file" && dir=. + ;; + + *) + $echo "$modename: warning \`-dlopen' is ignored for non-libtool libraries and objects" 1>&2 + 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 + -*) ;; + *) + # Do a test to see if this is really a libtool program. + if (${SED} -e '4q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + # If there is no directory component, then add one. + case $file in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + # Transform arg to wrapped name. + file="$progdir/$program" + fi + ;; + esac + # Quote arguments (to preserve shell metacharacters). + file=`$echo "X$file" | $Xsed -e "$sed_quote_subst"` + args="$args \"$file\"" + done + + if test -z "$run"; then + if test -n "$shlibpath_var"; then + # Export the shlibpath_var. + eval "export $shlibpath_var" + fi + + # Restore saved environment variables + if test "${save_LC_ALL+set}" = set; then + LC_ALL="$save_LC_ALL"; export LC_ALL + fi + if test "${save_LANG+set}" = set; then + LANG="$save_LANG"; export LANG + fi + + # Now prepare to actually exec the command. + exec_cmd="\$cmd$args" + else + # 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 0 + fi + ;; + + # libtool clean and uninstall mode + clean | uninstall) + modename="$modename: $mode" + rm="$nonopt" + files= + rmforce= + 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) rm="$rm $arg"; rmforce=yes ;; + -*) rm="$rm $arg" ;; + *) files="$files $arg" ;; + esac + done + + if test -z "$rm"; then + $echo "$modename: you must specify an RM program" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + rmdirs= + + origobjdir="$objdir" + for file in $files; do + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` + if test "X$dir" = "X$file"; then + dir=. + objdir="$origobjdir" + else + objdir="$dir/$origobjdir" + fi + name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + test "$mode" = uninstall && objdir="$dir" + + # Remember objdir for removal later, being careful to avoid duplicates + if test "$mode" = clean; then + case " $rmdirs " in + *" $objdir "*) ;; + *) rmdirs="$rmdirs $objdir" ;; + 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 test "$rmforce" = yes; then + continue + fi + + rmfiles="$file" + + case $name in + *.la) + # Possibly a libtool archive, so verify it. + if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + . $dir/$name + + # Delete the libtool libraries and symlinks. + for n in $library_names; do + rmfiles="$rmfiles $objdir/$n" + done + test -n "$old_library" && rmfiles="$rmfiles $objdir/$old_library" + test "$mode" = clean && rmfiles="$rmfiles $objdir/$name $objdir/${name}i" + + if test "$mode" = uninstall; then + if test -n "$library_names"; then + # Do each command in the postuninstall commands. + eval cmds=\"$postuninstall_cmds\" + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" + if test "$?" -ne 0 && test "$rmforce" != yes; then + exit_status=1 + fi + done + IFS="$save_ifs" + fi + + if test -n "$old_library"; then + # Do each command in the old_postuninstall commands. + eval cmds=\"$old_postuninstall_cmds\" + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" + if test "$?" -ne 0 && test "$rmforce" != yes; then + exit_status=1 + fi + done + IFS="$save_ifs" + fi + # FIXME: should reinstall the best remaining shared library. + fi + fi + ;; + + *.lo) + # Possibly a libtool object, so verify it. + if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + + # Read the .lo file + . $dir/$name + + # Add PIC object to the list of files to remove. + if test -n "$pic_object" \ + && test "$pic_object" != none; then + rmfiles="$rmfiles $dir/$pic_object" + fi + + # Add non-PIC object to the list of files to remove. + if test -n "$non_pic_object" \ + && test "$non_pic_object" != none; then + rmfiles="$rmfiles $dir/$non_pic_object" + fi + fi + ;; + + *) + if test "$mode" = clean ; then + noexename=$name + case $file in + *.exe) + file=`$echo $file|${SED} 's,.exe$,,'` + noexename=`$echo $name|${SED} 's,.exe$,,'` + # $file with .exe has already been added to rmfiles, + # add $file without .exe + rmfiles="$rmfiles $file" + ;; + esac + # Do a test to see if this is a libtool program. + if (${SED} -e '4q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + relink_command= + . $dir/$noexename + + # note $name still contains .exe if it was in $file originally + # as does the version of $file that was added into $rmfiles + rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}" + if test "$fast_install" = yes && test -n "$relink_command"; then + rmfiles="$rmfiles $objdir/lt-$name" + fi + if test "X$noexename" != "X$name" ; then + rmfiles="$rmfiles $objdir/lt-${noexename}.c" + fi + fi + fi + ;; + esac + $show "$rm $rmfiles" + $run $rm $rmfiles || exit_status=1 + done + objdir="$origobjdir" + + # Try to remove the ${objdir}s in the directories where we deleted files + for dir in $rmdirs; do + if test -d "$dir"; then + $show "rmdir $dir" + $run rmdir $dir >/dev/null 2>&1 + fi + done + + exit $exit_status + ;; + + "") + $echo "$modename: you must specify a MODE" 1>&2 + $echo "$generic_help" 1>&2 + exit 1 + ;; + esac + + if test -z "$exec_cmd"; then + $echo "$modename: invalid operation mode \`$mode'" 1>&2 + $echo "$generic_help" 1>&2 + exit 1 + fi +fi # test -z "$show_help" + +if test -n "$exec_cmd"; then + eval exec $exec_cmd + exit 1 +fi + +# We need to display help for each of the modes. +case $mode in +"") $echo \ +"Usage: $modename [OPTION]... [MODE-ARG]... + +Provide generalized library-building support services. + + --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 + --finish same as \`--mode=finish' + --help display this help message and exit + --mode=MODE use operation mode MODE [default=inferred from MODE-ARGS] + --quiet same as \`--silent' + --silent don't print informational messages + --tag=TAG use configuration variables from tag TAG + --version print version information + +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. Try \`$modename --help --mode=MODE' for +a more detailed description of MODE. + +Report bugs to ." + exit 0 + ;; + +clean) + $echo \ +"Usage: $modename [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: $modename [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 + -prefer-pic try to building PIC objects only + -prefer-non-pic try to building non-PIC objects only + -static always build a \`.o' file suitable for static linking + +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: $modename [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: $modename [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: $modename [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 rest of the components are interpreted as arguments to that command (only +BSD-compatible install options are recognized)." + ;; + +link) + $echo \ +"Usage: $modename [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 + -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 + -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 + -static do not do any dynamic linking of libtool libraries + -version-info CURRENT[:REVISION[:AGE]] + specify library version info [each variable defaults to 0] + +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: $modename [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." + ;; + +*) + $echo "$modename: invalid operation mode \`$mode'" 1>&2 + $echo "$help" 1>&2 + exit 1 + ;; +esac + +$echo +$echo "Try \`$modename --help' for more information about other modes." + +exit 0 + +# The TAGs below are defined such that we never get into a situation +# in which 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: Index: ext/libicpf/missing =================================================================== diff -u -N --- ext/libicpf/missing (revision 0) +++ ext/libicpf/missing (revision e17c80d36eaa0430313e7d1058aa7a301d1510af) @@ -0,0 +1,336 @@ +#! /bin/sh +# Common stub for a few missing GNU programs while installing. +# Copyright (C) 1996, 1997, 1999, 2000, 2002 Free Software Foundation, Inc. +# Originally by Fran,cois Pinard , 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# 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 + +run=: + +# In the cases where this matters, `missing' is being run in the +# srcdir already. +if test -f configure.ac; then + configure_ac=configure.ac +else + configure_ac=configure.in +fi + +case "$1" in +--run) + # Try to run requested program, and just exit if it succeeds. + run= + shift + "$@" && exit 0 + ;; +esac + +# If it does not exist, or fails to run (possibly an outdated version), +# try to emulate it. +case "$1" in + + -h|--h|--he|--hel|--help) + echo "\ +$0 [OPTION]... PROGRAM [ARGUMENT]... + +Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an +error status if there is no known handling for PROGRAM. + +Options: + -h, --help display this help and exit + -v, --version output version information and exit + --run try to run the given command, and emulate it if it fails + +Supported PROGRAM values: + aclocal touch file \`aclocal.m4' + autoconf touch file \`configure' + autoheader touch file \`config.h.in' + automake touch all \`Makefile.in' files + bison create \`y.tab.[ch]', if possible, from existing .[ch] + flex create \`lex.yy.c', if possible, from existing .c + help2man touch the output file + lex create \`lex.yy.c', if possible, from existing .c + makeinfo touch the output file + tar try tar, gnutar, gtar, then tar without non-portable flags + yacc create \`y.tab.[ch]', if possible, from existing .[ch]" + ;; + + -v|--v|--ve|--ver|--vers|--versi|--versio|--version) + echo "missing 0.4 - GNU automake" + ;; + + -*) + echo 1>&2 "$0: Unknown \`$1' option" + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 + ;; + + aclocal*) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + fi + + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`acinclude.m4' or \`${configure_ac}'. You might want + to install the \`Automake' and \`Perl' packages. Grab them from + any GNU archive site." + touch aclocal.m4 + ;; + + autoconf) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + fi + + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`${configure_ac}'. You might want to install the + \`Autoconf' and \`GNU m4' packages. Grab them from any GNU + archive site." + touch configure + ;; + + autoheader) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + fi + + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`acconfig.h' or \`${configure_ac}'. You might want + to install the \`Autoconf' and \`GNU m4' packages. Grab them + from any GNU archive site." + files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` + test -z "$files" && files="config.h" + touch_files= + for f in $files; do + case "$f" in + *:*) touch_files="$touch_files "`echo "$f" | + sed -e 's/^[^:]*://' -e 's/:.*//'`;; + *) touch_files="$touch_files $f.in";; + esac + done + touch $touch_files + ;; + + automake*) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + fi + + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. + You might want to install the \`Automake' and \`Perl' packages. + Grab them from any GNU archive site." + find . -type f -name Makefile.am -print | + sed 's/\.am$/.in/' | + while read f; do touch "$f"; done + ;; + + autom4te) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + fi + + echo 1>&2 "\ +WARNING: \`$1' is needed, and you do not seem to have it handy on your + system. You might have modified some files without having the + proper tools for further handling them. + You can get \`$1Help2man' as part of \`Autoconf' from any GNU + archive site." + + file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'` + test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'` + if test -f "$file"; then + touch $file + else + test -z "$file" || exec >$file + echo "#! /bin/sh" + echo "# Created by GNU Automake missing as a replacement of" + echo "# $ $@" + echo "exit 0" + chmod +x $file + exit 1 + fi + ;; + + bison|yacc) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified a \`.y' file. You may need the \`Bison' package + in order for those modifications to take effect. You can get + \`Bison' from any GNU archive site." + rm -f y.tab.c y.tab.h + if [ $# -ne 1 ]; then + eval LASTARG="\${$#}" + case "$LASTARG" in + *.y) + SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" y.tab.c + fi + SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" y.tab.h + fi + ;; + esac + fi + if [ ! -f y.tab.h ]; then + echo >y.tab.h + fi + if [ ! -f y.tab.c ]; then + echo 'main() { return 0; }' >y.tab.c + fi + ;; + + lex|flex) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified a \`.l' file. You may need the \`Flex' package + in order for those modifications to take effect. You can get + \`Flex' from any GNU archive site." + rm -f lex.yy.c + if [ $# -ne 1 ]; then + eval LASTARG="\${$#}" + case "$LASTARG" in + *.l) + SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" lex.yy.c + fi + ;; + esac + fi + if [ ! -f lex.yy.c ]; then + echo 'main() { return 0; }' >lex.yy.c + fi + ;; + + help2man) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + fi + + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified a dependency of a manual page. You may need the + \`Help2man' package in order for those modifications to take + effect. You can get \`Help2man' from any GNU archive site." + + file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` + if test -z "$file"; then + file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'` + fi + if [ -f "$file" ]; then + touch $file + else + test -z "$file" || exec >$file + echo ".ab help2man is required to generate this page" + exit 1 + fi + ;; + + makeinfo) + if test -z "$run" && (makeinfo --version) > /dev/null 2>&1; then + # We have makeinfo, but it failed. + exit 1 + fi + + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified a \`.texi' or \`.texinfo' file, or any other file + indirectly affecting the aspect of the manual. The spurious + call might also be the consequence of using a buggy \`make' (AIX, + DU, IRIX). You might want to install the \`Texinfo' package or + the \`GNU make' package. Grab either from any GNU archive site." + file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` + if test -z "$file"; then + file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` + file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file` + fi + touch $file + ;; + + tar) + shift + if test -n "$run"; then + echo 1>&2 "ERROR: \`tar' requires --run" + exit 1 + fi + + # We have already tried tar in the generic part. + # Look for gnutar/gtar before invocation to avoid ugly error + # messages. + if (gnutar --version > /dev/null 2>&1); then + gnutar "$@" && exit 0 + fi + if (gtar --version > /dev/null 2>&1); then + gtar "$@" && exit 0 + fi + firstarg="$1" + if shift; then + case "$firstarg" in + *o*) + firstarg=`echo "$firstarg" | sed s/o//` + tar "$firstarg" "$@" && exit 0 + ;; + esac + case "$firstarg" in + *h*) + firstarg=`echo "$firstarg" | sed s/h//` + tar "$firstarg" "$@" && exit 0 + ;; + esac + fi + + echo 1>&2 "\ +WARNING: I can't seem to be able to run \`tar' with the given arguments. + You may want to install GNU tar or Free paxutils, or check the + command line arguments." + exit 1 + ;; + + *) + echo 1>&2 "\ +WARNING: \`$1' is needed, and you do not seem to have it handy on your + system. You might have modified some files without having the + proper tools for further handling them. Check the \`README' file, + it often tells you about the needed prerequirements for installing + this package. You may also peek at any GNU archive site, in case + some other package would contain this missing \`$1' program." + exit 1 + ;; +esac + +exit 0 Index: ext/libicpf/mkinstalldirs =================================================================== diff -u -N --- ext/libicpf/mkinstalldirs (revision 0) +++ ext/libicpf/mkinstalldirs (revision e17c80d36eaa0430313e7d1058aa7a301d1510af) @@ -0,0 +1,111 @@ +#! /bin/sh +# mkinstalldirs --- make directory hierarchy +# Author: Noah Friedman +# Created: 1993-05-16 +# Public domain + +errstatus=0 +dirmode="" + +usage="\ +Usage: mkinstalldirs [-h] [--help] [-m mode] dir ..." + +# process command line arguments +while test $# -gt 0 ; do + case $1 in + -h | --help | --h*) # -h for help + echo "$usage" 1>&2 + exit 0 + ;; + -m) # -m PERM arg + shift + test $# -eq 0 && { echo "$usage" 1>&2; exit 1; } + dirmode=$1 + shift + ;; + --) # stop option processing + shift + break + ;; + -*) # unknown option + echo "$usage" 1>&2 + exit 1 + ;; + *) # first non-opt arg + break + ;; + esac +done + +for file +do + if test -d "$file"; then + shift + else + break + fi +done + +case $# in + 0) exit 0 ;; +esac + +case $dirmode in + '') + if mkdir -p -- . 2>/dev/null; then + echo "mkdir -p -- $*" + exec mkdir -p -- "$@" + fi + ;; + *) + if mkdir -m "$dirmode" -p -- . 2>/dev/null; then + echo "mkdir -m $dirmode -p -- $*" + exec mkdir -m "$dirmode" -p -- "$@" + fi + ;; +esac + +for file +do + set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` + shift + + pathcomp= + for d + do + pathcomp="$pathcomp$d" + case $pathcomp in + -*) pathcomp=./$pathcomp ;; + esac + + if test ! -d "$pathcomp"; then + echo "mkdir $pathcomp" + + mkdir "$pathcomp" || lasterr=$? + + if test ! -d "$pathcomp"; then + errstatus=$lasterr + else + if test ! -z "$dirmode"; then + echo "chmod $dirmode $pathcomp" + lasterr="" + chmod "$dirmode" "$pathcomp" || lasterr=$? + + if test ! -z "$lasterr"; then + errstatus=$lasterr + fi + fi + fi + fi + + pathcomp="$pathcomp/" + done +done + +exit $errstatus + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# End: +# mkinstalldirs ends here Index: ext/libicpf/scripts/check_icpf.m4 =================================================================== diff -u -N --- ext/libicpf/scripts/check_icpf.m4 (revision 0) +++ ext/libicpf/scripts/check_icpf.m4 (revision e17c80d36eaa0430313e7d1058aa7a301d1510af) @@ -0,0 +1,74 @@ +dnl @synopsis CT_CHECK_ICPF +dnl +dnl This macro tries to find the headers and libraries for the +dnl icpf library. +dnl +dnl If includes are found, the variable ICPFINCPATH will be set. If +dnl librarys are found, the variable ICPFLIBPATH will be set. if no check +dnl was successful, the script exits with a error message. +dnl +dnl @category InstalledPackages +dnl @author Ixen Gerthannes, heavily based on CT_CHECK_POSTGRES_DB by Christian Toepp +dnl @version 2005-07-25 +dnl @license AllPermissive + +AC_DEFUN([CT_CHECK_ICPF], [ + +AC_ARG_WITH(libicpf, + [ --with-libicpf=PREFIX Prefix of your libicpf installation], + [icpf_prefix=$withval], [icpf_prefix=]) +AC_ARG_WITH(libicpf-inc, + [ --with-libicpf-inc=PATH Path to the include directory of libicpf], + [icpf_inc=$withval], [icpf_inc=]) +AC_ARG_WITH(libicpf-lib, + [ --with-libicpf-lib=PATH Path to the library of libicpf], + [icpf_lib=$withval], [icpf_lib=]) + + +AC_SUBST(ICPFINCPATH) +AC_SUBST(ICPFLIBPATH) + +if test "$icpf_prefix" != ""; then + AC_MSG_CHECKING([for libicpf includes in $icpf_prefix/include]) + if test -f "$icpf_prefix/include/libicpf.h" ; then + ICPFINCPATH="-I$icpf_prefix/include" + AC_MSG_RESULT([yes]) + else + AC_MSG_ERROR(libicpf.h not found) + fi + AC_MSG_CHECKING([for libicpf library in $icpf_prefix/lib]) + if test -f "$icpf_prefix/lib/libicpf.a" ; then + ICPFLIBPATH="-L$icpf_prefix/lib" + AC_MSG_RESULT([yes]) + else + AC_MSG_ERROR(libicpf.a not found) + fi +else + if test "$icpf_inc" != ""; then + AC_MSG_CHECKING([for libicpf includes in $icpf_inc]) + if test -f "$icpf_inc/libicpf.h" ; then + ICPFINCPATH="-I$icpf_inc" + AC_MSG_RESULT([yes]) + else + AC_MSG_ERROR(libicpf.h not found) + fi + fi + if test "$icpf_lib" != ""; then + AC_MSG_CHECKING([for libicpf library in $icpf_lib]) + if test -f "$icpf_lib/libicpf.a" ; then + ICPFLIBPATH="-L$icpf_lib" + AC_MSG_RESULT([yes]) + else + AC_MSG_ERROR(libicpf.a not found) + fi + fi +fi + +if test "$ICPFINCPATH" = "" ; then + AC_CHECK_HEADER([libicpf.h], [], AC_MSG_ERROR(libicpf.h not found)) +fi +if test "$ICPFLIBPATH" = "" ; then + AC_MSG_ERROR(libicpf.a not found) +fi + +]) Index: ext/libicpf/src/Makefile.am =================================================================== diff -u -N --- ext/libicpf/src/Makefile.am (revision 0) +++ ext/libicpf/src/Makefile.am (revision e17c80d36eaa0430313e7d1058aa7a301d1510af) @@ -0,0 +1,18 @@ +lib_LTLIBRARIES = libicpf.la +libicpf_la_SOURCES = callback.cpp exception.cpp \ + str.cpp log.cpp dumpctx.cpp cfg.cpp str_help.cpp \ + crc32.cpp file.cpp module.cpp conv.cpp crypt.cpp rijndael-alg-fst.c \ + rijndael-api-fst.c sha256.c + +# set the include path found by configure +INCLUDES = $(all_includes) + +# the library search path. +libicpf_la_LDFLAGS = $(all_libraries) +libicpf_la_LIBADD = -ldl -lpthread +dist_include_HEADERS = callback.h exception.h str.h dumpctx.h cfg.h module.h \ + file.h log.h cfg.h str_help.h crc32.h libicpf.h gen_types.h \ + conv.h crypt.h err_codes.h gen_types.h macros.h mutex.h \ + rijndael-alg-fst.h rijndael-api-fst.h sha256.h +AM_CFLAGS = -Wall -Wshadow -DLIBICPF_EXPORTS +AM_CXXFLAGS = -Wall -Wshadow -DLIBICPF_EXPORTS Index: ext/libicpf/src/callback.cpp =================================================================== diff -u -N --- ext/libicpf/src/callback.cpp (revision 0) +++ ext/libicpf/src/callback.cpp (revision e17c80d36eaa0430313e7d1058aa7a301d1510af) @@ -0,0 +1,152 @@ +/*************************************************************************** + * Copyright (C) 2004 by J�zef Starosczyk * + * copyhandler@o2.pl * + * * + * This program 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 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 Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +/** \file callback.cpp + * \brief File provides the implementation of callback classes. + */ +#include "callback.h" + +BEGIN_ICPF_NAMESPACE + +callback1::callback1() +{ + +} + +callback1::~callback1() +{ + +} + +/** Executes a callback list associated with this object. + * \param[in] pData - parameter that will be passed to a user callback function + */ +void callback1::exec(ptr_t pData) +{ + m_lock.lock(); + try + { + for (std::list<_CALLBACKDATA1>::iterator it=m_lCalls.begin();it != m_lCalls.end();it++) + (*((*it).pfn))((*it).pParam, pData); + m_lock.unlock(); + } + catch(...) + { + m_lock.unlock(); + throw; + } +} + +/** Connects a user callback function to this object. + * \param[in] pfn - user callback function address + * \param[in] pParam - user parameter to pass to the callback function when executing + */ +void callback1::connect(PFNCALLBACKPROC1 pfn, ptr_t pParam) +{ + _CALLBACKDATA1 cd; + cd.pfn=pfn; + cd.pParam=pParam; + + m_lock.lock(); + m_lCalls.push_back(cd); + m_lock.unlock(); +} + +/** Disconnects the user callback function if connected earlier. + * \param[in] pfn - address of a function to remove + */ +void callback1::disconnect(PFNCALLBACKPROC1 pfn) +{ + m_lock.lock(); + for (std::list<_CALLBACKDATA1>::iterator it=m_lCalls.begin();it != m_lCalls.end();it++) + { + if ( (*it).pfn == pfn ) + { + m_lCalls.erase(it); + m_lock.unlock(); + return; + } + } + m_lock.unlock(); +} + +callback2::callback2() +{ + +} + +callback2::~callback2() +{ + +} + +/** Executes a callback list associated with this object. + * \param[in] pData - first parameter that will be passed to a user callback function + * \param[in] pData2 - second parameter that will be passed to a user callback function + */ +void callback2::exec(ptr_t pData, ptr_t pData2) +{ + m_lock.lock(); + try + { + for (std::list<_CALLBACKDATA2>::iterator it=m_lCalls.begin();it != m_lCalls.end();it++) + (*((*it).pfn))((*it).pParam, pData, pData2); + m_lock.unlock(); + } + catch(...) + { + m_lock.unlock(); + throw; + } +} + +/** Connects a user callback function to this object. + * \param[in] pfn - user callback function address + * \param[in] pParam - user parameter to pass to the callback function when executing + */ +void callback2::connect(PFNCALLBACKPROC2 pfn, ptr_t pParam) +{ + _CALLBACKDATA2 cd; + cd.pfn=pfn; + cd.pParam=pParam; + + m_lock.lock(); + m_lCalls.push_back(cd); + m_lock.unlock(); +} + +/** Disconnects the user callback function if connected earlier. + * \param[in] pfn - address of a function to remove + */ +void callback2::disconnect(PFNCALLBACKPROC2 pfn) +{ + m_lock.lock(); + for (std::list<_CALLBACKDATA2>::iterator it=m_lCalls.begin();it != m_lCalls.end();it++) + { + if ( (*it).pfn == pfn ) + { + m_lCalls.erase(it); + m_lock.unlock(); + return; + } + } + m_lock.unlock(); +} + +END_ICPF_NAMESPACE Index: ext/libicpf/src/callback.h =================================================================== diff -u -N --- ext/libicpf/src/callback.h (revision 0) +++ ext/libicpf/src/callback.h (revision e17c80d36eaa0430313e7d1058aa7a301d1510af) @@ -0,0 +1,111 @@ +/*************************************************************************** + * Copyright (C) 2004 by J�zef Starosczyk * + * copyhandler@o2.pl * + * * + * This program 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 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 Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef __CALLBACK_H__ +#define __CALLBACK_H__ + +/** \file callback.h + * \brief Provides callback classes + */ + +#include "libicpf.h" +#include "gen_types.h" +#include +#include "mutex.h" + +/// Callback1-type callback function +typedef void(*PFNCALLBACKPROC1)(ptr_t, ptr_t); +/// Callback2-type callback function +typedef void(*PFNCALLBACKPROC2)(ptr_t, ptr_t, ptr_t); + +BEGIN_ICPF_NAMESPACE + +/// Helper structure for callback1 class +struct _CALLBACKDATA1 +{ + PFNCALLBACKPROC1 pfn; ///< Callback function that is to be called + ptr_t pParam; ///< The user parameter of a function to be called +}; + +/// Helper structure for callback2 class +struct _CALLBACKDATA2 +{ + PFNCALLBACKPROC2 pfn; ///< Callback function that is to be called + ptr_t pParam; ///< The user parameter of a function to be called +}; + +/** \brief Callback class with one parameter. + * + * Class provides a simple interface for user to call a specific callback + * function(s) registered by the user. Good for notifying user that something + * had happened. + */ +class LIBICPF_API callback1 +{ +public: +/** \name Construction/destruction */ +/**@{*/ + callback1(); ///< Standard constructor + ~callback1(); ///< Standard destructor +/**@}*/ + +/** \name User interface */ +/**@{*/ + void exec(ptr_t pData); ///< Executes registered callback functions with the pData as the first param + + void connect(PFNCALLBACKPROC1 pfn, ptr_t); ///< Connects the callback function to this callback class + void disconnect(PFNCALLBACKPROC1 pfn); ///< Disconnects the callback function from this callback class +/**@}*/ + +protected: + std::list<_CALLBACKDATA1> m_lCalls; ///< List of the callback structures to execute + mutex m_lock; ///< Mutex for locking connect/disconnect calls +}; + +/** \brief Callback class with two parameters. + * + * Class provides a simple interface for user to call a specific callback + * function(s) registered by the user. Good for notifying user that something + * had happened. + */ +class LIBICPF_API callback2 +{ +public: +/** \name Construction/destruction */ +/**@{*/ + callback2(); ///< Standard constructor + ~callback2(); ///< Standard destructor +/**@}*/ + +/** \name User interface */ +/**@{*/ + void exec(ptr_t pData, ptr_t pData2); ///< Executes registered callback functions with the pData as the first param + + void connect(PFNCALLBACKPROC2 pfn, ptr_t pParam); ///< Connects the callback function to this callback class + void disconnect(PFNCALLBACKPROC2 pfn); ///< Disconnects the callback function from this callback class +/**@}*/ + +protected: + std::list<_CALLBACKDATA2> m_lCalls; ///< List of the callback structures to execute + mutex m_lock; ///< Mutex for locking connect/disconnect calls +}; + +END_ICPF_NAMESPACE + +#endif Index: ext/libicpf/src/cfg.cpp =================================================================== diff -u -N --- ext/libicpf/src/cfg.cpp (revision 0) +++ ext/libicpf/src/cfg.cpp (revision e17c80d36eaa0430313e7d1058aa7a301d1510af) @@ -0,0 +1,1377 @@ +/*************************************************************************** + * Copyright (C) 2004 by J�zef Starosczyk * + * copyhandler@o2.pl * + * * + * This program 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 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 Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +/** \file cfg.cpp + * \brief A placeholder for config class definitions. + * \todo Modify the class to use file class as a file access layer. + */ + +#include "cfg.h" +#include +#include +#include "str.h" +#include +#include "str_help.h" +#ifdef USE_ENCRYPTION + #include "crypt.h" +#endif +/// Specifies maximum line length of the .conf file +#define MAX_LINE 1024 + +#ifdef _WIN32 + /// A small helper for win32 systems + #define snprintf _snprintf +#endif + +BEGIN_ICPF_NAMESPACE + +/// A global instance of a config class +config *__g_cfg=NULL; + +////////////////////////////////////////////////////////////////////////////////// +// prop_group class + +/** Function adds a new property id to the group. + * \param[in] iProp - id of a property to add + */ +void prop_group::add(int_t iProp) +{ + m_vProperties.push_back(iProp); +} + +/** Function searches for a specific property id inside the list. + * \return True if the property has been found, false if not. + */ +bool prop_group::is_set(int_t iProp) +{ + for (std::vector::iterator it=m_vProperties.begin();it != m_vProperties.end();it++) + { + if ((*it) == iProp) + return true; + } + + return false; +} + +/** Function returns a count of properties contained in the list. + * \return A count of properties. + */ +ulong_t prop_group::count() +{ + return (ulong_t)m_vProperties.size(); +} + +/** Function returns a property ID at a specified index. + * \param[in] - an index + * \return A property id. + */ +int_t prop_group::get_at(int_t iIndex) +{ + return m_vProperties.at(iIndex); +} + +/** Function returns the group id. + * \return A group ID. + */ +ulong_t prop_group::get_groupid() +{ + return m_ulGroupID; +} + +///////////////////////////////////////////////////////////////////////////////////// +// config class + +/** Retrieves a pointer to a global instance of a config class + * \return Pointer to the config class + */ +config* get_config() +{ + return __g_cfg; +} + +/** Constructs a config object. + * \param[in] bGlobal - specifies if this class should be globally accessible by the get_config() friend + * function. + */ +config::config(bool bGlobal) + :m_bModified(false) +{ + if (bGlobal) + __g_cfg=this; +} + +/** Destructs the config class. + */ +config::~config() +{ +} + +/** Function opens the specified file, reads all the lines sequentially + * and stores discovered property values in the internal structures. + * \param[in] pszFile - path to a .conf file (could have any extension) + * \return -1 on error or 0 if operation finished succesfully + * \note The properties does not have to be registered prior to use this function. + */ +int_t config::read(const char_t* pszFile) +{ + // NOTE: this function should reset the m_bModified flag + // open the file + FILE* pFile; + if ( (pFile=fopen(pszFile, "r")) == NULL) + return -1; + + char_t szLine[MAX_LINE], *pszData; + + // lock the instance - has to be done here to make sure all settings are + // consistent if reloaded on-the-fly + m_lock.lock(); + while(fgets(szLine, MAX_LINE, pFile)) + { + szLine[MAX_LINE-1]='\0'; // needed when the line is too int_t + pszData=szLine; + + // interpret the line + // skip the whitespaces at the beginning + while(is_whitespace(*pszData)) + pszData++; + + // skip the comments and empty lines + if (pszData[0] == '#' || pszData[0] == ';' || strlen(pszData) == 0) + continue; + + // split the line to the part on the left of '=' and to the right + char_t* pVal=strchr(pszData, '='); + if (pVal != NULL) + { + pVal[0]='\0'; + pVal++; + + // so we have name in the pszData and value pVal + process_line(trim(pszData), trim(pVal)); + } + } + + m_bModified=false; + m_lock.unlock(); + + m_clbPropertyChanged.exec((ptr_t)-1, NULL); + + fclose(pFile); + + return 0; +} + +/** Writes all the registered properties into the given file. To avoid + * deleting any comments or unused properties from a file - the function + * read all the file into memory (!) and modifies only the lines that + * contains the requested property key (or adds a new entry at the end). + * After that the file is being overwritten. + * \param[in] pszFile - path to a .conf file to which the properties shoud be written + * \return -1 on error, 0 on success. + */ +int_t config::write(const char_t* pszFile) +{ + // if the config was not modified - why bother writing + if (!m_bModified) + return 0; + + // at first - read the current file (whole) - line by line + std::vector vLines; + FILE* pFile=fopen(pszFile, "r"); + if (pFile != NULL) + { + char_t szLine[MAX_LINE]; + while(fgets(szLine, MAX_LINE, pFile)) + { + vLines.push_back((const char_t*)trim(szLine)); + } + + fclose(pFile); + } + + // apply the registered properties to the lines + // NOTE: properties in the unreg cannot have changed, so we don't need to bother with them + m_lock.lock(); + +#ifdef USE_ENCRYPTION + // encrypt everything if needed + try + { + for (std::vector<_PROP>::iterator it = m_vProps.begin();it != m_vProps.end();it++) + { + encrypt_property(&(*it)); + } + } + catch(...) + { + m_lock.unlock(); + throw; + } +#endif + + bool bFnd=false; + string str; + for (std::vector<_PROP>::iterator it=m_vProps.begin();it != m_vProps.end();it++) + { + // process only if the property was modified + // NOTE: if the file has been modified manually then they won't be overwritten + if ((*it).bModified) + { + // check every line that has been read for property match + bFnd=false; + for (std::vector::iterator sit=vLines.begin();sit != vLines.end();sit++) + { + // line matches ? + if ((*sit).cmpn((*it).pszName, strlen((*it).pszName)) == 0) + { + // replace the line with a new value + prepare_line(&(*it), &(*sit)); + bFnd=true; + break; // break the inner 'for' + } + } + + // if the line was not found - add the line at the end + if (!bFnd) + { + prepare_line(&(*it), &str); + vLines.push_back(str); + } + + // mark as written, although it is a lie ;) + (*it).bModified=false; + } + } + m_bModified=false; + m_lock.unlock(); + + // save the new copy of file + // NOTE: at this point the props are all marked as non-modified - if the write fails then all the data are lost + if ( (pFile=fopen(pszFile, "w")) == NULL) + return -1; + + for (std::vector::iterator it=vLines.begin();it != vLines.end();it++) + { + if (fprintf(pFile, STRFMT "\n", (const char_t*)(*it)) < 0) + return -1; + } + + fclose(pFile); + + return 0; +} + +/** Function returns a property type for a given property id. + * \note The function returns only the type, and not the rest of the property flags. + * \param[in] iProp - property id to get info about. + * \return The property type. + */ +int_t config::get_proptype(int_t iProp) +{ + m_lock.lock(); + + int_t iRet=m_vProps.at(iProp).iType & PTM_TYPE; + + m_lock.unlock(); + return iRet; +} + +/** Function registers property with int_t value, specified range and flags. Also + * checks if the property has already been registered if PF_CHECK flag has been specified (if it + * is, then the existing identifier is returned and nothing is changed). + * \param[in] pszName - name of the property (key in key = value) + * \param[in] iDef - default value for the property + * \param[in] iLo - the lesser value of value's allowable range + * \param[in] iHi - the higher value of value's allowable range + * \param[in] iFlags - additional flags that should be associated with property + * \return Property ID of the newly registered property. + */ +int_t config::register_int(const char_t* pszName, int_t iDef, int_t iLo, int_t iHi, int_t iFlags) +{ + // check if there is already registered value with the given name + m_lock.lock(); + int_t iRes; + if (iFlags & PF_CHECK && (iRes=is_registered(pszName)) != -1) + { + m_lock.unlock(); + return iRes; + } + else + { + _PROP prop; + + // check if the property is in the unreg container + if ( (iRes = is_unreg(pszName)) == -1 ) + { + // property not found in the unreg - means that this is quite new stuff + prop.bModified=true; + prop.pszName=new char_t[strlen(pszName)+1]; + strcpy(prop.pszName, pszName); + prop.val.i.iVal=iDef; // will be overwritten when reading file + } + else + { + // get the entry + prop=m_vUnreg.at(iRes); + m_vUnreg.erase(m_vUnreg.begin()+iRes); + + // set the value from a string + int_t iVal=atol(prop.val.pszVal); + delete [] prop.val.pszVal; + prop.val.i.iVal=iVal; + } + + // common part + prop.iType=PT_INT | iFlags; + prop.val.i.iLo=iLo; + prop.val.i.iHi=iHi; + + // add to the list + m_vProps.push_back(prop); + m_bModified=true; + iRes=(int_t)(m_vProps.size()-1); + m_lock.unlock(); + + return iRes; + } +} + +/** Function registers property with uint_t value, specified range and flags. Also + * checks if the property is registered if PF_CHECK flag has been specified (if it + * is, then the existing identifier is returned and nothing is changed. + * \param[in] pszName - name of the property (key in key = value) + * \param[in] uiDef - default value for the property + * \param[in] uiLo - the lesser value of value's allowable range + * \param[in] uiHi - the higher value of value's allowable range + * \param[in] iFlags - additional flags that should be associated with property + * \return Property ID of the newly registered property. + */ +int_t config::register_uint(const char_t* pszName, uint_t uiDef, uint_t uiLo, uint_t uiHi, int_t iFlags) +{ + // check if there is already registered value with the given name + m_lock.lock(); + int_t iRes; + if (iFlags & PF_CHECK && (iRes=is_registered(pszName)) != -1) + { + m_lock.unlock(); + return iRes; + } + else + { + _PROP prop; + + if ( (iRes = is_unreg(pszName)) == -1 ) + { + prop.pszName=new char_t[strlen(pszName)+1]; + strcpy(prop.pszName, pszName); + prop.val.ui.uiVal=uiDef; // will be overwritten when reading file + prop.bModified=true; + } + else + { + // get the entry + prop=m_vUnreg.at(iRes); + m_vUnreg.erase(m_vUnreg.begin()+iRes); + + uint_t uiVal=strtoul(prop.val.pszVal, NULL, 10); + delete [] prop.val.pszVal; + prop.val.ui.uiVal=uiVal; + } + + // common part + prop.iType=PT_UINT | iFlags; + prop.val.ui.uiLo=uiLo; + prop.val.ui.uiHi=uiHi; + + // add to the list + m_vProps.push_back(prop); + m_bModified=true; + iRes=(int_t)(m_vProps.size()-1); + m_lock.unlock(); + + return iRes; + } +} + +/** Function registers property with longlong_t value, specified range and flags. Also + * checks if the property is registered if PF_CHECK flag has been specified (if it + * is, then the existing identifier is returned and nothing is changed. + * \param[in] pszName - name of the property (key in key = value) + * \param[in] llDef - default value for the property + * \param[in] llLo - the lesser value of value's allowable range + * \param[in] llHi - the higher value of value's allowable range + * \param[in] iFlags - additional flags that should be associated with property + * \return Property ID of the newly registered property. + */ +int_t config::register_longlong(const char_t* pszName, longlong_t llDef, longlong_t llLo, longlong_t llHi, int_t iFlags) +{ + // check if there is already registered value with the given name + m_lock.lock(); + int_t iRes; + if (iFlags & PF_CHECK && (iRes=is_registered(pszName)) != -1) + { + m_lock.unlock(); + return iRes; + } + else + { + _PROP prop; + + if ( (iRes = is_unreg(pszName)) == -1 ) + { + prop.pszName=new char_t[strlen(pszName)+1]; + strcpy(prop.pszName, pszName); + prop.val.ll.llVal=llDef; // will be overwritten when reading file + prop.bModified=true; + } + else + { + // get the entry + prop=m_vUnreg.at(iRes); + m_vUnreg.erase(m_vUnreg.begin()+iRes); + + ll_t llVal; +#ifdef _WIN32 + llVal=_atoi64(prop.val.pszVal); +#else + llVal=atoll(prop.val.pszVal); +#endif + delete [] prop.val.pszVal; + prop.val.ll.llVal=llVal; + } + + // common + prop.iType=PT_LONGLONG | iFlags; + prop.val.ll.llLo=llLo; + prop.val.ll.llHi=llHi; + + // add to the list + m_vProps.push_back(prop); + m_bModified=true; + iRes=(int_t)(m_vProps.size()-1); + m_lock.unlock(); + + return iRes; + } +} + +/** Function registers property with ulonglong_t value, specified range and flags. Also + * checks if the property is registered if PF_CHECK flag has been specified (if it + * is, then the existing identifier is returned and nothing is changed. + * \param[in] pszName - name of the property (key in key = value) + * \param[in] ullDef - default value for the property + * \param[in] ullLo - the lesser value of value's allowable range + * \param[in] ullHi - the higher value of value's allowable range + * \param[in] iFlags - additional flags that should be associated with property + * \return Property ID of the newly registered property. + */ +int_t config::register_ulonglong(const char_t* pszName, ulonglong_t ullDef, ulonglong_t ullLo, ulonglong_t ullHi, int_t iFlags) +{ + // check if there is already registered value with the given name + m_lock.lock(); + int_t iRes; + if (iFlags & PF_CHECK && (iRes=is_registered(pszName)) != -1) + { + m_lock.unlock(); + return iRes; + } + else + { + _PROP prop; + + if ( (iRes = is_unreg(pszName)) == -1 ) + { + prop.pszName=new char_t[strlen(pszName)+1]; + strcpy(prop.pszName, pszName); + prop.val.ull.ullVal=ullDef; // will be overwritten when reading file + prop.bModified=true; + } + else + { + prop=m_vUnreg.at(iRes); + m_vUnreg.erase(m_vUnreg.begin()+iRes); + + ull_t ullVal; +#ifdef _WIN32 + ullVal=(ulonglong_t)_atoi64(prop.val.pszVal); +#else + ullVal=(ulonglong_t)atoll(prop.val.pszVal); +#endif + delete [] prop.val.pszVal; + prop.val.ull.ullVal=ullVal; + } + + // common + prop.iType=PT_ULONGLONG | iFlags; + prop.val.ull.ullLo=ullLo; + prop.val.ull.ullHi=ullHi; + + // add to the list + m_vProps.push_back(prop); + m_bModified=true; + iRes=(int_t)(m_vProps.size()-1); + m_lock.unlock(); + + return iRes; + } +} + +/** Function registers property with bool value and flags. Also + * checks if the property is registered if PF_CHECK flag has been specified (if it + * is, then the existing identifier is returned and nothing is changed. + * \param[in] pszName - name of the property (key in key = value) + * \param[in] bDef - default value for the property + * \param[in] iFlags - additional flags that should be associated with property + * \return Property ID of the newly registered property. + */ +int_t config::register_bool(const char_t* pszName, bool bDef, int_t iFlags) +{ + // check if there is already registered value with the given name + m_lock.lock(); + int_t iRes; + if (iFlags & PF_CHECK && (iRes=is_registered(pszName)) != -1) + { + m_lock.unlock(); + return iRes; + } + else + { + _PROP prop; + + if ( (iRes = is_unreg(pszName)) == -1 ) + { + prop.pszName=new char_t[strlen(pszName)+1]; + strcpy(prop.pszName, pszName); + prop.val.bVal=bDef; // current + prop.bModified=true; + } + else + { + prop=m_vUnreg.at(iRes); + m_vUnreg.erase(m_vUnreg.begin()+iRes); + + bool bVal; + if (strcmp(prop.val.pszVal, "yes") == 0) + bVal=true; + else if (strcmp(prop.val.pszVal, "no") == 0) + bVal=false; + else + bVal=atoi(prop.val.pszVal) != 0; + + delete [] prop.val.pszVal; + prop.val.bVal=bVal; + } + + // common + prop.iType=PT_BOOL | iFlags; + + // add to the list + m_vProps.push_back(prop); + m_bModified=true; + iRes=(int_t)(m_vProps.size()-1); + m_lock.unlock(); + + return iRes; + } +} + +/** Function registers property with string value and flags. Also + * checks if the property is registered if PF_CHECK flag has been specified (if it + * is, then the existing identifier is returned and nothing is changed. + * If the property is marked as encrypted, then the default value is being treated as + * unencrypted (and the appropriate flag is being set). + * \param[in] pszName - name of the property (key in key = value) + * \param[in] pszDef - default value for the property + * \param[in] iFlags - additional flags that should be associated with property + * \return Property ID of the newly registered property. + */ +int_t config::register_string(const char_t* pszName, const char_t* pszDef, int_t iFlags) +{ + // check if there is already registered value with the given name + m_lock.lock(); + int_t iRes; + if (iFlags & PF_CHECK && (iRes=is_registered(pszName)) != -1) + { + m_lock.unlock(); + return iRes; + } + else + { + _PROP prop; + + if ( (iRes = is_unreg(pszName)) == -1 ) + { + prop.iType=PT_STRING | iFlags; +#ifdef USE_ENCRYPTION + if (iFlags & PF_ENCRYPTED) + prop.iType |= PF_DECODED; +#endif + prop.pszName=new char_t[strlen(pszName)+1]; + strcpy(prop.pszName, pszName); + + prop.val.pszVal=new char_t[strlen(pszDef)+1]; + strcpy(prop.val.pszVal, pszDef); + prop.bModified=true; + } + else + { + prop=m_vUnreg.at(iRes); + m_vUnreg.erase(m_vUnreg.begin()+iRes); + prop.iType = PT_STRING | iFlags; + } + + // add to the list + m_vProps.push_back(prop); + m_bModified=true; + iRes=(int_t)(m_vProps.size()-1); + m_lock.unlock(); + + return iRes; + } +} + +/** Functions retrieves the int_t value associated with a given property ID. Can be called + * from any thread. + * \param[in] iProp - property identifier returned by one of the register_* functions + * \return The property value. + */ +int_t config::get_int(int_t iProp) +{ + m_lock.lock(); + + assert((m_vProps.at(iProp).iType & PTM_TYPE) == PT_INT); + + int_t iRet=m_vProps.at(iProp).val.i.iVal; + m_lock.unlock(); + return iRet; +} + +/** Functions retrieves the uint_t value associated with a given property ID. Can be called + * from any thread. + * \param[in] iProp - property identifier returned by one of the register_* functions + * \return The property value. + */ +uint_t config::get_uint(int_t iProp) +{ + m_lock.lock(); + + assert((m_vProps.at(iProp).iType & PTM_TYPE) == PT_UINT); + + int_t ulRet=m_vProps.at(iProp).val.ui.uiVal; + m_lock.unlock(); + return ulRet; +} + +/** Functions retrieves the longlong_t value associated with a given property ID. Can be called + * from any thread. + * \param[in] iProp - property identifier returned by one of the register_* functions + * \return The property value. + */ +longlong_t config::get_longlong(int_t iProp) +{ + m_lock.lock(); + + assert((m_vProps.at(iProp).iType & PTM_TYPE) == PT_LONGLONG); + + longlong_t llRet=m_vProps.at(iProp).val.ll.llVal; + m_lock.unlock(); + return llRet; +} + +/** Functions retrieves the ulonglong_t value associated with a given property ID. Can be called + * from any thread. + * \param[in] iProp - property identifier returned by one of the register_* functions + * \return The property value. + */ +ulonglong_t config::get_ulonglong(int_t iProp) +{ + m_lock.lock(); + + assert((m_vProps.at(iProp).iType & PTM_TYPE) == PT_ULONGLONG); + + ulonglong_t ullRet=m_vProps.at(iProp).val.ull.ullVal; + m_lock.unlock(); + return ullRet; +} + +/** Functions retrieves the bool value associated with a given property ID. Can be called + * from any thread. + * \param[in] iProp - property identifier returned by one of the register_* functions + * \return The property value. + */ +bool config::get_bool(int_t iProp) +{ + m_lock.lock(); + + assert((m_vProps.at(iProp).iType & PTM_TYPE) == PT_BOOL); + + bool bRet=m_vProps.at(iProp).val.bVal; + m_lock.unlock(); + return bRet; +} + +/** Functions retrieves the string value associated with a given property ID. Can be called + * from any thread. The string contained in the internal structure is copied to the buffer + * specified by user. Max count of chars that can be copied is specified by the buffer length. + * \param[in] iProp - property identifier returned by one of the register_* functions + * \param[out] psz - buffer for the string + * \param[in] tMaxLen - length of the buffer + */ +void config::get_string(int_t iProp, char_t* psz, size_t tMaxLen) +{ + m_lock.lock(); + + assert((m_vProps.at(iProp).iType & PTM_TYPE) == PT_STRING); + + _PROP& prop=m_vProps.at(iProp); + +#ifdef USE_ENCRYPTION + // if the property is encrypted and not decoded yet - decode it + try + { + decrypt_property(&prop); + } + catch(...) + { + m_lock.unlock(); + throw; + } +#endif + + char_t* pszSrc=prop.val.pszVal; + strncpy(psz, pszSrc, tMaxLen); + psz[tMaxLen-1]='\0'; + + m_lock.unlock(); +} + +/** Functions retrieves the int_t value associated with a given property ID. Can be called + * from any thread. Function returns a pointer to a string contained in the internal structures + * so it is definitely faster than the other get_string function, but is much nore dangerous. + * \param[in] iProp - property identifier returned by one of the register_* functions + * \return The pointer to a string contained in the internal structure. + */ +char_t* config::get_string(int_t iProp) +{ + m_lock.lock(); + + assert((m_vProps.at(iProp).iType & PTM_TYPE) == PT_STRING); + + _PROP& prop=m_vProps.at(iProp); + +#ifdef USE_ENCRYPTION + // if the property is encrypted and not decoded yet - decode it + try + { + decrypt_property(&prop); + } + catch(...) + { + m_lock.unlock(); + throw; + } +#endif + + char_t* psz=prop.val.pszVal; + char_t* pszNew=new char_t[strlen(psz)+1]; + strcpy(pszNew, psz); + + m_lock.unlock(); + + return pszNew; +} + +/** Function sets the int_t value for a property with specified ID. Can be + * called from any thread. + * \param[in] iProp - property identifier returned by one of the register_* functions + * \param[in] lVal - the new value of property to set + */ +void config::set_int(int_t iProp, int_t iVal, prop_group* pGroup) +{ + m_lock.lock(); + + // get the data + _PROP& prop=m_vProps.at(iProp); + + assert((m_vProps.at(iProp).iType & PTM_TYPE) == PT_INT); + + int_t iOldVal=prop.val.i.iVal; + + // check the range + if (iVal < prop.val.i.iLo) + prop.val.i.iVal=prop.val.i.iLo; + else if (iVal > prop.val.i.iHi) + prop.val.i.iVal=prop.val.i.iHi; + else + prop.val.i.iVal=iVal; + + bool bMod=(prop.val.i.iVal != iOldVal); + if (bMod) + { + prop.bModified=true; + m_bModified=true; + } + m_lock.unlock(); + + if (bMod) + { + if (pGroup) + pGroup->add(iProp); + else + { + prop_group* pg=begin_group(-1); + pg->add(iProp); + end_group(pg); + } + } +} + +/** Function sets the uint_t value for a property with specified ID. Can be + * called from any thread. + * \param[in] iProp - property identifier returned by one of the register_* functions + * \param[in] uiVal - the new value of property to set + */ +void config::set_uint(int_t iProp, uint_t uiVal, prop_group* pGroup) +{ + m_lock.lock(); + + // get the data + _PROP& prop=m_vProps.at(iProp); + + assert((m_vProps.at(iProp).iType & PTM_TYPE) == PT_UINT); + + uint_t uiOldVal=prop.val.ui.uiVal; + + // check the range + if (uiVal < prop.val.ui.uiLo) + prop.val.ui.uiVal=prop.val.ui.uiLo; + else if (uiVal > prop.val.ui.uiHi) + prop.val.ui.uiVal=prop.val.ui.uiHi; + else + prop.val.ui.uiVal=uiVal; + + bool bMod=(prop.val.ui.uiVal != uiOldVal); + + if (bMod) + { + prop.bModified=true; + m_bModified=true; + } + m_lock.unlock(); + + if (bMod) + { + if (pGroup) + pGroup->add(iProp); + else + { + prop_group* pg=begin_group(-1); + pg->add(iProp); + end_group(pg); + } + } +} + +/** Function sets the longlong_t value for a property with specified ID. Can be + * called from any thread. + * \param[in] iProp - property identifier returned by one of the register_* functions + * \param[in] llVal - the new value of property to set + */ +void config::set_longlong(int_t iProp, longlong_t llVal, prop_group* pGroup) +{ + m_lock.lock(); + + // get the data + _PROP& prop=m_vProps.at(iProp); + + assert((m_vProps.at(iProp).iType & PTM_TYPE) == PT_LONGLONG); + + ll_t llOldVal=prop.val.ll.llVal; + + // check the range + if (llVal < prop.val.ll.llLo) + prop.val.ll.llVal=prop.val.ll.llLo; + else if (llVal > prop.val.ll.llHi) + prop.val.ll.llVal=prop.val.ll.llHi; + else + prop.val.ll.llVal=llVal; + + bool bMod=(prop.val.ll.llVal != llOldVal); + + if (bMod) + { + prop.bModified=true; + m_bModified=true; + } + m_lock.unlock(); + + if (bMod) + { + if (pGroup) + pGroup->add(iProp); + else + { + prop_group* pg=begin_group(-1); + pg->add(iProp); + end_group(pg); + } + } +} + +/** Function sets the ulonglong_t value for a property with specified ID. Can be + * called from any thread. + * \param[in] iProp - property identifier returned by one of the register_* functions + * \param[in] ullVal - the new value of property to set + */ +void config::set_ulonglong(int_t iProp, ulonglong_t ullVal, prop_group* pGroup) +{ + m_lock.lock(); + + // get the data + _PROP& prop=m_vProps.at(iProp); + + assert((m_vProps.at(iProp).iType & PTM_TYPE) == PT_ULONGLONG); + + ull_t ullOldVal=prop.val.ull.ullVal; + + // check the range + if (ullVal < prop.val.ull.ullLo) + prop.val.ull.ullVal=prop.val.ull.ullLo; + else if (ullVal > prop.val.ull.ullHi) + prop.val.ull.ullVal=prop.val.ull.ullHi; + else + prop.val.ull.ullVal=ullVal; + + bool bMod=(prop.val.ull.ullVal != ullOldVal); + + if (bMod) + { + prop.bModified=true; + m_bModified=true; + } + m_lock.unlock(); + + if (bMod) + { + if (pGroup) + pGroup->add(iProp); + else + { + prop_group* pg=begin_group(-1); + pg->add(iProp); + end_group(pg); + } + } +} + +/** Function sets the bool value for a property with specified ID. Can be + * called from any thread. + * \param[in] iProp - property identifier returned by one of the register_* functions + * \param[in] bVal - the new value of property to set + */ +void config::set_bool(int_t iProp, bool bVal, prop_group* pGroup) +{ + m_lock.lock(); + + // get the data + _PROP& prop=m_vProps.at(iProp); + assert((m_vProps.at(iProp).iType & PTM_TYPE) == PT_BOOL); + + bool bMod=(prop.val.bVal != bVal); + if (bMod) + { + prop.val.bVal=bVal; + + prop.bModified=true; + m_bModified=true; + } + m_lock.unlock(); + + if (bMod) + { + if (pGroup) + pGroup->add(iProp); + else + { + prop_group* pg=begin_group(-1); + pg->add(iProp); + end_group(pg); + } + } +} + +/** Function sets the string value for a property with specified ID. Can be + * called from any thread. + * \param[in] iProp - property identifier returned by one of the register_* functions + * \param[in] pszVal - the new value of property to set + */ +void config::set_string(int_t iProp, const char_t* pszVal, prop_group* pGroup) +{ + m_lock.lock(); + + _PROP& prop=m_vProps.at(iProp); + + assert((m_vProps.at(iProp).iType & PTM_TYPE) == PT_STRING); + + delete [] prop.val.pszVal; + prop.val.pszVal=new char_t[strlen(pszVal)+1]; + strcpy(prop.val.pszVal, pszVal); + + prop.bModified=true; + m_bModified=true; + +#ifdef USE_ENCRYPTION + // make sure the property is marked decoded + if (prop.iType & PF_ENCRYPTED) + prop.iType |= PF_DECODED; +#endif + + m_lock.unlock(); + + if (pGroup) + pGroup->add(iProp); + else + { + prop_group* pg=begin_group(-1); + pg->add(iProp); + end_group(pg); + } +} + +#ifdef USE_ENCRYPTION + +/** The function starts a new property group. Used to group notifications about the property changes (usually + * sent by using set_* functions. The notification informations are being passed to the callback object only + * after the end_group() was called. + * \param[in] ulID - group id + * \return A pointer to a new property group. Must be released using end_group(). + */ +prop_group* config::begin_group(ulong_t ulID) +{ + return new prop_group(ulID); +} + +/** Ends a property group started with a begin_group(). Releases the allocated pointer and sends a group property + * change information to the callback. + * \param[in] pGroup - pointer to the property group allocated with begin_group() + */ +void config::end_group(prop_group* pGroup) +{ + assert(pGroup); + if (pGroup->count() > 0) + m_clbPropertyChanged.exec((ptr_t)pGroup->get_groupid(), (ptr_t)pGroup); + delete pGroup; +} + +/** This function sets a password to be used with the encrypted properties. If this is the first password to be used + * then it is being set only. But if there was another password set previously, then any property encoded with the + * previous password will be decrypted using an old password before setting a new one. + * \param[in] pszPass - a new password to be set. + */ +void config::set_password(const char_t* pszPass) +{ + m_lock.lock(); + + if (!m_strPassword.is_empty()) + { + // decrypt everything (if not already) using old password (if exists) + try + { + for (std::vector<_PROP>::iterator it=m_vProps.begin();it != m_vProps.end();it++) + { + decrypt_property(&(*it)); + } + } + catch(...) + { + m_lock.unlock(); + throw; + } + } + + // set a new pass + char_t szPass[64+1]; + str2key256(pszPass, szPass); + + m_strPassword=(const char_t*)szPass; + + m_lock.unlock(); +} + +/** Internal function that encrypts a one specified property structure. Does make a check regarding + * the correctness of the property. If it does not met the criteria, then function does nothing. + * \param[in/out] prop - address of the structure describing the property. + */ +void config::encrypt_property(_PROP* prop) +{ + printf("Encrypting...\n"); + + if ((prop->iType & (PT_STRING | PF_ENCRYPTED | PF_DECODED)) == (PT_STRING | PF_ENCRYPTED | PF_DECODED)) + { + printf("Real encrypt...\n"); + int_t iLen=(int_t)(((strlen(prop->val.pszVal)+1)*sizeof(char_t)+16)*2); + char_t *pszOut=new char_t[iLen]; + try + { + strcrypt_aes256(prop->val.pszVal, (const char_t*)m_strPassword, pszOut); + } + catch(...) + { + delete [] pszOut; + throw; + } + + delete [] prop->val.pszVal; + prop->val.pszVal=pszOut; + + prop->iType &= ~PF_DECODED; + } +} + +/** Internal function that decrypts a one specified property structure. Does make a check regarding + * the correctness of the property. If it does not met the criteria, then function does nothing. + * \param[in/out] prop - address of the structure describing the property. + */ +void config::decrypt_property(_PROP* prop) +{ + if ((prop->iType & (PT_STRING | PF_ENCRYPTED | PF_DECODED)) == (PT_STRING | PF_ENCRYPTED)) + { + int_t iLen=(int_t)(strlen(prop->val.pszVal)/2); + char_t *pszOut=new char_t[iLen]; + try + { + strdecrypt_aes256(prop->val.pszVal, (const char_t*)m_strPassword, pszOut); + } + catch(...) + { + delete [] pszOut; + throw; + } + + delete [] prop->val.pszVal; + prop->val.pszVal=pszOut; + + prop->iType |= PF_DECODED; + } +} + +#endif + +/** Function trims whitespaces at the beginning and at the end of a string. + * The data in the string is modified, so any whitespace char_t at the end of a string + * is replaced with '\\0', and the function returns a pointer to the first character + * in the string that is not a whitespace. + * \param[in,out] pszString - string to process + * \return Pointer to the first non-whitespace character in a string. + */ +char_t* config::trim(char_t* pszString) +{ + char_t *pszData=pszString; + + // skip the whitespaces at the beginning + while(is_whitespace(*pszData)) + pszData++; + + // the end + size_t iLen=strlen(pszData); + if (iLen != 0) + { + iLen--; + while (iLen > 0 && is_whitespace(*(pszData+iLen))) + pszData[iLen--]='\0'; + } + return pszData; +} + +/** Processes the two strings given (a key = value) - checks if there is any + * registered property with a given name, and if there is - the given value + * is applied to the property in the format specified by that property. + * \param[in] pszName - name of the property to find + * \param[in] pszValue - value of the property; the string is processed using + * the property type found + */ +void config::process_line(const char_t* pszName, const char_t* pszValue) +{ + // check if the property name is registered + for (std::vector<_PROP>::iterator it=m_vProps.begin();it != m_vProps.end();it++) + { + if (strcmp((*it).pszName, pszName) == 0) + { + // this function is called from read() which reads the standard stuff from a .conf file + (*it).bModified=false; + + // this is it - type of property + switch (it->iType & PTM_TYPE) + { + case PT_INT: + { + it->val.i.iVal=atol(pszValue); + break; + } + case PT_UINT: + { + it->val.ui.uiVal=strtoul(pszValue, NULL, 10); + break; + } + case PT_LONGLONG: + { +#ifdef _WIN32 + it->val.ll.llVal=_atoi64(pszValue); +#else + it->val.ll.llVal=atoll(pszValue); +#endif + break; + } + case PT_ULONGLONG: + { +#ifdef _WIN32 + it->val.ull.ullVal=(ulonglong_t)_atoi64(pszValue); +#else + it->val.ull.ullVal=(ulonglong_t)atoll(pszValue); +#endif + break; + } + case PT_BOOL: + { + if (strcmp(pszValue, "yes") == 0) + it->val.bVal=true; + else if (strcmp(pszValue, "no") == 0) + it->val.bVal=false; + else + it->val.bVal=atoi(pszValue) != 0; + break; + } + case PT_STRING: + { + // delete the old value and add the new one + delete [] it->val.pszVal; + it->val.pszVal=new char_t[strlen(pszValue)+1]; + strcpy(it->val.pszVal, pszValue); + + // update the encryption ststus +#ifdef USE_ENCRYPTION + (*it).iType &= ~PF_DECODED; +#endif + + break; + } + } + + // we need not more processing + return; + } + } + + // if the property wasn't found - add to the unreg as string prop + _PROP prop; + prop.iType=PT_STRING; + prop.pszName=new char_t[strlen(pszName)+1]; + strcpy(prop.pszName, pszName); + prop.bModified=false; + prop.val.pszVal=new char_t[strlen(pszValue)+1]; + strcpy(prop.val.pszVal, pszValue); + + m_vUnreg.push_back(prop); +} + +/** Prepares the string with the property value to be written to a file. + * There is no sane limitation of the string length (but one should be careful + * because such a limitation is integrated with read-related functions. + * \param[in] prop - pointer to the internal structure with property description + * \param[out] pres - pointer to a string object that will receive the line of text + */ +void config::prepare_line(const _PROP* prop, string* pres) +{ + assert(prop && pres); + + char_t szLine[MAX_LINE]; + switch(prop->iType & PTM_TYPE) + { + case PT_INT: + { + snprintf(szLine, MAX_LINE, STRFMT " = " LFMT, prop->pszName, prop->val.i.iVal); + break; + } + case PT_UINT: + { + snprintf(szLine, MAX_LINE, STRFMT " = " ULFMT, prop->pszName, prop->val.ui.uiVal); + break; + } + case PT_LONGLONG: + { + snprintf(szLine, MAX_LINE, STRFMT " = " LLFMT, prop->pszName, prop->val.ll.llVal); + break; + } + case PT_ULONGLONG: + { + snprintf(szLine, MAX_LINE, STRFMT " = " ULLFMT, prop->pszName, prop->val.ull.ullVal); + break; + } + case PT_BOOL: + { + snprintf(szLine, MAX_LINE, STRFMT " = " ULFMT, prop->pszName, (uint_t)prop->val.bVal); + break; + } + case PT_STRING: + { + snprintf(szLine, MAX_LINE, STRFMT " = " STRFMT, prop->pszName, prop->val.pszVal); + break; + } + } + + szLine[MAX_LINE-1]='\0'; +// printf(szLine); + *pres=szLine; +} + +/** Searches for a property with a given name and returns a property + * ID if found. + * \param[in] pszName - property name to search for + * \return The property ID if property has been found, or -1 if not. + */ +int_t config::is_registered(const char_t* pszName) +{ + // enum through all of the existing nodes + for (std::vector<_PROP>::iterator it=m_vProps.begin();it != m_vProps.end();it++) + { + if (strcmp(pszName, (*it).pszName) == 0) + return (int_t)(it-m_vProps.begin()); + } + + return -1; // no property found +} + +/** Searches for an unregistered property contained in the unreg container. Returns an + * index in the container unreg (if the entry have been found) or -1 (if not). + * \param[in] pszName - name of the property to search for + * \return Property index if found, -1 if not. + */ +int_t config::is_unreg(const char_t* pszName) +{ + // enum through all of the existing nodes + for (std::vector<_PROP>::iterator it=m_vUnreg.begin();it != m_vUnreg.end();it++) + { + if (strcmp(pszName, (*it).pszName) == 0) + return (int_t)(it-m_vUnreg.begin()); + } + + return -1; // no property found +} + +END_ICPF_NAMESPACE Index: ext/libicpf/src/cfg.h =================================================================== diff -u -N --- ext/libicpf/src/cfg.h (revision 0) +++ ext/libicpf/src/cfg.h (revision e17c80d36eaa0430313e7d1058aa7a301d1510af) @@ -0,0 +1,255 @@ +/*************************************************************************** + * Copyright (C) 2004 by J�zef Starosczyk * + * copyhandler@o2.pl * + * * + * This program 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 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 Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef __CFG_H__ +#define __CFG_H__ + +/** \file cfg.h + * \brief A placeholder for config class. + */ +#include +#include "mutex.h" +#include "libicpf.h" +#include "gen_types.h" +#include "callback.h" +#include "str.h" + +BEGIN_ICPF_NAMESPACE + +// property types +/// Property type mask +#define PTM_TYPE 0x00ff +/// Signed 32-bit type property +#define PT_INT 0x0001 +/// Unsigned 32-bit type property +#define PT_UINT 0x0002 +/// Signed 64-bit type property +#define PT_LONGLONG 0x0003 +/// Unsigned 64-bit type property +#define PT_ULONGLONG 0x0004 +/// Bool type property +#define PT_BOOL 0x0005 +/// String type property +#define PT_STRING 0x0006 + +// some flags +/// Property flags mask +#define PFM_FLAGS 0xff00 +/// Standard property flag +#define PF_NULL 0x0000 +/// The string specifies a pathname flag +#define PF_PATH 0x1000 +/// Flag that force checking if the property has already been registered (when registering a property) +#define PF_CHECK 0x2000 +/// This flag indicates that the property has been encrypted with a password (only string values) +#define PF_ENCRYPTED 0x4000 +/// The property is currently in decrypted state (but should be encrypted when saving) +#define PF_DECODED 0x8000 + +class config; + +extern config *__g_cfg; + +/** \brief Structure contain information about one property. + * + * Struct is used to store information about any property type (name, value, + * default value, allowed range, ...). + */ +struct _PROP +{ + int_t iType; ///< Type of the property (PT_*, PF_*) + char_t *pszName; ///< Property name (as displayed in the .conf file) + bool bModified; ///< States if the property value has been modified + union prop /// Union with different types of properties + { + struct INTP /// Long-type property + { + int_t iVal; ///< Long value + int_t iLo; ///< Minimum allowed value for the int_t property + int_t iHi; ///< Maximum allowed value for the int_t property + } i; + + struct UINTP /// Unsigned int_t-type property + { + uint_t uiVal; ///< Unsigned int_t value + uint_t uiLo; ///< Minimum allowed value for the uint_t property + uint_t uiHi; ///< Maximum allowed value for the uint_t property + } ui; + + struct LLVAL /// Long int_t-type property + { + longlong_t llVal; ///< Long int_t value + longlong_t llLo; ///< Minimum allowed value for the longlong_t property + longlong_t llHi; ///< Maximum allowed value for the longlong_t property + } ll; + + struct ULLVAL /// Unsigned longlong_t-type property + { + ulonglong_t ullVal; ///< Unsigned longlong_t value + ulonglong_t ullLo; ///< Minimum allowed value for the ulonglong_t property + ulonglong_t ullHi; ///< Maximum allowed value for the ulonglong_t property + } ull; + + bool bVal; ///< A bool-type value + + char_t* pszVal; ///< A string-type value + } val; + +}; + +/** \brief Property group handling class + * + * Class is being used to manipulate the property groups (in connection with config::begin_group() and + * config::end_group(). + */ +class LIBICPF_API prop_group +{ +public: + prop_group(ulong_t ulID) { m_ulGroupID=ulID; }; ///< Standard constructor + ~prop_group() { }; ///< Standard destructor + + void add(int_t iProp); ///< Adds a new property id to the list + bool is_set(int_t iProp); ///< Checks if a property id is set inside this list + ulong_t count(); ///< Returns a count of properties in a list + int_t get_at(int_t iIndex); ///< Returns a property id at a given index + ulong_t get_groupid(); ///< Retrieves the group id + +protected: + std::vector m_vProperties; ///< List of properties in a group + ulong_t m_ulGroupID; ///< The group ID +}; + +/** \brief Configuration management class. + * + * Class allows user to read and write configuration file in standard unix + * format (comments, empty lines and key=value strings). Class is fully thread-safe. + * Access to the properties is done by registering one and then getting or setting + * a value using the property identifier. + */ +class LIBICPF_API config +{ +public: +/** \name Construction/destruction */ +/**@{*/ + config(bool bGlobal); ///< Standard constructor + ~config(); ///< Standard destructor +/**@}*/ + +/** \name Reading and writing to the file */ +/**@{*/ + int_t read(const char_t *pszFile); ///< Opens the file with the properties + int_t write(const char_t* pszFile); ///< Saves the registered properties to the file +/**@}*/ + +/** \name Class lock/unlock functions */ +/**@{*/ + /// Locks the config class for one thread + void lock() { m_lock.lock(); }; + /// Unlocks the class + void unlock() { m_lock.unlock(); }; +/**@}*/ + + // property type management +/** Property types */ +/**@{*/ + int_t get_proptype(int_t iProp); ///< Retrieves the property type +/**@}*/ + + // registering the properties +/** \name Properties registration functions */ +/**@{*/ + /// Registers int_t-type property + int_t register_int(const char_t* pszName, int_t iDef, int_t iLo, int_t iHi, int_t iFlags=PF_NULL | PF_CHECK); + /// Registers uint_t-type property + int_t register_uint(const char_t* pszName, uint_t uiDef, uint_t uiLo, uint_t uiHi, int_t iFlags=PF_NULL | PF_CHECK); + /// Registers longlong_t-type property + int_t register_longlong(const char_t* pszName, longlong_t llDef, longlong_t llLo, longlong_t llHi, int_t iFlags=PF_NULL | PF_CHECK); + /// Registers ulonglong_t-type property + int_t register_ulonglong(const char_t* pszName, ulonglong_t ullDef, ulonglong_t ullLo, ulonglong_t ullHi, int_t iFlags=PF_NULL | PF_CHECK); + /// Registers bool-type property + int_t register_bool(const char_t* pszName, bool bDef, int_t iFlags=PF_NULL | PF_CHECK); + /// Registers string-type property + int_t register_string(const char_t* pszName, const char_t* pszDef, int_t iFlags=PF_NULL | PF_CHECK); +/**@}*/ + + + // getting property data +/** \name Getting and setting values */ +/**@{*/ + int_t get_int(int_t iProp); ///< Gets the value of int_t-type property + uint_t get_uint(int_t iProp); ///< Gets the value of uint_t-type property + longlong_t get_longlong(int_t iProp); ///< Gets the value of longlong_t-type property + ulonglong_t get_ulonglong(int_t iProp); ///< Gets the value of ulonglong_t-type property + bool get_bool(int_t iProp); ///< Gets the value of bool-type property + void get_string(int_t iProp, char_t* psz, size_t tMaxLen); ///< Gets the value of string-type property + char_t* get_string(int_t iProp); ///< Gets the value of ulonglong_t-type property (faster and more dangerous) + + // setting property data + void set_int(int_t iProp, int_t iVal, prop_group* pGroup=NULL); ///< Sets the value of int_t-type property + void set_uint(int_t iProp, uint_t uiVal, prop_group* pGroup=NULL); ///< Sets the value of uint_t-type property + void set_longlong(int_t iProp, longlong_t llVal, prop_group* pGroup=NULL); ///< Sets the value of longlong_t-type property + void set_ulonglong(int_t iProp, ulonglong_t ullVal, prop_group* pGroup=NULL); ///< Sets the value of ulonglong_t-type property + void set_bool(int_t iProp, bool bVal, prop_group* pGroup=NULL); ///< Sets the value of bool-type property + void set_string(int_t iProp, const char_t* pszVal, prop_group* pGroup=NULL); ///< Sets the value of string-type property +/**@}*/ + + // group support +/** \name Property group support */ +/**@{*/ + prop_group* begin_group(ulong_t ulID); ///< Begins a property group (currently handles multiple property changes when setting property values) + void end_group(prop_group* pGroup); ///< Ends a property group +/**@}*/ + +#ifdef USE_ENCRYPTION +/** \name Encryption related */ +/**@{*/ + void set_password(const char_t* pszPass); ///< Sets a password to encrypt/decrypt the properties +/**@}*/ +#endif + + friend config* get_config(); ///< Retrieves the pointer to the global config class + +protected: + char_t* trim(char_t* pszString); ///< Gets rid of whitespace characters from a string + void process_line(const char_t* pszName, const char_t* pszValue); ///< Sets a property value if registered + void prepare_line(const _PROP* prop, string* pres); ///< Prepares a line of text with property key and value to write to a file + int_t is_registered(const char_t* pszName); ///< Checks if a property with a given key has been registered + int_t is_unreg(const char_t* pszName); ///< Chacks if the path is contained in unreg container + +#ifdef USE_ENCRYPTION + void encrypt_property(_PROP* prop); ///< Encrypts a string property + void decrypt_property(_PROP* prop); ///< Decrypts a string property +#endif + +public: + mutex m_lock; ///< Lock for the multi-threaded access to the properties + std::vector<_PROP> m_vProps; ///< Vector with properties + std::vector<_PROP> m_vUnreg; ///< Properties read from file, but not registered. + bool m_bModified; ///< Global modification flag - states if any property is in modified state + +#ifdef USE_ENCRYPTION + string m_strPassword; ///< Password to encrypt/decrypt properties with +#endif + callback2 m_clbPropertyChanged; ///< Callback (callback1) which is executed when any property has changed + // First param is count of properties changed (-1 if all changed), second one the prop_group* (or NULL if none changed) +}; + +END_ICPF_NAMESPACE + +#endif Index: ext/libicpf/src/conv.cpp =================================================================== diff -u -N --- ext/libicpf/src/conv.cpp (revision 0) +++ ext/libicpf/src/conv.cpp (revision e17c80d36eaa0430313e7d1058aa7a301d1510af) @@ -0,0 +1,75 @@ +/*************************************************************************** + * Copyright (C) 2004 by J�zef Starosczyk * + * copyhandler@o2.pl * + * * + * This program 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 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 Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "conv.h" +#include + +BEGIN_ICPF_NAMESPACE + +char_t __hex[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; + +LIBICPF_API void bin2hex(uchar_t* pbyIn, uint_t tInCount, char_t *pszOut) +{ + for (uint_t i=0;i> 4) & 0x0f]; + *pszOut++=__hex[pbyIn[i] & 0x0f]; + } +} + +LIBICPF_API bool hex2bin(const char_t* pszIn, uint_t tInCount, uchar_t *pbyOut) +{ + // we can pass -1 as in size - count it then + if (tInCount == (uint_t)-1) + tInCount=strlen(pszIn); + + // make sure the tInCount is even + tInCount &= ~((size_t)1); + uchar_t by; + for (size_t i=0;i= '0' && *pszIn <= '9') + by=(*pszIn - '0') << 4; + else if (*pszIn >= 'a' && *pszIn <= 'f') + by=(*pszIn - 'a' + 10) << 4; + else if (*pszIn >= 'A' && *pszIn <= 'F') + by=(*pszIn - 'A' + 10) << 4; + else + return false; + + // lsb 4bits + *pszIn++; + if (*pszIn >= '0' && *pszIn <= '9') + by|=(*pszIn - '0'); + else if (*pszIn >= 'a' && *pszIn <= 'f') + by|=(*pszIn - 'a' + 10); + else if (*pszIn >= 'A' && *pszIn <= 'F') + by|=(*pszIn - 'A' + 10); + else + return false; + + *pszIn++; + *pbyOut++=by; + } + + return true; +} + +END_ICPF_NAMESPACE Index: ext/libicpf/src/conv.h =================================================================== diff -u -N --- ext/libicpf/src/conv.h (revision 0) +++ ext/libicpf/src/conv.h (revision e17c80d36eaa0430313e7d1058aa7a301d1510af) @@ -0,0 +1,34 @@ +/*************************************************************************** + * Copyright (C) 2004 by J�zef Starosczyk * + * copyhandler@o2.pl * + * * + * This program 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 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 Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef __CONV_H__ +#define __CONV_H__ + +#include "libicpf.h" +#include "gen_types.h" + +BEGIN_ICPF_NAMESPACE + +LIBICPF_API void bin2hex(uchar_t *pbyIn, uint_t tInCount, char_t *pszOut); +LIBICPF_API bool hex2bin(const char_t* pszIn, uint_t tInCount, uchar_t* pbyOut); + +END_ICPF_NAMESPACE + +#endif + Index: ext/libicpf/src/crc32.cpp =================================================================== diff -u -N --- ext/libicpf/src/crc32.cpp (revision 0) +++ ext/libicpf/src/crc32.cpp (revision e17c80d36eaa0430313e7d1058aa7a301d1510af) @@ -0,0 +1,156 @@ +/*************************************************************************** + * Copyright (C) 2004 by J�zef Starosczyk * + * copyhandler@o2.pl * + * * + * This program 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 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 Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +/** \file crc32.cpp + * \brief Contain implementation of a function counting crc32 checksum + */ + +#include "crc32.h" +#include + +BEGIN_ICPF_NAMESPACE + +/// Helper data for calculating crc32 values +uint_t __crc32data__[256] = +{ + 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, + 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, + 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, + 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, + 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, + 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, + 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, + 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, + 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, + 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, + 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, + 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, + 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, + 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, + 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, + 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, + + 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, + 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, + 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, + 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, + 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, + 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, + 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, + 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, + 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, + 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, + 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, + 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, + 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, + 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, + 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, + 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, + + 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, + 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, + 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, + 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, + 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, + 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, + 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, + 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, + 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, + 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, + 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, + 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, + 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, + 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, + 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, + 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, + + 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, + 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, + 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, + 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, + 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, + 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, + 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, + 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, + 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, + 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, + 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, + 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, + 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, + 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, + 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, + 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D, +}; + +/** \brief Updates the partial crc32 checksum with an additional byte. + * \param[in] byte - next byte of a buffer to process + * \param[in,out] pdwCrc32 - ptr to a current crc32 checksum + */ +inline void __crc32partial(byte_t byte, uint_t *pdwCrc32) +{ + *pdwCrc32 = ((*pdwCrc32) >> 8) ^ __crc32data__[byte ^ ((*pdwCrc32) & 0x000000FF)]; +} + +/** Function calculates the crc32 checksum for the given data buffer. + * \param[in] pbyData - pointer to a buffer with data which checksum is to be calculated + * \param[in] tLen - length of the data in a buffer + * \return Calculated crc32 checksum. + */ +uint_t crc32(byte_t* pbyData, size_t tLen) +{ + uint_t dwCRC=0xffffffff; + for (size_t i=0;i + +BEGIN_ICPF_NAMESPACE + +/// Calculates crc32 checksum for a given data +LIBICPF_API uint_t crc32(byte_t* pbyData, size_t tLen); + +LIBICPF_API void crc32_begin(uint_t *puiValue); +LIBICPF_API void crc32_partial(uint_t *puiPrev, byte_t *pbyData, size_t tLen); +LIBICPF_API void crc32_finish(uint_t* puiValue); + +END_ICPF_NAMESPACE + +#endif Index: ext/libicpf/src/crypt.cpp =================================================================== diff -u -N --- ext/libicpf/src/crypt.cpp (revision 0) +++ ext/libicpf/src/crypt.cpp (revision e17c80d36eaa0430313e7d1058aa7a301d1510af) @@ -0,0 +1,166 @@ +/*************************************************************************** + * Copyright (C) 2004 by J�zef Starosczyk * + * copyhandler@o2.pl * + * * + * This program 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 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 Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "crypt.h" +#include "rijndael-api-fst.h" +#include "conv.h" +#include "sha256.h" +#include "exception.h" +#include "err_codes.h" +#include + +#ifdef USE_ENCRYPTION + +BEGIN_ICPF_NAMESPACE + +// output buffer might be in size+16 +LIBICPF_API int_t crypt_aes256(const ptr_t pIn, int_t iCnt, const char_t* pszPass, ptr_t pOut) +{ + // init the cipher + cipherInstance ci; + int_t iRes; + if ((iRes=cipherInit(&ci, MODE_ECB, NULL)) < 0) + THROW(exception::format("cipherInit() in crypt_aes256() failed with result " IFMT, iRes), EE_INIT, 0, 0); + + // make the key + keyInstance ki; + if ((iRes=makeKey(&ki, DIR_ENCRYPT, 256, pszPass)) < 0) + THROW(exception::format("makeKey in crypt_aes256() failed with result " IFMT, iRes), EE_CRYPT, 0, 0); + + // now encrypt the data + if ((iRes=padEncrypt(&ci, &ki, (uchar_t*)pIn, iCnt, (uchar_t*)pOut)) < 0) + THROW(exception::format("padEncrypt() in crypt_aes256() failed with result " IFMT, iRes), EE_CRYPT, 0, 0); + + return iRes; +} + +// output buffer has to have iCnt size +LIBICPF_API int_t decrypt_aes256(const ptr_t pIn, int_t iCnt, const char_t* pszPass, ptr_t pOut) +{ + // init the cipher + cipherInstance ci; + int iRes; + if ((iRes=cipherInit(&ci, MODE_ECB, NULL)) < 0) + THROW(exception::format("cipherInit() in decrypt_aes256() failed with result " IFMT, iRes), EE_INIT, 0, 0); + + // make the key + keyInstance ki; + if ((iRes=makeKey(&ki, DIR_DECRYPT, 256, pszPass)) < 0) + THROW(exception::format("makeKey in decrypt_aes256() failed with result " IFMT, iRes), EE_DECRYPT, 0, 0); + + // decrypt the data + if ((iRes=padDecrypt(&ci, &ki, (uchar_t*)pIn, iCnt, (uchar_t*)pOut)) <= 0) + THROW(exception::format("padEncrypt() in decrypt_aes256() failed with result " IFMT, iRes), EE_DECRYPT, 0, 0); + + return iRes; +} + +// out buffer has to be of size ((_tcslen(pszIn)+1)*sizeof(char_t)+16)*2 +LIBICPF_API int_t strcrypt_aes256(const char_t* pszIn, const char_t* pszPass, char_t* pszOut) +{ + // init the cipher + cipherInstance ci; + int_t iRes; + if ((iRes=cipherInit(&ci, MODE_ECB, NULL)) < 0) + THROW(exception::format("cipherInit() in strcrypt_aes256() failed with result " IFMT, iRes), EE_INIT, 0, 0); + + // make the key + keyInstance ki; + if ((iRes=makeKey(&ki, DIR_ENCRYPT, 256, pszPass)) < 0) + THROW(exception::format("cipherInit() in strcrypt_aes256() failed with result " IFMT, iRes), EE_INIT, 0, 0); + + // count of data to encrypt, buffer for encrypted output + size_t tLen=strlen(pszIn)+1; + char_t *pszData=new char_t[tLen+16]; // for padding + + // now encrypt the data + if ((iRes=padEncrypt(&ci, &ki, (uchar_t*)pszIn, (int_t)tLen*sizeof(char_t), (uchar_t*)pszData)) < 0) + { + delete [] pszData; + THROW(exception::format("padEncrypt() in strcrypt_aes256() failed with result " IFMT, iRes), EE_DECRYPT, 0, 0); + } + + // make the data hex + bin2hex((uchar_t*)pszData, iRes, pszOut); + pszOut[iRes*2]='\0'; + + // delete the old stuff + delete [] pszData; + + return iRes*2; +} + +// out buffer size must be _tcslen(pszIn)/2 +LIBICPF_API int_t strdecrypt_aes256(const char_t* pszIn, const char_t* pszPass, char_t* pszOut) +{ + // count of input data - check if there is anything to process + size_t tLen=strlen(pszIn); + + // init the cipher + cipherInstance ci; + int iRes; + if ((iRes=cipherInit(&ci, MODE_ECB, NULL)) < 0) + THROW(exception::format("cipherInit() in crypt_aes256() failed with result " IFMT, iRes), EE_INIT, 0, 0); + + // make the key + keyInstance ki; + if ((iRes=makeKey(&ki, DIR_DECRYPT, 256, pszPass)) < 0) + THROW(exception::format("cipherInit() in strcrypt_aes256() failed with result " IFMT, iRes), EE_INIT, 0, 0); + + // buffer for hex data + uchar_t *pby=new uchar_t[tLen/2]; + + // decode hex data + if (!hex2bin(pszIn, tLen, pby)) + { + delete [] pby; + THROW("hex2bin in strdecrypt_aes256() failed", CE_HEX2BIN, 0, 0); + } + + // decrypt the data + if ((iRes=padDecrypt(&ci, &ki, pby, (int)tLen/2, (uchar_t*)(pszOut))) <= 0) + { + delete [] pby; + THROW(exception::format("padDecrypt() in strdecrypt_aes256() failed with result " IFMT, iRes), EE_DECRYPT, 0, 0); + } + + // delete buffers + delete [] pby; + + return (int_t)strlen(pszOut); +} + +// pszKey of size 64+1B +LIBICPF_API void str2key256(const char_t* pszString, char_t* pszKey) +{ + // generate the SHA256 from this password + uchar_t byData[32]; + sha256_context sc; + sha256_starts(&sc); + sha256_update(&sc, (uchar_t*)pszString, (ulong_t)strlen(pszString)*sizeof(char_t)); + sha256_finish(&sc, byData); + + // now the hexed hash + bin2hex(byData, 32, pszKey); + pszKey[64]='\0'; +} + +END_ICPF_NAMESPACE + +#endif Index: ext/libicpf/src/crypt.h =================================================================== diff -u -N --- ext/libicpf/src/crypt.h (revision 0) +++ ext/libicpf/src/crypt.h (revision e17c80d36eaa0430313e7d1058aa7a301d1510af) @@ -0,0 +1,49 @@ +/*************************************************************************** + * Copyright (C) 2004 by J�zef Starosczyk * + * copyhandler@o2.pl * + * * + * This program 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 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 Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef __CRYPT_H__ +#define __CRYPT_H__ + +#include "libicpf.h" +#include "gen_types.h" + +#ifdef USE_ENCRYPTION + +BEGIN_ICPF_NAMESPACE + +/// output buffer might be in size+16 +LIBICPF_API int_t crypt_aes256(const ptr_t pIn, int_t iCnt, const char_t* pszPass, ptr_t pOut); + +// output buffer has to have iCnt size +LIBICPF_API int_t decrypt_aes256(const ptr_t pIn, int_t iCnt, const char_t* pszPass, ptr_t pOut); + +// out buffer has to be of size ((strlen(pszIn)+1)*sizeof(char_t)+16)*2 +LIBICPF_API int_t strcrypt_aes256(const char_t* pszIn, const char_t* pszPass, char_t* pszOut); + +// out buffer size must be strlen(pszIn)/2 +LIBICPF_API int_t strdecrypt_aes256(const char_t* pszIn, const char_t* pszPass, char_t* pszOut); + +// pszKey of size 64+1B +LIBICPF_API void str2key256(const char_t* pszString, char_t* pszKey); + +END_ICPF_NAMESPACE + +#endif + +#endif Index: ext/libicpf/src/dumpctx.cpp =================================================================== diff -u -N --- ext/libicpf/src/dumpctx.cpp (revision 0) +++ ext/libicpf/src/dumpctx.cpp (revision e17c80d36eaa0430313e7d1058aa7a301d1510af) @@ -0,0 +1,236 @@ +/*************************************************************************** + * Copyright (C) 2004 by J�zef Starosczyk * + * copyhandler@o2.pl * + * * + * This program 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 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 Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +/** \file dumpctx.cpp + * \brief Contain implementation of class dumpctx - a debug helper class. + */ +#include "dumpctx.h" +#include +#include "log.h" +#include "macros.h" + +BEGIN_ICPF_NAMESPACE + +#ifdef _WIN32 + #define snprintf _snprintf +#endif + +/** Constructor stores the passed data in the internal members. + * \param[in] uiType - type of dump (one of the DCX_*) + * \param[in] pParam - additional param - the type of theis param depends on the ulType + */ +dumpctx::dumpctx(uint_t uiType, ptr_t pParam) +{ + m_uiType=uiType; + if (uiType == DCX_FILE) + { + size_t tLen=strlen((const char_t*)pParam); + m_pParam=(ptr_t)new char_t[tLen+1]; + strcpy((char_t*)m_pParam, (const char_t*)pParam); + } + else + m_pParam=pParam; +} + +/** Destructor frees the internal data if needed + */ +dumpctx::~dumpctx() +{ + if (m_uiType == DCX_FILE) + delete [] (char_t*)m_pParam; +} + +/** Function opens the dump. It means initializing the internal string + * that will contain the dump result and locking the class (using mutex). + * \note Always call the close() member if you have opened the dump. + */ +void dumpctx::open(const char_t* pszObject) +{ + m_lock.lock(); + m_strBuffer=pszObject; + m_strBuffer+="\n"; +} + +/** Closes the dump. Depending on the type specified in the constructor the + * function outputs the dump to the specified location. Also the internal + * buffer is cleared. + */ +void dumpctx::close() +{ + // perform a dump - depending on the type of a dest object + switch(m_uiType) + { + case DCX_STD: + { + printf(m_strBuffer); + break; + } + case DCX_FILE: + { + FILE* pFile=fopen((const char_t*)m_pParam, "a"); + if (pFile != NULL) + { + fprintf(pFile, m_strBuffer); + fclose(pFile); + } + + break; + } + case DCX_FILEHANDLE: + { + fprintf((FILE*)m_pParam, m_strBuffer); + break; + } + case DCX_LOG: + { + ((log_file*)m_pParam)->logd(m_strBuffer); + break; + } + } + + // clean the internal buffer + m_strBuffer.clear(); + + m_lock.unlock(); +} + +/** Function dumps (stores in the internal string object) the given ansi string. + * Strings longer than MAX_DUMP characters will be truncated. + * \param[in] pszName - name of the member variable of the dumped object + * \param[in] pszValue - an ansi string - the value of a given member + */ +void dumpctx::dump(const char_t* pszName, const char_t* pszValue) +{ + snprintf(m_szBuffer, MAX_DUMP, STRFMT " (string):\n\t" PTRFMT " (\"" STRFMT "\")\n", pszName, pszValue, pszValue); + m_szBuffer[MAX_DUMP-1]='\0'; + m_strBuffer+=m_szBuffer; +} + +/** Function dumps (stores in the internal string object) the given unicode string. + * Strings longer than MAX_DUMP characters will be truncated. + * \param[in] pszName - name of the member variable of the dumped object + * \param[in] pszValue - an unicode string - the value of a given member + */ +void dumpctx::dump(const char_t* pszName, const wchar_t* pszValue) +{ + snprintf(m_szBuffer, MAX_DUMP, STRFMT " (wide string):\n\t" PTRFMT " (\"" WSTRFMT "\")\n", pszName, pszValue, pszValue); + m_szBuffer[MAX_DUMP-1]='\0'; + m_strBuffer+=m_szBuffer; +} + +/** Function dumps (stores in the internal string object) the given character. + * \param[in] pszName - name of the member variable of the dumped object + * \param[in] cValue - a character (signed char_t) value + */ +void dumpctx::dump(const char_t* pszName, const char_t cValue) +{ + snprintf(m_szBuffer, MAX_DUMP, STRFMT " (char_t):\n\t'" CHARFMT "' (hex: " CXFMT " / dec: " CFMT ")\n", pszName, cValue, (short_t)cValue, (short_t)cValue); + m_szBuffer[MAX_DUMP-1]='\0'; + m_strBuffer+=m_szBuffer; +} + +/** Function dumps (stores in the internal string object) the given short_t. + * \param[in] pszName - name of the member variable of the dumped object + * \param[in] sValue - a short_t value to dump + */ +void dumpctx::dump(const char_t* pszName, const short_t sValue) +{ + snprintf(m_szBuffer, MAX_DUMP, STRFMT " (short_t):\n\t" SFMT " (hex: " SXFMT ")\n", pszName, sValue, sValue); + m_szBuffer[MAX_DUMP-1]='\0'; + m_strBuffer+=m_szBuffer; +} + +/** Function dumps (stores in the internal string object) the given int_t. + * \param[in] pszName - name of the member variable of the dumped object + * \param[in] iValue - a int_t value to dump + */ +void dumpctx::dump(const char_t* pszName, const int_t iValue) +{ + snprintf(m_szBuffer, MAX_DUMP, STRFMT " (int_t):\n\t" LFMT " (hex: " LXFMT ")\n", pszName, iValue, iValue); + m_szBuffer[MAX_DUMP-1]='\0'; + m_strBuffer+=m_szBuffer; +} + +/** Function dumps (stores in the internal string object) the given uchar_t. + * \param[in] pszName - name of the member variable of the dumped object + * \param[in] ucValue - an uchar_t value to dump + */ +void dumpctx::dump(const char_t* pszName, const uchar_t ucValue) +{ + snprintf(m_szBuffer, MAX_DUMP, STRFMT " (uchar_t):\n\t'" UCHARFMT "' (hex: " UCXFMT " / dec: " UCFMT ")\n", pszName, ucValue, (ushort_t)ucValue, (ushort_t)ucValue); + m_szBuffer[MAX_DUMP-1]='\0'; + m_strBuffer+=m_szBuffer; +} + +/** Function dumps (stores in the internal string object) the given ushort_t. + * \param[in] pszName - name of the member variable of the dumped object + * \param[in] usValue - an ushort_t value to dump + */ +void dumpctx::dump(const char_t* pszName, const ushort_t usValue) +{ + snprintf(m_szBuffer, MAX_DUMP, STRFMT " (ushort_t):\n\t" USFMT " (hex: " USXFMT ")\n", pszName, usValue, usValue); + m_szBuffer[MAX_DUMP-1]='\0'; + m_strBuffer+=m_szBuffer; +} + +/** Function dumps (stores in the internal string object) the given uint_t. + * \param[in] pszName - name of the member variable of the dumped object + * \param[in] uiValue - an uint_t value to dump + */ +void dumpctx::dump(const char_t* pszName, const uint_t uiValue) +{ + snprintf(m_szBuffer, MAX_DUMP, STRFMT " (uint_t):\n\t" ULFMT " (hex: " ULXFMT ")\n", pszName, uiValue, uiValue); + m_szBuffer[MAX_DUMP-1]='\0'; + m_strBuffer+=m_szBuffer; +} + +/** Function dumps (stores in the internal string object) the longlong_t. + * \param[in] pszName - name of the member variable of the dumped object + * \param[in] llValue - a longlong_t value to dump + */ +void dumpctx::dump(const char_t* pszName, const longlong_t llValue) +{ + snprintf(m_szBuffer, MAX_DUMP, STRFMT " (longlong_t):\n\t" LLFMT " (hex: " LLXFMT ")\n", pszName, llValue, llValue); + m_szBuffer[MAX_DUMP-1]='\0'; + m_strBuffer+=m_szBuffer; +} + +/** Function dumps (stores in the internal string object) the ulonglong_t. + * \param[in] pszName - name of the member variable of the dumped object + * \param[in] ullValue - an ulonglong_t value to dump + */ +void dumpctx::dump(const char_t* pszName, const ulonglong_t ullValue) +{ + snprintf(m_szBuffer, MAX_DUMP, STRFMT " (ulonglong_t):\n\t" ULLFMT " (hex: " ULLXFMT ")\n", pszName, ullValue, ullValue); + m_szBuffer[MAX_DUMP-1]='\0'; + m_strBuffer+=m_szBuffer; +} + +/** Function dumps (stores in the internal string object) the untyped pointer. + * \param[in] pszName - name of the member variable of the dumped object + * \param[in] pValue - an untyped pointer value to dump + */ +void dumpctx::dump(const char_t* pszName, const ptr_t pValue) +{ + snprintf(m_szBuffer, MAX_DUMP, STRFMT " (ptr_t):\n\t" PTRFMT "\n", pszName, pValue); + m_szBuffer[MAX_DUMP-1]='\0'; + m_strBuffer+=m_szBuffer; +} + +END_ICPF_NAMESPACE Index: ext/libicpf/src/dumpctx.h =================================================================== diff -u -N --- ext/libicpf/src/dumpctx.h (revision 0) +++ ext/libicpf/src/dumpctx.h (revision e17c80d36eaa0430313e7d1058aa7a301d1510af) @@ -0,0 +1,97 @@ +/*************************************************************************** + * Copyright (C) 2004 by J�zef Starosczyk * + * copyhandler@o2.pl * + * * + * This program 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 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 Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +/** \file dumpctx.h + * \brief Contain class dumpctx - a debug helper class. + */ + +#ifndef __DUMPCONTEXT_H__ +#define __DUMPCONTEXT_H__ + +#include "mutex.h" +#include "gen_types.h" +#include "str.h" + +BEGIN_ICPF_NAMESPACE + +/// Maximum size of a single variable dump (ie. string) +#define MAX_DUMP 4096 + +// dump type flags +/// Std out; pParam is NULL +#define DCX_STD 0x00000000 +/// File object; pParam is const char_t* with file path +#define DCX_FILE 0x00000001 +/// File object; pParam is FILE* - handle to a file opened in write mode +#define DCX_FILEHANDLE 0x00000002 +/// Log file; pParam is log_file* with the given log (dump's will be logged as LT_DEBUG) +#define DCX_LOG 0x00000003 + + +/** \brief Class used as dump context (debugging purposes). + * + * Class should be used to perform dump's of any object's internal state. + * Any class could (should?) use this class as a param to the dump member. + * Usage is quite simple - construct an object with needed flags and when + * need to dump an object - call open with an object name, dump what's needed + * and then close. + * Class is thread safe. + */ +class LIBICPF_API dumpctx +{ +public: +/** \name Construction/destruction */ +/**@{*/ + dumpctx(uint_t ulType, ptr_t pParam=NULL); ///< Standard constructor + ~dumpctx(); ///< Standard destructor +/**@}*/ + +/** \name Opening/closing dump process */ +/**@{*/ + void open(const char_t* pszObject); ///< Begins the specified object dump + void close(); ///< Ends the object dump +/**@}*/ + +/** \name Dumping functions + * Operations to be executed between calls to open() and close() + */ +/**@{*/ + void dump(const char_t* pszName, const char_t* pszValue); ///< Ansi string dump + void dump(const char_t* pszName, const wchar_t* pszValue); ///< Unicode string dump + void dump(const char_t* pszName, const char_t cValue); ///< char_t dump + void dump(const char_t* pszName, const short_t sValue); ///< short_t dump + void dump(const char_t* pszName, const int_t iValue); ///< int_t dump + void dump(const char_t* pszName, const uchar_t ucValue); ///< uchar_t dump + void dump(const char_t* pszName, const ushort_t usValue); ///< ushort_t dump + void dump(const char_t* pszName, const uint_t uiValue); ///< uint_t dump + void dump(const char_t* pszName, const longlong_t llValue); ///< longlong_t dump + void dump(const char_t* pszName, const ulonglong_t ullValue); ///< ulonglong_t dump + void dump(const char_t* pszName, const ptr_t pValue); ///< pointer dump +/**@}*/ +protected: + mutex m_lock; ///< Mutex blocking class between open() and close() calls + string m_strBuffer; ///< String object that will gather information about dump + char_t m_szBuffer[MAX_DUMP]; ///< Buffer used in formatting output data + uint_t m_uiType; ///< Type of dump (as passed to constructor) + ptr_t m_pParam; ///< Parameter - the real type depends on the m_ulType field +}; + +END_ICPF_NAMESPACE + +#endif Index: ext/libicpf/src/err_codes.h =================================================================== diff -u -N --- ext/libicpf/src/err_codes.h (revision 0) +++ ext/libicpf/src/err_codes.h (revision e17c80d36eaa0430313e7d1058aa7a301d1510af) @@ -0,0 +1,99 @@ +/*************************************************************************** + * Copyright (C) 2004 by J�zef Starosczyk * + * copyhandler@o2.pl * + * * + * This program 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 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 Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef __ERR_CODES_H__ +#define __ERR_CODES_H__ + +//////////////////////////////////////////////////////////////// +// file related +/// Base define for file related errors +#define FE_BASE 0x00010000 + +/// Unknown error +#define FERR_UNKNOWN (FE_BASE+0x0000) +/// Error while opening file +#define FERR_OPEN (FE_BASE+0x0001) +/// Error while closing file +#define FERR_CLOSE (FE_BASE+0x0002) +/// Error reading data from file +#define FERR_READ (FE_BASE+0x0003) +/// Error writing data to a file +#define FERR_WRITE (FE_BASE+0x0004) +/// Error setting file pointer position +#define FERR_SEEK (FE_BASE+0x0005) +/// eof encountered - currently unused +#define FERR_EOF (FE_BASE+0x0006) +/// error while setting an eof in file +#define FERR_SETEOF (FE_BASE+0x0007) +/// error getting file size +#define FERR_GETSIZE (FE_BASE+0x0008) +/// serialization error +#define FERR_SERIALIZE (FE_BASE+0x0009) +/// trying to read the data beyond the index +#define FERR_MEMORY (FE_BASE+0x000a) +/// encryption/decryption error +#define FERR_CRYPT (FE_BASE+0x000b) +/// search error +#define FERR_SEARCH (FE_BASE+0x000c) +/// set/get attrib error +#define FERR_FINFO (FE_BASE+0x000d) +/// fast-move/rename error +#define FERR_MOVE (FE_BASE+0x000e) +/// Unicode strings not supported in this build of library +#define FERR_UNICODE (FE_BASE+0x000f) + +//////////////////////////////////////////////////////////////////// +// module-related +/// Base define for module related errors +#define PE_BASE 0x00000000 + +/// plugin found with the id equal to one of the loaded plugins +#define PE_DUPLICATEPLUG (PE_BASE+0x0000) +/// the module does not implement a mandatory function (or other words - cannot load an export from a module) +#define PE_CALLNOTIMPLEMENTED (PE_BASE+0x0001) +/// the search error +#define PE_SEARCHERROR (PE_BASE+0x0002) +/// Cannot load an external module +#define PE_CANNOTLOAD (PE_BASE+0x0003) +/// Cannot unload the external module +#define PE_CANNOTUNLOAD (PE_BASE+0x0004) +/// Module not found +#define PE_NOTFOUND (PE_BASE+0x0005) + +///////////////////////////////////////////////////////////////////// +// encryption related + +/// Base define for encryption related error codes +#define EE_BASE 0x00020000 + +/// Initialization of the cipher failed +#define EE_INIT (EE_BASE+0x0000) +/// Encryption failed +#define EE_CRYPT (EE_BASE+0x0001) +/// Decryption failed +#define EE_DECRYPT (EE_BASE+0x0002) + +///////////////////////////////////////////////////////////////////// +// conversion related +/// Base define for conversion errors +#define CE_BASE 0x00030000 +/// Error in converting a hex string to the binary data +#define CE_HEX2BIN (CE_BASE+0x0000) + +#endif Index: ext/libicpf/src/exception.cpp =================================================================== diff -u -N --- ext/libicpf/src/exception.cpp (revision 0) +++ ext/libicpf/src/exception.cpp (revision e17c80d36eaa0430313e7d1058aa7a301d1510af) @@ -0,0 +1,184 @@ +/*************************************************************************** + * Copyright (C) 2004 by J�zef Starosczyk * + * copyhandler@o2.pl * + * * + * This program 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 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 Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +/** \file exception.cpp + * \brief Contain an implementation of an exception handling class. + */ +#include "exception.h" +#include +#include + +BEGIN_ICPF_NAMESPACE + +#ifdef _WIN32 + #define snprintf _snprintf + #define vsnprintf _vsnprintf +#endif + +/// Defines max length of the exception description +#define MAX_EXCEPTION 4096 + +/** Constructor that takes the const description. The description (along with other char_t* parameters) + * are copied to the internal members (so there is some memory allocation). + * \param[in] pszDesc - exception description (currently should be in english) + * \param[in] pszFilename - source file name from which the exception is thrown + * \param[in] pszFunction - function name from which the exception is thrown + * \param[in] uiLine - line in the source file from which the exception is thrown + * \param[in] uiAppCode - application defined error code + * \param[in] uiSystemCode - system error code (platform dependent) + * \param[in] uiReserved - currently unused; must be 0 + */ +exception::exception(const char_t* pszDesc, const char_t* pszFilename, const char_t* pszFunction, uint_t uiLine, uint_t uiAppCode, uint_t uiSystemCode, uint_t uiReserved) +{ + set_string(&m_pszDesc, pszDesc); + set_string(&m_pszFilename, pszFilename); + set_string(&m_pszFunction, pszFunction); + m_uiLine=uiLine; + m_uiAppCode=uiAppCode; + m_uiSystemCode=uiSystemCode; + m_uiReserved=uiReserved; +} + +/** Constructor that takes the ptr to a buffer as a description. The pointer to a buffer is + * stored in the internal member and will be deleted in the destructor. Other char_t* parameters + * are copied to the internal members (so there is some memory allocated). + * \param[in] pszDesc - ptr to exception description (currently should be in english) allocated with new operator + * \param[in] pszFilename - source file name from which the exception is thrown + * \param[in] pszFunction - function name from which the exception is thrown + * \param[in] uiLine - line in the source file from which the exception is thrown + * \param[in] uiAppCode - application defined error code + * \param[in] uiSystemCode - system error code (platform dependent) + * \param[in] uiReserved - currently unused; must be 0 + */ +exception::exception(char_t* pszDesc, const char_t* pszFilename, const char_t* pszFunction, uint_t uiLine, uint_t uiAppCode, uint_t uiSystemCode, uint_t uiReserved) +{ + m_pszDesc=pszDesc; + set_string(&m_pszFilename, pszFilename); + set_string(&m_pszFunction, pszFunction); + m_uiLine=uiLine; + m_uiAppCode=uiAppCode; + m_uiSystemCode=uiSystemCode; + m_uiReserved=uiReserved; +} + +/** Destructor deletes all the allocated memory for the exception object + */ +exception::~exception() +{ + delete [] m_pszDesc; + delete [] m_pszFilename; + delete [] m_pszFunction; +} + +/** Throws an exception as the arguments specify. Function made to provide a mean to throw an exception + * without worrying about the exception deletion. This function allocates an exception using this' dll + * stack, so the exception may be safely removed using ::del() member. + * All the parameters are being passed to the constructor without changes. + * \param[in] pszDesc - ptr to exception description (currently should be in english) allocated with new operator + * \param[in] pszFilename - source file name from which the exception is thrown + * \param[in] pszFunction - function name from which the exception is thrown + * \param[in] uiLine - line in the source file from which the exception is thrown + * \param[in] uiAppCode - application defined error code + * \param[in] uiSystemCode - system error code (platform dependent) + * \param[in] uiReserved - currently unused; must be 0 + */ +void exception::raise(const char* pszDesc, const char_t* pszFilename, const char_t* pszFunction, uint_t uiLine, uint_t uiAppCode, uint_t uiSystemCode, uint_t uiReserved) +{ + throw new exception(pszDesc, pszFilename, pszFunction, uiLine, uiAppCode, uiSystemCode, uiReserved); +} + +/** Deletes this class (deallocates the memory). This class must be allocated by + * the 'new' operator. Use only if the exception object has been allocated within + * the library. + */ +void exception::del() +{ + delete this; +} + +/** Function retrieves the full information about the exception into + * the string buffer specified by user. + * \param[out] pszInfo - buffer fot the full exception description + * \param[in] tMaxLen - size of the specified buffer + * \return Pointer to the exception description (to the pszInfo to be specific) + */ +const char_t* exception::get_info(char_t* pszInfo, intptr_t tMaxLen) +{ + snprintf(pszInfo, tMaxLen, "description: " STRFMT "\nfile: " STRFMT "\nfunction: " STRFMT "\nline: " ULFMT "\napp code: " ULFMT "\nsys code: " ULFMT "\nreserved: " ULFMT "\n", + m_pszDesc, m_pszFilename, m_pszFunction, m_uiLine, m_uiAppCode, m_uiSystemCode, m_uiReserved); + pszInfo[tMaxLen-1]='\0'; + + return pszInfo; +} + +/** Function logs the full information about an exception to the specified log file. + * \param[in] pszDesc - additional description of the exception object + * \param[in] plog - pointer to a log file to log the exception to + */ +void exception::log(const char_t* pszDesc, log_file* plog) +{ + plog->loge(STRFMT "\n\tdesc: " STRFMT "\n\tfile: " STRFMT "\n\tfunc: " STRFMT "\n\tline: " ULFMT "\n\tapp code: " ULFMT "\n\tsys code: " ULFMT "\n\treserved: " ULFMT "\n", + pszDesc, m_pszDesc, m_pszFilename, m_pszFunction, m_uiLine, m_uiAppCode, m_uiSystemCode, m_uiReserved); +} + +/** Function logs the full information about an exception to the specified log file. + * Function takes two additional descriptions - will be logged as separated by space one description. + * \param[in] pszDesc - additional description of the exception object + * \param[in] pszDesc2 - the second part of an additional description + * \param[in] plog - pointer to a log file to log the exception to + */ +void exception::log(const char_t* pszDesc, const char_t* pszDesc2, log_file* plog) +{ + plog->loge(STRFMT " " STRFMT "\n\tdesc: " STRFMT "\n\tfile: " STRFMT "\n\tfunc: " STRFMT "\n\tline: " ULFMT "\n\tapp code: " ULFMT "\n\tsys code: " ULFMT "\n\treserved: " ULFMT "\n", + pszDesc, pszDesc2, m_pszDesc, m_pszFilename, m_pszFunction, m_uiLine, m_uiAppCode, m_uiSystemCode, m_uiReserved); +} + +/** Exception's description formatting routine. Acts just as normal sprintf + * function, but allocates a buffer for the output result and returns a pointer + * to it. Used for formatting the exception description - usage: + * THROW(exception::format("test " STRFMT , "abc"), ...). + * It will enforce compiler to use the second constructor (non-const description). + * And the allocated buffer (result of this func) will be freed. + * \param[in] pszFormat - format string followed by some additional data (as in printf) + * \return Pointer to the newly allocated buffer with formatted output. + */ +char_t* exception::format(const char_t* pszFormat, ...) +{ + va_list vl; + va_start(vl, pszFormat); + + // alloc some space - no more than MAX_EXCEPTION chracters + char_t* psz=new char_t[MAX_EXCEPTION]; + vsnprintf(psz, MAX_EXCEPTION, pszFormat, vl); + psz[MAX_EXCEPTION-1]='\0'; + return psz; +} + +/** Allocates a string buffer and makes a copy of an input data. Used to + * make a copy of the constructor string parameteres. + * \param[out] pszOut - pointer to char_t* which will receive the new buffer address + * \param[in] pszIn - string to make a copy of + */ +void exception::set_string(char_t** pszOut, const char_t* pszIn) +{ + *pszOut=new char_t[strlen(pszIn)+1]; + strcpy(*pszOut, pszIn); +} + +END_ICPF_NAMESPACE Index: ext/libicpf/src/exception.h =================================================================== diff -u -N --- ext/libicpf/src/exception.h (revision 0) +++ ext/libicpf/src/exception.h (revision e17c80d36eaa0430313e7d1058aa7a301d1510af) @@ -0,0 +1,100 @@ +/*************************************************************************** + * Copyright (C) 2004 by J�zef Starosczyk * + * copyhandler@o2.pl * + * * + * This program 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 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 Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +/** \file exception.h + * \brief Contain an exception handling class. + */ + +#ifndef __EXCEPTION_H__ +#define __EXCEPTION_H__ + +#include "log.h" +#include "libicpf.h" +#include "gen_types.h" + +/** \brief Macro used for throwing an exception the easy way. + * + * Macro throws an exception specified by the parameters. Other params needed by + * the exception class are taken indirectly from the position of a macro in the + * source file. + * \param[in] desc - error description; if any formatting should be used use exception::format() function + * \param[in] app_code - application error code (definitions are in engine_defs.h) + * \param[in] sys_code - system error code (platform specific) + * \param[in] reserved_code - currently unused; must be 0 + */ +#undef THROW +//#define THROW(desc,app_code,sys_code,reserved_code) throw new icpf::exception(desc, __FILE__, __FUNCTION__, __LINE__,app_code,sys_code,reserved_code) +#define THROW(desc,app_code,sys_code,reserved_code) icpf::exception::raise(desc, __FILE__, __FUNCTION__, __LINE__, app_code, sys_code, reserved_code) +/// Logs an exception in a log file +#define LOG_EXCEPTION(except, ptr_log) (except)->log("Caught an exception in ", __FUNCTION__, ptr_log) +/// Logs an unknown exception in a log file +#define LOG_UEXCEPTION(ptr_log) (ptr_log)->loge("Caught an unknown exception in " STRFMT, __FUNCTION__) + +BEGIN_ICPF_NAMESPACE + +/** \brief Exception class used by most of the engine. + * + * Exception class thrown by most of the engine functions. Provides user + * with an additional formatting and outputting capabilities. + */ +class LIBICPF_API exception +{ +public: +/** \name Construction/destruction */ +/**@{*/ + /// Standard constructor that takes the const description + exception(const char_t* pszDesc, const char_t* pszFilename, const char_t* pszFunction, uint_t uiLine, uint_t uiAppCode, uint_t uiSystemCode, uint_t uiReserved); + /// Standard constructor that takes non-const ptr to a buffer as the description + exception(char_t* pszDesc, const char_t* pszFilename, const char_t* pszFunction, uint_t uiLine, uint_t uiAppCode, uint_t uiSystemCode, uint_t uiReserved); + /// Standard destructor + ~exception(); + + /// Raises an exception + static void raise(const char* pszDesc, const char_t* pszFilename, const char_t* pszFunction, uint_t uiLine, uint_t uiAppCode, uint_t uiSystemCode, uint_t uiReserved); + void del(); ///< Deletes this class (if allocated with new operator) +/**@}*/ + +/** \name Outputting */ +/**@{*/ + const char_t* get_info(char_t* pszInfo, intptr_t tMaxLen); ///< Retrieves the exception information to a specified string buffer + void log(const char_t* pszDesc, log_file* plog); ///< Logs the exception information to the log file + void log(const char_t* pszDesc, const char_t* pszDesc2, log_file* plog); ///< Logs the exception to the log file with an additional description +/**@}*/ + +/** \name Formatting */ +/**@{*/ + static char_t* format(const char_t* pszFormat, ...); ///< Description formatting function +/**@}*/ + +protected: + void set_string(char_t** pszOut, const char_t* pszIn); ///< Makes a copy of an input string + +public: + char_t* m_pszDesc; ///< Exception description + char_t* m_pszFilename; ///< Source file in which the exception has been thrown + char_t* m_pszFunction; ///< Function name in the source file in which the exception has been thrown + uint_t m_uiLine; ///< Line in the source file in which the exception has been thrown + uint_t m_uiAppCode; ///< Application error code + uint_t m_uiSystemCode; ///< System error code (platform dependent) + uint_t m_uiReserved; ///< Reserved code - currently unused and should be 0 +}; + +END_ICPF_NAMESPACE + +#endif Index: ext/libicpf/src/file.cpp =================================================================== diff -u -N --- ext/libicpf/src/file.cpp (revision 0) +++ ext/libicpf/src/file.cpp (revision e17c80d36eaa0430313e7d1058aa7a301d1510af) @@ -0,0 +1,1311 @@ +/*************************************************************************** + * Copyright (C) 2004 by J�zef Starosczyk * + * copyhandler@o2.pl * + * * + * This program 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 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 Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +/** \file file.cpp + * \brief Contains file/serializer class */ + +#include "file.h" +#include "crc32.h" +#include +#include "macros.h" +#include "err_codes.h" +#include "crypt.h" + +#ifndef _WIN32 + #include + #include + #include + #include +#endif + +//#include "stdio.h" // TEMP: only for temporary printf support + +BEGIN_ICPF_NAMESPACE + +#ifdef USE_ENCRYPTION + #include "crypt.h" +#endif + +#include + +/// Serialization buffer increment value +#define SERIALBUFFER_DELTA 4096UL + +// for making life easier +#ifdef _WIN32 + /// Macro representing the current value of last encountered error + #define CURRENT_LAST_ERROR GetLastError() + /// Null value for a file handle - platform compatibility helper + #define FNULL NULL +#else + /// Windoze compatibility macro - value returned from erroneous call to ::open() system call + #define INVALID_HANDLE_VALUE -1 + /// Macro representing the current value of last encountered error + #define CURRENT_LAST_ERROR errno + /// Null value for a file handle - platform compatibility helper + #define FNULL 0 +#endif + + +/** Standard constructor - nullifies all member variables. + */ +file::file() +{ + m_hFile=FNULL; + m_pszPath=NULL; + m_uiFlags=0; + m_uiBufferSize=0; + m_pbyBuffer=NULL; + m_uiCurrentPos=0; + m_uiDataCount=0; + m_bBuffered=false; + m_bLastOperation=false; + m_bRememberedState=false; + m_pbySerialBuffer=NULL; + m_uiSerialBufferSize=0; + m_uiSerialBufferPos=0; + m_bSerializing=0; +} + +/** Standard destructor - tries to close a file, but catches any exception thrown + * and does not throw it again. + */ +file::~file() +{ + // close all the stuff, but make sure no exception is thrown + try + { + close(); + } + catch(exception* e) + { + e->del(); + } +} + +/** Opens a filesystem object (a file) with a given flags and (if needed) with + * some buffer size used in internal buffering. In case of error throws a ch::exception* + * with the error description. + * \param[in] pszPath - path to a file to open + * \param[in] uiFlags - flags that determine the type of access to a file (FA_*) + * \param[in] uiBufSize - buffer size that will be used for internal buffering (if enabled) + */ +void file::open(const char_t* pszPath, uint_t uiFlags, uint_t uiBufSize) +{ + // check if this object is ready to open a file + if (m_hFile) + close(); + + // check for the flags completion +#ifdef _WIN32 + uint_t mode=0, flags=OPEN_EXISTING; +#else + int_t mode=0; +#endif + + // read flag + if (uiFlags & FA_READ) +#ifdef _WIN32 + mode |= GENERIC_READ; +#else + mode |= O_RDONLY; +#endif + + // write flag + if (uiFlags & FA_WRITE) +#ifdef _WIN32 + mode |= GENERIC_WRITE; +#else + mode |= O_WRONLY; +#endif + + // creation flag + if (uiFlags & FA_CREATE) +#ifdef _WIN32 + { + if (uiFlags & FA_TRUNCATE) + flags = CREATE_ALWAYS; + else + flags = OPEN_ALWAYS; + } +#else + mode |= O_CREAT; +#endif + + // truncation + if (uiFlags & FA_TRUNCATE) +#ifdef _WIN32 + { + if (!(uiFlags & FA_CREATE)) + flags = TRUNCATE_EXISTING; + } +#else + mode |= O_TRUNC; +#endif + + // make a system call +#ifdef _WIN32 + m_hFile=::CreateFile(pszPath, mode, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, flags, FILE_ATTRIBUTE_NORMAL, NULL); +#else + m_hFile=::open(pszPath, mode); +#endif + + if (m_hFile == INVALID_HANDLE_VALUE) + { + m_hFile=FNULL; + THROW(exception::format("[file] Cannot open the file " STRFMT " with flags " ULXFMT, pszPath, uiFlags), FERR_OPEN, CURRENT_LAST_ERROR, 0); + } + else + { + // remember the path of this file + m_pszPath=new char_t[strlen(pszPath)+1]; + strcpy(m_pszPath, pszPath); + + // remember the mode + m_uiFlags=uiFlags; + + // is this buffered ? + set_buffering((uiFlags & FA_BUFFERED) != 0, uiBufSize); + } +} + +/** Tries to save the data contained in internal buffer (if any) and frees all the + * resources used by this class. Can be used on closed files. In case of error the + * ch::exception is thrown. + */ +void file::close() +{ + // only if the file has been opened + if (m_hFile != FNULL) + { + // flush all data + flush(); + + // free strings and other data (at first, because of the destruction call) + delete [] m_pszPath; + m_pszPath=NULL; + delete [] m_pbyBuffer; + m_pbyBuffer=NULL; + + delete [] m_pbySerialBuffer; + m_pbySerialBuffer=NULL; + + m_uiFlags=0; + m_bLastOperation=false; + + m_bBuffered=false; + m_uiBufferSize=0; + m_uiCurrentPos=0; + m_uiDataCount=0; + + m_bSerializing=false; + m_uiSerialBufferSize=0; + m_uiSerialBufferPos=0; + m_uiDataBlockFlags=0; + +#ifdef USE_ENCRYPTION + m_strPassword.clear(); +#endif + + m_bRememberedState=false; + + // close the file +#ifdef _WIN32 + if (!::CloseHandle(m_hFile)) +#else + if (::close(m_hFile) == -1) +#endif + THROW(exception::format("[file] Cannot close the handle associated with a file " STRFMT, m_pszPath), FERR_CLOSE, CURRENT_LAST_ERROR, 0); + else + m_hFile=FNULL; + } +} + +/** Does anything only if the file is opened, the operation is being buffered and the data + * count contained in the internal buffer is >0. If the last operation performed was + * storing data then the function tries to store a packet of data to the file. If the data + * has been read lately then only the file pointer will be repositioned. Also the internal buffer + * will be made empty. Function can throw an ch::exception in case of error. + */ +void file::flush() +{ + if (m_hFile && m_bBuffered && m_uiDataCount > 0) + { + if (m_bLastOperation) + { + // last operation - storing data + _write_packet(); + } + else + { + // last - reading data + // set file pointer to position current-(m_uiDataCount-m_uiCurrentPos) + _seek(-(int_t)(m_uiDataCount-m_uiCurrentPos), FS_CURRENT); + m_uiCurrentPos=0; + m_uiDataCount=0; + } + } +} + +/** Tries to read a specified count of bytes from a file to the specified buffer. + * If the is currently in buffered state the reading is being done with internal + * buffering. It could be helpful when reading small amounts of data. + * \param[out] pBuffer - ptr to a buffer that is about to receive data + * \param[in] iSize - count of bytes to read + * \return Count of bytes that has been read (could be less than iSize) + */ +int_t file::read(ptr_t pBuffer, int_t iSize) +{ + assert(m_hFile); // forgot to open the file ? + assert(iSize >= 0); // you out of your mind to try to read negative value of bytes ??? + + // flush if needed + if (m_bLastOperation) + { + flush(); + m_bLastOperation=false; + } + + if (!m_bBuffered) + { + // unbuffered operation (read what is needed) +#ifdef _WIN32 + DWORD rd=0; + if (!ReadFile(m_hFile, pBuffer, iSize, &rd, NULL)) +#else + int_t rd=0; + if ((rd=::read(m_hFile, pBuffer, iSize)) < 0) +#endif + THROW(exception::format("Cannot read data from file " STRFMT, m_pszPath), FERR_READ, CURRENT_LAST_ERROR, 0); + + return (int_t)rd; // if 0 - eof (not treated as exception) + } + else + { + // reads must be done by packets + uint_t uiCurrPos=0; // position in external buffer + while (uiCurrPos < (uint_t)iSize) + { + // are there any data left ? + if (m_uiDataCount == 0 || m_uiCurrentPos == m_uiDataCount) + { + if (_read_packet() == 0) + return uiCurrPos; // return what was read 'til now + } + + // copy data into external buffer + uint_t uiCount=minval(m_uiDataCount-m_uiCurrentPos, iSize-uiCurrPos); + memcpy(((byte_t*)pBuffer)+uiCurrPos, m_pbyBuffer+m_uiCurrentPos, uiCount); + + // update positions + uiCurrPos+=uiCount; + m_uiCurrentPos+=uiCount; + } + + return uiCurrPos; + } +} + +/** Tries to write a specified amount of data from a buffer to a file. If the buffered + * operations are enabled then this operation could store data in the internal buffer + * instead of a file. + * \param[in] pBuffer - ptr to a buffer with data to store + * \param[in] iSize - count of data to store + * \return Count of data that has been stored + */ +int_t file::write(ptr_t pBuffer, int_t iSize) +{ + assert(m_hFile); + + if (!m_bLastOperation) + { + flush(); + m_bLastOperation=true; + } + + if (!m_bBuffered) + { + // standard write +#ifdef _WIN32 + DWORD wr=0; + if (!WriteFile(m_hFile, pBuffer, iSize, &wr, NULL)) +#else + int_t wr; + if ((wr=::write(m_hFile, pBuffer, iSize) == -1)) +#endif + THROW(exception::format("[file] Cannot write data to a file", m_pszPath), FERR_WRITE, CURRENT_LAST_ERROR, 0); + + return (int_t)wr; + } + else + { + uint_t uiPos=0; + + while (uiPos < (uint_t)iSize) + { + // check if buffer need storing + if (m_uiCurrentPos == m_uiBufferSize) + _write_packet(); + + // now add to internal buffer some data + uint_t uiCount=minval(m_uiBufferSize-m_uiCurrentPos, iSize-uiPos); + + memcpy(m_pbyBuffer+m_uiCurrentPos, ((byte_t*)pBuffer)+uiPos, uiCount); + + // update + m_uiCurrentPos+=uiCount; + m_uiDataCount+=uiCount; + uiPos+=uiCount; + } + + return uiPos; + } +} + +/** Tries to read a string from a file. Uses a buffering to achieve it. If the + * current file mode is unbuffered then this function enables buffering, makes + * requested operation and disables buffering. If the buffer is too small to + * contain all the line read then the rest of line is lost. + * \param[out] pszStr - ptr to a buffer to receive a string + * \param[in] uiMaxLen - size of the string buffer + * \return If the line has been succesfully read. + */ +bool file::read_line(char_t* pszStr, uint_t uiMaxLen) +{ + // for unbuffered operations enable buffering for this op + if (m_bBuffered) + return _read_string(pszStr, uiMaxLen); + else + { + uint_t uiSize=m_uiBufferSize; + set_buffering(true, 4096); + + bool bRet=_read_string(pszStr, uiMaxLen); + + set_buffering(false, uiSize); + return bRet; + } +} + +/** Tries to write some text into a file. Function allocates a buffer for the string + * copy and appends a \\r\\n to this text. + * \param[in] pszString - string to store + */ +void file::write_line(char_t* pszString) +{ + assert(m_hFile); + + if (!m_bLastOperation) + { + flush(); + m_bLastOperation=true; + } + + // make new string with \r\n at the end - cannot use old buffer - unknown size + // NOTE: \r\n added for windoze compat; when reading file function properly handles unix style line endings + uint_t uiLen=(uint_t)strlen(pszString); + + char_t *pszData=new char_t[uiLen+3]; + strcpy(pszData, pszString); + pszData[uiLen]='\r'; + pszData[uiLen+1]='\n'; + pszData[uiLen+2]='\0'; + + try + { + if (m_bBuffered) + { + uint_t uiStrPos=0; // current index in pszString + uint_t uiMin=0; // helper + uint_t uiSize=uiLen+2; + + // processing whole string + while (uiStrPos < uiSize) + { + if (m_uiCurrentPos == m_uiBufferSize) + _write_packet(); + + // count of chars to be copied + uiMin=minval(uiSize-uiStrPos, m_uiBufferSize-m_uiCurrentPos); + + // copy data from pszString into internal buffer (maybe part of it) + memcpy(m_pbyBuffer+m_uiCurrentPos, pszData+uiStrPos, uiMin); + + // move offsets + m_uiCurrentPos+=uiMin; + m_uiDataCount+=uiMin; + uiStrPos+=uiMin; + } + } + else + { + // standard write +#ifdef _WIN32 + DWORD wr=0; + if (!WriteFile(m_hFile, pszData, uiLen+2, &wr, NULL)) +#else + int_t wr; + if ((wr=::write(m_hFile, pszData, uiLen+2)) == -1) +#endif + THROW(exception::format("Cannot write data to a file " STRFMT, m_pszPath), FERR_WRITE, CURRENT_LAST_ERROR, 0); + } + + delete [] pszData; + } + catch(...) + { + delete [] pszData; + throw; + } +} + +/** Moves the file pointer to some place in the file. If the file is in buffered + * state, then the data is flushed and then the real seek takes place. + * \param[in] llOffset - offset of the new file pointer position + * \param[in] uiFrom - specifies the relative point (FS_*) from which the llOffset will be counted + */ +void file::seek(longlong_t llOffset, uint_t uiFrom) +{ + // flush buffer + flush(); + + // seek + _seek(llOffset, uiFrom); +} + +/** Retrieves the current file pointer position (corrected by the content of + * internal buffer if buffered mode enabled). + * \return Current file position. + */ +longlong_t file::getpos() +{ + // return corrected by internal members current file position + return _seek(0, FS_CURRENT)-m_uiDataCount+m_uiCurrentPos; +} + +/** Tries to set end-of-file marker on the current file pointer position. The internal buffer + * is flushed before truncating (or extending). + */ +void file::seteof() +{ + assert(m_hFile); + + // flush da buffers + flush(); + + // now set the end of file +#ifdef _WIN32 + if (!::SetEndOfFile(m_hFile)) +#else + if (::ftruncate(m_hFile, getpos()) == -1) +#endif + THROW(exception::format("[file] Cannot truncate the file " STRFMT, m_pszPath), FERR_SETEOF, CURRENT_LAST_ERROR, 0); +} + +/** Returns a size of the file. + * \return Size of the file. + */ +longlong_t file::get_size() +{ + flush(); + +#ifdef _WIN32 + ULARGE_INTEGER li; + li.LowPart=GetFileSize(m_hFile, &li.HighPart); + if (li.LowPart == INVALID_FILE_SIZE && GetLastError() != NO_ERROR) +#else + // NOTE: a strange way to check the file size... + struct stat st; + if (fstat(m_hFile, &st) == -1) +#endif + THROW(exception::format("[file] Cannot get the size of the file " STRFMT, m_pszPath), FERR_GETSIZE, CURRENT_LAST_ERROR, 0); + +#ifdef _WIN32 + return li.QuadPart; +#else + return st.st_size; +#endif +} + +/** Changes the buffering state (or internal buffer length). The internal buffer + * is always flushed before making any changes. + * \param[in] bEnable - specifies if the buffering is about to be enabled + * \param[in] uiSize - the new size of the internal buffer + */ +void file::set_buffering(bool bEnable, uint_t uiSize) +{ + assert(uiSize > 0); // couldn't use 0-sized internal buffer + + // flush + flush(); + + // delete old buffer + if (m_bBuffered && (!bEnable || uiSize != m_uiBufferSize)) + { + delete [] m_pbyBuffer; + m_pbyBuffer=NULL; + } + + // alloc new buffer if needed + if (bEnable && (!m_bBuffered || uiSize != m_uiBufferSize)) + m_pbyBuffer=new byte_t[uiSize]; + + m_bBuffered=bEnable; + m_uiBufferSize=uiSize; +} + +/** Switches access mode to unbuffered one and remembers the last state. If already + * in unbuffered mode the function does nothing. + */ +void file::switch_unbuffered() +{ + if (!m_bBuffered) + return; // it's already unbuffered - leave it as is + else + { + m_bRememberedState=true; // mark that we change state to a different one + set_buffering(false, m_uiBufferSize); // do no change internal buffer size + } +} + +/** Switches access mode to buffered one and remembers the last state. If already + * in buffered mode the function does nothing. + */ +void file::switch_buffered() +{ + if (m_bBuffered) + return; // already buffered + else + { + m_bRememberedState=true; + set_buffering(true, m_uiBufferSize); + } +} + +/** Restores the buffered/unbuffered access mode if stored with switch_* functions. + */ +void file::restore_state() +{ + // restore state only if changed + if (m_bRememberedState) + { + set_buffering(!m_bBuffered, m_uiBufferSize); + m_bRememberedState=false; + } +} + +#ifdef USE_ENCRYPTION +/** Function sets the password used for symmetric encryption/decryption + * of some serialization blocks. + * \param[in] pszPass - passphrase used for encryption/decryption + */ +void file::set_password(const char_t* pszPass) +{ + // generate the SHA256 from this password + char_t szPass[64+1]; + str2key256(pszPass, szPass); + m_strPassword=szPass; +} + +#endif + +/** Begins the serialization data block. Each block can have it's + * own flags. Each block have to be ended with datablock_end before + * beginning another one. If the access is read then function tries to read + * the data block from a file and checks the crc checksums. If writing - only + * the buffer is allocated and initialized. + * Blocks cannot be nested. + * \param[in] uiFlags - block flags - look at BF_* macros + */ +void file::datablock_begin(uint_t uiFlags) +{ + // do not call begin data block within another data block + assert(!m_bSerializing && m_pbySerialBuffer == NULL); + + // alloc the new buffer and insert there a header (a few unsigned chars) + m_pbySerialBuffer=new byte_t[SERIALBUFFER_DELTA]; + m_uiSerialBufferSize=SERIALBUFFER_DELTA; + + // check flags + if ((m_uiFlags & FA_READ) && (m_uiFlags & FA_WRITE)) + THROW(exception::format("[file] Tried to begin a data block with file " STRFMT " opened for both read and write.", m_pszPath), FERR_SERIALIZE, 0, 0); + + // action + if (m_uiFlags & FA_WRITE) + { + // reserve some space for a header + m_uiSerialBufferPos=sizeof(SERIALIZEINFOHEADER); + } + else + { + // we need to read the block from a file + if (read(m_pbySerialBuffer, sizeof(SERIALIZEINFOHEADER)) != sizeof(SERIALIZEINFOHEADER)) + { + _clear_serialization(); + THROW(exception::format("[file] Cannot read the specified amount of data from a file (reading serialization header).", m_pszPath), FERR_SERIALIZE, CURRENT_LAST_ERROR, 0); + } + + // move forward + m_uiSerialBufferPos=sizeof(SERIALIZEINFOHEADER); + + // determine the size of the remaining data in file + SERIALIZEINFOHEADER* psih=(SERIALIZEINFOHEADER*)m_pbySerialBuffer; + uint_t uiSize=psih->iRealSize-sizeof(SERIALIZEINFOHEADER); + + // check the header crc + uint_t uihc=crc32(m_pbySerialBuffer, sizeof(SERIALIZEINFOHEADER)-sizeof(uint_t)); + if (uihc != psih->uiHeaderCRC32) + { + _clear_serialization(); + THROW(exception::format("[file] Block contained in file " STRFMT " is corrupted. Header CRC check failed.", m_pszPath), FERR_SERIALIZE, 0, 0); + } + + // resize the buffer + _sbuf_resize(psih->iRealSize); + + // refresh the psih + psih=(SERIALIZEINFOHEADER*)m_pbySerialBuffer; + + // read the remaining data + if (read(m_pbySerialBuffer+m_uiSerialBufferPos, uiSize) != (int_t)uiSize) + { + _clear_serialization(); + THROW(exception::format("Cannot read specified amount of data from a file " STRFMT " (reading the after-header data).", m_pszPath), FERR_SERIALIZE, CURRENT_LAST_ERROR, 0); + } + +#ifdef USE_ENCRYPTION + // decrypt the data + if (uiFlags & BF_ENCRYPTED && !m_strPassword.is_empty()) + { + if (decrypt_aes256(m_pbySerialBuffer+m_uiSerialBufferPos, uiSize, m_strPassword, m_pbySerialBuffer+m_uiSerialBufferPos) < 0) + { + _clear_serialization(); + THROW(exception::format("Cannot decrypt the data read from the serialization file " STRFMT ".", m_pszPath), FERR_CRYPT, 0, 0); + } + } +#endif + // NOTE: do not update the position - we need ptr at the beginning of data + // now we are almost ready to retrieve data - only the crc check for the data + uint_t uiCRC=crc32(m_pbySerialBuffer+sizeof(SERIALIZEINFOHEADER), psih->iDataSize-sizeof(SERIALIZEINFOHEADER)); + if (psih->uiCRC32 != uiCRC) + { + _clear_serialization(); + THROW(exception::format("CRC check of the data read from file " STRFMT " failed.", m_pszPath), FERR_SERIALIZE, 0, 0); + } + } + + // make a mark + m_uiDataBlockFlags=uiFlags; + m_bSerializing=true; +} + +/** Ends the data block opened previously with datablock_begin. If the access is writing + * then the function updates the crc checksums in the buffer and tries to write the block + * of data to the file. If reading - only the serialization is cancelled. + */ +void file::datablock_end() +{ + // make sure everything is ok + assert(m_bSerializing && m_pbySerialBuffer != NULL); + + // check the operation type + if ((m_uiFlags & FA_READ) && (m_uiFlags & FA_WRITE)) + THROW(exception::format("[file] Tried to end a data block with file " STRFMT " opened for both read and write.", m_pszPath), FERR_SERIALIZE, 0, 0); + + // when writing - make a header, ...; when reading - do nothing important + if (m_uiFlags & FA_WRITE) + { + // check if there is any data + if (m_uiSerialBufferPos == sizeof(SERIALIZEINFOHEADER)) + return; // no data has been serialized + + // fill the header (real data information) + SERIALIZEINFOHEADER *psih=(SERIALIZEINFOHEADER*)m_pbySerialBuffer; + psih->iDataSize=m_uiSerialBufferPos; + psih->uiCRC32=crc32(m_pbySerialBuffer+sizeof(SERIALIZEINFOHEADER), m_uiSerialBufferPos-sizeof(SERIALIZEINFOHEADER)); + +#ifdef USE_ENCRYPTION + // we could encrypt the data here if needed + if (m_uiDataBlockFlags & BF_ENCRYPTED && !m_strPassword.is_empty()) + { + int_t iRes=crypt_aes256((ptr_t)(m_pbySerialBuffer+sizeof(SERIALIZEINFOHEADER)), m_uiSerialBufferPos-sizeof(SERIALIZEINFOHEADER), m_strPassword, (ptr_t)(m_pbySerialBuffer+sizeof(SERIALIZEINFOHEADER))); + if (iRes < 0) + { + _clear_serialization(); + THROW("Cannot encrypt the data to store.", FERR_CRYPT, 0, 0); + } + + // fill the header + psih->iRealSize=iRes+sizeof(SERIALIZEINFOHEADER); + } + else + { +#endif + // the rest of header + psih->iRealSize=m_uiSerialBufferPos; +#ifdef USE_ENCRYPTION + } +#endif + + // calc the header crc + psih->uiHeaderCRC32=crc32(m_pbySerialBuffer, sizeof(SERIALIZEINFOHEADER)-sizeof(uint_t)); + + // write the buffer + write(m_pbySerialBuffer, psih->iRealSize); + } + + // remove all the traces of serializing + _clear_serialization(); +} + +/** Writes some bytes of data to a serialization buffer opened + * with the datablock_begin. Causes the class to reallocate an internal + * buffer(if needed) to make all the data fit into the buffer. + * NOTE: do not use too large data blocks because of the buffer reallocation. + * \param[in] pData - buffer address with some data + * \param[in] uiSize - count of bytes to write + */ +void file::swrite(ptr_t pData, uint_t uiSize) +{ + _sbuf_append(pData, uiSize); +} + +/** Reads some bytes of data from a serialization buffer opened by + * datablock_end call. + * \param[out] pData - buffer for the received data + * \param[in] uiSize - count of data to read; if user requests more data than available then an exception will be thrown + */ +void file::sread(ptr_t pData, uint_t uiSize) +{ + _sbuf_read(pData, uiSize); +} + +/** Writes a value of a given type to the file. This is a serialization related function, so + * the datablock has to be opened prior to using this operator. + * \param[in] val - value to be stored in a file + * \return Reference to this file object. + */ +file& file::operator<<(bool val) +{ + swrite(&val, sizeof(val)); + return *this; +} + +/** Reads a value of a given type from the file. This is a serialization related function, so + * the datablock has to be opened prior to using this operator. + * \param[in] val - reference to a variable to receive data + * \return Reference to this file object. + */ +file& file::operator>>(bool& val) +{ + sread(&val, sizeof(val)); + return *this; +} + +/** Writes a value of a given type to the file. This is a serialization related function, so + * the datablock has to be opened prior to using this operator. + * \param[in] val - value to be stored in a file + * \return Reference to this file object. + */ +file& file::operator<<(char_t val) +{ + swrite(&val, sizeof(val)); + return *this; +} + +/** Reads a value of a given type from the file. This is a serialization related function, so + * the datablock has to be opened prior to using this operator. + * \param[in] val - reference to a variable to receive data + * \return Reference to this file object. + */ +file& file::operator>>(char_t& val) +{ + sread(&val, sizeof(val)); + return *this; +} + +/** Writes a value of a given type to the file. This is a serialization related function, so + * the datablock has to be opened prior to using this operator. + * \param[in] val - value to be stored in a file + * \return Reference to this file object. + */ +file& file::operator<<(uchar_t val) +{ + swrite(&val, sizeof(val)); + return *this; +} + +/** Reads a value of a given type from the file. This is a serialization related function, so + * the datablock has to be opened prior to using this operator. + * \param[in] val - reference to a variable to receive data + * \return Reference to this file object. + */ +file& file::operator>>(uchar_t& val) +{ + sread(&val, sizeof(val)); + return *this; +} + +/** Writes a value of a given type to the file. This is a serialization related function, so + * the datablock has to be opened prior to using this operator. + * \param[in] val - value to be stored in a file + * \return Reference to this file object. + */ +file& file::operator<<(short_t val) +{ + swrite(&val, sizeof(val)); + return *this; +} + +/** Reads a value of a given type from the file. This is a serialization related function, so + * the datablock has to be opened prior to using this operator. + * \param[in] val - reference to a variable to receive data + * \return Reference to this file object. + */ +file& file::operator>>(short_t& val) +{ + sread(&val, sizeof(val)); + return *this; +} + +/** Writes a value of a given type to the file. This is a serialization related function, so + * the datablock has to be opened prior to using this operator. + * \param[in] val - value to be stored in a file + * \return Reference to this file object. + */ +file& file::operator<<(ushort_t val) +{ + swrite(&val, sizeof(val)); + return *this; +} + +/** Reads a value of a given type from the file. This is a serialization related function, so + * the datablock has to be opened prior to using this operator. + * \param[in] val - reference to a variable to receive data + * \return Reference to this file object. + */ +file& file::operator>>(ushort_t& val) +{ + sread(&val, sizeof(val)); + return *this; +} + +/** Writes a value of a given type to the file. This is a serialization related function, so + * the datablock has to be opened prior to using this operator. + * \param[in] val - value to be stored in a file + * \return Reference to this file object. + */ +file& file::operator<<(int_t val) +{ + swrite(&val, sizeof(val)); + return *this; +} + +/** Reads a value of a given type from the file. This is a serialization related function, so + * the datablock has to be opened prior to using this operator. + * \param[in] val - reference to a variable to receive data + * \return Reference to this file object. + */ +file& file::operator>>(int_t& val) +{ + sread(&val, sizeof(val)); + return *this; +} + +/** Writes a value of a given type to the file. This is a serialization related function, so + * the datablock has to be opened prior to using this operator. + * \param[in] val - value to be stored in a file + * \return Reference to this file object. + */ +file& file::operator<<(uint_t val) +{ + swrite(&val, sizeof(val)); + return *this; +} + +/** Reads a value of a given type from the file. This is a serialization related function, so + * the datablock has to be opened prior to using this operator. + * \param[in] val - reference to a variable to receive data + * \return Reference to this file object. + */ +file& file::operator>>(uint_t& val) +{ + sread(&val, sizeof(val)); + return *this; +} + +/** Writes a value of a given type to the file. This is a serialization related function, so + * the datablock has to be opened prior to using this operator. + * \param[in] val - value to be stored in a file + * \return Reference to this file object. + */ +file& file::operator<<(ll_t val) +{ + swrite(&val, sizeof(val)); + return *this; +} + +/** Reads a value of a given type from the file. This is a serialization related function, so + * the datablock has to be opened prior to using this operator. + * \param[in] val - reference to a variable to receive data + * \return Reference to this file object. + */ +file& file::operator>>(ll_t& val) +{ + sread(&val, sizeof(val)); + return *this; +} + +/** Writes a value of a given type to the file. This is a serialization related function, so + * the datablock has to be opened prior to using this operator. + * \param[in] val - value to be stored in a file + * \return Reference to this file object. + */ +file& file::operator<<(ull_t val) +{ + swrite(&val, sizeof(val)); + return *this; +} + +/** Reads a value of a given type from the file. This is a serialization related function, so + * the datablock has to be opened prior to using this operator. + * \param[in] val - reference to a variable to receive data + * \return Reference to this file object. + */ +file& file::operator>>(ull_t& val) +{ + sread(&val, sizeof(val)); + return *this; +} + +/** Stores a string object in the file. + * \param[in] str - reference to the string object to store. + * \return Reference to this object. + */ +file& file::operator<<(string& str) +{ +#ifdef ALLOW_UNICODE + if (str.is_unicode()) + { + // get the internal buffer with at least 1 character (NULL) + wchar_t* psz=str.get_bufferu(1); + int_t iLen=(int_t)(str.bytelen()); + + // store len + swrite(&iLen, sizeof(int_t)); + + // an unicode flag + bool bUnicode=str.is_unicode(); + swrite(&bUnicode, sizeof(bool)); + + // and the buffer itself + swrite(psz, iLen); + } + else + { +#endif + // internal buffer + char_t* psz=str.get_buffera(1); + int_t iLen=(int_t)(str.bytelen()); + + // write the length + swrite(&iLen, sizeof(int_t)); + + // write the unicode flag - for compatibility with unicode version of the code + bool bUnicode=false; + swrite(&bUnicode, sizeof(bool)); + + // write the data + swrite(psz, iLen); +#ifdef ALLOW_UNICODE + } +#endif + + return *this; +} + +/** Reads a string object from this file. + * \param[in] str - reference to the string object to receive the string. + * \return Reference to this object. + */ +file& file::operator>>(string& str) +{ + // read the length + int_t iLen=0; + sread(&iLen, sizeof(int_t)); + + // read the unicode flag + bool bUnicode=false; + sread(&bUnicode, sizeof(bool)); + + if (bUnicode) + { +#ifdef ALLOW_UNICODE + str.clear(); + str.make_unicode(); + wchar_t* psz=str.get_bufferu(iLen); + + sread(psz, iLen); + str.release_buffer(); +#else + THROW("Cannot read an unicode string from a file. This library was not built with unicode support.", FERR_UNICODE, 0, 0); +#endif + } + else + { + // ansi string + str.clear(); + str.make_ansi(); + char_t* psz=str.get_buffera(iLen); + + sread(psz, iLen); + str.release_buffer(); + } + + return *this; +} + +/** Cancels the serialization process and removes all the traces of data being serialized + * (it includes deleting the serialization buffer). + */ +void file::_clear_serialization() +{ + // remove all the traces of serializing + delete [] m_pbySerialBuffer; + m_pbySerialBuffer=NULL; + m_uiSerialBufferSize=0; + m_uiSerialBufferPos=0; + m_bSerializing=false; +} + +/** Used to read the next packet of data into the internal buffer (used for + * buffering). + * \return Count of bytes that has been read from a file. + */ +uint_t file::_read_packet() +{ + assert(m_hFile); + + // read data +#ifdef _WIN32 + DWORD rd=0; + if (!ReadFile(m_hFile, m_pbyBuffer, m_uiBufferSize, &rd, NULL)) +#else + int_t rd; + if ((rd=::read(m_hFile, m_pbyBuffer, m_uiBufferSize)) == -1) +#endif + THROW(exception::format("[file] Cannot read data from a file " STRFMT ".", m_pszPath), FERR_READ, CURRENT_LAST_ERROR, 0); + + // reset internal members + m_uiDataCount=rd; + m_uiCurrentPos=0; + + return rd; +} + +/** Used to write the next packet of data from an internal buffer (buffering + * related) to a file. + * \return Count of bytes written. + */ +uint_t file::_write_packet() +{ + assert(m_hFile); + +#ifdef _WIN32 + DWORD wr=0; + if (!WriteFile(m_hFile, m_pbyBuffer, m_uiDataCount, &wr, NULL)) +#else + int_t wr; + if ((wr=::write(m_hFile, m_pbyBuffer, m_uiDataCount)) == -1) +#endif + { + THROW(exception::format("Cannot write data to a file " STRFMT ".", m_pszPath), FERR_WRITE, CURRENT_LAST_ERROR, 0); + } + + // reset internal members + m_uiDataCount=0; + m_uiCurrentPos=0; + + return wr; +} + +/** Reads some data from the internal serialization buffer. + * \param[out] pData - ptr to a buffer that is about to receive data + * \param[in] uiLen - count of data to be read + */ +void file::_sbuf_read(ptr_t pData, uint_t uiLen) +{ + // check if we are reading + assert(m_uiFlags & FA_READ); + + // check the ranges + if (m_uiSerialBufferPos+uiLen > m_uiSerialBufferSize) + { + // throw an exception - read beyond the data range in a given object + THROW(exception::format("[file] Trying to read the serialization data beyond the range (file " STRFMT ").", m_pszPath), FERR_MEMORY, CURRENT_LAST_ERROR, 0); + } + + // read the data + memcpy(pData, m_pbySerialBuffer+m_uiSerialBufferPos, uiLen); + m_uiSerialBufferPos+=uiLen; +} + +/** Appends some bytes to the internal serialization buffer (data block). + * \param[in] pData - ptr to a data buffer + * \param[in] uiCount - count of data to store + */ +void file::_sbuf_append(ptr_t pData, uint_t uiCount) +{ + // check if we are writing + assert(m_uiFlags & FA_WRITE); + + // check serial buffer size (if there is enough room for the data) + if (m_uiSerialBufferPos+uiCount > m_uiSerialBufferSize) + { + // we need a buffer reallocation + uint_t uiDelta=((uiCount/SERIALBUFFER_DELTA)+1)*SERIALBUFFER_DELTA; + + // alloc the new buffer + _sbuf_resize(m_uiSerialBufferSize+uiDelta); + } + + // real storage of the data + if (uiCount > 0) + { + memcpy(m_pbySerialBuffer+m_uiSerialBufferPos, pData, uiCount); + m_uiSerialBufferPos+=uiCount; + } +} + +/** Resizes the internal serialization buffer to the new length. + * Also does copy the old data to the new buffer. + * \param[in] uiNewLen - new buffer length + */ +void file::_sbuf_resize(uint_t uiNewLen) +{ + // alloc the new buffer + byte_t* pbyNewBuffer=new byte_t[uiNewLen]; + + // copy the old data into the new one + uint_t uiCount=minval(m_uiSerialBufferPos, uiNewLen); + if (m_uiSerialBufferPos > 0) + memcpy(pbyNewBuffer, m_pbySerialBuffer, uiCount); + + // delete the old buffer + delete [] m_pbySerialBuffer; + + // set the new buffer inplace and update the internal size + m_pbySerialBuffer=pbyNewBuffer; + m_uiSerialBufferSize=uiNewLen; +} + + +/** Reads a line of text from text file - only for buffered operations. + * Properly interpretes the windoze and unix line endings. + * \param[out] pszStr - buffer for the string that is about to be read + * \param[in] uiMaxLen - size of the string buffer + * \return Bool value that states if the string has been read. + */ +bool file::_read_string(char_t* pszStr, uint_t uiMaxLen) +{ + assert(m_hFile); // file wasn't opened - error opening or you've forgotten to do so ? + + // last time was writing - free buffer + if (m_bLastOperation) + { + flush(); + m_bLastOperation=false; + } + + // zero all the string + memset(pszStr, 0, uiMaxLen*sizeof(char_t)); + + // additional vars + uint_t uiStrPos=0; // current pos in external buffer + bool bSecondPass=false; // if there is need to check data for 0x0a char_t + + // copy each char_t into pszString + for (;;) + { + // if buffer is empty - fill it + if (m_uiDataCount == 0 || m_uiCurrentPos == m_uiDataCount) + { + if (_read_packet() == 0) + return strlen(pszStr) != 0; + } + + // skipping 0x0a in second pass + if (bSecondPass) + { + if (m_pbyBuffer[m_uiCurrentPos] == 0x0a) + m_uiCurrentPos++; + return true; + } + + // now process chars + while (m_uiCurrentPos < m_uiDataCount) + { + if (m_pbyBuffer[m_uiCurrentPos] == 0x0d) + { + bSecondPass=true; + m_uiCurrentPos++; + break; + } + else if (m_pbyBuffer[m_uiCurrentPos] == 0x0a) + { + m_uiCurrentPos++; + return true; + } + else + { + if (uiStrPos < uiMaxLen-1) + pszStr[uiStrPos++]=m_pbyBuffer[m_uiCurrentPos]; + m_uiCurrentPos++; + } + } + } +} + +/** Sets file pointer in a file. + * \param[in] llOffset - position to move the file pointer to + * \param[in] uiFrom - the relative position of a base position (FS_*) + * \return The new file pointer position. + */ +longlong_t file::_seek(longlong_t llOffset, uint_t uiFrom) +{ +#ifdef _WIN32 + LARGE_INTEGER li; + li.QuadPart = llOffset; + li.LowPart = SetFilePointer (m_hFile, li.LowPart, &li.HighPart, uiFrom); + + if (li.LowPart == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR) +#else + int_t lRes; + if ((lRes=lseek(m_hFile, llOffset, uiFrom)) == -1) +#endif + THROW(exception::format("Seek error in file " STRFMT ".", m_pszPath), FERR_SEEK, CURRENT_LAST_ERROR, 0); + +#ifdef _WIN32 + return li.QuadPart; +#else + return lRes; +#endif +} + +END_ICPF_NAMESPACE Index: ext/libicpf/src/file.h =================================================================== diff -u -N --- ext/libicpf/src/file.h (revision 0) +++ ext/libicpf/src/file.h (revision e17c80d36eaa0430313e7d1058aa7a301d1510af) @@ -0,0 +1,257 @@ +/*************************************************************************** + * Copyright (C) 2004 by J�zef Starosczyk * + * copyhandler@o2.pl * + * * + * This program 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 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 Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +/** \file file.h + * \brief Contains system independent file/serializer class + * \todo Apply properly handling of the encryption/decryption stuff. + * \todo Modify the class so it could handle full 64bit files. + * \todo Correct the file creation flags under linux (wrong umask value?). + */ + +#ifndef __FILE_H__ +#define __FILE_H__ + +#include "exception.h" +#include "libicpf.h" +#include "str.h" + +/// A synonym for the file class +#define serializer file; + +// file access modes +/// Read access to the file +#define FA_READ 0x0001 +/// Write access to the file +#define FA_WRITE 0x0002 +/// Create file if does not exist +#define FA_CREATE 0x0004 +/// Truncate file if not empty +#define FA_TRUNCATE 0x0008 + +// additional mode mods +/// Enable buffered access +#define FA_BUFFERED 0x8000 + +// begin data block flags +/// Standard flag - cannot be combined with others +#define BF_NONE 0x00 +#ifdef USE_ENCRYPTION +/// The block should be encrypted +#define BF_ENCRYPTED 0x01 +#endif + +// seek constants +#ifdef _WIN32 + /// Seeks from the current file pointer position + #define FS_CURRENT FILE_CURRENT + /// Seeks from the beginning of the file + #define FS_SET FILE_BEGIN + /// Seeks from the end of file + #define FS_END FILE_END +#else + /// Seeks from the current file pointer position + #define FS_CURRENT SEEK_CUR + /// Seeks from the beginning of the file + #define FS_SET SEEK_SET + /// Seeks from the end of file + #define FS_END SEEK_END +#endif + +BEGIN_ICPF_NAMESPACE + +/** \brief Structure describes the data inside a data block + * + * Structure contain crc fields to make sure data block is consistent. + * Also the real data size and stored data size are included */ +struct SERIALIZEINFOHEADER +{ + // main header + int_t iDataSize; ///< Size of the meaningful data (including this header) + int_t iRealSize; ///< Size of the data stored in file (may differ from ulDataSize ie. when encrypting) + uint_t uiCRC32; ///< Crc32 of the data (only the data part) + + // helper + uint_t uiHeaderCRC32; ///< Header's crc32 (without this field) +}; + +/** \brief Platform independent file and serialization class + * + * Class allows to access file objects using system dependent functions. Allow + * to use internal buffering for faster reading small amounts of data. + * Also allows to serialize data in blocks (with crc checksums). + */ +class LIBICPF_API file +{ +public: + // construction/destruction +/** \name Construction/destruction +@{*/ + file(); ///< Constructs a file object + ~file(); ///< Destructs a file object +/**@}*/ + +/** \name Standard operations + * Standard file operations that works both in buffered and unbuffered mode. + */ +/**@{*/ + // open/close the file + void open(const char_t* pszPath, uint_t uiFlags, uint_t uiBufSize=4096); ///< Opens a file with a given path + void close(); ///< Closes the currently opened file + + // reads or writes the data from/to a file (uses buffering for these operations if enabled) + int_t read(ptr_t pBuffer, int_t iSize); ///< Reads some data from a file + int_t write(ptr_t pBuffer, int_t iSize); ///< Writes some data to a file + + // handling the lines of text in a file (autodetecting the windows/unix style of line ending) + bool read_line(char_t* pszStr, uint_t uiMaxLen); ///< Reads a line of text from a file + void write_line(char_t* pszString); ///< Writes a line of text to a file + + // position related functions + void seek(longlong_t llOffset, uint_t uiFrom); ///< Moves a file pointer in a file + longlong_t getpos(); ///< Gets the current position of a file pointer + + // size related functions + void seteof(); ///< Sets the end of file in the current file pointer place + longlong_t get_size(); ///< Retrieves the size of a file + + void flush(); ///< Flushes the internal buffers +/**@}*/ + + +/** \name Buffering state functions + * Operations that allow manipulating the file buffering state. + */ +/**@{*/ + // buffered/unbuffered state management + /// Enables or disables the buffering + void set_buffering(bool bEnable=true, uint_t dwSize=4096); + /// Returns the buffering state + bool is_buffered() { return m_bBuffered; }; + /// Returns the current buffer size (for buffered operations) + uint_t get_buffersize() { return m_uiBufferSize; }; + + void switch_unbuffered(); ///< Stores current buffered/unbuffered state and switches to unbuffered + void switch_buffered(); ///< Stores current buffered/unbuffered state and switches to buffered + void restore_state(); ///< Restores (un)buffered last state +/**@}*/ + +/** \name Serialization functions + * Operations that allow manipulating the file buffering state. + */ +/**@{*/ + // serialization (block operation) + void datablock_begin(uint_t dwFlags=BF_NONE); ///< Begins the serialization data block + void datablock_end(); ///< Ends the serialization data block + +#ifdef USE_ENCRYPTION + void set_password(const char_t* pszPass); ///< Sets encryption/decryption password for serialization +#endif + + // serialization stuff + void swrite(ptr_t pData, uint_t dwSize); ///< Appends some data to the serialialization buffer + void sread(ptr_t pData, uint_t dwSize); ///< Reads some data from serialization buffer + + // state checking + /// Checks if the class is performing write-type serialization + bool is_storing() { return (m_uiFlags & FA_WRITE) != 0; }; + /// Checks if the class is performing read-type serialization + bool is_loading() { return (m_uiFlags & FA_READ) != 0; }; + + // storing&reading data + file& operator<<(bool val); ///< Stores a given 'val' parameter in the file + file& operator>>(bool& val); ///< Reads a value of a given type from the file + file& operator<<(char_t val); ///< Stores a given 'val' parameter in the file + file& operator>>(char_t& val); ///< Reads a value of a given type from the file + file& operator<<(uchar_t val); ///< Stores a given 'val' parameter in the file + file& operator>>(uchar_t& val); ///< Reads a value of a given type from the file + file& operator<<(short_t val); ///< Stores a given 'val' parameter in the file + file& operator>>(short_t& val); ///< Reads a value of a given type from the file + file& operator<<(ushort_t val); ///< Stores a given 'val' parameter in the file + file& operator>>(ushort_t& val); ///< Reads a value of a given type from the file + file& operator<<(int_t val); ///< Stores a given 'val' parameter in the file + file& operator>>(int_t& val); ///< Reads a value of a given type from the file + file& operator<<(uint_t val); ///< Stores a given 'val' parameter in the file + file& operator>>(uint_t& val); ///< Reads a value of a given type from the file + file& operator<<(ll_t val); ///< Stores a given 'val' parameter in the file + file& operator>>(ll_t& val); ///< Reads a value of a given type from the file + file& operator<<(ull_t val); ///< Stores a given 'val' parameter in the file + file& operator>>(ull_t& val); ///< Reads a value of a given type from the file + +/* /// Stores some integral type as a part of serialization data block + template file& operator<<(T tData) { swrite(&tData, sizeof(T)); return *this; }; + /// Reads some integral type from a serialization data block + template file& operator>>(T& tData) { sread(&tData, sizeof(T)); return *this; };*/ + + // specialized serialization stuff + file& operator<<(icpf::string& str); ///< Stores a CString object in this file (only usable when used in an MFC program) + file& operator>>(icpf::string& str); ///< Reads a CString object from this file (only usable when used in an mfc program) +/**@}*/ + +protected: + // serialization related internal functions + void _sbuf_append(ptr_t pData, uint_t dwCount); ///< Adds some data to the end of serialization buffer + void _sbuf_resize(uint_t dwNewLen); ///< Resizes the serialization buffer to make some more additional space + void _sbuf_read(ptr_t pData, uint_t dwLen); ///< Gets some data from the serialization buffer + void _clear_serialization(); ///< Cancels the serialization + + // file-buffering related operations + uint_t _read_packet(); ///< Reads next packet of data into the internal buffer + uint_t _write_packet(); ///< Writes next packet of data into a file + + bool _read_string(char_t* pszStr, uint_t dwMaxLen); ///< Reads a string from an internal buffer + longlong_t _seek(longlong_t llOffset, uint_t uiFrom); ///< A standard seek command done wo any flushing + +protected: +#ifdef _WIN32 + HANDLE m_hFile; ///< Handle to a real file +#else + intptr_t m_hFile; ///< Handle to a real file +#endif + char_t* m_pszPath; ///< Path to the opened file as passed to file::open() + uint_t m_uiFlags; ///< File flags as passed to file::open() + + bool m_bLastOperation; ///< States the last operation performed - false=>READ, true=>WRITE + + // read/write buffering + bool m_bBuffered; ///< States if the file is currently in buffered state + uint_t m_uiBufferSize; ///< Internal buffer size for buffering + byte_t* m_pbyBuffer; ///< Ptr to the internal buffer + uint_t m_uiCurrentPos; ///< Current position in the internal buffer + uint_t m_uiDataCount; ///< Count of data in the internal buffer (counting from beginning) + + // state + bool m_bRememberedState; ///< Specifies if the buffering state was saved + + // serialization stuff + bool m_bSerializing; ///< States if the serialization is in progress + byte_t* m_pbySerialBuffer; ///< Serialization buffer + uint_t m_uiSerialBufferSize; ///< Current size of the serialization buffer + uint_t m_uiSerialBufferPos; ///< Current position in the serialization buffer + uint_t m_uiDataBlockFlags; ///< Flags of the current serialization block + + +#ifdef USE_ENCRYPTION + // encryption related + string m_strPassword; ///< Password used for encryption/decryption of serialization data +#endif +}; + +END_ICPF_NAMESPACE + +#endif Index: ext/libicpf/src/gen_types.h =================================================================== diff -u -N --- ext/libicpf/src/gen_types.h (revision 0) +++ ext/libicpf/src/gen_types.h (revision e17c80d36eaa0430313e7d1058aa7a301d1510af) @@ -0,0 +1,267 @@ +/*************************************************************************** + * Copyright (C) 2004 by J�zef Starosczyk * + * copyhandler@o2.pl * + * * + * This program 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 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 Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +/** \file engine_config.h + * \brief Contains some compile-time settings for the whole engine. + */ +#ifndef __ENGINE_CONFIG_H__ +#define __ENGINE_CONFIG_H__ + +#ifdef HAVE_CONFIG_H + #include "config.h" +#endif + +#ifdef HAVE_INTTYPES_H + #include +#else + #include +#endif + +// formatting-related macros +// chars +/// Printf-style format string for displaying char_t value (as char) +#define CHARFMT "%c" +/// Printf-style format string for displaying uchar_t value (as char) +#define UCHARFMT CHARFMT + +// char related numbers (workaround for (u)chars - values are(should be) converted to (u)short_t) +/// Printf-style format string for displaying char_t as a number (the number has to be converted to short_t) +#define CFMT "%hd" +/// Printf-style format string for displaying char_t as a hexadecimal number (the number has to be converted to short_t) +#define CXFMT "0x%.2hx" +/// Printf-style format string for displaying uchar_t as a number (the number has to be converted to ushort_t) +#define UCFMT "%hu" +/// Printf-style format string for displaying uchar_t as a hexadecimal number (the number has to be converted to ushort_t) +#define UCXFMT CXFMT + +// numbers +// 16-bit +/// Printf-style format string for displaying short_t as a number +#define SFMT "%hd" +/// Printf-style format string for displaying short_t as a hex number +#define SXFMT "0x%.4hx" +/// Printf-style format string for displaying ushort_t as a number +#define USFMT "%hu" +/// Printf-style format string for displaying ushort_t as a hex number +#define USXFMT SXFMT + +// 32-bit +#ifdef _WIN32 + /// Printf-style format string for displaying long_t + #define LFMT "%ld" + /// Printf-style format string for displaying long_t as a hex number + #define LXFMT "0x%.8lx" + /// Printf-style format string for displaying ulong_t + #define ULFMT "%lu" +#else + /// Printf-style format string for displaying long_t + #define LFMT "%d" + /// Printf-style format string for displaying long_t as a hex number + #define LXFMT "0x%.8x" + /// Printf-style format string for displaying ulong_t + #define ULFMT "%u" +#endif + +/// Printf-style format string for displaying int_t +#define IFMT LFMT +/// Printf-style format string for displaying int_t as a hex number +#define IXFMT LXFMT +/// Printf-style format string for displaying uint_t +#define UIFMT ULFMT +/// Printf-style format string for displaying ulong_t as a hex number +#define ULXFMT LXFMT +/// Printf-style format string for displaying uint_t as a hex number +#define UIXFMT ULXFMT + +// 64-bit & system dependent +#ifdef _WIN32 + /// Printf-style format string for displaying ulonglong_t as a number + #define ULLFMT "%I64u" + /// Printf-style format string for displaying ulonglong_t as a hex number + #define ULLXFMT "0x%.16I64x" + /// Printf-style format string for displaying longlong_t + #define LLFMT "%I64d" + /// Printf-style format string for displaying longlong_t as a hex number + #define LLXFMT ULLXFMT + + #ifdef _WIN64 + /// Printf-style format string for displaying intptr_t + #define IPTRFMT LLFMT + /// Printf-style format string for displaying longptr_t + #define LPTRFMT LLFMT + /// Printf-style format string for displaying intptr_t as a hex number + #define IPTRXFMT LLXFMT + /// Printf-style format string for displaying longptr_t as a hex number + #define LPTRXFMT LLXFMT + /// Printf-style format string for displaying uintptr_t + #define UIPTRFMT ULLFMT + /// Printf-style format string for displaying ulongptr_t + #define ULPTRFMT ULLFMT + /// Printf-style format string for displaying uintptr_t as a hex number + #define UIPTRXFMT ULLXFMT + /// Printf-style format string for displaying ulongptr_t as a hex number + #define ULPTRXFMT ULLXFMT + #else + /// Printf-style format string for displaying intptr_t + #define IPTRFMT LFMT + /// Printf-style format string for displaying longptr_t + #define LPTRFMT LFMT + /// Printf-style format string for displaying intptr_t as a hex number + #define IPTRXFMT LXFMT + /// Printf-style format string for displaying longptr_t as a hex number + #define LPTRXFMT LXFMT + /// Printf-style format string for displaying uintptr_t + #define UIPTRFMT ULFMT + /// Printf-style format string for displaying ulongptr_t + #define ULPTRFMT ULFMT + /// Printf-style format string for displaying uintptr_t as a hex number + #define UIPTRXFMT ULXFMT + /// Printf-style format string for displaying ulongptr_t as a hex number + #define ULPTRXFMT ULXFMT + #endif +#else + /// Printf-style format string for displaying ulonglong_t as a number + #define ULLFMT "%llu" + /// Printf-style format string for displaying ulonglong_t as a hex number + #define ULLXFMT "0x%.16llx" + /// Printf-style format string for displaying longlong_t + #define LLFMT "%lld" + /// Printf-style format string for displaying longlong_t as a hex number + #define LLXFMT ULLXFMT + + // FIXME: distinguish between linux 32-bit architecture and 64-bit architecture here + /// Printf-style format string for displaying intptr_t + #define IPTRFMT "%ld" + /// Printf-style format string for displaying longptr_t + #define LPTRFMT IPTRFMT + /// Printf-style format string for displaying intptr_t as a hex number + #define IPTRXFMT "0x%.8lx" + /// Printf-style format string for displaying longptr_t as a hex number + #define LPTRXFMT IPTRXFMT + /// Printf-style format string for displaying uintptr_t + #define UIPTRFMT "%lu" + /// Printf-style format string for displaying ulongptr_t + #define ULPTRFMT UIPTRFMT + /// Printf-style format string for displaying uintptr_t as a hex number + #define UIPTRXFMT "0x%.8lx" + /// Printf-style format string for displaying ulongptr_t as a hex number + #define ULPTRXFMT UIPTRXFMT +#endif + +// strings +/// Printf-style format string for displaying ansi strings (char_t based strings) +#define STRFMT "%s" +#ifdef _WIN32 + /// Printf-style format string for displaying wide strings (wchar_t based strings) + #define WSTRFMT "%S" +#else + /// Printf-style format string for displaying wide strings (wchar_t based strings) + #define WSTRFMT "%ls" +#endif + +// pointer +/// Printf-style format string for displaying pointers +#define PTRFMT "%p" + +// standard types and formats used throughout the library +// exactly 1 byte +/// Byte type (8bit unsigned int) +typedef unsigned char byte_t; + +// chars +/// 8bit signed char +typedef char char_t; +/// 8bit unsigned char +typedef unsigned char uchar_t; + +// 16-bit integers +/// 16bit short integer +typedef short short_t; +/// 16bit unsigned short integer +typedef unsigned short ushort_t; + +// 32-bit integers +#ifdef _WIN32 + #ifdef _WIN64 + /// 32bit integer + typedef long int_t; + /// 32bit integer + typedef long long_t; + /// 32bit unsigned integer + typedef unsigned long uint_t; + /// 32bit unsigned long + typedef unsigned long ulong_t + #else + /// 32bit integer + typedef int int_t; + /// 32bit integer + typedef long long_t; + /// 32bit unsigned integer + typedef unsigned int uint_t; + /// 32bit unsigned integer + typedef unsigned long ulong_t; + #endif +#else + /// 32bit integer + typedef int int_t; + /// 32bit integer + typedef int long_t; + /// 32bit unsigned integer + typedef unsigned int uint_t; + /// 32bit unsigned integer + typedef unsigned int ulong_t; +#endif + +// 64-bit integers +/// 64bit long long +typedef long long longlong_t; +/// 64bit unsigned long long +typedef unsigned long long ulonglong_t; +/// 64bit long long +typedef longlong_t ll_t; +/// 64bit unsigned long long +typedef ulonglong_t ull_t; + +// platform dependent integers (32-bit on 32-bit platforms, 64-bit on 64-bit platforms) +#ifdef _WIN32 + /// platform-dependent size signed integer (32-bit on 32-bit platforms, 64-bit on 64-bit platforms) +// typedef int intptr_t; + /// platform-dependent size signed integer (32-bit on 32-bit platforms, 64-bit on 64-bit platforms) + typedef intptr_t longptr_t; + /// platform-dependent size unsigned integer (32-bit on 32-bit platforms, 64-bit on 64-bit platforms) +// typedef unsigned int uintptr_t; + /// platform-dependent size unsigned integer (32-bit on 32-bit platforms, 64-bit on 64-bit platforms) + typedef uintptr_t ulongptr_t; +#else + // linux and other + /// platform-dependent size signed integer (32-bit on 32-bit platforms, 64-bit on 64-bit platforms) +// typedef long intptr_t; + /// platform-dependent size signed integer (32-bit on 32-bit platforms, 64-bit on 64-bit platforms) + typedef intptr_t longptr_t; + /// platform-dependent size unsigned integer (32-bit on 32-bit platforms, 64-bit on 64-bit platforms) +// typedef unsigned long uintptr_t; + /// platform-dependent size unsigned integer (32-bit on 32-bit platforms, 64-bit on 64-bit platforms) + typedef uintptr_t ulongptr_t; +#endif + +// pointer +/// untyped pointer +typedef void* ptr_t; + +#endif Index: ext/libicpf/src/libicpf.cpp =================================================================== diff -u -N --- ext/libicpf/src/libicpf.cpp (revision 0) +++ ext/libicpf/src/libicpf.cpp (revision e17c80d36eaa0430313e7d1058aa7a301d1510af) @@ -0,0 +1,23 @@ +// libicpf.cpp : Defines the entry point for the DLL application. +// + +#ifdef _WIN32 +#include + +BOOL APIENTRY DllMain( HANDLE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved + ) +{ + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + break; + } + return TRUE; +} + +#endif Index: ext/libicpf/src/libicpf.h =================================================================== diff -u -N --- ext/libicpf/src/libicpf.h (revision 0) +++ ext/libicpf/src/libicpf.h (revision e17c80d36eaa0430313e7d1058aa7a301d1510af) @@ -0,0 +1,56 @@ +#ifndef __LIBICPF_H__ +#define __LIBICPF_H__ + +/** \brief Allows unicode handling throughout the files + * + * It means that the engine would process fs object's paths + * in the better standard - if possible then with current ANSI code page (one-byte + * chars) or with UNICODE strings (with 2-byte per char strings). + * \note if this is disabled (#undef) then the data saved by ie. unicode windows + * system may not be readable (because we won't use the iconv package on linux + * systems nor use any of the unicode functions in windows systems). + * Recommended setting is 'defined'. + */ +#define ALLOW_UNICODE + +/** \brief Enables use of encryption throughout this library. + * + * Enabling this macro enables usage of the encryption in some modules. + */ +#define USE_ENCRYPTION + +// import/export macros +#ifdef _WIN32 + #ifdef LIBICPF_EXPORTS + /** \brief Import/export macros + * + * These macros are being used throughout the whole code. They are meant to + * export symbols (if the LIBICPF_EXPORTS is defined) from this library + * (also for importing (when LIBICPF_EXPORTS macro is undefined) in other apps). + */ + #define LIBICPF_API __declspec(dllexport) + #else + /** \brief Import/export macros + * + * These macros are being used throughout the whole code. They are meant to + * export symbols (if the LIBICPF_EXPORTS is defined) from this library + * (also for importing (when LIBICPF_EXPORTS macro is undefined) in other apps). + */ + #define LIBICPF_API __declspec(dllimport) + #endif +#else + /** \brief Import/export macros + * + * These macros are being used throughout the whole code. They are meant to + * export symbols (if the LIBICPF_EXPORTS is defined) from this library + * (also for importing (when LIBICPF_EXPORTS macro is undefined) in other apps). + */ + #define LIBICPF_API +#endif + +/// Begins ch namespace +#define BEGIN_ICPF_NAMESPACE namespace icpf { +/// Ends ch namespace +#define END_ICPF_NAMESPACE }; + +#endif Index: ext/libicpf/src/log.cpp =================================================================== diff -u -N --- ext/libicpf/src/log.cpp (revision 0) +++ ext/libicpf/src/log.cpp (revision e17c80d36eaa0430313e7d1058aa7a301d1510af) @@ -0,0 +1,515 @@ +/*************************************************************************** + * Copyright (C) 2004 by J�zef Starosczyk * + * copyhandler@o2.pl * + * * + * This program 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 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 Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +/** \file log.cpp + * \brief Contains the implamentation of a log class. + */ +#include "log.h" +#include +#include +#include +#include +#include +#include "macros.h" + +#ifdef WIN32 + #include + #include + #include +#else + #include +#endif + +BEGIN_ICPF_NAMESPACE + +/// Table of strings representing the log message types +const char_t* __logtype_str[] = { "debug", "info", "warning", "error" }; + +/// Global variable initialized when constructing log_file object +log_file* __g_log=NULL; + +log_file::log_file() +{ + __g_log=this; + m_pszPath=NULL; + m_bLogStd=false; + m_iLogLevel=LT_DEBUG; +#ifdef WIN32 + _fmode=_O_BINARY; +#endif +} + +log_file::~log_file() +{ + __g_log=NULL; + delete [] m_pszPath; +} + +/** Creates a global instance of a log file. + * \param[in] pszPath - path to a log file to write to + * \param[in] iMaxSize - maximum size of a log file + * \param[in] iLogLevel - minimum log level of the messages to log + * \param[in] bLogStd - log the messages also to stdout/stderr + * \param[in] bClean - cleans the log file upon opening + * \return True if the log file has been successfully initialized or false if not. + */ +bool create_log(const char_t* pszPath, int_t iMaxSize, int_t iLogLevel, bool bLogStd, bool bClean) +{ + log_file* pLog=new log_file(); + if (!pLog->init(pszPath, iMaxSize, iLogLevel, bLogStd, bClean)) + { + delete pLog; + return false; + } + + return true; +} + +/** Initializes the constructed log file. + * \param[in] pszPath - path to a log file to write to + * \param[in] iMaxSize - maximum size of a log file + * \param[in] iLogLevel - minimum log level of the messages to log + * \param[in] bLogStd - log the messages also to stdout/stderr + * \param[in] bClean - cleans the log file upon opening + * \return True if the log file has been successfully initialized or false if not. + */ +bool log_file::init(const char_t* pszPath, int_t iMaxSize, int_t iLogLevel, bool bLogStd, bool bClean) +{ + delete [] m_pszPath; + m_pszPath=new char_t[strlen(pszPath)+1]; + strcpy(m_pszPath, pszPath); + + m_iMaxSize=iMaxSize; + m_bLogStd=bLogStd; + m_iLogLevel=iLogLevel; + + FILE* pFile=fopen(pszPath, bClean ? "w" : "a"); + if (pFile == NULL) + return false; + + fclose(pFile); + return true; +} + +/** Retrieves the current size of a log file. + * Quite slow function - have to access the file by opening and closing it. + * \return Current file size. + */ +int_t log_file::size() +{ + assert(m_pszPath); + + int_t iSize=-1; + FILE* pFile=fopen(m_pszPath, "r"); + if (pFile != NULL) + { + if (fseek(pFile, 0, SEEK_END) == 0) + iSize=ftell(pFile); + } + + fclose(pFile); + + return iSize; +} + +// @lAdd - count of bytes that would be appended to the file +/** Truncates the current log file content so when adding some new text the + * file size won't exceed the maximum size specified in init(). + * \param[in] iAdd - size of the new string to be added to the log file + * \return True if truncate succeeded or false if not. + */ +bool log_file::truncate(int_t iAdd) +{ + assert(m_pszPath); + + // if we doesn't need to truncate anything + if (m_iMaxSize <= 0) + return true; + + // make some checks + int_t iSize=size(); + if (iSize <= 0 || iSize+iAdd < m_iMaxSize) + return false; + + // establish the new file size (1/3rd of the current size or max_size-add_size) + int_t iNewSize=minval((int_t)(iSize*0.66), m_iMaxSize-iAdd); + +#ifdef _WIN32 + // win32 does not have the ftruncate function, so we have to make some API calls + HANDLE hFile=CreateFile(m_pszPath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (hFile != INVALID_HANDLE_VALUE) + { + // seek + if (SetFilePointer(hFile, iSize-iNewSize, NULL, FILE_BEGIN) != INVALID_SET_FILE_POINTER) + { + // read the string to the eol + DWORD dwRD; + char_t szBuffer[4096]; + if (ReadFile(hFile, szBuffer, 4096, &dwRD, NULL)) + { + szBuffer[(dwRD > 0) ? dwRD-1 : 0]='\0'; + + // replace the /r and /n in the log to the \0 + for (DWORD i=0;i 0) + { + // seek to the dst + fseek(pFile, iDst, SEEK_SET); + + fflush(pFile); + // write the buffer to the dest offset + tWR=fwrite(szBuffer, 1, tRD, pFile); + iDst+=tWR; + } + + iSrc+=tRD; + } + while(tRD != 0); + + // now truncate the file to the needed size + ftruncate(fileno(pFile), iDst); + + fclose(pFile); + return true; + } + + fclose(pFile); + } +#endif + + return false; +} + +/** Logs a formatted message to a log file. + * \param[in] iType - type of the log message (LT_*) + * \param[in] bStd - log also to stdout/stderr if true + * \param[in] pszStr - format string for the following parameters + */ +void log_file::log(int_t iType, bool bStd, const char_t* pszStr, ...) +{ + if (iType < m_iLogLevel) + return; + + va_list va; + va_start(va, pszStr); + logv(iType, bStd, pszStr, va); + va_end(va); +} + +/** Logs a formatted message to a log file. + * \param[in] iType - type of the log message (LT_*) + * \param[in] bStd - log also to stdout/stderr if true + * \param[in] pszStr - format string for the following parameters + * \param[in] va - variable argument list + */ +void log_file::logv(int_t iType, bool bStd, const char_t* pszStr, va_list va) +{ + if (iType < m_iLogLevel) + return; + + char_t szBuf1[1024]; + vsprintf(szBuf1, pszStr, va); // user passed stuff + + logs(iType, bStd, szBuf1); +} + +/** Logs an unformatted message to a log file. + * \param[in] iType - type of the log message (LT_*) + * \param[in] bStd - log also to stdout/stderr if true + * \param[in] pszStr - message string + */ +void log_file::logs(int_t iType, bool bStd, const char_t* pszStr) +{ + assert(m_pszPath); + + if (iType < m_iLogLevel) + return; + + // log time + time_t t=time(NULL); + char_t szData[128]; + strcpy(szData, ctime(&t)); + size_t tLen=strlen(szData)-1; + while(szData[tLen] == '\n') + szData[tLen--]='\0'; + + m_lock.lock(); + + // check the size constraints + truncate((int_t)(strlen(pszStr)+1)); + FILE* pFile=fopen(m_pszPath, "a"); + bool bFailed=false; + if (pFile) + { + if (fprintf(pFile, "[" STRFMT "] [" STRFMT "] " STRFMT "\n", szData, __logtype_str[iType], pszStr) < 0) + bFailed=true; + fclose(pFile); + } + else + bFailed=true; + if (bFailed || (m_bLogStd && !bStd)) + { + switch(iType) + { + case LT_ERROR: + { + fprintf(stderr, "[" STRFMT "] [" STRFMT "] " STRFMT "\n", szData, __logtype_str[iType], pszStr); + break; + } + default: + { + fprintf(stdout, "[" STRFMT "] [" STRFMT "] " STRFMT "\n", szData, __logtype_str[iType], pszStr); + break; + } + } + } + else if (bStd) + { + switch(iType) + { + case LT_ERROR: + { + fprintf(stderr, STRFMT ": " STRFMT "\n", __logtype_str[iType], pszStr); + break; + } + case LT_INFO: + { + fprintf(stdout, STRFMT "\n", pszStr); + break; + } + default: + { + fprintf(stdout, STRFMT ": " STRFMT "\n", __logtype_str[iType], pszStr); + break; + } + } + } + + m_lock.unlock(); +} + +#if _LOG_LEVEL <= LT_DEBUG +/** Logs a formatted debug message to a log file. + * \param[in] pszStr - format string for the given parameters + */ +void log_file::logd(const char_t* pszStr, ...) +{ + if (m_iLogLevel > LT_DEBUG) + return; + + va_list va; + va_start(va, pszStr); + logv(LT_DEBUG, false, pszStr, va); + va_end(va); +} + +/** Logs a formatted debug message to a log file(also outputs to stdout). + * \param[in] pszStr - format string for the given parameters + */ +void log_file::logds(const char_t* pszStr, ...) +{ + if (m_iLogLevel > LT_DEBUG) + return; + + va_list va; + va_start(va, pszStr); + logv(LT_DEBUG, true, pszStr, va); + va_end(va); +} + +#else +void log_file::logd(const char_t* pszStr, ...) +{ +} + +void log_file::logds(const char_t* pszStr, ...) +{ +} +#endif + +#if _LOG_LEVEL <= LT_INFO +/** Logs a formatted informational message to a log file. + * \param[in] pszStr - format string for the given parameters + */ +void log_file::logi(const char_t* pszStr, ...) +{ + if (m_iLogLevel > LT_INFO) + return; + + va_list va; + va_start(va, pszStr); + logv(LT_INFO, false, pszStr, va); + va_end(va); +} + +/** Logs a formatted informational message to a log file(also outputs to stdout). + * \param[in] pszStr - format string for the given parameters + */ +void log_file::logis(const char_t* pszStr, ...) +{ + if (m_iLogLevel > LT_INFO) + return; + + va_list va; + va_start(va, pszStr); + logv(LT_INFO, true, pszStr, va); + va_end(va); +} +#else +void log_file::logi(const char_t* pszStr, ...) +{ +} + +void log_file::logis(const char_t* pszStr, ...) +{ +} + +#endif + +#if _LOG_LEVEL <= LT_WARNING +/** Logs a formatted warning message to a log file. + * \param[in] pszStr - format string for the given parameters + */ +void log_file::logw(const char_t* pszStr, ...) +{ + if (m_iLogLevel > LT_WARNING) + return; + + va_list va; + va_start(va, pszStr); + logv(LT_WARNING, false, pszStr, va); + va_end(va); +} + +/** Logs a formatted warning message to a log file(also outputs to stdout). + * \param[in] pszStr - format string for the given parameters + */ +void log_file::logws(const char_t* pszStr, ...) +{ + if (m_iLogLevel > LT_WARNING) + return; + va_list va; + va_start(va, pszStr); + logv(LT_WARNING, true, pszStr, va); + va_end(va); +} + +#else +void log_file::logw(const char_t* pszStr, ...) +{ +} + +void log_file::logws(const char_t* pszStr, ...) +{ +} + +#endif + +/** Logs a formatted error message to a log file. + * \param[in] pszStr - format string for the given parameters + */ +void log_file::loge(const char_t* pszStr, ...) +{ + va_list va; + va_start(va, pszStr); + logv(LT_ERROR, false, pszStr, va); + va_end(va); +} + +/** Logs a formatted error message to a log file(also outputs to stderr). + * \param[in] pszStr - format string for the given parameters + */ +void log_file::loges(const char_t* pszStr, ...) +{ + va_list va; + va_start(va, pszStr); + logv(LT_ERROR, true, pszStr, va); + va_end(va); +} + +END_ICPF_NAMESPACE Index: ext/libicpf/src/log.h =================================================================== diff -u -N --- ext/libicpf/src/log.h (revision 0) +++ ext/libicpf/src/log.h (revision e17c80d36eaa0430313e7d1058aa7a301d1510af) @@ -0,0 +1,171 @@ +/*************************************************************************** + * Copyright (C) 2004 by J�zef Starosczyk * + * copyhandler@o2.pl * + * * + * This program 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 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 Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +/** \file log.h + * \brief Contains the log class. + */ +#ifndef __LOG_H__ +#define __LOG_H__ + +#include +#include "mutex.h" +#include "libicpf.h" +#include "gen_types.h" + +BEGIN_ICPF_NAMESPACE + +/// Log message type - debug +#define LT_DEBUG 0x00 +/// Log message type - informational +#define LT_INFO 0x01 +/// Log message type - warning +#define LT_WARNING 0x02 +/// Log message type - error +#define LT_ERROR 0x03 + +class log_file; + +extern log_file* __g_log; + +#ifndef _LOG_LEVEL +/** \brief Specifies the log level used by program. + * + * All the log messages used in code will be checked against this log level + * and if below then they will be removed from the code (probably). + */ +#define _LOG_LEVEL LT_DEBUG +#endif + +/// Logs a message using the global instance of the log class. +#define LOG\ + __g_log->log + +/// Logs a debug message using the global instance of the log class. +#define LOGD\ + __g_log->logd +/// Logs a debug message (with outputting it to stdout) using the global instance of the log class. +#define LOGDS\ + __g_log->logds + +/// Logs an informational message using the global instance of the log class. +#define LOGI\ + __g_log->logi +/// Logs an informational message (with outputting it to stdout) using the global instance of the log class. +#define LOGIS\ + __g_log->logis + +/// Logs a warning message using the global instance of the log class. +#define LOGW\ + __g_log->logw +/// Logs a warning (with outputting it to stdout) message using the global instance of the log class. +#define LOGWS\ + __g_log->logws + +/// Logs an error message using the global instance of the log class. +#define LOGE\ + __g_log->loge +/// Logs an error message (with outputting it to stdout) using the global instance of the log class. +#define LOGES\ + __g_log->loges + +/** \brief Class provides the message logging capability. + * + * Class used to perform message logging to the external file. Provides a possibility + * of limiting the max size of a file and to cut the log message types below a specific + * level. When constructed, class makes a global variable accessed by the friend function + * get_log() . As a helpers there has been some macros introduced (LOGXXX) that makes usage + * of the global variable. + * Usage: either construct a log_file object and init() it, or call a friend create_log() + * and delete_log() when finished using the class. + * Class is thread safe. + */ +class LIBICPF_API log_file +{ +public: +/** \name Construction/destruction */ +/**@{*/ + log_file(); ///< Standard constructor + ~log_file(); ///< Standard destructor +/**@}*/ + +/** \name Initialization */ +/**@{*/ + bool init(const char_t* pszPath, int_t iMaxSize, int_t iLogLevel, bool bLogStd, bool bClean); ///< Initializes the logging object +/**@}*/ + +/** \name Logging functions */ +/**@{*/ + void logs(int_t iType, bool bStd, const char_t* pszStr); ///< Logs a string without formatting + void log(int_t iType, bool bStd, const char_t* pszStr, ...); ///< Logs a string with formatting + void logv(int_t iType, bool bStd, const char_t* pszStr, va_list va); ///< Logs a string using va_list + +#if _LOG_LEVEL <= LT_DEBUG + void logd(const char_t* pszStr, ...); ///< Logs a debug message with formatting + void logds(const char_t* pszStr, ...); ///< Logs a debug message with formatting (also prints to stdout) +#else + void logd(const char_t* pszStr, ...); + void logds(const char_t* pszStr, ...); +#endif + +#if _LOG_LEVEL <= LT_INFO + void logi(const char_t* pszStr, ...); ///< Logs an informational message with formatting + void logis(const char_t* pszStr, ...); ///< Logs an informational message with formatting(also prints to stdout) +#else + void logi(const char_t* pszStr, ...); + void logis(const char_t* pszStr, ...); +#endif + +#if _LOG_LEVEL <= LT_WARNING + void logw(const char_t* pszStr, ...); ///< Logs a warning message with formatting + void logws(const char_t* pszStr, ...); ///< Logs a warning message with formatting(also prints to stdout) +#else + void logw(const char_t* pszStr, ...); + void logws(const char_t* pszStr, ...); +#endif + + void loge(const char_t* pszStr, ...); ///< Logs an error message with formatting + void loges(const char_t* pszStr, ...); ///< Logs an error message with formatting(also prints to stderr) +/**@}*/ + + /// Gets the global instance of the log file + friend log_file* get_log() { return __g_log; }; + /// Creates a global instance of a log file + friend bool create_log(const char_t* pszPath, int_t iMaxSize, int_t iLogLevel, bool bLogStd, bool bClean); + /// Deletes a global instance of a log dile + friend void delete_log() { delete __g_log; }; + +protected: + /// Truncates a log file not to exceed the max file size + bool truncate(int_t iAdd); + /// Returns the size of a log file + int_t size(); + +public: + char_t* m_pszPath; ///< Path to the log file + int_t m_iMaxSize; ///< Maximum size of the log file + bool m_bLogStd; ///< Log also to stdout/stderr + int_t m_iLogLevel; ///< Log level (similar to the _LOG_LEVEL, but change'able after compilation) + +protected: + mutex m_lock; ///< Lock for making the class thread safe +}; + +END_ICPF_NAMESPACE + +#endif Index: ext/libicpf/src/macros.h =================================================================== diff -u -N --- ext/libicpf/src/macros.h (revision 0) +++ ext/libicpf/src/macros.h (revision e17c80d36eaa0430313e7d1058aa7a301d1510af) @@ -0,0 +1,45 @@ +/*************************************************************************** + * Copyright (C) 2004 by J�zef Starosczyk * + * copyhandler@o2.pl * + * * + * This program 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 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 Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef __MACROS_H__ +#define __MACROS_H__ + +/** \file macros.h + * \brief Contains some helper macros used throughout other files + */ + +// macros for rounding up and down some values to the nearest ?*chunk +/// Rounding up value to the nearest chunk multiplicity +#define ROUNDUP(val,chunk) ((val + chunk - 1) & ~(chunk-1)) +/// Rounding down value to the nearest chunk multiplicity +#define ROUNDDOWN(val,chunk) (val & ~(chunk-1)) + +// cross-platform __FUNCTION__ macro +#ifndef _WIN32 + /// Some helper for non-windoze systems (unified cross-platform __FUNCTION__ macro) + #define __FUNCTION__ __PRETTY_FUNCTION__ +#endif + +// minimum/maximum macros +/// Returns the lesser value from two given as params +#define minval(a,b) ((a) < (b) ? (a) : (b)) +/// Returns the greater value from two given as params +#define maxval(a,b) ((a) > (b) ? (a) : (b)) + +#endif Index: ext/libicpf/src/module.cpp =================================================================== diff -u -N --- ext/libicpf/src/module.cpp (revision 0) +++ ext/libicpf/src/module.cpp (revision e17c80d36eaa0430313e7d1058aa7a301d1510af) @@ -0,0 +1,1176 @@ +/*************************************************************************** + * Copyright (C) 2004 by J�zef Starosczyk * + * copyhandler@o2.pl * + * * + * This program 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 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 Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +/** \file module.cpp + * \brief File contain an implementation of the module (and related) classes. + */ + +#include "module.h" +#include +#include "err_codes.h" + +#ifndef _WIN32 + #include +#endif + +BEGIN_ICPF_NAMESPACE + +/** Constructs a module_param class and initializes all the internal members + * to their initial values. + */ +module_param::module_param() +{ + m_midModuleID=NULL_MODULE; + m_uiPropStart=0; +} + +/** Destructs the module_param class. + */ +module_param::~module_param() +{ + +} + +/** Locks the class (multi-threaded access). + */ +void module_param::lock() +{ + m_lock.lock(); +} + +/** Unlocks the class (multi-threaded access). + */ +void module_param::unlock() +{ + m_lock.unlock(); +} + +/** Returns a module id associated with this class. + * \return Module ID + * \note The usage of mutex inside of this function is unnecessary, because + * the module id is not supposed to change. + */ +moduleid_t module_param::get_moduleid() const +{ + return m_midModuleID; +} + +/** Reads the properties from the configuration object (config class). Function + * implemented as virtual - it does not do anything in this (base) class. Should + * be implemented in the derived classes. Function should read the properties registered + * earlier with register_properties() from a given config object and initialize + * the internal structure data (m_pParams). The given structure should be allocated + * earlier (ie. in the constructor of the derived class). + * Calling this function should be the first operation done in the derived class' function. + * \param[in] pcfg - pointer to the config object to read the properties from + */ +void module_param::read_config(config* /*pcfg*/) +{ +} + +/** Function writes the internal configuration options to the given configuration + * object (config class). Declared virtual and the base implementation does not + * do anything. Should be implemented in the derived classes. The purpose of this + * function is to write data from the internal data structure (m_pParams) to the + * given config class. The structure should be allocated and initialized earlier. + * Calling this function should be the first operation done in the derived class' function. + * \param[in] pcfg - pointer to the config object to write the properties to + */ +void module_param::write_config(config* /*pcfg*/) +{ +} + +/** Function registers the properties used in the internal data structure (m_pParams) + * to the given configuration object (config class). Function declared as virtual and + * the base implementation does not do anything. In derived classes this function should + * register the properties with the config object and store the first returned property ID + * in the m_ulPropStart internal member. + * Calling this function should be the first operation done in the derived class' function. + * \note When registering properties user should lock the config object to make sure + * the ID's will be the subsequent numbers and not pseudo-random ones. + * \param[in] pcfg - pointer to the configuration object with which the props should be registered. + */ +void module_param::register_properties(config* /*pcfg*/) +{ +} + +// store/restore from/to a file (serializer) +/** Function stores the internal data structure settings to the external file (file class). + * Declared as virtual - base implementation does not do anything. In derived classes this + * function should store the members of the internal structure (m_pParams) in the given + * file object in some order (that must be used also in load() function). + * Calling this function should be the first operation done in the derived class' function. + * \param[in] ser - serialization object to write the data to + */ +void module_param::store(file& /*ser*/) +{ +} + +/** Function loads the internal data structure from a file (file class). Declared as + * virtual - base implementation does not do anything. In derived classes function + * should read the properties from a given file object (in the order used in store() function). + * Calling this function should be the first operation done in the derived class' function. + * \param[in] ser - serialization object that contains the data to be read + */ +void module_param::load(file& /*ser*/) +{ +} + +/** Standard constructor - does nothing currently. + */ +modparam_list::modparam_list() +{ + +} + +/** Standard destructor - clears the internal list of module_params. Also, each entry + * is being deleted before clearing. If you want to preserve the elements from being deleted - + * use the clear(false) method before destrying this object. + */ +modparam_list::~modparam_list() +{ + clear(true); +} + +/** Inserts a module_param to this list. + * \param[in] pEntry - address of a module_param class to be inserted. It should be allocated by + * the 'new' operator if you would like to use bDelete parameter set in other + * methods. + */ +void modparam_list::insert(module_param* pEntry) +{ + assert(pEntry); + m_lock.lock(); + m_mMods.insert(std::pair(pEntry->get_moduleid(), pEntry)); + m_lock.unlock(); +} + +/** Removes a module from the list. Also delete a module_param if specified. + * \param[in] tEntry - module id associated with an entry to remove + * \param[in] bDelete - specifies, if the delete operator should be called on an entry + * before removing it from the list. + * \return If the entry was successfully removed (true) or not (false). + */ +bool modparam_list::remove(moduleid_t tEntry, bool bDelete) +{ + m_lock.lock(); + std::map::iterator it = m_mMods.find(tEntry); + if (it != m_mMods.end()) + { + // delete if needed + if (bDelete) + delete it->second; + m_mMods.erase(it); + m_lock.unlock(); + return true; + } + else + { + m_lock.unlock(); + return false; + } +} + +/** Removes all the items from this list. + * \param[in] bDelete - if true, then all the items will be 'delete''d before removing. + */ +void modparam_list::clear(bool bDelete) +{ + m_lock.lock(); + if (bDelete) + { + for (std::map::iterator it=m_mMods.begin();it != m_mMods.end();it++) + { + delete it->second; + } + } + + m_mMods.clear(); + m_lock.unlock(); +} + +/** Searches for a module_param associated with a given module id. + * \param[in] mid - module id to search for + * \return Pointer to a module_param class, or NULL if not found. + */ +module_param* modparam_list::find(moduleid_t mid) +{ + m_lock.lock(); + std::map::iterator it = m_mMods.find(mid); + if (it != m_mMods.end()) + { + m_lock.unlock(); + return it->second; + } + else + { + m_lock.unlock(); + return NULL; + } +} + +/** A group wrapper over the module_param::read_config(). Calls the method for each of the module_param's. + * \param[in] pcfg - pointer to a configuration object to read the data from. + */ +void modparam_list::read_config(config* pcfg) +{ + // read the config for all entries + m_lock.lock(); + try + { + for (std::map::iterator it=m_mMods.begin();it != m_mMods.end();it++) + { + it->second->read_config(pcfg); + } + } + catch(...) + { + m_lock.unlock(); + throw; + } + m_lock.unlock(); +} + +/** A group wrapper over the module_param::write_config(). Calls the method for each of the module_param's. + * \param[in] pcfg - pointer to a configuration object to write the data to. + */ +void modparam_list::write_config(config* pcfg) +{ + m_lock.lock(); + try + { + for (std::map::iterator it=m_mMods.begin();it != m_mMods.end();it++) + { + it->second->write_config(pcfg); + } + } + catch(...) + { + m_lock.unlock(); + throw; + } + m_lock.unlock(); +} + +/** A group wrapper over the module_param::register_properties(). Calls the method for each of the module_param's. + * \param[in] pcfg - pointer to a configuration object to register the properties with. + */ +void modparam_list::register_properties(config* pcfg) +{ + m_lock.lock(); + try + { + for (std::map::iterator it=m_mMods.begin();it != m_mMods.end();it++) + { + it->second->register_properties(pcfg); + } + } + catch(...) + { + m_lock.unlock(); + throw; + } + m_lock.unlock(); +} + +/** A group wrapper over the module_param::store(). Calls the method for each of the module_param's. + * \param[in] ser - a serialization object to write the data to + */ +void modparam_list::store(file& ser) +{ + m_lock.lock(); + try + { + for (std::map::iterator it=m_mMods.begin();it != m_mMods.end();it++) + { + it->second->store(ser); + } + } + catch(...) + { + m_lock.unlock(); + throw; + } + m_lock.unlock(); +} + +/** A group wrapper over the module_param::load(). Calls the method for each of the module_param's. + * \param[in] ser - a serialization object to read the data from + */ +void modparam_list::load(file& ser) +{ + m_lock.lock(); + try + { + for (std::map::iterator it=m_mMods.begin();it != m_mMods.end();it++) + { + it->second->load(ser); + } + } + catch(...) + { + m_lock.unlock(); + throw; + } + m_lock.unlock(); +} + +/////////////////////////////////////////////////////////////////////////// +/** Constructor - makes a copy of the MODULE_INITDATA passed as the parameter + * and stores the given flags in the internal member. Also nullifies all the other class + * members. The module information is initialized with NULL values and for internal + * modules this should be corrected in the constructor of the derived class. + * \param[in] pData - pointer to the structure with some parameters (the copy of it + * will be stored in the internal member - not the pointer itself). + * \param[in] uiFlags - module flags that are about to be stored in the internal member (MF_*) + */ +module::module(const MODULE_INITDATA* pData, uint_t uiFlags) +{ + m_pmp=NULL; + m_pmid=pData; + m_ulFlags=uiFlags; + m_lRefCount=0; + + // module information + m_mi.uiInfoLen=sizeof(MODULE_INFO); + m_mi.midID=NULL_MODULE; + m_mi.szAuthor[0]='\0'; + m_mi.szName[0]='\0'; + m_mi.szVersion[0]='\0'; + m_mi.uiType=MT_NONE; + + m_hModule=NULL; + m_pszPath=NULL; + m_pfnGetInfo=NULL; + m_pfnInit=NULL; + m_pfnUninit=NULL; + m_pfnAllocModparam=NULL; +} + +/** Destructor. Tries to close the module (close(true) function). If the closing + * function throws an exception it is caught, logged to the log file (MODULE_INITDATA) + * and the exception is removed. + */ +module::~module() +{ + try + { + close(true); + } + catch(exception* e) + { + LOG_EXCEPTION(e, m_pmid->plog); + e->del(); + } +} + +// external modules support (called only for the external modules) +/** Function opens the external file as the program module. After successful + * file opening this function loads all exports from the module (using load_exports() + * function) and caches the module information in the internal member if all goes ok. + * If something goes wrong the exception* is thrown. All information (excluding exceptions + * are logged to the log file (MODULE_INITDATA)). + * \param[in] pszPath - full path to the module that is about to be loaded + */ +void module::open(const char_t* pszPath) +{ + assert(m_ulFlags & MF_EXTERNAL); // only for the external modules + + m_pmid->plog->logi("[module] Loading external module " STRFMT, pszPath); + + // try to load external library +#ifdef _WIN32 + if ( (m_hModule=::LoadLibrary(pszPath)) == NULL) + THROW(exception::format("Cannot load external module " STRFMT, pszPath), PE_CANNOTLOAD, GetLastError(), 0); +#else + if ( (m_hModule=dlopen(pszPath, RTLD_LAZY)) == NULL) + THROW(exception::format("Cannot load external module " STRFMT " (" STRFMT ")", pszPath, dlerror()), PE_CANNOTLOAD, 0, 0); +#endif + + m_pmid->plog->logi("[module] External module loaded successfully (handle " PTRFMT ")", m_hModule); + + // load all needed exports (function must throw if export does not exist) + m_pmid->plog->logd("[module] Loading exports for the module (handle " PTRFMT ")", m_hModule); + load_exports(); + m_pmid->plog->logd("[module] Exports loaded for the module (handle " PTRFMT ")", m_hModule); + + // cache the module information + m_pmid->plog->logd("[module] Caching module (handle " PTRFMT ") information", m_hModule); + (*m_pfnGetInfo)(&m_mi); + m_pmid->plog->logd("[module] Cached module (handle " PTRFMT ") information - id: " MODIDFMT ", type: " ULFMT ", name: " STRFMT ", version: " STRFMT ", author: " STRFMT "", m_hModule, m_mi.midID, m_mi.uiType, m_mi.szName, m_mi.szVersion, m_mi.szAuthor); + + // store the path + m_pszPath=new char_t[strlen(pszPath)+1]; + strcpy(m_pszPath, pszPath); +} + +// close the module - it's safe to call it more than once +/** Closes the external module. At first it uninitializes the module that is about to + * be unloaded and then closes the module and resets all(except the module info) the + * internal data. Function is safe to be called more than once. If any problem occur + * there is the exception* thrown. + * \param[in] bFullDestruct - should be true only in destructor. Means deleting the path string + * before uninitialization (and not after as with false). + */ +void module::close(bool bFullDestruct) +{ + // if called from a destructor - release some of the memory allocated + if (bFullDestruct) + { + // delete the path allocated earlier + delete [] m_pszPath; + m_pszPath=NULL; + } + + // uninit the module if wasn't already + uninit(); + + // release stuff related to external module + if (m_hModule != NULL) + { + m_pmid->plog->logd("[module] Unloading an external module (handle " PTRFMT ")", m_hModule); + +#ifdef _WIN32 + if (!::FreeLibrary(m_hModule)) + THROW(exception::format("Cannot unload the external module (handle " PTRFMT ")", m_hModule), PE_CANNOTUNLOAD, GetLastError(), 0); +#else + if (dlclose(m_hModule) != 0) + THROW(exception::format("Cannot unload the external module - " STRFMT " (handle " PTRFMT ")", dlerror(), m_hModule), PE_CANNOTUNLOAD, 0, 0); +#endif + m_pmid->plog->logd("[module] ...external module unloaded (handle " PTRFMT ")", m_hModule); + } + + m_hModule=NULL; + m_pfnGetInfo=NULL; + m_pfnInit=NULL; + m_pfnUninit=NULL; + + // release a memory when sure the module has been succesfully freed + if (!bFullDestruct) + { + delete [] m_pszPath; + m_pszPath=NULL; + } +} + +/** Retrieves the module information (author, ... as in MODULE_INFO struct). This function + * does not use the internal cache for external modules - there is always a call made to the + * module. Internal modules always use caching (it's their only info source). + * \param[out] pInfo - receives the module information + */ +void module::get_info(MODULE_INFO* pInfo) +{ + if (m_ulFlags & MF_EXTERNAL) + { + assert(m_hModule); + + (*m_pfnGetInfo)(pInfo); + } + else + *pInfo=m_mi; +} + +/** Function initializes the module. For external modules the module's init() function will be + * called. For internal modules this should be the first function called from within the init() + * function of the derived class. If the function fails it can return false or throw an exception. + * Function is safe to be called multiple times - the real init() functions will be called + * only once. + * \note In the internal modules the init() function in the derived classes should check for + * the MF_INITIALIZED flag and do not perform any initialization if flag is set to 0. + * \param[in] pData - module initialization data - should be the same as in constructor + * \return True if the function succeeds, false otherwise. + */ +bool module::init(const MODULE_INITDATA* pData) +{ + // return if already initialized + if (m_ulFlags & MF_INITIALIZED) + return true; + + if (m_ulFlags & MF_EXTERNAL) + { + m_pmid->plog->logi("[module] Making external module initialization (id=" MODIDXFMT ")...", get_id()); + if ((*m_pfnInit)(pData, &m_pmp)) + { + m_pmid->plog->logi("[module] ...external module initialized successfully (id=" MODIDXFMT ").", get_id()); + m_ulFlags |= MF_INITIALIZED; + return true; + } + else + { + m_pmid->plog->logi("[module] ...external module initialization failed (id=" MODIDXFMT ").", get_id()); + return false; + } + } + else + { + m_ulFlags |= MF_INITIALIZED; + return true; + } +} + +// uninitializes a module +// safe to call multiple times (ext module uninit() func will be called only once) +/** Uninitializes a module. This is the first function to be called in uninit() function + * of the derived classes (internal modules). For external modules this function calls the + * module's init() function. This function is safe to be called multiple times - the real + * initialization functions will be called only once. On error either false value can be returned + * or exception* will be thrown. + * \note For internal modules - this function at first should check if the module has been + * initialized (by checking the MF_INITIALIZED flag - it must be set). If it is not then + * no uninitialization should be done. + * \return True if all went ok, false otherwise. + */ +bool module::uninit() +{ + if (m_ulFlags & MF_INITIALIZED) + { + if (m_ulFlags & MF_EXTERNAL) + { + m_pmid->plog->logi("[module] Making external module uninitialization (id=" MODIDXFMT ")...", get_id()); + if ((*m_pfnUninit)(&m_pmp)) + { + m_pmid->plog->logi("[module] ...external module uninitialization succeeded (id=" MODIDXFMT ").", get_id()); + + // delete the module parameters/informations if allocated + cleanup(); + + return true; + } + else + { + m_pmid->plog->logi("[module] ...external module uninitialization failed (id=" MODIDXFMT ").", get_id()); + return false; + } + } + else + { + // delete the module parameters/informations if allocated + cleanup(); + + return true; + } + } + else + return true; // already uninitialized +} + +/** Allocates a module_param for this module. External modules should allocate the needed class + * and return it in the alloc_modparam(). Internal modules do not need to call this function. + * And overloaded function should just alloc the class and return it. + * \return Allocated class. Note that the returned pointer is being cast to module_param, but most + * likely this will be another class that has module_param as a base class. + */ +module_param* module::alloc_modparam() +{ + assert(m_ulFlags & MF_INITIALIZED); + if (m_ulFlags & MF_EXTERNAL) + return (*m_pfnAllocModparam)(); + else + return NULL; +} + +// called to load all exported functions (must be called for any derived load_exports()) +/** Loads the exports associated with a given type of module. This should be the first function + * to be called in load_exports() of derived classes. If a specified exports does not + * exist in a module an exception* is thrown. + * \note Use the MAP_EXPORT macro here to assign together the function name to the + * function address. + */ +void module::load_exports() +{ + MAP_EXPORT(m_hModule, m_pfnGetInfo, "get_info"); + MAP_EXPORT(m_hModule, m_pfnInit, "init"); + MAP_EXPORT(m_hModule, m_pfnUninit, "uninit"); + MAP_EXPORT(m_hModule, m_pfnAllocModparam, "alloc_modparam"); +} + +/** Cleanup function used in uninit() to make sure the module_param stuff + * is freed if needed. Also resets the MF_INITIALIZED flag. + */ +void module::cleanup() +{ + // delete the module parameters/informations if allocated + if (m_pmp) + { + m_pmp->write_config(m_pmid->pcfg); + delete m_pmp; + m_pmp=NULL; + } + + m_ulFlags &= ~MF_INITIALIZED; +} + +///////////////////////////////////////////////////////////////// +/** Constructor - makes a copy of the MODULE_INITDATA structure and + * stores it in the internal member. + */ +module_list::module_list(const MODULE_INITDATA* pData) +{ + m_pmid=pData; +} + +/** Destructor - calls the remove_all(true) to get rid of all modules before + * class is destroyed. Any exception thrown in the remove_all() function is being + * logged to a log file (MODULE_INITDATA) and the exception is deleted. + */ +module_list::~module_list() +{ + try + { + remove_all(true); + } + catch(exception* e) + { + LOG_EXCEPTION(e, m_pmid->plog); + e->del(); + } +} + +#ifndef _WIN32 +/** Helper function for filtering filesystem entries. It allows selecting only the + * filesystem entries that appears to be the proper modules. Function used in linux. + * \param[in] pent - directory entry to process + * \return >0 for the entry to be accepted, 0 if not. + */ +int_t module_list::mod_filter(const struct dirent *pent) +{ + size_t tLen=strlen(pent->d_name), tExtLen=strlen(MODULE_EXT); + if (tLen >= tExtLen && strcmp(pent->d_name+tLen-tExtLen, MODULE_EXT) == 0) + return 1; + else + return 0; +} +#endif + +/** Function scans a specified directory for the files that looks like modules. + * Macro MODULE_EXT specifies the file extension (in format ".ext") used in modules. + * Only modules that types matches (even partially) the specified type are added to + * the list. All the performed operations are logged into the log file. + * There are no exception throws or return values. + * \param[in] pszPath - path to the directory with modules (must be trailed with '\\' or '/' - system dependent) + * \param[in] uiType - types of modules to be added to the list + */ +void module_list::scan(const char_t* pszPath, uint_t uiType) +{ + m_pmid->plog->logi("[module_list] Scanning directory " STRFMT " for external modules of type " ULFMT, pszPath, uiType); + uint_t uiCount=0; // count of modules found + +#ifdef _WIN32 + // create full search path + char_t sz[_MAX_PATH]; + _snprintf(sz, _MAX_PATH, STRFMT "*" STRFMT, pszPath, MODULE_EXT); + size_t tLen=strlen(pszPath); + + WIN32_FIND_DATA wfd; + HANDLE hFind=::FindFirstFile(sz, &wfd); + if (hFind != INVALID_HANDLE_VALUE) + { + BOOL bFound=TRUE; + while (bFound) + { + // append a name to the input path (NOTE: it's a small optimization so it looks like there's something's missing). + strcpy(sz+tLen, wfd.cFileName); +#else + dirent **ppde; + char_t sz[PATH_MAX]; + strcpy(sz, pszPath); + size_t tLen=strlen(pszPath); + + int_t iCnt=scandir(pszPath, &ppde, mod_filter, NULL); + while (iCnt--) + { + strcpy(sz+tLen, ppde[iCnt]->d_name); +#endif + module* pmod=new module(m_pmid, true); + try + { + pmod->open(sz); + + if (pmod->get_type() & uiType) + { + push_back(pmod); + uiCount++; + } + else + delete pmod; // also calls module::close(), but does not throw an exception + } + catch(exception* e) + { + m_pmid->plog->logw("[module_list] Caught an exception while trying to open a module (path=" STRFMT ").Ignoring module.", sz); + LOG_EXCEPTION(e, m_pmid->plog); + + e->del(); + delete pmod; + } +#ifdef _WIN32 + bFound=::FindNextFile(hFind, &wfd); + } + + if (!::FindClose(hFind)) + m_pmid->plog->logd("[module_list] Cannot close a find handle in module::open(), system error " ULFMT ". Ignoring.", GetLastError()); + } + +#else + free(ppde[iCnt]); + } + free(ppde); +#endif + m_pmid->plog->logi("[module_list] Completed scanning for external modules in directory " STRFMT ". Found " ULFMT " modules with type matching " ULFMT, pszPath, uiCount, uiType); +} + +// getting a module from a vector +/** Searches for a module in a list given it's ID. When using this function + * user should fully lock the module_list and before releasing the lock he should + * use module::acquire() to make sure the module won't be unloaded when being used. + * \param[in] mid - module ID to find in the list + * \return Pointer to the module or NULL if module not found. + */ +module* module_list::find(moduleid_t mid) +{ + module* mod; + + m_lock.lock(); + std::map::iterator it=m_mModules.find(mid); + if (it != m_mModules.end()) + mod=(*it).second; + else + mod=NULL; + m_lock.unlock(); + + return mod; +} + +/** Function returns a module at a specified position. When using this function + * user should lock the entire module_list and before releasing lock he should + * use module::acquire() function to ensure the module to remain loaded. + * \param[in] tPos - index of the module to return address of; the position must + * be in range. The debug version of program asserts if range exceeded. + * \return Address of a module. + */ +module* module_list::at(size_t tPos) +{ + assert(tPos < m_vModules.size()); + + m_lock.lock(); + module* mod=m_vModules.at(tPos); + m_lock.unlock(); + + return mod; +} + +// adding a new items (modules) +/** Function inserts a module into the list at the specified position. Module is being + * initialized before insertion (if not already initialized). An exception* is thrown + * if any error occurs. + * \param[in] tPos - position in the list to insert the module at (-1 = at the end) + * \param[in] tModule - address of a module to be inserted into the list + */ +void module_list::insert(size_t tPos, module* tModule) +{ + m_pmid->plog->logd("[module_list] Initializing the module (id=" MODIDXFMT ")", tModule->get_id()); + tModule->init(m_pmid); // can throw an exception + + m_pmid->plog->logd("[module_list] Inserting the module (id=" MODIDXFMT ") to the module list at the position " ULPTRXFMT, tModule->get_id(), tPos); + + m_lock.lock(); + + try + { + std::map::iterator it=m_mModules.find(tModule->get_id()); + if (it != m_mModules.end()) + { + THROW(exception::format("Module with a specified id=" MODIDXFMT " (name: " STRFMT ", version: " STRFMT ", author: " STRFMT ") already exists (name: " STRFMT ", version: " STRFMT ", author: " STRFMT ")", + tModule->get_id(), tModule->get_name(), tModule->get_version(), tModule->get_author(), + (*it).second->get_name(), (*it).second->get_version(), (*it).second->get_author()), + PE_DUPLICATEPLUG, 0, 0); + } + else + { + if (tPos != (size_t)-1) + { + assert(tPos <= m_vModules.size()); + m_vModules.insert(m_vModules.begin()+tPos, tModule); + } + else + m_vModules.push_back(tModule); + + m_mModules.insert(std::pair(tModule->get_id(), tModule)); + } + + m_lock.unlock(); + } + catch(...) + { + m_lock.unlock(); + throw; + } +} + +/** Adds a module at the beginning of the list. Function uses the insert() function. + * \param[in] tModule - address of the module to add + */ +void module_list::push_front(module* tModule) +{ + insert(0, tModule); +} + +/** Adds a module at the end of a list. Function uses the insert() function to perform + * the requested operation. + * \param[in] tModule - address of a module to add + */ +void module_list::push_back(module* tModule) +{ + insert((size_t)-1, tModule); +} + +// repositioning modules in a vector +/** Changes the positions of the 2 modules (given by their ID's) - swaps them. + * \param[in] t1, t2 - module ID's of the modules to be swapped + */ +void module_list::swap(moduleid_t t1, moduleid_t t2) +{ + m_lock.lock(); + std::vector::iterator it1, it2, it; + + // enum through the all modules + if (find_module(t1, t2, &it1, &it2)) + swap(it1, it2); + else + m_pmid->plog->logd("[module_list] Swapping modules failed - one of the modules not found (id1=" MODIDXFMT ", id2=" MODIDXFMT ")", t1, t2); + + m_lock.unlock(); +} + +/** Changes the positions of the 2 modules (given by their positions) - swaps them. + * \param[in] tPos1, tPos2 - positions of the modules to be swapped + */ +void module_list::swap(size_t tPos1, size_t tPos2) +{ + assert(tPos1 <= m_vModules.size() && tPos2 <= m_vModules.size()); + + m_lock.lock(); + swap(m_vModules.begin()+tPos1, m_vModules.begin()+tPos2); + m_lock.unlock(); +} + +/** Moves the module (given by it's ID) to the position given as a second parameter. + * \param[in] tID - ID of a module to move + * \param[in] tNewPos - new position at which the module should appear + */ +void module_list::move(moduleid_t tID, size_t tNewPos) +{ + assert(tNewPos < m_vModules.size()); + + m_lock.lock(); + + std::vector::iterator it; + if (find_module(tID, &it)) + { + module* mod=(*it); + m_vModules.erase(it); + m_vModules.insert(m_vModules.begin()+tNewPos, mod); + } + + m_lock.unlock(); +} + +/** Sorts the modules in order given by the vector passed as the parameter. + * \param[in] vIDs - address of a vector that contains sorted (in the requested way) + * module ID's. + */ +void module_list::sort(std::vector* vIDs) +{ + m_lock.lock(); + + // clear the vector + m_vModules.clear(); + + // and now process the data from map + module* mod; + for (std::vector::iterator it=vIDs->begin();it != vIDs->end();it++) + { + if ( (mod=find(*it)) != NULL_MODULE ) + m_vModules.push_back(mod); + } + + m_lock.unlock(); +} + +/** Function fills the vector given as the parameter with the modules ID's + * with the order as in the current list. + * \param[in] vIDs - address of a vector that will receive the module ID's. + */ +void module_list::get_positions(std::vector* vIDs) +{ + m_lock.lock(); + + for (std::vector::iterator it=m_vModules.begin();it != m_vModules.end();it++) + { + vIDs->push_back((*it)->get_id()); + } + + m_lock.unlock(); +} + +/** Returns the current count of modules contained in the list. + * \return Count of modules. + */ +size_t module_list::size() +{ + m_lock.lock(); + size_t tLen=m_vModules.size(); + m_lock.unlock(); + + return tLen; +} + +// removing +/** Removes a module from a list (given it's ID). It means uninitializing the module + * and then closing it. If the module is being currently used (see module::acquire() and module::release()) + * then it is not removed (except when the bForce flag is specified). In case of error + * the exception is thrown or false is returned. + * \param[in] tID - id of a module to remove + * \param[in] bForce - if true then the module reference count >0 does not block removing. + * \return True if everything went ok, false otherwise. + */ +bool module_list::remove(moduleid_t tID, bool bForce) +{ + // find the tID module iterator + bool bRes; + + m_lock.lock(); + + try + { + std::vector::iterator it; + if (find_module(tID, &it)) + bRes=remove(it, bForce); + else + { + m_pmid->plog->logd("[module_list] Cannot remove module (id=" MODIDXFMT ") - it does not exist", tID); + bRes=false; + } + + m_lock.unlock(); + } + catch(...) + { + m_lock.unlock(); + throw; + } + + return bRes; +} + +/** Removes a module from a list (given it's position). It means uninitializing the module + * and then closing it. If the module is being currently used (see module::acquire() and module::release()) + * then it is not removed (except when the bForce flag is specified). In case of error + * the exception is thrown or false is returned. + * \param[in] tPos - position of a module to remove + * \param[in] bForce - if true then the module reference count >0 does not block removing. + * \return True if everything went ok, false otherwise. + */ +bool module_list::remove(size_t tPos, bool bForce) +{ + assert(tPos <= m_vModules.size()); + + m_lock.lock(); + + bool bRes; + try + { + bRes=remove(m_vModules.begin()+tPos, bForce); + m_lock.unlock(); + } + catch(...) + { + m_lock.unlock(); + throw; + } + + return bRes; +} + +/** Removes all the modules from a list. Depending the bForce parameter either all + * modules are removed or only the unused ones. When error is encountered while removing + * individual modules then it is logged to the log file and removed. + * \param[in] bForce - specifies if the modules should be removed only if they are unused (false) + * or always (true). + */ +void module_list::remove_all(bool bForce) +{ + m_lock.lock(); + std::vector::iterator it=m_vModules.end(); + while (it != m_vModules.begin()) + { + try + { + remove(--it, bForce); + } + catch(exception* e) + { + m_pmid->plog->logd("[module_list] Caught an exception in module_list::remove_all() while removing module from a list.Ignoring."); + LOG_EXCEPTION(e, m_pmid->plog); + e->del(); + } + } + m_lock.unlock(); +} + +////////////////////////////////////// +/** Removes a module from a list (given it's internal iterator). It means uninitializing the module + * and then closing it. If the module is being currently used (see module::acquire() and module::release()) + * then it is not removed (except when the bForce flag is specified). In case of error + * the exception is thrown or false is returned. + * \param[in] it - iterator that specifies position of a module in the internal vector + * \param[in] bForce - if true then the module reference count >0 does not block removing + * \return True if everything went ok, false otherwise. + */ +bool module_list::remove(std::vector::iterator it, bool bForce) +{ + module* mod=(*it); + moduleid_t tid=mod->get_id(); + + m_pmid->plog->logi("[module_list] Trying to remove module (id=" MODIDXFMT ")", tid); + + if (mod->get_refcount() != 0) + { + if (!bForce) + { + m_pmid->plog->logw("[module_list] Cannot remove module (id=" MODIDXFMT ") due to module's reference count=" LFMT, tid, mod->get_refcount()); + return false; // cannot unload + } + else + m_pmid->plog->logw("[module_list] Removing module (id=" MODIDXFMT ") with reference count=" LFMT, tid, mod->get_refcount()); + } + + // uninit&close the module - both can throw an exception + try + { + if (!mod->uninit()) + { + // cannot uninit module + if (!bForce) + { + m_pmid->plog->logw("[module_list] Cannot remove module (id=" MODIDXFMT ") due to uninit problems", tid); + return false; + } + else + m_pmid->plog->logw("[module_list] Removing module (id=" MODIDXFMT ") knowing that module uninit proc failed", tid); + } + } + catch(exception* e) + { + if (!bForce) + throw; // rethrow the exception - will be reported by some other func + else + { + m_pmid->plog->logw("[module_list] Removing module (id=" MODIDXFMT ") knowing that module uninit proc had thrown an exception", tid); + LOG_EXCEPTION(e, m_pmid->plog); + e->del(); + } + } + + // try to close module + try + { + mod->close(); + } + catch(exception* e) + { + if (!bForce) + throw; + else + { + m_pmid->plog->logw("[module_list] Removing module (id=" MODIDXFMT ") knowing that module close proc had thrown an exception", tid); + LOG_EXCEPTION(e, m_pmid->plog); + e->del(); + } + } + + // remove the module from the list + m_vModules.erase(it); + std::map::iterator mit=m_mModules.find(tid); + if (mit != m_mModules.end()) + m_mModules.erase(mit); + + m_pmid->plog->logi("[module_list] Module (id=" MODIDXFMT ") removed successfully", tid); + return true; +} + +/** Changes the placement of the two modules (given by their iterators in the internal vector). + * \param[in] it1, it2 - positions of the modules in the internal vector + */ +void module_list::swap(std::vector::iterator it1, std::vector::iterator it2) +{ + module* mod=(*it1); + (*it1)=(*it2); + (*it2)=mod; +} + +/** Searches for a specified module (by it's ID) and stores the iterator in the iterator + * passed as the parameter. + * \param[in] tID - ID of the module to search for + * \param[out] pit - address of an iterator that is about to receive the module position + * \return True if the module was found, false otherwise. + */ +bool module_list::find_module(moduleid_t tID, std::vector::iterator* pit) +{ + // find the requested module + std::vector::iterator it; + (*pit)=m_vModules.end(); + + for (it=m_vModules.begin();it != m_vModules.end();it++) + { + // check if this is one of the requested modules + if ((*it)->get_id() == tID) + { + (*pit)=it; + break; + } + } + + return ((*pit) != m_vModules.end()); +} + +/** Searches for a specified modules (by their ID's) and stores the iterators in the iterators + * passed as the parameters. + * \param[in] tID1, tID2 - ID's of the modules to search for + * \param[out] pit1, pit2 - address of an iterators that are about to receive the module positions + * \return True if the module was found, false otherwise. + */ +bool module_list::find_module(moduleid_t tID1, moduleid_t tID2, std::vector::iterator* pit1, std::vector::iterator* pit2) +{ + // find the requested module + std::vector::iterator it; + (*pit1)=(*pit2)=m_vModules.end(); + + for (it=m_vModules.begin();it != m_vModules.end();it++) + { + // check if this is one of the requested modules + if ((*it)->get_id() == tID1) + (*pit1)=it; + else if ((*it)->get_id() == tID2) + (*pit2)=it; + } + + return ((*pit1) != m_vModules.end() && (*pit2) != m_vModules.end()); +} + +END_ICPF_NAMESPACE Index: ext/libicpf/src/module.h =================================================================== diff -u -N --- ext/libicpf/src/module.h (revision 0) +++ ext/libicpf/src/module.h (revision e17c80d36eaa0430313e7d1058aa7a301d1510af) @@ -0,0 +1,416 @@ +/*************************************************************************** + * Copyright (C) 2004 by J�zef Starosczyk * + * copyhandler@o2.pl * + * * + * This program 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 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 Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +/** \file module.h + * \brief File contain declaration of the module (and related) classes. + */ + +#ifndef __MODULE_H__ +#define __MODULE_H__ + +#include "libicpf.h" +#include "mutex.h" +#include "cfg.h" +#include "log.h" +#include "file.h" +#include +#include +#include "gen_types.h" + +// inclusion of dirent.h +#if HAVE_DIRENT_H + #include + #define NAMLEN(dirent) strlen((dirent)->d_name) +#else + #define dirent direct + #define NAMLEN(dirent) (dirent)->d_namlen + #if HAVE_SYS_NDIR_H + #include + #endif + #if HAVE_SYS_DIR_H + #include + #endif + #if HAVE_NDIR_H + #include + #endif +#endif + +#ifndef MODULE_EXT + /// File extension to use with modules + #define MODULE_EXT "" +#endif + +BEGIN_ICPF_NAMESPACE + +/// NULL module ID +#define NULL_MODULE 0x00000000 + +// module types +/// Module type NONE +#define MT_NONE 0x00000000 +/// Module type ALL +#define MT_ALL 0xffffffff + +// module flags +/// Module flag NONE +#define MF_NONE 0x00000000 +/// The module is an external one +#define MF_EXTERNAL 0x00000001 + +/** \brief States that the init() func for the module has been successfully called. + * + * If the flag is set it means that the module function init() has been called succesfully + * and the uninit() call may be executed. Flag used to make sure there will be only one + * subsequent call to init() and uninit() functions in the external module even if they + * will be called more than once in a program. + */ +#define MF_INITIALIZED 0x00000002 + +/// Type describes the module id. +typedef ulonglong_t moduleid_t; +/// Module ID formatting text to be used in formatting routines +#define MODIDFMT ULLFMT +/// Module ID (hex) formatting text to be used in formatting routines +#define MODIDXFMT ULLXFMT + +/** Makes a module ID from a given parameters. + * \param[in] internal - bool that specifies if this is the internal module + * \param[in] type - module type(could be a bitmask) - only the lower 28 bits will be used + * \param[in] unique_id - 32-bit unique id (should be randomly generated) + */ +#define MAKE_MODID(internal,type,unique_id)\ + ((internal ? 0ULL : 0x8000000000000000ULL) | (((ulonglong_t)type & 0x0fffffff) << 32) | unique_id) + +/** \brief Class for managing the parameters of a module. + * + * Class provides support for a module parameters. It could be used outside the module (ie. after + * module destruction) to store module settings to a file or to configuration. + * \todo This class needs some more clarification - how to use it, the purpose, ... + */ +class LIBICPF_API module_param +{ +public: +/** \name Construction/destruction */ +/**@{*/ + module_param(); ///< Standard constructor + virtual ~module_param(); ///< Standard destructor +/**@}*/ + +/** \name Locking/unlocking */ +/**@{*/ + void lock(); ///< Locks the class (gets exclusive ownership of this object) + void unlock(); ///< Unlocks the class (releases the ownership) +/**@}*/ + +/** \name Informations */ +/**@*/ + moduleid_t get_moduleid() const; ///< Returns a module id associated with this class +/**@}*/ + +/** \name Configuration support */ +/**@{*/ + virtual void read_config(config* pcfg); ///< Reads the configuration properties from a config object + virtual void write_config(config* pcfg); ///< Writes the internal properties to the config object + virtual void register_properties(config* pcfg); ///< Registers properties for use with the config object +/**@}*/ + +/** \name Serialization support */ +/**@{*/ + virtual void store(file& ser); ///< Stores the internal properties in the serialization object (file) + virtual void load(file& ser); ///< Loads the internal properties from a serialization object (file) +/**@}*/ + +protected: + moduleid_t m_midModuleID; ///< ID of a module that owns this parameters + uint_t m_uiPropStart; ///< ID of the first registered property (see register_properties()) + mutex m_lock; ///< Access lock for performing safe multi-threaded operations +}; + +/** \brief Class handling lists of module_param's. + * + * Class handles the management of lists of module_param classes. One module can have only + * one module_param (or derived) class associated with it. + */ +class LIBICPF_API modparam_list +{ +public: +/** \name Construction/destruction */ +/**@{*/ + modparam_list(); ///< Standard constructor + ~modparam_list(); ///< Standard destructor +/**@}*/ + +/** \name Standard operations */ +/**@{*/ + void insert(module_param* pEntry); ///< Inserts a new module_param to this container + bool remove(moduleid_t tEntry, bool bDelete=true); ///< Removes a module_param associated with a given module id + void clear(bool bDelete=true); ///< Removes all the entries from the list + module_param* find(moduleid_t mid); ///< Searches for a module_param associated with a given module id +/**@}*/ + +/** \name Configuration support */ +/**@{*/ + void read_config(config* pcfg); ///< Reads the configuration properties from a config object + void write_config(config* pcfg); ///< Writes the internal properties to the config object + void register_properties(config* pcfg); ///< Registers properties for use with the config object +/**@}*/ + +/** \name Serialization support */ +/**@{*/ + void store(file& ser); ///< Stores the internal properties in the serialization object (file) + void load(file& ser); ///< Loads the internal properties from a serialization object (file) +/**@}*/ + +protected: + std::map m_mMods; ///< Internal map of module parameters + mutex m_lock; ///< A locking mutex +}; + +/** \brief Module information struct + * + * Structure contains some fields used to identify a module (module name, + * id, type, author information and so on). + */ +struct MODULE_INFO +{ + uint_t uiInfoLen; ///< Count of bytes contained in this struct (filled by plugin) + char_t szAuthor[128]; ///< Author's full name + char_t szName[128]; ///< Plugin name + char_t szVersion[32]; ///< Version string + moduleid_t midID; ///< 64-bit module ID + uint_t uiType; ///< Type of a module (app-dependent) +}; + +/** \brief Structure with initialization data for a module + * + * Structure contains init parameters passed into the constructor and + * the init() function of a module and module_list class. + */ +struct MODULE_INITDATA +{ + config *pcfg; ///< Global configuration object + log_file *plog; ///< Log file object to perform logging to +}; + +// external functions typedefs +/// Prototype of the external module get_info() function +typedef void(*PFNMGETINFO)(MODULE_INFO*); +/// Prototype of the external module init() function +typedef bool(*PFNMINIT)(const MODULE_INITDATA*, module_param**); +/// Prototype of the external module uninit() function +typedef bool(*PFNMUNINIT)(module_param**); +/// Allocates a new module_param-derived parameter +typedef module_param*(*PFNALLOCMODPARAM)(); + +// module handle definition +#ifdef _WIN32 + /// System dependent module handle definition + #define MHANDLE HMODULE +#else + /// System dependent module handle definition + #define MHANDLE ptr_t +#endif + +// helper for loading exports +#ifdef _WIN32 + /** \brief Maps a module exported function to some class member + * + * Macro used to simplify loading function exported from an external + * modules (see module::load_exports()). + * \param[in] module - external module handle + * \param[in] var - variable that will receive the function address + * \param[in] fn_name - string with the function name to get addres of + * \note Macro throws an exception if the export cannot be loaded. + */ + #define MAP_EXPORT(module,var,fn_name)\ + (FARPROC&)var=::GetProcAddress(module, fn_name);\ + if (var == NULL)\ + THROW(exception::format("Cannot load an export " STRFMT " from the external module (handle " PTRFMT ")", fn_name, module), PE_CALLNOTIMPLEMENTED, GetLastError(), 0); +#else + /** \brief Maps a module exported function to some class member + * + * Macro used to simplify loading function exported from an external + * modules (see module::load_exports()). + * \param[in] module - external module handle + * \param[in] var - variable that will receive the function address + * \param[in] fn_name - string with the function name to get addres of + * \note Macro throws an exception if the export cannot be loaded. + */ + #define MAP_EXPORT(module,var,fn_name)\ + *((ptr_t*)&var)=dlsym(module, fn_name);\ + if (var == NULL)\ + THROW(exception::format("Cannot load an export " STRFMT " from the external module - " STRFMT " (handle " PTRFMT ")", fn_name, dlerror(), module), PE_CALLNOTIMPLEMENTED, 0, 0); +#endif + +/** \brief Module handling class + * + * This class allows handling of the internal and external modules. This is a base class + * from which should be derived any other module classes that handle different types + * of modules. + */ +class LIBICPF_API module +{ +public: +/** \name Construction/destruction */ +/**@{*/ + module(const MODULE_INITDATA* pData, uint_t uiFlags=MF_EXTERNAL); ///< Standard constructor + virtual ~module(); ///< Standard destructor +/**@}*/ + +/** \name External modules support */ +/**@{*/ + void open(const char_t* pszPath); ///< Opens an external module (file) + void close(bool bFullDestruct=false); ///< Closes an external module (uninitializes if needed) +/**@}*/ + +/** \name Module information */ +/**@{*/ + /// Retrieves the module information directly from the module + void get_info(MODULE_INFO* pInfo); + /// Returns an address of the cached module information structure + const MODULE_INFO* get_info() { return &m_mi; }; + /// Returns module ID from the cached information struct + moduleid_t get_id() const { return m_mi.midID; }; + /// Returns author string address from the cached information struct + const char_t* get_author() const { return m_mi.szAuthor; }; + /// Returns version string address from the cached information struct + const char_t* get_version() const { return m_mi.szVersion; }; + /// Returns module name string address from the cached information struct + const char_t* get_name() const { return m_mi.szName; }; + /// Returns module type from the cached information struct + uint_t get_type() const { return m_mi.uiType; }; +/**@}*/ + +/** \name Module parameters */ +/**@{*/ + virtual module_param* alloc_modparam(); ///< Allocates a module_param (or derived) class - should be overloaded. +/**@}*/ + +/** \name Initialization/uninitialization */ +/**@{*/ + virtual bool init(const MODULE_INITDATA* pData); ///< Initializes the module (if not initialized yet) + virtual bool uninit(); ///< Uninitializes the module (if not uninitialized yet) +/**@}*/ + +/** \name Reference counting */ +/**@{*/ + /// Retrieves the current reference count + int_t get_refcount() const { return m_lRefCount; }; + /// Increases the reference count + void acquire() { ++m_lRefCount; }; + /// Decreases the reference count + int_t release() { return --m_lRefCount; }; +/**@}*/ + +protected: + /// Loads all needed exports from an external module + virtual void load_exports(); + + /// Cleans up the internal stuff + void cleanup(); + +protected: + const MODULE_INITDATA* m_pmid; ///< Module data struct ptr passed in the constructor + module_param* m_pmp; ///< Pointer to a module parameters class (managed by a module). + + MODULE_INFO m_mi; ///< Module information struct (cached for external modules, filled in constructor for internal) + + int_t m_lRefCount; ///< Current reference count + + // external stuff + uint_t m_ulFlags; ///< Module flags (MF_*) + char_t* m_pszPath; ///< Full file path for an external module + MHANDLE m_hModule; ///< Handle to the loaded external module (NULL_MODULE if not loaded) + PFNMGETINFO m_pfnGetInfo; ///< Pointer to the module's get_info() function + PFNMINIT m_pfnInit; ///< Pointer to the module's init() function + PFNMUNINIT m_pfnUninit; ///< Pointer to the module's uninit() function + PFNALLOCMODPARAM m_pfnAllocModparam; ///< Pointer to the module's alloc_modparam() function +}; + +/** \brief Module management class + * + * Class was designed to allow easier handling of a module lists. Provides + * a basic operations on a list of modules (searching, inserting, removing, ...). + * Should be a base for any module management class. + */ +class LIBICPF_API module_list +{ +public: +/** \name Construction/destruction */ +/**@{*/ + module_list(const MODULE_INITDATA* pData); ///< Standard constructor + ~module_list(); ///< Standard destructor +/**@}*/ + +/** \name Adding/removing */ +/**@{*/ + void scan(const char_t* pszPath, uint_t uiType=MT_ALL); ///< Scans a directory for some modules + + // adding a new items (modules) + void insert(size_t tPos, module* tModule); ///< Inserts a module at a specified position + void push_front(module* tModule); ///< Adds a module at the beginning of a list + void push_back(module* tModule); ///< Adds a module at the end of a list + + // removing + bool remove(moduleid_t tID, bool bForce=false); ///< Removes a module from the list by its ID + bool remove(size_t tPos, bool bForce=false); ///< Removes a module from the list by its position + void remove_all(bool bForce=false); ///< Removes all the modules from the list +/**@}*/ + +/** \name Searching */ +/**@{*/ + module* find(moduleid_t mid); ///< Searches a list for the module with the specified ID + module* at(size_t tPos); ///< Gets the module at a specified position on the list +/**@}*/ + +/** \name Module repositioning */ +/**@{*/ + void swap(moduleid_t t1, moduleid_t t2); ///< Swaps two modules positions by their ID's + void swap(size_t tPos1, size_t tPos2); ///< Swaps two modules positions by their positions + void move(moduleid_t tID, size_t tNewPos); ///< Moves the specified module to a new position + void sort(std::vector* vIDs); ///< Sorts the modules using a module id vector + void get_positions(std::vector* vIDs); ///< Retrieves the current modules positions +/**@}*/ + +/** \name Other */ +/**@{*/ + size_t size(); ///< Retrieves a count of modules in a list +/**@}*/ + +protected: + void swap(std::vector::iterator it1, std::vector::iterator it2); ///< Swaps two modules positions by their vector iterators + bool find_module(moduleid_t tID, std::vector::iterator* pit); ///< Searches for the module by it's ID and returns an iterator + bool find_module(moduleid_t tID1, moduleid_t tID2, std::vector::iterator* pit1, std::vector::iterator* pit2); ///< Searches for two modules by their ID's - returns iterators + bool remove(std::vector::iterator it, bool bForce=false); ///< Removes a module from this list given the vector iterator + +#ifndef _WIN32 + static int_t mod_filter(const struct dirent *pent); ///< Helper function to filter directory entries under linux +#endif + +protected: + std::vector m_vModules; ///< Vector with the loaded modules (used to make this class preserve the module positions) + std::map m_mModules; ///< Mapping module id->module pointer + const MODULE_INITDATA* m_pmid; ///< Module initialization data (used for module::init() functions and/or constructors) + + mutex m_lock; ///< Thread-safe access guarantee +}; + +END_ICPF_NAMESPACE + +#endif Index: ext/libicpf/src/mutex.h =================================================================== diff -u -N --- ext/libicpf/src/mutex.h (revision 0) +++ ext/libicpf/src/mutex.h (revision e17c80d36eaa0430313e7d1058aa7a301d1510af) @@ -0,0 +1,126 @@ +/*************************************************************************** + * Copyright (C) 2004 by J�zef Starosczyk * + * copyhandler@o2.pl * + * * + * This program 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 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 Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +/** \file mutex.h + * \brief Contains mutex class for thread safe access. + */ +#ifndef __MUTEX_H__ +#define __MUTEX_H__ + +#ifdef _WIN32 + #include +#else + #include +#endif + +#include "libicpf.h" +#include "gen_types.h" + +BEGIN_ICPF_NAMESPACE + +/** \brief Class provides the locking and unlocking capabilities for use with threads. + * + * Class is a simple wrapper over the system related thread locking functions. In linux + * those functions are pthread_mutex_* and in windoze the functions related to CRITICAL_SECTION + * structure. + */ +class LIBICPF_API mutex +{ +public: +/** \name Construction/destruction */ +/**@{*/ + /** \brief Standard constructor + */ + mutex() + { +#ifdef _WIN32 + ::InitializeCriticalSection(&m_cs); +#else + pthread_mutexattr_t mta; + pthread_mutexattr_init(&mta); +//#warning Recursive mutexes are disabled; Make sure you use them the right way. + pthread_mutexattr_settype(&mta, PTHREAD_MUTEX_RECURSIVE_NP); + pthread_mutex_init(&m_mutex, &mta); + + pthread_mutexattr_destroy(&mta); +#endif + }; + + /** \brief Standard destructor + */ + ~mutex() + { +#ifdef _WIN32 + ::DeleteCriticalSection(&m_cs); +#else + pthread_mutex_destroy(&m_mutex); +#endif + }; +/**@}*/ + + // standard locking +/** \name Locking/unlocking */ +/**@{*/ + + /** \brief Locks access to some part of code for the current thread + * + * Locks access to some code using the platform specific functions. + * \return True if succeeded or false if not. + * \note The call under windows always return true. + */ + bool lock() + { +#ifdef _WIN32 + ::EnterCriticalSection(&m_cs); + return true; +#else + return pthread_mutex_lock(&m_mutex) == 0; +#endif + }; + + /** \brief Unlock access to some locked part of code + * + * Unlocks access to some code using the platform specific functions. + * \return True if succeeded or false if not. + * \note The call under windows always return true. + */ + bool unlock() + { +#ifdef _WIN32 + ::LeaveCriticalSection(&m_cs); + return true; +#else + return pthread_mutex_unlock(&m_mutex) == 0; // return 0 on success +#endif + }; +/**@}*/ + +protected: +#ifdef _WIN32 + /// Underlying windows locking structure + CRITICAL_SECTION m_cs; +#else + /// Underlying linux locking structure/handle + pthread_mutex_t m_mutex; +#endif +}; + +END_ICPF_NAMESPACE + +#endif Index: ext/libicpf/src/rijndael-alg-fst.c =================================================================== diff -u -N --- ext/libicpf/src/rijndael-alg-fst.c (revision 0) +++ ext/libicpf/src/rijndael-alg-fst.c (revision e17c80d36eaa0430313e7d1058aa7a301d1510af) @@ -0,0 +1,1402 @@ +/** + * rijndael-alg-fst.c + * + * @version 3.0 (December 2000) + * + * Optimised ANSI C code for the Rijndael cipher (now AES) + * + * @author Vincent Rijmen + * @author Antoon Bosselaers + * @author Paulo Barreto + * + * This code is hereby placed in the public domain. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''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 AUTHORS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include + +#include + + +#include "rijndael-alg-fst.h" + +/* +Te0[x] = S [x].[02, 01, 01, 03]; +Te1[x] = S [x].[03, 02, 01, 01]; +Te2[x] = S [x].[01, 03, 02, 01]; +Te3[x] = S [x].[01, 01, 03, 02]; +Te4[x] = S [x].[01, 01, 01, 01]; + +Td0[x] = Si[x].[0e, 09, 0d, 0b]; +Td1[x] = Si[x].[0b, 0e, 09, 0d]; +Td2[x] = Si[x].[0d, 0b, 0e, 09]; +Td3[x] = Si[x].[09, 0d, 0b, 0e]; +Td4[x] = Si[x].[01, 01, 01, 01]; +*/ + +static const u32 Te0[256] = { + 0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU, + 0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U, + 0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU, + 0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU, + 0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U, + 0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU, + 0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU, + 0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU, + 0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU, + 0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU, + 0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U, + 0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU, + 0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU, + 0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U, + 0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU, + 0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU, + 0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU, + 0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU, + 0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU, + 0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U, + 0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU, + 0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU, + 0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU, + 0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU, + 0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U, + 0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U, + 0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U, + 0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U, + 0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU, + 0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U, + 0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U, + 0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU, + 0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU, + 0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U, + 0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U, + 0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U, + 0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU, + 0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U, + 0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU, + 0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U, + 0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU, + 0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U, + 0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U, + 0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU, + 0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U, + 0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U, + 0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U, + 0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U, + 0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U, + 0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U, + 0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U, + 0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U, + 0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU, + 0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U, + 0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U, + 0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U, + 0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U, + 0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U, + 0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U, + 0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU, + 0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U, + 0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U, + 0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U, + 0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU, +}; +static const u32 Te1[256] = { + 0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU, + 0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U, + 0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU, + 0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U, + 0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU, + 0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U, + 0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU, + 0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U, + 0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U, + 0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU, + 0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U, + 0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U, + 0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U, + 0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU, + 0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U, + 0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U, + 0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU, + 0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U, + 0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U, + 0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U, + 0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU, + 0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU, + 0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U, + 0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU, + 0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU, + 0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U, + 0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU, + 0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U, + 0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU, + 0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U, + 0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U, + 0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U, + 0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU, + 0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U, + 0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU, + 0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U, + 0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU, + 0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U, + 0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U, + 0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU, + 0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU, + 0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU, + 0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U, + 0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U, + 0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU, + 0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U, + 0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU, + 0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U, + 0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU, + 0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U, + 0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU, + 0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU, + 0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U, + 0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU, + 0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U, + 0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU, + 0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U, + 0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U, + 0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U, + 0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU, + 0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU, + 0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U, + 0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU, + 0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U, +}; +static const u32 Te2[256] = { + 0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU, + 0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U, + 0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU, + 0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U, + 0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU, + 0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U, + 0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU, + 0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U, + 0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U, + 0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU, + 0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U, + 0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U, + 0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U, + 0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU, + 0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U, + 0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U, + 0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU, + 0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U, + 0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U, + 0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U, + 0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU, + 0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU, + 0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U, + 0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU, + 0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU, + 0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U, + 0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU, + 0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U, + 0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU, + 0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U, + 0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U, + 0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U, + 0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU, + 0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U, + 0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU, + 0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U, + 0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU, + 0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U, + 0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U, + 0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU, + 0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU, + 0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU, + 0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U, + 0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U, + 0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU, + 0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U, + 0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU, + 0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U, + 0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU, + 0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U, + 0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU, + 0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU, + 0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U, + 0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU, + 0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U, + 0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU, + 0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U, + 0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U, + 0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U, + 0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU, + 0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU, + 0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U, + 0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU, + 0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U, +}; +static const u32 Te3[256] = { + + 0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U, + 0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U, + 0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U, + 0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU, + 0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU, + 0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU, + 0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U, + 0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU, + 0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU, + 0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U, + 0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U, + 0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU, + 0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU, + 0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU, + 0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU, + 0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU, + 0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U, + 0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU, + 0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU, + 0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U, + 0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U, + 0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U, + 0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U, + 0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U, + 0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU, + 0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U, + 0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU, + 0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU, + 0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U, + 0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U, + 0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U, + 0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU, + 0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U, + 0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU, + 0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU, + 0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U, + 0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U, + 0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU, + 0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U, + 0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU, + 0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U, + 0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U, + 0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U, + 0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U, + 0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU, + 0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U, + 0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU, + 0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U, + 0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU, + 0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U, + 0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU, + 0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU, + 0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU, + 0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU, + 0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U, + 0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U, + 0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U, + 0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U, + 0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U, + 0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U, + 0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU, + 0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U, + 0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU, + 0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU, +}; +static const u32 Te4[256] = { + 0x63636363U, 0x7c7c7c7cU, 0x77777777U, 0x7b7b7b7bU, + 0xf2f2f2f2U, 0x6b6b6b6bU, 0x6f6f6f6fU, 0xc5c5c5c5U, + 0x30303030U, 0x01010101U, 0x67676767U, 0x2b2b2b2bU, + 0xfefefefeU, 0xd7d7d7d7U, 0xababababU, 0x76767676U, + 0xcacacacaU, 0x82828282U, 0xc9c9c9c9U, 0x7d7d7d7dU, + 0xfafafafaU, 0x59595959U, 0x47474747U, 0xf0f0f0f0U, + 0xadadadadU, 0xd4d4d4d4U, 0xa2a2a2a2U, 0xafafafafU, + 0x9c9c9c9cU, 0xa4a4a4a4U, 0x72727272U, 0xc0c0c0c0U, + 0xb7b7b7b7U, 0xfdfdfdfdU, 0x93939393U, 0x26262626U, + 0x36363636U, 0x3f3f3f3fU, 0xf7f7f7f7U, 0xccccccccU, + 0x34343434U, 0xa5a5a5a5U, 0xe5e5e5e5U, 0xf1f1f1f1U, + 0x71717171U, 0xd8d8d8d8U, 0x31313131U, 0x15151515U, + 0x04040404U, 0xc7c7c7c7U, 0x23232323U, 0xc3c3c3c3U, + 0x18181818U, 0x96969696U, 0x05050505U, 0x9a9a9a9aU, + 0x07070707U, 0x12121212U, 0x80808080U, 0xe2e2e2e2U, + 0xebebebebU, 0x27272727U, 0xb2b2b2b2U, 0x75757575U, + 0x09090909U, 0x83838383U, 0x2c2c2c2cU, 0x1a1a1a1aU, + 0x1b1b1b1bU, 0x6e6e6e6eU, 0x5a5a5a5aU, 0xa0a0a0a0U, + 0x52525252U, 0x3b3b3b3bU, 0xd6d6d6d6U, 0xb3b3b3b3U, + 0x29292929U, 0xe3e3e3e3U, 0x2f2f2f2fU, 0x84848484U, + 0x53535353U, 0xd1d1d1d1U, 0x00000000U, 0xededededU, + 0x20202020U, 0xfcfcfcfcU, 0xb1b1b1b1U, 0x5b5b5b5bU, + 0x6a6a6a6aU, 0xcbcbcbcbU, 0xbebebebeU, 0x39393939U, + 0x4a4a4a4aU, 0x4c4c4c4cU, 0x58585858U, 0xcfcfcfcfU, + 0xd0d0d0d0U, 0xefefefefU, 0xaaaaaaaaU, 0xfbfbfbfbU, + 0x43434343U, 0x4d4d4d4dU, 0x33333333U, 0x85858585U, + 0x45454545U, 0xf9f9f9f9U, 0x02020202U, 0x7f7f7f7fU, + 0x50505050U, 0x3c3c3c3cU, 0x9f9f9f9fU, 0xa8a8a8a8U, + 0x51515151U, 0xa3a3a3a3U, 0x40404040U, 0x8f8f8f8fU, + 0x92929292U, 0x9d9d9d9dU, 0x38383838U, 0xf5f5f5f5U, + 0xbcbcbcbcU, 0xb6b6b6b6U, 0xdadadadaU, 0x21212121U, + 0x10101010U, 0xffffffffU, 0xf3f3f3f3U, 0xd2d2d2d2U, + 0xcdcdcdcdU, 0x0c0c0c0cU, 0x13131313U, 0xececececU, + 0x5f5f5f5fU, 0x97979797U, 0x44444444U, 0x17171717U, + 0xc4c4c4c4U, 0xa7a7a7a7U, 0x7e7e7e7eU, 0x3d3d3d3dU, + 0x64646464U, 0x5d5d5d5dU, 0x19191919U, 0x73737373U, + 0x60606060U, 0x81818181U, 0x4f4f4f4fU, 0xdcdcdcdcU, + 0x22222222U, 0x2a2a2a2aU, 0x90909090U, 0x88888888U, + 0x46464646U, 0xeeeeeeeeU, 0xb8b8b8b8U, 0x14141414U, + 0xdedededeU, 0x5e5e5e5eU, 0x0b0b0b0bU, 0xdbdbdbdbU, + 0xe0e0e0e0U, 0x32323232U, 0x3a3a3a3aU, 0x0a0a0a0aU, + 0x49494949U, 0x06060606U, 0x24242424U, 0x5c5c5c5cU, + 0xc2c2c2c2U, 0xd3d3d3d3U, 0xacacacacU, 0x62626262U, + 0x91919191U, 0x95959595U, 0xe4e4e4e4U, 0x79797979U, + 0xe7e7e7e7U, 0xc8c8c8c8U, 0x37373737U, 0x6d6d6d6dU, + 0x8d8d8d8dU, 0xd5d5d5d5U, 0x4e4e4e4eU, 0xa9a9a9a9U, + 0x6c6c6c6cU, 0x56565656U, 0xf4f4f4f4U, 0xeaeaeaeaU, + 0x65656565U, 0x7a7a7a7aU, 0xaeaeaeaeU, 0x08080808U, + 0xbabababaU, 0x78787878U, 0x25252525U, 0x2e2e2e2eU, + 0x1c1c1c1cU, 0xa6a6a6a6U, 0xb4b4b4b4U, 0xc6c6c6c6U, + 0xe8e8e8e8U, 0xddddddddU, 0x74747474U, 0x1f1f1f1fU, + 0x4b4b4b4bU, 0xbdbdbdbdU, 0x8b8b8b8bU, 0x8a8a8a8aU, + 0x70707070U, 0x3e3e3e3eU, 0xb5b5b5b5U, 0x66666666U, + 0x48484848U, 0x03030303U, 0xf6f6f6f6U, 0x0e0e0e0eU, + 0x61616161U, 0x35353535U, 0x57575757U, 0xb9b9b9b9U, + 0x86868686U, 0xc1c1c1c1U, 0x1d1d1d1dU, 0x9e9e9e9eU, + 0xe1e1e1e1U, 0xf8f8f8f8U, 0x98989898U, 0x11111111U, + 0x69696969U, 0xd9d9d9d9U, 0x8e8e8e8eU, 0x94949494U, + 0x9b9b9b9bU, 0x1e1e1e1eU, 0x87878787U, 0xe9e9e9e9U, + 0xcecececeU, 0x55555555U, 0x28282828U, 0xdfdfdfdfU, + 0x8c8c8c8cU, 0xa1a1a1a1U, 0x89898989U, 0x0d0d0d0dU, + 0xbfbfbfbfU, 0xe6e6e6e6U, 0x42424242U, 0x68686868U, + 0x41414141U, 0x99999999U, 0x2d2d2d2dU, 0x0f0f0f0fU, + 0xb0b0b0b0U, 0x54545454U, 0xbbbbbbbbU, 0x16161616U, +}; +static const u32 Td0[256] = { + 0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U, + 0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U, + 0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U, + 0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU, + 0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U, + 0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U, + 0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU, + 0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U, + 0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU, + 0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U, + 0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U, + 0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U, + 0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U, + 0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU, + 0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U, + 0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU, + 0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U, + 0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU, + 0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U, + 0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U, + 0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U, + 0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU, + 0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U, + 0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU, + 0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U, + 0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU, + 0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U, + 0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU, + 0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU, + 0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U, + 0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU, + 0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U, + 0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU, + 0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U, + 0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U, + 0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U, + 0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU, + 0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U, + 0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U, + 0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU, + 0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U, + 0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U, + 0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U, + 0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U, + 0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U, + 0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU, + 0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U, + 0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U, + 0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U, + 0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U, + 0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U, + 0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU, + 0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU, + 0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU, + 0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU, + 0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U, + 0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U, + 0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU, + 0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU, + 0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U, + 0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU, + 0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U, + 0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U, + 0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U, +}; +static const u32 Td1[256] = { + 0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU, + 0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U, + 0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU, + 0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, 0x8fb562a3U, + 0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U, + 0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U, + 0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U, + 0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U, + 0x6a75c289U, 0x78f48e79U, 0x6b99583eU, 0xdd27b971U, + 0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU, + 0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU, + 0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU, + 0x58704868U, 0x198f45fdU, 0x8794de6cU, 0xb7527bf8U, + 0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU, + 0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U, + 0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U, + 0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U, + 0xcd65daf4U, 0xd50605beU, 0x1fd13462U, 0x8ac4a6feU, + 0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU, + 0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U, + 0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU, + 0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U, + 0x241998fbU, 0x97d6bde9U, 0xcc894043U, 0x7767d99eU, + 0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU, + 0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U, + 0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U, + 0xfbfd0effU, 0x560f8538U, 0x1e3daed5U, 0x27362d39U, + 0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU, + 0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U, + 0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU, + 0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U, + 0x0b0e090dU, 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U, + 0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U, + 0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU, + 0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U, + 0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U, + 0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U, + 0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U, + 0x6c2bb316U, 0x99a970b9U, 0xfa119448U, 0x2247e964U, + 0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U, + 0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU, + 0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU, + 0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U, + 0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, 0xf582c3afU, + 0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U, + 0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU, + 0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU, + 0x65e6956eU, 0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U, + 0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU, + 0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U, + 0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U, + 0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U, + 0x8d764dd6U, 0x4d43efb0U, 0x54ccaa4dU, 0xdfe49604U, + 0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U, + 0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U, + 0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U, + 0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU, + 0xeecea927U, 0x35b761c9U, 0xede11ce5U, 0x3c7a47b1U, + 0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U, + 0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU, + 0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U, + 0x72161dc3U, 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U, + 0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U, + 0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U, +}; +static const u32 Td2[256] = { + 0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U, + 0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U, + 0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U, + 0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, 0xa38fb562U, + 0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU, + 0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U, + 0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U, + 0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U, + 0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, 0x71dd27b9U, + 0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU, + 0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U, + 0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U, + 0x68587048U, 0xfd198f45U, 0x6c8794deU, 0xf8b7527bU, + 0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U, + 0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U, + 0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U, + 0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U, + 0xf4cd65daU, 0xbed50605U, 0x621fd134U, 0xfe8ac4a6U, + 0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U, + 0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU, + + 0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U, + 0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U, + 0xfb241998U, 0xe997d6bdU, 0x43cc8940U, 0x9e7767d9U, + 0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U, + 0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U, + 0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU, + 0xfffbfd0eU, 0x38560f85U, 0xd51e3daeU, 0x3927362dU, + 0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U, + 0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU, + 0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U, + 0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU, + 0x0d0b0e09U, 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU, + 0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU, + 0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU, + 0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U, + 0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U, + 0x247d854aU, 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U, + 0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U, + 0x166c2bb3U, 0xb999a970U, 0x48fa1194U, 0x642247e9U, + 0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U, + 0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U, + 0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU, + 0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU, + 0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, 0xaff582c3U, + 0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U, + 0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU, + 0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU, + 0x6e65e695U, 0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U, + 0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U, + 0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U, + 0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U, + 0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U, + 0xd68d764dU, 0xb04d43efU, 0x4d54ccaaU, 0x04dfe496U, + 0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U, + 0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU, + 0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U, + 0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U, + 0x27eecea9U, 0xc935b761U, 0xe5ede11cU, 0xb13c7a47U, + 0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U, + 0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U, + 0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U, + 0xc372161dU, 0x250cbce2U, 0x498b283cU, 0x9541ff0dU, + 0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U, + 0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U, +}; +static const u32 Td3[256] = { + 0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU, + 0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU, + 0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U, + 0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, 0x62a38fb5U, + 0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU, + 0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU, + 0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U, + 0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU, + 0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, 0xb971dd27U, + 0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU, + 0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U, + 0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U, + 0x48685870U, 0x45fd198fU, 0xde6c8794U, 0x7bf8b752U, + 0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U, + 0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U, + 0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU, + 0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU, + 0xdaf4cd65U, 0x05bed506U, 0x34621fd1U, 0xa6fe8ac4U, + 0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U, + 0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU, + 0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU, + 0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U, + 0x98fb2419U, 0xbde997d6U, 0x4043cc89U, 0xd99e7767U, + 0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U, + 0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U, + 0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU, + 0x0efffbfdU, 0x8538560fU, 0xaed51e3dU, 0x2d392736U, + 0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U, + 0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU, + 0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU, + 0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U, + 0x090d0b0eU, 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U, + 0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U, + 0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU, + 0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U, + 0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U, + 0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U, + 0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U, + 0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, 0xe9642247U, + 0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U, + 0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U, + 0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU, + 0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U, + 0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, 0xc3aff582U, + 0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU, + 0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU, + 0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U, + 0x956e65e6U, 0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU, + 0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U, + 0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U, + 0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U, + 0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U, + 0x4dd68d76U, 0xefb04d43U, 0xaa4d54ccU, 0x9604dfe4U, + 0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U, + 0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU, + 0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU, + 0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU, + 0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U, 0x47b13c7aU, + 0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U, + 0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U, + 0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U, + 0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU, + 0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U, + 0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U, +}; +static const u32 Td4[256] = { + 0x52525252U, 0x09090909U, 0x6a6a6a6aU, 0xd5d5d5d5U, + 0x30303030U, 0x36363636U, 0xa5a5a5a5U, 0x38383838U, + 0xbfbfbfbfU, 0x40404040U, 0xa3a3a3a3U, 0x9e9e9e9eU, + 0x81818181U, 0xf3f3f3f3U, 0xd7d7d7d7U, 0xfbfbfbfbU, + 0x7c7c7c7cU, 0xe3e3e3e3U, 0x39393939U, 0x82828282U, + 0x9b9b9b9bU, 0x2f2f2f2fU, 0xffffffffU, 0x87878787U, + 0x34343434U, 0x8e8e8e8eU, 0x43434343U, 0x44444444U, + 0xc4c4c4c4U, 0xdedededeU, 0xe9e9e9e9U, 0xcbcbcbcbU, + 0x54545454U, 0x7b7b7b7bU, 0x94949494U, 0x32323232U, + 0xa6a6a6a6U, 0xc2c2c2c2U, 0x23232323U, 0x3d3d3d3dU, + 0xeeeeeeeeU, 0x4c4c4c4cU, 0x95959595U, 0x0b0b0b0bU, + 0x42424242U, 0xfafafafaU, 0xc3c3c3c3U, 0x4e4e4e4eU, + 0x08080808U, 0x2e2e2e2eU, 0xa1a1a1a1U, 0x66666666U, + 0x28282828U, 0xd9d9d9d9U, 0x24242424U, 0xb2b2b2b2U, + 0x76767676U, 0x5b5b5b5bU, 0xa2a2a2a2U, 0x49494949U, + 0x6d6d6d6dU, 0x8b8b8b8bU, 0xd1d1d1d1U, 0x25252525U, + 0x72727272U, 0xf8f8f8f8U, 0xf6f6f6f6U, 0x64646464U, + 0x86868686U, 0x68686868U, 0x98989898U, 0x16161616U, + 0xd4d4d4d4U, 0xa4a4a4a4U, 0x5c5c5c5cU, 0xccccccccU, + 0x5d5d5d5dU, 0x65656565U, 0xb6b6b6b6U, 0x92929292U, + 0x6c6c6c6cU, 0x70707070U, 0x48484848U, 0x50505050U, + 0xfdfdfdfdU, 0xededededU, 0xb9b9b9b9U, 0xdadadadaU, + 0x5e5e5e5eU, 0x15151515U, 0x46464646U, 0x57575757U, + 0xa7a7a7a7U, 0x8d8d8d8dU, 0x9d9d9d9dU, 0x84848484U, + 0x90909090U, 0xd8d8d8d8U, 0xababababU, 0x00000000U, + 0x8c8c8c8cU, 0xbcbcbcbcU, 0xd3d3d3d3U, 0x0a0a0a0aU, + 0xf7f7f7f7U, 0xe4e4e4e4U, 0x58585858U, 0x05050505U, + 0xb8b8b8b8U, 0xb3b3b3b3U, 0x45454545U, 0x06060606U, + 0xd0d0d0d0U, 0x2c2c2c2cU, 0x1e1e1e1eU, 0x8f8f8f8fU, + 0xcacacacaU, 0x3f3f3f3fU, 0x0f0f0f0fU, 0x02020202U, + 0xc1c1c1c1U, 0xafafafafU, 0xbdbdbdbdU, 0x03030303U, + 0x01010101U, 0x13131313U, 0x8a8a8a8aU, 0x6b6b6b6bU, + 0x3a3a3a3aU, 0x91919191U, 0x11111111U, 0x41414141U, + 0x4f4f4f4fU, 0x67676767U, 0xdcdcdcdcU, 0xeaeaeaeaU, + 0x97979797U, 0xf2f2f2f2U, 0xcfcfcfcfU, 0xcecececeU, + 0xf0f0f0f0U, 0xb4b4b4b4U, 0xe6e6e6e6U, 0x73737373U, + 0x96969696U, 0xacacacacU, 0x74747474U, 0x22222222U, + 0xe7e7e7e7U, 0xadadadadU, 0x35353535U, 0x85858585U, + 0xe2e2e2e2U, 0xf9f9f9f9U, 0x37373737U, 0xe8e8e8e8U, + 0x1c1c1c1cU, 0x75757575U, 0xdfdfdfdfU, 0x6e6e6e6eU, + 0x47474747U, 0xf1f1f1f1U, 0x1a1a1a1aU, 0x71717171U, + 0x1d1d1d1dU, 0x29292929U, 0xc5c5c5c5U, 0x89898989U, + 0x6f6f6f6fU, 0xb7b7b7b7U, 0x62626262U, 0x0e0e0e0eU, + 0xaaaaaaaaU, 0x18181818U, 0xbebebebeU, 0x1b1b1b1bU, + 0xfcfcfcfcU, 0x56565656U, 0x3e3e3e3eU, 0x4b4b4b4bU, + 0xc6c6c6c6U, 0xd2d2d2d2U, 0x79797979U, 0x20202020U, + 0x9a9a9a9aU, 0xdbdbdbdbU, 0xc0c0c0c0U, 0xfefefefeU, + 0x78787878U, 0xcdcdcdcdU, 0x5a5a5a5aU, 0xf4f4f4f4U, + 0x1f1f1f1fU, 0xddddddddU, 0xa8a8a8a8U, 0x33333333U, + 0x88888888U, 0x07070707U, 0xc7c7c7c7U, 0x31313131U, + 0xb1b1b1b1U, 0x12121212U, 0x10101010U, 0x59595959U, + 0x27272727U, 0x80808080U, 0xececececU, 0x5f5f5f5fU, + 0x60606060U, 0x51515151U, 0x7f7f7f7fU, 0xa9a9a9a9U, + 0x19191919U, 0xb5b5b5b5U, 0x4a4a4a4aU, 0x0d0d0d0dU, + 0x2d2d2d2dU, 0xe5e5e5e5U, 0x7a7a7a7aU, 0x9f9f9f9fU, + 0x93939393U, 0xc9c9c9c9U, 0x9c9c9c9cU, 0xefefefefU, + 0xa0a0a0a0U, 0xe0e0e0e0U, 0x3b3b3b3bU, 0x4d4d4d4dU, + 0xaeaeaeaeU, 0x2a2a2a2aU, 0xf5f5f5f5U, 0xb0b0b0b0U, + 0xc8c8c8c8U, 0xebebebebU, 0xbbbbbbbbU, 0x3c3c3c3cU, + 0x83838383U, 0x53535353U, 0x99999999U, 0x61616161U, + 0x17171717U, 0x2b2b2b2bU, 0x04040404U, 0x7e7e7e7eU, + 0xbabababaU, 0x77777777U, 0xd6d6d6d6U, 0x26262626U, + 0xe1e1e1e1U, 0x69696969U, 0x14141414U, 0x63636363U, + 0x55555555U, 0x21212121U, 0x0c0c0c0cU, 0x7d7d7d7dU, +}; +static const u32 rcon[] = { + 0x01000000, 0x02000000, 0x04000000, 0x08000000, + 0x10000000, 0x20000000, 0x40000000, 0x80000000, + 0x1B000000, 0x36000000, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */ +}; + +#define SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00) + +#ifdef _MSC_VER +#define GETU32(p) SWAP(*((u32 *)(p))) +#define PUTU32(ct, st) { *((u32 *)(ct)) = SWAP((st)); } +#else +#define GETU32(pt) (((u32)(pt)[0] << 24) ^ ((u32)(pt)[1] << 16) ^ ((u32)(pt)[2] << 8) ^ ((u32)(pt)[3])) +#define PUTU32(ct, st) { (ct)[0] = (u8)((st) >> 24); (ct)[1] = (u8)((st) >> 16); (ct)[2] = (u8)((st) >> 8); (ct)[3] = (u8)(st); } +#endif + +/** + * Expand the cipher key into the encryption key schedule. + * + * @return the number of rounds for the given cipher key size. + */ +int rijndaelKeySetupEnc(u32 rk[/*4*(Nr + 1)*/], const u8 cipherKey[], int keyBits) { + int i = 0; + u32 temp; + + rk[0] = GETU32(cipherKey ); + rk[1] = GETU32(cipherKey + 4); + rk[2] = GETU32(cipherKey + 8); + rk[3] = GETU32(cipherKey + 12); + if (keyBits == 128) { + for (;;) { + temp = rk[3]; + rk[4] = rk[0] ^ + (Te4[(temp >> 16) & 0xff] & 0xff000000) ^ + (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^ + (Te4[(temp ) & 0xff] & 0x0000ff00) ^ + (Te4[(temp >> 24) ] & 0x000000ff) ^ + rcon[i]; + rk[5] = rk[1] ^ rk[4]; + rk[6] = rk[2] ^ rk[5]; + rk[7] = rk[3] ^ rk[6]; + if (++i == 10) { + return 10; + } + rk += 4; + } + } + rk[4] = GETU32(cipherKey + 16); + rk[5] = GETU32(cipherKey + 20); + if (keyBits == 192) { + for (;;) { + temp = rk[ 5]; + rk[ 6] = rk[ 0] ^ + (Te4[(temp >> 16) & 0xff] & 0xff000000) ^ + (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^ + (Te4[(temp ) & 0xff] & 0x0000ff00) ^ + (Te4[(temp >> 24) ] & 0x000000ff) ^ + rcon[i]; + rk[ 7] = rk[ 1] ^ rk[ 6]; + rk[ 8] = rk[ 2] ^ rk[ 7]; + rk[ 9] = rk[ 3] ^ rk[ 8]; + if (++i == 8) { + return 12; + } + rk[10] = rk[ 4] ^ rk[ 9]; + rk[11] = rk[ 5] ^ rk[10]; + rk += 6; + } + } + rk[6] = GETU32(cipherKey + 24); + rk[7] = GETU32(cipherKey + 28); + if (keyBits == 256) { + for (;;) { + temp = rk[ 7]; + rk[ 8] = rk[ 0] ^ + (Te4[(temp >> 16) & 0xff] & 0xff000000) ^ + (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^ + (Te4[(temp ) & 0xff] & 0x0000ff00) ^ + (Te4[(temp >> 24) ] & 0x000000ff) ^ + rcon[i]; + rk[ 9] = rk[ 1] ^ rk[ 8]; + rk[10] = rk[ 2] ^ rk[ 9]; + rk[11] = rk[ 3] ^ rk[10]; + if (++i == 7) { + return 14; + } + temp = rk[11]; + rk[12] = rk[ 4] ^ + (Te4[(temp >> 24) ] & 0xff000000) ^ + (Te4[(temp >> 16) & 0xff] & 0x00ff0000) ^ + (Te4[(temp >> 8) & 0xff] & 0x0000ff00) ^ + (Te4[(temp ) & 0xff] & 0x000000ff); + rk[13] = rk[ 5] ^ rk[12]; + rk[14] = rk[ 6] ^ rk[13]; + rk[15] = rk[ 7] ^ rk[14]; + + rk += 8; + } + } + return 0; +} + +/** + * Expand the cipher key into the decryption key schedule. + * + * @return the number of rounds for the given cipher key size. + */ +int rijndaelKeySetupDec(u32 rk[/*4*(Nr + 1)*/], const u8 cipherKey[], int keyBits) { + int Nr, i, j; + u32 temp; + + /* expand the cipher key: */ + Nr = rijndaelKeySetupEnc(rk, cipherKey, keyBits); + /* invert the order of the round keys: */ + for (i = 0, j = 4*Nr; i < j; i += 4, j -= 4) { + temp = rk[i ]; rk[i ] = rk[j ]; rk[j ] = temp; + temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp; + temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp; + temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp; + } + /* apply the inverse MixColumn transform to all round keys but the first and the last: */ + for (i = 1; i < Nr; i++) { + rk += 4; + rk[0] = + Td0[Te4[(rk[0] >> 24) ] & 0xff] ^ + Td1[Te4[(rk[0] >> 16) & 0xff] & 0xff] ^ + Td2[Te4[(rk[0] >> 8) & 0xff] & 0xff] ^ + Td3[Te4[(rk[0] ) & 0xff] & 0xff]; + rk[1] = + Td0[Te4[(rk[1] >> 24) ] & 0xff] ^ + Td1[Te4[(rk[1] >> 16) & 0xff] & 0xff] ^ + Td2[Te4[(rk[1] >> 8) & 0xff] & 0xff] ^ + Td3[Te4[(rk[1] ) & 0xff] & 0xff]; + rk[2] = + Td0[Te4[(rk[2] >> 24) ] & 0xff] ^ + Td1[Te4[(rk[2] >> 16) & 0xff] & 0xff] ^ + Td2[Te4[(rk[2] >> 8) & 0xff] & 0xff] ^ + Td3[Te4[(rk[2] ) & 0xff] & 0xff]; + rk[3] = + Td0[Te4[(rk[3] >> 24) ] & 0xff] ^ + Td1[Te4[(rk[3] >> 16) & 0xff] & 0xff] ^ + Td2[Te4[(rk[3] >> 8) & 0xff] & 0xff] ^ + Td3[Te4[(rk[3] ) & 0xff] & 0xff]; + } + return Nr; +} + +void rijndaelEncrypt(const u32 rk[/*4*(Nr + 1)*/], int Nr, const u8 pt[16], u8 ct[16]) { + u32 s0, s1, s2, s3, t0, t1, t2, t3; +#ifndef FULL_UNROLL + int r; +#endif /* ?FULL_UNROLL */ + + /* + * map byte array block to cipher state + * and add initial round key: + */ + s0 = GETU32(pt ) ^ rk[0]; + s1 = GETU32(pt + 4) ^ rk[1]; + s2 = GETU32(pt + 8) ^ rk[2]; + s3 = GETU32(pt + 12) ^ rk[3]; +#ifdef FULL_UNROLL + /* round 1: */ + t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[ 4]; + t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[ 5]; + t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[ 6]; + t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[ 7]; + /* round 2: */ + s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[ 8]; + s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[ 9]; + s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[10]; + s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[11]; + /* round 3: */ + t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[12]; + t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[13]; + t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[14]; + t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[15]; + /* round 4: */ + s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[16]; + s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[17]; + s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[18]; + s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[19]; + /* round 5: */ + t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[20]; + t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[21]; + t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[22]; + t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[23]; + /* round 6: */ + s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[24]; + s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[25]; + s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[26]; + s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[27]; + /* round 7: */ + t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[28]; + t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[29]; + t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[30]; + t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[31]; + /* round 8: */ + s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[32]; + s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[33]; + s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[34]; + s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[35]; + /* round 9: */ + t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[36]; + t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[37]; + t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[38]; + t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[39]; + if (Nr > 10) { + /* round 10: */ + s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[40]; + s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[41]; + s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[42]; + s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[43]; + /* round 11: */ + t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[44]; + t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[45]; + t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[46]; + t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[47]; + if (Nr > 12) { + /* round 12: */ + s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[48]; + s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[49]; + s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[50]; + s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[51]; + /* round 13: */ + t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[52]; + t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[53]; + t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[54]; + t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[55]; + } + } + rk += Nr << 2; +#else /* !FULL_UNROLL */ + /* + * Nr - 1 full rounds: + */ + r = Nr >> 1; + for (;;) { + t0 = + Te0[(s0 >> 24) ] ^ + Te1[(s1 >> 16) & 0xff] ^ + Te2[(s2 >> 8) & 0xff] ^ + Te3[(s3 ) & 0xff] ^ + rk[4]; + t1 = + Te0[(s1 >> 24) ] ^ + Te1[(s2 >> 16) & 0xff] ^ + Te2[(s3 >> 8) & 0xff] ^ + Te3[(s0 ) & 0xff] ^ + rk[5]; + t2 = + Te0[(s2 >> 24) ] ^ + Te1[(s3 >> 16) & 0xff] ^ + Te2[(s0 >> 8) & 0xff] ^ + Te3[(s1 ) & 0xff] ^ + rk[6]; + t3 = + Te0[(s3 >> 24) ] ^ + Te1[(s0 >> 16) & 0xff] ^ + Te2[(s1 >> 8) & 0xff] ^ + Te3[(s2 ) & 0xff] ^ + rk[7]; + + rk += 8; + if (--r == 0) { + break; + } + + s0 = + Te0[(t0 >> 24) ] ^ + Te1[(t1 >> 16) & 0xff] ^ + Te2[(t2 >> 8) & 0xff] ^ + Te3[(t3 ) & 0xff] ^ + rk[0]; + s1 = + Te0[(t1 >> 24) ] ^ + Te1[(t2 >> 16) & 0xff] ^ + Te2[(t3 >> 8) & 0xff] ^ + Te3[(t0 ) & 0xff] ^ + rk[1]; + s2 = + Te0[(t2 >> 24) ] ^ + Te1[(t3 >> 16) & 0xff] ^ + Te2[(t0 >> 8) & 0xff] ^ + Te3[(t1 ) & 0xff] ^ + rk[2]; + s3 = + Te0[(t3 >> 24) ] ^ + Te1[(t0 >> 16) & 0xff] ^ + Te2[(t1 >> 8) & 0xff] ^ + Te3[(t2 ) & 0xff] ^ + rk[3]; + } +#endif /* ?FULL_UNROLL */ + /* + * apply last round and + * map cipher state to byte array block: + */ + s0 = + (Te4[(t0 >> 24) ] & 0xff000000) ^ + (Te4[(t1 >> 16) & 0xff] & 0x00ff0000) ^ + (Te4[(t2 >> 8) & 0xff] & 0x0000ff00) ^ + (Te4[(t3 ) & 0xff] & 0x000000ff) ^ + rk[0]; + PUTU32(ct , s0); + s1 = + (Te4[(t1 >> 24) ] & 0xff000000) ^ + (Te4[(t2 >> 16) & 0xff] & 0x00ff0000) ^ + (Te4[(t3 >> 8) & 0xff] & 0x0000ff00) ^ + (Te4[(t0 ) & 0xff] & 0x000000ff) ^ + rk[1]; + PUTU32(ct + 4, s1); + s2 = + (Te4[(t2 >> 24) ] & 0xff000000) ^ + (Te4[(t3 >> 16) & 0xff] & 0x00ff0000) ^ + (Te4[(t0 >> 8) & 0xff] & 0x0000ff00) ^ + (Te4[(t1 ) & 0xff] & 0x000000ff) ^ + rk[2]; + PUTU32(ct + 8, s2); + s3 = + (Te4[(t3 >> 24) ] & 0xff000000) ^ + (Te4[(t0 >> 16) & 0xff] & 0x00ff0000) ^ + (Te4[(t1 >> 8) & 0xff] & 0x0000ff00) ^ + (Te4[(t2 ) & 0xff] & 0x000000ff) ^ + rk[3]; + PUTU32(ct + 12, s3); +} + +void rijndaelDecrypt(const u32 rk[/*4*(Nr + 1)*/], int Nr, const u8 ct[16], u8 pt[16]) { + u32 s0, s1, s2, s3, t0, t1, t2, t3; +#ifndef FULL_UNROLL + int r; +#endif /* ?FULL_UNROLL */ + + /* + * map byte array block to cipher state + * and add initial round key: + */ + s0 = GETU32(ct ) ^ rk[0]; + s1 = GETU32(ct + 4) ^ rk[1]; + s2 = GETU32(ct + 8) ^ rk[2]; + s3 = GETU32(ct + 12) ^ rk[3]; +#ifdef FULL_UNROLL + /* round 1: */ + t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[ 4]; + t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[ 5]; + t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[ 6]; + t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[ 7]; + /* round 2: */ + s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[ 8]; + s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[ 9]; + s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[10]; + s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[11]; + /* round 3: */ + t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[12]; + t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[13]; + t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[14]; + t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[15]; + /* round 4: */ + s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[16]; + s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[17]; + s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[18]; + s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[19]; + /* round 5: */ + t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[20]; + t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[21]; + t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[22]; + t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[23]; + /* round 6: */ + s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[24]; + s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[25]; + s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[26]; + s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[27]; + /* round 7: */ + t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[28]; + t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[29]; + t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[30]; + t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[31]; + /* round 8: */ + s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[32]; + s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[33]; + s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[34]; + s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[35]; + /* round 9: */ + t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[36]; + t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[37]; + t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[38]; + t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[39]; + if (Nr > 10) { + /* round 10: */ + s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[40]; + s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[41]; + s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[42]; + s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[43]; + /* round 11: */ + t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[44]; + t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[45]; + t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[46]; + t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[47]; + if (Nr > 12) { + /* round 12: */ + s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[48]; + s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[49]; + s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[50]; + s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[51]; + /* round 13: */ + t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[52]; + t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[53]; + t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[54]; + t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[55]; + } + } + rk += Nr << 2; +#else /* !FULL_UNROLL */ + /* + * Nr - 1 full rounds: + */ + r = Nr >> 1; + for (;;) { + t0 = + Td0[(s0 >> 24) ] ^ + Td1[(s3 >> 16) & 0xff] ^ + Td2[(s2 >> 8) & 0xff] ^ + Td3[(s1 ) & 0xff] ^ + rk[4]; + t1 = + Td0[(s1 >> 24) ] ^ + Td1[(s0 >> 16) & 0xff] ^ + Td2[(s3 >> 8) & 0xff] ^ + Td3[(s2 ) & 0xff] ^ + rk[5]; + t2 = + Td0[(s2 >> 24) ] ^ + Td1[(s1 >> 16) & 0xff] ^ + Td2[(s0 >> 8) & 0xff] ^ + Td3[(s3 ) & 0xff] ^ + rk[6]; + t3 = + Td0[(s3 >> 24) ] ^ + Td1[(s2 >> 16) & 0xff] ^ + Td2[(s1 >> 8) & 0xff] ^ + Td3[(s0 ) & 0xff] ^ + rk[7]; + + rk += 8; + if (--r == 0) { + break; + } + + s0 = + Td0[(t0 >> 24) ] ^ + Td1[(t3 >> 16) & 0xff] ^ + Td2[(t2 >> 8) & 0xff] ^ + Td3[(t1 ) & 0xff] ^ + rk[0]; + s1 = + Td0[(t1 >> 24) ] ^ + Td1[(t0 >> 16) & 0xff] ^ + Td2[(t3 >> 8) & 0xff] ^ + Td3[(t2 ) & 0xff] ^ + rk[1]; + s2 = + Td0[(t2 >> 24) ] ^ + Td1[(t1 >> 16) & 0xff] ^ + Td2[(t0 >> 8) & 0xff] ^ + Td3[(t3 ) & 0xff] ^ + rk[2]; + s3 = + Td0[(t3 >> 24) ] ^ + Td1[(t2 >> 16) & 0xff] ^ + Td2[(t1 >> 8) & 0xff] ^ + Td3[(t0 ) & 0xff] ^ + rk[3]; + } +#endif /* ?FULL_UNROLL */ + /* + * apply last round and + * map cipher state to byte array block: + */ + s0 = + (Td4[(t0 >> 24) ] & 0xff000000) ^ + (Td4[(t3 >> 16) & 0xff] & 0x00ff0000) ^ + (Td4[(t2 >> 8) & 0xff] & 0x0000ff00) ^ + (Td4[(t1 ) & 0xff] & 0x000000ff) ^ + rk[0]; + PUTU32(pt , s0); + s1 = + (Td4[(t1 >> 24) ] & 0xff000000) ^ + (Td4[(t0 >> 16) & 0xff] & 0x00ff0000) ^ + (Td4[(t3 >> 8) & 0xff] & 0x0000ff00) ^ + (Td4[(t2 ) & 0xff] & 0x000000ff) ^ + rk[1]; + PUTU32(pt + 4, s1); + s2 = + (Td4[(t2 >> 24) ] & 0xff000000) ^ + (Td4[(t1 >> 16) & 0xff] & 0x00ff0000) ^ + (Td4[(t0 >> 8) & 0xff] & 0x0000ff00) ^ + (Td4[(t3 ) & 0xff] & 0x000000ff) ^ + rk[2]; + PUTU32(pt + 8, s2); + s3 = + (Td4[(t3 >> 24) ] & 0xff000000) ^ + (Td4[(t2 >> 16) & 0xff] & 0x00ff0000) ^ + (Td4[(t1 >> 8) & 0xff] & 0x0000ff00) ^ + (Td4[(t0 ) & 0xff] & 0x000000ff) ^ + rk[3]; + PUTU32(pt + 12, s3); +} + +#ifdef INTERMEDIATE_VALUE_KAT + +void rijndaelEncryptRound(const u32 rk[/*4*(Nr + 1)*/], int Nr, u8 block[16], int rounds) { + int r; + u32 s0, s1, s2, s3, t0, t1, t2, t3; + + /* + * map byte array block to cipher state + * and add initial round key: + */ + s0 = GETU32(block ) ^ rk[0]; + s1 = GETU32(block + 4) ^ rk[1]; + s2 = GETU32(block + 8) ^ rk[2]; + s3 = GETU32(block + 12) ^ rk[3]; + rk += 4; + + /* + * Nr - 1 full rounds: + */ + for (r = (rounds < Nr ? rounds : Nr - 1); r > 0; r--) { + t0 = + Te0[(s0 >> 24) ] ^ + Te1[(s1 >> 16) & 0xff] ^ + Te2[(s2 >> 8) & 0xff] ^ + Te3[(s3 ) & 0xff] ^ + rk[0]; + t1 = + Te0[(s1 >> 24) ] ^ + Te1[(s2 >> 16) & 0xff] ^ + Te2[(s3 >> 8) & 0xff] ^ + Te3[(s0 ) & 0xff] ^ + rk[1]; + t2 = + Te0[(s2 >> 24) ] ^ + Te1[(s3 >> 16) & 0xff] ^ + Te2[(s0 >> 8) & 0xff] ^ + Te3[(s1 ) & 0xff] ^ + rk[2]; + t3 = + Te0[(s3 >> 24) ] ^ + Te1[(s0 >> 16) & 0xff] ^ + Te2[(s1 >> 8) & 0xff] ^ + Te3[(s2 ) & 0xff] ^ + rk[3]; + + s0 = t0; + s1 = t1; + s2 = t2; + s3 = t3; + rk += 4; + + } + + /* + * apply last round and + * map cipher state to byte array block: + */ + if (rounds == Nr) { + t0 = + (Te4[(s0 >> 24) ] & 0xff000000) ^ + (Te4[(s1 >> 16) & 0xff] & 0x00ff0000) ^ + (Te4[(s2 >> 8) & 0xff] & 0x0000ff00) ^ + (Te4[(s3 ) & 0xff] & 0x000000ff) ^ + rk[0]; + t1 = + (Te4[(s1 >> 24) ] & 0xff000000) ^ + (Te4[(s2 >> 16) & 0xff] & 0x00ff0000) ^ + (Te4[(s3 >> 8) & 0xff] & 0x0000ff00) ^ + (Te4[(s0 ) & 0xff] & 0x000000ff) ^ + rk[1]; + t2 = + (Te4[(s2 >> 24) ] & 0xff000000) ^ + (Te4[(s3 >> 16) & 0xff] & 0x00ff0000) ^ + (Te4[(s0 >> 8) & 0xff] & 0x0000ff00) ^ + (Te4[(s1 ) & 0xff] & 0x000000ff) ^ + rk[2]; + t3 = + (Te4[(s3 >> 24) ] & 0xff000000) ^ + (Te4[(s0 >> 16) & 0xff] & 0x00ff0000) ^ + (Te4[(s1 >> 8) & 0xff] & 0x0000ff00) ^ + (Te4[(s2 ) & 0xff] & 0x000000ff) ^ + rk[3]; + + s0 = t0; + s1 = t1; + s2 = t2; + s3 = t3; + } + + PUTU32(block , s0); + PUTU32(block + 4, s1); + PUTU32(block + 8, s2); + PUTU32(block + 12, s3); +} + +void rijndaelDecryptRound(const u32 rk[/*4*(Nr + 1)*/], int Nr, u8 block[16], int rounds) { + int r; + u32 s0, s1, s2, s3, t0, t1, t2, t3; + + /* + * map byte array block to cipher state + * and add initial round key: + */ + s0 = GETU32(block ) ^ rk[0]; + s1 = GETU32(block + 4) ^ rk[1]; + s2 = GETU32(block + 8) ^ rk[2]; + s3 = GETU32(block + 12) ^ rk[3]; + rk += 4; + + /* + * Nr - 1 full rounds: + */ + for (r = (rounds < Nr ? rounds : Nr) - 1; r > 0; r--) { + t0 = + Td0[(s0 >> 24) ] ^ + Td1[(s3 >> 16) & 0xff] ^ + Td2[(s2 >> 8) & 0xff] ^ + Td3[(s1 ) & 0xff] ^ + rk[0]; + t1 = + Td0[(s1 >> 24) ] ^ + Td1[(s0 >> 16) & 0xff] ^ + Td2[(s3 >> 8) & 0xff] ^ + Td3[(s2 ) & 0xff] ^ + rk[1]; + t2 = + Td0[(s2 >> 24) ] ^ + Td1[(s1 >> 16) & 0xff] ^ + Td2[(s0 >> 8) & 0xff] ^ + Td3[(s3 ) & 0xff] ^ + rk[2]; + t3 = + Td0[(s3 >> 24) ] ^ + Td1[(s2 >> 16) & 0xff] ^ + Td2[(s1 >> 8) & 0xff] ^ + Td3[(s0 ) & 0xff] ^ + rk[3]; + + s0 = t0; + s1 = t1; + s2 = t2; + s3 = t3; + rk += 4; + + } + + /* + * complete the last round and + * map cipher state to byte array block: + */ + t0 = + (Td4[(s0 >> 24) ] & 0xff000000) ^ + (Td4[(s3 >> 16) & 0xff] & 0x00ff0000) ^ + (Td4[(s2 >> 8) & 0xff] & 0x0000ff00) ^ + (Td4[(s1 ) & 0xff] & 0x000000ff); + t1 = + (Td4[(s1 >> 24) ] & 0xff000000) ^ + (Td4[(s0 >> 16) & 0xff] & 0x00ff0000) ^ + (Td4[(s3 >> 8) & 0xff] & 0x0000ff00) ^ + (Td4[(s2 ) & 0xff] & 0x000000ff); + t2 = + (Td4[(s2 >> 24) ] & 0xff000000) ^ + (Td4[(s1 >> 16) & 0xff] & 0x00ff0000) ^ + (Td4[(s0 >> 8) & 0xff] & 0x0000ff00) ^ + (Td4[(s3 ) & 0xff] & 0x000000ff); + t3 = + (Td4[(s3 >> 24) ] & 0xff000000) ^ + (Td4[(s2 >> 16) & 0xff] & 0x00ff0000) ^ + (Td4[(s1 >> 8) & 0xff] & 0x0000ff00) ^ + (Td4[(s0 ) & 0xff] & 0x000000ff); + + if (rounds == Nr) { + t0 ^= rk[0]; + t1 ^= rk[1]; + t2 ^= rk[2]; + t3 ^= rk[3]; + } + + PUTU32(block , t0); + PUTU32(block + 4, t1); + PUTU32(block + 8, t2); + PUTU32(block + 12, t3); +} + +#endif /* INTERMEDIATE_VALUE_KAT */ Index: ext/libicpf/src/rijndael-alg-fst.h =================================================================== diff -u -N --- ext/libicpf/src/rijndael-alg-fst.h (revision 0) +++ ext/libicpf/src/rijndael-alg-fst.h (revision e17c80d36eaa0430313e7d1058aa7a301d1510af) @@ -0,0 +1,47 @@ +/** + * rijndael-alg-fst.h + * + * @version 3.0 (December 2000) + * + * Optimised ANSI C code for the Rijndael cipher (now AES) + * + * @author Vincent Rijmen + * @author Antoon Bosselaers + * @author Paulo Barreto + * + * This code is hereby placed in the public domain. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''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 AUTHORS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef __RIJNDAEL_ALG_FST_H +#define __RIJNDAEL_ALG_FST_H + +#define MAXKC (256/32) +#define MAXKB (256/8) +#define MAXNR 14 + +typedef unsigned char u8; +typedef unsigned short u16; +typedef unsigned int u32; + +int rijndaelKeySetupEnc(u32 rk[/*4*(Nr + 1)*/], const u8 cipherKey[], int keyBits); +int rijndaelKeySetupDec(u32 rk[/*4*(Nr + 1)*/], const u8 cipherKey[], int keyBits); +void rijndaelEncrypt(const u32 rk[/*4*(Nr + 1)*/], int Nr, const u8 pt[16], u8 ct[16]); +void rijndaelDecrypt(const u32 rk[/*4*(Nr + 1)*/], int Nr, const u8 ct[16], u8 pt[16]); + +#ifdef INTERMEDIATE_VALUE_KAT +void rijndaelEncryptRound(const u32 rk[/*4*(Nr + 1)*/], int Nr, u8 block[16], int rounds); +void rijndaelDecryptRound(const u32 rk[/*4*(Nr + 1)*/], int Nr, u8 block[16], int rounds); +#endif /* INTERMEDIATE_VALUE_KAT */ + +#endif /* __RIJNDAEL_ALG_FST_H */ Index: ext/libicpf/src/rijndael-api-fst.c =================================================================== diff -u -N --- ext/libicpf/src/rijndael-api-fst.c (revision 0) +++ ext/libicpf/src/rijndael-api-fst.c (revision e17c80d36eaa0430313e7d1058aa7a301d1510af) @@ -0,0 +1,444 @@ +/** + * rijndael-api-fst.c + * + * @version 2.9 (December 2000) + * + * Optimised ANSI C code for the Rijndael cipher (now AES) + * + * @author Vincent Rijmen + * @author Antoon Bosselaers + * @author Paulo Barreto + * + * This code is hereby placed in the public domain. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''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 AUTHORS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Acknowledgements: + * + * We are deeply indebted to the following people for their bug reports, + * fixes, and improvement suggestions to this implementation. Though we + * tried to list all contributions, we apologise in advance for any + * missing reference. + * + * Andrew Bales + * Markus Friedl + * John Skodon + */ + +#include +#include +#include + +#include "rijndael-alg-fst.h" +#include "rijndael-api-fst.h" + +int makeKey(keyInstance *key, BYTE direction, int keyLen, const char *keyMaterial) { + int i; + char *keyMat; + u8 cipherKey[MAXKB]; + + if (key == NULL) { + return BAD_KEY_INSTANCE; + } + + if ((direction == DIR_ENCRYPT) || (direction == DIR_DECRYPT)) { + key->direction = direction; + } else { + return BAD_KEY_DIR; + } + + if ((keyLen == 128) || (keyLen == 192) || (keyLen == 256)) { + key->keyLen = keyLen; + } else { + return BAD_KEY_MAT; + } + + if (keyMaterial != NULL) { + strncpy(key->keyMaterial, keyMaterial, keyLen/4); + } + + /* initialize key schedule: */ + keyMat = key->keyMaterial; + for (i = 0; i < key->keyLen/8; i++) { + int t, v; + + t = *keyMat++; + if ((t >= '0') && (t <= '9')) v = (t - '0') << 4; + else if ((t >= 'a') && (t <= 'f')) v = (t - 'a' + 10) << 4; + else if ((t >= 'A') && (t <= 'F')) v = (t - 'A' + 10) << 4; + else return BAD_KEY_MAT; + + t = *keyMat++; + if ((t >= '0') && (t <= '9')) v ^= (t - '0'); + else if ((t >= 'a') && (t <= 'f')) v ^= (t - 'a' + 10); + else if ((t >= 'A') && (t <= 'F')) v ^= (t - 'A' + 10); + else return BAD_KEY_MAT; + + cipherKey[i] = (u8)v; + } + if (direction == DIR_ENCRYPT) { + key->Nr = rijndaelKeySetupEnc(key->rk, cipherKey, keyLen); + } else { + key->Nr = rijndaelKeySetupDec(key->rk, cipherKey, keyLen); + } + rijndaelKeySetupEnc(key->ek, cipherKey, keyLen); + return TRUE; +} + +int cipherInit(cipherInstance *cipher, BYTE mode, char *IV) { + if ((mode == MODE_ECB) || (mode == MODE_CBC) || (mode == MODE_CFB1)) { + cipher->mode = mode; + } else { + return BAD_CIPHER_MODE; + } + if (IV != NULL) { + int i; + for (i = 0; i < MAX_IV_SIZE; i++) { + int t, j; + + t = IV[2*i]; + if ((t >= '0') && (t <= '9')) j = (t - '0') << 4; + else if ((t >= 'a') && (t <= 'f')) j = (t - 'a' + 10) << 4; + else if ((t >= 'A') && (t <= 'F')) j = (t - 'A' + 10) << 4; + else return BAD_CIPHER_INSTANCE; + + t = IV[2*i+1]; + if ((t >= '0') && (t <= '9')) j ^= (t - '0'); + else if ((t >= 'a') && (t <= 'f')) j ^= (t - 'a' + 10); + else if ((t >= 'A') && (t <= 'F')) j ^= (t - 'A' + 10); + else return BAD_CIPHER_INSTANCE; + + cipher->IV[i] = (u8)j; + } + } else { + memset(cipher->IV, 0, MAX_IV_SIZE); + } + return TRUE; +} + +int blockEncrypt(cipherInstance *cipher, keyInstance *key, + BYTE *input, int inputLen, BYTE *outBuffer) { + int i, k, t, numBlocks; + u8 block[16], *iv; + + if (cipher == NULL || + key == NULL || + key->direction == DIR_DECRYPT) { + return BAD_CIPHER_STATE; + } + if (input == NULL || inputLen <= 0) { + return 0; /* nothing to do */ + } + + numBlocks = inputLen/128; + + switch (cipher->mode) { + case MODE_ECB: + for (i = numBlocks; i > 0; i--) { + rijndaelEncrypt(key->rk, key->Nr, input, outBuffer); + input += 16; + outBuffer += 16; + } + break; + + case MODE_CBC: + iv = cipher->IV; + for (i = numBlocks; i > 0; i--) { + ((u32*)block)[0] = ((u32*)input)[0] ^ ((u32*)iv)[0]; + ((u32*)block)[1] = ((u32*)input)[1] ^ ((u32*)iv)[1]; + ((u32*)block)[2] = ((u32*)input)[2] ^ ((u32*)iv)[2]; + ((u32*)block)[3] = ((u32*)input)[3] ^ ((u32*)iv)[3]; + rijndaelEncrypt(key->rk, key->Nr, block, outBuffer); + iv = outBuffer; + input += 16; + outBuffer += 16; + } + break; + + case MODE_CFB1: + iv = cipher->IV; + for (i = numBlocks; i > 0; i--) { + + memcpy(outBuffer, input, 16); + for (k = 0; k < 128; k++) { + rijndaelEncrypt(key->ek, key->Nr, iv, block); + outBuffer[k >> 3] ^= (block[0] & 0x80U) >> (k & 7); + for (t = 0; t < 15; t++) { + iv[t] = (iv[t] << 1) | (iv[t + 1] >> 7); + } + iv[15] = (iv[15] << 1) | ((outBuffer[k >> 3] >> (7 - (k & 7))) & 1); + } + outBuffer += 16; + input += 16; + } + break; + + default: + return BAD_CIPHER_STATE; + } + + return 128*numBlocks; +} + +/** + * Encrypt data partitioned in octets, using RFC 2040-like padding. + * + * @param input data to be encrypted (octet sequence) + * @param inputOctets input length in octets (not bits) + * @param outBuffer encrypted output data + * + * @return length in octets (not bits) of the encrypted output buffer. + */ +int padEncrypt(cipherInstance *cipher, keyInstance *key, + BYTE *input, int inputOctets, BYTE *outBuffer) { + int i, numBlocks, padLen; + u8 block[16], *iv; + + if (cipher == NULL || + key == NULL || + key->direction == DIR_DECRYPT) { + return BAD_CIPHER_STATE; + } + if (input == NULL || inputOctets <= 0) { + return 0; /* nothing to do */ + } + + numBlocks = inputOctets/16; + + switch (cipher->mode) { + case MODE_ECB: + for (i = numBlocks; i > 0; i--) { + rijndaelEncrypt(key->rk, key->Nr, input, outBuffer); + input += 16; + outBuffer += 16; + } + padLen = 16 - (inputOctets - 16*numBlocks); + assert(padLen > 0 && padLen <= 16); + memcpy(block, input, 16 - padLen); + memset(block + 16 - padLen, padLen, padLen); + rijndaelEncrypt(key->rk, key->Nr, block, outBuffer); + break; + + case MODE_CBC: + iv = cipher->IV; + for (i = numBlocks; i > 0; i--) { + ((u32*)block)[0] = ((u32*)input)[0] ^ ((u32*)iv)[0]; + ((u32*)block)[1] = ((u32*)input)[1] ^ ((u32*)iv)[1]; + ((u32*)block)[2] = ((u32*)input)[2] ^ ((u32*)iv)[2]; + ((u32*)block)[3] = ((u32*)input)[3] ^ ((u32*)iv)[3]; + rijndaelEncrypt(key->rk, key->Nr, block, outBuffer); + iv = outBuffer; + input += 16; + outBuffer += 16; + } + padLen = 16 - (inputOctets - 16*numBlocks); + assert(padLen > 0 && padLen <= 16); + for (i = 0; i < 16 - padLen; i++) { + block[i] = input[i] ^ iv[i]; + } + for (i = 16 - padLen; i < 16; i++) { + block[i] = (BYTE)padLen ^ iv[i]; + } + rijndaelEncrypt(key->rk, key->Nr, block, outBuffer); + break; + + default: + return BAD_CIPHER_STATE; + } + + return 16*(numBlocks + 1); +} + +int blockDecrypt(cipherInstance *cipher, keyInstance *key, + BYTE *input, int inputLen, BYTE *outBuffer) { + int i, k, t, numBlocks; + u8 block[16], *iv; + + if (cipher == NULL || + key == NULL || + cipher->mode != MODE_CFB1 && key->direction == DIR_ENCRYPT) { + return BAD_CIPHER_STATE; + } + if (input == NULL || inputLen <= 0) { + return 0; /* nothing to do */ + } + + numBlocks = inputLen/128; + + switch (cipher->mode) { + case MODE_ECB: + for (i = numBlocks; i > 0; i--) { + rijndaelDecrypt(key->rk, key->Nr, input, outBuffer); + input += 16; + outBuffer += 16; + } + break; + + case MODE_CBC: + iv = cipher->IV; + for (i = numBlocks; i > 0; i--) { + rijndaelDecrypt(key->rk, key->Nr, input, block); + ((u32*)block)[0] ^= ((u32*)iv)[0]; + ((u32*)block)[1] ^= ((u32*)iv)[1]; + ((u32*)block)[2] ^= ((u32*)iv)[2]; + ((u32*)block)[3] ^= ((u32*)iv)[3]; + memcpy(cipher->IV, input, 16); + memcpy(outBuffer, block, 16); + input += 16; + outBuffer += 16; + } + break; + + case MODE_CFB1: + iv = cipher->IV; + for (i = numBlocks; i > 0; i--) { + memcpy(outBuffer, input, 16); + + for (k = 0; k < 128; k++) { + rijndaelEncrypt(key->ek, key->Nr, iv, block); + for (t = 0; t < 15; t++) { + iv[t] = (iv[t] << 1) | (iv[t + 1] >> 7); + } + iv[15] = (iv[15] << 1) | ((input[k >> 3] >> (7 - (k & 7))) & 1); + outBuffer[k >> 3] ^= (block[0] & 0x80U) >> (k & 7); + } + outBuffer += 16; + input += 16; + } + break; + + default: + return BAD_CIPHER_STATE; + } + + return 128*numBlocks; +} + +int padDecrypt(cipherInstance *cipher, keyInstance *key, + BYTE *input, int inputOctets, BYTE *outBuffer) { + int i, numBlocks, padLen; + u8 block[16]; + + if (cipher == NULL || + key == NULL || + key->direction == DIR_ENCRYPT) { + return BAD_CIPHER_STATE; + } + if (input == NULL || inputOctets <= 0) { + return 0; /* nothing to do */ + } + if (inputOctets % 16 != 0) { + return BAD_DATA; + } + + numBlocks = inputOctets/16; + + switch (cipher->mode) { + case MODE_ECB: + /* all blocks but last */ + for (i = numBlocks - 1; i > 0; i--) { + rijndaelDecrypt(key->rk, key->Nr, input, outBuffer); + input += 16; + outBuffer += 16; + } + /* last block */ + rijndaelDecrypt(key->rk, key->Nr, input, block); + padLen = block[15]; + if (padLen > 16) { + return BAD_DATA; + } + for (i = 16 - padLen; i < 16; i++) { + if (block[i] != padLen) { + return BAD_DATA; + } + } + memcpy(outBuffer, block, 16 - padLen); + break; + + case MODE_CBC: + /* all blocks but last */ + for (i = numBlocks - 1; i > 0; i--) { + rijndaelDecrypt(key->rk, key->Nr, input, block); + ((u32*)block)[0] ^= ((u32*)cipher->IV)[0]; + ((u32*)block)[1] ^= ((u32*)cipher->IV)[1]; + ((u32*)block)[2] ^= ((u32*)cipher->IV)[2]; + ((u32*)block)[3] ^= ((u32*)cipher->IV)[3]; + memcpy(cipher->IV, input, 16); + memcpy(outBuffer, block, 16); + input += 16; + outBuffer += 16; + } + /* last block */ + rijndaelDecrypt(key->rk, key->Nr, input, block); + ((u32*)block)[0] ^= ((u32*)cipher->IV)[0]; + ((u32*)block)[1] ^= ((u32*)cipher->IV)[1]; + ((u32*)block)[2] ^= ((u32*)cipher->IV)[2]; + ((u32*)block)[3] ^= ((u32*)cipher->IV)[3]; + padLen = block[15]; + if (padLen <= 0 || padLen > 16) { + return BAD_DATA; + } + for (i = 16 - padLen; i < 16; i++) { + if (block[i] != padLen) { + return BAD_DATA; + } + } + memcpy(outBuffer, block, 16 - padLen); + break; + + default: + return BAD_CIPHER_STATE; + } + + return 16*numBlocks - padLen; +} + +#ifdef INTERMEDIATE_VALUE_KAT +/** + * cipherUpdateRounds: + * + * Encrypts/Decrypts exactly one full block a specified number of rounds. + * Only used in the Intermediate Value Known Answer Test. + * + * Returns: + * TRUE - on success + * BAD_CIPHER_STATE - cipher in bad state (e.g., not initialized) + */ +int cipherUpdateRounds(cipherInstance *cipher, keyInstance *key, + BYTE *input, int inputLen, BYTE *outBuffer, int rounds) { + u8 block[16]; + + if (cipher == NULL || key == NULL) { + return BAD_CIPHER_STATE; + } + + memcpy(block, input, 16); + + switch (key->direction) { + case DIR_ENCRYPT: + rijndaelEncryptRound(key->rk, key->Nr, block, rounds); + break; + + case DIR_DECRYPT: + rijndaelDecryptRound(key->rk, key->Nr, block, rounds); + break; + + default: + return BAD_KEY_DIR; + } + + memcpy(outBuffer, block, 16); + + return TRUE; +} +#endif /* INTERMEDIATE_VALUE_KAT */ Index: ext/libicpf/src/rijndael-api-fst.h =================================================================== diff -u -N --- ext/libicpf/src/rijndael-api-fst.h (revision 0) +++ ext/libicpf/src/rijndael-api-fst.h (revision e17c80d36eaa0430313e7d1058aa7a301d1510af) @@ -0,0 +1,119 @@ +/** + * rijndael-api-fst.h + * + * @version 2.9 (December 2000) + * + * Optimised ANSI C code for the Rijndael cipher (now AES) + * + * @author Vincent Rijmen + * @author Antoon Bosselaers + * @author Paulo Barreto + * + * This code is hereby placed in the public domain. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''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 AUTHORS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Acknowledgements: + * + * We are deeply indebted to the following people for their bug reports, + * fixes, and improvement suggestions to this implementation. Though we + * tried to list all contributions, we apologise in advance for any + * missing reference. + * + * Andrew Bales + * Markus Friedl + * John Skodon + */ + +#ifndef __RIJNDAEL_API_FST_H +#define __RIJNDAEL_API_FST_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "rijndael-alg-fst.h" + +/* Generic Defines */ +#define DIR_ENCRYPT 0 /* Are we encrpyting? */ +#define DIR_DECRYPT 1 /* Are we decrpyting? */ +#define MODE_ECB 1 /* Are we ciphering in ECB mode? */ +#define MODE_CBC 2 /* Are we ciphering in CBC mode? */ +#define MODE_CFB1 3 /* Are we ciphering in 1-bit CFB mode? */ +#define TRUE 1 +#define FALSE 0 +#define BITSPERBLOCK 128 /* Default number of bits in a cipher block */ + +/* Error Codes */ +#define BAD_KEY_DIR -1 /* Key direction is invalid, e.g., unknown value */ +#define BAD_KEY_MAT -2 /* Key material not of correct length */ +#define BAD_KEY_INSTANCE -3 /* Key passed is not valid */ +#define BAD_CIPHER_MODE -4 /* Params struct passed to cipherInit invalid */ +#define BAD_CIPHER_STATE -5 /* Cipher in wrong state (e.g., not initialized) */ +#define BAD_BLOCK_LENGTH -6 +#define BAD_CIPHER_INSTANCE -7 +#define BAD_DATA -8 /* Data contents are invalid, e.g., invalid padding */ +#define BAD_OTHER -9 /* Unknown error */ + +/* Algorithm-specific Defines */ +#define MAX_KEY_SIZE 64 /* # of ASCII char's needed to represent a key */ +#define MAX_IV_SIZE 16 /* # bytes needed to represent an IV */ + +/* Typedefs */ + +typedef unsigned char BYTE; + +/* The structure for key information */ +typedef struct { + BYTE direction; /* Key used for encrypting or decrypting? */ + int keyLen; /* Length of the key */ + char keyMaterial[MAX_KEY_SIZE+1]; /* Raw key data in ASCII, e.g., user input or KAT values */ + int Nr; /* key-length-dependent number of rounds */ + u32 rk[4*(MAXNR + 1)]; /* key schedule */ + u32 ek[4*(MAXNR + 1)]; /* CFB1 key schedule (encryption only) */ +} keyInstance; + +/* The structure for cipher information */ +typedef struct { /* changed order of the components */ + BYTE mode; /* MODE_ECB, MODE_CBC, or MODE_CFB1 */ + BYTE IV[MAX_IV_SIZE]; /* A possible Initialization Vector for ciphering */ +} cipherInstance; + +/* Function prototypes */ + +int makeKey(keyInstance *key, BYTE direction, int keyLen, const char *keyMaterial); + +int cipherInit(cipherInstance *cipher, BYTE mode, char *IV); + +int blockEncrypt(cipherInstance *cipher, keyInstance *key, + BYTE *input, int inputLen, BYTE *outBuffer); + +int padEncrypt(cipherInstance *cipher, keyInstance *key, + BYTE *input, int inputOctets, BYTE *outBuffer); + +int blockDecrypt(cipherInstance *cipher, keyInstance *key, + BYTE *input, int inputLen, BYTE *outBuffer); + +int padDecrypt(cipherInstance *cipher, keyInstance *key, + BYTE *input, int inputOctets, BYTE *outBuffer); + +#ifdef INTERMEDIATE_VALUE_KAT +int cipherUpdateRounds(cipherInstance *cipher, keyInstance *key, + BYTE *input, int inputLen, BYTE *outBuffer, int Rounds); +#endif /* INTERMEDIATE_VALUE_KAT */ + +#ifdef __cplusplus +} +#endif +#endif /* __RIJNDAEL_API_FST_H */ Index: ext/libicpf/src/sha256.c =================================================================== diff -u -N --- ext/libicpf/src/sha256.c (revision 0) +++ ext/libicpf/src/sha256.c (revision e17c80d36eaa0430313e7d1058aa7a301d1510af) @@ -0,0 +1,369 @@ +/* + * FIPS-180-2 compliant SHA-256 implementation + * + * Copyright (C) 2001-2003 Christophe Devine + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include + +#include "sha256.h" + +#define GET_UINT32(n,b,i) \ +{ \ + (n) = ( (uint32) (b)[(i) ] << 24 ) \ + | ( (uint32) (b)[(i) + 1] << 16 ) \ + | ( (uint32) (b)[(i) + 2] << 8 ) \ + | ( (uint32) (b)[(i) + 3] ); \ +} + +#define PUT_UINT32(n,b,i) \ +{ \ + (b)[(i) ] = (uint8) ( (n) >> 24 ); \ + (b)[(i) + 1] = (uint8) ( (n) >> 16 ); \ + (b)[(i) + 2] = (uint8) ( (n) >> 8 ); \ + (b)[(i) + 3] = (uint8) ( (n) ); \ +} + +void sha256_starts( sha256_context *ctx ) +{ + ctx->total[0] = 0; + ctx->total[1] = 0; + + ctx->state[0] = 0x6A09E667; + ctx->state[1] = 0xBB67AE85; + ctx->state[2] = 0x3C6EF372; + ctx->state[3] = 0xA54FF53A; + ctx->state[4] = 0x510E527F; + ctx->state[5] = 0x9B05688C; + ctx->state[6] = 0x1F83D9AB; + ctx->state[7] = 0x5BE0CD19; +} + +void sha256_process( sha256_context *ctx, uint8 data[64] ) +{ + uint32 temp1, temp2, W[64]; + uint32 A, B, C, D, E, F, G, H; + + GET_UINT32( W[0], data, 0 ); + GET_UINT32( W[1], data, 4 ); + GET_UINT32( W[2], data, 8 ); + GET_UINT32( W[3], data, 12 ); + GET_UINT32( W[4], data, 16 ); + GET_UINT32( W[5], data, 20 ); + GET_UINT32( W[6], data, 24 ); + GET_UINT32( W[7], data, 28 ); + GET_UINT32( W[8], data, 32 ); + GET_UINT32( W[9], data, 36 ); + GET_UINT32( W[10], data, 40 ); + GET_UINT32( W[11], data, 44 ); + GET_UINT32( W[12], data, 48 ); + GET_UINT32( W[13], data, 52 ); + GET_UINT32( W[14], data, 56 ); + GET_UINT32( W[15], data, 60 ); + +#define SHR(x,n) ((x & 0xFFFFFFFF) >> n) +#define ROTR(x,n) (SHR(x,n) | (x << (32 - n))) + +#define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3)) +#define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10)) + +#define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22)) +#define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25)) + +#define F0(x,y,z) ((x & y) | (z & (x | y))) +#define F1(x,y,z) (z ^ (x & (y ^ z))) + +#define _R(t) \ +( \ + W[t] = S1(W[t - 2]) + W[t - 7] + \ + S0(W[t - 15]) + W[t - 16] \ +) + +#define P(a,b,c,d,e,f,g,h,x,K) \ +{ \ + temp1 = h + S3(e) + F1(e,f,g) + K + x; \ + temp2 = S2(a) + F0(a,b,c); \ + d += temp1; h = temp1 + temp2; \ +} + + A = ctx->state[0]; + B = ctx->state[1]; + C = ctx->state[2]; + D = ctx->state[3]; + E = ctx->state[4]; + F = ctx->state[5]; + G = ctx->state[6]; + H = ctx->state[7]; + + P( A, B, C, D, E, F, G, H, W[ 0], 0x428A2F98 ); + P( H, A, B, C, D, E, F, G, W[ 1], 0x71374491 ); + P( G, H, A, B, C, D, E, F, W[ 2], 0xB5C0FBCF ); + P( F, G, H, A, B, C, D, E, W[ 3], 0xE9B5DBA5 ); + P( E, F, G, H, A, B, C, D, W[ 4], 0x3956C25B ); + P( D, E, F, G, H, A, B, C, W[ 5], 0x59F111F1 ); + P( C, D, E, F, G, H, A, B, W[ 6], 0x923F82A4 ); + P( B, C, D, E, F, G, H, A, W[ 7], 0xAB1C5ED5 ); + P( A, B, C, D, E, F, G, H, W[ 8], 0xD807AA98 ); + P( H, A, B, C, D, E, F, G, W[ 9], 0x12835B01 ); + P( G, H, A, B, C, D, E, F, W[10], 0x243185BE ); + P( F, G, H, A, B, C, D, E, W[11], 0x550C7DC3 ); + P( E, F, G, H, A, B, C, D, W[12], 0x72BE5D74 ); + P( D, E, F, G, H, A, B, C, W[13], 0x80DEB1FE ); + P( C, D, E, F, G, H, A, B, W[14], 0x9BDC06A7 ); + P( B, C, D, E, F, G, H, A, W[15], 0xC19BF174 ); + P( A, B, C, D, E, F, G, H, _R(16), 0xE49B69C1 ); + P( H, A, B, C, D, E, F, G, _R(17), 0xEFBE4786 ); + P( G, H, A, B, C, D, E, F, _R(18), 0x0FC19DC6 ); + P( F, G, H, A, B, C, D, E, _R(19), 0x240CA1CC ); + P( E, F, G, H, A, B, C, D, _R(20), 0x2DE92C6F ); + P( D, E, F, G, H, A, B, C, _R(21), 0x4A7484AA ); + P( C, D, E, F, G, H, A, B, _R(22), 0x5CB0A9DC ); + P( B, C, D, E, F, G, H, A, _R(23), 0x76F988DA ); + P( A, B, C, D, E, F, G, H, _R(24), 0x983E5152 ); + P( H, A, B, C, D, E, F, G, _R(25), 0xA831C66D ); + P( G, H, A, B, C, D, E, F, _R(26), 0xB00327C8 ); + P( F, G, H, A, B, C, D, E, _R(27), 0xBF597FC7 ); + P( E, F, G, H, A, B, C, D, _R(28), 0xC6E00BF3 ); + P( D, E, F, G, H, A, B, C, _R(29), 0xD5A79147 ); + P( C, D, E, F, G, H, A, B, _R(30), 0x06CA6351 ); + P( B, C, D, E, F, G, H, A, _R(31), 0x14292967 ); + P( A, B, C, D, E, F, G, H, _R(32), 0x27B70A85 ); + P( H, A, B, C, D, E, F, G, _R(33), 0x2E1B2138 ); + P( G, H, A, B, C, D, E, F, _R(34), 0x4D2C6DFC ); + P( F, G, H, A, B, C, D, E, _R(35), 0x53380D13 ); + P( E, F, G, H, A, B, C, D, _R(36), 0x650A7354 ); + P( D, E, F, G, H, A, B, C, _R(37), 0x766A0ABB ); + P( C, D, E, F, G, H, A, B, _R(38), 0x81C2C92E ); + P( B, C, D, E, F, G, H, A, _R(39), 0x92722C85 ); + P( A, B, C, D, E, F, G, H, _R(40), 0xA2BFE8A1 ); + P( H, A, B, C, D, E, F, G, _R(41), 0xA81A664B ); + P( G, H, A, B, C, D, E, F, _R(42), 0xC24B8B70 ); + P( F, G, H, A, B, C, D, E, _R(43), 0xC76C51A3 ); + P( E, F, G, H, A, B, C, D, _R(44), 0xD192E819 ); + P( D, E, F, G, H, A, B, C, _R(45), 0xD6990624 ); + P( C, D, E, F, G, H, A, B, _R(46), 0xF40E3585 ); + P( B, C, D, E, F, G, H, A, _R(47), 0x106AA070 ); + P( A, B, C, D, E, F, G, H, _R(48), 0x19A4C116 ); + P( H, A, B, C, D, E, F, G, _R(49), 0x1E376C08 ); + P( G, H, A, B, C, D, E, F, _R(50), 0x2748774C ); + P( F, G, H, A, B, C, D, E, _R(51), 0x34B0BCB5 ); + P( E, F, G, H, A, B, C, D, _R(52), 0x391C0CB3 ); + P( D, E, F, G, H, A, B, C, _R(53), 0x4ED8AA4A ); + P( C, D, E, F, G, H, A, B, _R(54), 0x5B9CCA4F ); + P( B, C, D, E, F, G, H, A, _R(55), 0x682E6FF3 ); + P( A, B, C, D, E, F, G, H, _R(56), 0x748F82EE ); + P( H, A, B, C, D, E, F, G, _R(57), 0x78A5636F ); + P( G, H, A, B, C, D, E, F, _R(58), 0x84C87814 ); + P( F, G, H, A, B, C, D, E, _R(59), 0x8CC70208 ); + P( E, F, G, H, A, B, C, D, _R(60), 0x90BEFFFA ); + P( D, E, F, G, H, A, B, C, _R(61), 0xA4506CEB ); + P( C, D, E, F, G, H, A, B, _R(62), 0xBEF9A3F7 ); + P( B, C, D, E, F, G, H, A, _R(63), 0xC67178F2 ); + + ctx->state[0] += A; + ctx->state[1] += B; + ctx->state[2] += C; + ctx->state[3] += D; + ctx->state[4] += E; + ctx->state[5] += F; + ctx->state[6] += G; + ctx->state[7] += H; +} + +void sha256_update( sha256_context *ctx, uint8 *input, uint32 length ) +{ + uint32 left, fill; + + if( ! length ) return; + + left = ctx->total[0] & 0x3F; + fill = 64 - left; + + ctx->total[0] += length; + ctx->total[0] &= 0xFFFFFFFF; + + if( ctx->total[0] < length ) + ctx->total[1]++; + + if( left && length >= fill ) + { + memcpy( (void *) (ctx->buffer + left), + (void *) input, fill ); + sha256_process( ctx, ctx->buffer ); + length -= fill; + input += fill; + left = 0; + } + + while( length >= 64 ) + { + sha256_process( ctx, input ); + length -= 64; + input += 64; + } + + if( length ) + { + memcpy( (void *) (ctx->buffer + left), + (void *) input, length ); + } +} + +static uint8 sha256_padding[64] = +{ + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +void sha256_finish( sha256_context *ctx, uint8 digest[32] ) +{ + uint32 last, padn; + uint32 high, low; + uint8 msglen[8]; + + high = ( ctx->total[0] >> 29 ) + | ( ctx->total[1] << 3 ); + low = ( ctx->total[0] << 3 ); + + PUT_UINT32( high, msglen, 0 ); + PUT_UINT32( low, msglen, 4 ); + + last = ctx->total[0] & 0x3F; + padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); + + sha256_update( ctx, sha256_padding, padn ); + sha256_update( ctx, msglen, 8 ); + + PUT_UINT32( ctx->state[0], digest, 0 ); + PUT_UINT32( ctx->state[1], digest, 4 ); + PUT_UINT32( ctx->state[2], digest, 8 ); + PUT_UINT32( ctx->state[3], digest, 12 ); + PUT_UINT32( ctx->state[4], digest, 16 ); + PUT_UINT32( ctx->state[5], digest, 20 ); + PUT_UINT32( ctx->state[6], digest, 24 ); + PUT_UINT32( ctx->state[7], digest, 28 ); +} + +#ifdef TEST + +#include +#include + +/* + * those are the standard FIPS-180-2 test vectors + */ + +static char *msg[] = +{ + "abc", + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", + NULL +}; + +static char *val[] = +{ + "ba7816bf8f01cfea414140de5dae2223" \ + "b00361a396177a9cb410ff61f20015ad", + "248d6a61d20638b8e5c026930c3e6039" \ + "a33ce45964ff2167f6ecedd419db06c1", + "cdc76e5c9914fb9281a1c7e284d73e67" \ + "f1809a48a497200e046d39ccc7112cd0" +}; + +int main( int argc, char *argv[] ) +{ + FILE *f; + int i, j; + char output[65]; + sha256_context ctx; + unsigned char buf[1000]; + unsigned char sha256sum[32]; + + if( argc < 2 ) + { + printf( "\n SHA-256 Validation Tests:\n\n" ); + + for( i = 0; i < 3; i++ ) + { + printf( " Test %d ", i + 1 ); + + sha256_starts( &ctx ); + + if( i < 2 ) + { + sha256_update( &ctx, (uint8 *) msg[i], + strlen( msg[i] ) ); + } + else + { + memset( buf, 'a', 1000 ); + + for( j = 0; j < 1000; j++ ) + { + sha256_update( &ctx, (uint8 *) buf, 1000 ); + } + } + + sha256_finish( &ctx, sha256sum ); + + for( j = 0; j < 32; j++ ) + { + sprintf( output + j * 2, "%02x", sha256sum[j] ); + } + + if( memcmp( output, val[i], 64 ) ) + { + printf( "failed!\n" ); + return( 1 ); + } + + printf( "passed.\n" ); + } + + printf( "\n" ); + } + else + { + if( ! ( f = fopen( argv[1], "rb" ) ) ) + { + perror( "fopen" ); + return( 1 ); + } + + sha256_starts( &ctx ); + + while( ( i = fread( buf, 1, sizeof( buf ), f ) ) > 0 ) + { + sha256_update( &ctx, buf, i ); + } + + sha256_finish( &ctx, sha256sum ); + + for( j = 0; j < 32; j++ ) + { + printf( "%02x", sha256sum[j] ); + } + + printf( " %s\n", argv[1] ); + } + + return( 0 ); +} + +#endif \ No newline at end of file Index: ext/libicpf/src/sha256.h =================================================================== diff -u -N --- ext/libicpf/src/sha256.h (revision 0) +++ ext/libicpf/src/sha256.h (revision e17c80d36eaa0430313e7d1058aa7a301d1510af) @@ -0,0 +1,33 @@ +#ifndef _SHA256_H +#define _SHA256_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +#ifndef uint8 +#define uint8 unsigned char +#endif + +#ifndef uint32 +#define uint32 unsigned long int +#endif + +typedef struct +{ + uint32 total[2]; + uint32 state[8]; + uint8 buffer[64]; +} +sha256_context; + +void sha256_starts( sha256_context *ctx ); +void sha256_update( sha256_context *ctx, uint8 *input, uint32 length ); +void sha256_finish( sha256_context *ctx, uint8 digest[32] ); + +#ifdef __cplusplus +} +#endif + +#endif /* sha256.h */ Index: ext/libicpf/src/str.cpp =================================================================== diff -u -N --- ext/libicpf/src/str.cpp (revision 0) +++ ext/libicpf/src/str.cpp (revision e17c80d36eaa0430313e7d1058aa7a301d1510af) @@ -0,0 +1,1789 @@ +/*************************************************************************** + * Copyright (C) 2004 by J�zef Starosczyk * + * copyhandler@o2.pl * + * * + * This program 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 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 Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +/** \file str.cpp + * \brief Contains the string class implementation. + */ + +#include "str.h" +#include +#include +#include "macros.h" +#include "str_help.h" +#include "dumpctx.h" +#include + +#ifdef _WIN32 + #include +#endif + +///< Increment value for internal string buffer +#define CHUNK_INCSIZE 64 + +// if (buffer_size-string_size > CHUNK_DECSIZE) then the buffer will be shrinked +///< Difference value above which the string will be shrinked +#define CHUNK_DECSIZE 256 + +BEGIN_ICPF_NAMESPACE + +/** Standard constructor + * \param[in] wFlags - initialization flags (SDF_*) + */ +str_data::str_data(short_t wFlags) + : m_pszBuffer(NULL), + m_tBufSize(0), + m_wRefCount(1), + m_wFlags(wFlags) +{ +} + +/** Standard destructor; Frees the internal buffer. + */ +str_data::~str_data() +{ + free_buffer(); +} + +/** Resets the object - frees buffer memory and sets internal members into the initial state. + */ +void str_data::free_buffer() +{ +#ifdef ALLOW_UNICODE + if (m_wFlags & SDF_UNICODE) + delete [] (wchar_t*)m_pszBuffer; + else +#endif + delete [] m_pszBuffer; + m_pszBuffer=NULL; + m_tBufSize=0; + m_wFlags=SDF_NONE; +} + +/** Creates a duplicate of the string data object. Returned pointer is freshly + * allocated and needs to be destroyed. + * \return Pointer to the newly allocated duplicate data object. + */ +str_data* str_data::dup() +{ + str_data* psd=new str_data(m_wFlags); + psd->m_tBufSize=m_tBufSize; +#ifdef ALLOW_UNICODE + if (m_wFlags & SDF_UNICODE) + { + psd->m_pszBuffer=(char_t*)new wchar_t[m_tBufSize]; + wcscpy((wchar_t*)psd->m_pszBuffer, (const wchar_t*)m_pszBuffer); + } + else + { +#endif + psd->m_pszBuffer=new char_t[m_tBufSize]; + strcpy(psd->m_pszBuffer, m_pszBuffer); +#ifdef ALLOW_UNICODE + } +#endif + + return psd; +} + +/** Resizes the internal string buffer to the new size (and copies the old buffer + * contents into the new one if needed). Does not provide the rounding capabilities. + * If the new size is 0 then the buffer is sized to the smallest possible value. + * \param[in] tNewSize - specifies the new buffer size; if 0 then the CHUNK_INCSIZE is + * taken as the size + * \param[in] bCopy - if the current buffer contents should be copied to the new buffer + * \note If the parameter bCopy is false then function puts the null character at the beginning + * of the buffer (sets the string length to 0). + */ +void str_data::resize_buffer(size_t tNewSize, bool bCopy) +{ + assert(m_wRefCount == 1); // is this copy writable ? + + // make sure we resize to some reasonable value + if (tNewSize == 0) + tNewSize=CHUNK_INCSIZE; + +#ifdef ALLOW_UNICODE + char_t* psz; + if (m_wFlags & SDF_UNICODE) + psz=(char_t*)new wchar_t[tNewSize]; + else + psz=new char_t[tNewSize]; +#else + char_t* psz=new char_t[tNewSize]; +#endif + + // now copy if requested + if (bCopy && m_pszBuffer) + { + size_t tCurrent=length(); + tCurrent=(tCurrent < tNewSize) ? tCurrent : tNewSize; + +#ifdef ALLOW_UNICODE + if (m_wFlags & SDF_UNICODE) + { + wcsncpy((wchar_t*)psz, (wchar_t*)m_pszBuffer, tCurrent); + ((wchar_t*)psz)[tCurrent]=L'\0'; + } + else + { +#endif + strncpy(psz, m_pszBuffer, tCurrent); + psz[tCurrent]='\0'; +#ifdef ALLOW_UNICODE + } +#endif + + } + else +#ifdef ALLOW_UNICODE + { + if (m_wFlags & SDF_UNICODE) + ((wchar_t*)psz)[0]=L'\0'; + else +#endif + psz[0]='\0'; +#ifdef ALLOW_UNICODE + } +#endif + + // store data +#ifdef ALLOW_UNICODE + if (m_wFlags & SDF_UNICODE) + delete [] (wchar_t*)m_pszBuffer; + else +#endif + delete [] m_pszBuffer; + m_pszBuffer=psz; + m_tBufSize=tNewSize; +} + +/** Resizes the internal string buffer to the new size (and copies the old buffer + * contents into the new one if needed). Function checks if the buffer needs to be + * resized or not (the buffer is enlarged only if the new size is greater than the + * current buffer size; buffer is shrinked if the new size is smaller than + * (current size - CHUNK_DECSIZE). + * \param[in] tNewSize - specifies the new buffer size; if 0 then the CHUNK_INCSIZE is + * taken as the size + * \param[in] bCopy - if the current buffer contents should be copied to the new buffer + */ +void str_data::resize_buffer_check(size_t tNewSize, bool bCopy) +{ + assert(m_wRefCount == 1); // is this copy writable ? + + // make sure we resize to some reasonable value + if (tNewSize == 0) + tNewSize=CHUNK_INCSIZE; + + if (tNewSize > m_tBufSize || tNewSize+CHUNK_DECSIZE < m_tBufSize) + resize_buffer(tNewSize, bCopy); +} + +/** Function calculates the length of a string in characters (doesn't matter if the string + * is unicode or ansi). + * \note All length checks should be done through this function, because of possible future + * update that will store the string length in the internal member. + * \return The string length in characters, not including the terminating '\\0' + */ +size_t str_data::length() const +{ + if (m_pszBuffer) + { +#ifdef ALLOW_UNICODE + if (m_wFlags & SDF_UNICODE) + return wcslen((wchar_t*)m_pszBuffer); + else +#endif + return strlen(m_pszBuffer); + } + else + return 0; +} + +/** Function calculates the string length using length() function, but outputs + * the string length in bytes instead of characters. + * \return The string length in bytes (including the terminating null character). + */ +size_t str_data::bytelen() const +{ + if (m_wFlags & SDF_UNICODE) + return (length()+1)*sizeof(wchar_t); + else + return (length()+1); +} + +#ifdef ALLOW_UNICODE +/** Changes the internal buffer type to unicode (if ansi). It means only that + * unicode flag is being set, and the buffer size (which is measured in chars) + * is modified according to the size of type wchar_t. + */ +void str_data::switch_unicode() +{ + assert(m_wRefCount == 1); + if (!(m_wFlags & SDF_UNICODE)) + { + m_wFlags |= SDF_UNICODE; + m_tBufSize /= sizeof(wchar_t); + } +} + +/** Changes the internal buffer type to ansi (if unicode). It means only that + * unicode flag is being reset(set to 0), and the buffer size (which is measured in chars) + * is modified according to the size of type wchar_t. + */ +void str_data::switch_ansi() +{ + assert(m_wRefCount == 1); + if (m_wFlags & SDF_UNICODE) + { + m_wFlags &= ~SDF_UNICODE; + m_tBufSize *= sizeof(wchar_t); + } +} +#endif + +/** Assigns a new string buffer to this data object. If there was any other + * buffer allocated - it's freed before assign. + * \param[in] pszSrc - buffer with the source string + * \param[in] tLen - size of the buffer to be assigned (may be greater than the string length) + * \note The tLen param should include the termination null character + */ +void str_data::assign(char_t* pszSrc, size_t tLen) +{ + assert(m_wRefCount == 1); + + // make sure the buffer is freed + free_buffer(); + + m_pszBuffer=pszSrc; + m_tBufSize=tLen; + m_wFlags &= ~SDF_UNICODE; +} + +#ifdef ALLOW_UNICODE +/** Assigns a new string buffer to this data object. If there was any other + * buffer allocated - it's freed before assign. + * \param[in] pszSrc - buffer with the source string + * \param[in] tLen - size of the buffer to be assigned (may be greater than the string length) + * \note The tLen param should include the termination null character + */ +void str_data::assign(wchar_t* pszSrc, size_t tLen) +{ + assert(m_wRefCount == 1); + + // make sure the buffer is freed + free_buffer(); + + m_pszBuffer=(char_t*)pszSrc; + m_tBufSize=tLen; + m_wFlags |= SDF_UNICODE; +} +#endif + +/** Standard constructor - allocates the underlying data object + */ +string::string() +{ + m_psd=new str_data(SDF_NONE); +} + +/** Constructor allocates the underlying data object and initializes it with + * a given ansi string. + * \param[in] pszStr - source ansi string + */ +string::string(const char_t* pszStr) +{ + m_psd=new str_data(SDF_NONE); + set_str(pszStr); +} + +#ifdef ALLOW_UNICODE +/** Constructor allocates the underlying data object and initializes it with + * a given unicode string. + * \param[in] pszStr - source unicode string + */ +string::string(const wchar_t* pszStr) +{ + m_psd=new str_data(SDF_UNICODE); + set_str(pszStr); +} +#endif + +/** Constructor increases the reference count in the parameter's data object + * and copies only the data object address. + * \param[in] str - source string object + */ +string::string(const string& str) +{ + m_psd=str.m_psd; + m_psd->inc_refcount(); +} + +/** Destructor releases the underlying data object. + */ +string::~string() +{ + release_data(); +} + +/** Operator releases the current data object, stores a pointer to + * the data object from the given string object and increases a reference + * count. + * \param[in] src - source string object + * \return A reference to the current string. + */ +const string& string::operator=(const string& src) +{ + release_data(); + m_psd=src.m_psd; + m_psd->inc_refcount(); + + return *this; +} + +/** Operator makes an own copy of underlying data object (if needed) and copy + * there given ansi string. + * \param[in] pszSrc - source ansi string + * \return A reference to the current string object. + */ +const string& string::operator=(const char_t* pszSrc) +{ + set_str(pszSrc); + + return *this; +} + +#ifdef ALLOW_UNICODE +/** Operator makes an own copy of underlying data object (if needed) and copy + * there the given unicode string. + * \param[in] pszSrc - source unicode string + * \return A reference to the current string object. + */ +const string& string::operator=(const wchar_t* pszSrc) +{ + set_str(pszSrc); + + return *this; +} +#endif + +/** Operator concatenates a given string object with the current content of + * this string and returns a new string object. + * \param[in] src - string object that will be appended + * \return A new string object with concatenated strings. + */ +const string string::operator+(const string& src) const +{ + string str(*this); + str.merge(src); + + return str; +} + +/** Operator concatenates a given ansi string with the current content of + * this string and returns a new string object. + * \param[in] pszSrc - ansi string that will be appended + * \return A new string object with concatenated strings. + */ +const string string::operator+(const char_t* pszSrc) const +{ + string str(*this); + str.merge(pszSrc); + + return str; +} + +#ifdef ALLOW_UNICODE +/** Operator concatenates a given unicode string with the current content of + * this string and returns a new string object. + * \param[in] pszSrc - unicode string that will be appended + * \return A new string object with concatenated strings. + */ +const string string::operator+(const wchar_t* pszSrc) const +{ + string str(*this); + str.merge(pszSrc); + + return str; +} +#endif + +/** Operator appends a given string object to own internal buffer. + * \param[in] src - string object that will be appended + * \return A reference to this. + */ +const string& string::operator+=(const string& src) +{ + merge(src); + return *this; +} + +/** Operator appends a given ansi string to own internal buffer. + * \param[in] pszSrc - ansi string that will be appended + * \return A reference to this. + */ +const string& string::operator+=(const char_t* pszSrc) +{ + merge(pszSrc); + return *this; +} + +#ifdef ALLOW_UNICODE +/** Operator appends a given unicode string to own internal buffer. + * \param[in] pszSrc - unicode string that will be appended + * \return A reference to this. + */ +const string& string::operator+=(const wchar_t* pszSrc) +{ + merge(pszSrc); + return *this; +} +#endif + +/** Function counts the length of a string in characters (doesn't matter if the string + * is unicode or ansi). + * \note All length checks should be done through this function, because of possible future + * update that will store the string length in the internal member. + * \return The string length in characters, not including the terminating '\\0' + */ +size_t string::length() const +{ + return m_psd->length(); +} + +/** Function calculates the string length using length() function, but outputs + * the string length in bytes instead of characters. + * \return The string length in bytes (including the terminating null character). + */ +size_t string::bytelen() const +{ + return m_psd->bytelen(); +} + +/** Function makes own data object writable and clears it. Does not delete the + * internal buffer - only sets the content to '\\0'. + */ +void string::clear() +{ + // make sure we have the modifiable object without allocated string buffer + make_writable(MWF_DELETE); +} + +/** Function checks if the string is empty. + * \return True if this string is empty, false otherwise. + */ +bool string::is_empty() const +{ + assert(m_psd != NULL); + + return (m_psd->m_pszBuffer == NULL) || (m_psd->m_pszBuffer[0] == '\0' +#ifdef ALLOW_UNICODE + && (!(m_psd->m_wFlags & SDF_UNICODE) || m_psd->m_pszBuffer[1] == '\0') +#endif + ); +} + +/** Function merges the given ansi string with the current content of an internal buffer. + * \param[in] pszSrc - ansi string to append + */ +void string::merge(const char_t* pszSrc) +{ + assert(pszSrc); + + make_writable(MWF_COPY); + + // append the second +#ifdef ALLOW_UNICODE + if (m_psd->m_wFlags & SDF_UNICODE) + { + // convert ansi->wide and append it to this + wchar_t *psz=NULL; + if (convert_to_unicode(pszSrc, &psz) > 0) + { + // how much memory do we need ? + size_t tLen=length()+wcslen(psz)+1; + tLen=ROUNDUP(tLen, CHUNK_INCSIZE); + + m_psd->resize_buffer_check(tLen, true); + wcscat((wchar_t*)m_psd->m_pszBuffer, psz); + } + delete [] psz; + } + else + { +#endif + size_t tLen=length()+strlen(pszSrc)+1; + tLen=ROUNDUP(tLen, CHUNK_INCSIZE); + + m_psd->resize_buffer_check(tLen, true); + strcat(m_psd->m_pszBuffer, pszSrc); +#ifdef ALLOW_UNICODE + } +#endif +} + +#ifdef ALLOW_UNICODE +/** Function merges the given unicode string with the current content of an internal buffer. + * \param[in] pszSrc - unicode string to append + */ +void string::merge(const wchar_t* pszSrc) +{ + assert(pszSrc); + + // make string unicode so we don't lose any unicode character when adding new string + make_unicode(); + + // append + size_t tLen=length()+wcslen(pszSrc)+1; + tLen=ROUNDUP(tLen, CHUNK_INCSIZE); + + m_psd->resize_buffer_check(tLen, true); + wcscat((wchar_t*)m_psd->m_pszBuffer, pszSrc); +} +#endif + +/** Function merges the given string object with the current content of an internal buffer. + * \param[in] src - string object to append + */ +void string::merge(const string& src) +{ + make_writable(MWF_COPY); + + size_t tLen=src.length(); + if (tLen > 0) + { + tLen+=length()+1; + tLen=ROUNDUP(tLen, CHUNK_INCSIZE); + + // append the second +#ifdef ALLOW_UNICODE + if (m_psd->m_wFlags & SDF_UNICODE) + { + // resize buffer a bit + m_psd->resize_buffer_check(tLen, true); + + if (src.m_psd->m_wFlags & SDF_UNICODE) + wcscat((wchar_t*)m_psd->m_pszBuffer, (wchar_t*)src.m_psd->m_pszBuffer); + else + { + // convert ansi->wide and append it to this + wchar_t *psz=NULL; + if (convert_to_unicode(src.m_psd->m_pszBuffer, &psz) > 0) + wcscat((wchar_t*)m_psd->m_pszBuffer, psz); + delete [] psz; + } + } + else + { + if (src.m_psd->m_wFlags & SDF_UNICODE) + { + // source is unicode and this is ansi string - make this unicode not to lose any unicode char_t + make_unicode(); + + m_psd->resize_buffer_check(tLen, true); + + wcscat((wchar_t*)m_psd->m_pszBuffer, (wchar_t*)src.m_psd->m_pszBuffer); + } + else + { +#endif + m_psd->resize_buffer_check(tLen, true); + strcat(m_psd->m_pszBuffer, src.m_psd->m_pszBuffer); +#ifdef ALLOW_UNICODE + } + } +#endif + } +} + +/** Returns a new string object with the left part of this string object. + * \param[in] tLen - count of characters to copy to the new string object + * \return The string with the left part of the current string. + */ +string string::left(size_t tLen) const +{ + string str; + size_t tStrLen=length(); + tStrLen=minval(tStrLen, tLen); + +#ifdef ALLOW_UNICODE + if (is_unicode()) + { + str.make_unicode(); + str.m_psd->resize_buffer_check(ROUNDUP(tStrLen+1, CHUNK_INCSIZE), false); + wcsncpy((wchar_t*)str.m_psd->m_pszBuffer, (wchar_t*)m_psd->m_pszBuffer, tStrLen); + ((wchar_t*)str.m_psd->m_pszBuffer)[tStrLen]=L'\0'; + } + else + { +#endif + str.m_psd->resize_buffer_check(ROUNDUP(tStrLen+1, CHUNK_INCSIZE), false); + strncpy(str.m_psd->m_pszBuffer, m_psd->m_pszBuffer, tStrLen); + str.m_psd->m_pszBuffer[tStrLen]='\0'; +#ifdef ALLOW_UNICODE + } +#endif + return str; +} + +/** Returns a new string object with the right part of this string object. + * \param[in] tLen - count of characters to copy to the new string object + * \return The string with the right part of the current string. + */ +string string::right(size_t tLen) const +{ + size_t tFullLen=length(); + size_t tStrLen=minval(tFullLen, tLen); + string str; +#ifdef ALLOW_UNICODE + if (is_unicode()) + { + str.make_unicode(); + str.m_psd->resize_buffer_check(ROUNDUP(tStrLen+1, CHUNK_INCSIZE), false); + wcsncpy((wchar_t*)str.m_psd->m_pszBuffer, ((wchar_t*)m_psd->m_pszBuffer)+tFullLen-tStrLen, tStrLen+1); + } + else + { +#endif + str.m_psd->resize_buffer_check(ROUNDUP(tStrLen+1, CHUNK_INCSIZE), false); + strncpy(str.m_psd->m_pszBuffer, m_psd->m_pszBuffer+tFullLen-tStrLen, tStrLen+1); +#ifdef ALLOW_UNICODE + } +#endif + + return str; +} + +/** Returns a new string object with the middle part of this string object. + * \param[in] tStart - position of the first character to copy + * \param[in] tLen - count of chars to copy + * \return The string with the middle part of the current string. + */ +string string::mid(size_t tStart, size_t tLen) const +{ + string str; + size_t tStrLen=length(); + + assert(tStart < tStrLen); // make sure we start at the right place + + // check the count + if (tLen > tStrLen-tStart) + tLen=tStrLen-tStart; + +#ifdef ALLOW_UNICODE + if (is_unicode()) + { + str.make_unicode(); + str.m_psd->resize_buffer_check(ROUNDUP(tLen, CHUNK_INCSIZE), false); + wcsncpy((wchar_t*)str.m_psd->m_pszBuffer, ((wchar_t*)m_psd->m_pszBuffer)+tStart, tLen); + ((wchar_t*)str.m_psd->m_pszBuffer)[tStrLen]=L'\0'; + } + else + { +#endif + str.m_psd->resize_buffer_check(ROUNDUP(tLen, CHUNK_INCSIZE), false); + strncpy(str.m_psd->m_pszBuffer, m_psd->m_pszBuffer+tStart, tLen); + (str.m_psd->m_pszBuffer)[tStrLen]='\0'; +#ifdef ALLOW_UNICODE + } +#endif + + return str; +} + +/** Makes this string it's left part. Much faster than using standard + * left() function. + * \param[in] tLen - count of characters at the beginning of the string to be left in a string. + * \param[in] bReallocBuffer - if the internal string buffer is to be reallocated if exceeds + * the allowable range size (CHUNK_INCSIZE, CHUNK_DECSIZE). + * \see left() + */ +void string::left_self(size_t tLen, bool bReallocBuffer) +{ + assert(tLen <= length()); + + // insert the '\0' at the requested position +#ifdef ALLOW_UNICODE + if (is_unicode()) + ((wchar_t*)m_psd->m_pszBuffer)[tLen]=L'\0'; + else +#endif + m_psd->m_pszBuffer[tLen]='\0'; + + if (bReallocBuffer) + m_psd->resize_buffer_check(ROUNDUP(tLen, CHUNK_INCSIZE), true); +} + +/** Makes this string it's right part. Much faster than using standard + * right() function. + * \param[in] tLen - count of characters at the end of the string to be left in a string. + * \param[in] bReallocBuffer - if the internal string buffer is to be reallocated if exceeds + * the allowable range size (CHUNK_INCSIZE, CHUNK_DECSIZE). + * \see right() + */ +void string::right_self(size_t tLen, bool bReallocBuffer) +{ + size_t tStrLen=length(); + assert(tLen <= tStrLen); + +#ifdef ALLOW_UNICODE + if (is_unicode()) + wmemmove((wchar_t*)m_psd->m_pszBuffer, ((wchar_t*)m_psd->m_pszBuffer)+tStrLen-tLen, tLen+1); + else +#endif + memmove(m_psd->m_pszBuffer, m_psd->m_pszBuffer+tStrLen-tLen, tLen+1); + + if (bReallocBuffer) + m_psd->resize_buffer_check(ROUNDUP(tLen, CHUNK_INCSIZE), true); +} + +/** Makes this string it's middle part. Much faster than using standard + * mid() function. + * \param[in] tStart - starting position of a text to be left in a string + * \param[in] tLen - count of characters at the middle of the string to be left in a string. + * \param[in] bReallocBuffer - if the internal string buffer is to be reallocated if exceeds + * the allowable range size (CHUNK_INCSIZE, CHUNK_DECSIZE). + * \see mid() + */ +void string::mid_self(size_t tStart, size_t tLen, bool bReallocBuffer) +{ + size_t tStrLen=length(); + assert(tStart < tStrLen); + + // check the count + if (tLen > tStrLen-tStart) + tLen=tStrLen-tStart; + +#ifdef ALLOW_UNICODE + if (is_unicode()) + { + wmemmove((wchar_t*)m_psd->m_pszBuffer, ((wchar_t*)m_psd->m_pszBuffer)+tStart, tLen); + ((wchar_t*)m_psd->m_pszBuffer)[tLen]=L'\0'; + } + else + { +#endif + memmove(m_psd->m_pszBuffer, m_psd->m_pszBuffer+tStart, tLen); + m_psd->m_pszBuffer[tLen]='\0'; +#ifdef ALLOW_UNICODE + } +#endif + if (bReallocBuffer) + m_psd->resize_buffer_check(ROUNDUP(tLen, CHUNK_INCSIZE), true); +} + +/** Compares a string with the given ansi string. Comparison is case sensitive. + * \param[in] psz - ansi string to which the string object will be compared + * \return <0 if this string object is "less" than psz, 0 if they are equal and >0 otherwise. + */ +int_t string::cmp(const char_t* psz) const +{ + assert(psz); + +#ifdef ALLOW_UNICODE + if (m_psd->m_wFlags & SDF_UNICODE) + { + char_t* pszConv=NULL; + int_t iRes=-1; + if (convert_to_ansi((wchar_t*)m_psd->m_pszBuffer, &pszConv) > 0) + iRes=strcmp(psz, pszConv); + + delete [] pszConv; + + return iRes; + } + else + { +#endif + return strcmp(m_psd->m_pszBuffer, psz); +#ifdef ALLOW_UNICODE + } +#endif +} + +#ifdef ALLOW_UNICODE +/** Compares a string with the given unicode string. Comparison is case sensitive. + * \param[in] psz - unicode string to which the string object will be compared + * \return <0 if this string object is "less" than psz, 0 if they are equal and >0 otherwise. + */ +int_t string::cmp(const wchar_t* psz) const +{ + assert(psz); + + if (m_psd->m_wFlags & SDF_UNICODE) + { + return wcscmp((wchar_t*)m_psd->m_pszBuffer, psz); + } + else + { + char_t* pszConv=NULL; + int_t iRes=-1; + if (convert_to_ansi(psz, &pszConv) > 0) + iRes=strcmp(m_psd->m_pszBuffer, pszConv); + + delete [] pszConv; + + return iRes; + } +} +#endif + +/** Compares a string with the given string object. Comparison is case sensitive. + * \param[in] str - string object to which internal string object will be compared + * \return <0 if this string object is "less" than psz, 0 if they are equal and >0 otherwise. + */ +int_t string::cmp(const string& str) const +{ +#ifdef ALLOW_UNICODE + if (str.is_unicode()) + { + if (is_unicode()) + { + // both strings unicode + return wcscmp((wchar_t*)str.m_psd->m_pszBuffer, (wchar_t*)m_psd->m_pszBuffer); + } + else + { + // only the external string is unicode + char_t* pszConv=NULL; + int_t iRes=-1; + if (convert_to_ansi((wchar_t*)str.m_psd->m_pszBuffer, &pszConv) > 0) + iRes=strcmp(pszConv, m_psd->m_pszBuffer); + + delete [] pszConv; + + return iRes; + } + } + else + { + if (is_unicode()) + { + // only internal string unicode + char_t* pszConv=NULL; + int_t iRes=-1; + if (convert_to_ansi((wchar_t*)m_psd->m_pszBuffer, &pszConv) > 0) + iRes=strcmp(pszConv, str.m_psd->m_pszBuffer); + + delete [] pszConv; + + return iRes; + } + else + { +#endif + // both string ansi + return strcmp(str.m_psd->m_pszBuffer, m_psd->m_pszBuffer); +#ifdef ALLOW_UNICODE + } + } +#endif +} + +/** Compares a string with the given ansi string. Comparison is case insensitive. + * \param[in] psz - ansi string to which internal string object will be compared + * \return <0 if this string object is "less" than psz, 0 if they are equal and >0 otherwise. + */ +int_t string::cmpi(const char_t* psz) const +{ + assert(psz); + +#ifdef ALLOW_UNICODE + if (m_psd->m_wFlags & SDF_UNICODE) + { + char_t* pszConv=NULL; + int_t iRes=-1; + if (convert_to_ansi((wchar_t*)m_psd->m_pszBuffer, &pszConv) > 0) + iRes=stricmp(psz, pszConv); + + delete [] pszConv; + + return iRes; + } + else + { +#endif + return stricmp(m_psd->m_pszBuffer, psz); +#ifdef ALLOW_UNICODE + } +#endif +} + +#ifdef ALLOW_UNICODE +/** Compares a string with the given unicode string. Comparison is case insensitive. + * \param[in] psz - unicode string to which internal string object will be compared + * \return <0 if this string object is "less" than psz, 0 if they are equal and >0 otherwise. + */ +int_t string::cmpi(const wchar_t* psz) const +{ + assert(psz); + + if (m_psd->m_wFlags & SDF_UNICODE) + { + return wcsicmp((wchar_t*)m_psd->m_pszBuffer, psz); + } + else + { + char_t* pszConv=NULL; + int_t iRes=-1; + if (convert_to_ansi(psz, &pszConv) > 0) + iRes=stricmp(m_psd->m_pszBuffer, pszConv); + + delete [] pszConv; + + return iRes; + } +} +#endif + +/** Compares a string with the given string object. Comparison is case insensitive. + * \param[in] str - string object to which internal string object will be compared + * \return <0 if this string object is "less" than str, 0 if they are equal and >0 otherwise. + */ +int_t string::cmpi(const string& str) const +{ +#ifdef ALLOW_UNICODE + if (str.is_unicode()) +{ + if (is_unicode()) + { + // both strings unicode + return wcsicmp((wchar_t*)str.m_psd->m_pszBuffer, (wchar_t*)m_psd->m_pszBuffer); + } + else + { + // only the external string is unicode + char_t* pszConv=NULL; + int_t iRes=-1; + if (convert_to_ansi((wchar_t*)str.m_psd->m_pszBuffer, &pszConv) > 0) + iRes=stricmp(pszConv, m_psd->m_pszBuffer); + + delete [] pszConv; + + return iRes; + } +} + else +{ + if (is_unicode()) + { + // only internal string unicode + char_t* pszConv=NULL; + int_t iRes=-1; + if (convert_to_ansi((wchar_t*)m_psd->m_pszBuffer, &pszConv) > 0) + iRes=stricmp(pszConv, str.m_psd->m_pszBuffer); + + delete [] pszConv; + + return iRes; + } + else + { +#endif + // both string ansi + return stricmp(str.m_psd->m_pszBuffer, m_psd->m_pszBuffer); +#ifdef ALLOW_UNICODE + } +} +#endif +} + +/** Function compares a given count of characters of own internal buffer content + * with a given ansi string. Comparison is case sensitive. + * \param[in] psz - ansi string to compare + * \param[in] tLen - count of characters to compare (-1 to detect shorter string) + * \param[in] bLenCheck - causes the function to check if the len given as a param + * is valid (if not then -2 is returned) + * \return <0 if this string object is "less" than str, 0 if they are equal and >0 otherwise. + * \note Do not use tLen=-1 and bLenCheck=true - it will degrade performance. + */ +int_t string::cmpn(const char_t* psz, size_t tLen, bool bLenCheck) const +{ + assert(psz); + + // if len is -1 then set len to the shorter len + if (tLen == (size_t)-1) + { + tLen=length(); + size_t t=strlen(psz); + if (tLen > t) + tLen=t; + } + + // make a length check to avoid running out of range + if (bLenCheck && (tLen > length() || tLen > strlen(psz))) + return -2; + +#ifdef ALLOW_UNICODE + if (m_psd->m_wFlags & SDF_UNICODE) + { + char_t* pszConv=NULL; + int_t iRes=-2; + if (convert_to_ansi((wchar_t*)m_psd->m_pszBuffer, &pszConv) > 0) + iRes=strncmp(psz, pszConv, tLen); + + delete [] pszConv; + + return iRes; + } + else + { +#endif + return strncmp(m_psd->m_pszBuffer, psz, tLen); +#ifdef ALLOW_UNICODE + } +#endif +} + +#ifdef ALLOW_UNICODE +/** Function compares a given count of characters of own internal buffer content + * with a given unicode string. Comparison is case sensitive. + * \param[in] psz - unicode string to compare + * \param[in] tLen - count of characters to compare (-1 to detect shorter string) + * \param[in] bLenCheck - causes the function to check if the len given as a param + * is valid (if not then -2 is returned) + * \return <0 if this string object is "less" than psz, 0 if they are equal and >0 otherwise. + */ +int_t string::cmpn(const wchar_t* psz, size_t tLen, bool bLenCheck) const +{ + assert(psz); + + // if len is -1 then set len to the shorter len + if (tLen == (size_t)-1) + { + tLen=length(); + size_t t=wcslen(psz); + if (tLen > t) + tLen=t; + } + + // make a length check to avoid running out of range + if (bLenCheck && (tLen > length() || tLen > wcslen(psz))) + return -2; + + if (m_psd->m_wFlags & SDF_UNICODE) + { + return wcsncmp((wchar_t*)m_psd->m_pszBuffer, psz, tLen); + } + else + { + char_t* pszConv=NULL; + int_t iRes=-2; + if (convert_to_ansi(psz, &pszConv) > 0) + iRes=strncmp(m_psd->m_pszBuffer, pszConv, tLen); + + delete [] pszConv; + + return iRes; + } +} +#endif + +/** Function compares a given count of characters of own internal buffer content + * with a given string object. Comparison is case sensitive. + * \param[in] str - string object to compare + * \param[in] tLen - count of characters to compare (-1 to detect shorter string) + * \param[in] bLenCheck - causes the function to check if the len given as a param + * is valid (if not then -2 is returned) + * \return <0 if this string object is "less" than str, 0 if they are equal and >0 otherwise. + */ +int_t string::cmpn(const string& str, size_t tLen, bool bLenCheck) const +{ + // if len is -1 then set len to the shorter len + if (tLen == (size_t)-1) + { + tLen=length(); + size_t t=str.length(); + if (tLen > t) + tLen=t; + } + + // make a length check to avoid running out of range + if (bLenCheck && (tLen > length() || tLen > str.length())) + return -2; + +#ifdef ALLOW_UNICODE + if (str.is_unicode()) + { + if (is_unicode()) + { + // both strings unicode + return wcsncmp((wchar_t*)str.m_psd->m_pszBuffer, (wchar_t*)m_psd->m_pszBuffer, tLen); + } + else + { + // only the external string is unicode + char_t* pszConv=NULL; + int_t iRes=-2; + if (convert_to_ansi((wchar_t*)str.m_psd->m_pszBuffer, &pszConv) > 0) + iRes=strncmp(pszConv, m_psd->m_pszBuffer, tLen); + + delete [] pszConv; + + return iRes; + } + } + else + { + if (is_unicode()) + { + // only internal string unicode + char_t* pszConv=NULL; + int_t iRes=-2; + if (convert_to_ansi((wchar_t*)m_psd->m_pszBuffer, &pszConv) > 0) + iRes=strncmp(pszConv, str.m_psd->m_pszBuffer, tLen); + + delete [] pszConv; + + return iRes; + } + else + { +#endif + // both string ansi + return strncmp(str.m_psd->m_pszBuffer, m_psd->m_pszBuffer, tLen); +#ifdef ALLOW_UNICODE + } + } +#endif +} + +/** Function compares a given count of characters of own internal buffer content + * with a given ansi string. Comparison is case insensitive. + * \param[in] psz - ansi string to compare + * \param[in] tLen - count of characters to compare (-1 to detect shorter string) + * \param[in] bLenCheck - causes the function to check if the len given as a param + * is valid (if not then -2 is returned) + * \return <0 if this string object is "less" than psz, 0 if they are equal and >0 otherwise. + */ +int_t string::cmpin(const char_t* psz, size_t tLen, bool bLenCheck) const +{ + assert(psz); + + // if len is -1 then set len to the shorter len + if (tLen == (size_t)-1) + { + tLen=length(); + size_t t=strlen(psz); + if (tLen > t) + tLen=t; + } + + // make a length check to avoid running out of range + if (bLenCheck && (tLen > length() || tLen > strlen(psz))) + return -2; + +#ifdef ALLOW_UNICODE + if (m_psd->m_wFlags & SDF_UNICODE) + { + char_t* pszConv=NULL; + int_t iRes=-1; + if (convert_to_ansi((wchar_t*)m_psd->m_pszBuffer, &pszConv) > 0) + iRes=strnicmp(psz, pszConv, tLen); + + delete [] pszConv; + + return iRes; + } + else + { +#endif + return strnicmp(m_psd->m_pszBuffer, psz, tLen); +#ifdef ALLOW_UNICODE + } +#endif +} + +#ifdef ALLOW_UNICODE +/** Function compares a given count of characters of own internal buffer content + * with a given unicode string. Comparison is case insensitive. + * \param[in] psz - unicode string to compare + * \param[in] tLen - count of characters to compare (-1 to detect shorter string) + * \param[in] bLenCheck - causes the function to check if the len given as a param + * is valid (if not then -2 is returned) + * \return <0 if this string object is "less" than psz, 0 if they are equal and >0 otherwise. + */ +int_t string::cmpin(const wchar_t* psz, size_t tLen, bool bLenCheck) const +{ + assert(psz); + + // if len is -1 then set len to the shorter len + if (tLen == (size_t)-1) + { + tLen=length(); + size_t t=wcslen(psz); + if (tLen > t) + tLen=t; + } + + // make a length check to avoid running out of range + if (bLenCheck && (tLen > length() || tLen > wcslen(psz))) + return -2; + + if (m_psd->m_wFlags & SDF_UNICODE) + { + return wcsnicmp((wchar_t*)m_psd->m_pszBuffer, psz, tLen); + } + else + { + char_t* pszConv=NULL; + int_t iRes=-1; + if (convert_to_ansi(psz, &pszConv) > 0) + iRes=strnicmp(m_psd->m_pszBuffer, pszConv, tLen); + + delete [] pszConv; + + return iRes; + } +} +#endif + +/** Function compares a given count of characters of own internal buffer content + * with a given string object. Comparison is case insensitive. + * \param[in] str - string object to compare + * \param[in] tLen - count of characters to compare (-1 to detect shorter string) + * \param[in] bLenCheck - causes the function to check if the len given as a param + * is valid (if not then -2 is returned) + * \return <0 if this string object is "less" than str, 0 if they are equal and >0 otherwise. + */ +int_t string::cmpin(const string& str, size_t tLen, bool bLenCheck) const +{ + // if len is -1 then set len to the shorter len + if (tLen == (size_t)-1) + { + tLen=length(); + size_t t=str.length(); + if (tLen > t) + tLen=t; + } + + // make a length check to avoid running out of range + if (bLenCheck && (tLen > length() || tLen > str.length())) + return -2; + +#ifdef ALLOW_UNICODE + if (str.is_unicode()) + { + if (is_unicode()) + { + // both strings unicode + return wcsnicmp((wchar_t*)str.m_psd->m_pszBuffer, (wchar_t*)m_psd->m_pszBuffer, tLen); + } + else + { + // only the external string is unicode + char_t* pszConv=NULL; + int_t iRes=-1; + if (convert_to_ansi((wchar_t*)str.m_psd->m_pszBuffer, &pszConv) > 0) + iRes=strnicmp(pszConv, m_psd->m_pszBuffer, tLen); + + delete [] pszConv; + + return iRes; + } + } + else + { + if (is_unicode()) + { + // only internal string unicode + char_t* pszConv=NULL; + int_t iRes=-1; + if (convert_to_ansi((wchar_t*)m_psd->m_pszBuffer, &pszConv) > 0) + iRes=strnicmp(pszConv, str.m_psd->m_pszBuffer, tLen); + + delete [] pszConv; + + return iRes; + } + else + { +#endif + // both string ansi + return strnicmp(str.m_psd->m_pszBuffer, m_psd->m_pszBuffer, tLen); +#ifdef ALLOW_UNICODE + } + } +#endif +} + +/** Returns a character at a given position. Function is very slow (needs to recalc the size of the string + * and make a few comparisons), but quite safe - if the index is out of range then -1 is returned. + * Make sure to interpret the returned character according to unicode flag. If the string is unicode, then the + * character returned is also unicode (and vice versa). + * \param[in] tPos - index of the character to return. + * \return Character code of character on a specified position, or -1 if out of range. + */ +int_t string::at(size_t tPos) const +{ + size_t tSize=length(); // very slow +#ifdef ALLOW_UNICODE + if (is_unicode()) + { + if (tPos < tSize && tPos >=0) + return (int_t)(((wchar_t*)m_psd->m_pszBuffer)[tPos]); + else + return -1; + } + else + { +#endif + if (tPos < tSize && tPos >=0) + return (int_t)(((char_t*)m_psd->m_pszBuffer)[tPos]); + else + return -1; +#ifdef ALLOW_UNICODE + } +#endif +} + +/** Returns a pointer to the ansi internal buffer. If the buffer is in unicode format + * then NULL value is returned. Internal buffer is resized to the specified value + * if currently smaller than requested (if -1 is specified as tMinSize then the buffer + * is not resized, and the return value could be NULL). + * \param[in] tMinSize - requested minimal size of the internal buffer (-1 if the size is not to be changed). + * \return Pointer to the internal ansi buffer. + */ +char_t* string::get_buffera(size_t tMinSize) +{ +#ifdef ALLOW_UNICODE + assert(!(m_psd->m_wFlags & SDF_UNICODE)); + + if (m_psd->m_wFlags & SDF_UNICODE) + return NULL; +#endif + + // resize buffer if needed + if (tMinSize != (size_t)-1 && tMinSize > m_psd->m_tBufSize) + m_psd->resize_buffer_check(ROUNDUP(tMinSize, CHUNK_INCSIZE), true); + + return m_psd->m_pszBuffer; +} + +#ifdef ALLOW_UNICODE +/** Returns a pointer to the unicode internal buffer. If the buffer is in ansi format + * then NULL value is returned. Internal buffer is resized to the specified value + * if currently smaller than requested (if -1 is specified as tMinSize then the buffer + * is not resized, and the return value could be NULL). + * \param[in] tMinSize - requested minimal size of the internal buffer (-1 if the size of the string should not be changed) + * \return Pointer to the internal unicode buffer. + */ +wchar_t* string::get_bufferu(size_t tMinSize) +{ + assert(m_psd->m_wFlags & SDF_UNICODE); + + if (!(m_psd->m_wFlags & SDF_UNICODE)) + return NULL; + + if (tMinSize != (size_t)-1 && tMinSize > m_psd->m_tBufSize) + m_psd->resize_buffer_check(ROUNDUP(tMinSize, CHUNK_INCSIZE), true); + + return (wchar_t*)m_psd->m_pszBuffer; +} +#endif + +/** Releases buffer got by user by calling get_bufferx functions. The current + * job of this function is to make sure the string will terminate with null + * character at the end of the buffer. + */ +void string::release_buffer() +{ + // just to make sure user does not crash everything +#ifdef ALLOW_UNICODE + if (is_unicode()) + ((wchar_t*)m_psd->m_pszBuffer)[m_psd->m_tBufSize-1]=L'\0'; + else +#endif + m_psd->m_pszBuffer[m_psd->m_tBufSize-1]='\0'; +} + +#ifdef ALLOW_UNICODE +/** Converts the internal buffer contents to the unicode format (if not already + * unicode). + */ +void string::make_unicode() +{ + if (!is_unicode()) + { + // make a string conversion + if (m_psd->m_pszBuffer) + { + wchar_t* pszOut; + size_t tSize=convert_to_unicode(m_psd->m_pszBuffer, &pszOut); + + // delete the current buffer + make_writable(MWF_DELETE); + + // assign a new buffer + m_psd->assign(pszOut, tSize); + } + else + m_psd->switch_unicode(); + } +} + +/** Converts the internal buffer contents to the ansi format (if not already + * ansi). + */ +void string::make_ansi() +{ + if (is_unicode()) + { + if (m_psd->m_pszBuffer) + { + // make a string conversion + char_t* pszOut; + size_t tSize=convert_to_ansi((wchar_t*)m_psd->m_pszBuffer, &pszOut); + + // delete the current buffer + make_writable(MWF_DELETE); + + // assign a new buffer + m_psd->assign(pszOut, tSize); + } + else + m_psd->switch_ansi(); + } +} +#endif + +/** Dumps internal contents of this class. + * \param[in] pctx - dump context to receive object info + */ +void string::dump(dumpctx* pctx) +{ + pctx->open("string"); + pctx->dump("m_psd", (ptr_t)m_psd); +#ifdef ALLOW_UNICODE + if (is_unicode()) + pctx->dump("m_psd->m_pszBuffer [unicode]", (wchar_t*)m_psd->m_pszBuffer); + else +#endif + pctx->dump("m_psd->m_pszBuffer [ansi]", m_psd->m_pszBuffer); + + pctx->dump("m_psd->m_tBufSize", (longlong_t)m_psd->m_tBufSize); + pctx->dump("m_psd->m_wRefCount", m_psd->m_wRefCount); + pctx->dump("m_psd->m_wFlags", m_psd->m_wFlags); + pctx->close(); +} + +/** Displays the string contents on screen using standard printf() function. The format of displayed + * string is either ansi("string_content") or unicode("string_content"). + */ +void string::print() +{ +#ifdef ALLOW_UNICODE + if (is_unicode()) + printf("unicode(\"" WSTRFMT "\")", (wchar_t*)m_psd->m_pszBuffer); + else +#endif + printf("ansi(\"" STRFMT "\")", (char_t*)m_psd->m_pszBuffer); +} + +/** Cast operator - tries to return a pointer to char_t* using the current internal + * buffer. If the internal buffer is in unicode format, then the debug version asserts + * and release return NULL. + * \return Pointer to an ansi string (could be null). + */ +string::operator const char_t*() const +{ + if (m_psd->m_pszBuffer) + { +#ifdef ALLOW_UNICODE + if (m_psd->m_wFlags & SDF_UNICODE) + { + // what to do here - convert using external buffer or assert ? + assert(false); // cannot cast unicode string to the ansi one using operator + return NULL; + } + else +#endif + return m_psd->m_pszBuffer; + } + else + return ""; +} + +#ifdef ALLOW_UNICODE +/** Cast operator - tries to return a pointer to wchar_t* using the current internal + * buffer. If the internal buffer is in ansi format, then the debug version asserts + * and release return NULL. + * \return Pointer to an unicode string (could be null). + */ +string::operator const wchar_t*() const +{ + if (m_psd->m_pszBuffer) + { + if (m_psd->m_wFlags & SDF_UNICODE) + return (wchar_t*)m_psd->m_pszBuffer; + else + { + assert(false); // cannot cast ansi string to unicode using operator + return NULL; + } + } + else + return L""; +} +#endif + +#ifdef ALLOW_UNICODE +/** Function converts unicode string into the ansi one. The output buffer is + * allocated by this function and needs to be deleted by user. + * \param[in] pszIn - unicode string to be converted + * \param[out] pszOut - ptr to the char_t* that will receive new buffer's address + * \return Size of the output string (including the terminating '\\0' character). + * \todo Add detecting default system charset (linux) instead of hard-coding iso8859-2. + */ +size_t string::convert_to_ansi(const wchar_t* pszIn, char_t** pszOut) +{ + assert(pszIn && pszOut); + +#ifdef _WIN32 + size_t tLen; + if ( (tLen=WideCharToMultiByte(CP_ACP, 0, pszIn, -1, NULL, 0, NULL, NULL)) != 0 ) + { + *pszOut=new char_t[tLen]; + return WideCharToMultiByte(CP_ACP, 0, pszIn, -1, *pszOut, (int_t)tLen, NULL, NULL); + } + else + { + *pszOut=NULL; + return 0; + } +#else + // FIXME: the destination charset should be the default system one and not hard-coded iso8859-2 + // NOTE: do not use this func to convert strings from/to a file (especially on gnu linux + // where unicode (wchar_t) characters has 4 bytes instead of 2 + iconv_t it=iconv_open("ISO8859-2", "WCHAR_T"); + + // alloc some memory + size_t tOutLen=wcslen(pszIn)+1, tInLen=tOutLen*sizeof(wchar_t); + size_t tTotal=tOutLen; + char_t* psz=new char_t[tInLen], *pszStart=psz; + + if (iconv(it, (char_t**)&pszIn, &tInLen, (char_t**)&psz, &tOutLen) != (size_t)-1) + { + // close conversion object + iconv_close(it); + + // store ptr + *pszOut=pszStart; + return tTotal-tOutLen; + } + else + { + // close conversion object + iconv_close(it); + + // return nothing + delete [] psz; + *pszOut=NULL; + return 0; + } +#endif +} + +/** Function converts ansi string into the unicode one. The output buffer is + * allocated by this function and needs to be deleted by user. + * \param[in] pszIn - ansi string to be converted + * \param[out] pszOut - ptr to the wchar_t* that will receive new buffer's address + * \return Size of the output string (including the terminating '\\0' character). + * \todo Add detecting default system charset (linux) instead of hard-coding iso8859-2. + */ +size_t string::convert_to_unicode(const char_t* pszIn, wchar_t** pszOut) +{ + assert(pszIn && pszOut); + +#ifdef _WIN32 + size_t tLen; + if ( (tLen=MultiByteToWideChar(CP_ACP, 0, pszIn, -1, NULL, 0)) != 0 ) + { + *pszOut=new wchar_t[tLen]; + return MultiByteToWideChar(CP_ACP, 0, pszIn, -1, *pszOut, (int_t)tLen); + } + else + { + *pszOut=NULL; + return 0; + } +#else + // FIXME: correct the character set from hard-coded iso8859-2 to the native system's one + // NOTE: do not use to convert charsets when reading/writing to file + iconv_t it=iconv_open("WCHAR_T", "ISO8859-2"); + if (it == (iconv_t)-1) + { + *pszOut=NULL; + return 0; + } + + // alloc some memory + // NOTE: outlen is only inlen*sizeof(wchar_t) because of 4-byte wchar_t chars in gnu/linux + size_t tInLen=strlen(pszIn)+1, tOutLen=tInLen*sizeof(wchar_t); + size_t tTotal=tInLen; + wchar_t* psz=new wchar_t[tInLen], *pszStart=psz; + + if (iconv(it, (char_t**)&pszIn, &tInLen, (char_t**)&psz, &tOutLen) != (size_t)-1) + { + // close conversion object + iconv_close(it); + + // store the pointer + *pszOut=pszStart; + + return tTotal-tOutLen; + } + else + { + // close conversion handle + iconv_close(it); + + // return nothing + delete [] pszStart; + *pszOut=NULL; + return 0; + } +#endif +} +#endif + +/** Function makes the internal data object writable, copies the given ansi string into + * the internal string buffer and removes the unicode flag if needed. + * \param[in] pszStr - source ansi string + */ +void string::set_str(const char_t* pszStr) +{ + assert(pszStr); + + // make writable without allocating any buffer + make_writable(MWF_PARTIALDEL); + + // make sure the buffer is in ansi mode + m_psd->switch_ansi(); + + size_t tLen=strlen(pszStr)+1; // new str length + m_psd->resize_buffer_check(ROUNDUP(tLen, CHUNK_INCSIZE), false); + strcpy(m_psd->m_pszBuffer, pszStr); +} + +#ifdef ALLOW_UNICODE +/** Function makes the internal data object writable, copies the given unicode string into + * the internal string buffer and sets the unicode flag if needed. + * \param[in] pszStr - source unicode string + */ +void string::set_str(const wchar_t* pszStr) +{ + assert(pszStr); + + make_writable(MWF_PARTIALDEL); + m_psd->switch_unicode(); + + size_t tLen=wcslen(pszStr)+1; // new str length + m_psd->resize_buffer_check(ROUNDUP(tLen, CHUNK_INCSIZE), false); + wcscpy((wchar_t*)m_psd->m_pszBuffer, (wchar_t*)pszStr); +} +#endif + +/** Function prepares the internal data object to make any modifications to it. + * If the reference count of the underlying data object is greater than 1 (it means + * more than 1 string is using that object) the function makes an own copy of it, else + * nothing is done. + * \param[in] iType - type of making writable (MWF_*) + * \param[in] pParam - type dependent parameter + */ +void string::make_writable(int_t iType, ptr_t pParam) +{ + assert(m_psd->m_wRefCount > 0); + + // check if we need to make our own copy of data + if (m_psd->m_wRefCount > 1) + { + switch(iType) + { + case MWF_COPY: + { + // make a copy of the internal data object and set it as internal after releasing the old one + str_data* psd=m_psd->dup(); + release_data(); + m_psd=psd; + break; + } + case MWF_PARTIALDEL: + case MWF_DELETE: + { + // alloc only the internal data object and do not allocate the string buffer + str_data* psd=new str_data(m_psd->m_wFlags); + release_data(); + m_psd=psd; + break; + } + case MWF_NEW: + { + // alloc the new internal string data object and make there an empty string + str_data* psd=new str_data(m_psd->m_wFlags); + psd->resize_buffer_check(ROUNDUP((size_t)pParam, CHUNK_INCSIZE), false); + release_data(); + m_psd=psd; + } + default: + assert(false); // some strange flag + } + } + else + { + switch(iType) + { + case MWF_COPY: + { + // do nothing - the object is in requested state + break; + } + case MWF_DELETE: + { + // the thing to do is to delete the internal string without deleting the internal data object + m_psd->free_buffer(); + break; + } + case MWF_NEW: + { + // only resize the internal buffer + m_psd->resize_buffer_check(ROUNDUP((size_t)pParam, CHUNK_INCSIZE), false); + break; + } + case MWF_PARTIALDEL: + { + // left the string buffer as is + break; + } + default: + assert(false); // some strange flag + } + } +} + +/** Function releases the underlying data object. It means that reference count for + * that object is decreased and if the ref count is 0 - the object is freed. + */ +void string::release_data() +{ + if (m_psd->dec_refcount()) + delete m_psd; + m_psd=NULL; +} + +END_ICPF_NAMESPACE Index: ext/libicpf/src/str.h =================================================================== diff -u -N --- ext/libicpf/src/str.h (revision 0) +++ ext/libicpf/src/str.h (revision e17c80d36eaa0430313e7d1058aa7a301d1510af) @@ -0,0 +1,301 @@ +/*************************************************************************** + * Copyright (C) 2004 by J�zef Starosczyk * + * copyhandler@o2.pl * + * * + * This program 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 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 Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef __STR_H__ +#define __STR_H__ + +/** \file str.h + * \brief Contain string management classes + */ + +#include "libicpf.h" +#include "gen_types.h" +#include +#include "macros.h" + +#ifdef ALLOW_UNICODE + #include +#endif + +#ifndef _WIN32 + #include +#endif + +BEGIN_ICPF_NAMESPACE + +/// External class - to avoid inclusion of dumpctx.h +class dumpctx; + +/////////////////////////////////////////////////////////////// +// str_data flags +/// Standard string data flags +#define SDF_NONE 0x0000 + +/// The string is unicode +#define SDF_UNICODE 0x0001 + +////////////////////////////////////////////////////////////// +// make_writable flags +/// Standard - makes a copy of an underlying object if reference count >1 +#define MWF_COPY 0x00000000 +/// Causes the internal string buffer to be deleted +#define MWF_DELETE 0x00000001 +/// Causes new buffer to be allocated with a specified size (empty one) +#define MWF_NEW 0x00000002 +/** \brief Partial delete. + * + * If the object has to be allocated then it's done *without* allocating the internal buffer. + * Else the buffer is left as is. + */ +#define MWF_PARTIALDEL 0x00000003 + +/** \brief String storage class (helper) + * + * The class is used by the ch::string class as a helper that contains + * all of the string data. Allows to use the reference counting strings. + */ +class LIBICPF_API str_data +{ +public: +/** \name Construction/destruction */ +/*@{*/ + str_data(short_t wFlags); + ~str_data(); +/*@}*/ + +/** \name Operations */ +/*@{*/ + /// Increases reference count + void inc_refcount() { ++m_wRefCount; }; + + /** \brief Decreases refcount + * + * \return True when it's safe to delete this object or false if not. + */ + bool dec_refcount() { if (--m_wRefCount > 0) return false; else return true; }; + + // sizes the buffer with and wo size checking + void resize_buffer(size_t tNewSize, bool bCopy); ///< Changes the size of the internal buffer with size checking + void resize_buffer_check(size_t tNewSize, bool bCopy); ///< Changes the size of the internal string buffer without size checking + + // length checks + size_t length() const; ///< Returns the length of this string in chars (without terminating null character) + size_t bytelen() const; ///< Returns the length of a string in bytes (with terminating null character) + +#ifdef ALLOW_UNICODE + void switch_unicode(); ///< Changes the internal buffer type to unicode (nullifies the string) + void switch_ansi(); ///< Changes the internal buffer type to ansi (nullifies the string) +#endif + + + void assign(char_t* pszSrc, size_t tLen); ///< Assigns an ansi buffer as the internal string data +#ifdef ALLOW_UNICODE + void assign(wchar_t* pszSrc, size_t tLen); ///< Assigns an unicode buffer as the internal string data +#endif + + /// Frees the internal buffer + void free_buffer(); + + /// Duplicates this object + str_data* dup(); + +/*@}*/ + +public: + char_t* m_pszBuffer; ///< Contents of the string (could be the wchar_t*) + size_t m_tBufSize; ///< Size of the buffer (in chars, *NOT* bytes) + short_t m_wRefCount; ///< Reference count + short_t m_wFlags; ///< Flags +}; + +/////////////////////////////////////////////////////////////// +// string manipulation class +/** \brief String manipulation class + * + * Class allows user to manipulate string objects (either standard ANSI char_t* + * based strings or UNICODE ones - wchar_t related) with simple functions and + * operators. + */ +class LIBICPF_API string +{ +public: +/** \name Construction/destruction */ +/*@{*/ + string(); ///< Standard constructor + string(const char_t* pszStr); ///< Constructor that takes const char_t* as an initial string +#ifdef ALLOW_UNICODE + string(const wchar_t* pszStr); ///< Constructor that takes const wchar_t* as an initial string +#endif + string(const string& str); ///< Standard copy constructor + + ~string(); ///< Standard destructor +/*@}*/ + +/** \name Operators */ +/**@{*/ + // assignment + const string& operator=(const string& src); ///< Assign operator for string objects + const string operator+(const string& src) const; ///< Concatenate operator for string objects + const string& operator+=(const string& src); ///< Merge operator for string objects + + const string& operator=(const char_t* pszSrc); ///< Assign operator for ansi strings + const string operator+(const char_t* pszSrc) const; ///< Concatenate operator for ansi strings + const string& operator+=(const char_t* pszSrc); ///< Merge operator for ansi strings + +#ifdef ALLOW_UNICODE + const string& operator=(const wchar_t* pszSrc); ///< Assign operator from unicode strings + const string operator+(const wchar_t* pszSrc) const; ///< Concatenate operator for unicode strings + const string& operator+=(const wchar_t* pszSrc); ///< Merge operator for unicode strings +#endif + + // comparison + /// Makes case sensitive comparison to the ansi string ( see cmp(const char_t* psz) ) + bool operator<(const char_t* psz) const { return cmp(psz) < 0; }; + /// Makes case sensitive comparison to the ansi string ( see cmp(const char_t* psz) ) + bool operator<=(const char_t* psz) const { return cmp(psz) <= 0; }; + /// Makes case sensitive comparison to the ansi string ( see cmp(const char_t* psz) ) + bool operator==(const char_t* psz) const { return cmp(psz) == 0; }; + /// Makes case sensitive comparison to the ansi string ( see cmp(const char_t* psz) ) + bool operator>=(const char_t* psz) const { return cmp(psz) >= 0; }; + /// Makes case sensitive comparison to the ansi string ( see cmp(const char_t* psz) ) + bool operator>(const char_t* psz) const { return cmp(psz) > 0; }; + /// Makes case sensitive comparison to the ansi string ( see cmp(const char_t* psz) ) + bool operator!=(const char_t* psz) const { return cmp(psz) != 0; }; + + /// Makes case sensitive comparison to the unicode string ( see cmp(const wchar_t* psz) ) + bool operator<(const wchar_t* psz) const { return cmp(psz) < 0; }; + /// Makes case sensitive comparison to the unicode string ( see cmp(const wchar_t* psz) ) + bool operator<=(const wchar_t* psz) const { return cmp(psz) <= 0; }; + /// Makes case sensitive comparison to the unicode string ( see cmp(const wchar_t* psz) ) + bool operator==(const wchar_t* psz) const { return cmp(psz) == 0; }; + /// Makes case sensitive comparison to the unicode string ( see cmp(const wchar_t* psz) ) + bool operator>=(const wchar_t* psz) const { return cmp(psz) >= 0; }; + /// Makes case sensitive comparison to the unicode string ( see cmp(const wchar_t* psz) ) + bool operator>(const wchar_t* psz) const { return cmp(psz) > 0; }; + /// Makes case sensitive comparison to the unicode string ( see cmp(const wchar_t* psz) ) + bool operator!=(const wchar_t* psz) const { return cmp(psz) != 0; }; + +#ifdef ALLOW_UNICODE + /// Makes case sensitive comparison to the string object ( see cmp(const string& str) ) + bool operator<(const string& str) const { return cmp(str) < 0; }; + /// Makes case sensitive comparison to the string object ( see cmp(const string& str) ) + bool operator<=(const string& str) const { return cmp(str) <= 0; }; + /// Makes case sensitive comparison to the string object ( see cmp(const string& str) ) + bool operator==(const string& str) const { return cmp(str) == 0; }; + /// Makes case sensitive comparison to the string object ( see cmp(const string& str) ) + bool operator>=(const string& str) const { return cmp(str) >= 0; }; + /// Makes case sensitive comparison to the string object ( see cmp(const string& str) ) + bool operator>(const string& str) const { return cmp(str) >= 0; }; + /// Makes case sensitive comparison to the string object ( see cmp(const string& str) ) + bool operator!=(const string& str) const { return cmp(str) != 0; }; +#endif + + // cast operators + operator const char_t*() const; ///< Cast operator to char_t* +#ifdef ALLOW_UNICODE + operator const wchar_t*() const; ///< Cast operator to wchar_t* +#endif +/**@}*/ + +/** \name Standard operations */ +/**@{*/ + // appends the given string to this + void merge(const char_t* pszSrc); ///< Appends an ansi string to the string object + void merge(const wchar_t* pszSrc); ///< Appends an unicode string to the string object + void merge(const string& src); ///< Appends a string object to another string object + + string left(size_t tLen) const; ///< Returns string with the left part of a source string + string right(size_t tLen) const; ///< Returns string with the right part of a source string + string mid(size_t tStart, size_t tLen=(size_t)-1) const; ///< Returns string with the middle part of a source string + + void left_self(size_t tLen, bool bReallocBuffer=true); ///< Makes this string it's left part + void right_self(size_t tLen, bool bReallocBuffer=true); ///< Makes this string it's right part + void mid_self(size_t tStart, size_t tLen=(size_t)-1, bool bReallocBuffer=true); ///< Makes this string it's middle part + + // comparation + int_t cmp(const char_t* psz) const; ///< Comparison of this string object with a given ansi string + int_t cmp(const wchar_t* psz) const; ///< Comparison of this string object with a given unicode string + int_t cmp(const string& str) const; ///< Comparison of this string object with another string object + + int_t cmpi(const char_t* psz) const; ///< Comparison (case insensitive) of this string object with a given ansi string + int_t cmpi(const wchar_t* psz) const; ///< Comparison (case insensitive) of this string object with a given unicode string + int_t cmpi(const string& str) const; ///< Comparison (case insensitive) of this string object with another string object + + int_t cmpn(const char_t* psz, size_t tLen, bool bLenCheck=true) const; ///< Compares some chars of the string object with a given ansi string + int_t cmpn(const wchar_t* psz, size_t tLen, bool bLenCheck=true) const; ///< Compares some chars of the string object with a given unicode string + int_t cmpn(const string& str, size_t tLen, bool bLenCheck=true) const; ///< Compares some chars of the string object with another string object + + int_t cmpin(const char_t* psz, size_t tLen, bool bLenCheck=true) const; ///< Compares (case insensitive) some chars of the string object with a given ansi string + int_t cmpin(const wchar_t* psz, size_t tLen, bool bLenCheck=true) const; ///< Compares (case insensitive) some chars of the string object with a given unicode string + int_t cmpin(const string& str, size_t tLen, bool bLenCheck=true) const; ///< Compares (case insensitive) some chars of the string object with another string object + + int_t at(size_t tPos) const; ///< Gets a character at a specified position + char_t* get_buffera(size_t tMinSize); ///< Gives user access to the ansi internal buffer + wchar_t* get_bufferu(size_t tMinSize); ///< Gives user access to the unicode internal buffer + void release_buffer(); ///< Releases the buffer get from get_bufferx functions + + size_t length() const; ///< Returns the length of this string in chars + size_t bytelen() const; ///< Returns the length of a string in bytes (with terminating null character) + + void clear(); ///< Clear the contents of the string object + + bool is_empty() const; ///< Returns true if the string is empty +/**@}*/ + +/** \name Conversion routines */ +/**@{*/ +#ifdef ALLOW_UNICODE + /// Checks if string is in unicode storage mode + bool is_unicode() const { return m_psd->m_wFlags & SDF_UNICODE; }; + + void make_unicode(); ///< Makes the string internal buffer unicode + void make_ansi(); ///< Makes the string internal buffer ansi +#endif +/**@}*/ + +/** \name Debug stuff */ +/**@{*/ + void dump(dumpctx* pctx); ///< Dumps the contents of this class to the dump context + void print(); ///< Prints the contents of this class +/**@}*/ + +protected: + void set_str(const char_t* pszStr); ///< Makes a copy of a given ansi string and store it in internal string buffer +#ifdef ALLOW_UNICODE + void set_str(const wchar_t* pszStr); ///< Makes a copy of a given unicode string and store it in internal string buffer +#endif + + // converts the internal buffer to the other format +#ifdef ALLOW_UNICODE + static size_t convert_to_ansi(const wchar_t* pszIn, char_t** pszOut); ///< Converts an unicode string into the ansi one + static size_t convert_to_unicode(const char_t* pszIn, wchar_t** pszOut); ///< Converts an ansi string into the unicode one +#endif + + void make_writable(int_t iType, ptr_t pParam=NULL); ///< Makes an underlying data object writable + + // checks the refcount and frees the data (refcount <=0) or leaves untouched (refcount >0) + void release_data(); ///< Releases an underlying data object from this string (if refcount <= 0 then data object is deleted) + +public: + str_data *m_psd; ///< Pointer to an underlying data object (str_data) +}; + +END_ICPF_NAMESPACE + +#endif Index: ext/libicpf/src/str_help.cpp =================================================================== diff -u -N --- ext/libicpf/src/str_help.cpp (revision 0) +++ ext/libicpf/src/str_help.cpp (revision e17c80d36eaa0430313e7d1058aa7a301d1510af) @@ -0,0 +1,36 @@ +/*************************************************************************** + * Copyright (C) 2004 by J�zef Starosczyk * + * copyhandler@o2.pl * + * * + * This program 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 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 Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +/** \file str_help.cpp + * \brief Contain implementation of some string helper functions. + */ +#include "str_help.h" + +BEGIN_ICPF_NAMESPACE + +/** Checks if the character is a whitespace. + * \param[in] ch - character to check + * \return True if the character is a whitespace one, false otherwise. + */ +LIBICPF_API bool is_whitespace(char_t ch) +{ + return (ch >= 0x09 && ch <= 0x0d) || ch == 0x20; +} + +END_ICPF_NAMESPACE Index: ext/libicpf/src/str_help.h =================================================================== diff -u -N --- ext/libicpf/src/str_help.h (revision 0) +++ ext/libicpf/src/str_help.h (revision e17c80d36eaa0430313e7d1058aa7a301d1510af) @@ -0,0 +1,44 @@ +/*************************************************************************** + * Copyright (C) 2004 by J�zef Starosczyk * + * copyhandler@o2.pl * + * * + * This program 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 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 Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +/** \file str_help.h + * \brief Contain some string helper functions. + */ +#ifndef __STRHELP_H__ +#define __STRHELP_H__ + +#include "libicpf.h" +#include "gen_types.h" + +BEGIN_ICPF_NAMESPACE + +// some cross-platform compatibility macros +#ifndef _WIN32 + #define stricmp strcasecmp + #define wcsicmp wcscasecmp + #define strnicmp strncasecmp + #define wcsnicmp wcsncasecmp +#endif + +/// Checks if a given character is a whitespace character +LIBICPF_API bool is_whitespace(char_t ch); + +END_ICPF_NAMESPACE + +#endif