понедельник, 17 мая 2010 г.

Раскладка для телефона

Прочитал статью "Улучшенная раскладка для телефона", задумался...

Основная проблема не T9 режима - это подряд идущие символы, которые приходятся на одну клавишу. Необходимо выжидать, чтобы текущий символ зафиксировался, чтобы можно было начать набирать новый.

И тут меня осенило...

вторник, 27 апреля 2010 г.

libpthread-stubs.so.0 not found

Недавно, после очередного обновления, случилась поломка Exherbo. После обновления libpthread-stubs с версии 0.2 на версию 0.3 перестали загружаться в частности иксы. Ну я знал на что иду, когда ставил Exherbo, нас такими вещами не удивишь.

Гораздо хуже было, когда, в 2006 в Gentoo сломался expat. Там ни одно приложение вообще не работало, в том числе и python, без которого житть не может emerge.

Здесь - так, цветочки. Хотя reconcilio почему-то не хочет лечить ситуацию и спотыкается на первом же пакете.

четверг, 22 апреля 2010 г.

Более-менее...

Все таки мы неправильно как-то живем. Нашими интерфейсами руководят низменные железные ограничения. Вот например - часто в интерфейсах нас просят ввести 0, если ограничений не предполагается. Но, по моему 0 - это ноль, это совершенно не похоже на бесконечность. И если с точки зрения архитектуры удобно делить значения на нулевые и ненулевые, то с точки зрения интерфейса - это нелогично.

И размышляя таким образом о физической природе чисел я дошел до стандартной библиотеки...

вторник, 13 апреля 2010 г.

Больше предупреждений, хороший и разных

Хорошая практика программирования рекомендует включать максимум предупреждений компилятора и добиваться того, чтобы их не возникало в процессе компиляции. Заставить один C++ проект компилироваться без предупреждений достаточно легко. Но если в рамках одного проекта используются модули на C/C++ - все становится значительно интереснее.

Есть предупреждения, применимые только для C++ (например: -Weffc++, -Woverloaded-virtual, -Wold-style-cast). Я не пробовал включать их для си, могу предположить, что последует ругань и правильно. А поскольку для C они не имеют смысла - в данном контексте они не интересны.

Для обоих языков в первом приближении я отобрал три варнинга: -Wsign-conversion -Wconversion -pedantic. Остановимся на них поподробнее.

Начать стоит с того, что в си enum - всегда int.
enum {
 TEST1 = 0x100000000ULL,
 TEST2 = 0xffffffffU,
 TEST3 = 0x7fffffff
};
$ gcc -c -std=c99 -pedantic test.c
test.c:2: предупреждение: в ISO C значения перечислимого типа ограничены диапазоном типа ‘int’
test.c:3: предупреждение: в ISO C значения перечислимого типа ограничены диапазоном типа ‘int’
Причем это справедливо и для amd64, в этом легко убедиться например так:
BOOST_STATIC_ASSERT(sizeof(int) == 4);
В то же время в C++ с enum не возникает никаких проблем. В C++ тип enum есть собственно enum, даже знаковость которого определяется позже. Единственный возникающий в данной ситуации момент - стандарт C++ 99 года не любит определений ULL, считая их C99 long long integer constant, Для C++ даже U писать не обязательно, главное, чтобы значение могло уместиться в long, то есть быть не больше 32-64 бит в зависимости от типа платформы.

Это наводит на мысль, что переносимое приложение не должно использовать в enum значения больше 32 бит длиной.

Значение sizeof(TEST1) в С++ варьируется в зависимости от наполнения enum от 4 до 8.

Другой интересный момент, справедливый для обоих языков:
const unsigned int t1 = TEST1;
const unsigned int t2 = 0;
const unsigned int t3 = argc > 1 ? TEST1 : 0;
$ gcc -m64 -o test -std=c99 -Wsign-conversion test.c
test.c:3: предупреждение: conversion to ‘unsigned int’ from ‘int’ may change the sign of the result
Ошибка возникает в третьей строке фрагмента, и лечится заменой 0, на 0U... Хотя тот же 0 во второй строке не вызывает проблем.

И напоследок - ошибочная ситуация в gcc:
При попытке присвоить битовому полю значение какой-то переменной практически всегда происходит ошибка, и обойти ее практически не представляется возможным.
unsigned int x = 0x7f;
struct {
 unsigned int a:7;
} t = { .a = x };
$ gcc -std=c99 -Wconversion test.c
test.c:4: предупреждение: conversion to ‘unsigned char:7’ from ‘unsigned int’ may alter its value
Не существует способа привести переменную к битовому полю.

В принципе я не вижу большой необходимости из кожи вон лезть, чтобы задушить любую ругань компилятора. Наша цель - обеспечить корректность кода. Ругань компилятора - это средство для привлечения внимания к подозрительным местам.

Главное чтобы борьба за чистоту кода производилась с пониманием первопричин. Тупые приведения типов (через reinterpret_cast конечно) до добра еще никого не доводили. Даже если эта конструкция и находит применение в коде - она достаточно бросается в глаза и вызывает стойкое желание избавиться от нее. Но лучше оставить предупреждение, которое бросается в глаза еще сильнее.

