public static function is_version($string)
 {
     // Only numeric or decimal, and at least a decimal (not int)
     return pts_strings::string_only_contains($string, pts_strings::CHAR_NUMERIC | pts_strings::CHAR_DECIMAL) && pts_strings::string_contains($string, pts_strings::CHAR_DECIMAL);
 }
 public function is_results_tracker()
 {
     // If there are more than five results and the only changes in the system identifier names are numeric changes, assume it's a tracker
     // i.e. different dates or different versions of a package being tested
     if ($this->is_tracker === -1) {
         $identifiers = $this->get_system_identifiers();
         if (isset($identifiers[5])) {
             // dirty SHA1 hash check
             $is_sha1_hash = strlen($identifiers[0]) == 40 && strpos($identifiers[0], ' ') === false;
             $has_sha1_shorthash = false;
             foreach ($identifiers as $i => &$identifier) {
                 $has_sha1_shorthash = ($i == 0 || $has_sha1_shorthash) && isset($identifier[7]) && pts_strings::string_only_contains(substr($identifier, -8), pts_strings::CHAR_NUMERIC | pts_strings::CHAR_LETTER) && strpos($identifier, ' ') === false;
                 $identifier = pts_strings::remove_from_string($identifier, pts_strings::CHAR_NUMERIC | pts_strings::CHAR_DASH | pts_strings::CHAR_DECIMAL);
             }
             $this->is_tracker = count(array_unique($identifiers)) <= 1 || $is_sha1_hash || $has_sha1_shorthash;
             if ($this->is_tracker) {
                 $hw = $this->get_system_hardware();
                 if (isset($hw[1]) && count($hw) == count(array_unique($hw))) {
                     // it can't be a results tracker if the hardware is always different
                     $this->is_tracker = false;
                 }
             }
             if ($this->is_tracker == false) {
                 // See if only numbers are changing between runs
                 foreach ($identifiers as $i => &$identifier) {
                     if (($x = strpos($identifier, ': ')) !== false) {
                         $identifier = substr($identifier, $x + 2);
                     }
                     if ($i > 0 && pts_strings::remove_from_string($identifier, pts_strings::CHAR_NUMERIC | pts_strings::CHAR_DECIMAL) != pts_strings::remove_from_string($identifiers[$i - 1], pts_strings::CHAR_NUMERIC | pts_strings::CHAR_DECIMAL)) {
                         return false;
                     }
                 }
                 $this->is_tracker = true;
             }
         } else {
             // Definitely not a tracker as not over 5 results
             $this->is_tracker = false;
         }
     }
     return $this->is_tracker;
 }
 public static function motherboard_string()
 {
     // Returns the motherboard / system model name or number
     $info = null;
     if (phodevi::is_macosx()) {
         $info = phodevi_osx_parser::read_osx_system_profiler('SPHardwareDataType', 'ModelName');
     } else {
         if (phodevi::is_solaris()) {
             $manufacturer = phodevi_solaris_parser::read_sun_ddu_dmi_info(array('MotherBoardInformation,Manufacturer', 'SystemInformation,Manufacturer'));
             $product = phodevi_solaris_parser::read_sun_ddu_dmi_info(array('MotherBoardInformation,Product', 'SystemInformation,Product', 'SystemInformation,Model'));
             if (count($manufacturer) == 1 && count($product) == 1) {
                 $info = $manufacturer[0] . ' ' . $product[0];
             }
         } else {
             if (phodevi::is_bsd()) {
                 $vendor = phodevi_bsd_parser::read_kenv('smbios.system.maker');
                 $product = phodevi_bsd_parser::read_kenv('smbios.system.product');
                 $version = phodevi_bsd_parser::read_kenv('smbios.system.version');
                 // for at least Lenovo ThinkPads this is where it displays ThinkPad model
                 if ($vendor != null && ($product != null || $version != null)) {
                     $info = $vendor . ' ' . $product . ' ' . $version;
                 } else {
                     if (($vendor = phodevi_bsd_parser::read_sysctl('hw.vendor')) != false && ($version = phodevi_bsd_parser::read_sysctl(array('hw.version', 'hw.product'))) != false) {
                         $info = trim($vendor . ' ' . $version);
                     } else {
                         if (($acpi = phodevi_bsd_parser::read_sysctl('dev.acpi.0.%desc')) != false) {
                             $info = trim($acpi);
                         }
                     }
                 }
             } else {
                 if (phodevi::is_linux()) {
                     $vendor = phodevi_linux_parser::read_sys_dmi(array('board_vendor', 'sys_vendor'));
                     $name = phodevi_linux_parser::read_sys_dmi(array('board_name', 'product_name'));
                     $version = phodevi_linux_parser::read_sys_dmi(array('board_version', 'product_version'));
                     if ($vendor != false && $name != false) {
                         $info = strpos($name . ' ', $vendor . ' ') === false ? $vendor . ' ' : null;
                         $info .= $name;
                         if ($version != false && strpos($info, $version) === false && pts_strings::string_only_contains($version, pts_strings::CHAR_NUMERIC | pts_strings::CHAR_DECIMAL)) {
                             $info .= (substr($version, 0, 1) == 'v' ? ' ' : ' v') . $version;
                         }
                     }
                     if (empty($info)) {
                         if ($info == null) {
                             $hw_string = phodevi_linux_parser::read_cpuinfo('Hardware');
                             if (count($hw_string) == 1) {
                                 $info = $hw_string[0];
                             }
                         }
                         $bios_vendor = phodevi_linux_parser::read_sys_dmi('bios_vendor');
                         $bios_version = phodevi_linux_parser::read_sys_dmi('bios_version');
                         if ($bios_vendor != null) {
                             $info = $bios_vendor . ' ' . $bios_version;
                         }
                         if ($info == null) {
                             $hw_string = phodevi_linux_parser::read_cpuinfo('machine');
                             if (count($hw_string) == 1) {
                                 $info = $hw_string[0];
                             }
                         }
                     }
                     if (empty($info)) {
                         $info = phodevi_linux_parser::read_sys_dmi('product_name');
                     }
                     if (empty($info) && is_file('/sys/bus/soc/devices/soc0/machine')) {
                         $info = pts_file_io::file_get_contents('/sys/bus/soc/devices/soc0/machine');
                     }
                     if (empty($info)) {
                         // Works on the MIPS Creator CI20
                         $hardware = phodevi_linux_parser::read_cpuinfo('Hardware');
                         if (!empty($hardware)) {
                             $info = array_pop($hardware);
                         }
                     }
                 } else {
                     if (phodevi::is_windows()) {
                         $info = phodevi_windows_parser::read_cpuz('Mainboard Model', null);
                     }
                 }
             }
         }
     }
     if ((strpos($info, 'Mac ') !== false || strpos($info, 'MacBook') !== false) && strpos($info, 'Apple') === false) {
         $info = 'Apple ' . $info;
     }
     // ensure words aren't repeated (e.g. VMware VMware Virtual and MSI MSI X58M (MS-7593))
     $info = implode(' ', array_unique(explode(' ', $info)));
     return $info;
 }
 public static function sw_filesystem()
 {
     // Determine file-system type
     $fs = null;
     if (phodevi::is_macosx()) {
         $fs = phodevi_osx_parser::read_osx_system_profiler('SPSerialATADataType', 'FileSystem');
         if ($fs == null && pts_client::executable_in_path('mount')) {
             $mount = shell_exec('mount 2>&1');
             if (stripos($mount, ' on / (hfs, local, journaled)') !== false) {
                 $fs = 'Journaled HFS+';
             } else {
                 if (stripos($mount, ' on / (hfs') !== false) {
                     $fs = 'HFS+';
                 }
             }
         }
     } else {
         if (phodevi::is_bsd()) {
             if (pts_client::executable_in_path('mount')) {
                 $mount = shell_exec('mount 2>&1');
                 if (($start = strpos($mount, 'on / (')) != false) {
                     // FreeBSD, DragonflyBSD mount formatting
                     /*
                     -bash-4.0$ mount
                     ROOT on / (hammer, local)
                     /dev/da0s1a on /boot (ufs, local)
                     /pfs/@@-1:00001 on /var (null, local)
                     /pfs/@@-1:00002 on /tmp (null, local)
                     /pfs/@@-1:00003 on /usr (null, local)
                     /pfs/@@-1:00004 on /home (null, local)
                     /pfs/@@-1:00005 on /usr/obj (null, local)
                     /pfs/@@-1:00006 on /var/crash (null, local)
                     /pfs/@@-1:00007 on /var/tmp (null, local)
                     procfs on /proc (procfs, local)
                     */
                     // TODO: improve this in case there are other partitions, etc
                     $fs = substr($mount, $start + 6);
                     $fs = substr($fs, 0, strpos($fs, ','));
                 } else {
                     if (($start = strpos($mount, 'on / type')) != false) {
                         // OpenBSD 5.0 formatting is slightly different from above FreeBSD example
                         // TODO: improve this in case there are other partitions, etc
                         $fs = substr($mount, $start + 10);
                         $fs = substr($fs, 0, strpos($fs, ' '));
                     }
                 }
             }
         } else {
             if (phodevi::is_hurd()) {
                 // Very rudimentary Hurd filesystem detection support but works for at least a clean Debian GNU/Hurd EXT2 install
                 if (pts_client::executable_in_path('mount')) {
                     $mount = shell_exec('mount 2>&1');
                     if (($start = strpos($mount, 'on / type')) != false) {
                         $fs = substr($mount, $start + 10);
                         $fs = substr($fs, 0, strpos($fs, ' '));
                         if (substr($fs, -2) == 'fs') {
                             $fs = substr($fs, 0, -2);
                         }
                     }
                 }
             } else {
                 if (phodevi::is_linux() || phodevi::is_solaris()) {
                     $fs = trim(shell_exec('stat ' . pts_client::test_install_root_path() . ' -L -f -c %T 2> /dev/null'));
                     switch ($fs) {
                         case 'ext2/ext3':
                             if (isset(phodevi::$vfs->mounts)) {
                                 $fstab = phodevi::$vfs->mounts;
                                 $fstab = str_replace('/boot ', 'IGNORE', $fstab);
                                 $using_ext2 = strpos($fstab, ' ext2') !== false;
                                 $using_ext3 = strpos($fstab, ' ext3') !== false;
                                 $using_ext4 = strpos($fstab, ' ext4') !== false;
                                 if (!$using_ext2 && !$using_ext3 && $using_ext4) {
                                     $fs = 'ext4';
                                 } else {
                                     if (!$using_ext2 && !$using_ext4 && $using_ext3) {
                                         $fs = 'ext3';
                                     } else {
                                         if (!$using_ext3 && !$using_ext4 && $using_ext2) {
                                             $fs = 'ext2';
                                         } else {
                                             if (is_dir('/proc/fs/ext4/')) {
                                                 $fs = 'ext4';
                                             } else {
                                                 if (is_dir('/proc/fs/ext3/')) {
                                                     $fs = 'ext3';
                                                 }
                                             }
                                         }
                                     }
                                 }
                             }
                             break;
                         case 'Case-sensitive Journaled HFS+':
                             $fs = 'HFS+';
                             break;
                         case 'MS-DOS FAT32':
                             $fs = 'FAT32';
                             break;
                         case 'UFSD_NTFS_COMPR':
                             $fs = 'NTFS';
                             break;
                         case 'ecryptfs':
                             if (isset(phodevi::$vfs->mounts)) {
                                 // An easy attempt to determine what file-system is underneath ecryptfs if being compared
                                 // For now just attempt to figure out the root file-system.
                                 if (($s = strrpos(phodevi::$vfs->mounts, ' / ')) !== false) {
                                     $s = substr(phodevi::$vfs->mounts, $s + 3);
                                     $s = substr($s, 0, strpos($s, ' '));
                                     if ($s != null && !isset($s[18]) && $s != 'rootfs' && pts_strings::string_only_contains($s, pts_strings::CHAR_LETTER | pts_strings::CHAR_NUMERIC)) {
                                         $fs = $s . ' (ecryptfs)';
                                     }
                                 }
                             }
                             break;
                         default:
                             if (substr($fs, 0, 9) == 'UNKNOWN (') {
                                 $magic_block = substr($fs, 9, -1);
                                 $known_magic_blocks = array('0x9123683e' => 'Btrfs', '0x2fc12fc1' => 'zfs', '0x482b' => 'HFS+', '0x65735546' => 'FUSE', '0x565a4653' => 'ReiserFS', '0x52345362' => 'Reiser4', '0x3434' => 'NILFS2', '0x5346414f' => 'OpenAFS', '0x47504653' => 'GPFS', '0x5941ff53' => 'YAFFS', '0xff534d42' => 'CIFS', '0x24051905' => 'UBIFS', '0x1021994' => 'TMPFS', '0x73717368' => 'SquashFS', '0xc97e8168' => 'LogFS', '0x5346544E' => 'NTFS', '0xf15f' => 'eCryptfs', '0x61756673' => 'AuFS', '0xbd00bd0' => 'Lustre', '0xaad7aaea' => 'PanFS', '0xf2f52010' => 'F2FS', '0xc36400' => 'CephFS');
                                 foreach ($known_magic_blocks as $hex => $name) {
                                     if ($magic_block == $hex) {
                                         $fs = $name;
                                         break;
                                     }
                                 }
                             }
                             break;
                     }
                     if (strpos($fs, 'UNKNOWN') !== false && isset(phodevi::$vfs->mounts)) {
                         $mounts = phodevi::$vfs->mounts;
                         $fs_r = array();
                         $fs_checks = array('squashfs' => 'SquashFS', 'aufs' => 'AuFS', 'unionfs' => 'UnionFS');
                         foreach ($fs_checks as $fs_module => $fs_name) {
                             if (strpos($mounts, $fs_module) != false) {
                                 array_push($fs_r, $fs_name);
                             }
                         }
                         if (count($fs_r) > 0) {
                             $fs = implode(' + ', $fs_r);
                         }
                     }
                 } else {
                     if (phodevi::is_windows()) {
                         return null;
                     }
                 }
             }
         }
     }
     if (empty($fs)) {
         $fs = 'Unknown';
     }
     return $fs;
 }
 public static function analyze_result_file_intent(&$result_file, &$flagged_results = -1, $return_all_changed_indexes = false)
 {
     $identifiers = array();
     $hw = array();
     $sw = array();
     foreach ($result_file->get_systems() as $system) {
         array_push($identifiers, $system->get_identifier());
         array_push($hw, $system->get_hardware());
         array_push($sw, $system->get_software());
     }
     if (count($identifiers) < 2) {
         // Not enough tests to be valid for anything
         return false;
     }
     foreach ($identifiers as $identifier) {
         if (pts_strings::string_only_contains($identifier, pts_strings::CHAR_NUMERIC | pts_strings::CHAR_DASH | pts_strings::CHAR_SPACE)) {
             // All the identifiers are just dates or other junk
             return false;
         }
     }
     $hw_unique = array_unique($hw);
     $sw_unique = array_unique($sw);
     $desc = false;
     if (count($hw_unique) == 1 && count($sw_unique) == 1) {
         // The hardware and software is maintained throughout the testing, so if there's a change in results its something we aren't monitoring
         // TODO XXX: Not sure this below check is needed anymore...
         if (true || count($hw) > 2 && $result_file->get_test_count() != count($hw)) {
             $desc = array('Unknown', implode(', ', $identifiers));
         }
     } else {
         if (count($sw_unique) == 1) {
             // The software is being maintained, but the hardware is being flipped out
             $rows = array();
             $data = array();
             pts_result_file_analyzer::system_components_to_table($data, $identifiers, $rows, $hw);
             pts_result_file_analyzer::compact_result_table_data($data, $identifiers, true);
             $desc = pts_result_file_analyzer::analyze_system_component_changes($data, $rows, array(array('Processor', 'Motherboard', 'Chipset', 'Audio', 'Network'), array('Processor', 'Motherboard', 'Chipset', 'Network'), array('Processor', 'Chipset', 'Graphics'), array('Processor', 'Graphics'), array('Processor', 'Chipset'), array('Motherboard', 'Chipset'), array('Motherboard', 'Chipset', 'Audio', 'Network'), array('Graphics', 'Audio')), $return_all_changed_indexes);
         } else {
             if (count($hw_unique) == 1) {
                 // The hardware is being maintained, but the software is being flipped out
                 $rows = array();
                 $data = array();
                 pts_result_file_analyzer::system_components_to_table($data, $identifiers, $rows, $sw);
                 pts_result_file_analyzer::compact_result_table_data($data, $identifiers, true);
                 $desc = pts_result_file_analyzer::analyze_system_component_changes($data, $rows, array(array('Display Driver', 'OpenGL'), array('OpenGL'), array('Display Driver')), $return_all_changed_indexes);
             } else {
                 // Both software and hardware are being flipped out
                 $rows = array();
                 $data = array();
                 pts_result_file_analyzer::system_components_to_table($data, $identifiers, $rows, $hw);
                 pts_result_file_analyzer::system_components_to_table($data, $identifiers, $rows, $sw);
                 pts_result_file_analyzer::compact_result_table_data($data, $identifiers, true);
                 $desc = pts_result_file_analyzer::analyze_system_component_changes($data, $rows, array(array('Memory', 'Graphics', 'Display Driver', 'OpenGL'), array('Graphics', 'Monitor', 'Kernel', 'Display Driver', 'OpenGL'), array('Graphics', 'Monitor', 'Display Driver', 'OpenGL'), array('Graphics', 'Kernel', 'Display Driver', 'OpenGL'), array('Graphics', 'Display Driver', 'OpenGL'), array('Graphics', 'OpenGL'), array('Graphics', 'Kernel'), array('Graphics', 'Display Driver')), $return_all_changed_indexes);
             }
         }
     }
     if ($desc) {
         if ($flagged_results === -1) {
             return $desc;
         } else {
             $mark_results = self::locate_interesting_results($result_file, $flagged_results);
             return array($desc[0], $desc[1], $mark_results);
         }
     }
     return false;
 }
 public static function evaluate_string_to_qualifier($supplied, $bind_version = true, $check_only_type = false)
 {
     $qualified = false;
     $c_repo = null;
     $repos = self::linked_repositories();
     if (($c = strpos($supplied, '/')) !== false) {
         // A repository was explicitly defined
         $c_repo = substr($supplied, 0, $c);
         $test = substr($supplied, $c + 1);
         // If it's in the linked repo list it should have refreshed when starting client
         if (!in_array($c_repo, $repos)) {
             // Pull in this repository's index
             pts_openbenchmarking::refresh_repository_lists($repos);
         }
         $repos = array($c_repo);
     } else {
         // If it's in the linked repo list it should have refreshed when starting client
         $test = $supplied;
     }
     if (($c = strrpos($test, '-')) !== false) {
         $version = substr($test, $c + 1);
         // TODO: functionalize this and read against types.xsd
         if (isset($version[2]) && !isset($version[8]) && pts_strings::string_only_contains($version, pts_strings::CHAR_NUMERIC | pts_strings::CHAR_DECIMAL)) {
             $test = substr($test, 0, $c);
         } else {
             $version = null;
         }
     } else {
         $version = null;
     }
     if ($test == null) {
         return false;
     }
     foreach ($repos as $repo) {
         if ($repo == 'local') {
             if (self::check_only_type_compare($check_only_type, 'test')) {
                 if (is_file(PTS_TEST_PROFILE_PATH . $repo . '/' . $test . '/test-definition.xml')) {
                     return $repo . '/' . $test;
                     // ($bind_version ? '-' . $version : null)
                 } else {
                     if (is_file(PTS_TEST_PROFILE_PATH . $repo . '/' . $test . '-' . $version . '/test-definition.xml')) {
                         return $repo . '/' . $test . '-' . $version;
                         // ($bind_version ? '-' . $version : null)
                     }
                 }
             }
             if (self::check_only_type_compare($check_only_type, 'suite')) {
                 if (is_file(PTS_TEST_SUITE_PATH . $repo . '/' . $test . '/suite-definition.xml')) {
                     return $repo . '/' . $test;
                     // ($bind_version ? '-' . $version : null)
                 } else {
                     if (is_file(PTS_TEST_SUITE_PATH . $repo . '/' . $test . '-' . $version . '/suite-definition.xml')) {
                         return $repo . '/' . $test . '-' . $version;
                         // ($bind_version ? '-' . $version : null)
                     }
                 }
             }
         }
         $repo_index = pts_openbenchmarking::read_repository_index($repo);
         if (is_array($repo_index) && isset($repo_index['tests'][$test]) && self::check_only_type_compare($check_only_type, 'test')) {
             // The test profile at least exists
             // Looking for a particular test profile version?
             if ($version != null) {
                 if (!in_array($version, $repo_index['tests'][$test]['versions'])) {
                     // Grep to see if the version passed was e.g. 1.3 instead of 1.3.3
                     $versions = $repo_index['tests'][$test]['versions'];
                     sort($versions);
                     foreach (array_reverse($versions) as $check_version) {
                         if (strstr($check_version, $version) != false) {
                             $version = $check_version;
                             break;
                         }
                     }
                 }
                 if (in_array($version, $repo_index['tests'][$test]['versions'])) {
                     pts_openbenchmarking::download_test_profile($repo . '/' . $test . '-' . $version);
                     return $repo . '/' . $test . ($bind_version ? '-' . $version : null);
                 }
             } else {
                 // Assume to use the latest version unless something else is installed
                 $available_versions = $repo_index['tests'][$test]['versions'];
                 $version = $available_versions[0];
                 // the latest version available
                 if (pts_c::$test_flags & pts_c::is_run_process) {
                     // Check to see if an older version of the test profile is currently installed
                     foreach ($available_versions as $i => $v) {
                         if (is_file(pts_client::test_install_root_path() . $repo . '/' . $test . '-' . $v . '/pts-install.xml')) {
                             $version = $v;
                             if ($i > 0 && pts_c::$test_flags ^ pts_c::batch_mode) {
                                 // It's not the latest test profile version available
                                 trigger_error($repo . '/' . $test . ': The latest test profile version available for upgrade is ' . $available_versions[0] . ' but version ' . $version . ' is the latest currently installed.', E_USER_WARNING);
                             }
                             break;
                         }
                     }
                 }
                 pts_openbenchmarking::download_test_profile($repo . '/' . $test . '-' . $version);
                 return $repo . '/' . $test . ($bind_version ? '-' . $version : null);
             }
         }
         if (is_array($repo_index) && isset($repo_index['suites'][$test]) && self::check_only_type_compare($check_only_type, 'suite')) {
             // The test profile at least exists
             // Looking for a particular test profile version?
             if ($version != null) {
                 if (!in_array($version, $repo_index['suites'][$test]['versions'])) {
                     // Grep to see if the version passed was e.g. 1.3 instead of 1.3.3
                     $versions = $repo_index['suites'][$test]['versions'];
                     sort($versions);
                     foreach (array_reverse($versions) as $check_version) {
                         if (strstr($check_version, $version) != false) {
                             $version = $check_version;
                             break;
                         }
                     }
                 }
                 if (in_array($version, $repo_index['suites'][$test]['versions'])) {
                     pts_openbenchmarking::download_test_suite($repo . '/' . $test . '-' . $version);
                     return $repo . '/' . $test . ($bind_version ? '-' . $version : null);
                 }
             } else {
                 // Assume to use the latest version
                 $version = array_shift($repo_index['suites'][$test]['versions']);
                 pts_openbenchmarking::download_test_suite($repo . '/' . $test . '-' . $version);
                 return $repo . '/' . $test . ($bind_version ? '-' . $version : null);
             }
         }
     }
     return false;
 }
 public static function is_vendor_string($vendor)
 {
     return isset($vendor[2]) && pts_strings::string_only_contains($vendor, pts_strings::CHAR_LETTER | pts_strings::CHAR_NUMERIC | pts_strings::CHAR_DECIMAL | pts_strings::CHAR_SPACE | pts_strings::CHAR_DASH) && !pts_strings::has_in_istring($vendor, array('manufacturer', 'vendor', 'unknown', 'generic', 'warning')) && (!isset($vendor[7]) || strpos($vendor, ' ') !== false || pts_strings::times_occurred($vendor, pts_strings::CHAR_NUMERIC) == 0) && pts_strings::string_contains($vendor, pts_strings::CHAR_LETTER) && (isset($vendor[4]) || pts_strings::times_occurred($vendor, pts_strings::CHAR_LETTER) > 1) && substr($vendor, -1) != '-';
 }
 public static function monitor_string()
 {
     $monitor = null;
     if (phodevi::is_macosx()) {
         $system_profiler = shell_exec('system_profiler SPDisplaysDataType 2>&1');
         $system_profiler = substr($system_profiler, strrpos($system_profiler, 'Displays:'));
         $system_profiler = substr($system_profiler, strpos($system_profiler, "\n"));
         $monitor = trim(substr($system_profiler, 0, strpos($system_profiler, ':')));
         if ($monitor == 'Display Connector') {
             $monitor = null;
         }
     } else {
         if (phodevi::is_nvidia_graphics() && isset(phodevi::$vfs->xorg_log)) {
             $log_parse = phodevi::$vfs->xorg_log;
             $offset = 0;
             $monitor = array();
             /* e.g.
             			$ cat /var/log/Xorg.0.log | grep -i connected
             			[    18.174] (--) NVIDIA(0):     Acer P243W (DFP-0) (connected)
             			[    18.174] (--) NVIDIA(0):     Acer AL2223W (DFP-1) (connected)
             			*/
             while (($monitor_pos = strpos($log_parse, ') (connected)', $offset)) !== false || ($monitor_pos = strpos($log_parse, ') (boot, connected)', $offset)) !== false) {
                 $m = substr($log_parse, 0, $monitor_pos);
                 $m = substr($m, strrpos($m, '): ') + 2);
                 $m = trim(substr($m, 0, strpos($m, ' (')));
                 if (!empty($m) && !isset($m[32]) && isset($m[6])) {
                     array_push($monitor, $m);
                 }
                 $offset = $monitor_pos + 2;
             }
             // technically should be fine reporting multiple of the same monitor
             // but fglrx/catalyst as of late 2013 is in habit of reporting monitors twice
             $monitor = array_unique($monitor);
             $monitor = implode(' + ', $monitor);
         } else {
             if (isset(phodevi::$vfs->xorg_log)) {
                 $log_parse = phodevi::$vfs->xorg_log;
                 $offset = 0;
                 $monitor = array();
                 while (($monitor_name = strpos($log_parse, 'Monitor name:', $offset)) !== false) {
                     $log_parse = substr($log_parse, $monitor_name + 14);
                     $m = trim(substr($log_parse, 0, strpos($log_parse, "\n")));
                     if (!empty($m)) {
                         array_push($monitor, $m);
                     }
                 }
                 // technically should be fine reporting multiple of the same monitor
                 // but fglrx/catalyst as of late 2013 is in habit of reporting monitors twice
                 $monitor = array_unique($monitor);
                 $monitor = implode(' + ', $monitor);
             }
         }
     }
     if ($monitor == null && phodevi::is_linux()) {
         // Attempt to find the EDID over sysfs and then decode it for monitor name (0xFC)
         // For at least Intel DRM drivers there is e.g. /sys/class/drm/card0-HDMI-A-2/edid
         // Also works at least for Radeon DRM driver too
         foreach (glob('/sys/class/drm/*/edid') as $edid_file) {
             $edid_file = pts_file_io::file_get_contents($edid_file);
             if ($edid_file == null) {
                 continue;
             }
             $edid = bin2hex($edid_file);
             $x = 0;
             while ($x = strpos($edid, '00fc', $x)) {
                 // 00fc indicates start of EDID monitor descriptor block
                 $encoded = substr($edid, $x + 4, 36);
                 $edid_monitor_name_block = null;
                 for ($i = 0; $i < strlen($encoded); $i += 2) {
                     $hex = substr($encoded, $i, 2);
                     if ($hex == 15 || $hex == '0a') {
                         break;
                     }
                     $ch = chr(hexdec($hex));
                     $edid_monitor_name_block .= $ch;
                 }
                 $edid_monitor_name_block = trim($edid_monitor_name_block);
                 if (pts_strings::string_only_contains($edid_monitor_name_block, pts_strings::CHAR_LETTER | pts_strings::CHAR_NUMERIC | pts_strings::CHAR_DECIMAL | pts_strings::CHAR_SPACE | pts_strings::CHAR_DASH)) {
                     $monitor = $edid_monitor_name_block;
                     break;
                 }
                 $x++;
             }
             if ($monitor != null) {
                 break;
             }
         }
     }
     return empty($monitor) ? false : $monitor;
 }
 public function is_supported_value($input)
 {
     $supported = false;
     if (is_array($this->option_supported_values)) {
         if (in_array($input, $this->option_supported_values)) {
             $supported = true;
         }
     } else {
         if (empty($input) && $this->option_default_value != null) {
             $supported = true;
         } else {
             switch ($this->option_supported_values) {
                 case 'NUMERIC':
                     if (is_numeric($input)) {
                         $supported = true;
                     }
                     break;
                 case 'NUMERIC_DASH':
                     if (!empty($input) && pts_strings::string_only_contains($input, pts_strings::CHAR_NUMERIC | pts_strings::CHAR_DASH)) {
                         $supported = true;
                     }
                     break;
                 case 'ALPHA_NUMERIC':
                     if (!empty($input) && pts_strings::string_only_contains($input, pts_strings::CHAR_NUMERIC | pts_strings::CHAR_LETTER)) {
                         $supported = true;
                     }
                     break;
                 case 'HTTP_URL':
                     if (substr($input, 0, 7) == 'http://') {
                         $supported = true;
                     }
                     break;
                 case 'LOCAL_DIRECTORY':
                     if (is_dir($input)) {
                         $supported = true;
                     }
                     break;
                 case 'LOCAL_FILE':
                     if (is_file($input)) {
                         $supported = true;
                     }
                     break;
                 case 'LOCAL_EXECUTABLE':
                     if (is_executable($input)) {
                         $supported = true;
                     }
                     break;
                 case 'PTS_TEST_RESULT':
                     if (pts_result_file::is_test_result_file($input)) {
                         $supported = true;
                     }
                 case 'INSTALLED_TEST':
                     if (in_array($input, pts_tests::installed_tests())) {
                         $supported = true;
                     }
                 case 'VALID_SAVE_NAME':
                     if (!empty($input) && pts_types::identifier_to_object($input) == false) {
                         $supported = true;
                     }
                 case 'NOT_EMPTY':
                     if (!empty($input)) {
                         $supported = true;
                     }
                 case '':
                     $supported = true;
                     break;
             }
         }
     }
     if ($supported && !empty($this->option_function_check)) {
         $supported = call_user_func($this->option_function_check, $input) == true;
     }
     return $supported;
 }