1 /*
2  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  *  Copyright (C) 2015 - Scilab Enterprises - Calixte DENIZET
4  *
5  * Copyright (C) 2012 - 2016 - Scilab Enterprises
6  *
7  * This file is hereby licensed under the terms of the GNU GPL v2.0,
8  * pursuant to article 5.3.4 of the CeCILL v.2.1.
9  * This file was originally licensed under the terms of the CeCILL v2.1,
10  * and continues to be available under such terms.
11  * For more information, see the COPYING file which you should have received
12  * along with this program.
13  *
14  */
15 
16 #ifndef __COUNTER_HXX__
17 #define __COUNTER_HXX__
18 
19 #include <chrono>
20 
21 #include "allexp.hxx"
22 #include "alltypes.hxx"
23 #include "allvar.hxx"
24 
25 #include "MacroLoc.hxx"
26 
27 namespace coverage
28 {
29 
30 class Counter
31 {
32 
33     uint64_t counter;
34     uint64_t cumTime;
35     std::chrono::steady_clock::time_point start;
36     bool isRunning;
37     types::Macro* macro;
38     ast::Exp* e;
39 
40   public:
Counter(types::Macro * _macro,ast::Exp * _e)41     Counter(types::Macro* _macro, ast::Exp* _e) : counter(0), cumTime(0), macro(_macro), e(_e), isRunning(false) {}
42 
inc()43     inline void inc()
44     {
45         ++counter;
46     }
47 
get() const48     inline uint64_t get() const
49     {
50         return counter;
51     }
52 
getMacro()53     inline types::Macro* getMacro()
54     {
55         return macro;
56     }
57 
getExp()58     inline ast::Exp* getExp()
59     {
60         return e;
61     }
62 
getMacro() const63     inline types::Macro* getMacro() const
64     {
65         return macro;
66     }
67 
getExp() const68     inline ast::Exp* getExp() const
69     {
70         return e;
71     }
72 
startChrono()73     inline void startChrono()
74     {
75         start = std::chrono::steady_clock::now();
76         isRunning = true;
77     }
78 
stopChrono()79     inline void stopChrono()
80     {
81         if (isRunning)
82         {
83             cumTime += std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::steady_clock::now() - start).count();
84             isRunning = false;
85         }
86     }
87 
getNanoTime() const88     inline uint64_t getNanoTime() const
89     {
90         return cumTime;
91     }
92 };
93 
94 class CallCounter
95 {
96     uint64_t counter;
97 
98   public:
CallCounter()99     CallCounter() : counter(0) {}
100 
inc()101     inline void inc()
102     {
103         ++counter;
104     }
105 
get() const106     inline uint64_t get() const
107     {
108         return counter;
109     }
110 
get()111     inline uint64_t get()
112     {
113         return counter;
114     }
115 };
116 
117 struct CounterPredicate
118 {
119     struct by_file_and_location
120     {
operator ()coverage::CounterPredicate::by_file_and_location121         bool operator()(const Location& o1, const Location& o2) const
122         {
123             return o1.first_line < o2.first_line || (o1.first_line == o2.first_line && o2.last_line < o1.last_line);
124         };
125 
operator ()coverage::CounterPredicate::by_file_and_location126         bool operator()(const Counter& o1, const Counter& o2) const
127         {
128             bool file = o1.getMacro()->getFileName() < o2.getMacro()->getFileName();
129             if (!file && o1.getMacro()->getFileName() == o2.getMacro()->getFileName())
130             {
131                 const Location& l1 = o1.getExp()->getLocation();
132                 const Location& l2 = o2.getExp()->getLocation();
133                 return this->operator()(l1, l2);
134             }
135             return file;
136         };
137 
operator ()coverage::CounterPredicate::by_file_and_location138         bool operator()(types::Macro* o1, const Counter& o2) const
139         {
140             bool file = o1->getFileName() < o2.getMacro()->getFileName();
141             if (!file && o1->getFileName() == o2.getMacro()->getFileName())
142             {
143                 const Location& l1 = o1->getBody()->getLocation();
144                 const Location& l2 = o2.getExp()->getLocation();
145                 return this->operator()(l1, l2);
146             }
147 
148             return file;
149         };
150 
operator ()coverage::CounterPredicate::by_file_and_location151         bool operator()(const Counter& o1, types::Macro* o2) const
152         {
153             bool file = o1.getMacro()->getFileName() < o2->getFileName();
154             if (!file && o1.getMacro()->getFileName() == o2->getFileName())
155             {
156                 const Location& l1 = o1.getExp()->getLocation();
157                 const Location& l2 = o2->getBody()->getLocation();
158                 return this->operator()(l1, l2);
159             }
160 
161             return file;
162         };
163 
operator ()coverage::CounterPredicate::by_file_and_location164         bool operator()(const Counter& o1, const MacroLoc& o2) const
165         {
166             if (o1.getMacro()->getName() == o2.name)
167             {
168                 return this->operator()(o1.getExp()->getLocation(), o2.loc);
169             }
170             return o1.getMacro()->getName() < o2.name;
171         };
172 
operator ()coverage::CounterPredicate::by_file_and_location173         bool operator()(const MacroLoc& o1, const Counter& o2) const
174         {
175             if (o1.name == o2.getMacro()->getName())
176             {
177                 return this->operator()(o1.loc, o2.getExp()->getLocation());
178             }
179             return o1.name < o2.getMacro()->getName();
180         };
181     };
182 };
183 
184 } // namespace coverage
185 
186 #endif // __COUNTER_HXX__
187