Analizo-1.25.5/0000775000175000017500000000000014676555272012556 5ustar joeniojoenioAnalizo-1.25.5/LICENSE0000644000175000017500000010477714676555272013601 0ustar joeniojoenioThis software is Copyright (c) 2024 by Joenio Marques da Costa . This is free software, licensed under: The GNU General Public License, Version 3, June 2007 GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . Analizo-1.25.5/AUTHORS0000644000175000017500000000347414676555272013634 0ustar joeniojoenioAlexandre Almeida Barbosa Allan Nobre Alysson Raniere Antonio Terceiro Athos Ribeiro Bryan de Holanda Caio Salgado Carlos Filipe Charles Oliveira <18oliveira.charles@gmail.com> Damyan Ivanov Edson Alves Hugo Neves de Carvalho Igor Gabriel Igor Ribeiro Barbosa Duarte Izabela Cardoso Joenio Marques da Costa Jonathan Moraes João M. Miranda João Paulo Busche João Paulo Ferreira Kamilla Crozara Kleber Luan Guimarães Lucas Costa Lucas Kanashiro Luciano Leão Macartur Sousa Marcelo Ferreira Mateus Andrade Matheus Miranda Mohammad S Anwar Paulo Borba Paulo Meirelles Rafael Martins Rafael Reggiani Manzo Roger Lenke Sabryna de Sousa Tiago Pereira Victor Cotrim brunobrg luca pablodiegoss Andreas Gustafsson Luiz Romário Santana Rios Analizo-1.25.5/dist.ini0000644000175000017500000000311514676555272014220 0ustar joeniojoenioname = Analizo license = GPL_3 copyright_holder = Joenio Marques da Costa [@Filter] -bundle = @Basic -remove = Readme [MetaJSON] [VersionFromModule] [Prereqs / BuildRequires] Git::Wrapper = 0 List::MoreUtils = 0 File::ShareDir = 0 File::Share = 0 Term::UI = 0 [Prereqs / TestRequires] Test::Class = 0 Test::Exception = 0 Test::MockObject = 0 Test::MockModule = 0 Test::BDD::Cucumber = 0.61 File::LibMagic = 0 Archive::Extract = 0 File::Slurp = 0 Test::Spelling = 0 [Prereqs / RuntimeRequires] Class::Accessor = 0 DBD::SQLite = 0 DBI = 1.635 CHI = 0 Digest::SHA = 0 File::Copy::Recursive = 0 FindBin::libs = 0 List::Compare = 0 JSON = 0 Graph = 0 YAML::XS = 0.75 Statistics::Descriptive = 0 Term::ProgressBar = 0 ZMQ::FFI = 0 File::HomeDir = 0 Graph::Writer::Dot = 2.09 App::Cmd = 0 Env::Path = 0 Class::Inspector = 0 local::lib = 0 [Prereqs / ConfigureRequires] Alien::Doxyparse = 0.17 [PodSyntaxTests] [@Git] tag_format = %v [GenerateFile] filename = AUTHORS content_is_template = 1 content = {{ `./refresh-authors` }} content = Andreas Gustafsson content = Luiz Romário Santana Rios [Repository] [Bugtracker] web = http://github.com/analizo/%s/issues [ArchiveRelease] Analizo-1.25.5/META.yml0000644000175000017500000000261414676555272014030 0ustar joeniojoenio--- abstract: 'multi-language source code analysis toolkit' author: - 'Joenio Marques da Costa ' build_requires: Archive::Extract: '0' File::LibMagic: '0' File::Share: '0' File::ShareDir: '0' File::Slurp: '0' Git::Wrapper: '0' List::MoreUtils: '0' Term::UI: '0' Test::BDD::Cucumber: '0.61' Test::Class: '0' Test::Exception: '0' Test::MockModule: '0' Test::MockObject: '0' Test::Spelling: '0' configure_requires: Alien::Doxyparse: '0.17' ExtUtils::MakeMaker: '0' File::ShareDir::Install: '0.06' dynamic_config: 0 generated_by: 'Dist::Zilla version 6.032, CPAN::Meta::Converter version 2.150010' license: gpl meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: '1.4' name: Analizo requires: App::Cmd: '0' CHI: '0' Class::Accessor: '0' Class::Inspector: '0' DBD::SQLite: '0' DBI: '1.635' Digest::SHA: '0' Env::Path: '0' File::Copy::Recursive: '0' File::HomeDir: '0' FindBin::libs: '0' Graph: '0' Graph::Writer::Dot: '2.09' JSON: '0' List::Compare: '0' Statistics::Descriptive: '0' Term::ProgressBar: '0' YAML::XS: '0.75' ZMQ::FFI: '0' local::lib: '0' resources: bugtracker: http://github.com/analizo/Analizo/issues repository: git://github.com/analizo/analizo.git version: 1.25.5 x_generated_by_perl: v5.38.2 x_serialization_backend: 'YAML::Tiny version 1.74' x_spdx_expression: GPL-3.0-only Analizo-1.25.5/MANIFEST0000644000175000017500000002751614676555272013720 0ustar joeniojoenio# This file was automatically generated by Dist::Zilla::Plugin::Manifest v6.032. AUTHORS CHANGELOG.md Dockerfile HACKING.md INSTALL.md LICENSE MANIFEST MANIFEST.SKIP META.json META.yml Makefile.PL PROFILING.md README.md RELEASE.md Vagrantfile bin/analizo development-setup.sh dist.ini lib/Analizo.pm lib/Analizo/Batch.pm lib/Analizo/Batch/Directories.pm lib/Analizo/Batch/Git.pm lib/Analizo/Batch/Job.pm lib/Analizo/Batch/Job/Directories.pm lib/Analizo/Batch/Job/Git.pm lib/Analizo/Batch/Output.pm lib/Analizo/Batch/Output/CSV.pm lib/Analizo/Batch/Output/DB.pm lib/Analizo/Batch/Runner.pm lib/Analizo/Batch/Runner/Parallel.pm lib/Analizo/Batch/Runner/Sequential.pm lib/Analizo/Command.pm lib/Analizo/Command/files_graph.pm lib/Analizo/Command/graph.pm lib/Analizo/Command/help.pm lib/Analizo/Command/metrics.pm lib/Analizo/Command/metrics_batch.pm lib/Analizo/Command/metrics_history.pm lib/Analizo/Command/tree_evolution.pm lib/Analizo/Extractor.pm lib/Analizo/Extractor/Doxyparse.pm lib/Analizo/FilenameFilter.pm lib/Analizo/Filter/Client.pm lib/Analizo/GlobalMetric/ChangeCost.pm lib/Analizo/GlobalMetric/MethodsPerAbstractClass.pm lib/Analizo/GlobalMetric/TotalAbstractClasses.pm lib/Analizo/GlobalMetrics.pm lib/Analizo/LanguageFilter.pm lib/Analizo/Metric/AfferentConnections.pm lib/Analizo/Metric/AverageCycloComplexity.pm lib/Analizo/Metric/AverageMethodLinesOfCode.pm lib/Analizo/Metric/AverageNumberOfParameters.pm lib/Analizo/Metric/CouplingBetweenObjects.pm lib/Analizo/Metric/DepthOfInheritanceTree.pm lib/Analizo/Metric/LackOfCohesionOfMethods.pm lib/Analizo/Metric/LinesOfCode.pm lib/Analizo/Metric/MaximumMethodLinesOfCode.pm lib/Analizo/Metric/NumberOfAttributes.pm lib/Analizo/Metric/NumberOfChildren.pm lib/Analizo/Metric/NumberOfMethods.pm lib/Analizo/Metric/NumberOfPublicAttributes.pm lib/Analizo/Metric/NumberOfPublicMethods.pm lib/Analizo/Metric/ResponseForClass.pm lib/Analizo/Metric/StructuralComplexity.pm lib/Analizo/Metrics.pm lib/Analizo/Model.pm lib/Analizo/ModuleMetric.pm lib/Analizo/ModuleMetrics.pm lib/Test/Analizo.pm lib/Test/Analizo/BDD/Cucumber/Extension.pm lib/Test/Analizo/Class.pm lib/Test/Analizo/Git.pm profile.pl refresh-authors share/README share/bash-completion/analizo t/Analizo.t t/Analizo/Batch.t t/Analizo/Batch/Directories.t t/Analizo/Batch/Git.t t/Analizo/Batch/Job.t t/Analizo/Batch/Job/Directories.t t/Analizo/Batch/Job/Git.t t/Analizo/Batch/Output.t t/Analizo/Batch/Output/CSV.t t/Analizo/Batch/Output/DB.t t/Analizo/Batch/Runner.t t/Analizo/Batch/Runner/Parallel.t t/Analizo/Batch/Runner/Sequential.t t/Analizo/Command.t t/Analizo/Command/files_graph.t t/Analizo/Command/graph.t t/Analizo/Command/help.t t/Analizo/Command/metrics.t t/Analizo/Command/metrics_batch.t t/Analizo/Command/metrics_history.t t/Analizo/Command/tree_evolution.t t/Analizo/Extractor.t t/Analizo/Extractor/Doxyparse.t t/Analizo/FilenameFilter.t t/Analizo/GlobalMetric/ChangeCost.t t/Analizo/GlobalMetric/MethodsPerAbstractClass.t t/Analizo/GlobalMetric/TotalAbstractClasses.t t/Analizo/GlobalMetrics.t t/Analizo/LanguageFilter.t t/Analizo/Metric/AfferentConnections/AfferentConnectionsByInheritance.t t/Analizo/Metric/AfferentConnections/AfferentConnectionsByReference.t t/Analizo/Metric/AfferentConnections/AfferentConnectionsComplete.t t/Analizo/Metric/AverageCycloComplexity.t t/Analizo/Metric/AverageMethodLinesOfCode.t t/Analizo/Metric/AverageNumberOfParameters.t t/Analizo/Metric/CouplingBetweenObjects.t t/Analizo/Metric/DepthOfInheritanceTree.t t/Analizo/Metric/LackOfCohesionOfMethods.t t/Analizo/Metric/LinesOfCode.t t/Analizo/Metric/MaximumMethodLinesOfCode.t t/Analizo/Metric/NumberOfAttributes.t t/Analizo/Metric/NumberOfChildren.t t/Analizo/Metric/NumberOfMethods.t t/Analizo/Metric/NumberOfPublicAttributes.t t/Analizo/Metric/NumberOfPublicMethods.t t/Analizo/Metric/ResponseForClass.t t/Analizo/Metric/StructuralComplexity.t t/Analizo/Metrics.t t/Analizo/Model.t t/Analizo/ModuleMetric.t t/Analizo/ModuleMetrics.t t/author-pod-spell.t t/author-pod-syntax.t t/features.t t/features/dot-analizo.feature t/features/doxyparse.feature t/features/exclude.feature t/features/files_graph.feature t/features/graph/cluster.feature t/features/graph/functions.feature t/features/graph/help.feature t/features/graph/input-files.feature t/features/graph/modules.feature t/features/graph/omit.feature t/features/graph/output-file.feature t/features/graph/plain.feature t/features/language_support.feature t/features/manpage-on-help.feature t/features/metrics-batch.feature t/features/metrics/abstract_classes.feature t/features/metrics/average_number_of_parameters.feature t/features/metrics/change_cost.feature t/features/metrics/coupling_between_objects.feature t/features/metrics/cyclomatic_complexity.feature t/features/metrics/deep_inheritance_afferent_connections.feature t/features/metrics/global_only.feature t/features/metrics/language_filter.feature t/features/metrics/list.feature t/features/metrics/methods_per_abstract_class.feature t/features/metrics/modules_with_defined_attributes.feature t/features/metrics/modules_with_defined_methods.feature t/features/metrics/number_of_attributes.feature t/features/metrics/number_of_methods.feature t/features/metrics/number_of_public_methods.feature t/features/metrics/output_file.feature t/features/metrics/statistics_values.feature t/features/metrics/total_modules.feature t/features/metrics_history.feature t/features/metrics_history_db.feature t/features/module_file_mapping.feature t/features/step_definitions/analizo_steps.pl t/features/tree_evolution.feature t/features/void-argument.feature t/features/wrapper.feature t/samples/abstract_class/csharp/Dog.cs t/samples/abstract_class/csharp/FourLeggedAnimal.cs t/samples/abstract_class/csharp/Program.cs t/samples/abstract_class/java/AbstractDao.java t/samples/android-framework/android-5.1.1_r38/AudioTrackShared.cpp t/samples/android-framework/android-5.1.1_r38/LICENSE.TXT t/samples/android-framework/android-5.1.1_r38/MCLinker.cpp t/samples/animals/cpp/Makefile t/samples/animals/cpp/animal.h t/samples/animals/cpp/cat.cc t/samples/animals/cpp/cat.h t/samples/animals/cpp/dog.cc t/samples/animals/cpp/dog.h t/samples/animals/cpp/main.cc t/samples/animals/cpp/mammal.h t/samples/animals/csharp/Animal.cs t/samples/animals/csharp/Cat.cs t/samples/animals/csharp/Dog.cs t/samples/animals/csharp/Main.cs t/samples/animals/csharp/Makefile t/samples/animals/csharp/Mammal.cs t/samples/animals/java/Animal.java t/samples/animals/java/Cat.java t/samples/animals/java/Dog.java t/samples/animals/java/Main.java t/samples/animals/java/Makefile t/samples/animals/java/Mammal.java t/samples/conditionals/c/cc1.c t/samples/conditionals/c/cc2.c t/samples/conditionals/c/cc3.c t/samples/conditionals/c/cc4.c t/samples/conditionals/csharp/cc1.cs t/samples/conditionals/csharp/cc2.cs t/samples/conditionals/csharp/cc3.cs t/samples/conditionals/csharp/cc4.cs t/samples/cyclical_graph/c/b.cc t/samples/cyclical_graph/c/b.h t/samples/cyclical_graph/c/c.cc t/samples/cyclical_graph/c/c.h t/samples/cyclical_graph/c/d.cc t/samples/cyclical_graph/c/d.h t/samples/cyclical_graph/c/e.cc t/samples/cyclical_graph/c/e.h t/samples/cyclical_graph/c/f.cc t/samples/cyclical_graph/c/f.h t/samples/cyclical_graph/c/main.cc t/samples/cyclical_graph/csharp/B.cs t/samples/cyclical_graph/csharp/C.cs t/samples/cyclical_graph/csharp/D.cs t/samples/cyclical_graph/csharp/E.cs t/samples/cyclical_graph/csharp/F.cs t/samples/cyclical_graph/csharp/Program.cs t/samples/deep_inheritance/java/Dog.java t/samples/deep_inheritance/java/DogFirstGreatGrandson.java t/samples/deep_inheritance/java/DogFirstPuppy.java t/samples/deep_inheritance/java/DogGrandson.java t/samples/deep_inheritance/java/DogSecondGreatGrandson.java t/samples/deep_inheritance/java/DogSecondPuppy.java t/samples/deep_inheritance/java/DogSuperYoung.java t/samples/deep_inheritance/java/Human.java t/samples/deep_inheritance/java/ShopController.java t/samples/deep_inheritance/java/VenderShop.java t/samples/enumeration/Enumeration.java t/samples/enumeration/Main.java t/samples/evolution.tar.gz t/samples/file_with_two_modules/cpp/Makefile t/samples/file_with_two_modules/cpp/classes.cc t/samples/file_with_two_modules/cpp/classes.h t/samples/file_with_two_modules/cpp/main.cc t/samples/file_with_two_modules/csharp/Classes.cs t/samples/file_with_two_modules/csharp/Program.cs t/samples/foo.tar.gz t/samples/hello_world/c/Makefile t/samples/hello_world/c/hello_world.c t/samples/hello_world/c/hello_world.h t/samples/hello_world/c/main.c t/samples/hello_world/cpp/Makefile t/samples/hello_world/cpp/hello_world.cc t/samples/hello_world/cpp/hello_world.h t/samples/hello_world/cpp/main.cc t/samples/hello_world/csharp/HelloWorld.cs t/samples/hello_world/csharp/Makefile t/samples/hello_world/csharp/main.cs t/samples/hello_world/java/HelloWorld.java t/samples/hello_world/java/Main.java t/samples/hello_world/java/Makefile t/samples/hierarchical_graph/c/b.cc t/samples/hierarchical_graph/c/b.h t/samples/hierarchical_graph/c/c.cc t/samples/hierarchical_graph/c/c.h t/samples/hierarchical_graph/c/d.cc t/samples/hierarchical_graph/c/d.h t/samples/hierarchical_graph/c/e.cc t/samples/hierarchical_graph/c/e.h t/samples/hierarchical_graph/c/f.cc t/samples/hierarchical_graph/c/f.h t/samples/hierarchical_graph/c/main.cc t/samples/hierarchical_graph/csharp/B.cs t/samples/hierarchical_graph/csharp/C.cs t/samples/hierarchical_graph/csharp/D.cs t/samples/hierarchical_graph/csharp/E.cs t/samples/hierarchical_graph/csharp/F.cs t/samples/hierarchical_graph/csharp/Program.cs t/samples/httpd-2.4.38/http_config.h t/samples/httpd-2.4.38/mod_suexec.c t/samples/httpd-2.4.38/mod_suexec.h t/samples/kdelibs/backportglobal.h t/samples/kdelibs/daterange.cpp t/samples/kdelibs/daterange.h t/samples/kdelibs/parser.cpp t/samples/macro/using_macro.c t/samples/macro/using_macro.h t/samples/mixed/Backend.java t/samples/mixed/CSharp_Backend.cs t/samples/mixed/UI.java t/samples/mixed/native_backend.c t/samples/mlpack-3.0.0/parse_command_line.hpp t/samples/multidir/c/Makefile t/samples/multidir/c/lib/Makefile t/samples/multidir/c/lib/lib.h t/samples/multidir/c/lib/main.c t/samples/multidir/c/src/Makefile t/samples/multidir/c/src/main.c t/samples/multidir/cpp/Makefile t/samples/multidir/cpp/hello.cc t/samples/multidir/cpp/src/hello.cc t/samples/multidir/cpp/src/hello.h t/samples/multidir/cpp/test/hello_test.cc t/samples/multidir/csharp/Makefile t/samples/multidir/csharp/hello.cs t/samples/multidir/csharp/src/hello.cs t/samples/multidir/csharp/test/hello_test.cs t/samples/multiple_inheritance/java/Animal.java t/samples/multiple_inheritance/java/Bird.java t/samples/multiple_inheritance/java/Flying.java t/samples/multiple_inheritance/java/Horse.java t/samples/multiple_inheritance/java/Pegasus.java t/samples/multiple_inheritance/java/README.md t/samples/polygons/cpp/Polygon.cpp t/samples/polygons/csharp/Polygon.cs t/samples/polygons/csharp/Program.cs t/samples/polygons/csharp/Rect.cs t/samples/polygons/csharp/Square.cs t/samples/polygons/csharp/Tetragon.cs t/samples/polygons/csharp/Triangle.cs t/samples/polygons/java/Polygon.java t/samples/polygons/java/Polygons.java t/samples/polygons/java/Retangle.java t/samples/polygons/java/Square.java t/samples/polygons/java/Tetragon.java t/samples/polygons/java/Triangle.java t/samples/printer/cpp/Makefile t/samples/printer/cpp/printer.cc t/samples/printer/csharp/Printer1.cs t/samples/printer/csharp/Printer2.cs t/samples/printer/csharp/Program.cs t/samples/printer/java/Printer1.java t/samples/printer/java/Printer2.java t/samples/sample_basic-1.0.yml t/samples/sample_basic/c/Makefile t/samples/sample_basic/c/config.sh t/samples/sample_basic/c/module1.c t/samples/sample_basic/c/module2.c t/samples/sample_basic/c/module2.h t/samples/sample_basic/c/module3.c t/samples/sample_basic/c/module3.h t/samples/sample_basic/csharp/Module1.cs t/samples/sample_basic/csharp/Module2.cs t/samples/sample_basic/csharp/Program.cs t/samples/tree-evolution.tar.gz t/samples/tree_id/1.c t/samples/tree_id/2.c t/samples/void/main.c t/samples/wildcard/GenericClass.java t/samples/wildcard/WildcardClass.java Analizo-1.25.5/README.md0000644000175000017500000000305714676555272014040 0ustar joeniojoenio[![ko-fi](https://www.ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/H2H41AOOZ) # About Analizo Analizo is a suite of source code analysis tools, aimed at being language-independent and extensible. The project home page is http://analizo.org # Installation See [INSTALL.md](INSTALL.md). # Development See [HACKING.md](HACKING.md). # Copyright Copyright © The Analizo developers. Please see the [AUTHORS](https://metacpan.org/release/Analizo/source/AUTHORS) file for a full list of the copyright holders. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . # Acknowledgments Analizo has been supported by several organizations: * [Brazilian National Research Council (CNPQ)](http://www.cnpq.br/) * [Bahia State's Research Support Foundation (FAPESB)](http://www.fapesb.ba.gov.br/) * [The Brazilian National Institute of Science and Technology for Software Engineering](http://www.ines.org.br/) * [Qualipso project](http://www.qualipso.org/) * [USP FLOSS Competence Center](http://ccsl.ime.usp.br/) Analizo-1.25.5/META.json0000644000175000017500000000503414676555272014177 0ustar joeniojoenio{ "abstract" : "multi-language source code analysis toolkit", "author" : [ "Joenio Marques da Costa " ], "dynamic_config" : 0, "generated_by" : "Dist::Zilla version 6.032, CPAN::Meta::Converter version 2.150010", "license" : [ "gpl_3" ], "meta-spec" : { "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", "version" : 2 }, "name" : "Analizo", "prereqs" : { "build" : { "requires" : { "File::Share" : "0", "File::ShareDir" : "0", "Git::Wrapper" : "0", "List::MoreUtils" : "0", "Term::UI" : "0" } }, "configure" : { "requires" : { "Alien::Doxyparse" : "0.17", "ExtUtils::MakeMaker" : "0", "File::ShareDir::Install" : "0.06" } }, "develop" : { "requires" : { "Test::Pod" : "1.41" } }, "runtime" : { "requires" : { "App::Cmd" : "0", "CHI" : "0", "Class::Accessor" : "0", "Class::Inspector" : "0", "DBD::SQLite" : "0", "DBI" : "1.635", "Digest::SHA" : "0", "Env::Path" : "0", "File::Copy::Recursive" : "0", "File::HomeDir" : "0", "FindBin::libs" : "0", "Graph" : "0", "Graph::Writer::Dot" : "2.09", "JSON" : "0", "List::Compare" : "0", "Statistics::Descriptive" : "0", "Term::ProgressBar" : "0", "YAML::XS" : "0.75", "ZMQ::FFI" : "0", "local::lib" : "0" } }, "test" : { "requires" : { "Archive::Extract" : "0", "File::LibMagic" : "0", "File::Slurp" : "0", "Test::BDD::Cucumber" : "0.61", "Test::Class" : "0", "Test::Exception" : "0", "Test::MockModule" : "0", "Test::MockObject" : "0", "Test::Spelling" : "0" } } }, "release_status" : "stable", "resources" : { "bugtracker" : { "web" : "http://github.com/analizo/Analizo/issues" }, "repository" : { "type" : "git", "url" : "git://github.com/analizo/analizo.git", "web" : "https://github.com/analizo/analizo" } }, "version" : "1.25.5", "x_generated_by_perl" : "v5.38.2", "x_serialization_backend" : "Cpanel::JSON::XS version 4.38", "x_spdx_expression" : "GPL-3.0-only" } Analizo-1.25.5/Dockerfile0000644000175000017500000000134214676555272014546 0ustar joeniojoenioFROM debian:buster # Creates analizo user and group inside container RUN useradd -ms /bin/bash analizo # Set the working directory to /home/analizo WORKDIR /home/analizo # Copy the current directory contents into the container at /home/analizo ADD . /home/analizo # Install any needed packages running development-setup.sh script RUN apt-get -y update && apt-get -y install sudo apt-utils && apt-get -y clean RUN ./development-setup.sh # Define analizo user as owner of all files under /home/analizo RUN chown -R analizo:analizo /home/analizo # Switch from root user to analizo user USER analizo:analizo # Add analizo bin to $PATH ENV PATH $PATH:/home/analizo/bin # By default show the analizo version CMD ./bin/analizo --version Analizo-1.25.5/profile.pl0000755000175000017500000000043214676555272014553 0ustar joeniojoenio#!/usr/bin/perl -w use Devel::NYTProf; use FindBin::libs; use Analizo; use strict; use warnings; my $analizo = Analizo->new; $analizo->execute_command( $analizo->prepare_command( $ENV{COMMAND} // 'metrics', $ENV{SOURCE} // $ARGV[0] // 't/samples/hello_world/cpp/' ) ); Analizo-1.25.5/RELEASE.md0000644000175000017500000000151614676555272014161 0ustar joeniojoenio# Rough instructions for releasing packages * make the code ready * all tests are passing on linux, freebsd and any other supported platform * make sure VERSION in lib/Analizo.pm is correct * update CHANGELOG.md, commit * git push * run `dzil release` (see "Release task" below for details) * update Debian package (see "Debian package" below) * update analizo.org site to point to the newer version * update VERSION in lib/Analizo.pm to the next version, commit ### Release task The Dist::Zilla task `dzil release` do: * run all tests * build a tar.gz package and upload to CPAN * create and push git tag to GitHub ### Debian package Analizo has oficial Debian package and it's managed at Debian Perl Group umbrella: * https://salsa.debian.org/perl-team/modules/packages/analizo/ Please update Debian package on every Analizo release. Analizo-1.25.5/INSTALL.md0000644000175000017500000001077414676555272014215 0ustar joeniojoenio# Installation You have more than one choice of install, see below. ## Debian package ### Newer versions Analizo 1.26.0 (not released yet) and later versions are oficially on Debian then all you need to install is (as root): ```console apt install analizo ``` ### Versions before 1.26.0 Analizo is readily available as a Debian package. This package might work with Ubuntu 18.04 or upper versions as well. For Ubuntu 16.04 version see this [section](#running-on-ubuntu-1604). Installing the Debian package has the follwing advantages: 1. you do not have to compile anything 2. all dependencies are installed automatically for you 3. new versions will be automatically available for upgrading the version on your system. You will find the instructions to install Analizo Debian package below. All of the steps must be performed as =root= user: 1) Create a file /etc/apt/sources.list.d/analizo.list file with the following contents: ```console deb http://analizo.org/download/ ./ deb-src http://analizo.org/download/ ./ ``` 2) Add the repository signing key to your list of trusted keys: ```console wget -O - http://analizo.org/download/signing-key.asc | apt-key add - ``` 3) Update your package lists: ```console apt-get update ``` 4) Install analizo: ```console apt-get install analizo ``` ## From CPAN Install [cpanminus](https://metacpan.org/pod/App::cpanminus) and building dependencies (see "Installing dependencies on non-Debian systems" on HACKING.md) then run `cpanm`: ```console cpanm Analizo ``` ## From sources Download the analizo tarball linked from the download page, extract it and run the following commands inside the analizo-x.y.z directory: ```console perl Makefile.PL make sudo make install ``` See the HACKING.md file for instructions on how to install Analizo dependencies. You need to install the dependencies before installing Analizo from sources. ## Running on Ubuntu 16.04 As reported in this [issue](https://github.com/analizo/analizo/issues/149) Analizo __.deb__ package had some problems during installation on Ubuntu Xenial versions. This problem is caused by an incompatible version of Perl. So, to workaround this follow those steps. 1) Install [perlbrew](https://perlbrew.pl/). Perlbrew is a management tool to install diferent versions of Perl without mixing out with your local enviroment. Install and check if the instalation was sucessufull: ```console sudo apt install perlbrew perlbrew --version ``` 2) Install a newest version of Perl: ```console perlbrew init perlbrew install perl-5.26.1 perlbrew switch perl-5.26.1 ``` 3) This step will change you to an enviroment with the Perl you just installed. Install [cpanminus](https://metacpan.org/pod/App::cpanminus): ```console cpan App::cpanminus ``` 4) It's important before you install Analizo that you have this following dependencies: ```console sudo apt install libssl-dev libmagic-dev libzmq-dev libexpat1-dev gnuplot git ``` 5) Then you can install Analizo ```console cpanm Analizo ``` ## Using Docker You can run your development environment without installing any dependency, using only the last docker image released. ```bash docker run --rm \ -v $LOCAL_REPO_PATH:/home/analizo/ \ -v $FOLDER_TO_ANALIZE:/src/ \ analizo/stable:1.22.0 \ bash -c "cd /src && analizo $1 $2 $3 $4" ``` This first volume will map the your local development Analizo to the path of Analizo inside the container. Making it run your local version instead of the original 1.22.0 code. The second volume will map your folder to be analized and put it inside the /src of the container to be analized by the new analizo receiving the $n parameters. If you need more than 4 parameters, some $5 or more should be added. To make it easier to use, you can create a bash function configured for your local pc, inside your __~/.bashrc__, as such: ```bash danalizo(){ path_to_local_repo=/absolute/path/to/dev_analizo/ docker run --rm -v $path_to_local_repo:/home/analizo/ -v $PWD:/src/ analizo/stable:1.22.0 bash -c "cd /src && analizo $1 $2 $3 $4" } ``` Now you can use your local analizo as: ```bash danalizo danalizo metrics goodcode.c danalizo graph --modules ./myproject/ ``` **Warning** : We are using __$PWD__ to copy the files to be analyzed to the container, so you can only analyze files and folders inside your current folder, do NOT use absolute paths or like: "danalizo metrics ../../file.c" or "danalizo graph /home/user/file.java".Analizo-1.25.5/HACKING.md0000644000175000017500000001101514676555272014140 0ustar joeniojoenio# Hacking ## Getting the source code ```console git clone https://github.com/analizo/analizo.git ``` ## Installing Dependencies Note that this option of installing dependencies is recommended just to create a development environment to hack analizo. Run this command: ```console ./development-setup.sh ``` If you are using Debian, the script will do everything you need, but it requires Debian 11 or superior. If you are using another system, you will have to install some dependencies first. Check the "Installing dependencies on non-Debian systems" below. ### Installing dependencies on non-Debian systems 1) Install Doxyparse build dependencies: flex, bison, libqt4-dev, gcc, gcc-c++, python, and git (your operating system probably already has packages for these) 2) Install Doxyparse (see [Doxyparse README](https://github.com/doxygen/doxygen/tree/master/addon/doxyparse)) ## Running the test suite Just run `dzil test` in the root of the sources: ```console dzil test ``` To run a single unit test use `prove`: ```console prove t/Analizo/Metrics.t ``` Features can also be executed with `pherkin` as: ```console pherkin t/features/metrics-batch.feature ``` See "Installing Dependencies" above for a guide to install all the software that's needed to run Analizo tests. ## Running the test suite on FreeBSD It uses Vagrant FreeBSD VM running on top of libvirt. Steps: ```console vagrant up --provider=libvirt vagrant ssh sudo pkg install p5-App-cpanminus p5-Dist-Zilla p5-local-lib p5-ZMQ-FFI p5-Import-Into flex bison cmake python git cd analizo dzil -I ~/perl5/lib/perl5 authordeps --missing | cpanm --notest dzil -I ~/perl5/lib/perl5 listdeps --missing | cpanm --notest dzil -I ~/perl5/lib/perl5 test ``` To keep Analizo's source sync with VM: vagrant rsync-auto To update Vagrant image: vagrant box update --provider=libvirt Stop VM: vagrant halt Remove VM: vagrant destroy ## Building ```console dzil build ``` ## Style and Good practices Always write automated tests for your code: * if you are adding a new feature, write a new cucumber feature file that shows how the feature is expected to work * if you are fixing a bug, make sure that you add a test that fails because of the bug, and then work on a fix to it. * If removing any code does not make any test to fail, then that code can be removed at any time. * Make sure the existing tests still pass after you change, add or remove any code. Refactoring code to make it simpler, easier to change or extend is always a good thing. Just make sure that the entire test suite still passes after you do any refactoring. Use 2 indentation of 2 spaces. Please always put the opening curly brace of a block in the same line of the corresponding instruction (e.g. if, for etc). Good: ``` if (...) \{ ... \} ``` Bad: ``` if (...) \{ ... \} ``` Always "use strict" in the top of new modules. Don't bother changing the AUTHORS file. It's automatically generated as part of the release process. See the dist.ini for more information. # Sending patches Send the patches to the Analizo mailing list: analizo@googlegroups.com (see subscription instructions at [community page](community.html)) or to `joenio@joenio.me`. Or create a pull request on github. To create a patch: ```console git clone https://github.com/analizo/analizo.git cd analizo edit file git commit file git format-patch origin ``` This will generate patch files named like `0001-message-you-typed-for-the-commit.patch`. If you want to make several changes, please consider making one commit (and therefore one patch) for each different logical change you want to make. In this case, after running git format-patch you'll have a series of patch files named like 0001-..., 0002-..., just send them all. You are encouraged to learn how to use git since it's a powerful version control system and it can make it easy for you to keep in sync with Analizo development. Please write good commits messages. Read the following two links, and use common sense: - [A note about git commit messages](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html) - [5 useful tips for a better commit message](http://robots.thoughtbot.com/post/48933156625/5-useful-tips-for-a-better-commit-message) Patches with multiple authors should list the authors in the end of commit message, using a `Signed-off-by` tag, one author per line. Example: ``` Signed-off-by: John Doe Signed-off-by: Random Hacker ``` See commit `005c3bff4e0809eae0340e7629678186d1621930` for an example. Analizo-1.25.5/Vagrantfile0000644000175000017500000000023114676555272014735 0ustar joeniojoenioVagrant.configure("2") do |config| config.vm.box = "generic/freebsd12" config.vm.synced_folder ".", "/home/vagrant/analizo" end # vim: filetype=ruby Analizo-1.25.5/bin/0000775000175000017500000000000014676555272013326 5ustar joeniojoenioAnalizo-1.25.5/bin/analizo0000755000175000017500000000013414676555272014705 0ustar joeniojoenio#!/usr/bin/env perl use FindBin::libs; use Analizo; use strict; use warnings; Analizo->run; Analizo-1.25.5/t/0000775000175000017500000000000014676555272013021 5ustar joeniojoenioAnalizo-1.25.5/t/Analizo.t0000644000175000017500000000246514676555272014610 0ustar joeniojoeniopackage t::Analizo; use strict; use warnings; use parent qw(Test::Analizo::Class); use Test::More; use Test::Analizo; BEGIN { use_ok 'Analizo' }; sub constructor: Tests { my $analizo = Analizo->new; isa_ok($analizo, 'Analizo'); isa_ok($analizo, 'App::Cmd'); } sub load_config_file : Tests { my $analizo = Analizo->new; on_tmpdir(sub { open CONFIG, '>', '.analizo'; print CONFIG 'metrics: --language java', "\n"; close CONFIG; my $config = $analizo->config; is_deeply($config, {metrics => '--language java'}); }); } sub empty_hash_when_no_config_file : Tests { my $analizo = Analizo->new; my $config = $analizo->config; is_deeply($config, {}); } sub load_command_options : Tests { my $analizo = Analizo->new; on_tmpdir(sub { open CONFIG, '>', '.analizo'; print CONFIG 'graph: --cluster -o file.dot', "\n"; close CONFIG; my @options = $analizo->load_command_options('graph'); is_deeply(\@options, ['--cluster', '-o', 'file.dot']); }); } sub empty_array_for_command_with_no_options : Tests { my $analizo = Analizo->new; on_tmpdir(sub { open CONFIG, '>', '.analizo'; print CONFIG 'metrics: --language java', "\n"; close CONFIG; my @options = $analizo->load_command_options('graph'); is_deeply(\@options, []); }); } __PACKAGE__->runtests; Analizo-1.25.5/t/features.t0000644000175000017500000000200614676555272015020 0ustar joeniojoenio#!perl use strict; use warnings; use local::lib; use Test::BDD::Cucumber; # This will find step definitions and feature files in the directory you point # it at below use Test::BDD::Cucumber::Loader; # This harness prints out nice TAP use Test::BDD::Cucumber::Harness::TAP; # Load a directory with Cucumber files in it. It will recursively execute any # file matching .*_steps.pl as a Step file, and .*\.feature as a feature file. # The features are returned in @features, and the executor is created with the # step definitions loaded. my ($executor, @features) = Test::BDD::Cucumber::Loader->load('t/features/'); # Create a Harness to execute against. TestBuilder harness prints TAP my $harness = Test::BDD::Cucumber::Harness::TAP->new({}); use Test::Analizo::BDD::Cucumber::Extension; $executor->add_extensions('Test::Analizo::BDD::Cucumber::Extension'); # For each feature found, execute it, using the Harness to print results $executor->execute($_, $harness) for @features; # Shutdown gracefully $harness->shutdown(); Analizo-1.25.5/t/Analizo/0000775000175000017500000000000014676555272014416 5ustar joeniojoenioAnalizo-1.25.5/t/Analizo/Model.t0000644000175000017500000003110014676555272015634 0ustar joeniojoeniopackage t::Analizo::Model; use strict; use warnings; use parent qw(Test::Analizo::Class); use Test::More; use Analizo::Model; sub constructor : Tests { isa_ok(Analizo::Model->new, 'Analizo::Model'); } sub empty_object : Tests { my $model = Analizo::Model->new; isa_ok($model->modules, 'HASH', 'must have modules'); isa_ok($model->members, 'HASH', 'must have members'); } sub declaring_modules : Tests { my $model = Analizo::Model->new; $model->declare_module('Module1'); $model->declare_module('Module2'); my @modules = $model->module_names; is($modules[0], 'Module1'); is($modules[1], 'Module2'); } sub declaring_modules_with_files : Tests { my $model = Analizo::Model->new; $model->declare_module('Module1', 'src/module1.c'); is_deeply($model->files('Module1'), ['src/module1.c']); } sub retrieving_modules_by_file : Tests { my $model = Analizo::Model->new; $model->declare_module('Module1', 'src/module1.c'); my @module = $model->module_by_file('src/module1.c'); is($module[0], 'Module1'); $model->declare_module('Module2', 'src/module1.c'); my @modules = $model->module_by_file('src/module1.c'); is_deeply(['Module1', 'Module2'], \@modules); } sub declaring_inheritance : Tests { my $model = Analizo::Model->new; $model->add_inheritance('Child', 'Parent'); my @parents = $model->inheritance('Child'); is($parents[0], 'Parent', 'class with one superclass'); $model->add_inheritance('Child', 'AnotherParent'); @parents = $model->inheritance("Child"); is($parents[1], 'AnotherParent', 'class with two superclasses'); } sub declaring_function : Tests { my $model = Analizo::Model->new; $model->declare_function('mymodule', 'myfunction'); $model->declare_function('mymodule', 'anotherfunction'); ok((grep { $_ eq 'myfunction' } keys(%{$model->members})), "declared function must be stored"); is('mymodule', $model->members->{'myfunction'}, 'must map function to module'); ok((grep { $_ eq 'mymodule'} keys(%{$model->modules})), 'declaring a function must declare its module'); ok((grep { $_ eq 'myfunction' } @{$model->{modules}->{'mymodule'}->{functions}}), 'must store members in a module'); ok((grep { $_ eq 'anotherfunction' } keys(%{$model->members})), "another declared function must be stored"); is('mymodule', $model->members->{'anotherfunction'}, 'must map another function to module'); ok((grep { $_ eq 'mymodule'} keys(%{$model->modules})), 'declaring a another function must declare its module'); ok((grep { $_ eq 'anotherfunction' } @{$model->{modules}->{'mymodule'}->{functions}}), 'must store members in a module'); } sub declaring_variables : Tests { my $model = Analizo::Model->new; $model->declare_variable('mymodule', 'myvariable'); ok((grep { $_ eq 'myvariable' } keys(%{$model->members})), "declared variable must be stored"); is('mymodule', $model->members->{'myvariable'}, 'must map variable to module'); ok((grep { $_ eq 'mymodule'} keys(%{$model->modules})), 'declaring a variable must declare its module'); ok((grep { $_ eq 'myvariable' } @{$model->modules->{'mymodule'}->{variables}}), 'must store variable in a module'); } sub adding_calls : Tests { my $model = Analizo::Model->new; $model->add_call('function1', 'function2'); is($model->calls->{'function1'}->{'function2'}, 'direct', 'must register function call'); } sub indirect_calls : Tests { my $model = Analizo::Model->new; $model->add_call('f1', 'f2', 'indirect'); is($model->calls->{'f1'}->{'f2'}, 'indirect', 'must register indirect call'); } sub addding_variable_uses : Tests { my $model = Analizo::Model->new; $model->add_variable_use('function1', 'variable9'); is($model->calls->{'function1'}->{'variable9'}, 'variable', 'must register variable use'); } sub querying_variables : Tests { my $model = Analizo::Model->new; $model->declare_variable('mod1', 'v1'); $model->declare_variable('mod1', 'v2'); ok((grep { $_ eq 'v1' } $model->variables('mod1')), 'must list v1 in variables'); ok((grep { $_ eq 'v2' } $model->variables('mod1')), 'must list v2 in variables'); } sub querying_functions : Tests { my $model = Analizo::Model->new; $model->declare_function('mod1', 'f1'); $model->declare_function('mod1', 'f2'); ok((grep { $_ eq 'f1' } $model->functions('mod1')), 'must list f1 in functions'); ok((grep { $_ eq 'f2' } $model->functions('mod1')), 'must list f2 in functions'); } sub querying_members : Tests { my $model = Analizo::Model->new; $model->declare_function('mod1', 'f1'); $model->declare_variable('mod1', 'v1'); $model->declare_function('mod1', 'f2'); $model->declare_variable('mod1', 'v2'); ok((grep { $_ eq 'f1' } $model->all_members('mod1')), 'must list f1 in functions'); ok((grep { $_ eq 'f2' } $model->all_members('mod1')), 'must list f2 in functions'); ok((grep { $_ eq 'v1' } $model->all_members('mod1')), 'must list v1 in variables'); ok((grep { $_ eq 'v2' } $model->all_members('mod1')), 'must list v2 in variables'); } sub declaring_protection : Tests { my $model = Analizo::Model->new; $model->add_protection('main::f1', 'public'); is($model->{protection}->{'main::f1'}, 'public'); } sub declating_lines_of_code : Tests { my $model = Analizo::Model->new; $model->add_loc('main::f1', 50); is($model->{lines}->{'main::f1'}, 50); } sub declaring_number_of_parameters { my $model = Analizo::Model->new; $model->add_parameters('main::function', 2); is($model->{parameters}->{'main::function'}, 2); } sub declaring_number_of_conditional_paths : Tests { my $model = Analizo::Model->new; $model->add_conditional_paths('main::function', 2); is($model->{conditional_paths}->{'main::function'}, 2); } sub adding_abstract_class : Tests { my $model = Analizo::Model->new; $model->add_abstract_class('An_Abstract_Class'); is($model->abstract_classes, 1, 'model detects an abstract class'); } sub build_graphs_from_function_calls : Tests { my $model = Analizo::Model->new; $model->declare_module('a', 'src/a.c'); $model->declare_module('b', 'src/b.c'); $model->declare_module('c', 'src/c.c'); $model->declare_function('a', 'a::name()'); $model->declare_function('b', 'b::name()'); $model->declare_function('c', 'c::name()'); $model->add_call('a::name()', 'b::name()'); $model->add_call('a::name()', 'c::name()'); my $graph_modules = $model->modules_graph; my $graph_files = $model->files_graph; is("$graph_modules", 'a-b,a-c'); is("$graph_files", 'src/a-src/b,src/a-src/c'); } sub build_graphs_from_inheritance : Tests { my $model = Analizo::Model->new; $model->declare_module('a', 'src/a.c'); $model->declare_module('b', 'src/b.c'); $model->declare_module('c', 'src/c.c'); $model->declare_module('d', 'src/d.c'); $model->add_inheritance('a', 'b'); $model->add_inheritance('a', 'c'); $model->add_inheritance('c', 'd'); my $graph_modules = $model->modules_graph; my $graph_files = $model->files_graph; is("$graph_modules", 'a-b,a-c,a-d,c-d'); is("$graph_files", 'src/a-src/b,src/a-src/c,src/a-src/d,src/c-src/d'); } sub build_graphs_from_funcion_calls_and_inheritance : Tests { my $model = Analizo::Model->new; $model->declare_module('a', 'src/a.c'); $model->declare_module('b', 'src/b.c'); $model->declare_module('c', 'src/c.c'); $model->declare_module('d', 'src/d.c'); $model->declare_module('e', 'src/e.c'); $model->add_inheritance('b', 'd'); $model->add_inheritance('d', 'e'); $model->declare_function('a', 'a::name()'); $model->declare_function('b', 'b::name()'); $model->declare_function('c', 'c::name()'); $model->add_call('a::name()', 'b::name()'); $model->add_call('a::name()', 'c::name()'); my $graph_modules = $model->modules_graph; my $graph_files = $model->files_graph; is("$graph_modules", 'a-b,a-c,b-d,b-e,d-e'); is("$graph_files", 'src/a-src/b,src/a-src/c,src/b-src/d,src/b-src/e,src/d-src/e'); } sub use_file_as_vertices_in_graphs : Tests { my $model = Analizo::Model->new; $model->declare_module('a', 'src/a.c'); $model->declare_module('b', 'src/b.c'); $model->declare_module('c', 'src/c.c'); my @modules_vertices = sort $model->modules_graph->vertices; my @files_vertices = sort $model->files_graph->vertices; is_deeply(\@modules_vertices, ['a', 'b', 'c']); is_deeply(\@files_vertices, ['src/a', 'src/b', 'src/c']); } sub group_files_when_build_graphs : Tests { my $model = Analizo::Model->new; $model->declare_module('a', 'src/a.h'); $model->declare_module('a', 'src/a.c'); $model->declare_module('b', 'src/b.h'); $model->declare_module('b', 'src/b.c'); $model->declare_module('c', 'src/c.c'); $model->declare_module('c', 'src/c.h'); my @modules_vertices = sort $model->modules_graph->vertices; my @files_vertices = sort $model->files_graph->vertices; is_deeply(\@modules_vertices, ['a', 'b', 'c']); is_deeply(\@files_vertices, ['src/a', 'src/b', 'src/c']); } sub empty_call_graph : Tests { my $model = Analizo::Model->new; is($model->callgraph, '', 'empty output must give empty digraph'); } sub listing_calls : Tests { my $model = Analizo::Model->new; $model->declare_function('module1', 'function1'); $model->declare_function('module1', 'function2'); $model->add_call('function1', 'function2', 'direct'); is( $model->callgraph, 'function1-function2', 'must generate correctly a graph with one call' ); } sub listing_two_calls : Tests { my $model = Analizo::Model->new; $model->declare_function('module1', 'function1(type)'); $model->declare_function('module1', 'function2(type1, type2)'); $model->declare_function('module1', 'function3()'); $model->add_call('function1(type *)', 'function2(type1, type2)', 'direct'); $model->add_call('function1(type *)', 'function3()', 'direct'); is( $model->callgraph, 'function1(type *)-function2(type1, type2),function1(type *)-function3()', 'must generate correctly a graph with f1 -> f2, f1 -> f3' ); } sub listing_only_defined_functions : Tests { my $model = Analizo::Model->new; $model->declare_function('module1', 'function1'); $model->declare_function('module2', 'function2'); $model->add_call('function1', 'function2'); $model->add_call('function2', 'function3'); is( $model->callgraph, 'function1-function2', 'must include by default only functions inside the project' ); } sub ommiting_functions : Tests { my $model = Analizo::Model->new; $model->declare_function('module1', 'function1'); $model->declare_function('module1', 'function2'); $model->declare_function('module1', 'function3'); $model->add_call('function1', 'function2'); $model->add_call('function1', 'function3'); is( $model->callgraph(omit => ['function3']), 'function1-function2', 'must be able to omit a called function' ); is( $model->callgraph(omit => ['function1']), '', 'must be able to omit a caller function' ); } sub including_external_functions : Tests { my $model = Analizo::Model->new; $model->declare_function('module1', 'function1'); $model->add_call('function1', 'function2'); is( $model->callgraph(include_externals => 1), 'function1-function2', 'must be able to omit a called function' ); } sub groupping_by_module : Tests { my $model = Analizo::Model->new; $model->declare_function('cluster1.c.r1874.expand', 'function1'); $model->declare_function('cluster2.c.r9873.expand', 'function2'); $model->declare_function('cluster2.c.r9873.expand', 'function3'); $model->add_call('function1', 'function2'); $model->add_call('function1', 'function3'); is( $model->callgraph(group_by_module => 1), 'cluster1.c-cluster2.c', 'must list correctly a single dependency arrow between two modules' ); $model->add_call('function1', 'function4'); $model->declare_function('cluster3.c.r8773.expand', 'function4'); is( $model->callgraph(group_by_module => 1), 'cluster1.c-cluster2.c,cluster1.c-cluster3.c', 'must list arrow targets in lexicographic order' ); $model->add_call('function5', 'function1'); $model->declare_function('cluster0.c.r7412.expand', 'function5'); is( $model->callgraph(group_by_module => 1), 'cluster0.c-cluster1.c,cluster1.c-cluster2.c,cluster1.c-cluster3.c', 'must list arrow sources in in lexicographic order' ); } sub use_of_variables : Tests { my $model = Analizo::Model->new; $model->declare_function('module1.c.r1234.expand', 'function1'); $model->declare_variable('module2.c', 'myvariable'); $model->add_variable_use('function1', 'myvariable'); is( $model->callgraph, 'function1-myvariable', 'must output declared variables' ); # test grouping by module is( $model->callgraph(group_by_module => 1), 'module1.c-module2.c', 'must use variable information for inter-module dependencies' ); } __PACKAGE__->runtests; Analizo-1.25.5/t/Analizo/Batch.t0000644000175000017500000000141214676555272015620 0ustar joeniojoeniopackage t::Analizo::Batch; use strict; use warnings; use parent qw(Test::Analizo::Class); use Test::More; use Test::Analizo; use Analizo::Batch; use Analizo::Batch::Job; sub constructor: Tests { isa_ok(Analizo::Batch->new, 'Analizo::Batch'); } sub next : Tests { can_ok('Analizo::Batch', 'next'); my $batch = Analizo::Batch->new; is($batch->next, undef); } sub count : Tests { can_ok("Analizo::Batch", 'count'); } sub pass_filters_forward : Tests { my $batch = mock(Analizo::Batch->new); my $job = Analizo::Batch::Job->new; $batch->mock('fetch_next', sub { $job }); my $filter = Analizo::LanguageFilter->new('c'); $batch->filters($filter); $batch->next(); is_deeply($job->filters, [$filter], 'must pass filters into job'); } __PACKAGE__->runtests; Analizo-1.25.5/t/Analizo/Metrics.t0000644000175000017500000000370314676555272016212 0ustar joeniojoeniopackage t::Analizo::Metrics; use strict; use warnings; use parent qw(Test::Analizo::Class); use Test::More; use Analizo::Metrics; use Analizo::Model; use vars qw($model $metrics); sub setup : Test(setup) { $model = Analizo::Model->new; $metrics = Analizo::Metrics->new(model => $model); } sub constructor : Tests { isa_ok($metrics, 'Analizo::Metrics'); } sub model : Tests { can_ok($metrics, 'model'); is($metrics->model, $model); } sub sample_modules_for_report { # first module $model->declare_module('mod1'); $model->declare_function('mod1' , 'f1a'); $model->declare_function('mod1' , 'f1b'); $model->declare_variable('mod1' , 'v1'); $model->add_variable_use($_, 'v1') for qw(f1a f1b); # second module $model->declare_module('mod2'); $model->declare_function('mod2', 'f2'); $model->add_call('f2', 'f1a'); $model->add_call('f2', 'f1b'); } sub report : Tests { sample_modules_for_report(); my $output = $metrics->report; $output =~ m/total_modules: ([0-9]+)/; my $modules = $1; is($modules, 2, 'reporting number of classes in YAML stream'); ok($output =~ /_module: mod1/, 'reporting module 1'); ok($output =~ /_module: mod2/, 'reporting module 2'); } sub report_global_only : Tests { sample_modules_for_report(); my $output = $metrics->report_global_metrics_only; ok($output =~ /total_modules: 2/, 'reporting number of classes (it is global)'); ok($output !~ /_module: mod1/, 'not reporting module 1 details'); ok($output !~ /_module: mod2/, 'not reporting module 2 details'); } sub report_without_modules_at_all : Tests { # if this call does not crash we are fine $metrics->report; } sub list_of_metrics : Tests { my %metrics = $metrics->list_of_metrics(); cmp_ok(scalar(keys(%metrics)), '>', 0, 'must list metrics'); } sub metrics_for : Tests { sample_modules_for_report(); my $data = $metrics->metrics_for('mod1'); is(ref($data), 'HASH'); is($data->{_module}, 'mod1'); } __PACKAGE__->runtests; Analizo-1.25.5/t/Analizo/Command.t0000644000175000017500000000216514676555272016163 0ustar joeniojoeniopackage t::Analizo::Command; use strict; use warnings; use parent qw(Test::Analizo::Class); use Test::More; use Test::Analizo; use Test::Exception; BEGIN { use_ok 'Analizo::Command' }; sub any_command_is_a_subclass_of_Analizo_Command : Tests { my $analizo = Analizo->new; my ($cmd) = $analizo->prepare_command('fake'); isa_ok($cmd, 'Analizo::Command'); } sub version_information : Tests { my $analizo = Analizo->new; my ($cmd) = $analizo->prepare_command('fake'); like($cmd->version_information, qr/^\S+ version \d+\.\d+\.\d+(~rc\d+)?$/); } sub execute_some_command : Tests { my $analizo = Analizo->new; my $return = $analizo->execute_command( $analizo->prepare_command('fake') ); is($return, "command fake executed"); } sub executing_commands_with_version_argument_is_not_allowed : Tests { my $analizo = Analizo->new; throws_ok { $analizo->execute_command( $analizo->prepare_command('fake', '--version') ) } qr /Invalid option/; } __PACKAGE__->runtests; package t::Analizo::Command::fake; use Analizo -command; use parent qw(Analizo::Command); sub validate {} sub execute { "command fake executed" } 1; Analizo-1.25.5/t/Analizo/Extractor.t0000644000175000017500000001350714676555272016562 0ustar joeniojoeniopackage t::Analizo::Extractor; use strict; use warnings; use parent qw(Test::Analizo::Class); use Test::More; use Test::Exception; use Analizo::Extractor; use Analizo::LanguageFilter; use Analizo::Model; # Redefine constructor so that this test class can instantiate # Analizo::Extractor directly use Test::MockModule; my $AnalizoExtractor = Test::MockModule->new('Analizo::Extractor'); $AnalizoExtractor->mock('new', sub { return bless {}, 'Analizo::Extractor'}); eval('$Analizo::Extractor::QUIET = 1;'); # the eval is to avoid Test::* complaining about possible typo sub constructor : Tests { isa_ok(Analizo::Extractor->new, 'Analizo::Extractor'); } sub has_a_current_member : Tests { can_ok('Analizo::Extractor', 'current_member'); } ############################################################################## # BEGIN test of indicating current module ############################################################################## sub current_module : Tests { my $extractor = Analizo::Extractor->new; $extractor->current_module('module1.c'); is($extractor->current_module, 'module1.c', 'must be able to set the current module'); $extractor->current_module('module2.c'); is($extractor->current_module, 'module2.c', 'must be able to change the current module'); } sub current_file : Tests { my $extractor = Analizo::Extractor->new; is($extractor->current_file, undef); $extractor->current_file('file1.c'); is($extractor->current_file, 'file1.c'); } sub current_file_plus_current_module : Tests { my $extractor = Analizo::Extractor->new; my $model = Analizo::Model->new; $extractor->{model} = $model; $extractor->current_file('person.cpp'); $extractor->current_module('Person'); is_deeply($model->{module_by_file}->{'person.cpp'}, ['Person']); } sub process_must_delegate_to_actually_process : Tests { my $called = 0; no warnings; local *Analizo::Extractor::actually_process = sub { $called = 1; }; use warnings; Analizo::Extractor->new->process; ok($called); } sub load_doxyparse_extractor : Tests { lives_ok { Analizo::Extractor->load('Doxyparse') }; } sub fail_when_load_invalid_extractor : Tests { dies_ok { Analizo::Extractor->load('ThisNotExists') }; } sub load_doxyparse_extractor_by_alias : Tests { lives_ok { isa_ok(Analizo::Extractor->load('doxy'), 'Analizo::Extractor::Doxyparse'); } } sub dont_allow_code_injection: Tests { lives_ok { isa_ok(Analizo::Extractor->load('Doxyparse; die("BOOM!")'), 'Analizo::Extractor::Doxyparse'); } } sub has_filters : Tests { my $extractor = Analizo::Extractor->new; can_ok($extractor, 'filters'); my $filters = $extractor->filters; is_deeply([], $filters); my $language = {}; $extractor->filters($language); $filters = $extractor->filters; is($language, $filters->[0]); } sub must_consider_only__supported_languages : Tests { my $extractor = Analizo::Extractor->new; my @processed = (); no warnings; local *Analizo::Extractor::actually_process = sub { my ($self, @options) = @_; @processed = @options; }; use warnings; my $path = 't/samples/mixed'; $extractor->process($path); @processed = sort @processed; my @expected = qw( t/samples/mixed/Backend.java t/samples/mixed/CSharp_Backend.cs t/samples/mixed/UI.java t/samples/mixed/native_backend.c ); is_deeply(\@processed, \@expected); } sub must_filter_input_with_language_filter : Tests { my @processed = (); no warnings; local *Analizo::Extractor::actually_process = sub { my ($self, @options) = @_; @processed = @options; }; my $extractor = Analizo::Extractor->new; $extractor->filters(Analizo::LanguageFilter->new('java')); $extractor->process('t/samples/mixed'); my @expected = ('t/samples/mixed/Backend.java', 't/samples/mixed/UI.java'); @processed = sort(@processed); is_deeply(\@processed, \@expected); } sub must_create_filters_for_excluded_dirs : Tests { my $extractor = Analizo::Extractor->new; my $filters = $extractor->filters; is(scalar @$filters, 0); # addding the first excluded directory filter also adds a null language filter $extractor->exclude('test'); $filters = $extractor->filters; is(scalar @$filters, 2); $extractor->exclude('uitest'); $filters = $extractor->filters; is(scalar(@$filters), 3); } sub must_not_process_files_in_excluded_dirs : Tests { my @processed = (); no warnings; local *Analizo::Extractor::actually_process = sub { my ($self, @options) = @_; @processed = sort(@options); }; use warnings; my $extractor = Analizo::Extractor->new; $extractor->exclude('t/samples/multidir/cpp/test'); $extractor->process('t/samples/multidir/cpp'); is_deeply(\@processed, ['t/samples/multidir/cpp/hello.cc', 't/samples/multidir/cpp/src/hello.cc', 't/samples/multidir/cpp/src/hello.h']); } sub must_not_exclude_everything_in_the_case_of_unexisting_excluded_dir : Tests { my @processed = (); no warnings; local *Analizo::Extractor::actually_process = sub { my ($self, @options) = @_; @processed = sort(@options); }; use warnings; my $extractor = Analizo::Extractor->new; ok(! -e 't/samples/animals/cpp/test'); $extractor->exclude('t/samples/animals/cpp/test'); # does not exist! $extractor->process('t/samples/animals/cpp'); isnt(0, scalar @processed); } sub must_not_ignore_filter_by_default : Tests { no warnings; local *Analizo::Extractor::apply_filters = sub { die "apply_filters() was called" }; use warnings; my $extractor = Analizo::Extractor->new; dies_ok { $extractor->process('t/samples/mixed') }; } sub force_ignore_filter : Tests { no warnings; local *Analizo::Extractor::use_filters = sub { 0; }; local *Analizo::Extractor::apply_filters = sub { die "apply_filters() was called" }; use warnings; my $extractor = Analizo::Extractor->new; lives_ok { $extractor->process('t/samples/mixed') }; } __PACKAGE__->runtests; Analizo-1.25.5/t/Analizo/Batch/0000775000175000017500000000000014676555272015437 5ustar joeniojoenioAnalizo-1.25.5/t/Analizo/Batch/Git.t0000644000175000017500000000373014676555272016350 0ustar joeniojoeniopackage t::Analizo::Batch::Git; use strict; use warnings; use parent qw(Test::Analizo::Class); use Test::More; use Test::Analizo; use Test::Analizo::Git; use Cwd 'abs_path'; use Test::MockObject; use Analizo::Batch::Git; my $TESTDIR = tmpdir() . '/evolution'; sub constructor : Tests { isa_ok(Analizo::Batch::Git->new, 'Analizo::Batch::Git'); } sub create_with_and_without_args : Tests { # without arg: git repo is the current directory my $batch1 = on_dir($TESTDIR, sub { __create(); }); # with arg: git repo is in the directory named by the argument my $batch2 = __create($TESTDIR); is($batch1->directory, $batch2->directory); is($batch1->directory, abs_path($TESTDIR)); my $job1 = $batch1->next(); my $job2 = $batch2->next(); is($job1->id, $job2->id); is($job1->id, $MAIN); } sub traverse_repository : Tests { my $batch = __create($TESTDIR); $batch->filters(Analizo::LanguageFilter->new('cpp')); my %jobs = (); while (my $job = $batch->next()) { $jobs{$job->id} = 1; } ok($jobs{$MAIN}, 'main commit must be listed'); ok($jobs{$SOME_COMMIT}, 'intermediate relevant commit must be listed'); ok(!$jobs{$IRRELEVANT_COMMIT}, 'intermediate IRRELEVANT commit must not be listed'); } sub count : Tests { my $batch = __create($TESTDIR); $batch->initialize(); is($batch->count, 7); } sub default_filter : Tests { my $batch = __create($TESTDIR); while (my $job = $batch->next()) { my @files = grep { /\.(cc|h)$/ } keys(%{$job->changed_files}); ok(scalar(@files) > 0, sprintf("must not analyze commit containing only (%s)", join(',', keys(%{$job->changed_files})))); } } sub find_commit : Tests { my $batch = __create($TESTDIR); $batch->initialize(); is($batch->find('abczyx1234'), undef); my $main = $batch->find($MAIN); isa_ok($main, 'Analizo::Batch::Job::Git'); is($main->id, $MAIN); } sub __create { my @args = @_; Analizo::Batch::Git->new(@args); } unpack_sample_git_repository( sub { __PACKAGE__->runtests; } ) Analizo-1.25.5/t/Analizo/Batch/Job.t0000644000175000017500000001351014676555272016334 0ustar joeniojoeniopackage t::Analizo::Batch::Job; use strict; use warnings; use parent qw(Test::Analizo::Class); use Test::More; use Test::MockObject::Extends; use Test::MockModule; use File::Path qw(remove_tree); use Test::Analizo; use Analizo::Batch::Job; sub constructor : Tests { isa_ok(Analizo::Batch::Job->new, 'Analizo::Batch::Job'); } my @EXPOSED_INTERFACE = qw( prepare execute cleanup parallel_prepare parallel_cleanup model metrics id directory metadata metadata_hashref ); sub exposed_interface : Tests { can_ok('Analizo::Batch::Job', @EXPOSED_INTERFACE); } sub before_execute : Tests { my $job = Analizo::Batch::Job->new; is($job->model, undef); is($job->metrics, undef); } sub execute : Tests { # model and metrics must be set my $job = Test::MockObject::Extends->new(Analizo::Batch::Job->new); my $prepared = 0; $job->mock('prepare', sub { $prepared = 1; }); my $cleaned = 0; $job->mock('cleanup', sub { die('cleanup() must be called after prepare()') unless $prepared; $cleaned = 1; }); my $metrics_data_called = undef; my $MetricsMock = Test::MockModule->new('Analizo::Metrics'); $MetricsMock->mock('data', sub { $metrics_data_called = 1; }); on_dir( 't/samples/hello_world/c', sub { $job->execute(); } ); ok($prepared && $cleaned, 'must call prepare() and cleanup() on execute'); isa_ok($job->model, 'Analizo::Model'); isa_ok($job->metrics, 'Analizo::Metrics'); isa_ok($job->metrics->model, 'Analizo::Model'); ok($metrics_data_called, 'must force metrics calculation during execute() bu calling $metrics->data()'); } sub empty_metadata_by_default : Tests { my $job = Analizo::Batch::Job->new; is_deeply($job->metadata(), []); } sub metadata_as_hash : Tests { my $job = mock(Analizo::Batch::Job->new); $job->mock('metadata', sub { [['field1', 'value1'],['field2', 'value2']]}); my $hash = $job->metadata_hashref(); is($hash->{field1}, 'value1'); is($hash->{field2}, 'value2'); is(scalar(keys(%$hash)), 2); } sub project_name : Tests { my $job = Analizo::Batch::Job->new; $job->directory('myproject'); is($job->project_name, 'myproject'); $job->directory('/path/to/my/project'); is($job->project_name, 'project'); } sub pass_filters_to_extractor : Tests { my @filters = (); my $extractor = mock(bless {}, 'Analizo::Extractor'); $extractor->mock( 'process', sub { my ($self) = @_; push @filters, @{$self->filters}; } ); my $module = Test::MockModule->new('Analizo::Extractor'); $module->mock( 'load', sub { $extractor; } ); my $job = Analizo::Batch::Job->new; my $cpp_filter = Analizo::LanguageFilter->new('cpp'); $job->filters($cpp_filter); on_dir( 't/samples/hello_world/cpp/', sub { $job->execute(); } ); is_deeply(\@filters, [$cpp_filter], 'must pass filters to extractor object'); } use File::Temp qw/ tempdir /; $ENV{ANALIZO_CACHE} = tempdir(CLEANUP => 1); sub cache_of_model_and_metrics : Tests { # first time my $job1 = Analizo::Batch::Job->new; on_dir( 't/samples/animals/cpp', sub { $job1->execute(); }); my $model1 = $job1->model; my $metrics1 = $job1->metrics; my $model_result = 'cache used'; my $AnalizoExtractor = Test::MockModule->new('Analizo::Extractor'); $AnalizoExtractor->mock('process', sub { $model_result = 'cache not used!' }); my $metrics_result = 'cache used'; my $AnalizoMetrics = Test::MockModule->new('Analizo::Metrics'); $AnalizoMetrics->mock('data', sub { $metrics_result = 'cache not used!' }); # second time my $job2 = Analizo::Batch::Job->new; on_dir( 't/samples/animals/cpp', sub { $job2->execute(); }); my $model2 = $job2->model; my $metrics2 = $job2->metrics; $model2->{calls}->{'Animal::name()'} = {}; $model2->{calls}->{'Mammal::~Mammal()'} = {}; is($model_result, 'cache used', 'use cache for model'); is($metrics_result, 'cache used', 'use cache for metrics'); # FIXME commenting failing test only in order to release a new version # but we need to fix it ASAP (issue #77) is_deeply($model2, $model1, 'cached model is the same'); is_deeply($metrics2, $metrics1, 'cached metrics is the same '); } sub stores_cache_on_distinct_dirs_for_each_version : Tests { my $FileSpec = Test::MockModule->new('File::Spec'); $FileSpec->mock('splitdir', sub { '/bypass_the_tempdir_creation_on_development_environment' }); local $ENV{ANALIZO_CACHE} = undef; my $job = Analizo::Batch::Job->new; local $Analizo::VERSION = "1.1.1"; like ($job->_get_cache_dir, qr/1\.1\.1$/); local $Analizo::VERSION = "2.2.2"; like ($job->_get_cache_dir, qr/2\.2\.2$/); } sub invalidates_cache_after_upgrade_version : Tests { my $FileSpec = Test::MockModule->new('File::Spec'); $FileSpec->mock('splitdir', sub { '/bypass_the_tempdir_creation_on_development_environment' }); local $ENV{ANALIZO_CACHE} = undef; local $Analizo::VERSION = "1.1.1"; my $job_a = Analizo::Batch::Job->new; $job_a->cache->set('metrics', 'metrics values'); ok ($job_a->cache->get('metrics'), 'metrics values sucessfully retrievied from the cache'); my $job_b = Analizo::Batch::Job->new; ok ($job_b->cache->get('metrics'), 'values for metrics found on cache for same analizo version'); local $Analizo::VERSION = "2.2.2"; my $job_c = Analizo::Batch::Job->new; ok (!$job_c->cache->get('metrics'), 'values for metrics should not found for other analizo version'); # remove all cache directories created in this testcase foreach ($job_a->_get_cache_dir, $job_b->_get_cache_dir, $job_c->_get_cache_dir) { remove_tree $_ if -e $_; } } sub tree_id : Tests { my $job = Analizo::Batch::Job->new; my $id; on_dir( 't/samples/tree_id', sub { $id = $job->tree_id('.'); } ); is($id, '83f5a5c359f3dc8317519240e32f1f51f68bc051'); # calculated by hand # calculated by Perl oneliner using Digest::SHA module } __PACKAGE__->runtests; Analizo-1.25.5/t/Analizo/Batch/Runner.t0000644000175000017500000000211414676555272017071 0ustar joeniojoeniopackage t::Analizo::Batch::Runner; use strict; use warnings; use parent qw(Test::Analizo::Class); use Test::More; use Test::Analizo; use Analizo::Batch::Runner; use Analizo::Batch::Output; sub interface : Tests { can_ok('Analizo::Batch::Runner', 'run'); can_ok('Analizo::Batch::Runner', 'actually_run'); } sub interaction_with_output : Tests { my $runner = Analizo::Batch::Runner->new; my $batch = {}; my $output = mock(Analizo::Batch::Output->new); my $initialized = 0; my $flushed = 0; $output->mock('initialize', sub { $initialized = 1; }); $output->mock('flush', sub { $flushed = 1; }); $runner->run($batch, $output); ok($initialized, 'must initialize output object'); ok($flushed, 'must flush output object'); } sub progress : Tests { my $runner = Analizo::Batch::Runner->new; my $job = undef; my $step = undef; my $total = undef; $runner->progress(sub { my ($j, $i, $n) = @_; $job = $j; $step = $i; $total = $n; }); my $_j = {}; $runner->report_progress($_j, 33, 99); is($job, $_j); is($step, 33); is($total, 99); } __PACKAGE__->runtests; Analizo-1.25.5/t/Analizo/Batch/Output.t0000644000175000017500000000223714676555272017126 0ustar joeniojoeniopackage t::Analizo::Batch::Output; use strict; use warnings; use parent qw(Test::Analizo::Class); use Test::More; use Test::Analizo; use Analizo::Batch::Output; sub constructor : Tests { isa_ok(__create(), 'Analizo::Batch::Output'); } sub exposed_interface : Tests { can_ok('Analizo::Batch::Output', qw(requires_metrics push initialize flush)); } sub not_require_metrics_by_default : Tests { my $output = __create(); is($output->requires_metrics, 0); } sub should_write_to_output_file : Tests { my $output = mock(__create()); my $delegated = undef; $output->mock('write_data', sub { my ($that, $fh) = @_; $delegated = (ref($fh) eq 'GLOB'); }); $output->file('t/tmp/output.tmp'); $output->flush(); ok(-e 't/tmp/output.tmp', 'output must be written to file'); ok($delegated, 'must delegate actualy writing to subclasses'); } sub must_write_to_stdout_when_no_file_is_given : Tests { my $output = mock(__create()); my $write_data_called = 0; $output->mock('write_data', sub { if ($_[1] eq *STDOUT) { $write_data_called++ }}); $output->flush(); ok($write_data_called == 1); } sub __create { Analizo::Batch::Output->new; } __PACKAGE__->runtests; Analizo-1.25.5/t/Analizo/Batch/Job/0000775000175000017500000000000014676555272016151 5ustar joeniojoenioAnalizo-1.25.5/t/Analizo/Batch/Job/Git.t0000644000175000017500000001452414676555272017065 0ustar joeniojoeniopackage t::Analizo::Batch::Job::Git; use strict; use warnings; use parent qw(Test::Analizo::Class); use Test::More; use Test::Analizo; use Cwd; use File::Basename; use Test::MockObject; use Test::Analizo::Git; use Analizo::Batch::Job::Git; use Analizo::Batch::Git; my $TESTDIR = 'evolution'; sub constructor : Tests { isa_ok(Analizo::Batch::Job::Git->new, 'Analizo::Batch::Job::Git'); } sub constructor_with_arguments : Tests { my $id = $MAIN; my $job = Analizo::Batch::Job::Git->new($TESTDIR, $id); is($job->directory, $TESTDIR); is($job->{actual_directory}, $TESTDIR); is($job->id, $id); } sub parallelism_support : Tests { my $job = __find($MAIN); $job->parallel_prepare(); isnt($job->{actual_directory}, $TESTDIR); ok(-d $job->{actual_directory}, "different work directory must be created"); ok(-d File::Spec->catfile($job->{actual_directory}, '.git'), "content must be copied"); $job->parallel_cleanup(); ok(! -d $job->{actual_directory}, "different work directory must be removed when parallel_cleanup is called."); is($job->project_name, basename($TESTDIR), 'parallelism support must not mess with project name'); } sub prepare_and_cleanup : Tests { my $job = mock(__find($SOME_COMMIT)); my @checkouts = (); $job->mock('git_checkout', sub { push @checkouts, $_[1]; } ); my $oldcwd = getcwd(); $job->prepare(); my $newcwd = getcwd(); $job->cleanup(); ok($newcwd ne $oldcwd, 'prepare must change dir'); ok(getcwd eq $oldcwd, 'cleanup must change cwd back'); is_deeply(\@checkouts, [$SOME_COMMIT, 'main'], 'cleanup must checkout given commit and go back to previous one'); } sub git_checkout_should_actually_checkout : Tests { my $job = __find($SOME_COMMIT); my $getHEAD = sub { my $commit = `git log --format=%H | head -n 1`; chomp($commit); return $commit; }; my $main1 = on_dir($TESTDIR, $getHEAD); $job->prepare(); my $commit = on_dir($TESTDIR, $getHEAD); $job->cleanup(); my $main2 = on_dir($TESTDIR, $getHEAD); my $branch = on_dir($TESTDIR, sub { $job->git_current_branch() }); is($commit, $SOME_COMMIT); is($main1, $main2); is($main2, $MAIN); is($branch, 'main'); } sub must_NOT_keep_a_reference_to_batch : Tests { my $batch = __get_repo(); my $job = __find(); $job->batch($batch); ok(!exists($job->{batch})); } sub changed_files : Tests { my $repo = __get_repo(); my $main = $repo->find($MAIN); is_deeply($main->changed_files, {'input.cc' => 'M'}); my $some_commit = $repo->find($SOME_COMMIT); is_deeply($some_commit->changed_files, {'prog.cc' => 'M'}); my $add_output_commit = $repo->find($ADD_OUTPUT_COMMIT); is_deeply($add_output_commit->changed_files, { 'output.cc' => 'A', 'output.h' => 'A', 'prog.cc' => 'M' }); my $relevant_merge_commit = $repo->find($RELEVANT_MERGE); is_deeply($relevant_merge_commit->changed_files, { 'prog.cc' => 'MM' }); } sub previous_relevant : Tests { my $batch = __get_repo(); my $first = $batch->find($FIRST_COMMIT); is($first->previous_relevant, undef); my $main = $batch->find($MAIN); is($main->previous_relevant, '0a06a6fcc2e7b4fe56d134e89d74ad028bb122ed'); my $commit = $batch->find('0a06a6fcc2e7b4fe56d134e89d74ad028bb122ed'); is($commit->previous_relevant, 'eb67c27055293e835049b58d7d73ce3664d3f90e'); } sub previous_relevant_with_parent_without_previous_relevant : Tests { my $repo = __get_repo('foo'); my $job = $repo->find('874073a5a36004cf26794a7ff2eacf496f29b786'); is($job->previous_relevant, undef, 'must return undef as previous_relevant when parent is a merge commit without any previous relevant commits'); } sub relevant_merge : Tests { my $batch = __get_repo(); my $relevant_merge = $batch->find($RELEVANT_MERGE); ok($relevant_merge->relevant()); } sub previous_wanted : Tests { my $batch = __get_repo(); my $main = $batch->find($MAIN); is($main->previous_wanted, $main->previous_relevant); my $merge = $batch->find($MERGE_COMMIT); is($merge->previous_wanted, undef); } sub metadata : Tests { my $repo = __get_repo(); my $main = $repo->find($MAIN); my $metadata = $main->metadata(); metadata_ok($metadata, 'author_name', 'Antonio Terceiro', 'author name'); metadata_ok($metadata, 'author_email', 'terceiro@softwarelivre.org', 'author email'); metadata_ok($metadata, 'author_date', 1297788040, 'author date'); # UNIX timestamp for [Tue Feb 15 13:40:40 2011 -0300] metadata_ok($metadata, 'previous_commit_id', '0a06a6fcc2e7b4fe56d134e89d74ad028bb122ed', 'previous commit'); metadata_ok($metadata, 'changed_files', {'input.cc' => 'M'}, 'changed files'); my @files_entry = grep { $_->[0] eq 'files' } @$metadata; my $files = $files_entry[0]->[1]; is($files->{'input.cc'}, '0e85dc55b30f5e257ce5615bfcb229d1ace13e01'); is($files->{'input.h'}, '44edccb29f8b8ba252f15988edacfad481606c45'); is($files->{'output.cc'}, 'ed526e137858cb903730a1886db430c28d6bebcf'); is($files->{'output.h'}, 'a67e1b0986b9cab18fbbb12d0f941982c74d724d'); is($files->{'prog.cc'}, '91745088e303c9440b6d58a5232b5d753d3c91f5'); ok(!defined($files->{Makefile}), 'must not include non-code files in tree'); my $first = $repo->find($FIRST_COMMIT); metadata_ok($first->metadata, 'previous_commit_id', undef, 'unexisting commit id'); } sub merge_and_first_commit_detection : Tests { my $repo = __get_repo(); my $main = $repo->find($MAIN); ok(!$main->is_merge); ok(!$main->is_first_commit); my $first = $repo->find($FIRST_COMMIT); ok($first->is_first_commit); my $merge = $repo->find($MERGE_COMMIT); ok($merge->is_merge); } sub metadata_ok { my ($metadata,$field,$value,$testname) = @_; if (is(ref($metadata), 'ARRAY', $testname)) { my @entries = grep { $_->[0] eq $field } @$metadata; my $entry = $entries[0]; if (is(ref($entry), 'ARRAY', $testname)) { is_deeply($entry->[1], $value, $testname); } } } sub __find { my ($id) = @_; if (defined($id)) { my $repo = __get_repo(); return $repo->find($id); } else { return Analizo::Batch::Job::Git->new; } } my %REPOS = (); sub __get_repo { my ($repoid) = @_; $repoid ||= $TESTDIR; if (defined($REPOS{$repoid})) { return $REPOS{$repoid}; } my $repo = Analizo::Batch::Git->new($repoid); $repo->initialize(); $REPOS{$repoid} = $repo; return $repo; } unpack_sample_git_repository( sub { my $cwd = getcwd; chdir tmpdir(); __PACKAGE__->runtests; chdir $cwd; }, 'evolution', 'foo' ); Analizo-1.25.5/t/Analizo/Batch/Job/Directories.t0000644000175000017500000000154014676555272020610 0ustar joeniojoeniopackage t::Analizo::Batch::Job::Directories; use strict; use warnings; use parent qw(Test::Analizo::Class); use Test::More; use Test::Analizo; use Analizo::Batch::Job::Directories; use Cwd; sub constructor : Tests { my $job = __create_job('c'); isa_ok($job, 'Analizo::Batch::Job::Directories'); is($job->directory, 'c'); is($job->id, 'c'); } sub prepare_and_cleanup : Tests { my $job = __create_job('c'); on_dir( 't/samples/hello_world/', sub { my $oldcwd = getcwd; $job->prepare(); my $newcwd = getcwd(); $job->cleanup(); ok($newcwd ne $oldcwd, 'must change dir in prepare()'); ok($oldcwd eq getcwd, 'must change back dir in cleanup()'); } ) } sub __create_job { my @args = @_; on_dir('t/samples/hello_world', sub { Analizo::Batch::Job::Directories->new(@args) }); } __PACKAGE__->runtests; Analizo-1.25.5/t/Analizo/Batch/Output/0000775000175000017500000000000014676555272016737 5ustar joeniojoenioAnalizo-1.25.5/t/Analizo/Batch/Output/DB.t0000644000175000017500000002342514676555272017415 0ustar joeniojoeniopackage t::Analizo::Batch::Output::DB; use strict; use warnings; use parent qw(Test::Analizo::Class); use Test::More; use Test::Analizo; my $TMPDIR = tmpdir(); my $OUTFILE = $TMPDIR . '/out.sqlite3'; use Analizo::Batch::Output::DB; use DBI; use Analizo::Batch::Job; use Analizo::Batch::Job::Directories; sub basics : Tests { isa_ok(Analizo::Batch::Output::DB->new, 'Analizo::Batch::Output'); isa_ok(Analizo::Batch::Output::DB->new, 'Analizo::Batch::Output::DB'); } sub destination_database : Tests { my $output = __create(); is($output->database, 'dbi:SQLite:output.sqlite3', 'use SQLite output by default'); # specify an specific output file $output->file('mydb.sqlite3'); is($output->database, 'dbi:SQLite:mydb.sqlite3', 'use SQLite with a custom DB name'); # use an explicit DBI data source instead $output->file('dbi:mysql:mydb'); is($output->database, 'dbi:mysql:mydb'); } sub setting_up_a_database : Tests { # new database my $output = __create(); $output->file($OUTFILE); $output->initialize(); table_created_ok($OUTFILE, 'projects'); table_created_ok($OUTFILE, 'commits'); table_created_ok($OUTFILE, 'developers'); table_created_ok($OUTFILE, 'modules'); table_created_ok($OUTFILE, 'module_versions'); table_created_ok($OUTFILE, 'commits_module_versions'); # relationship table # try to re-initialize an existing database - should not crash my $output2 = __create(); $output2->file($OUTFILE); $output2->initialize(); } sub add_project_data : Tests { my $output = __create($OUTFILE); my $job = Analizo::Batch::Job->new; $job->directory('/path/to/niceproject'); $output->push($job); select_one_ok($OUTFILE, "select * from projects where name = 'niceproject'", 'must insert project the first time'); $output->push($job); select_one_ok($OUTFILE, "select * from projects where name = 'niceproject'", 'must not insert same project twice'); } sub add_commit_and_developer_data : Tests { my $output = __create($OUTFILE); my $job = mock(Analizo::Batch::Job->new); $job->directory('/path/to/niceproject'); $job->id('XPTO'); $job->mock( 'metadata_hashref', sub { { 'author_name' => 'Jonh Doe', 'author_email' => 'jdoe@example.com', 'previous_commit_id' => 'PREVIOUS', 'author_date' => '1313206352', } } ); $output->push($job); select_one_ok($OUTFILE, "SELECT * FROM commits JOIN projects on (projects.id = commits.project_id) WHERE commits.id = 'XPTO'"); select_one_ok($OUTFILE, "SELECT * FROM developers JOIN commits on (commits.developer_id = developers.id) WHERE developers.name = 'Jonh Doe' AND developers.email = 'jdoe\@example.com' AND commits.id = 'XPTO'"); select_one_ok($OUTFILE, "SELECT * FROM commits WHERE id = 'XPTO' AND previous_commit_id = 'PREVIOUS' AND date = '1313206352'"); # pushing the same data again should not crash $output->push($job); } my $SAMPLE = ('t/samples/animals/cpp'); sub add_module_data_for_modules_changed_by_commit : Tests { my $output = __create($OUTFILE); my $job = mock(Analizo::Batch::Job::Directories->new($SAMPLE)); $job->id('foo'); $job->execute(); $job->mock( 'metadata_hashref', sub { { 'changed_files' => { 'mammal.h' => 'M', 'dog.cc' => 'M', }, 'files' => { 'mammal.h' => '1111111111111111111111111111111111111111', 'dog.cc' => '2222222222222222222222222222222222222222', 'dog.h' => '3333333333333333333333333333333333333333', 'cat.cc' => '4444444444444444444444444444444444444444', 'cat.h' => '5555555555555555555555555555555555555555', } } } ); $job->mock('project_name', sub { 'animals'; }); $output->push($job); for my $module ('Mammal', 'Dog') { # module select_one_ok($OUTFILE, "SELECT * FROM modules JOIN projects ON (projects.id = modules.project_id) WHERE projects.name = 'animals' AND modules.name = '$module'"); # module_versions and commits_module_versions select_one_ok($OUTFILE, "SELECT * FROM modules JOIN module_versions ON (module_versions.module_id = modules.id) JOIN commits_module_versions ON (commits_module_versions.module_version_id = module_versions.id) JOIN commits ON (commits_module_versions.commit_id = commits.id) WHERE commits.id = 'foo' AND modules.name = '$module' AND module_versions.lcom4 >= 0 AND module_versions.cbo >= 0"); } select_ok($OUTFILE, "SELECT * FROM module_versions JOIN commits_module_versions ON (module_versions.id = commits_module_versions.module_version_id) JOIN commits ON (commits.id = commits_module_versions.commit_id) WHERE commit_id = 'foo'", 3); select_one_ok($OUTFILE, "SELECT * FROM modules JOIN module_versions ON (module_versions.module_id = modules.id) WHERE modules.name = 'Mammal' AND module_versions.id = '1111111111111111111111111111111111111111'"); # one module with multiple files: concatenate SHA1 of files and calculate the SHA1 of that. select_one_ok($OUTFILE, "SELECT * FROM modules JOIN module_versions ON (module_versions.module_id = modules.id) WHERE modules.name = 'Dog' AND module_versions.id = '452219454519b29aae2e135c470d97d9e234976b'"); } sub changed_added_module_versions : Tests { my $output = __create($OUTFILE); my $job = mock(Analizo::Batch::Job::Directories->new($SAMPLE)); $job->id('foo'); $job->execute(); $job->mock( 'metadata_hashref', sub { { 'changed_files' => { 'mammal.h' => 'M', 'dog.cc' => 'A', 'dog.h' => 'A', 'cat.cc' => 'A', 'cat.h' => 'M', }, 'files' => { 'mammal.h' => '1111111111111111111111111111111111111111', 'dog.cc' => '2222222222222222222222222222222222222222', 'dog.h' => '3333333333333333333333333333333333333333', 'cat.cc' => '4444444444444444444444444444444444444444', 'cat.h' => '5555555555555555555555555555555555555555', } } } ); $job->mock('project_name', sub { 'animals'; }); $output->push($job); select_one_ok($OUTFILE, "SELECT * FROM commits_module_versions WHERE commit_id = 'foo' AND module_version_id = '1111111111111111111111111111111111111111' AND modified AND NOT added"); # 452219454519b29aae2e135c470d97d9e234976b = sha1(22222222222222222222222222222222222222223333333333333333333333333333333333333333) select_one_ok($OUTFILE, "SELECT * FROM commits_module_versions WHERE commit_id = 'foo' AND module_version_id = '452219454519b29aae2e135c470d97d9e234976b' AND added AND NOT modified"); # f676c6d81e63377edc2f9ec60b1bc2359b94606f = sha1(44444444444444444444444444444444444444445555555555555555555555555555555555555555) select_one_ok($OUTFILE, "SELECT * FROM commits_module_versions WHERE commit_id = 'foo' AND module_version_id = 'f676c6d81e63377edc2f9ec60b1bc2359b94606f' AND modified AND NOT added"); } sub module_versions_with_the_same_id : Tests { my $output = __create($OUTFILE); my $job = mock(Analizo::Batch::Job::Directories->new($SAMPLE)); $job->mock('project_name', sub { 'animals'; }); $job->id('foo'); $job->execute(); $job->mock( 'metadata_hashref', sub { { 'changed_files' => { 'animal.h' => 'A', 'mammal.h' => 'M', }, 'files' => { 'animal.h' => '1111111111111111111111111111111111111111', 'mammal.h' => '1111111111111111111111111111111111111111', } } } ); $output->push($job); select_ok($OUTFILE, "SELECT * FROM module_versions WHERE id = '1111111111111111111111111111111111111111'", 2); } sub global_metrics : Tests { my $output = __create($OUTFILE); my $job = mock(Analizo::Batch::Job::Directories->new($SAMPLE)); $job->mock('project_name', sub { 'animals'; }); $job->id('foo'); $job->execute(); $output->push($job); select_one_ok($OUTFILE, "SELECT * FROM commits where total_abstract_classes > 0"); } sub files_with_multiple_modules : Tests { my $output = __create($OUTFILE); my $job = mock(Analizo::Batch::Job::Directories->new('t/samples/file_with_two_modules/cpp')); $job->mock('project_name', sub { 'multiple' }); $job->id("foo"); $job->execute; $job->mock( 'metadata_hashref', sub { { 'changed_files' => { 'classes.cc' => 'A', 'classes.h' => 'A', 'main.cc' => 'A', }, 'files' => { 'classes.cc' => '1111111111111111111111111111111111111111', 'classes.h' => '2222222222222222222222222222222222222222', 'main.cc' => '3333333333333333333333333333333333333333', } } } ); $output->push($job); select_ok($OUTFILE, 'SELECT * FROM modules', 3); } sub numeric_autoincrement_pk : Tests { ok(Analizo::Batch::Output::DB::_numeric_autoinc_pk('dbi:SQLite:file.sqlite3') =~ /AUTOINCREMENT/); ok(Analizo::Batch::Output::DB::_numeric_autoinc_pk('dbi:Pg:dbname=analizo') =~ /SERIAL/); } sub __create { my ($file) = @_; my $output = Analizo::Batch::Output::DB->new; if ($file) { $output->file($file); $output->initialize(); } return $output; } sub setup : Test(setup) { system("mkdir", "-p", $TMPDIR); } sub teardown : Test(teardown) { system("rm", "-rf", $TMPDIR); } sub table_created_ok($$) { my ($db, $table) = @_; my $dbh = DBI->connect("dbi:SQLite:$db"); my $TABLE = uc($table); $table = lc($table); my @tables = $dbh->tables(); my $projects_table = scalar(grep { lc($_) =~ /$table/ } @tables); ok($projects_table, "must create $TABLE table"); } sub select_ok($$$) { my ($db, $query, $count) = @_; my $dbh = DBI->connect("dbi:SQLite:$db"); my $rows = $dbh->selectall_arrayref($query); my $row_count = scalar(@$rows); is($row_count, $count, "[$query] returned $row_count rows instead of exactly $count"); } sub select_one_ok($$) { my ($db, $query) = @_; select_ok($db, $query, 1); } __PACKAGE__->runtests; Analizo-1.25.5/t/Analizo/Batch/Output/CSV.t0000644000175000017500000000602314676555272017556 0ustar joeniojoeniopackage t::Analizo::Batch::Output::CSV; use strict; use warnings; use parent qw(Test::Analizo::Class); use Test::More; use Test::Analizo; use Analizo::Batch::Output::CSV; use Analizo::Batch::Job::Directories; my $TMPDIR = tmpdir(); my $TMPFILE = "$TMPDIR/output.csv"; sub setup : Tests(setup) { system("mkdir", "-p", $TMPDIR); } sub teardown : Tests(teardown) { system("rm", "-rf", $TMPDIR); } sub constructor : Tests { my $output = __create(); isa_ok($output, 'Analizo::Batch::Output::CSV'); } sub writing_data : Tests { my $output = __create(); my $job1 = Analizo::Batch::Job::Directories->new('t/samples/animals/cpp'); $job1->execute(); $output->push($job1); my $job2 = Analizo::Batch::Job::Directories->new('t/samples/animals/java'); $job2->execute(); $output->push($job2); $output->file($TMPFILE); $output->flush(); my @lines = readfile $TMPFILE; ok(scalar(@lines) == 3, 'must write data to output file'); ok($lines[0] =~ /^\w+(,\w+)+$/, 'first line must contain column names'); my $empty_lines = grep { /^\s*$/ } @lines; ok($empty_lines == 0, 'CSV output must not contain empty lines'); } sub job_metadata : Tests { my $job = mock(Analizo::Batch::Job::Directories->new('t/samples/animals/cpp')); $job->mock('metadata', sub { [ ['data1', 88], [ 'data2', 77 ] ] }); $job->mock('id', sub { 99 }); $job->execute(); my $output = __create(); $output->file($TMPFILE); $output->push($job); $output->flush(); my @lines = readfile($TMPFILE); ok($lines[0] =~ /^id,data1,data2/, 'must list metadata fields'); ok($lines[1] =~ /^99,88,77/, 'must include metadata values'); } sub must_write_list_data_as_string : Tests { my $job = mock(Analizo::Batch::Job::Directories->new('t/samples/animals/cpp')); $job->execute(); $job->mock( 'metadata', sub { [['values', ['onething','otherthing']],] } ); my $output = __create(); $output->file($TMPFILE); $output->push($job); $output->flush(); my @lines = readfile $TMPFILE; like($lines[1], qr/,"onething;otherthing",/); } sub must_write_hash_data_as_string : Tests { my $job = mock(Analizo::Batch::Job::Directories->new('t/samples/animals/cpp')); $job->execute(); $job->mock( 'metadata', sub { [['data', { 'key1' => 'value1', 'key2' => 'value2'}]]} ); my $output = __create(); $output->file($TMPFILE); $output->push($job); $output->flush(); my @lines = readfile($TMPFILE); like($lines[1], qr/,"key1:value1;key2:value2",/); } sub must_return_short_names_of_metrics : Tests { my $output = __create(); my @short_names = (); @short_names = $output->_extract_short_names_of_metrics(); ok($short_names[0] eq "acc", "must list acc metric name"); ok($short_names[1] eq "accm", "must list accm metric name"); ok($short_names[2] eq "amloc", "must list amloc metric name"); ok($short_names[3] eq "anpm", "must list anpm metric name"); } sub __create { my @args = @_; my $output = mock(Analizo::Batch::Output::CSV->new(@args)); $output->mock('write_details', sub { }); return $output; } __PACKAGE__->runtests; 1; Analizo-1.25.5/t/Analizo/Batch/Directories.t0000644000175000017500000000217514676555272020103 0ustar joeniojoeniopackage t::Analizo::Batch::Directories; use strict; use warnings; use parent qw(Test::Analizo::Class); use Test::More; use Test::Analizo; use Analizo::Batch::Directories; sub expose_list_of_dirs : Tests { can_ok('Analizo::Batch::Directories', 'directories'); } sub create_with_no_arguments : Tests { my $batch = __create_batch(); my @actual = sort(@{$batch->directories}); is_deeply(\@actual, ['c', 'cpp', 'csharp', 'java']); } sub create_with_arguments : Tests { my $batch = __create_batch(qw(c cpp)); is_deeply($batch->directories, ['c', 'cpp']); } sub create_with_bad_arguments : Tests { my $batch = __create_batch(qw(c fortran)); is_deeply(['c'], $batch->directories); } sub deliver_jobs : Tests { my $batch = __create_batch(qw(c cpp)); my $job = $batch->next(); is($job->directory, 'c'); $job = $batch->next(); is($job->directory, 'cpp'); is(undef, $batch->next()); } sub count : Tests { my $batch = __create_batch(qw(c cpp)); is($batch->count, 2); } sub __create_batch { my @args = @_; on_dir('t/samples/hello_world', sub { Analizo::Batch::Directories->new(@args) }); } __PACKAGE__->runtests; 1; Analizo-1.25.5/t/Analizo/Batch/Runner/0000775000175000017500000000000014676555272016710 5ustar joeniojoenioAnalizo-1.25.5/t/Analizo/Batch/Runner/Parallel.t0000644000175000017500000000127314676555272020632 0ustar joeniojoeniopackage t::Analizo::Batch::Runner::Parallel; use strict; use warnings; use parent qw(Test::Analizo::Class); use Test::More; use Test::Analizo; use Analizo::Batch::Runner::Parallel; use Analizo::Batch::Runner::Sequential; use Analizo::Batch::Output; use Analizo::Batch::Directories; sub constuctor : Tests { my $obj = __create(); isa_ok($obj, 'Analizo::Batch::Runner'); isa_ok($obj, 'Analizo::Batch::Runner::Parallel'); } sub number_of_parallel_processes : Tests { my $default = __create(); is($default->parallelism, 2); my $four = __create(4); is($four->parallelism, 4); } sub __create { my @args = @_; Analizo::Batch::Runner::Parallel->new(@args); } __PACKAGE__->runtests; Analizo-1.25.5/t/Analizo/Batch/Runner/Sequential.t0000644000175000017500000000276014676555272021212 0ustar joeniojoeniopackage t::Analizo::Batch::Runner::Sequential; use strict; use warnings; use parent qw(Test::Analizo::Class); use Test::More; use Test::Analizo; use Analizo::Batch::Runner::Sequential; use Analizo::Batch; use Analizo::Batch::Job; use Analizo::Batch::Output; sub constructor : Tests { my $obj = __create(); isa_ok($obj, 'Analizo::Batch::Runner'); isa_ok($obj, 'Analizo::Batch::Runner::Sequential'); } sub empty_batch_wont_crash : Tests { my $batch = Analizo::Batch->new; my $output = Analizo::Batch::Output->new; my $runner = __create(); $runner->run($batch, $output); } sub run : Tests { my $batch = mock(Analizo::Batch->new); my $job1 = mock(Analizo::Batch::Job->new); my $job2 = mock(Analizo::Batch::Job->new); my $output = mock(Analizo::Batch::Output->new); $batch->set_series('next', $job1, $job2, undef); my $job1_executed = 0; $job1->mock('execute', sub { $job1_executed++ }); my $job2_executed = 0; $job2->mock('execute', sub { $job2_executed++ }); my @jobs_pushed = (); $output->mock('push', sub { push @jobs_pushed, $_[1] }); my $output_flushed = 0; $output->mock('flush', sub { $output_flushed++ }); my $runner = __create(); $runner->run($batch, $output); ok($job1_executed == 1, 'job1 must be executed'); ok($job2_executed == 1, 'job2 must be executed'); is_deeply(\@jobs_pushed, [$job1, $job2]); ok($output_flushed == 1, 'output must be flushed exactly once'); } sub __create { Analizo::Batch::Runner::Sequential->new; } __PACKAGE__->runtests; Analizo-1.25.5/t/Analizo/ModuleMetric.t0000644000175000017500000000112414676555272017170 0ustar joeniojoeniopackage t::Analizo::ModuleMetric; use strict; use warnings; use parent qw(Test::Analizo::Class); use Test::More; use Test::MockModule; use Analizo::ModuleMetric; sub caches_calculate_results : Tests { my $AnalizoMetric = Test::MockModule->new('Analizo::ModuleMetric'); my $metric = Analizo::ModuleMetric->new; $AnalizoMetric->mock('calculate', sub { return 1; }); is($metric->value('MyModule'), 1); $AnalizoMetric->mock( 'calculate', sub { die("should not be called again!") } ); $metric->value('MyModule'); # if this does not crash we are OK } __PACKAGE__->runtests; Analizo-1.25.5/t/Analizo/Command/0000775000175000017500000000000014676555272015774 5ustar joeniojoenioAnalizo-1.25.5/t/Analizo/Command/help.t0000644000175000017500000000102414676555272017104 0ustar joeniojoeniopackage t::Analizo::Command::help; use strict; use warnings; use parent qw(Test::Analizo::Class); use Test::More; use Test::Analizo; use Analizo; BEGIN { use_ok 'Analizo::Command::help' }; sub constructor : Tests { my $analizo = Analizo->new; my ($cmd) = $analizo->prepare_command('help'); isa_ok($cmd, 'App::Cmd::Command::help'); } sub is_a_subclass_of_Analizo_Command : Tests { my $analizo = Analizo->new; my ($cmd) = $analizo->prepare_command('help'); isa_ok($cmd, 'Analizo::Command'); } __PACKAGE__->runtests; Analizo-1.25.5/t/Analizo/Command/graph.t0000644000175000017500000000103014676555272017252 0ustar joeniojoeniopackage t::Analizo::Command::graph; use strict; use warnings; use parent qw(Test::Analizo::Class); use Test::More; use Test::Analizo; use Analizo; BEGIN { use_ok 'Analizo::Command::graph' }; sub constructor : Tests { my $analizo = Analizo->new; my ($cmd) = $analizo->prepare_command('graph'); isa_ok($cmd, 'Analizo::Command::graph'); } sub is_a_subclass_of_Analizo_Command : Tests { my $analizo = Analizo->new; my ($cmd) = $analizo->prepare_command('graph'); isa_ok($cmd, 'Analizo::Command'); } __PACKAGE__->runtests; Analizo-1.25.5/t/Analizo/Command/metrics.t0000644000175000017500000000104214676555272017622 0ustar joeniojoeniopackage t::Analizo::Command::metrics; use strict; use warnings; use parent qw(Test::Analizo::Class); use Test::More; use Test::Analizo; use Analizo; BEGIN { use_ok 'Analizo::Command::metrics' }; sub constructor : Tests { my $analizo = Analizo->new; my ($cmd) = $analizo->prepare_command('metrics'); isa_ok($cmd, 'Analizo::Command::metrics'); } sub is_a_subclass_of_Analizo_Command : Tests { my $analizo = Analizo->new; my ($cmd) = $analizo->prepare_command('metrics'); isa_ok($cmd, 'Analizo::Command'); } __PACKAGE__->runtests; Analizo-1.25.5/t/Analizo/Command/files_graph.t0000644000175000017500000000106614676555272020445 0ustar joeniojoeniopackage t::Analizo::Command::files_graph; use strict; use warnings; use parent qw(Test::Analizo::Class); use Test::More; use Test::Analizo; use Analizo; BEGIN { use_ok 'Analizo::Command::files_graph' }; sub constructor : Tests { my $analizo = Analizo->new; my ($cmd) = $analizo->prepare_command('files-graph'); isa_ok($cmd, 'Analizo::Command::files_graph'); } sub is_a_subclass_of_Analizo_Command : Tests { my $analizo = Analizo->new; my ($cmd) = $analizo->prepare_command('files-graph'); isa_ok($cmd, 'Analizo::Command'); } __PACKAGE__->runtests; Analizo-1.25.5/t/Analizo/Command/metrics_batch.t0000644000175000017500000000110014676555272020756 0ustar joeniojoeniopackage t::Analizo::Command::metrics_batch; use strict; use warnings; use parent qw(Test::Analizo::Class); use Test::More; use Test::Analizo; use Analizo; BEGIN { use_ok 'Analizo::Command::metrics_batch' }; sub constructor : Tests { my $analizo = Analizo->new; my ($cmd) = $analizo->prepare_command('metrics-batch'); isa_ok($cmd, 'Analizo::Command::metrics_batch'); } sub is_a_subclass_of_Analizo_Command : Tests { my $analizo = Analizo->new; my ($cmd) = $analizo->prepare_command('metrics-batch'); isa_ok($cmd, 'Analizo::Command'); } __PACKAGE__->runtests; Analizo-1.25.5/t/Analizo/Command/tree_evolution.t0000644000175000017500000000110514676555272021217 0ustar joeniojoeniopackage t::Analizo::Command::tree_evolution; use strict; use warnings; use parent qw(Test::Analizo::Class); use Test::More; use Test::Analizo; use Analizo; BEGIN { use_ok 'Analizo::Command::tree_evolution' }; sub constructor : Tests { my $analizo = Analizo->new; my ($cmd) = $analizo->prepare_command('tree-evolution'); isa_ok($cmd, 'Analizo::Command::tree_evolution'); } sub is_a_subclass_of_Analizo_Command : Tests { my $analizo = Analizo->new; my ($cmd) = $analizo->prepare_command('tree-evolution'); isa_ok($cmd, 'Analizo::Command'); } __PACKAGE__->runtests; Analizo-1.25.5/t/Analizo/Command/metrics_history.t0000644000175000017500000000232014676555272021403 0ustar joeniojoeniopackage t::Analizo::Command::metrics_history; use strict; use warnings; use parent qw(Test::Analizo::Class); use Test::More; use Test::Analizo; use Analizo; BEGIN { use_ok 'Analizo::Command::metrics_history' }; sub constructor : Tests { my $analizo = Analizo->new; my ($cmd) = $analizo->prepare_command('metrics-history'); isa_ok($cmd, 'Analizo::Command::metrics_history'); } sub is_a_subclass_of_Analizo_Command : Tests { my $analizo = Analizo->new; my ($cmd) = $analizo->prepare_command('metrics-history'); isa_ok($cmd, 'Analizo::Command'); } sub output_driver : Tests { my $analizo = Analizo->new; my ($cmd) = $analizo->prepare_command('metrics-history'); cmp_ok($cmd->output_driver('csv'), 'eq', 'Analizo::Batch::Output::CSV'); cmp_ok($cmd->output_driver('db'), 'eq', 'Analizo::Batch::Output::DB'); } sub nil_for_unavaiable_output_driver : Tests { my $analizo = Analizo->new; my ($cmd) = $analizo->prepare_command('metrics-history'); ok(! $cmd->output_driver('something')); } sub load_output_driver : Tests { my $analizo = Analizo->new; my ($cmd) = $analizo->prepare_command('metrics-history'); isa_ok($cmd->output_driver('csv'), 'Analizo::Batch::Output::CSV'); } __PACKAGE__->runtests; Analizo-1.25.5/t/Analizo/GlobalMetrics.t0000644000175000017500000001540314676555272017333 0ustar joeniojoeniopackage t::Analizo::GlobalMetrics; use strict; use warnings; use parent qw(Test::Analizo::Class); use Test::More; use Statistics::Descriptive; use Analizo::GlobalMetrics; use Analizo::Model; use vars qw($model $global_metrics); sub setup : Test(setup) { $model = Analizo::Model->new; $global_metrics = Analizo::GlobalMetrics->new(model => $model); } sub constructor : Tests { isa_ok($global_metrics, 'Analizo::GlobalMetrics'); } sub model : Tests { is($global_metrics->model, $model); } sub metric_from_global_metrics_package : Tests{ $model->add_abstract_class('mod'); $model->declare_function('mod', 'f1'); my $report = $global_metrics->report(); is($report->{'total_abstract_classes'}, 1, '1 abstract class'); is($report->{'total_methods_per_abstract_class'}, 1, '1 method per abstract class'); } sub total_modules : Tests { my $report = $global_metrics->report; is($report->{'total_modules'}, 0); my %dummy_module_values = (); $global_metrics->add_module_values(\%dummy_module_values); $report = $global_metrics->report; is($report->{'total_modules'}, 1); } sub total_modules_with_defined_methods_when_no_modules_where_defined : Tests { my $report = $global_metrics->report; is($report->{'total_modules_with_defined_methods'}, 0); } sub total_modules_with_defined_methods_when_a_module_has_nom : Tests{ my %module_values = (nom => 1); $global_metrics->add_module_values(\%module_values); my $report = $global_metrics->report; is($report->{'total_modules_with_defined_methods'}, 1); } sub total_modules_with_defined_methods_when_a_module_has_no_nom : Tests { my %module_values = (nom => 0); $global_metrics->add_module_values(\%module_values); my $report = $global_metrics->report; is($report->{'total_modules_with_defined_methods'}, 0); } sub total_modules_with_defined_attributes_when_no_modules_where_defined : Tests { my $report = $global_metrics->report; is($report->{'total_modules_with_defined_attributes'}, 0); } sub total_modules_with_defined_attributes_when_a_module_has_noa : Tests{ my %module_values = (noa => 1); $global_metrics->add_module_values(\%module_values); my $report = $global_metrics->report; is($report->{'total_modules_with_defined_attributes'}, 1); } sub total_modules_with_defined_attributes_when_a_module_has_no_noa : Tests { my %module_values = (noa => 0); $global_metrics->add_module_values(\%module_values); my $report = $global_metrics->report; is($report->{'total_modules_with_defined_attributes'}, 0); } sub total_nom_with_no_nom_found : Tests { my $report = $global_metrics->report; is($report->{'total_nom'}, 0); } sub one_total_nom_found : Tests { my %module_values = (nom => 1); $global_metrics->add_module_values(\%module_values); my $report = $global_metrics->report; is($report->{'total_nom'}, 1); } sub sum_the_values_of_nom_found : Tests { my %module_values = (nom => 1); $global_metrics->add_module_values(\%module_values); my %other_values = (nom => 3); $global_metrics->add_module_values(\%other_values); my $report = $global_metrics->report; is($report->{'total_nom'}, 4); } sub total_loc_with_no_loc_found : Tests { my $report = $global_metrics->report; is($report->{'total_loc'}, 0); } sub one_total_loc_found : Tests { my %module_values = (loc => 1); $global_metrics->add_module_values(\%module_values); my $report = $global_metrics->report; is($report->{'total_loc'}, 1); } sub sum_the_values_of_loc_found : Tests { my %module_values = (loc => 1); $global_metrics->add_module_values(\%module_values); my %other_values = (loc => 3); $global_metrics->add_module_values(\%other_values); my $report = $global_metrics->report; is($report->{'total_loc'}, 4); } sub add_loc_mean_when_there_was_no_added_values : Tests { my $report = $global_metrics->report; is($report->{'loc_mean'}, undef); } sub add_loc_mean_when_there_was_one_added_values : Tests { my %module_values = (loc => 1); $global_metrics->add_module_values(\%module_values); my $report = $global_metrics->report; is($report->{'loc_mean'}, 1); } sub add_loc_mean_when_there_were_two_added_values : Tests { my %module_values = (loc => 1); $global_metrics->add_module_values(\%module_values); my %other_values = (loc => 3); $global_metrics->add_module_values(\%other_values); my $report = $global_metrics->report; is($report->{'loc_mean'}, 2); } sub add_lcom4_mean_when_there_were_two_added_values : Tests { my %module_values = (lcom4 => 1); $global_metrics->add_module_values(\%module_values); my %other_values = (lcom4 => 3); $global_metrics->add_module_values(\%other_values); my $report = $global_metrics->report; is($report->{'lcom4_mean'}, 2); } sub add_rfc_sum_when_there_were_two_added_values : Tests { my %module_values = (rfc => 1); $global_metrics->add_module_values(\%module_values); my %other_values = (rfc => 3); $global_metrics->add_module_values(\%other_values); my $report = $global_metrics->report; is($report->{'rfc_sum'}, 4); } sub should_have_other_descriptive_statistics : Tests { my %module_values = (rfc => 1); $global_metrics->add_module_values(\%module_values); my $report = $global_metrics->report; isnt($report->{'rfc_mean'}, undef); isnt($report->{'rfc_quantile_max'}, undef); isnt($report->{'rfc_standard_deviation'}, undef); isnt($report->{'rfc_sum'}, undef); isnt($report->{'rfc_variance'}, undef); } sub should_have_distributions_statistics : Tests { my %module_values = (rfc => 4); $global_metrics->add_module_values(\%module_values); $global_metrics->add_module_values(\%module_values); $global_metrics->add_module_values(\%module_values); $global_metrics->add_module_values(\%module_values); my $report = $global_metrics->report; isnt($report->{'rfc_kurtosis'}, undef); isnt($report->{'rfc_skewness'}, undef); } sub should_add_total_coupling_factor : Tests { my $report = $global_metrics->report; is($report->{'total_cof'}, 1); my %module_values = (acc => 1); $global_metrics->add_module_values(\%module_values); $global_metrics->add_module_values(\%module_values); $global_metrics->add_module_values(\%module_values); $report = $global_metrics->report; is($report->{'total_cof'}, 0.5); } sub should_ignore_module_name : Tests { my %module_values = ('_module' => 'mod1'); $global_metrics->add_module_values(\%module_values); my $report = $global_metrics->report; is($report->{'_module'}, undef); } sub list_of_metrics : Tests { my %metrics = $global_metrics->list(); cmp_ok(scalar(keys(%metrics)), '>', 0, 'must list metrics'); } sub should_ignore_filename : Tests { my %values = (_filename => 'main.c'); $global_metrics->add_module_values(\%values); my $report = $global_metrics->report; ok(! grep(/^_filename/, keys %$report), "Should ignore _filename metrics"); } __PACKAGE__->runtests; Analizo-1.25.5/t/Analizo/ModuleMetrics.t0000644000175000017500000000173514676555272017363 0ustar joeniojoeniopackage t::Analizo::ModuleMetrics; use strict; use warnings; use parent qw(Test::Analizo::Class); use Test::More; use Analizo::Model; use Analizo::ModuleMetrics; use vars qw($model $module_metrics ); sub setup : Test(setup) { $model = Analizo::Model->new; $module_metrics = Analizo::ModuleMetrics->new(model => $model); } sub constructor : Tests { isa_ok($module_metrics, 'Analizo::ModuleMetrics'); } sub list_of_metrics : Tests { my %metrics = $module_metrics->list(); cmp_ok(scalar(keys(%metrics)), '>', 0, 'must list metrics'); } sub metrics_of_module : Tests { $model->declare_function('mod1', 'f1'); $model->add_protection('f1', 'public'); $model->add_loc('f1', 10); $model->declare_function('mod1', 'f2'); $model->add_loc('f2', 10); my $report = $module_metrics->report('mod1'); is($report->{'_module'}, 'mod1'); is($report->{'nom'}, 2); is($report->{'noa'}, 0); is($report->{'npm'}, 1); is($report->{'amloc'}, 10); } __PACKAGE__->runtests; Analizo-1.25.5/t/Analizo/FilenameFilter.t0000644000175000017500000000175014676555272017472 0ustar joeniojoeniopackage t::Analizo::FilenameFilter; use strict; use warnings; use parent qw(Test::Analizo::Class); use Test::More; use Analizo::FilenameFilter; sub constructor : Tests { isa_ok(Analizo::FilenameFilter->new, 'Analizo::FilenameFilter'); } sub null_object : Tests { my $filter = Analizo::FilenameFilter->new; ok($filter->matches('test.c')); } sub excluder : Tests { my $excluder = Analizo::FilenameFilter->exclude('test', 'stats'); isa_ok($excluder, 'Analizo::FilenameFilter'); ok(!$excluder->matches('test')); ok(!$excluder->matches('test/test.c')); ok(!$excluder->matches('stats')); ok(!$excluder->matches('stats/stats.c')); ok($excluder->matches('main.c')); } sub must_match_filenames_with_or_without_leading_dot : Tests { my $filter = Analizo::FilenameFilter->exclude('test', 'src'); ok(!$filter->matches('test')); ok(!$filter->matches('./test')); # now also exclude 'src' ok(!$filter->matches('src')); ok(!$filter->matches('./src')); } __PACKAGE__->runtests; Analizo-1.25.5/t/Analizo/LanguageFilter.t0000644000175000017500000000373214676555272017477 0ustar joeniojoeniopackage t::Analizo::LanguageFilter; use strict; use warnings; use parent qw(Test::Analizo::Class); use Test::More; use Analizo::LanguageFilter; sub constructor : Tests { isa_ok(Analizo::LanguageFilter->new, 'Analizo::LanguageFilter'); } sub null_object_matches_everything_that_is_supported : Tests { my $filter = Analizo::LanguageFilter->new(); ok($filter->matches('test.c')); ok($filter->matches('Test.java')); ok(!$filter->matches('Makefile')) } sub c_filter_matches_dot_c_and_dot_h : Tests { my $filter = Analizo::LanguageFilter->new('c'); ok($filter->matches('test.c')); ok($filter->matches('test.h')); ok(!$filter->matches('Test.java')); } sub cpp_filter_matches_cpp_cc_cxx_hpp_h_hh : Tests { my $filter = Analizo::LanguageFilter->new("cpp"); ok($filter->matches('test.cpp')); ok($filter->matches('test.cxx')); ok($filter->matches('test.cc')); ok($filter->matches('test.hpp')); ok($filter->matches('test.h')); ok($filter->matches('test.hh')); ok(!$filter->matches('test.c')); ok(!$filter->matches('test.java')); } sub java_filter_matches_java_only : Tests { my $filter = Analizo::LanguageFilter->new('java'); ok($filter->matches('Test.java')); ok(!$filter->matches('Test.c')); ok(!$filter->matches('Test.h')); ok(!$filter->matches('Test.cpp')); } sub must_be_case_insensitive : Tests { my $filter = Analizo::LanguageFilter->new('all'); ok($filter->matches('test.C')); ok($filter->matches('test.CPP')); ok($filter->matches('Test.H')); ok($filter->matches('Test.JAVA')); } sub list_languages : Tests { my @language_list = Analizo::LanguageFilter->list; ok(grep { /^java$/ } @language_list); ok(grep { /^cpp$/ } @language_list); } sub csharp_filter_matches_cs_only : Tests { my $filter = Analizo::LanguageFilter->new('csharp'); ok($filter->matches('Test.cs')); ok(!$filter->matches('Test.java')); ok(!$filter->matches('Test.c')); ok(!$filter->matches('Test.h')); ok(!$filter->matches('Test.cpp')); } __PACKAGE__->runtests; Analizo-1.25.5/t/Analizo/Metric/0000775000175000017500000000000014676555272015641 5ustar joeniojoenioAnalizo-1.25.5/t/Analizo/Metric/LinesOfCode.t0000644000175000017500000000207114676555272020156 0ustar joeniojoeniopackage t::Analizo::Metric::LinesOfCode; use strict; use warnings; use parent qw(Test::Analizo::Class); use Test::More; use File::Basename; use Analizo::Model; use Analizo::Metric::LinesOfCode; eval('$Analizo::Metric::QUIET = 1;'); # the eval is to avoid Test::* complaining about possible typo use vars qw($model $loc); sub setup : Test(setup) { $model = Analizo::Model->new; $loc = Analizo::Metric::LinesOfCode->new(model => $model); } sub use_package : Tests { use_ok('Analizo::Metric::LinesOfCode'); } sub has_model : Tests { is($loc->model, $model); } sub description : Tests { is($loc->description, "Lines of Code"); } sub calculate : Tests { is($loc->calculate('mod1'), 0, 'empty module has 0 loc'); $model->declare_function('mod1', 'mod1::f1'); $model->add_loc('mod1::f1', 10); is($loc->calculate('mod1'), 10, 'one module, with 10 loc'); $model->declare_function('mod1', 'mod1::f2'); $model->add_loc('mod1::f2', 20); is($loc->calculate('mod1'), 30, 'adding another module with 20 loc makes the total equal 30'); } __PACKAGE__->runtests; Analizo-1.25.5/t/Analizo/Metric/NumberOfMethods.t0000644000175000017500000000204414676555272021065 0ustar joeniojoeniopackage t::Analizo::Metric::NumberOfMethods; use strict; use warnings; use parent qw(Test::Analizo::Class); use Test::More; use File::Basename; use Analizo::Model; use Analizo::Metric::NumberOfMethods; eval('$Analizo::Metric::QUIET = 1;'); # the eval is to avoid Test::* complaining about possible typo use vars qw($model $nom); sub setup : Test(setup) { $model = Analizo::Model->new; $nom = Analizo::Metric::NumberOfMethods->new(model => $model); } sub use_package : Tests { use_ok('Analizo::Metric::NumberOfMethods'); } sub has_model : Tests { is($nom->model, $model); } sub description : Tests { is($nom->description, "Number of Methods"); } sub calculate : Tests { is($nom->calculate('mod1'), 0, 'empty modules have no functions'); $model->declare_function("mod1", 'f1'); is($nom->calculate('mod1'), 1, 'module with just one function has number of functions = 1'); $model->declare_function('mod1', 'f2'); is($nom->calculate('mod1'), 2, 'module with just two functions has number of functions = 2'); } __PACKAGE__->runtests; Analizo-1.25.5/t/Analizo/Metric/ResponseForClass.t0000644000175000017500000000270414676555272021262 0ustar joeniojoeniopackage t::Analizo::Metric::ResponseForClass; use strict; use warnings; use parent qw(Test::Analizo::Class); use Test::More; use File::Basename; use Analizo::Model; use Analizo::Metric::ResponseForClass; eval('$Analizo::Metric::QUIET = 1;'); # the eval is to avoid Test::* complaining about possible typo use vars qw($model $rfc); sub setup : Test(setup) { $model = Analizo::Model->new; $rfc = Analizo::Metric::ResponseForClass->new(model => $model); } sub use_package : Tests { use_ok('Analizo::Metric::ResponseForClass'); } sub has_model : Tests { is($rfc->model, $model); } sub description : Tests { is($rfc->description, "Response for a Class"); } sub calculate : Tests { $model->declare_module('module'); is($rfc->calculate('module'), 0, "no functions declared on the module"); $model->declare_function('module', 'function'); is($rfc->calculate('module'), 1, "one function declared on the module"); $model->declare_function('module', 'another_function'); is($rfc->calculate('module'), 2, "two functions declared on the module"); $model->declare_function('module2', 'function2'); $model->add_call('function', 'function2'); is($rfc->calculate('module'), 3, "two functions and one call declared on the module"); $model->declare_function('module2', 'function3'); $model->add_call('another_function', 'function3'); is($rfc->calculate('module'), 4, "two functions and two calls declared on the module"); } __PACKAGE__->runtests; Analizo-1.25.5/t/Analizo/Metric/NumberOfChildren.t0000644000175000017500000000274314676555272021220 0ustar joeniojoeniopackage t::Analizo::Metric::NumberOfChildren; use strict; use warnings; use parent qw(Test::Analizo::Class); use Test::More; use File::Basename; use Analizo::Model; use Analizo::Metric::NumberOfChildren; eval('$Analizo::Metric::QUIET = 1;'); # the eval is to avoid Test::* complaining about possible typo use vars qw($model $noc); sub setup : Test(setup) { $model = Analizo::Model->new; $noc = Analizo::Metric::NumberOfChildren->new(model => $model); } sub use_package : Tests { use_ok('Analizo::Metric::NumberOfChildren'); } sub has_model : Tests { is($noc->model, $model); } sub description : Tests{ is($noc->description, "Number of Children"); } sub calculate : Tests { $model->declare_module('A'); $model->declare_module('B'); $model->declare_module('C'); $model->declare_module('D'); is($noc->calculate('A'), 0, 'no children module A'); is($noc->calculate('B'), 0, 'no children module B'); is($noc->calculate('C'), 0, 'no children module C'); $model->add_inheritance('B', 'A'); is($noc->calculate('A'), 1, 'one child module A'); is($noc->calculate('B'), 0, 'no children module B'); $model->add_inheritance('C', 'A'); is($noc->calculate('A'), 2, 'two children module A'); is($noc->calculate('C'), 0, 'no children module C'); $model->add_inheritance('D', 'C'); is($noc->calculate('A'), 2, 'two children module A'); is($noc->calculate('C'), 1, 'one child module C'); is($noc->calculate('D'), 0, 'no children module D'); } __PACKAGE__->runtests; Analizo-1.25.5/t/Analizo/Metric/NumberOfAttributes.t0000644000175000017500000000203114676555272021604 0ustar joeniojoeniopackage t::Analizo::Metric::NumberOfAttributes; use strict; use warnings; use parent qw(Test::Analizo::Class); use Test::More; use File::Basename; use Analizo::Model; use Analizo::Metric::NumberOfAttributes; eval('$Analizo::Metric::QUIET = 1;'); # the eval is to avoid Test::* complaining about possible typo use vars qw($model $noa); sub setup : Test(setup) { $model = Analizo::Model->new; $noa = Analizo::Metric::NumberOfAttributes->new(model => $model); } sub use_package : Tests { use_ok('Analizo::Metric::NumberOfAttributes'); } sub has_model : Tests { is($noa->model, $model); } sub description : Tests { is($noa->description, "Number of Attributes"); } sub calculate : Tests { is($noa->calculate('module1'), 0, 'empty modules have no attributes'); $model->declare_variable('module1', 'attr1'); is($noa->calculate('module1'), 1, 'module with one defined attribute'); $model->declare_variable('module1', 'attr2'); is($noa->calculate('module1'), 2, 'module with two defined attribute'); } __PACKAGE__->runtests; Analizo-1.25.5/t/Analizo/Metric/StructuralComplexity.t0000644000175000017500000000377614676555272022267 0ustar joeniojoeniopackage t::Analizo::Metric::StructuralComplexity; use strict; no strict 'subs'; use warnings; use parent qw(Test::Analizo::Class); use Test::More; use File::Basename; use Analizo::Model; use Analizo::Metric::StructuralComplexity; use Analizo::Metric::CouplingBetweenObjects; use Analizo::Metric::LackOfCohesionOfMethods; eval('$Analizo::Metric::QUIET = 1;'); # the eval is to avoid Test::* complaining about possible typo use vars qw($model $sc $cbo $lcom4); sub setup : Test(setup) { $model = Analizo::Model->new; $cbo = undef; $lcom4 = undef; $sc = Analizo::Metric::StructuralComplexity->new(model => $model, cbo => $cbo, lcom4 => $lcom4); } sub use_package : Tests { use_ok('Analizo::Metric::StructuralComplexity'); } sub has_model : Tests { is($sc->model, $model); } sub description : Tests { is($sc->description, "Structural Complexity"); } sub sc_definition : Tests { no warnings; local *Analizo::Metric::LackOfCohesionOfMethods::calculate = sub { 2 }; local *Analizo::Metric::CouplingBetweenObjects::calculate = sub { 3 }; use warnings; $cbo = Analizo::Metric::CouplingBetweenObjects->new(model => $model); $lcom4 = Analizo::Metric::LackOfCohesionOfMethods->new(model => $model); $sc = Analizo::Metric::StructuralComplexity->new(model => $model, cbo => $cbo, lcom4 => $lcom4); is($sc->calculate('mod1'), 6); } sub sc_implementation : Tests { my $lcom4_called = undef; my $cbo_called = undef; no warnings; local *Analizo::Metric::LackOfCohesionOfMethods::calculate = sub { $lcom4_called = 1; return 2; }; local *Analizo::Metric::CouplingBetweenObjects::calculate = sub { $cbo_called = 1; return 5; }; use warnings; $cbo = Analizo::Metric::CouplingBetweenObjects->new(model => $model); $lcom4 = Analizo::Metric::LackOfCohesionOfMethods->new(model => $model); $sc = Analizo::Metric::StructuralComplexity->new(model => $model, cbo => $cbo, lcom4 => $lcom4); my $sc_value = $sc->calculate('mod1'); ok($lcom4_called); ok($cbo_called); is($sc_value, 10); } __PACKAGE__->runtests; Analizo-1.25.5/t/Analizo/Metric/NumberOfPublicMethods.t0000644000175000017500000000235014676555272022224 0ustar joeniojoeniopackage t::Analizo::Metric::NumberOfPublicMethods; use strict; use warnings; use parent qw(Test::Analizo::Class); use Test::More; use File::Basename; use Analizo::Model; use Analizo::Metric::NumberOfPublicMethods; eval('$Analizo::Metric::QUIET = 1;'); # the eval is to avoid Test::* complaining about possible typo use vars qw($model $npm); sub setup : Test(setup) { $model = Analizo::Model->new; $npm = Analizo::Metric::NumberOfPublicMethods->new(model => $model); } sub use_package : Tests { use_ok('Analizo::Metric::NumberOfPublicMethods'); } sub has_model : Tests { is($npm->model, $model); } sub description : Tests { is($npm->description, "Number of Public Methods"); } sub calculate : Tests { is($npm->calculate('mod1'), 0, 'empty modules have 0 public functions'); $model->declare_function('mod1', 'mod1::f1'); $model->add_protection('mod1::f1', 'public'); is($npm->calculate('mod1'), 1, 'one public function added'); $model->declare_function('mod1', 'mod1::f2'); $model->add_protection('mod1::f2', 'public'); is($npm->calculate('mod1'), 2, 'another public function added'); $model->declare_function('mod1', 'mod1::f3'); is($npm->calculate('mod1'), 2, 'not public function added'); } __PACKAGE__->runtests; Analizo-1.25.5/t/Analizo/Metric/AverageCycloComplexity.t0000644000175000017500000000255614676555272022456 0ustar joeniojoeniopackage t::Analizo::Metric::AverageCycloComplexity; use strict; use warnings; use parent qw(Test::Analizo::Class); use Test::More; use File::Basename; use Analizo::Model; use Analizo::Metric::AverageCycloComplexity; eval('$Analizo::Metric::QUIET = 1;'); # the eval is to avoid Test::* complaining about possible typo use vars qw($model $accm); sub setup : Test(setup) { $model = Analizo::Model->new; $accm = Analizo::Metric::AverageCycloComplexity->new(model => $model); } sub use_package : Tests { use_ok('Analizo::Metric::AverageCycloComplexity'); } sub has_model : Tests { is($accm->model, $model); } sub description : Tests { is($accm->description, "Average Cyclomatic Complexity per Method"); } sub calculate : Tests { $model->declare_module('module'); is($accm->calculate('module'), 0, 'no function'); $model->declare_function('module', 'module::function'); $model->add_conditional_paths('module::function', 2); is($accm->calculate('module'), 3, 'one function with two conditional paths'); $model->declare_function('module', 'module::function1'); $model->add_conditional_paths('module::function1', 1); $model->declare_function('module', 'module::function2'); $model->add_conditional_paths('module::function2', 3); is($accm->calculate('module'), 3, 'two function with three average cyclomatic complexity per method'); } __PACKAGE__->runtests; Analizo-1.25.5/t/Analizo/Metric/CouplingBetweenObjects.t0000644000175000017500000000322614676555272022433 0ustar joeniojoeniopackage t::Analizo::Metric::CouplingBetweenObjects; use strict; use warnings; use parent qw(Test::Analizo::Class); use Test::More; use File::Basename; use Analizo::Model; use Analizo::Metric::CouplingBetweenObjects; eval('$Analizo::Metric::QUIET = 1;'); # the eval is to avoid Test::* complaining about possible typo use vars qw($model $cbo); sub setup : Test(setup) { $model = Analizo::Model->new; $cbo = Analizo::Metric::CouplingBetweenObjects->new(model => $model); } sub use_package : Tests { use_ok('Analizo::Metric::CouplingBetweenObjects'); } sub has_model : Tests { is($cbo->model, $model); } sub description : Tests { is($cbo->description, "Coupling Between Objects"); } sub calculate : Tests { $model->declare_function('mod1', 'f1'); $model->declare_function('mod2', 'f2'); is($cbo->calculate('mod1'), 0, 'no cbo'); $model->add_call('f1', 'f1'); is($cbo->calculate('mod1'), 0, 'calling itself does not count as cbo'); $model->add_call('f1', 'f2'); is($cbo->calculate('mod1'), 1, 'calling a single other module'); $model->declare_function('mod3', 'f3'); $model->add_call('f1', 'f3'); is($cbo->calculate('mod1'), 2, 'calling two function in distinct modules'); $model->declare_function('mod3', 'f3a'); $model->add_call('f1', 'f3a'); is($cbo->calculate('mod1'), 2, 'calling two different functions in the same module'); } sub discard_external_symbols_for_calculate : Tests { $model->declare_function('mod1', 'f1'); $model->declare_function('mod2', 'f2'); $model->add_call('f1', 'f2'); $model->add_call('f1', 'external_function'); is($cbo->calculate('mod1'), 1, 'calling a external function'); } __PACKAGE__->runtests; Analizo-1.25.5/t/Analizo/Metric/DepthOfInheritanceTree.t0000644000175000017500000000237114676555272022352 0ustar joeniojoeniopackage t::Analizo::Metric::DepthOfInheritanceTree; use strict; use warnings; use parent qw(Test::Analizo::Class); use Test::More; use File::Basename; use Analizo::Model; use Analizo::Metric::DepthOfInheritanceTree; eval('$Analizo::Metric::QUIET = 1;'); # the eval is to avoid Test::* complaining about possible typo use vars qw($model $dit); sub setup : Test(setup) { $model = Analizo::Model->new; $dit = Analizo::Metric::DepthOfInheritanceTree->new(model => $model); } sub use_package : Tests { use_ok('Analizo::Metric::DepthOfInheritanceTree'); } sub has_model : Tests { is($dit->model, $model); } sub description : Tests { return "Depth of Inheritance Tree"; } sub calculate : Tests { $model->add_inheritance('Level1', 'Level2'); $model->add_inheritance('Level2', 'Level3'); is($dit->calculate('Level1'), 2, 'DIT = 2'); is($dit->calculate('Level2'), 1, 'DIT = 1'); is($dit->calculate('Level3'), 0, 'DIT = 0'); } sub calculate_with_multiple_inheritance : Tests { $model->add_inheritance('Level1', 'Level2A'); $model->add_inheritance('Level1', 'Level2B'); $model->add_inheritance('Level2B', 'Level3B'); is($dit->calculate('Level1'), 2, 'with multiple inheritance take the larger DIT between the parents'); } __PACKAGE__->runtests; Analizo-1.25.5/t/Analizo/Metric/LackOfCohesionOfMethods.t0000644000175000017500000000425014676555272022465 0ustar joeniojoeniopackage t::Analizo::Metric::LackOfCohesionOfMethods; use strict; use warnings; use parent qw(Test::Analizo::Class); use Test::More; use File::Basename; use Analizo::Model; use Analizo::Metric::LackOfCohesionOfMethods; eval('$Analizo::Metric::QUIET = 1;'); # the eval is to avoid Test::* complaining about possible typo use vars qw($model $lcom4); sub setup : Test(setup) { $model = Analizo::Model->new; $lcom4 = Analizo::Metric::LackOfCohesionOfMethods->new(model => $model); } sub use_package : Tests { use_ok('Analizo::Metric::LackOfCohesionOfMethods'); } sub has_model : Tests { is($lcom4->model, $model); } sub description : Tests { is($lcom4->description, "Lack of Cohesion of Methods"); } sub calculate : Tests { $model->declare_function('mod1', $_) for qw(f1 f2); is($lcom4->calculate('mod1'), 2, 'two unrelated functions'); $model->declare_variable('mod1', 'v1'); $model->add_variable_use($_, 'v1') for qw(f1 f2); is($lcom4->calculate('mod1'), 1, 'two cohesive functions'); $model->declare_function('mod1', 'f3'); $model->declare_variable('mod1', 'v2'); $model->add_variable_use('f3', 'v2'); is($lcom4->calculate('mod1'), 2, 'two different usage components'); $model->declare_function('mod1', 'f4'); $model->declare_variable('mod1', 'v3'); $model->add_variable_use('f4', 'v3'); is($lcom4->calculate('mod1'), 3, 'three different usage components'); } sub calculate_2 : Tests { $model->declare_function('mod1', 'f1'); $model->declare_function('mod1', 'f2'); $model->declare_function('mod1', 'f3'); $model->declare_variable('mod1', 'v1'); $model->add_call('f1', 'f2'); $model->add_call('f1', 'f3', 'indirect'); $model->add_variable_use('f2', 'v1'); is($lcom4->calculate('mod1'), '1', 'different types of connections'); } sub calculate_3 : Tests { $model->declare_function('mod1', 'f1'); $model->declare_function('mod1', 'f2'); $model->declare_function('mod1', 'f3'); $model->add_call('f1', 'f2'); # f1 and f3 calls the same function in another module $model->add_call('f1', 'ff'); $model->add_call('f3', 'ff'); is($lcom4->calculate('mod1'), 2, 'functions outside the module don\'t count for LCOM4'); } __PACKAGE__->runtests; Analizo-1.25.5/t/Analizo/Metric/MaximumMethodLinesOfCode.t0000644000175000017500000000221314676555272022653 0ustar joeniojoeniopackage t::Analizo::Metric::MaximumMethodLinesOfCode; use strict; use warnings; use parent qw(Test::Analizo::Class); use Test::More; use File::Basename; use Analizo::Model; use Analizo::Metric::MaximumMethodLinesOfCode; eval('$Analizo::Metric::QUIET = 1;'); # the eval is to avoid Test::* complaining about possible typo use vars qw($model $mmloc); sub setup : Test(setup) { $model = Analizo::Model->new; $mmloc = Analizo::Metric::MaximumMethodLinesOfCode->new(model => $model); } sub use_package : Tests { use_ok('Analizo::Metric::MaximumMethodLinesOfCode'); } sub has_model : Tests { is($mmloc->model, $model); } sub description : Tests { is($mmloc->description, "Max Method LOC"); } sub calculate : Tests { is($mmloc->calculate('mod1'), 0, 'empty module has max loc 0'); $model->declare_function('mod1', 'mod1::f1'); $model->add_loc('mod1::f1', 10); is($mmloc->calculate('mod1'), 10, 'one module, with 10 loc, makes max loc = 10'); $model->declare_function('mod1', 'mod1::f2'); $model->add_loc('mod1::f2', 5); is($mmloc->calculate('mod1'), 10, 'adding module with 5 loc makes the max continue 10'); } __PACKAGE__->runtests; Analizo-1.25.5/t/Analizo/Metric/NumberOfPublicAttributes.t0000644000175000017500000000237314676555272022754 0ustar joeniojoeniopackage t::Analizo::Metric::NumberOfPublicAttributes; use strict; use warnings; use parent qw(Test::Analizo::Class); use Test::More; use File::Basename; use Analizo::Model; use Analizo::Metric::NumberOfPublicAttributes; eval('$Analizo::Metric::QUIET = 1;'); # the eval is to avoid Test::* complaining about possible typo use vars qw($model $npa); sub setup : Test(setup) { $model = Analizo::Model->new; $npa = Analizo::Metric::NumberOfPublicAttributes->new(model => $model); } sub use_package : Tests { use_ok('Analizo::Metric::NumberOfPublicAttributes'); } sub has_model : Tests { is($npa->model, $model); } sub description : Tests { is($npa->description, "Number of Public Attributes"); } sub calculate : Tests { is($npa->calculate('mod1'), 0, 'empty modules have 0 public attributes'); $model->declare_variable('mod1', 'mod1::a1'); $model->add_protection('mod1::a1', 'public'); is($npa->calculate('mod1'), 1, 'one public attribute added'); $model->declare_variable('mod1', 'mod1::a2'); $model->add_protection('mod1::a2', 'public'); is($npa->calculate('mod1'), 2, 'another public attribute added'); $model->declare_variable('mod1', 'mod1::a3'); is($npa->calculate('mod1'), 2, 'not public attribute added'); } __PACKAGE__->runtests; Analizo-1.25.5/t/Analizo/Metric/AverageMethodLinesOfCode.t0000644000175000017500000000223014676555272022607 0ustar joeniojoeniopackage t::Analizo::Metric::AverageMethodLinesOfCode; use strict; use warnings; use parent qw(Test::Analizo::Class); use Test::More; use File::Basename; use Analizo::Model; use Analizo::Metric::AverageMethodLinesOfCode; eval('$Analizo::Metric::QUIET = 1;'); # the eval is to avoid Test::* complaining about possible typo use vars qw($model $amloc); sub setup : Test(setup) { $model = Analizo::Model->new; $amloc = Analizo::Metric::AverageMethodLinesOfCode->new(model => $model); } sub use_package : Tests { use_ok('Analizo::Metric::AverageMethodLinesOfCode'); } sub has_model : Tests { is($amloc->model, $model); } sub description : Tests { is($amloc->description, "Average Method Lines of Code"); } sub calculate : Tests { is($amloc->calculate('mod1'), 0, 'empty module has max loc 0'); $model->declare_function('mod1', 'mod1::f1'); $model->add_loc('mod1::f1', 10); is($amloc->calculate('mod1'), 10, 'one module, with 10 loc, makes avg loc = 10'); $model->declare_function('mod1', 'mod1::f2'); $model->add_loc('mod1::f2', 6); is($amloc->calculate('mod1'), 8, 'adding module with 5 loc makes the avg continue 10'); } __PACKAGE__->runtests; Analizo-1.25.5/t/Analizo/Metric/AverageNumberOfParameters.t0000644000175000017500000000204414676555272023060 0ustar joeniojoeniopackage t::Analizo::Metric::AverageNumberOfParameters; use strict; use warnings; use parent qw(Test::Analizo::Class); use Test::More; use File::Basename; use Analizo::Model; use Analizo::Metric::AverageNumberOfParameters; eval('$Analizo::Metric::QUIET = 1;'); # the eval is to avoid Test::* complaining about possible typo use vars qw($model $anpm); sub setup : Test(setup) { $model = Analizo::Model->new; $anpm = Analizo::Metric::AverageNumberOfParameters->new(model => $model); } sub use_package : Tests { use_ok('Analizo::Metric::AverageNumberOfParameters'); } sub has_model : Tests { is($anpm->model, $model); } sub description : Tests { is($anpm->description, "Average Number of Parameters per Method"); } sub calculate : Tests { $model->declare_module('module'); is($anpm->calculate('module'), 0, 'no parameters declared'); $model->declare_function('module', 'module::function'); $model->add_parameters('module::function', 1); is($anpm->calculate('module'), 1, 'one function with one parameter'); } __PACKAGE__->runtests; Analizo-1.25.5/t/Analizo/Metric/AfferentConnections/0000775000175000017500000000000014676555272021576 5ustar joeniojoenioAnalizo-1.25.5/t/Analizo/Metric/AfferentConnections/AfferentConnectionsComplete.t0000644000175000017500000000363014676555272027411 0ustar joeniojoeniopackage t::Analizo::Metric::AfferentConnections::AfferentConnectionsComplete; use strict; use warnings; use parent qw(Test::Analizo::Class); use Test::More; use File::Basename; use Analizo::Model; use Analizo::Metric::AfferentConnections; eval('$Analizo::Metric::QUIET = 1;'); # the eval is to avoid Test::* complaining about possible typo use vars qw($model $acc); sub setup : Test(setup) { $model = Analizo::Model->new; $acc = Analizo::Metric::AfferentConnections->new(model => $model); $model->declare_module('Friend', 'Friend.c'); $model->declare_module('Child', 'Child.c'); $model->declare_module('Mother', 'Mother.c'); $model->declare_module('MotherSister', 'MotherSister.c'); $model->declare_module('GrandMother', 'GrandMother.c'); $model->declare_function('Friend', 'friendTalk'); $model->declare_function('Child', 'childListen'); $model->declare_function('GrandMother', 'grandMotherListen'); $model->add_call('friendTalk', 'childListen'); $model->add_call('friendTalk', 'grandMotherListen'); $model->add_inheritance('Child', 'Mother'); $model->add_inheritance('Mother', 'GrandMother'); $model->add_inheritance('MotherSister', 'GrandMother'); } sub use_package : Tests { use_ok('Analizo::Metric::AfferentConnections'); } sub has_model : Tests { is($acc->model, $model); } sub description : Tests { is($acc->description, 'Afferent Connections per Class (used to calculate COF - Coupling Factor)'); } sub calculate_inheritance_and_references : Tests { is($acc->calculate('GrandMother'), 4, 'deeper inheritance and reference counts as acc'); is($acc->calculate('Child'), 1, 'calls counts as acc to child'); is($acc->calculate('Mother'), 1, 'inheritance counts as acc to mother'); is($acc->calculate('MotherSister'), 0, 'have no inheritance neither calls to mother sister'); is($acc->calculate('Friend'), 0, 'have no inheritance neither calls to friend'); } __PACKAGE__->runtests; Analizo-1.25.5/t/Analizo/Metric/AfferentConnections/AfferentConnectionsByReference.t0000644000175000017500000000463514676555272030040 0ustar joeniojoeniopackage t::Analizo::Metric::AfferentConnections::AfferentConnectionsByReference; use strict; use warnings; use parent qw(Test::Analizo::Class); use Test::More; use File::Basename; use Analizo::Model; use Analizo::Metric::AfferentConnections; eval('$Analizo::Metric::QUIET = 1;'); # the eval is to avoid Test::* complaining about possible typo use vars qw($model $acc); sub setup : Test(setup) { $model = Analizo::Model->new; $acc = Analizo::Metric::AfferentConnections->new(model => $model); $model->declare_module('A', 'A.c'); $model->declare_function('A', 'fA'); $model->declare_function('A', 'fA2'); $model->declare_module('B', 'B.c'); $model->declare_function('B', 'fB'); $model->declare_variable('B', 'vB'); $model->declare_module('C', 'C.c'); $model->declare_function('C', 'fC'); $model->declare_variable('C', 'vC'); } sub use_package : Tests { use_ok('Analizo::Metric::AfferentConnections'); } sub has_model : Tests { is($acc->model, $model); } sub description : Tests { is($acc->description, 'Afferent Connections per Class (used to calculate COF - Coupling Factor)'); } sub calculate_calling_function_of_another_module : Tests { $model->add_call('fA', 'fB'); is($acc->calculate('A'), 0, 'no calls to a module'); is($acc->calculate('B'), 1, 'calling function of another module'); } sub calculate_adding_variable_of_another_module : Tests { $model->add_call('fA', 'fB'); $model->add_variable_use('fA', 'vB'); is($acc->calculate('A'), 0, 'no calls to a module'); is($acc->calculate('B'), 1, 'adding variable of another module'); } sub calculate_calling_variable_of_another_module : Tests { $model->add_call('fA', 'fC'); is($acc->calculate('A'), 0, 'no calls to a module'); is($acc->calculate('C'), 1, 'calling variable of another module'); } sub calculate_calling_itself_does_not_count : Tests { $model->add_call('fA', 'fA2'); is($acc->calculate('A'), 0, 'calling itself does not count as acc'); } sub calculate_calling_module_twice : Tests { $model->add_call('fA', 'fB'); $model->add_variable_use('fA', 'vB'); $model->add_call('fA', 'fC'); $model->add_call('fA', 'fA2'); $model->add_variable_use('fB', 'vC'); is($acc->calculate('C'), 2, 'calling module twice'); } sub calculate_empty_acc : Tests { is($acc->calculate('A'), 0, 'no acc module A'); is($acc->calculate('B'), 0, 'no acc module B'); is($acc->calculate('C'), 0, 'no acc module C'); } __PACKAGE__->runtests; Analizo-1.25.5/t/Analizo/Metric/AfferentConnections/AfferentConnectionsByInheritance.t0000644000175000017500000000471114676555272030366 0ustar joeniojoeniopackage t::Analizo::Metric::AfferentConnections::AfferentConnectionsByInheritance; use strict; use warnings; use parent qw(Test::Analizo::Class); use Test::More; use File::Basename; use Analizo::Model; use Analizo::Metric::AfferentConnections; eval('$Analizo::Metric::QUIET = 1;'); # the eval is to avoid Test::* complaining about possible typo use vars qw($model $acc); sub setup : Test(setup) { $model = Analizo::Model->new; $acc = Analizo::Metric::AfferentConnections->new(model => $model); $model->declare_module('Mother', 'Mother.c'); $model->declare_module('Child1', 'Child1.c'); $model->declare_module('Child2', 'Child2.c'); $model->declare_module('Grandchild1', 'Grandchild1.c'); $model->declare_module('Grandchild2', 'Grandchild2.c'); } sub use_package : Tests { use_ok('Analizo::Metric::AfferentConnections'); } sub has_model : Tests { is($acc->model, $model); } sub description : Tests { is($acc->description, 'Afferent Connections per Class (used to calculate COF - Coupling Factor)'); } sub calculate_first_degree_inheritance : Tests { $model->add_inheritance('Child1', 'Mother'); is($acc->calculate('Mother'), 1, 'inheritance counts as acc to superclass'); is($acc->calculate('Child1'), 0, 'inheritance does not count as acc to child'); } sub calculate_multiple_childs : Tests { $model->add_inheritance('Child1', 'Mother'); $model->add_inheritance('Child2', 'Mother'); is($acc->calculate('Mother'), 2, 'multiple inheritance counts as acc'); is($acc->calculate('Child2'), 0, 'inheritance does not count as acc to another child'); } sub calculate_deeper_tree : Tests { $model->add_inheritance('Child1', 'Mother'); $model->add_inheritance('Child2', 'Mother'); $model->add_inheritance('Grandchild1', 'Child1'); is($acc->calculate('Grandchild1'), 0, 'grandchilds acc is not affected'); is($acc->calculate('Child1'), 1, 'grandchild extending a child counts'); is($acc->calculate('Mother'), 3, 'the deeper the tree, the biggest acc'); } sub calculate_deeper_tree_new_grandchild : Tests { $model->add_inheritance('Child1', 'Mother'); $model->add_inheritance('Child2', 'Mother'); $model->add_inheritance('Grandchild1', 'Child1'); $model->add_inheritance('Grandchild2', 'Child2'); is($acc->calculate('Grandchild2'), 0, 'grandchilds acc is not affected'); is($acc->calculate('Child2'), 1, 'grandchild extending a child counts'); is($acc->calculate('Mother'), 4, 'the deeper the tree, the biggest acc'); } __PACKAGE__->runtests; Analizo-1.25.5/t/Analizo/Extractor/0000775000175000017500000000000014676555272016371 5ustar joeniojoenioAnalizo-1.25.5/t/Analizo/Extractor/Doxyparse.t0000644000175000017500000003022514676555272020534 0ustar joeniojoeniopackage t::Analizo::Extractor::Doxyparse; use strict; use warnings; use parent qw(Test::Analizo::Class); use Test::More; use Test::Exception; use File::Basename; use Analizo::Extractor; eval('$Analizo::Extractor::QUIET = 1;'); # the eval is to avoid Test::* complaining about possible typo sub constructor : Tests { use_ok('Analizo::Extractor::Doxyparse'); my $extractor = Analizo::Extractor->load('Doxyparse'); isa_ok($extractor, 'Analizo::Extractor::Doxyparse'); isa_ok($extractor, 'Analizo::Extractor'); } sub has_a_model : Tests { isa_ok((Analizo::Extractor->load('Doxyparse'))->model, 'Analizo::Model'); } sub current_module : Tests { my $extractor = Analizo::Extractor->load('Doxyparse'); $extractor->current_module('module1.c'); is($extractor->current_module, 'module1.c', 'must be able to set the current module'); $extractor->current_module('module2.c'); is($extractor->current_module, 'module2.c', 'must be able to change the current module'); } sub inheritance : Tests { my $extractor = Analizo::Extractor->load('Doxyparse'); $extractor->feed("--- src/child.cpp: Child: inherits: Parent "); my @result = $extractor->model->inheritance('Child'); is($result[0], 'Parent', 'extractor detects inheritance'); } sub detect_function_declaration : Tests { my $extractor = Analizo::Extractor->load('Doxyparse'); $extractor->feed("--- src/module1.c: module1.c: defines: - myfunction(): type: function line: 5 "); ok(grep { $_ eq 'module1::myfunction()' } @{$extractor->model->{modules}->{'module1'}->{functions}}); is($extractor->current_member, 'module1::myfunction()', 'must set the current function'); $extractor->feed("--- src/module1.c: module1.c: defines: - myfunction(): type: function line: 5 - parametered_function(String): type: function line: 5 "); ok(grep { $_ eq 'module1::parametered_function(String)' } @{$extractor->model->{modules}->{'module1'}->{functions}}); is($extractor->current_member, 'module1::parametered_function(String)', 'must set the current function again'); $extractor->feed("--- src/module1.c: module1.c: defines: - myfunction(): type: function line: 5 - parametered_function(String): type: function line: 5 - weird_function(hello_world *): type: function line: 5 "); ok(grep { $_ eq 'module1::weird_function(hello_world *)' } @{$extractor->model->{modules}->{'module1'}->{functions}}); is($extractor->current_member, 'module1::weird_function(hello_world *)', 'must set the current function one more time'); } sub detect_variable_declaration : Tests { my $extractor = Analizo::Extractor->load('Doxyparse'); $extractor->feed("--- src/module1.c: module1.c: defines: - myvariable: type: variable line: 10 "); ok(grep { $_ eq 'module1::myvariable' } @{$extractor->model->{modules}->{'module1'}->{variables}}); $extractor->current_module; # only read the current module is(scalar(grep { $_ eq 'module1::myvariable' } @{$extractor->model->{modules}->{'module1'}->{variables}}), 1, 'must not read variable declarations when reading the name of the current module'); ok($extractor->model->{members}->{'module1::myvariable'}); } sub detect_direct_function_calls : Tests { my $extractor = Analizo::Extractor->load('Doxyparse'); $extractor->feed("--- src/module1.c: module1.c: defines: - callerfunction(): type: function line: 5 uses: - say_hello(): type: function defined_in: module2.c - say_hello_with_arg(string): type: function defined_in: module2.c - weird_say_hello(hello_world *): type: function defined_in: module2.c "); is($extractor->model->{calls}->{'module1::callerfunction()'}->{'module2::say_hello()'}, 'direct'); is($extractor->model->{calls}->{'module1::callerfunction()'}->{'module2::say_hello_with_arg(string)'}, 'direct'); is($extractor->model->{calls}->{'module1::callerfunction()'}->{'module2::weird_say_hello(hello_world *)'}, 'direct'); } sub detect_variable_uses : Tests { my $extractor = Analizo::Extractor->load('Doxyparse'); $extractor->feed("--- src/module1.c: module1.c: defines: - callerfunction: type: function line: 5 uses: - myvariable: type: variable defined_in: module2 - hello_world_say(hello_world *): type: function line: 10 uses: - avariable: type: variable defined_in: module2 "); is($extractor->model->{calls}->{'module1::callerfunction'}->{'module2::myvariable'}, 'variable'); is($extractor->model->{calls}->{'module1::hello_world_say(hello_world *)'}->{'module2::avariable'}, 'variable'); } sub detect_function_protection : Tests { my $extractor = Analizo::Extractor->load('Doxyparse'); $extractor->feed("--- src/module1.c: module1.c: defines: - public_function: type: function line: 5 protection: public - non_public_function: type: function line: 15 "); is($extractor->model->{protection}->{'module1::public_function'}, 'public'); is($extractor->model->{protection}->{'module1::non_public_function'}, undef); } sub detect_variable_protection : Tests { my $extractor = Analizo::Extractor->load('Doxyparse'); $extractor->feed("--- src/module1.c: module1.c: defines: - private_variable: type: variable line: 1 - public_variable: type: variable line: 1 protection: public "); is($extractor->model->{protection}->{'module1::private_variable'}, undef); is($extractor->model->{protection}->{'module1::public_variable'}, 'public'); } sub detect_lines_of_code : Tests { my $extractor = Analizo::Extractor->load('Doxyparse'); $extractor->feed("--- src/module1.c: module1.c: defines: - one_function: type: function line: 5 lines_of_code: 12 - another_function: type: function line: 50 "); is($extractor->model->{lines}->{'module1::one_function'}, 12); is($extractor->model->{lines}->{'module1::another_function'}, undef); } sub detect_number_of_parameters : Tests { my $extractor = Analizo::Extractor->load('Doxyparse'); $extractor->feed("--- src/module1.c: module1.c: defines: - one_function: type: function line: 5 parameters: 1 "); is($extractor->model->{parameters}->{'module1::one_function'}, 1); } sub detect_conditional_paths : Tests { my $extractor = Analizo::Extractor->load('Doxyparse', current_module => 'module1.c'); $extractor->feed("--- src/module1.c: module1.c: defines: - one_function: type: function line: 5 conditional_paths: 3 protection: public lines_of_code: 18 "); is($extractor->model->{conditional_paths}->{'module1::one_function'}, 3); } sub detect_abstract_class : Tests { my $extractor = Analizo::Extractor->load('Doxyparse'); $extractor->feed("--- src/test.cpp: An_Abstract_Class: information: abstract class "); my @result = $extractor->model->abstract_classes; is($result[0], 'An_Abstract_Class', 'extractor detects an abstract class'); } sub reading_from_one_input_file : Tests { # set up my $extractor = Analizo::Extractor->load('Doxyparse'); # one file $extractor->process('t/samples/sample_basic/c/module1.c'); is(scalar(keys(%{$extractor->model->members})), 1, 'module1 has once member'); ok(grep { $_ eq 'module1::main()' } keys(%{$extractor->model->members}), 'main is member of module1'); is(scalar(keys(%{$extractor->model->{modules}})), 1, 'we have once module'); ok(grep { $_ eq 'module1' } keys(%{$extractor->model->{modules}})); } sub reading_from_some_input_files : Tests { # set up my $sample_dir = 't/samples/sample_basic/c'; my $extractor = Analizo::Extractor->load('Doxyparse'); # some files $extractor->process($sample_dir . '/module1.c', $sample_dir . '/module2.c'); is(scalar(keys(%{$extractor->model->members})), 3, 'module1 and module2 has 3 members'); is(scalar(keys(%{$extractor->model->{modules}})), 2, 'we have 2 modules'); is($extractor->model->{calls}->{'module1::main()'}->{'module2::say_hello()'}, 'direct'); is($extractor->model->{calls}->{'module1::main()'}->{'module2::say_bye()'}, 'direct'); } sub reading_from_directories : Tests { # set up my $extractor = Analizo::Extractor->load('Doxyparse'); # directory $extractor->process('t/samples/sample_basic/c'); is(scalar(keys(%{$extractor->model->members})), 5); is(scalar(keys(%{$extractor->model->{modules}})), 3); is($extractor->model->{calls}->{'module1::main()'}->{'module2::say_hello()'}, 'direct'); is($extractor->model->{calls}->{'module1::main()'}->{'module2::say_bye()'}, 'direct'); } sub invalid_doxyparse_input : Tests { # this test is to make sure that the extractor can handle malformed input, # e.g. receiving function/variable declarations before a current module is # declared. (it happends sometime) my $extractor = Analizo::Extractor::Doxyparse->new; $extractor->feed("--- wrong: type: function line: 10 src/module1.c: module1.c: defines: - right: type: function line: 10 "); #$extractor->feed(" function wrong in line 10"); # malformed input #$extractor->current_module('module1.c'); #$extractor->feed(" function right in line 10"); # well-formed input is(scalar($extractor->model->functions('module1')), 1); # with 1 function } sub current_file : Tests { my $extractor = Analizo::Extractor::Doxyparse->new; my $current_file_called_correctly = undef; no warnings; local *Analizo::Extractor::Doxyparse::current_file = sub { my ($self, $current_file) = @_; if (defined($current_file) && $current_file eq 'src/person.h') { $current_file_called_correctly = 1; } }; use warnings; $extractor->feed("--- src/person.h: person.h: "); ok($current_file_called_correctly); } sub current_file_strip_pwd : Tests { use Cwd; my $pwd = getcwd(); my $extractor = Analizo::Extractor::Doxyparse->new; $extractor->feed("--- $pwd/src/test.c: test.c: "); is($extractor->current_file(), 'src/test.c') } sub use_full_filename_for_C_modules : Tests { my $extractor = Analizo::Extractor::Doxyparse->new; $extractor->process('t/samples/multidir/c'); my @modules = $extractor->model->module_names(); ok(grep { /^lib\/main$/ } @modules); ok(grep { /^src\/main$/ } @modules); } sub module_name_can_contain_spaces : Tests { my $extractor = Analizo::Extractor::Doxyparse->new; $extractor->feed("--- src/template.cpp: TemplatedClass< true >: "); is($extractor->current_module, 'TemplatedClass< true >') } sub detects_multiple_inheritance_properly : Tests { # set up my $extractor = Analizo::Extractor->load('Doxyparse'); lives_ok { # directory $extractor->process('t/samples/multiple_inheritance/java/'); ok(grep({ $_ eq 'Animal' } @{ $extractor->model->{inheritance}->{'Bird'} }), 'Bird inherits Animal'); ok(grep { $_ eq 'Flying' } @{ $extractor->model->{inheritance}->{'Bird'} }, 'Bird inherits Flying'); ok(grep { $_ eq 'Animal' } @{ $extractor->model->{inheritance}->{'Horse'} }, 'Horse inherits Animal'); ok(grep { $_ eq 'Horse' } @{ $extractor->model->{inheritance}->{'Pegasus'} }, 'Pegasus inherits Horse'); ok(grep { $_ eq 'Flying' } @{ $extractor->model->{inheritance}->{'Pegasus'} }, 'Pegasus inherits Flying'); } 'multiple inheritance detected'; } __PACKAGE__->runtests; Analizo-1.25.5/t/Analizo/GlobalMetric/0000775000175000017500000000000014676555272016762 5ustar joeniojoenioAnalizo-1.25.5/t/Analizo/GlobalMetric/ChangeCost.t0000644000175000017500000000263014676555272021164 0ustar joeniojoeniopackage t::Analizo::GlobalMetric::ChangeCost; use strict; use warnings; use parent qw(Test::Analizo::Class); use Test::More; use Analizo::Model; use vars qw($model $metric); BEGIN { use_ok 'Analizo::GlobalMetric::ChangeCost'; } sub setup : Test(setup) { $model = Analizo::Model->new; $metric = Analizo::GlobalMetric::ChangeCost->new(model => $model); } sub has_model : Tests { is($metric->model, $model); } sub description : Tests { is($metric->description, "Change Cost"); } sub calculate_for_an_empty_callgraph : Tests { is($metric->calculate, undef, 'no change cost'); } sub calculate : Tests { $model->declare_module('a', 'src/a.c'); $model->declare_module('b', 'src/b.c'); $model->declare_module('c', 'src/c.c'); $model->declare_module('d', 'src/d.c'); $model->declare_module('e', 'src/e.c'); $model->declare_module('f', 'src/f.c'); $model->declare_function('a', 'a::name()'); $model->declare_function('b', 'b::name()'); $model->declare_function('c', 'c::name()'); $model->declare_function('d', 'd::name()'); $model->declare_function('e', 'e::name()'); $model->declare_function('f', 'f::name()'); $model->add_call('a::name()', 'b::name()'); $model->add_call('a::name()', 'c::name()'); $model->add_call('b::name()', 'd::name()'); $model->add_call('c::name()', 'e::name()'); $model->add_call('e::name()', 'f::name()'); is($metric->calculate, 0.42); } __PACKAGE__->runtests; Analizo-1.25.5/t/Analizo/GlobalMetric/TotalAbstractClasses.t0000644000175000017500000000203014676555272023225 0ustar joeniojoeniopackage t::Analizo::GlobalMetric::TotalAbstractClasses; use strict; use warnings; use parent qw(Test::Analizo::Class); use Test::More; use File::Basename; use Analizo::Model; use Analizo::GlobalMetric::TotalAbstractClasses; eval('$Analizo::Metric::QUIET = 1;'); # the eval is to avoid Test::* complaining about possible typo use vars qw($model $tac); sub setup : Test(setup) { $model = Analizo::Model->new; $tac = Analizo::GlobalMetric::TotalAbstractClasses->new(model => $model); } sub use_package : Tests { use_ok('Analizo::GlobalMetric::TotalAbstractClasses'); } sub has_model : Tests { is($tac->model, $model); } sub description : Tests { is($tac->description, "Total Abstract Classes"); } sub calculate : Tests { is($tac->calculate('mod'), 0, 'no abstract classes declared'); $model->add_abstract_class('abstract1'); is($tac->calculate('mod'), 1, 'one abstract classes declared'); $model->add_abstract_class('abstract2'); is($tac->calculate('mod'), 2, 'two abstract classes declared'); } __PACKAGE__->runtests; Analizo-1.25.5/t/Analizo/GlobalMetric/MethodsPerAbstractClass.t0000644000175000017500000000216714676555272023677 0ustar joeniojoeniopackage t::Analizo::GlobalMetric::MethodsPerAbstractClass; use strict; use warnings; use parent qw(Test::Analizo::Class); use Test::More; use File::Basename; use Analizo::Model; use Analizo::GlobalMetric::MethodsPerAbstractClass; use vars qw($model $mac); sub setup : Test(setup) { $model = Analizo::Model->new; $mac = Analizo::GlobalMetric::MethodsPerAbstractClass->new(model => $model); } sub use_package : Tests { use_ok('Analizo::GlobalMetric::MethodsPerAbstractClass'); } sub has_model : Tests { is($mac->model, $model); } sub description : Tests { is($mac->description, "Methods per Abstract Class"); } sub calculate : Tests { is($mac->calculate, 0, 'no abstract classes'); $model->declare_module('A'); $model->add_abstract_class('A'); is($mac->calculate, 0, 'no methods on abstract classes'); $model->declare_function('A', 'functionA'); is($mac->calculate, 1, 'one methods on one abstract classes'); $model->declare_module('B'); $model->add_abstract_class('B'); $model->declare_function('B', 'functionB'); is($mac->calculate, 1, 'one methods on one abstract classes'); } __PACKAGE__->runtests; Analizo-1.25.5/t/author-pod-spell.t0000644000175000017500000000165014676555272016405 0ustar joeniojoenio BEGIN { unless ($ENV{AUTHOR_TESTING}) { print qq{1..0 # SKIP these tests are for testing by the author\n}; exit } } use strict; use warnings; use Test::More; use Test::Spelling; use Pod::Wordlist; add_stopwords(); all_pod_files_spelling_ok( qw( bin lib ) ); __DATA__ ACC ACCM al AMLOC analized analizo Analizo Andreas ANPM Araujo bd cardinality Carliss CBO Chidamber codigo Costa CPUs csv cxx cyclomatic Cyclomatic da DIT doxyparse Doxyparse dsm DSN ecfb efd egypt fbad globalonly GPL Graphviz Gratio Guerreiro Gustafsson Hedley Hennell hh hpp Hyatt Joao Joenio Kemerer Kessler Khoshgoftaar kurtosis LCOM LOC MacCormack McCabe Meirelles metricas Moreira Munson myproject neato NOA NOC NOM NPA NPM Paulo pgdb Pimenta Piveta PNG PostScript progressbar relicensed relicensing Rusnak Shyam skewness Soares src Taghi Terceiro undirected Monitoramento código de fonte livre métricas projetos Marques SC cc cf java db Analizo-1.25.5/t/samples/0000775000175000017500000000000014676555272014465 5ustar joeniojoenioAnalizo-1.25.5/t/samples/foo.tar.gz0000644000175000017500000002344114676555272016401 0ustar joeniojoenio] xUnFdbâ~Z˭I;vUaqGQQQAAe :.@dWGP@n[՝I4t`˹sUQ^sL$vowQG3 MQ$g#)k#1L!Ma@~oJ*Uϥ4I,W9ei,&"Y΅4i,HK|@3Or4%TP23$/AnDzxIEu+* 0xUR0˲g?X}ies7J%oVSnes5 n[k}'ݐ7;twgθfU]-|۷8qo~䱷{n}uv(9cX?̞ԭ͋Uk>x/~{#P:"Y %Y SB&9E%iEgDJ($$\3(XӔ.YߺM]U]4Ki9G.l@v_?[snok® W1_.f[w#yɖE/VRǑuV˚>{!}ٿ']V|S+ >Gy){ 7I]; O>yw^9U_~'<Gi[))E0Bђ,<#sGPզ+?4յJHN$Yd !]ٕOi}_Y]ں,.,[Ԃ ibO SA䯪,/,eU|IB6bcOS4?Tgyn㋲v}g\2c57?}ky{[{DO𨶳&.rw {Tv]f(MwwZ4YѨJ(cyC۶Ê>Ż}Y=OMIcglv嚭 ~th3R~Uc;YoIǖGy_o?e٠y{׏f _/ڽ(o9ݡ;_;S}aN{gJ#Ӌ4c )= x$Q%IB(i$R8ʟX?4UM#G(lz7ۆJu79ҡT;,gҡŭ.!ݼ[)1-_x$sS$QHVxRdJ2QjzY? *a Lߓco>.>9vWOgЖVN7 %)6+O %?E*q haxdFus$#*^U|z[wTw,8X̻•ń%?N/y5Wvm6ߏ'=`b(鴮D9P2xܔY 2pA%-xc~/YSBom o%"M,j%?_JJ&Hs$#D2,*"xHJdy}4MiO R?o^5!CK9z+%L iUU="e**3*" }4??%yxmκ?9۽Z}\3UOfO`ǛOUrѡI[:߸|jgiC?/|F 1P+﮻Oϗ㫕>vBan_-%[^nCoзog '^]츛-عrM.ܷ<;Ȋ1?{GJIL8g,O%?H3"/" ^yApG`i4"G?oX?SB?ɚ_YzaUE8[QTM7doRZi[im6/RC ϧ;w?ϔP2"#*PJ4yx,xxRL*- Ynܵ <ȇk >mQ٠pww¡ܯ*=`b(E=@s/i~c;5LL˜H1D'eYYIVݼ2T ?M1u7%Yckm+uՖVJGSH %?K<aE^Ui$*T#B ,+"- VHW~cԿTyth+Gq}(ػ>̻3wwپĞR|̒W6vbVgު ,a}OQ˟-_?۪Vwɔ-ݶWG\}Ք]g6s12>{.Uܫ}?vAXTO61dŵw?pqG>A n籸v/*2y);.;lk 풍ZXjǏge2hɨ9)!ji_{P,)){ˠEcK i>,eN Wv{&1ʇD ȯ W BTUyu iX` \!ˑ"{H#^941٫Wٙ#$Dx R ѯ@UzM}ZT_.hc_ D XKfmEu- Pb"4؋}p,r9px,GL{fM&k=7 o_TKL ɿ:buZ &VUԘ9?XK{iS XMzu PЫ+DjCz<CR Ѡ> T軌VD| mxVbwմh*C@u+ޕxU uMhz:֯ND W(p4bU v #.E8 'P]GN8!6AeAfgO{ʚF]Ⱥ1^/oMsBoki69z#54[,|H Hh!YSC>Tf[a[+ FD鞟?TԈXwsZ_J (_J3]0+t] VwU r 0~@~L0aNazq.4~`cq;R ϮA l&5EF;AA !!NQSCUW,/ !AۍpbñULTgBĽྍJzW {~WTFs8 ;47Kk JUt 8OТ7[&[ga 9 ҂WU׏aȢv i8"Lj*ҁ $W! G86b|ȏRf1%lIG".ѯ'H@5nd#B8f&c+Y$Տc~)ʮzQτp f$ g5ӈ $Y9d.Īrɵ'h{c, ۴`b=24V`.8CBtT*;l -j`NDdSeGGQvF:*:2?%ʲytU"#Fբy0=F8 ~FvrkW@Z-G/. e-G`=`r.;h:&T qQm޺ˎ|;;g8bYdg=<,gdt8H|P%XY¿23ژCFC(jQKY1cXעtŔwte0 xA1>cFK/>8Pnh+=0Xb9oa0g,z*щSnƈʥaxFsYo1\={f7 B LgD~X^G_O{0#Ua(cJ ^t͕Db%͘FEU=x8(iFPGV<"H F6:~#'ѴA$x[KkFR!MhWHfL ZbqAFj 8Qd$7-& DT|0(,51J¹]=sqn* v5 ooc? YI O&GxcaEAaG-԰& %6q:Ób7嘞D_"<({u sU@@$ G$ 7N7JVdeCG$9YIC I !p[ĭ2Vd) sDSɜ%]f.u*`T)`>Qo W >&J2>zCY4  2"$d]QQ;~MFS xUB&J׍! hYZeϳ7v5CR3P^Ft0h|;"]qkJ?,(/"@y  | čn yc38G>/V1&)iEBks3+S%G68n;KA &  xbwwxD)"夷3) ۻ5qD,<*UhnDR#< )t09Oխ8Dqf{ NF3 KcjRdxvٳu%{v,UVG4h_āE~IJ:upʁ`DZ!;S '"$&xs }kVId<1(߆bEXo<^M.4ۄA%زKe{ЬW#1qNᢸ^e SOJ'KYu +H.cWVuV ӏQpq9e"fW9 ^9cg& <Ŕ^ˡ=<idfCj%GZ,9;sR " 8+.i QBb ȁ؆+ާv[ xƠ9AvV2J#`]G2lެ}H~M<Jޙc|:K䌷33noꁼ=j+'%oiBE/vyBBɦ0r3HǨj<;+ xJN&aMF#-}dфdޥIolQ)Kz,>>9vcȂ yL^Zh"%d;}< 'KPzmC—_B^Ll´qh r`?)9@ǃŭkIX/HqFL-NT_ [ Ź^_ }h&SXzu<}iYϴ %HroªܪNK6 k$Ћ^ՂXd(vbaZL`JhD!KgQ U@}?/p'.a`S?}JLԥ j hpL} yUo+ʰsV V-؊QUOhM",$QN\h\P ]ƷmRv&⠍+uX;Ygq2/<}f(ьE;h)৔ʿbⲼɛGDHÇO~k7eeww|9#݋WnH1 S[~Dzذ$G6qxq%%W.nA˨ j E+eyD $}(XXk_CK9ˈSAg wUA :|( E/M#zB%70N"-BK'E .ͧQSɖ Lͪ0X.DЀ Ffn!p|(WN9ȩf!rH"A2I *zBAbf&tQ Kx~&O@-,ď8E@OT(z{c#%# UWXBOz$Gf4f)..&z=q#^\UͬR:U(<2Aktqj}(Dځu$1Iz&1hC x'j(7Je/}Ƨ ğ8^PcdZK~'N>7$OrO&4L`:Za* 9 aQ~LJ_AAXsȍT&;_qכ}ԻzFT4qᯔ,²Z `Q6"֍X.H]VOT{'Mt$WU 4ȹ㥎_=AF"^iٜl;a 6H`Q.gWE}gz >/2뼷Nx'ǎ_շl@^[: ej‹́+(tJm$9J*^F^er݁\rVf $ٲ}9 $i70H ŎC?B߯4B4uxE<: <`]D(q{y$:"AP_TZNc8XDiR c_RD]&h,9זvkju2ͧŅ^-܏2X:_@:h0$x'@YQ#8% gZo+U|O#u7:lpovkV`-OIːG2UfL00W PΞ$a︮\q~G\f/'*}mZ'FL8% xJp?uڶmۭegO7tZuzz=n;C#=h=kf-]A#2&]QLfQ0THs(ga>@J,0abJrZ/u/A7m`E{#yŚ . lZm?/&c;p@t5Vif<ܠjLr՘CwU5f9kp m7[u_-=lşQ-VURc~rR &"h(c`ӷ)8T$Lf'ox`RJ;sO5҇( yI :Eu9*(;AInzٮ$65[L8e+\7{"@2(+)fxI>J:S#RAπ#h;&Ӊ5M=?KxJҥ}&H2dvo5 ^!{UIR]mSN U+aXH# C筨iFUin8O!꠹4,rP T?aIVN9 5U;$T6~펹c;I?徑25H_'lus7^joϘwu/{X,R;2Q/:Ҕ9o'$O:f=sV T߷ȯ?wZ럳:@f?J.OkۤmmzC Nk{ݽnﷺaNط;Fc*G]׻P nlȯku6_5A;ݶ^^빾3PǓY^ȕA38g0u&xz]VVZlT6U9"rڈlcjl8qT)UQ\T0;Wc;ub>a[kI^=%uo%¤{VQҵnΰ۞z}HGfOa\+UMQl+2{OW6Kn[ u}NQq;tu `{ ]aٳkd_HzP鎤;bfwcmAO΀ qL?-+[UQ int main(void) { printf("main(void) has no args\n"); return 0; } Analizo-1.25.5/t/samples/mixed/0000775000175000017500000000000014676555272015573 5ustar joeniojoenioAnalizo-1.25.5/t/samples/mixed/UI.java0000644000175000017500000000032714676555272016753 0ustar joeniojoeniopublic class UI { private Backend backend = new Backend(); public static void main(String[] args) { System.out.println("test"); } public void callBackend() { this.backend.processRequest(0); } } Analizo-1.25.5/t/samples/mixed/Backend.java0000644000175000017500000000012114676555272017755 0ustar joeniojoeniopublic class Backend { public void processRequest(int data) { // ... } } Analizo-1.25.5/t/samples/mixed/native_backend.c0000644000175000017500000000010114676555272020662 0ustar joeniojoenio#include void process_request() { // ... whatever } Analizo-1.25.5/t/samples/mixed/CSharp_Backend.cs0000644000175000017500000000014014676555272020702 0ustar joeniojoeniousing System; class CSharp_Backend { public void ProcessRequest() { // Anything... } } Analizo-1.25.5/t/samples/evolution.tar.gz0000644000175000017500000003575214676555272017652 0ustar joeniojoenio 8UkJmL[BkS1{̼e̥c,)C,d* H*72H;Nvt󿮟׳k?_}ٛDsWۄEߢH($nWxyx>Z gr)6=7'zhac*7YyۀRY+`Z%)-y=m3& p-)8Ck ve!U>MṲou )Tr'ܤ1ӝ%&)GkG"hi8*ĢH(p hRM_ [AĠWrȏT3*LKؗY4ODaϏ- h$X" $#C$P&ⷌ ewYGc? z0 ΄LHF([ ;QE-zVg-ZmMG̍|;sJ8t^ec^œ,2Z k4Uӂ~x+Kz|b*QVSdd>IYoiȏ\蘨Jm١,InKŠpYKZVec*. ~6xM<{)Jُ-1^ T+9H<@`HdOEQxLƁ$"Ia H<$!(2W? B"?zM#UM%ff2[q2]TG;R']AS@FV.S=oTv`AC+1f947=S+HkqirXX8Ci]~ŜM$yj9ov`#Y 9tW0˦yKK UO0#[Tԟ!q%?c@ϲhiAC"@"D D,C ā$[? XˡkkUK~ؚS>[UbʕCO.6~um8Nݍ4` m~LUbZ(_`,5%e2R#{Qod}F!ŸAΤy g:rBӐSc=Y1WT=d-=$T~J_6a8"4 "2:Ð,Rt"-1W? DQ+hh;o3! ?`UV/g/ p} </?g~_@ D@ ė`?C+l ϐZB;?وJat@6K-Qç"׏rle&) >wusrK ̗ȶ=S h B%xl?4AYڤ*JQDb 7,RKROsin?--: 1lֳbaG&,5F[J##ϚNXE=vpԶL wU뇭U"-'H |+7k.1imR{~t|֩aˍϋ)-a'|> W׻fn7s[f@c&9%r]F᪭ʜ1: Ei B0Mdsmj;x?R]UVfp~H,b|i!r"?H C T,C; ?Y1x"8]Yv>[cN ; A/gwV.Q Ϙ:&daә}Hd1śBnxnjױ=*>;ywm?箥d K(HZ?t?3˦BL@&RIܜ"W]?řr (M"*Ee/?XSu%}T)kN痧kCyإR̓{ ] $;I *x >Ž.aw-bɩTu #gd,-»w8F$| wL8s[,vqlR](%B JkК.|!J-P{>BJQP}Ja}PXYq2#lPgׅRi(CGzqYX[kkvtgX:kIES&r˾G\au4WĊQ߯_c|"AXwYdOs-/-ŀL9GLh_p@Ap{;?F_dpv]n[NJMb^a;tQSjr;*k/y0}W:|a ^׷w,CCcr,/tQ[ WzC֙}WyԚo^zW쨘dt>";7*6@=9*f9$A*+;xIb¿d5sR$ykJg h xw4IBc൉ I6 0}ԝ 2c 39`}ud?7; @!AWz:zAW%rΖVMu&5OȮ8ToqW`{/&q`Fl,BY7ҷf9ݽ֟蒑̛28$ZrMBb~"޷Lf],0|ii{.zV|WP՗; ]8^kሰIޫՈh:u,!SNn+1{:P1OuH"OtH)%䞜z19>19Av7dނج`zKC%jL0t)&܋~,AsXw+c{vɜ-D|ikPSAG$al %/h,0Ao4ژvNm8yZ>g`-xP܃^^r޽ mY<=œ׬q W+8- x1cOhشS DՍ]Ͱ9͵h2'^N0ZN K[w *յ0FMY1Vwbpxuv{gY r:WNϖ0})x3EãQ7%^:8TՐl\ᾘ/޾8QU̟驡sG"Xخ7Jo{s\M:@g2tʆL yɰm\fnO4L[m?<8Uu9-r *) &E!r=<}Dx䳂^A0w}h~lRa5^8˥f$Cʚu|gQ͵SsG7&ʺRW=]ƺUͩ-crOHkn?j j'jm{Jy/Wr0,.' '0X쓭9^,LO 1RUyĆcwyX[X 6jo M_:di3p A+Sual酘KwDѧVVnKحckaoX(S{&7*[+AP9DoQqlH$dCvjZ뭭-zThն^TV?DB )>_y|\vgycfvY1{xqٲ,;|icGyFU8`tÚĉlqdnHyyPg:V =Gl /7|DɜM2A2~:z#|Z[@b\?gYle q}lUԒ+u߭峸Mz=twvS"f'b_dgfv~[*-w?-2(7 x!gaLAmeʏ.u>Pk*o|$Y]ט&wn8j{!C#>.q>Nit+<-wb*5%ɛh4aTvlg||t?=Y4Y{8}>6neN5񡅱Ȣ'i\eoR>n^vs~)8e(ɤ\]#%gl|9-O;h*nѮ1V?~͖v txЕ4}{FqdƇq8e^l}u5|C^<|l`ܬk;v1\V~<-1zC~mQojTJ׺L/~)wcv.bwX{˲3/릣֞ x>9εD͝4Ej{˯ܪ81i 2 \F&}Vj'{Y>']zI|o"R"񂖈'gwX/Gfb=55 k*;/iW1qj#v:V|%/ pRYzz{+KϞ./GڼoNIO]07N`󦯺`LSryнi>ǃ/RNVLЋg\q㓋dL?^e^Ãc=uh5w绎lzg_O:lz{6@_ MVV3H-4VN15762bΟ>+TdndM_|[K#Sn Z rI'I@`^3v1ʨr$wW%kFoN[h/?ryIdղ/S!K7BULI]cڇ{L߰m?-_ָ;(!.;B$Yna113gxw@鞻UUtٹc5q=Wno'EhfCwF}<Û3yuM<uV{si/ oѸ_Z >|֊FHjXS;[Jﺠk5J:8Q R+K}Dhۯi5ؿ{G"zi5ɄBHKRH S D{z^>_-TCVFmʭ=ΆQ'.Q[K⯟ }iE3^ħݓ7CBvewxץ氞gnv*fUQVԷ9^rHlY\vN%=9E, Q,u)dzsfasc|T>_!7Sy*CޗLY"~؉P& Kg31I3&]d~ _qG+}qoP"QE&yDr 76/ _zisZ dwlO]{ʺb[1-WM\r/B;S@Ʌ+uhc`6#~&.aKew۰=(!n 5Z6zjVhl0`u9G"{yKfkXw6+><~@hahZ_"K?](ET*`fe*H,`5|^M84i:$ӼNV"iuA(hXֳGoZۛT{{ZOBM@I^`PHje:YQD1(C}ʉ$5E @V)I(`0MIKTU9TA)tRZBO $C\J ׃IIS s ^Q*VHI:R3MJ y PDh0hNul O$Ntl ')r\)41قi## I mпJdFւAW.LM4OC3hADh)0TP)}j@o!D(@bW;487=H28}bRL^GLi7%% 6PIkL @TtA5(i`.PQZIIVjZm6Sf\K80%NT< 8^|r} FZUlBi~ Z&mΜh8h<n{Wr:' 0gFMғA.B/ +.b枰j&NpP>`FWy>ͬNjIGtmr)Uee[+kF[w6707t4 |j#2V>TIA!tQ*ؠd-vQwQEydџe1-rQ9#PSPb9Ca80Ci.}>}8_MIp(IˠE x^ rD`Sv ת)51a参LFzeI:PSzq}*8^2_B.?Ą0T{{ɔ W /? WV[E#j5M)eC| x*czHRТ4wK=ANQ }NBM Uxj-`U{?$7 >:9yOX)mˡ=aXg7YP/1=RsC0R=QK<Eԉ "cUL*JG3(ÌFL,%{< ^)TcnOYaR4M=jXXP R(;f*Oݹ.0%ek\=q<}tr.}ęNa䝙`,:YҡXHqFZxM-{Ct֜hM+J]iPQ+Bb1dsTy } ac{9NFˆKϏoJo8dbLya^˵OdAhMKbyOy5_l+XŇL`(ׅߕZ _Y)z32'0 ӾQ3(,`/G=`rH/) C*IqS)6ƢXwhq 2*l~S$}Rql(^P] .՜Hf_kM3 V4uYOK"l[ךd\5XD ;uqXdJ!Kh"O㿟/N GN/z_,&j2 gmUM%ԻP9#Z×gzы/l: 2>U bg|6)Z u*+uvw3YIXەEma ߨ)'*c}o~|'Oh%-0ѵ?fY 5]FoV#ZHM+t8%,˟ gv*OiP@LR?f4`ql \\Gt9"OdH}rFrRHQ8 P0i+ZǼlTi@WNTSsrgB͌=!ŎNL9Q UIQ9D٠'b*⒚ =0ę_ tID˄W$S#4M82RCPyZ)zx0w`Wɳ:JӉ(/r+ jAoSJ JߘҰl;@mfa鯀k/VT Ui `1i{d2fɢɯ+/#SiF97 De2£[\@ul&ō_D$$)jEP卸@FV,*\WjT}LL ?7k ?E}>_?֍x9R&6ސV:+TRAo׋1בQ@VՈɘŬzaWZ+}и7ܵ빍wP7/CE,DYiCqdYGu9J*^F^.]\ Pr6f m9' HR?aPʀ dﱘJ 89GQ\J)X[Aϋ1F H4w{ytDHm }h**K7*Pz'O;J/wwNww+8fύ ՝ K&s|2)c-sg5Pz]O'Nhh0PG/+A@'c9@oQ=hkc[}x9j$6;kM{Z)WZmTY J_UYL=1GOs9çPeRѼ)RdT&YxyAU uব?'Y)7ef͹XHx|6"# t3׏<>l{?s%2( MRYK" Ҙs7h"H%5TPM||l aC< >\m\/[S l;=Wqv3t@'|hXsScJŧƔ_թ1UпiULò@]WKM6_ j,-YJQηjdyBG)l$({ 0 FC^OE,"\iSaM=^:`;ϠBn4+Jl0]ʐ Psm&I*xq;ءn 8+{"( ܔ`i M)[~4٪'He%Q6S!"ałi\20}wڱR q櫙aZDžғ2 9.ԙdȂ LTxҫ2ȓޡE9e*RF2[=2<``x0Di6|Oސ @s?Ƚ Aqrk1ҡۙcʁ̉Y ~$F_CZo_~ez tY)6CV0pgw@m=sk?{Y9{\ X<YZG:T#Уh6TB>xo)?Z{DDǫNI\nϲXvz6ny]aw֏R;<$RvTZG%4v72 =Kw67m9VcȞ '1 1C_}Iɯ4v ƖZVnefhaY @~#ߏtaYc7p}!Ɩᏼ0XrI𕛅 ﺍ+n/4t۸ox4Z_>GOnsk4|÷xhq=DQdq#|7aNAoQ_{x K(08sd{,;'Z 9Bx?Am_dٍ48Umm 5 t2LE1E9ngݟ-b<,H1IbB}:{LK NNar<ݴW~0#ug:ϔQ6Sy(pe"%X@ˍ":UU޾nY,x-jj_lDMz܈ln7}3^N3 N}%=i_sc_A6JR_Zk3zZ?ϊkbj9 4C> nHxцz\M#SG@ /Om׫O~Yg$]ڷ<%nl}#ϕW[ա+jcv_nۯGM]'Rb>lpm_V%j}+E8쁺t?sQT^ Nп~{-%>_۴1M` I6j6j ]nBVXca_xǿZQxR>_t[vWަ:q("Y 5ƣ 4tWAmimP?M[в#yҭmt^)'3u#| EVvO݀.n#o 'v-"- Y/UFs:'gAoxr~y';;e|Rt1k,LQL"d %idJGIaw1臝.<|z"u_jH7QT WmlE7@/rORaW&ƌ*~ 4@ 4@ 4@ 4t,@Analizo-1.25.5/t/samples/animals/0000775000175000017500000000000014676555272016111 5ustar joeniojoenioAnalizo-1.25.5/t/samples/animals/cpp/0000775000175000017500000000000014676555272016673 5ustar joeniojoenioAnalizo-1.25.5/t/samples/animals/cpp/cat.h0000644000175000017500000000026314676555272017612 0ustar joeniojoenio#ifndef _CAT_H_ #define _CAT_H_ #include "mammal.h" class Cat : public Mammal { private: char* _name; public: Cat(char*); virtual const char* name(); }; #endif Analizo-1.25.5/t/samples/animals/cpp/dog.h0000644000175000017500000000026314676555272017614 0ustar joeniojoenio#ifndef _DOG_H_ #define _DOG_H_ #include "mammal.h" class Dog : public Mammal { private: char* _name; public: Dog(char*); virtual const char* name(); }; #endif Analizo-1.25.5/t/samples/animals/cpp/cat.cc0000644000175000017500000000016414676555272017750 0ustar joeniojoenio#include "cat.h" Cat::Cat(char* name) { this->_name = name; } const char* Cat::name() { return this->_name; } Analizo-1.25.5/t/samples/animals/cpp/dog.cc0000644000175000017500000000016414676555272017752 0ustar joeniojoenio#include "dog.h" Dog::Dog(char* name) { this->_name = name; } const char* Dog::name() { return this->_name; } Analizo-1.25.5/t/samples/animals/cpp/main.cc0000644000175000017500000000042514676555272020125 0ustar joeniojoenio#include "animal.h" #include "mammal.h" #include "cat.h" #include "dog.h" #include int main() { Animal* dog = new Dog("Odie"); Mammal* cat = new Cat("Garfield"); std::cout << dog->name() << std::endl; std::cout << cat->name() << std::endl; return 0; } Analizo-1.25.5/t/samples/animals/cpp/Makefile0000644000175000017500000000012114676555272020323 0ustar joeniojoenioCC = g++ animals: dog.o cat.o main.o $(CC) -o $@ $^ clean: rm -f *.o animals Analizo-1.25.5/t/samples/animals/cpp/animal.h0000644000175000017500000000015714676555272020306 0ustar joeniojoenio#ifndef _ANIMAL_H_ #define _ANIMAL_H_ class Animal { public: virtual const char* name() = 0; }; #endif Analizo-1.25.5/t/samples/animals/cpp/mammal.h0000644000175000017500000000017614676555272020312 0ustar joeniojoenio#ifndef _MAMMAL_H_ #define _MAMMAL_H_ #include "animal.h" class Mammal: public Animal { virtual ~Mammal() = 0; }; #endif Analizo-1.25.5/t/samples/animals/java/0000775000175000017500000000000014676555272017032 5ustar joeniojoenioAnalizo-1.25.5/t/samples/animals/java/Makefile0000644000175000017500000000007514676555272020472 0ustar joeniojoenioAnimal.class: *.java javac Main.java clean: rm -f *.class Analizo-1.25.5/t/samples/animals/java/Cat.java0000644000175000017500000000023514676555272020402 0ustar joeniojoeniopublic class Cat extends Mammal { private String _name; public Cat(String name) { _name = name; } public String name() { return _name; } } Analizo-1.25.5/t/samples/animals/java/Dog.java0000644000175000017500000000023514676555272020404 0ustar joeniojoeniopublic class Dog extends Mammal { private String _name; public Dog(String name) { _name = name; } public String name() { return _name; } } Analizo-1.25.5/t/samples/animals/java/Main.java0000644000175000017500000000032514676555272020557 0ustar joeniojoeniopublic class Main { public static void main(String[] args) { Animal dog = new Dog("Odie"); Mammal cat = new Cat("Garfield"); System.out.println(dog.name()); System.out.println(cat.name()); } } Analizo-1.25.5/t/samples/animals/java/Mammal.java0000644000175000017500000000012014676555272021070 0ustar joeniojoeniopublic abstract class Mammal extends Animal { public abstract void close(); } Analizo-1.25.5/t/samples/animals/java/Animal.java0000644000175000017500000000010214676555272021065 0ustar joeniojoeniopublic abstract class Animal { public abstract String name(); } Analizo-1.25.5/t/samples/animals/csharp/0000775000175000017500000000000014676555272017371 5ustar joeniojoenioAnalizo-1.25.5/t/samples/animals/csharp/Dog.cs0000644000175000017500000000024014676555272020423 0ustar joeniojoeniopublic class Dog : Mammal { private string _name; public Dog(string name) { _name = name; } public override string name() { return _name; } } Analizo-1.25.5/t/samples/animals/csharp/Cat.cs0000644000175000017500000000024014676555272020421 0ustar joeniojoeniopublic class Cat : Mammal { private string _name; public Cat(string name) { _name = name; } public override string name() { return _name; } } Analizo-1.25.5/t/samples/animals/csharp/Main.cs0000644000175000017500000000034214676555272020601 0ustar joeniojoeniousing System; public class main { public static void Main(string[] args) { Animal dog = new Dog("Odie"); Mammal cat = new Cat("Garfield"); Console.WriteLine(dog.name()); Console.WriteLine(cat.name()); } } Analizo-1.25.5/t/samples/animals/csharp/Makefile0000644000175000017500000000006014676555272021023 0ustar joeniojoenioAnimal.exe: *.cs mcs *.cs clean: rm -f *.exe Analizo-1.25.5/t/samples/animals/csharp/Mammal.cs0000644000175000017500000000011314676555272021115 0ustar joeniojoeniopublic abstract class Mammal : Animal { public virtual void close() {} } Analizo-1.25.5/t/samples/animals/csharp/Animal.cs0000644000175000017500000000010214676555272021110 0ustar joeniojoeniopublic abstract class Animal { public abstract string name(); } Analizo-1.25.5/t/samples/kdelibs/0000775000175000017500000000000014676555272016102 5ustar joeniojoenioAnalizo-1.25.5/t/samples/kdelibs/parser.cpp0000644000175000017500000000672314676555272020110 0ustar joeniojoenio/* **ANALIZO NOTE** This file was copied from kdelibs project for testing analizo features. The original file was modified and some code was deleted to keep only what is needed to create automated tests on analizo side fixing the bug below. - https://github.com/analizo/analizo/issues/138 kdelibs repository: - https://github.com/KDE/kdelibs.git Original file was copied from the commit 668ef94b2b from kdelibs git repository and it is located inside kdelibs repository on the path below. - khtml/css/parser.cpp Link to the original file on GitHub: - https://github.com/KDE/kdelibs/blob/668ef94b2b861f7ec4aa20941bcb6493bc4367be/khtml/css/parser.cpp */ /* A Bison parser, made by GNU Bison 2.5.1. */ /* Bison implementation for Yacc-like parsers in C Copyright (C) 1984, 1989-1990, 2000-2012 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work under terms of your choice, so long as that work isn't itself a parser generator using the skeleton or a modified version thereof as a parser skeleton. Alternatively, if you modify or redistribute the parser skeleton itself, you may (at your option) remove this special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ /* C LALR(1) parser skeleton written by Richard Stallman, by simplifying the original so-called "semantic" parser. */ #define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) /* The number of symbols on the RHS of the reduced rule. Keep to zero when no symbol should be popped. */ int yylen = 0; yytoken = 0; yyss = yyssa; yyvs = yyvsa; yystacksize = YYINITDEPTH; YYDPRINTF ((stderr, "Starting parse\n")); yystate = 0; yyerrstatus = 0; yynerrs = 0; yychar = YYEMPTY; /* Cause a token to be read. */ /* Initialize stack pointers. Waste one element of value and location stack so that they stay on the same level as the state stack. The wasted elements are never initialized. */ yyssp = yyss; yyvsp = yyvs; goto yysetstate; /*------------------------------------------------------------. | yynewstate -- Push a new state, which is found in yystate. | `------------------------------------------------------------*/ yynewstate: /* In all cases, when you get here, the value and location stacks have just been pushed. So pushing a state here evens the stacks. */ yyssp++; yysetstate: *yyssp = yystate; if (yyss + yystacksize - 1 <= yyssp) { /* Get the current used size of the three stacks, in elements. */ YYSIZE_T yysize = yyssp - yyss + 1; Analizo-1.25.5/t/samples/kdelibs/daterange.h0000644000175000017500000001425414676555272020211 0ustar joeniojoenio/* **ANALIZO NOTE** This file was copied from kdelibs project for testing analizo features. The original file was copied as-is to create automated tests on analizo side fixing the bug below. - https://github.com/analizo/analizo/issues/148 GitHub kdelibs repository: - https://github.com/KDE/kdelibs.git Original file was copied from the commit 668ef94b2b from kdelibs git repository and it is located inside kdelibs repository on the path below. - nepomuk/utils/daterange.h Link to the original file on GitHub: - https://github.com/KDE/kdelibs/blob/668ef94b2b861f7ec4aa20941bcb6493bc4367be/nepomuk/utils/daterange.h */ /* Copyright (c) 2009-2010 Sebastian Trueg 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) version 3 or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 14 of version 3 of the license. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef _DATE_RANGE_H_ #define _DATE_RANGE_H_ #include #include class QDebug; /** * \class DateRange daterange.h DateRange * * \brief A simple data structure storing a start and an end date. * * %DateRange is a very simple data structure storing a start and an end date. * The really interesting parts are the static factory methods which take the * current calendar system into account and, thus, create accurate values. * * \author Sebastian Trueg */ class DateRange { public: /** * Create a new range */ DateRange( const QDate& s = QDate(), const QDate& e = QDate() ); /** * Copy constructor */ DateRange( const DateRange& other ); /** * Destructor */ ~DateRange(); /** * Make this range a copy of \p other */ DateRange& operator=( const DateRange& other ); /** * Start date of the range. */ QDate start() const; /** * End date of the range. */ QDate end() const; /** * Checks if both start and end are valid dates * and if end is after start. */ bool isValid() const; /** * Set the start to \p date. */ void setStart( const QDate& date ); /** * Set the end to \p date. */ void setEnd( const QDate& date ); /** * \returns a DateRange with both start and end * dates set to QDate::currentDate() */ static DateRange today(); /** * The flags allow to change the result returned by several of the * static factory methods provided by DateRange such as thisWeek() * or thisMonth(). */ enum DateRangeFlag { /** * No flags. */ NoDateRangeFlags = 0x0, /** * Exclude days that are in the future. thisWeek() for example * will not include the days in the week that come after the current * day. */ ExcludeFutureDays = 0x1 }; Q_DECLARE_FLAGS( DateRangeFlags, DateRangeFlag ) /** * Takes KLocale::weekStartDay() into account. * \sa DateRangeFlag */ static DateRange thisWeek( DateRangeFlags flags = NoDateRangeFlags ); /** * Takes KLocale::weekStartDay() into account. * \param flags ExcludeFutureDays does only makes sense for a date in the current week. For * future weeks it is ignored. * \sa DateRangeFlag */ static DateRange weekOf( const QDate& date, DateRangeFlags flags = NoDateRangeFlags ); /** * \return A DateRange which includes all days of the current month. * * \sa DateRangeFlag */ static DateRange thisMonth( DateRangeFlags flags = NoDateRangeFlags ); /** * \param flags ExcludeFutureDays does only makes sense for a date in the current month. For * future months it is ignored. * \return A DateRange which includes all days of the month in which * \p date falls. * \sa DateRangeFlag */ static DateRange monthOf( const QDate& date, DateRangeFlags flags = NoDateRangeFlags ); /** * \return A DateRange which includes all days of the current year. * \sa DateRangeFlag */ static DateRange thisYear( DateRangeFlags flags = NoDateRangeFlags ); /** * \param flags ExcludeFutureDays does only makes sense for a date in the current year. For * future years it is ignored. * \return A DateRange which includes all days of the year in which * \p date falls. * \sa DateRangeFlags */ static DateRange yearOf( const QDate& date, DateRangeFlags flags = NoDateRangeFlags ); /** * \return A DateRange which spans the last \p n days. */ static DateRange lastNDays( int n ); /** * \return A DateRange which spans the last \p n weeks, * including the already passed days in the current week. */ static DateRange lastNWeeks( int n ); /** * \return A DateRange which spans the last \p n months, * including the already passed days in the current month. */ static DateRange lastNMonths( int n ); private: class Private; QSharedDataPointer d; }; /** * Comparison operator * * \related DateRange */ bool operator==( const DateRange& r1, const DateRange& r2 ); /** * Comparison operator * * \related DateRange */ bool operator!=( const DateRange& r1, const DateRange& r2 ); /** * Allows using DateRange in hashed structures such as QHash or QMap. * * \related DateRange */ uint qHash( const DateRange& range ); /** * Debug streaming operator * * \relates DateRange */ QDebug operator<<( QDebug dbg, const DateRange& range ); Q_DECLARE_OPERATORS_FOR_FLAGS( DateRange::DateRangeFlags ) #endif Analizo-1.25.5/t/samples/kdelibs/daterange.cpp0000644000175000017500000001521214676555272020537 0ustar joeniojoenio/* **ANALIZO NOTE** This file was copied from kdelibs project for testing analizo features. The original file was copied as-is to create automated tests on analizo side fixing the bug below. - https://github.com/analizo/analizo/issues/148 GitHub kdelibs repository: - https://github.com/KDE/kdelibs.git Original file was copied from the commit 668ef94b2b from kdelibs git repository and it is located inside kdelibs repository on the path below. - nepomuk/utils/daterange.cpp Link to the original file on GitHub: - https://github.com/KDE/kdelibs/blob/668ef94b2b861f7ec4aa20941bcb6493bc4367be/nepomuk/utils/daterange.cpp */ /* Copyright (c) 2009-2010 Sebastian Trueg 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) version 3 or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 14 of version 3 of the license. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "daterange.h" #include "kglobal.h" #include "klocale.h" #include "kcalendarsystem.h" #include #include class DateRange::Private : public QSharedData { public: QDate m_start; QDate m_end; }; DateRange::DateRange( const QDate& s, const QDate& e ) : d(new Private()) { d->m_start = s; d->m_end = e; } DateRange::DateRange( const DateRange& other ) { d = other.d; } DateRange::~DateRange() { } DateRange& DateRange::operator=( const DateRange& other ) { d = other.d; return *this; } QDate DateRange::start() const { return d->m_start; } QDate DateRange::end() const { return d->m_end; } bool DateRange::isValid() const { return KGlobal::locale()->calendar()->isValid(d->m_start) && KGlobal::locale()->calendar()->isValid(d->m_end) && d->m_start <= d->m_end; } void DateRange::setStart( const QDate& date ) { d->m_start = date; } void DateRange::setEnd( const QDate& date ) { d->m_end = date; } // static DateRange DateRange::today() { const QDate today = QDate::currentDate(); return DateRange( today, today ); } namespace { /** * Put \p day into the week range 1...weekDays */ int dateModulo( int day, int weekDays ) { day = day%weekDays; if ( day == 0 ) return weekDays; else return day; } } // static DateRange DateRange::thisWeek( DateRangeFlags flags ) { return weekOf( QDate::currentDate(), flags ); } // static DateRange DateRange::weekOf( const QDate& date, DateRangeFlags flags ) { const int daysInWeek = KGlobal::locale()->calendar()->daysInWeek( date ); const int weekStartDay = KGlobal::locale()->weekStartDay(); const int weekEndDay = dateModulo( weekStartDay+daysInWeek-1, daysInWeek ); const int dayOfWeek = KGlobal::locale()->calendar()->dayOfWeek( date ); DateRange range; if ( weekStartDay > dayOfWeek ) range.d->m_start = date.addDays( - (dayOfWeek + daysInWeek - weekStartDay) ); else range.d->m_start = date.addDays( - (dayOfWeek - weekStartDay) ); if ( weekEndDay < dayOfWeek ) range.d->m_end = date.addDays( weekEndDay + daysInWeek - dayOfWeek ); else range.d->m_end = date.addDays( weekEndDay - dayOfWeek); if( flags & ExcludeFutureDays ) { const QDate today = QDate::currentDate(); if( range.start() <= today && range.end() >= today ) range.setEnd( today ); } return range; } // static DateRange DateRange::thisMonth( DateRangeFlags flags ) { return monthOf( QDate::currentDate(), flags ); } // static DateRange DateRange::monthOf( const QDate& date, DateRangeFlags flags ) { DateRange range( KGlobal::locale()->calendar()->firstDayOfMonth( date ), KGlobal::locale()->calendar()->lastDayOfMonth( date ) ); if( flags & ExcludeFutureDays ) { const QDate today = QDate::currentDate(); if( range.start() <= today && range.end() >= today ) range.setEnd( today ); } return range; } // static DateRange DateRange::thisYear( DateRangeFlags flags ) { return yearOf( QDate::currentDate(), flags ); } // static DateRange DateRange::yearOf( const QDate& date, DateRangeFlags flags ) { DateRange range( KGlobal::locale()->calendar()->firstDayOfYear( date ), KGlobal::locale()->calendar()->lastDayOfYear( date ) ); if( flags & ExcludeFutureDays ) { const QDate today = QDate::currentDate(); if( date.year() == today.year() ) range.setEnd( today ); } return range; } // static DateRange DateRange::lastNDays( int n ) { DateRange range = today(); range.setStart( range.start().addDays( -n ) ); return range; } // static DateRange DateRange::lastNWeeks( int n ) { // This week is the first week DateRange range = thisWeek( false ); // go into the previous week range.setStart( range.start().addDays( -1 ) ); // from that on we go back n-1 weeks, for each of those we call daysInWeek for( int i = 1; i < n; ++i ) { QDate weekDay = range.start(); weekDay.addDays( -KGlobal::locale()->calendar()->daysInWeek( weekDay ) ); range.setStart( weekDay ); } // go back to the start of the next week, thus, reverting the -1 we did above range.setStart( range.start().addDays( 1 ) ); return range; } // static DateRange DateRange::lastNMonths( int n ) { // This month is the first month DateRange range = thisMonth( false ); // move the start n-1 months back range.setStart( KGlobal::locale()->calendar()->addMonths(range.start(), n-1 ) ); return range; } bool operator==( const DateRange& r1, const DateRange& r2 ) { return r1.start() == r2.start() && r1.end() == r2.end(); } bool operator!=( const DateRange& r1, const DateRange& r2 ) { return r1.start() != r2.start() || r1.end() != r2.end(); } uint qHash( const DateRange& range ) { return qHash( range.start() ) ^ qHash( range.end() ); } QDebug operator<<( QDebug dbg, const DateRange& range ) { dbg.nospace() << "DateRange(" << range.start() << range.end() << ")"; return dbg; } Analizo-1.25.5/t/samples/kdelibs/backportglobal.h0000644000175000017500000000442514676555272021244 0ustar joeniojoenio/* **ANALIZO NOTE** This file was copied from kdelibs project for testing analizo features. The original file was modified and some code was deleted to keep only what is needed to create automated tests on analizo side fixing the bug below. - https://github.com/analizo/analizo/issues/173 GitHub kdelibs repository: - https://github.com/KDE/kdelibs.git Original file was copied from the commit 0f4cf41b22 from kdelibs git repository and it is located inside kdelibs repository on the path below. - experimental/libkdeclarative/bindings/backportglobal.h Link to the original file on GitHub: - https://github.com/KDE/kdelibs/blob/9941ebff54bd9d4349c0384dfa0cca2ace9549c4/experimental/libkdeclarative/bindings/backportglobal.h */ /**************************************************************************** ** ** This file is part of the Qt Script Generator. ** ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). ** ** Contact: Nokia Corporation info@qt.nokia.com ** ** GNU Lesser General Public License Usage ** This file may be used under the terms of the GNU Lesser General Public ** License version 2.1 as published by the Free Software Foundation ** and appearing in the file LICENSE.LGPL included in the packaging of ** this file. Please review the following information to ensure the GNU ** Lesser General Public License version 2.1 requirements will be met: ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** Copyright (C) 2011 Nokia. All rights reserved ****************************************************************************/ #ifndef QTSCRIPTEXTENSIONS_GLOBAL_H #define QTSCRIPTEXTENSIONS_GLOBAL_H #include #define DECLARE_GET_METHOD(Class, __get__) \ BEGIN_DECLARE_METHOD(Class, __get__) { \ return qScriptValueFromValue(eng, self->__get__()); \ } END_DECLARE_METHOD #define DECLARE_SET_METHOD(Class, T, __set__) \ BEGIN_DECLARE_METHOD(Class, __set__) { \ self->__set__(qscriptvalue_cast(ctx->argument(0))); \ return eng->undefinedValue(); \ } END_DECLARE_METHOD #define DECLARE_GET_SET_METHODS(Class, T, __get__, __set__) \ DECLARE_GET_METHOD(Class, /*T,*/ __get__) \ DECLARE_SET_METHOD(Class, T, __set__) namespace QScript { enum { UserOwnership = 1 }; } // namespace QScript #endif // QTSCRIPTEXTENSIONS_GLOBAL_H Analizo-1.25.5/t/samples/multidir/0000775000175000017500000000000014676555272016316 5ustar joeniojoenioAnalizo-1.25.5/t/samples/multidir/c/0000775000175000017500000000000014676555272016540 5ustar joeniojoenioAnalizo-1.25.5/t/samples/multidir/c/Makefile0000644000175000017500000000006114676555272020173 0ustar joeniojoenio%: $(MAKE) -C lib/ $@ $(MAKE) -C src/ $@ all: Analizo-1.25.5/t/samples/multidir/c/lib/0000775000175000017500000000000014676555272017306 5ustar joeniojoenioAnalizo-1.25.5/t/samples/multidir/c/lib/lib.h0000644000175000017500000000010614676555272020220 0ustar joeniojoenio#ifndef _LIB_H_ #define _LIB_H_ void say_hello(); #endif // _LIB_H_ Analizo-1.25.5/t/samples/multidir/c/lib/main.c0000644000175000017500000000012714676555272020374 0ustar joeniojoenio#include #include "lib.h" void say_hello() { printf("Hello, world!\n"); } Analizo-1.25.5/t/samples/multidir/c/lib/Makefile0000644000175000017500000000011614676555272020742 0ustar joeniojoenioall: lib.o lib.o: main.c gcc -c -o $@ $< lib.o: lib.h clean: $(RM) lib.o Analizo-1.25.5/t/samples/multidir/c/src/0000775000175000017500000000000014676555272017327 5ustar joeniojoenioAnalizo-1.25.5/t/samples/multidir/c/src/main.c0000644000175000017500000000012114676555272020407 0ustar joeniojoenio#include "lib.h" int main(int argc, char** argv) { say_hello(); return 0; } Analizo-1.25.5/t/samples/multidir/c/src/Makefile0000644000175000017500000000021014676555272020756 0ustar joeniojoenioCFLAGS = -I../lib all: hello hello: ../lib/lib.o main.o $(CC) -o $@ $^ ../lib/lib.o: $(MAKE) -C ../lib clean: $(RM) hello main.o Analizo-1.25.5/t/samples/multidir/cpp/0000775000175000017500000000000014676555272017100 5ustar joeniojoenioAnalizo-1.25.5/t/samples/multidir/cpp/hello.cc0000644000175000017500000000020414676555272020504 0ustar joeniojoenio#include #include "hello.h" int main() { HelloWorld hello; std::cout << hello.message() << std::endl; return 0; } Analizo-1.25.5/t/samples/multidir/cpp/Makefile0000644000175000017500000000031014676555272020530 0ustar joeniojoenioCXXFLAGS=-Isrc all: hello test/hello_test hello: hello.o src/hello.o $(CXX) -o $@ $^ test/hello_test: src/hello.o test/hello_test.o $(CXX) -o $@ $^ clean: $(RM) hello test/hello_test */*.o *.o Analizo-1.25.5/t/samples/multidir/cpp/src/0000775000175000017500000000000014676555272017667 5ustar joeniojoenioAnalizo-1.25.5/t/samples/multidir/cpp/src/hello.h0000644000175000017500000000023114676555272021135 0ustar joeniojoenio#ifndef _HELLO_H_ #define _HELLO_H_ #include using namespace std; class HelloWorld { public: string message(); }; #endif // _HELLO_H_ Analizo-1.25.5/t/samples/multidir/cpp/src/hello.cc0000644000175000017500000000014414676555272021276 0ustar joeniojoenio#include "hello.h" using namespace std; string HelloWorld::message() { return "Hello, world"; } Analizo-1.25.5/t/samples/multidir/cpp/test/0000775000175000017500000000000014676555272020057 5ustar joeniojoenioAnalizo-1.25.5/t/samples/multidir/cpp/test/hello_test.cc0000644000175000017500000000030314676555272022522 0ustar joeniojoenio#include #include int main() { HelloWorld hello; if (hello.message() != "Hello, world") { std::cout << "Test failed" << std::endl; return 1; } return 0; } Analizo-1.25.5/t/samples/multidir/csharp/0000775000175000017500000000000014676555272017576 5ustar joeniojoenioAnalizo-1.25.5/t/samples/multidir/csharp/Makefile0000644000175000017500000000022414676555272021232 0ustar joeniojoenioall: hello test/hello_test hello: mcs hello.cs src/hello.cs test/hello_test: mcs src/hello.cs test/hello_test.cs clean: $(RM) *.exe src/*.exe Analizo-1.25.5/t/samples/multidir/csharp/hello.cs0000644000175000017500000000024714676555272021231 0ustar joeniojoeniousing System; public class main { static public int Main() { HelloWorld hello = new HelloWorld(); Console.WriteLine(hello.message()); return 0; } } Analizo-1.25.5/t/samples/multidir/csharp/src/0000775000175000017500000000000014676555272020365 5ustar joeniojoenioAnalizo-1.25.5/t/samples/multidir/csharp/src/hello.cs0000644000175000017500000000012714676555272022015 0ustar joeniojoeniopublic class HelloWorld { public string message() { return "Hello, world"; } } Analizo-1.25.5/t/samples/multidir/csharp/test/0000775000175000017500000000000014676555272020555 5ustar joeniojoenioAnalizo-1.25.5/t/samples/multidir/csharp/test/hello_test.cs0000644000175000017500000000036314676555272023246 0ustar joeniojoeniousing System; public class hello_test { static public int Main() { HelloWorld hello = new HelloWorld(); if (hello.message() != "Hello, world") { Console.WriteLine("Test failed"); return 1; } return 0; } } Analizo-1.25.5/t/samples/macro/0000775000175000017500000000000014676555272015566 5ustar joeniojoenioAnalizo-1.25.5/t/samples/macro/using_macro.c0000644000175000017500000000027514676555272020242 0ustar joeniojoenio// https://github.com/analizo/analizo/issues/154 #include SOME_EXTERNAL_MACRO(1); int main(int argc, char **argv) { printf("this program has just this one main() method"); } Analizo-1.25.5/t/samples/macro/using_macro.h0000644000175000017500000000011614676555272020241 0ustar joeniojoenio#include SOME_EXTERNAL_MACRO(1); int main(int argc, char **argv); Analizo-1.25.5/t/samples/sample_basic-1.0.yml0000644000175000017500000001223414676555272020126 0ustar joeniojoenio--- acc_kurtosis: 0 acc_mean: 0.666666666666667 acc_mode: 1 acc_quantile_lower: 0.5 acc_quantile_max: 1 acc_quantile_median: 1 acc_quantile_min: 0 acc_quantile_ninety_five: 1 acc_quantile_upper: 1 acc_skewness: 0 acc_standard_deviation: 0.577350269189626 acc_sum: 2 acc_variance: 0.333333333333333 accm_kurtosis: 0 accm_mean: 1 accm_mode: 1 accm_quantile_lower: 1 accm_quantile_max: 1 accm_quantile_median: 1 accm_quantile_min: 1 accm_quantile_ninety_five: 1 accm_quantile_upper: 1 accm_skewness: 0 accm_standard_deviation: 0 accm_sum: 3 accm_variance: 0 amloc_kurtosis: 0 amloc_mean: 8 amloc_mode: 3 amloc_quantile_lower: 3 amloc_quantile_max: 18 amloc_quantile_median: 3 amloc_quantile_min: 3 amloc_quantile_ninety_five: 18 amloc_quantile_upper: 10.5 amloc_skewness: 0 amloc_standard_deviation: 8.66025403784439 amloc_sum: 24 amloc_variance: 75 anpm_kurtosis: 0 anpm_mean: 0 anpm_mode: 0 anpm_quantile_lower: 0 anpm_quantile_max: 0 anpm_quantile_median: 0 anpm_quantile_min: 0 anpm_quantile_ninety_five: 0 anpm_quantile_upper: 0 anpm_skewness: 0 anpm_standard_deviation: 0 anpm_sum: 0 anpm_variance: 0 cbo_kurtosis: 0 cbo_mean: 0.666666666666667 cbo_mode: 0 cbo_quantile_lower: 0 cbo_quantile_max: 2 cbo_quantile_median: 0 cbo_quantile_min: 0 cbo_quantile_ninety_five: 2 cbo_quantile_upper: 1 cbo_skewness: 0 cbo_standard_deviation: 1.15470053837925 cbo_sum: 2 cbo_variance: 1.33333333333333 change_cost: 0.56 dit_kurtosis: 0 dit_mean: 0 dit_mode: 0 dit_quantile_lower: 0 dit_quantile_max: 0 dit_quantile_median: 0 dit_quantile_min: 0 dit_quantile_ninety_five: 0 dit_quantile_upper: 0 dit_skewness: 0 dit_standard_deviation: 0 dit_sum: 0 dit_variance: 0 lcom4_kurtosis: 0 lcom4_mean: 1.33333333333333 lcom4_mode: 1 lcom4_quantile_lower: 1 lcom4_quantile_max: 2 lcom4_quantile_median: 1 lcom4_quantile_min: 1 lcom4_quantile_ninety_five: 2 lcom4_quantile_upper: 1.5 lcom4_skewness: 0 lcom4_standard_deviation: 0.577350269189626 lcom4_sum: 4 lcom4_variance: 0.333333333333333 loc_kurtosis: 0 loc_mean: 9 loc_mode: ~ loc_quantile_lower: 4.5 loc_quantile_max: 18 loc_quantile_median: 6 loc_quantile_min: 3 loc_quantile_ninety_five: 18 loc_quantile_upper: 12 loc_skewness: 0 loc_standard_deviation: 7.93725393319377 loc_sum: 27 loc_variance: 63 mmloc_kurtosis: 0 mmloc_mean: 8 mmloc_mode: 3 mmloc_quantile_lower: 3 mmloc_quantile_max: 18 mmloc_quantile_median: 3 mmloc_quantile_min: 3 mmloc_quantile_ninety_five: 18 mmloc_quantile_upper: 10.5 mmloc_skewness: 0 mmloc_standard_deviation: 8.66025403784439 mmloc_sum: 24 mmloc_variance: 75 noa_kurtosis: 0 noa_mean: 0.333333333333333 noa_mode: 0 noa_quantile_lower: 0 noa_quantile_max: 1 noa_quantile_median: 0 noa_quantile_min: 0 noa_quantile_ninety_five: 1 noa_quantile_upper: 0.5 noa_skewness: 0 noa_standard_deviation: 0.577350269189626 noa_sum: 1 noa_variance: 0.333333333333333 noc_kurtosis: 0 noc_mean: 0 noc_mode: 0 noc_quantile_lower: 0 noc_quantile_max: 0 noc_quantile_median: 0 noc_quantile_min: 0 noc_quantile_ninety_five: 0 noc_quantile_upper: 0 noc_skewness: 0 noc_standard_deviation: 0 noc_sum: 0 noc_variance: 0 nom_kurtosis: 0 nom_mean: 1.33333333333333 nom_mode: 1 nom_quantile_lower: 1 nom_quantile_max: 2 nom_quantile_median: 1 nom_quantile_min: 1 nom_quantile_ninety_five: 2 nom_quantile_upper: 1.5 nom_skewness: 0 nom_standard_deviation: 0.577350269189626 nom_sum: 4 nom_variance: 0.333333333333333 npa_kurtosis: 0 npa_mean: 0.333333333333333 npa_mode: 0 npa_quantile_lower: 0 npa_quantile_max: 1 npa_quantile_median: 0 npa_quantile_min: 0 npa_quantile_ninety_five: 1 npa_quantile_upper: 0.5 npa_skewness: 0 npa_standard_deviation: 0.577350269189626 npa_sum: 1 npa_variance: 0.333333333333333 npm_kurtosis: 0 npm_mean: 1.33333333333333 npm_mode: 1 npm_quantile_lower: 1 npm_quantile_max: 2 npm_quantile_median: 1 npm_quantile_min: 1 npm_quantile_ninety_five: 2 npm_quantile_upper: 1.5 npm_skewness: 0 npm_standard_deviation: 0.577350269189626 npm_sum: 4 npm_variance: 0.333333333333333 rfc_kurtosis: 0 rfc_mean: 2.66666666666667 rfc_mode: ~ rfc_quantile_lower: 1.5 rfc_quantile_max: 5 rfc_quantile_median: 2 rfc_quantile_min: 1 rfc_quantile_ninety_five: 5 rfc_quantile_upper: 3.5 rfc_skewness: 0 rfc_standard_deviation: 2.08166599946613 rfc_sum: 8 rfc_variance: 4.33333333333333 sc_kurtosis: 0 sc_mean: 0.666666666666667 sc_mode: 0 sc_quantile_lower: 0 sc_quantile_max: 2 sc_quantile_median: 0 sc_quantile_min: 0 sc_quantile_ninety_five: 2 sc_quantile_upper: 1 sc_skewness: 0 sc_standard_deviation: 1.15470053837925 sc_sum: 2 sc_variance: 1.33333333333333 total_abstract_classes: 0 total_cof: 0.333333333333333 total_eloc: 40 total_loc: 27 total_methods_per_abstract_class: 0 total_modules: 3 total_modules_with_defined_attributes: 1 total_modules_with_defined_methods: 3 total_nom: 4 --- _filename: - module1.c _module: module1 acc: 0 accm: 1 amloc: 18 anpm: 0 cbo: 2 dit: 0 lcom4: 1 loc: 18 mmloc: 18 noa: 0 noc: 0 nom: 1 npa: 0 npm: 1 rfc: 5 sc: 2 --- _filename: - module2.c - module2.h _module: module2 acc: 1 accm: 1 amloc: 3 anpm: 0 cbo: 0 dit: 0 lcom4: 2 loc: 6 mmloc: 3 noa: 0 noc: 0 nom: 2 npa: 0 npm: 2 rfc: 2 sc: 0 --- _filename: - module3.c - module3.h _module: module3 acc: 1 accm: 1 amloc: 3 anpm: 0 cbo: 0 dit: 0 lcom4: 1 loc: 3 mmloc: 3 noa: 1 noc: 0 nom: 1 npa: 1 npm: 1 rfc: 1 sc: 0 Analizo-1.25.5/t/samples/cyclical_graph/0000775000175000017500000000000014676555272017431 5ustar joeniojoenioAnalizo-1.25.5/t/samples/cyclical_graph/c/0000775000175000017500000000000014676555272017653 5ustar joeniojoenioAnalizo-1.25.5/t/samples/cyclical_graph/c/b.h0000644000175000017500000000020614676555272020241 0ustar joeniojoenio#ifndef _B_H_ #define _B_H_ class B { private: char* _name; public: B(char*); virtual const char* name(); }; #endif Analizo-1.25.5/t/samples/cyclical_graph/c/f.h0000644000175000017500000000020614676555272020245 0ustar joeniojoenio#ifndef _F_H_ #define _F_H_ class F { private: char* _name; public: F(char*); virtual const char* name(); }; #endif Analizo-1.25.5/t/samples/cyclical_graph/c/c.h0000644000175000017500000000020614676555272020242 0ustar joeniojoenio#ifndef _C_H_ #define _C_H_ class C { private: char* _name; public: C(char*); virtual const char* name(); }; #endif Analizo-1.25.5/t/samples/cyclical_graph/c/d.h0000644000175000017500000000020614676555272020243 0ustar joeniojoenio#ifndef _D_H_ #define _D_H_ class D { private: char* _name; public: D(char*); virtual const char* name(); }; #endif Analizo-1.25.5/t/samples/cyclical_graph/c/e.h0000644000175000017500000000020614676555272020244 0ustar joeniojoenio#ifndef _E_H_ #define _E_H_ class E { private: char* _name; public: E(char*); virtual const char* name(); }; #endif Analizo-1.25.5/t/samples/cyclical_graph/c/d.cc0000644000175000017500000000015414676555272020403 0ustar joeniojoenio#include "d.h" D::D(char* name) { this->_name = name; } const char* D::name() { return this->_name; } Analizo-1.25.5/t/samples/cyclical_graph/c/f.cc0000644000175000017500000000032214676555272020402 0ustar joeniojoenio#include "f.h" #include "c.h" #include F::F(char* name) { this->_name = name; } const char* F::name() { C* c = new C("Letter C"); std::cout << c->name() << std::endl; return this->_name; } Analizo-1.25.5/t/samples/cyclical_graph/c/e.cc0000644000175000017500000000032214676555272020401 0ustar joeniojoenio#include "e.h" #include "f.h" #include E::E(char* name) { this->_name = name; } const char* E::name() { F* f = new F("Letter F"); std::cout << f->name() << std::endl; return this->_name; } Analizo-1.25.5/t/samples/cyclical_graph/c/b.cc0000644000175000017500000000032214676555272020376 0ustar joeniojoenio#include "b.h" #include "d.h" #include B::B(char* name) { this->_name = name; } const char* B::name() { D* d = new D("Letter D"); std::cout << d->name() << std::endl; return this->_name; } Analizo-1.25.5/t/samples/cyclical_graph/c/c.cc0000644000175000017500000000032214676555272020377 0ustar joeniojoenio#include "c.h" #include "e.h" #include C::C(char* name) { this->_name = name; } const char* C::name() { E* e = new E("Letter E"); std::cout << e->name() << std::endl; return this->_name; } Analizo-1.25.5/t/samples/cyclical_graph/c/main.cc0000644000175000017500000000032614676555272021105 0ustar joeniojoenio#include "b.h" #include "c.h" #include int main() { B* b = new B("Letter B"); C* c = new C("Letter C"); std::cout << b->name() << std::endl; std::cout << c->name() << std::endl; return 0; } Analizo-1.25.5/t/samples/cyclical_graph/csharp/0000775000175000017500000000000014676555272020711 5ustar joeniojoenioAnalizo-1.25.5/t/samples/cyclical_graph/csharp/C.cs0000644000175000017500000000043614676555272021423 0ustar joeniojoeniousing System; using e; namespace c { public class C { private string _name; public C(string name) { this._name = name; } public string name() { E eprint = new E("Letter E"); Console.WriteLine(eprint.name()); return this._name; } } } Analizo-1.25.5/t/samples/cyclical_graph/csharp/B.cs0000644000175000017500000000043614676555272021422 0ustar joeniojoeniousing System; using d; namespace b { public class B { private string _name; public B(string name) { this._name = name; } public string name() { D dprint = new D("Letter D"); Console.WriteLine(dprint.name()); return this._name; } } } Analizo-1.25.5/t/samples/cyclical_graph/csharp/D.cs0000644000175000017500000000031114676555272021414 0ustar joeniojoeniousing System; namespace d { public class D { private string _name; public D(string name) { this._name = name; } public string name() { return this._name; } } } Analizo-1.25.5/t/samples/cyclical_graph/csharp/E.cs0000644000175000017500000000043614676555272021425 0ustar joeniojoeniousing System; using f; namespace e { public class E { private string _name; public E(string name) { this._name = name; } public string name() { F fprint = new F("Letter F"); Console.WriteLine(fprint.name()); return this._name; } } } Analizo-1.25.5/t/samples/cyclical_graph/csharp/F.cs0000644000175000017500000000043614676555272021426 0ustar joeniojoeniousing System; using c; namespace f { public class F { private string _name; public F(string name) { this._name = name; } public string name() { C cprint = new C("Letter C"); Console.WriteLine(cprint.name()); return this._name; } } } Analizo-1.25.5/t/samples/cyclical_graph/csharp/Program.cs0000644000175000017500000000033714676555272022650 0ustar joeniojoeniousing c; using b; using System; public class Program { static void Main(string[] args) { B b = new B("Letter B"); C c = new C("Letter C"); Console.WriteLine(b.name()); Console.WriteLine(c.name()); } } Analizo-1.25.5/t/samples/hello_world/0000775000175000017500000000000014676555272016777 5ustar joeniojoenioAnalizo-1.25.5/t/samples/hello_world/c/0000775000175000017500000000000014676555272017221 5ustar joeniojoenioAnalizo-1.25.5/t/samples/hello_world/c/main.c0000644000175000017500000000040214676555272020303 0ustar joeniojoenio#include "hello_world.h" int main() { hello_world* hello1 = hello_world_new(); hello_world_say(hello1); hello_world* hello2 = hello_world_new(); hello_world_say(hello2); hello_world_destroy(hello1); hello_world_destroy(hello2); return 0; } Analizo-1.25.5/t/samples/hello_world/c/Makefile0000644000175000017500000000010114676555272020647 0ustar joeniojoeniohello_world: main.o hello_world.o clean: rm -f *.o hello_world Analizo-1.25.5/t/samples/hello_world/c/hello_world.h0000644000175000017500000000036214676555272021703 0ustar joeniojoenio#ifndef _HELLO_WORLD_H_ #define _HELLO_WORLD_H_ typedef struct _hello_world { int id; } hello_world; hello_world* hello_world_new(); void hello_world_say(hello_world*); void hello_world_destroy(hello_world*); #endif // _HELLO_WORLD_H_ Analizo-1.25.5/t/samples/hello_world/c/hello_world.c0000644000175000017500000000074314676555272021701 0ustar joeniojoenio#include #include #include "hello_world.h" static int hello_world_id = 0; hello_world* hello_world_new() { hello_world* obj = (hello_world*)(malloc(sizeof(hello_world))); obj->id = (hello_world_id++); return obj; } void hello_world_say(hello_world* hello_obj) { printf("Hello, world! My id is %d\n", hello_obj->id); } void hello_world_destroy(hello_world* hello_obj) { printf("Goodbye, world! My id is %d\n", hello_obj->id); free(hello_obj); } Analizo-1.25.5/t/samples/hello_world/cpp/0000775000175000017500000000000014676555272017561 5ustar joeniojoenioAnalizo-1.25.5/t/samples/hello_world/cpp/main.cc0000644000175000017500000000044714676555272021017 0ustar joeniojoenio#include "hello_world.h" int main() { HelloWorld hello1; HelloWorld hello2; hello1.say(); hello2.say(); // even if we don't need to destroy these objects explicitly, we call // destroy() to make this similar to the C code hello1.destroy(); hello2.destroy(); return 0; } Analizo-1.25.5/t/samples/hello_world/cpp/Makefile0000644000175000017500000000011314676555272021212 0ustar joeniojoenioCC = g++ hello_world: main.o hello_world.o clean: rm -f *.o hello_world Analizo-1.25.5/t/samples/hello_world/cpp/hello_world.h0000644000175000017500000000040614676555272022242 0ustar joeniojoenio#ifndef _HELLO_WORLD_H_ #define _HELLO_WORLD_H_ class HelloWorld { private: int _id; static int _id_seq; void private_method(); public: HelloWorld(); void say(); void destroy(); int public_variable; }; #endif // _HELLO_WORLD_H_ Analizo-1.25.5/t/samples/hello_world/cpp/hello_world.cc0000644000175000017500000000071014676555272022376 0ustar joeniojoenio#include #include "hello_world.h" int HelloWorld::_id_seq = 0; int HelloWorld::public_variable = 0; void HelloWorld::private_method() { std::cout << "prrr" << std::endl; } HelloWorld::HelloWorld() { this->_id = (HelloWorld::_id_seq++); } void HelloWorld::destroy() { std::cout << "Goobdye, world! My id is " << this->_id << std::endl; } void HelloWorld::say() { std::cout << "Hello, world! My id is " << this->_id << std::endl; } Analizo-1.25.5/t/samples/hello_world/java/0000775000175000017500000000000014676555272017720 5ustar joeniojoenioAnalizo-1.25.5/t/samples/hello_world/java/Makefile0000644000175000017500000000024614676555272021360 0ustar joeniojoeniohello_world: Main.class HelloWorld.class @echo '#!/bin/sh' > $@ @echo "java Main" >> $@ @chmod +x $@ %.class: %.java javac $< clean: rm -f *.class hello_world Analizo-1.25.5/t/samples/hello_world/java/Main.java0000644000175000017500000000065014676555272021446 0ustar joeniojoeniopublic class Main { public static void main(String[] args) { HelloWorld hello1 = new HelloWorld(); HelloWorld hello2 = new HelloWorld(); hello1.say(); hello2.say(); // Yes, I know Java does not need destructors, but I want the program to // work just like the C and C++ ones, and I cannot guarantee when (or if) // finalize() will be called. hello1.destroy(); hello2.destroy(); } } Analizo-1.25.5/t/samples/hello_world/java/HelloWorld.java0000644000175000017500000000065614676555272022643 0ustar joeniojoeniopublic class HelloWorld { private static int _id_seq = 0; private int _id; public static int hello = 1; public HelloWorld() { this._id = (_id_seq++); } public void say() { System.out.println("Hello, world! My is id " + _id); } public void destroy() { System.out.println("Goodbye, world! My id is " + _id); } private void private_method() { hello = 2; System.out.println(hello); } } Analizo-1.25.5/t/samples/hello_world/csharp/0000775000175000017500000000000014676555272020257 5ustar joeniojoenioAnalizo-1.25.5/t/samples/hello_world/csharp/main.cs0000644000175000017500000000054314676555272021532 0ustar joeniojoeniopublic class main { static public void Main() { HelloWorld hello1 = new HelloWorld(); HelloWorld hello2 = new HelloWorld(); hello1.say(); hello2.say(); // // even if we don't need to destroy these objects explicitly, we call // // destroy() to make this similar to the C code hello1.destroy(); hello2.destroy(); } } Analizo-1.25.5/t/samples/hello_world/csharp/Makefile0000644000175000017500000000007114676555272021713 0ustar joeniojoeniodefault: mcs main.cs HelloWorld.cs clean: rm -f *.exe Analizo-1.25.5/t/samples/hello_world/csharp/HelloWorld.cs0000644000175000017500000000070314676555272022657 0ustar joeniojoeniousing System; public class HelloWorld { private static int _id_seq = 0; private int _id; public static int hello = 1; public HelloWorld() { this._id = (HelloWorld._id_seq++); } public void say() { Console.WriteLine("Hello, world! My id is " + _id); } public void destroy() { Console.WriteLine("Goobdye, world! My id is " + _id); } private void private_method() { hello = 2; Console.WriteLine(hello); } } Analizo-1.25.5/t/samples/conditionals/0000775000175000017500000000000014676555272017153 5ustar joeniojoenioAnalizo-1.25.5/t/samples/conditionals/c/0000775000175000017500000000000014676555272017375 5ustar joeniojoenioAnalizo-1.25.5/t/samples/conditionals/c/cc4.c0000644000175000017500000000035414676555272020212 0ustar joeniojoeniovoid cc4() { if (something) { printf("ok\n"); } else { if (otherthing) { if (someotherthing) { printf("don't know\n"); } else { printf("me neither\n"); } printf("nope\n"); } } } Analizo-1.25.5/t/samples/conditionals/c/cc1.c0000644000175000017500000000004114676555272020200 0ustar joeniojoeniovoid cc1() { printf("ok\n"); } Analizo-1.25.5/t/samples/conditionals/c/cc3.c0000644000175000017500000000017114676555272020206 0ustar joeniojoeniovoid cc3() { if (something) { printf("ok\n"); } else { if (otherthing) { printf("nope\n"); } } } Analizo-1.25.5/t/samples/conditionals/c/cc2.c0000644000175000017500000000013314676555272020203 0ustar joeniojoeniovoid cc2() { if (something) { printf("ok\n"); } else { printf("nope\n"); } } Analizo-1.25.5/t/samples/conditionals/csharp/0000775000175000017500000000000014676555272020433 5ustar joeniojoenioAnalizo-1.25.5/t/samples/conditionals/csharp/cc4.cs0000644000175000017500000000051114676555272021426 0ustar joeniojoeniousing System; public void cc4() { if (something) { Console.WriteLine("ok\n"); } else { if (otherthing) { if (someotherthing) { Console.WriteLine("Something\n"); } else { Console.WriteLine("Some other thing\n"); } Console.WriteLine("nope\n"); } } } Analizo-1.25.5/t/samples/conditionals/csharp/cc2.cs0000644000175000017500000000020714676555272021426 0ustar joeniojoeniousing System; public void cc2() { if (something) { Console.WriteLine("ok\n"); } else { Console.WriteLine("nope\n"); } } Analizo-1.25.5/t/samples/conditionals/csharp/cc3.cs0000644000175000017500000000025514676555272021432 0ustar joeniojoeniousing System; public void cc3() { if (something) { Console.WriteLine("ok\n"); } else { if (otherthing) { Console.WriteLine("nope\n"); } } } Analizo-1.25.5/t/samples/conditionals/csharp/cc1.cs0000644000175000017500000000010114676555272021416 0ustar joeniojoeniousing System; public void cc1() { Console.WriteLine("ok\n"); }Analizo-1.25.5/t/samples/printer/0000775000175000017500000000000014676555272016150 5ustar joeniojoenioAnalizo-1.25.5/t/samples/printer/cpp/0000775000175000017500000000000014676555272016732 5ustar joeniojoenioAnalizo-1.25.5/t/samples/printer/cpp/Makefile0000644000175000017500000000005214676555272020365 0ustar joeniojoenioprinter: printer.cc clean: rm -f printer Analizo-1.25.5/t/samples/printer/cpp/printer.cc0000644000175000017500000000065214676555272020725 0ustar joeniojoenio#include #include using namespace std; class Printer1 { private: string message; public: Printer1(string); }; Printer1::Printer1(string msg) { this->message = msg; } class Printer2 { private: string message; public: Printer2(string); }; Printer2::Printer2(string message) { this->message = message; } int main() { Printer1 p1("one"); Printer2 p2("two"); return 0; } Analizo-1.25.5/t/samples/printer/csharp/0000775000175000017500000000000014676555272017430 5ustar joeniojoenioAnalizo-1.25.5/t/samples/printer/csharp/Program.cs0000644000175000017500000000022214676555272021360 0ustar joeniojoeniousing System; class Program { static void Main() { Printer1 print1 = new Printer1("one"); Printer2 print2 = new Printer2("two"); } } Analizo-1.25.5/t/samples/printer/csharp/Printer1.cs0000644000175000017500000000017114676555272021460 0ustar joeniojoeniousing System; class Printer1 { private string message; public Printer1(string msg) { this.message = msg; } } Analizo-1.25.5/t/samples/printer/csharp/Printer2.cs0000644000175000017500000000017114676555272021461 0ustar joeniojoeniousing System; class Printer2 { private string message; public Printer2(string msg) { this.message = msg; } } Analizo-1.25.5/t/samples/printer/java/0000775000175000017500000000000014676555272017071 5ustar joeniojoenioAnalizo-1.25.5/t/samples/printer/java/Printer2.java0000644000175000017500000000014214676555272021434 0ustar joeniojoenioclass Printer2 { private String message; Printer2(String msg) { this.message = msg; } } Analizo-1.25.5/t/samples/printer/java/Printer1.java0000644000175000017500000000014214676555272021433 0ustar joeniojoenioclass Printer1 { private String message; Printer1(String msg) { this.message = msg; } } Analizo-1.25.5/t/samples/tree-evolution.tar.gz0000644000175000017500000002470714676555272020605 0ustar joeniojoenio\ \LP2I(uMb{% pgN35oIl%Vy+"-#^+,wL)$߿~>gssys^Lh\r a-Ân@Xt6`tGZj(!)Geby5w_ m-?4&6_С. f2?:l:?Mg Z|6nר!#FC GoLVP#\!*4'4H{vC;#YQM$'s}hk5zuY@lѧiz@6bL I!!FN"ڀc mETR,pQ (!HI|WA1rc(Y \](aL BNN Y?f?63azˁԽIusHX]]߱lH`EC\>( i&0AkV#?e&Z?iFp ^PZTߐ׽ew%24HR"۷/F4c}@p_kll}M8{taw%w7?aVkќ3Fb ^cP, )"Dw"Digh`dѴ9"DR @]!~ ExZMI<6$M9s*m;Ʋu`{!L#F[5?&_h& ?]"Q>jqВ34Ok!Т&æqh 2(و@b, fx[?AcX#{7f 0@S{FMݠ[rv.w~!{UZTX7s `}/˟=k!Z? > zA3GatDHPb8s,:RA_L:g !ȏ{]7Bh6٥xa[u5A#I(agEaY=om5$pƞJé3 U,:ʕQ/ a}}@Q1luС5ŸΦMYm}.f{okKc6\D7=v 4|۹#QǪnv.pOqdi9_.J>leR8;~xW']ML_:Zu}IYhsf~sCCV]hAܷTٟ/7.R^q=oN:tirּ!-{WNX|'졑}@찾8>'7pKIq%E'\ێʴd4Z ][h2طlrKk*VqujE[o{d/p8c(m7i iդ6A.sytOdd^4{jp'tq_zmw9|_ cB|%>v*9Q$sꗐSUEEdG33m=L=mK Y3n*zyNgѶ?_s"#VݶT.UVK?',g'}_Nt7E|EKWe=/.7=d{>o~F,=Iz:PZjGnG+]RnD"`l$r 9n]EY=rvvvUF=l3ť:X<&v$(37$U3:{OMUu7զVVDEJ-3JS}֞;le΍1.&x1Rؖ:> tcprh;$:m.SwOhVq<n엱Cz{Wy)?5{lߠCVDqQέIX-Gd~>fLtۍ_Rƌ%Rl2'O V[[oM̲*2izoy.zwQB]WGmYdxmQj|mwQuT~>@,fCVs(0.peN tcy8oeAM]Y9exeqG9w)5kW/H-rϙ oCRnKV*ۡlrW^'fL&$vW_VgW?S \ &^Gq!BcNNn;ൕmf]w2wVtIFɂniK`74Cҋz5rmr;TE.ucȄԩωqƀ\lWTR|Zx*ԉIJ}Nzsvn<2"2ֆ`s iiF8jce&/)N4!fM <`@weТA]N qY%ǩ^,@[kx4yҐWչ7;w h:A@/@M{1ؖt^׃s*AR־^ԲS~5kRŵ }X&?zAէav2@-C@eTGhi>y1ؿ^4sCk -L^p:&xI! rdh]j$OWlB+Mȕ6;SW,C@=abUӟhB$] Oy'uȍ~[Qo]qWHcn7sO[q}Ar' u4az=kf2?<gN ι*Rb%8" P*!LB|T* )⃄r%'W+e ˀD1P1E6DPH!+Q ATŽJLՠ.*/xJDARDi+ΫCՠ$0!%B1h$ 7fݩT* /6F ѦT. Š4([7l%*C\ ECPc}KEϫ]/ˣZ/a~дJQ($q ㋨*Do6v`N _)V`8?ƠJ0"B0HiY5&[ ՏHK5(EĒ:Nj !%P/g J9>k`jPm*( PJ1of % 2L3 0iT.nwT/Mz{D"9D b c!RWaTVI'v@cQ{/7fOANt s{_j)OhLLZ# *5Hx|>0>Zz*)"@[ln 5WO.h O4} `4'0ؿ>?O"G@dr0/J;kA`xl6L 8uğ;PKA+8+ԐJ )-X%iYg\&㡦`G3amI~&~E1E :"yd98g;ϖmhJ r4oݸH;Y{I꺻13r _b? hL fC8UR?ahJD~rS'7•c{>A)j Z MyX\9W@BAj ld d P(>A;4;{NkM A(ܨ/ zm1Xwà-ͳ@e N12|i(9ZUx$S5Ms2认0Uqq`:W6O gXKkYѬGPA7}rȊh3 5 ݶu*i]Do2ƞD1Au;YaQ@(8NvP9+TDREԍj_:[n Ūy*dX0XGQ$֙@8D0A)EP˸Gպ`iX2?\pVu_|Uh|_7ʎXHbW NB4f&#xĨ 9f5@Հ,@HkўTk*}J'7A; 9dtvlX_':W֜RcBv~ZyZ `)Hx|k7ig'3TSS+JU fsd%2(Q.{^7 zg{PCDic5W%Zi_z* Po<7E,*[Z#Rnj8A,kʄsPG{`ꅀNMSTW_9#}4jI `P({F`+ F,Ҹ2  hr#Ju(yw[c=ʊAd=&E ^XHXm8[($zCD>Pj'~w61GǨG.}2 Q *7Qi:68ඛXfOn3%` 0?!~8{'8k5u]Wl0 #qrdp'7H7p|؈r6Xi$< U݆Vw&t/iF 9ǫ xvHJ"?$ÉiE>+RR7`&@!9,Q[!GbM}i&| HJ'Ki9,wу.ǭwnB*{N]6l=Ź= I੦DRe[/h 4IJJ#k-FOЫO8ECG!}lBzQ%t{C6hZZ XyH-;Bu^2Hhvt#`[g=Pl}|Ly8yLU^0lYӏrTx f:ZDE̠ /P׸!#,^8xYk%^i3'Syu`^f j`jǂ6@+bci:'L wP!D7Q0hK>)u0Qxgq +cVgdg4E3<~`= @qPʏ%viO4ݗY<@m ?'X?1sKXDEK0 B!O7e7>\iTJLDq 导Z"%d7'/qQj Hl_9Fˁ9ƱڦFd5٨]JƃmjIX/̌XsdFL=N4bV9 .Mg w[eI2pp:ӳƴBR ywFei RaeK%|fƁIKb/Z Ů]^]IZI 'e Lo.wϞj_1k\`W?}JL4ŃGfԞ!V*7{m/֯:W,Ղz <~Boa!B{.w\y=vh~K\Oi#v3FϪ*E\rŋO{TgcvU BTU UM="B2vX #9e%xnT_ poHl& ʏFhbǒ1EsWqdb_;wЀQi[U5F sK(92{:B G M8!0#$7ym %hPH5&;AP`{ie6P^F $ȏ +/dP[=?j*9H  DX;!f0őu^Rf<$ F/ 5IdJ2c@L U;N GT`rQpdckIܷN*CpQþ+Kd^/55I!8 &!4G#P!ĹxX/lCO9Q U( Fy H ea *W?t@x>܄|2P6?5v(?l>~B25آ]~ʁFҾjɀK1P:E0 p+H "E#$ p0Y+^.BWKs`BBc-|`CKZgKd%bV/-*f\MU%EX_)"`g r9yyy!¢,K1~G#'I83;Iw@ :Ї`ST:OOT:5pg?O~_b }QZo^5O_כ4k5աKA"5A[N~vzJ *(Ν& -T X{SKh0}`IQky%*rkӻHC_WUǷVv/^m?%v_&73_U[!B9{8rrŦ{h?y dWe{kGȑIRgԁ U u࡬?t&E)WܯnԶ^۱5ޡÃ^aoຎ;;m18Ѹ'N=<88;#/uhx8>z"ѤAP%?>¹ sY0衘B8-mhJ˩>v~P`/_)I}fyaMA D=?[[)wf_a뿍?4 |@*n Kg?@Y&j͍B^Nyǿ/[:O۱oSiJ0*#L?7H`/ؓ ^E)ڑVecnWZCQn]+w/Svl$23M>(0];ˈK[LfmF"Mu_%`MnbF} | ٛOVk1F;#eZ|Gue*/ÿJT(Ʋ?g?/~oU/.ڠeϿ;{ ;VvuR^w MeHҪ.~4~ASL+,#+|#+u// .n#$e)KYʲܡAnalizo-1.25.5/t/samples/enumeration/0000775000175000017500000000000014676555272017013 5ustar joeniojoenioAnalizo-1.25.5/t/samples/enumeration/Main.java0000644000175000017500000000040014676555272020532 0ustar joeniojoeniopublic class Main { enum MyEnumeration { A, B, C, D } public static void main(String[] args) { MyEnumeration enumeration = MyEnumeration.A; if (enumeration.equals(MyEnumeration.A)) { System.out.println("Hello, World!"); } } } Analizo-1.25.5/t/samples/enumeration/Enumeration.java0000644000175000017500000000006414676555272022142 0ustar joeniojoeniopublic enum Enumeration { ONE, TWO, THREE, FOUR } Analizo-1.25.5/t/samples/polygons/0000775000175000017500000000000014676555272016337 5ustar joeniojoenioAnalizo-1.25.5/t/samples/polygons/csharp/0000775000175000017500000000000014676555272017617 5ustar joeniojoenioAnalizo-1.25.5/t/samples/polygons/csharp/Rect.cs0000644000175000017500000000040314676555272021036 0ustar joeniojoeniousing System; class Rect : Tetragon { public Rect(int w, int h) { this.width = w; this.heigth = h; } public override int Area() { return (width * heigth); } public override int Perimeter() { return (width * 2 + heigth * 2); } } Analizo-1.25.5/t/samples/polygons/csharp/Square.cs0000644000175000017500000000033514676555272021405 0ustar joeniojoeniousing System; class Square : Tetragon { public Square(int w) { this.width = w; } public override int Area() { return (width * width); } public override int Perimeter() { return (width * 4); } } Analizo-1.25.5/t/samples/polygons/csharp/Program.cs0000644000175000017500000000065714676555272021563 0ustar joeniojoeniousing System; class Program { static void Main() { Square square = new Square(2); Rect rect = new Rect(2,3); Triangle triangle = new Triangle(4,7); Console.WriteLine("Area: {0}, Perimeter: {1}", square.Area(), square.Perimeter()); Console.WriteLine("Area: {0}, Perimeter: {1}", rect.Area(), rect.Perimeter()); Console.WriteLine("Area: {0}, Perimeter: {1}", triangle.Area(), triangle.Perimeter()); } } Analizo-1.25.5/t/samples/polygons/csharp/Polygon.cs0000644000175000017500000000021314676555272021567 0ustar joeniojoeniousing System; abstract class Polygon { protected int width, heigth; public abstract int Area(); public abstract int Perimeter(); } Analizo-1.25.5/t/samples/polygons/csharp/Tetragon.cs0000644000175000017500000000021014676555272021720 0ustar joeniojoeniousing System; abstract class Tetragon : Polygon { public abstract override int Area(); public abstract override int Perimeter(); } Analizo-1.25.5/t/samples/polygons/csharp/Triangle.cs0000644000175000017500000000040114676555272021704 0ustar joeniojoeniousing System; class Triangle : Polygon { public Triangle(int w, int h) { this.width = w; this.heigth = h; } public override int Area() { return (width * heigth / 2); } public override int Perimeter() { return (width * 3); } } Analizo-1.25.5/t/samples/polygons/cpp/0000775000175000017500000000000014676555272017121 5ustar joeniojoenioAnalizo-1.25.5/t/samples/polygons/cpp/Polygon.cpp0000644000175000017500000000222614676555272021254 0ustar joeniojoenio// abstract base class #include using namespace std; class CPolygon { protected: int width, height; virtual int perimeter(void) =0; public: void set_values (int a, int b) { width=a; height=b; } virtual int area (void) =0; }; class CTetragon: public CPolygon { protected: virtual int perimeter(void) =0; public: virtual int area (void) =0; }; class CSquare: public CTetragon { protected: int perimeter(void) { return (width*4); } public: int area (void) { return (width * width); } }; class CRetangle: public CTetragon { protected: int perimeter(void) { return (width*2 + height*2); } public: int area (void) { return (width * height); } }; class CTriangle: public CPolygon { protected: int perimeter(void) { return (width*3); } public: int area (void) { return (width * height / 2); } }; int main () { CRectangle rect; CTriangle trgl; CPolygon * ppoly1 = ▭ CPolygon * ppoly2 = &trgl; ppoly1->set_values (4,5); ppoly2->set_values (4,5); cout << ppoly1->area() << endl; cout << ppoly2->area() << endl; return 0; } Analizo-1.25.5/t/samples/polygons/java/0000775000175000017500000000000014676555272017260 5ustar joeniojoenioAnalizo-1.25.5/t/samples/polygons/java/Square.java0000644000175000017500000000014214676555272021356 0ustar joeniojoeniopublic class Square extends Tetragon { public int area () { return (width * width); } } Analizo-1.25.5/t/samples/polygons/java/Polygon.java0000644000175000017500000000037614676555272021556 0ustar joeniojoeniopublic abstract class Polygon { protected int width, height; public polygon (int width){ this.width = width; } public polygon (int width, int height){ this.width = width; this.height = height; } public abstract int area (); } Analizo-1.25.5/t/samples/polygons/java/Retangle.java0000644000175000017500000000014514676555272021662 0ustar joeniojoeniopublic class Retangle extends Tetragon { public int area () { return (width * height); } } Analizo-1.25.5/t/samples/polygons/java/Polygons.java0000644000175000017500000000030014676555272021724 0ustar joeniojoeniopublic Class Polygons{ public static void main(string args[]){ Square square = new Square(2); Retangle retangle = new Retangle(2,3); Triangle triangle = new Triangle(4,7); } } Analizo-1.25.5/t/samples/polygons/java/Tetragon.java0000644000175000017500000000012714676555272021704 0ustar joeniojoeniopublic abstract class Tetragon extends Polygon { public abstract int area (); } Analizo-1.25.5/t/samples/polygons/java/Triangle.java0000644000175000017500000000014614676555272021667 0ustar joeniojoeniopublic class Triangle extends Polygon { public int area () { return (width * height/2); } } Analizo-1.25.5/t/samples/sample_basic/0000775000175000017500000000000014676555272017107 5ustar joeniojoenioAnalizo-1.25.5/t/samples/sample_basic/c/0000775000175000017500000000000014676555272017331 5ustar joeniojoenioAnalizo-1.25.5/t/samples/sample_basic/c/Makefile0000644000175000017500000000022714676555272020770 0ustar joeniojoenioCFLAGS = -dr OBJECTS = module1.o module2.o module3.o all: program program: $(OBJECTS) gcc -o $@ $(OBJECTS) clean: rm -f *.o *.expand program tags Analizo-1.25.5/t/samples/sample_basic/c/module2.c0000644000175000017500000000022014676555272021034 0ustar joeniojoenio#include #include "module2.h" void say_hello() { printf("Hello, world!\n"); } void say_bye() { printf("Bye, cruel world!\n"); } Analizo-1.25.5/t/samples/sample_basic/c/module2.h0000644000175000017500000000014214676555272021044 0ustar joeniojoenio#ifndef _MODULE2_H_ #define _MODULE2_H_ void say_hello(); void say_bye(); #endif // _MODULE2_H_ Analizo-1.25.5/t/samples/sample_basic/c/module1.c0000644000175000017500000000047214676555272021044 0ustar joeniojoenio#include #include "module2.h" #include "module3.h" int main() { int localvar = 0; void (*f)(); say_hello(); say_bye(); printf("variable = %d\n", variable); variable = 20; printf("variable = %d\n", variable); printf("localvar = %d\n", localvar); f = callback; f(); return 0; } Analizo-1.25.5/t/samples/sample_basic/c/module3.h0000644000175000017500000000014714676555272021052 0ustar joeniojoenio#ifndef _MODULE3_H_ #define _MODULE3_H_ extern int variable; void callback(); #endif // _MODULE3_H_ Analizo-1.25.5/t/samples/sample_basic/c/config.sh0000644000175000017500000000037714676555272021137 0ustar joeniojoeniotests_dir="$(dirname $0)/tests" mkdir -p ${tests_dir} expected_cmdline="${tests_dir}/${test_name}.cmdline" expected_stdout="${tests_dir}/${test_name}.out" expected_stderr="${tests_dir}/${test_name}.err" expected_status="${tests_dir}/${test_name}.status" Analizo-1.25.5/t/samples/sample_basic/c/module3.c0000644000175000017500000000017014676555272021041 0ustar joeniojoenio#include "module3.h" #include int variable = 15; void callback() { printf("this is callback function"); } Analizo-1.25.5/t/samples/sample_basic/csharp/0000775000175000017500000000000014676555272020367 5ustar joeniojoenioAnalizo-1.25.5/t/samples/sample_basic/csharp/Module1.cs0000644000175000017500000000027614676555272022227 0ustar joeniojoeniousing System; class Module1 { public static void SayHello() { Console.WriteLine("Hello, world"); } public static void SayBye() { Console.WriteLine("Byem cruel world"); } } Analizo-1.25.5/t/samples/sample_basic/csharp/Program.cs0000644000175000017500000000054014676555272022322 0ustar joeniojoeniousing System; class Program { static void Main() { int localvar = 0; Module1.SayHello(); Module1.SayBye(); Console.WriteLine("Variable = {0}", Module2.variable); Module2.variable = 20; Console.WriteLine("Variable = {0}", Module2.variable); Console.WriteLine("Variable = {0}", localvar); Module2.Callback(); } } Analizo-1.25.5/t/samples/sample_basic/csharp/Module2.cs0000644000175000017500000000023714676555272022225 0ustar joeniojoeniousing System; class Module2 { public static int variable = 15; public static void Callback() { Console.WriteLine("this is callback function"); } } Analizo-1.25.5/t/samples/hierarchical_graph/0000775000175000017500000000000014676555272020264 5ustar joeniojoenioAnalizo-1.25.5/t/samples/hierarchical_graph/c/0000775000175000017500000000000014676555272020506 5ustar joeniojoenioAnalizo-1.25.5/t/samples/hierarchical_graph/c/b.h0000644000175000017500000000020614676555272021074 0ustar joeniojoenio#ifndef _B_H_ #define _B_H_ class B { private: char* _name; public: B(char*); virtual const char* name(); }; #endif Analizo-1.25.5/t/samples/hierarchical_graph/c/f.h0000644000175000017500000000020614676555272021100 0ustar joeniojoenio#ifndef _F_H_ #define _F_H_ class F { private: char* _name; public: F(char*); virtual const char* name(); }; #endif Analizo-1.25.5/t/samples/hierarchical_graph/c/c.h0000644000175000017500000000020614676555272021075 0ustar joeniojoenio#ifndef _C_H_ #define _C_H_ class C { private: char* _name; public: C(char*); virtual const char* name(); }; #endif Analizo-1.25.5/t/samples/hierarchical_graph/c/d.h0000644000175000017500000000020614676555272021076 0ustar joeniojoenio#ifndef _D_H_ #define _D_H_ class D { private: char* _name; public: D(char*); virtual const char* name(); }; #endif Analizo-1.25.5/t/samples/hierarchical_graph/c/e.h0000644000175000017500000000020614676555272021077 0ustar joeniojoenio#ifndef _E_H_ #define _E_H_ class E { private: char* _name; public: E(char*); virtual const char* name(); }; #endif Analizo-1.25.5/t/samples/hierarchical_graph/c/d.cc0000644000175000017500000000015414676555272021236 0ustar joeniojoenio#include "d.h" D::D(char* name) { this->_name = name; } const char* D::name() { return this->_name; } Analizo-1.25.5/t/samples/hierarchical_graph/c/f.cc0000644000175000017500000000015414676555272021240 0ustar joeniojoenio#include "f.h" F::F(char* name) { this->_name = name; } const char* F::name() { return this->_name; } Analizo-1.25.5/t/samples/hierarchical_graph/c/e.cc0000644000175000017500000000032214676555272021234 0ustar joeniojoenio#include "e.h" #include "f.h" #include E::E(char* name) { this->_name = name; } const char* E::name() { F* f = new F("Letter F"); std::cout << f->name() << std::endl; return this->_name; } Analizo-1.25.5/t/samples/hierarchical_graph/c/b.cc0000644000175000017500000000032214676555272021231 0ustar joeniojoenio#include "b.h" #include "d.h" #include B::B(char* name) { this->_name = name; } const char* B::name() { D* d = new D("Letter D"); std::cout << d->name() << std::endl; return this->_name; } Analizo-1.25.5/t/samples/hierarchical_graph/c/c.cc0000644000175000017500000000032214676555272021232 0ustar joeniojoenio#include "c.h" #include "e.h" #include C::C(char* name) { this->_name = name; } const char* C::name() { E* e = new E("Letter E"); std::cout << e->name() << std::endl; return this->_name; } Analizo-1.25.5/t/samples/hierarchical_graph/c/main.cc0000644000175000017500000000032614676555272021740 0ustar joeniojoenio#include "b.h" #include "c.h" #include int main() { B* b = new B("Letter B"); C* c = new C("Letter C"); std::cout << b->name() << std::endl; std::cout << c->name() << std::endl; return 0; } Analizo-1.25.5/t/samples/hierarchical_graph/csharp/0000775000175000017500000000000014676555272021544 5ustar joeniojoenioAnalizo-1.25.5/t/samples/hierarchical_graph/csharp/C.cs0000644000175000017500000000043614676555272022256 0ustar joeniojoeniousing System; using e; namespace c { public class C { private string _name; public C(string name) { this._name = name; } public string name() { E eprint = new E("Letter E"); Console.WriteLine(eprint.name()); return this._name; } } } Analizo-1.25.5/t/samples/hierarchical_graph/csharp/B.cs0000644000175000017500000000043614676555272022255 0ustar joeniojoeniousing System; using d; namespace b { public class B { private string _name; public B(string name) { this._name = name; } public string name() { D dprint = new D("Letter D"); Console.WriteLine(dprint.name()); return this._name; } } } Analizo-1.25.5/t/samples/hierarchical_graph/csharp/D.cs0000644000175000017500000000031114676555272022247 0ustar joeniojoeniousing System; namespace d { public class D { private string _name; public D(string name) { this._name = name; } public string name() { return this._name; } } } Analizo-1.25.5/t/samples/hierarchical_graph/csharp/E.cs0000644000175000017500000000043614676555272022260 0ustar joeniojoeniousing System; using f; namespace e { public class E { private string _name; public E(string name) { this._name = name; } public string name() { F fprint = new F("Letter F"); Console.WriteLine(fprint.name()); return this._name; } } } Analizo-1.25.5/t/samples/hierarchical_graph/csharp/F.cs0000644000175000017500000000031014676555272022250 0ustar joeniojoeniousing System; namespace f { public class F { private string _name; public F(string name) { this._name = name; } public string name() { return this._name; } } } Analizo-1.25.5/t/samples/hierarchical_graph/csharp/Program.cs0000644000175000017500000000033714676555272023503 0ustar joeniojoeniousing c; using b; using System; public class Program { static void Main(string[] args) { B b = new B("Letter B"); C c = new C("Letter C"); Console.WriteLine(b.name()); Console.WriteLine(c.name()); } } Analizo-1.25.5/t/samples/httpd-2.4.38/0000775000175000017500000000000014676555272016342 5ustar joeniojoenioAnalizo-1.25.5/t/samples/httpd-2.4.38/mod_suexec.h0000644000175000017500000000306314676555272020646 0ustar joeniojoenio/* **ANALIZO NOTE** This file was copied here from httpd-2.4.38 as is just to be used as input on analizo testsuite in order to fix the issue #155. - https://github.com/analizo/analizo/issues/155 httpd repository: - https://github.com/apache/httpd/tree/2.4.38 Original file was copied from the tag 2.4.38 from httpd git repository and it is located on the path below. - modules/generators/mod_suexec.h Link to the original file on GitHub: - https://github.com/apache/httpd/blob/2.4.38/modules/generators/mod_suexec.h */ /* Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * @file mod_suexec.h * @brief SuExec Extension Module for Apache * * @defgroup MOD_SUEXEC mod_suexec * @ingroup APACHE_MODS * @{ */ #include "unixd.h" typedef struct { ap_unix_identity_t ugid; int active; } suexec_config_t; /** @}*/ Analizo-1.25.5/t/samples/httpd-2.4.38/mod_suexec.c0000644000175000017500000001151514676555272020642 0ustar joeniojoenio/* **ANALIZO NOTE** This file was copied here from httpd-2.4.38 as is just to be used as input on analizo testsuite in order to fix the issue #155. - https://github.com/analizo/analizo/issues/155 httpd repository: - https://github.com/apache/httpd/tree/2.4.38 Original file was copied from the tag 2.4.38 from httpd git repository and it is located on the path below. - modules/generators/mod_suexec.c Link to the original file on GitHub: - https://github.com/apache/httpd/blob/2.4.38/modules/generators/mod_suexec.c */ /* Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "httpd.h" #include "http_config.h" #include "http_core.h" #include "http_log.h" #include "http_request.h" #include "apr_strings.h" #include "unixd.h" #include "mpm_common.h" #include "mod_suexec.h" module AP_MODULE_DECLARE_DATA suexec_module; /* * Create a configuration specific to this module for a server or directory * location, and fill it with the default settings. */ static void *mkconfig(apr_pool_t *p) { suexec_config_t *cfg = apr_palloc(p, sizeof(suexec_config_t)); cfg->active = 0; return cfg; } /* * Respond to a callback to create configuration record for a server or * vhost environment. */ static void *create_mconfig_for_server(apr_pool_t *p, server_rec *s) { return mkconfig(p); } /* * Respond to a callback to create a config record for a specific directory. */ static void *create_mconfig_for_directory(apr_pool_t *p, char *dir) { return mkconfig(p); } static const char *set_suexec_ugid(cmd_parms *cmd, void *mconfig, const char *uid, const char *gid) { suexec_config_t *cfg = (suexec_config_t *) mconfig; const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_CONTEXT); if (err != NULL) { return err; } if (!ap_unixd_config.suexec_enabled) { return apr_pstrcat(cmd->pool, "SuexecUserGroup configured, but " "suEXEC is disabled: ", ap_unixd_config.suexec_disabled_reason, NULL); } cfg->ugid.uid = ap_uname2id(uid); cfg->ugid.gid = ap_gname2id(gid); cfg->ugid.userdir = 0; cfg->active = 1; return NULL; } static ap_unix_identity_t *get_suexec_id_doer(const request_rec *r) { suexec_config_t *cfg = (suexec_config_t *) ap_get_module_config(r->per_dir_config, &suexec_module); return cfg->active ? &cfg->ugid : NULL; } #define SUEXEC_POST_CONFIG_USERDATA "suexec_post_config_userdata" static int suexec_post_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s) { void *reported; apr_pool_userdata_get(&reported, SUEXEC_POST_CONFIG_USERDATA, s->process->pool); if ((reported == NULL) && ap_unixd_config.suexec_enabled) { ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, s, APLOGNO(01232) "suEXEC mechanism enabled (wrapper: %s)", SUEXEC_BIN); apr_pool_userdata_set((void *)1, SUEXEC_POST_CONFIG_USERDATA, apr_pool_cleanup_null, s->process->pool); } return OK; } #undef SUEXEC_POST_CONFIG_USERDATA /* * Define the directives specific to this module. This structure is referenced * later by the 'module' structure. */ static const command_rec suexec_cmds[] = { /* XXX - Another important reason not to allow this in .htaccess is that * the ap_[ug]name2id() is not thread-safe */ AP_INIT_TAKE2("SuexecUserGroup", set_suexec_ugid, NULL, RSRC_CONF, "User and group for spawned processes"), { NULL } }; static void suexec_hooks(apr_pool_t *p) { ap_hook_get_suexec_identity(get_suexec_id_doer,NULL,NULL,APR_HOOK_MIDDLE); ap_hook_post_config(suexec_post_config,NULL,NULL,APR_HOOK_MIDDLE); } AP_DECLARE_MODULE(suexec) = { STANDARD20_MODULE_STUFF, create_mconfig_for_directory, /* create per-dir config */ NULL, /* merge per-dir config */ create_mconfig_for_server, /* server config */ NULL, /* merge server config */ suexec_cmds, /* command table */ suexec_hooks /* register hooks */ }; Analizo-1.25.5/t/samples/httpd-2.4.38/http_config.h0000644000175000017500000015724714676555272021035 0ustar joeniojoenio/* **ANALIZO NOTE** This file was copied here from httpd-2.4.38 as is just to be used as input on analizo testsuite in order to fix the issue #155. - https://github.com/analizo/analizo/issues/155 httpd repository: - https://github.com/apache/httpd/tree/2.4.38 Original file was copied from the tag 2.4.38 from httpd git repository and it is located on the path below. - include/http_config.h Link to the original file on GitHub: - https://github.com/apache/httpd/blob/2.4.38/include/http_config.h */ /* Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * @file http_config.h * @brief Apache Configuration * * @defgroup APACHE_CORE_CONFIG Configuration * @ingroup APACHE_CORE * @{ */ #ifndef APACHE_HTTP_CONFIG_H #define APACHE_HTTP_CONFIG_H #include "util_cfgtree.h" #include "ap_config.h" #include "apr_tables.h" #ifdef __cplusplus extern "C" { #endif /* * The central data structures around here... */ /* Command dispatch structures... */ /** * How the directives arguments should be parsed. * @remark Note that for all of these except RAW_ARGS, the config routine is * passed a freshly allocated string which can be modified or stored * or whatever... */ enum cmd_how { RAW_ARGS, /**< cmd_func parses command line itself */ TAKE1, /**< one argument only */ TAKE2, /**< two arguments only */ ITERATE, /**< one argument, occurring multiple times * (e.g., IndexIgnore) */ ITERATE2, /**< two arguments, 2nd occurs multiple times * (e.g., AddIcon) */ FLAG, /**< One of 'On' or 'Off' */ NO_ARGS, /**< No args at all, e.g. </Directory> */ TAKE12, /**< one or two arguments */ TAKE3, /**< three arguments only */ TAKE23, /**< two or three arguments */ TAKE123, /**< one, two or three arguments */ TAKE13, /**< one or three arguments */ TAKE_ARGV /**< an argc and argv are passed */ }; /** * This structure is passed to a command which is being invoked, * to carry a large variety of miscellaneous data which is all of * use to *somebody*... */ typedef struct cmd_parms_struct cmd_parms; #if defined(AP_HAVE_DESIGNATED_INITIALIZER) || defined(DOXYGEN) /** * All the types of functions that can be used in directives * @internal */ typedef union { /** function to call for a no-args */ const char *(*no_args) (cmd_parms *parms, void *mconfig); /** function to call for a raw-args */ const char *(*raw_args) (cmd_parms *parms, void *mconfig, const char *args); /** function to call for a argv/argc */ const char *(*take_argv) (cmd_parms *parms, void *mconfig, int argc, char *const argv[]); /** function to call for a take1 */ const char *(*take1) (cmd_parms *parms, void *mconfig, const char *w); /** function to call for a take2 */ const char *(*take2) (cmd_parms *parms, void *mconfig, const char *w, const char *w2); /** function to call for a take3 */ const char *(*take3) (cmd_parms *parms, void *mconfig, const char *w, const char *w2, const char *w3); /** function to call for a flag */ const char *(*flag) (cmd_parms *parms, void *mconfig, int on); } cmd_func; /** This configuration directive does not take any arguments */ # define AP_NO_ARGS func.no_args /** This configuration directive will handle its own parsing of arguments*/ # define AP_RAW_ARGS func.raw_args /** This configuration directive will handle its own parsing of arguments*/ # define AP_TAKE_ARGV func.take_argv /** This configuration directive takes 1 argument*/ # define AP_TAKE1 func.take1 /** This configuration directive takes 2 arguments */ # define AP_TAKE2 func.take2 /** This configuration directive takes 3 arguments */ # define AP_TAKE3 func.take3 /** This configuration directive takes a flag (on/off) as a argument*/ # define AP_FLAG func.flag /** mechanism for declaring a directive with no arguments */ # define AP_INIT_NO_ARGS(directive, func, mconfig, where, help) \ { directive, { .no_args=func }, mconfig, where, RAW_ARGS, help } /** mechanism for declaring a directive with raw argument parsing */ # define AP_INIT_RAW_ARGS(directive, func, mconfig, where, help) \ { directive, { .raw_args=func }, mconfig, where, RAW_ARGS, help } /** mechanism for declaring a directive with raw argument parsing */ # define AP_INIT_TAKE_ARGV(directive, func, mconfig, where, help) \ { directive, { .take_argv=func }, mconfig, where, TAKE_ARGV, help } /** mechanism for declaring a directive which takes 1 argument */ # define AP_INIT_TAKE1(directive, func, mconfig, where, help) \ { directive, { .take1=func }, mconfig, where, TAKE1, help } /** mechanism for declaring a directive which takes multiple arguments */ # define AP_INIT_ITERATE(directive, func, mconfig, where, help) \ { directive, { .take1=func }, mconfig, where, ITERATE, help } /** mechanism for declaring a directive which takes 2 arguments */ # define AP_INIT_TAKE2(directive, func, mconfig, where, help) \ { directive, { .take2=func }, mconfig, where, TAKE2, help } /** mechanism for declaring a directive which takes 1 or 2 arguments */ # define AP_INIT_TAKE12(directive, func, mconfig, where, help) \ { directive, { .take2=func }, mconfig, where, TAKE12, help } /** mechanism for declaring a directive which takes multiple 2 arguments */ # define AP_INIT_ITERATE2(directive, func, mconfig, where, help) \ { directive, { .take2=func }, mconfig, where, ITERATE2, help } /** mechanism for declaring a directive which takes 1 or 3 arguments */ # define AP_INIT_TAKE13(directive, func, mconfig, where, help) \ { directive, { .take3=func }, mconfig, where, TAKE13, help } /** mechanism for declaring a directive which takes 2 or 3 arguments */ # define AP_INIT_TAKE23(directive, func, mconfig, where, help) \ { directive, { .take3=func }, mconfig, where, TAKE23, help } /** mechanism for declaring a directive which takes 1 to 3 arguments */ # define AP_INIT_TAKE123(directive, func, mconfig, where, help) \ { directive, { .take3=func }, mconfig, where, TAKE123, help } /** mechanism for declaring a directive which takes 3 arguments */ # define AP_INIT_TAKE3(directive, func, mconfig, where, help) \ { directive, { .take3=func }, mconfig, where, TAKE3, help } /** mechanism for declaring a directive which takes a flag (on/off) argument */ # define AP_INIT_FLAG(directive, func, mconfig, where, help) \ { directive, { .flag=func }, mconfig, where, FLAG, help } #else /* AP_HAVE_DESIGNATED_INITIALIZER */ typedef const char *(*cmd_func) (); # define AP_NO_ARGS func # define AP_RAW_ARGS func # define AP_TAKE_ARGV func # define AP_TAKE1 func # define AP_TAKE2 func # define AP_TAKE3 func # define AP_FLAG func # define AP_INIT_NO_ARGS(directive, func, mconfig, where, help) \ { directive, func, mconfig, where, RAW_ARGS, help } # define AP_INIT_RAW_ARGS(directive, func, mconfig, where, help) \ { directive, func, mconfig, where, RAW_ARGS, help } # define AP_INIT_TAKE_ARGV(directive, func, mconfig, where, help) \ { directive, func, mconfig, where, TAKE_ARGV, help } # define AP_INIT_TAKE1(directive, func, mconfig, where, help) \ { directive, func, mconfig, where, TAKE1, help } # define AP_INIT_ITERATE(directive, func, mconfig, where, help) \ { directive, func, mconfig, where, ITERATE, help } # define AP_INIT_TAKE2(directive, func, mconfig, where, help) \ { directive, func, mconfig, where, TAKE2, help } # define AP_INIT_TAKE12(directive, func, mconfig, where, help) \ { directive, func, mconfig, where, TAKE12, help } # define AP_INIT_ITERATE2(directive, func, mconfig, where, help) \ { directive, func, mconfig, where, ITERATE2, help } # define AP_INIT_TAKE13(directive, func, mconfig, where, help) \ { directive, func, mconfig, where, TAKE13, help } # define AP_INIT_TAKE23(directive, func, mconfig, where, help) \ { directive, func, mconfig, where, TAKE23, help } # define AP_INIT_TAKE123(directive, func, mconfig, where, help) \ { directive, func, mconfig, where, TAKE123, help } # define AP_INIT_TAKE3(directive, func, mconfig, where, help) \ { directive, func, mconfig, where, TAKE3, help } # define AP_INIT_FLAG(directive, func, mconfig, where, help) \ { directive, func, mconfig, where, FLAG, help } #endif /* AP_HAVE_DESIGNATED_INITIALIZER */ /** * The command record structure. Modules can define a table of these * to define the directives it will implement. */ typedef struct command_struct command_rec; struct command_struct { /** Name of this command */ const char *name; /** The function to be called when this directive is parsed */ cmd_func func; /** Extra data, for functions which implement multiple commands... */ void *cmd_data; /** What overrides need to be allowed to enable this command. */ int req_override; /** What the command expects as arguments */ enum cmd_how args_how; /** 'usage' message, in case of syntax errors */ const char *errmsg; }; /** * @defgroup ConfigDirectives Allowed locations for configuration directives. * * The allowed locations for a configuration directive are the union of * those indicated by each set bit in the req_override mask. * * @{ */ #define OR_NONE 0 /**< *.conf is not available anywhere in this override */ #define OR_LIMIT 1 /**< *.conf inside <Directory> or <Location> and .htaccess when AllowOverride Limit */ #define OR_OPTIONS 2 /**< *.conf anywhere and .htaccess when AllowOverride Options */ #define OR_FILEINFO 4 /**< *.conf anywhere and .htaccess when AllowOverride FileInfo */ #define OR_AUTHCFG 8 /**< *.conf inside <Directory> or <Location> and .htaccess when AllowOverride AuthConfig */ #define OR_INDEXES 16 /**< *.conf anywhere and .htaccess when AllowOverride Indexes */ #define OR_UNSET 32 /**< bit to indicate that AllowOverride has not been set */ #define ACCESS_CONF 64 /**< *.conf inside <Directory> or <Location> */ #define RSRC_CONF 128 /**< *.conf outside <Directory> or <Location> */ #define EXEC_ON_READ 256 /**< force directive to execute a command which would modify the configuration (like including another file, or IFModule */ /* Flags to determine whether syntax errors in .htaccess should be * treated as nonfatal (log and ignore errors) */ #define NONFATAL_OVERRIDE 512 /* Violation of AllowOverride rule */ #define NONFATAL_UNKNOWN 1024 /* Unrecognised directive */ #define NONFATAL_ALL (NONFATAL_OVERRIDE|NONFATAL_UNKNOWN) #define PROXY_CONF 2048 /**< *.conf inside <Proxy> only */ /** this directive can be placed anywhere */ #define OR_ALL (OR_LIMIT|OR_OPTIONS|OR_FILEINFO|OR_AUTHCFG|OR_INDEXES) /** @} */ /** * This can be returned by a function if they don't wish to handle * a command. Make it something not likely someone will actually use * as an error code. */ #define DECLINE_CMD "\a\b" /** Common structure for reading of config files / passwd files etc. */ typedef struct ap_configfile_t ap_configfile_t; struct ap_configfile_t { /**< an apr_file_getc()-like function */ apr_status_t (*getch) (char *ch, void *param); /**< an apr_file_gets()-like function */ apr_status_t (*getstr) (void *buf, apr_size_t bufsiz, void *param); /**< a close handler function */ apr_status_t (*close) (void *param); /**< the argument passed to getch/getstr/close */ void *param; /**< the filename / description */ const char *name; /**< current line number, starting at 1 */ unsigned line_number; }; /** * This structure is passed to a command which is being invoked, * to carry a large variety of miscellaneous data which is all of * use to *somebody*... */ struct cmd_parms_struct { /** Argument to command from cmd_table */ void *info; /** Which allow-override bits are set */ int override; /** Which allow-override-opts bits are set */ int override_opts; /** Table of directives allowed per AllowOverrideList */ apr_table_t *override_list; /** Which methods are <Limit>ed */ apr_int64_t limited; /** methods which are limited */ apr_array_header_t *limited_xmethods; /** methods which are xlimited */ ap_method_list_t *xlimited; /** Config file structure. */ ap_configfile_t *config_file; /** the directive specifying this command */ ap_directive_t *directive; /** Pool to allocate new storage in */ apr_pool_t *pool; /** Pool for scratch memory; persists during configuration, but * wiped before the first request is served... */ apr_pool_t *temp_pool; /** Server_rec being configured for */ server_rec *server; /** If configuring for a directory, pathname of that directory. * NOPE! That's what it meant previous to the existence of <Files>, * <Location> and regex matching. Now the only usefulness that can be * derived from this field is whether a command is being called in a * server context (path == NULL) or being called in a dir context * (path != NULL). */ char *path; /** configuration command */ const command_rec *cmd; /** per_dir_config vector passed to handle_command */ struct ap_conf_vector_t *context; /** directive with syntax error */ const ap_directive_t *err_directive; }; /** * Flags associated with a module. */ #define AP_MODULE_FLAG_NONE (0) #define AP_MODULE_FLAG_ALWAYS_MERGE (1 << 0) /** * Module structures. Just about everything is dispatched through * these, directly or indirectly (through the command and handler * tables). */ typedef struct module_struct module; struct module_struct { /** API version, *not* module version; check that module is * compatible with this version of the server. */ int version; /** API minor version. Provides API feature milestones. Not checked * during module init */ int minor_version; /** Index to this modules structures in config vectors. */ int module_index; /** The name of the module's C file */ const char *name; /** The handle for the DSO. Internal use only */ void *dynamic_load_handle; /** A pointer to the next module in the list * @var module_struct *next */ struct module_struct *next; /** Magic Cookie to identify a module structure; It's mainly * important for the DSO facility (see also mod_so). */ unsigned long magic; /** Function to allow MPMs to re-write command line arguments. This * hook is only available to MPMs. * @param The process that the server is running in. */ void (*rewrite_args) (process_rec *process); /** Function to allow all modules to create per directory configuration * structures. * @param p The pool to use for all allocations. * @param dir The directory currently being processed. * @return The per-directory structure created */ void *(*create_dir_config) (apr_pool_t *p, char *dir); /** Function to allow all modules to merge the per directory configuration * structures for two directories. * @param p The pool to use for all allocations. * @param base_conf The directory structure created for the parent directory. * @param new_conf The directory structure currently being processed. * @return The new per-directory structure created */ void *(*merge_dir_config) (apr_pool_t *p, void *base_conf, void *new_conf); /** Function to allow all modules to create per server configuration * structures. * @param p The pool to use for all allocations. * @param s The server currently being processed. * @return The per-server structure created */ void *(*create_server_config) (apr_pool_t *p, server_rec *s); /** Function to allow all modules to merge the per server configuration * structures for two servers. * @param p The pool to use for all allocations. * @param base_conf The directory structure created for the parent directory. * @param new_conf The directory structure currently being processed. * @return The new per-directory structure created */ void *(*merge_server_config) (apr_pool_t *p, void *base_conf, void *new_conf); /** A command_rec table that describes all of the directives this module * defines. */ const command_rec *cmds; /** A hook to allow modules to hook other points in the request processing. * In this function, modules should call the ap_hook_*() functions to * register an interest in a specific step in processing the current * request. * @param p the pool to use for all allocations */ void (*register_hooks) (apr_pool_t *p); /** A bitmask of AP_MODULE_FLAG_* */ int flags; }; /** * The AP_MAYBE_UNUSED macro is used for variable declarations that * might potentially exhibit "unused var" warnings on some compilers if * left untreated. * Since static intializers are not part of the C language (C89), making * (void) usage is not possible. However many compiler have proprietary * mechanism to suppress those warnings. */ #ifdef AP_MAYBE_UNUSED #elif defined(__GNUC__) # define AP_MAYBE_UNUSED(x) x __attribute__((unused)) #elif defined(__LCLINT__) # define AP_MAYBE_UNUSED(x) /*@unused@*/ x #else # define AP_MAYBE_UNUSED(x) x #endif /** * The APLOG_USE_MODULE macro is used choose which module a file belongs to. * This is necessary to allow per-module loglevel configuration. * * APLOG_USE_MODULE indirectly sets APLOG_MODULE_INDEX and APLOG_MARK. * * If a module should be backward compatible with versions before 2.3.6, * APLOG_USE_MODULE needs to be enclosed in a ifdef APLOG_USE_MODULE block. * * @param foo name of the module symbol of the current module, without the * trailing "_module" part * @see APLOG_MARK */ #define APLOG_USE_MODULE(foo) \ extern module AP_MODULE_DECLARE_DATA foo##_module; \ AP_MAYBE_UNUSED(static int * const aplog_module_index) = &(foo##_module.module_index) /** * AP_DECLARE_MODULE is a convenience macro that combines a call of * APLOG_USE_MODULE with the definition of the module symbol. * * If a module should be backward compatible with versions before 2.3.6, * APLOG_USE_MODULE should be used explicitly instead of AP_DECLARE_MODULE. */ #define AP_DECLARE_MODULE(foo) \ APLOG_USE_MODULE(foo); \ module AP_MODULE_DECLARE_DATA foo##_module /** * @defgroup ModuleInit Module structure initializers * * Initializer for the first few module slots, which are only * really set up once we start running. Note that the first two slots * provide a version check; this should allow us to deal with changes to * the API. The major number should reflect changes to the API handler table * itself or removal of functionality. The minor number should reflect * additions of functionality to the existing API. (the server can detect * an old-format module, and either handle it back-compatibly, or at least * signal an error). See src/include/ap_mmn.h for MMN version history. * @{ */ /** The one used in Apache 1.3, which will deliberately cause an error */ #define STANDARD_MODULE_STUFF this_module_needs_to_be_ported_to_apache_2_0 /** Use this in all standard modules */ #define STANDARD20_MODULE_STUFF MODULE_MAGIC_NUMBER_MAJOR, \ MODULE_MAGIC_NUMBER_MINOR, \ -1, \ __FILE__, \ NULL, \ NULL, \ MODULE_MAGIC_COOKIE, \ NULL /* rewrite args spot */ /** Use this only in MPMs */ #define MPM20_MODULE_STUFF MODULE_MAGIC_NUMBER_MAJOR, \ MODULE_MAGIC_NUMBER_MINOR, \ -1, \ __FILE__, \ NULL, \ NULL, \ MODULE_MAGIC_COOKIE /** @} */ /* CONFIGURATION VECTOR FUNCTIONS */ /** configuration vector structure */ typedef struct ap_conf_vector_t ap_conf_vector_t; /** * Generic accessors for other modules to get at their own module-specific * data * @param cv The vector in which the modules configuration is stored. * usually r->per_dir_config or s->module_config * @param m The module to get the data for. * @return The module-specific data */ AP_DECLARE(void *) ap_get_module_config(const ap_conf_vector_t *cv, const module *m); /** * Generic accessors for other modules to set their own module-specific * data * @param cv The vector in which the modules configuration is stored. * usually r->per_dir_config or s->module_config * @param m The module to set the data for. * @param val The module-specific data to set */ AP_DECLARE(void) ap_set_module_config(ap_conf_vector_t *cv, const module *m, void *val); /** * When module flags have been introduced, and a way to check this. */ #define AP_MODULE_FLAGS_MMN_MAJOR 20120211 #define AP_MODULE_FLAGS_MMN_MINOR 70 #define AP_MODULE_HAS_FLAGS(m) \ AP_MODULE_MAGIC_AT_LEAST(AP_MODULE_FLAGS_MMN_MAJOR, \ AP_MODULE_FLAGS_MMN_MINOR) /** * Generic accessor for the module's flags * @param m The module to get the flags from. * @return The module-specific flags */ AP_DECLARE(int) ap_get_module_flags(const module *m); #if !defined(AP_DEBUG) #define ap_get_module_config(v,m) \ (((void **)(v))[(m)->module_index]) #define ap_set_module_config(v,m,val) \ ((((void **)(v))[(m)->module_index]) = (val)) #endif /* AP_DEBUG */ /** * Generic accessor for modules to get the module-specific loglevel * @param s The server from which to get the loglevel. * @param index The module_index of the module to get the loglevel for. * @return The module-specific loglevel */ AP_DECLARE(int) ap_get_server_module_loglevel(const server_rec *s, int index); /** * Generic accessor for modules the module-specific loglevel * @param c The connection from which to get the loglevel. * @param index The module_index of the module to get the loglevel for. * @return The module-specific loglevel */ AP_DECLARE(int) ap_get_conn_module_loglevel(const conn_rec *c, int index); /** * Generic accessor for modules the module-specific loglevel * @param c The connection from which to get the loglevel. * @param s The server from which to get the loglevel if c does not have a * specific loglevel configuration. * @param index The module_index of the module to get the loglevel for. * @return The module-specific loglevel */ AP_DECLARE(int) ap_get_conn_server_module_loglevel(const conn_rec *c, const server_rec *s, int index); /** * Generic accessor for modules to get the module-specific loglevel * @param r The request from which to get the loglevel. * @param index The module_index of the module to get the loglevel for. * @return The module-specific loglevel */ AP_DECLARE(int) ap_get_request_module_loglevel(const request_rec *r, int index); /** * Accessor to set module-specific loglevel * @param p A pool * @param l The ap_logconf struct to modify. * @param index The module_index of the module to set the loglevel for. * @param level The new log level */ AP_DECLARE(void) ap_set_module_loglevel(apr_pool_t *p, struct ap_logconf *l, int index, int level); #if !defined(AP_DEBUG) #define ap_get_conn_logconf(c) \ ((c)->log ? (c)->log : \ &(c)->base_server->log) #define ap_get_conn_server_logconf(c,s) \ ( ( (c)->log != &(c)->base_server->log && (c)->log != NULL ) ? \ (c)->log : \ &(s)->log ) #define ap_get_request_logconf(r) \ ((r)->log ? (r)->log : \ (r)->connection->log ? (r)->connection->log : \ &(r)->server->log) #define ap_get_module_loglevel(l,i) \ (((i) < 0 || (l)->module_levels == NULL || (l)->module_levels[i] < 0) ? \ (l)->level : \ (l)->module_levels[i]) #define ap_get_server_module_loglevel(s,i) \ (ap_get_module_loglevel(&(s)->log,i)) #define ap_get_conn_module_loglevel(c,i) \ (ap_get_module_loglevel(ap_get_conn_logconf(c),i)) #define ap_get_conn_server_module_loglevel(c,s,i) \ (ap_get_module_loglevel(ap_get_conn_server_logconf(c,s),i)) #define ap_get_request_module_loglevel(r,i) \ (ap_get_module_loglevel(ap_get_request_logconf(r),i)) #endif /* AP_DEBUG */ /** * Set all module-specific loglevels to val * @param l The log config for which to set the loglevels. * @param val the value to set all loglevels to */ AP_DECLARE(void) ap_reset_module_loglevels(struct ap_logconf *l, int val); /** * Generic command handling function for strings * @param cmd The command parameters for this directive * @param struct_ptr pointer into a given type * @param arg The argument to the directive * @return An error string or NULL on success */ AP_DECLARE_NONSTD(const char *) ap_set_string_slot(cmd_parms *cmd, void *struct_ptr, const char *arg); /** * Generic command handling function for integers * @param cmd The command parameters for this directive * @param struct_ptr pointer into a given type * @param arg The argument to the directive * @return An error string or NULL on success */ AP_DECLARE_NONSTD(const char *) ap_set_int_slot(cmd_parms *cmd, void *struct_ptr, const char *arg); /** * Parsing function for log level * @param str The string to parse * @param val The parsed log level * @return An error string or NULL on success */ AP_DECLARE(const char *) ap_parse_log_level(const char *str, int *val); /** * Return true if the specified method is limited by being listed in * a <Limit> container, or by *not* being listed in a <LimitExcept> * container. * * @param method Pointer to a string specifying the method to check. * @param cmd Pointer to the cmd_parms structure passed to the * directive handler. * @return 0 if the method is not limited in the current scope */ AP_DECLARE(int) ap_method_is_limited(cmd_parms *cmd, const char *method); /** * Generic command handling function for strings, always sets the value * to a lowercase string * @param cmd The command parameters for this directive * @param struct_ptr pointer into a given type * @param arg The argument to the directive * @return An error string or NULL on success */ AP_DECLARE_NONSTD(const char *) ap_set_string_slot_lower(cmd_parms *cmd, void *struct_ptr, const char *arg); /** * Generic command handling function for flags stored in an int * @param cmd The command parameters for this directive * @param struct_ptr pointer into a given type * @param arg The argument to the directive (either 1 or 0) * @return An error string or NULL on success */ AP_DECLARE_NONSTD(const char *) ap_set_flag_slot(cmd_parms *cmd, void *struct_ptr, int arg); /** * Generic command handling function for flags stored in a char * @param cmd The command parameters for this directive * @param struct_ptr pointer into a given type * @param arg The argument to the directive (either 1 or 0) * @return An error string or NULL on success */ AP_DECLARE_NONSTD(const char *) ap_set_flag_slot_char(cmd_parms *cmd, void *struct_ptr, int arg); /** * Generic command handling function for files * @param cmd The command parameters for this directive * @param struct_ptr pointer into a given type * @param arg The argument to the directive * @return An error string or NULL on success */ AP_DECLARE_NONSTD(const char *) ap_set_file_slot(cmd_parms *cmd, void *struct_ptr, const char *arg); /** * Generic command handling function to respond with cmd->help as an error * @param cmd The command parameters for this directive * @param struct_ptr pointer into a given type * @param arg The argument to the directive * @return The cmd->help value as the error string * @note This allows simple declarations such as: * @code * AP_INIT_RAW_ARGS("Foo", ap_set_deprecated, NULL, OR_ALL, * "The Foo directive is no longer supported, use Bar"), * @endcode */ AP_DECLARE_NONSTD(const char *) ap_set_deprecated(cmd_parms *cmd, void *struct_ptr, const char *arg); /** * For modules which need to read config files, open logs, etc. this returns * the canonical form of fname made absolute to ap_server_root. * @param p pool to allocate data from * @param fname The file name */ AP_DECLARE(char *) ap_server_root_relative(apr_pool_t *p, const char *fname); /** * Compute the name of a run-time file (e.g., shared memory "file") relative * to the appropriate run-time directory. Absolute paths are returned as-is. * The run-time directory is configured via the DefaultRuntimeDir directive or * at build time. */ AP_DECLARE(char *) ap_runtime_dir_relative(apr_pool_t *p, const char *fname); /* Finally, the hook for dynamically loading modules in... */ /** * Add a module to the server * @param m The module structure of the module to add * @param p The pool of the same lifetime as the module * @param s The module's symbol name (used for logging) */ AP_DECLARE(const char *) ap_add_module(module *m, apr_pool_t *p, const char *s); /** * Remove a module from the server. There are some caveats: * when the module is removed, its slot is lost so all the current * per-dir and per-server configurations are invalid. So we should * only ever call this function when you are invalidating almost * all our current data. I.e. when doing a restart. * @param m the module structure of the module to remove */ AP_DECLARE(void) ap_remove_module(module *m); /** * Add a module to the chained modules list and the list of loaded modules * @param mod The module structure of the module to add * @param p The pool with the same lifetime as the module * @param s The module's symbol name (used for logging) */ AP_DECLARE(const char *) ap_add_loaded_module(module *mod, apr_pool_t *p, const char *s); /** * Remove a module fromthe chained modules list and the list of loaded modules * @param mod the module structure of the module to remove */ AP_DECLARE(void) ap_remove_loaded_module(module *mod); /** * Find the name of the specified module * @param m The module to get the name for * @return the name of the module */ AP_DECLARE(const char *) ap_find_module_name(module *m); /** * Find the short name of the module identified by the specified module index * @param module_index The module index to get the name for * @return the name of the module, NULL if not found */ AP_DECLARE(const char *) ap_find_module_short_name(int module_index); /** * Find a module based on the name of the module * @param name the name of the module * @return the module structure if found, NULL otherwise */ AP_DECLARE(module *) ap_find_linked_module(const char *name); /** * Open a ap_configfile_t as apr_file_t * @param ret_cfg open ap_configfile_t struct pointer * @param p The pool to allocate the structure from * @param name the name of the file to open */ AP_DECLARE(apr_status_t) ap_pcfg_openfile(ap_configfile_t **ret_cfg, apr_pool_t *p, const char *name); /** * Allocate a ap_configfile_t handle with user defined functions and params * @param p The pool to allocate from * @param descr The name of the file * @param param The argument passed to getch/getstr/close * @param getc_func The getch function * @param gets_func The getstr function * @param close_func The close function */ AP_DECLARE(ap_configfile_t *) ap_pcfg_open_custom(apr_pool_t *p, const char *descr, void *param, apr_status_t (*getc_func) (char *ch, void *param), apr_status_t (*gets_func) (void *buf, apr_size_t bufsiz, void *param), apr_status_t (*close_func) (void *param)); /** * Read one line from open ap_configfile_t, strip leading and trailing * whitespace, increase line number * @param buf place to store the line read * @param bufsize size of the buffer * @param cfp File to read from * @return error status, APR_ENOSPC if bufsize is too small for the line */ AP_DECLARE(apr_status_t) ap_cfg_getline(char *buf, apr_size_t bufsize, ap_configfile_t *cfp); /** * Read one char from open configfile_t, increase line number upon LF * @param ch place to store the char read * @param cfp The file to read from * @return error status */ AP_DECLARE(apr_status_t) ap_cfg_getc(char *ch, ap_configfile_t *cfp); /** * Detach from open ap_configfile_t, calling the close handler * @param cfp The file to close * @return 1 on success, 0 on failure */ AP_DECLARE(int) ap_cfg_closefile(ap_configfile_t *cfp); /** * Convert a return value from ap_cfg_getline or ap_cfg_getc to a user friendly * string. * @param p The pool to allocate the string from * @param cfp The config file * @param rc The return value to convert * @return The error string, NULL if rc == APR_SUCCESS */ AP_DECLARE(const char *) ap_pcfg_strerror(apr_pool_t *p, ap_configfile_t *cfp, apr_status_t rc); /** * Read all data between the current <foo> and the matching </foo>. All * of this data is forgotten immediately. * @param cmd The cmd_parms to pass to the directives inside the container * @param directive The directive name to read until * @return Error string on failure, NULL on success * @note If cmd->pool == cmd->temp_pool, ap_soak_end_container() will assume * .htaccess context and use a lower maximum line length. */ AP_DECLARE(const char *) ap_soak_end_container(cmd_parms *cmd, char *directive); /** * Read all data between the current <foo> and the matching </foo> and build * a config tree from it * @param p pool to allocate from * @param temp_pool Temporary pool to allocate from * @param parms The cmd_parms to pass to all directives read * @param current The current node in the tree * @param curr_parent The current parent node * @param orig_directive The directive to read until hit. * @return Error string on failure, NULL on success * @note If p == temp_pool, ap_build_cont_config() will assume .htaccess * context and use a lower maximum line length. */ AP_DECLARE(const char *) ap_build_cont_config(apr_pool_t *p, apr_pool_t *temp_pool, cmd_parms *parms, ap_directive_t **current, ap_directive_t **curr_parent, char *orig_directive); /** * Build a config tree from a config file * @param parms The cmd_parms to pass to all of the directives in the file * @param conf_pool The pconf pool * @param temp_pool The temporary pool * @param conftree Place to store the root node of the config tree * @return Error string on erro, NULL otherwise * @note If conf_pool == temp_pool, ap_build_config() will assume .htaccess * context and use a lower maximum line length. */ AP_DECLARE(const char *) ap_build_config(cmd_parms *parms, apr_pool_t *conf_pool, apr_pool_t *temp_pool, ap_directive_t **conftree); /** * Walk a config tree and setup the server's internal structures * @param conftree The config tree to walk * @param parms The cmd_parms to pass to all functions * @param section_vector The per-section config vector. * @return Error string on error, NULL otherwise */ AP_DECLARE(const char *) ap_walk_config(ap_directive_t *conftree, cmd_parms *parms, ap_conf_vector_t *section_vector); /** * @defgroup ap_check_cmd_context Check command context * @{ */ /** * Check the context a command is used in. * @param cmd The command to check * @param forbidden Where the command is forbidden. * @return Error string on error, NULL on success */ AP_DECLARE(const char *) ap_check_cmd_context(cmd_parms *cmd, unsigned forbidden); #define NOT_IN_VIRTUALHOST 0x01 /**< Forbidden in <VirtualHost> */ #define NOT_IN_LIMIT 0x02 /**< Forbidden in <Limit> */ #define NOT_IN_DIRECTORY 0x04 /**< Forbidden in <Directory> */ #define NOT_IN_LOCATION 0x08 /**< Forbidden in <Location> */ #define NOT_IN_FILES 0x10 /**< Forbidden in <Files> or <If>*/ #define NOT_IN_HTACCESS 0x20 /**< Forbidden in .htaccess files */ #define NOT_IN_PROXY 0x40 /**< Forbidden in <Proxy> */ /** Forbidden in <Directory>/<Location>/<Files><If>*/ #define NOT_IN_DIR_LOC_FILE (NOT_IN_DIRECTORY|NOT_IN_LOCATION|NOT_IN_FILES) /** Forbidden in <Directory>/<Location>/<Files><If><Proxy>*/ #define NOT_IN_DIR_CONTEXT (NOT_IN_LIMIT|NOT_IN_DIR_LOC_FILE|NOT_IN_PROXY) /** Forbidden in <VirtualHost>/<Limit>/<Directory>/<Location>/<Files>/<If><Proxy>*/ #define GLOBAL_ONLY (NOT_IN_VIRTUALHOST|NOT_IN_DIR_CONTEXT) /** @} */ /** * @brief This structure is used to assign symbol names to module pointers */ typedef struct { const char *name; module *modp; } ap_module_symbol_t; /** * The topmost module in the list * @var module *ap_top_module */ AP_DECLARE_DATA extern module *ap_top_module; /** * Array of all statically linked modules * @var module *ap_prelinked_modules[] */ AP_DECLARE_DATA extern module *ap_prelinked_modules[]; /** * Array of all statically linked modulenames (symbols) * @var ap_module_symbol_t ap_prelinked_module_symbols[] */ AP_DECLARE_DATA extern ap_module_symbol_t ap_prelinked_module_symbols[]; /** * Array of all preloaded modules * @var module *ap_preloaded_modules[] */ AP_DECLARE_DATA extern module *ap_preloaded_modules[]; /** * Array of all loaded modules * @var module **ap_loaded_modules */ AP_DECLARE_DATA extern module **ap_loaded_modules; /* For mod_so.c... */ /** Run a single module's two create_config hooks * @param p the pool to allocate from * @param s The server to configure for. * @param m The module to configure */ AP_DECLARE(void) ap_single_module_configure(apr_pool_t *p, server_rec *s, module *m); /* For http_main.c... */ /** * Add all of the prelinked modules into the loaded module list * @param process The process that is currently running the server */ AP_DECLARE(const char *) ap_setup_prelinked_modules(process_rec *process); /** * Show the preloaded configuration directives, the help string explaining * the directive arguments, in what module they are handled, and in * what parts of the configuration they are allowed. Used for httpd -h. */ AP_DECLARE(void) ap_show_directives(void); /** * Returns non-zero if a configuration directive of the given name has * been registered by a module at the time of calling. * @param p Pool for temporary allocations * @param name Directive name */ AP_DECLARE(int) ap_exists_directive(apr_pool_t *p, const char *name); /** * Show the preloaded module names. Used for httpd -l. */ AP_DECLARE(void) ap_show_modules(void); /** * Show the MPM name. Used in reporting modules such as mod_info to * provide extra information to the user */ AP_DECLARE(const char *) ap_show_mpm(void); /** * Read all config files and setup the server * @param process The process running the server * @param temp_pool A pool to allocate temporary data from. * @param config_name The name of the config file * @param conftree Place to store the root of the config tree * @return The setup server_rec list. */ AP_DECLARE(server_rec *) ap_read_config(process_rec *process, apr_pool_t *temp_pool, const char *config_name, ap_directive_t **conftree); /** * Run all rewrite args hooks for loaded modules * @param process The process currently running the server */ AP_DECLARE(void) ap_run_rewrite_args(process_rec *process); /** * Run the register hooks function for a specified module * @param m The module to run the register hooks function fo * @param p The pool valid for the lifetime of the module */ AP_DECLARE(void) ap_register_hooks(module *m, apr_pool_t *p); /** * Setup all virtual hosts * @param p The pool to allocate from * @param main_server The head of the server_rec list */ AP_DECLARE(void) ap_fixup_virtual_hosts(apr_pool_t *p, server_rec *main_server); /** * Reserve some modules slots for modules loaded by other means than * EXEC_ON_READ directives. * Relevant modules should call this in the pre_config stage. * @param count The number of slots to reserve. */ AP_DECLARE(void) ap_reserve_module_slots(int count); /** * Reserve some modules slots for modules loaded by a specific * non-EXEC_ON_READ config directive. * This counts how often the given directive is used in the config and calls * ap_reserve_module_slots() accordingly. * @param directive The name of the directive */ AP_DECLARE(void) ap_reserve_module_slots_directive(const char *directive); /* For http_request.c... */ /** * Setup the config vector for a request_rec * @param p The pool to allocate the config vector from * @return The config vector */ AP_DECLARE(ap_conf_vector_t*) ap_create_request_config(apr_pool_t *p); /** * Setup the config vector for per dir module configs * @param p The pool to allocate the config vector from * @return The config vector */ AP_CORE_DECLARE(ap_conf_vector_t *) ap_create_per_dir_config(apr_pool_t *p); /** * Run all of the modules merge per dir config functions * @param p The pool to pass to the merge functions * @param base The base directory config structure * @param new_conf The new directory config structure */ AP_CORE_DECLARE(ap_conf_vector_t*) ap_merge_per_dir_configs(apr_pool_t *p, ap_conf_vector_t *base, ap_conf_vector_t *new_conf); /** * Allocate new ap_logconf and make (deep) copy of old ap_logconf * @param p The pool to alloc from * @param old The ap_logconf to copy (may be NULL) * @return The new ap_logconf struct */ AP_DECLARE(struct ap_logconf *) ap_new_log_config(apr_pool_t *p, const struct ap_logconf *old); /** * Merge old ap_logconf into new ap_logconf. * old and new must have the same life time. * @param old_conf The ap_logconf to merge from * @param new_conf The ap_logconf to merge into */ AP_DECLARE(void) ap_merge_log_config(const struct ap_logconf *old_conf, struct ap_logconf *new_conf); /* For http_connection.c... */ /** * Setup the config vector for a connection_rec * @param p The pool to allocate the config vector from * @return The config vector */ AP_CORE_DECLARE(ap_conf_vector_t*) ap_create_conn_config(apr_pool_t *p); /* For http_core.c... (<Directory> command and virtual hosts) */ /** * parse an htaccess file * @param result htaccess_result * @param r The request currently being served * @param override Which overrides are active * @param override_opts Which allow-override-opts bits are set * @param override_list Table of directives allowed for override * @param path The path to the htaccess file * @param access_name The list of possible names for .htaccess files * int The status of the current request */ AP_CORE_DECLARE(int) ap_parse_htaccess(ap_conf_vector_t **result, request_rec *r, int override, int override_opts, apr_table_t *override_list, const char *path, const char *access_name); /** * Setup a virtual host * @param p The pool to allocate all memory from * @param hostname The hostname of the virtual hsot * @param main_server The main server for this Apache configuration * @param ps Place to store the new server_rec * return Error string on error, NULL on success */ AP_CORE_DECLARE(const char *) ap_init_virtual_host(apr_pool_t *p, const char *hostname, server_rec *main_server, server_rec **ps); /** * Process a config file for Apache * @param s The server rec to use for the command parms * @param fname The name of the config file * @param conftree The root node of the created config tree * @param p Pool for general allocation * @param ptemp Pool for temporary allocation */ AP_DECLARE(const char *) ap_process_resource_config(server_rec *s, const char *fname, ap_directive_t **conftree, apr_pool_t *p, apr_pool_t *ptemp); /** * Process all matching files as Apache configs * @param s The server rec to use for the command parms * @param fname The filename pattern of the config file * @param conftree The root node of the created config tree * @param p Pool for general allocation * @param ptemp Pool for temporary allocation * @param optional Whether a no-match wildcard is allowed * @see apr_fnmatch for pattern handling */ AP_DECLARE(const char *) ap_process_fnmatch_configs(server_rec *s, const char *fname, ap_directive_t **conftree, apr_pool_t *p, apr_pool_t *ptemp, int optional); /** * Process all directives in the config tree * @param s The server rec to use in the command parms * @param conftree The config tree to process * @param p The pool for general allocation * @param ptemp The pool for temporary allocations * @return OK if no problems */ AP_DECLARE(int) ap_process_config_tree(server_rec *s, ap_directive_t *conftree, apr_pool_t *p, apr_pool_t *ptemp); /** * Store data which will be retained across unload/load of modules * @param key The unique key associated with this module's retained data * @param size in bytes of the retained data (to be allocated) * @return Address of new retained data structure, initially cleared */ AP_DECLARE(void *) ap_retained_data_create(const char *key, apr_size_t size); /** * Retrieve data which was stored by ap_retained_data_create() * @param key The unique key associated with this module's retained data * @return Address of previously retained data structure, or NULL if not yet saved */ AP_DECLARE(void *) ap_retained_data_get(const char *key); /* Module-method dispatchers, also for http_request.c */ /** * Run the handler phase of each module until a module accepts the * responsibility of serving the request * @param r The current request * @return The status of the current request */ AP_CORE_DECLARE(int) ap_invoke_handler(request_rec *r); /* for mod_perl */ /** * Find a given directive in a command_rec table * @param name The directive to search for * @param cmds The table to search * @return The directive definition of the specified directive */ AP_CORE_DECLARE(const command_rec *) ap_find_command(const char *name, const command_rec *cmds); /** * Find a given directive in a list of modules. * @param cmd_name The directive to search for * @param mod Pointer to the first module in the linked list; will be set to * the module providing cmd_name * @return The directive definition of the specified directive. * *mod will be changed to point to the module containing the * directive. */ AP_CORE_DECLARE(const command_rec *) ap_find_command_in_modules(const char *cmd_name, module **mod); /** * Ask a module to create per-server and per-section (dir/loc/file) configs * (if it hasn't happened already). The results are stored in the server's * config, and the specified per-section config vector. * @param server The server to operate upon. * @param section_vector The per-section config vector. * @param section Which section to create a config for. * @param mod The module which is defining the config data. * @param pconf A pool for all configuration allocations. * @return The (new) per-section config data. */ AP_CORE_DECLARE(void *) ap_set_config_vectors(server_rec *server, ap_conf_vector_t *section_vector, const char *section, module *mod, apr_pool_t *pconf); /* Hooks */ /** * Run the header parser functions for each module * @param r The current request * @return OK or DECLINED */ AP_DECLARE_HOOK(int,header_parser,(request_rec *r)) /** * Run the pre_config function for each module * @param pconf The config pool * @param plog The logging streams pool * @param ptemp The temporary pool * @return OK or DECLINED on success anything else is a error */ AP_DECLARE_HOOK(int,pre_config,(apr_pool_t *pconf,apr_pool_t *plog, apr_pool_t *ptemp)) /** * Run the check_config function for each module * @param pconf The config pool * @param plog The logging streams pool * @param ptemp The temporary pool * @param s the server to operate upon * @return OK or DECLINED on success anything else is a error */ AP_DECLARE_HOOK(int,check_config,(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s)) /** * Run the test_config function for each module; this hook is run * only if the server was invoked to test the configuration syntax. * @param pconf The config pool * @param s The list of server_recs * @note To avoid reordering problems due to different buffering, hook * functions should only apr_file_*() to print to stdout/stderr and * not simple printf()/fprintf(). * */ AP_DECLARE_HOOK(void,test_config,(apr_pool_t *pconf, server_rec *s)) /** * Run the post_config function for each module * @param pconf The config pool * @param plog The logging streams pool * @param ptemp The temporary pool * @param s The list of server_recs * @return OK or DECLINED on success anything else is a error */ AP_DECLARE_HOOK(int,post_config,(apr_pool_t *pconf,apr_pool_t *plog, apr_pool_t *ptemp,server_rec *s)) /** * Run the open_logs functions for each module * @param pconf The config pool * @param plog The logging streams pool * @param ptemp The temporary pool * @param s The list of server_recs * @return OK or DECLINED on success anything else is a error */ AP_DECLARE_HOOK(int,open_logs,(apr_pool_t *pconf,apr_pool_t *plog, apr_pool_t *ptemp,server_rec *s)) /** * Run the child_init functions for each module * @param pchild The child pool * @param s The list of server_recs in this server */ AP_DECLARE_HOOK(void,child_init,(apr_pool_t *pchild, server_rec *s)) /** * Run the handler functions for each module * @param r The request_rec * @remark non-wildcard handlers should HOOK_MIDDLE, wildcard HOOK_LAST */ AP_DECLARE_HOOK(int,handler,(request_rec *r)) /** * Run the quick handler functions for each module. The quick_handler * is run before any other requests hooks are called (location_walk, * directory_walk, access checking, et. al.). This hook was added * to provide a quick way to serve content from a URI keyed cache. * * @param r The request_rec * @param lookup_uri Controls whether the caller actually wants content or not. * lookup is set when the quick_handler is called out of * ap_sub_req_lookup_uri() */ AP_DECLARE_HOOK(int,quick_handler,(request_rec *r, int lookup_uri)) /** * Retrieve the optional functions for each module. * This is run immediately before the server starts. Optional functions should * be registered during the hook registration phase. */ AP_DECLARE_HOOK(void,optional_fn_retrieve,(void)) /** * Allow modules to open htaccess files or perform operations before doing so * @param r The current request * @param dir_name The directory for which the htaccess file should be opened * @param access_name The filename for which the htaccess file should be opened * @param conffile Where the pointer to the opened ap_configfile_t must be * stored * @param full_name Where the full file name of the htaccess file must be * stored. * @return APR_SUCCESS on success, * APR_ENOENT or APR_ENOTDIR if no htaccess file exists, * AP_DECLINED to let later modules do the opening, * any other error code on error. */ AP_DECLARE_HOOK(apr_status_t,open_htaccess, (request_rec *r, const char *dir_name, const char *access_name, ap_configfile_t **conffile, const char **full_name)) /** * Core internal function, use ap_run_open_htaccess() instead. */ apr_status_t ap_open_htaccess(request_rec *r, const char *dir_name, const char *access_name, ap_configfile_t **conffile, const char **full_name); /** * A generic pool cleanup that will reset a pointer to NULL. For use with * apr_pool_cleanup_register. * @param data The address of the pointer * @return APR_SUCCESS */ AP_DECLARE_NONSTD(apr_status_t) ap_pool_cleanup_set_null(void *data); #ifdef __cplusplus } #endif #endif /* !APACHE_HTTP_CONFIG_H */ /** @} */ Analizo-1.25.5/t/samples/wildcard/0000775000175000017500000000000014676555272016256 5ustar joeniojoenioAnalizo-1.25.5/t/samples/wildcard/GenericClass.java0000644000175000017500000000013314676555272021456 0ustar joeniojoeniopublic class GenericClass { public void print(){ System.out.print(T.class); } } Analizo-1.25.5/t/samples/wildcard/WildcardClass.java0000644000175000017500000000032014676555272021631 0ustar joeniojoenioimport java.util.Collection; public class WildcardClass extends Printer> { public void helloWildcard(){ GenericClass variable = new GenericClass(); variable.print(); } } Analizo-1.25.5/t/samples/abstract_class/0000775000175000017500000000000014676555272017455 5ustar joeniojoenioAnalizo-1.25.5/t/samples/abstract_class/csharp/0000775000175000017500000000000014676555272020735 5ustar joeniojoenioAnalizo-1.25.5/t/samples/abstract_class/csharp/Dog.cs0000644000175000017500000000027514676555272021777 0ustar joeniojoenioclass Dog : FourLeggedAnimal { public override string Describe() { string result = base.Describe(); result += " In fact, it's a dog!"; return result; } }Analizo-1.25.5/t/samples/abstract_class/csharp/Program.cs0000644000175000017500000000036514676555272022675 0ustar joeniojoeniousing System; namespace AbstractClasses { class Program { static void Main(string[] args) { Dog dog = new Dog(); Console.WriteLine(dog.Describe()); Console.ReadKey(); } } }Analizo-1.25.5/t/samples/abstract_class/csharp/FourLeggedAnimal.cs0000644000175000017500000000011214676555272024421 0ustar joeniojoenioabstract class FourLeggedAnimal { public abstract string Describe(); }Analizo-1.25.5/t/samples/abstract_class/java/0000775000175000017500000000000014676555272020376 5ustar joeniojoenioAnalizo-1.25.5/t/samples/abstract_class/java/AbstractDao.java0000644000175000017500000000540214676555272023427 0ustar joeniojoeniopackage br.usp.ime.ccsl.kalibro.database.daos; import static br.usp.ime.ccsl.kalibro.core.utilities.ReflectionUtils.*; import br.usp.ime.ccsl.kalibro.core.types.KalibroType; import br.usp.ime.ccsl.kalibro.database.DatabaseConnector; import java.awt.Color; import java.lang.reflect.Method; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Date; /** * Parent class of all Kalibro data access objects. Contains utility data access methods. * * @author Carlos Morais */ public abstract class AbstractDao { protected DatabaseConnector connector; public AbstractDao() throws SQLException { this(new DatabaseConnector()); } public AbstractDao(DatabaseConnector connector) { this.connector = connector; } /** * Returns the string quoted (with simple quotes). * A simple quote is also added before any simple quote present in the original string. * This method should be used for preventing SQL injection. * * Example: "Joana d'Arc" becomes "'Joana d''Arc'" */ protected String quote(Object object) { if (new Double(Double.POSITIVE_INFINITY).equals(object)) return "" + Double.MAX_VALUE; if (new Double(Double.NEGATIVE_INFINITY).equals(object)) return "" + Double.MIN_VALUE; if (object instanceof Color) return "" + ((Color) object).getRGB(); if (object instanceof Date) return "" + ((Date) object).getTime(); return (object == null) ? "null" : "'" + object.toString().replaceAll("'", "''") + "'"; } private String prepare(String skeleton, KalibroType object) { String result = skeleton; for (Method method : object.getClass().getMethods()) result = result.replace("$" + method.getName(), quote(getValue(method.getName(), object))); return result; } /** * Replaces the occurrences of "$" + fieldName with the values of the field for the specified object. For * example, "name = $name" becomes "name = 'Sample'" if object.name = "Sample". For more than one object, * prepare(skeleton, object1, object2) id equivalent to * prepare(prepare(skeleton, object1), object2). */ protected String prepare(String skeleton, KalibroType... objects) { String result = skeleton; for (KalibroType object : objects) result = prepare(result, object); return result; } /** * Does what ResultSet.getDouble() does, but when the field content is null, returns a null * Double object instead of 0.0 */ protected Double getDouble(ResultSet resultSet, String column) throws SQLException { double value = resultSet.getDouble(column); return resultSet.wasNull() ? null : value; } } Analizo-1.25.5/t/samples/deep_inheritance/0000775000175000017500000000000014676555272017753 5ustar joeniojoenioAnalizo-1.25.5/t/samples/deep_inheritance/java/0000775000175000017500000000000014676555272020674 5ustar joeniojoenioAnalizo-1.25.5/t/samples/deep_inheritance/java/Dog.java0000644000175000017500000000015214676555272022244 0ustar joeniojoenioclass Dog { String name; Human owner; public Human getOwner(){ return owner; } } Analizo-1.25.5/t/samples/deep_inheritance/java/Human.java0000644000175000017500000000015314676555272022604 0ustar joeniojoenioclass Human { String name; Dog pet; public Dog getPetName(){ return pet.name; } } Analizo-1.25.5/t/samples/deep_inheritance/java/VenderShop.java0000644000175000017500000000026114676555272023611 0ustar joeniojoenioclass VenderShop { public void sellDogTo(Human owner){ Dog dog = new Dog(); dog.name = "Toby"; dog.owner = owner; owner.pet = dog; } } Analizo-1.25.5/t/samples/deep_inheritance/java/DogGrandson.java0000644000175000017500000000010714676555272023740 0ustar joeniojoenioclass DogGrandson extends DogFirstPuppy { String number_of_eyes; } Analizo-1.25.5/t/samples/deep_inheritance/java/DogSuperYoung.java0000644000175000017500000000010714676555272024305 0ustar joeniojoenioclass DogSuperYoung extends DogFirstGreatGrandson { String accs; } Analizo-1.25.5/t/samples/deep_inheritance/java/DogFirstPuppy.java0000644000175000017500000000006614676555272024316 0ustar joeniojoenioclass DogFirstPuppy extends Dog { String color; } Analizo-1.25.5/t/samples/deep_inheritance/java/DogSecondPuppy.java0000644000175000017500000000006514676555272024441 0ustar joeniojoenioclass DogSecondPuppy extends Dog { String age; } Analizo-1.25.5/t/samples/deep_inheritance/java/ShopController.java0000644000175000017500000000031214676555272024506 0ustar joeniojoenioclass ShopController { public void main(){ Human owner = new Human(); owner.name = "Robson"; VenderShop vender = new VenderShop(); vender.sellDogTo(owner); } } Analizo-1.25.5/t/samples/deep_inheritance/java/DogFirstGreatGrandson.java0000644000175000017500000000010614676555272025732 0ustar joeniojoenioclass DogFirstGreatGrandson extends DogGrandson { String noses; } Analizo-1.25.5/t/samples/deep_inheritance/java/DogSecondGreatGrandson.java0000644000175000017500000000010614676555272026056 0ustar joeniojoenioclass DogSecondGreatGrandson extends DogGrandson { String arms; } Analizo-1.25.5/t/samples/file_with_two_modules/0000775000175000017500000000000014676555272021060 5ustar joeniojoenioAnalizo-1.25.5/t/samples/file_with_two_modules/cpp/0000775000175000017500000000000014676555272021642 5ustar joeniojoenioAnalizo-1.25.5/t/samples/file_with_two_modules/cpp/main.cc0000644000175000017500000000017014676555272023071 0ustar joeniojoenio#include "classes.h" int main(int argc, char** argv) { Class1 c1; Class2 c2; c1.say(); c2.say(); return 0; } Analizo-1.25.5/t/samples/file_with_two_modules/cpp/Makefile0000644000175000017500000000013314676555272023275 0ustar joeniojoenioall: program program: main.o classes.o $(CXX) -o $@ $^ clean: $(RM) *.o $(RM) program Analizo-1.25.5/t/samples/file_with_two_modules/cpp/classes.h0000644000175000017500000000023114676555272023442 0ustar joeniojoenio#ifndef _CLASSES_H_ #define _CLASSES_H_ class Class1 { public: void say(); }; class Class2 { public: void say(); }; #endif // _CLASSES_H_ Analizo-1.25.5/t/samples/file_with_two_modules/cpp/classes.cc0000644000175000017500000000020714676555272023603 0ustar joeniojoenio#include "classes.h" void Class1::say() { // don't say nothing, actually } void Class2::say() { // don't say nothing, actually } Analizo-1.25.5/t/samples/file_with_two_modules/csharp/0000775000175000017500000000000014676555272022340 5ustar joeniojoenioAnalizo-1.25.5/t/samples/file_with_two_modules/csharp/Classes.cs0000644000175000017500000000032714676555272024264 0ustar joeniojoenionamespace classes { public class Class1 { public void say() { // don't say nothing, actually } } public class Class2 { public void say() { // don't say nothing, actually } } } Analizo-1.25.5/t/samples/file_with_two_modules/csharp/Program.cs0000644000175000017500000000025314676555272024274 0ustar joeniojoeniousing classes; public class Program { static void Main(string[] args) { Class1 c1 = new Class1(); Class2 c2 = new Class2(); c1.say(); c2.say(); } } Analizo-1.25.5/t/samples/mlpack-3.0.0/0000775000175000017500000000000014676555272016370 5ustar joeniojoenioAnalizo-1.25.5/t/samples/mlpack-3.0.0/parse_command_line.hpp0000644000175000017500000001641714676555272022727 0ustar joeniojoenio/* **ANALIZO NOTE** This file was copied here from mlpack project as is just to be used as input on analizo testsuite in order to fix the issue #120. - https://github.com/analizo/analizo/issues/120 mlpack repository: - https://github.com/mlpack/mlpack Original file was copied from the tag mlpack-3.0.0 from mlpack git repository and it is located on the path below. - src/mlpack/bindings/cli/parse_command_line.hpp Link to the original file on GitHub: - https://github.com/mlpack/mlpack/blob/mlpack-3.0.0/src/mlpack/bindings/cli/parse_command_line.hpp See full copyrigth info at: - https://github.com/mlpack/mlpack/blob/mlpack-3.0.0/COPYRIGHT.txt */ /** * @file parse_command_line.hpp * @author Ryan Curtin * @author Matthew Amidon * * Parse the command line options. * * mlpack is free software; you may redistribute it and/or modify it under the * terms of the 3-clause BSD license. You should have received a copy of the * 3-clause BSD license along with mlpack. If not, see * http://www.opensource.org/licenses/BSD-3-Clause for more information. */ #ifndef MLPACK_BINDINGS_CLI_PARSE_COMMAND_LINE_HPP #define MLPACK_BINDINGS_CLI_PARSE_COMMAND_LINE_HPP #include #include #include "print_help.hpp" namespace mlpack { namespace bindings { namespace cli { // Add default parameters that are included in every program. PARAM_FLAG("help", "Default help info.", "h"); PARAM_STRING_IN("info", "Get help on a specific module or option.", "", ""); PARAM_FLAG("verbose", "Display informational messages and the full list of " "parameters and timers at the end of execution.", "v"); PARAM_FLAG("version", "Display the version of mlpack.", "V"); /** * Parse the command line, setting all of the options inside of the CLI object * to their appropriate given values. */ void ParseCommandLine(int argc, char** argv) { // First, we need to build the boost::program_options variables for parsing. using namespace boost::program_options; options_description desc; variables_map vmap; // Go through list of options in order to add them. std::map& parameters = CLI::Parameters(); typedef std::map::const_iterator IteratorType; std::map boostNameMap; for (IteratorType it = parameters.begin(); it != parameters.end(); ++it) { // Add the parameter to desc. const util::ParamData& d = it->second; CLI::GetSingleton().functionMap[d.tname]["AddToPO"](d, NULL, (void*) &desc); // Generate the name the user passes on the command line. std::string boostName; CLI::GetSingleton().functionMap[d.tname]["MapParameterName"](d, NULL, (void*) &boostName); boostNameMap[boostName] = d.name; } // Mark that we did parsing. CLI::GetSingleton().didParse = true; // Parse the command line, then place the values in the right place. try { basic_parsed_options bpo(parse_command_line(argc, argv, desc)); // Iterate over all the options, looking for duplicate parameters. If we // find any, remove the duplicates. Note that vector options can have // duplicates, so we check for those with max_tokens(). for (size_t i = 0; i < bpo.options.size(); ++i) { for (size_t j = i + 1; j < bpo.options.size(); ++j) { if ((bpo.options[i].string_key == bpo.options[j].string_key) && (desc.find(bpo.options[i].string_key, false).semantic()->max_tokens() <= 1)) { // If a duplicate is found, check to see if either one has a value. if (bpo.options[i].value.size() == 0 && bpo.options[j].value.size() == 0) { // If neither has a value, we'll consider it a duplicate flag and // remove the duplicate. It's important to not break out of this // loop because there might be another duplicate later on in the // vector. bpo.options.erase(bpo.options.begin() + j); --j; // Fix the index. } else { // If one or both has a value, produce an error and politely // terminate. We pull the name from the original_tokens, rather // than from the string_key, because the string_key is the parameter // after aliases have been expanded. Log::Fatal << "\"" << bpo.options[j].original_tokens[0] << "\" is " << "defined multiple times." << std::endl; } } } } store(bpo, vmap); } catch (std::exception& ex) { Log::Fatal << "Caught exception from parsing command line: " << ex.what() << std::endl; } // Now iterate through the filled vmap, and overwrite default values with // anything that's found on the command line. for (variables_map::iterator i = vmap.begin(); i != vmap.end(); ++i) { // There is not a possibility of an unknown option, since // boost::program_options would have already thrown an exception. Because // some names may be mapped, we have to look through each ParamData object // and get its boost name. const std::string identifier = boostNameMap[i->first]; util::ParamData& param = parameters[identifier]; param.wasPassed = true; CLI::GetSingleton().functionMap[param.tname]["SetParam"](param, (void*) &vmap[i->first].value(), NULL); } // Flush the buffer, make sure changes are propagated to vmap. notify(vmap); // If the user specified any of the default options (--help, --version, or // --info), handle those. // --version is prioritized over --help. if (CLI::HasParam("version")) { std::cout << CLI::GetSingleton().ProgramName() << ": part of " << util::GetVersion() << "." << std::endl; exit(0); // Don't do anything else. } // Default help message. if (CLI::HasParam("help")) { Log::Info.ignoreInput = false; PrintHelp(); exit(0); // The user doesn't want to run the program, he wants help. } // Info on a specific parameter. if (CLI::HasParam("info")) { Log::Info.ignoreInput = false; std::string str = CLI::GetParam("info"); // The info node should always be there, but the user may not have specified // anything. if (str != "") { PrintHelp(str); exit(0); } // Otherwise just print the generalized help. PrintHelp(); exit(0); } // Print whether or not we have debugging symbols. This won't show anything // if we have not compiled in debugging mode. Log::Debug << "Compiled with debugging symbols." << std::endl; if (CLI::HasParam("verbose")) { // Give [INFO ] output. Log::Info.ignoreInput = false; } // Now, issue an error if we forgot any required options. for (std::map::const_iterator iter = parameters.begin(); iter != parameters.end(); ++iter) { const util::ParamData d = iter->second; if (d.required) { const std::string boostName; CLI::GetSingleton().functionMap[d.tname]["MapParameterName"](d, NULL, (void*) &boostName); if (!vmap.count(boostName)) { Log::Fatal << "Required option --" << boostName << " is undefined." << std::endl; } } } } } // namespace cli } // namespace bindings } // namespace mlpack #endif Analizo-1.25.5/t/samples/multiple_inheritance/0000775000175000017500000000000014676555272020671 5ustar joeniojoenioAnalizo-1.25.5/t/samples/multiple_inheritance/java/0000775000175000017500000000000014676555272021612 5ustar joeniojoenioAnalizo-1.25.5/t/samples/multiple_inheritance/java/Bird.java0000644000175000017500000000016014676555272023330 0ustar joeniojoenioclass Bird extends Animal implements Flying { @Override public void fly() { //Do something useful } } Analizo-1.25.5/t/samples/multiple_inheritance/java/README.md0000644000175000017500000000024514676555272023070 0ustar joeniojoenioThis source-code was inspired by the András Iványi reply on Stack Overflow thread below: * https://stackoverflow.com/questions/21824402/java-multiple-inheritance Analizo-1.25.5/t/samples/multiple_inheritance/java/Horse.java0000644000175000017500000000012014676555272023524 0ustar joeniojoenioclass Horse extends Animal { @Override public void eat() { hp+=2; } } Analizo-1.25.5/t/samples/multiple_inheritance/java/Flying.java0000644000175000017500000000005214676555272023700 0ustar joeniojoeniointerface Flying { public void fly(); } Analizo-1.25.5/t/samples/multiple_inheritance/java/Animal.java0000644000175000017500000000013014676555272023646 0ustar joeniojoenioabstract class Animal { private Integer hp = 0; public void eat() { hp++; } } Analizo-1.25.5/t/samples/multiple_inheritance/java/Pegasus.java0000644000175000017500000000026014676555272024060 0ustar joeniojoenioclass Pegasus extends Horse implements Flying { //now every time when your Pegasus eats, will receive +2 hp @Override public void fly() { //Do something useful } } Analizo-1.25.5/t/samples/android-framework/0000775000175000017500000000000014676555272020100 5ustar joeniojoenioAnalizo-1.25.5/t/samples/android-framework/android-5.1.1_r38/0000775000175000017500000000000014676555272022654 5ustar joeniojoenioAnalizo-1.25.5/t/samples/android-framework/android-5.1.1_r38/LICENSE.TXT0000644000175000017500000000554614676555272024347 0ustar joeniojoenio============================================================================== MCLinker Release License ============================================================================== University of Illinois/NCSA Open Source License Copyright (c) 2011-2013 MediaTek Inc. All rights reserved. Developed by: MCLinker Team. MediaTek Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal with the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimers. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimers in the documentation and/or other materials provided with the distribution. * Neither the names of the LLVM Team, University of Illinois at Urbana-Champaign, nor the names of its contributors may be used to endorse or promote products derived from this Software without specific prior written permission. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE. ============================================================================== Copyrights and Licenses for Third Party Software Distributed with LLVM: ============================================================================== The LLVM software contains code written by third parties. Such software will have its own individual LICENSE.TXT file in the directory in which it appears. This file will describe the copyrights, license, and restrictions which apply to that code. The disclaimer of warranty in the University of Illinois Open Source License applies to all code in the LLVM Distribution, and nothing in any of the other licenses gives permission to use the names of the LLVM Team or the University of Illinois to endorse or promote products derived from this Software. The following pieces of software have additional or alternate copyrights, licenses, and/or restrictions: Program Directory ------- --------- Google Test utils/gtest/ Quake test/Android/Quake/ Quake2 test/Android/Quake2/ Analizo-1.25.5/t/samples/android-framework/android-5.1.1_r38/MCLinker.cpp0000644000175000017500000003661114676555272025031 0ustar joeniojoenio/* **ANALIZO NOTE** This file was copied from The Android Open Source Project for testing analizo features. The original file was copied as-is to create automated tests on analizo side fixing the bug below. - https://github.com/analizo/analizo/issues/110 Android source code repositories: - https://android.googlesource.com/ Original file was copied from the tag android-5.1.1_r38 from Android git repository and it is located on the path below. - lib/CodeGen/MCLinker.cpp Link to the original file on git repository: - https://android.googlesource.com/platform/frameworks/compile/mclinker/+/refs/tags/android-5.1.1_r38/lib/CodeGen/MCLinker.cpp LICENSE: - https://android.googlesource.com/platform/frameworks/compile/mclinker/+/refs/tags/android-5.1.1_r38/LICENSE.TXT */ //===- MCLinker.cpp -------------------------------------------------------===// // // The MCLinker Project // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // This file implements the MCLinker class. // //===----------------------------------------------------------------------===// #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace mcld; using namespace llvm; char MCLinker::m_ID = 0; //===----------------------------------------------------------------------===// // Help Functions //===----------------------------------------------------------------------===// static inline bool CompareAction(const InputAction* X, const InputAction* Y) { return (X->position() < Y->position()); } //===----------------------------------------------------------------------===// // Positional Options // There are four kinds of positional options: // 1. Inputs, object files, such as /tmp/XXXX.o // 2. Namespecs, short names of libraries. A namespec may refer to an archive // or a shared library. For example, -lm. // 3. Attributes of inputs. Attributes describe inputs appears after them. // For example, --as-needed and --whole-archive. // 4. Groups. A Group is a set of archives. Linkers repeatedly read archives // in groups until there is no new undefined symbols. // 5. Bitcode. Bitcode is a kind of object files. MCLinker compiles it to // object file first, then link it as a object file. (Bitcode is recorded // in BitcodeOption, not be read by LLVM Command Line library.) //===----------------------------------------------------------------------===// // Inputs //===----------------------------------------------------------------------===// static cl::list ArgInputObjectFiles(cl::Positional, cl::desc("[input object files]"), cl::ZeroOrMore); //===----------------------------------------------------------------------===// // Namespecs //===----------------------------------------------------------------------===// static cl::list ArgNameSpecList("l", cl::ZeroOrMore, cl::desc("Add the archive or object file specified by namespec to " "the list of files to link."), cl::value_desc("namespec"), cl::Prefix); static cl::alias ArgNameSpecListAlias("library", cl::desc("alias for -l"), cl::aliasopt(ArgNameSpecList)); //===----------------------------------------------------------------------===// // Attributes //===----------------------------------------------------------------------===// static cl::list ArgWholeArchiveList("whole-archive", cl::ValueDisallowed, cl::desc("For each archive mentioned on the command line after " "the --whole-archive option, include all object files " "in the archive.")); static cl::list ArgNoWholeArchiveList("no-whole-archive", cl::ValueDisallowed, cl::desc("Turn off the effect of the --whole-archive option for " "subsequent archive files.")); static cl::list ArgAsNeededList("as-needed", cl::ValueDisallowed, cl::desc("This option affects ELF DT_NEEDED tags for dynamic " "libraries mentioned on the command line after the " "--as-needed option.")); static cl::list ArgNoAsNeededList("no-as-needed", cl::ValueDisallowed, cl::desc("Turn off the effect of the --as-needed option for " "subsequent dynamic libraries")); static cl::list ArgAddNeededList("add-needed", cl::ValueDisallowed, cl::desc("--add-needed causes DT_NEEDED tags are always " "emitted for those libraries from DT_NEEDED tags. " "This is the default behavior.")); static cl::list ArgNoAddNeededList("no-add-needed", cl::ValueDisallowed, cl::desc("--no-add-needed causes DT_NEEDED tags will never be " "emitted for those libraries from DT_NEEDED tags")); static cl::list ArgBDynamicList("Bdynamic", cl::ValueDisallowed, cl::desc("Link against dynamic library")); static cl::alias ArgBDynamicListAlias1("dy", cl::desc("alias for --Bdynamic"), cl::aliasopt(ArgBDynamicList)); static cl::alias ArgBDynamicListAlias2("call_shared", cl::desc("alias for --Bdynamic"), cl::aliasopt(ArgBDynamicList)); static cl::list ArgBStaticList("Bstatic", cl::ValueDisallowed, cl::desc("Link against static library")); static cl::alias ArgBStaticListAlias1("dn", cl::desc("alias for --Bstatic"), cl::aliasopt(ArgBStaticList)); static cl::alias ArgBStaticListAlias2("static", cl::desc("alias for --Bstatic"), cl::aliasopt(ArgBStaticList)); static cl::alias ArgBStaticListAlias3("non_shared", cl::desc("alias for --Bstatic"), cl::aliasopt(ArgBStaticList)); //===----------------------------------------------------------------------===// // Groups //===----------------------------------------------------------------------===// static cl::list ArgStartGroupList("start-group", cl::ValueDisallowed, cl::desc("start to record a group of archives")); static cl::alias ArgStartGroupListAlias("(", cl::desc("alias for --start-group"), cl::aliasopt(ArgStartGroupList)); static cl::list ArgEndGroupList("end-group", cl::ValueDisallowed, cl::desc("stop recording a group of archives")); static cl::alias ArgEndGroupListAlias(")", cl::desc("alias for --end-group"), cl::aliasopt(ArgEndGroupList)); //===----------------------------------------------------------------------===// // --defsym //===----------------------------------------------------------------------===// static cl::list ArgDefSymList("defsym", cl::ZeroOrMore, cl::desc("Define a symbol"), cl::value_desc("symbol=expression")); //===----------------------------------------------------------------------===// // MCLinker //===----------------------------------------------------------------------===// MCLinker::MCLinker(LinkerConfig& pConfig, mcld::Module& pModule, FileHandle& pFileHandle) : MachineFunctionPass(m_ID), m_Config(pConfig), m_Module(pModule), m_FileHandle(pFileHandle), m_pBuilder(NULL), m_pLinker(NULL) { } MCLinker::~MCLinker() { delete m_pLinker; delete m_pBuilder; } bool MCLinker::doInitialization(llvm::Module &pM) { // Now, all input arguments are prepared well, send it into ObjectLinker m_pLinker = new Linker(); if (!m_pLinker->emulate(m_Module.getScript(), m_Config)) return false; m_pBuilder = new IRBuilder(m_Module, m_Config); initializeInputTree(*m_pBuilder); return true; } bool MCLinker::doFinalization(llvm::Module &pM) { if (!m_pLinker->link(m_Module, *m_pBuilder)) return true; if (!m_pLinker->emit(m_Module, m_FileHandle.handler())) return true; return false; } bool MCLinker::runOnMachineFunction(MachineFunction& pF) { // basically, linkers do nothing during function is generated. return false; } void MCLinker::initializeInputTree(IRBuilder& pBuilder) { if (0 == ArgInputObjectFiles.size() && 0 == ArgNameSpecList.size() && !m_Config.bitcode().hasDefined()) { fatal(diag::err_no_inputs); return; } size_t num_actions = ArgInputObjectFiles.size() + ArgNameSpecList.size() + ArgWholeArchiveList.size() + ArgNoWholeArchiveList.size() + ArgAsNeededList.size() + ArgNoAsNeededList.size() + ArgAddNeededList.size() + ArgNoAddNeededList.size() + ArgBDynamicList.size() + ArgBStaticList.size() + ArgStartGroupList.size() + ArgEndGroupList.size() + ArgDefSymList.size() + 1; // bitcode std::vector actions; actions.reserve(num_actions); // ----- scripts ----- // /// -T if (!m_Config.options().getScriptList().empty()) { GeneralOptions::const_script_iterator ii, ie = m_Config.options().script_end(); for (ii = m_Config.options().script_begin(); ii != ie; ++ii) { actions.push_back(new ScriptAction(0x0, *ii, ScriptFile::LDScript, m_Module.getScript().directories())); actions.push_back(new ContextAction(0x0)); actions.push_back(new MemoryAreaAction(0x0, FileHandle::ReadOnly)); } } /// --defsym cl::list::iterator defsym, dsBegin, dsEnd; dsBegin = ArgDefSymList.begin(); dsEnd = ArgDefSymList.end(); for (defsym = dsBegin; defsym != dsEnd; ++defsym) { unsigned int pos = ArgDefSymList.getPosition(defsym - dsBegin); actions.push_back(new DefSymAction(pos, *defsym)); } // ----- inputs ----- // cl::list::iterator input, inBegin, inEnd; inBegin = ArgInputObjectFiles.begin(); inEnd = ArgInputObjectFiles.end(); for (input = inBegin; input != inEnd; ++input) { unsigned int pos = ArgInputObjectFiles.getPosition(input - inBegin); actions.push_back(new InputFileAction(pos, *input)); actions.push_back(new ContextAction(pos)); actions.push_back(new MemoryAreaAction(pos, FileHandle::ReadOnly)); } // ----- namespecs ----- // cl::list::iterator namespec, nsBegin, nsEnd; nsBegin = ArgNameSpecList.begin(); nsEnd = ArgNameSpecList.end(); for (namespec = nsBegin; namespec != nsEnd; ++namespec) { unsigned int pos = ArgNameSpecList.getPosition(namespec - nsBegin); actions.push_back(new NamespecAction(pos, *namespec, m_Module.getScript().directories())); actions.push_back(new ContextAction(pos)); actions.push_back(new MemoryAreaAction(pos, FileHandle::ReadOnly)); } // ----- attributes ----- // /// --whole-archive cl::list::iterator attr, attrBegin, attrEnd; attrBegin = ArgWholeArchiveList.begin(); attrEnd = ArgWholeArchiveList.end(); for (attr = attrBegin; attr != attrEnd; ++attr) { unsigned int pos = ArgWholeArchiveList.getPosition(attr - attrBegin); actions.push_back(new WholeArchiveAction(pos)); } /// --no-whole-archive attrBegin = ArgNoWholeArchiveList.begin(); attrEnd = ArgNoWholeArchiveList.end(); for (attr = attrBegin; attr != attrEnd; ++attr) { unsigned int pos = ArgNoWholeArchiveList.getPosition(attr - attrBegin); actions.push_back(new NoWholeArchiveAction(pos)); } /// --as-needed attrBegin = ArgAsNeededList.begin(); attrEnd = ArgAsNeededList.end(); for (attr = attrBegin; attr != attrEnd; ++attr) { unsigned int pos = ArgAsNeededList.getPosition(attr - attrBegin); actions.push_back(new AsNeededAction(pos)); } /// --no-as-needed attrBegin = ArgNoAsNeededList.begin(); attrEnd = ArgNoAsNeededList.end(); for (attr = attrBegin; attr != attrEnd; ++attr) { unsigned int pos = ArgNoAsNeededList.getPosition(attr - attrBegin); actions.push_back(new NoAsNeededAction(pos)); } /// --add--needed attrBegin = ArgAddNeededList.begin(); attrEnd = ArgAddNeededList.end(); for (attr = attrBegin; attr != attrEnd; ++attr) { unsigned int pos = ArgAddNeededList.getPosition(attr - attrBegin); actions.push_back(new AddNeededAction(pos)); } /// --no-add--needed attrBegin = ArgNoAddNeededList.begin(); attrEnd = ArgNoAddNeededList.end(); for (attr = attrBegin; attr != attrEnd; ++attr) { unsigned int pos = ArgNoAddNeededList.getPosition(attr - attrBegin); actions.push_back(new NoAddNeededAction(pos)); } /// --Bdynamic attrBegin = ArgBDynamicList.begin(); attrEnd = ArgBDynamicList.end(); for (attr = attrBegin; attr != attrEnd; ++attr) { unsigned int pos = ArgBDynamicList.getPosition(attr - attrBegin); actions.push_back(new BDynamicAction(pos)); } /// --Bstatic attrBegin = ArgBStaticList.begin(); attrEnd = ArgBStaticList.end(); for (attr = attrBegin; attr != attrEnd; ++attr) { unsigned int pos = ArgBStaticList.getPosition(attr - attrBegin); actions.push_back(new BStaticAction(pos)); } // ----- groups ----- // /// --start-group cl::list::iterator group, gsBegin, gsEnd; gsBegin = ArgStartGroupList.begin(); gsEnd = ArgStartGroupList.end(); for (group = gsBegin; group != gsEnd; ++group) { unsigned int pos = ArgStartGroupList.getPosition(group - gsBegin); actions.push_back(new StartGroupAction(pos)); } /// --end-group gsBegin = ArgEndGroupList.begin(); gsEnd = ArgEndGroupList.end(); for (group = gsBegin; group != gsEnd; ++group) { unsigned int pos = ArgEndGroupList.getPosition(group - gsBegin); actions.push_back(new EndGroupAction(pos)); } // ----- bitcode ----- // if (m_Config.bitcode().hasDefined()) { actions.push_back(new BitcodeAction(m_Config.bitcode().getPosition(), m_Config.bitcode().getPath())); } // stable sort std::stable_sort(actions.begin(), actions.end(), CompareAction); // build up input tree std::vector::iterator action, actionEnd = actions.end(); for (action = actions.begin(); action != actionEnd; ++action) { (*action)->activate(pBuilder.getInputBuilder()); delete *action; } if (pBuilder.getInputBuilder().isInGroup()) report_fatal_error("no matched --start-group and --end-group"); } Analizo-1.25.5/t/samples/android-framework/android-5.1.1_r38/AudioTrackShared.cpp0000644000175000017500000010330014676555272026530 0ustar joeniojoenio/* **ANALIZO NOTE** This file was copied from The Android Open Source Project for testing analizo features. The original file was copied as-is to create automated tests on analizo side fixing the bug below. - https://github.com/analizo/analizo/issues/112 Android source code repositories: - https://android.googlesource.com/ Original file was copied from the tag android-5.1.1_r38 from Android git repository and it is located on the path below. - media/libmedia/AudioTrackShared.cpp Link to the original file on git repository: - https://android.googlesource.com/platform/frameworks/av/+/refs/tags/android-5.1.1_r38/media/libmedia/AudioTrackShared.cpp */ /* * Copyright (C) 2007 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #define LOG_TAG "AudioTrackShared" //#define LOG_NDEBUG 0 #include #include #include #include namespace android { // used to clamp a value to size_t. TODO: move to another file. template size_t clampToSize(T x) { return x > SIZE_MAX ? SIZE_MAX : x < 0 ? 0 : (size_t) x; } audio_track_cblk_t::audio_track_cblk_t() : mServer(0), mFutex(0), mMinimum(0), mVolumeLR(GAIN_MINIFLOAT_PACKED_UNITY), mSampleRate(0), mSendLevel(0), mFlags(0) { memset(&u, 0, sizeof(u)); } // --------------------------------------------------------------------------- Proxy::Proxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount, size_t frameSize, bool isOut, bool clientInServer) : mCblk(cblk), mBuffers(buffers), mFrameCount(frameCount), mFrameSize(frameSize), mFrameCountP2(roundup(frameCount)), mIsOut(isOut), mClientInServer(clientInServer), mIsShutdown(false), mUnreleased(0) { } // --------------------------------------------------------------------------- ClientProxy::ClientProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount, size_t frameSize, bool isOut, bool clientInServer) : Proxy(cblk, buffers, frameCount, frameSize, isOut, clientInServer), mEpoch(0) { } const struct timespec ClientProxy::kForever = {INT_MAX /*tv_sec*/, 0 /*tv_nsec*/}; const struct timespec ClientProxy::kNonBlocking = {0 /*tv_sec*/, 0 /*tv_nsec*/}; #define MEASURE_NS 10000000 // attempt to provide accurate timeouts if requested >= MEASURE_NS // To facilitate quicker recovery from server failure, this value limits the timeout per each futex // wait. However it does not protect infinite timeouts. If defined to be zero, there is no limit. // FIXME May not be compatible with audio tunneling requirements where timeout should be in the // order of minutes. #define MAX_SEC 5 status_t ClientProxy::obtainBuffer(Buffer* buffer, const struct timespec *requested, struct timespec *elapsed) { LOG_ALWAYS_FATAL_IF(buffer == NULL || buffer->mFrameCount == 0); struct timespec total; // total elapsed time spent waiting total.tv_sec = 0; total.tv_nsec = 0; bool measure = elapsed != NULL; // whether to measure total elapsed time spent waiting status_t status; enum { TIMEOUT_ZERO, // requested == NULL || *requested == 0 TIMEOUT_INFINITE, // *requested == infinity TIMEOUT_FINITE, // 0 < *requested < infinity TIMEOUT_CONTINUE, // additional chances after TIMEOUT_FINITE } timeout; if (requested == NULL) { timeout = TIMEOUT_ZERO; } else if (requested->tv_sec == 0 && requested->tv_nsec == 0) { timeout = TIMEOUT_ZERO; } else if (requested->tv_sec == INT_MAX) { timeout = TIMEOUT_INFINITE; } else { timeout = TIMEOUT_FINITE; if (requested->tv_sec > 0 || requested->tv_nsec >= MEASURE_NS) { measure = true; } } struct timespec before; bool beforeIsValid = false; audio_track_cblk_t* cblk = mCblk; bool ignoreInitialPendingInterrupt = true; // check for shared memory corruption if (mIsShutdown) { status = NO_INIT; goto end; } for (;;) { int32_t flags = android_atomic_and(~CBLK_INTERRUPT, &cblk->mFlags); // check for track invalidation by server, or server death detection if (flags & CBLK_INVALID) { ALOGV("Track invalidated"); status = DEAD_OBJECT; goto end; } // check for obtainBuffer interrupted by client if (!ignoreInitialPendingInterrupt && (flags & CBLK_INTERRUPT)) { ALOGV("obtainBuffer() interrupted by client"); status = -EINTR; goto end; } ignoreInitialPendingInterrupt = false; // compute number of frames available to write (AudioTrack) or read (AudioRecord) int32_t front; int32_t rear; if (mIsOut) { // The barrier following the read of mFront is probably redundant. // We're about to perform a conditional branch based on 'filled', // which will force the processor to observe the read of mFront // prior to allowing data writes starting at mRaw. // However, the processor may support speculative execution, // and be unable to undo speculative writes into shared memory. // The barrier will prevent such speculative execution. front = android_atomic_acquire_load(&cblk->u.mStreaming.mFront); rear = cblk->u.mStreaming.mRear; } else { // On the other hand, this barrier is required. rear = android_atomic_acquire_load(&cblk->u.mStreaming.mRear); front = cblk->u.mStreaming.mFront; } ssize_t filled = rear - front; // pipe should not be overfull if (!(0 <= filled && (size_t) filled <= mFrameCount)) { if (mIsOut) { ALOGE("Shared memory control block is corrupt (filled=%zd, mFrameCount=%zu); " "shutting down", filled, mFrameCount); mIsShutdown = true; status = NO_INIT; goto end; } // for input, sync up on overrun filled = 0; cblk->u.mStreaming.mFront = rear; (void) android_atomic_or(CBLK_OVERRUN, &cblk->mFlags); } // don't allow filling pipe beyond the nominal size size_t avail = mIsOut ? mFrameCount - filled : filled; if (avail > 0) { // 'avail' may be non-contiguous, so return only the first contiguous chunk size_t part1; if (mIsOut) { rear &= mFrameCountP2 - 1; part1 = mFrameCountP2 - rear; } else { front &= mFrameCountP2 - 1; part1 = mFrameCountP2 - front; } if (part1 > avail) { part1 = avail; } if (part1 > buffer->mFrameCount) { part1 = buffer->mFrameCount; } buffer->mFrameCount = part1; buffer->mRaw = part1 > 0 ? &((char *) mBuffers)[(mIsOut ? rear : front) * mFrameSize] : NULL; buffer->mNonContig = avail - part1; mUnreleased = part1; status = NO_ERROR; break; } struct timespec remaining; const struct timespec *ts; switch (timeout) { case TIMEOUT_ZERO: status = WOULD_BLOCK; goto end; case TIMEOUT_INFINITE: ts = NULL; break; case TIMEOUT_FINITE: timeout = TIMEOUT_CONTINUE; if (MAX_SEC == 0) { ts = requested; break; } // fall through case TIMEOUT_CONTINUE: // FIXME we do not retry if requested < 10ms? needs documentation on this state machine if (!measure || requested->tv_sec < total.tv_sec || (requested->tv_sec == total.tv_sec && requested->tv_nsec <= total.tv_nsec)) { status = TIMED_OUT; goto end; } remaining.tv_sec = requested->tv_sec - total.tv_sec; if ((remaining.tv_nsec = requested->tv_nsec - total.tv_nsec) < 0) { remaining.tv_nsec += 1000000000; remaining.tv_sec++; } if (0 < MAX_SEC && MAX_SEC < remaining.tv_sec) { remaining.tv_sec = MAX_SEC; remaining.tv_nsec = 0; } ts = &remaining; break; default: LOG_ALWAYS_FATAL("obtainBuffer() timeout=%d", timeout); ts = NULL; break; } int32_t old = android_atomic_and(~CBLK_FUTEX_WAKE, &cblk->mFutex); if (!(old & CBLK_FUTEX_WAKE)) { if (measure && !beforeIsValid) { clock_gettime(CLOCK_MONOTONIC, &before); beforeIsValid = true; } errno = 0; (void) syscall(__NR_futex, &cblk->mFutex, mClientInServer ? FUTEX_WAIT_PRIVATE : FUTEX_WAIT, old & ~CBLK_FUTEX_WAKE, ts); // update total elapsed time spent waiting if (measure) { struct timespec after; clock_gettime(CLOCK_MONOTONIC, &after); total.tv_sec += after.tv_sec - before.tv_sec; long deltaNs = after.tv_nsec - before.tv_nsec; if (deltaNs < 0) { deltaNs += 1000000000; total.tv_sec--; } if ((total.tv_nsec += deltaNs) >= 1000000000) { total.tv_nsec -= 1000000000; total.tv_sec++; } before = after; beforeIsValid = true; } switch (errno) { case 0: // normal wakeup by server, or by binderDied() case EWOULDBLOCK: // benign race condition with server case EINTR: // wait was interrupted by signal or other spurious wakeup case ETIMEDOUT: // time-out expired // FIXME these error/non-0 status are being dropped break; default: status = errno; ALOGE("%s unexpected error %s", __func__, strerror(status)); goto end; } } } end: if (status != NO_ERROR) { buffer->mFrameCount = 0; buffer->mRaw = NULL; buffer->mNonContig = 0; mUnreleased = 0; } if (elapsed != NULL) { *elapsed = total; } if (requested == NULL) { requested = &kNonBlocking; } if (measure) { ALOGV("requested %ld.%03ld elapsed %ld.%03ld", requested->tv_sec, requested->tv_nsec / 1000000, total.tv_sec, total.tv_nsec / 1000000); } return status; } void ClientProxy::releaseBuffer(Buffer* buffer) { LOG_ALWAYS_FATAL_IF(buffer == NULL); size_t stepCount = buffer->mFrameCount; if (stepCount == 0 || mIsShutdown) { // prevent accidental re-use of buffer buffer->mFrameCount = 0; buffer->mRaw = NULL; buffer->mNonContig = 0; return; } LOG_ALWAYS_FATAL_IF(!(stepCount <= mUnreleased && mUnreleased <= mFrameCount)); mUnreleased -= stepCount; audio_track_cblk_t* cblk = mCblk; // Both of these barriers are required if (mIsOut) { int32_t rear = cblk->u.mStreaming.mRear; android_atomic_release_store(stepCount + rear, &cblk->u.mStreaming.mRear); } else { int32_t front = cblk->u.mStreaming.mFront; android_atomic_release_store(stepCount + front, &cblk->u.mStreaming.mFront); } } void ClientProxy::binderDied() { audio_track_cblk_t* cblk = mCblk; if (!(android_atomic_or(CBLK_INVALID, &cblk->mFlags) & CBLK_INVALID)) { android_atomic_or(CBLK_FUTEX_WAKE, &cblk->mFutex); // it seems that a FUTEX_WAKE_PRIVATE will not wake a FUTEX_WAIT, even within same process (void) syscall(__NR_futex, &cblk->mFutex, mClientInServer ? FUTEX_WAKE_PRIVATE : FUTEX_WAKE, 1); } } void ClientProxy::interrupt() { audio_track_cblk_t* cblk = mCblk; if (!(android_atomic_or(CBLK_INTERRUPT, &cblk->mFlags) & CBLK_INTERRUPT)) { android_atomic_or(CBLK_FUTEX_WAKE, &cblk->mFutex); (void) syscall(__NR_futex, &cblk->mFutex, mClientInServer ? FUTEX_WAKE_PRIVATE : FUTEX_WAKE, 1); } } size_t ClientProxy::getMisalignment() { audio_track_cblk_t* cblk = mCblk; return (mFrameCountP2 - (mIsOut ? cblk->u.mStreaming.mRear : cblk->u.mStreaming.mFront)) & (mFrameCountP2 - 1); } size_t ClientProxy::getFramesFilled() { audio_track_cblk_t* cblk = mCblk; int32_t front; int32_t rear; if (mIsOut) { front = android_atomic_acquire_load(&cblk->u.mStreaming.mFront); rear = cblk->u.mStreaming.mRear; } else { rear = android_atomic_acquire_load(&cblk->u.mStreaming.mRear); front = cblk->u.mStreaming.mFront; } ssize_t filled = rear - front; // pipe should not be overfull if (!(0 <= filled && (size_t) filled <= mFrameCount)) { ALOGE("Shared memory control block is corrupt (filled=%zd); shutting down", filled); return 0; } return (size_t)filled; } // --------------------------------------------------------------------------- void AudioTrackClientProxy::flush() { // This works for mFrameCountP2 <= 2^30 size_t increment = mFrameCountP2 << 1; size_t mask = increment - 1; audio_track_cblk_t* cblk = mCblk; int32_t newFlush = (cblk->u.mStreaming.mRear & mask) | ((cblk->u.mStreaming.mFlush & ~mask) + increment); android_atomic_release_store(newFlush, &cblk->u.mStreaming.mFlush); } bool AudioTrackClientProxy::clearStreamEndDone() { return (android_atomic_and(~CBLK_STREAM_END_DONE, &mCblk->mFlags) & CBLK_STREAM_END_DONE) != 0; } bool AudioTrackClientProxy::getStreamEndDone() const { return (mCblk->mFlags & CBLK_STREAM_END_DONE) != 0; } status_t AudioTrackClientProxy::waitStreamEndDone(const struct timespec *requested) { struct timespec total; // total elapsed time spent waiting total.tv_sec = 0; total.tv_nsec = 0; audio_track_cblk_t* cblk = mCblk; status_t status; enum { TIMEOUT_ZERO, // requested == NULL || *requested == 0 TIMEOUT_INFINITE, // *requested == infinity TIMEOUT_FINITE, // 0 < *requested < infinity TIMEOUT_CONTINUE, // additional chances after TIMEOUT_FINITE } timeout; if (requested == NULL) { timeout = TIMEOUT_ZERO; } else if (requested->tv_sec == 0 && requested->tv_nsec == 0) { timeout = TIMEOUT_ZERO; } else if (requested->tv_sec == INT_MAX) { timeout = TIMEOUT_INFINITE; } else { timeout = TIMEOUT_FINITE; } for (;;) { int32_t flags = android_atomic_and(~(CBLK_INTERRUPT|CBLK_STREAM_END_DONE), &cblk->mFlags); // check for track invalidation by server, or server death detection if (flags & CBLK_INVALID) { ALOGV("Track invalidated"); status = DEAD_OBJECT; goto end; } if (flags & CBLK_STREAM_END_DONE) { ALOGV("stream end received"); status = NO_ERROR; goto end; } // check for obtainBuffer interrupted by client // check for obtainBuffer interrupted by client if (flags & CBLK_INTERRUPT) { ALOGV("waitStreamEndDone() interrupted by client"); status = -EINTR; goto end; } struct timespec remaining; const struct timespec *ts; switch (timeout) { case TIMEOUT_ZERO: status = WOULD_BLOCK; goto end; case TIMEOUT_INFINITE: ts = NULL; break; case TIMEOUT_FINITE: timeout = TIMEOUT_CONTINUE; if (MAX_SEC == 0) { ts = requested; break; } // fall through case TIMEOUT_CONTINUE: // FIXME we do not retry if requested < 10ms? needs documentation on this state machine if (requested->tv_sec < total.tv_sec || (requested->tv_sec == total.tv_sec && requested->tv_nsec <= total.tv_nsec)) { status = TIMED_OUT; goto end; } remaining.tv_sec = requested->tv_sec - total.tv_sec; if ((remaining.tv_nsec = requested->tv_nsec - total.tv_nsec) < 0) { remaining.tv_nsec += 1000000000; remaining.tv_sec++; } if (0 < MAX_SEC && MAX_SEC < remaining.tv_sec) { remaining.tv_sec = MAX_SEC; remaining.tv_nsec = 0; } ts = &remaining; break; default: LOG_ALWAYS_FATAL("waitStreamEndDone() timeout=%d", timeout); ts = NULL; break; } int32_t old = android_atomic_and(~CBLK_FUTEX_WAKE, &cblk->mFutex); if (!(old & CBLK_FUTEX_WAKE)) { errno = 0; (void) syscall(__NR_futex, &cblk->mFutex, mClientInServer ? FUTEX_WAIT_PRIVATE : FUTEX_WAIT, old & ~CBLK_FUTEX_WAKE, ts); switch (errno) { case 0: // normal wakeup by server, or by binderDied() case EWOULDBLOCK: // benign race condition with server case EINTR: // wait was interrupted by signal or other spurious wakeup case ETIMEDOUT: // time-out expired break; default: status = errno; ALOGE("%s unexpected error %s", __func__, strerror(status)); goto end; } } } end: if (requested == NULL) { requested = &kNonBlocking; } return status; } // --------------------------------------------------------------------------- StaticAudioTrackClientProxy::StaticAudioTrackClientProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount, size_t frameSize) : AudioTrackClientProxy(cblk, buffers, frameCount, frameSize), mMutator(&cblk->u.mStatic.mSingleStateQueue), mBufferPosition(0) { } void StaticAudioTrackClientProxy::flush() { LOG_ALWAYS_FATAL("static flush"); } void StaticAudioTrackClientProxy::setLoop(size_t loopStart, size_t loopEnd, int loopCount) { // This can only happen on a 64-bit client if (loopStart > UINT32_MAX || loopEnd > UINT32_MAX) { // FIXME Should return an error status return; } StaticAudioTrackState newState; newState.mLoopStart = (uint32_t) loopStart; newState.mLoopEnd = (uint32_t) loopEnd; newState.mLoopCount = loopCount; size_t bufferPosition; if (loopCount == 0 || (bufferPosition = getBufferPosition()) >= loopEnd) { bufferPosition = loopStart; } mBufferPosition = bufferPosition; // snapshot buffer position until loop is acknowledged. (void) mMutator.push(newState); } size_t StaticAudioTrackClientProxy::getBufferPosition() { size_t bufferPosition; if (mMutator.ack()) { bufferPosition = (size_t) mCblk->u.mStatic.mBufferPosition; if (bufferPosition > mFrameCount) { bufferPosition = mFrameCount; } } else { bufferPosition = mBufferPosition; } return bufferPosition; } // --------------------------------------------------------------------------- ServerProxy::ServerProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount, size_t frameSize, bool isOut, bool clientInServer) : Proxy(cblk, buffers, frameCount, frameSize, isOut, clientInServer), mAvailToClient(0), mFlush(0) { } status_t ServerProxy::obtainBuffer(Buffer* buffer, bool ackFlush) { LOG_ALWAYS_FATAL_IF(buffer == NULL || buffer->mFrameCount == 0); if (mIsShutdown) { goto no_init; } { audio_track_cblk_t* cblk = mCblk; // compute number of frames available to write (AudioTrack) or read (AudioRecord), // or use previous cached value from framesReady(), with added barrier if it omits. int32_t front; int32_t rear; // See notes on barriers at ClientProxy::obtainBuffer() if (mIsOut) { int32_t flush = cblk->u.mStreaming.mFlush; rear = android_atomic_acquire_load(&cblk->u.mStreaming.mRear); front = cblk->u.mStreaming.mFront; if (flush != mFlush) { // effectively obtain then release whatever is in the buffer size_t mask = (mFrameCountP2 << 1) - 1; int32_t newFront = (front & ~mask) | (flush & mask); ssize_t filled = rear - newFront; // Rather than shutting down on a corrupt flush, just treat it as a full flush if (!(0 <= filled && (size_t) filled <= mFrameCount)) { ALOGE("mFlush %#x -> %#x, front %#x, rear %#x, mask %#x, newFront %#x, filled %d=%#x", mFlush, flush, front, rear, mask, newFront, filled, filled); newFront = rear; } mFlush = flush; android_atomic_release_store(newFront, &cblk->u.mStreaming.mFront); // There is no danger from a false positive, so err on the side of caution if (true /*front != newFront*/) { int32_t old = android_atomic_or(CBLK_FUTEX_WAKE, &cblk->mFutex); if (!(old & CBLK_FUTEX_WAKE)) { (void) syscall(__NR_futex, &cblk->mFutex, mClientInServer ? FUTEX_WAKE_PRIVATE : FUTEX_WAKE, 1); } } front = newFront; } } else { front = android_atomic_acquire_load(&cblk->u.mStreaming.mFront); rear = cblk->u.mStreaming.mRear; } ssize_t filled = rear - front; // pipe should not already be overfull if (!(0 <= filled && (size_t) filled <= mFrameCount)) { ALOGE("Shared memory control block is corrupt (filled=%zd); shutting down", filled); mIsShutdown = true; } if (mIsShutdown) { goto no_init; } // don't allow filling pipe beyond the nominal size size_t availToServer; if (mIsOut) { availToServer = filled; mAvailToClient = mFrameCount - filled; } else { availToServer = mFrameCount - filled; mAvailToClient = filled; } // 'availToServer' may be non-contiguous, so return only the first contiguous chunk size_t part1; if (mIsOut) { front &= mFrameCountP2 - 1; part1 = mFrameCountP2 - front; } else { rear &= mFrameCountP2 - 1; part1 = mFrameCountP2 - rear; } if (part1 > availToServer) { part1 = availToServer; } size_t ask = buffer->mFrameCount; if (part1 > ask) { part1 = ask; } // is assignment redundant in some cases? buffer->mFrameCount = part1; buffer->mRaw = part1 > 0 ? &((char *) mBuffers)[(mIsOut ? front : rear) * mFrameSize] : NULL; buffer->mNonContig = availToServer - part1; // After flush(), allow releaseBuffer() on a previously obtained buffer; // see "Acknowledge any pending flush()" in audioflinger/Tracks.cpp. if (!ackFlush) { mUnreleased = part1; } return part1 > 0 ? NO_ERROR : WOULD_BLOCK; } no_init: buffer->mFrameCount = 0; buffer->mRaw = NULL; buffer->mNonContig = 0; mUnreleased = 0; return NO_INIT; } void ServerProxy::releaseBuffer(Buffer* buffer) { LOG_ALWAYS_FATAL_IF(buffer == NULL); size_t stepCount = buffer->mFrameCount; if (stepCount == 0 || mIsShutdown) { // prevent accidental re-use of buffer buffer->mFrameCount = 0; buffer->mRaw = NULL; buffer->mNonContig = 0; return; } LOG_ALWAYS_FATAL_IF(!(stepCount <= mUnreleased && mUnreleased <= mFrameCount)); mUnreleased -= stepCount; audio_track_cblk_t* cblk = mCblk; if (mIsOut) { int32_t front = cblk->u.mStreaming.mFront; android_atomic_release_store(stepCount + front, &cblk->u.mStreaming.mFront); } else { int32_t rear = cblk->u.mStreaming.mRear; android_atomic_release_store(stepCount + rear, &cblk->u.mStreaming.mRear); } cblk->mServer += stepCount; size_t half = mFrameCount / 2; if (half == 0) { half = 1; } size_t minimum = (size_t) cblk->mMinimum; if (minimum == 0) { minimum = mIsOut ? half : 1; } else if (minimum > half) { minimum = half; } // FIXME AudioRecord wakeup needs to be optimized; it currently wakes up client every time if (!mIsOut || (mAvailToClient + stepCount >= minimum)) { ALOGV("mAvailToClient=%zu stepCount=%zu minimum=%zu", mAvailToClient, stepCount, minimum); int32_t old = android_atomic_or(CBLK_FUTEX_WAKE, &cblk->mFutex); if (!(old & CBLK_FUTEX_WAKE)) { (void) syscall(__NR_futex, &cblk->mFutex, mClientInServer ? FUTEX_WAKE_PRIVATE : FUTEX_WAKE, 1); } } buffer->mFrameCount = 0; buffer->mRaw = NULL; buffer->mNonContig = 0; } // --------------------------------------------------------------------------- size_t AudioTrackServerProxy::framesReady() { LOG_ALWAYS_FATAL_IF(!mIsOut); if (mIsShutdown) { return 0; } audio_track_cblk_t* cblk = mCblk; int32_t flush = cblk->u.mStreaming.mFlush; if (flush != mFlush) { // FIXME should return an accurate value, but over-estimate is better than under-estimate return mFrameCount; } // the acquire might not be necessary since not doing a subsequent read int32_t rear = android_atomic_acquire_load(&cblk->u.mStreaming.mRear); ssize_t filled = rear - cblk->u.mStreaming.mFront; // pipe should not already be overfull if (!(0 <= filled && (size_t) filled <= mFrameCount)) { ALOGE("Shared memory control block is corrupt (filled=%zd); shutting down", filled); mIsShutdown = true; return 0; } // cache this value for later use by obtainBuffer(), with added barrier // and racy if called by normal mixer thread // ignores flush(), so framesReady() may report a larger mFrameCount than obtainBuffer() return filled; } bool AudioTrackServerProxy::setStreamEndDone() { audio_track_cblk_t* cblk = mCblk; bool old = (android_atomic_or(CBLK_STREAM_END_DONE, &cblk->mFlags) & CBLK_STREAM_END_DONE) != 0; if (!old) { (void) syscall(__NR_futex, &cblk->mFutex, mClientInServer ? FUTEX_WAKE_PRIVATE : FUTEX_WAKE, 1); } return old; } void AudioTrackServerProxy::tallyUnderrunFrames(uint32_t frameCount) { audio_track_cblk_t* cblk = mCblk; cblk->u.mStreaming.mUnderrunFrames += frameCount; // FIXME also wake futex so that underrun is noticed more quickly (void) android_atomic_or(CBLK_UNDERRUN, &cblk->mFlags); } // --------------------------------------------------------------------------- StaticAudioTrackServerProxy::StaticAudioTrackServerProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount, size_t frameSize) : AudioTrackServerProxy(cblk, buffers, frameCount, frameSize), mObserver(&cblk->u.mStatic.mSingleStateQueue), mPosition(0), mFramesReadySafe(frameCount), mFramesReady(frameCount), mFramesReadyIsCalledByMultipleThreads(false) { mState.mLoopStart = 0; mState.mLoopEnd = 0; mState.mLoopCount = 0; } void StaticAudioTrackServerProxy::framesReadyIsCalledByMultipleThreads() { mFramesReadyIsCalledByMultipleThreads = true; } size_t StaticAudioTrackServerProxy::framesReady() { // Can't call pollPosition() from multiple threads. if (!mFramesReadyIsCalledByMultipleThreads) { (void) pollPosition(); } return mFramesReadySafe; } ssize_t StaticAudioTrackServerProxy::pollPosition() { size_t position = mPosition; StaticAudioTrackState state; if (mObserver.poll(state)) { bool valid = false; size_t loopStart = state.mLoopStart; size_t loopEnd = state.mLoopEnd; if (state.mLoopCount == 0) { if (loopStart > mFrameCount) { loopStart = mFrameCount; } // ignore loopEnd mPosition = position = loopStart; mFramesReady = mFrameCount - mPosition; mState.mLoopCount = 0; valid = true; } else if (state.mLoopCount >= -1) { if (loopStart < loopEnd && loopEnd <= mFrameCount && loopEnd - loopStart >= MIN_LOOP) { // If the current position is greater than the end of the loop // we "wrap" to the loop start. This might cause an audible pop. if (position >= loopEnd) { mPosition = position = loopStart; } if (state.mLoopCount == -1) { mFramesReady = INT64_MAX; } else { // mFramesReady is 64 bits to handle the effective number of frames // that the static audio track contains, including loops. // TODO: Later consider fixing overflow, but does not seem needed now // as will not overflow if loopStart and loopEnd are Java "ints". mFramesReady = int64_t(state.mLoopCount) * (loopEnd - loopStart) + mFrameCount - mPosition; } mState = state; valid = true; } } if (!valid || mPosition > mFrameCount) { ALOGE("%s client pushed an invalid state, shutting down", __func__); mIsShutdown = true; return (ssize_t) NO_INIT; } mFramesReadySafe = clampToSize(mFramesReady); // This may overflow, but client is not supposed to rely on it mCblk->u.mStatic.mBufferPosition = (uint32_t) position; } return (ssize_t) position; } status_t StaticAudioTrackServerProxy::obtainBuffer(Buffer* buffer, bool ackFlush __unused) { if (mIsShutdown) { buffer->mFrameCount = 0; buffer->mRaw = NULL; buffer->mNonContig = 0; mUnreleased = 0; return NO_INIT; } ssize_t positionOrStatus = pollPosition(); if (positionOrStatus < 0) { buffer->mFrameCount = 0; buffer->mRaw = NULL; buffer->mNonContig = 0; mUnreleased = 0; return (status_t) positionOrStatus; } size_t position = (size_t) positionOrStatus; size_t end = mState.mLoopCount != 0 ? mState.mLoopEnd : mFrameCount; size_t avail; if (position < end) { avail = end - position; size_t wanted = buffer->mFrameCount; if (avail < wanted) { buffer->mFrameCount = avail; } else { avail = wanted; } buffer->mRaw = &((char *) mBuffers)[position * mFrameSize]; } else { avail = 0; buffer->mFrameCount = 0; buffer->mRaw = NULL; } // As mFramesReady is the total remaining frames in the static audio track, // it is always larger or equal to avail. LOG_ALWAYS_FATAL_IF(mFramesReady < avail); buffer->mNonContig = mFramesReady == INT64_MAX ? SIZE_MAX : clampToSize(mFramesReady - avail); mUnreleased = avail; return NO_ERROR; } void StaticAudioTrackServerProxy::releaseBuffer(Buffer* buffer) { size_t stepCount = buffer->mFrameCount; LOG_ALWAYS_FATAL_IF(!(stepCount <= mFramesReady)); LOG_ALWAYS_FATAL_IF(!(stepCount <= mUnreleased)); if (stepCount == 0) { // prevent accidental re-use of buffer buffer->mRaw = NULL; buffer->mNonContig = 0; return; } mUnreleased -= stepCount; audio_track_cblk_t* cblk = mCblk; size_t position = mPosition; size_t newPosition = position + stepCount; int32_t setFlags = 0; if (!(position <= newPosition && newPosition <= mFrameCount)) { ALOGW("%s newPosition %zu outside [%zu, %zu]", __func__, newPosition, position, mFrameCount); newPosition = mFrameCount; } else if (mState.mLoopCount != 0 && newPosition == mState.mLoopEnd) { newPosition = mState.mLoopStart; if (mState.mLoopCount == -1 || --mState.mLoopCount != 0) { setFlags = CBLK_LOOP_CYCLE; } else { setFlags = CBLK_LOOP_FINAL; } } if (newPosition == mFrameCount) { setFlags |= CBLK_BUFFER_END; } mPosition = newPosition; if (mFramesReady != INT64_MAX) { mFramesReady -= stepCount; } mFramesReadySafe = clampToSize(mFramesReady); cblk->mServer += stepCount; // This may overflow, but client is not supposed to rely on it cblk->u.mStatic.mBufferPosition = (uint32_t) newPosition; if (setFlags != 0) { (void) android_atomic_or(setFlags, &cblk->mFlags); // this would be a good place to wake a futex } buffer->mFrameCount = 0; buffer->mRaw = NULL; buffer->mNonContig = 0; } void StaticAudioTrackServerProxy::tallyUnderrunFrames(uint32_t frameCount __unused) { // Unlike AudioTrackServerProxy::tallyUnderrunFrames() used for streaming tracks, // we don't have a location to count underrun frames. The underrun frame counter // only exists in AudioTrackSharedStreaming. Fortunately, underruns are not // possible for static buffer tracks other than at end of buffer, so this is not a loss. // FIXME also wake futex so that underrun is noticed more quickly (void) android_atomic_or(CBLK_UNDERRUN, &mCblk->mFlags); } // --------------------------------------------------------------------------- } // namespace android Analizo-1.25.5/t/author-pod-syntax.t0000644000175000017500000000045414676555272016615 0ustar joeniojoenio#!perl BEGIN { unless ($ENV{AUTHOR_TESTING}) { print qq{1..0 # SKIP these tests are for testing by the author\n}; exit } } # This file was automatically generated by Dist::Zilla::Plugin::PodSyntaxTests. use strict; use warnings; use Test::More; use Test::Pod 1.41; all_pod_files_ok(); Analizo-1.25.5/t/features/0000775000175000017500000000000014676555272014637 5ustar joeniojoenioAnalizo-1.25.5/t/features/exclude.feature0000644000175000017500000000222614676555272017645 0ustar joeniojoenioFeature: exclude directories from the analysis As a software developer in a large project I want to exclude some directories from the source code analysis In order to not analyse non-production code such as tests Scenario: excluding test directory Given I am in t/samples/multidir/ When I run "analizo metrics --exclude test ." Then the output must match "module: HelloWorld" And the output must not match "module: hello_test" Examples: | language | | cpp | | csharp | Scenario: excluding a list of directories Given I am in t/samples/multidir/ When I run "analizo metrics --exclude test:src ." Then the output must not match "module: HelloWorld" And the output must not match "module: hello_test" Examples: | language | | cpp | | csharp | Scenario: excluding src directory Given I am in t/samples/multidir/ When I run "analizo metrics --exclude src ." Then the output must match "module: hello_test" And the output must not match "module: HelloWorld" Examples: | language | | cpp | | csharp | Analizo-1.25.5/t/features/wrapper.feature0000644000175000017500000000177714676555272017706 0ustar joeniojoenioFeature: analizo wrapper script Scenario: invoking a tool When I run "analizo metrics lib t" Then analizo must emit a warning matching "Usage:" And analizo must emit a warning matching "analizo.metrics" And the exit status must not be 0 Scenario: must not pass --version ahead When I run "analizo metrics --version" Then analizo must emit a warning matching "Invalid option: --version" And the exit status must not be 0 Scenario: display help When I run "analizo --help" Then the output must match "[NAME|N^HNA^HAM^HME^HE]\\s+analizo\\s" And the output must match "[USAGE|U^HUS^HSA^HAG^HGE^HE]\\s+analizo\\s" And the exit status must be 0 Scenario: display version When I run "analizo --version" Then the output must match "^analizo version [0-9]+.[0-9]+.[0-9]+" And the exit status must be 0 Scenario: invalid option When I run "analizo --invalid-option" Then the output must match "Unrecognized command" And the exit status must not be 0 Analizo-1.25.5/t/features/doxyparse.feature0000644000175000017500000000277414676555272020242 0ustar joeniojoenioFeature: doxyparse extractor external tool As a Analizo developer I want to guarantee that doxyparse deal with any source code To provide reliability for Analizo users Scenario: don't die parsing MCLinker.cpp from android 5.1.1 Given I am in t/samples/android-framework/android-5.1.1_r38 When I run "analizo metrics ." Then the exit status must be 0 Scenario: don't duplicate YAML keys parsing AudioTrackShared.cpp from android 5.1.1 Given I am in t/samples/android-framework/android-5.1.1_r38 When I run "analizo metrics ." Then analizo must not emit a warning matching "YAML_LOAD_WARN_DUPLICATE_KEY" Scenario: don't abort parsing mlpack 3.0.0 Given I am in t/samples/mlpack-3.0.0 When I run "analizo metrics ." Then analizo must not emit a warning matching "Aborted" And the exit status must be 0 Scenario: don't die parsing kdelibs warning about unknown escape character Given I am in t/samples/kdelibs When I run "analizo metrics ." Then analizo must not emit a warning matching "Error" And the exit status must be 0 Scenario: don't die parsing mod_suexec.h from http 2.4.38 Given I am in t/samples/httpd-2.4.38 When I run "analizo metrics ." Then analizo must not emit a warning matching "Not a HASH reference" And the exit status must be 0 Scenario: allow dot on module filename Given I am in t/samples/sample_basic/c When I run "analizo metrics ." Then analizo must report that file module1.c declares module module1 Analizo-1.25.5/t/features/graph/0000775000175000017500000000000014676555272015740 5ustar joeniojoenioAnalizo-1.25.5/t/features/graph/omit.feature0000644000175000017500000000126614676555272020270 0ustar joeniojoenioFeature: omitting certain modules Scenario: omitting say_bye Given I am in t/samples/sample_basic/ When I run "analizo graph --omit 'module2::say_bye()' ." Then the output must not match "module2::say_bye()" Scenario: omitting two functions Given I am in t/samples/sample_basic/ When I run "analizo graph --omit 'module2::say_bye()','module2::say_hello()' ." Then the output must not match "module2::say_bye()" Then the output must not match "module2::say_hello()" Scenario: omitting depending functions Given I am in t/samples/sample_basic/ When I run "analizo graph --omit 'module1::main()' ." Then the output must not match "module1::main()" Analizo-1.25.5/t/features/graph/help.feature0000644000175000017500000000030214676555272020236 0ustar joeniojoenioFeature: displaying version Scenario: running without any arguments When I run "analizo graph" Then analizo must emit a warning matching "Usage:" And the exit status must not be 0 Analizo-1.25.5/t/features/graph/plain.feature0000644000175000017500000000100714676555272020414 0ustar joeniojoenioFeature: plain analizo graph run Scenario: simply running analizo Given I am in t/samples/sample_basic/c/ When I run "analizo graph ." Then analizo must report that "module1::main()" depends on "module3::variable" Then analizo must report that "module1::main()" depends on "module3::callback()" Then analizo must report that "module1::main()" depends on "module2::say_bye()" Then analizo must report that "module1::main()" depends on "module2::say_hello()" And the exit status must be 0 Analizo-1.25.5/t/features/graph/modules.feature0000644000175000017500000000041614676555272020764 0ustar joeniojoenioFeature: group by modules Scenario: sample project Given I am in t/samples/sample_basic/c/ When I run "analizo graph --modules ." Then analizo must report that "module1" depends on "module2" Then analizo must report that "module1" depends on "module3" Analizo-1.25.5/t/features/graph/cluster.feature0000644000175000017500000000106314676555272020774 0ustar joeniojoenioFeature: clustering subroutines in the same module together Scenario: clustering dependencies Given I am in t/samples/sample_basic/c/ When I run "analizo graph --cluster ." Then analizo must report that "module1::main()" is part of "module1" Then analizo must report that "module2::say_hello()" is part of "module2" Then analizo must report that "module2::say_bye()" is part of "module2" Then analizo must report that "module3::variable" is part of "module3" Then analizo must report that "module3::callback()" is part of "module3" Analizo-1.25.5/t/features/graph/functions.feature0000644000175000017500000000052314676555272021323 0ustar joeniojoenioFeature: functions calls Scenario: detect function calls among classes Given I am in t/samples/animals/cpp When I run "analizo graph ." Then analizo must report that "Cat::Cat(char *)" depends on "Cat::_name" And analizo must not report that "Cat::Cat(char *)" depends on "Cat::name()" And the exit status must be 0 Analizo-1.25.5/t/features/graph/output-file.feature0000644000175000017500000000163014676555272021570 0ustar joeniojoenioFeature: output file for graph tool Scenario: passing output file in the command line Given I am in . When I run "analizo graph --output output.dot.tmp t/samples/sample_basic/c/" Then the contents of "output.dot.tmp" must match "module1" And the exit status must be 0 Scenario: passing output file in an unexisting directory Given I am in . When I run "analizo graph --output /this/directory/must/not/exists/output.dot t/samples/sample_basic/c/" Then analizo must emit a warning matching "No such file or directory" And the exit status must not be 0 Scenario: passing output file without permission to write Given I am in . When I run "touch output.tmp" And I run "chmod 000 output.tmp" And I run "analizo graph --output output.tmp t/samples/sample_basic/c/" Then the exit status must not be 0 And analizo must emit a warning matching "Permission denied" Analizo-1.25.5/t/features/graph/input-files.feature0000644000175000017500000000077014676555272021556 0ustar joeniojoenioFeature: input files for graph tool Scenario: passing specific files in the command line Given I am in t/samples/sample_basic/c When I run "analizo graph module1.c module2.c" Then the output must match "module1" And the output must match "module2" And the output must not match "module3" Scenario: passing unexisting file Given I am in t/samples/sample_basic/c When I run "analizo graph unexisting-file.c" Then analizo must emit a warning matching "is not readable" Analizo-1.25.5/t/features/dot-analizo.feature0000644000175000017500000000215414676555272020435 0ustar joeniojoenioFeature: loading command line options from .analizo As a analizo user I want to store command line options in a file called .analizo inside my project So that I don't need to alway pass all those options on the command line Scenario: analizo metrics Given I copy t/samples/mixed into a temporary directory And I create a file called .analizo with the following content """ metrics: --language java """ When I run "analizo metrics ." Then the output must not match "native_backend.c" And the output must match "UI.java" And the exit status must be 0 Scenario: all others Given I change to an empty temporary directory And I create a file called .analizo with the following content """ : --help """ When I run "analizo " Then the output must match "analizo is part of the analizo suite." Examples: | command | | graph | | metrics | | metrics-batch | | metrics-history | | tree-evolution | | files-graph | | help | Analizo-1.25.5/t/features/files_graph.feature0000644000175000017500000000215414676555272020477 0ustar joeniojoenioFeature: dependency graph among files As a software engineering reasearcher I want to know the all relationships between all files on project So that I can run analizo files-graph to produces a DOT graph from source-code Scenario: relation between function call Given I am in t/samples/animals/ When I run "analizo files-graph ." Then analizo must report that "" depends on "" Examples: | language | referent | referenced | | cpp | main | animal | | java | Main | Animal | | csharp | Main | Animal | Scenario: relation between inheritance Given I am in t/samples/animals/ When I run "analizo files-graph ." Then analizo must report that "" depends on "" Examples: | language | referent | referenced | | cpp | dog | mammal | | java | Dog | Mammal | | csharp | Dog | Mammal | | cpp | mammal | animal | | java | Mammal | Animal | | csharp | Mammal | Animal | Analizo-1.25.5/t/features/metrics/0000775000175000017500000000000014676555272016305 5ustar joeniojoenioAnalizo-1.25.5/t/features/metrics/list.feature0000644000175000017500000000057114676555272020636 0ustar joeniojoenioFeature: list metrics As a Research or Practioner I want to extract metrics from source code So that I can learn, understand and evaluate it Scenario: listing metrics When I run "analizo metrics --list" Then analizo must present a list of metrics Scenario: listing metrics When I run "analizo metrics -l" Then analizo must present a list of metrics Analizo-1.25.5/t/features/metrics/change_cost.feature0000644000175000017500000000260014676555272022133 0ustar joeniojoenioFeature: change cost degree As a software developer I want analizo to report the degree of change cost in my code So that I can evaluate it Scenario: "Hello, world" project Given I am in t/samples/hello_world/ When I run "analizo metrics ." Then analizo must report that the project has change_cost = 0.75 Examples: | language | | cpp | | java | | csharp | Scenario: "Animals" project Given I am in t/samples/animals/ When I run "analizo metrics ." Then analizo must report that the project has change_cost = Examples: | language | change_cost | | cpp | 0.44 | | java | 0.44 | | csharp | 0.44 | Scenario: "Hieracchical Graph" project Given I am in t/samples/hierarchical_graph/ When I run "analizo metrics ." Then analizo must report that the project has change_cost = Examples: | language | change_cost | | c | 0.42 | | csharp | 0.28 | Scenario: "Cyclical Graph" project Given I am in t/samples/cyclical_graph/ When I run "analizo metrics ." Then analizo must report that the project has change_cost = Examples: | language | change_cost | | c | 0.5 | | csharp | 0.36 | Analizo-1.25.5/t/features/metrics/global_only.feature0000644000175000017500000000101014676555272022151 0ustar joeniojoenioFeature: output only global metrics As a researcher I want to ouput only the global metrics So that I can evaluate several projects at once Background: Given I am in t/samples/sample_basic/c/ Scenario: simple case When I run "analizo metrics --global-only ." Then the output must match "cbo_mean:" And the output must not match "_module:" Scenario: short version When I run "analizo metrics -g ." Then the output must match "cbo_mean:" And the output must not match "_module:" Analizo-1.25.5/t/features/metrics/output_file.feature0000644000175000017500000000161414676555272022221 0ustar joeniojoenioFeature: output file for metrics tool Scenario: passing output file in the command line Given I am in . When I run "analizo metrics --output output.yml.tmp t/samples/sample_basic/" Then the contents of "output.yml.tmp" must match "module2" And the exit status must be 0 Scenario: passing output file without permission to write Given I am in . When I run "touch output.tmp" And I run "chmod 000 output.tmp" And I run "analizo metrics --output output.tmp t/samples/sample_basic/" Then the exit status must not be 0 And analizo must emit a warning matching "Permission denied" Scenario: passing output file in an unexisting directory Given I am in . When I run "analizo metrics --output /this/directory/must/not/exists/output.yml t/samples" Then the exit status must not be 0 And analizo must emit a warning matching "No such file or directory" Analizo-1.25.5/t/features/metrics/total_modules.feature0000644000175000017500000000050314676555272022531 0ustar joeniojoenioFeature: total modules As a software developer I want analizo to report the total number of modules in my code So that I can evaluate it Scenario: Java Enumeration sample Given I am in t/samples/enumeration When I run "analizo metrics ." Then analizo must report that the project has total_modules = 3 Analizo-1.25.5/t/features/metrics/language_filter.feature0000644000175000017500000000222314676555272023007 0ustar joeniojoenioFeature: language filters As a software developer in a multi-language project I want to analyze only one programming language So that the results are as correct as possible Scenario: filtering for C code Given I am in t/samples/mixed When I run "analizo metrics --language c ." Then the output must match "native_backend" And the output must not match "UI" And the output must not match "Backend" And the output must not match "CSharp_Backend" Scenario: filtering for Java code Given I am in t/samples/mixed When I run "analizo metrics --language java ." Then the output must match "UI" And the output must match "Backend" And the output must not match "native_backend" And the output must not match "CSharp_Backend" Scenario: filtering for CSharp code Given I am in t/samples/mixed When I run "analizo metrics --language csharp ." Then the output must match "CSharp_Backend" And the output must not match "UI" And the output must not match "native_backend" Scenario: listing languages When I run "analizo metrics --language list" Then analizo must present a list of languages Analizo-1.25.5/t/features/metrics/abstract_classes.feature0000644000175000017500000000300714676555272023200 0ustar joeniojoenioFeature: number of abstract classes As a software developer I want analizo to report the number of abstract classes in my code So that I can evaluate it Scenario: "Hello, world" project Given I am in t/samples/hello_world/ When I run "analizo metrics ." Then analizo must report that the project has total_abstract_classes = 0 Examples: | language | | cpp | | java | | csharp | Scenario: "Animals" project Given I am in t/samples/animals/ When I run "analizo metrics ." Then analizo must report that the project has total_abstract_classes = Examples: | language | total_abstract_classes | | cpp | 2 | | java | 2 | | csharp | 1 | Scenario: "Polygons" project Given I am in t/samples/polygons/ When I run "analizo metrics ." Then analizo must report that the project has total_abstract_classes = 2 Examples: | language | | cpp | | java | | csharp | Scenario: "AbstractClass" project Given I am in t/samples/abstract_class/ When I run "analizo metrics ." Then analizo must report that the project has total_abstract_classes = 1 And analizo must report that the project has total_methods_per_abstract_class = Examples: | language | total_mpac | | java | 6 | | csharp | 1 | Analizo-1.25.5/t/features/metrics/number_of_methods.feature0000644000175000017500000000244114676555272023360 0ustar joeniojoenioFeature: number of methods As a software developer I want analizo to report the number of methods of each module So that I can evaluate it Scenario: number of methods of the polygon java sample Given I am in t/samples// When I run "analizo metrics ." Then analizo must report that module has nom = Examples: | sample | language | module | nom | | polygons | cpp | CPolygon | 3 | | polygons | cpp | CTetragon | 2 | | polygons | java | Polygon | 3 | | polygons | csharp | Polygon | 2 | | polygons | csharp | Tetragon | 2 | | animals | cpp | Animal | 1 | | animals | cpp | Cat | 2 | | animals | cpp | Dog | 2 | | animals | java | Animal | 1 | | animals | java | Cat | 2 | | animals | java | Dog | 2 | | animals | csharp | Animal | 1 | | animals | csharp | Cat | 2 | | animals | csharp | Dog | 2 | Scenario: not computes macro on C code as method definition Given I am in t/samples/macro When I run "analizo metrics ." Then analizo must report that module using_macro has nom = 1 Analizo-1.25.5/t/features/metrics/statistics_values.feature0000644000175000017500000000230114676555272023425 0ustar joeniojoenioFeature: output statistics values of metrics As a researcher I want to ouput statistics values of metrics So that I can evaluate a project at once Scenario: "Hello, world" project Given I am in t/samples/hello_world/ When I run "analizo metrics ." Then the output must match "_mean:" Then the output must match "_mode:" Then the output must match "_standard_deviation:" Then the output must match "_sum:" Then the output must match "_variance:" Then the output must match "_quantile_min:" Then the output must match "_quantile_lower:" Then the output must match "_quantile_median:" Then the output must match "_quantile_upper:" Then the output must match "_quantile_max:" Then the output must match "_kurtosis:" Then the output must match "_skewness:" Examples: | metric | | acc | | accm | | amloc | | anpm | | cbo | | dit | | lcom4 | | loc | | mmloc | | noa | | noc | | nom | | npm | | npa | | rfc | | sc | Analizo-1.25.5/t/features/metrics/number_of_attributes.feature0000644000175000017500000000116314676555272024103 0ustar joeniojoenioFeature: number of attributes metric As a software developer I want to calculate the number of attributes per module metric So that I can evaluate my code Scenario: number of attributes in the "Animals" project Given I am in t/samples/animals/ When I run "analizo metrics ." Then analizo must report that module Dog has noa = 1 And analizo must report that module Cat has noa = 1 And analizo must report that module has noa = 0 Examples: | language | main_module | | cpp | main | | java | Main | | csharp | main | Analizo-1.25.5/t/features/metrics/cyclomatic_complexity.feature0000644000175000017500000000121114676555272024257 0ustar joeniojoenioFeature: average cyclomatic complexity per method As a software developer I want to calculate the average cyclomatic complexity per method of my code So that I can spot the more complex modules and refactor them Scenario: my "conditionals" C project Given I am in t/samples/conditionals/ When I run "analizo metrics ." Then analizo must report that module cc1 has accm = 1 Then analizo must report that module cc2 has accm = 2 Then analizo must report that module cc3 has accm = 3 Then analizo must report that module cc4 has accm = 4 Examples: | language | | c | | csharp | Analizo-1.25.5/t/features/metrics/coupling_between_objects.feature0000644000175000017500000000164714676555272024732 0ustar joeniojoenioFeature: coupling between objects As a software developer I want analizo to report the value of CBO metric in my code So that I can evaluate it Scenario: "Hello, world" project Given I am in t/samples/hello_world/ When I run "analizo metrics ." Then analizo must report that module has cbo = 1 Examples: | language | module | | c | main | | cpp | main | | java | Main | | csharp | main | Scenario: "Animals" project Given I am in t/samples/animals/ When I run "analizo metrics ." Then analizo must report that module has cbo = Examples: | language | module | value | | cpp | main | 1 | | cpp | mammal | 0 | | java | Main | 1 | | java | Mammal | 0 | | csharp | main | 1 | | csharp | Mammal | 0 | Analizo-1.25.5/t/features/metrics/number_of_public_methods.feature0000644000175000017500000000210314676555272024711 0ustar joeniojoenioFeature: number of public methods metric As a software developer I want to calculate the number of public methods per module metric So that I can evaluate my code Scenario: number of attributes in the "Animals" project Given I am in t/samples// When I run "analizo metrics ." Then analizo must report that module has npm = Examples: | sample | language | module | npm | | polygons | cpp | CPolygon | 2 | | polygons | cpp | CTetragon | 1 | | polygons | java | Polygon | 3 | | polygons | csharp | Polygon | 2 | | animals | cpp | Animal | 1 | | animals | cpp | Cat | 2 | | animals | cpp | Dog | 2 | | animals | java | Animal | 1 | | animals | java | Cat | 2 | | animals | java | Dog | 2 | | animals | csharp | Animal | 1 | | animals | csharp | Cat | 2 | | animals | csharp | Dog | 2 | Analizo-1.25.5/t/features/metrics/methods_per_abstract_class.feature0000644000175000017500000000215414676555272025243 0ustar joeniojoenioFeature: total number of methods per abstract class As a software developer I want analizo to report the number of abstract classes in my code So that I can evaluate it Scenario: "Hello, world" project Given I am in t/samples/hello_world/ When I run "analizo metrics ." Then analizo must report that the project has total_methods_per_abstract_class = 0 Examples: | language | | cpp | | java | | csharp | Scenario: "Animals" project Given I am in t/samples/animals/ When I run "analizo metrics ." Then analizo must report that the project has total_methods_per_abstract_class = Examples: | language | value | | cpp | 1 | | java | 1 | | csharp | 1 | Scenario: "Polygons" project Given I am in t/samples/polygons/ When I run "analizo metrics ." Then analizo must report that the project has total_methods_per_abstract_class = Examples: | language | value | | cpp | 2.5 | | java | 2 | | csharp | 2 | Analizo-1.25.5/t/features/metrics/average_number_of_parameters.feature0000644000175000017500000000145114676555272025552 0ustar joeniojoenioFeature: average number of parameters metric As a software developer I want to calculate the average number of arguments per method metric So that I can evaluate my code Scenario: number of parameters in the "Animals" project Given I am in t/samples/animals/ When I run "analizo metrics ." Then analizo must report that module Dog has anpm = And analizo must report that module Cat has anpm = And analizo must report that module has anpm = Examples: | language | main_module | anpm_main | anpm_dog | anpm_cat | | cpp | main | 0 | 0.5 | 0.5 | | java | Main | 1 | 0.5 | 0.5 | | csharp | main | 1 | 0.5 | 0.5 | Analizo-1.25.5/t/features/metrics/modules_with_defined_methods.feature0000644000175000017500000000140614676555272025565 0ustar joeniojoenioFeature: number of abstract classes As a software developer I want analizo to report the number of modules with at least a defined method in my code So that I can evaluate it Scenario: "Hello, world" project Given I am in t/samples/hello_world/ When I run "analizo metrics ." Then analizo must report that the project has total_modules_with_defined_methods = 2 Examples: | language | | cpp | | java | | csharp | Scenario: "Animals" project Given I am in t/samples/animals/ When I run "analizo metrics ." Then analizo must report that the project has total_modules_with_defined_methods = 5 Examples: | language | | cpp | | java | | csharp | Analizo-1.25.5/t/features/metrics/modules_with_defined_attributes.feature0000644000175000017500000000141414676555272026307 0ustar joeniojoenioFeature: number of abstract classes As a software developer I want analizo to report the number of modules with at least a defined method in my code So that I can evaluate it Scenario: "Hello, world" project Given I am in t/samples/hello_world/ When I run "analizo metrics ." Then analizo must report that the project has total_modules_with_defined_attributes = 1 Examples: | language | | cpp | | java | | csharp | Scenario: "Animals" project Given I am in t/samples/animals/ When I run "analizo metrics ." Then analizo must report that the project has total_modules_with_defined_attributes = 2 Examples: | language | | cpp | | java | | csharp | Analizo-1.25.5/t/features/metrics/deep_inheritance_afferent_connections.feature0000644000175000017500000000160114676555272027420 0ustar joeniojoenioFeature: afferent connections with deep inheritance As a software developer I want analizo to report the afferent connections of each module So that I can evaluate it Scenario: afferent connections of the dog family java sample Given I am in t/samples/deep_inheritance/java When I run "analizo metrics ." Then analizo must report that module has acc = Examples: | module | acc | | Dog | 8 | | DogFirstGreatGrandson | 1 | | DogFirstPuppy | 4 | | DogGrandson | 3 | | DogSecondGreatGrandson | 0 | | DogSecondPuppy | 0 | | DogSuperYoung | 0 | | Human | 2 | | ShopController | 0 | | VenderShop | 1 | Analizo-1.25.5/t/features/void-argument.feature0000644000175000017500000000060614676555272020775 0ustar joeniojoenioFeature: c code with void argument As a software engineering reasearcher I want to know the arguments of each function on a project So that I can run analizo metrics calculate number of parameters Scenario: calculate anpn on function with void argument Given I am in t/samples/void/ When I run "analizo metrics ." Then analizo must report that module main has anpm = 0 Analizo-1.25.5/t/features/metrics-batch.feature0000644000175000017500000000375514676555272020751 0ustar joeniojoenioFeature: metrics batch As a software engineering researcher I want to analyze several different projects So I can compare their metrics Scenario: "hello, world" Given I am in t/samples/hello_world/ When I run "analizo metrics-batch" Then the output must match "I: Processed c." And the output must match "I: Processed cpp." And the output must match "I: Processed java." Scenario: summarizing Given I am in t/samples/hello_world/ When I run "analizo metrics-batch --quiet -o data.csv && cat data.csv && rm -f *.csv" Then the output must match "^id," And the output must not match ",---," And the output must match "c," And the output must match "cpp," And the output must match "java," And the output must not match "I: Processed" Scenario: support for parallel processing Given I copy t/samples/hello_world/* into a temporary directory When I run "analizo metrics-batch -q -o sequential.csv" And I run "analizo metrics-batch -q -o parallel.csv -p 2" And I run "sort sequential.csv > sequential-sorted.csv" And I run "sort parallel.csv > parallel-sorted.csv" And I run "diff -u sequential-sorted.csv parallel-sorted.csv" Then the output must not match "---" Then the exit status must be 0 Scenario: passing two input directories as argument Given I copy t/samples/hello_world/* into a temporary directory When I run "analizo metrics-batch --quiet -o data.csv cpp java" Then the exit status must be 0 And the file "c-details.csv" should not exist And the file "cpp-details.csv" should exist And the file "java-details.csv" should exist Scenario: passing one input directory as argument Given I copy t/samples/hello_world/* into a temporary directory When I run "analizo metrics-batch --quiet -o data.csv cpp" Then the exit status must be 0 And the file "c-details.csv" should not exist And the file "cpp-details.csv" should exist And the file "java-details.csv" should not exist Analizo-1.25.5/t/features/tree_evolution.feature0000644000175000017500000000117514676555272021261 0ustar joeniojoenioFeature: tree evolution As a software engineering reasearcher I want to know what directories existed during the project lifetime So that I can analyze only the production code (and not tests etc) Scenario: sample git repository When I explode t/samples/tree-evolution.tar.gz And I run "analizo tree-evolution" Then the output lines must match "# 073290fbad0254793bd3ecfb97654c04368d0039\\nsrc\\n#" Then the output lines must match "# 85f7db08f7b7b0b62e3c0023b2743d529b0d5b4b\\nsrc\\nsrc/input\\n#" Then the output lines must match "# f41cf7d0351e812285efd60c6d957c330b1f61a1\\nsrc\\nsrc/input\\nsrc/output" Analizo-1.25.5/t/features/manpage-on-help.feature0000644000175000017500000000116514676555272021165 0ustar joeniojoenioFeature: give manpage on --help As a user I want to read the manpage when passing --help command line option In order to get instructions on how to use the tools Scenario: display manpage for `analizo ` When I run "analizo --help" Then the output must match "[NAME|N^HNA^HAM^HME^HE]\\s+analizo-" Then the output must match "[USAGE|U^HUS^HSA^HAG^HGE^HE]\\s+analizo \\[OPTIONS\\]" Examples: | tool | | graph | | metrics | | metrics-batch | | metrics-history | | tree-evolution | | files-graph | Analizo-1.25.5/t/features/metrics_history.feature0000644000175000017500000000712614676555272021447 0ustar joeniojoenioFeature: analizo metrics-history As a software engineering researcher I want to analyse the entire history of a project To understand its development process Scenario: listing merge commits with code changes that should be analyzed When I explode t/samples/evolution.tar.gz And I run "analizo metrics-history --list ." Then the output must match "0a06a6fcc2e7b4fe56d134e89d74ad028bb122ed" And the output must match "eb67c27055293e835049b58d7d73ce3664d3f90e" And the output must match "aa2d0fcb7879485d5ff1cd189743f91f04bea8ce" And the output must match "e8faf88f0e20a193d700b6c68eeb31897dd85e53" And the output must match "d7f52e74dc3d8f57640e83d41c5e9f8fcf621c00" And the output must match "0d3c023120ad4e9f519a03fff275d048c52671ad" Scenario: non-code commits should not be analyzed When I explode t/samples/evolution.tar.gz And I run "analizo metrics-history --list ." Then the output must not match "ba62278e976944c0334103aa0044535169e1a51e" Scenario: merge commits without code change should not be analyzed When I explode t/samples/evolution.tar.gz And I run "analizo metrics-history --list ." Then the output must not match "0fdaaa7dcc8073332a957024fafc8c98f165e725" Scenario: actually processing merge commits When I explode t/samples/evolution.tar.gz And I run "analizo metrics-history -o metrics.csv . && cat metrics.csv" Then the output must match "^id,previous_commit_id,author_date,author_name,author_email,.*,sc_mean" And the output must match "0a06a6fcc2e7b4fe56d134e89d74ad028bb122ed,eb67c27055293e835049b58d7d73ce3664d3f90e" And the output must match "eb67c27055293e835049b58d7d73ce3664d3f90e,," And the output must match "aa2d0fcb7879485d5ff1cd189743f91f04bea8ce,d7f52e74dc3d8f57640e83d41c5e9f8fcf621c00" And the output must match "e8faf88f0e20a193d700b6c68eeb31897dd85e53,d7f52e74dc3d8f57640e83d41c5e9f8fcf621c00" And the output must match "d7f52e74dc3d8f57640e83d41c5e9f8fcf621c00,0d3c023120ad4e9f519a03fff275d048c52671ad" Scenario: actually processing initial commit and first commit after a non-relevant merge When I explode t/samples/evolution.tar.gz And I run "analizo metrics-history -o metrics.csv . && cat metrics.csv" Then the output must match "0d3c023120ad4e9f519a03fff275d048c52671ad,," And the output must match "8183eafad3a0f3eff6e8869f1bdbfd255e86825a,0a06a6fcc2e7b4fe56d134e89d74ad028bb122ed" Scenario: support for parallel processing Given I copy t/samples/evolution.tar.gz into a temporary directory When I run "tar xzf evolution.tar.gz" And I run "cd evolution && analizo metrics-history -o ../sequential.csv" And I run "cd evolution && analizo metrics-history -p 2 -o ../parallel.csv" Then the exit status must be 0 When I run "sort sequential.csv > sequential-sorted.csv" And I run "sort parallel.csv > parallel-sorted.csv" And I run "diff -u sequential-sorted.csv parallel-sorted.csv" Then the output must not match "---" And the exit status must be 0 Scenario: parsing git log format containing renamed files among status of changed files Given I copy t/samples/evolution.tar.gz into a temporary directory When I run "tar xzf evolution.tar.gz" And I run "cd evolution && git checkout doc && analizo metrics-history ." Then the exit status must be 0 Scenario: language filters Given I copy t/samples/mixed into a temporary directory When I run "(cd mixed && git init && git add * && git commit -m 'initial commit')" And I run "analizo metrics-history --language java mixed" Then the output must not match "native_backend.c" Analizo-1.25.5/t/features/language_support.feature0000644000175000017500000001074114676555272021574 0ustar joeniojoenioFeature: multi-language support As a Researcher or Practioneer I want to be able to analyze software in different languages In order do compare them Scenario: dependency between modules Given I am in t/samples/hello_world/ When I run "analizo graph --modules ." Then analizo must report that "" depends on "" Examples: | language | main_module | hello_world_module | | c | main | hello_world | | cpp | main | HelloWorld | | java | Main | HelloWorld | | csharp | main | HelloWorld | Scenario: dependency between specific functions Given I am in t/samples/hello_world/ When I run "analizo graph ." Then analizo must report that "" depends on "" And analizo must report that "" depends on "" Examples: | language | main_function | hello_say | hello_destroy | | c | main::main() | hello_world::hello_world_say(hello_world *) | hello_world::hello_world_destroy(hello_world *) | | cpp | main::main() | HelloWorld::say() | HelloWorld::destroy() | | java | Main::main(String[]) | HelloWorld::say() | HelloWorld::destroy() | | csharp | main::Main() | HelloWorld::say() | HelloWorld::destroy() | Scenario: intra-module dependencies Given I am in t/samples/hello_world/ When I run "analizo graph ." Then analizo must report that "" depends on "" And analizo must report that "" depends on "" Examples: | language | hello_say | hello_destroy | hello_id | | c | hello_world::hello_world_say(hello_world *) | hello_world::hello_world_destroy(hello_world *) | hello_world::_hello_world::id | | cpp | HelloWorld::say() | HelloWorld::destroy() | HelloWorld::_id | | java | HelloWorld::say() | HelloWorld::destroy() | HelloWorld::_id | | csharp | HelloWorld::say() | HelloWorld::destroy() | HelloWorld::_id | Scenario: some metrics Given I am in t/samples/hello_world/ When I run "analizo metrics ." Then analizo must report that the project has total_modules = 2 And analizo must report that module has nom = 1 And analizo must report that module has npm = 3 And analizo must report that module has nom = And analizo must report that module has npa = Examples: | language | main_module | hello_world_module | total_methods | public_attributes | | c | main | hello_world | 3 | 2 | | cpp | main | HelloWorld | 4 | 1 | | java | Main | HelloWorld | 4 | 1 | | csharp | main | HelloWorld | 4 | 1 | Scenario: inheritance data Given I am in t/samples/animals/ When I run "analizo graph --modules ." Then analizo must report that "Cat" depends on "Mammal" And analizo must report that "Dog" depends on "Mammal" And analizo must report that "Mammal" depends on "Animal" When I run "analizo metrics ." Then analizo must report that module Cat has dit = 2 And analizo must report that module Dog has dit = 2 And analizo must report that module Mammal has dit = 1 And analizo must report that module Animal has dit = 0 Examples: | language | | cpp | | java | # not sure what to expect in this case Scenario: mixed Java and C Given I am in t/samples/mixed When I run "analizo metrics ." Then the output must match "_module: native_backend" And the output must match "_module: UI" And the output must match "_module: Backend" Analizo-1.25.5/t/features/metrics_history_db.feature0000644000175000017500000000100314676555272022100 0ustar joeniojoenioFeature: storing VCS data in a database As a software engineering researcher I want to store data about the changes in a project So that I can analyze the development process Scenario: basics When I explode t/samples/evolution.tar.gz And I run "analizo metrics-history -f db -o data.db" Then the exit status must be 0 When I run "select * from modules" on database "data.db" Then the output must match "Input" And the output must match "Output" And the output must match "prog" Analizo-1.25.5/t/features/module_file_mapping.feature0000644000175000017500000000475614676555272022225 0ustar joeniojoenioFeature: mapping modules to filenames As a software engineering resesearcher I want to know in which file each module is declared So that I can compare that with data from the VCS Scenario: C++, runing against some directory When I run "analizo metrics t/samples/animals/cpp" Then analizo must report that file animal.h declares module Animal And analizo must report that file cat.cc declares module Cat And analizo must report that file cat.h declares module Cat And analizo must report that file cat.cc not declares module Dog And analizo must report that file cat.h not declares module Dog Scenario: C++, running against current directory Given I am in t/samples/animals/cpp When I run "analizo metrics ." Then analizo must report that file animal.h declares module Animal And analizo must report that file cat.cc declares module Cat And analizo must report that file cat.h declares module Cat Scenario: Java When I run "analizo metrics t/samples/animals/java" Then analizo must report that file Animal.java declares module Animal Scenario: C Given I am in t/samples/hello_world/c When I run "analizo metrics ." Then analizo must report that module hello_world has _filename = [hello_world.c,hello_world.h] And analizo must report that file hello_world.c declares module hello_world And analizo must report that file hello_world.h declares module hello_world Scenario: CSharp hello_world Given I am in t/samples/hello_world/csharp When I run "analizo metrics ." Then analizo must report that module HelloWorld has _filename = [HelloWorld.cs] Scenario: CSharp polygons Given I am in t/samples/polygons/csharp When I run "analizo metrics ." Then analizo must report that file Polygon.cs declares module Polygon And analizo must report that file Rect.cs declares module Rect And analizo must report that file Triangle.cs declares module Triangle Scenario: Java Generics WildCard sample Given I am in t/samples/wildcard When I run "analizo metrics ." Then analizo must report that file WildcardClass.java declares module WildcardClass And analizo must report that file GenericClass.java declares module GenericClass Scenario: Java Enumeration sample Given I am in t/samples/enumeration When I run "analizo metrics ." Then analizo must report that file Main.java declares module Main::MyEnumeration And analizo must report that file Enumeration.java declares module Enumeration Analizo-1.25.5/t/features/step_definitions/0000775000175000017500000000000014676555272020205 5ustar joeniojoenioAnalizo-1.25.5/t/features/step_definitions/analizo_steps.pl0000644000175000017500000001356314676555272023423 0ustar joeniojoeniouse strict; use warnings; use Test::More; use Test::BDD::Cucumber::StepFile; use File::Slurp; use File::Temp qw( tempdir ); use File::Copy::Recursive qw( rcopy ); use YAML::XS; use File::LibMagic; use Archive::Extract; use DBI; use File::Spec; our $exit_status; our $stdout; our $stderr; use Env qw(@PATH $PWD); push @PATH, "$PWD/blib/script", "$PWD/bin"; use IPC::Open3; use Symbol 'gensym'; When qr/^I run "([^\"]*)"$/, sub { my ($c) = @_; my $command = $1; my ($IN, $STDOUT, $STDERR); $STDERR = gensym; my $pid = open3($IN, $STDOUT, $STDERR, "$command 2>tmp.err"); waitpid $pid, 0; $exit_status = $?; local $/ = undef; $stdout = <$STDOUT>; $stderr = <$STDERR> . read_file('tmp.err'); }; When qr/^I run "([^\"]*)" on database "([^\"]*)"$/, sub { my ($c) = @_; my $statement = $1; my $db = $2; my @a = DBI->connect("dbi:SQLite:$db")->selectall_array($statement); $stdout = join("\n", map { join("|", @$_) } @a), "\n"; }; Then qr/^the output must match "([^\"]*)"$/, sub { my ($c) = @_; like($stdout, qr/$1|\Q$1\E/); }; Then qr/^the output must not match "([^\"]*)"$/, sub { my ($c) = @_; unlike($stdout, qr/$1|\Q$1\E/); }; Then qr/^the exit status must be (\d+)$/, sub { my ($c) = @_; cmp_ok($exit_status, '==', $1); }; Then qr/^the exit status must not be (\d+)$/, sub { my ($c) = @_; cmp_ok($exit_status, '!=', $1); }; Step qr/^I copy (.*) into a temporary directory$/, sub { my ($c) = @_; my $tmpdir = tempdir("analizo-XXXXXXXXXX", CLEANUP => 1, DIR => File::Spec->tmpdir); rcopy($1, $tmpdir); chdir $tmpdir; }; Given qr/^I create a file called (.+) with the following content$/, sub { my ($c) = @_; open FILE, '>', $1 or die $!; if ($c->data =~ m/<\w+>/) { # The Test::BDD::Cucumber not support replace strings in the content # by the values in table "Examples:", the code above does this. # Not yet know how find out what line of "Examples:" we are, then for now # we create entries for all values in the table. # TODO Implement it on Test::BDD::Cucumber in the right way and contribute # back to upstream. foreach my $row (@{ $c->scenario->data }) { foreach my $col (keys %$row) { (my $data = $c->data) =~ s/<$col>/$row->{$col}/sg; print FILE "$data"; } } } else { print FILE $c->data; } close FILE; }; Given qr/^I change to an empty temporary directory$/, sub { my ($c) = @_; chdir tempdir("analizo-XXXXXXXXXX", CLEANUP => 1, DIR => File::Spec->tmpdir); }; Given qr/^I am in (.+)$/, sub { my ($c) = @_; chdir $1; }; Then qr/^analizo must emit a warning matching "([^\"]*)"$/, sub { my ($c) = @_; like($stderr, qr/$1|\Q$1\E/); }; Then qr/^analizo must not emit a warning matching "([^\"]*)"$/, sub { my ($c) = @_; unlike($stderr, qr/$1|\Q$1\E/); }; Then qr/^analizo must report that "([^\"]*)" is part of "([^\"]*)"$/, sub { my ($c) = @_; my ($func, $mod) = ($1, $2); like($stdout, qr/subgraph "cluster_$mod" \{[^}]*node[^}]*"\Q$func\E";/); }; Then qr/^analizo must report that "([^\"]*)" depends on "([^\"]*)"$/, sub { my ($c) = @_; my ($dependent, $depended) = ($1, $2); like($stdout, qr/"\Q$dependent\E" -> "\Q$depended\E"/); }; Then qr/^analizo must not report that "([^\"]*)" depends on "([^\"]*)"$/, sub { my ($c) = @_; my ($dependent, $depended) = ($1, $2); unlike($stdout, qr/"\Q$dependent\E" -> "\Q$depended\E"/); }; Then qr/^the contents of "(.+)" must match "([^\"]*)"$/, sub { my ($c) = @_; my ($file, $pattern) = ($1, $2); like(read_file($file), qr/$pattern/); }; Then qr/^analizo must report that the project has (.+) = ([\d\.]+)$/, sub { my ($c) = @_; my ($metric, $n) = ($1, $2); my @stream = Load($stdout); cmp_ok($stream[0]->{$metric}, '==', $n); }; Then qr/^analizo must report that module (.+) has (.+) = (.+)$/, sub { my ($c) = @_; my ($module, $metric, $value) = ($1, $2, $3); my @stream = Load($stdout); my ($module_metrics) = grep { $_->{_module} && $_->{_module} eq $module } @stream; if ($module_metrics->{$metric}) { if ($value =~ /^\d+|\d+\.\d+$/) { cmp_ok($module_metrics->{$metric}, '==', $value); } elsif ($value =~ /^\[(.*)\]$/) { my @values = split(/\s*,\s*/, $1); is_deeply($module_metrics->{$metric}, \@values); } } }; Then qr/^analizo must report that file (.+) not declares module (.+)$/, sub { my ($c) = @_; my ($filename, $module) = ($1, $2); my @stream = Load($stdout); my ($document) = grep { $_->{_module} && $_->{_module} eq $module } @stream; ok(!grep { /^$filename$/ } @{$document->{_filename}}); }; Then qr/^analizo must report that file (.+) declares module (.+)$/, sub { my ($c) = @_; my ($filename, $module) = ($1, $2); my @stream = Load($stdout); my ($document) = grep { $_->{_module} && $_->{_module} eq $module } @stream; ok(grep { /^$filename$/ } @{$document->{_filename}}); }; Then qr/^analizo must present a list of metrics$/, sub { my ($c) = @_; like($stdout, qr/Global Metrics:/); like($stdout, qr/Module Metrics:/); }; Then qr/^analizo must present a list of languages$/, sub { my ($c) = @_; like($stdout, qr/Languages:/); }; Then qr/^the file "([^\"]*)" should exist$/, sub { my ($c) = @_; my $file = $1; ok(-e $file); }; Then qr/^the file "([^\"]*)" should not exist$/, sub { my ($c) = @_; my $file = $1; ok(! -e $file); }; Then qr/^the file "(.*?)" should have type (.*)$/, sub { my ($c) = @_; my ($file, $type) = ($1, $2); my $magic = File::LibMagic->new; my $mime = $magic->checktype_filename($file); like($mime, qr/$type;/); }; When qr/^I explode (.+)$/, sub { my ($c) = @_; my $tarball = $1; my $archive = Archive::Extract->new(archive => $tarball); $archive->extract(to => tempdir("analizo-XXXXXXXXXX", CLEANUP => 1, DIR => File::Spec->tmpdir)); chdir $archive->extract_path; }; Then qr/^the output lines must match "([^\"]*)"$/, sub { my ($c) = @_; my $pattern = $1; like($stdout, qr/$pattern/); }; Analizo-1.25.5/Makefile.PL0000644000175000017500000000622614676555272014534 0ustar joeniojoenio# This file was automatically generated by Dist::Zilla::Plugin::MakeMaker v6.032. use strict; use warnings; use ExtUtils::MakeMaker; use File::ShareDir::Install; $File::ShareDir::Install::INCLUDE_DOTFILES = 1; $File::ShareDir::Install::INCLUDE_DOTDIRS = 1; install_share dist => "share"; my %WriteMakefileArgs = ( "ABSTRACT" => "multi-language source code analysis toolkit", "AUTHOR" => "Joenio Marques da Costa ", "BUILD_REQUIRES" => { "File::Share" => 0, "File::ShareDir" => 0, "Git::Wrapper" => 0, "List::MoreUtils" => 0, "Term::UI" => 0 }, "CONFIGURE_REQUIRES" => { "Alien::Doxyparse" => "0.17", "ExtUtils::MakeMaker" => 0, "File::ShareDir::Install" => "0.06" }, "DISTNAME" => "Analizo", "EXE_FILES" => [ "bin/analizo" ], "LICENSE" => "gpl", "NAME" => "Analizo", "PREREQ_PM" => { "App::Cmd" => 0, "CHI" => 0, "Class::Accessor" => 0, "Class::Inspector" => 0, "DBD::SQLite" => 0, "DBI" => "1.635", "Digest::SHA" => 0, "Env::Path" => 0, "File::Copy::Recursive" => 0, "File::HomeDir" => 0, "FindBin::libs" => 0, "Graph" => 0, "Graph::Writer::Dot" => "2.09", "JSON" => 0, "List::Compare" => 0, "Statistics::Descriptive" => 0, "Term::ProgressBar" => 0, "YAML::XS" => "0.75", "ZMQ::FFI" => 0, "local::lib" => 0 }, "TEST_REQUIRES" => { "Archive::Extract" => 0, "File::LibMagic" => 0, "File::Slurp" => 0, "Test::BDD::Cucumber" => "0.61", "Test::Class" => 0, "Test::Exception" => 0, "Test::MockModule" => 0, "Test::MockObject" => 0, "Test::Spelling" => 0 }, "VERSION" => "1.25.5", "test" => { "TESTS" => "t/*.t t/Analizo/*.t t/Analizo/Batch/*.t t/Analizo/Batch/Job/*.t t/Analizo/Batch/Output/*.t t/Analizo/Batch/Runner/*.t t/Analizo/Command/*.t t/Analizo/Extractor/*.t t/Analizo/GlobalMetric/*.t t/Analizo/Metric/*.t t/Analizo/Metric/AfferentConnections/*.t" } ); my %FallbackPrereqs = ( "App::Cmd" => 0, "Archive::Extract" => 0, "CHI" => 0, "Class::Accessor" => 0, "Class::Inspector" => 0, "DBD::SQLite" => 0, "DBI" => "1.635", "Digest::SHA" => 0, "Env::Path" => 0, "File::Copy::Recursive" => 0, "File::HomeDir" => 0, "File::LibMagic" => 0, "File::Share" => 0, "File::ShareDir" => 0, "File::Slurp" => 0, "FindBin::libs" => 0, "Git::Wrapper" => 0, "Graph" => 0, "Graph::Writer::Dot" => "2.09", "JSON" => 0, "List::Compare" => 0, "List::MoreUtils" => 0, "Statistics::Descriptive" => 0, "Term::ProgressBar" => 0, "Term::UI" => 0, "Test::BDD::Cucumber" => "0.61", "Test::Class" => 0, "Test::Exception" => 0, "Test::MockModule" => 0, "Test::MockObject" => 0, "Test::Spelling" => 0, "YAML::XS" => "0.75", "ZMQ::FFI" => 0, "local::lib" => 0 ); unless ( eval { ExtUtils::MakeMaker->VERSION(6.63_03) } ) { delete $WriteMakefileArgs{TEST_REQUIRES}; delete $WriteMakefileArgs{BUILD_REQUIRES}; $WriteMakefileArgs{PREREQ_PM} = \%FallbackPrereqs; } delete $WriteMakefileArgs{CONFIGURE_REQUIRES} unless eval { ExtUtils::MakeMaker->VERSION(6.52) }; WriteMakefile(%WriteMakefileArgs); { package MY; use File::ShareDir::Install qw(postamble); } Analizo-1.25.5/CHANGELOG.md0000644000175000017500000002115514676555272014371 0ustar joeniojoenio# Changelog All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). ## [Unreleased] ### Added - (for new features) ### Changed - (for changes in existing functionality) ### Deprecated - (for soon-to-be removed features) ### Removed - (for now removed features) ### Fixed - (for any bug fixes) ### Security - (in case of vulnerabilities) ## [1.25.5] - 2024-09-30 ### Changed - declare Graph::Writer::Dot 2.09 requirement on Dist::Zilla dist.ini file ### Security - replace `system("command $arg")` by `system("command", $arg)` to avoids invoking potentially dangerous shell commands ## [1.25.4] - 2022-08-21 ### Fixed - fix Analizo::Metric::AfferentConnections POD syntax error - add new recommended test dependency Test::Pod ## [1.25.3] - 2022-08-20 ### Added - add document on how to run Analizo with Docker ### Changed - create variable $TEMP before run Doxyparse - change copyright holder name to use fullname - enrich samples copyright and licensing notices - rename master branch to main - add `tar` flag to avoid changing files ownership when run as root ### Fixed - fix install documentation - fix reference paper for ACC metric - remove duplicity of authors names in .mailmap file - fix misspelling and spelling test - rm shebang from bash-completion ## [1.25.2] - 2022-07-22 ### Changed - change debian stretch to buster on dockerfile ### Removed - get rid of travis-ci (preparing to migrate to gitlab) ### Fixed - make sure Graph::TransitiveClosure::Matrix is loaded ## [1.25.1] - 2021-01-05 ### Fixed - error cpantester "can't locate local::lib" - ignore prototype functions to fix NOM metric ## [1.25.0] - 2021-01-04 ### Changed - Depends on doxyparse 1.9.0 (provided by Alien::Doxyparse 0.17) - Depends on DBI 1.635+ ### Removed - Drop YAML dependency, using YAML::XS instead ### Fixed - Add samples to improve testcases for errors on YAML syntax - Add freebsd support * using shebang `/usr/bin/env perl` instead of `/usr/bin/perl` * fixed args for manpage command line tool on freebsd * documented steps on how to run testcases on freebsd ## [1.24.0] - 2020-04-15 ### Changed - Use local::lib on t/festures.t - Depends on doxyparse 1.8.18 (provided by Alien::Doxyparse 0.16) - Update copyright year 2014-2019 - Improve ACCM metric documentation - Update bash completion script - Use Digest::SHA instead of `sha1sum` ### Removed - Removed Debian package source files ### Fixed - Fix warnings about uninitialized value on tests - Removed failing Parallelel unit testcase - Fixed some spelling errors - Fixed documentation about `--modules` param on `analizo graph` - Fixed parsing method signature on newer doxyparse YAML output - Fixed warning about Cucumber TestBuilder deprecation - Declared requirement for Test::BDD::Cucumber::Harness::TAP ## [1.23.0] - 2019-08-10 ### Added - Added new tool files-graph to output graph among files in DOT format - Add Ubuntu 16 install instructions on documentation ### Changed - Depends on doxyparse 1.8.15 provided by Alien::Doxyparse 0.13 - Stores cache on distinct dirs for each Analizo version - Improve ACC metric description on documentation ### Fixed - Added test for void arguments on C code - Fix tests to run on right place `t/samples/sample_basic/c/` - Added missing prereq Graph::Writer::Dot as suggested by CPANTS - Added atomated tests for httpd-2.4.38 errors - Added samples for bug parsing kdelibs project ### Removed - Removed the evolution-matrix visualization tool - Removed the dsm visualization tool ## [1.22.0] - 2018-09-25 ### Removed - Removed global metric `total_eloc` - Removed dependency for `sloccount` external tool ### Changed - Development setup installs Doxyparse from latest source master branch - Improved the performance for ACC metric calculation ### Fixed - Update to the newer Doxyparse 1.8.14-7 (fix invalid YAML with "\" char) - Invalid references to function - Limit Doxyparse YAML output identifiers to 1024 chars ## [1.21.0] - 2018-04-30 ### Added - Added documentation about the meaning of 0 (zero) value for metrics - Added documentation for C# language support - Added tests for Java Enumerations and Java Generics with Wildcards - Added tests for Doxyparse bug parsing mlpack source-code ### Changed - authors listed on 'Signed-off-by' added to AUTHORS file - Improving performance by using module `YAML::XS` instead of `YAML` - Improving performance avoid calculating `Graph` every time ### Deprecated - Global metric `total_eloc` (Total Effective Lines of Code) is going to be removed next release ### Removed - Removed dependency for module `Moo` - Removed dependency for pragma `base` ### Fixed - Fix documentation for LCOM4 metric - Fix missing dependency for `Class::Inspector` - Removing cache after every test execution ## [1.20.8] - 2018-03-23 ### Added - Auto generate META.json using dzil plugin MetaJSON ### Fixed - Changed markdown syntax to fix pandoc html transforming - Tests depends on File::Slurp - Env::Path is required at runtime ### Removed - Removed dependency for Method::Signatures ## [1.20.7] - 2018-02-07 ### Changed - Change development script to install CPAN modules without sudo. ### Fixed - Fix tests to run under Perl located in different paths. ### Removed - Removed external dependency for `man`. ## [1.20.6] - 2018-02-06 ### Changed - Added doxyparse as Debian dependency (hardcoded). - Added sloccount as Debian dependency (hardcoded). ### Deprecated - Analizo visualization tools `dsm` and `evolution-matrix` are going to be removed from Analizo, the tools will be refactored or just removed. ### Removed - Removed external dependency for `sqlite3`. - Removed external dependency for `man`. ## [1.20.5] - 2018-02-03 ### Changed - Depends on doxyparse 1.8.14-4 provided by Alien::Doxyparse 0.06. ### Fixed - Fix dependencies to run test suite on cpantesters. - Fix travis-ci build. ## [1.20.4] - 2018-02-02 ### Fixed - Fix YAML duplicate key. - Fix bin PATH for doxyparse and sloccount external tools. - Fix missing dependencie for App::Cmd. ## [1.20.3] - 2018-01-26 ### Changed - Test suite refactored (package namespace t::Analizo renamed to Test::Analizo). ## [1.20.2] - 2018-01-06 ### Added - New dependencies: Alien::Doxyparse Alien::SLOCCount. ### Fixed - Avoid warnings about YAML duplicate map key "inherits". ## [1.20.1] - 2018-01-02 ### Added - Changelog based on "Keep a Changelog" project. ### Changed - Copyright holder name and email. - Development documentation updated. ### Fixed - Dist::Zilla::Deb `debuild` task to build Debian package. - Declaring missing Debian dependencies. ## [1.20.0] - 2017-12-29 ### Added - Source code metrics documentation. - Dockerfile added. - Support for C# (CSharp). - More automated tests. ### Changed - Doxyparse Extractor uses YAML output. - Depends on Doxyparse 1.8.14+. - Build process migrated from Rake to Dist::Zilla. - Migrate from ZeroMQ to ZMQ::FFI. ### Removed - CLANG Extractor removed. - Security metrics provided by CLANG Extractor removed. - Analizo site source code moved to new repository. - Ruby dependency removed. ### Fixed - Fixed Docker setup to run tests on Travis. - Script development-setup.sh fixed. - Running of a single acceptance Cucumber test fixed. [Unreleased]: https://github.com/analizo/analizo/compare/1.25.5...HEAD [1.25.5]: https://github.com/analizo/analizo/compare/1.25.4...1.25.5 [1.25.4]: https://github.com/analizo/analizo/compare/1.25.3...1.25.4 [1.25.3]: https://github.com/analizo/analizo/compare/1.25.2...1.25.3 [1.25.2]: https://github.com/analizo/analizo/compare/1.25.1...1.25.2 [1.25.1]: https://github.com/analizo/analizo/compare/1.25.0...1.25.1 [1.25.0]: https://github.com/analizo/analizo/compare/1.24.0...1.25.0 [1.24.0]: https://github.com/analizo/analizo/compare/1.23.0...1.24.0 [1.23.0]: https://github.com/analizo/analizo/compare/1.22.0...1.23.0 [1.22.0]: https://github.com/analizo/analizo/compare/1.21.0...1.22.0 [1.21.0]: https://github.com/analizo/analizo/compare/1.20.8...1.21.0 [1.20.8]: https://github.com/analizo/analizo/compare/1.20.7...1.20.8 [1.20.7]: https://github.com/analizo/analizo/compare/1.20.6...1.20.7 [1.20.6]: https://github.com/analizo/analizo/compare/1.20.5...1.20.6 [1.20.5]: https://github.com/analizo/analizo/compare/1.20.4...1.20.5 [1.20.4]: https://github.com/analizo/analizo/compare/1.20.3...1.20.4 [1.20.3]: https://github.com/analizo/analizo/compare/1.20.2...1.20.3 [1.20.2]: https://github.com/analizo/analizo/compare/1.20.1...1.20.2 [1.20.1]: https://github.com/analizo/analizo/compare/1.20.0...1.20.1 [1.20.0]: https://github.com/analizo/analizo/compare/1.19.1...1.20.0 Analizo-1.25.5/PROFILING.md0000644000175000017500000000205314676555272014427 0ustar joeniojoenio# Profiling analizo Run the desired command under the profiler: ```console analizo=/path/to/analizo perl -d:DProf -I$analizo/lib $analizo/lib/Analizo/Command/COMMAND ``` Process the profiler output (this has to be run from the same directory where you run the profiler): ```console dprofpp ``` ## Using Devel::NYTProf Run the desired command under the profiler: ```console COMMAND=metrics SOURCE=t/samples/hello_world/cpp/ perl profile.pl ``` Process the profiler output (this has to be run from the same directory where you run the profiler) in HTML format: ```console nytprofhtml --open ``` You can run profiler running analizo over any source-code you want by passing via command line argument or $SOURCE variable, eg: ```console SOURCE=t/samples/hello_world/cpp/ perl profile.pl ``` ```console perl profile.pl t/samples/hello_world/cpp/ ``` * [Profiling Perl](http://www.perl.com/pub/2004/06/25/profiling.html), by Simon Cozens * [Devel::NYTProf - Profiling Perl code](https://www.perl.org/about/whitepapers/perl-profiling.html), by Leo Lapworth Analizo-1.25.5/share/0000775000175000017500000000000014676555272013660 5ustar joeniojoenioAnalizo-1.25.5/share/README0000644000175000017500000000003014676555272014527 0ustar joeniojoenioAnalizo share directory Analizo-1.25.5/share/bash-completion/0000775000175000017500000000000014676555272016744 5ustar joeniojoenioAnalizo-1.25.5/share/bash-completion/analizo0000644000175000017500000000453514676555272020331 0ustar joeniojoenio_analizo_help() { local options options="-h -v --usage --help --version" if [[ ${cur} == -* ]] ; then COMPREPLY=( $(compgen -W "${options}" -- ${cur})) else COMPREPLY=( $(compgen -f ${cur}) ) fi return 0 } _analizo_graph() { local options options="-t -m -c -e -o -h -u --omit --cluster --modules --extractor --output --help" if [[ ${cur} == -* ]] ; then COMPREPLY=( $(compgen -W "${options}" -- ${cur})) else COMPREPLY=( $(compgen -d ${cur}) ) fi return 0 } _analizo_files-graph() { local options options="-e -o -h --extractor --output --help --usage" if [[ ${cur} == -* ]] ; then COMPREPLY=( $(compgen -W "${options}" -- ${cur})) else COMPREPLY=( $(compgen -d ${cur}) ) fi return 0 } _analizo_metrics() { local options options="-e -h -l -o -g -n -d --extractor --help --list --output --global-only --language --exclude --usage" if [[ ${cur} == -* ]] ; then COMPREPLY=( $(compgen -W "${options}" -- ${cur})) else COMPREPLY=( $(compgen -d ${cur}) ) fi return 0 } _analizo_metrics-batch() { local options options="-p -h -o -q --parallel --help --output --quiet --usage" if [[ ${cur} == -* ]] ; then COMPREPLY=( $(compgen -W "${options}" -- ${cur})) else COMPREPLY=( $(compgen -d ${cur}) ) fi return 0 } _analizo_metrics-history() { local options options="-p -n -o -f -l -b -h -u --parallel --language --output --format --list --progressbar --help --usage" if [[ ${cur} == -* ]] ; then COMPREPLY=( $(compgen -W "${options}" -- ${cur})) else COMPREPLY=( $(compgen -d ${cur}) ) fi return 0 } _analizo_tree-evolution() { local options options="-l -h --language --help --usage" if [[ ${cur} == -* ]] ; then COMPREPLY=( $(compgen -W "${options}" -- ${cur})) else COMPREPLY=( $(compgen -d ${cur}) ) fi return 0 } _analizo() { local cur prev opts tools COMPREPLY=() _get_comp_words_by_ref cur prev opts="-v -h --version --help --usage" tools="help files-graph graph metrics metrics-batch metrics-history tree-evolution" case "${prev}" in analizo) if [[ ${cur} == -* ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- ${cur})) return 0 else COMPREPLY=( $(compgen -W "${tools}" -- ${cur}) ) return 0 fi ;; *) for tool in $tools do if [ $prev == $tool ]; then _analizo_${tool} return 0 fi done return 0 ;; esac return 0 } complete -F _analizo analizo Analizo-1.25.5/MANIFEST.SKIP0000644000175000017500000000012414676555272014447 0ustar joeniojoenio^\.git/ ^Makefile$ ^MANIFEST\.(bak|old)$ ^blib/ ^pm_to_blib$ ^MYMETA.yml$ ^debuild/ Analizo-1.25.5/lib/0000775000175000017500000000000014676555272013324 5ustar joeniojoenioAnalizo-1.25.5/lib/Analizo.pm0000644000175000017500000001060514676555272015257 0ustar joeniojoeniopackage Analizo; use App::Cmd::Setup -app; use strict; use warnings; use local::lib; our $VERSION = '1.25.5'; =head1 NAME analizo - multi-language source code analysis toolkit =head1 USAGE analizo [tool-options] [ ...] analizo to I means that I depends on I. =head1 SEE ALSO B, B, B, B =head1 COPYRIGHT AND AUTHORS See B. =cut 1; Analizo-1.25.5/lib/Analizo/Command/metrics.pm0000644000175000017500000001166614676555272020313 0ustar joeniojoeniopackage Analizo::Command::metrics; use Analizo -command; use parent qw(Analizo::Command); use strict; use warnings; use Analizo::Metrics; use Analizo::Batch::Job::Directories; use File::Basename; # ABSTRACT: analizo's metric reporting tool =head1 NAME analizo-metrics - analizo's metric reporting tool =head1 USAGE analizo metrics [OPTIONS] [] =cut sub usage_desc { "%c metrics %o []" } sub opt_spec { my ($class, $app) = @_; return ( [ 'list|l', 'displays metric list' ], [ 'extractor=s', 'which extractor method use to parse the source code' ], [ 'globalonly|global-only|g', 'only output global (project-wide) metrics' ], [ 'output|o=s', 'output file name' ], [ 'language=s', 'process only filenames matching known extensions for the > programming' ], [ 'exclude|x=s', 'exclude (a colon-separated list of directories) from the analysis' ], [ 'includedirs|I=s', 'include (a colon-separated list of directories) with C/C++ header files', { default => '.' } ], [ 'libdirs|L=s', 'include (a colon-separated list of directories) with C/C++ static and dynamic libraries files', { default => '.' } ], [ 'libs=s', 'include (a colon-separated list of directories) with C/C++ linked libraries files', { default => '.' } ], ); } sub validate { my ($self, $opt, $args) = @_; if (@$args > 1) { $self->usage_error('No more than one is suported'); } my @unreadable = grep { ! -r $_ || ! -e $_ } @$args; if (@unreadable) { foreach my $file (@unreadable) { $self->usage_error("Input '$file' is not readable"); } } if ($opt->output && ! -w dirname($opt->output)) { $self->usage_error("No such file or directory"); } } sub execute { my ($self, $opt, $args) = @_; if($opt->list){ my $metrics_handler = Analizo::Metrics->new(model => Analizo::Model->new); my %metrics = $metrics_handler->list_of_metrics(); my %global_metrics = $metrics_handler->list_of_global_metrics(); print "Global Metrics:\n"; foreach my $key (sort keys %global_metrics){ print "$key - $global_metrics{$key}\n"; } print "\nModule Metrics:\n"; foreach my $key (sort keys %metrics){ print "$key - $metrics{$key}\n"; } exit 0; } my $tree = $args->[0] || '.'; my $job = Analizo::Batch::Job::Directories->new($tree); $job->extractor($opt->extractor); if ($opt->language) { require Analizo::LanguageFilter; if ($opt->language eq 'list') { my @language_list = Analizo::LanguageFilter->list; print "Languages:\n"; $" = "\n"; print "@language_list\n"; exit 0; } my $language_filter = Analizo::LanguageFilter->new($opt->language); $job->filters($language_filter); } if ($opt->exclude) { my @excluded_directories = split(':', $opt->exclude); $job->exclude(@excluded_directories); } $job->includedirs($opt->includedirs); $job->libdirs($opt->libdirs); $job->libs($opt->libs); $job->execute(); my $metrics = $job->metrics; if ($opt->output) { open STDOUT, '>', $opt->output or die "$!\n"; } if ($opt->globalonly) { print $metrics->report_global_metrics_only; } else { print $metrics->report; } close STDOUT; } =head1 DESCRIPTION analizo metrics analyzes source code in I and produces a metrics report. If I is omitted, the current directory (I<.>) is assumed. The produced report is written to the standard output, or to a file using the I<--output> option, using the YAML format (see I) analizo metrics is part of the analizo suite. =head1 OPTIONS =over =item Tells analizo which source code directory you want to parse. =item --extractor Define which extractor method use to parse the source code. Default is Doxyparse. When using the Doxyparse extractor (default), all files matching the languages supported by doxyparse are processed, unless I<--language> is used. =item --list, -l Displays metric list. =item --output , -o Writes the output to instead of standard output. =item --globalonly, --global-only, -g Don't output the details about modules: only output global (project-wide) metrics. =item --language Process only filenames matching known extensions for the > programming language. To see which languages are supported, pass B<--language list>. =item --exclude , -x Exclude > (a colon-separated list of directories) from the analysis. This is useful, for example, when you want to focus on production code and exclude test code from the analysis. You could do that by passing something like pass B<--exclude test>. =back =head1 OUTPUT FORMAT The output is a stream of YAML documents. The first one presents metrics for the project as a whole. The subsequent ones present per-module metrics, and thus there will be as many of them as there are modules in your project. =head1 COPYRIGHT AND AUTHORS See B. =cut 1; Analizo-1.25.5/lib/Analizo/Command/files_graph.pm0000644000175000017500000000474514676555272021130 0ustar joeniojoeniopackage Analizo::Command::files_graph; use Analizo -command; use parent qw(Analizo::Command); use strict; use warnings; use Analizo::Extractor; use Graph::Writer::Dot; use File::Basename; # ABSTRACT: dependency graph generator among files =head1 NAME analizo-files-graph - dependency graph generator among files =head1 USAGE analizo files-graph [OPTIONS] [ [ ...]] =cut sub usage_desc { "%c files-graph %o [ [ ...]]" } sub command_names { qw/files-graph/ } sub opt_spec { return ( [ 'output|o=s', 'output file name' ], ); } sub validate { my ($self, $opt, $args) = @_; $self->usage_error("No input files!") unless @$args; my @unreadable = grep { ! -r $_ || ! -e $_ } @$args; if (@unreadable) { foreach my $file (@unreadable) { $self->usage_error("$file is not readable"); } } if ($opt->output && ! -w dirname($opt->output)) { $self->usage_error("No such file or directory"); } } sub execute { my ($self, $opt, $args) = @_; my $extractor = Analizo::Extractor->load('Doxyparse'); $extractor->process(@$args); my $graph = $extractor->model->files_graph; if ($opt->output) { open STDOUT, '>', $opt->output or die "$!"; } my $stdout = \*STDOUT; my $graph_writer = Graph::Writer::Dot->new; $graph_writer->write_graph($graph, $stdout); close STDOUT; } =head1 DESCRIPTION analizo files-graph reads the dependency information from one or more source code directories passed as arguments, and produces as output the graph of dependencies between the files of the software in the graphviz(1) format. analizo files-graph is part of the analizo suite and was implemented to represent the old analizo dsm output tool in a textual format, as the dsm tool is going to be removed from analizo suite. The dependency graph includes relationships among files including function calls, inheritances and attribute use. analizo files-graph is part of the analizo suite. =head1 REQUIRED ARGUMENTS =over =item ... The input directories (or files) with source code to be processed. Although you can pass individual files as input, this tool is more useful if you pass entire source directories. =back =head1 OPTIONS =over =item --output , -o Use a file as output =back =head1 VIEWING THE GRAPH See B. =head1 READING THE GRAPH See B. =head1 SEE ALSO B, B, B, B =head1 COPYRIGHT AND AUTHORS See B. =cut 1; Analizo-1.25.5/lib/Analizo/Command/metrics_batch.pm0000644000175000017500000000663514676555272021454 0ustar joeniojoeniopackage Analizo::Command::metrics_batch; use Analizo -command; use parent qw(Analizo::Command); use strict; use warnings; use Analizo::Batch::Directories; use Analizo::Batch::Output::CSV; use File::Basename; # ABSTRACT: processes several source code directories in batch =head1 NAME analizo-metrics-batch - processes several source code directories in batch =head1 USAGE analizo metrics-batch [OPTIONS] [ [ ...]] =cut sub usage_desc { "%c metrics-batch %o [ [ ...]]" } sub command_names { qw/metrics-batch/ } sub opt_spec { return ( [ 'output|o=s', 'output file name', { default => 'metrics.csv' } ], [ 'quiet|q', 'supresses messages to standard output' ], [ 'parallel|p=i', 'activates support for parallel processing' ], ); } sub validate { my ($self, $opt, $args) = @_; if ($opt->output && ! -w dirname($opt->output)) { $self->usage_error("Output is not writable!"); } } sub execute { my ($self, $opt, $args) = @_; my $runner = undef; if ($opt->parallel) { require Analizo::Batch::Runner::Parallel; $runner = Analizo::Batch::Runner::Parallel->new($opt->parallel); } else { require Analizo::Batch::Runner::Sequential; $runner = Analizo::Batch::Runner::Sequential->new; } unless ($opt->quiet) { $runner->progress( sub { my ($job, $done, $total) = @_; printf("I: Processed %s.\n", $job->id); } ); } my $batch = Analizo::Batch::Directories->new(@$args); my $output = Analizo::Batch::Output::CSV->new; $output->file($opt->output); $runner->run($batch, $output); } =head1 DESCRIPTION Processes several source code directories in batch running B for each and optionally consolidating the results in a single data file. B is useful when you want to analyze several projects at once, or several different versions of the same project. You pass a list of directories in the command line and each one will be analyzed as a separate project. If no directories are passed in the command line, all of the subdirectories of the current directory will be analized. For example, suppose you want to process 5 consecutive releases of I, from version 0.1.0 to 0.5.0. =over =item First you unpack the release tarballs for those versions in a directory, say /tmp/analysis: $ ls -1 /tmp/analysis myproject-0.1.0 myproject-0.2.0 myproject-0.3.0 myproject-0.4.0 myproject-0.5.0 =item Then you change to that directory, and then run B: $ cd /tmp/analysis $ analizo metrics-batch =item B will collect the metrics data in a single .csv file, that you can import in spreadsheet software or statistical packages. =back analizo metrics-batch is part of the analizo suite. =head1 OPTIONS =over =item --parallel N, -p N Activates support for parallel processing, using I concurrent worker processes. Usually you will want N to be less than or equal to the number of CPUs in your machine. Note that analizo metrics extraction is a CPU-intensive process, so setting N as the exactly number of CPUs you have may bring your machine to an unusable state. =item --output , -o Write output to . Default is to write to I. That file can then be opened in data analysis programs. =item --quiet, -q Suppresses messages to standard output. =back =head1 COPYRIGHT AND AUTHORS See B. =cut 1; Analizo-1.25.5/lib/Analizo/Command/tree_evolution.pm0000644000175000017500000000556514676555272021711 0ustar joeniojoeniopackage Analizo::Command::tree_evolution; use Analizo -command; use parent qw(Analizo::Command); use strict; use warnings; use Digest::SHA qw(sha1_hex); use File::Basename; use Analizo::LanguageFilter; #ABSTRACT: watch the evolution of the source code =head1 NAME analizo-tree-evolution - watch the evolution of the source code =head1 USAGE analizo tree-evolution [OPTIONS] =cut sub command_names { qw/tree-evolution/ } sub opt_spec { return ( [ 'language|l=s', 'filters the source tree by language', { default => 'all' } ], ); } sub validate {} sub execute { my ($self, $opt, $args) = @_; my $filter = Analizo::LanguageFilter->new($opt->language); local $ENV{PATH} = '/usr/local/bin:/usr/bin:/bin'; open COMMITS, "git log --reverse --format=%H|"; my @commits = ; chomp @commits; close COMMITS; my %trees = (); for my $commit (@commits) { my @tree = `git ls-tree -r --name-only $commit`; chomp(@tree); my %dirs = map { dirname($_) => 1 } (grep { $filter->matches($_) } @tree); @tree = sort(grep { $_ ne '.' } keys(%dirs)); next unless (@tree); my $tree = join("\n", @tree); my $sha1 = sha1_hex($tree); if (!exists($trees{$sha1})) { print "# $commit\n"; print $tree, "\n"; $trees{$sha1} = 1; } } } 1; =head1 DESCRIPTION Watch the evolution of the source code tree in a Git repository. When run inside a Git repository, B will output all different sets of directories found in the project's history. For each commit in which a new directory was added or removed, you will have the commit hash and a snapshot of the source code tree at that commit. For example, consider the following sample execution of B against a sample Git repository: $ analizo tree-evolution # 073290fbad0254793bd3ecfb97654c04368d0039 src # 85f7db08f7b7b0b62e3c0023b2743d529b0d5b4b src src/input # f41cf7d0351e812285efd60c6d957c330b1f61a1 src src/input src/output The output shows us the following information: =over =item Commit I<073290fbad0254793bd3ecfb97654c04368d0039> was the first commit in the project, and back then the project had a "src" directory. =item In commit I<85f7db08f7b7b0b62e3c0023b2743d529b0d5b4b>, a directory called src/input was added to the tree. =item Finally, commit I introduced another directory called src/output. =back analizo tree-evolution is part of the analizo suite. =head1 OPTIONS =over =item --language LANGUAGE, -l LANGUAGE Filters the source tree by language. When determining the contents of the source tree, only consider directories that contain files that match the expected file extensions for LANGUAGE. LANGUAGE can be one of I, I and I. The default behaviour is to consider all files in the repository. =back =head1 COPYRIGHT AND AUTHORS See B. =cut Analizo-1.25.5/lib/Analizo/Command/metrics_history.pm0000644000175000017500000001436214676555272022070 0ustar joeniojoeniopackage Analizo::Command::metrics_history; use Analizo -command; use parent qw(Analizo::Command); use strict; use warnings; use Analizo::Batch::Git; #ABSTRACT: processes a Git repository collection metrics =head1 NAME analizo-metrics-history - processes a Git repository collection metrics =head1 USAGE analizo metrics-history [OPTIONS] [] =cut sub usage_desc { "%c metrics-history %o []" } sub command_names { qw/metrics-history/ } sub opt_spec { return ( [ 'output|o=s', 'output file name' ], [ 'list|l', 'just print out the ids of the commits that would be processed '], [ 'language=s', 'process only filenames matching known extensions for the programming' ], [ 'exclude|x=s', 'exclude (a colon-separated list of directories) from the analysis' ], [ 'parallel|p=i', 'activates support for parallel processing' ], [ 'format|f=s', 'specifies the output format', { default => 'csv' } ], [ 'progressbar|b', 'displays a progress bar during the execution' ], ); } sub validate { my ($self, $opt, $args) = @_; unless ($self->output_driver($opt->format)) { $self->usage_error("Invalid output driver " . $opt->format); } } sub output_driver { my ($self, $format) = @_; my %available_outputs = ( csv => 'Analizo::Batch::Output::CSV', db => 'Analizo::Batch::Output::DB', ); $available_outputs{$format}; } sub load_output_driver { my ($self, $format) = @_; my $output_driver = $self->output_driver($format); eval "require $output_driver"; return $output_driver->new; } sub execute { my ($self, $opt, $args) = @_; my $batch = Analizo::Batch::Git->new(@$args); if ($opt->list) { while (my $job = $batch->next()) { print $job->id, "\n"; } exit 0; } if ($opt->language) { require Analizo::LanguageFilter; my $language_filter = Analizo::LanguageFilter->new($opt->language); $batch->filters($language_filter); } if ($opt->exclude) { my @excluded_directories = split(':', $opt->exclude); $batch->exclude(@excluded_directories); } my $output = $self->load_output_driver($opt->format); if ($opt->output) { $output->file($opt->output); } my $runner = undef; if ($opt->parallel) { require Analizo::Batch::Runner::Parallel; $runner = Analizo::Batch::Runner::Parallel->new($opt->parallel); } else { require Analizo::Batch::Runner::Sequential; $runner = Analizo::Batch::Runner::Sequential->new; } if ($opt->progressbar) { require Term::ProgressBar; my $progressbar = Term::ProgressBar->new({ count => 100, ETA => 'linear' }); $runner->progress( sub { my ($job, $done, $total) = @_; $progressbar->update(100 * $done / $total); } ); } $runner->run($batch, $output); } 1; =head1 DESCRIPTION Processes a Git repository collection metrics for every single revision. B will process I, a Git repository with a working copy of the source code (i.e. not a bare git repository), checkout every relevant commit and run B on it. The metrics for all of the revisions will be accumulated in a file called I inside I. If I is omitted, the current directory (.) s assumed. analizo metrics-history is part of the analizo suite. =head1 RELEVANT COMMITS B considers as relevant the commits that changed at least one source code file. Consequently, it skips all the commits where no source code file was changed, such as documentation, translations, build system changes, etc. Currently we support C, C++, Java and C# projects, and therefore files considered source code are the ones terminated in I<.c>, I<.h>, I<.cpp>, I<.cxx>, I<.cc>, I<.hh>, I<.hpp>, I<.java> and I<.cs>. =head1 OPTIONS =over =item --parallel N, -p N Activates support for parallel processing, using I concurrent worker processes. Usually you will want N to be less than or equal to the number of CPUs in your machine. Note that analizo metrics extraction is a CPU-intensive process, so setting N as the exactly number of CPUs you have may bring your machine to an unusable state. =item --language LANGUAGE, --exclude DIRECTORY Use programming language and directory exclusion filters. See B for a description of these options. =item --output , -o Make the output be written to I. The default value and valid values depend on the output format, see "Output formats" below. =item --format FORMAT, -f FORMAT Specifies with output driver, and consequently the output format, to use. See "Output Formats" below for a description of the available output drivers. =item --list, -l Instead of actually processing the history, just print out the ids of the commits that would be processed. =item --progressbar, -b Displays a progress bar during the execution, so that you know approximately how long analizo is going to take to finish. =back =head1 Output formats Using the I<--format> option, you can use the following output drivers: =head2 csv This is the default output driver. By default, the output will be written to the standard output. If can direct the output to a file using the I<--output> option. =head2 db Stores the extracted data in a relational database. When you use this driver, you can specify where exactly to store the data using the I<--output> option. If you do not specify an explicit target, analizo will write to a SQLite database in a file called I in the current directory. If you pass a filename, and analizo will store the data in a SQLite database that will be created on that file. You can direct the output to any other database by using I<--output DSN>, where I is a DBI Data Source Name. You can check B(3pm) for details. Note that if you a database other than SQLite, you must make sure that you have the corresponding DBI driver installed. Examples: B<$ analizo metrics-history -f db -o history.db> Writes the output to a SQLite database called I. B<$ analizo metrics-history -f db -o 'dbi:Pg:dbname=pgdb'> Writes the data to a PostgreSQL database called I. This requires the I Perl module. analizo was not tested with MySQL yet. =head1 SEE ALSO B =head1 COPYRIGHT AND AUTHORS See B. =cut Analizo-1.25.5/lib/Analizo/ModuleMetrics.pm0000644000175000017500000000624714676555272020042 0ustar joeniojoeniopackage Analizo::ModuleMetrics; use strict; use parent qw(Class::Accessor::Fast); use Analizo::Metric::AfferentConnections; use Analizo::Metric::AverageCycloComplexity; use Analizo::Metric::AverageMethodLinesOfCode; use Analizo::Metric::AverageNumberOfParameters; use Analizo::Metric::CouplingBetweenObjects; use Analizo::Metric::DepthOfInheritanceTree; use Analizo::Metric::LackOfCohesionOfMethods; use Analizo::Metric::LinesOfCode; use Analizo::Metric::MaximumMethodLinesOfCode; use Analizo::Metric::NumberOfAttributes; use Analizo::Metric::NumberOfChildren; use Analizo::Metric::NumberOfMethods; use Analizo::Metric::NumberOfPublicAttributes; use Analizo::Metric::NumberOfPublicMethods; use Analizo::Metric::ResponseForClass; use Analizo::Metric::StructuralComplexity; __PACKAGE__->mk_accessors(qw(model metric_calculators)); sub new { my ($package, %args) = @_; my @instance_variables = ( model => $args{model}, metric_calculators => _initialize_metric_calculators($args{model}) ); return bless { @instance_variables }, $package; } sub _initialize_metric_calculators { my ($model) = @_; my $cbo = Analizo::Metric::CouplingBetweenObjects->new(model => $model); my $lcom4 = Analizo::Metric::LackOfCohesionOfMethods->new(model => $model); my %calculators = ( acc => Analizo::Metric::AfferentConnections->new(model => $model), accm => Analizo::Metric::AverageCycloComplexity->new(model => $model), amloc => Analizo::Metric::AverageMethodLinesOfCode->new(model => $model), anpm => Analizo::Metric::AverageNumberOfParameters->new(model => $model), cbo => $cbo, dit => Analizo::Metric::DepthOfInheritanceTree->new(model => $model), lcom4 => $lcom4, loc => Analizo::Metric::LinesOfCode->new(model => $model), mmloc => Analizo::Metric::MaximumMethodLinesOfCode->new(model => $model), noa => Analizo::Metric::NumberOfAttributes->new(model => $model), noc => Analizo::Metric::NumberOfChildren->new(model => $model), nom => Analizo::Metric::NumberOfMethods->new(model => $model), npm => Analizo::Metric::NumberOfPublicMethods->new(model => $model), npa => Analizo::Metric::NumberOfPublicAttributes->new(model => $model), rfc => Analizo::Metric::ResponseForClass->new(model => $model), sc => Analizo::Metric::StructuralComplexity->new(model => $model, cbo => $cbo, lcom4 => $lcom4), ); return \%calculators; } sub list { my ($self) = @_; my %list = (); for my $metric (keys %{$self->metric_calculators}) { $list{$metric} = $self->metric_calculators->{$metric}->description; } return %list; } sub report { my ($self, $module) = @_; my %values = (); $values{'_module'} = $module; for my $metric (keys %{$self->metric_calculators}) { my $value = $self->metric_calculators->{$metric}->value($module); $values{$metric} = $value; } #FIXME: move to another function $self->model->files($module); return \%values; } 1; Analizo-1.25.5/lib/Analizo/GlobalMetrics.pm0000644000175000017500000001302114676555272020001 0ustar joeniojoeniopackage Analizo::GlobalMetrics; use strict; use parent qw(Class::Accessor::Fast); use Analizo::GlobalMetric::TotalAbstractClasses; use Analizo::GlobalMetric::MethodsPerAbstractClass; use Analizo::GlobalMetric::ChangeCost; use Statistics::Descriptive; __PACKAGE__->mk_accessors(qw( model calculators metric_report values_lists module_metrics_list )); sub new { my ($package, %args) = @_; my @instance_variables = ( model => $args{model}, calculators => _initialize_calculators($args{model}), metric_report => _initialize_metric_report(), values_lists => {}, ); return bless { @instance_variables }, $package; } sub _initialize_calculators { my ($model) = @_; my %calculators = ( total_abstract_classes => Analizo::GlobalMetric::TotalAbstractClasses->new(model => $model), total_methods_per_abstract_class => Analizo::GlobalMetric::MethodsPerAbstractClass->new(model => $model), change_cost => Analizo::GlobalMetric::ChangeCost->new(model => $model), ); return \%calculators; } sub _initialize_metric_report { my %metric_report = ( total_modules => 0, total_modules_with_defined_methods => 0, total_modules_with_defined_attributes => 0, total_nom => 0, total_loc => 0, total_cof => 0 ); return \%metric_report; } sub list { my ($self) = @_; my %list = ( total_cof => "Total Coupling Factor", total_modules => "Total Number of Modules", total_nom => "Total Number of Methods", total_loc => "Total Lines of Code", total_modules_with_defined_methods => "Total number of modules with at least one defined method", total_modules_with_defined_attributes => "Total number of modules with at least one defined attributes" ); for my $metric (keys %{$self->calculators}) { $list{$metric} = $self->calculators->{$metric}->description; } return %list; } sub add_module_values { my ($self, $values) = @_; $self->_update_metric_report($values); $self->_add_values_to_values_lists($values); } sub _update_metric_report { my ($self, $values) = @_; $self->metric_report->{'total_modules'} += 1; $self->metric_report->{'total_modules_with_defined_methods'} += 1 if $values->{'nom'} > 0; $self->metric_report->{'total_modules_with_defined_attributes'} += 1 if $values->{'noa'} > 0; $self->metric_report->{'total_nom'} += $values->{'nom'}; $self->metric_report->{'total_loc'} += $values->{'loc'}; } sub _add_values_to_values_lists { my ($self, $values) = @_; for my $metric (keys %{$values}) { $self->_add_metric_value_to_values_list($metric, $values->{$metric}); } } sub _add_metric_value_to_values_list { my ($self, $metric, $metric_value) = @_; if( $metric ne '_module' && $metric ne '_filename' ) { $self->values_lists->{$metric} = [] unless ($self->values_lists->{$metric}); push @{$self->values_lists->{$metric}}, $metric_value; } } sub report { my ($self) = @_; $self->_include_metrics_from_calculators; $self->_add_statistics; $self->_add_total_coupling_factor; return \%{$self->metric_report}; } sub _include_metrics_from_calculators { my ($self) = @_; for my $metric (keys %{$self->calculators}) { $self->metric_report->{$metric} = $self->calculators->{$metric}->calculate(); } } sub _add_statistics { my ($self) = @_; for my $metric (keys %{$self->values_lists}) { my $statistics = Statistics::Descriptive::Full->new(); $statistics->add_data(@{$self->values_lists->{$metric}}); $self->_add_descriptive_statistics($metric, $statistics); $self->_add_distributions_statistics($metric, $statistics); } } sub _add_descriptive_statistics { my ($self, $metric, $statistics) = @_; $self->metric_report->{$metric . "_mean"} = $statistics->mean(); $self->metric_report->{$metric . "_mode"} = $statistics->mode(); $self->metric_report->{$metric . "_standard_deviation"} = $statistics->standard_deviation(); $self->metric_report->{$metric . "_sum"} = $statistics->sum(); $self->metric_report->{$metric . "_variance"} = $statistics->variance(); $self->metric_report->{$metric . "_quantile_min"} = $statistics->min(); #minimum $self->metric_report->{$metric . "_quantile_lower"} = $statistics->quantile(1); #lower quartile $self->metric_report->{$metric . "_quantile_median"} = $statistics->median(); #median $self->metric_report->{$metric . "_quantile_upper"} = $statistics->quantile(3); #upper quartile $self->metric_report->{$metric . "_quantile_ninety_five"} = $statistics->percentile(95); #95th percentile $self->metric_report->{$metric . "_quantile_max"} = $statistics->max(); #maximum } sub _add_distributions_statistics { my ($self, $metric, $statistics) = @_; if (($statistics->count >= 4) && ($statistics->variance() > 0)) { $self->metric_report->{$metric . "_kurtosis"} = $statistics->kurtosis(); $self->metric_report->{$metric . "_skewness"} = $statistics->skewness(); } else { $self->metric_report->{$metric . "_kurtosis"} = 0; $self->metric_report->{$metric . "_skewness"} = 0; } } sub _add_total_coupling_factor { my ($self) = @_; my $total_modules = $self->metric_report->{'total_modules'}; my $total_acc = $self->metric_report->{'acc_sum'}; $self->metric_report->{"total_cof"} = $self->coupling_factor($total_acc, $total_modules); } sub coupling_factor { my ($self, $total_acc, $total_modules) = @_; return ($total_modules > 1) ? $total_acc / _number_of_combinations($total_modules) : 1; } sub _number_of_combinations { my ($total_modules) = @_; return $total_modules * ($total_modules - 1); } 1; Analizo-1.25.5/lib/Analizo/Filter/0000775000175000017500000000000014676555272016146 5ustar joeniojoenioAnalizo-1.25.5/lib/Analizo/Filter/Client.pm0000644000175000017500000000233714676555272017725 0ustar joeniojoeniopackage Analizo::Filter::Client; use File::Find; sub filters { my ($self, @new_filters) = @_; $self->{filters} ||= []; if (@new_filters) { push @{$self->{filters}}, @new_filters; } return $self->{filters}; } sub has_filters { my ($self) = @_; return exists($self->{filters}) && exists($self->{filters}->[0]); } sub share_filters_with($$) { my ($self, $other) = @_; $other->{filters} = $self->{filters}; } sub exclude { my ($self, @dirs) = @_; if (!$self->{excluding_dirs}) { $self->{excluding_dirs} = 1; $self->filters(Analizo::LanguageFilter->new); } $self->filters(Analizo::FilenameFilter->exclude(@dirs)); } sub filename_matches_filters { my ($self, $filename) = @_; for my $filter (@{$self->filters}) { unless ($filter->matches($filename)) { return 0; } } return 1; } sub apply_filters { my ($self, @input) = @_; unless ($self->has_filters) { # By default, only look at supported languages $self->filters(Analizo::LanguageFilter->new('all')); } my @result = (); for my $input (@input) { find( { wanted => sub { push @result, $_ if !-d $_ && $self->filename_matches_filters($_); }, no_chdir => 1 }, $input ); } return @result; } 1; Analizo-1.25.5/lib/Analizo/FilenameFilter.pm0000644000175000017500000000077714676555272020156 0ustar joeniojoeniopackage Analizo::FilenameFilter; use strict; use warnings; sub new { my ($package, @options) = @_; my $self = { regex => '.', reverse => 0, @options }; return bless $self, __PACKAGE__; } sub exclude { my ($package, @paths) = @_; my $regex = sprintf("^(./)?(%s)", join('|', @paths)); return $package->new(regex => $regex, reverse => 1); } sub matches { my ($self, $filename) = @_; my $match = ($filename =~ /$self->{regex}/); return $self->{reverse} ? !$match : $match; } 1; Analizo-1.25.5/lib/Analizo/LanguageFilter.pm0000644000175000017500000000121114676555272020141 0ustar joeniojoeniopackage Analizo::LanguageFilter; use strict; use warnings; use Carp; use parent qw(Analizo::FilenameFilter); our $FILTERS = { c => 'c|h', cpp => 'cpp|cxx|cc|h|hh|hpp', java => 'java', csharp => 'cs', }; $FILTERS->{all} = join('|', values(%$FILTERS)); sub new { my ($package, $filter_type) = @_; $filter_type ||= 'all'; my $regex = $FILTERS->{$filter_type}; if (!defined($regex)) { croak "E: Unknown language filter $filter_type"; } my $self = { regex => '\.(' . $regex . '|' . uc($regex) . ')$', }; return bless $self, $package; } sub list { my ($self) = @_; sort keys %$FILTERS; } 1; Analizo-1.25.5/lib/Analizo/Metric/0000775000175000017500000000000014676555272016144 5ustar joeniojoenioAnalizo-1.25.5/lib/Analizo/Metric/LinesOfCode.pm0000644000175000017500000000255014676555272020634 0ustar joeniojoeniopackage Analizo::Metric::LinesOfCode; use strict; use parent qw(Class::Accessor::Fast Analizo::ModuleMetric); use Statistics::Descriptive; =head1 NAME Analizo::Metric::LinesOfCode - Lines of Code (LOC) metric =head1 DESCRIPTION The metric calculation is based on the following article and calculates the program size in lines of code, excluding blank lines and comments. Article: I by Taghi M. Khoshgoftaar and John C. Munson. See the paragraph about Lines of Code in the article: A description of the specific quantitative complexity data collected for each program is as follows: ... program size in lines of code (non-comment, non-blank lines) in program (LOC). =cut __PACKAGE__->mk_accessors(qw( model )); sub new { my ($package, %args) = @_; my @instance_variables = ( model => $args{model} ); return bless { @instance_variables }, $package; } sub description { return "Lines of Code"; } sub calculate { my ($self, $module) = @_; my @functions = $self->model->functions($module); if (scalar(@functions) == 0) { return 0; } my $statisticalCalculator = Statistics::Descriptive::Full->new(); for my $function (@functions) { $statisticalCalculator->add_data($self->model->{lines}->{$function} || 0); } return $statisticalCalculator->sum(); } 1; Analizo-1.25.5/lib/Analizo/Metric/NumberOfMethods.pm0000644000175000017500000000240414676555272021541 0ustar joeniojoeniopackage Analizo::Metric::NumberOfMethods; use strict; use parent qw(Class::Accessor::Fast Analizo::ModuleMetric); =head1 NAME Analizo::Metric::NumberOfMethods - Number of Methods (NOM) metric =head1 DESCRIPTION The metric calculation is based on the following article and calculates the number of methods per class to measure the size of the classes in terms of its implemented operations. Article: I by Paulo Roberto Miranda Meirelles. See the adaptation of the paragraph about Number of Methods in the article: ... This metric is used to help to identify the potential reuse of a class. In general, the classes with a large number of methods are harder to be reused, because they are more likely to be less cohesive (Lorenz and Kidd, 1994). Thus, it's recommended that a class don't have a excessive number of methods (Beck, 1997). =cut __PACKAGE__->mk_accessors(qw( model )); sub new { my ($package, %args) = @_; my @instance_variables = ( model => $args{model} ); return bless { @instance_variables }, $package; } sub description { return "Number of Methods"; } sub calculate { my ($self, $module) = @_; my @functions = $self->model->functions($module); return scalar(@functions); } 1; Analizo-1.25.5/lib/Analizo/Metric/NumberOfChildren.pm0000644000175000017500000000337014676555272021671 0ustar joeniojoeniopackage Analizo::Metric::NumberOfChildren; use strict; use parent qw(Class::Accessor::Fast Analizo::ModuleMetric); =head1 NAME Analizo::Metric::NumberOfChildren - Number of Children (NOC) metric =head1 DESCRIPTION The metric calculation is based on the following article and calculates the number of immediate subclasses subordinate to a class in the hierarchy. Article: I by Linda H. Rosenberg and Lawrence E. Hyatt. See the paragraph about Number of Children in the article: The number of children is the number of immediate subclasses subordinate to a class in the hierarchy. It is an indicator of the potential influence a class can have on the design and on the system. The greater the number of children, the greater the likelihood of improper abstraction of the parent and may be a case of misuse of subclassing. But the greater the number of children, the greater the reusability since inheritance is a form of reuse. If a class has a large number of children, it may require more testing of the methods of that class, thus increase the testing time. =cut __PACKAGE__->mk_accessors(qw( model )); sub new { my ($package, %args) = @_; my @instance_variables = ( model => $args{model} ); return bless { @instance_variables }, $package; } sub description { return "Number of Children"; } sub calculate { my ($self, $module) = @_; my $number_of_children = 0; for my $other_module ($self->model->module_names) { $number_of_children++ if ($self->_module_parent_of_other($module, $other_module)); } return $number_of_children; } sub _module_parent_of_other { my ($self, $module, $other_module) = @_; return grep {$_ eq $module} $self->model->inheritance($other_module); } 1; Analizo-1.25.5/lib/Analizo/Metric/ResponseForClass.pm0000644000175000017500000000333314676555272021735 0ustar joeniojoeniopackage Analizo::Metric::ResponseForClass; use strict; use parent qw(Class::Accessor::Fast Analizo::ModuleMetric); =head1 NAME Analizo::Metric::ResponseForClass - Response for Class (RFC) metric =head1 DESCRIPTION The metric calculation is based on the following article and calculates the sum between the number of methods in the module and the number of functions called by each module function. Article: I by Shyam R. Chidamber and Chris F. Kemerer. See the paragraph about Response for Class in the article: ... The response set of a class is a set of methods that can potentially be executed in response to a message received by an object of that class. The cardinality of this set is a measure of the attributes of objects in the class. Since it specifically includes methods called from outside the class, it is also a measure of the potential communication between the class and other classes. =cut __PACKAGE__->mk_accessors(qw( model )); sub new { my ($package, %args) = @_; my @instance_variables = ( model => $args{model} ); return bless { @instance_variables }, $package; } sub description { return "Response for a Class"; } sub calculate { my ($self, $module) = @_; my @functions = $self->model->functions($module); my $number_of_functions = scalar @functions; my $number_of_functions_called_by_module_functions = $self->_number_of_functions_called_by(@functions); return $number_of_functions + $number_of_functions_called_by_module_functions; } sub _number_of_functions_called_by { my ($self, @functions) = @_; my $count = 0; for my $function (@functions){ $count += scalar keys(%{$self->model->calls->{$function}}); } return $count; } 1; Analizo-1.25.5/lib/Analizo/Metric/NumberOfAttributes.pm0000644000175000017500000000224514676555272022267 0ustar joeniojoeniopackage Analizo::Metric::NumberOfAttributes; use strict; use parent qw(Class::Accessor::Fast Analizo::ModuleMetric); =head1 NAME Analizo::Metric::NumerOfAttributes - Number of Attributes (NOA) metric =head1 DESCRIPTION The metric calculation is based on the following article and calculates the number of attributes of a class. Article: I by Paulo Roberto Miranda Meirelles. See the adaptation of the paragraph about Number of Attributes in the article: Calculates the number of attributes of a class. Its minimum value is zero and there is no upper limit to its result. A class with many attributes may indicate that it has many responsibilities and presents a low cohesion, i. e., is probably dealing with several different subjects. =cut __PACKAGE__->mk_accessors(qw( model )); sub new { my ($package, %args) = @_; my @instance_variables = ( model => $args{model} ); return bless { @instance_variables }, $package; } sub description { return "Number of Attributes"; } sub calculate { my ($self, $module) = @_; my @variables = $self->model->variables($module); return scalar(@variables); } 1; Analizo-1.25.5/lib/Analizo/Metric/AfferentConnections.pm0000644000175000017500000000342614676555272022442 0ustar joeniojoeniopackage Analizo::Metric::AfferentConnections; use strict; use parent qw(Class::Accessor::Fast Analizo::ModuleMetric); =head1 NAME Analizo::Metric::AfferentConnections - Afferent Connections per Class (ACC) metric =head1 DESCRIPTION The metric calculation is based on the following article and calculates the class connectivity. PhD Thesis: I by Paulo Roberto Miranda Meirelles. See the adaptation of the paragraph about Afferent Connections per Class in the article: Measures the connectivity of a class. If a class C access a method or attribute of a class C, consider C a client of the supplier class C, denoting C<< Ci => Cj >>. Consider the follow function: client(Ci, Cj) = 1, if (Ci => Cj) and (Ci != Cj) client(Ci, Cj) = 0, otherwise. So C, where C is the total number of system classes. If the value of this metric is large, a change in the class has substantially more side effects, making maintenance more difficult. =head1 REFERENCES =over =item * L =back =cut __PACKAGE__->mk_accessors(qw( model analized_module)); sub new { my ($package, %args) = @_; my @instance_variables = ( model => $args{model}, analized_modules => undef ); return bless { @instance_variables }, $package; } sub description { return 'Afferent Connections per Class (used to calculate COF - Coupling Factor)'; } sub calculate { my ($self, $module) = @_; $self->analized_module($module); my $acc_result = $self->model->modules_graph->in_degree($module); return $acc_result ? $acc_result : 0; } 1; Analizo-1.25.5/lib/Analizo/Metric/StructuralComplexity.pm0000644000175000017500000000250714676555272022732 0ustar joeniojoeniopackage Analizo::Metric::StructuralComplexity; use strict; use parent qw(Class::Accessor::Fast Analizo::ModuleMetric); use Analizo::Metric::CouplingBetweenObjects; use Analizo::Metric::LackOfCohesionOfMethods; =head1 NAME Analizo::Metric::StructuralComplexity - Structural Complexity (SC) metric =head1 DESCRIPTION The metric calculation is based on the following article and calculates the structural complexity. Article: I by Paulo Roberto Miranda Meirelles. See the adaptation of the paragraph about Structural Complexity in the article: When combined with a metric, the coupling and cohesion product is positively correlated to the maintenance effort. Therefore, we use in this PhD research the coupling product (CBO) and cohesion (LCOM4) as our structural complexity metric (Darcy et al., 2005). =cut __PACKAGE__->mk_accessors(qw( model cbo lcom4 )); sub new { my ($package, %args) = @_; my @instance_variables = ( model => $args{model}, cbo => $args{cbo}, lcom4 => $args{lcom4}, ); return bless { @instance_variables }, $package; } sub description { return "Structural Complexity"; } sub calculate { my ($self, $module) = @_; my $cbo = $self->cbo->value($module); my $lcom4 = $self->lcom4->value($module); return ($cbo * $lcom4); } 1; Analizo-1.25.5/lib/Analizo/Metric/NumberOfPublicMethods.pm0000644000175000017500000000264614676555272022710 0ustar joeniojoeniopackage Analizo::Metric::NumberOfPublicMethods; use strict; use parent qw(Class::Accessor::Fast Analizo::ModuleMetric); =head1 NAME Analizo::Metric::NumerOfPublicMethods - Number of Public Methods (NPM) metric =head1 DESCRIPTION The metric calculation is based on the following article and calculates the number of public methods of a class. Article: I by Paulo Roberto Miranda Meirelles. See the adaptation of the paragraph about Number of Public Methods in the article: Represents the size of the "interface" of the class. Methods are directly related to the operations provided in the respective class. High values for this metric indicate that a class has many methods and probably many responsibilities, which conflicts with good programming practices (Beck, 1997). =cut __PACKAGE__->mk_accessors(qw( model )); sub new { my ($package, %args) = @_; my @instance_variables = ( model => $args{model} ); return bless { @instance_variables }, $package; } sub description { return "Number of Public Methods"; } sub calculate { my ($self, $module) = @_; my $count = 0; for my $function ($self->model->functions($module)) { $count += 1 if $self->_is_public($function); } return $count; } sub _is_public { my ($self, $function) = @_; return $self->model->{protection}->{$function} && $self->model->{protection}->{$function} eq "public"; } 1; Analizo-1.25.5/lib/Analizo/Metric/AverageCycloComplexity.pm0000644000175000017500000000343614676555272023130 0ustar joeniojoeniopackage Analizo::Metric::AverageCycloComplexity; use strict; use parent qw(Class::Accessor::Fast Analizo::ModuleMetric); use Statistics::Descriptive; =head1 NAME Analizo::Metric::AverageCycloComplexity - Average Cyclomatic Complexity per Method (ACCM) metric =head1 DESCRIPTION The metric calculation is based on the following article and calculates the cyclomatic complexity of the program. Article: I. The Average Cyclomatic Complexity per Method is calculated counting the predicates (i.e., decision points, or conditional paths) on each method plus one, then a mean of all methods is returned as the final value of ACCM. The cyclomatic complexity of a program represented as a graph can be calculated using a formula of graph theory: v(G) = e - n + 2 Where C is the number of edges and C is the number of nodes of the graph. Another good reference is: I. =cut __PACKAGE__->mk_accessors(qw( model )); sub new { my ($package, %args) = @_; my @instance_variables = ( model => $args{model} ); return bless { @instance_variables }, $package; } sub description { return 'Average Cyclomatic Complexity per Method'; } sub calculate { my ($self, $module) = @_; my @functions = $self->model->functions($module); if (scalar(@functions) == 0) { return 0; } my $statisticalCalculator = Statistics::Descriptive::Full->new(); for my $function (@functions) { $statisticalCalculator->add_data($self->model->{conditional_paths}->{$function} + 1); } return $statisticalCalculator->mean(); } 1; Analizo-1.25.5/lib/Analizo/Metric/CouplingBetweenObjects.pm0000644000175000017500000000427714676555272023116 0ustar joeniojoeniopackage Analizo::Metric::CouplingBetweenObjects; use strict; use parent qw(Class::Accessor::Fast Analizo::ModuleMetric); =head1 NAME Analizo::Metric::CouplingBetweenObjects - Coupling Between Objects (CBO) metric =head1 DESCRIPTION The metric calculation is based on the following article and calculates the number of calls to other modules. Article: I by Shyam R. Chidamber and Chris F. Kemerer. See the paragraph about Coupling Between Objects in the article: Theoretical Basis: CBO relates to the notion that an object is coupled to another object if one of them acts on the other, i.e., methods of one use method or instance variables of another. As stated earlier, since objects of the same class have the same properties, two classes are coupled when methods declared in on class use methods or instance variables defined by the other class. =cut __PACKAGE__->mk_accessors(qw( model analized_module calls_to )); sub new { my ($package, %args) = @_; my @instance_variables = ( model => $args{model}, analized_module => undef, calls_to => {}, ); return bless { @instance_variables }, $package; } sub description { return "Coupling Between Objects"; } sub calculate { my ($self, $module) = @_; $self->analized_module($module); $self->calls_to({}); my $number_of_calls_to_other_modules = $self->_number_of_calls_to_other_modules(); return $number_of_calls_to_other_modules; } sub _number_of_calls_to_other_modules { my ($self) = @_; for my $caller_function ($self->model->functions($self->analized_module)) { $self->_add_number_of_calls_to_other_modules($caller_function); } return (scalar keys(%{$self->calls_to})); } sub _add_number_of_calls_to_other_modules { my ($self, $caller_function) = @_; for my $called_function (keys(%{$self->model->calls->{$caller_function}})) { $self->_add_function_module_other_then_analized_module($called_function); } } sub _add_function_module_other_then_analized_module { my ($self, $called_function) = @_; my $called_module = $self->model->members->{$called_function}; $self->calls_to->{$called_module}++ if ($called_module && $called_module ne $self->analized_module); } 1; Analizo-1.25.5/lib/Analizo/Metric/DepthOfInheritanceTree.pm0000644000175000017500000000273214676555272023027 0ustar joeniojoeniopackage Analizo::Metric::DepthOfInheritanceTree; use strict; use parent qw(Class::Accessor::Fast Analizo::ModuleMetric); =head1 NAME Analizo::Metric::DepthOfInheritanceTree - Depth of Inheritance Tree (DIT) metric =head1 DESCRIPTION The metric calculation is based on the following article and calculates the longest path from a module to the class hierarchy root. Article: I by Eduardo Kessler Piveta, Ana Moreira, Marcelo Soares Pimenta, Joao Araujo, Pedro Guerreiro and R. Tom Price. See the adaptation of the paragraph about Depth of Inheritance Tree in the article: Considering a function C<< s(x) : Module -> Module >> that computes the super-class or super-aspect of a giver module, the value of DIT is given by: DIT(m) = DIT(s(m)) + 1, ifc m != rootClass DIT(m) = 0, otherwise. =cut __PACKAGE__->mk_accessors(qw( model )); sub new { my ($package, %args) = @_; my @instance_variables = ( model => $args{model} ); return bless { @instance_variables }, $package; } sub description { return "Depth of Inheritance Tree"; } sub calculate { my ($self, $module) = @_; my @parents = $self->model->inheritance($module); return 1 + $self->_depth_of_deepest_inheritance_tree(@parents) if (@parents); return 0; } sub _depth_of_deepest_inheritance_tree { my ($self, @parents) = @_; my @parent_dits = map { $self->calculate($_) } @parents; my @sorted = reverse(sort(@parent_dits)); return $sorted[0]; } 1; Analizo-1.25.5/lib/Analizo/Metric/LackOfCohesionOfMethods.pm0000644000175000017500000000514414676555272023144 0ustar joeniojoeniopackage Analizo::Metric::LackOfCohesionOfMethods; use strict; use parent qw(Class::Accessor::Fast Analizo::ModuleMetric); use Graph; =head1 NAME Analizo::Metric::LackOfCohesionOfMethods - Lack of Cohesion of Methods (LCOM4) metric =head1 DESCRIPTION The metric calculation is based on the following article and calculates the cohesion of the class. Article: M. Hitz and B. Montazeri, "Measuring coupling and cohesion in object-oriented systems," in Proceedings of the International. Symposium on Applied Corporate Computing, 1995. http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.409.4862 The LCOM4 value for a module is the number of connected components of an undirected graph, where the nodes are the module's subroutines (methods, functions etc.), and the edges indicate that two subroutines use at least one attribute/variable in common, or that one subroutines calls the other. These connected components represent independent parts of a module, and modules that have more than one of them have independent, distinct responsibilities. You can see a study using the LCOM4 metric on the following paper: Terceiro, Antonio, et al. "Understanding structural complexity evolution: A quantitative analysis." Software Maintenance and Reengineering (CSMR), 2012 16th European Conference on. IEEE, 2012. NBR 6023 http://ieeexplore.ieee.org/abstract/document/6178856/ For a comparative study on the various LCOM1, LCOM2, LCOM3, LCOM4 and LCOM5 see: Kaur, Taranjeet, and Rupinder Kaur. "Comparison of various lacks of Cohesion Metrics." International Journal of Computer Trends and Technology (IJCTT) 4.5 (2013). NBR 6023 http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.686.2543 =cut __PACKAGE__->mk_accessors(qw( model graph )); sub new { my ($package, %args) = @_; my @instance_variables = ( model => $args{model}, graph => Graph->new, ); return bless { @instance_variables }, $package; } sub description { return "Lack of Cohesion of Methods"; } sub calculate { my ($self, $module) = @_; my $graph = Graph->new; my @functions = $self->model->functions($module); my @variables = $self->model->variables($module); for my $function (@functions) { $graph->add_vertex($function); for my $used (keys(%{$self->model->calls->{$function}})) { # only include in the graph functions and variables that are inside the module. if ((grep { $_ eq $used } @functions) || (grep { $_ eq $used } @variables)) { $graph->add_edge($function, $used); } } } my @components = $graph->weakly_connected_components; return scalar @components; } 1; Analizo-1.25.5/lib/Analizo/Metric/MaximumMethodLinesOfCode.pm0000644000175000017500000000127514676555272023336 0ustar joeniojoeniopackage Analizo::Metric::MaximumMethodLinesOfCode; use strict; use parent qw(Class::Accessor::Fast Analizo::ModuleMetric); use Statistics::Descriptive; __PACKAGE__->mk_accessors(qw( model )); sub new { my ($package, %args) = @_; my @instance_variables = ( model => $args{model} ); return bless { @instance_variables }, $package; } sub description { return "Max Method LOC"; } sub calculate { my ($self, $module) = @_; my $statisticalCalculator = Statistics::Descriptive::Full->new(); for my $function ($self->model->functions($module)) { $statisticalCalculator->add_data($self->model->{lines}->{$function} || 0); } return $statisticalCalculator->max() || 0; } 1; Analizo-1.25.5/lib/Analizo/Metric/NumberOfPublicAttributes.pm0000644000175000017500000000275014676555272023427 0ustar joeniojoeniopackage Analizo::Metric::NumberOfPublicAttributes; use strict; use parent qw(Class::Accessor::Fast Analizo::ModuleMetric); =head1 NAME Analizo::Metric::NumberOfPublicAttributes - Number of Public Attributes (NPA) metric =head1 DESCRIPTION The metric calculation is based on the following article and calculates the number of public attributes of a class. Article: I by Paulo Roberto Miranda Meirelles. See the adaptation of the paragraph about Number of Public Attributes in the article: It measures the encapsulation. The attributes of a class must only serve to the functionalities of itself. Thus, good programming practices recommend that the attributes of a class must be manipulated using the access methods (Beck, 1997), the attributes of a class must be private, indicating that the ideal number for this metric is zero. =cut __PACKAGE__->mk_accessors(qw( model )); sub new { my ($package, %args) = @_; my @instance_variables = ( model => $args{model} ); return bless { @instance_variables }, $package; } sub description { return "Number of Public Attributes"; } sub calculate { my ($self, $module) = @_; my $count = 0; for my $attribute ($self->model->variables($module)) { $count += 1 if $self->_is_public($attribute); } return $count; } sub _is_public { my ($self, $attribute) = @_; return $self->model->{protection}->{$attribute} && $self->model->{protection}->{$attribute} eq "public"; } 1; Analizo-1.25.5/lib/Analizo/Metric/AverageMethodLinesOfCode.pm0000644000175000017500000000266114676555272023273 0ustar joeniojoeniopackage Analizo::Metric::AverageMethodLinesOfCode; use strict; use parent qw(Class::Accessor::Fast Analizo::ModuleMetric); use Statistics::Descriptive; =head1 NAME Analizo::Metric::AverageMethodLinesOfCode - Average Method Lines of Code (AMLOC) metric =head1 DESCRIPTION The metric calculation is based on the following article and calculates the average number of lines of code per method. Article: I by Paulo Roberto Miranda Meirelles. See the adaptation of the paragraph about Average Method Lines of Code metric: This metric indicates if the code is well distributed between the methods. How bigger, "heavier" are the methods. It's preferable to have a lot of small and of easy understanding operations than few large and complex operations. =cut __PACKAGE__->mk_accessors(qw( model )); sub new { my ($package, %args) = @_; my @instance_variables = ( model => $args{model} ); return bless { @instance_variables }, $package; } sub description { return "Average Method Lines of Code"; } sub calculate { my ($self, $module) = @_; my @functions = $self->model->functions($module); if (scalar(@functions) == 0) { return 0; } my $statisticalCalculator = Statistics::Descriptive::Full->new(); for my $function (@functions) { $statisticalCalculator->add_data($self->model->{lines}->{$function} || 0); } return $statisticalCalculator->mean(); } 1; Analizo-1.25.5/lib/Analizo/Metric/AverageNumberOfParameters.pm0000644000175000017500000000277314676555272023545 0ustar joeniojoeniopackage Analizo::Metric::AverageNumberOfParameters; use strict; use parent qw(Class::Accessor::Fast Analizo::ModuleMetric); use Statistics::Descriptive; =head1 NAME Analizo::Metric::AverageNumberOfParamters - Average Number of Parameters (ANPM) metric =head1 DESCRIPTION The metric calculation is based on the following article and calculates the average of the number of parameters of the class methods. Article: I by Paulo Roberto Miranda Meirelles. See the adaptation of the paragraph about Average Number of Parameters per Class in the article: "Calculates the average of parameters of the class methods. Its minimum value is zero and there is no upper limit to its result, but a high number of parameters may indicate that a method may have one more responsibility, i. e., more than one function" =cut __PACKAGE__->mk_accessors(qw( model )); sub new { my ($package, %args) = @_; my @instance_variables = ( model => $args{model} ); return bless { @instance_variables }, $package; } sub description { return "Average Number of Parameters per Method"; } sub calculate { my ($self, $module) = @_; my @functions = $self->model->functions($module); if (scalar(@functions) == 0) { return 0; } my $statisticalCalculator = Statistics::Descriptive::Full->new(); for my $function (@functions) { $statisticalCalculator->add_data($self->model->{parameters}->{$function} || 0); } return $statisticalCalculator->mean(); } 1; Analizo-1.25.5/lib/Analizo/Extractor/0000775000175000017500000000000014676555272016674 5ustar joeniojoenioAnalizo-1.25.5/lib/Analizo/Extractor/Doxyparse.pm0000644000175000017500000001400214676555272021203 0ustar joeniojoeniopackage Analizo::Extractor::Doxyparse; use strict; use warnings; use parent qw(Analizo::Extractor); use File::Temp qw/ tempfile /; use Cwd; use YAML::XS; use File::Spec::Functions qw/ tmpdir /; sub new { my ($package, @options) = @_; return bless { files => [], @options }, $package; } sub _add_file { my ($self, $file) = @_; push(@{$self->{files}}, $file); } sub _cpp_hack { my ($self, $module) = @_; my $current = $self->current_file; if (defined($current) && $current =~ /^(.*)\.(h|hpp)$/) { my $prefix = $1; # look for a previously added .cpp/.cc/etc my @implementations = grep { /^$prefix\.(cpp|cxx|cc)$/ } @{$self->{files}}; foreach my $file (@implementations) { $self->model->declare_module($module, $file); } } if (defined($current) && $current =~ /^(.*)\.(cpp|cxx|cc)$/) { my $prefix = $1; # look for a previously added .h/.hpp/etc my @implementations = grep { /^$prefix\.(h|hpp)$/ } @{$self->{files}}; foreach my $file (@implementations) { $self->model->declare_module($module, $file); } } } sub feed { my ($self, $doxyparse_output, $line) = @_; my $yaml = undef; eval { $yaml = Load($doxyparse_output) }; if ($@) { die $!; } foreach my $full_filename (sort keys %$yaml) { # current file declaration my $file = _strip_current_directory($full_filename); $self->current_file($file); $self->_add_file($file); # current module declaration foreach my $module (keys %{$yaml->{$full_filename}}) { my $modulename = _file_to_module($module); next if defined $yaml->{$full_filename}->{$module} && ref($yaml->{$full_filename}->{$module}) ne 'HASH'; $self->current_module($modulename); $self->_cpp_hack($modulename); # inheritance if (defined $yaml->{$full_filename}->{$module}->{inherits}) { if (ref $yaml->{$full_filename}->{$module}->{inherits} eq 'ARRAY') { foreach my $inherits (@{ $yaml->{$full_filename}->{$module}->{inherits} }) { $self->model->add_inheritance($self->current_module, $inherits); } } else { my $inherits = $yaml->{$full_filename}->{$module}->{inherits}; $self->model->add_inheritance($self->current_module, $inherits); } } # abstract class if (defined $yaml->{$full_filename}->{$module}->{information}) { if ($yaml->{$full_filename}->{$module}->{information} eq 'abstract class') { $self->model->add_abstract_class($self->current_module); } } foreach my $definition (@{$yaml->{$full_filename}->{$module}->{defines}}) { my ($name) = keys %$definition; next if $definition->{$name}->{prototype} and $definition->{$name}->{prototype} eq 'yes'; my $type = $definition->{$name}->{type}; my $qualified_name = _qualified_name($self->current_module, $name); $self->{current_member} = $qualified_name; # function declarations if ($type eq 'function') { $self->model->declare_function($self->current_module, $qualified_name); } # variable declarations elsif ($type eq 'variable') { $self->model->declare_variable($self->current_module, $qualified_name); } #FIXME: Implement define treatment (no novo doxyparse identifica como type = "macro definition") # define declarations elsif ($type eq 'macro definition') { #$self->{current_member} = $qualified_name; } # public members if (defined $definition->{$name}->{protection}) { my $protection = $definition->{$name}->{protection}; $self->model->add_protection($self->current_member, $protection); } # method LOC if (defined $definition->{$name}->{lines_of_code}) { $self->model->add_loc($self->current_member, $definition->{$name}->{lines_of_code}); } # method parameters if (defined $definition->{$name}->{parameters}) { $self->model->add_parameters($self->current_member, $definition->{$name}->{parameters}); } # method conditional paths if (defined $definition->{$name}->{conditional_paths}) { $self->model->add_conditional_paths($self->current_member, $definition->{$name}->{conditional_paths}); } foreach my $uses (@{ $definition->{$name}->{uses} }) { my ($uses_name) = keys %$uses; my $uses_type = $uses->{$uses_name}->{type}; my $defined_in = $uses->{$uses_name}->{defined_in}; my $qualified_uses_name = _qualified_name($defined_in, $uses_name); # function calls/uses if ($uses_type eq 'function') { $self->model->add_call($self->current_member, $qualified_uses_name, 'direct'); } # variable references elsif ($uses_type eq 'variable') { $self->model->add_variable_use($self->current_member, $qualified_uses_name); } } } } } } # concat module with symbol (e.g. main::to_string) sub _qualified_name { my ($file, $symbol) = @_; _file_to_module($file) . '::' . $symbol; } # discard file suffix (e.g. .c or .h) sub _file_to_module { my ($filename) = @_; $filename ||= 'unknown'; $filename =~ s/\.\w+$//; return $filename; } sub _strip_current_directory { my ($file) = @_; my $pwd = getcwd(); $file =~ s#^$pwd/##; return $file; } sub actually_process { my ($self, @input_files) = @_; my ($temp_handle, $temp_filename) = tempfile(); foreach my $input_file (@input_files) { print $temp_handle "$input_file\n" } close $temp_handle; eval 'use Alien::Doxyparse'; $ENV{PATH} = join(':', $ENV{PATH}, Alien::Doxyparse->bin_dir) unless $@; eval { local $ENV{TEMP} = tmpdir(); open DOXYPARSE, "doxyparse - < $temp_filename |" or die "can't run doxyparse: $!"; local $/ = undef; my $doxyparse_output = ; close DOXYPARSE or die "doxyparse error"; $self->feed($doxyparse_output); unlink $temp_filename; }; if($@) { warn($@); exit -1; } } 1; Analizo-1.25.5/lib/Analizo/GlobalMetric/0000775000175000017500000000000014676555272017265 5ustar joeniojoenioAnalizo-1.25.5/lib/Analizo/GlobalMetric/ChangeCost.pm0000644000175000017500000000345614676555272021647 0ustar joeniojoeniopackage Analizo::GlobalMetric::ChangeCost; use strict; use parent qw(Class::Accessor::Fast); use List::Util qw( sum ); use Graph::TransitiveClosure::Matrix; =head1 NAME Analizo::GlobalMetric::ChangeCost - Change Cost global metric =head1 DESCRIPTION The metric calculation is based on the following article and calculates the degree to which a change to any file causes a (potential) change to other files in the system. Article: Exploring the Structure of Complex Software Designs: An Empirical Study of Open Source and Proprietary Code by Alan MacCormack, John Rusnak and Carliss Baldwin. See the paragraph about Change Cost in the article: "... characterize the structure of a design is by measuring the degree of 'coupling' it exhibits, as captured by the degree to which a change to any single element causes a (potential) change to other elements in the system, either directly or indirectly (i.e., through a chain of dependencies that exist across elements). ... measures the percentage of elements affected, on average, when a change is made to one element in the system." =cut __PACKAGE__->mk_accessors(qw( model )); sub new { my ($package, %args) = @_; my @instance_variables = ( model => $args{model}, ); return bless { @instance_variables }, $package; } sub description { return "Change Cost"; } sub calculate { my ($self) = @_; my $reachability_matrix = $self->model->files_graph->transitive_closure_matrix; my @vertices = sort $reachability_matrix->vertices; my $rows = scalar @vertices; return unless $rows; my @fan_out = (0) x $rows; my $n = 0; foreach my $i (@vertices) { foreach my $j (@vertices) { $fan_out[$n] += $reachability_matrix->[0]->get($i, $j); } $fan_out[$n] = $fan_out[$n] / $rows; $n++; } sprintf("%0.02f", sum(@fan_out) / $rows); } 1; Analizo-1.25.5/lib/Analizo/GlobalMetric/TotalAbstractClasses.pm0000644000175000017500000000100014676555272023675 0ustar joeniojoeniopackage Analizo::GlobalMetric::TotalAbstractClasses; use strict; use parent qw(Class::Accessor::Fast); __PACKAGE__->mk_accessors(qw( model )); sub new { my ($package, %args) = @_; my @instance_variables = ( model => $args{model}, ); return bless { @instance_variables }, $package; } sub description { return "Total Abstract Classes"; } sub calculate { my ($self)= @_; my @total_of_abstract_classes = $self->model->abstract_classes; return scalar(@total_of_abstract_classes) || 0; } 1; Analizo-1.25.5/lib/Analizo/GlobalMetric/MethodsPerAbstractClass.pm0000644000175000017500000000145514676555272024352 0ustar joeniojoeniopackage Analizo::GlobalMetric::MethodsPerAbstractClass; use strict; use parent qw(Class::Accessor::Fast); __PACKAGE__->mk_accessors(qw( model)); sub new { my ($package, %args) = @_; my @instance_variables = ( model => $args{model}, ); return bless { @instance_variables }, $package; } sub description { return "Methods per Abstract Class"; } sub calculate { my ($self) = @_; my $total_number_of_methods = 0; my @abstract_classes = $self->model->abstract_classes; for my $abstract_class (@abstract_classes) { $total_number_of_methods += (scalar $self->model->functions($abstract_class)) || 0; } return _division($total_number_of_methods, scalar @abstract_classes); } sub _division { my ($dividend, $divisor) = @_; return ($divisor > 0) ? ($dividend / $divisor) : 0; } 1; Analizo-1.25.5/refresh-authors0000755000175000017500000000115614676555272015626 0ustar joeniojoenio#!/usr/bin/perl use strict; use Git::Wrapper; use List::MoreUtils qw(uniq); my $git = Git::Wrapper->new('./'); sub git_log_grep { my $string = shift; return map { s/^\s*$string\s*//; $_ } grep { /$string/ } $git->RUN('log', {grep => $string}); } my @authors = $git->RUN('log', {pretty => "format:%aN <%aE>"}); my @signed_authors = git_log_grep('Signed-off-by:'); my @co_authors = git_log_grep('Co-authored-by:'); foreach (@signed_authors, @co_authors) { eval { my @_co_authors = $git->RUN('check-mailmap', $_); push @authors, @_co_authors; }; } print join("\n", uniq sort @authors); Analizo-1.25.5/development-setup.sh0000755000175000017500000000442014676555272016573 0ustar joeniojoenio#!/bin/sh set -e setup_debian() { which wget || sudo apt-get -q -y -f install wget which gpg || sudo apt-get -q -y -f install gnupg which lsb_release || sudo apt-get -q -y -f install lsb-release codename=$(lsb_release -c | awk '{print($2)}') if type prepare_$codename >/dev/null 2>&1; then prepare_$codename else echo "WARNING: no specific preparation steps for $codename" fi which apt-file || sudo apt-get -q -y -f install apt-file sudo apt-get update sudo apt-file update sudo apt-get -q -y -f install dh-make-perl libdist-zilla-perl liblocal-lib-perl cpanminus doxygen-doxyparse packages=$(locate_package $(dzil authordeps)) if [ -n "$packages" ]; then sudo apt-get -q -y -f install $packages fi dzil authordeps --missing | cpanm --notest packages=$(locate_package $(dzil listdeps)) if [ -n "$packages" ]; then sudo apt-get -q -y -f install $packages fi dzil listdeps --missing | cpanm --notest } locate_package() { packages= for module in $@; do package=$(dh-make-perl locate $module | grep 'package$' | grep ' is in ' | sed 's/.\+is in \(.\+\) package/\1/') packages="$packages $package" done echo $packages } # FIXME share data with Makefile.PL/dist.ini needed_programs=' cpanm git pkg-config ' needed_libraries=' uuid libzmq ' check_non_perl_dependencies() { failed=false for program in $needed_programs; do printf "Looking for $program ... " if ! which $program; then echo "*** $program NOT FOUND *** " failed=true fi done for package in $needed_libraries; do printf "Looking for $package ... " if pkg-config $package; then echo OK else echo "*** ${package}-dev NOT FOUND ***" failed=true fi done if [ "$failed" = 'true' ]; then echo echo "ERROR: missing dependencies" echo "See HACKING for tips on how to install missing dependencies" exit 1 fi } setup_generic() { check_non_perl_dependencies dzil listdeps | cpanm } if [ ! -f ./bin/analizo ]; then echo "Please run this script from the root of Analizo sources!" exit 1 fi force_generic=false if [ "$1" = '--generic' ]; then force_generic=true fi if [ -x /usr/bin/dpkg -a -x /usr/bin/apt-get -a "$force_generic" = false ]; then setup_debian else setup_generic fi