Commit 81b6314cb513f3e48c788722b9b024bf7c47a601

Authored by Jay Berkenbilt
1 parent f99e0af4

QPDFJob: fix logic errors in handling arrays

The code was assuming everything was happening inside dictionaries.
Instead, make the dictionary key handler creatino explicit only when
iterating through dictionary keys.
generate_auto_job
@@ -454,7 +454,7 @@ class Main: @@ -454,7 +454,7 @@ class Main:
454 identifier = self.to_identifier(table, 'argEnd', False) 454 identifier = self.to_identifier(table, 'argEnd', False)
455 self.decls.append(f'void {identifier}();') 455 self.decls.append(f'void {identifier}();')
456 456
457 - def handle_json_trivial(self, key, fdata): 457 + def handle_json_trivial(self, flag_key, fdata):
458 config = None 458 config = None
459 for t, [kind, v] in fdata['tables'].items(): 459 for t, [kind, v] in fdata['tables'].items():
460 # We have determined that all tables, if multiple, have 460 # We have determined that all tables, if multiple, have
@@ -463,106 +463,98 @@ class Main: @@ -463,106 +463,98 @@ class Main:
463 config = tdata['config'] 463 config = tdata['config']
464 if kind == 'bare': 464 if kind == 'bare':
465 self.json_init.append( 465 self.json_init.append(
466 - f'addBare("{key}", [this]() {{ {config}->{key}(); }});') 466 + f'addBare([this]() {{ {config}->{flag_key}(); }});')
467 elif kind == 'optional_parameter' or kind == 'required_parameter': 467 elif kind == 'optional_parameter' or kind == 'required_parameter':
468 # No optional parameters in json 468 # No optional parameters in json
469 self.json_init.append( 469 self.json_init.append(
470 - f'addParameter("{key}", [this](char const* p)'  
471 - f' {{ {config}->{key}(p); }});') 470 + f'addParameter([this](char const* p)'
  471 + f' {{ {config}->{flag_key}(p); }});')
472 elif kind == 'optional_choices' or kind == 'required_choices': 472 elif kind == 'optional_choices' or kind == 'required_choices':
473 # No optional choices in json 473 # No optional choices in json
474 self.json_init.append( 474 self.json_init.append(
475 - f'addChoices("{key}", {v}_choices,'  
476 - f' [this](char const* p) {{ {config}->{key}(p); }});') 475 + f'addChoices({v}_choices,'
  476 + f' [this](char const* p) {{ {config}->{flag_key}(p); }});')
477 477
478 - def handle_json_manual(self, key, path): 478 + def handle_json_manual(self, path):
479 method = re.sub(r'\.([a-zA-Z0-9])', 479 method = re.sub(r'\.([a-zA-Z0-9])',
480 lambda x: x.group(1).upper(), 480 lambda x: x.group(1).upper(),
481 - f'setup{path}.{key}')  
482 - self.json_decls.append(  
483 - f'void {method}(std::string const&);')  
484 - self.json_init.append(  
485 - f'doSetup("{key}", bindSetup(&Handlers::{method}));') 481 + f'setup{path}')
  482 + self.json_decls.append(f'void {method}();')
  483 + self.json_init.append(f'{method}();')
486 484
487 def option_to_json_key(self, s): 485 def option_to_json_key(self, s):
488 return self.to_identifier(s, '', False) 486 return self.to_identifier(s, '', False)
489 487
490 - def build_schema(self, j, s, flag, path, expected, options_seen):  
491 - if flag: 488 + def flag_to_schema_key(self, k):
  489 + if k.startswith('_'):
  490 + schema_key = k[1:]
  491 + else:
  492 + schema_key = re.sub(r'[^\.]+\.', '', k)
  493 + return self.option_to_json_key(schema_key)
  494 +
  495 + def build_schema(self, j, path, flag, expected, options_seen):
  496 + if flag in expected:
  497 + options_seen.add(flag)
  498 + elif not (flag == '' or flag.startswith('_') or isinstance(j, str)):
  499 + raise Exception(f'json: unknown key {flag}')
  500 +
  501 + if isinstance(j, dict):
  502 + schema_value = {}
  503 + if flag:
  504 + identifier = self.to_identifier(path, '', False)
  505 + self.json_decls.append(f'void begin{identifier}(JSON);')
  506 + self.json_decls.append(f'void end{identifier}();')
  507 + self.json_init.append(
  508 + f'beginDict(bindJSON(&Handlers::begin{identifier}),'
  509 + f' bindBare(&Handlers::end{identifier})); // {path}')
  510 + for k, v in j.items():
  511 + schema_key = self.flag_to_schema_key(k)
  512 + subpath = f'{path}.{schema_key}'
  513 + self.json_init.append(f'pushKey("{schema_key}");')
  514 + schema_value[schema_key] = self.build_schema(
  515 + v, subpath, k, expected, options_seen)
  516 + self.json_init.append(f'popHandler(); // key: {schema_key}')
  517 + elif isinstance(j, list):
  518 + if len(j) != 1:
  519 + raise Exception('json contains array with length != 1')
492 identifier = self.to_identifier(path, '', False) 520 identifier = self.to_identifier(path, '', False)
493 - self.json_decls.append(f'void begin{identifier}(JSON);')  
494 - self.json_decls.append(f'void end{identifier}();') 521 + self.json_decls.append(f'void begin{identifier}Array(JSON);')
  522 + self.json_decls.append(f'void end{identifier}Array();')
  523 + self.json_init.append(
  524 + f'beginArray(bindJSON(&Handlers::begin{identifier}Array),'
  525 + f' bindBare(&Handlers::end{identifier}Array));'
  526 + f' // {path}[]')
  527 + schema_value = [
  528 + self.build_schema(j[0], path, flag,
  529 + expected, options_seen)
  530 + ]
495 self.json_init.append( 531 self.json_init.append(
496 - f'beginDict("{flag}",'  
497 - f' bindJSON(&Handlers::begin{identifier}),'  
498 - f' bindBare(&Handlers::end{identifier})); // {path}')  
499 - for k, v in j.items(): 532 + f'popHandler(); // array: {path}[]')
  533 + else:
  534 + schema_value = j
  535 + if schema_value is None:
  536 + schema_value = re.sub(
  537 + r'--(\S+)',
  538 + lambda x: self.option_to_json_key(x.group(1)),
  539 + expected[flag]['help'])
500 is_trivial = False 540 is_trivial = False
501 - if k in expected: 541 + if flag in expected:
502 is_trivial = True 542 is_trivial = True
503 common_config = None 543 common_config = None
504 - for t in expected[k]['tables']: 544 + for t in expected[flag]['tables']:
505 tdata = self.by_table[t] 545 tdata = self.by_table[t]
506 - if k in tdata['manual']: 546 + if flag in tdata['manual']:
507 is_trivial = False 547 is_trivial = False
508 if common_config is None: 548 if common_config is None:
509 common_config = tdata['config'] 549 common_config = tdata['config']
510 elif common_config != tdata['config']: 550 elif common_config != tdata['config']:
511 is_trivial = False 551 is_trivial = False
512 - elif not (k.startswith('_') or isinstance(v, str)):  
513 - raise Exception(f'json: unknown key {k}')  
514 - if k.startswith('_'):  
515 - schema_key = k[1:] 552 + config_key = self.flag_to_schema_key(flag)
  553 + if is_trivial:
  554 + self.handle_json_trivial(config_key, expected[flag])
516 else: 555 else:
517 - schema_key = re.sub(r'[^\.]+\.', '', k)  
518 - schema_key = self.option_to_json_key(schema_key)  
519 - schema_value = v  
520 - is_dict = False  
521 - if k in expected:  
522 - options_seen.add(re.sub('^_', '', k))  
523 - if v is None:  
524 - schema_value = re.sub(  
525 - r'--(\S+)',  
526 - lambda x: self.option_to_json_key(x.group(1)),  
527 - expected[k]['help'])  
528 - if (isinstance(v, dict)):  
529 - is_dict = True  
530 - schema_value = {}  
531 - self.build_schema(v, schema_value,  
532 - schema_key, f'{path}.{schema_key}',  
533 - expected, options_seen)  
534 - elif (isinstance(v, list)):  
535 - if len(v) != 1:  
536 - raise Exception('json contains array with length != 1')  
537 - if isinstance(v[0], dict):  
538 - is_dict = True  
539 - schema_value = [{}]  
540 - subpath = f'{path}.{schema_key}'  
541 - identifier = self.to_identifier(subpath, '', False)  
542 - self.json_decls.append(  
543 - f'void begin{identifier}Array(JSON);')  
544 - self.json_decls.append(  
545 - f'void end{identifier}Array();')  
546 - self.json_init.append(  
547 - f'beginArray("{flag}",'  
548 - f' bindJSON(&Handlers::begin{identifier}Array),'  
549 - f' bindBare(&Handlers::end{identifier}Array));'  
550 - f' // {subpath}[]')  
551 - self.build_schema(v[0], schema_value[0],  
552 - schema_key, subpath,  
553 - expected, options_seen)  
554 - self.json_init.append(  
555 - f'endContainer(); // {subpath}[]')  
556 - elif schema_value is None:  
557 - raise Exception(f'unknown schema value for {k}')  
558 - s[schema_key] = schema_value  
559 - if not is_dict:  
560 - if is_trivial:  
561 - self.handle_json_trivial(schema_key, expected[k])  
562 - else:  
563 - self.handle_json_manual(schema_key, path)  
564 - if flag:  
565 - self.json_init.append(f'endContainer(); // {path}') 556 + self.handle_json_manual(path)
  557 + return schema_value
