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