Commit 11a86e444da4ffcb0d5aa5203fda2d0ebc001a7c

Authored by Jay Berkenbilt
1 parent 842a9d92

QPDFJob: autogenerate json init and declarations

Now still have to go through and implement the handlers.
generate_auto_job
@@ -364,16 +364,17 @@ class Main: @@ -364,16 +364,17 @@ class Main:
364 self.json_decls = [] 364 self.json_decls = []
365 self.json_init = [] 365 self.json_init = []
366 self.jdata = {} 366 self.jdata = {}
  367 + self.by_table = {}
367 368
368 - def add_jdata(flag, table): 369 + def add_jdata(flag, table, details):
369 nonlocal self 370 nonlocal self
370 if table == 'help': 371 if table == 'help':
371 self.help_options.add(f'--{flag}') 372 self.help_options.add(f'--{flag}')
372 elif flag in self.jdata: 373 elif flag in self.jdata:
373 - self.jdata[flag]['tables'].add(table) 374 + self.jdata[flag]['tables'][table] = details
374 else: 375 else:
375 self.jdata[flag] = { 376 self.jdata[flag] = {
376 - 'tables': set([table]), 377 + 'tables': {table: details},
377 } 378 }
378 379
379 self.init.append('auto b = [this](void (ArgParser::*f)()) {') 380 self.init.append('auto b = [this](void (ArgParser::*f)()) {')
@@ -384,11 +385,14 @@ class Main: @@ -384,11 +385,14 @@ class Main:
384 self.init.append('};') 385 self.init.append('};')
385 self.init.append('') 386 self.init.append('')
386 for k, v in data['choices'].items(): 387 for k, v in data['choices'].items():
387 - s = f'char const* {k}_choices[] = {{' 388 + s = f'static char const* {k}_choices[] = {{'
388 for i in v: 389 for i in v:
389 s += f'"{i}", ' 390 s += f'"{i}", '
390 - self.init.append(s + '0};') 391 + s += '0};'
  392 + self.init.append(s)
  393 + self.json_init.append(s)
391 self.init.append('') 394 self.init.append('')
  395 + self.json_init.append('')
392 396
393 for o in data['options']: 397 for o in data['options']:
394 table = o['table'] 398 table = o['table']
@@ -402,6 +406,13 @@ class Main: @@ -402,6 +406,13 @@ class Main:
402 config = o.get('config', None) 406 config = o.get('config', None)
403 table_prefix = o.get('prefix', '') 407 table_prefix = o.get('prefix', '')
404 arg_prefix = 'arg' + table_prefix 408 arg_prefix = 'arg' + table_prefix
  409 + config_prefix = o.get('config_prefix', table_prefix)
  410 + manual = o.get('manual', [])
  411 + json_prefix = table_prefix or table
  412 + self.by_table[json_prefix] = {
  413 + 'config': config,
  414 + 'manual': manual,
  415 + }
405 if table == 'main': 416 if table == 'main':
406 self.init.append('this->ap.selectMainOptionTable();') 417 self.init.append('this->ap.selectMainOptionTable();')
407 elif table == 'help': 418 elif table == 'help':
@@ -430,33 +441,58 @@ class Main: @@ -430,33 +441,58 @@ class Main:
430 441
431 for i, [kind, v] in flags.items(): 442 for i, [kind, v] in flags.items():
432 self.options_without_help.add(f'--{i}') 443 self.options_without_help.add(f'--{i}')
433 - add_jdata(i, table_prefix or table)  
434 - if config is None or i in o.get('manual', []): 444 + add_jdata(i, json_prefix, [kind, v])
  445 + if config is None or i in manual:
435 identifier = self.to_identifier(i, arg_prefix, False) 446 identifier = self.to_identifier(i, arg_prefix, False)
436 self.handle_flag(i, identifier, kind, v) 447 self.handle_flag(i, identifier, kind, v)
437 else: 448 else:
438 identifier = self.to_identifier(i, '', False) 449 identifier = self.to_identifier(i, '', False)
439 - prefix = o.get('config_prefix', table_prefix)  
440 self.handle_trivial( 450 self.handle_trivial(
441 - i, identifier, config, prefix, kind, v) 451 + i, identifier, config, config_prefix, kind, v)
442 452
443 if table not in ('main', 'help'): 453 if table not in ('main', 'help'):
444 identifier = self.to_identifier(table, 'argEnd', False) 454 identifier = self.to_identifier(table, 'argEnd', False)
445 self.decls.append(f'void {identifier}();') 455 self.decls.append(f'void {identifier}();')
446 456
447 - def generate_schema(self, data):  
448 - # XXX check data['json'] against what we know from jdata.  
449 - # Ultimately be able to generate a schema as well as  
450 - # JSONHandler and registering stuff. 457 + def handle_json_trivial(self, key, fdata):
  458 + config = None
  459 + for t, [kind, v] in fdata['tables'].items():
  460 + # We have determined that all tables, if multiple, have
  461 + # the same config.
  462 + tdata = self.by_table[t]
  463 + config = tdata['config']
  464 + if kind == 'bare':
  465 + self.json_init.append(
  466 + f'addBare("{key}", [this]() {{ {config}->{key}(); }});')
  467 + elif kind == 'optional_parameter' or kind == 'required_parameter':
  468 + # No optional parameters in json
  469 + self.json_init.append(
  470 + f'addParameter("{key}", [this](char const* p)'
  471 + f' {{ {config}->{key}(p); }});')
  472 + elif kind == 'optional_choices' or kind == 'required_choices':
  473 + # No optional choices in json
  474 + self.json_init.append(
  475 + f'addChoices("{key}", {v}_choices,'
  476 + f' [this](char const* p) {{ {config}->{key}(p); }});')
  477 +
  478 + def handle_json_manual(self, key, path):
  479 + method = re.sub(r'\.([a-zA-Z0-9])',
  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}));')
451 486
  487 + def generate_schema(self, data):
452 # Check to make sure that every command-line option is 488 # Check to make sure that every command-line option is
453 # represented either in data['json'] or data['no-json']. 489 # represented either in data['json'] or data['no-json'].
454 490
455 # Build a list of options that we expect. If an option appears 491 # Build a list of options that we expect. If an option appears
456 # once, we just expect to see it once. If it appears in more 492 # once, we just expect to see it once. If it appears in more
457 # than one options table, we need to see a separate version of 493 # than one options table, we need to see a separate version of
458 - # it for each option table. It is represented prepended in  
459 - # job.yml with the table prefix. The table prefix is removed 494 + # it for each option table. It is represented in job.yml
  495 + # prepended with the table prefix. The table prefix is removed