566 558
567 def generate_schema(self, data): 559 def generate_schema(self, data):
568 # Check to make sure that every command-line option is 560 # Check to make sure that every command-line option is
@@ -588,9 +580,8 @@ class Main: @@ -588,9 +580,8 @@ class Main:
588 # go. This verifies consistency between command-line options 580 # go. This verifies consistency between command-line options
589 # and the json section of the data and builds up a schema by 581 # and the json section of the data and builds up a schema by
590 # populating with help information as available. 582 # populating with help information as available.
591 - self.schema = {}  
592 - self.build_schema(data['json'], self.schema, '', '',  
593 - expected, options_seen) 583 + self.schema = self.build_schema(
  584 + data['json'], '', '', expected, options_seen)
594 if options_seen != set(expected.keys()): 585 if options_seen != set(expected.keys()):
595 raise Exception('missing from json: ' + 586 raise Exception('missing from json: ' +
596 str(set(expected.keys()) - options_seen)) 587 str(set(expected.keys()) - options_seen))
job.sums
1 # Generated by generate_auto_job 1 # Generated by generate_auto_job
2 -generate_auto_job 8c88accfa988c8d6035c3e7e012bbde3da0c76fdfaba8e1460112bf344dc7b4f 2 +generate_auto_job e28f3fb4938f6307bb4c23c084c239832dbee3bbaedf19a22fb19215312b30b0
3 include/qpdf/auto_job_c_att.hh 7ad43bb374c1370ef32ebdcdcb7b73a61d281f7f4e3f12755585872ab30fb60e 3 include/qpdf/auto_job_c_att.hh 7ad43bb374c1370ef32ebdcdcb7b73a61d281f7f4e3f12755585872ab30fb60e
4 include/qpdf/auto_job_c_copy_att.hh 32275d03cdc69b703dd7e02ba0bbe15756e714e9ad185484773a6178dc09e1ee 4 include/qpdf/auto_job_c_copy_att.hh 32275d03cdc69b703dd7e02ba0bbe15756e714e9ad185484773a6178dc09e1ee
5 include/qpdf/auto_job_c_enc.hh 72e138c7b96ed5aacdce78c1dec04b1c20d361faec4f8faf52f64c1d6be99265 5 include/qpdf/auto_job_c_enc.hh 72e138c7b96ed5aacdce78c1dec04b1c20d361faec4f8faf52f64c1d6be99265
@@ -10,8 +10,8 @@ job.yml 14622557f5c96f379645f01c3d21b3d03bb8fd9c6062a3af429430d5348f5538 @@ -10,8 +10,8 @@ job.yml 14622557f5c96f379645f01c3d21b3d03bb8fd9c6062a3af429430d5348f5538
10 libqpdf/qpdf/auto_job_decl.hh 9f79396ec459f191be4c5fe34cf88c265cf47355a1a945fa39169d1c94cf04f6 10 libqpdf/qpdf/auto_job_decl.hh 9f79396ec459f191be4c5fe34cf88c265cf47355a1a945fa39169d1c94cf04f6
11 libqpdf/qpdf/auto_job_help.hh 23c79f1d2c02bda28f64aace17f69487205c797e7ae2234892cbbabab49d6d47 11 libqpdf/qpdf/auto_job_help.hh 23c79f1d2c02bda28f64aace17f69487205c797e7ae2234892cbbabab49d6d47
12 libqpdf/qpdf/auto_job_init.hh 8e9e31b6099a662497339b27f6e2d7f779f35011e88a834bee8811c33405a0fe 12 libqpdf/qpdf/auto_job_init.hh 8e9e31b6099a662497339b27f6e2d7f779f35011e88a834bee8811c33405a0fe
13 -libqpdf/qpdf/auto_job_json_decl.hh f349b55cf85d07a28aeb4bef257bdbcbe16f76b8065d01154161897b1e0fa643  
14 -libqpdf/qpdf/auto_job_json_init.hh 60d08982781bd568ab6083d325441f99a6bc39f72492558b8a64757373b2cfbe  
15 -libqpdf/qpdf/auto_job_schema.hh a483911bb1fda9cca53f3021bcdf26998604eabb23f131c78055c52d33ff5a4f 13 +libqpdf/qpdf/auto_job_json_decl.hh 4846055075dcb7365c56c02150e955979b522d14f4329ce7a8a302ccd1d7aa2a
  14 +libqpdf/qpdf/auto_job_json_init.hh a8053ffcd4cc8c533a269805c79bba6757e5d17800f0d18938adf16e896694a3
  15 +libqpdf/qpdf/auto_job_schema.hh 3cd89b775118e09aa99fed200ca36c8a8dec8d17bc039012ca210b6a33ce1d8a
16 manual/_ext/qpdf.py e9ac9d6c70642a3d29281ee5ad92ae2422dee8be9306fb8a0bc9dba0ed5e28f3 16 manual/_ext/qpdf.py e9ac9d6c70642a3d29281ee5ad92ae2422dee8be9306fb8a0bc9dba0ed5e28f3
17 manual/cli.rst 79140e023faa0cb77afe0b1dc512dd120ee5617f4db82f842596e4f239f93882 17 manual/cli.rst 79140e023faa0cb77afe0b1dc512dd120ee5617f4db82f842596e4f239f93882
libqpdf/QPDFJob_json.cc
@@ -27,24 +27,20 @@ namespace @@ -27,24 +27,20 @@ namespace
27 typedef std::function<void()> bare_handler_t; 27 typedef std::function<void()> bare_handler_t;
28 typedef std::function<void(char const*)> param_handler_t; 28 typedef std::function<void(char const*)> param_handler_t;
29 typedef std::function<void(JSON)> json_handler_t; 29 typedef std::function<void(JSON)> json_handler_t;
30 - typedef std::function<void(std::string const& key)> setup_handler_t;  
31 -  
32 - void addBare(std::string const& key, bare_handler_t);  
33 - void addParameter(std::string const& key, param_handler_t);  
34 - void addChoices(std::string const& key, char const** choices,  
35 - param_handler_t);  
36 - void doSetup(std::string const& key, setup_handler_t);  
37 - void beginDict(std::string const& key,  
38 - json_handler_t start_fn, 30 +
  31 + void addBare(bare_handler_t);
  32 + void addParameter(param_handler_t);
  33 + void addChoices(char const** choices, param_handler_t);
  34 + void pushKey(std::string const& key);
  35 + void beginDict(json_handler_t start_fn,
39 bare_handler_t end_fn); 36 bare_handler_t end_fn);
40 - void beginArray(std::string const& key,  
41 - json_handler_t start_fn, 37 + void beginArray(json_handler_t start_fn,
42 bare_handler_t end_fn); 38 bare_handler_t end_fn);
43 - void endContainer(); 39 + void ignoreItem();
  40 + void popHandler();
