Branch data Line data Source code
1 : : #include "precizer.h"
2 : :
3 : : /**
4 : : * @brief Retrieve a const pointer to a flag descriptor by index
5 : : *
6 : : * Uses the mem helper to obtain a typed readonly view of the @ref Flags array and
7 : : * performs bounds checking. Returns NULL if the descriptor is missing, type
8 : : * verification fails, or the index is out of range
9 : : */
10 : 8 : static const Flags *lookup(
11 : : const memory *flags,
12 : : size_t index)
13 : : {
14 : 8 : const Flags *flags_data_view = m_data_ro(Flags,flags);
15 : :
16 [ + - - + ]: 8 : if(flags_data_view == NULL || index >= flags->length)
17 : : {
18 : 0 : return(NULL);
19 : : }
20 : :
21 : 8 : return(&flags_data_view[index]);
22 : : }
23 : :
24 : : /**
25 : : * @brief Print database metadata fields that changed between two snapshots
26 : : *
27 : : * Expands a metadata-change bit mask into user-visible field names and detailed
28 : : * values. The function is used when final database-file consistency checks need
29 : : * to explain why the database file metadata differs from the saved baseline
30 : : *
31 : : * @param[in] change_flags_mask Bit mask describing which metadata fields changed
32 : : * @param[in] before Saved metadata snapshot from the beginning of the run
33 : : * @param[in] after Current metadata snapshot from the end of the run
34 : : * @return SUCCESS when there is nothing to print or the difference was printed,
35 : : * otherwise FAILURE for missing snapshots
36 : : */
37 : 2 : Return show_difference(
38 : : Changed change_flags_mask,
39 : : const CmpctStat *before,
40 : : const CmpctStat *after)
41 : : {
42 : : /* Validate input parameters */
43 [ + - - + ]: 2 : if(NULL == before || NULL == after)
44 : : {
45 : 0 : return(FAILURE);
46 : : }
47 : :
48 [ - + ]: 2 : if(change_flags_mask == IDENTICAL)
49 : : {
50 : 0 : return(SUCCESS);
51 : : }
52 : :
53 : : /* Status returned by this function through provide()
54 : : Default value assumes successful completion */
55 : 2 : Return status = SUCCESS;
56 : :
57 : 2 : m_create(Flags,flags);
58 : 2 : call(m_resize(flags,4));
59 : :
60 : 2 : Flags *flags_data_rewritable = m_data(Flags,flags);
61 : :
62 [ - + ]: 2 : if(flags_data_rewritable == NULL)
63 : : {
64 : 0 : m_del(flags);
65 : 0 : provide(FAILURE);
66 : : }
67 : :
68 : 2 : flags_data_rewritable[0] = (Flags){SIZE_CHANGED,"lsize"};
69 : 2 : flags_data_rewritable[1] = (Flags){ALLOCATED_SIZE_CHANGED,"asize"};
70 : 2 : flags_data_rewritable[2] = (Flags){STATUS_CHANGED_TIME,"ctime"};
71 : 2 : flags_data_rewritable[3] = (Flags){MODIFICATION_TIME_CHANGED,"mtime"};
72 : :
73 : 2 : unsigned int flags_found = 0;
74 : 2 : bool first_word = true;
75 : :
76 : : /* Check each flag */
77 [ + + ]: 10 : for(size_t i = 0; i < flags->length; i++)
78 : : {
79 : 8 : const Flags *flag = lookup(flags,i);
80 : :
81 [ - + ]: 8 : if(flag == NULL)
82 : : {
83 : 0 : break;
84 : : }
85 : :
86 [ + + ]: 8 : if(((unsigned int)change_flags_mask & (unsigned int)flag->flag_value) != 0u)
87 : : {
88 [ + + ]: 4 : if(first_word == true)
89 : : {
90 : 2 : slog(ERROR,"Database file details: ");
91 : 2 : first_word = false;
92 : : }
93 : :
94 : : /* Add separator if not the first flag */
95 [ + + ]: 4 : if(flags_found > 0)
96 : : {
97 : 2 : slog(ERROR|UNDECOR," & ");
98 : : }
99 : 4 : slog(ERROR|UNDECOR,"%s",flag->flag_name);
100 : 4 : show_metadata(ERROR,flag->flag_value,before,after);
101 : 4 : flags_found++;
102 : : }
103 : : }
104 : :
105 [ + - ]: 2 : if(flags_found > 0)
106 : : {
107 : 2 : slog(ERROR|UNDECOR,"\n");
108 : : }
109 : :
110 : 2 : m_del(flags);
111 : :
112 : 2 : provide(SUCCESS);
113 : : }
|