460 # in the schema. 496 # in the schema.
461 expected = {} 497 expected = {}
462 for k, v in self.jdata.items(): 498 for k, v in self.jdata.items():
@@ -466,8 +502,6 @@ class Main: @@ -466,8 +502,6 @@ class Main:
466 else: 502 else:
467 for t in sorted(tables): 503 for t in sorted(tables):
468 expected[f'{t}.{k}'] = {**v} 504 expected[f'{t}.{k}'] = {**v}
469 - for _, v in expected.items():  
470 - del v['tables']  
471 options_seen = set(data['no-json']) 505 options_seen = set(data['no-json'])
472 506
473 self.schema = {} 507 self.schema = {}
@@ -479,11 +513,29 @@ class Main: @@ -479,11 +513,29 @@ class Main:
479 # go. This verifies consistency between command-line options 513 # go. This verifies consistency between command-line options
480 # and the json section of the data and builds up a schema by 514 # and the json section of the data and builds up a schema by
481 # populating with help information as available. 515 # populating with help information as available.
482 - def build_schema(j, s): 516 + def build_schema(j, s, flag, path):
  517 + if flag:
  518 + identifier = self.to_identifier(path, '', False)
  519 + self.json_decls.append(f'void begin{identifier}();')
  520 + self.json_decls.append(f'void end{identifier}();')
  521 + self.json_init.append(
  522 + f'beginDict("{flag}",'
  523 + f' bindBare(&Handlers::begin{identifier}),'
  524 + f' bindBare(&Handlers::end{identifier})); // {path}')
483 for k, v in j.items(): 525 for k, v in j.items():
484 - if not (k in expected or  
485 - k.startswith('_') or  
486 - isinstance(v, str)): 526 + is_trivial = False
  527 + if k in expected:
  528 + is_trivial = True
  529 + common_config = None
  530 + for t in expected[k]['tables']:
  531 + tdata = self.by_table[t]
  532 + if k in tdata['manual']:
  533 + is_trivial = False
  534 + if common_config is None:
  535 + common_config = tdata['config']
  536 + elif common_config != tdata['config']:
  537 + is_trivial = False
  538 + elif not (k.startswith('_') or isinstance(v, str)):
487 raise Exception(f'json: unknown key {k}') 539 raise Exception(f'json: unknown key {k}')
488 if k.startswith('_'): 540 if k.startswith('_'):
489 schema_key = k[1:] 541 schema_key = k[1:]
@@ -491,6 +543,7 @@ class Main: @@ -491,6 +543,7 @@ class Main:
491 schema_key = re.sub(r'[^\.]+\.', '', k) 543 schema_key = re.sub(r'[^\.]+\.', '', k)
492 schema_key = option_to_json_key(schema_key) 544 schema_key = option_to_json_key(schema_key)
493 schema_value = v 545 schema_value = v
  546 + is_dict = False
494 if k in expected: 547 if k in expected:
495 options_seen.add(re.sub('^_', '', k)) 548 options_seen.add(re.sub('^_', '', k))
496 if v is None: 549 if v is None:
@@ -499,19 +552,30 @@ class Main: @@ -499,19 +552,30 @@ class Main:
499 lambda x: option_to_json_key(x.group(1)), 552 lambda x: option_to_json_key(x.group(1)),
500 expected[k]['help']) 553 expected[k]['help'])
501 if (isinstance(v, dict)): 554 if (isinstance(v, dict)):
  555 + is_dict = True
502 schema_value = {} 556 schema_value = {}
503 - build_schema(v, schema_value) 557 + build_schema(v, schema_value,
  558 + schema_key, f'{path}.{schema_key}')
504 elif (isinstance(v, list)): 559 elif (isinstance(v, list)):
505 if len(v) != 1: 560 if len(v) != 1:
506 raise Exception('json contains array with length != 1') 561 raise Exception('json contains array with length != 1')
507 if isinstance(v[0], dict): 562 if isinstance(v[0], dict):
  563 + is_dict = True
508 schema_value = [{}] 564 schema_value = [{}]
509 - build_schema(v[0], schema_value[0]) 565 + build_schema(v[0], schema_value[0],
  566 + schema_key, f'{path}.{schema_key}')
510 elif schema_value is None: 567 elif schema_value is None:
511 raise Exception(f'unknown schema value for {k}') 568 raise Exception(f'unknown schema value for {k}')
512 s[schema_key] = schema_value 569 s[schema_key] = schema_value
  570 + if not is_dict:
  571 + if is_trivial:
  572 + self.handle_json_trivial(schema_key, expected[k])
  573 + else:
  574 + self.handle_json_manual(schema_key, path)
  575 + if flag:
  576 + self.json_init.append(f'endDict(); // {path}')
513 577
514 - build_schema(data['json'], self.schema) 578 + build_schema(data['json'], self.schema, '', '')
515 if options_seen != set(expected.keys()): 579 if options_seen != set(expected.keys()):
516 raise Exception('missing from json: ' + 580 raise Exception('missing from json: ' +
517 str(set(expected.keys()) - options_seen)) 581 str(set(expected.keys()) - options_seen))
@@ -540,9 +604,7 @@ class Main: @@ -540,9 +604,7 @@ class Main:
540 identifier = f'{prefix}_{identifier.upper()}' 604 identifier = f'{prefix}_{identifier.upper()}'
541 else: 605 else:
542 if prefix: 606 if prefix:
543 - identifier = f'{prefix}_{identifier.lower()}'  
544 - else:  
545 - identifier = identifier.lower() 607 + identifier = f'{prefix}_{identifier}'
546 identifier = re.sub(r'_([a-z])', 608 identifier = re.sub(r'_([a-z])',
547 lambda x: x.group(1).upper(), 609 lambda x: x.group(1).upper(),
548 identifier).replace('_', '') 610 identifier).replace('_', '')
job.sums
1 # Generated by generate_auto_job 1 # Generated by generate_auto_job
2 -generate_auto_job f9aa6ddc529f5be910566a59329d1d2fea7d18c7e5c014fe30f6567a3bd518aa 2 +generate_auto_job 53b2b81e8cb38f1bfa0053f351f37fe9e9437eb2cef808ff0c01cfc56ca20946
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
6 include/qpdf/auto_job_c_main.hh 516adb23cc7e44e614e436880be870d0574e4ebbc706cd855a1360000eed31bb 6 include/qpdf/auto_job_c_main.hh 516adb23cc7e44e614e436880be870d0574e4ebbc706cd855a1360000eed31bb
7 include/qpdf/auto_job_c_pages.hh 931840b329a36ca0e41401190e04537b47f2867671a6643bfd8da74014202671 7 include/qpdf/auto_job_c_pages.hh 931840b329a36ca0e41401190e04537b47f2867671a6643bfd8da74014202671
8 include/qpdf/auto_job_c_uo.hh 0585b7de459fa479d9e51a45fa92de0ff6dee748efc9ec1cedd0dde6cee1ad50 8 include/qpdf/auto_job_c_uo.hh 0585b7de459fa479d9e51a45fa92de0ff6dee748efc9ec1cedd0dde6cee1ad50
9 -job.yml 1590fd16fd17ed40db9aa56b6713c844cfd61b3a6d0441a3ccd122b7371c68e9 9 +job.yml d9be74c397e1f272ac6a81981a528c332f8bd7b98d58ae6ba6f60875391567e8
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 3b6323189480a7d782563c9d2b5bc29b8dcd19c6dcc89840b207e38cb503d3f1  
13 -libqpdf/qpdf/auto_job_json_decl.hh 931840b329a36ca0e41401190e04537b47f2867671a6643bfd8da74014202671  
14 -libqpdf/qpdf/auto_job_json_init.hh 931840b329a36ca0e41401190e04537b47f2867671a6643bfd8da74014202671  
15 -libqpdf/qpdf/auto_job_schema.hh 1c3b4b5488270f8d200ed345573e3a241f15baff6fb7e97ec3d044103b2546d9 12 +libqpdf/qpdf/auto_job_init.hh 8e9e31b6099a662497339b27f6e2d7f779f35011e88a834bee8811c33405a0fe
  13 +libqpdf/qpdf/auto_job_json_decl.hh d729213332b92ee0da89d1cad0318ab96aec443f37d208fbbc8d56e9d1398ac2
  14 +libqpdf/qpdf/auto_job_json_init.hh a28c2c2b83d1c0036d3d07172dffb1eac1b75ce3d6a615a87111e9f3bd3dad58
  15 +libqpdf/qpdf/auto_job_schema.hh 9962f09f3260c01d4165a6ddf2814a0621395dcb5d80a3d310f580a1b7d3baba
