xref: /netbsd-src/external/gpl3/gcc/dist/libstdc++-v3/doc/doxygen/stdheader.cc (revision b1e838363e3c6fc78a55519254d99869742dd33c)
1 #include <string>
2 #include <string_view>
3 #include <map>
4 #include <set>
5 #include <algorithm>
6 #include <iterator>
7 #include <iostream>
8 
9 // This is a slow larval-stage kludge to help massage the generated man
10 // pages.  It's used like this:
11 const std::string_view usage = R"(
12 Takes on stdin, whitespace-separated words of the form
13 
14     [bits/]stl_foo.h
15     [bits/]std_foo.h
16 
17 and writes on stdout the nearest matching standard header name.
18 
19 Takes no command-line arguments.
20 )";
21 
22 // List of standard headers
23 std::set<std::string_view> std_headers;
24 // Map of partial header filenames to standard headers.
25 std::map<std::string_view, std::string_view>  headers;
26 
init_map()27 void init_map()
28 {
29     // Enter the glamourous world of data entry!!  Maintain these!
30     // Because the map_header function removes common prefixes and suffixes,
31     // a header "bits/st[dl]_foo.h" will automatically map to "foo" if that
32     // is a standard header, so we don't need to list those cases here.
33     headers["atomic_base.h"]            = "atomic";
34     headers["atomic_lockfree_defines.h"] = "atomic";
35     headers["atomic_timed_wait.h"]      = "atomic";
36     headers["atomic_wait.h"]            = "atomic";
37     headers["algorithmfwd.h"]           = "algorithm";
38     headers["algo.h"]                   = "algorithm";
39     headers["algobase.h"]               = "algorithm";
40     headers["ranges_algo.h"]            = "algorithm";
41     headers["ranges_algobase.h"]        = "algorithm";
42     headers["heap.h"]                   = "algorithm";
43     headers["exception_ptr.h"]          = "exception";
44     headers["nested_exception.h"]       = "exception";
45     headers["fs_dir.h"]                 = "filesystem";
46     headers["fs_fwd.h"]                 = "filesystem";
47     headers["fs_ops.h"]                 = "filesystem";
48     headers["fs_path.h"]                = "filesystem";
49     headers["binders.h"]                = "functional";
50     headers["function.h"]               = "functional";
51     headers["functional_hash.h"]        = "functional";
52     headers["mofunc_impl.h"]            = "functional";
53     headers["move_only_function.h"]     = "functional";
54     headers["invoke.h"]                 = "functional";
55     headers["refwrap.h"]                = "functional";
56     headers["quoted_string.h"]          = "iomanip";
57     headers["ios_base.h"]               = "ios";
58     headers["basic_ios.h"]              = "ios";
59     headers["basic_ios.tcc"]            = "ios";
60     headers["iosfwd.h"]                 = "iosfwd";
61     headers["iostream.h"]               = "iostream";
62     headers["iterator_base_funcs.h"]    = "iterator";
63     headers["iterator_base_types.h"]    = "iterator";
64     headers["stream_iterator.h"]        = "iterator";
65     headers["streambuf_iterator.h"]     = "iterator";
66     headers["iterator_concepts.h"]      = "iterator";
67     headers["range_access.h"]           = "iterator";
68     headers["codecvt.h"]                = "locale";
69     headers["c++locale.h"]              = "locale";
70     headers["localefwd.h"]              = "locale";
71     headers["ctype_base.h"]             = "locale";
72     headers["locale_classes.h"]         = "locale";
73     headers["locale_classes.tcc"]       = "locale";
74     headers["locale_facets.h"]          = "locale";
75     headers["locale_facets.tcc"]        = "locale";
76     headers["locale_facets_nonio.h"]    = "locale";
77     headers["locale_facets_nonio.tcc"]  = "locale";
78     headers["locale_conv.h"]            = "locale";
79     headers["multimap.h"]               = "map";
80     headers["memoryfwd.h"]              = "memory";
81     headers["align.h"]                  = "memory";
82     headers["alloc_traits.h"]           = "memory";
83     headers["auto_ptr.h"]		= "memory";
84     headers["construct.h"]              = "memory";
85     headers["allocator.h"]              = "memory";
86     headers["raw_storage_iter.h"]       = "memory";
87     headers["tempbuf.h"]                = "memory";
88     headers["uninitialized.h"]          = "memory";
89     headers["shared_ptr.h"]             = "memory";
90     headers["shared_ptr_base.h"]        = "memory";
91     headers["shared_ptr_atomic.h"]      = "memory";
92     headers["unique_ptr.h"]             = "memory";
93     headers["ranges_uninitialized.h"]   = "memory";
94     headers["ptr_traits.h"]             = "memory";
95     headers["uses_allocator.h"]         = "memory";
96     headers["uses_allocator_args.h"]    = "memory";
97     headers["unique_lock.h"]            = "mutex";
98     headers["uniform_int_dist.h"]       = "random";
99     headers["ranges_base.h"]            = "ranges";
100     headers["ranges_util.h"]            = "ranges";
101     headers["ranges_cmp.h"]             = "functional";
102     headers["regex_automaton.h"]        = "regex";
103     headers["regex_automaton.tcc"]      = "regex";
104     headers["regex_compiler.h"]         = "regex";
105     headers["regex_compiler.tcc"]       = "regex";
106     headers["regex_constants.h"]        = "regex";
107     headers["regex_error.h"]            = "regex";
108     headers["regex_executor.h"]         = "regex";
109     headers["regex_executor.tcc"]       = "regex";
110     headers["regex_scanner.h"]          = "regex";
111     headers["regex_scanner.tcc"]        = "regex";
112     headers["semaphore_base.h"]         = "semaphore";
113     headers["multiset.h"]               = "set";
114     headers["node_handle.h"]            = "set";
115     headers["functexcept.h"]            = "stdexcept";
116     headers["char_traits.h"]            = "string";
117     headers["stringfwd.h"]              = "string";
118     headers["postypes.h"]               = "string";
119     headers["basic_string.h"]           = "string";
120     headers["basic_string.tcc"]         = "string";
121     headers["cow_string.h"]             = "string";
122     headers["string_view.tcc"]          = "string_view";
123     headers["this_thread_sleep.h"]      = "thread";
124     headers["tree.h"]                   = "map";
125     headers["pair.h"]                   = "utility";
126     headers["relops.h"]                 = "utility";
127     headers["gslice.h"]                 = "valarray";
128     headers["gslice_array.h"]           = "valarray";
129     headers["indirect_array.h"]         = "valarray";
130     headers["mask_array.h"]             = "valarray";
131     headers["slice_array.h"]            = "valarray";
132     headers["valarray_after.h"]         = "valarray";
133     headers["valarray_before.h"]        = "valarray";
134     headers["valarray_array.h"]         = "valarray";
135     headers["valarray_array.tcc"]       = "valarray";
136     headers["valarray_meta.h"]          = "valarray";
137     headers["bvector.h"]                = "vector";
138 
139     //headers["concurrence.h"]             who knows
140     //headers["atomicity.h"]               who knows
141 
142     headers["abs.h"]                    = "cstdlib";
143     headers["specfun.h"]                = "cmath";
144 
145     // This list is complete as of the October 2021 working draft.
146     std_headers = {
147 	"algorithm", "any", "array", "atomic",
148 	"barrier", "bit", "bitset",
149 	"charconv", "chrono", "codecvt", "compare", "complex",
150 	"concepts", "condition_variable", "coroutine",
151 	"deque",
152 	"exception", "execution",
153 	"filesystem", "format", "forward_list", "fstream",
154 	"functional", "future",
155 	"initializer_list", "iomanip", "ios", "iosfwd",
156 	"iostream", "istream", "iterator",
157 	"latch", "limits", "list", "locale",
158 	"map", "memory", "memory_resource", "mutex",
159 	"new", "numbers", "numeric",
160 	"optional", "ostream",
161 	"queue",
162 	"random", "ranges", "ratio", "regex",
163 	"scoped_allocator", "semaphore", "set", "shared_mutex",
164 	"source_location", "span", "spanstream", "sstream",
165 	"stack", "stacktrace", "stdexcept", "stop_token",
166 	"streambuf", "string", "string_view", "strstream",
167 	"syncstream", "system_error",
168 	"thread", "tuple", "typeindex", "typeinfo", "type_traits",
169 	"unordered_map", "unordered_set", "utility",
170 	"valarray", "variant", "vector", "version",
171 
172 	"cassert", "cctype", "cerrno", "cfenv", "cfloat",
173 	"cinttypes", "climits", "clocale", "cmath", "csetjmp",
174 	"csignal", "cstdarg", "cstddef", "cstdint", "cstdio",
175 	"cstdlib", "cstring", "ctime", "cuchar", "cwchar",
176 	"cwctype",
177 
178 	"assert.h", "ctype.h", "errno.h", "fenv.h", "float.h",
179 	"inttypes.h", "limits.h", "locale.h", "math.h", "setjmp.h",
180 	"signal.h", "stdarg.h", "stddef.h", "stdint.h", "stdio.h",
181 	"stdlib.h", "string.h", "time.h", "uchar.h", "wchar.h",
182 	"wctype.h",
183     };
184 
185     // In case we missed any:
186     for (const auto& h : headers)
187 	std_headers.insert(h.second);
188 }
189 
190 
map_header(std::string_view header)191 std::string_view map_header (std::string_view header)
192 {
193     // if it doesn't contain a "." then it's already a std header
194     if (!header.contains('.'))
195     {
196 	// make sure it's in the set:
197 	std_headers.insert(header);
198 	return header;
199     }
200 
201     for (std::string_view prefix : {"bits/", "stl_", "std_"})
202 	if (header.starts_with(prefix))
203 	    header.remove_prefix(prefix.size());
204 
205     if (auto it = headers.find(header); it != headers.end())
206 	return it->second;
207 
208     for (std::string_view ext : {".h", ".tcc"})
209 	if (header.ends_with(ext))
210 	{
211 	    header.remove_suffix(ext.size());
212 	    break;
213 	}
214 
215     if (auto it = std_headers.find(header); it != std_headers.end())
216 	return *it;
217 
218     return {};
219 }
220 
map_header_or_complain(std::string header)221 std::string map_header_or_complain (std::string header)
222 {
223     // For <experimental/xxx.h> and <tr1/xxx.h> try to map <xxx.h>
224     // then add the directory back to it.
225     if (header.contains('.'))
226 	for (std::string_view dir : {"experimental/", "tr1/"})
227 	    if (header.starts_with(dir))
228 	    {
229 		auto h = map_header(header.substr(dir.size()));
230 		if (!h.empty())
231 		    return std::string(dir) + std::string(h);
232 		return std::string(header);
233 	    }
234 
235     if (auto mapped = map_header(header); !mapped.empty())
236 	return std::string(mapped);
237 
238     std::cerr << "Could not map <" << header << "> to a standard header\n";
239     return std::string(header);
240 }
241 
242 
main(int argc,char ** argv)243 int main (int argc, char** argv)
244 {
245     if (argc > 1)
246     {
247         std::cerr << "Usage: " << argv[0] << '\n' << usage;
248 	return 1;
249     }
250 
251     init_map();
252 
253     std::transform(std::istream_iterator<std::string>(std::cin), {},
254 		   std::ostream_iterator<std::string>(std::cout),
255 		   map_header_or_complain);
256 }
257