#!/usr/bin/perl -w # NAME: tidyxmlcfg.pl # AIM: Examine the xml config file use strict; use warnings; use File::Basename; # split path ($name,$dir,$ext) = fileparse($file [, qr/\.[^.]*/] ) use Cwd; my $os = $^O; my $perl_dir = '/home/geoff/bin'; my $PATH_SEP = '/'; my $temp_dir = '/tmp'; if ($os =~ /win/i) { $perl_dir = 'C:\GTools\perl'; $temp_dir = $perl_dir; $PATH_SEP = "\\"; } unshift(@INC, $perl_dir); require 'lib_utils.pl' or die "Unable to load 'lib_utils.pl' Check paths in \@INC...\n"; # log file stuff our ($LF); my $pgmname = $0; if ($pgmname =~ /(\\|\/)/) { my @tmpsp = split(/(\\|\/)/,$pgmname); $pgmname = $tmpsp[-1]; } my $outfile = $temp_dir.$PATH_SEP."temp.$pgmname.txt"; open_log($outfile); # user variables my $VERS = "0.0.5 2015-01-09"; my $load_log = 0; my $in_file = ''; my $verbosity = 0; my $out_file = ''; # ### DEBUG ### my $debug_on = 1; my $def_file = 'C:\Projects\qt\qt-gui\data\tidycfg.xml'; ### program variables my @warnings = (); my $cwd = cwd(); sub VERB1() { return $verbosity >= 1; } sub VERB2() { return $verbosity >= 2; } sub VERB5() { return $verbosity >= 5; } sub VERB9() { return $verbosity >= 9; } sub show_warnings($) { my ($val) = @_; if (@warnings) { prt( "\nGot ".scalar @warnings." WARNINGS...\n" ); foreach my $itm (@warnings) { prt("$itm\n"); } prt("\n"); } else { prt( "\nNo warnings issued.\n\n" ) if (VERB9()); } } sub pgm_exit($$) { my ($val,$msg) = @_; if (length($msg)) { $msg .= "\n" if (!($msg =~ /\n$/)); prt($msg); } show_warnings($val); close_log($outfile,$load_log); exit($val); } sub prtw($) { my ($tx) = shift; $tx =~ s/\n$//; prt("$tx\n"); push(@warnings,$tx); } my $cppstatic = "// static objects\n"; # 1. create tab class # class GeneralTab : public QWidget # { # Q_OBJECT # public: # GeneralTab(const QFileInfo &fileInfo, QWidget *parent = 0); #}; sub get_tab_class($) { my $name = shift; my $txt = <setChecked(true); sub get_bool_cb($$) { my ($label,$token) = @_; my $text = "$label (Boolean)"; my $txt = <setChecked(true); } EOF return $txt; } sub get_bool_cb3($$) { my ($label,$token) = @_; my $text = "$label (AutoBool)"; my $txt = <setTristate(true); i = getConfigABool(\"$label\"); if (i == 0) { $token->setChecked(false); // $token->setCheckState(Qt::Unchecked); // 0 } else if (i == 1) { $token->setChecked(true); // $token->setCheckState(Qt::Checked); // 2 } else { $token->setCheckState(Qt::PartiallyChecked); // 1 } EOF return $txt; } sub get_edit_int($$) { my ($label,$token) = @_; my $te = $token."Ed"; my $text = "$label (Integer)"; my $txt = "\n"; $txt .= " QLabel *$token = new QLabel(\"$text\");\n"; $txt .= " i = getConfigInt(\"$label\");\n"; $txt .= " s = QString::number(i);\n"; $txt .= " QLineEdit *$te = new QLineEdit(s);\n"; $txt .= " $te->setMaximumWidth(50);\n"; return $txt; } sub get_edit_stg($$) { my ($label,$token) = @_; my $te = $token."Ed"; my $text = "$label (String)"; my $txt = "\n"; $txt .= " QLabel *$token = new QLabel(\"$text\");\n"; $txt .= " s = getConfigStg(\"$label\");\n"; $txt .= " QLineEdit *$te = new QLineEdit(s);\n"; return $txt; } sub get_combo($$$$) { my ($label,$token,$exam,$typ) = @_; my @arr = split(",",$exam); my $cnt = scalar @arr; my $cb = $token."Comb"; my $lo = $token."Lay"; my $comb = "on_combo_change".$typ; if ($cnt == 0) { return " // combo failed $label, $token, $exam\n"; } my ($itm); my $txt = "\n"; $txt .= " QGroupBox *$token = new QGroupBox(\"$label\");\n"; $txt .= " QComboBox *$cb = new QComboBox();\n"; foreach $itm (@arr) { $itm = trim_all($itm); $txt .= " $cb->addItem(\"$itm\",\"$itm\");\n"; } if ($typ == 1) { $txt .= " s = getConfigEnc(\"$label\");\n"; } elsif ($typ == 2) { $txt .= " s = getConfigEnum(\"$label\");\n"; } elsif ($typ == 3) { $txt .= " s = getConfigPick(\"$label\");\n"; } $txt .= " i = $cb->findData(s);\n"; $txt .= " if (i != -1) {\n"; $txt .= " $cb->setCurrentIndex(i);\n"; $txt .= " }\n"; $txt .= " QVBoxLayout *$lo = new QVBoxLayout;\n"; $txt .= " $lo->addWidget($cb);\n"; $txt .= " $lo->addStretch(1);\n"; $txt .= " $token->setLayout($lo);\n"; $txt .= " // this FAILED ???\n"; $txt .= " // connect($cb, SIGNAL(currentIndexChanged(int)), this, SLOT($comb(\"$label\")));\n"; return $txt; } sub get_tab_name($) { my $name = shift; $name = uc(substr($name,0,1)).substr($name,1)."Tab"; return $name; } sub get_lo_name($) { my $name = shift; $name = uc(substr($name,0,1)).substr($name,1)."Layout"; return $name; } # QLabel *fileNameLabel = new QLabel(tr("File Name:")); # QLineEdit *fileNameEdit = new QLineEdit(fileInfo.fileName()); sub show_options($) { my ($ra) = @_; # \@options); my $len = scalar @{$ra}; my ($rh,$op,$val,$class,$type,$def,$name,$tt,$label,$token,$lon,$hcnt,$roa,$i,$exam,$curr); my @opts = qw( name type default example seealso description ); my %classes = (); $op = 'class'; foreach $rh (@{$ra}) { if (defined ${$rh}{$op}) { $val = ${$rh}{$op}; $classes{$val} = 1; } } my @arr = sort keys %classes; my $cnt = scalar @arr; prt("Have $len options, $cnt classes - ".join(" ",@arr)."\n"); my $cpp = "// Generated by $pgmname ".lu_get_YYYYMMDD_hhmmss_UTC(time())."\n"; my $chh = ''; my @checkboxes = (); foreach $class (@arr) { prt("\nOption class '$class'\n"); $name = get_tab_name($class); $lon = get_lo_name($class); $chh .= get_tab_class($name); $cpp .= get_imp_head($name); @checkboxes = (); # clear widget to add foreach $rh (@{$ra}) { $curr = ${$rh}{class}; $type = ${$rh}{type}; $def = ${$rh}{default}; $label = ${$rh}{name}; $tt = ${$rh}{description}; $exam = ${$rh}{example}; $token = $label; if ($curr ne $class) { # UGH - Want to switch some page classes if (($curr eq 'markup') && ($class eq 'encoding') && (($label eq 'doctype')||($label eq 'repeated-attributes')) ) { # add this markup to encoding page } elsif (($curr eq 'markup') && ($class eq 'misc') && ($label eq 'alt-text') ) { # add this markup to misc page } else { next; } } else { # $class and $curr are the SAME # have moved two to another page if (($curr eq 'markup') && (($label eq 'doctype')||($label eq 'repeated-attributes')|| ($label eq 'alt-text') ) ) { next; # these have been MOVED to 'encoding' or 'misc' # mainly due to 'markup' has too many options } } $token =~ s/\-/_/g; if ($type eq 'Boolean') { $cpp .= get_bool_cb($label,$token); push(@checkboxes,[$token,$type,$label]); # save to add to layout } elsif ($type eq 'Integer') { $cpp .= get_edit_int($label,$token); push(@checkboxes,[$token,$type,$label]); # save to add to layout push(@checkboxes,[$token.'Ed',$type,$label]); # save to add to layout } elsif ($type eq 'AutoBool') { $cpp .= get_bool_cb3($label,$token); push(@checkboxes,[$token,$type,$label]); # save to add to layout } elsif ($type eq 'String') { $cpp .= get_edit_stg($label,$token); push(@checkboxes,[$token,$type,$label]); # save to add to layout push(@checkboxes,[$token.'Ed',$type,$label]); # save to add to layout } elsif ($type eq 'Tag names') { $cpp .= get_edit_stg($label,$token); push(@checkboxes,[$token,$type,$label]); # save to add to layout push(@checkboxes,[$token.'Ed',$type,$label]); # save to add to layout } elsif ($type eq 'Encoding') { $cpp .= get_combo($label,$token,$exam,1); push(@checkboxes,[$token,$type,$label]); # save to add to layout } elsif ($type eq 'enum') { $cpp .= get_combo($label,$token,$exam,2); push(@checkboxes,[$token,$type,$label]); # save to add to layout } elsif ($type eq 'DocType') { $cpp .= get_combo($label,$token,$exam,3); push(@checkboxes,[$token,$type,$label]); # save to add to layout } else { prt("\n"); foreach $op (@opts) { if (defined ${$rh}{$op}) { $val = ${$rh}{$op}; prt("$op: $val\n"); } } } } $cnt = scalar @checkboxes; if ($class eq 'markup') { $hcnt = int($cnt / 2); my $n1 = $lon."1"; my $n2 = $lon."2"; $cpp .= "\n"; $cpp .= " QVBoxLayout *$n1 = new QVBoxLayout;\n"; for ($i = 0; $i < $hcnt; $i++) { $roa = $checkboxes[$i]; $token = ${$roa}[0]; $type = ${$roa}[1]; $label = ${$roa}[2]; $cpp .= " $n1->addWidget($token);\n"; } $cpp .= "\n"; $cpp .= " QVBoxLayout *$n2 = new QVBoxLayout;\n"; for (; $i < $cnt; $i++) { $roa = $checkboxes[$i]; $token = ${$roa}[0]; $type = ${$roa}[1]; $label = ${$roa}[2]; $cpp .= " $n2->addWidget($token);\n"; } $cpp .= "\n"; $cpp .= " QHBoxLayout *$lon = new QHBoxLayout;\n"; $cpp .= " $lon->addLayout($n1);\n"; $cpp .= " $lon->addLayout($n2);\n"; $cpp .= " setLayout($lon);\n"; } else { $cpp .= "\n"; $cpp .= " QVBoxLayout *$lon = new QVBoxLayout;\n"; for ($i = 0; $i < $cnt; $i++) { $roa = $checkboxes[$i]; $token = ${$roa}[0]; $type = ${$roa}[1]; $label = ${$roa}[2]; $cpp .= " $lon->addWidget($token);\n"; } $cpp .= " $lon->addStretch(1);\n"; $cpp .= " setLayout($lon);\n"; } $cpp .= "}\n\n"; } #prt($chh); prt($cpp); $load_log = 1; } sub process_in_file($) { my ($inf) = @_; if (! open INF, "<$inf") { pgm_exit(1,"ERROR: Unable to open file [$inf]\n"); } my @lines = ; close INF; my $lncnt = scalar @lines; prt("Processing $lncnt lines, from [$inf]...\n"); my ($line,$inc,$lnn,$len,$tag,$txt,$intag,$i,$ch,$cn,$i2,$inquot,$qc,$last); $lnn = 0; $tag = ''; $txt = ''; $intag = 0; $inquot = 0; my @tagstack = (); my $inconfig = 0; my $inopt = 0; my $inname = 0; my $intype = 0; my $indef = 0; my $inex = 0; my $indesc = 0; my $inseealso = 0; my $inem = 0; my $incode = 0; my $inanch = 0; my $href = ''; my %hash = (); # for each option my @options = (); # stack option hashes foreach $line (@lines) { chomp $line; $lnn++; $line = trim_all($line); $len = length($line); next if ($len == 0); for ($i = 0; $i < $len; $i++) { $i2 = $i + 1; $ch = substr($line,$i,1); if ($intag) { $tag .= $ch; if ($ch eq '>') { if (VERB5()) { prt($txt) if (length($txt)); prt($tag); } if ($tag =~ /^<\/(\w+)>/) { $inc = $1; # closing tag prt("\n") if (VERB5()); if (@tagstack) { $last = pop @tagstack; if ($last ne $inc) { prtw("WARNING: $lnn: Closing tag '$tag' NOT not last '$last' on stack\n"); } else { if ($last eq 'config') { # $inconfig = 0; } elsif ($last eq 'option') { #