16 manual/_ext/qpdf.py e9ac9d6c70642a3d29281ee5ad92ae2422dee8be9306fb8a0bc9dba0ed5e28f3 16 manual/_ext/qpdf.py e9ac9d6c70642a3d29281ee5ad92ae2422dee8be9306fb8a0bc9dba0ed5e28f3
17 manual/cli.rst 79140e023faa0cb77afe0b1dc512dd120ee5617f4db82f842596e4f239f93882 17 manual/cli.rst 79140e023faa0cb77afe0b1dc512dd120ee5617f4db82f842596e4f239f93882
@@ -253,16 +253,13 @@ json: @@ -253,16 +253,13 @@ json:
253 # a "schema" (as in JSON.hh) for the json input to QPDFJob. The 253 # a "schema" (as in JSON.hh) for the json input to QPDFJob. The
254 # leading underscore is removed. 254 # leading underscore is removed.
255 _input: 255 _input:
256 - # QXXXQ need to figure out how to specify input and output  
257 - _file:  
258 - _name: "input filename"  
259 - main.password:  
260 - password-file:  
261 - _empty: "qxxxq empty" 256 + _fileName: "input filename"
  257 + main.password:
  258 + password-file:
  259 + empty:
262 _output: 260 _output:
263 - _file:  
264 - _name: "output filename"  
265 - _replace-input: "qxxxq replace input" 261 + _fileName: "output filename"
  262 + _replace-input: "set to true to replace input"
266 _options: 263 _options:
267 qdf: 264 qdf:
268 preserve-unreferenced: 265 preserve-unreferenced:
libqpdf/QPDFJob_json.cc
@@ -23,20 +23,23 @@ namespace @@ -23,20 +23,23 @@ namespace
23 void usage(std::string const& message); 23 void usage(std::string const& message);
24 void initHandlers(); 24 void initHandlers();
25 25
26 - typedef std::function<void()> bare_arg_handler_t;  
27 - typedef std::function<void(char const*)> param_arg_handler_t;  
28 -  
29 - void addBare(std::string const& key, bare_arg_handler_t);  
30 - void addParameter(std::string const& key, bool required,  
31 - param_arg_handler_t);  
32 - void addChoices(std::string const& key,  
33 - bool required, char const** choices,  
34 - param_arg_handler_t); 26 + typedef std::function<void()> bare_handler_t;
  27 + typedef std::function<void(char const*)> param_handler_t;
  28 + typedef std::function<void(std::string const& key)> setup_handler_t;
  29 +
  30 + void addBare(std::string const& key, bare_handler_t);
  31 + void addParameter(std::string const& key, param_handler_t);
  32 + void addChoices(std::string const& key, char const** choices,
  33 + param_handler_t);
  34 + void doSetup(std::string const& key, setup_handler_t);
35 void beginDict(std::string const& key, 35 void beginDict(std::string const& key,
36 - bare_arg_handler_t start_fn,  
37 - bare_arg_handler_t end_fn); 36 + bare_handler_t start_fn,
  37 + bare_handler_t end_fn);
38 void endDict(); 38 void endDict();
39 39
  40 + bare_handler_t bindBare(void (Handlers::*f)());
  41 + setup_handler_t bindSetup(void (Handlers::*f)(std::string const&));
  42 +
40 std::list<std::shared_ptr<JSONHandler>> json_handlers; 43 std::list<std::shared_ptr<JSONHandler>> json_handlers;
41 JSONHandler* jh; // points to last of json_handlers 44 JSONHandler* jh; // points to last of json_handlers
42 std::shared_ptr<QPDFJob::Config> c_main; 45 std::shared_ptr<QPDFJob::Config> c_main;
@@ -61,6 +64,18 @@ Handlers::usage(std::string const&amp; message) @@ -61,6 +64,18 @@ Handlers::usage(std::string const&amp; message)
61 throw QPDFUsage(message); 64 throw QPDFUsage(message);
62 } 65 }
63 66
  67 +Handlers::bare_handler_t
  68 +Handlers::bindBare(void (Handlers::*f)())
  69 +{
  70 + return std::bind(std::mem_fn(f), this);
  71 +}
  72 +
  73 +Handlers::setup_handler_t
  74 +Handlers::bindSetup(void (Handlers::*f)(std::string const&))
  75 +{
  76 + return std::bind(std::mem_fn(f), this, std::placeholders::_1);
  77 +}
  78 +