44 41
45 bare_handler_t bindBare(void (Handlers::*f)()); 42 bare_handler_t bindBare(void (Handlers::*f)());
46 json_handler_t bindJSON(void (Handlers::*f)(JSON)); 43 json_handler_t bindJSON(void (Handlers::*f)(JSON));
47 - setup_handler_t bindSetup(void (Handlers::*f)(std::string const&));  
48 44
49 std::list<std::shared_ptr<JSONHandler>> json_handlers; 45 std::list<std::shared_ptr<JSONHandler>> json_handlers;
50 bool partial; 46 bool partial;
@@ -84,12 +80,6 @@ Handlers::bindJSON(void (Handlers::*f)(JSON)) @@ -84,12 +80,6 @@ Handlers::bindJSON(void (Handlers::*f)(JSON))
84 return std::bind(std::mem_fn(f), this, std::placeholders::_1); 80 return std::bind(std::mem_fn(f), this, std::placeholders::_1);
85 } 81 }
86 82
87 -Handlers::setup_handler_t  
88 -Handlers::bindSetup(void (Handlers::*f)(std::string const&))  
89 -{  
90 - return std::bind(std::mem_fn(f), this, std::placeholders::_1);  
91 -}  
92 -  
93 void 83 void
94 Handlers::initHandlers() 84 Handlers::initHandlers()
95 { 85 {
@@ -113,10 +103,9 @@ Handlers::initHandlers() @@ -113,10 +103,9 @@ Handlers::initHandlers()
113 } 103 }
114 104
115 void 105 void
116 -Handlers::addBare(std::string const& key, bare_handler_t fn) 106 +Handlers::addBare(bare_handler_t fn)
117 { 107 {
118 - auto h = std::make_shared<JSONHandler>();  
119 - h->addBoolHandler([this, fn](std::string const& path, bool v){ 108 + jh->addBoolHandler([this, fn](std::string const& path, bool v){
120 if (! v) 109 if (! v)
121 { 110 {
122 usage(path + ": value must be true"); 111 usage(path + ": value must be true");
@@ -126,26 +115,22 @@ Handlers::addBare(std::string const&amp; key, bare_handler_t fn) @@ -126,26 +115,22 @@ Handlers::addBare(std::string const&amp; key, bare_handler_t fn)
126 fn(); 115 fn();
127 } 116 }
128 }); 117 });
129 - jh->addDictKeyHandler(key, h);  
130 } 118 }
131 119
132 void 120 void
133 -Handlers::addParameter(std::string const& key, param_handler_t fn) 121 +Handlers::addParameter(param_handler_t fn)
134 { 122 {
135 - auto h = std::make_shared<JSONHandler>();  
136 - h->addStringHandler( 123 + jh->addStringHandler(
137 [fn](std::string const& path, std::string const& parameter){ 124 [fn](std::string const& path, std::string const& parameter){
138 fn(parameter.c_str()); 125 fn(parameter.c_str());
139 }); 126 });
140 - jh->addDictKeyHandler(key, h);  
141 } 127 }
142 128
143 void 129 void
144 -Handlers::addChoices(std::string const& key, char const** choices, 130 +Handlers::addChoices(char const** choices,
145 param_handler_t fn) 131 param_handler_t fn)
146 { 132 {
147 - auto h = std::make_shared<JSONHandler>();  
148 - h->addStringHandler( 133 + jh->addStringHandler(
149 [fn, choices, this]( 134 [fn, choices, this](
150 std::string const& path, std::string const& parameter){ 135 std::string const& path, std::string const& parameter){
151 136
@@ -180,47 +165,45 @@ Handlers::addChoices(std::string const&amp; key, char const** choices, @@ -180,47 +165,45 @@ Handlers::addChoices(std::string const&amp; key, char const** choices,
180 } 165 }
181 fn(parameter.c_str()); 166 fn(parameter.c_str());
182 }); 167 });
183 - jh->addDictKeyHandler(key, h);  
184 } 168 }
185 169
186 void 170 void
187 -Handlers::doSetup(std::string const& key, setup_handler_t fn) 171 +Handlers::pushKey(std::string const& key)
188 { 172 {
189 - fn(key); 173 + auto new_jh = std::make_shared<JSONHandler>();
  174 + this->jh->addDictKeyHandler(key, new_jh);
  175 + this->json_handlers.push_back(new_jh);
  176 + this->jh = new_jh.get();
190 } 177 }
191 178
192 void 179 void
193 -Handlers::beginDict(std::string const& key,  
194 - json_handler_t start_fn,  
195 - bare_handler_t end_fn) 180 +Handlers::beginDict(json_handler_t start_fn, bare_handler_t end_fn)
196 { 181 {
197 - auto new_jh = std::make_shared<JSONHandler>();  
198 - new_jh->addDictHandlers( 182 + jh->addDictHandlers(
199 [start_fn](std::string const&, JSON j){ start_fn(j); }, 183 [start_fn](std::string const&, JSON j){ start_fn(j); },
200 [end_fn](std::string const&){ end_fn(); }); 184 [end_fn](std::string const&){ end_fn(); });
201 - this->jh->addDictKeyHandler(key, new_jh);  
202 - this->json_handlers.push_back(new_jh);  
203 - this->jh = new_jh.get();  
204 } 185 }
205 186
206 void 187 void
207 -Handlers::beginArray(std::string const& key,  
208 - json_handler_t start_fn,  
209 - bare_handler_t end_fn) 188 +Handlers::beginArray(json_handler_t start_fn, bare_handler_t end_fn)
210 { 189 {
211 - auto new_jh = std::make_shared<JSONHandler>();  
212 auto item_jh = std::make_shared<JSONHandler>(); 190 auto item_jh = std::make_shared<JSONHandler>();
213 - new_jh->addArrayHandlers( 191 + jh->addArrayHandlers(
214 [start_fn](std::string const&, JSON j){ start_fn(j); }, 192 [start_fn](std::string const&, JSON j){ start_fn(j); },
215 [end_fn](std::string const&){ end_fn(); }, 193 [end_fn](std::string const&){ end_fn(); },
216 item_jh); 194 item_jh);
217 - this->jh->addDictKeyHandler(key, new_jh);  
218 this->json_handlers.push_back(item_jh); 195 this->json_handlers.push_back(item_jh);
219 this->jh = item_jh.get(); 196 this->jh = item_jh.get();
220 } 197 }
221 198
222 void 199 void
223 -Handlers::endContainer() 200 +Handlers::ignoreItem()
  201 +{
  202 + jh->addAnyHandler([](std::string const&, JSON){});
  203 +}
  204 +
  205 +void
  206 +Handlers::popHandler()
224 { 207 {
225 this->json_handlers.pop_back(); 208 this->json_handlers.pop_back();
226 this->jh = this->json_handlers.back().get(); 209 this->jh = this->json_handlers.back().get();
@@ -245,25 +228,25 @@ Handlers::endInput() @@ -245,25 +228,25 @@ Handlers::endInput()
245 } 228 }
246 229
247 void 230 void
248 -Handlers::setupInputFilename(std::string const& key) 231 +Handlers::setupInputFilename()
249 { 232 {
250 - addParameter(key, [this](char const* p) { 233 + addParameter([this](char const* p) {
251 c_main->inputFile(p); 234 c_main->inputFile(p);
252 }); 235 });
253 } 236 }
254 237
255 void 238 void
256 -Handlers::setupInputPassword(std::string const& key) 239 +Handlers::setupInputPassword()
257 { 240 {
258 - addParameter(key, [this](char const* p) { 241 + addParameter([this](char const* p) {
259 c_main->password(p); 242 c_main->password(p);
260 }); 243 });
261 } 244 }
262 245
263 void 246 void
264 -Handlers::setupInputEmpty(std::string const& key) 247 +Handlers::setupInputEmpty()
265 { 248 {
266 - addBare(key, [this]() { 249 + addBare([this]() {
267 c_main->emptyInput(); 250 c_main->emptyInput();
268 }); 251 });
269 } 252 }
@@ -281,17 +264,17 @@ Handlers::endOutput() @@ -281,17 +264,17 @@ Handlers::endOutput()
281 } 264 }
282 265
283 void 266 void
284 -Handlers::setupOutputFilename(std::string const& key) 267 +Handlers::setupOutputFilename()
285 { 268 {
286 - addParameter(key, [this](char const* p) { 269 + addParameter([this](char const* p) {
287 c_main->outputFile(p); 270 c_main->outputFile(p);
288 }); 271 });
289 } 272 }
290 273
291 void 274 void
292 -Handlers::setupOutputReplaceInput(std::string const& key) 275 +Handlers::setupOutputReplaceInput()
293 { 276 {
294 - addBare(key, [this]() { 277 + addBare([this]() {
295 c_main->replaceInput(); 278 c_main->replaceInput();
296 }); 279 });
297 } 280 }
@@ -359,15 +342,17 @@ Handlers::endOutputOptionsEncrypt() @@ -359,15 +342,17 @@ Handlers::endOutputOptionsEncrypt()
359 } 342 }
360 343
361 void 344 void
362 -Handlers::setupOutputOptionsEncryptUserPassword(std::string const& key) 345 +Handlers::setupOutputOptionsEncryptUserPassword()
363 { 346 {
364 - // Key handled in beginOutputOptionsEncrypt 347 + // handled in beginOutputOptionsEncrypt
  348 + ignoreItem();
365 } 349 }
366 350
367 void 351 void
368 -Handlers::setupOutputOptionsEncryptOwnerPassword(std::string const& key) 352 +Handlers::setupOutputOptionsEncryptOwnerPassword()
369 { 353 {
370 - // Key handled in beginOutputOptionsEncrypt 354 + // handled in beginOutputOptionsEncrypt
  355 + ignoreItem();
371 } 356 }
372 357
373 void 358 void
@@ -431,6 +416,30 @@ Handlers::endInspect() @@ -431,6 +416,30 @@ Handlers::endInspect()
431 } 416 }
432 417
433 void 418 void
  419 +Handlers::beginInspectJsonKeyArray(JSON)
  420 +{
  421 + // nothing needed
  422 +}
  423 +
  424 +void
  425 +Handlers::endInspectJsonKeyArray()
  426 +{
  427 + // nothing needed
  428 +}
  429 +
  430 +void
  431 +Handlers::beginInspectJsonObjectArray(JSON)
  432 +{
  433 + // nothing needed
  434 +}
  435 +
  436 +void
  437 +Handlers::endInspectJsonObjectArray()
  438 +{
  439 + // nothing needed
  440 +}
  441 +
  442 +void
