Analizo-1.25.4/0000755000175000017500000000000014300274526012533 5ustar joeniojoenioAnalizo-1.25.4/dist.ini0000644000175000017500000000311214300274526014174 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 = 0 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.4/README.md0000644000175000017500000000305714300274526014017 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.4/profile.pl0000755000175000017500000000043214300274526014532 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.4/MANIFEST0000644000175000017500000002764214300274526013677 0ustar joeniojoenio# This file was automatically generated by Dist::Zilla::Plugin::Manifest v6.025. 99-details.csv 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-details.csv 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-details.csv 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.4/t/0000755000175000017500000000000014300274526012776 5ustar joeniojoenioAnalizo-1.25.4/t/author-pod-spell.t0000644000175000017500000000165014300274526016364 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.4/t/author-pod-syntax.t0000644000175000017500000000045414300274526016574 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.4/t/features.t0000644000175000017500000000200614300274526014777 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.4/t/features/0000755000175000017500000000000014300274526014614 5ustar joeniojoenioAnalizo-1.25.4/t/features/exclude.feature0000644000175000017500000000222614300274526017624 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.4/t/features/wrapper.feature0000644000175000017500000000177714300274526017665 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.4/t/features/tree_evolution.feature0000644000175000017500000000117514300274526021240 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.4/t/features/step_definitions/0000755000175000017500000000000014300274526020162 5ustar joeniojoenioAnalizo-1.25.4/t/features/step_definitions/analizo_steps.pl0000644000175000017500000001356314300274526023402 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.4/t/features/metrics_history_db.feature0000644000175000017500000000100314300274526022057 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.4/t/features/dot-analizo.feature0000644000175000017500000000215414300274526020414 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.4/t/features/metrics-batch.feature0000644000175000017500000000375514300274526020730 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.4/t/features/void-argument.feature0000644000175000017500000000060614300274526020754 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.4/t/features/language_support.feature0000644000175000017500000001074114300274526021553 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.4/t/features/metrics_history.feature0000644000175000017500000000712614300274526021426 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.4/t/features/graph/0000755000175000017500000000000014300274526015715 5ustar joeniojoenioAnalizo-1.25.4/t/features/graph/functions.feature0000644000175000017500000000052314300274526021302 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.4/t/features/graph/modules.feature0000644000175000017500000000041614300274526020743 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.4/t/features/graph/cluster.feature0000644000175000017500000000106314300274526020753 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.4/t/features/graph/omit.feature0000644000175000017500000000126614300274526020247 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.4/t/features/graph/plain.feature0000644000175000017500000000100714300274526020373 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.4/t/features/graph/help.feature0000644000175000017500000000030214300274526020215 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.4/t/features/graph/input-files.feature0000644000175000017500000000077014300274526021535 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.4/t/features/graph/output-file.feature0000644000175000017500000000163014300274526021547 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.4/t/features/metrics/0000755000175000017500000000000014300274527016263 5ustar joeniojoenioAnalizo-1.25.4/t/features/metrics/number_of_public_methods.feature0000644000175000017500000000210314300274526024670 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.4/t/features/metrics/modules_with_defined_methods.feature0000644000175000017500000000140614300274527025545 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.4/t/features/metrics/global_only.feature0000644000175000017500000000101014300274526022130 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.4/t/features/metrics/total_modules.feature0000644000175000017500000000050314300274526022510 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.4/t/features/metrics/coupling_between_objects.feature0000644000175000017500000000164714300274526024711 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.4/t/features/metrics/number_of_methods.feature0000644000175000017500000000244114300274526023337 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.4/t/features/metrics/modules_with_defined_attributes.feature0000644000175000017500000000141414300274527026267 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.4/t/features/metrics/list.feature0000644000175000017500000000057114300274526020615 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.4/t/features/metrics/language_filter.feature0000644000175000017500000000222314300274526022766 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.4/t/features/metrics/statistics_values.feature0000644000175000017500000000230114300274526023404 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.4/t/features/metrics/abstract_classes.feature0000644000175000017500000000300714300274526023157 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.4/t/features/metrics/cyclomatic_complexity.feature0000644000175000017500000000121114300274526024236 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.4/t/features/metrics/output_file.feature0000644000175000017500000000161414300274526022200 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.4/t/features/metrics/change_cost.feature0000644000175000017500000000260014300274526022112 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.4/t/features/metrics/average_number_of_parameters.feature0000644000175000017500000000145114300274527025532 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.4/t/features/metrics/methods_per_abstract_class.feature0000644000175000017500000000215414300274527025223 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.4/t/features/metrics/deep_inheritance_afferent_connections.feature0000644000175000017500000000160114300274527027400 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.4/t/features/metrics/number_of_attributes.feature0000644000175000017500000000116314300274526024062 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.4/t/features/manpage-on-help.feature0000644000175000017500000000116514300274526021144 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.4/t/features/files_graph.feature0000644000175000017500000000215414300274526020456 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.4/t/features/doxyparse.feature0000644000175000017500000000277414300274526020221 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.4/t/features/module_file_mapping.feature0000644000175000017500000000475614300274526022204 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.4/t/Analizo.t0000644000175000017500000000246514300274526014567 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.4/t/samples/0000755000175000017500000000000014300274527014443 5ustar joeniojoenioAnalizo-1.25.4/t/samples/tree_id/0000755000175000017500000000000014300274526016055 5ustar joeniojoenioAnalizo-1.25.4/t/samples/tree_id/2.c0000644000175000017500000000000214300274526016352 0ustar joeniojoenio2 Analizo-1.25.4/t/samples/tree_id/1.c0000644000175000017500000000000214300274526016351 0ustar joeniojoenio1 Analizo-1.25.4/t/samples/polygons/0000755000175000017500000000000014300274526016314 5ustar joeniojoenioAnalizo-1.25.4/t/samples/polygons/cpp/0000755000175000017500000000000014300274526017076 5ustar joeniojoenioAnalizo-1.25.4/t/samples/polygons/cpp/Polygon.cpp0000644000175000017500000000222614300274526021233 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.4/t/samples/polygons/csharp/0000755000175000017500000000000014300274526017574 5ustar joeniojoenioAnalizo-1.25.4/t/samples/polygons/csharp/Square.cs0000644000175000017500000000033514300274526021364 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.4/t/samples/polygons/csharp/Program.cs0000644000175000017500000000065714300274526021542 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.4/t/samples/polygons/csharp/Polygon.cs0000644000175000017500000000021314300274526021546 0ustar joeniojoeniousing System; abstract class Polygon { protected int width, heigth; public abstract int Area(); public abstract int Perimeter(); } Analizo-1.25.4/t/samples/polygons/csharp/Rect.cs0000644000175000017500000000040314300274526021015 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.4/t/samples/polygons/csharp/Tetragon.cs0000644000175000017500000000021014300274526021677 0ustar joeniojoeniousing System; abstract class Tetragon : Polygon { public abstract override int Area(); public abstract override int Perimeter(); } Analizo-1.25.4/t/samples/polygons/csharp/Triangle.cs0000644000175000017500000000040114300274526021663 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.4/t/samples/polygons/java/0000755000175000017500000000000014300274526017235 5ustar joeniojoenioAnalizo-1.25.4/t/samples/polygons/java/Square.java0000644000175000017500000000014214300274526021335 0ustar joeniojoeniopublic class Square extends Tetragon { public int area () { return (width * width); } } Analizo-1.25.4/t/samples/polygons/java/Tetragon.java0000644000175000017500000000012714300274526021663 0ustar joeniojoeniopublic abstract class Tetragon extends Polygon { public abstract int area (); } Analizo-1.25.4/t/samples/polygons/java/Retangle.java0000644000175000017500000000014514300274526021641 0ustar joeniojoeniopublic class Retangle extends Tetragon { public int area () { return (width * height); } } Analizo-1.25.4/t/samples/polygons/java/Triangle.java0000644000175000017500000000014614300274526021646 0ustar joeniojoeniopublic class Triangle extends Polygon { public int area () { return (width * height/2); } } Analizo-1.25.4/t/samples/polygons/java/Polygon.java0000644000175000017500000000037614300274526021535 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.4/t/samples/polygons/java/Polygons.java0000644000175000017500000000030014300274526021703 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.4/t/samples/abstract_class/0000755000175000017500000000000014300274526017432 5ustar joeniojoenioAnalizo-1.25.4/t/samples/abstract_class/csharp/0000755000175000017500000000000014300274526020712 5ustar joeniojoenioAnalizo-1.25.4/t/samples/abstract_class/csharp/FourLeggedAnimal.cs0000644000175000017500000000011214300274526024400 0ustar joeniojoenioabstract class FourLeggedAnimal { public abstract string Describe(); }Analizo-1.25.4/t/samples/abstract_class/csharp/Program.cs0000644000175000017500000000036514300274526022654 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.4/t/samples/abstract_class/csharp/Dog.cs0000644000175000017500000000027514300274526021756 0ustar joeniojoenioclass Dog : FourLeggedAnimal { public override string Describe() { string result = base.Describe(); result += " In fact, it's a dog!"; return result; } }Analizo-1.25.4/t/samples/abstract_class/java/0000755000175000017500000000000014300274526020353 5ustar joeniojoenioAnalizo-1.25.4/t/samples/abstract_class/java/AbstractDao.java0000644000175000017500000000540214300274526023406 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.4/t/samples/sample_basic/0000755000175000017500000000000014300274526017064 5ustar joeniojoenioAnalizo-1.25.4/t/samples/sample_basic/c/0000755000175000017500000000000014300274526017306 5ustar joeniojoenioAnalizo-1.25.4/t/samples/sample_basic/c/config.sh0000644000175000017500000000037714300274526021116 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.4/t/samples/sample_basic/c/Makefile0000644000175000017500000000022714300274526020747 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.4/t/samples/sample_basic/c/module2.c0000644000175000017500000000022014300274526021013 0ustar joeniojoenio#include #include "module2.h" void say_hello() { printf("Hello, world!\n"); } void say_bye() { printf("Bye, cruel world!\n"); } Analizo-1.25.4/t/samples/sample_basic/c/module3.c0000644000175000017500000000017014300274526021020 0ustar joeniojoenio#include "module3.h" #include int variable = 15; void callback() { printf("this is callback function"); } Analizo-1.25.4/t/samples/sample_basic/c/module3.h0000644000175000017500000000014714300274526021031 0ustar joeniojoenio#ifndef _MODULE3_H_ #define _MODULE3_H_ extern int variable; void callback(); #endif // _MODULE3_H_ Analizo-1.25.4/t/samples/sample_basic/c/module1.c0000644000175000017500000000047214300274526021023 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.4/t/samples/sample_basic/c/module2.h0000644000175000017500000000014214300274526021023 0ustar joeniojoenio#ifndef _MODULE2_H_ #define _MODULE2_H_ void say_hello(); void say_bye(); #endif // _MODULE2_H_ Analizo-1.25.4/t/samples/sample_basic/csharp/0000755000175000017500000000000014300274526020344 5ustar joeniojoenioAnalizo-1.25.4/t/samples/sample_basic/csharp/Program.cs0000644000175000017500000000054014300274526022301 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.4/t/samples/sample_basic/csharp/Module2.cs0000644000175000017500000000023714300274526022204 0ustar joeniojoeniousing System; class Module2 { public static int variable = 15; public static void Callback() { Console.WriteLine("this is callback function"); } } Analizo-1.25.4/t/samples/sample_basic/csharp/Module1.cs0000644000175000017500000000027614300274526022206 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.4/t/samples/hello_world/0000755000175000017500000000000014300274526016754 5ustar joeniojoenioAnalizo-1.25.4/t/samples/hello_world/c/0000755000175000017500000000000014300274526017176 5ustar joeniojoenioAnalizo-1.25.4/t/samples/hello_world/c/main.c0000644000175000017500000000040214300274526020262 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.4/t/samples/hello_world/c/Makefile0000644000175000017500000000010114300274526020626 0ustar joeniojoeniohello_world: main.o hello_world.o clean: rm -f *.o hello_world Analizo-1.25.4/t/samples/hello_world/c/hello_world.c0000644000175000017500000000074314300274526021660 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.4/t/samples/hello_world/c/hello_world.h0000644000175000017500000000036214300274526021662 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.4/t/samples/hello_world/cpp/0000755000175000017500000000000014300274526017536 5ustar joeniojoenioAnalizo-1.25.4/t/samples/hello_world/cpp/Makefile0000644000175000017500000000011314300274526021171 0ustar joeniojoenioCC = g++ hello_world: main.o hello_world.o clean: rm -f *.o hello_world Analizo-1.25.4/t/samples/hello_world/cpp/main.cc0000644000175000017500000000044714300274526020776 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.4/t/samples/hello_world/cpp/hello_world.cc0000644000175000017500000000071014300274526022355 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.4/t/samples/hello_world/cpp/hello_world.h0000644000175000017500000000040614300274526022221 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.4/t/samples/hello_world/csharp/0000755000175000017500000000000014300274526020234 5ustar joeniojoenioAnalizo-1.25.4/t/samples/hello_world/csharp/Makefile0000644000175000017500000000007114300274526021672 0ustar joeniojoeniodefault: mcs main.cs HelloWorld.cs clean: rm -f *.exe Analizo-1.25.4/t/samples/hello_world/csharp/main.cs0000644000175000017500000000054314300274526021511 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.4/t/samples/hello_world/csharp/HelloWorld.cs0000644000175000017500000000070314300274526022636 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.4/t/samples/hello_world/java/0000755000175000017500000000000014300274526017675 5ustar joeniojoenioAnalizo-1.25.4/t/samples/hello_world/java/Makefile0000644000175000017500000000024614300274526021337 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.4/t/samples/hello_world/java/Main.java0000644000175000017500000000065014300274526021425 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.4/t/samples/hello_world/java/HelloWorld.java0000644000175000017500000000065614300274526022622 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.4/t/samples/deep_inheritance/0000755000175000017500000000000014300274526017730 5ustar joeniojoenioAnalizo-1.25.4/t/samples/deep_inheritance/java/0000755000175000017500000000000014300274527020652 5ustar joeniojoenioAnalizo-1.25.4/t/samples/deep_inheritance/java/Dog.java0000644000175000017500000000015214300274526022223 0ustar joeniojoenioclass Dog { String name; Human owner; public Human getOwner(){ return owner; } } Analizo-1.25.4/t/samples/deep_inheritance/java/DogGrandson.java0000644000175000017500000000010714300274526023717 0ustar joeniojoenioclass DogGrandson extends DogFirstPuppy { String number_of_eyes; } Analizo-1.25.4/t/samples/deep_inheritance/java/Human.java0000644000175000017500000000015314300274526022563 0ustar joeniojoenioclass Human { String name; Dog pet; public Dog getPetName(){ return pet.name; } } Analizo-1.25.4/t/samples/deep_inheritance/java/DogSecondPuppy.java0000644000175000017500000000006514300274526024420 0ustar joeniojoenioclass DogSecondPuppy extends Dog { String age; } Analizo-1.25.4/t/samples/deep_inheritance/java/VenderShop.java0000644000175000017500000000026114300274526023570 0ustar joeniojoenioclass VenderShop { public void sellDogTo(Human owner){ Dog dog = new Dog(); dog.name = "Toby"; dog.owner = owner; owner.pet = dog; } } Analizo-1.25.4/t/samples/deep_inheritance/java/ShopController.java0000644000175000017500000000031214300274526024465 0ustar joeniojoenioclass ShopController { public void main(){ Human owner = new Human(); owner.name = "Robson"; VenderShop vender = new VenderShop(); vender.sellDogTo(owner); } } Analizo-1.25.4/t/samples/deep_inheritance/java/DogSecondGreatGrandson.java0000644000175000017500000000010614300274527026036 0ustar joeniojoenioclass DogSecondGreatGrandson extends DogGrandson { String arms; } Analizo-1.25.4/t/samples/deep_inheritance/java/DogSuperYoung.java0000644000175000017500000000010714300274526024264 0ustar joeniojoenioclass DogSuperYoung extends DogFirstGreatGrandson { String accs; } Analizo-1.25.4/t/samples/deep_inheritance/java/DogFirstGreatGrandson.java0000644000175000017500000000010614300274527025712 0ustar joeniojoenioclass DogFirstGreatGrandson extends DogGrandson { String noses; } Analizo-1.25.4/t/samples/deep_inheritance/java/DogFirstPuppy.java0000644000175000017500000000006614300274526024275 0ustar joeniojoenioclass DogFirstPuppy extends Dog { String color; } Analizo-1.25.4/t/samples/kdelibs/0000755000175000017500000000000014300274526016057 5ustar joeniojoenioAnalizo-1.25.4/t/samples/kdelibs/parser.cpp0000644000175000017500000000672314300274526020067 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.4/t/samples/kdelibs/daterange.cpp0000644000175000017500000001521214300274526020516 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.4/t/samples/kdelibs/backportglobal.h0000644000175000017500000000442514300274526021223 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.4/t/samples/kdelibs/daterange.h0000644000175000017500000001425414300274526020170 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.4/t/samples/macro/0000755000175000017500000000000014300274526015543 5ustar joeniojoenioAnalizo-1.25.4/t/samples/macro/using_macro.c0000644000175000017500000000027514300274526020221 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.4/t/samples/macro/using_macro.h0000644000175000017500000000011614300274526020220 0ustar joeniojoenio#include SOME_EXTERNAL_MACRO(1); int main(int argc, char **argv); Analizo-1.25.4/t/samples/tree-evolution.tar.gz0000644000175000017500000002470714300274526020564 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.4/t/samples/mixed/0000755000175000017500000000000014300274526015550 5ustar joeniojoenioAnalizo-1.25.4/t/samples/mixed/CSharp_Backend.cs0000644000175000017500000000014014300274526020661 0ustar joeniojoeniousing System; class CSharp_Backend { public void ProcessRequest() { // Anything... } } Analizo-1.25.4/t/samples/mixed/native_backend.c0000644000175000017500000000010114300274526020641 0ustar joeniojoenio#include void process_request() { // ... whatever } Analizo-1.25.4/t/samples/mixed/Backend.java0000644000175000017500000000012114300274526017734 0ustar joeniojoeniopublic class Backend { public void processRequest(int data) { // ... } } Analizo-1.25.4/t/samples/mixed/UI.java0000644000175000017500000000032714300274526016732 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.4/t/samples/foo.tar.gz0000644000175000017500000002344114300274526016360 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 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.4/t/samples/cyclical_graph/c/d.cc0000644000175000017500000000015414300274526020362 0ustar joeniojoenio#include "d.h" D::D(char* name) { this->_name = name; } const char* D::name() { return this->_name; } Analizo-1.25.4/t/samples/cyclical_graph/c/b.cc0000644000175000017500000000032214300274526020355 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.4/t/samples/cyclical_graph/c/main.cc0000644000175000017500000000032614300274526021064 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.4/t/samples/cyclical_graph/c/b.h0000644000175000017500000000020614300274526020220 0ustar joeniojoenio#ifndef _B_H_ #define _B_H_ class B { private: char* _name; public: B(char*); virtual const char* name(); }; #endif Analizo-1.25.4/t/samples/cyclical_graph/c/f.cc0000644000175000017500000000032214300274526020361 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.4/t/samples/cyclical_graph/c/e.h0000644000175000017500000000020614300274526020223 0ustar joeniojoenio#ifndef _E_H_ #define _E_H_ class E { private: char* _name; public: E(char*); virtual const char* name(); }; #endif Analizo-1.25.4/t/samples/cyclical_graph/c/d.h0000644000175000017500000000020614300274526020222 0ustar joeniojoenio#ifndef _D_H_ #define _D_H_ class D { private: char* _name; public: D(char*); virtual const char* name(); }; #endif Analizo-1.25.4/t/samples/cyclical_graph/c/c.h0000644000175000017500000000020614300274526020221 0ustar joeniojoenio#ifndef _C_H_ #define _C_H_ class C { private: char* _name; public: C(char*); virtual const char* name(); }; #endif Analizo-1.25.4/t/samples/cyclical_graph/c/f.h0000644000175000017500000000020614300274526020224 0ustar joeniojoenio#ifndef _F_H_ #define _F_H_ class F { private: char* _name; public: F(char*); virtual const char* name(); }; #endif Analizo-1.25.4/t/samples/cyclical_graph/c/e.cc0000644000175000017500000000032214300274526020360 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.4/t/samples/cyclical_graph/csharp/0000755000175000017500000000000014300274526020666 5ustar joeniojoenioAnalizo-1.25.4/t/samples/cyclical_graph/csharp/E.cs0000644000175000017500000000043614300274526021404 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.4/t/samples/cyclical_graph/csharp/D.cs0000644000175000017500000000031114300274526021373 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.4/t/samples/cyclical_graph/csharp/Program.cs0000644000175000017500000000033714300274526022627 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.4/t/samples/cyclical_graph/csharp/F.cs0000644000175000017500000000043614300274526021405 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.4/t/samples/cyclical_graph/csharp/B.cs0000644000175000017500000000043614300274526021401 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.4/t/samples/cyclical_graph/csharp/C.cs0000644000175000017500000000043614300274526021402 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.4/t/samples/animals/0000755000175000017500000000000014300274526016066 5ustar joeniojoenioAnalizo-1.25.4/t/samples/animals/cpp/0000755000175000017500000000000014300274526016650 5ustar joeniojoenioAnalizo-1.25.4/t/samples/animals/cpp/animal.h0000644000175000017500000000015714300274526020265 0ustar joeniojoenio#ifndef _ANIMAL_H_ #define _ANIMAL_H_ class Animal { public: virtual const char* name() = 0; }; #endif Analizo-1.25.4/t/samples/animals/cpp/dog.h0000644000175000017500000000026314300274526017573 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.4/t/samples/animals/cpp/Makefile0000644000175000017500000000012114300274526020302 0ustar joeniojoenioCC = g++ animals: dog.o cat.o main.o $(CC) -o $@ $^ clean: rm -f *.o animals Analizo-1.25.4/t/samples/animals/cpp/main.cc0000644000175000017500000000042514300274526020104 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.4/t/samples/animals/cpp/cat.cc0000644000175000017500000000016414300274526017727 0ustar joeniojoenio#include "cat.h" Cat::Cat(char* name) { this->_name = name; } const char* Cat::name() { return this->_name; } Analizo-1.25.4/t/samples/animals/cpp/mammal.h0000644000175000017500000000017614300274526020271 0ustar joeniojoenio#ifndef _MAMMAL_H_ #define _MAMMAL_H_ #include "animal.h" class Mammal: public Animal { virtual ~Mammal() = 0; }; #endif Analizo-1.25.4/t/samples/animals/cpp/dog.cc0000644000175000017500000000016414300274526017731 0ustar joeniojoenio#include "dog.h" Dog::Dog(char* name) { this->_name = name; } const char* Dog::name() { return this->_name; } Analizo-1.25.4/t/samples/animals/cpp/cat.h0000644000175000017500000000026314300274526017571 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.4/t/samples/animals/csharp/0000755000175000017500000000000014300274526017346 5ustar joeniojoenioAnalizo-1.25.4/t/samples/animals/csharp/Mammal.cs0000644000175000017500000000011314300274526021074 0ustar joeniojoeniopublic abstract class Mammal : Animal { public virtual void close() {} } Analizo-1.25.4/t/samples/animals/csharp/Main.cs0000644000175000017500000000034214300274526020560 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.4/t/samples/animals/csharp/Makefile0000644000175000017500000000006014300274526021002 0ustar joeniojoenioAnimal.exe: *.cs mcs *.cs clean: rm -f *.exe Analizo-1.25.4/t/samples/animals/csharp/Dog.cs0000644000175000017500000000024014300274526020402 0ustar joeniojoeniopublic class Dog : Mammal { private string _name; public Dog(string name) { _name = name; } public override string name() { return _name; } } Analizo-1.25.4/t/samples/animals/csharp/Animal.cs0000644000175000017500000000010214300274526021067 0ustar joeniojoeniopublic abstract class Animal { public abstract string name(); } Analizo-1.25.4/t/samples/animals/csharp/Cat.cs0000644000175000017500000000024014300274526020400 0ustar joeniojoeniopublic class Cat : Mammal { private string _name; public Cat(string name) { _name = name; } public override string name() { return _name; } } Analizo-1.25.4/t/samples/animals/java/0000755000175000017500000000000014300274526017007 5ustar joeniojoenioAnalizo-1.25.4/t/samples/animals/java/Dog.java0000644000175000017500000000023514300274526020363 0ustar joeniojoeniopublic class Dog extends Mammal { private String _name; public Dog(String name) { _name = name; } public String name() { return _name; } } Analizo-1.25.4/t/samples/animals/java/Makefile0000644000175000017500000000007514300274526020451 0ustar joeniojoenioAnimal.class: *.java javac Main.java clean: rm -f *.class Analizo-1.25.4/t/samples/animals/java/Main.java0000644000175000017500000000032514300274526020536 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.4/t/samples/animals/java/Animal.java0000644000175000017500000000010214300274526021044 0ustar joeniojoeniopublic abstract class Animal { public abstract String name(); } Analizo-1.25.4/t/samples/animals/java/Mammal.java0000644000175000017500000000012014300274526021047 0ustar joeniojoeniopublic abstract class Mammal extends Animal { public abstract void close(); } Analizo-1.25.4/t/samples/animals/java/Cat.java0000644000175000017500000000023514300274526020361 0ustar joeniojoeniopublic class Cat extends Mammal { private String _name; public Cat(String name) { _name = name; } public String name() { return _name; } } Analizo-1.25.4/t/samples/animals/java-details.csv0000644000175000017500000000051214300274526021145 0ustar joeniojoeniofilename,module,acc,accm,amloc,anpm,cbo,dit,lcom4,loc,mmloc,noa,noc,nom,npa,npm,rfc,sc Animal.java,Animal,4,1,1,0,0,0,1,1,1,0,1,1,0,1,1,0 Cat.java,Cat,0,1,3,0.5,0,2,1,6,3,1,0,2,0,2,4,0 Dog.java,Dog,0,1,3,0.5,0,2,1,6,3,1,0,2,0,2,4,0 Main.java,Main,0,1,6,1,1,0,1,6,6,0,0,1,0,1,2,1 Mammal.java,Mammal,2,1,1,0,0,1,1,1,1,0,2,1,0,1,1,0 Analizo-1.25.4/t/samples/animals/cpp-details.csv0000644000175000017500000000051214300274526021006 0ustar joeniojoeniofilename,module,acc,accm,amloc,anpm,cbo,dit,lcom4,loc,mmloc,noa,noc,nom,npa,npm,rfc,sc animal.h,Animal,4,1,1,0,0,0,1,1,1,0,1,1,0,1,1,0 cat.h/cat.cc,Cat,0,1,3,0.5,0,2,1,6,3,1,0,2,0,2,4,0 dog.h/dog.cc,Dog,0,1,3,0.5,0,2,1,6,3,1,0,2,0,2,4,0 main.cc,main,0,1,9,0,1,0,1,9,9,0,0,1,0,1,2,1 mammal.h,Mammal,2,1,1,0,0,1,1,1,1,0,2,1,0,0,1,0 Analizo-1.25.4/t/samples/enumeration/0000755000175000017500000000000014300274526016770 5ustar joeniojoenioAnalizo-1.25.4/t/samples/enumeration/Main.java0000644000175000017500000000040014300274526020511 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.4/t/samples/enumeration/Enumeration.java0000644000175000017500000000006414300274526022121 0ustar joeniojoeniopublic enum Enumeration { ONE, TWO, THREE, FOUR } Analizo-1.25.4/t/samples/multiple_inheritance/0000755000175000017500000000000014300274526020646 5ustar joeniojoenioAnalizo-1.25.4/t/samples/multiple_inheritance/java/0000755000175000017500000000000014300274526021567 5ustar joeniojoenioAnalizo-1.25.4/t/samples/multiple_inheritance/java/README.md0000644000175000017500000000024514300274526023047 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.4/t/samples/multiple_inheritance/java/Animal.java0000644000175000017500000000013014300274526023625 0ustar joeniojoenioabstract class Animal { private Integer hp = 0; public void eat() { hp++; } } Analizo-1.25.4/t/samples/multiple_inheritance/java/Flying.java0000644000175000017500000000005214300274526023657 0ustar joeniojoeniointerface Flying { public void fly(); } Analizo-1.25.4/t/samples/multiple_inheritance/java/Bird.java0000644000175000017500000000016014300274526023307 0ustar joeniojoenioclass Bird extends Animal implements Flying { @Override public void fly() { //Do something useful } } Analizo-1.25.4/t/samples/multiple_inheritance/java/Pegasus.java0000644000175000017500000000026014300274526024037 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.4/t/samples/multiple_inheritance/java/Horse.java0000644000175000017500000000012014300274526023503 0ustar joeniojoenioclass Horse extends Animal { @Override public void eat() { hp+=2; } } Analizo-1.25.4/t/samples/wildcard/0000755000175000017500000000000014300274526016233 5ustar joeniojoenioAnalizo-1.25.4/t/samples/wildcard/GenericClass.java0000644000175000017500000000013314300274526021435 0ustar joeniojoeniopublic class GenericClass { public void print(){ System.out.print(T.class); } } Analizo-1.25.4/t/samples/wildcard/WildcardClass.java0000644000175000017500000000032014300274526021610 0ustar joeniojoenioimport java.util.Collection; public class WildcardClass extends Printer> { public void helloWildcard(){ GenericClass variable = new GenericClass(); variable.print(); } } Analizo-1.25.4/t/samples/android-framework/0000755000175000017500000000000014300274527020056 5ustar joeniojoenioAnalizo-1.25.4/t/samples/android-framework/android-5.1.1_r38/0000755000175000017500000000000014300274527022632 5ustar joeniojoenioAnalizo-1.25.4/t/samples/android-framework/android-5.1.1_r38/LICENSE.TXT0000644000175000017500000000554614300274527024327 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.4/t/samples/android-framework/android-5.1.1_r38/MCLinker.cpp0000644000175000017500000003661114300274527025011 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.4/t/samples/android-framework/android-5.1.1_r38/AudioTrackShared.cpp0000644000175000017500000010330014300274527026510 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.4/t/samples/printer/0000755000175000017500000000000014300274526016125 5ustar joeniojoenioAnalizo-1.25.4/t/samples/printer/cpp/0000755000175000017500000000000014300274526016707 5ustar joeniojoenioAnalizo-1.25.4/t/samples/printer/cpp/Makefile0000644000175000017500000000005214300274526020344 0ustar joeniojoenioprinter: printer.cc clean: rm -f printer Analizo-1.25.4/t/samples/printer/cpp/printer.cc0000644000175000017500000000065214300274526020704 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.4/t/samples/printer/csharp/0000755000175000017500000000000014300274526017405 5ustar joeniojoenioAnalizo-1.25.4/t/samples/printer/csharp/Printer2.cs0000644000175000017500000000017114300274526021440 0ustar joeniojoeniousing System; class Printer2 { private string message; public Printer2(string msg) { this.message = msg; } } Analizo-1.25.4/t/samples/printer/csharp/Program.cs0000644000175000017500000000022214300274526021337 0ustar joeniojoeniousing System; class Program { static void Main() { Printer1 print1 = new Printer1("one"); Printer2 print2 = new Printer2("two"); } } Analizo-1.25.4/t/samples/printer/csharp/Printer1.cs0000644000175000017500000000017114300274526021437 0ustar joeniojoeniousing System; class Printer1 { private string message; public Printer1(string msg) { this.message = msg; } } Analizo-1.25.4/t/samples/printer/java/0000755000175000017500000000000014300274526017046 5ustar joeniojoenioAnalizo-1.25.4/t/samples/printer/java/Printer1.java0000644000175000017500000000014214300274526021412 0ustar joeniojoenioclass Printer1 { private String message; Printer1(String msg) { this.message = msg; } } Analizo-1.25.4/t/samples/printer/java/Printer2.java0000644000175000017500000000014214300274526021413 0ustar joeniojoenioclass Printer2 { private String message; Printer2(String msg) { this.message = msg; } } Analizo-1.25.4/t/samples/multidir/0000755000175000017500000000000014300274526016273 5ustar joeniojoenioAnalizo-1.25.4/t/samples/multidir/c/0000755000175000017500000000000014300274526016515 5ustar joeniojoenioAnalizo-1.25.4/t/samples/multidir/c/src/0000755000175000017500000000000014300274526017304 5ustar joeniojoenioAnalizo-1.25.4/t/samples/multidir/c/src/main.c0000644000175000017500000000012114300274526020366 0ustar joeniojoenio#include "lib.h" int main(int argc, char** argv) { say_hello(); return 0; } Analizo-1.25.4/t/samples/multidir/c/src/Makefile0000644000175000017500000000021014300274526020735 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.4/t/samples/multidir/c/Makefile0000644000175000017500000000006114300274526020152 0ustar joeniojoenio%: $(MAKE) -C lib/ $@ $(MAKE) -C src/ $@ all: Analizo-1.25.4/t/samples/multidir/c/lib/0000755000175000017500000000000014300274526017263 5ustar joeniojoenioAnalizo-1.25.4/t/samples/multidir/c/lib/main.c0000644000175000017500000000012714300274526020353 0ustar joeniojoenio#include #include "lib.h" void say_hello() { printf("Hello, world!\n"); } Analizo-1.25.4/t/samples/multidir/c/lib/Makefile0000644000175000017500000000011614300274526020721 0ustar joeniojoenioall: lib.o lib.o: main.c gcc -c -o $@ $< lib.o: lib.h clean: $(RM) lib.o Analizo-1.25.4/t/samples/multidir/c/lib/lib.h0000644000175000017500000000010614300274526020177 0ustar joeniojoenio#ifndef _LIB_H_ #define _LIB_H_ void say_hello(); #endif // _LIB_H_ Analizo-1.25.4/t/samples/multidir/cpp/0000755000175000017500000000000014300274526017055 5ustar joeniojoenioAnalizo-1.25.4/t/samples/multidir/cpp/src/0000755000175000017500000000000014300274526017644 5ustar joeniojoenioAnalizo-1.25.4/t/samples/multidir/cpp/src/hello.h0000644000175000017500000000023114300274526021114 0ustar joeniojoenio#ifndef _HELLO_H_ #define _HELLO_H_ #include using namespace std; class HelloWorld { public: string message(); }; #endif // _HELLO_H_ Analizo-1.25.4/t/samples/multidir/cpp/src/hello.cc0000644000175000017500000000014414300274526021255 0ustar joeniojoenio#include "hello.h" using namespace std; string HelloWorld::message() { return "Hello, world"; } Analizo-1.25.4/t/samples/multidir/cpp/Makefile0000644000175000017500000000031014300274526020507 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.4/t/samples/multidir/cpp/test/0000755000175000017500000000000014300274526020034 5ustar joeniojoenioAnalizo-1.25.4/t/samples/multidir/cpp/test/hello_test.cc0000644000175000017500000000030314300274526022501 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.4/t/samples/multidir/cpp/hello.cc0000644000175000017500000000020414300274526020463 0ustar joeniojoenio#include #include "hello.h" int main() { HelloWorld hello; std::cout << hello.message() << std::endl; return 0; } Analizo-1.25.4/t/samples/multidir/csharp/0000755000175000017500000000000014300274526017553 5ustar joeniojoenioAnalizo-1.25.4/t/samples/multidir/csharp/src/0000755000175000017500000000000014300274526020342 5ustar joeniojoenioAnalizo-1.25.4/t/samples/multidir/csharp/src/hello.cs0000644000175000017500000000012714300274526021774 0ustar joeniojoeniopublic class HelloWorld { public string message() { return "Hello, world"; } } Analizo-1.25.4/t/samples/multidir/csharp/Makefile0000644000175000017500000000022414300274526021211 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.4/t/samples/multidir/csharp/test/0000755000175000017500000000000014300274526020532 5ustar joeniojoenioAnalizo-1.25.4/t/samples/multidir/csharp/test/hello_test.cs0000644000175000017500000000036314300274526023225 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.4/t/samples/multidir/csharp/hello.cs0000644000175000017500000000024714300274526021210 0ustar joeniojoeniousing System; public class main { static public int Main() { HelloWorld hello = new HelloWorld(); Console.WriteLine(hello.message()); return 0; } } Analizo-1.25.4/t/samples/sample_basic-1.0.yml0000644000175000017500000001223414300274526020105 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.4/t/samples/mlpack-3.0.0/0000755000175000017500000000000014300274526016345 5ustar joeniojoenioAnalizo-1.25.4/t/samples/mlpack-3.0.0/parse_command_line.hpp0000644000175000017500000001641714300274526022706 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.4/t/samples/evolution.tar.gz0000644000175000017500000003575214300274526017631 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.4/t/samples/void/0000755000175000017500000000000014300274526015403 5ustar joeniojoenioAnalizo-1.25.4/t/samples/void/main.c0000644000175000017500000000013114300274526016466 0ustar joeniojoenio#include int main(void) { printf("main(void) has no args\n"); return 0; } Analizo-1.25.4/t/samples/httpd-2.4.38/0000755000175000017500000000000014300274526016317 5ustar joeniojoenioAnalizo-1.25.4/t/samples/httpd-2.4.38/mod_suexec.h0000644000175000017500000000306314300274526020625 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.4/t/samples/httpd-2.4.38/http_config.h0000644000175000017500000015724714300274526021014 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.4/t/samples/httpd-2.4.38/mod_suexec.c0000644000175000017500000001151514300274526020621 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.4/t/samples/hierarchical_graph/0000755000175000017500000000000014300274526020241 5ustar joeniojoenioAnalizo-1.25.4/t/samples/hierarchical_graph/c/0000755000175000017500000000000014300274526020463 5ustar joeniojoenioAnalizo-1.25.4/t/samples/hierarchical_graph/c/c.cc0000644000175000017500000000032214300274526021211 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.4/t/samples/hierarchical_graph/c/d.cc0000644000175000017500000000015414300274526021215 0ustar joeniojoenio#include "d.h" D::D(char* name) { this->_name = name; } const char* D::name() { return this->_name; } Analizo-1.25.4/t/samples/hierarchical_graph/c/b.cc0000644000175000017500000000032214300274526021210 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.4/t/samples/hierarchical_graph/c/main.cc0000644000175000017500000000032614300274526021717 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.4/t/samples/hierarchical_graph/c/b.h0000644000175000017500000000020614300274526021053 0ustar joeniojoenio#ifndef _B_H_ #define _B_H_ class B { private: char* _name; public: B(char*); virtual const char* name(); }; #endif Analizo-1.25.4/t/samples/hierarchical_graph/c/f.cc0000644000175000017500000000015414300274526021217 0ustar joeniojoenio#include "f.h" F::F(char* name) { this->_name = name; } const char* F::name() { return this->_name; } Analizo-1.25.4/t/samples/hierarchical_graph/c/e.h0000644000175000017500000000020614300274526021056 0ustar joeniojoenio#ifndef _E_H_ #define _E_H_ class E { private: char* _name; public: E(char*); virtual const char* name(); }; #endif Analizo-1.25.4/t/samples/hierarchical_graph/c/d.h0000644000175000017500000000020614300274526021055 0ustar joeniojoenio#ifndef _D_H_ #define _D_H_ class D { private: char* _name; public: D(char*); virtual const char* name(); }; #endif Analizo-1.25.4/t/samples/hierarchical_graph/c/c.h0000644000175000017500000000020614300274526021054 0ustar joeniojoenio#ifndef _C_H_ #define _C_H_ class C { private: char* _name; public: C(char*); virtual const char* name(); }; #endif Analizo-1.25.4/t/samples/hierarchical_graph/c/f.h0000644000175000017500000000020614300274526021057 0ustar joeniojoenio#ifndef _F_H_ #define _F_H_ class F { private: char* _name; public: F(char*); virtual const char* name(); }; #endif Analizo-1.25.4/t/samples/hierarchical_graph/c/e.cc0000644000175000017500000000032214300274526021213 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.4/t/samples/hierarchical_graph/csharp/0000755000175000017500000000000014300274526021521 5ustar joeniojoenioAnalizo-1.25.4/t/samples/hierarchical_graph/csharp/E.cs0000644000175000017500000000043614300274526022237 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.4/t/samples/hierarchical_graph/csharp/D.cs0000644000175000017500000000031114300274526022226 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.4/t/samples/hierarchical_graph/csharp/Program.cs0000644000175000017500000000033714300274526023462 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.4/t/samples/hierarchical_graph/csharp/F.cs0000644000175000017500000000031014300274526022227 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.4/t/samples/hierarchical_graph/csharp/B.cs0000644000175000017500000000043614300274526022234 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.4/t/samples/hierarchical_graph/csharp/C.cs0000644000175000017500000000043614300274526022235 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.4/t/Analizo/0000755000175000017500000000000014300274526014373 5ustar joeniojoenioAnalizo-1.25.4/t/Analizo/Command.t0000644000175000017500000000216514300274526016142 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.4/t/Analizo/FilenameFilter.t0000644000175000017500000000175014300274526017451 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.4/t/Analizo/ModuleMetrics.t0000644000175000017500000000173514300274526017342 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.4/t/Analizo/GlobalMetrics.t0000644000175000017500000001540314300274526017312 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.4/t/Analizo/Batch.t0000644000175000017500000000141214300274526015577 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.4/t/Analizo/Extractor/0000755000175000017500000000000014300274526016346 5ustar joeniojoenioAnalizo-1.25.4/t/Analizo/Extractor/Doxyparse.t0000644000175000017500000003022514300274526020513 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.4/t/Analizo/Extractor.t0000644000175000017500000001350714300274526016541 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.4/t/Analizo/GlobalMetric/0000755000175000017500000000000014300274526016737 5ustar joeniojoenioAnalizo-1.25.4/t/Analizo/GlobalMetric/MethodsPerAbstractClass.t0000644000175000017500000000216714300274526023656 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.4/t/Analizo/GlobalMetric/TotalAbstractClasses.t0000644000175000017500000000203014300274526023204 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.4/t/Analizo/GlobalMetric/ChangeCost.t0000644000175000017500000000263014300274526021143 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.4/t/Analizo/Metrics.t0000644000175000017500000000370314300274526016171 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.4/t/Analizo/ModuleMetric.t0000644000175000017500000000112414300274526017147 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.4/t/Analizo/Metric/0000755000175000017500000000000014300274527015617 5ustar joeniojoenioAnalizo-1.25.4/t/Analizo/Metric/LinesOfCode.t0000644000175000017500000000207114300274526020135 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.4/t/Analizo/Metric/AverageNumberOfParameters.t0000644000175000017500000000204414300274526023037 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.4/t/Analizo/Metric/NumberOfAttributes.t0000644000175000017500000000203114300274526021563 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.4/t/Analizo/Metric/NumberOfMethods.t0000644000175000017500000000204414300274526021044 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.4/t/Analizo/Metric/NumberOfPublicAttributes.t0000644000175000017500000000237314300274526022733 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.4/t/Analizo/Metric/LackOfCohesionOfMethods.t0000644000175000017500000000425014300274526022444 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.4/t/Analizo/Metric/AfferentConnections/0000755000175000017500000000000014300274527021554 5ustar joeniojoenioAnalizo-1.25.4/t/Analizo/Metric/AfferentConnections/AfferentConnectionsByInheritance.t0000644000175000017500000000471114300274527030346 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.4/t/Analizo/Metric/AfferentConnections/AfferentConnectionsComplete.t0000644000175000017500000000363014300274527027371 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.4/t/Analizo/Metric/AfferentConnections/AfferentConnectionsByReference.t0000644000175000017500000000463514300274527030020 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.4/t/Analizo/Metric/AverageMethodLinesOfCode.t0000644000175000017500000000223014300274526022566 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.4/t/Analizo/Metric/DepthOfInheritanceTree.t0000644000175000017500000000237114300274526022331 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.4/t/Analizo/Metric/MaximumMethodLinesOfCode.t0000644000175000017500000000221314300274526022632 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.4/t/Analizo/Metric/NumberOfChildren.t0000644000175000017500000000274314300274526021177 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.4/t/Analizo/Metric/NumberOfPublicMethods.t0000644000175000017500000000235014300274526022203 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.4/t/Analizo/Metric/ResponseForClass.t0000644000175000017500000000270414300274526021241 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.4/t/Analizo/Metric/CouplingBetweenObjects.t0000644000175000017500000000322614300274526022412 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.4/t/Analizo/Metric/StructuralComplexity.t0000644000175000017500000000377614300274526022246 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.4/t/Analizo/Metric/AverageCycloComplexity.t0000644000175000017500000000255614300274526022435 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.4/t/Analizo/Command/0000755000175000017500000000000014300274526015751 5ustar joeniojoenioAnalizo-1.25.4/t/Analizo/Command/files_graph.t0000644000175000017500000000106614300274526020424 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.4/t/Analizo/Command/metrics.t0000644000175000017500000000104214300274526017601 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.4/t/Analizo/Command/metrics_batch.t0000644000175000017500000000110014300274526020735 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.4/t/Analizo/Command/tree_evolution.t0000644000175000017500000000110514300274526021176 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.4/t/Analizo/Command/graph.t0000644000175000017500000000103014300274526017231 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.4/t/Analizo/Command/help.t0000644000175000017500000000102414300274526017063 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.4/t/Analizo/Command/metrics_history.t0000644000175000017500000000232014300274526021362 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.4/t/Analizo/Batch/0000755000175000017500000000000014300274526015414 5ustar joeniojoenioAnalizo-1.25.4/t/Analizo/Batch/Output/0000755000175000017500000000000014300274526016714 5ustar joeniojoenioAnalizo-1.25.4/t/Analizo/Batch/Output/CSV.t0000644000175000017500000000601314300274526017534 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.4/t/Analizo/Batch/Output/DB.t0000644000175000017500000002341514300274526017373 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.4/t/Analizo/Batch/Job.t0000644000175000017500000001351014300274526016313 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.4/t/Analizo/Batch/Runner.t0000644000175000017500000000211414300274526017050 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.4/t/Analizo/Batch/Output.t0000644000175000017500000000223714300274526017105 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.4/t/Analizo/Batch/Job/0000755000175000017500000000000014300274526016126 5ustar joeniojoenioAnalizo-1.25.4/t/Analizo/Batch/Job/Git.t0000644000175000017500000001452414300274526017044 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.4/t/Analizo/Batch/Job/Directories.t0000644000175000017500000000154014300274526020567 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.4/t/Analizo/Batch/Git.t0000644000175000017500000000373014300274526016327 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.4/t/Analizo/Batch/Directories.t0000644000175000017500000000217514300274526020062 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.4/t/Analizo/Batch/Runner/0000755000175000017500000000000014300274526016665 5ustar joeniojoenioAnalizo-1.25.4/t/Analizo/Batch/Runner/Parallel.t0000644000175000017500000000127314300274526020611 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.4/t/Analizo/Batch/Runner/Sequential.t0000644000175000017500000000276014300274526021171 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.4/t/Analizo/Model.t0000644000175000017500000003110014300274526015613 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.4/t/Analizo/LanguageFilter.t0000644000175000017500000000373214300274526017456 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.4/LICENSE0000644000175000017500000010477714300274526013560 0ustar joeniojoenioThis software is Copyright (c) 2022 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.4/INSTALL.md0000644000175000017500000001077414300274526014174 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.4/development-setup.sh0000755000175000017500000000442014300274526016552 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 Analizo-1.25.4/RELEASE.md0000644000175000017500000000151614300274526014140 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.4/PROFILING.md0000644000175000017500000000205314300274526014406 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.4/refresh-authors0000755000175000017500000000115614300274526015605 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.4/Vagrantfile0000644000175000017500000000023114300274526014714 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.4/HACKING.md0000644000175000017500000001101514300274526014117 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.4/99-details.csv0000644000175000017500000000051214300274526015132 0ustar joeniojoeniofilename,module,acc,accm,amloc,anpm,cbo,dit,lcom4,loc,mmloc,noa,noc,nom,npa,npm,rfc,sc animal.h,Animal,4,1,1,0,0,0,1,1,1,0,1,1,0,1,1,0 cat.h/cat.cc,Cat,0,1,3,0.5,0,2,1,6,3,1,0,2,0,2,4,0 dog.h/dog.cc,Dog,0,1,3,0.5,0,2,1,6,3,1,0,2,0,2,4,0 main.cc,main,0,1,9,0,1,0,1,9,9,0,0,1,0,1,2,1 mammal.h,Mammal,2,1,1,0,0,1,1,1,1,0,2,1,0,0,1,0 Analizo-1.25.4/lib/0000755000175000017500000000000014300274526013301 5ustar joeniojoenioAnalizo-1.25.4/lib/Test/0000755000175000017500000000000014300274526014220 5ustar joeniojoenioAnalizo-1.25.4/lib/Test/Analizo.pm0000644000175000017500000000270214300274526016154 0ustar joeniojoeniopackage Test::Analizo; use strict; use warnings; use parent qw( Exporter ); our @EXPORT = qw( on_dir on_tmpdir mock tmpdir unpack_sample_git_repository readfile ); use Test::MockObject::Extends; use File::Path qw(remove_tree); sub on_dir { my ($dir, $code) = @_; my $previous_pwd = `pwd`; chomp $previous_pwd; chdir $dir; if (wantarray()) { my @list = &$code(); chdir $previous_pwd; return @list; } my $result = &$code(); chdir $previous_pwd; return $result; } sub mock { my ($object) = @_; Test::MockObject::Extends->new($object); } sub tmpdir { my ($package, $filename, $line) = caller; return tmpdir_for($filename); } use Cwd 'abs_path'; sub tmpdir_for { my ($filename) = @_; $filename = abs_path($filename); return $filename . '.tmpdir'; } sub on_tmpdir { my ($code) = @_; my $tmpdir = tmpdir; mkdir $tmpdir; my $result = on_dir($tmpdir, $code); remove_tree $tmpdir; return $result; } sub unpack_sample_git_repository { my ($code, @repos) = @_; if (!@repos) { @repos = ('evolution'); } my ($package, $filename, $line) = caller; my $tmpdir = tmpdir_for($filename); system("mkdir -p $tmpdir"); for my $repo (@repos) { system("tar xzf t/samples/$repo.tar.gz -C $tmpdir --no-same-owner"); } &$code(); system("rm -rf $tmpdir"); } sub readfile { my ($filename) = @_; open INPUT, $filename; my @lines = ; close INPUT; chomp @lines; return @lines; } 1; Analizo-1.25.4/lib/Test/Analizo/0000755000175000017500000000000014300274526015615 5ustar joeniojoenioAnalizo-1.25.4/lib/Test/Analizo/BDD/0000755000175000017500000000000014300274526016206 5ustar joeniojoenioAnalizo-1.25.4/lib/Test/Analizo/BDD/Cucumber/0000755000175000017500000000000014300274526017753 5ustar joeniojoenioAnalizo-1.25.4/lib/Test/Analizo/BDD/Cucumber/Extension.pm0000644000175000017500000000125514300274526022270 0ustar joeniojoeniopackage Test::Analizo::BDD::Cucumber::Extension; use strict; use warnings; use File::Temp qw( tempdir ); use File::Path qw(remove_tree); use File::Spec; use parent qw(Test::BDD::Cucumber::Extension); use Cwd; our $top_dir = cwd(); $ENV{LC_ALL} = 'C'; $ENV{PATH} = "$top_dir:$ENV{PATH}"; sub pre_scenario { my ($self, $scenario, $feature_stash, $scenario_stash) = @_; $ENV{ANALIZO_CACHE} = tempdir("analizo-XXXXXXXXXX", CLEANUP => 1, DIR => File::Spec->tmpdir); } sub post_scenario { my ($self, $scenario, $feature_stash, $scenario_stash, $failed) = @_; unlink 'tmp.out'; unlink 'tmp.err'; unlink glob('*.tmp'); remove_tree $ENV{ANALIZO_CACHE}; chdir $top_dir; } 1; Analizo-1.25.4/lib/Test/Analizo/Git.pm0000644000175000017500000000130714300274526016677 0ustar joeniojoeniopackage Test::Analizo::Git; use parent 'Exporter'; @EXPORT = qw( $MAIN $SOME_COMMIT $IRRELEVANT_COMMIT $FIRST_COMMIT $MERGE_COMMIT $ADD_OUTPUT_COMMIT $RELEVANT_MERGE ); our $MAIN = '8183eafad3a0f3eff6e8869f1bdbfd255e86825a'; # first commit id in sample our $SOME_COMMIT = '0a06a6fcc2e7b4fe56d134e89d74ad028bb122ed'; # some commit in the middle of the history our $IRRELEVANT_COMMIT = 'acd043761ee8071e8cef792629ccbb9492c53132'; our $FIRST_COMMIT = '0d3c023120ad4e9f519a03fff275d048c52671ad'; our $MERGE_COMMIT = '0fdaaa7dcc8073332a957024fafc8c98f165e725'; our $ADD_OUTPUT_COMMIT = 'e8faf88f0e20a193d700b6c68eeb31897dd85e53'; our $RELEVANT_MERGE = 'eb67c27055293e835049b58d7d73ce3664d3f90e'; 1; Analizo-1.25.4/lib/Test/Analizo/Class.pm0000644000175000017500000000103414300274526017216 0ustar joeniojoeniopackage Test::Analizo::Class; use strict; use warnings; use local::lib; use parent qw( Test::Class ); use File::Path qw(remove_tree); use File::Temp qw( tempdir ); use File::Spec; sub create_tmpdir : Test(setup) { mkdir 't/tmp'; } sub cleanup_tmpdir : Test(teardown) { remove_tree 't/tmp'; } sub create_analizo_cache_tmpdir : Test(setup) { $ENV{ANALIZO_CACHE} = tempdir("analizo-XXXXXXXXXX", CLEANUP => 1, DIR => File::Spec->tmpdir); } sub cleanup_analizo_cache_tmpdir : Test(teardown) { remove_tree $ENV{ANALIZO_CACHE}; } 1; Analizo-1.25.4/lib/Analizo.pm0000644000175000017500000001060514300274526015236 0ustar joeniojoeniopackage Analizo; use App::Cmd::Setup -app; use strict; use warnings; use local::lib; our $VERSION = '1.25.4'; =head1 NAME analizo - multi-language source code analysis toolkit =head1 USAGE analizo [tool-options] [ ...] analizo