summaryrefslogtreecommitdiff
path: root/p
diff options
context:
space:
mode:
authorschodet2005-07-29 22:27:52 +0000
committerschodet2005-07-29 22:27:52 +0000
commit98fa1a95ba5cf876691e56a0ab75673516b86f9e (patch)
tree576ee3ccf60599a9943d43532e90baadf7bfbc41 /p
parent62662d162c217d2457df4abb9355165b79de816d (diff)
Première version de l'analyseur de todo.
Diffstat (limited to 'p')
-rw-r--r--p/todo/todo.pl99
1 files changed, 99 insertions, 0 deletions
diff --git a/p/todo/todo.pl b/p/todo/todo.pl
new file mode 100644
index 0000000..31e55da
--- /dev/null
+++ b/p/todo/todo.pl
@@ -0,0 +1,99 @@
+#!/usr/bin/perl -w
+#
+# Tool to parse todo files.
+#
+use strict;
+
+# Parse a todo file and add tasks to \%todos.
+sub parse_todo
+{
+ my ($todos, $path, $file) = @_;
+ my $owner;
+ local $_;
+ local *FILE;
+ # Check for duplicates and create task list.
+ die "duplicate path: $path" if exists $$todos{''};
+ $$todos{''} = [ ];
+ my $tasks = $$todos{''};
+ # Open file.
+ open FILE, "<$file" or die "$file: $!";
+ # Read each lines.
+ while (<FILE>)
+ {
+ chomp;
+ # Task line.
+ /^([-+=x]) (?:\(([^)]+)\) |)(.+)$/ and do {
+ my ($state, $owner, $text) = ($1, $2 || $owner, $3);
+ #$owner = $1 if $2 =~ /^\((.*)\) $/;
+ my @owners = split /, */, $owner;
+ # Read next lines.
+ while (<FILE>)
+ {
+ chomp;
+ # Continued task, new paragraph.
+ /^ $/ and $text .= "\n", next;
+ # Continued task.
+ /^ (.*)$/ and $text .= ' ' . $1, next;
+ last;
+ }
+ # Add task.
+ push @$tasks, {
+ state => $state,
+ owner => [ @owners ],
+ text => $text
+ };
+ last unless defined $_;
+ redo;
+ };
+ # Default owner line.
+ /^\(([^)]+)\)$/ and $owner = $1, next;
+ # Subtask line.
+ /^[-\w\d]+$/ and do {
+ my $path = $path . '/' . $_;
+ $$todos{$_} ||= { };
+ my $todos = $$todos{$_};
+ die "duplicate path: $path" if exists $$todos{''};
+ $$todos{''} = [ ];
+ $tasks = $$todos{''};
+ next;
+ };
+ # Empty line.
+ /^$/ and next;
+ # Else, die.
+ die 'Invalid format';
+ }
+ # Close file.
+ close FILE;
+}
+
+# Read dir and parse each todo files it contains.
+sub parse_dir
+{
+ my ($todos, $path, $dir) = @_;
+ local $_;
+ local @_;
+ local *DIR;
+ # Read files list.
+ opendir DIR, $dir or die "$dir: $!";
+ @_ = readdir DIR;
+ closedir DIR;
+ # Filter todo files & dirs lists.
+ my @todofiles = grep { !/^\./ && /\.todo$/ && -f "$dir/$_" } @_;
+ s/\.todo$// foreach @todofiles;
+ my @tododirs = grep { !/^\./ && -d "$dir/$_" } @_;
+ # Create empty hashes.
+ $$todos{$_} ||= { } foreach @todofiles, @tododirs;
+ # Process each todo files.
+ parse_todo ($$todos{$_}, "$path/$_", "$dir/$_.todo") foreach @todofiles;
+ # Recurse into each dirs.
+ parse_dir ($$todos{$_}, "$path/$_", "$dir/$_") foreach @tododirs;
+}
+
+my %todos;
+
+parse_dir (\%todos, '', '.');
+
+{
+ use Data::Dumper;
+ print Dumper \%todos;
+}