警告: 不明なエスケープシーケンス '\d'

表題はLANG=Cなら「warning: unknown escape sequence '\d'」。
GRegex(GLibの正規表現)の一般キャラクタタイプ(整数を表す「\d」など)が使えなくて悩んでいた。

#include <glib.h>
int main(int argc, char *argv[])
{
  GRegex *reg;
  GError *error = NULL;
  reg = g_regex_new ("\d\D\s\S\w\W",
                     0,
                     0, /* match flag */
                     &error);
  return 0;
}

このようなコードを用意してコンパイルすると、


$ []gcc `pkg-config --cflags --libs glib-2.0` sample.c[]
[]sample.c:6:22: 警告: 不明なエスケープシーケンス '\d'[]
[]sample.c:6:22: 警告: 不明なエスケープシーケンス '\D'[]
[]sample.c:6:22: 警告: 不明なエスケープシーケンス '\s'[]
[]sample.c:6:22: 警告: 不明なエスケープシーケンス '\S'[]
[]sample.c:6:22: 警告: 不明なエスケープシーケンス '\w'[]
[]sample.c:6:22: 警告: 不明なエスケープシーケンス '\W'[]
となってしまう。このためX11 Mouse Cursor plug-in for GIMPでは「\d」のかわりに「[:digit:]」を使っていた。おそらくかなり初歩的な見落としがあるのだろうと思ったがどうしてもわからないためgtk-app-devel-listに質問して見たところ、Cでは「\」は特別な意味があるので「\\」と書かないといけないよと教えていただいた。orz...
いろいろ検索しても同じところで悩んでいるケースを見つけられなかったので、こんなアホなところではまっていたのは自分だけなのかもしれないが後に続く人のためにここに記す・・・。

Icon Theme Updater 0.8.1 をリリース

Icon Theme Updater 0.8.1 をリリースした。今回はicon-naming-utilsに含まれる「icon-name-mapping(XML:Simpleを使ったPerlスクリプト)」を使う代わりにPythonのネイティブなコードでシンボリックリンクを張ることでかなり動作が速くなった。
ついでに以下のようなBashスクリプトを作って自動テストを行えるようにした。

#!/bin/bash
#カレントディレクトリのアイコンテーマを展開して
#iconup.pyをかけた後で~/.iconsに移動する

for tgz in *.tar.gz; do
  directory=$(tar zxvf ${tgz} |sed -rn '1s@([^/]+).*@\1@p')
  cd $directory
  ~/IconThemeUpdater/iconup.py
  if [ ! $? ] ; then exit 1; fi
  cd ..
  rm -rf /home/tks/.icons/$directory
  mv $directory /home/tks/.icons/
done
for tbz in *.tar.bz2; do
  directory=$(tar jxvf ${tbz} |sed -rn '1s@([^/]+).*@\1@p')
  cd $directory
  ~/IconThemeUpdater/iconup.py
  if [ ! $? ] ; then exit 1; fi
  cd ..
  rm -rf /home/tks/.icons/$directory
  mv $directory /home/tks/.icons/
done

Icon Theme Updater 0.8 をリリース

Icon Theme Updater 0.8をリリースした。Gnome-Look.orgからダウンロードできる。
これは古いアイコンテーマを自動でアップデートし、新しいデスクトップ環境やソフトウェアでも適切なアイコンを表示できるようにするPythonスクリプトである。(スクリーンショット参照)
GNOME/GTK+アプリだけでなくKDE/QTアプリでも動くことを目標にしているがまだ試していない。

既にicon-naming-utilsというPerlスクリプトがあり、これは新しいアイコンの名前に対して古い名前のシンボリックリンクを張り、古いソフトウェアに新しいアイコンテーマが適切なアイコンを提供できるようにするものである。
これに対してIcon Theme Updater 0.8icon-naming-utilsの持っているデータベースを利用して古い名前のアイコンを新しい名前(パス)に移動する*1ことで古いアイコンテーマをアップデートしあたらしいソフトウェアに対応させる。
ただしこのデータベースはかなり抜けている部分が多くあまりメンテナンスされていない様なので、これを補完する自前の物もアーカイブに入れてある。自前のデータもかなり足りないし間違っている物もあると思われるので何か見つけた人にはコメントで知らせて欲しい。

関連記事:xml.parsers.expatのよくわからない挙動

*1:その後でicon-naming-utilsを走らせ後方互換性も確保している

xml.parsers.expatのよくわからない挙動

icon-naming-utilsに含まれる「legacy-icon-mapping.xml」をxml.parsers.expatを使ってパースし、
「link要素の値」->(「context要素のdir属性」, 「icon要素のname属性」)
となる辞書を返すpythonスクリプトを書いてみた。
iconmap2.py:

# -*- coding: utf-8 -*-
from __future__ import with_statement
from xml.parsers.expat import ParserCreate

_cnt = ""
_name = ""
_data = ""
_dict = {}

