source: trunk/essentials/dev-lang/perl/ext/Errno/Errno_pm.PL@ 3397

Last change on this file since 3397 was 3181, checked in by bird, 19 years ago

perl 5.8.8

File size: 12.1 KB
Line 
1use ExtUtils::MakeMaker;
2use Config;
3use strict;
4
5our $VERSION = "1.09_01";
6
7my %err = ();
8my %wsa = ();
9
10unlink "Errno.pm" if -f "Errno.pm";
11open OUT, ">Errno.pm" or die "Cannot open Errno.pm: $!";
12select OUT;
13my $file;
14my @files = get_files();
15if ($Config{gccversion} ne '' && $^O eq 'MSWin32') {
16 # MinGW complains "warning: #pragma system_header ignored outside include
17 # file" if the header files are processed individually, so include them
18 # all in .c file and process that instead.
19 open INCS, '>includes.c' or
20 die "Cannot open includes.c";
21 foreach $file (@files) {
22 next if $file eq 'errno.c';
23 next unless -f $file;
24 print INCS qq[#include "$file"\n];
25 }
26 close INCS;
27 process_file('includes.c');
28 unlink 'includes.c';
29}
30else {
31 foreach $file (@files) {
32 process_file($file);
33 }
34}
35write_errno_pm();
36unlink "errno.c" if -f "errno.c";
37
38sub process_file {
39 my($file) = @_;
40
41 # for win32 perl under cygwin, we need to get a windows pathname
42 if ($^O eq 'MSWin32' && $Config{cc} =~ /\B-mno-cygwin\b/ &&
43 defined($file) && !-f $file) {
44 chomp($file = `cygpath -w "$file"`);
45 }
46
47 return unless defined $file and -f $file;
48# warn "Processing $file\n";
49
50 local *FH;
51 if (($^O eq 'VMS') && ($Config{vms_cc_type} ne 'gnuc')) {
52 unless(open(FH," LIBRARY/EXTRACT=ERRNO/OUTPUT=SYS\$OUTPUT $file |")) {
53 warn "Cannot open '$file'";
54 return;
55 }
56 } elsif ($Config{gccversion} ne ''
57 # OpenSTEP has gcc 2.7.2.1 which recognizes but
58 # doesn't implement the -dM flag.
59 && $^O ne 'openstep' && $^O ne 'next' && $^O ne 'darwin'
60 ) {
61 # With the -dM option, gcc outputs every #define it finds
62 unless(open(FH,"$Config{cc} -E -dM $Config{cppflags} $file |")) {
63 warn "Cannot open '$file'";
64 return;
65 }
66 } else {
67 unless(open(FH,"< $file")) {
68 # This file could be a temporary file created by cppstdin
69 # so only warn under -w, and return
70 warn "Cannot open '$file'" if $^W;
71 return;
72 }
73 }
74
75 if ($^O eq 'MacOS') {
76 while(<FH>) {
77 $err{$1} = $2
78 if /^\s*#\s*define\s+(E\w+)\s+(\d+)/;
79 }
80 } else {
81 while(<FH>) {
82 $err{$1} = 1
83 if /^\s*#\s*define\s+(E\w+)\s+/;
84 if ($^O eq 'MSWin32') {
85 $wsa{$1} = 1
86 if /^\s*#\s*define\s+WSA(E\w+)\s+/;
87 }
88 }
89 }
90 close(FH);
91}
92
93my $cppstdin;
94
95sub default_cpp {
96 unless (defined $cppstdin) {
97 use File::Spec;
98 $cppstdin = $Config{cppstdin};
99 my $upup_cppstdin = File::Spec->catfile(File::Spec->updir,
100 File::Spec->updir,
101 "cppstdin");
102 my $cppstdin_is_wrapper =
103 ($cppstdin eq 'cppstdin'
104 and -f $upup_cppstdin
105 and -x $upup_cppstdin);
106 $cppstdin = $upup_cppstdin if $cppstdin_is_wrapper;
107 }
108 return "$cppstdin $Config{cppflags} $Config{cppminus}";
109}
110
111sub get_files {
112 my %file = ();
113 # VMS keeps its include files in system libraries (well, except for Gcc)
114 if ($^O eq 'VMS') {
115 if ($Config{vms_cc_type} eq 'decc') {
116 $file{'Sys$Library:DECC$RTLDEF.TLB'} = 1;
117 } elsif ($Config{vms_cc_type} eq 'vaxc') {
118 $file{'Sys$Library:vaxcdef.tlb'} = 1;
119 } elsif ($Config{vms_cc_type} eq 'gcc') {
120 $file{'gnu_cc_include:[000000]errno.h'} = 1;
121 }
122 } elsif ($^O eq 'os390') {
123 # OS/390 C compiler doesn't generate #file or #line directives
124 $file{'/usr/include/errno.h'} = 1;
125 } elsif ($^O eq 'vmesa') {
126 # OS/390 C compiler doesn't generate #file or #line directives
127 $file{'../../vmesa/errno.h'} = 1;
128 } elsif ($Config{archname} eq 'epoc') {
129 # Watch out for cross compiling for EPOC (usually done on linux)
130 $file{'/usr/local/epocemx/epocsdk/include/libc/sys/errno.h'} = 1;
131 } elsif ($^O eq 'linux' &&
132 $Config{gccversion} ne '' # might be using, say, Intel's icc
133 ) {
134 # Some Linuxes have weird errno.hs which generate
135 # no #file or #line directives
136 my $linux_errno_h = -e '/usr/include/errno.h' ?
137 '/usr/include/errno.h' : '/usr/local/include/errno.h';
138 $file{$linux_errno_h} = 1;
139 } elsif ($^O eq 'MacOS') {
140 # note that we are only getting the GUSI errno's here ...
141 # we might miss out on compiler-specific ones
142 $file{"$ENV{GUSI}include:sys:errno.h"} = 1;
143
144 } elsif ($^O eq 'beos') {
145 # hidden in a special place
146 $file{'/boot/develop/headers/posix/errno.h'} = 1;
147
148 } elsif ($^O eq 'vos') {
149 # avoid problem where cpp returns non-POSIX pathnames
150 $file{'/system/include_library/errno.h'} = 1;
151 } else {
152 open(CPPI,"> errno.c") or
153 die "Cannot open errno.c";
154
155 if ($^O eq 'NetWare') {
156 print CPPI "#include <nwerrno.h>\n";
157 } else {
158 print CPPI "#include <errno.h>\n";
159 if ($^O eq 'MSWin32') {
160 print CPPI "#define _WINSOCKAPI_\n"; # don't drag in everything
161 print CPPI "#include <winsock.h>\n";
162 }
163 }
164
165 close(CPPI);
166
167 # invoke CPP and read the output
168 if ($^O eq 'MSWin32' || $^O eq 'NetWare') {
169 open(CPPO,"$Config{cpprun} $Config{cppflags} errno.c |") or
170 die "Cannot run '$Config{cpprun} $Config{cppflags} errno.c'";
171 } else {
172 my $cpp = default_cpp();
173 open(CPPO,"$cpp < errno.c |") or
174 die "Cannot exec $cpp";
175 }
176
177 my $pat;
178 if (($^O eq 'MSWin32' || $^O eq 'NetWare') and $Config{cc} =~ /^bcc/i) {
179 $pat = '^/\*\s+(.+)\s+\d+\s*:\s+\*/';
180 }
181 else {
182 $pat = '^#\s*(?:line)?\s*\d+\s+"([^"]+)"';
183 }
184 while(<CPPO>) {
185 if ($^O eq 'os2' or $^O eq 'MSWin32' or $^O eq 'NetWare') {
186 if (/$pat/o) {
187 my $f = $1;
188 $f =~ s,\\\\,/,g;
189 $file{$f} = 1;
190 }
191 }
192 else {
193 $file{$1} = 1 if /$pat/o;
194 }
195 }
196 close(CPPO);
197 }
198 return keys %file;
199}
200
201sub write_errno_pm {
202 my $err;
203
204 # quick sanity check
205
206 die "No error definitions found" unless keys %err;
207
208 # create the CPP input
209
210 open(CPPI,"> errno.c") or
211 die "Cannot open errno.c";
212
213 if ($^O eq 'NetWare') {
214 print CPPI "#include <nwerrno.h>\n";
215 }
216 else {
217 print CPPI "#include <errno.h>\n";
218 }
219 if ($^O eq 'MSWin32') {
220 print CPPI "#include <winsock.h>\n";
221 foreach $err (keys %wsa) {
222 print CPPI "#ifndef $err\n";
223 print CPPI "#define $err WSA$err\n";
224 print CPPI "#endif\n";
225 $err{$err} = 1;
226 }
227 }
228
229 foreach $err (keys %err) {
230 print CPPI '"',$err,'" [[',$err,']]',"\n";
231 }
232
233 close(CPPI);
234
235 unless ($^O eq 'MacOS' || $^O eq 'beos') { # trust what we have / get later
236 # invoke CPP and read the output
237
238 if ($^O eq 'VMS') {
239 my $cpp = "$Config{cppstdin} $Config{cppflags} $Config{cppminus}";
240 $cpp =~ s/sys\$input//i;
241 open(CPPO,"$cpp errno.c |") or
242 die "Cannot exec $Config{cppstdin}";
243 } elsif ($^O eq 'MSWin32' || $^O eq 'NetWare') {
244 open(CPPO,"$Config{cpprun} $Config{cppflags} errno.c |") or
245 die "Cannot run '$Config{cpprun} $Config{cppflags} errno.c'";
246 } else {
247 my $cpp = default_cpp();
248 open(CPPO,"$cpp < errno.c |")
249 or die "Cannot exec $cpp";
250 }
251
252 %err = ();
253
254 while(<CPPO>) {
255 my($name,$expr);
256 next unless ($name, $expr) = /"(.*?)"\s*\[\s*\[\s*(.*?)\s*\]\s*\]/;
257 next if $name eq $expr;
258 $expr =~ s/\(?\([a-z_]\w*\)([^\)]*)\)?/$1/i; # ((type)0xcafebabe) at alia
259 $expr =~ s/((?:0x)?[0-9a-fA-F]+)[LU]+\b/$1/g; # 2147483647L et alia
260 next if $expr =~ m/^[a-zA-Z]+$/; # skip some Win32 functions
261 if($expr =~ m/^0[xX]/) {
262 $err{$name} = hex $expr;
263 }
264 else {
265 $err{$name} = eval $expr;
266 }
267 delete $err{$name} unless defined $err{$name};
268 }
269 close(CPPO);
270 }
271
272 # Many of the E constants (including ENOENT, which is being
273 # used in the Perl test suite a lot), are available only as
274 # enums in BeOS, so compiling and executing some code is about
275 # only way to find out what the numeric Evalues are. In fact above, we
276 # didn't even bother to get the values of the ones that have numeric
277 # values, since we can get all of them here, anyway.
278
279 if ($^O eq 'beos') {
280 if (open(C, ">errno.c")) {
281 my @allerrs = keys %err;
282 print C <<EOF;
283#include <errno.h>
284#include <stdio.h>
285int main() {
286EOF
287 for (@allerrs) {
288 print C qq[printf("$_ %d\n", $_);]
289 }
290 print C "}\n";
291 close C;
292 system("cc -o errno errno.c");
293 unlink("errno.c");
294 if (open(C, "./errno|")) {
295 while (<C>) {
296 if (/^(\w+) (-?\d+)$/) { $err{$1} = $2 }
297 }
298 close(C);
299 } else {
300 die "failed to execute ./errno: $!\n";
301 }
302 unlink("errno");
303 } else {
304 die "failed to create errno.c: $!\n";
305 }
306 }
307
308 # Write Errno.pm
309
310 print <<"EDQ";
311#
312# This file is auto-generated. ***ANY*** changes here will be lost
313#
314
315package Errno;
316our (\@EXPORT_OK,\%EXPORT_TAGS,\@ISA,\$VERSION,\%errno,\$AUTOLOAD);
317use Exporter ();
318use Config;
319use strict;
320
321"\$Config{'archname'}-\$Config{'osvers'}" eq
322"$Config{'archname'}-$Config{'osvers'}" or
323 die "Errno architecture ($Config{'archname'}-$Config{'osvers'}) does not match executable architecture (\$Config{'archname'}-\$Config{'osvers'})";
324
325\$VERSION = "$VERSION";
326\$VERSION = eval \$VERSION;
327\@ISA = qw(Exporter);
328
329EDQ
330
331 my $len = 0;
332 my @err = sort { $err{$a} <=> $err{$b} } keys %err;
333 map { $len = length if length > $len } @err;
334
335 my $j = "\@EXPORT_OK = qw(" . join(" ",keys %err) . ");\n";
336 $j =~ s/(.{50,70})\s/$1\n\t/g;
337 print $j,"\n";
338
339print <<'ESQ';
340%EXPORT_TAGS = (
341 POSIX => [qw(
342ESQ
343
344 my $k = join(" ", grep { exists $err{$_} }
345 qw(E2BIG EACCES EADDRINUSE EADDRNOTAVAIL EAFNOSUPPORT
346 EAGAIN EALREADY EBADF EBUSY ECHILD ECONNABORTED
347 ECONNREFUSED ECONNRESET EDEADLK EDESTADDRREQ EDOM EDQUOT
348 EEXIST EFAULT EFBIG EHOSTDOWN EHOSTUNREACH EINPROGRESS
349 EINTR EINVAL EIO EISCONN EISDIR ELOOP EMFILE EMLINK
350 EMSGSIZE ENAMETOOLONG ENETDOWN ENETRESET ENETUNREACH
351 ENFILE ENOBUFS ENODEV ENOENT ENOEXEC ENOLCK ENOMEM
352 ENOPROTOOPT ENOSPC ENOSYS ENOTBLK ENOTCONN ENOTDIR
353 ENOTEMPTY ENOTSOCK ENOTTY ENXIO EOPNOTSUPP EPERM
354 EPFNOSUPPORT EPIPE EPROCLIM EPROTONOSUPPORT EPROTOTYPE
355 ERANGE EREMOTE ERESTART EROFS ESHUTDOWN ESOCKTNOSUPPORT
356 ESPIPE ESRCH ESTALE ETIMEDOUT ETOOMANYREFS ETXTBSY
357 EUSERS EWOULDBLOCK EXDEV));
358
359 $k =~ s/(.{50,70})\s/$1\n\t/g;
360 print "\t",$k,"\n )]\n);\n\n";
361
362 foreach $err (@err) {
363 printf "sub %s () { %d }\n",,$err,$err{$err};
364 }
365
366 print <<'ESQ';
367
368sub TIEHASH { bless [] }
369
370sub FETCH {
371 my ($self, $errname) = @_;
372 my $proto = prototype("Errno::$errname");
373 my $errno = "";
374 if (defined($proto) && $proto eq "") {
375 no strict 'refs';
376 $errno = &$errname;
377 $errno = 0 unless $! == $errno;
378 }
379 return $errno;
380}
381
382sub STORE {
383 require Carp;
384 Carp::confess("ERRNO hash is read only!");
385}
386
387*CLEAR = \&STORE;
388*DELETE = \&STORE;
389
390sub NEXTKEY {
391 my($k,$v);
392 while(($k,$v) = each %Errno::) {
393 my $proto = prototype("Errno::$k");
394 last if (defined($proto) && $proto eq "");
395 }
396 $k
397}
398
399sub FIRSTKEY {
400 my $s = scalar keys %Errno::; # initialize iterator
401 goto &NEXTKEY;
402}
403
404sub EXISTS {
405 my ($self, $errname) = @_;
406 my $r = ref $errname;
407 my $proto = !$r || $r eq 'CODE' ? prototype($errname) : undef;
408 defined($proto) && $proto eq "";
409}
410
411tie %!, __PACKAGE__;
412
4131;
414__END__
415
416=head1 NAME
417
418Errno - System errno constants
419
420=head1 SYNOPSIS
421
422 use Errno qw(EINTR EIO :POSIX);
423
424=head1 DESCRIPTION
425
426C<Errno> defines and conditionally exports all the error constants
427defined in your system C<errno.h> include file. It has a single export
428tag, C<:POSIX>, which will export all POSIX defined error numbers.
429
430C<Errno> also makes C<%!> magic such that each element of C<%!> has a
431non-zero value only if C<$!> is set to that value. For example:
432
433 use Errno;
434
435 unless (open(FH, "/fangorn/spouse")) {
436 if ($!{ENOENT}) {
437 warn "Get a wife!\n";
438 } else {
439 warn "This path is barred: $!";
440 }
441 }
442
443If a specified constant C<EFOO> does not exist on the system, C<$!{EFOO}>
444returns C<"">. You may use C<exists $!{EFOO}> to check whether the
445constant is available on the system.
446
447=head1 CAVEATS
448
449Importing a particular constant may not be very portable, because the
450import will fail on platforms that do not have that constant. A more
451portable way to set C<$!> to a valid value is to use:
452
453 if (exists &Errno::EFOO) {
454 $! = &Errno::EFOO;
455 }
456
457=head1 AUTHOR
458
459Graham Barr <[email protected]>
460
461=head1 COPYRIGHT
462
463Copyright (c) 1997-8 Graham Barr. All rights reserved.
464This program is free software; you can redistribute it and/or modify it
465under the same terms as Perl itself.
466
467=cut
468
469ESQ
470
471}
Note: See TracBrowser for help on using the repository browser.