]> matita.cs.unibo.it Git - helm.git/blob - helm/papers/use_case/stats/stats.cc
ocaml 3.09 transition
[helm.git] / helm / papers / use_case / stats / stats.cc
1
2 #include <vector>
3 #include <cassert>
4 #include <GdomeSmartDOM.hh>
5
6 #include <ext/hash_map>
7 namespace stdx = __gnu_cxx;
8
9 namespace DOM = GdomeSmartDOM;
10
11 int n_elements;
12 int n_leaf_elements;
13 int n_text_nodes;
14 int n_blank_text_nodes;
15 int n_attributes;
16 int max_attributes;
17 int max_children;
18 stdx::hash_map<int,int> depths;
19 std::vector<int> widths;
20
21 bool
22 is_blank(const std::string& s)
23 {
24   for (int i = 0; i < s.length(); i++)
25     if (!isspace(s[i])) return false;
26   return true;
27 }
28
29 void
30 add_depth(int depth)
31 {
32   stdx::hash_map<int,int>::iterator p = depths.find(depth);
33   if (p != depths.end())
34     p->second++;
35   else
36     depths[depth] = 1;
37 }
38
39 void
40 visit(DOM::Node node, int depth)
41 {
42   assert(node);
43
44   add_depth(depth);
45
46   switch (node.get_nodeType())
47     {
48     case DOM::Node::ELEMENT_NODE:
49       {
50         n_elements++;
51         const int n_attrs = node.get_attributes().get_length();
52         n_attributes += n_attrs;
53         max_attributes = std::max(max_attributes, n_attrs);
54         if (!node.get_firstChild()) n_leaf_elements++;
55       }
56       break;
57     case DOM::Node::TEXT_NODE:
58       n_text_nodes++;
59       if (is_blank(node.get_nodeValue())) n_blank_text_nodes++;
60       break;
61     case DOM::Node::ATTRIBUTE_NODE:
62       break;
63     }
64
65   int n_children = 0;
66   for (DOM::Node p = node.get_firstChild(); p; p = p.get_nextSibling())
67     {
68       visit(p, depth + 1);
69       n_children++;
70     }
71   max_children = std::max(max_children, n_children);
72
73   if (node.get_firstChild())
74     widths.push_back(n_children);
75 }
76
77 void
78 print_results(const std::string& URI, long size)
79 {
80   int n_depths = 0;
81   int tot_depth = 0;
82   int max_depth = 0;
83   for (stdx::hash_map<int,int>::const_iterator p = depths.begin(); p != depths.end(); p++)
84     {
85       n_depths += p->second;
86       tot_depth += p->first * p->second;
87       max_depth = std::max(max_depth, p->first);
88     }
89
90   int tot_width = 0;
91   for (std::vector<int>::const_iterator p = widths.begin(); p != widths.end(); p++)
92     tot_width += *p;
93
94   std::cout << "<stats for=\"" << URI << "\">" << std::endl;
95   std::cout << "  <size>" << size << "</size>" << std::endl;
96   std::cout << "  <depth>" << std::endl;
97   std::cout << "    <max>" << max_depth << "</max>" << std::endl;
98   std::cout << "    <leaf-avg>" << tot_depth / ((double) n_depths) << "</leaf-avg>" << std::endl;
99   std::cout << "  </depth>" << std::endl;
100   std::cout << "  <width>" << std::endl;
101   std::cout << "    <max>" << max_children << "</max>" << std::endl;
102   std::cout << "    <inner-avg>" << tot_width / ((double) widths.size()) << "</inner-avg>" << std::endl;
103   std::cout << "  </width>" << std::endl;  
104   std::cout << "  <elements>" << std::endl;
105   std::cout << "    <total>" << n_elements << "</total>" << std::endl;
106   std::cout << "    <leaf>" << n_leaf_elements << "</leaf>" << std::endl;
107   std::cout << "  </elements>" << std::endl;
108   std::cout << "  <text-nodes>" << std::endl;
109   std::cout << "    <total>" << n_text_nodes << "</total>" << std::endl;
110   std::cout << "    <blank>" << n_blank_text_nodes << "</blank>" << std::endl;
111   std::cout << "  </text-nodes>" << std::endl;
112   std::cout << "  <attributes>" << std::endl;
113   std::cout << "    <total>" << n_attributes << "</total>" << std::endl;
114   std::cout << "    <max>" << max_attributes << "</max>" << std::endl;
115   std::cout << "  </attributes>" << std::endl;
116   std::cout << "</stats>" << std::endl;
117 }
118
119 int
120 main(int argc, char* argv[])
121 {
122   if (argc != 3) {
123     std::cerr << "Usage: stats <URI> <size>" << std::endl;
124     return -1;
125   }
126
127   DOM::DOMImplementation di;
128   DOM::Document doc = di.createDocumentFromURI(argv[1]);
129   visit(doc, 0);
130   print_results(argv[1], atoi(argv[2]));
131 }