On Mon, Oct 09, 2006 at 12:02:38AM +0400, Dmitry V. Levin wrote: > On Sun, Oct 08, 2006 at 11:43:24PM +0400, Alexey Tourbin wrote: > > On Wed, Oct 04, 2006 at 10:11:57PM +0400, QA Team Robot wrote: > > > syntax error at /usr/src/tmp/perl-buildroot/usr/lib/perl5/i386-linux/bits/syslog.ph line 9, near ", ..." > > > # /usr/src/tmp/perl-buildroot/usr/lib/perl5/i386-linux/bits/syslog.ph: deparse failed, trying to recover with -Mbits > > > > h2ph не понимает макросов с перменным списокм аргументов, а с > > FORTIFY_SOURCE теперь в /usr/include/bits/syslog.h вижу: > > > > 25 extern void __syslog_chk (int __pri, int __flag, __const char *__fmt, ...) > > 26 __attribute__ ((__format__ (__printf__, 3, 4))); > > 27 > > 28 #define syslog(pri, ...) \ > > 29 __syslog_chk (pri, __USE_FORTIFY_LEVEL - 1, __VA_ARGS__) > > > > Научить h2ph понимать такие макросы мне слабо. Впрочем он и так такие > > простыни на свет производит, что спасать мне его и не хочется. В общем > > во время фриза непонятно что со всем этим делать. Удалю-ка я все эти > > *.ph и будь что будет. > > А зачем эти *.ph нужны? Что делают другие перловоды? Они нужны для очень старого софта, за одним маленьким исключением. h2ph пытается распарсить *.h файлы и представить их в эквивалентном перловом синтаксисе, чтобы были доступны константы из enum и define. Это константы типа LOG_* из sys/syslog.h и A[PF]_ из sys/socket.h. При более современном подходе эти константы компилируются вместе с функциями-обертками (в *.so файлах). Так, в perl-base есть модули Sys::Syslog и Socket. Можно создать фиктивные *.ph файлы и все эти констант импортировать из модулей. (Константы это функции с пустым прототипом; в некоторых случаях перл умеет такие константы "инлайнить", избегая собственно вызова функции.) h2ph плох тем что там не GLR parser какой-нибудь а чисто детский лепет на уровне if (/^#\s*define\s*(\w+)) или if (/^enum\s*{/). И там уже и так хак на хаке сидит. Маленькое исключение о котором я сказал это номера системных вызовов. В перле есть встроенная функция syscall -- обертка к либсишно-ядерному вызову, она в качестве первого аргумента берет номер системного вызова, а calling conventions там как раз до некоторой степени учитываются. Всё ещё распространена практика, хотя и не сильно, добираться до некоторых не очень хорошо портируемых системных вызовов за счет syscall. См. например perl-MDK-Common. Ну на пальцах require 'sys/syscall.ph'; # номера вызовов &SYS_* sub sync { return syscall(&SYS_sync) == 0; } Я попробовал сделать syscall.ph в обход h2ph за счет "cpp -dM" и последующего cpp уже без -dM. В случае с syscall.ph это ёщё работает (см. аттач), хотя уже видно, что cpp не полностью проводит eval'юацию выражений и из-за этого могут быть проблемы. sub SYS_chroot () { 61 } sub SYS_clock_getres () { (259 +7) } Случай с syscall.ph не единственный. В перле есть ещё встроенная функция ioctl(), а со вторым его аргументом такая же история, как с первым аргументом у syscall. То есть предполагается, что ты сделаешь ioctl.ph и сможешь взять оттуда номера запросов. Но ioctl.ph сделать столь же простым макаром уже не удается, там появляются выражения типа sub TIOCGPTN () { (((2U) << (((0 +8)+8)+14)) | ((('T')) << (0 +8)) | (((0x30)) << 0) | (((sizeof(unsigned int))) << ((0 +8)+8))) } которые перл вычислить уже не может. Значит идея с cpp -dM в случае с ioctl.ph накрывается медным тазом. То есть становится ясно, что подход опять же ненадежный. В дистре ioctl.ph и syscall.ph должны быть. Насчет остального можно покрутить пальцем у виска, а это пока нет. Если на перле не понтяно что я там делаю тогда вот скетч на шелле $ cpp -dM -include sys/syscall.h