434 Handlers::beginOptionsAddAttachmentArray(JSON) 443 Handlers::beginOptionsAddAttachmentArray(JSON)
435 { 444 {
436 // nothing needed 445 // nothing needed
@@ -456,9 +465,9 @@ Handlers::endOptionsAddAttachment() @@ -456,9 +465,9 @@ Handlers::endOptionsAddAttachment()
456 } 465 }
457 466
458 void 467 void
459 -Handlers::setupOptionsAddAttachmentPath(std::string const& key) 468 +Handlers::setupOptionsAddAttachmentPath()
460 { 469 {
461 - addParameter(key, [this](char const* p) { 470 + addParameter([this](char const* p) {
462 c_att->path(p); 471 c_att->path(p);
463 }); 472 });
464 } 473 }
@@ -489,17 +498,17 @@ Handlers::endOptionsCopyAttachmentsFrom() @@ -489,17 +498,17 @@ Handlers::endOptionsCopyAttachmentsFrom()
489 } 498 }
490 499
491 void 500 void
492 -Handlers::setupOptionsCopyAttachmentsFromPath(std::string const& key) 501 +Handlers::setupOptionsCopyAttachmentsFromPath()
493 { 502 {
494 - addParameter(key, [this](char const* p) { 503 + addParameter([this](char const* p) {
495 c_copy_att->path(p); 504 c_copy_att->path(p);
496 }); 505 });
497 } 506 }
498 507
499 void 508 void
500 -Handlers::setupOptionsCopyAttachmentsFromPassword(std::string const& key) 509 +Handlers::setupOptionsCopyAttachmentsFromPassword()
501 { 510 {
502 - addParameter(key, [this](char const* p) { 511 + addParameter([this](char const* p) {
503 c_copy_att->password(p); 512 c_copy_att->password(p);
504 }); 513 });
505 } 514 }
@@ -554,21 +563,24 @@ Handlers::endOptionsPages() @@ -554,21 +563,24 @@ Handlers::endOptionsPages()
554 } 563 }
555 564
556 void 565 void
557 -Handlers::setupOptionsPagesFile(std::string const& key) 566 +Handlers::setupOptionsPagesFile()
558 { 567 {
559 // handled in beginOptionsPages 568 // handled in beginOptionsPages
  569 + ignoreItem();
560 } 570 }
561 571
562 void 572 void
563 -Handlers::setupOptionsPagesPassword(std::string const& key) 573 +Handlers::setupOptionsPagesPassword()
564 { 574 {
565 // handled in beginOptionsPages 575 // handled in beginOptionsPages
  576 + ignoreItem();
566 } 577 }
567 578
568 void 579 void
569 -Handlers::setupOptionsPagesRange(std::string const& key) 580 +Handlers::setupOptionsPagesRange()
570 { 581 {
571 // handled in beginOptionsPages 582 // handled in beginOptionsPages
  583 + ignoreItem();
572 } 584 }
573 585
574 void 586 void
@@ -585,17 +597,17 @@ Handlers::endOptionsOverlay() @@ -585,17 +597,17 @@ Handlers::endOptionsOverlay()
585 } 597 }
586 598
587 void 599 void
588 -Handlers::setupOptionsOverlayFile(std::string const& key) 600 +Handlers::setupOptionsOverlayFile()
589 { 601 {
590 - addParameter(key, [this](char const* p) { 602 + addParameter([this](char const* p) {
591 c_uo->path(p); 603 c_uo->path(p);
592 }); 604 });
593 } 605 }
594 606
595 void 607 void
596 -Handlers::setupOptionsOverlayPassword(std::string const& key) 608 +Handlers::setupOptionsOverlayPassword()
597 { 609 {
598 - addParameter(key, [this](char const* p) { 610 + addParameter([this](char const* p) {
599 c_uo->password(p); 611 c_uo->password(p);
600 }); 612 });
601 } 613 }
@@ -614,17 +626,17 @@ Handlers::endOptionsUnderlay() @@ -614,17 +626,17 @@ Handlers::endOptionsUnderlay()
614 } 626 }
615 627
616 void 628 void
617 -Handlers::setupOptionsUnderlayFile(std::string const& key) 629 +Handlers::setupOptionsUnderlayFile()
618 { 630 {
619 - addParameter(key, [this](char const* p) { 631 + addParameter([this](char const* p) {
620 c_uo->path(p); 632 c_uo->path(p);
621 }); 633 });
622 } 634 }
623 635
624 void 636 void
625 -Handlers::setupOptionsUnderlayPassword(std::string const& key) 637 +Handlers::setupOptionsUnderlayPassword()
626 { 638 {
627 - addParameter(key, [this](char const* p) { 639 + addParameter([this](char const* p) {
628 c_uo->password(p); 640 c_uo->password(p);
629 }); 641 });
630 } 642 }
libqpdf/qpdf/auto_job_json_decl.hh
@@ -5,19 +5,19 @@ @@ -5,19 +5,19 @@
5 // 5 //
6 void beginInput(JSON); 6 void beginInput(JSON);
7 void endInput(); 7 void endInput();
8 -void setupInputFilename(std::string const&);  
9 -void setupInputPassword(std::string const&);  
10 -void setupInputEmpty(std::string const&); 8 +void setupInputFilename();
  9 +void setupInputPassword();
  10 +void setupInputEmpty();
11 void beginOutput(JSON); 11 void beginOutput(JSON);
12 void endOutput(); 12 void endOutput();
13 -void setupOutputFilename(std::string const&);  
14 -void setupOutputReplaceInput(std::string const&); 13 +void setupOutputFilename();
  14 +void setupOutputReplaceInput();
15 void beginOutputOptions(JSON); 15 void beginOutputOptions(JSON);
16 void endOutputOptions(); 16 void endOutputOptions();
17 void beginOutputOptionsEncrypt(JSON); 17 void beginOutputOptionsEncrypt(JSON);
18 void endOutputOptionsEncrypt(); 18 void endOutputOptionsEncrypt();
19 -void setupOutputOptionsEncryptUserPassword(std::string const&);  
20 -void setupOutputOptionsEncryptOwnerPassword(std::string const&); 19 +void setupOutputOptionsEncryptUserPassword();
  20 +void setupOutputOptionsEncryptOwnerPassword();
21 void beginOutputOptionsEncrypt40bit(JSON); 21 void beginOutputOptionsEncrypt40bit(JSON);
22 void endOutputOptionsEncrypt40bit(); 22 void endOutputOptionsEncrypt40bit();
23 void beginOutputOptionsEncrypt128bit(JSON); 23 void beginOutputOptionsEncrypt128bit(JSON);
@@ -26,31 +26,35 @@ void beginOutputOptionsEncrypt256bit(JSON); @@ -26,31 +26,35 @@ void beginOutputOptionsEncrypt256bit(JSON);
26 void endOutputOptionsEncrypt256bit(); 26 void endOutputOptionsEncrypt256bit();
27 void beginInspect(JSON); 27 void beginInspect(JSON);
28 void endInspect(); 28 void endInspect();
  29 +void beginInspectJsonKeyArray(JSON);
  30 +void endInspectJsonKeyArray();
  31 +void beginInspectJsonObjectArray(JSON);
  32 +void endInspectJsonObjectArray();
29 void beginOptions(JSON); 33 void beginOptions(JSON);
30 void endOptions(); 34 void endOptions();
31 void beginOptionsAddAttachmentArray(JSON); 35 void beginOptionsAddAttachmentArray(JSON);
32 void endOptionsAddAttachmentArray(); 36 void endOptionsAddAttachmentArray();
33 void beginOptionsAddAttachment(JSON); 37 void beginOptionsAddAttachment(JSON);
34 void endOptionsAddAttachment(); 38 void endOptionsAddAttachment();
35 -void setupOptionsAddAttachmentPath(std::string const&); 39 +void setupOptionsAddAttachmentPath();
36 void beginOptionsCopyAttachmentsFromArray(JSON); 40 void beginOptionsCopyAttachmentsFromArray(JSON);
37 void endOptionsCopyAttachmentsFromArray(); 41 void endOptionsCopyAttachmentsFromArray();
38 void beginOptionsCopyAttachmentsFrom(JSON); 42 void beginOptionsCopyAttachmentsFrom(JSON);
39 void endOptionsCopyAttachmentsFrom(); 43 void endOptionsCopyAttachmentsFrom();
40 -void setupOptionsCopyAttachmentsFromPath(std::string const&);  
41 -void setupOptionsCopyAttachmentsFromPassword(std::string const&); 44 +void setupOptionsCopyAttachmentsFromPath();
  45 +void setupOptionsCopyAttachmentsFromPassword();
42 void beginOptionsPagesArray(JSON); 46 void beginOptionsPagesArray(JSON);
43 void endOptionsPagesArray(); 47 void endOptionsPagesArray();
44 void beginOptionsPages(JSON); 48 void beginOptionsPages(JSON);
45 void endOptionsPages(); 49 void endOptionsPages();
46 -void setupOptionsPagesFile(std::string const&);  
47 -void setupOptionsPagesPassword(std::string const&);  
48 -void setupOptionsPagesRange(std::string const&); 50 +void setupOptionsPagesFile();
  51 +void setupOptionsPagesPassword();
  52 +void setupOptionsPagesRange();
49 void beginOptionsOverlay(JSON); 53 void beginOptionsOverlay(JSON);
50 void endOptionsOverlay(); 54 void endOptionsOverlay();
51 -void setupOptionsOverlayFile(std::string const&);  
52 -void setupOptionsOverlayPassword(std::string const&); 55 +void setupOptionsOverlayFile();
  56 +void setupOptionsOverlayPassword();
53 void beginOptionsUnderlay(JSON); 57 void beginOptionsUnderlay(JSON);
54 void endOptionsUnderlay(); 58 void endOptionsUnderlay();
55 -void setupOptionsUnderlayFile(std::string const&);  
56 -void setupOptionsUnderlayPassword(std::string const&); 59 +void setupOptionsUnderlayFile();
  60 +void setupOptionsUnderlayPassword();
