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