7 my ($do_cfile,$do_hfile);
8 my ($do_hkcu_reg,$do_reg);
9 &GetOptions
("cfile" => \
$do_cfile,
10 "hfile" => \
$do_hfile,
11 "hkcu-reg" => \
$do_hkcu_reg,
14 # -----------------------------------------------------------------------------
16 my %typemap = ('b' => 'bool',
20 'as' => 'list:string');
25 for my $filename (@ARGV) {
26 my $parser = new XML
::Parser
('Style' => 'Tree');
27 my $tree = $parser->parsefile ($filename);
29 my $mode = $tree->[0];
31 if ($mode eq 'gconfschemafile') {
32 &walk_gconf_tree
([], [{},@
$tree]);
33 } elsif ($mode eq 'schemalist') {
34 &walk_gsetting_tree
([], [{},@
$tree]);
36 die "$0: Unknown type of xml [$mode].\n";
42 my ($parents,$contents) = @_;
44 if (ref ($contents) eq 'ARRAY') {
45 my @items = @
$contents;
46 my $attrs = shift @items;
49 my $tag = shift @items;
50 my $args = shift @items;
54 if (@
$parents > 2 && $parents->[-2] eq 'schema') {
55 my $key = $parents->[-1];
56 next if $key eq 'locale';
57 $schema->{$key} = $args;
60 $parents->[-3] eq 'schema' &&
61 $parents->[-2] eq 'locale') {
62 my $key = $parents->[-1];
63 next if $key ne 'default';
64 $schema->{$key} = $args;
67 $schema = {} if $tag eq 'schema';
68 if (@
$parents > 1 && $parents->[-1] eq 'schema') {
69 # This handles empty defaults.
72 &walk_gconf_tree
([@
$parents,$tag],$args);
73 push @schemas, $schema if $tag eq 'schema';
79 sub unquote_gschema_string
{
81 die "$0: invalid string value: $val\n" unless
83 substr($val,0,1) eq substr($val,-1,1) &&
85 $val = substr ($val, 1, length ($val) - 2);
89 sub unquote_gschema_string_list
{
91 return undef if $val eq '[]';
92 die "$0: invalid string value: $val\n" unless
94 substr($val,0,1) eq '[' &&
95 substr($val,-1,1) eq ']');
96 $val = substr ($val, 1, length ($val) - 2);
98 while ($val =~ s/^'([^']*)'// or $val =~ s/^"([^']*)"//) {
108 sub walk_gsetting_tree
{
109 my ($parents,$contents) = @_;
111 if (ref ($contents) eq 'ARRAY') {
112 my @items = @
$contents;
113 my $attrs = shift @items;
116 my $tag = shift @items;
117 my $args = shift @items;
121 if (@
$parents > 2 && $parents->[-2] eq 'key') {
122 my $key = $parents->[-1];
124 if ($key eq 'default' && $schema->{'type'} eq 'string') {
125 $val = &unquote_gschema_string
($val);
126 } elsif ($key eq 'default' &&
127 $schema->{'type'} eq 'list' &&
128 $schema->{'list_type'} eq 'string') {
129 $val = &unquote_gschema_string_list
($val);
131 $schema->{$key} = $val;
137 my $thisattrs = $args->[0];
139 $schema->{'applyto'} =
140 $attrs->{'path'} . $thisattrs->{'name'};
141 my $type = $typemap{$thisattrs->{'type'}};
142 if ($type =~ /^list:(.*)$/) {
143 $schema->{'type'} = 'list';
144 $schema->{'list_type'} = $1;
146 $schema->{'type'} = $type;
149 if (@
$parents > 1 && $parents->[-1] eq 'schema') {
150 # This handles empty defaults.
151 $schema->{$tag} = '';
153 &walk_gsetting_tree
([@
$parents,$tag],$args);
154 push @schemas, $schema if $tag eq 'key';
160 # -----------------------------------------------------------------------------
162 my %extra_attributes =
163 ('/org/gnome/gnumeric/core/gui/editing/enter_moves_dir' => {
164 'gtype' => 'GO_TYPE_DIRECTION',
165 'default' => 'GO_DIRECTION_DOWN', # Should match schema
168 '/org/gnome/gnumeric/printsetup/preferred-unit' => {
169 'gtype' => 'GTK_TYPE_UNIT',
170 'default' => 'GTK_UNIT_MM', # Should match schema
173 '/apps/gnome-settings/gnumeric/toolbar_style' => {
175 'gtype' => 'GTK_TYPE_TOOLBAR_STYLE',
176 'default' => 'GTK_TOOLBAR_ICONS', # Should match schema
179 '/org/gnome/gnumeric/core/gui/editing/recalclag' => {
184 '/org/gnome/gnumeric/core/gui/editing/autocomplete-min-chars' => {
189 '/org/gnome/gnumeric/core/gui/toolbars/format-position' => {
190 'gtype' => 'GTK_TYPE_POSITION',
195 '/org/gnome/gnumeric/core/gui/toolbars/object-position' => {
196 'gtype' => 'GTK_TYPE_POSITION',
201 '/org/gnome/gnumeric/core/gui/toolbars/standard-position' => {
202 'gtype' => 'GTK_TYPE_POSITION',
207 '/org/gnome/gnumeric/core/sort/dialog/max-initial-clauses' => {
212 '/org/gnome/gnumeric/core/workbook/n-cols' => {
213 'min' => 'GNM_MIN_COLS',
214 'max' => 'GNM_MAX_COLS',
217 '/org/gnome/gnumeric/core/workbook/n-rows' => {
218 'min' => 'GNM_MIN_ROWS',
219 'max' => 'GNM_MAX_ROWS',
222 '/org/gnome/gnumeric/core/workbook/n-sheet' => {
227 '/org/gnome/gnumeric/core/workbook/autosave_time' => {
229 'max' => '365 * 24 * 60 * 60',
232 '/org/gnome/gnumeric/core/xml/compression-level' => {
237 '/org/gnome/gnumeric/functionselector/num-of-recent' => {
242 '/org/gnome/gnumeric/printsetup/paper-orientation' => {
243 'min' => 'GTK_PAGE_ORIENTATION_PORTRAIT',
244 'max' => 'GTK_PAGE_ORIENTATION_REVERSE_LANDSCAPE',
247 '/org/gnome/gnumeric/printsetup/scale-height' => {
252 '/org/gnome/gnumeric/printsetup/scale-width' => {
257 '/org/gnome/gnumeric/undo/max_descriptor_width' => {
262 '/org/gnome/gnumeric/undo/maxnum' => {
267 '/org/gnome/gnumeric/undo/size' => {
272 '/org/gnome/gnumeric/core/defaultfont/size' => {
277 '/org/gnome/gnumeric/core/gui/screen/horizontaldpi' => {
282 '/org/gnome/gnumeric/core/gui/screen/verticaldpi' => {
287 '/org/gnome/gnumeric/core/gui/window/x' => {
292 '/org/gnome/gnumeric/core/gui/window/y' => {
297 '/org/gnome/gnumeric/core/gui/window/zoom' => {
302 '/org/gnome/gnumeric/printsetup/hf-font-size' => {
307 '/org/gnome/gnumeric/printsetup/margin-bottom' => {
312 '/org/gnome/gnumeric/printsetup/margin-gtk-bottom' => {
317 '/org/gnome/gnumeric/printsetup/margin-gtk-left' => {
322 '/org/gnome/gnumeric/printsetup/margin-gtk-right' => {
327 '/org/gnome/gnumeric/printsetup/margin-gtk-top' => {
332 '/org/gnome/gnumeric/printsetup/margin-top' => {
337 '/org/gnome/gnumeric/printsetup/scale-percentage-value' => {
342 '/org/gnome/gnumeric/searchreplace/scope' => {
347 '/org/gnome/gnumeric/searchreplace/error-behaviour' => {
352 '/org/gnome/gnumeric/searchreplace/regex' => {
357 '/org/gnome/gnumeric/stf/export/format' => {
358 'gtype' => 'GNM_STF_FORMAT_MODE_TYPE',
359 'default' => 'GNM_STF_FORMAT_AUTO', # Should match schema
362 '/org/gnome/gnumeric/stf/export/quoting' => {
363 'gtype' => 'GSF_OUTPUT_CSV_QUOTING_MODE_TYPE',
364 'default' => 'GSF_OUTPUT_CSV_QUOTING_MODE_AUTO', # Should match schema
369 foreach my $key (keys %extra_attributes) {
371 if ($newkey eq '/apps/gnome-settings/gnumeric/toolbar_style') {
372 $newkey = '/org/gnome/gnumeric/toolbar-style';
374 $newkey = lc $newkey;
377 $extra_attributes{$newkey} = $extra_attributes{$key};
380 sub apply_extra_attributes
{
381 foreach my $schema (@schemas) {
382 my $key = $schema->{'applyto'};
383 my $e = $extra_attributes{$key};
385 foreach my $k (keys %$e) {
386 $schema->{$k} = $e->{$k};
392 @schemas = sort { $a->{'applyto'} cmp $b->{'applyto'} } @schemas;
397 foreach my $schema (@schemas) {
398 $schema->{'i'} = $i++;
402 # -----------------------------------------------------------------------------
407 return "NULL" unless defined $s;
409 return '"' . join ('',
414 } (split (//, $s))) . '"';
419 &apply_extra_attributes
();
422 ('bool' => 'gboolean',
425 'string' => 'const char *',
426 'list:string' => 'GSList *',
427 'GO_TYPE_DIRECTION' => 'GODirection',
428 'GTK_TYPE_UNIT' => 'GtkUnit',
429 'GTK_TYPE_TOOLBAR_STYLE' => 'GtkToolbarStyle',
430 'GTK_TYPE_POSITION' => 'GtkPositionType',
431 'GNM_STF_FORMAT_MODE_TYPE' => 'GnmStfFormatMode',
432 'GSF_OUTPUT_CSV_QUOTING_MODE_TYPE' => 'GsfOutputCsvQuotingMode',
440 foreach my $schema (@schemas) {
441 my $i = $schema->{'i'};
442 my $key = $schema->{'applyto'};
443 my $type = $schema->{'type'};
444 $type .= ":" . $schema->{'list_type'} if $type eq 'list';
445 my $default = $schema->{'default'};
446 my $min = $schema->{'min'};
447 my $max = $schema->{'max'};
448 my $gtype = ($schema->{'gtype'} || '0');
450 my $ctype = $type_to_ctype{$gtype || $type};
451 my $ctypes = "$ctype "; $ctypes =~ s/\*\s/\*/;
454 $var =~ s{^/org/gnome/gnumeric/}{};
455 $var =~ s{^/apps/gnome-settings/gnumeric/}{};
456 $var =~ s{[^a-zA-Z0-9_]}{_}g;
458 my $watch_name = "watch_$var";
461 if ($key =~ s{/org/gnome/gnumeric/}{}) {
462 my $dir = $key; $dir =~ s{/[^/]+$}{};
465 $needs_conf = 0 if $schema->{'noconfnode'};
468 my $get_conf_code = "";
470 my $id = "gnm_conf_get_${var}_node";
472 $hfile .= "GOConfNode *$id (void);\n";
474 $get_conf_code .= "GOConfNode *\n";
475 $get_conf_code .= "$id (void)\n";
476 $get_conf_code .= "{\n";
477 $get_conf_code .= "\treturn get_watch_node (&$watch_name);\n";
478 $get_conf_code .= "}\n\n";
480 $hfile .= "${ctypes}gnm_conf_get_$var (void);\n";
481 $hfile .= "void gnm_conf_set_$var (${ctypes}x);\n\n";
483 my $get_head = "$ctype\ngnm_conf_get_$var (void)";
484 my $set_head = "void\ngnm_conf_set_$var (${ctypes}x)";
486 my $short_desc = $schema->{'_summary'};
487 my $long_desc = $schema->{'_description'};
489 if ($type eq 'bool') {
490 $default = uc $default;
492 $cfile .= "static struct cb_watch_bool $watch_name = {\n";
493 $cfile .= "\t0, \"$key\",\n";
494 $cfile .= "\t" . "e_c_string
($short_desc) . ",\n";
495 $cfile .= "\t" . "e_c_string
($long_desc) . ",\n";
496 $cfile .= "\t$default,\n";
499 $cfile .= "$get_head\n";
501 $cfile .= "\tif (!$watch_name.handler)\n";
502 $cfile .= "\t\twatch_bool (&$watch_name);\n";
503 $cfile .= "\treturn $watch_name.var;\n";
506 $cfile .= "$set_head\n";
508 $cfile .= "\tif (!$watch_name.handler)\n";
509 $cfile .= "\t\twatch_bool (&$watch_name);\n";
510 $cfile .= "\tset_bool (&$watch_name, x);\n";
512 } elsif ($type eq 'int' || $type eq 'float') {
513 my $ltype = $type_to_ctype{$type};
514 die "$0: No min for $key\n" unless defined $min;
515 die "$0: No max for $key\n" unless defined $max;
517 $cfile .= "static struct cb_watch_$ltype $watch_name = {\n";
518 $cfile .= "\t0, \"$key\",\n";
519 $cfile .= "\t" . "e_c_string
($short_desc) . ",\n";
520 $cfile .= "\t" . "e_c_string
($long_desc) . ",\n";
521 $cfile .= "\t$min, $max, $default,\n";
524 $cfile .= "$get_head\n";
526 $cfile .= "\tif (!$watch_name.handler)\n";
527 $cfile .= "\t\twatch_$ltype (&$watch_name);\n";
528 $cfile .= "\treturn $watch_name.var;\n";
532 $cfile .= "gnm_conf_set_$var ($ctype x)\n";
534 $cfile .= "\tif (!$watch_name.handler)\n";
535 $cfile .= "\t\twatch_$ltype (&$watch_name);\n";
536 $cfile .= "\tset_$ltype (&$watch_name, x);\n";
538 } elsif ($type eq 'string' && $gtype eq '0') {
539 $cfile .= "static struct cb_watch_string $watch_name = {\n";
540 $cfile .= "\t0, \"$key\",\n";
541 $cfile .= "\t" . "e_c_string
($short_desc) . ",\n";
542 $cfile .= "\t" . "e_c_string
($long_desc) . ",\n";
543 $cfile .= "\t" . "e_c_string
($default) . ",\n";
546 $cfile .= "$get_head\n";
548 $cfile .= "\tif (!$watch_name.handler)\n";
549 $cfile .= "\t\twatch_string (&$watch_name);\n";
550 $cfile .= "\treturn $watch_name.var;\n";
553 $cfile .= "$set_head\n";
555 $cfile .= "\tg_return_if_fail (x != NULL);\n";
556 $cfile .= "\tif (!$watch_name.handler)\n";
557 $cfile .= "\t\twatch_string (&$watch_name);\n";
558 $cfile .= "\tset_string (&$watch_name, x);\n";
560 } elsif ($type eq 'string' && $gtype ne '0') {
561 $cfile .= "static struct cb_watch_enum $watch_name = {\n";
562 $cfile .= "\t0, \"$key\",\n";
563 $cfile .= "\t" . "e_c_string
($short_desc) . ",\n";
564 $cfile .= "\t" . "e_c_string
($long_desc) . ",\n";
565 $cfile .= "\t$default,\n";
568 $cfile .= "$get_head\n";
570 $cfile .= "\tif (!$watch_name.handler)\n";
571 $cfile .= "\t\twatch_enum (&$watch_name, $gtype);\n";
572 $cfile .= "\treturn $watch_name.var;\n";
576 $cfile .= "gnm_conf_set_$var ($ctype x)\n";
578 $cfile .= "\tif (!$watch_name.handler)\n";
579 $cfile .= "\t\twatch_enum (&$watch_name, $gtype);\n";
580 $cfile .= "\tset_enum (&$watch_name, x);\n";
582 } elsif ($type eq 'list:string') {
583 $cfile .= "static struct cb_watch_string_list $watch_name = {\n";
584 $cfile .= "\t0, \"$key\",\n";
585 $cfile .= "\t" . "e_c_string
($short_desc) . ",\n";
586 $cfile .= "\t" . "e_c_string
($long_desc) . ",\n";
589 $cfile .= "/**\n * gnm_conf_get_$var:\n *\n";
590 $cfile .= " * Returns: (element-type char) (transfer none):\n **/\n";
591 $cfile .= "$get_head\n";
593 $cfile .= "\tif (!$watch_name.handler)\n";
594 $cfile .= "\t\twatch_string_list (&$watch_name);\n";
595 $cfile .= "\treturn $watch_name.var;\n";
598 $cfile .= "/**\n * gnm_conf_set_$var:\n";
599 $cfile .= " * \@x: (element-type char): list of strings\n *\n **/\n";
600 $cfile .= "$set_head\n";
602 $cfile .= "\tif (!$watch_name.handler)\n";
603 $cfile .= "\t\twatch_string_list (&$watch_name);\n";
604 $cfile .= "\tset_string_list (&$watch_name, x);\n";
607 die "$0: Unhandled type $type\n";
610 $cfile .= $get_conf_code;
613 for my $dir (sort keys %dirs) {
615 $var =~ s{[^a-zA-Z0-9_]}{_}g;
617 my $id = "gnm_conf_get_${var}_dir_node";
619 $hfile .= "GOConfNode *$id (void);\n";
621 $cfile .= "GOConfNode *\n";
622 $cfile .= "$id (void)\n";
624 $cfile .= "\treturn get_node (\"$dir\", NULL);\n";
628 $cfile =~ s/\n\n+$/\n/;
629 $hfile =~ s/\n\n+$/\n/;
631 print $hfile if $do_hfile;
632 print $cfile if $do_cfile;
635 # -----------------------------------------------------------------------------
640 # --------------------
641 # Bizarre ordering of schemas.
646 foreach my $schema (@schemas) {
647 my $key = $schema->{'applyto'};
648 my $dir = $key; $dir =~ s{/[^/]+$}{};
650 my $group = $dir_group{$dir};
651 if (!defined $group) {
652 $group = $dir_group{$dir} = $i++;
656 # Unshift to reverse the order within the group for no reason other
657 # than matching old code.
658 unshift @
{$groups[$group]}, $schema;
665 # --------------------
670 foreach my $schema (@schemas) {
671 my $key = $schema->{'applyto'};
672 my $type = $schema->{'type'};
673 $type .= ":" . $schema->{'list_type'} if $type eq 'list';
674 my $default = $schema->{'default'};
676 # Outdated; keys now start with /org/
677 # next unless $key =~ s{^/apps/}{};
679 next unless $key =~ s{^/org/gnome/}{};
682 my @items = split ('/', $key);
683 my $var = pop @items;
684 foreach my $item (@items) {
687 if (!exists $dirs{$wkey}) {
694 if ($type eq 'bool') {
695 printf "hex:0%d", ($default =~ /TRUE/i ?
1 : 0);
696 } elsif ($type eq 'int') {
697 printf "dword:%08x", $default;
698 } elsif ($type eq 'float') {
699 printf "\"%s\"", $default;
700 } elsif ($type eq 'string') {
701 print "e_c_string
($default);
702 } elsif ($type eq 'list:string') {
704 $default = "" unless defined $default;
705 if ($default =~ s{^\[(.*)\]$}{$1}) {
706 my $l = 7 + length ($var);
707 while ($default ne '') {
712 if ($default =~ m{^,}) {
715 $default = substr ($default, 1);
717 my $c = ord (substr ($default, 0, 1));
718 printf("%02x,00,", $c);
720 $default = substr ($default, 1);
726 die "$0: Unhandled type $type\n";
735 # -----------------------------------------------------------------------------
738 &create_hcfile
() if $do_hfile || $do_cfile;
739 &create_reg
("HKEY_USERS\\.DEFAULT\\Software") if $do_reg;
740 &create_reg
("HKEY_CURRENT_USER\\Software") if $do_hkcu_reg;