ЭЛЕКТРОННАЯ БИБЛИОТЕКА КОАПП |
Сборники Художественной, Технической, Справочной, Английской, Нормативной, Исторической, и др. литературы. |
12.14. Using h2ph to Translate C #include FilesProblemSomeone gave you code that generates the bizarre error message:
You want to know what it means and how to fix it. SolutionGet your system administrator to do this, running as the superuser: % cd /usr/include; h2ph sys/syscall.h However, most include files require other include files, which means you should probably just translate them all: % cd /usr/include; h2ph *.h */*.h If that reports too many filenames or misses some that are more deeply nested, try this instead: % cd /usr/include; find . -name '*.h' -print | xargs h2ph DiscussionA file whose name ends in When h2ph's translation process works, it's wonderful. When it doesn't, you're probably out of luck. As system architectures and include files become more complex, h2ph fails more frequently. If you're lucky, the constants you need are already in the Fcntl, Socket, or POSIX modules. The POSIX module implements constants from sys/file.h, sys/errno.h, and sys/wait.h, among others. It also allows fancy tty handling, as described in Recipe 15.8. So what can you do with these .ph files? Here are a few examples. The first uses the pessimally non-portable # file FineTime.pm package main; require 'sys/syscall.ph'; die "No SYS_gettimeofday in sys/syscall.ph" unless defined &SYS_gettimeofday; package FineTime; use strict; require Exporter; use vars qw(@ISA @EXPORT_OK); @ISA = qw(Exporter); @EXPORT_OK = qw(time); sub time() { my $tv = pack("LL", ()); # presize buffer to two longs syscall(&main::SYS_gettimeofday, $tv, undef) >= 0 or die "gettimeofday: $!"; my($seconds, $microseconds) = unpack("LL", $tv); return $seconds + ($microseconds / 1_000_000); } 1; If you are forced to The sys/ioctl.ph file, if you can get it to build on your system, is the gateway to your system's idiosyncratic I/O functions through the Example 12.1: jam#!/usr/bin/perl -w # jam - stuff characters down STDIN's throat require 'sys/ioctl.ph'; die "no TIOCSTI" unless defined &TIOCSTI; sub jam { local $SIG{TTOU} = "IGNORE"; # "Stopped for tty output" local *TTY; # make local filehandle open(TTY, "+</dev/tty") or die "no tty: $!"; for (split(//, $_[0])) { ioctl(TTY, &TIOCSTI, $_) or die "bad TIOCSTI: $!"; } close(TTY); } jam("@ARGV\n"); Since sys/ioctl.h translation is so dodgy, you'll probably have to run this C program to get your TIOCSTI value. % cat > tio.c <<EOF && cc tio.c && a.out
#include <sys/ioctl.h>
main() { printf("%#08x\n", TIOCSTI); }
EOF
Another popular use for Example 12.2: winsz#!/usr/bin/perl # winsz - find x and y for chars and pixels require 'sys/ioctl.ph'; die "no TIOCGWINSZ " unless defined &TIOCGWINSZ; open(TTY, "+</dev/tty") or die "No tty: $!"; unless (ioctl(TTY, &TIOCGWINSZ, $winsize='')) { die sprintf "$0: ioctl TIOCGWINSZ (%08x: $!)\n", &TIOCGWINSZ; } ($row, $col, $xpixel, $ypixel) = unpack('S4', $winsize); print "(row,col) = ($row,$col)"; print " (xpixel,ypixel) = ($xpixel,$ypixel)" if $xpixel || $ypixel; print "\n"; As you see, as soon as you start playing with .ph files, Fortunately, less fragile mechanisms are increasingly available. CPAN modules for most of these functions now exist, which should theoretically prove more robust than sourcing .ph files. See Alsoh2ph (1); the instructions on running h2ph in the INSTALL file from the perl source distribution; the |