Можно предложить борцам на чистоту кода периодически устраивать параноидальные проверки с большим количеством опций, которые, возможно, не удастся расчистить целиком. А в обычные дни обходится более скромным подмножеством опций, но при этом обязательно используя -Werror. :)

PS: Интересное на этом конечно же не заканчивается - это лишь первый взгляд. Может быть последует продолжение, если будет не лень, совсем я что-то забыл про блог.

пятница, 5 февраля 2010 г.

Mercurial сервер

Стоит у меня под столом UltraSPARC5. Машина старая, валялась без дела. А я давний любитель всего экзотического решил приобщить ее для общественной пользы.

Залил туда Gentoo, поставил вебсервер, mediawiki, ejabberd... Хотел поставить Google Wave, но в то время он был еще сырой, и не работал. Да и java на спарк не встает, во всяком случае у Gentoo не встает.

И тут, недавно, меня посетила еще одна мысль. Подниму ка я там scm сервер. Это позволит хранить отдельно всякие вне проектные рабочие разработки. Лишняя копия, как говорится, никогда не бывает лишней. Эта, пусть слабенькая, машинка прекрасно с справится с этой задачей.

Пусть простят меня поклонники Линуса Торвальдса - git мне никогда не нравился, хотя мне приходилось им пользоваться. На данный момент мне нравится Mercurial.

Согласно этой инструкции мы настраиваем пользователя и наслаждаемся репозиторием через ssh.

Борьба с вебмордой неожиданно затянулась. Хоть для меня скорость и не является решающим фактором - я старательно следовал инструкциям по настройке fastcgi, но добился лишь того, что я могу ходить на сервер от корня (от http://.../hg), но попытка ввести что нибудь после /hg неизменно приводит к проблемам. Сервер перенаправляет /hg на /hg.fcgi и других запросов упорно не хочет принимать. Ну не писать же везде /hg.fcgi/blablabla... лишнее.

А поскольку скорость не является для меня решающим фактором - я в конце концов нашел официальную инструкцию по настройке cgi под lighttpd. Она попроще и после нее все работает почти сразу.

Для коммитоов https не нужен, настроим авторизацию на пуш согласно той же официальной инструкции.

Но возникла проблема. htpasswd - является частью апача и в комплект lighttpd не входит. Ну не ставить же апач ради такой фигни? Значит можно выбрать другой метод авторизации. Меня бы устроила встроенная авторизация на основе /etc/passwd, но так lighttpd кажется не умеет. Здесь описаны возможность mod_auth. Генерируем /home/scm/.htdigest с его помощью.
$HTTP["querystring"] =~ "cmd=unbundle" {
        auth.require = (   "" => (
                "method"  => "digest",
                "realm"   => "Mercurial repo",
                "require" => "valid-user"
        ))
}

auth.backend = "htdigest"
auth.backend.htdigest.userfile = "/home/scm/.htdigest"
Но этого недостаточно. Нужно еще в конкретном репозитории разрешить не-ssl пушинг, и прописать юзеров, которые могут это делать.
scm@sparc ~/hg/xap/.hg $ cat hgrc
[web]
push_ssl = false
allow_push = dron

Теперь можно проверить... (я конечно и в процессе неоднократно проверял, сейчас финальный тест)
$ hg clone http://10.4.2.91/hg/xap
...
10 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ cd xap
$ echo "Ридми я до сих пор не написал" > readme.txt
$ hg add readme.txt
$ hg commit -m "Тестовый коммит"
$ hg push
pushing to http://10.4.2.91/hg/xap
searching for changes
http authorization required
realm: Mercurial repo
user: dron@infosec.ru
password:
abort: authorization failed
Тудыть ее... А, забыл lighttpd перезагрузить...
...
user: dron
password:
abort: HTTP Error 500: Internal Server Error
Доступа чтоль не хватает?
$ cd /home/scm/hg; chmod -R g+w *
(Пользователь lighttpd у нас включен в группу scm). А вот и нет... недостаточно... только
$ cd /home/scm/hg; chown -R lighttpd:lighttpd *
спас сервер. Не понятно. Везде для групп стоит rw, для каталогов - rwx. Но установка одной группы в lighttpd не спасает положение.

Теперь мне совсем не ясно - зачем я заводил юзера scm? Хотя может быть для fcgi (с отдельной службой, вероятно работающей от имени scm) это и было нужно. Но пусть пока будет так.

Остались несколько проблем, и https не самая большая из них. Вот самая большая:
$ hg push
...
user: dron@infosec.ru
password:
abort: authorization failed
$ hg push
...
user: dron
password:
adding changesets
add changeset a63be34dcf21
adding manifests
adding file changes
adding readme.txt revisions
added 1 changesets with 1 changes to 1 files
updating the branch cache
Вот так, dron в качестве имени - воспринимает, а dron@infosec.ru - нет. Вероятно проблема где-то mod_auth, потому что не сходится авторизация. И что с этим делать?..