LCOV - code coverage report
Current view: top level - src - precizer.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 100.0 % 36 36
Test Date: 2026-03-31 13:51:38 Functions: 100.0 % 2 2
Branches: 86.4 % 88 76

             Branch data     Line data    Source code
       1                 :             : /**
       2                 :             :  *
       3                 :             :  * @file precizer.c
       4                 :             :  * @brief Main file
       5                 :             :  *
       6                 :             :  */
       7                 :             : #include "precizer.h"
       8                 :             : 
       9                 :             : /**
      10                 :             :  * Global definitions
      11                 :             :  *
      12                 :             :  */
      13                 :             : 
      14                 :             : // Global variable controls signals to interrupt execution
      15                 :             : // Atomic variable is very fast and will be called very often
      16                 :             : _Atomic bool global_interrupt_flag = false;
      17                 :             : 
      18                 :             : // The global structure Config where all runtime settings will be stored
      19                 :             : Config _config;
      20                 :             : Config *config = &_config;
      21                 :             : 
      22                 :             : /**
      23                 :             :  * @mainpage
      24                 :             :  * @brief precizer is a CLI application designed to verify the integrity of files after synchronization.
      25                 :             :  * The program recursively traverses directories and creates a database
      26                 :             :  * of files and their checksums, followed by a quick comparison.
      27                 :             :  *
      28                 :             :  * @author Dennis Razumovsky
      29                 :             :  * @details precizer specializes in managing vast file systems.
      30                 :             :  * The program identifies synchronization errors by cross-referencing
      31                 :             :  * data and checksums from various sources. Alternatively, it can be
      32                 :             :  * used to crawl historical changes by comparing databases from the
      33                 :             :  * same sources over different times
      34                 :             :  */
      35                 :             : /**
      36                 :             :  * @brief Program entry point for normal and TESTITALL builds
      37                 :             :  *
      38                 :             :  * @details Initializes runtime state, executes the main workflow, prints final
      39                 :             :  * diagnostics, and returns the shell exit status. In TESTITALL builds the same
      40                 :             :  * implementation is exposed as `test_main()`
      41                 :             :  *
      42                 :             :  * @param argc Number of CLI arguments
      43                 :             :  * @param argv CLI argument vector
      44                 :             :  * @return Process exit status for the completed run
      45                 :             :  */
      46                 :             : #ifndef TESTITALL // Unit testing library
      47                 :         229 : int main(
      48                 :             :         int  argc,
      49                 :             :         char **argv)
      50                 :             : #else
      51                 :         226 : int test_main(
      52                 :             :         int  argc,
      53                 :             :         char **argv)
      54                 :             : #endif // TESTITALL
      55                 :             : {
      56                 :             :         /* This function was reviewed line by line by a human and is not AI-generated
      57                 :             :            Any change to this function requires separate explicit approval */
      58                 :             : 
      59                 :             :         /* Status returned by this function through provide()
      60                 :             :            Default value assumes successful completion */
      61                 :         455 :         Return status = SUCCESS;
      62                 :             : 
      63                 :             :         // Stack storage for traversal stats, zero-initialized.
      64                 :         455 :         TraversalSummary _summary = {0};
      65                 :             :         // Use pointer form for consistency.
      66                 :         455 :         TraversalSummary *summary = &_summary;
      67                 :             : 
      68                 :             :         // Initialize configuration with values
      69                 :         455 :         init_config();
      70                 :             : 
      71                 :             :         // Fill Config structure
      72                 :             :         // parsing command line arguments
      73   [ +  -  +  + ]:         455 :         run(parse_arguments(argc,argv));
      74                 :             : 
      75                 :             :         // Compile PCRE2 patterns from --ignore, --include, --lock-checksum once
      76                 :             :         // so that file traversal reuses compiled objects instead of recompiling per file
      77   [ +  +  -  + ]:         455 :         run(compile_patterns());
      78                 :             : 
      79                 :             :         // Print program identity only when argument parsing is not in info mode
      80         [ +  + ]:         455 :         if((status & INFO) == 0)
      81                 :             :         {
      82                 :         425 :                 about();
      83                 :             :         }
      84                 :             : 
      85                 :             :         // Verify that the provided paths exist and
      86                 :             :         // are directories
      87   [ +  +  -  + ]:         455 :         run(paths_detect());
      88                 :             : 
      89                 :             :         // Initialize signals interception like Ctrl+C
      90   [ +  +  -  + ]:         455 :         run(init_signals());
      91                 :             : 
      92                 :             :         // The current directory where app being executed
      93   [ +  +  -  + ]:         455 :         run(determine_running_dir());
      94                 :             : 
      95                 :             :         // Generate DB file name if
      96                 :             :         // not passed as an argument
      97   [ +  +  -  + ]:         455 :         run(db_determine_name());
      98                 :             : 
      99                 :             :         // Validate database file existence and set up existence flag
     100   [ +  +  +  + ]:         455 :         run(db_primary_file_validate_existence());
     101                 :             : 
     102                 :             :         // Define the database operation mode
     103   [ +  +  +  + ]:         455 :         run(db_determine_mode());
     104                 :             : 
     105                 :             :         // Primary database file integrity check
     106   [ +  +  +  + ]:         455 :         run(db_primary_file_test());
     107                 :             : 
     108                 :             :         // Initialize SQLite database
     109   [ +  +  +  + ]:         455 :         run(db_init());
     110                 :             : 
     111                 :             :         // Compare databases
     112   [ +  +  +  + ]:         455 :         run(db_compare());
     113                 :             : 
     114                 :             :         // Check whether the database already exists or not yet
     115   [ +  +  +  + ]:         455 :         run(db_contains_data());
     116                 :             : 
     117                 :             :         // Verify that the provided path arguments match
     118                 :             :         // the paths stored in the database
     119   [ +  +  +  + ]:         455 :         run(db_validate_paths());
     120                 :             : 
     121                 :             :         // Save new prefixes that has been passed as
     122                 :             :         // arguments
     123   [ +  +  -  + ]:         455 :         run(db_save_prefixes());
     124                 :             : 
     125                 :             :         // Just get a statistic
     126                 :         455 :         summary->stats_only_pass = true;
     127   [ +  +  -  + ]:         455 :         run(file_list(summary));
     128                 :             : 
     129                 :             :         // Get file list and their checksums
     130                 :         455 :         summary->stats_only_pass = false;
     131   [ +  +  +  + ]:         455 :         run(file_list(summary));
     132                 :             : 
     133                 :             :         // Update the database. Remove files that
     134                 :             :         // no longer exist.
     135   [ +  +  -  + ]:         455 :         run(db_delete_missing_metadata());
     136                 :             : 
     137                 :             :         // Print remembered warning and error lines when delayed output is enabled
     138   [ -  +  +  + ]:         455 :         call(show_remembered_messages());
     139                 :             : 
     140                 :             :         // Print final totals and runtime metrics after delayed warnings/errors.
     141                 :             :         // This runs only for successful execution flow.
     142         [ +  + ]:         455 :         if((SUCCESS|WARNING) & status)
     143                 :             :         {
     144                 :         421 :                 show_statistics(summary);
     145                 :         421 :                 show_elapsed(summary);
     146                 :             :         }
     147                 :             : 
     148                 :             :         // Disable journaling, flush the journal to the main database,
     149                 :             :         // clear the cache, and close the database
     150   [ -  +  +  + ]:         455 :         call(db_close(config->db,&config->db_primary_file_modified));
     151                 :             : 
     152                 :             :         // Optimizing the space occupied by a database file.
     153   [ +  +  -  + ]:         455 :         run(db_primary_consider_vacuum());
     154                 :             : 
     155                 :             :         // Print out whether there have been changes to
     156                 :             :         // the file system and accordingly against the database
     157                 :             :         // since the last research
     158   [ +  +  +  + ]:         455 :         run(status_of_changes());
     159                 :             : 
     160                 :             :         // Free allocated memory
     161                 :             :         // for arrays and variables
     162                 :         455 :         free_config();
     163                 :             : 
     164                 :         455 :         return(exit_status(status,argv));
     165                 :             : }
        

Generated by: LCOV version 2.0-1