64 void 79 void
65 Handlers::initHandlers() 80 Handlers::initHandlers()
66 { 81 {
@@ -72,33 +87,6 @@ Handlers::initHandlers() @@ -72,33 +87,6 @@ Handlers::initHandlers()
72 87
73 # include <qpdf/auto_job_json_init.hh> 88 # include <qpdf/auto_job_json_init.hh>
74 89
75 - // QXXXQ  
76 - auto empty = [](){};  
77 - beginDict("input", empty, empty);  
78 - beginDict("file", empty, empty);  
79 - addParameter("name", true, [this](char const* p) {  
80 - c_main->inputFile(p);  
81 - });  
82 - endDict(); // input.file  
83 - endDict(); // input  
84 - beginDict("output", empty, empty);  
85 - beginDict("file", empty, empty);  
86 - addParameter("name", true, [this](char const* p) {  
87 - c_main->outputFile(p);  
88 - });  
89 - endDict(); // output.file  
90 - beginDict("options", empty, empty);  
91 - addBare("qdf", [this]() {  
92 - c_main->qdf();  
93 - });  
94 - char const* choices[] = {"disable", "preserve", "generate", 0};  
95 - addChoices("objectStreams", true, choices, [this](char const* p) {  
96 - c_main->objectStreams(p);  
97 - });  
98 - endDict(); // output.options  
99 - endDict(); // output  
100 - // /QXXXQ  
101 -  
102 if (this->json_handlers.size() != 1) 90 if (this->json_handlers.size() != 1)
103 { 91 {
104 throw std::logic_error("QPDFJob_json: json_handlers size != 1 at end"); 92 throw std::logic_error("QPDFJob_json: json_handlers size != 1 at end");
@@ -106,7 +94,7 @@ Handlers::initHandlers() @@ -106,7 +94,7 @@ Handlers::initHandlers()
106 } 94 }
107 95
108 void 96 void
109 -Handlers::addBare(std::string const& key, bare_arg_handler_t fn) 97 +Handlers::addBare(std::string const& key, bare_handler_t fn)
110 { 98 {
111 auto h = std::make_shared<JSONHandler>(); 99 auto h = std::make_shared<JSONHandler>();
112 h->addBoolHandler([this, fn](std::string const& path, bool v){ 100 h->addBoolHandler([this, fn](std::string const& path, bool v){
@@ -123,29 +111,19 @@ Handlers::addBare(std::string const&amp; key, bare_arg_handler_t fn) @@ -123,29 +111,19 @@ Handlers::addBare(std::string const&amp; key, bare_arg_handler_t fn)
123 } 111 }
124 112
125 void 113 void
126 -Handlers::addParameter(std::string const& key,  
127 - bool required,  
128 - param_arg_handler_t fn) 114 +Handlers::addParameter(std::string const& key, param_handler_t fn)
129 { 115 {
130 auto h = std::make_shared<JSONHandler>(); 116 auto h = std::make_shared<JSONHandler>();
131 h->addStringHandler( 117 h->addStringHandler(
132 [fn](std::string const& path, std::string const& parameter){ 118 [fn](std::string const& path, std::string const& parameter){
133 fn(parameter.c_str()); 119 fn(parameter.c_str());
134 }); 120 });
135 - if (! required)  
136 - {  
137 - h->addNullHandler(  
138 - [fn](std::string const& path){  
139 - fn(nullptr);  
140 - });  
141 - }  
142 jh->addDictKeyHandler(key, h); 121 jh->addDictKeyHandler(key, h);
143 } 122 }
144 123
145 void 124 void
146 -Handlers::addChoices(std::string const& key,  
147 - bool required, char const** choices,  
148 - param_arg_handler_t fn) 125 +Handlers::addChoices(std::string const& key, char const** choices,
  126 + param_handler_t fn)
149 { 127 {
150 auto h = std::make_shared<JSONHandler>(); 128 auto h = std::make_shared<JSONHandler>();
151 h->addStringHandler( 129 h->addStringHandler(
@@ -183,20 +161,19 @@ Handlers::addChoices(std::string const&amp; key, @@ -183,20 +161,19 @@ Handlers::addChoices(std::string const&amp; key,
183 } 161 }
184 fn(parameter.c_str()); 162 fn(parameter.c_str());
185 }); 163 });
186 - if (! required)  
187 - {  
188 - h->addNullHandler(  
189 - [fn](std::string const& path){  
190 - fn(nullptr);  
191 - });  
192 - }  
193 jh->addDictKeyHandler(key, h); 164 jh->addDictKeyHandler(key, h);
194 } 165 }
195 166
196 void 167 void
  168 +Handlers::doSetup(std::string const& key, setup_handler_t fn)
  169 +{
  170 + fn(key);
  171 +}
  172 +
  173 +void
197 Handlers::beginDict(std::string const& key, 174 Handlers::beginDict(std::string const& key,
198 - bare_arg_handler_t start_fn,  
199 - bare_arg_handler_t end_fn) 175 + bare_handler_t start_fn,
  176 + bare_handler_t end_fn)
200 { 177 {
201 auto new_jh = std::make_shared<JSONHandler>(); 178 auto new_jh = std::make_shared<JSONHandler>();
202 new_jh->addDictHandlers( 179 new_jh->addDictHandlers(
@@ -221,6 +198,314 @@ Handlers::handle(JSON&amp; j) @@ -221,6 +198,314 @@ Handlers::handle(JSON&amp; j)
221 } 198 }
222 199
223 void 200 void
  201 +Handlers::beginInput()
  202 +{
  203 + // nothing needed
  204 +}
  205 +
  206 +void
  207 +Handlers::endInput()
  208 +{
  209 + // nothing needed
  210 +}
  211 +
  212 +void
  213 +Handlers::setupInputFileName(std::string const& key)
  214 +{
  215 + addParameter(key, [this](char const* p) {
  216 + c_main->inputFile(p);
  217 + });
  218 +}
  219 +
  220 +void
  221 +Handlers::setupInputPassword(std::string const& key)
  222 +{
  223 + // QXXXQ
  224 +}
  225 +
  226 +void
  227 +Handlers::setupInputEmpty(std::string const& key)
  228 +{
  229 + addBare(key, [this]() {
  230 + c_main->emptyInput();
  231 + });
  232 +}
  233 +
  234 +void
  235 +Handlers::beginOutput()
  236 +{
  237 + // nothing needed
  238 +}
  239 +
  240 +void
  241 +Handlers::endOutput()
  242 +{
  243 + // nothing needed
  244 +}
  245 +
  246 +void
  247 +Handlers::setupOutputFileName(std::string const& key)
  248 +{
  249 + addParameter(key, [this](char const* p) {
  250 + c_main->outputFile(p);
  251 + });
  252 +}
  253 +
  254 +void
  255 +Handlers::setupOutputReplaceInput(std::string const& key)
  256 +{
  257 + addBare(key, [this]() {
  258 + c_main->replaceInput();
  259 + });
  260 +}
  261 +
  262 +void
  263 +Handlers::beginOutputOptions()
  264 +{
  265 + // nothing needed
  266 +}
  267 +
  268 +void
  269 +Handlers::endOutputOptions()
  270 +{
  271 + // nothing needed
  272 +}
  273 +
  274 +void
  275 +Handlers::beginOutputOptionsEncrypt()
  276 +{
  277 + // QXXXQ
  278 +}
  279 +
  280 +void
  281 +Handlers::endOutputOptionsEncrypt()
  282 +{
  283 + // QXXXQ
  284 +}
  285 +
  286 +void
  287 +Handlers::setupOutputOptionsEncryptKeyLength(std::string const& key)
  288 +{
  289 + // QXXXQ
  290 +}
  291 +
  292 +void
  293 +Handlers::setupOutputOptionsEncryptUserPassword(std::string const& key)
  294 +{
  295 + // QXXXQ
  296 +}
  297 +
  298 +void
  299 +Handlers::setupOutputOptionsEncryptOwnerPassword(std::string const& key)
  300 +{
  301 + // QXXXQ
  302 +}
  303 +
  304 +void
  305 +Handlers::beginOutputOptionsEncrypt40Bit()
  306 +{
  307 + // QXXXQ
  308 +}
  309 +
  310 +void
  311 +Handlers::endOutputOptionsEncrypt40Bit()
  312 +{
  313 + // QXXXQ
  314 +}
  315 +
  316 +void
  317 +Handlers::beginOutputOptionsEncrypt128Bit()
  318 +{
  319 + // QXXXQ
  320 +}
  321 +
  322 +void
  323 +Handlers::endOutputOptionsEncrypt128Bit()
  324 +{
  325 + // QXXXQ
  326 +}
  327 +
  328 +void
  329 +Handlers::beginOutputOptionsEncrypt256Bit()
  330 +{
  331 + // QXXXQ
  332 +}
  333 +
  334 +void
  335 +Handlers::endOutputOptionsEncrypt256Bit()
  336 +{
  337 + // QXXXQ
  338 +}
  339 +
  340 +void
  341 +Handlers::beginOptions()
  342 +{
  343 + // nothing needed
  344 +}
  345 +
  346 +void
  347 +Handlers::endOptions()
  348 +{
  349 + // nothing needed
  350 +}
  351 +
  352 +void
  353 +Handlers::beginInspect()
  354 +{
  355 + // nothing needed
  356 +}
  357 +
  358 +void
  359 +Handlers::endInspect()
  360 +{
  361 + // nothing needed
  362 +}
  363 +
  364 +void
  365 +Handlers::beginTransform()
  366 +{
  367 + // nothing needed
  368 +}
  369 +
  370 +void
  371 +Handlers::endTransform()
  372 +{
  373 + // nothing needed
  374 +}
  375 +
  376 +void
  377 +Handlers::beginModify()
  378 +{
  379 + // nothing needed
  380 +}
  381 +
  382 +void
  383 +Handlers::endModify()
  384 +{
  385 + // nothing needed
  386 +}
  387 +
  388 +void
  389 +Handlers::beginModifyAddAttachment()
  390 +{
  391 + // QXXXQ
  392 +}
  393 +
  394 +void
  395 +Handlers::endModifyAddAttachment()
  396 +{
  397 + // QXXXQ
  398 +}
  399 +
  400 +void
  401 +Handlers::setupModifyAddAttachmentPath(std::string const& key)
  402 +{
  403 + // QXXXQ
  404 +}
  405 +
  406 +void
  407 +Handlers::beginModifyCopyAttachmentsFrom()
  408 +{
  409 + // QXXXQ
  410 +}
  411 +
  412 +void
  413 +Handlers::endModifyCopyAttachmentsFrom()
  414 +{
  415 + // QXXXQ
  416 +}
  417 +
  418 +void
  419 +Handlers::setupModifyCopyAttachmentsFromPath(std::string const& key)
  420 +{
  421 + // QXXXQ
  422 +}
  423 +
  424 +void
  425 +Handlers::setupModifyCopyAttachmentsFromPassword(std::string const& key)
  426 +{
  427 + // QXXXQ
  428 +}
  429 +
  430 +void
  431 +Handlers::beginModifyPages()
  432 +{
  433 + // QXXXQ
  434 +}
  435 +
  436 +void
  437 +Handlers::endModifyPages()
  438 +{
  439 + // QXXXQ
  440 +}
  441 +
  442 +void
  443 +Handlers::setupModifyPagesFile(std::string const& key)
  444 +{
  445 + // QXXXQ
  446 +}
  447 +
  448 +void
  449 +Handlers::setupModifyPagesPassword(std::string const& key)
  450 +{
  451 + // QXXXQ
  452 +}
  453 +
  454 +void
  455 +Handlers::setupModifyPagesRange(std::string const& key)
  456 +{
  457 + // QXXXQ
  458 +}
  459 +
  460 +void
  461 +Handlers::beginModifyOverlay()
  462 +{
  463 + // QXXXQ
  464 +}
  465 +
  466 +void
  467 +Handlers::endModifyOverlay()
  468 +{
  469 + // QXXXQ
  470 +}
  471 +
  472 +void
  473 +Handlers::setupModifyOverlayFile(std::string const& key)
  474 +{
  475 + // QXXXQ
  476 +}
  477 +
  478 +void
  479 +Handlers::setupModifyOverlayPassword(std::string const& key)
  480 +{
  481 + // QXXXQ
  482 +}
  483 +
  484 +void
  485 +Handlers::beginModifyUnderlay()
  486 +{
  487 + // QXXXQ
  488 +}
  489 +
  490 +void
  491 +Handlers::endModifyUnderlay()
  492 +{
  493 + // QXXXQ
  494 +}
  495 +
  496 +void
  497 +Handlers::setupModifyUnderlayFile(std::string const& key)
  498 +{
  499 + // QXXXQ
  500 +}
  501 +
  502 +void
  503 +Handlers::setupModifyUnderlayPassword(std::string const& key)
  504 +{
  505 + // QXXXQ
  506 +}
  507 +
  508 +void
224 QPDFJob::initializeFromJson(std::string const& json) 509 QPDFJob::initializeFromJson(std::string const& json)
225 { 510 {
226 std::list<std::string> errors; 511 std::list<std::string> errors;
libqpdf/qpdf/auto_job_init.hh
@@ -10,16 +10,16 @@ auto p = [this](void (ArgParser::*f)(char *)) { @@ -10,16 +10,16 @@ auto p = [this](void (ArgParser::*f)(char *)) {
10 return QPDFArgParser::bindParam(f, this); 10 return QPDFArgParser::bindParam(f, this);
11 }; 11 };
12 12
13 -char const* yn_choices[] = {"y", "n", 0};  
14 -char const* password_mode_choices[] = {"bytes", "hex-bytes", "unicode", "auto", 0};  
15 -char const* stream_data_choices[] = {"compress", "preserve", "uncompress", 0};  
16 -char const* decode_level_choices[] = {"none", "generalized", "specialized", "all", 0};  
17 -char const* object_streams_choices[] = {"disable", "preserve", "generate", 0};  
18 -char const* remove_unref_choices[] = {"auto", "yes", "no", 0};  
19 -char const* flatten_choices[] = {"all", "print", "screen", 0};  
20 -char const* json_key_choices[] = {"acroform", "attachments", "encrypt", "objectinfo", "objects", "outlines", "pagelabels", "pages", 0};  
21 -char const* print128_choices[] = {"full", "low", "none", 0};  
22 -char const* modify128_choices[] = {"all", "annotate", "form", "assembly", "none", 0}; 13 +static char const* yn_choices[] = {"y", "n", 0};
  14 +static char const* password_mode_choices[] = {"bytes", "hex-bytes", "unicode", "auto", 0};
  15 +static char const* stream_data_choices[] = {"compress", "preserve", "uncompress", 0};
  16 +static char const* decode_level_choices[] = {"none", "generalized", "specialized", "all", 0};
  17 +static char const* object_streams_choices[] = {"disable", "preserve", "generate", 0};
  18 +static char const* remove_unref_choices[] = {"auto", "yes", "no", 0};
  19 +static char const* flatten_choices[] = {"all", "print", "screen", 0};
  20 +static char const* json_key_choices[] = {"acroform", "attachments", "encrypt", "objectinfo", "objects", "outlines", "pagelabels", "pages", 0};
  21 +static char const* print128_choices[] = {"full", "low", "none", 0};
  22 +static char const* modify128_choices[] = {"all", "annotate", "form", "assembly", "none", 0};
23 23
24 this->ap.selectHelpOptionTable(); 24 this->ap.selectHelpOptionTable();
25 this->ap.addBare("version", b(&ArgParser::argVersion)); 25 this->ap.addBare("version", b(&ArgParser::argVersion));
libqpdf/qpdf/auto_job_json_decl.hh
@@ -3,3 +3,53 @@ @@ -3,3 +3,53 @@
3 // Edits will be automatically overwritten if the build is 3 // Edits will be automatically overwritten if the build is
4 // run in maintainer mode. 4 // run in maintainer mode.
5 // 5 //
  6 +void beginInput();
  7 +void endInput();
  8 +void setupInputFileName(std::string const&);
  9 +void setupInputPassword(std::string const&);
  10 +void setupInputEmpty(std::string const&);
  11 +void beginOutput();
  12 +void endOutput();
  13 +void setupOutputFileName(std::string const&);
  14 +void setupOutputReplaceInput(std::string const&);
  15 +void beginOutputOptions();
  16 +void endOutputOptions();
  17 +void beginOutputOptionsEncrypt();
  18 +void endOutputOptionsEncrypt();
  19 +void setupOutputOptionsEncryptKeyLength(std::string const&);
  20 +void setupOutputOptionsEncryptUserPassword(std::string const&);
  21 +void setupOutputOptionsEncryptOwnerPassword(std::string const&);
  22 +void beginOutputOptionsEncrypt40Bit();
  23 +void endOutputOptionsEncrypt40Bit();
  24 +void beginOutputOptionsEncrypt128Bit();
  25 +void endOutputOptionsEncrypt128Bit();
  26 +void beginOutputOptionsEncrypt256Bit();
  27 +void endOutputOptionsEncrypt256Bit();
  28 +void beginOptions();
  29 +void endOptions();
  30 +void beginInspect();
  31 +void endInspect();
  32 +void beginTransform();
  33 +void endTransform();
  34 +void beginModify();
  35 +void endModify();
  36 +void beginModifyAddAttachment();
  37 +void endModifyAddAttachment();
  38 +void setupModifyAddAttachmentPath(std::string const&);
  39 +void beginModifyCopyAttachmentsFrom();
  40 +void endModifyCopyAttachmentsFrom();
  41 +void setupModifyCopyAttachmentsFromPath(std::string const&);
  42 +void setupModifyCopyAttachmentsFromPassword(std::string const&);
  43 +void beginModifyPages();
  44 +void endModifyPages();
  45 +void setupModifyPagesFile(std::string const&);
  46 +void setupModifyPagesPassword(std::string const&);
  47 +void setupModifyPagesRange(std::string const&);
  48 +void beginModifyOverlay();
  49 +void endModifyOverlay();
  50 +void setupModifyOverlayFile(std::string const&);
  51 +void setupModifyOverlayPassword(std::string const&);
  52 +void beginModifyUnderlay();
  53 +void endModifyUnderlay();
  54 +void setupModifyUnderlayFile(std::string const&);
  55 +void setupModifyUnderlayPassword(std::string const&);
libqpdf/qpdf/auto_job_json_init.hh
@@ -3,3 +3,174 @@ @@ -3,3 +3,174 @@
3 // Edits will be automatically overwritten if the build is 3 // Edits will be automatically overwritten if the build is
4 // run in maintainer mode. 4 // run in maintainer mode.
5 // 5 //
  6 +static char const* yn_choices[] = {"y", "n", 0};
  7 +static char const* password_mode_choices[] = {"bytes", "hex-bytes", "unicode", "auto", 0};
  8 +static char const* stream_data_choices[] = {"compress", "preserve", "uncompress", 0};
  9 +static char const* decode_level_choices[] = {"none", "generalized", "specialized", "all", 0};
  10 +static char const* object_streams_choices[] = {"disable", "preserve", "generate", 0};
  11 +static char const* remove_unref_choices[] = {"auto", "yes", "no", 0};
  12 +static char const* flatten_choices[] = {"all", "print", "screen", 0};
  13 +static char const* json_key_choices[] = {"acroform", "attachments", "encrypt", "objectinfo", "objects", "outlines", "pagelabels", "pages", 0};
  14 +static char const* print128_choices[] = {"full", "low", "none", 0};
  15 +static char const* modify128_choices[] = {"all", "annotate", "form", "assembly", "none", 0};
  16 +
  17 +beginDict("input", bindBare(&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 +endDict(); // .input
  23 +beginDict("output", bindBare(&Handlers::beginOutput), bindBare(&Handlers::endOutput)); // .output
  24 +doSetup("fileName", bindSetup(&Handlers::setupOutputFileName));
  25 +doSetup("replaceInput", bindSetup(&Handlers::setupOutputReplaceInput));
  26 +beginDict("options", bindBare(&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", bindBare(&Handlers::beginOutputOptionsEncrypt), bindBare(&Handlers::endOutputOptionsEncrypt)); // .output.options.encrypt
  49 +doSetup("keyLength", bindSetup(&Handlers::setupOutputOptionsEncryptKeyLength));
  50 +doSetup("userPassword", bindSetup(&Handlers::setupOutputOptionsEncryptUserPassword));
  51 +doSetup("ownerPassword", bindSetup(&Handlers::setupOutputOptionsEncryptOwnerPassword));
  52 +beginDict("40Bit", bindBare(&Handlers::beginOutputOptionsEncrypt40Bit), bindBare(&Handlers::endOutputOptionsEncrypt40Bit)); // .output.options.encrypt.40Bit
  53 +addChoices("annotate", yn_choices, [this](char const* p) { c_enc->annotate(p); });
  54 +addChoices("extract", yn_choices, [this](char const* p) { c_enc->extract(p); });
  55 +addChoices("modify", modify128_choices, [this](char const* p) { c_enc->modify(p); });
  56 +addChoices("print", print128_choices, [this](char const* p) { c_enc->print(p); });
  57 +endDict(); // .output.options.encrypt.40Bit
  58 +beginDict("128Bit", bindBare(&Handlers::beginOutputOptionsEncrypt128Bit), bindBare(&Handlers::endOutputOptionsEncrypt128Bit)); // .output.options.encrypt.128Bit
  59 +addChoices("accessibility", yn_choices, [this](char const* p) { c_enc->accessibility(p); });
  60 +addChoices("annotate", yn_choices, [this](char const* p) { c_enc->annotate(p); });
  61 +addChoices("assemble", yn_choices, [this](char const* p) { c_enc->assemble(p); });
  62 +addBare("cleartextMetadata", [this]() { c_enc->cleartextMetadata(); });
  63 +addChoices("extract", yn_choices, [this](char const* p) { c_enc->extract(p); });
  64 +addChoices("form", yn_choices, [this](char const* p) { c_enc->form(p); });
  65 +addChoices("modifyOther", yn_choices, [this](char const* p) { c_enc->modifyOther(p); });
  66 +addChoices("modify", modify128_choices, [this](char const* p) { c_enc->modify(p); });
  67 +addChoices("print", print128_choices, [this](char const* p) { c_enc->print(p); });
  68 +addBare("forceV4", [this]() { c_enc->forceV4(); });
  69 +addChoices("useAes", yn_choices, [this](char const* p) { c_enc->useAes(p); });
  70 +endDict(); // .output.options.encrypt.128Bit
  71 +beginDict("256Bit", bindBare(&Handlers::beginOutputOptionsEncrypt256Bit), bindBare(&Handlers::endOutputOptionsEncrypt256Bit)); // .output.options.encrypt.256Bit
  72 +addChoices("accessibility", yn_choices, [this](char const* p) { c_enc->accessibility(p); });
  73 +addChoices("annotate", yn_choices, [this](char const* p) { c_enc->annotate(p); });
  74 +addChoices("assemble", yn_choices, [this](char const* p) { c_enc->assemble(p); });
  75 +addBare("cleartextMetadata", [this]() { c_enc->cleartextMetadata(); });
  76 +addChoices("extract", yn_choices, [this](char const* p) { c_enc->extract(p); });
  77 +addChoices("form", yn_choices, [this](char const* p) { c_enc->form(p); });
  78 +addChoices("modifyOther", yn_choices, [this](char const* p) { c_enc->modifyOther(p); });
  79 +addChoices("modify", modify128_choices, [this](char const* p) { c_enc->modify(p); });
  80 +addChoices("print", print128_choices, [this](char const* p) { c_enc->print(p); });
  81 +addBare("allowInsecure", [this]() { c_enc->allowInsecure(); });
  82 +addBare("forceR5", [this]() { c_enc->forceR5(); });
  83 +endDict(); // .output.options.encrypt.256Bit
  84 +endDict(); // .output.options.encrypt
  85 +endDict(); // .output.options
  86 +endDict(); // .output
  87 +beginDict("options", bindBare(&Handlers::beginOptions), bindBare(&Handlers::endOptions)); // .options
  88 +addBare("allowWeakCrypto", [this]() { c_main->allowWeakCrypto(); });
  89 +addBare("deterministicId", [this]() { c_main->deterministicId(); });
  90 +addChoices("keepFilesOpen", yn_choices, [this](char const* p) { c_main->keepFilesOpen(p); });
  91 +addParameter("keepFilesOpenThreshold", [this](char const* p) { c_main->keepFilesOpenThreshold(p); });
  92 +addBare("noWarn", [this]() { c_main->noWarn(); });
  93 +addBare("verbose", [this]() { c_main->verbose(); });
  94 +addBare("warningExit0", [this]() { c_main->warningExit0(); });
  95 +addBare("ignoreXrefStreams", [this]() { c_main->ignoreXrefStreams(); });
  96 +addBare("passwordIsHexKey", [this]() { c_main->passwordIsHexKey(); });
  97 +addChoices("passwordMode", password_mode_choices, [this](char const* p) { c_main->passwordMode(p); });
  98 +addBare("suppressPasswordRecovery", [this]() { c_main->suppressPasswordRecovery(); });
  99 +addBare("suppressRecovery", [this]() { c_main->suppressRecovery(); });
  100 +endDict(); // .options
  101 +beginDict("inspect", bindBare(&Handlers::beginInspect), bindBare(&Handlers::endInspect)); // .inspect
  102 +addBare("check", [this]() { c_main->check(); });
  103 +addBare("checkLinearization", [this]() { c_main->checkLinearization(); });
  104 +addBare("filteredStreamData", [this]() { c_main->filteredStreamData(); });
  105 +addBare("isEncrypted", [this]() { c_main->isEncrypted(); });
  106 +addBare("rawStreamData", [this]() { c_main->rawStreamData(); });
  107 +addBare("requiresPassword", [this]() { c_main->requiresPassword(); });
  108 +addBare("showEncryption", [this]() { c_main->showEncryption(); });
  109 +addBare("showEncryptionKey", [this]() { c_main->showEncryptionKey(); });
  110 +addBare("showLinearization", [this]() { c_main->showLinearization(); });
  111 +addBare("showNpages", [this]() { c_main->showNpages(); });
  112 +addParameter("showObject", [this](char const* p) { c_main->showObject(p); });
  113 +addBare("showPages", [this]() { c_main->showPages(); });
  114 +addBare("showXref", [this]() { c_main->showXref(); });
  115 +addBare("withImages", [this]() { c_main->withImages(); });
  116 +addBare("listAttachments", [this]() { c_main->listAttachments(); });
  117 +addParameter("showAttachment", [this](char const* p) { c_main->showAttachment(p); });
  118 +addBare("json", [this]() { c_main->json(); });
  119 +addChoices("jsonKey", json_key_choices, [this](char const* p) { c_main->jsonKey(p); });
  120 +addParameter("jsonObject", [this](char const* p) { c_main->jsonObject(p); });
  121 +endDict(); // .inspect
  122 +beginDict("transform", bindBare(&Handlers::beginTransform), bindBare(&Handlers::endTransform)); // .transform
  123 +addBare("coalesceContents", [this]() { c_main->coalesceContents(); });
  124 +addParameter("compressionLevel", [this](char const* p) { c_main->compressionLevel(p); });
  125 +addBare("externalizeInlineImages", [this]() { c_main->externalizeInlineImages(); });
  126 +addParameter("iiMinBytes", [this](char const* p) { c_main->iiMinBytes(p); });
  127 +addChoices("removeUnreferencedResources", remove_unref_choices, [this](char const* p) { c_main->removeUnreferencedResources(p); });
  128 +endDict(); // .transform
  129 +beginDict("modify", bindBare(&Handlers::beginModify), bindBare(&Handlers::endModify)); // .modify
  130 +beginDict("addAttachment", bindBare(&Handlers::beginModifyAddAttachment), bindBare(&Handlers::endModifyAddAttachment)); // .modify.addAttachment
  131 +doSetup("path", bindSetup(&Handlers::setupModifyAddAttachmentPath));
  132 +addParameter("creationdate", [this](char const* p) { c_att->creationdate(p); });
  133 +addParameter("description", [this](char const* p) { c_att->description(p); });
  134 +addParameter("filename", [this](char const* p) { c_att->filename(p); });
  135 +addParameter("key", [this](char const* p) { c_att->key(p); });
  136 +addParameter("mimetype", [this](char const* p) { c_att->mimetype(p); });
  137 +addParameter("moddate", [this](char const* p) { c_att->moddate(p); });
  138 +addBare("replace", [this]() { c_att->replace(); });
  139 +endDict(); // .modify.addAttachment
  140 +addParameter("removeAttachment", [this](char const* p) { c_main->removeAttachment(p); });
  141 +beginDict("copyAttachmentsFrom", bindBare(&Handlers::beginModifyCopyAttachmentsFrom), bindBare(&Handlers::endModifyCopyAttachmentsFrom)); // .modify.copyAttachmentsFrom
  142 +doSetup("path", bindSetup(&Handlers::setupModifyCopyAttachmentsFromPath));
  143 +doSetup("password", bindSetup(&Handlers::setupModifyCopyAttachmentsFromPassword));
  144 +addParameter("prefix", [this](char const* p) { c_copy_att->prefix(p); });
  145 +endDict(); // .modify.copyAttachmentsFrom
  146 +addParameter("collate", [this](char const* p) { c_main->collate(p); });
  147 +addChoices("flattenAnnotations", flatten_choices, [this](char const* p) { c_main->flattenAnnotations(p); });
  148 +addBare("flattenRotation", [this]() { c_main->flattenRotation(); });
  149 +addBare("generateAppearances", [this]() { c_main->generateAppearances(); });
  150 +addBare("keepInlineImages", [this]() { c_main->keepInlineImages(); });
  151 +addParameter("oiMinArea", [this](char const* p) { c_main->oiMinArea(p); });
  152 +addParameter("oiMinHeight", [this](char const* p) { c_main->oiMinHeight(p); });
  153 +addParameter("oiMinWidth", [this](char const* p) { c_main->oiMinWidth(p); });
  154 +addBare("optimizeImages", [this]() { c_main->optimizeImages(); });
  155 +beginDict("pages", bindBare(&Handlers::beginModifyPages), bindBare(&Handlers::endModifyPages)); // .modify.pages
  156 +doSetup("file", bindSetup(&Handlers::setupModifyPagesFile));
  157 +doSetup("password", bindSetup(&Handlers::setupModifyPagesPassword));
  158 +doSetup("range", bindSetup(&Handlers::setupModifyPagesRange));
  159 +endDict(); // .modify.pages
  160 +addBare("removePageLabels", [this]() { c_main->removePageLabels(); });
  161 +addParameter("rotate", [this](char const* p) { c_main->rotate(p); });
  162 +beginDict("overlay", bindBare(&Handlers::beginModifyOverlay), bindBare(&Handlers::endModifyOverlay)); // .modify.overlay
  163 +doSetup("file", bindSetup(&Handlers::setupModifyOverlayFile));
  164 +doSetup("password", bindSetup(&Handlers::setupModifyOverlayPassword));
  165 +addParameter("from", [this](char const* p) { c_uo->from(p); });
  166 +addParameter("repeat", [this](char const* p) { c_uo->repeat(p); });
  167 +addParameter("to", [this](char const* p) { c_uo->to(p); });
  168 +endDict(); // .modify.overlay
  169 +beginDict("underlay", bindBare(&Handlers::beginModifyUnderlay), bindBare(&Handlers::endModifyUnderlay)); // .modify.underlay
  170 +doSetup("file", bindSetup(&Handlers::setupModifyUnderlayFile));
  171 +doSetup("password", bindSetup(&Handlers::setupModifyUnderlayPassword));
  172 +addParameter("from", [this](char const* p) { c_uo->from(p); });
  173 +addParameter("repeat", [this](char const* p) { c_uo->repeat(p); });
  174 +addParameter("to", [this](char const* p) { c_uo->to(p); });
  175 +endDict(); // .modify.underlay
  176 +endDict(); // .modify
libqpdf/qpdf/auto_job_schema.hh
1 static constexpr char const* JOB_SCHEMA_DATA = R"({ 1 static constexpr char const* JOB_SCHEMA_DATA = R"({
2 "input": { 2 "input": {
3 - "file": {  
4 - "name": "input filename",  
5 - "password": "specify password",  
6 - "passwordFile": "read password from a file"  
7 - },  
8 - "empty": "qxxxq empty" 3 + "fileName": "input filename",
  4 + "password": "specify password",
  5 + "passwordFile": "read password from a file",
  6 + "empty": "empty input file"
9 }, 7 },
10 "output": { 8 "output": {
11 - "file": {  
12 - "name": "output filename"  
13 - },  
14 - "replaceInput": "qxxxq replace input", 9 + "fileName": "output filename",
  10 + "replaceInput": "set to true to replace input",
15 "options": { 11 "options": {
16 "qdf": "enable viewing PDF code in a text editor", 12 "qdf": "enable viewing PDF code in a text editor",
17 "preserveUnreferenced": "preserve unreferenced objects", 13 "preserveUnreferenced": "preserve unreferenced objects",