1 // Copyright 2008 John Maddock
2 //
3 // Use, modification and distribution are subject to the
4 // Boost Software License, Version 1.0.
5 // (See accompanying file LICENSE_1_0.txt
6 // or copy at http://www.boost.org/LICENSE_1_0.txt)
7
8 #ifndef BOOST_AUTO_INDEX_HPP
9 #define BOOST_AUTO_INDEX_HPP
10
11 #include <boost/version.hpp>
12
13 #if BOOST_VERSION < 104400
14 # error "This tool requires Boost 1.44 or later to build."
15 #endif
16
17 #define BOOST_FILESYSTEM_VERSION 3
18
19 #include "tiny_xml.hpp"
20 #include <boost/regex.hpp>
21 #include <boost/filesystem.hpp>
22 #include <boost/algorithm/string/case_conv.hpp>
23 #include <fstream>
24 #include <cctype>
25 #include <map>
26 #include <set>
27 #include <sstream>
28
29 struct index_info
30 {
31 std::string term; // The term goes in the index entry
32 boost::regex search_text; // What to search for when indexing the term.
33 boost::regex search_id; // What id's this term may be indexed in.
34 std::string category; // Index category (function, class, macro etc).
35 };
operator <(const index_info & a,const index_info & b)36 inline bool operator < (const index_info& a, const index_info& b)
37 {
38 return (a.term != b.term) ? (a.term < b.term) : (a.category < b.category);
39 }
40
41
42 struct index_entry;
43 typedef boost::shared_ptr<index_entry> index_entry_ptr;
44 bool operator < (const index_entry_ptr& a, const index_entry_ptr& b);
45 typedef std::set<index_entry_ptr> index_entry_set;
46
47 struct index_entry
48 {
49 std::string key; // The index term.
50 std::string sort_key; // upper case version of term used for sorting.
51 std::string id; // The id of the block that we will link to.
52 std::string category; // The category of this entry (function, class, macro etc).
53 index_entry_set sub_keys; // All our sub-keys.
54 bool preferred; // This entry is the preferred one for this key
55
index_entryindex_entry56 index_entry() : preferred(false) {}
index_entryindex_entry57 index_entry(const std::string& k) : key(k), sort_key(k), preferred(false) { boost::to_upper(sort_key); }
index_entryindex_entry58 index_entry(const std::string& k, const std::string& i) : key(k), sort_key(k), id(i), preferred(false) { boost::to_upper(sort_key); }
index_entryindex_entry59 index_entry(const std::string& k, const std::string& i, const std::string& c) : key(k), sort_key(k), id(i), category(c), preferred(false) { boost::to_upper(sort_key); }
60 };
61
62
operator <(const index_entry_ptr & a,const index_entry_ptr & b)63 inline bool operator < (const index_entry_ptr& a, const index_entry_ptr& b)
64 {
65 return ((a->sort_key != b->sort_key) ? (a->sort_key < b->sort_key) : (a->category < b->category));
66 }
67
68 struct id_rewrite_rule
69 {
70 bool base_on_id; // rewrite the title if "id" matches the section id, otherwise rewrite if title matches "id".
71 boost::regex id; // regex for the id or title to match
72 std::string new_name; // either literal string or format string for the new name.
73
id_rewrite_ruleid_rewrite_rule74 id_rewrite_rule(const std::string& i, const std::string& n, bool b)
75 : base_on_id(b), id(i), new_name(n) {}
76 };
77
78 struct node_id
79 {
80 const std::string* id;
81 node_id* prev;
82 };
83
84 struct title_info
85 {
86 std::string title;
87 title_info* prev;
88 };
89
90 struct file_scanner
91 {
92 boost::regex scanner, file_name_filter, section_filter;
93 std::string format_string, type, term_formatter;
94 };
95
operator <(const file_scanner & a,const file_scanner & b)96 inline bool operator < (const file_scanner & a, const file_scanner& b)
97 {
98 return a.type < b.type;
99 }
100
101 typedef std::multiset<file_scanner> file_scanner_set_type;
102
103 void process_script(const std::string& script);
104 void scan_dir(const std::string& dir, const std::string& mask, bool recurse);
105 void scan_file(const std::string& file);
106 void generate_indexes();
107 const std::string* find_attr(boost::tiny_xml::element_ptr node, const char* name);
108
109 extern file_scanner_set_type file_scanner_set;
110
add_file_scanner(const std::string & type,const std::string & scanner,const std::string & format,const std::string & term_formatter,const std::string & id_filter,const std::string & file_filter)111 inline void add_file_scanner(const std::string& type, const std::string& scanner, const std::string& format, const std::string& term_formatter, const std::string& id_filter, const std::string& file_filter)
112 {
113 file_scanner s;
114 s.type = type;
115 s.scanner = scanner;
116 s.format_string = format;
117 s.term_formatter = term_formatter;
118 if(file_filter.size())
119 s.file_name_filter = file_filter;
120 if(id_filter.size())
121 s.section_filter = id_filter;
122 file_scanner_set.insert(s);
123 }
124
125 extern std::set<index_info> index_terms;
126 extern std::set<std::pair<std::string, std::string> > found_terms;
127 extern bool no_duplicates;
128 extern bool verbose;
129 extern index_entry_set index_entries;
130 extern boost::tiny_xml::element_list indexes;
131 extern std::list<id_rewrite_rule> id_rewrite_list;
132 extern bool internal_indexes;
133 extern std::string prefix;
134 extern std::string internal_index_type;
135 extern boost::regex debug;
136
137 #endif
138