diff options
author | Peter Hutterer <peter.hutterer@who-t.net> | 2011-07-22 16:38:21 +1000 |
---|---|---|
committer | Peter Hutterer <peter.hutterer@who-t.net> | 2011-07-26 13:18:57 +1000 |
commit | e96b8ba5e703af0ccde30ecf86dc1674f7654ae7 (patch) | |
tree | f06cfdec6c08d6f8645474e20d3807e6c82a7544 /XOrg | |
parent | 500950a925c3b8f6c7235ae4a1dfc7892f955581 (diff) |
XOrg: add the start of an xorg.log parser
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Diffstat (limited to 'XOrg')
-rw-r--r-- | XOrg/Module.pm | 81 | ||||
-rwxr-xr-x | XOrg/xorglog.pm | 216 |
2 files changed, 297 insertions, 0 deletions
diff --git a/XOrg/Module.pm b/XOrg/Module.pm new file mode 100644 index 0000000..d437373 --- /dev/null +++ b/XOrg/Module.pm @@ -0,0 +1,81 @@ +#!/usr/bin/perl + +# Copyright © 2011 by Red Hat, Inc. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# Authors: Peter Hutterer <peter.hutterer@redhat.com> + + +# X.Org driver module + +package Module; +use Carp; +use warnings; +use strict; + +# Instance methods +sub new { + my $class = shift; + my $self = {@_}; + bless ($self, $class); +} + +# Module name +sub name { + my $self = shift; + my $name = shift; + + $self->{name} = $name if defined $name; + return $self->{name}; +} + +# Version triplet of the module (2, 3, 0) for 2.3.0 +sub version { + my $self = shift; + my $major = shift; + my $minor = shift; + my $patchlevel = shift; + + if (defined $major and defined $minor) { + $patchlevel = 0 if not defined $patchlevel; + $self->{version} = [($major, $minor, $patchlevel)]; + } + return $self->{version}; +} + +# ABI is a list of 3, e.g. ("input", 12, 2) for input ABI 12.2 +sub abi { + my $self = shift; + my $type = shift; + my $major = shift; + my $minor = shift; + + $self->{abi} = [($type, $major, $minor)]; + return $self->{abi}; +} + +# Path to module +sub path { + my $self = shift; + my $path = shift; + + $self->{path} = $path if defined $path; + return $self->{path}; +} + +1; + +# vim: set noexpandtab shiftwidth=8 tabstop=8: diff --git a/XOrg/xorglog.pm b/XOrg/xorglog.pm new file mode 100755 index 0000000..f3f2c54 --- /dev/null +++ b/XOrg/xorglog.pm @@ -0,0 +1,216 @@ +#!/usr/bin/perl + +# Copyright © 2011 by Red Hat, Inc. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# Authors: Peter Hutterer <peter.hutterer@redhat.com> + + +# Xorg.log parser + +package xorglog; + +use Module; +use warnings; +use strict; +use Carp; +use Data::Dumper; + +my $default_logfile = "/var/log/Xorg.0.log"; +my $time_regex = '^\[\d+\.\d+\]'; + +# Instance methods +sub new { + my $class = shift; + my $self = {@_}; + bless ($self, $class); + + if (not defined $self->{file}) { + carp "Filename is missing, using default filename $default_logfile.\n"; + $self->{file} = $default_logfile; + } + + my $file = $self->{file}; + + if (not -e $file) { + croak "File '$file' doesn't exist.\n"; + } + + $self->{modules} = {}; + $self->_parse($file); + + return $self; +} + +sub version { + my $self = shift; + my $major = shift; + my $minor = shift; + my $patchlevel = shift; + + if (defined $major) { + if (not defined $minor or not defined $patchlevel) { + croak "Invalid version number. Need 3 components.\n"; + return; + } + $self->{version} = [($major, $minor, $patchlevel)]; + } + + return $self->{version}; +} + +sub build_id { + my $self = shift; + my $build_id = shift; + + $self->{build_id} = $build_id if defined $build_id; + return $self->{build_id}; +} + +sub config_backend { + my $self = shift; + my $config_backend = shift; + + $self->{config_backend} = $config_backend if defined $config_backend; + return $self->{config_backend}; +} + +sub modules { + my $self = shift; + return $self->{modules}; +} + +# Returns 1/0 if AutoAddDevices is on/off. +sub auto_add_devices { + my $self = shift; + my $auto_add_devices = shift; + + $self->{auto_add_devices} = $auto_add_devices if defined $auto_add_devices; + return $self->{auto_add_devices}; +} + +# Internal functions +sub _parse_version { + my $self = shift; + my $line = shift; + + if ($line =~ /^X.Org X Server (\d+)\.(\d+)\.(\d+)/) { + $self->version($1, $2, $3); + return 1; + } + return 0; +} + +sub _parse_build_id { + my $self = shift; + my $line = shift; + + if ($line =~ /$time_regex Build ID: (.*)[ ]+/) { + $self->build_id($1); + return 1; + } + return 0; +} + +sub _parse_auto_add_devices { + my $self = shift; + my $line = shift; + + if ($line =~ /$time_regex \(==\) (Not a|A)utomatically adding devices/) { + $self->auto_add_devices(($1 cmp "A") == 0); + return 1; + } + return 0; +} + +sub _parse_config_backend { + my $self = shift; + my $log = shift; + + for (@{$log}) { + if ($_ =~ /$time_regex \(II\) The server relies on (udev|hal) to provide .*/) { + $self->config_backend($1); + last; + } + } +} + +sub _parse_modules { + my $self = shift; + my $log = shift; + my $current_module; + + # Each device has a "Loading /path/to/module/ line, that may overwrite + # the actual path to the module. Ignore all butthe next 4 lines after LoadModule: + my $i = 0; + while ($i < $#{$log}) { + my $line = $log->[$i++]; + if ($line =~ /$time_regex \(II\) LoadModule: \"(.*)\"/) { + $current_module = Module->new(name => $1); + $self->{modules}->{$1} = $current_module; + + my $j = 4; # 4 extra module lines after the LoadModule output + while ($j-- > 0) { + $line = $log->[$i++]; + if ($line =~ /$time_regex \(II\) Loading \/(.*)/) { + $current_module->path("/".$1) if defined $current_module; + } elsif ($line =~ /$time_regex.*, module version = (\d+).(\d+).(\d+)/) { + $current_module->version($1, $2, $3) if defined $current_module; + } elsif ($line =~ /$time_regex\s+ABI class: X.Org (Server Extension|Video Driver|Input Driver), version (\d+).(\d+)/) { + my $type; + $type = "extension" if ($1 eq "Server Extension"); + $type = "video" if ($1 eq "Video Driver"); + $type = "input" if ($1 eq "Input Driver"); + $current_module->abi($type, $2, $3); + } + } + } + } +} + +sub _parse { + my $self = shift; + my $file = shift; + + open XLOG, $file or croak "Failed to open file '$file'\n"; + my @log = <XLOG>; + + # Parse stuff that's always there + my $i = 0; + while ($i < $#log) { + while ($i < $#log) { + last if ($self->_parse_version($log[$i++])); + } + while ($i < $#log) { + last if ($self->_parse_build_id($log[$i++])); + } + while ($i < $#log) { + last if ($self->_parse_auto_add_devices($log[$i++])); + } + } + + # Stuff that _may_ be in the log, need to search the whole log for it. + $self->_parse_config_backend(\@log); + $self->_parse_modules(\@log); +} + + +my $xlog = xorglog->new(file => "/var/log/Xorg.0.log"); +print Dumper($xlog); + +1; + +# vim: set noexpandtab shiftwidth=8 tabstop=8: |