1 #!/usr/bin/perl -w 2 # 3 # $RCSfile: InfoPeriodicTableElements.pl,v $ 4 # $Date: 2015/02/28 20:46:20 $ 5 # $Revision: 1.28 $ 6 # 7 # Author: Manish Sud <msud@san.rr.com> 8 # 9 # Copyright (C) 2015 Manish Sud. All rights reserved. 10 # 11 # This file is part of MayaChemTools. 12 # 13 # MayaChemTools is free software; you can redistribute it and/or modify it under 14 # the terms of the GNU Lesser General Public License as published by the Free 15 # Software Foundation; either version 3 of the License, or (at your option) any 16 # later version. 17 # 18 # MayaChemTools is distributed in the hope that it will be useful, but without 19 # any warranty; without even the implied warranty of merchantability of fitness 20 # for a particular purpose. See the GNU Lesser General Public License for more 21 # details. 22 # 23 # You should have received a copy of the GNU Lesser General Public License 24 # along with MayaChemTools; if not, see <http://www.gnu.org/licenses/> or 25 # write to the Free Software Foundation Inc., 59 Temple Place, Suite 330, 26 # Boston, MA, 02111-1307, USA. 27 # 28 29 use strict; 30 use FindBin; use lib "$FindBin::Bin/../lib"; 31 use Getopt::Long; 32 use File::Basename; 33 use Text::ParseWords; 34 use Benchmark; 35 use FileUtil; 36 use TextUtil; 37 use PeriodicTable; 38 39 my($ScriptName, %Options, $StartTime, $EndTime, $TotalTime); 40 41 # Autoflush STDOUT 42 $| = 1; 43 44 # Starting message... 45 $ScriptName = basename($0); 46 print "\n$ScriptName: Starting...\n\n"; 47 $StartTime = new Benchmark; 48 49 # Get the options and setup script... 50 SetupScriptUsage(); 51 if ($Options{help}) { 52 die GetUsageFromPod("$FindBin::Bin/$ScriptName"); 53 } 54 55 print "Processing options...\n"; 56 my(%OptionsInfo); 57 ProcessOptions(); 58 59 ListElementProperties(); 60 print "\n$ScriptName:Done...\n\n"; 61 62 $EndTime = new Benchmark; 63 $TotalTime = timediff ($EndTime, $StartTime); 64 print "Total time: ", timestr($TotalTime), "\n"; 65 66 ############################################################################### 67 68 # List atomic properties for elements... 69 sub ListElementProperties { 70 my($ElementID, $ElementDataRef, $PropertyName, $PropertyValue, $PropertyUnits, $PropertyUnitsRef, @PropertyLabels, @PropertyValues); 71 72 print "Listing information for periodic table element(s)...\n"; 73 74 if ($OptionsInfo{FileOutput}) { 75 print "Generating file $OptionsInfo{OutFileName}...\n"; 76 open OUTFILE, ">$OptionsInfo{OutFileName}" or die "Couldn't open $OptionsInfo{OutFileName}: $!\n"; 77 } 78 79 # Setup property labels... 80 @PropertyLabels = (); 81 $PropertyUnitsRef = PeriodicTable::GetElementPropertiesNamesAndUnits(); 82 for $PropertyName (@{$OptionsInfo{SpecifiedProperies}}) { 83 $PropertyUnits = (exists $PropertyUnitsRef->{$PropertyName}) ? $PropertyUnitsRef->{$PropertyName} : ''; 84 if ($PropertyName =~ /^NaturalIsotopeData$/i) { 85 push @PropertyLabels, qw(MassNumber: RelativeAtomicMass: NaturalAbundance:); 86 } 87 else { 88 push @PropertyLabels, ($PropertyUnits ? "$PropertyName ($PropertyUnits):" : "$PropertyName:"); 89 } 90 } 91 92 if ($OptionsInfo{ElementRowsOutput}) { 93 ListHeaderRowData(\@PropertyLabels); 94 } 95 96 # Go over specified properties... 97 for $ElementID (@{$OptionsInfo{SpecifiedElementIDs}}) { 98 $ElementDataRef = PeriodicTable::GetElementPropertiesData($ElementID); 99 100 if (!$OptionsInfo{ElementRowsOutput}) { 101 if ($OptionsInfo{FileOutput}) { 102 print OUTFILE "\nListing atomic properties for element $ElementID...\n\n"; 103 } 104 else { 105 print "\nListing atomic properties for element $ElementID...\n\n"; 106 } 107 } 108 109 # Collect data.. 110 @PropertyValues = (); 111 for $PropertyName (@{$OptionsInfo{SpecifiedProperies}}) { 112 if ($PropertyName =~ /^NaturalIsotopeData$/i) { 113 push @PropertyValues, SetupIsotopeData($ElementID); 114 } 115 else { 116 $PropertyValue = $ElementDataRef->{$PropertyName}; 117 if (IsFloat($PropertyValue)) { 118 $PropertyValue = sprintf("%.$OptionsInfo{Precision}f", $PropertyValue) + 0; 119 } 120 push @PropertyValues, $PropertyValue; 121 } 122 } 123 # List data... 124 ListElementData(\@PropertyLabels, \@PropertyValues); 125 } 126 if ($OptionsInfo{FileOutput}) { 127 close OUTFILE; 128 } 129 print "\n"; 130 } 131 132 # List data for an element... 133 sub ListElementData { 134 my($DataLabelRef, $DataValueRef) = @_; 135 my($Index, $Line, $Value); 136 137 if ($OptionsInfo{ElementRowsOutput}) { 138 $Line = ''; 139 # Format data... 140 if ($OptionsInfo{OutQuote} || $Options{outdelim} !~ /^comma$/i) { 141 $Line = JoinWords($DataValueRef, $OptionsInfo{OutDelim}, $OptionsInfo{OutQuote}); 142 } 143 else { 144 # Always quote values containing commas... 145 $Line = ($DataValueRef->[0] =~ /\,/) ? qq("$DataValueRef->[0]") : $DataValueRef->[0]; 146 for $Index (1 .. $#{$DataValueRef} ) { 147 $Value = $DataValueRef->[$Index]; 148 if ($Value =~ /\,/) { 149 $Value = qq("$Value"); 150 } 151 $Line .= $OptionsInfo{OutDelim} . $Value; 152 } 153 } 154 if ($OptionsInfo{FileOutput}) { 155 print OUTFILE "$Line\n"; 156 } 157 else { 158 print "$Line\n"; 159 } 160 } 161 else { 162 # Format and list data... 163 $Line = ''; 164 for $Index (0 .. $#{$DataLabelRef} ) { 165 $Line = $DataLabelRef->[$Index] . ' ' . $DataValueRef->[$Index]; 166 if ($OptionsInfo{FileOutput}) { 167 print OUTFILE "$Line\n"; 168 } 169 else { 170 print "$Line\n"; 171 } 172 } 173 } 174 } 175 176 # List data for an element... 177 sub ListHeaderRowData { 178 my($DataLabelRef) = @_; 179 my($Line); 180 181 # Format data... 182 $Line = JoinWords($DataLabelRef, $OptionsInfo{OutDelim}, $OptionsInfo{OutQuote}); 183 $Line =~ s/\://g; 184 # List data... 185 if ($OptionsInfo{FileOutput}) { 186 print OUTFILE "$Line\n"; 187 } 188 else { 189 print "$Line\n"; 190 } 191 } 192 193 # Setup isotope data strings... 194 sub SetupIsotopeData { 195 my($ElementID) = @_; 196 my($MassNumber, $RelativeAtomicMass, $NaturalAbundance, $NaturalIsotopeDataRef, @MassNumbers, @RelativeAtomicMasses, @NaturalAbundances); 197 198 # Get natural isotope data: MassNumber, RelativeAtomicMass and NaturalAbundance 199 @MassNumbers = (); @RelativeAtomicMasses = (); @NaturalAbundances = (); 200 $NaturalIsotopeDataRef = PeriodicTable::GetElementNaturalIsotopesData($ElementID); 201 for $MassNumber (sort {$a <=> $b} keys %{$NaturalIsotopeDataRef}) { 202 $RelativeAtomicMass = $NaturalIsotopeDataRef->{$MassNumber}{RelativeAtomicMass}; 203 $NaturalAbundance = $NaturalIsotopeDataRef->{$MassNumber}{NaturalAbundance}; 204 push @MassNumbers, $MassNumber; 205 $RelativeAtomicMass = ($RelativeAtomicMass > 0) ? (sprintf("%.$OptionsInfo{Precision}f", $RelativeAtomicMass) + 0) : ''; 206 push @RelativeAtomicMasses, $RelativeAtomicMass; 207 $NaturalAbundance = ($NaturalAbundance > 0) ? (sprintf("%.$OptionsInfo{Precision}f", $NaturalAbundance) + 0) : ''; 208 push @NaturalAbundances, $NaturalAbundance; 209 } 210 $MassNumber = JoinWords(\@MassNumbers, ",", 0); 211 $RelativeAtomicMass = JoinWords(\@RelativeAtomicMasses, ",", 0); 212 $NaturalAbundance = JoinWords(\@NaturalAbundances, ",", 0); 213 return ($MassNumber, $RelativeAtomicMass, $NaturalAbundance); 214 } 215 216 # Get propery names from categories... 217 sub GetPropertyNamesFromCategories { 218 my($CategoryName) = @_; 219 my(@PropertyNames); 220 221 @PropertyNames = (); 222 if ($CategoryName =~ /^Basic$/i) { 223 @PropertyNames = ('AtomicNumber', 'ElementSymbol', 'ElementName', 'AtomicWeight', 'GroundStateConfiguration', 'GroupNumber', 'PeriodNumber', 'FirstIonizationEnergy'); 224 } elsif ($CategoryName =~ /^BasicAndNaturalIsotope$/i) { 225 # Natural isotope data includes: 'MassNumber', 'RelativeAtomicMass', 'NaturalAbundance' 226 @PropertyNames = ('AtomicNumber', 'ElementSymbol', 'ElementName', 'AtomicWeight', 'GroundStateConfiguration', 'GroupNumber', 'PeriodNumber', 'FirstIonizationEnergy', 'NaturalIsotopeData'); 227 } elsif ($CategoryName =~ /^NaturalIsotope$/i) { 228 @PropertyNames = ('AtomicNumber', 'ElementSymbol', 'ElementName', 'NaturalIsotopeData'); 229 } 230 231 return @PropertyNames; 232 } 233 234 # Process option values... 235 sub ProcessOptions { 236 %OptionsInfo = (); 237 238 $OptionsInfo{Mode} = $Options{mode}; 239 240 $OptionsInfo{OutDelim} = ($Options{outdelim} =~ /^tab$/i ) ? "\t" : (($Options{outdelim} =~ /^semicolon$/i) ? "\;" : "\,"); 241 $OptionsInfo{OutQuote} = ($Options{quote} =~ /^yes$/i) ? 1 : 0; 242 243 $OptionsInfo{Overwrite} = defined $Options{overwrite} ? $Options{overwrite} : undef; 244 $OptionsInfo{OutFileRoot} = defined $Options{root} ? $Options{root} : undef; 245 246 $OptionsInfo{Output} = $Options{output}; 247 $OptionsInfo{OutputStyle} = $Options{outputstyle}; 248 249 $OptionsInfo{ElementRowsOutput} = ($Options{outputstyle} =~ /^ElementRows$/i) ? 1 : 0; 250 $OptionsInfo{FileOutput} = ($Options{output} =~ /^File$/i) ? 1 : 0; 251 252 $OptionsInfo{Precision} = $Options{precision}; 253 254 my($ElementID, @ElementIDs, @GroupElements, @PeriodElements, %GroupNamesMap); 255 256 @{$OptionsInfo{SpecifiedElementIDs}} = (); 257 if (@ARGV >=1 && ($Options{mode} =~ /^All$/i) ) { 258 warn "Warning: Ignoring comman line element IDs: Not valid for All value of \"-m --mode\" option...\n"; 259 } 260 261 # Set up element IDs except for All mode... 262 @ElementIDs = (); 263 %GroupNamesMap = (); 264 265 if (@ARGV >=1 ) { 266 if ($Options{mode} !~ /^All$/i) { 267 push @ElementIDs, @ARGV; 268 } 269 } 270 else { 271 # Setup mode specified default values... 272 my($Nothing); 273 MODE: { 274 if ($Options{mode} =~ /^ElementID$/i) { push @ElementIDs, 'H'; last MODE; }; 275 if ($Options{mode} =~ /^AmericanGroupLabel$/i) { push @ElementIDs, 'IA'; last MODE; }; 276 if ($Options{mode} =~ /^EuropeanGroupLabel$/i) { push @ElementIDs, 'IA'; last MODE; }; 277 if ($Options{mode} =~ /^GroupNumber$/i) { push @ElementIDs, '1'; last MODE; }; 278 if ($Options{mode} =~ /^GroupName$/i) { push @ElementIDs, 'AlkaliMetals'; last MODE; }; 279 if ($Options{mode} =~ /^PeriodNumber$/i) { push @ElementIDs, '1'; last MODE; }; 280 $Nothing = 1; 281 } 282 } 283 if ($Options{mode} =~ /^GroupName$/i) { 284 # Map group names to what's stored in Perioidic table data file... 285 %GroupNamesMap = ('alkalimetals', 'Alkali metal', 'alkalineearthmetals', 'Alkaline earth metal', 'chalcogens', 'Chalcogen', 'coinagemetals', 'Coinage metal', 'halogens', 'Halogen', 'noblegases', 'Noble gas', 'pnictogens', 'Pnictogen', 'lanthanides', 'Lanthanoid', 'lanthanoids', 'Lanthanoid', 'actinides', 'Actinoid', 'actinoids', 'Actinoid' ); 286 } 287 288 # Generate list of elements... 289 if ($Options{mode} =~ /^All$/i) { 290 push @{$OptionsInfo{SpecifiedElementIDs}}, PeriodicTable::GetElements(); 291 } 292 else { 293 ELEMENTID: for $ElementID (@ElementIDs) { 294 if ($Options{mode} =~ /^ElementID$/i) { 295 if (PeriodicTable::IsElement($ElementID)) { 296 push @{$OptionsInfo{SpecifiedElementIDs}}, $ElementID; 297 } 298 else { 299 warn "Ignoring element ID, $ElementID, specified using command line parameter: Unknown element ID...\n"; 300 next ELEMENTID; 301 } 302 } 303 elsif ($Options{mode} =~ /^AmericanGroupLabel$/i) { 304 if (@GroupElements = PeriodicTable::GetElementsByAmericanStyleGroupLabel($ElementID)) { 305 push @{$OptionsInfo{SpecifiedElementIDs}}, @GroupElements; 306 } 307 else { 308 warn "Ignoring American style group label, $ElementID, specified using command line parameter: Unknown group label...\n"; 309 next ELEMENTID; 310 } 311 } 312 elsif ($Options{mode} =~ /^EuropeanGroupLabel$/i) { 313 if (@GroupElements = PeriodicTable::GetElementsByEuropeanStyleGroupLabel($ElementID)) { 314 push @{$OptionsInfo{SpecifiedElementIDs}}, @GroupElements; 315 } 316 else { 317 warn "Ignoring American style group label, $ElementID, specified using command line parameter: Unknown group label...\n"; 318 next ELEMENTID; 319 } 320 } 321 elsif ($Options{mode} =~ /^GroupNumber$/i) { 322 if (@GroupElements = PeriodicTable::GetElementsByGroupNumber($ElementID)) { 323 push @{$OptionsInfo{SpecifiedElementIDs}}, @GroupElements; 324 } 325 else { 326 warn "Ignoring group number, $ElementID, specified using command line parameter: Unknown group number...\n"; 327 next ELEMENTID; 328 } 329 } 330 elsif ($Options{mode} =~ /^GroupName$/i) { 331 if (exists $GroupNamesMap{lc($ElementID)}) { 332 @GroupElements = PeriodicTable::GetElementsByGroupName($GroupNamesMap{lc($ElementID)}); 333 push @{$OptionsInfo{SpecifiedElementIDs}}, @GroupElements; 334 } 335 else { 336 warn "Ignoring group name, $ElementID, specified using command line parameter: Unknown group name...\n"; 337 next ELEMENTID; 338 } 339 } 340 elsif ($Options{mode} =~ /^PeriodNumber$/i) { 341 if (@GroupElements = PeriodicTable::GetElementsByPeriodNumber($ElementID)) { 342 push @{$OptionsInfo{SpecifiedElementIDs}}, @GroupElements; 343 } 344 else { 345 warn "Ignoring period number, $ElementID, specified using command line parameter: Unknown period number...\n"; 346 next ELEMENTID; 347 } 348 } 349 } 350 } 351 SetupSpecifiedProperties(); 352 353 # Setup output file name... 354 $OptionsInfo{OutFileName} = ''; 355 if ($OptionsInfo{FileOutput}) { 356 my($OutFileRoot, $OutFileExt); 357 358 $OutFileRoot = ''; 359 $OutFileExt = "csv"; 360 if ($Options{outdelim} =~ /^tab$/i) { 361 $OutFileExt = "tsv"; 362 } 363 if ($Options{root}) { 364 my ($RootFileDir, $RootFileName, $RootFileExt) = ParseFileName($Options{root}); 365 if ($RootFileName && $RootFileExt) { 366 $OutFileRoot = $RootFileName; 367 } 368 else { 369 $OutFileRoot = $Options{root}; 370 } 371 } 372 else { 373 $OutFileRoot = 'PeriodicTableElementsInfo' . $Options{mode}; 374 } 375 $OptionsInfo{OutFileName} = $OutFileRoot . '.' . $OutFileExt; 376 if (!$Options{overwrite}) { 377 if (-e $OptionsInfo{OutFileName}) { 378 die "Error: Output file, $OptionsInfo{OutFileName}, already exists.\nUse \-o --overwrite\ option or specify a different name using \"-r --root\" option.\n"; 379 } 380 } 381 } 382 } 383 384 # Setup properties to list... 385 sub SetupSpecifiedProperties { 386 $OptionsInfo{Properties} = defined $Options{properties} ? $Options{properties} : undef; 387 388 $OptionsInfo{PropertiesMode} = $Options{propertiesmode}; 389 $OptionsInfo{PropertiesListing} = $Options{propertieslisting}; 390 391 # Make sure atomic appropriate properties/category names are specified... 392 @{$OptionsInfo{SpecifiedProperies}} = (); 393 if ($Options{properties} && ($Options{propertiesmode} =~ /^All$/i) ) { 394 warn "Warning: Ignoring values specifed by \"-p --properties\" option: Not valid for All value of \"--propertiesmode\" option...\n"; 395 } 396 if ($Options{propertiesmode} =~ /^All$/i) { 397 if ($Options{propertieslisting} =~ /^Alphabetical$/i) { 398 push @{$OptionsInfo{SpecifiedProperies}}, PeriodicTable::GetElementPropertiesNames('Alphabetical'); 399 } 400 else { 401 push @{$OptionsInfo{SpecifiedProperies}}, PeriodicTable::GetElementPropertiesNames(); 402 } 403 push @{$OptionsInfo{SpecifiedProperies}}, 'NaturalIsotopeData'; 404 } 405 else { 406 if ($Options{properties}) { 407 if ($Options{propertiesmode} =~ /^Categories$/i) { 408 # Check category name... 409 if ($Options{properties} !~ /^(Basic|BasicAndNaturalIsotope|NaturalIsotope)$/i) { 410 die "Error: The value specified, $Options{properties}, for option \"-p --properties\" in conjunction with \"Categories\" value for option \"--propertiesmode\" is not valid. Allowed values: Basic, BasicAndNaturalIsotope, NaturalIsotope\n"; 411 } 412 # Set propertynames... 413 push @{$OptionsInfo{SpecifiedProperies}}, GetPropertyNamesFromCategories($Options{properties}); 414 } 415 else { 416 # Check property names.. 417 my($Name, $PropertyName, @Names); 418 @Names = split /\,/, $Options{properties}; 419 NAME: for $Name (@Names) { 420 $PropertyName = RemoveLeadingAndTrailingWhiteSpaces($Name); 421 if ($PropertyName =~ /^NaturalIsotopeData$/i) { 422 push @{$OptionsInfo{SpecifiedProperies}}, $PropertyName; 423 next NAME; 424 } 425 if (PeriodicTable::IsElementProperty($PropertyName)) { 426 push @{$OptionsInfo{SpecifiedProperies}}, $PropertyName; 427 } 428 else { 429 warn "Warning: Ignoring value, $Name, specifed by \"-p --properties\" option: Unknown property name...\n"; 430 } 431 } 432 if ($Options{propertieslisting} =~ /^Alphabetical$/i) { 433 # AtomicNumber, ElementSymbol and ElementName are always listed first and 434 # NaturalIsotopeData in the end... 435 my($AtomicNumberPresent, $ElementSymbolPresent, $ElementNamePresent, $NaturalIsotopeDataPresent, @AlphabeticalProperties, %PropertiesMap); 436 %PropertiesMap = (); 437 @AlphabeticalProperties = (); 438 $AtomicNumberPresent = 0; $ElementSymbolPresent = 0; $ElementNamePresent = 0; $NaturalIsotopeDataPresent = 0; 439 NAME: for $Name (@{$OptionsInfo{SpecifiedProperies}}) { 440 if ($Name =~ /^AtomicNumber$/i) { 441 $AtomicNumberPresent = 1; 442 next NAME; 443 } 444 if ($Name =~ /^ElementSymbol$/i) { 445 $ElementSymbolPresent = 1; 446 next NAME; 447 } 448 if ($Name =~ /^ElementName$/i) { 449 $ElementNamePresent = 1; 450 next NAME; 451 } 452 if ($Name =~ /^NaturalIsotopeData$/i) { 453 $NaturalIsotopeDataPresent = 1; 454 next NAME; 455 } 456 $PropertiesMap{$Name} = $Name; 457 } 458 # Setup the alphabetical list... 459 if ($AtomicNumberPresent) { 460 push @AlphabeticalProperties, 'AtomicNumber'; 461 } 462 if ($ElementSymbolPresent) { 463 push @AlphabeticalProperties, 'ElementSymbol'; 464 } 465 if ($ElementNamePresent) { 466 push @AlphabeticalProperties, 'ElementName'; 467 } 468 for $Name (sort keys %PropertiesMap) { 469 push @AlphabeticalProperties, $Name; 470 } 471 if ($NaturalIsotopeDataPresent) { 472 push @AlphabeticalProperties, 'NaturalIsotopeData'; 473 } 474 @{$OptionsInfo{SpecifiedProperies}} = (); 475 push @{$OptionsInfo{SpecifiedProperies}}, @AlphabeticalProperties; 476 } 477 } 478 } 479 else { 480 # Set default value... 481 push @{$OptionsInfo{SpecifiedProperies}}, GetPropertyNamesFromCategories('Basic'); 482 } 483 } 484 } 485 486 # Setup script usage and retrieve command line arguments specified using various options... 487 sub SetupScriptUsage { 488 489 # Retrieve all the options... 490 %Options = (); 491 $Options{mode} = "ElementID"; 492 $Options{outdelim} = "comma"; 493 $Options{output} = "STDOUT"; 494 $Options{outputstyle} = "ElementBlock"; 495 $Options{precision} = 4; 496 $Options{propertiesmode} = "Categories"; 497 $Options{propertieslisting} = "ByGroup"; 498 $Options{quote} = "yes"; 499 500 if (!GetOptions(\%Options, "help|h", "mode|m=s", "outdelim=s", "output=s", "outputstyle=s", "overwrite|o", "precision=i", "properties|p=s", "propertieslisting=s", "propertiesmode=s", "quote|q=s", "root|r=s", "workingdir|w=s")) { 501 die "\nTo get a list of valid options and their values, use \"$ScriptName -h\" or\n\"perl -S $ScriptName -h\" command and try again...\n"; 502 } 503 if ($Options{workingdir}) { 504 if (! -d $Options{workingdir}) { 505 die "Error: The value specified, $Options{workingdir}, for option \"-w --workingdir\" is not a directory name.\n"; 506 } 507 chdir $Options{workingdir} or die "Error: Couldn't chdir $Options{workingdir}: $! \n"; 508 } 509 if ($Options{mode} !~ /^(ElementID|AmericanGroupLabel|EuropeanGroupLabel|GroupNumber|GroupName|PeriodNumber|All)$/i) { 510 die "Error: The value specified, $Options{mode}, for option \"-m --mode\" is not valid. Allowed values: ElementID, AmericanGroupLabel, EuropeanGroupLabel, GroupNumber, GroupName, PeriodNumber, or All\n"; 511 } 512 if ($Options{outdelim} !~ /^(comma|semicolon|tab)$/i) { 513 die "Error: The value specified, $Options{outdelim}, for option \"--outdelim\" is not valid. Allowed values: comma, tab, or semicolon\n"; 514 } 515 if ($Options{output} !~ /^(STDOUT|File)$/i) { 516 die "Error: The value specified, $Options{output}, for option \"--output\" is not valid. Allowed values: STDOUT or File\n"; 517 } 518 if ($Options{outputstyle} !~ /^(ElementBlock|ElementRows)$/i) { 519 die "Error: The value specified, $Options{outputstyle}, for option \"--outputstyle\" is not valid. Allowed values: ElementBlock or ElementRows\n"; 520 } 521 if (!IsPositiveInteger($Options{precision})) { 522 die "Error: The value specified, $Options{precision}, for option \"-p --precision\" is not valid. Allowed values: > 0 \n"; 523 } 524 if ($Options{propertiesmode} !~ /^(Categories|Names|All)$/i) { 525 die "Error: The value specified, $Options{propertiesmode}, for option \"--propertiesmode\" is not valid. Allowed values: Categories, Names, or All\n"; 526 } 527 if ($Options{propertieslisting} !~ /^(ByGroup|Alphabetical)$/i) { 528 die "Error: The value specified, $Options{propertieslisting}, for option \"--propertieslisting\" is not valid. Allowed values: ByGroup, or Alphabetical\n"; 529 } 530 if ($Options{quote} !~ /^(yes|no)$/i) { 531 die "Error: The value specified, $Options{quote}, for option \"-q --quote\" is not valid. Allowed values: yes or no\n"; 532 } 533 } 534