def make(buf=False):
  """Make database which is accessible by Databese.dict"""
  global _cnt
  global _name
  global _data
  global _dict
  map_file = "/usr/share/icon-naming-utils/legacy-icon-mapping.xml"

  p = ParserCreate()
  p.buffer_text = buf
  p.StartElementHandler = start_element
  p.EndElementHandler = end_element
  p.CharacterDataHandler = char_data

  try:
    with open(map_file, 'rb') as f:
      p.ParseFile(f)
  except IOError,  err:
    print err

  return _dict

def start_element(name, attrs):
  global _cnt
  global _name
  if name == 'context':
    _cnt = attrs["dir"]
  if name == 'icon':
    _name = attrs["name"]
    _dict[_name] = (_cnt, _name)

def end_element(name):
  global _cnt
  global _name
  global _data
  if name == 'link':
    _dict[_data] = (_cnt, _name)

def char_data(data):
  global _data
  _data = data.strip()

legacy-icon-mapping.xml

<?xml version="1.0" standalone="yes" ?>
<!DOCTYPE mapping SYSTEM "legacy-icon-mapping.dtd">

<mapping>
    <context dir="actions">
	<icon name="address-book-new">
	    <link>stock_new-address-book</link>
	</icon>
<!-- 中略 -->
	<icon name="view-sort-descending">
	    <link>gtk-sort-descending</link>
	</icon>
<!-- 中略 -->
    </context>
<!-- 中略 -->
</mapping>
>>> import mapdict2
>>> a = mapdict2.make()
>>> a["stock_new-address-book"]
(u'actions', u'address-book-new')

一見うまくいっているが実は反される辞書の一部のkeyが壊れており、インスタンスの「buffer_text」属性をTrueにすることでこれを防ぐことができる。

>>> reload(mapdict2) # reloadしないと次のmapdict2.make()でさっきのaも変更されてしまう。
>>> b = mapdict2.make(True) # 今度はbuffer_text=Trueで
>>> set(b.keys())-set(a.keys()) # 辞書のkeyを比べてみると・・・、
set([u'stock_text_right', u'gnome-mime-application-vnd.stardivision.calc', u'gtk-sort-descending'])
>>> set(a.keys())-set(b.keys())
set([u'rt-descending', u'ock_text_right', u'lc'])
buffer_text=True buffer_text=False
stock_text_right ock_text_right
gnome-mime-application-vnd.stardivision.calc lc
gtk-sort-descending rt-descending

上記3つのkeyがおかしくなっていた。python 3.0でもこの結果は同じだった。これはやはりexpatのバグなのだろうか?

使用したpythonのバージョン: 2.5.2


2009/01/25追記
解決した

kernel-2.6.27.9-159.fc10.i686でイヤホンが無音に

今日アップデートされたkernel-2.6.27.9-159.fc10.i686で起動してみたら、一見正常に動作しているように見えてイヤホンから音が出なくなった。スピーカからは音が出ている。Fedora Update Systemのコメントを見て気づいた。おそらく関連するBugzillaの報告と同じlspciの結果がVostro1400でも出ている。


$ []lspci -l[]
[]00:1b.0 Audio device: Intel Corporation 82801H (ICH8 Family) HD Audio Controller (rev 02)[]
セキュリティアップデートだが緊急性は低いとのことなのでとりあえず旧バージョンで過ごすことにする。
/etc/yum.conf:

[main]
cachedir=/var/cache/yum
#...中略...
exclude=kernel-2.6.27.9-159.fc10 kernel-devel-2.6.27.9-159.fc10

make: *** No rule to make target `scavenger.man', needed by `scavenger._man'.

tksmashiw2008-12-19

Fedora 10 に移行してgcc のバージョンが4.3 になったので、2008-07-12 internal compiler error: in build2_stat, at tree.c:3116でチャレンジしたScavenger for X WindowsのビルドにFedora 10 で再チャレンジした。


$ []rpm -q gcc[]
[]gcc-4.3.2-7.i386[]
$ []tar zxf xscavenger-1.4.4.tgz[]
$ []cd xscavenger-1.4.4[]
$ []cd src[]
$ []xmkmf[]
[]imake -DUseInstalled -I/usr/share/X11/config[]
$ []make[]
[]...省略...[]
[]make: *** No rule to make target `scavenger.man', needed by `scavenger._man'. Stop.[]
[]LANG=ja_JP.UTF-8なら「make: *** `scavenger._man' に必要なターゲット `scavenger.man'[]
[] を make するルールがありません. 中止.」[]
$ []ln -s scavenger.6 scavenger.man[] []scavenger.6へリンクをはる。[]
$ []make[]
[]...省略...[]
$ []sudo paco -lp xscavenger-1.4.4 'make install'[] []pacoでログを採りつつインストール[]
[]...省略...[]
$ []paco -f xscavenger[]
[]xscavenger-1.4.4:[]
[]/usr/bin/scavenger[]
[]/usr/lib/X11/scavenger/badguy.lbm[]
[]/usr/lib/X11/scavenger/brownblue.lbm[]
[]以下、「/usr/lib/X11/scavenger/」にインストールされたファイルが表示される。[]
$ []sudo paco -lp+ xscavenger-1.4.4 'gzip -c scavenger.6 > /usr/share/man/man6/scavenger.6.gz'[]
[]追加でマニュアルをインストール[]
$ []scavenger[] []scavengerが起動する。[]