summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Hutterer <peter.hutterer@who-t.net>2011-07-22 16:38:21 +1000
committerPeter Hutterer <peter.hutterer@who-t.net>2011-07-26 13:18:57 +1000
commite96b8ba5e703af0ccde30ecf86dc1674f7654ae7 (patch)
treef06cfdec6c08d6f8645474e20d3807e6c82a7544
parent500950a925c3b8f6c7235ae4a1dfc7892f955581 (diff)
XOrg: add the start of an xorg.log parser
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
-rw-r--r--XOrg/Module.pm81
-rwxr-xr-xXOrg/xorglog.pm216
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: