Friday, January 16, 2009

mmap_test.py

Another program out of boredem. For my CSE451 class, I was reading about IPC, and SHM and mmap() were discussed in the text. Thus, I looked into Python's support, and it looks like mmap() is included. The program here is essentially a "deranged cat," which uses two processes for no reason:

mmap_test.py

#!/usr/bin/python
from mmap import mmap
from os import fork, waitpid, WEXITSTATUS
from sys import exit, stdin

map = mmap(-1, 1024)
map.seek(0)
map.write_byte(chr(0))

pid = fork()
if pid == 0:
while True:
map.seek(0)
b = map.read_byte()
while b == chr(0):
map.seek(0)
b = map.read_byte()
if b == chr(3):
break
else:
print map.readline().rstrip()
map.seek(0)
map.write_byte(chr(0))
exit(0)._exit()
else:
while True:
st = stdin.readline(1022)
if st == '':
map.seek(0)
map.write_byte(chr(3))
break
else:
map.seek(1)
map.write(st)
map.seek(0)
map.write_byte(chr(1))

map.seek(0)
while map.read_byte() == chr(1):
map.seek(0)

id, status = waitpid(pid, 0)
map.close()
print 'Child exited with', WEXITSTATUS(status)

Tuesday, January 13, 2009

txp.pl/ctxp.pl

With a little bit of free time today, I decided to write something similar to TextExpander in Perl. Using getc and setc, it'll put and read from the clipboard of your GUI, respectively:

txp.pl

#!/usr/bin/perl -w
use strict;
use warnings;
use utf8;
use Clipboard;
use DBI;

my $usage = ($0 eq 'ctxp.pl' and "Usage: $0 key\n" or "Usage: $0 [ set key value | setf key | setf key | unset key | get key | getc key | list ]\n");

scalar @ARGV || die $usage;
my $action = shift @ARGV;

my $dbh = DBI->connect('dbi:SQLite:dbname=' . $ENV{HOME} . '/.txp_db', '', '');
$dbh->do('CREATE TABLE IF NOT EXISTS expanders(id INTEGER PRIMARY KEY AUTOINCREMENT, key VARCHAR(64), value TEXT)');



sub set_or_add {
my ($dbh, $key, $value) = @_;
if(scalar @{$dbh->selectall_arrayref('SELECT id FROM expanders WHERE key = ?', undef, $key)}) {
$dbh->do('UPDATE expanders SET value = ? WHERE key = ?', undef, $value, $key);
}
else {
$dbh->do('INSERT INTO expanders(key, value) VALUES(?, ?)', undef, $key, $value);
}
}
sub unset {
my ($dbh, $key) = @_;
my $sth = $dbh->prepare('DELETE FROM expanders WHERE key = ?');
$sth->execute($key);
return $sth->rows;
}
sub get {
my ($dbh, $key) = @_;
my $value = undef;
my $row = $dbh->selectrow_arrayref('SELECT * FROM expanders WHERE key = ?', undef, $key);
($value = ${$row}[2]) if($row);
return $value;
}

if($0 eq 'ctxp.pl') {
my $key = $action;
my $value = get($dbh, $key);
Clipboard->copy($value) if($value);
}
elsif($action eq 'set' and scalar @ARGV == 2) {
my ($key, $value) = @ARGV;
chomp($value);
set_or_add($dbh, $key, $value);
}
elsif($action eq 'setf' and scalar @ARGV == 1) {
my $key = shift @ARGV;
my @lines = <STDIN>;
my $value = join('', @lines);
chomp($value);
set_or_add($dbh, $key, $value);
}
elsif($action eq 'setc' and scalar @ARGV == 1) {
my $key = shift @ARGV;
my $value = Clipboard->paste();
chomp($value);
set_or_add($dbh, $key, $value);
}
elsif($action eq 'unset' and scalar @ARGV == 1) {
my $key = shift @ARGV;
my $count = unset($dbh, $key);
print "$count rows affected.\n";
}
elsif($action eq 'get' and scalar @ARGV == 1) {
my $key = shift @ARGV;
my $value = get($dbh, $key);
if($value) {
print "$value\n";
}
else {
print STDERR "No matches found for $key\n";
}
}
elsif($action eq 'getc' and scalar @ARGV == 1) {
my $key = shift @ARGV;
my $value = get($dbh, $key);
if($value) {
print "$value\n";
Clipboard->copy($value);
}
else {
print STDERR "No matches found for $key\n";
}
}
elsif($action eq 'list' and scalar @ARGV == 0) {
my $rows = $dbh->selectall_arrayref('SELECT * FROM expanders');
if(scalar @{$rows}) {
(print ${$_}[1] . ' => ' . ${$_}[2] . "\n") foreach(@{$rows});
}
else {
print STDERR "No mappings present.\n";
}
}
else {
print STDERR $usage;
}




$dbh->disconnect();
% perl txp.pl list
cows => How now brown cow.
nante => 何てね
% perl txp.pl unset cows
1 rows affected.
% echo 'Foos are bars.' | perl txp.pl setf foo
% perl txp.pl list
nante => 何てね
foo => Foos are bars.
% perl txp.pl set argv "Arrrgh."
% perl txp.pl list
nante => 何てね
foo => Foos are bars.
argv => Arrrgh.

safecp

After destroying an rc.lua for Awesome, I was motivated to write this simple script. It skips overwriting all files, unlike cp:

safecp

#!/usr/bin/python
from os import path
from sys import stderr, exit, argv
from shutil import copy, copytree

copymethod = copy
if len(argv) == 3:
src, dest = argv[1:3]
src, dest = unicode(src, 'utf8'), unicode(dest, 'utf8')
if path.exists(src):
if path.isdir(src):
print >>stderr, u'Copying directory recursively:', src
copymethod = copytree
if (not path.exists(dest)) or path.isdir(dest):
copymethod(src, dest)
else:
print >>stderr, u'Not overwriting existing file:', dest
exit(3)
else:
print >>stderr, u'File not found:', src
exit(2)
elif len(argv) > 3:
dest = unicode(argv.pop(), 'utf8')
src = argv[1:]
if path.isdir(dest):
for s in src:
s = unicode(s, 'utf8')
copymethod = copy
target = path.join(dest, path.basename(s))
if path.isdir(s):
print >>stderr, u'Copying directory recursively:', s
copymethod = copytree
if not path.exists(target):
copymethod(s, target)
else:
print >>stderr, u'Not overwriting existing file or directory:', target
else:
print >>stderr, u'Destination must be directory:', dest
exit(2)
else:
print >>stderr, u'Usage: %s src1 [ src2 [ src3 [ ... ]]] dest' % argv[0]
exit(1)