95
96
static void developer_usage (void);
96
97
static void parse_options (int argc, char **argv);
99
dump_item (const struct spv_item *item)
99
static struct output_item *
100
annotate_member_names (const struct output_item *in)
101
if (show_member_names && (item->xml_member || item->bin_member))
103
const char *x = item->xml_member;
104
const char *b = item->bin_member;
106
/* The strings below are not marked for translation because they are only
107
useful to developers. */
109
? xasprintf ("%s and %s:", x, b)
110
: xasprintf ("%s:", x ? x : b));
111
output_item_submit (text_item_create_nocopy (TEXT_ITEM_TITLE, s,
112
xstrdup ("Member Names")));
115
switch (spv_item_get_type (item))
117
case SPV_ITEM_HEADING:
121
spv_text_submit (item);
125
pivot_table_submit (pivot_table_ref (spv_item_get_table (item)));
135
output_item_submit (image_item_create (cairo_surface_reference (
136
spv_item_get_image (item))));
102
if (in->type == OUTPUT_ITEM_GROUP)
104
struct output_item *out = group_item_clone_empty (in);
105
for (size_t i = 0; i < in->group.n_children; i++)
107
const struct output_item *item = in->group.children[i];
108
const char *members[4];
109
size_t n = spv_info_get_members (item->spv_info, members,
110
sizeof members / sizeof *members);
113
struct string s = DS_EMPTY_INITIALIZER;
114
ds_put_cstr (&s, members[0]);
115
for (size_t i = 1; i < n; i++)
116
ds_put_format (&s, " and %s", members[i]);
117
group_item_add_child (out, text_item_create_nocopy (
118
TEXT_ITEM_TITLE, ds_steal_cstr (&s),
119
xstrdup ("Member Names")));
122
group_item_add_child (out, output_item_ref (item));
127
return output_item_ref (in);
148
print_item_directory (const struct spv_item *item)
131
print_item_directory (const struct output_item *item, int level)
150
for (int i = 1; i < spv_item_get_level (item); i++)
133
for (int i = 0; i < level; i++)
153
enum spv_item_type type = spv_item_get_type (item);
154
printf ("- %s", spv_item_type_to_string (type));
136
printf ("- %s", output_item_type_to_string (item->type));
156
const char *label = spv_item_get_label (item);
138
const char *label = output_item_get_label (item);
158
140
printf (" \"%s\"", label);
160
if (type == SPV_ITEM_TABLE)
142
if (item->type == OUTPUT_ITEM_TABLE)
162
const struct pivot_table *table = spv_item_get_table (item);
163
char *title = pivot_value_to_string (table->title, table);
144
char *title = pivot_value_to_string (item->table->title, item->table);
164
145
if (!label || strcmp (title, label))
165
146
printf (" title \"%s\"", title);
169
const char *command_id = spv_item_get_command_id (item);
171
printf (" command \"%s\"", command_id);
173
const char *subtype = spv_item_get_subtype (item);
174
if (subtype && (!label || strcmp (label, subtype)))
175
printf (" subtype \"%s\"", subtype);
177
if (!spv_item_is_visible (item))
178
printf (" (hidden)");
150
if (item->command_name)
151
printf (" command \"%s\"", item->command_name);
153
char *subtype = output_item_get_subtype (item);
156
if (!label || strcmp (label, subtype))
157
printf (" subtype \"%s\"", subtype);
162
printf (" (%s)", item->type == OUTPUT_ITEM_GROUP ? "collapsed" : "hidden");
180
164
if (show_member_names)
182
const char *members[] = {
166
const char *members[4];
167
size_t n = spv_info_get_members (item->spv_info, members,
168
sizeof members / sizeof *members);
189
for (size_t i = 0; i < sizeof members / sizeof *members; i++)
191
printf (" %s %s", n++ == 0 ? "in" : "and", members[i]);
170
for (size_t i = 0; i < n; i++)
171
printf (" %s %s", i == 0 ? "in" : "and", members[i]);
175
if (item->type == OUTPUT_ITEM_GROUP)
176
for (size_t i = 0; i < item->group.n_children; i++)
177
print_item_directory (item->group.children[i], level + 1);
201
185
error (1, 0, "%s", err);
188
static struct output_item *
189
read_and_filter_spv (const char *name, struct page_setup **psp)
191
struct output_item *root;
192
char *err = spv_read (name, &root, psp);
194
error (1, 0, "%s", err);
195
return output_select (root, criteria, n_criteria);
205
199
run_directory (int argc UNUSED, char **argv)
207
struct spv_reader *spv;
208
char *err = spv_open (argv[1], &spv);
210
error (1, 0, "%s", err);
212
struct spv_item **items;
214
spv_select (spv, criteria, n_criteria, &items, &n_items);
215
for (size_t i = 0; i < n_items; i++)
216
print_item_directory (items[i]);
224
const struct spv_item **nodes;
228
const struct spv_item *stub[N_STUB];
232
swap_nodes (const struct spv_item **a, const struct spv_item **b)
234
const struct spv_item *tmp = *a;
240
get_path (const struct spv_item *item, struct item_path *path)
242
size_t allocated = 10;
243
path->nodes = path->stub;
248
if (path->n >= allocated)
250
if (path->nodes == path->stub)
251
path->nodes = xmemdup (path->stub, sizeof path->stub);
252
path->nodes = x2nrealloc (path->nodes, &allocated,
253
sizeof *path->nodes);
255
path->nodes[path->n++] = item;
259
for (size_t i = 0; i < path->n / 2; i++)
260
swap_nodes (&path->nodes[i], &path->nodes[path->n - i - 1]);
264
free_path (struct item_path *path)
266
if (path && path->nodes != path->stub)
271
dump_heading_transition (const struct spv_item *old,
272
const struct spv_item *new)
277
struct item_path old_path, new_path;
278
get_path (old, &old_path);
279
get_path (new, &new_path);
282
for (; common < old_path.n && common < new_path.n; common++)
283
if (old_path.nodes[common] != new_path.nodes[common])
286
for (size_t i = common; i < old_path.n; i++)
287
output_item_submit (group_close_item_create ());
288
for (size_t i = common; i < new_path.n; i++)
289
output_item_submit (group_open_item_create (
290
new_path.nodes[i]->command_id,
291
new_path.nodes[i]->label));
293
free_path (&old_path);
294
free_path (&new_path);
201
struct output_item *root = read_and_filter_spv (argv[1], NULL);
202
for (size_t i = 0; i < root->group.n_children; i++)
203
print_item_directory (root->group.children[i], 0);
204
output_item_unref (root);
208
set_table_look_recursively (struct output_item *item,
209
const struct pivot_table_look *look)
211
if (item->type == OUTPUT_ITEM_TABLE)
212
pivot_table_set_look (item->table, look);
213
else if (item->type == OUTPUT_ITEM_GROUP)
214
for (size_t i = 0; i < item->group.n_children; i++)
215
set_table_look_recursively (item->group.children[i], look);
298
219
run_convert (int argc UNUSED, char **argv)
300
struct spv_reader *spv;
301
char *err = spv_open (argv[1], &spv);
303
error (1, 0, "%s", err);
221
struct page_setup *ps;
222
struct output_item *root = read_and_filter_spv (argv[1], &ps);
306
spv_item_set_table_look (spv_get_root (spv), table_look);
224
set_table_look_recursively (root, table_look);
225
if (show_member_names)
227
struct output_item *new_root = annotate_member_names (root);
228
output_item_unref (root);
308
232
output_engine_push ();
309
233
output_set_filename (argv[1]);
452
343
return a < b ? -1 : a > b;
346
static char * WARN_UNUSED_RESULT
347
dump_raw (struct zip_reader *zr, const char *member_name)
351
char *error = zip_member_read_all (zr, member_name, &data, &size);
354
fwrite (data, size, 1, stdout);
361
dump_light_table (const struct output_item *item)
365
error = dump_raw (item->spv_info->zip_reader,
366
item->spv_info->bin_member);
369
struct spvlb_table *table;
370
error = spv_read_light_table (item->spv_info->zip_reader,
371
item->spv_info->bin_member, &table);
376
qsort (table->borders->borders, table->borders->n_borders,
377
sizeof *table->borders->borders, compare_borders);
378
qsort (table->cells->cells, table->cells->n_cells,
379
sizeof *table->cells->cells, compare_cells);
381
spvlb_print_table (item->spv_info->bin_member, 0, table);
382
spvlb_free_table (table);
387
msg (ME, "%s", error);
456
393
run_dump_light_table (int argc UNUSED, char **argv)
458
395
if (raw && isatty (STDOUT_FILENO))
459
396
error (1, 0, "not writing binary data to tty");
461
struct spv_reader *spv;
462
char *err = spv_open (argv[1], &spv);
464
error (1, 0, "%s", err);
466
struct spv_item **items;
468
spv_select (spv, criteria, n_criteria, &items, &n_items);
469
for (size_t i = 0; i < n_items; i++)
471
if (!spv_item_is_light_table (items[i]))
479
error = spv_item_get_raw_light_table (items[i], &data, &size);
482
fwrite (data, size, 1, stdout);
488
struct spvlb_table *table;
489
error = spv_item_get_light_table (items[i], &table);
494
qsort (table->borders->borders, table->borders->n_borders,
495
sizeof *table->borders->borders, compare_borders);
496
qsort (table->cells->cells, table->cells->n_cells,
497
sizeof *table->cells->cells, compare_cells);
499
spvlb_print_table (items[i]->bin_member, 0, table);
500
spvlb_free_table (table);
505
msg (ME, "%s", error);
398
struct output_item *root = read_and_filter_spv (argv[1], NULL);
399
struct output_iterator iter;
400
OUTPUT_ITEM_FOR_EACH (&iter, root)
401
if (iter.cur->type == OUTPUT_ITEM_TABLE && !iter.cur->spv_info->xml_member)
402
dump_light_table (iter.cur);
403
output_item_unref (root);
407
dump_legacy_data (const struct output_item *item)
411
error = dump_raw (item->spv_info->zip_reader,
412
item->spv_info->bin_member);
415
struct spv_data data;
416
error = spv_read_legacy_data (item->spv_info->zip_reader,
417
item->spv_info->bin_member, &data);
420
printf ("%s:\n", item->spv_info->bin_member);
421
spv_data_dump (&data, stdout);
422
spv_data_uninit (&data);
429
msg (ME, "%s", error);
516
435
run_dump_legacy_data (int argc UNUSED, char **argv)
518
struct spv_reader *spv;
519
char *err = spv_open (argv[1], &spv);
521
error (1, 0, "%s", err);
523
437
if (raw && isatty (STDOUT_FILENO))
524
438
error (1, 0, "not writing binary data to tty");
526
struct spv_item **items;
528
spv_select (spv, criteria, n_criteria, &items, &n_items);
529
for (size_t i = 0; i < n_items; i++)
530
if (spv_item_is_legacy_table (items[i]))
532
struct spv_data data;
538
error = spv_item_get_raw_legacy_data (items[i], &data, &size);
541
fwrite (data, size, 1, stdout);
547
error = spv_item_get_legacy_data (items[i], &data);
550
printf ("%s:\n", items[i]->bin_member);
551
spv_data_dump (&data, stdout);
552
spv_data_uninit (&data);
559
msg (ME, "%s", error);
440
struct output_item *root = read_and_filter_spv (argv[1], NULL);
441
struct output_iterator iter;
442
OUTPUT_ITEM_FOR_EACH (&iter, root)
443
if (iter.cur->type == OUTPUT_ITEM_TABLE
444
&& iter.cur->spv_info->xml_member
445
&& iter.cur->spv_info->bin_member)
446
dump_legacy_data (iter.cur);
447
output_item_unref (root);
568
450
/* This is really bogus.
556
dump_legacy_table (int argc, char **argv, const struct output_item *item)
559
char *error_s = spv_read_xml_member (item->spv_info->zip_reader,
560
item->spv_info->xml_member,
561
false, "visualization", &doc);
562
dump_xml (argc, argv, item->spv_info->xml_member, error_s, doc);
674
566
run_dump_legacy_table (int argc, char **argv)
676
struct spv_reader *spv;
677
char *err = spv_open (argv[1], &spv);
679
error (1, 0, "%s", err);
681
struct spv_item **items;
683
spv_select (spv, criteria, n_criteria, &items, &n_items);
684
for (size_t i = 0; i < n_items; i++)
685
if (spv_item_is_legacy_table (items[i]))
688
char *error_s = spv_item_get_legacy_table (items[i], &doc);
689
dump_xml (argc, argv, items[i]->xml_member, error_s, doc);
568
struct output_item *root = read_and_filter_spv (argv[1], NULL);
569
struct output_iterator iter;
570
OUTPUT_ITEM_FOR_EACH (&iter, root)
571
if (iter.cur->type == OUTPUT_ITEM_TABLE
572
&& iter.cur->spv_info->xml_member)
573
dump_legacy_table (argc, argv, iter.cur);
574
output_item_unref (root);
578
dump_structure (int argc, char **argv, const struct output_item *item)
581
char *error_s = spv_read_xml_member (item->spv_info->zip_reader,
582
item->spv_info->structure_member,
583
true, "heading", &doc);
584
dump_xml (argc, argv, item->spv_info->structure_member, error_s, doc);
697
588
run_dump_structure (int argc, char **argv)
699
struct spv_reader *spv;
700
char *err = spv_open (argv[1], &spv);
702
error (1, 0, "%s", err);
590
struct output_item *root = read_and_filter_spv (argv[1], NULL);
704
struct spv_item **items;
706
spv_select (spv, criteria, n_criteria, &items, &n_items);
707
592
const char *last_structure_member = NULL;
708
for (size_t i = 0; i < n_items; i++)
709
if (!last_structure_member || strcmp (items[i]->structure_member,
710
last_structure_member))
712
last_structure_member = items[i]->structure_member;
715
char *error_s = spv_item_get_structure (items[i], &doc);
716
dump_xml (argc, argv, items[i]->structure_member, error_s, doc);
593
struct output_iterator iter;
594
OUTPUT_ITEM_FOR_EACH (&iter, root)
596
const struct output_item *item = iter.cur;
597
if (item->spv_info->structure_member
598
&& (!last_structure_member
599
|| strcmp (item->spv_info->structure_member,
600
last_structure_member)))
602
last_structure_member = item->spv_info->structure_member;
603
dump_structure (argc, argv, item);
606
output_item_unref (root);
610
is_any_legacy (const struct output_item *item)
612
if (item->type == OUTPUT_ITEM_TABLE)
613
return item->spv_info->xml_member != NULL;
614
else if (item->type == OUTPUT_ITEM_GROUP)
615
for (size_t i = 0; i < item->group.n_children; i++)
616
if (is_any_legacy (item->group.children[i]))
724
623
run_is_legacy (int argc UNUSED, char **argv)
726
struct spv_reader *spv;
727
char *err = spv_open (argv[1], &spv);
729
error (1, 0, "%s", err);
731
bool is_legacy = false;
733
struct spv_item **items;
735
spv_select (spv, criteria, n_criteria, &items, &n_items);
736
for (size_t i = 0; i < n_items; i++)
737
if (spv_item_is_legacy_table (items[i]))
625
struct output_item *root = read_and_filter_spv (argv[1], NULL);
626
bool is_legacy = is_any_legacy (root);
627
output_item_unref (root);
746
629
exit (is_legacy ? EXIT_SUCCESS : EXIT_FAILURE);
687
struct encoded_strings
690
struct string_array strings;
693
struct encoded_strings_table
695
struct encoded_strings *es;
700
collect_strings (const struct output_item *item,
701
struct encoded_strings_table *t)
704
struct spvlb_table *table;
705
error = spv_read_light_table (item->spv_info->zip_reader,
706
item->spv_info->bin_member, &table);
709
msg (ME, "%s", error);
714
const char *table_encoding = spvlb_table_get_encoding (table);
716
for (j = 0; j < t->n; j++)
717
if (!strcmp (t->es[j].encoding, table_encoding))
721
if (t->n >= t->allocated)
722
t->es = x2nrealloc (t->es, &t->allocated, sizeof *t->es);
723
t->es[t->n++] = (struct encoded_strings) {
724
.encoding = xstrdup (table_encoding),
725
.strings = STRING_ARRAY_INITIALIZER,
728
collect_spvlb_strings (table, &t->es[j].strings);
805
732
run_strings (int argc UNUSED, char **argv)
807
struct spv_reader *spv;
808
char *err = spv_open (argv[1], &spv);
810
error (1, 0, "%s", err);
812
struct encoded_strings
815
struct string_array strings;
819
size_t allocated_es = 0;
821
struct spv_item **items;
823
spv_select (spv, criteria, n_criteria, &items, &n_items);
824
for (size_t i = 0; i < n_items; i++)
826
if (!spv_item_is_light_table (items[i]))
830
struct spvlb_table *table;
831
error = spv_item_get_light_table (items[i], &table);
834
msg (ME, "%s", error);
839
const char *table_encoding = spvlb_table_get_encoding (table);
841
for (j = 0; j < n_es; j++)
842
if (!strcmp (es[j].encoding, table_encoding))
846
if (n_es >= allocated_es)
847
es = x2nrealloc (es, &allocated_es, sizeof *es);
848
es[n_es++] = (struct encoded_strings) {
849
.encoding = xstrdup (table_encoding),
850
.strings = STRING_ARRAY_INITIALIZER,
853
collect_spvlb_strings (table, &es[j].strings);
857
for (size_t i = 0; i < n_es; i++)
859
dump_strings (es[i].encoding, &es[i].strings);
860
free (es[i].encoding);
861
string_array_destroy (&es[i].strings);
734
struct output_item *root = read_and_filter_spv (argv[1], NULL);
736
struct encoded_strings_table t = { .es = NULL };
737
struct output_iterator iter;
738
OUTPUT_ITEM_FOR_EACH (&iter, root)
740
const struct output_item *item = iter.cur;
741
if (item->type == OUTPUT_ITEM_TABLE
742
&& !item->spv_info->xml_member
743
&& item->spv_info->bin_member)
744
collect_strings (item, &t);
747
for (size_t i = 0; i < t.n; i++)
749
dump_strings (t.es[i].encoding, &t.es[i].strings);
750
free (t.es[i].encoding);
751
string_array_destroy (&t.es[i].strings);
755
output_item_unref (root);
992
883
for (char *token = strtok (arg, ","); token; token = strtok (NULL, ","))
994
885
if (!strcmp (arg, "all"))
995
classes = SPV_ALL_CLASSES;
886
classes = OUTPUT_ALL_CLASSES;
996
887
else if (!strcmp (arg, "help"))
998
889
puts (_("The following object classes are supported:"));
999
for (int class = 0; class < SPV_N_CLASSES; class++)
1000
printf ("- %s\n", spv_item_class_to_string (class));
890
for (int class = 0; class < OUTPUT_N_CLASSES; class++)
891
printf ("- %s\n", output_item_class_to_string (class));
1005
int class = spv_item_class_from_string (token);
1006
if (class == SPV_N_CLASSES)
1007
error (1, 0, _("%s: unknown object class (use --select=help "
896
int class = output_item_class_from_string (token);
897
if (class == OUTPUT_N_CLASSES)
898
error (1, 0, _("unknown object class \"%s\" (use --select=help "
1008
899
"for help)"), arg);
1009
900
classes |= 1u << class;
1013
struct spv_criteria *c = get_criteria ();
1014
c->classes = invert ? classes ^ SPV_ALL_CLASSES : classes;
904
struct output_criteria *c = get_criteria ();
905
c->classes = invert ? classes ^ OUTPUT_ALL_CLASSES : classes;
1017
static struct spv_criteria_match *
908
static struct output_criteria_match *
1018
909
get_criteria_match (const char **arg)
1020
struct spv_criteria *c = get_criteria ();
911
struct output_criteria *c = get_criteria ();
1021
912
if ((*arg)[0] == '^')
1031
922
parse_commands (const char *arg)
1033
struct spv_criteria_match *cm = get_criteria_match (&arg);
924
struct output_criteria_match *cm = get_criteria_match (&arg);
1034
925
string_array_parse (&cm->commands, ss_cstr (arg), ss_cstr (","));
1038
929
parse_subtypes (const char *arg)
1040
struct spv_criteria_match *cm = get_criteria_match (&arg);
931
struct output_criteria_match *cm = get_criteria_match (&arg);
1041
932
string_array_parse (&cm->subtypes, ss_cstr (arg), ss_cstr (","));
1045
936
parse_labels (const char *arg)
1047
struct spv_criteria_match *cm = get_criteria_match (&arg);
938
struct output_criteria_match *cm = get_criteria_match (&arg);
1048
939
string_array_parse (&cm->labels, ss_cstr (arg), ss_cstr (","));
1052
943
parse_instances (char *arg)
1054
struct spv_criteria *c = get_criteria ();
945
struct output_criteria *c = get_criteria ();
1055
946
size_t allocated_instances = c->n_instances;
1057
948
for (char *token = strtok (arg, ","); token; token = strtok (NULL, ","))