xref: /aosp_15_r20/external/marisa-trie/tools/marisa-reverse-lookup.cc (revision ab8db090fce404b23716c4c9194221ee27efe31c)
1*ab8db090SAndroid Build Coastguard Worker #include <iostream>
2*ab8db090SAndroid Build Coastguard Worker #include <string>
3*ab8db090SAndroid Build Coastguard Worker 
4*ab8db090SAndroid Build Coastguard Worker #include <marisa.h>
5*ab8db090SAndroid Build Coastguard Worker 
6*ab8db090SAndroid Build Coastguard Worker #include "cmdopt.h"
7*ab8db090SAndroid Build Coastguard Worker 
8*ab8db090SAndroid Build Coastguard Worker namespace {
9*ab8db090SAndroid Build Coastguard Worker 
10*ab8db090SAndroid Build Coastguard Worker bool mmap_flag = true;
11*ab8db090SAndroid Build Coastguard Worker 
print_help(const char * cmd)12*ab8db090SAndroid Build Coastguard Worker void print_help(const char *cmd) {
13*ab8db090SAndroid Build Coastguard Worker   std::cerr << "Usage: " << cmd << " [OPTION]... DIC\n\n"
14*ab8db090SAndroid Build Coastguard Worker       "Options:\n"
15*ab8db090SAndroid Build Coastguard Worker       "  -m, --mmap-dictionary  use memory-mapped I/O to load a dictionary"
16*ab8db090SAndroid Build Coastguard Worker       " (default)\n"
17*ab8db090SAndroid Build Coastguard Worker       "  -r, --read-dictionary  read an entire dictionary into memory\n"
18*ab8db090SAndroid Build Coastguard Worker       "  -h, --help             print this help\n"
19*ab8db090SAndroid Build Coastguard Worker       << std::endl;
20*ab8db090SAndroid Build Coastguard Worker }
21*ab8db090SAndroid Build Coastguard Worker 
reverse_lookup(const char * const * args,std::size_t num_args)22*ab8db090SAndroid Build Coastguard Worker int reverse_lookup(const char * const *args, std::size_t num_args) {
23*ab8db090SAndroid Build Coastguard Worker   if (num_args == 0) {
24*ab8db090SAndroid Build Coastguard Worker     std::cerr << "error: dictionary is not specified" << std::endl;
25*ab8db090SAndroid Build Coastguard Worker     return 10;
26*ab8db090SAndroid Build Coastguard Worker   } else if (num_args > 1) {
27*ab8db090SAndroid Build Coastguard Worker     std::cerr << "error: more than one dictionaries are specified"
28*ab8db090SAndroid Build Coastguard Worker         << std::endl;
29*ab8db090SAndroid Build Coastguard Worker     return 11;
30*ab8db090SAndroid Build Coastguard Worker   }
31*ab8db090SAndroid Build Coastguard Worker 
32*ab8db090SAndroid Build Coastguard Worker   marisa::Trie trie;
33*ab8db090SAndroid Build Coastguard Worker   if (mmap_flag) {
34*ab8db090SAndroid Build Coastguard Worker     try {
35*ab8db090SAndroid Build Coastguard Worker       trie.mmap(args[0]);
36*ab8db090SAndroid Build Coastguard Worker     } catch (const marisa::Exception &ex) {
37*ab8db090SAndroid Build Coastguard Worker       std::cerr << ex.what() << ": failed to mmap a dictionary file: "
38*ab8db090SAndroid Build Coastguard Worker           << args[0] << std::endl;
39*ab8db090SAndroid Build Coastguard Worker       return 20;
40*ab8db090SAndroid Build Coastguard Worker     }
41*ab8db090SAndroid Build Coastguard Worker   } else {
42*ab8db090SAndroid Build Coastguard Worker     try {
43*ab8db090SAndroid Build Coastguard Worker       trie.load(args[0]);
44*ab8db090SAndroid Build Coastguard Worker     } catch (const marisa::Exception &ex) {
45*ab8db090SAndroid Build Coastguard Worker       std::cerr << ex.what() << ": failed to load a dictionary file: "
46*ab8db090SAndroid Build Coastguard Worker           << args[0] << std::endl;
47*ab8db090SAndroid Build Coastguard Worker       return 21;
48*ab8db090SAndroid Build Coastguard Worker     }
49*ab8db090SAndroid Build Coastguard Worker   }
50*ab8db090SAndroid Build Coastguard Worker 
51*ab8db090SAndroid Build Coastguard Worker   marisa::Agent agent;
52*ab8db090SAndroid Build Coastguard Worker   std::size_t key_id;
53*ab8db090SAndroid Build Coastguard Worker   while (std::cin >> key_id) {
54*ab8db090SAndroid Build Coastguard Worker     try {
55*ab8db090SAndroid Build Coastguard Worker       agent.set_query(key_id);
56*ab8db090SAndroid Build Coastguard Worker       trie.reverse_lookup(agent);
57*ab8db090SAndroid Build Coastguard Worker       std::cout << agent.key().id() << '\t';
58*ab8db090SAndroid Build Coastguard Worker       std::cout.write(agent.key().ptr(),
59*ab8db090SAndroid Build Coastguard Worker           static_cast<std::streamsize>(agent.key().length())) << '\n';
60*ab8db090SAndroid Build Coastguard Worker     } catch (const marisa::Exception &ex) {
61*ab8db090SAndroid Build Coastguard Worker       std::cerr << ex.what() << ": reverse_lookup() failed: "
62*ab8db090SAndroid Build Coastguard Worker           << key_id << std::endl;
63*ab8db090SAndroid Build Coastguard Worker       return 30;
64*ab8db090SAndroid Build Coastguard Worker     }
65*ab8db090SAndroid Build Coastguard Worker 
66*ab8db090SAndroid Build Coastguard Worker     if (!std::cout) {
67*ab8db090SAndroid Build Coastguard Worker       std::cerr << "error: failed to write results to standard output"
68*ab8db090SAndroid Build Coastguard Worker           << std::endl;
69*ab8db090SAndroid Build Coastguard Worker       return 30;
70*ab8db090SAndroid Build Coastguard Worker     }
71*ab8db090SAndroid Build Coastguard Worker   }
72*ab8db090SAndroid Build Coastguard Worker 
73*ab8db090SAndroid Build Coastguard Worker   return 0;
74*ab8db090SAndroid Build Coastguard Worker }
75*ab8db090SAndroid Build Coastguard Worker 
76*ab8db090SAndroid Build Coastguard Worker }  // namespace
77*ab8db090SAndroid Build Coastguard Worker 
main(int argc,char * argv[])78*ab8db090SAndroid Build Coastguard Worker int main(int argc, char *argv[]) {
79*ab8db090SAndroid Build Coastguard Worker   std::ios::sync_with_stdio(false);
80*ab8db090SAndroid Build Coastguard Worker 
81*ab8db090SAndroid Build Coastguard Worker   ::cmdopt_option long_options[] = {
82*ab8db090SAndroid Build Coastguard Worker     { "mmap-dictionary", 0, NULL, 'm' },
83*ab8db090SAndroid Build Coastguard Worker     { "read-dictionary", 0, NULL, 'r' },
84*ab8db090SAndroid Build Coastguard Worker     { "help", 0, NULL, 'h' },
85*ab8db090SAndroid Build Coastguard Worker     { NULL, 0, NULL, 0 }
86*ab8db090SAndroid Build Coastguard Worker   };
87*ab8db090SAndroid Build Coastguard Worker   ::cmdopt_t cmdopt;
88*ab8db090SAndroid Build Coastguard Worker   ::cmdopt_init(&cmdopt, argc, argv, "mrh", long_options);
89*ab8db090SAndroid Build Coastguard Worker   int label;
90*ab8db090SAndroid Build Coastguard Worker   while ((label = ::cmdopt_get(&cmdopt)) != -1) {
91*ab8db090SAndroid Build Coastguard Worker     switch (label) {
92*ab8db090SAndroid Build Coastguard Worker       case 'm': {
93*ab8db090SAndroid Build Coastguard Worker         mmap_flag = true;
94*ab8db090SAndroid Build Coastguard Worker         break;
95*ab8db090SAndroid Build Coastguard Worker       }
96*ab8db090SAndroid Build Coastguard Worker       case 'r': {
97*ab8db090SAndroid Build Coastguard Worker         mmap_flag = false;
98*ab8db090SAndroid Build Coastguard Worker         break;
99*ab8db090SAndroid Build Coastguard Worker       }
100*ab8db090SAndroid Build Coastguard Worker       case 'h': {
101*ab8db090SAndroid Build Coastguard Worker         print_help(argv[0]);
102*ab8db090SAndroid Build Coastguard Worker         return 0;
103*ab8db090SAndroid Build Coastguard Worker       }
104*ab8db090SAndroid Build Coastguard Worker       default: {
105*ab8db090SAndroid Build Coastguard Worker         return 1;
106*ab8db090SAndroid Build Coastguard Worker       }
107*ab8db090SAndroid Build Coastguard Worker     }
108*ab8db090SAndroid Build Coastguard Worker   }
109*ab8db090SAndroid Build Coastguard Worker   return reverse_lookup(cmdopt.argv + cmdopt.optind,
110*ab8db090SAndroid Build Coastguard Worker       static_cast<std::size_t>(cmdopt.argc - cmdopt.optind));
111*ab8db090SAndroid Build Coastguard Worker }
112