7 const char* hexes
= "0123456789abcdef";
9 std::string
quote_c_string(const std::string
& raw
);
11 std::string
quote_c_string(const std::string
& raw
)
13 std::ostringstream out
;
23 else if(ch
< 32 || ch
> 126)
24 out
<< "\\x" << hexes
[ch
/ 16] << hexes
[ch
% 16];
32 std::string
quote_help(const std::u32string
& raw
)
34 const size_t initial_width
= 8;
35 const size_t break_width
= 80;
36 std::ostringstream out
;
37 //Compute split positions.
38 std::set
<size_t> splits
;
40 size_t last_word_width
= initial_width
;
41 size_t width
= initial_width
;
42 for(size_t i
= 0; i
< raw
.length(); i
++) {
45 width
= initial_width
;
47 last_word_width
= initial_width
;
51 if(width
> break_width
&& last_word_width
> initial_width
) {
52 //Wordwrap at last word.
53 splits
.insert(last_word
);
54 width
= width
- last_word_width
+ initial_width
;
57 last_word_width
= width
;
59 //FIXME: Handle double-width characters.
64 for(size_t i
= 0; i
< raw
.length(); i
++) {
68 char32_t z
[2] = {raw
[i
]};
71 else if(z
[0] == U
'\n')
73 else if(z
[0] < 32 || z
[0] == 127)
74 out
<< "\\x" << hexes
[z
[0] / 16] << hexes
[z
[0] % 16];
83 void process_command(const std::string
& name
, JSON::node
& n
, std::ostream
& hdr
, std::ostream
& imp
)
87 std::string cmdsym
= n
.index(0).as_string8();
88 hdr
<< "extern command::stub " << cmdsym
<< ";" << std::endl
;
89 imp
<< "command::stub " << cmdsym
<< " = {" << std::endl
;
90 std::string desc
= (n
.index_count() >= 2) ? n
.index(1).as_string8() :
91 "No description available";
92 imp
<< "\t" << quote_c_string(name
) << ", " << quote_c_string(desc
) << "," << std::endl
;
94 if(n
.index_count() >= 3) {
95 auto& nc
= n
.index(2);
96 for(auto i
= nc
.begin(); i
!= nc
.end(); i
++) {
97 std::string hleafname
= i
.key8();
98 std::u32string hleafc
= i
->as_string();
100 imp
<< "\t\"\\n\"" << std::endl
;
102 imp
<< "\t" << quote_c_string(std::string("Syntax: ") + name
+ " " + hleafname
+ "\n")
104 imp
<< quote_help(hleafc
);
107 if(first
) imp
<< "\t\"No help available for '" << name
<< "'\"" << std::endl
;
108 imp
<< "};" << std::endl
;
112 int main(int argc
, char** argv
)
115 std::cerr
<< "Need one filename base" << std::endl
;
118 std::string fname
= argv
[1];
120 if(fname
.length() > 5 && fname
.substr(fname
.length() - 5) == ".json")
121 fname
= fname
.substr(0, fname
.length() - 5);
123 std::ifstream
infile(fname
+ std::string(".json"));
127 std::getline(infile
, tmp
);
128 in_json
= in_json
+ tmp
+ "\n";
130 JSON::node
n(in_json
);
132 std::string modname
= n
["__mod"].as_string8();
134 std::ofstream
hdr(fname
+ std::string(".hpp"));
135 std::ofstream
impl(fname
+ std::string(".cpp"));
136 impl
<< "#include \"cmdhelp/" << fname
<< ".hpp\"" << std::endl
;
137 impl
<< "namespace " << modname
<< std::endl
;
138 impl
<< "{" << std::endl
;
139 hdr
<< "#pragma once" << std::endl
;
140 hdr
<< "#include \"library/command.hpp\"" << std::endl
;
141 hdr
<< "namespace " << modname
<< std::endl
;
142 hdr
<< "{" << std::endl
;
143 for(auto i
= n
.begin(); i
!= n
.end(); i
++)
144 process_command(i
.key8(), *i
, hdr
, impl
);
145 impl
<< "}" << std::endl
;
146 hdr
<< "}" << std::endl
;