public function __construct($identifier = null)
 {
     $this->struct = array('external-dependencies' => array('name' => null, 'package_manager' => null, 'aliases' => array(), 'packages' => array()));
     if (PTS_IS_CLIENT) {
         $xml = PTS_EXDEP_PATH . 'xml/' . $identifier . '-packages.xml';
         $xml_parser = new nye_XmlReader($xml);
         $this->struct['external-dependencies']['name'] = $xml_parser->getXMLValue('PhoronixTestSuite/ExternalDependencies/Information/Name');
         $this->struct['external-dependencies']['package_manager'] = $xml_parser->getXMLValue('PhoronixTestSuite/ExternalDependencies/Information/PackageManager');
         $generic_package = $xml_parser->getXMLArrayValues('PhoronixTestSuite/ExternalDependencies/Package/GenericName');
         $distro_package = $xml_parser->getXMLArrayValues('PhoronixTestSuite/ExternalDependencies/Package/PackageName');
         $file_check = $xml_parser->getXMLArrayValues('PhoronixTestSuite/ExternalDependencies/Package/FileCheck');
         $arch_specific = $xml_parser->getXMLArrayValues('PhoronixTestSuite/ExternalDependencies/Package/ArchitectureSpecific');
         $os_version_specific = $xml_parser->getXMLArrayValues('PhoronixTestSuite/ExternalDependencies/Package/VersionSpecific');
         $os_version = phodevi::read_property('system', 'os-version');
         foreach (array_keys($generic_package) as $i) {
             if (empty($generic_package[$i])) {
                 continue;
             }
             $os_version_compliant = empty($os_version_specific[$i]) || in_array($os_version, pts_strings::comma_explode($os_version_specific[$i]));
             if ($os_version_compliant == false) {
                 continue;
             }
             $this->struct['external-dependencies']['packages'][$generic_package[$i]] = $this->get_package_format($distro_package[$i], $file_check[$i], $arch_specific[$i]);
         }
         $aliases = $xml_parser->getXMLValue('PhoronixTestSuite/ExternalDependencies/Information/Aliases');
         if ($aliases != null) {
             $aliases = pts_strings::trim_explode(',', $aliases);
             foreach ($aliases as $alias) {
                 if ($alias != null) {
                     $this->struct['external-dependencies']['aliases'][] = $alias;
                 }
             }
         }
     }
 }
 public function get_contained_test_result_objects()
 {
     $test_result_objects = array();
     $test_names = $this->xml_parser->getXMLArrayValues('PhoronixTestSuite/Execute/Test');
     $sub_modes = $this->xml_parser->getXMLArrayValues('PhoronixTestSuite/Execute/Mode');
     $sub_arguments = $this->xml_parser->getXMLArrayValues('PhoronixTestSuite/Execute/Arguments');
     $sub_arguments_description = $this->xml_parser->getXMLArrayValues('PhoronixTestSuite/Execute/Description');
     $override_test_options = $this->xml_parser->getXMLArrayValues('PhoronixTestSuite/Execute/OverrideTestOptions');
     for ($i = 0; $i < count($test_names); $i++) {
         $obj = pts_types::identifier_to_object($test_names[$i]);
         if ($obj instanceof pts_test_profile) {
             // Check for test profile values to override
             $override_options = array();
             if (!empty($override_test_options[$i])) {
                 foreach (explode(';', $override_test_options[$i]) as $override_string) {
                     $override_segments = pts_strings::trim_explode('=', $override_string);
                     if (count($override_segments) == 2 && !empty($override_segments[0]) && !empty($override_segments[1])) {
                         $override_options[$override_segments[0]] = $override_segments[1];
                     }
                 }
             }
             switch ($sub_modes[$i]) {
                 case 'BATCH':
                     $option_output = pts_test_run_options::batch_user_options($obj);
                     break;
                 case 'DEFAULTS':
                     $option_output = pts_test_run_options::default_user_options($obj);
                     break;
                 default:
                     $option_output = array(array($sub_arguments[$i]), array($sub_arguments_description[$i]));
                     break;
             }
             foreach (array_keys($option_output[0]) as $x) {
                 if ($override_options != null) {
                     $test_profile->set_override_values($override_options);
                 }
                 $test_result = new pts_test_result($obj);
                 $test_result->set_used_arguments($option_output[0][$x]);
                 $test_result->set_used_arguments_description($option_output[1][$x]);
                 array_push($test_result_objects, $test_result);
             }
         } else {
             if ($obj instanceof pts_test_suite) {
                 foreach ($obj->get_contained_test_result_objects() as $test_result) {
                     array_push($test_result_objects, $test_result);
                 }
             }
         }
     }
     return $test_result_objects;
 }
 public static function get_supported_devices()
 {
     if (phodevi::is_linux()) {
         //TODO write network_usage_linux function
         //			$iface_list = shell_exec("ls -1 /sys/class/net | grep -v lo");
         //			$iface_array = explode("\n", $iface_list);
         //
         //			return $iface_array;
         return NULL;
     }
     if (phodevi::is_bsd() || phodevi::is_macosx()) {
         $iface_list = shell_exec("ifconfig -lu | tr ' ' '\n' | grep -v 'lo0'");
         $iface_array = pts_strings::trim_explode(" ", $iface_list);
         return $iface_array;
     }
     return NULL;
 }
 public static function clear_iqr_outlier_results(&$test_result_buffer)
 {
     $is_multi_way = pts_render::multi_way_identifier_check($test_result_buffer->get_identifiers());
     if ($is_multi_way) {
         $group_values = array();
         $group_keys = array();
         foreach ($test_result_buffer->buffer_items as $key => &$buffer_item) {
             $identifier_r = pts_strings::trim_explode(': ', $buffer_item->get_result_identifier());
             if (!isset($group_values[$identifier_r[1]])) {
                 $group_values[$identifier_r[1]] = array();
                 $group_keys[$identifier_r[1]] = array();
             }
             array_push($group_values[$identifier_r[1]], $buffer_item->get_result_value());
             array_push($group_keys[$identifier_r[1]], $key);
         }
         foreach ($group_values as $group_key => $values) {
             // From: http://www.mathwords.com/o/outlier.htm
             $fqr = pts_math::first_quartile($values);
             $tqr = pts_math::third_quartile($values);
             $iqr_cut = ($tqr - $fqr) * 1.5;
             $bottom_cut = $fqr - $iqr_cut;
             $top_cut = $tqr + $iqr_cut;
             foreach ($group_keys[$group_key] as $key) {
                 $value = $test_result_buffer->buffer_items[$key]->get_result_value();
                 if ($value > $top_cut || $value < $bottom_cut) {
                     unset($test_result_buffer->buffer_items[$key]);
                 }
             }
         }
     } else {
         // From: http://www.mathwords.com/o/outlier.htm
         $values = $test_result_buffer->get_values();
         $fqr = pts_math::first_quartile($values);
         $tqr = pts_math::third_quartile($values);
         $iqr_cut = ($tqr - $fqr) * 1.5;
         $bottom_cut = $fqr - $iqr_cut;
         $top_cut = $tqr + $iqr_cut;
         foreach ($test_result_buffer->buffer_items as $key => &$buffer_item) {
             $value = $buffer_item->get_result_value();
             if ($value > $top_cut || $value < $bottom_cut) {
                 unset($test_result_buffer->buffer_items[$key]);
             }
         }
     }
 }
 public function report_error($level, $message, $file, $line)
 {
     $error_string = '[' . $level . '] ';
     if (strpos($message, PHP_EOL) === false) {
         $error_string .= $message . ' ';
     } else {
         foreach (pts_strings::trim_explode(PHP_EOL, $message) as $line_count => $line_string) {
             $error_string .= $line_string . PHP_EOL . str_repeat(' ', strlen($level) + 3);
         }
     }
     if ($file != null) {
         $error_string .= 'in ' . basename($file, '.php');
     }
     if ($line != 0) {
         $error_string .= ':' . $line;
     }
     $this->log($error_string);
 }
 private static function prepare_sensor_parameters()
 {
     $sensor_list = pts_strings::comma_explode(pts_module::read_variable('MONITOR'));
     $to_monitor = array();
     foreach ($sensor_list as $sensor) {
         $sensor_split = pts_strings::trim_explode('.', $sensor);
         // Set 'all' from the beginning (eg. all.cpu.frequency) as the last
         // element (cpu.frequency.all). As sensor parameters are also supported
         // now, it's handy to mark that we want to include all sensors of specified
         // type (cpu.all) or just all supported parameters of specified sensor
         // (cpu.frequency.all).
         if ($sensor_split[0] === 'all') {
             $sensor_split[] = 'all';
             array_shift($sensor_split);
         }
         $type =& $sensor_split[0];
         $name =& $sensor_split[1];
         $parameter =& $sensor_split[2];
         if (empty($to_monitor[$type][$name])) {
             $to_monitor[$type][$name] = array();
         }
         if ($parameter !== NULL) {
             $to_monitor[$type][$name][] = $parameter;
         }
     }
     return $to_monitor;
 }
 public function normalize_buffer_values($normalize_against = false)
 {
     if ($this->test_profile->get_display_format() != 'BAR_GRAPH') {
         return false;
     }
     $is_multi_way = pts_render::multi_way_identifier_check($this->test_result_buffer->get_identifiers());
     $keys = array_keys($this->test_result_buffer->buffer_items);
     if ($is_multi_way) {
         $key_sets = array();
         foreach ($keys as $k) {
             $identifier_r = pts_strings::trim_explode(': ', $this->test_result_buffer->buffer_items[$k]->get_result_identifier());
             if (!isset($key_sets[$identifier_r[0]])) {
                 $key_sets[$identifier_r[0]] = array();
             }
             array_push($key_sets[$identifier_r[0]], $k);
         }
     } else {
         $key_sets = array($keys);
     }
     foreach ($key_sets as $keys) {
         if ($this->test_profile->get_result_proportion() == 'LIB') {
             // Invert values for LIB
             foreach ($keys as $k) {
                 $this->test_result_buffer->buffer_items[$k]->reset_result_value(1 / $this->test_result_buffer->buffer_items[$k]->get_result_value());
             }
         }
         $divide_value = -1;
         if ($normalize_against != false) {
             foreach ($keys as $k) {
                 if ($is_multi_way && strpos($this->test_result_buffer->buffer_items[$k]->get_result_identifier(), ': ' . $normalize_against) !== false) {
                     // This allows it to just normalize against part of the string
                     $divide_value = $this->test_result_buffer->buffer_items[$k]->get_result_value();
                     break;
                 } else {
                     if ($this->test_result_buffer->buffer_items[$k]->get_result_identifier() == $normalize_against) {
                         $divide_value = $this->test_result_buffer->buffer_items[$k]->get_result_value();
                         break;
                     }
                 }
             }
         }
         if ($divide_value == -1) {
             foreach ($keys as $k) {
                 if ($this->test_result_buffer->buffer_items[$k]->get_result_value() < $divide_value || $divide_value == -1) {
                     $divide_value = $this->test_result_buffer->buffer_items[$k]->get_result_value();
                 }
             }
         }
         if ($divide_value != 0) {
             foreach ($keys as $k) {
                 $normalized = pts_math::set_precision($this->test_result_buffer->buffer_items[$k]->get_result_value() / $divide_value, max(3, $this->result_precision));
                 $this->test_result_buffer->buffer_items[$k]->reset_result_value($normalized);
                 $this->test_result_buffer->buffer_items[$k]->reset_raw_value(0);
             }
         }
     }
     $this->test_profile->set_result_proportion('HIB');
     $this->test_profile->set_result_scale('Relative Performance');
     return true;
 }
 public static function executable_in_path($executable, $ignore_paths_with = false)
 {
     static $cache = null;
     if (!isset($cache[$executable]) || $ignore_paths_with) {
         $paths = pts_strings::trim_explode(phodevi::is_windows() ? ';' : ':', ($path = pts_client::read_env('PATH')) == false ? '/usr/local/bin:/usr/bin:/usr/sbin:/bin' : $path);
         $executable_path = false;
         foreach ($paths as $path) {
             $path = pts_strings::add_trailing_slash($path);
             if (is_executable($path . $executable)) {
                 if ($ignore_paths_with && stripos($path, $ignore_paths_with) !== false) {
                     continue;
                 }
                 $executable_path = $path . $executable;
                 break;
             }
         }
         if ($ignore_paths_with) {
             // Don't cache calls using the $ignore_paths_with parameter
             return $executable_path;
         }
         $cache[$executable] = $executable_path;
     }
     return $cache[$executable];
 }
 public function generic_sub_heading($string)
 {
     if (!empty($string)) {
         // To generate the 'Phoronix Test Suite' heading string if not already done so
         pts_client::$display->generic_heading(null, false);
         foreach (pts_strings::trim_explode(PHP_EOL, $string) as $line_string) {
             echo $this->tab . $line_string . PHP_EOL;
         }
     }
 }
 public static function parse_equal_delimited_file($file, $key)
 {
     $return_value = false;
     foreach (explode("\n", pts_file_io::file_get_contents($file)) as $build_line) {
         list($descriptor, $value) = pts_strings::trim_explode('=', $build_line);
         if ($descriptor == $key) {
             $return_value = $value;
             break;
         }
     }
     return $return_value;
 }
 public static function read_sensors($attributes)
 {
     // Read LM_Sensors
     $value = false;
     if (isset(phodevi::$vfs->sensors)) {
         $sensors = phodevi::$vfs->sensors;
         $sensors_lines = explode("\n", $sensors);
         $attributes = pts_arrays::to_array($attributes);
         for ($j = 0; $j < count($attributes) && empty($value); $j++) {
             $attribute = $attributes[$j];
             for ($i = 0; $i < count($sensors_lines) && $value == false; $i++) {
                 $line = pts_strings::trim_explode(': ', $sensors_lines[$i]);
                 if (!isset($line[0])) {
                     continue;
                 }
                 $this_attribute = $line[0];
                 if ($this_attribute == $attribute) {
                     $this_remainder = trim(str_replace(array('+', '°'), ' ', $line[1]));
                     $this_value = substr($this_remainder, 0, strpos($this_remainder, ' '));
                     if (is_numeric($this_value) && $this_value > 0) {
                         $value = $this_value;
                     }
                 }
             }
         }
     }
     return $value;
 }
 public static function process_environment_variables_string_to_set($env_var_string)
 {
     if (!empty($env_var_string)) {
         foreach (explode(';', $env_var_string) as $ev) {
             if (strpos($ev, '=') != false) {
                 list($var, $value) = pts_strings::trim_explode('=', $ev);
                 pts_client::set_environment_variable($var, $value);
                 pts_module_manager::var_store_add($var, $value);
             }
         }
         pts_module_manager::detect_modules_to_load();
     }
 }
 public function points_of_possible_interest($threshold_level = 0.1)
 {
     $points_of_interest = array();
     if ($this->test_profile->get_display_format() != 'BAR_GRAPH') {
         return $points_of_interest;
     }
     $is_multi_way = pts_render::multi_way_identifier_check($this->test_result_buffer->get_identifiers());
     $keys = array_keys($this->test_result_buffer->buffer_items);
     if ($is_multi_way) {
         $key_sets = array();
         foreach ($keys as $k) {
             $identifier_r = pts_strings::trim_explode(': ', $this->test_result_buffer->buffer_items[$k]->get_result_identifier());
             if (!isset($key_sets[$identifier_r[0]])) {
                 $key_sets[$identifier_r[0]] = array();
             }
             $key_sets[$identifier_r[0]][] = $k;
         }
     } else {
         $key_sets = array($keys);
     }
     foreach ($key_sets as $keys) {
         $prev_value = -1;
         $prev_id = -1;
         foreach ($keys as $k) {
             $this_value = $this->test_result_buffer->buffer_items[$k]->get_result_value();
             $this_id = $this->test_result_buffer->buffer_items[$k]->get_result_identifier();
             if ($prev_value != -1 && $prev_id != -1) {
                 $d = abs($prev_value / $this_value - 1);
                 if ($d > $threshold_level) {
                     $points_of_interest[] = $this_id . ' - ' . $prev_id . ': ' . round($d * 100, 2) . '%';
                 }
             }
             $prev_value = $this_value;
             $prev_id = $this_id;
         }
     }
     return $points_of_interest;
 }
 public function read_sensor()
 {
     // Graphics processor real/current frequency
     $show_memory = false;
     $core_freq = 0;
     $mem_freq = 0;
     if (phodevi::is_nvidia_graphics()) {
         $nv_freq = phodevi_parser::read_nvidia_extension('GPUCurrentClockFreqs');
         $nv_freq = pts_strings::comma_explode($nv_freq);
         $core_freq = isset($nv_freq[0]) ? $nv_freq[0] : 0;
         $mem_freq = isset($nv_freq[1]) ? $nv_freq[1] : 0;
     } else {
         if (phodevi::is_ati_graphics() && phodevi::is_linux()) {
             $od_clocks = phodevi_linux_parser::read_ati_overdrive('CurrentClocks');
             if (is_array($od_clocks) && count($od_clocks) >= 2) {
                 $core_freq = array_shift($od_clocks);
                 $mem_freq = array_pop($od_clocks);
             }
         } else {
             if (phodevi::is_linux()) {
                 if (isset(phodevi::$vfs->radeon_pm_info)) {
                     // radeon_pm_info should be present with Linux 2.6.34+
                     foreach (pts_strings::trim_explode("\n", phodevi::$vfs->radeon_pm_info) as $pm_line) {
                         $pm_line = pts_strings::colon_explode($pm_line);
                         if (isset($pm_line[1])) {
                             list($descriptor, $value) = $pm_line;
                         } else {
                             continue;
                         }
                         switch ($descriptor) {
                             case 'current engine clock':
                                 $core_freq = pts_arrays::first_element(explode(' ', $value)) / 1000;
                                 break;
                             case 'current memory clock':
                                 $mem_freq = pts_arrays::first_element(explode(' ', $value)) / 1000;
                                 break;
                         }
                     }
                     if ($core_freq == null && ($x = strpos(phodevi::$vfs->radeon_pm_info, 'sclk: '))) {
                         $x = substr(phodevi::$vfs->radeon_pm_info, $x + strlen('sclk: '));
                         $x = substr($x, 0, strpos($x, ' '));
                         if (is_numeric($x)) {
                             if ($x > 1000) {
                                 $x = $x / 100;
                             }
                             $core_freq = $x;
                         }
                     }
                     if ($mem_freq == null && ($x = strpos(phodevi::$vfs->radeon_pm_info, 'mclk: '))) {
                         $x = substr(phodevi::$vfs->radeon_pm_info, $x + strlen('mclk: '));
                         $x = substr($x, 0, strpos($x, ' '));
                         if (is_numeric($x)) {
                             if ($x > 1000) {
                                 $x = $x / 100;
                             }
                             $mem_freq = $x;
                         }
                     }
                 } else {
                     if (is_file('/sys/class/drm/card0/gt_cur_freq_mhz')) {
                         $gt_cur_freq_mhz = pts_file_io::file_get_contents('/sys/class/drm/card0/gt_cur_freq_mhz');
                         if ($gt_cur_freq_mhz > 2) {
                             $core_freq = $gt_cur_freq_mhz;
                         }
                     } else {
                         if (is_file('/sys/class/drm/card0/device/performance_level')) {
                             $performance_level = pts_file_io::file_get_contents('/sys/class/drm/card0/device/performance_level');
                             $performance_level = explode(' ', $performance_level);
                             $core_string = array_search('core', $performance_level);
                             if ($core_string !== false && isset($performance_level[$core_string + 1])) {
                                 $core_string = str_ireplace('MHz', null, $performance_level[$core_string + 1]);
                                 if (is_numeric($core_string) && $core_string > $core_freq) {
                                     $core_freq = $core_string;
                                 }
                             }
                             $mem_string = array_search('memory', $performance_level);
                             if ($mem_string !== false && isset($performance_level[$mem_string + 1])) {
                                 $mem_string = str_ireplace('MHz', null, $performance_level[$mem_string + 1]);
                                 if (is_numeric($mem_string) && $mem_string > $mem_freq) {
                                     $mem_freq = $mem_string;
                                 }
                             }
                         } else {
                             if (isset(phodevi::$vfs->i915_cur_delayinfo)) {
                                 $i915_cur_delayinfo = phodevi::$vfs->i915_cur_delayinfo;
                                 $cagf = strpos($i915_cur_delayinfo, 'CAGF: ');
                                 if ($cagf !== false) {
                                     $cagf_mhz = substr($i915_cur_delayinfo, $cagf + 6);
                                     $cagf_mhz = substr($cagf_mhz, 0, strpos($cagf_mhz, 'MHz'));
                                     if (is_numeric($cagf_mhz)) {
                                         $core_freq = $cagf_mhz;
                                     }
                                 }
                             }
                         }
                     }
                 }
             }
         }
     }
     if (!is_numeric($core_freq)) {
         $core_freq = 0;
     }
     if (!is_numeric($mem_freq)) {
         $mem_freq = 0;
     }
     if ($core_freq == 0 && $mem_freq == 0) {
         $show_memory = false;
         $core_freq = -1;
     }
     return $show_memory ? array($core_freq, $mem_freq) : $core_freq;
 }
 public function buffer_values_to_percent()
 {
     $is_multi_way = pts_render::multi_way_identifier_check($this->get_identifiers());
     if ($is_multi_way) {
         $group_values = array();
         foreach ($this->buffer_items as &$buffer_item) {
             $identifier_r = pts_strings::trim_explode(': ', $buffer_item->get_result_identifier());
             if (!isset($group_values[$identifier_r[1]])) {
                 $group_values[$identifier_r[1]] = 0;
             }
             $group_values[$identifier_r[1]] += $buffer_item->get_result_value();
         }
         foreach ($this->buffer_items as &$buffer_item) {
             $identifier_r = pts_strings::trim_explode(': ', $buffer_item->get_result_identifier());
             $percent = pts_math::set_precision($buffer_item->get_result_value() / $group_values[$identifier_r[1]] * 100, 3);
             $buffer_item->reset_result_value($percent);
         }
     } else {
         $total_value = array_sum($this->get_values());
         foreach ($this->buffer_items as &$buffer_item) {
             $percent = pts_math::set_precision($buffer_item->get_result_value() / $total_value * 100, 3);
             $buffer_item->reset_result_value($percent);
         }
     }
 }
 public static function gpu_stock_frequency()
 {
     // Graphics processor stock frequency
     $core_freq = 0;
     $mem_freq = 0;
     if (phodevi::is_nvidia_graphics() && phodevi::is_macosx() == false) {
         // GPUDefault3DClockFreqs is the default and does not show under/over-clocking
         $clock_freqs_3d = pts_strings::comma_explode(phodevi_parser::read_nvidia_extension('GPU3DClockFreqs'));
         $clock_freqs_current = pts_strings::comma_explode(phodevi_parser::read_nvidia_extension('GPUCurrentClockFreqs'));
         if (is_array($clock_freqs_3d) && isset($clock_freqs_3d[1])) {
             list($core_freq, $mem_freq) = $clock_freqs_3d;
         }
         if (is_array($clock_freqs_current) && isset($clock_freqs_current[1])) {
             $core_freq = max($core_freq, $clock_freqs_current[0]);
             $mem_freq = max($mem_freq, $clock_freqs_current[1]);
         }
     } else {
         if (phodevi::is_ati_graphics() && phodevi::is_linux()) {
             $od_clocks = phodevi_linux_parser::read_ati_overdrive('CurrentPeak');
             if (is_array($od_clocks) && count($od_clocks) >= 2) {
                 list($core_freq, $mem_freq) = $od_clocks;
             }
         } else {
             if (phodevi::is_linux()) {
                 $display_driver = phodevi::read_property('system', 'display-driver');
                 switch ($display_driver) {
                     case '':
                     case 'nouveau':
                         if (is_file('/sys/class/drm/card0/device/performance_level')) {
                             /*
                             	EXAMPLE OUTPUTS:
                             	memory 1000MHz core 500MHz voltage 1300mV fanspeed 100%
                             	3: memory 333MHz core 500MHz shader 1250MHz fanspeed 100%
                             	c: memory 333MHz core 500MHz shader 1250MHz
                             */
                             $performance_level = pts_file_io::file_get_contents('/sys/class/drm/card0/device/performance_level');
                             $performance_level = explode(' ', $performance_level);
                             $core_string = array_search('core', $performance_level);
                             if ($core_string !== false && isset($performance_level[$core_string + 1])) {
                                 $core_string = str_ireplace('MHz', null, $performance_level[$core_string + 1]);
                                 if (is_numeric($core_string)) {
                                     $core_freq = $core_string;
                                 }
                             }
                             $mem_string = array_search('memory', $performance_level);
                             if ($mem_string !== false && isset($performance_level[$mem_string + 1])) {
                                 $mem_string = str_ireplace('MHz', null, $performance_level[$mem_string + 1]);
                                 if (is_numeric($mem_string)) {
                                     $mem_freq = $mem_string;
                                 }
                             }
                         } else {
                             if (is_file('/sys/class/drm/card0/device/pstate')) {
                                 // pstate is present with Linux 3.13 as the new performance states on Fermi/Kepler
                                 $performance_state = pts_file_io::file_get_contents('/sys/class/drm/card0/device/pstate');
                                 $performance_level = substr($performance_state, 0, strpos($performance_state, ' *'));
                                 if ($performance_level == null) {
                                     // Method for Linux 3.17+
                                     $performance_level = substr($performance_state, strpos($performance_state, 'AC: ') + 4);
                                     if ($t = strpos($performance_level, PHP_EOL)) {
                                         $performance_level = substr($performance_level, 0, $t);
                                     }
                                 } else {
                                     // Method for Linux ~3.13 through Linux 3.16
                                     $performance_level = substr($performance_level, strrpos($performance_level, ': ') + 2);
                                 }
                                 $performance_level = explode(' ', $performance_level);
                                 $core_string = array_search('core', $performance_level);
                                 if ($core_string !== false && isset($performance_level[$core_string + 1])) {
                                     $core_string = str_ireplace('MHz', null, $performance_level[$core_string + 1]);
                                     if (strpos($core_string, '-') !== false) {
                                         // to work around a range of values, e.g.
                                         // 0a: core 405-1032 MHz memory 1620 MHz AC DC *
                                         $core_string = max(explode('-', $core_string));
                                     }
                                     if (is_numeric($core_string)) {
                                         $core_freq = $core_string;
                                     }
                                 }
                                 $mem_string = array_search('memory', $performance_level);
                                 if ($mem_string !== false && isset($performance_level[$mem_string + 1])) {
                                     $mem_string = str_ireplace('MHz', null, $performance_level[$mem_string + 1]);
                                     if (strpos($mem_string, '-') !== false) {
                                         // to work around a range of values, e.g.
                                         // 0a: core 405-1032 MHz memory 1620 MHz AC DC *
                                         $mem_string = max(explode('-', $mem_string));
                                     }
                                     if (is_numeric($mem_string)) {
                                         $mem_freq = $mem_string;
                                     }
                                 }
                             }
                         }
                         if ($display_driver != null) {
                             break;
                         }
                     case 'radeon':
                         if (isset(phodevi::$vfs->radeon_pm_info)) {
                             // radeon_pm_info should be present with Linux 2.6.34+ but was changed with Linux 3.11 Radeon DPM
                             if (stripos(phodevi::$vfs->radeon_pm_info, 'default')) {
                                 foreach (pts_strings::trim_explode("\n", phodevi::$vfs->radeon_pm_info) as $pm_line) {
                                     if ($pm_line == null) {
                                         continue;
                                     }
                                     list($descriptor, $value) = pts_strings::colon_explode($pm_line);
                                     switch ($descriptor) {
                                         case 'default engine clock':
                                             $core_freq = pts_arrays::first_element(explode(' ', $value)) / 1000;
                                             break;
                                         case 'default memory clock':
                                             $mem_freq = pts_arrays::first_element(explode(' ', $value)) / 1000;
                                             break;
                                     }
                                 }
                             }
                             if ($core_freq == 0 && ($x = stripos(phodevi::$vfs->radeon_pm_info, 'sclk: ')) != false) {
                                 $x = substr(phodevi::$vfs->radeon_pm_info, $x + strlen('sclk: '));
                                 $x = substr($x, 0, strpos($x, ' '));
                                 if (is_numeric($x) && $x > 100) {
                                     if ($x > 10000) {
                                         $x = $x / 100;
                                     }
                                     $core_freq = $x;
                                 }
                                 if (($x = stripos(phodevi::$vfs->radeon_pm_info, 'mclk: ')) != false) {
                                     $x = substr(phodevi::$vfs->radeon_pm_info, $x + strlen('mclk: '));
                                     $x = substr($x, 0, strpos($x, ' '));
                                     if (is_numeric($x) && $x > 100) {
                                         if ($x > 10000) {
                                             $x = $x / 100;
                                         }
                                         $mem_freq = $x;
                                     }
                                 }
                             }
                         }
                         if ($core_freq == null) {
                             // Attempt to read the LAST power level reported to dmesg, this is the current way for Radeon DPM on Linux 3.11+
                             $dmesg_parse = isset(phodevi::$vfs->dmesg) ? phodevi::$vfs->dmesg : null;
                             if ($x = strrpos($dmesg_parse, ' sclk:')) {
                                 $dmesg_parse = substr($dmesg_parse, $x);
                                 $dmesg_parse = explode(' ', substr($dmesg_parse, 0, strpos($dmesg_parse, PHP_EOL)));
                                 $sclk = array_search('sclk:', $dmesg_parse);
                                 if ($sclk !== false && isset($dmesg_parse[$sclk + 1]) && is_numeric($dmesg_parse[$sclk + 1])) {
                                     $sclk = $dmesg_parse[$sclk + 1];
                                     if ($sclk > 10000) {
                                         $sclk = $sclk / 100;
                                     }
                                     $core_freq = $sclk;
                                 }
                                 $mclk = array_search('mclk:', $dmesg_parse);
                                 if ($mclk !== false && isset($dmesg_parse[$mclk + 1]) && is_numeric($dmesg_parse[$mclk + 1])) {
                                     $mclk = $dmesg_parse[$mclk + 1];
                                     if ($mclk > 10000) {
                                         $mclk = $mclk / 100;
                                     }
                                     $mem_freq = $mclk;
                                 }
                             }
                         }
                         if ($core_freq == null) {
                             // Old ugly way of handling the clock information
                             $log_parse = isset(phodevi::$vfs->xorg_log) ? phodevi::$vfs->xorg_log : null;
                             if ($engine_clock = strpos($log_parse, 'Default Engine Clock: ')) {
                                 $core_freq = substr($log_parse, $engine_clock + 22);
                                 $core_freq = substr($core_freq, 0, strpos($core_freq, "\n"));
                                 $core_freq = is_numeric($core_freq) ? $core_freq / 1000 : 0;
                                 if ($core_freq && ($mem_clock = strpos($log_parse, 'Default Memory Clock: '))) {
                                     $mem_freq = substr($log_parse, $mem_clock + 22);
                                     $mem_freq = substr($mem_freq, 0, strpos($mem_freq, "\n"));
                                     $mem_freq = is_numeric($mem_freq) ? $mem_freq / 1000 : 0;
                                 } else {
                                     $core_freq = 0;
                                 }
                             }
                         }
                         if ($display_driver != null) {
                             break;
                         }
                     case 'intel':
                         // try to read the maximum dynamic frequency
                         if (is_file('/sys/class/drm/card0/gt_max_freq_mhz')) {
                             $gt_max_freq_mhz = pts_file_io::file_get_contents('/sys/class/drm/card0/gt_max_freq_mhz');
                             if (is_numeric($gt_max_freq_mhz) && $gt_max_freq_mhz > 100) {
                                 // Tested on Linux 3.11. Assume the max frequency on any competent GPU is beyond 100MHz
                                 $core_freq = $gt_max_freq_mhz;
                             }
                         }
                         if ($core_freq == 0 && is_file('/sys/kernel/debug/dri/0/i915_max_freq')) {
                             $i915_max_freq = pts_file_io::file_get_contents('/sys/kernel/debug/dri/0/i915_max_freq');
                             $freq_mhz = substr($i915_max_freq, strpos($i915_max_freq, ': ') + 2);
                             if (is_numeric($freq_mhz)) {
                                 $core_freq = $freq_mhz;
                             }
                         }
                         // Fallback to base frequency
                         if ($core_freq == 0 && isset(phodevi::$vfs->i915_cur_delayinfo)) {
                             $i915_cur_delayinfo = phodevi::$vfs->i915_cur_delayinfo;
                             $freq = strpos($i915_cur_delayinfo, 'Max overclocked frequency: ');
                             if ($freq === false) {
                                 $freq = strpos($i915_cur_delayinfo, 'Max non-overclocked (RP0) frequency: ');
                             }
                             if ($freq === false) {
                                 $freq = strpos($i915_cur_delayinfo, 'Nominal (RP1) frequency: ');
                             }
                             if ($freq !== false) {
                                 $freq_mhz = substr($i915_cur_delayinfo, strpos($i915_cur_delayinfo, ': ', $freq) + 2);
                                 $freq_mhz = trim(substr($freq_mhz, 0, strpos($freq_mhz, 'MHz')));
                                 if (is_numeric($freq_mhz)) {
                                     $core_freq = $freq_mhz;
                                 }
                             }
                         }
                         if ($display_driver != null) {
                             break;
                         }
                 }
             }
         }
     }
     $core_freq = !is_numeric($core_freq) ? 0 : round($core_freq);
     $mem_freq = !is_numeric($mem_freq) ? 0 : round($mem_freq);
     return array($core_freq, $mem_freq);
 }
 public function execute_script($pass_arguments = null)
 {
     if ($this->script_file == null) {
         return false;
     }
     $script_contents = file_get_contents($this->script_file);
     $prev_exit_status = 0;
     $script_pointer = -1;
     do {
         $exit_status = 0;
         if ($prev_exit_status != 0) {
             $exit_status = $prev_exit_status;
             $prev_exit_status = 0;
         }
         $script_contents = substr($script_contents, $script_pointer + 1);
         $line = $script_contents;
         $prev_script_pointer = $script_pointer;
         if (($script_pointer = strpos($line, "\n")) !== false) {
             $line = substr($line, 0, $script_pointer);
         }
         $line_r = $line != null ? pts_strings::trim_explode(' ', $line) : null;
         switch (isset($line_r[0]) ? $line_r[0] : null) {
             case '':
                 break;
             case 'mv':
                 // TODO: implement folder support better
                 $line_r[1] = $this->get_real_path($line_r[1], $pass_arguments);
                 $line_r[2] = $this->get_real_path($line_r[2], $pass_arguments);
                 //pts_file_io::delete($line_r[2], null, true);
                 //copy($line_r[1], $line_r[2] . (is_dir($line_r[2]) ? basename($line_r[1]) : null));
                 //pts_file_io::delete($line_r[1], null, true);
                 rename($line_r[1], $line_r[2] . (is_dir($line_r[2]) ? basename($line_r[1]) : null));
                 break;
             case 'cp':
                 // TODO: implement folder support better
                 $line_r[1] = $this->get_real_path($line_r[1], $pass_arguments);
                 $line_r[2] = $this->get_real_path($line_r[2], $pass_arguments);
                 copy($line_r[1], $line_r[2] . (is_dir($line_r[2]) ? basename($line_r[1]) : null));
                 break;
             case 'cat':
                 // TODO: implement folder support better
                 $line_r[1] = $this->get_real_path($line_r[1], $pass_arguments);
                 $line_r[3] = $this->get_real_path($line_r[3], $pass_arguments);
                 copy($line_r[1], $line_r[3]);
                 break;
             case 'cd':
                 if ($line_r[1] == '..') {
                     if (substr($this->var_current_directory, -1) == '/') {
                         $this->var_current_directory = substr($this->var_current_directory, 0, -1);
                     }
                     $this->var_current_directory = substr($this->var_current_directory, 0, strrpos($this->var_current_directory, '/') + 1);
                 } else {
                     if ($line_r[1] == '~') {
                         $this->var_current_directory = $this->environmental_variables["HOME"];
                     } else {
                         if (substr($line_r[1], 0, 1) == '"') {
                             // On Windows some directories are encased in quotes for spaces in the directory names
                             array_shift($line_r);
                             $this->var_current_directory = implode(' ', $line_r);
                         } else {
                             if (is_readable($line_r[1])) {
                                 $this->var_current_directory = $line_r[1];
                             } else {
                                 if (is_readable($this->get_real_path($line_r[1], $pass_arguments))) {
                                     $this->var_current_directory = $this->get_real_path($line_r[1], $pass_arguments);
                                 }
                             }
                         }
                     }
                 }
                 break;
             case 'touch':
                 if (!is_file($this->var_current_directory . $line_r[1]) && is_writable($this->var_current_directory)) {
                     touch($this->var_current_directory . $line_r[1]);
                 }
                 break;
             case 'mkdir':
                 pts_file_io::mkdir($this->var_current_directory . $line_r[1]);
                 break;
             case 'rm':
                 for ($i = 1; $i < count($line_r); $i++) {
                     if (is_file($this->var_current_directory . $line_r[$i])) {
                         unlink($this->var_current_directory . $line_r[$i]);
                     } else {
                         if (is_dir($this->var_current_directory . $line_r[$i])) {
                             pts_file_io::delete($this->var_current_directory . $line_r[$i], null, true);
                         }
                     }
                 }
                 break;
             case 'chmod':
                 $chmod_file = self::find_file_in_array($line_r);
                 if ($chmod_file) {
                     chmod($chmod_file, 0755);
                 }
                 break;
             case 'unzip':
                 $zip_file = self::find_file_in_array($line_r);
                 pts_compression::zip_archive_extract($zip_file, $this->var_current_directory);
                 break;
             case 'tar':
                 // TODO: implement
                 break;
             case 'echo':
                 if ($line == "echo \$? > ~/install-exit-status") {
                     file_put_contents($this->var_current_directory . "install-exit-status", $exit_status);
                     break;
                 } else {
                     if ($line == "echo \$? > ~/test-exit-status") {
                         file_put_contents($this->var_current_directory . "test-exit-status", $exit_status);
                         break;
                     }
                 }
                 $start_echo = strpos($script_contents, "\"") + 1;
                 $end_echo = $start_echo - 1;
                 do {
                     $end_echo = strpos($script_contents, "\"", $end_echo + 1);
                 } while ($script_contents[$end_echo - 1] == "\\");
                 $script_pointer = strpos($script_contents, "\n", $end_echo);
                 $line_remainder = substr($script_contents, $end_echo + 1, $script_pointer - $end_echo - 1);
                 $echo_contents = substr($script_contents, $start_echo, $end_echo - $start_echo);
                 $this->parse_variables_in_string($echo_contents, $pass_arguments);
                 $echo_contents = str_replace("\\\$", "\$", $echo_contents);
                 $echo_contents = str_replace("\\\"", "\"", $echo_contents);
                 if (($to_file = strpos($line_remainder, ' > ')) !== false) {
                     $to_file = trim(substr($line_remainder, $to_file + 3));
                     if (($end_file = strpos($to_file, ' ')) !== false) {
                         $to_file = substr($to_file, 0, $end_file);
                     }
                     // TODO: right now it's expecting the file location pipe to be relative location
                     $echo_dir = pts_strings::add_trailing_slash(str_replace('"', null, $this->var_current_directory));
                     // needed for phodevi::is_windows() specviewperf10
                     file_put_contents($echo_dir . $to_file, $echo_contents . "\n");
                 } else {
                     echo $echo_contents;
                 }
                 break;
             case '#!/bin/sh':
             case '#':
             case null:
                 // IGNORE
                 break;
             case 'case':
                 //echo "\nUNHANDLED EVENT\n";
                 return false;
                 // TODO: decide how to handle
                 break;
             default:
                 $exec_output = array();
                 if (phodevi::is_windows() && substr($line, 0, 2) == "./") {
                     $line = substr($line, 2);
                 }
                 $this->parse_variables_in_string($line, $pass_arguments);
                 $cd_dir = $this->var_current_directory;
                 if (phodevi::is_windows() && strpos($cd_dir, ':\\') === 1) {
                     $cd_dir = str_replace('/', '\\', $cd_dir);
                     $cd_dir = str_replace('\\\\', '\\', $cd_dir);
                 }
                 exec("cd " . $cd_dir . " && " . $line . " 2>&1", $exec_output, $prev_exit_status);
                 break;
         }
     } while ($script_contents != false);
 }
 public function triggered_system_error($level, $message, $file, $line)
 {
     echo PHP_EOL . '[' . $level . '] ';
     if (strpos($message, PHP_EOL) === false) {
         echo $message . ' ';
     } else {
         foreach (pts_strings::trim_explode(PHP_EOL, $message) as $line_count => $line_string) {
             // ($line_count > 0 ? $this->tab : null)
             echo $line_string . PHP_EOL . str_repeat(' ', strlen($level) + 3);
         }
     }
     if ($file != null) {
         echo 'in ' . basename($file, '.php');
     }
     if ($line != 0) {
         echo ':' . $line;
     }
     echo PHP_EOL;
 }
 public static function prompt_text_menu($user_string, $options_r, $allow_multi_select = false, $return_index = false, $line_prefix = null)
 {
     $option_count = count($options_r);
     if ($option_count == 1) {
         return $return_index ? pts_arrays::last_element(array_keys($options_r)) : array_pop($options_r);
     }
     $select = array();
     do {
         echo PHP_EOL;
         $key_index = array();
         foreach (array_keys($options_r) as $i => $key) {
             $key_index[$i + 1] = $key;
             echo $line_prefix . ($i + 1) . ': ' . str_repeat(' ', strlen($option_count) - strlen($i + 1)) . $options_r[$key] . PHP_EOL;
         }
         echo $line_prefix . $user_string . ': ';
         $select_choice = pts_user_io::read_user_input();
         foreach ($allow_multi_select ? pts_strings::comma_explode($select_choice) : array($select_choice) as $choice) {
             if (in_array($choice, $options_r)) {
                 $select[] = array_search($choice, $options_r);
             } else {
                 if (isset($key_index[$choice])) {
                     $select[] = $key_index[$choice];
                 } else {
                     if ($allow_multi_select && strpos($choice, '-') !== false) {
                         $choice_range = pts_strings::trim_explode('-', $choice);
                         if (count($choice_range) == 2 && is_numeric($choice_range[0]) && is_numeric($choice_range[1]) && isset($key_index[$choice_range[0]]) && isset($key_index[$choice_range[1]])) {
                             for ($i = min($choice_range); $i <= max($choice_range); $i++) {
                                 $select[] = $key_index[$i];
                             }
                         }
                     }
                 }
             }
         }
     } while (!isset($select[0]));
     if ($return_index == false) {
         foreach ($select as &$index) {
             $index = $options_r[$index];
         }
     }
     return implode(',', $select);
 }
 public static function parse_value_string_vars($value_string)
 {
     $values = array();
     foreach (explode(';', $value_string) as $preset) {
         if (count($preset = pts_strings::trim_explode('=', $preset)) == 2) {
             $values[$preset[0]] = $preset[1];
         }
     }
     return $values;
 }