libqpdf/qpdf/auto_job_json_init.hh
@@ -14,161 +14,427 @@ static char const* json_key_choices[] = {&quot;acroform&quot;, &quot;attachments&quot;, &quot;encrypt&quot;, &quot; @@ -14,161 +14,427 @@ static char const* json_key_choices[] = {&quot;acroform&quot;, &quot;attachments&quot;, &quot;encrypt&quot;, &quot;
14 static char const* print128_choices[] = {"full", "low", "none", 0}; 14 static char const* print128_choices[] = {"full", "low", "none", 0};
15 static char const* modify128_choices[] = {"all", "annotate", "form", "assembly", "none", 0}; 15 static char const* modify128_choices[] = {"all", "annotate", "form", "assembly", "none", 0};
16 16
17 -beginDict("input", bindJSON(&Handlers::beginInput), bindBare(&Handlers::endInput)); // .input  
18 -doSetup("filename", bindSetup(&Handlers::setupInputFilename));  
19 -doSetup("password", bindSetup(&Handlers::setupInputPassword));  
20 -addParameter("passwordFile", [this](char const* p) { c_main->passwordFile(p); });  
21 -doSetup("empty", bindSetup(&Handlers::setupInputEmpty));  
22 -endContainer(); // .input  
23 -beginDict("output", bindJSON(&Handlers::beginOutput), bindBare(&Handlers::endOutput)); // .output  
24 -doSetup("filename", bindSetup(&Handlers::setupOutputFilename));  
25 -doSetup("replaceInput", bindSetup(&Handlers::setupOutputReplaceInput));  
26 -beginDict("options", bindJSON(&Handlers::beginOutputOptions), bindBare(&Handlers::endOutputOptions)); // .output.options  
27 -addBare("qdf", [this]() { c_main->qdf(); });  
28 -addBare("preserveUnreferenced", [this]() { c_main->preserveUnreferenced(); });  
29 -addBare("newlineBeforeEndstream", [this]() { c_main->newlineBeforeEndstream(); });  
30 -addChoices("normalizeContent", yn_choices, [this](char const* p) { c_main->normalizeContent(p); });  
31 -addChoices("streamData", stream_data_choices, [this](char const* p) { c_main->streamData(p); });  
32 -addChoices("compressStreams", yn_choices, [this](char const* p) { c_main->compressStreams(p); });  
33 -addBare("recompressFlate", [this]() { c_main->recompressFlate(); });  
34 -addChoices("decodeLevel", decode_level_choices, [this](char const* p) { c_main->decodeLevel(p); });  
35 -addBare("decrypt", [this]() { c_main->decrypt(); });  
36 -addBare("staticAesIv", [this]() { c_main->staticAesIv(); });  
37 -addBare("staticId", [this]() { c_main->staticId(); });  
38 -addBare("noOriginalObjectIds", [this]() { c_main->noOriginalObjectIds(); });  
39 -addParameter("copyEncryption", [this](char const* p) { c_main->copyEncryption(p); });  
40 -addParameter("encryptionFilePassword", [this](char const* p) { c_main->encryptionFilePassword(p); });  
41 -addBare("linearize", [this]() { c_main->linearize(); });  
42 -addParameter("linearizePass1", [this](char const* p) { c_main->linearizePass1(p); });  
43 -addChoices("objectStreams", object_streams_choices, [this](char const* p) { c_main->objectStreams(p); });  
44 -addParameter("minVersion", [this](char const* p) { c_main->minVersion(p); });  
45 -addParameter("forceVersion", [this](char const* p) { c_main->forceVersion(p); });  
46 -addBare("progress", [this]() { c_main->progress(); });  
47 -addParameter("splitPages", [this](char const* p) { c_main->splitPages(p); });  
48 -beginDict("encrypt", bindJSON(&Handlers::beginOutputOptionsEncrypt), bindBare(&Handlers::endOutputOptionsEncrypt)); // .output.options.encrypt  
49 -doSetup("userPassword", bindSetup(&Handlers::setupOutputOptionsEncryptUserPassword));  
50 -doSetup("ownerPassword", bindSetup(&Handlers::setupOutputOptionsEncryptOwnerPassword));  
51 -beginDict("40bit", bindJSON(&Handlers::beginOutputOptionsEncrypt40bit), bindBare(&Handlers::endOutputOptionsEncrypt40bit)); // .output.options.encrypt.40bit  
52 -addChoices("annotate", yn_choices, [this](char const* p) { c_enc->annotate(p); });  
53 -addChoices("extract", yn_choices, [this](char const* p) { c_enc->extract(p); });  
54 -addChoices("modify", modify128_choices, [this](char const* p) { c_enc->modify(p); });  
55 -addChoices("print", print128_choices, [this](char const* p) { c_enc->print(p); });  
56 -endContainer(); // .output.options.encrypt.40bit  
57 -beginDict("128bit", bindJSON(&Handlers::beginOutputOptionsEncrypt128bit), bindBare(&Handlers::endOutputOptionsEncrypt128bit)); // .output.options.encrypt.128bit  
58 -addChoices("accessibility", yn_choices, [this](char const* p) { c_enc->accessibility(p); });  
59 -addChoices("annotate", yn_choices, [this](char const* p) { c_enc->annotate(p); });  
60 -addChoices("assemble", yn_choices, [this](char const* p) { c_enc->assemble(p); });  
61 -addBare("cleartextMetadata", [this]() { c_enc->cleartextMetadata(); });  
62 -addChoices("extract", yn_choices, [this](char const* p) { c_enc->extract(p); });  
63 -addChoices("form", yn_choices, [this](char const* p) { c_enc->form(p); });  
64 -addChoices("modifyOther", yn_choices, [this](char const* p) { c_enc->modifyOther(p); });  
65 -addChoices("modify", modify128_choices, [this](char const* p) { c_enc->modify(p); });  
66 -addChoices("print", print128_choices, [this](char const* p) { c_enc->print(p); });  
67 -addBare("forceV4", [this]() { c_enc->forceV4(); });  
68 -addChoices("useAes", yn_choices, [this](char const* p) { c_enc->useAes(p); });  
69 -endContainer(); // .output.options.encrypt.128bit  
70 -beginDict("256bit", bindJSON(&Handlers::beginOutputOptionsEncrypt256bit), bindBare(&Handlers::endOutputOptionsEncrypt256bit)); // .output.options.encrypt.256bit  
71 -addChoices("accessibility", yn_choices, [this](char const* p) { c_enc->accessibility(p); });  
72 -addChoices("annotate", yn_choices, [this](char const* p) { c_enc->annotate(p); });  
73 -addChoices("assemble", yn_choices, [this](char const* p) { c_enc->assemble(p); });  
74 -addBare("cleartextMetadata", [this]() { c_enc->cleartextMetadata(); });  
75 -addChoices("extract", yn_choices, [this](char const* p) { c_enc->extract(p); });  
76 -addChoices("form", yn_choices, [this](char const* p) { c_enc->form(p); });  
77 -addChoices("modifyOther", yn_choices, [this](char const* p) { c_enc->modifyOther(p); });  
78 -addChoices("modify", modify128_choices, [this](char const* p) { c_enc->modify(p); });  
79 -addChoices("print", print128_choices, [this](char const* p) { c_enc->print(p); });  
80 -addBare("allowInsecure", [this]() { c_enc->allowInsecure(); });  
81 -addBare("forceR5", [this]() { c_enc->forceR5(); });  
82 -endContainer(); // .output.options.encrypt.256bit  
83 -endContainer(); // .output.options.encrypt  
84 -endContainer(); // .output.options  
85 -endContainer(); // .output  
86 -beginDict("inspect", bindJSON(&Handlers::beginInspect), bindBare(&Handlers::endInspect)); // .inspect  
87 -addBare("check", [this]() { c_main->check(); });  
88 -addBare("checkLinearization", [this]() { c_main->checkLinearization(); });  
89 -addBare("filteredStreamData", [this]() { c_main->filteredStreamData(); });  
90 -addBare("rawStreamData", [this]() { c_main->rawStreamData(); });  
91 -addBare("showEncryption", [this]() { c_main->showEncryption(); });  
92 -addBare("showEncryptionKey", [this]() { c_main->showEncryptionKey(); });  
93 -addBare("showLinearization", [this]() { c_main->showLinearization(); });  
94 -addBare("showNpages", [this]() { c_main->showNpages(); });  
95 -addParameter("showObject", [this](char const* p) { c_main->showObject(p); });  
96 -addBare("showPages", [this]() { c_main->showPages(); });  
97 -addBare("showXref", [this]() { c_main->showXref(); });  
98 -addBare("withImages", [this]() { c_main->withImages(); });  
99 -addBare("listAttachments", [this]() { c_main->listAttachments(); });  
100 -addParameter("showAttachment", [this](char const* p) { c_main->showAttachment(p); });  
101 -addBare("json", [this]() { c_main->json(); });  
102 -addChoices("jsonKey", json_key_choices, [this](char const* p) { c_main->jsonKey(p); });  
103 -addParameter("jsonObject", [this](char const* p) { c_main->jsonObject(p); });  
104 -endContainer(); // .inspect  
105 -beginDict("options", bindJSON(&Handlers::beginOptions), bindBare(&Handlers::endOptions)); // .options  
106 -addBare("allowWeakCrypto", [this]() { c_main->allowWeakCrypto(); });  
107 -addBare("deterministicId", [this]() { c_main->deterministicId(); });  
108 -addChoices("keepFilesOpen", yn_choices, [this](char const* p) { c_main->keepFilesOpen(p); });  
109 -addParameter("keepFilesOpenThreshold", [this](char const* p) { c_main->keepFilesOpenThreshold(p); });  
110 -addBare("noWarn", [this]() { c_main->noWarn(); });  
111 -addBare("verbose", [this]() { c_main->verbose(); });  
112 -addBare("ignoreXrefStreams", [this]() { c_main->ignoreXrefStreams(); });  
113 -addBare("passwordIsHexKey", [this]() { c_main->passwordIsHexKey(); });  
114 -addChoices("passwordMode", password_mode_choices, [this](char const* p) { c_main->passwordMode(p); });  
115 -addBare("suppressPasswordRecovery", [this]() { c_main->suppressPasswordRecovery(); });  
116 -addBare("suppressRecovery", [this]() { c_main->suppressRecovery(); });  
117 -addBare("coalesceContents", [this]() { c_main->coalesceContents(); });  
118 -addParameter("compressionLevel", [this](char const* p) { c_main->compressionLevel(p); });  
119 -addBare("externalizeInlineImages", [this]() { c_main->externalizeInlineImages(); });  
120 -addParameter("iiMinBytes", [this](char const* p) { c_main->iiMinBytes(p); });  
121 -addChoices("removeUnreferencedResources", remove_unref_choices, [this](char const* p) { c_main->removeUnreferencedResources(p); });  
122 -beginArray("options", bindJSON(&Handlers::beginOptionsAddAttachmentArray), bindBare(&Handlers::endOptionsAddAttachmentArray)); // .options.addAttachment[]  
123 -beginDict("addAttachment", bindJSON(&Handlers::beginOptionsAddAttachment), bindBare(&Handlers::endOptionsAddAttachment)); // .options.addAttachment  
124 -doSetup("path", bindSetup(&Handlers::setupOptionsAddAttachmentPath));  
125 -addParameter("creationdate", [this](char const* p) { c_att->creationdate(p); });  
126 -addParameter("description", [this](char const* p) { c_att->description(p); });  
127 -addParameter("filename", [this](char const* p) { c_att->filename(p); });  
128 -addParameter("key", [this](char const* p) { c_att->key(p); });  
129 -addParameter("mimetype", [this](char const* p) { c_att->mimetype(p); });  
130 -addParameter("moddate", [this](char const* p) { c_att->moddate(p); });  
131 -addBare("replace", [this]() { c_att->replace(); });  
132 -endContainer(); // .options.addAttachment  
133 -endContainer(); // .options.addAttachment[]  
134 -addParameter("removeAttachment", [this](char const* p) { c_main->removeAttachment(p); });  
135 -beginArray("options", bindJSON(&Handlers::beginOptionsCopyAttachmentsFromArray), bindBare(&Handlers::endOptionsCopyAttachmentsFromArray)); // .options.copyAttachmentsFrom[]  
136 -beginDict("copyAttachmentsFrom", bindJSON(&Handlers::beginOptionsCopyAttachmentsFrom), bindBare(&Handlers::endOptionsCopyAttachmentsFrom)); // .options.copyAttachmentsFrom  
137 -doSetup("path", bindSetup(&Handlers::setupOptionsCopyAttachmentsFromPath));  
138 -doSetup("password", bindSetup(&Handlers::setupOptionsCopyAttachmentsFromPassword));  
139 -addParameter("prefix", [this](char const* p) { c_copy_att->prefix(p); });  
140 -endContainer(); // .options.copyAttachmentsFrom  
141 -endContainer(); // .options.copyAttachmentsFrom[]  
142 -addParameter("collate", [this](char const* p) { c_main->collate(p); });  
143 -addChoices("flattenAnnotations", flatten_choices, [this](char const* p) { c_main->flattenAnnotations(p); });  
144 -addBare("flattenRotation", [this]() { c_main->flattenRotation(); });  
145 -addBare("generateAppearances", [this]() { c_main->generateAppearances(); });  
146 -addBare("keepInlineImages", [this]() { c_main->keepInlineImages(); });  
147 -addParameter("oiMinArea", [this](char const* p) { c_main->oiMinArea(p); });  
148 -addParameter("oiMinHeight", [this](char const* p) { c_main->oiMinHeight(p); });  
149 -addParameter("oiMinWidth", [this](char const* p) { c_main->oiMinWidth(p); });  
150 -addBare("optimizeImages", [this]() { c_main->optimizeImages(); });  
151 -beginArray("options", bindJSON(&Handlers::beginOptionsPagesArray), bindBare(&Handlers::endOptionsPagesArray)); // .options.pages[]  
152 -beginDict("pages", bindJSON(&Handlers::beginOptionsPages), bindBare(&Handlers::endOptionsPages)); // .options.pages  
153 -doSetup("file", bindSetup(&Handlers::setupOptionsPagesFile));  
154 -doSetup("password", bindSetup(&Handlers::setupOptionsPagesPassword));  
155 -doSetup("range", bindSetup(&Handlers::setupOptionsPagesRange));  
156 -endContainer(); // .options.pages  
157 -endContainer(); // .options.pages[]  
158 -addBare("removePageLabels", [this]() { c_main->removePageLabels(); });  
159 -addParameter("rotate", [this](char const* p) { c_main->rotate(p); });  
160 -beginDict("overlay", bindJSON(&Handlers::beginOptionsOverlay), bindBare(&Handlers::endOptionsOverlay)); // .options.overlay  
161 -doSetup("file", bindSetup(&Handlers::setupOptionsOverlayFile));  
162 -doSetup("password", bindSetup(&Handlers::setupOptionsOverlayPassword));  
163 -addParameter("from", [this](char const* p) { c_uo->from(p); });  
164 -addParameter("repeat", [this](char const* p) { c_uo->repeat(p); });  
165 -addParameter("to", [this](char const* p) { c_uo->to(p); });  
166 -endContainer(); // .options.overlay  
167 -beginDict("underlay", bindJSON(&Handlers::beginOptionsUnderlay), bindBare(&Handlers::endOptionsUnderlay)); // .options.underlay  
168 -doSetup("file", bindSetup(&Handlers::setupOptionsUnderlayFile));  
169 -doSetup("password", bindSetup(&Handlers::setupOptionsUnderlayPassword));  
170 -addParameter("from", [this](char const* p) { c_uo->from(p); });  
171 -addParameter("repeat", [this](char const* p) { c_uo->repeat(p); });  
172 -addParameter("to", [this](char const* p) { c_uo->to(p); });  
173 -endContainer(); // .options.underlay  
174 -endContainer(); // .options 17 +pushKey("input");
  18 +beginDict(bindJSON(&Handlers::beginInput), bindBare(&Handlers::endInput)); // .input
  19 +pushKey("filename");
  20 +setupInputFilename();
  21 +popHandler(); // key: filename
  22 +pushKey("password");
  23 +setupInputPassword();
  24 +popHandler(); // key: password
  25 +pushKey("passwordFile");
  26 +addParameter([this](char const* p) { c_main->passwordFile(p); });
  27 +popHandler(); // key: passwordFile
  28 +pushKey("empty");
  29 +setupInputEmpty();
  30 +popHandler(); // key: empty
  31 +popHandler(); // key: input
  32 +pushKey("output");
  33 +beginDict(bindJSON(&Handlers::beginOutput), bindBare(&Handlers::endOutput)); // .output
  34 +pushKey("filename");
  35 +setupOutputFilename();
  36 +popHandler(); // key: filename
  37 +pushKey("replaceInput");
  38 +setupOutputReplaceInput();
  39 +popHandler(); // key: replaceInput
  40 +pushKey("options");
  41 +beginDict(bindJSON(&Handlers::beginOutputOptions), bindBare(&Handlers::endOutputOptions)); // .output.options
  42 +pushKey("qdf");
  43 +addBare([this]() { c_main->qdf(); });
  44 +popHandler(); // key: qdf
  45 +pushKey("preserveUnreferenced");
  46 +addBare([this]() { c_main->preserveUnreferenced(); });
  47 +popHandler(); // key: preserveUnreferenced
  48 +pushKey("newlineBeforeEndstream");
  49 +addBare([this]() { c_main->newlineBeforeEndstream(); });
  50 +popHandler(); // key: newlineBeforeEndstream
  51 +pushKey("normalizeContent");
  52 +addChoices(yn_choices, [this](char const* p) { c_main->normalizeContent(p); });
  53 +popHandler(); // key: normalizeContent
  54 +pushKey("streamData");
  55 +addChoices(stream_data_choices, [this](char const* p) { c_main->streamData(p); });
  56 +popHandler(); // key: streamData
  57 +pushKey("compressStreams");
  58 +addChoices(yn_choices, [this](char const* p) { c_main->compressStreams(p); });
  59 +popHandler(); // key: compressStreams
  60 +pushKey("recompressFlate");
  61 +addBare([this]() { c_main->recompressFlate(); });
  62 +popHandler(); // key: recompressFlate
  63 +pushKey("decodeLevel");
  64 +addChoices(decode_level_choices, [this](char const* p) { c_main->decodeLevel(p); });
  65 +popHandler(); // key: decodeLevel
  66 +pushKey("decrypt");
  67 +addBare([this]() { c_main->decrypt(); });
  68 +popHandler(); // key: decrypt
  69 +pushKey("staticAesIv");
  70 +addBare([this]() { c_main->staticAesIv(); });
  71 +popHandler(); // key: staticAesIv
  72 +pushKey("staticId");
  73 +addBare([this]() { c_main->staticId(); });
  74 +popHandler(); // key: staticId
  75 +pushKey("noOriginalObjectIds");
  76 +addBare([this]() { c_main->noOriginalObjectIds(); });
  77 +popHandler(); // key: noOriginalObjectIds
  78 +pushKey("copyEncryption");
  79 +addParameter([this](char const* p) { c_main->copyEncryption(p); });
  80 +popHandler(); // key: copyEncryption
  81 +pushKey("encryptionFilePassword");
  82 +addParameter([this](char const* p) { c_main->encryptionFilePassword(p); });
  83 +popHandler(); // key: encryptionFilePassword
  84 +pushKey("linearize");
  85 +addBare([this]() { c_main->linearize(); });
  86 +popHandler(); // key: linearize
  87 +pushKey("linearizePass1");
  88 +addParameter([this](char const* p) { c_main->linearizePass1(p); });
  89 +popHandler(); // key: linearizePass1
  90 +pushKey("objectStreams");
  91 +addChoices(object_streams_choices, [this](char const* p) { c_main->objectStreams(p); });
  92 +popHandler(); // key: objectStreams
  93 +pushKey("minVersion");
  94 +addParameter([this](char const* p) { c_main->minVersion(p); });
  95 +popHandler(); // key: minVersion
  96 +pushKey("forceVersion");
  97 +addParameter([this](char const* p) { c_main->forceVersion(p); });
  98 +popHandler(); // key: forceVersion
  99 +pushKey("progress");
  100 +addBare([this]() { c_main->progress(); });
  101 +popHandler(); // key: progress
  102 +pushKey("splitPages");
  103 +addParameter([this](char const* p) { c_main->splitPages(p); });
  104 +popHandler(); // key: splitPages
  105 +pushKey("encrypt");
  106 +beginDict(bindJSON(&Handlers::beginOutputOptionsEncrypt), bindBare(&Handlers::endOutputOptionsEncrypt)); // .output.options.encrypt
  107 +pushKey("userPassword");
  108 +setupOutputOptionsEncryptUserPassword();
  109 +popHandler(); // key: userPassword
  110 +pushKey("ownerPassword");
  111 +setupOutputOptionsEncryptOwnerPassword();
  112 +popHandler(); // key: ownerPassword
  113 +pushKey("40bit");
  114 +beginDict(bindJSON(&Handlers::beginOutputOptionsEncrypt40bit), bindBare(&Handlers::endOutputOptionsEncrypt40bit)); // .output.options.encrypt.40bit
  115 +pushKey("annotate");
  116 +addChoices(yn_choices, [this](char const* p) { c_enc->annotate(p); });
  117 +popHandler(); // key: annotate
  118 +pushKey("extract");
  119 +addChoices(yn_choices, [this](char const* p) { c_enc->extract(p); });
  120 +popHandler(); // key: extract
  121 +pushKey("modify");
  122 +addChoices(modify128_choices, [this](char const* p) { c_enc->modify(p); });
  123 +popHandler(); // key: modify
  124 +pushKey("print");
  125 +addChoices(print128_choices, [this](char const* p) { c_enc->print(p); });
  126 +popHandler(); // key: print
  127 +popHandler(); // key: 40bit
  128 +pushKey("128bit");
  129 +beginDict(bindJSON(&Handlers::beginOutputOptionsEncrypt128bit), bindBare(&Handlers::endOutputOptionsEncrypt128bit)); // .output.options.encrypt.128bit
  130 +pushKey("accessibility");
  131 +addChoices(yn_choices, [this](char const* p) { c_enc->accessibility(p); });
  132 +popHandler(); // key: accessibility
  133 +pushKey("annotate");
  134 +addChoices(yn_choices, [this](char const* p) { c_enc->annotate(p); });
  135 +popHandler(); // key: annotate
  136 +pushKey("assemble");
  137 +addChoices(yn_choices, [this](char const* p) { c_enc->assemble(p); });
  138 +popHandler(); // key: assemble
  139 +pushKey("cleartextMetadata");
  140 +addBare([this]() { c_enc->cleartextMetadata(); });
  141 +popHandler(); // key: cleartextMetadata
  142 +pushKey("extract");
  143 +addChoices(yn_choices, [this](char const* p) { c_enc->extract(p); });
  144 +popHandler(); // key: extract
  145 +pushKey("form");
  146 +addChoices(yn_choices, [this](char const* p) { c_enc->form(p); });
  147 +popHandler(); // key: form
  148 +pushKey("modifyOther");
  149 +addChoices(yn_choices, [this](char const* p) { c_enc->modifyOther(p); });
  150 +popHandler(); // key: modifyOther
  151 +pushKey("modify");
  152 +addChoices(modify128_choices, [this](char const* p) { c_enc->modify(p); });
  153 +popHandler(); // key: modify
  154 +pushKey("print");
  155 +addChoices(print128_choices, [this](char const* p) { c_enc->print(p); });
  156 +popHandler(); // key: print
  157 +pushKey("forceV4");
  158 +addBare([this]() { c_enc->forceV4(); });
  159 +popHandler(); // key: forceV4
  160 +pushKey("useAes");
  161 +addChoices(yn_choices, [this](char const* p) { c_enc->useAes(p); });
  162 +popHandler(); // key: useAes
  163 +popHandler(); // key: 128bit
  164 +pushKey("256bit");
  165 +beginDict(bindJSON(&Handlers::beginOutputOptionsEncrypt256bit), bindBare(&Handlers::endOutputOptionsEncrypt256bit)); // .output.options.encrypt.256bit
  166 +pushKey("accessibility");
  167 +addChoices(yn_choices, [this](char const* p) { c_enc->accessibility(p); });
  168 +popHandler(); // key: accessibility
  169 +pushKey("annotate");
  170 +addChoices(yn_choices, [this](char const* p) { c_enc->annotate(p); });
  171 +popHandler(); // key: annotate
  172 +pushKey("assemble");
  173 +addChoices(yn_choices, [this](char const* p) { c_enc->assemble(p); });
  174 +popHandler(); // key: assemble
  175 +pushKey("cleartextMetadata");
  176 +addBare([this]() { c_enc->cleartextMetadata(); });
  177 +popHandler(); // key: cleartextMetadata
  178 +pushKey("extract");
  179 +addChoices(yn_choices, [this](char const* p) { c_enc->extract(p); });
  180 +popHandler(); // key: extract
  181 +pushKey("form");
  182 +addChoices(yn_choices, [this](char const* p) { c_enc->form(p); });
  183 +popHandler(); // key: form
  184 +pushKey("modifyOther");
  185 +addChoices(yn_choices, [this](char const* p) { c_enc->modifyOther(p); });
  186 +popHandler(); // key: modifyOther
  187 +pushKey("modify");
  188 +addChoices(modify128_choices, [this](char const* p) { c_enc->modify(p); });
  189 +popHandler(); // key: modify
  190 +pushKey("print");
  191 +addChoices(print128_choices, [this](char const* p) { c_enc->print(p); });
  192 +popHandler(); // key: print
  193 +pushKey("allowInsecure");
  194 +addBare([this]() { c_enc->allowInsecure(); });
  195 +popHandler(); // key: allowInsecure
  196 +pushKey("forceR5");
  197 +addBare([this]() { c_enc->forceR5(); });
  198 +popHandler(); // key: forceR5
  199 +popHandler(); // key: 256bit
  200 +popHandler(); // key: encrypt
  201 +popHandler(); // key: options
  202 +popHandler(); // key: output
  203 +pushKey("inspect");
  204 +beginDict(bindJSON(&Handlers::beginInspect), bindBare(&Handlers::endInspect)); // .inspect
  205 +pushKey("check");
  206 +addBare([this]() { c_main->check(); });
  207 +popHandler(); // key: check
  208 +pushKey("checkLinearization");
  209 +addBare([this]() { c_main->checkLinearization(); });
  210 +popHandler(); // key: checkLinearization
  211 +pushKey("filteredStreamData");
  212 +addBare([this]() { c_main->filteredStreamData(); });
  213 +popHandler(); // key: filteredStreamData
  214 +pushKey("rawStreamData");
  215 +addBare([this]() { c_main->rawStreamData(); });
  216 +popHandler(); // key: rawStreamData
  217 +pushKey("showEncryption");
  218 +addBare([this]() { c_main->showEncryption(); });
  219 +popHandler(); // key: showEncryption
  220 +pushKey("showEncryptionKey");
  221 +addBare([this]() { c_main->showEncryptionKey(); });
  222 +popHandler(); // key: showEncryptionKey
  223 +pushKey("showLinearization");
  224 +addBare([this]() { c_main->showLinearization(); });
  225 +popHandler(); // key: showLinearization
  226 +pushKey("showNpages");
  227 +addBare([this]() { c_main->showNpages(); });
  228 +popHandler(); // key: showNpages
  229 +pushKey("showObject");
  230 +addParameter([this](char const* p) { c_main->showObject(p); });
  231 +popHandler(); // key: showObject
  232 +pushKey("showPages");
  233 +addBare([this]() { c_main->showPages(); });
  234 +popHandler(); // key: showPages
  235 +pushKey("showXref");
  236 +addBare([this]() { c_main->showXref(); });
  237 +popHandler(); // key: showXref
  238 +pushKey("withImages");
  239 +addBare([this]() { c_main->withImages(); });
  240 +popHandler(); // key: withImages
  241 +pushKey("listAttachments");
  242 +addBare([this]() { c_main->listAttachments(); });
  243 +popHandler(); // key: listAttachments
  244 +pushKey("showAttachment");
  245 +addParameter([this](char const* p) { c_main->showAttachment(p); });
  246 +popHandler(); // key: showAttachment
  247 +pushKey("json");
  248 +addBare([this]() { c_main->json(); });
  249 +popHandler(); // key: json
  250 +pushKey("jsonKey");
  251 +beginArray(bindJSON(&Handlers::beginInspectJsonKeyArray), bindBare(&Handlers::endInspectJsonKeyArray)); // .inspect.jsonKey[]
  252 +addChoices(json_key_choices, [this](char const* p) { c_main->jsonKey(p); });
  253 +popHandler(); // array: .inspect.jsonKey[]
  254 +popHandler(); // key: jsonKey
  255 +pushKey("jsonObject");
  256 +beginArray(bindJSON(&Handlers::beginInspectJsonObjectArray), bindBare(&Handlers::endInspectJsonObjectArray)); // .inspect.jsonObject[]
  257 +addParameter([this](char const* p) { c_main->jsonObject(p); });
  258 +popHandler(); // array: .inspect.jsonObject[]
  259 +popHandler(); // key: jsonObject
  260 +popHandler(); // key: inspect
  261 +pushKey("options");
  262 +beginDict(bindJSON(&Handlers::beginOptions), bindBare(&Handlers::endOptions)); // .options
  263 +pushKey("allowWeakCrypto");
  264 +addBare([this]() { c_main->allowWeakCrypto(); });
  265 +popHandler(); // key: allowWeakCrypto
  266 +pushKey("deterministicId");
  267 +addBare([this]() { c_main->deterministicId(); });
  268 +popHandler(); // key: deterministicId
  269 +pushKey("keepFilesOpen");
  270 +addChoices(yn_choices, [this](char const* p) { c_main->keepFilesOpen(p); });
  271 +popHandler(); // key: keepFilesOpen
  272 +pushKey("keepFilesOpenThreshold");
  273 +addParameter([this](char const* p) { c_main->keepFilesOpenThreshold(p); });
  274 +popHandler(); // key: keepFilesOpenThreshold
  275 +pushKey("noWarn");
  276 +addBare([this]() { c_main->noWarn(); });
  277 +popHandler(); // key: noWarn
  278 +pushKey("verbose");
  279 +addBare([this]() { c_main->verbose(); });
  280 +popHandler(); // key: verbose
  281 +pushKey("ignoreXrefStreams");
  282 +addBare([this]() { c_main->ignoreXrefStreams(); });
  283 +popHandler(); // key: ignoreXrefStreams
  284 +pushKey("passwordIsHexKey");
  285 +addBare([this]() { c_main->passwordIsHexKey(); });
  286 +popHandler(); // key: passwordIsHexKey
  287 +pushKey("passwordMode");
  288 +addChoices(password_mode_choices, [this](char const* p) { c_main->passwordMode(p); });
  289 +popHandler(); // key: passwordMode
  290 +pushKey("suppressPasswordRecovery");
  291 +addBare([this]() { c_main->suppressPasswordRecovery(); });
  292 +popHandler(); // key: suppressPasswordRecovery
  293 +pushKey("suppressRecovery");
  294 +addBare([this]() { c_main->suppressRecovery(); });
  295 +popHandler(); // key: suppressRecovery
  296 +pushKey("coalesceContents");
  297 +addBare([this]() { c_main->coalesceContents(); });
  298 +popHandler(); // key: coalesceContents
  299 +pushKey("compressionLevel");
  300 +addParameter([this](char const* p) { c_main->compressionLevel(p); });
  301 +popHandler(); // key: compressionLevel
  302 +pushKey("externalizeInlineImages");
  303 +addBare([this]() { c_main->externalizeInlineImages(); });
  304 +popHandler(); // key: externalizeInlineImages
  305 +pushKey("iiMinBytes");
  306 +addParameter([this](char const* p) { c_main->iiMinBytes(p); });
  307 +popHandler(); // key: iiMinBytes
  308 +pushKey("removeUnreferencedResources");
  309 +addChoices(remove_unref_choices, [this](char const* p) { c_main->removeUnreferencedResources(p); });
  310 +popHandler(); // key: removeUnreferencedResources
  311 +pushKey("addAttachment");
  312 +beginArray(bindJSON(&Handlers::beginOptionsAddAttachmentArray), bindBare(&Handlers::endOptionsAddAttachmentArray)); // .options.addAttachment[]
  313 +beginDict(bindJSON(&Handlers::beginOptionsAddAttachment), bindBare(&Handlers::endOptionsAddAttachment)); // .options.addAttachment
  314 +pushKey("path");
  315 +setupOptionsAddAttachmentPath();
  316 +popHandler(); // key: path
  317 +pushKey("creationdate");
  318 +addParameter([this](char const* p) { c_att->creationdate(p); });
  319 +popHandler(); // key: creationdate
  320 +pushKey("description");
  321 +addParameter([this](char const* p) { c_att->description(p); });
  322 +popHandler(); // key: description
  323 +pushKey("filename");
  324 +addParameter([this](char const* p) { c_att->filename(p); });
  325 +popHandler(); // key: filename
  326 +pushKey("key");
  327 +addParameter([this](char const* p) { c_att->key(p); });
  328 +popHandler(); // key: key
  329 +pushKey("mimetype");
  330 +addParameter([this](char const* p) { c_att->mimetype(p); });
  331 +popHandler(); // key: mimetype
  332 +pushKey("moddate");
  333 +addParameter([this](char const* p) { c_att->moddate(p); });
  334 +popHandler(); // key: moddate
  335 +pushKey("replace");
  336 +addBare([this]() { c_att->replace(); });
  337 +popHandler(); // key: replace
  338 +popHandler(); // array: .options.addAttachment[]
  339 +popHandler(); // key: addAttachment
  340 +pushKey("removeAttachment");
  341 +addParameter([this](char const* p) { c_main->removeAttachment(p); });
  342 +popHandler(); // key: removeAttachment
  343 +pushKey("copyAttachmentsFrom");
  344 +beginArray(bindJSON(&Handlers::beginOptionsCopyAttachmentsFromArray), bindBare(&Handlers::endOptionsCopyAttachmentsFromArray)); // .options.copyAttachmentsFrom[]
  345 +beginDict(bindJSON(&Handlers::beginOptionsCopyAttachmentsFrom), bindBare(&Handlers::endOptionsCopyAttachmentsFrom)); // .options.copyAttachmentsFrom
  346 +pushKey("path");
  347 +setupOptionsCopyAttachmentsFromPath();
  348 +popHandler(); // key: path
  349 +pushKey("password");
  350 +setupOptionsCopyAttachmentsFromPassword();
  351 +popHandler(); // key: password
  352 +pushKey("prefix");
  353 +addParameter([this](char const* p) { c_copy_att->prefix(p); });
  354 +popHandler(); // key: prefix
  355 +popHandler(); // array: .options.copyAttachmentsFrom[]
  356 +popHandler(); // key: copyAttachmentsFrom
  357 +pushKey("collate");
  358 +addParameter([this](char const* p) { c_main->collate(p); });
  359 +popHandler(); // key: collate
  360 +pushKey("flattenAnnotations");
  361 +addChoices(flatten_choices, [this](char const* p) { c_main->flattenAnnotations(p); });
  362 +popHandler(); // key: flattenAnnotations
  363 +pushKey("flattenRotation");
  364 +addBare([this]() { c_main->flattenRotation(); });
  365 +popHandler(); // key: flattenRotation
  366 +pushKey("generateAppearances");
  367 +addBare([this]() { c_main->generateAppearances(); });
  368 +popHandler(); // key: generateAppearances
  369 +pushKey("keepInlineImages");
  370 +addBare([this]() { c_main->keepInlineImages(); });
  371 +popHandler(); // key: keepInlineImages
  372 +pushKey("oiMinArea");
  373 +addParameter([this](char const* p) { c_main->oiMinArea(p); });
  374 +popHandler(); // key: oiMinArea
  375 +pushKey("oiMinHeight");
  376 +addParameter([this](char const* p) { c_main->oiMinHeight(p); });
  377 +popHandler(); // key: oiMinHeight
  378 +pushKey("oiMinWidth");
  379 +addParameter([this](char const* p) { c_main->oiMinWidth(p); });
  380 +popHandler(); // key: oiMinWidth
  381 +pushKey("optimizeImages");
  382 +addBare([this]() { c_main->optimizeImages(); });
  383 +popHandler(); // key: optimizeImages
  384 +pushKey("pages");
  385 +beginArray(bindJSON(&Handlers::beginOptionsPagesArray), bindBare(&Handlers::endOptionsPagesArray)); // .options.pages[]
  386 +beginDict(bindJSON(&Handlers::beginOptionsPages), bindBare(&Handlers::endOptionsPages)); // .options.pages
  387 +pushKey("file");
  388 +setupOptionsPagesFile();
  389 +popHandler(); // key: file
  390 +pushKey("password");
  391 +setupOptionsPagesPassword();
  392 +popHandler(); // key: password
  393 +pushKey("range");
  394 +setupOptionsPagesRange();
  395 +popHandler(); // key: range
  396 +popHandler(); // array: .options.pages[]
  397 +popHandler(); // key: pages
  398 +pushKey("removePageLabels");
  399 +addBare([this]() { c_main->removePageLabels(); });
  400 +popHandler(); // key: removePageLabels
  401 +pushKey("rotate");
  402 +addParameter([this](char const* p) { c_main->rotate(p); });
  403 +popHandler(); // key: rotate
  404 +pushKey("overlay");
  405 +beginDict(bindJSON(&Handlers::beginOptionsOverlay), bindBare(&Handlers::endOptionsOverlay)); // .options.overlay
  406 +pushKey("file");
  407 +setupOptionsOverlayFile();
  408 +popHandler(); // key: file
  409 +pushKey("password");
  410 +setupOptionsOverlayPassword();
  411 +popHandler(); // key: password
  412 +pushKey("from");
  413 +addParameter([this](char const* p) { c_uo->from(p); });
  414 +popHandler(); // key: from
  415 +pushKey("repeat");
  416 +addParameter([this](char const* p) { c_uo->repeat(p); });
  417 +popHandler(); // key: repeat
  418 +pushKey("to");
  419 +addParameter([this](char const* p) { c_uo->to(p); });
  420 +popHandler(); // key: to
  421 +popHandler(); // key: overlay
  422 +pushKey("underlay");
  423 +beginDict(bindJSON(&Handlers::beginOptionsUnderlay), bindBare(&Handlers::endOptionsUnderlay)); // .options.underlay
  424 +pushKey("file");
  425 +setupOptionsUnderlayFile();
  426 +popHandler(); // key: file
  427 +pushKey("password");
  428 +setupOptionsUnderlayPassword();
  429 +popHandler(); // key: password
  430 +pushKey("from");
  431 +addParameter([this](char const* p) { c_uo->from(p); });
  432 +popHandler(); // key: from
  433 +pushKey("repeat");
  434 +addParameter([this](char const* p) { c_uo->repeat(p); });
  435 +popHandler(); // key: repeat
  436 +pushKey("to");
  437 +addParameter([this](char const* p) { c_uo->to(p); });
  438 +popHandler(); // key: to
  439 +popHandler(); // key: underlay
  440 +popHandler(); // key: options
libqpdf/qpdf/auto_job_schema.hh
@@ -85,10 +85,10 @@ static constexpr char const* JOB_SCHEMA_DATA = R&quot;({ @@ -85,10 +85,10 @@ static constexpr char const* JOB_SCHEMA_DATA = R&quot;({
85 "showAttachment": "export an embedded file", 85 "showAttachment": "export an embedded file",
86 "json": "show file in json format", 86 "json": "show file in json format",
87 "jsonKey": [ 87 "jsonKey": [
88 - null 88 + "restrict which keys are in json output"
89 ], 89 ],
90 "jsonObject": [ 90 "jsonObject": [
91 - null 91 + "restrict which objects are in JSON"
92 ] 92 ]
93 }, 93 },
94 "options": { 94 "options": {