for(;;), sort
[p5sagit/p5-mst-13.2.git] / ext / Errno / Errno_pm.PL
CommitLineData
eab60bb1 1use ExtUtils::MakeMaker;
2use Config;
3use strict;
4
f168a5e7 5our $VERSION = "1.111";
eab60bb1 6
7my %err = ();
8
9unlink "Errno.pm" if -f "Errno.pm";
10open OUT, ">Errno.pm" or die "Cannot open Errno.pm: $!";
11select OUT;
12my $file;
13foreach $file (get_files()) {
14 process_file($file);
15}
16write_errno_pm();
17unlink "errno.c" if -f "errno.c";
18
19sub process_file {
20 my($file) = @_;
21
6683669a 22 return unless defined $file and -f $file;
eab60bb1 23
24 local *FH;
25 if (($^O eq 'VMS') && ($Config{vms_cc_type} ne 'gnuc')) {
26 unless(open(FH," LIBRARY/EXTRACT=ERRNO/OUTPUT=SYS\$OUTPUT $file |")) {
27 warn "Cannot open '$file'";
28 return;
29 }
9ae2e8df 30 } elsif ($Config{gccversion} ne '') {
31 # With the -dM option, gcc outputs every #define it finds
ee1e7ac2 32 unless(open(FH,"$Config{cc} -E -dM $Config{cppflags} $file |")) {
9ae2e8df 33 warn "Cannot open '$file'";
34 return;
35 }
eab60bb1 36 } else {
37 unless(open(FH,"< $file")) {
def887e8 38 # This file could be a temporary file created by cppstdin
6ad8d9a8 39 # so only warn under -w, and return
40 warn "Cannot open '$file'" if $^W;
eab60bb1 41 return;
42 }
43 }
db5fd395 44
45 if ($^O eq 'MacOS') {
46 while(<FH>) {
47 $err{$1} = $2
48 if /^\s*#\s*define\s+(E\w+)\s+(\d+)/;
49 }
50 } else {
51 while(<FH>) {
52 $err{$1} = 1
53 if /^\s*#\s*define\s+(E\w+)\s+/;
54 }
55 }
56 close(FH);
eab60bb1 57}
58
def887e8 59my $cppstdin;
60
61sub default_cpp {
62 unless (defined $cppstdin) {
63 use File::Spec;
64 $cppstdin = $Config{cppstdin};
65 my $upup_cppstdin = File::Spec->catfile(File::Spec->updir,
66 File::Spec->updir,
67 "cppstdin");
68 my $cppstdin_is_wrapper =
69 ($cppstdin eq 'cppstdin'
70 and -f $upup_cppstdin
71 and -x $upup_cppstdin);
72 $cppstdin = $upup_cppstdin if $cppstdin_is_wrapper;
73 }
74 return "$cppstdin $Config{cppflags} $Config{cppminus}";
75}
76
eab60bb1 77sub get_files {
78 my %file = ();
79 # VMS keeps its include files in system libraries (well, except for Gcc)
80 if ($^O eq 'VMS') {
81 if ($Config{vms_cc_type} eq 'decc') {
82 $file{'Sys$Library:DECC$RTLDEF.TLB'} = 1;
83 } elsif ($Config{vms_cc_type} eq 'vaxc') {
84 $file{'Sys$Library:vaxcdef.tlb'} = 1;
85 } elsif ($Config{vms_cc_type} eq 'gcc') {
86 $file{'gnu_cc_include:[000000]errno.h'} = 1;
87 }
9d116dd7 88 } elsif ($^O eq 'os390') {
89 # OS/390 C compiler doesn't generate #file or #line directives
90 $file{'/usr/include/errno.h'} = 1;
092bebab 91 } elsif ($^O eq 'vmesa') {
92 # OS/390 C compiler doesn't generate #file or #line directives
93 $file{'../../vmesa/errno.h'} = 1;
a367e475 94 } elsif ($Config{archname} eq 'epoc') {
95 # Watch out for cross compiling for EPOC (usually done on linux)
96 $file{'/usr/local/epoc/include/libc/sys/errno.h'} = 1;
9ae2e8df 97 } elsif ($^O eq 'linux') {
98 # Some Linuxes have weird errno.hs which generate
99 # no #file or #line directives
100 $file{'/usr/include/errno.h'} = 1;
db5fd395 101 } elsif ($^O eq 'MacOS') {
102 # note that we are only getting the GUSI errno's here ...
103 # we might miss out on compiler-specific ones
104 $file{"$ENV{GUSI}include:sys:errno.h"} = 1;
105
eab60bb1 106 } else {
107 open(CPPI,"> errno.c") or
108 die "Cannot open errno.c";
109
110 print CPPI "#include <errno.h>\n";
111
112 close(CPPI);
113
114 # invoke CPP and read the output
6ad8d9a8 115 if ($^O eq 'MSWin32') {
116 open(CPPO,"$Config{cpprun} $Config{cppflags} errno.c |") or
117 die "Cannot run '$Config{cpprun} $Config{cppflags} errno.c'";
118 } else {
def887e8 119 my $cpp = default_cpp();
6ad8d9a8 120 open(CPPO,"$cpp < errno.c |") or
121 die "Cannot exec $cpp";
122 }
eab60bb1 123
124 my $pat;
125 if ($^O eq 'MSWin32' and $Config{cc} =~ /^bcc/i) {
126 $pat = '^/\*\s+(.+)\s+\d+\s*:\s+\*/';
127 }
128 else {
d0d1d9b9 129 $pat = '^#\s*(?:line)?\s*\d+\s+"([^"]+)"';
eab60bb1 130 }
131 while(<CPPO>) {
2449e420 132 if ($^O eq 'os2' or $^O eq 'MSWin32') {
0196e43b 133 if (/$pat/o) {
134 my $f = $1;
135 $f =~ s,\\\\,/,g;
136 $file{$f} = 1;
137 }
138 }
139 else {
140 $file{$1} = 1 if /$pat/o;
141 }
eab60bb1 142 }
143 close(CPPO);
144 }
145 return keys %file;
146}
147
148sub write_errno_pm {
149 my $err;
150
def887e8 151 # quick sanity check
152
153 die "No error definitions found" unless keys %err;
154
eab60bb1 155 # create the CPP input
156
157 open(CPPI,"> errno.c") or
158 die "Cannot open errno.c";
159
160 print CPPI "#include <errno.h>\n";
161
162 foreach $err (keys %err) {
163 print CPPI '"',$err,'" [[',$err,']]',"\n";
164 }
165
166 close(CPPI);
167
db5fd395 168 unless ($^O eq 'MacOS') { # trust what we have
eab60bb1 169 # invoke CPP and read the output
dcbf900d 170
db5fd395 171 if ($^O eq 'VMS') {
172 my $cpp = "$Config{cppstdin} $Config{cppflags} $Config{cppminus}";
173 $cpp =~ s/sys\$input//i;
174 open(CPPO,"$cpp errno.c |") or
175 die "Cannot exec $Config{cppstdin}";
176 } elsif ($^O eq 'MSWin32') {
177 open(CPPO,"$Config{cpprun} $Config{cppflags} errno.c |") or
178 die "Cannot run '$Config{cpprun} $Config{cppflags} errno.c'";
179 } else {
180 my $cpp = default_cpp();
181 open(CPPO,"$cpp < errno.c |")
182 or die "Cannot exec $cpp";
183 }
eab60bb1 184
db5fd395 185 %err = ();
eab60bb1 186
db5fd395 187 while(<CPPO>) {
188 my($name,$expr);
189 next unless ($name, $expr) = /"(.*?)"\s*\[\s*\[\s*(.*?)\s*\]\s*\]/;
190 next if $name eq $expr;
191 $err{$name} = eval $expr;
192 }
193 close(CPPO);
eab60bb1 194 }
eab60bb1 195
196 # Write Errno.pm
197
198 print <<"EDQ";
199#
200# This file is auto-generated. ***ANY*** changes here will be lost
201#
202
203package Errno;
f168a5e7 204our (\@EXPORT_OK,\%EXPORT_TAGS,\@ISA,\$VERSION,\%errno,\$AUTOLOAD);
eab60bb1 205use Exporter ();
206use Config;
207use strict;
208
8bc9d590 209"\$Config{'archname'}-\$Config{'osvers'}" eq
210"$Config{'archname'}-$Config{'osvers'}" or
81be85b8 211 die "Errno architecture ($Config{'archname'}-$Config{'osvers'}) does not match executable architecture (\$Config{'archname'}-\$Config{'osvers'})";
eab60bb1 212
213\$VERSION = "$VERSION";
214\@ISA = qw(Exporter);
215
216EDQ
217
218 my $len = 0;
219 my @err = sort { $err{$a} <=> $err{$b} } keys %err;
220 map { $len = length if length > $len } @err;
221
222 my $j = "\@EXPORT_OK = qw(" . join(" ",keys %err) . ");\n";
223 $j =~ s/(.{50,70})\s/$1\n\t/g;
224 print $j,"\n";
225
226print <<'ESQ';
227%EXPORT_TAGS = (
228 POSIX => [qw(
229ESQ
230
231 my $k = join(" ", grep { exists $err{$_} }
232 qw(E2BIG EACCES EADDRINUSE EADDRNOTAVAIL EAFNOSUPPORT
233 EAGAIN EALREADY EBADF EBUSY ECHILD ECONNABORTED
234 ECONNREFUSED ECONNRESET EDEADLK EDESTADDRREQ EDOM EDQUOT
235 EEXIST EFAULT EFBIG EHOSTDOWN EHOSTUNREACH EINPROGRESS
236 EINTR EINVAL EIO EISCONN EISDIR ELOOP EMFILE EMLINK
237 EMSGSIZE ENAMETOOLONG ENETDOWN ENETRESET ENETUNREACH
238 ENFILE ENOBUFS ENODEV ENOENT ENOEXEC ENOLCK ENOMEM
239 ENOPROTOOPT ENOSPC ENOSYS ENOTBLK ENOTCONN ENOTDIR
240 ENOTEMPTY ENOTSOCK ENOTTY ENXIO EOPNOTSUPP EPERM
241 EPFNOSUPPORT EPIPE EPROCLIM EPROTONOSUPPORT EPROTOTYPE
242 ERANGE EREMOTE ERESTART EROFS ESHUTDOWN ESOCKTNOSUPPORT
243 ESPIPE ESRCH ESTALE ETIMEDOUT ETOOMANYREFS ETXTBSY
244 EUSERS EWOULDBLOCK EXDEV));
245
246 $k =~ s/(.{50,70})\s/$1\n\t/g;
247 print "\t",$k,"\n )]\n);\n\n";
248
249 foreach $err (@err) {
250 printf "sub %s () { %d }\n",,$err,$err{$err};
251 }
252
253 print <<'ESQ';
254
255sub TIEHASH { bless [] }
256
257sub FETCH {
258 my ($self, $errname) = @_;
259 my $proto = prototype("Errno::$errname");
68301627 260 my $errno = "";
eab60bb1 261 if (defined($proto) && $proto eq "") {
262 no strict 'refs';
68301627 263 $errno = &$errname;
264 $errno = 0 unless $! == $errno;
eab60bb1 265 }
68301627 266 return $errno;
93014de6 267}
eab60bb1 268
269sub STORE {
270 require Carp;
271 Carp::confess("ERRNO hash is read only!");
272}
273
274*CLEAR = \&STORE;
275*DELETE = \&STORE;
276
277sub NEXTKEY {
278 my($k,$v);
279 while(($k,$v) = each %Errno::) {
280 my $proto = prototype("Errno::$k");
281 last if (defined($proto) && $proto eq "");
eab60bb1 282 }
283 $k
284}
285
286sub FIRSTKEY {
68301627 287 my $s = scalar keys %Errno::; # initialize iterator
eab60bb1 288 goto &NEXTKEY;
289}
290
291sub EXISTS {
292 my ($self, $errname) = @_;
293 my $proto = prototype($errname);
294 defined($proto) && $proto eq "";
295}
296
297tie %!, __PACKAGE__;
298
2991;
300__END__
301
302=head1 NAME
303
304Errno - System errno constants
305
306=head1 SYNOPSIS
307
308 use Errno qw(EINTR EIO :POSIX);
309
310=head1 DESCRIPTION
311
312C<Errno> defines and conditionally exports all the error constants
313defined in your system C<errno.h> include file. It has a single export
314tag, C<:POSIX>, which will export all POSIX defined error numbers.
315
93014de6 316C<Errno> also makes C<%!> magic such that each element of C<%!> has a
68301627 317non-zero value only if C<$!> is set to that value. For example:
eab60bb1 318
319 use Errno;
3cb6de81 320
eab60bb1 321 unless (open(FH, "/fangorn/spouse")) {
322 if ($!{ENOENT}) {
323 warn "Get a wife!\n";
324 } else {
325 warn "This path is barred: $!";
326 }
327 }
328
68301627 329If a specified constant C<EFOO> does not exist on the system, C<$!{EFOO}>
330returns C<"">. You may use C<exists $!{EFOO}> to check whether the
93014de6 331constant is available on the system.
332
68301627 333=head1 CAVEATS
334
335Importing a particular constant may not be very portable, because the
336import will fail on platforms that do not have that constant. A more
337portable way to set C<$!> to a valid value is to use:
338
339 if (exists &Errno::EFOO) {
340 $! = &Errno::EFOO;
341 }
342
eab60bb1 343=head1 AUTHOR
344
345Graham Barr <gbarr@pobox.com>
346
347=head1 COPYRIGHT
348
349Copyright (c) 1997-8 Graham Barr. All rights reserved.
350This program is free software; you can redistribute it and/or modify it
351under the same terms as Perl itself.
352
353=cut
354
355ESQ
356
357}