This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
11fed4f68173f8f2758e8c03739f2cf11cbb46e4
[perl5.git] / makedef.pl
1 #./perl -w
2 #
3 # Create the export list for perl.
4 #
5 # Needed by WIN32 and OS/2 for creating perl.dll,
6 # and by AIX for creating libperl.a when -Dusershrplib is in effect,
7 # and by VMS for creating perlshr.exe.
8 #
9 # Reads from information stored in
10 #
11 #    config.h
12 #    config.sh
13 #    global.sym
14 #    globvar.sym
15 #    intrpvar.h
16 #    miniperl.map (on OS/2)
17 #    perl5.def    (on OS/2; this is the old version of the file being made)
18 #    perlio.sym
19 #    perlvars.h
20 #
21 # plus long lists of function names hard-coded directly in this script.
22 #
23 # Writes the result to STDOUT.
24 #
25 # Normally this script is invoked from a makefile (e.g. win32/Makefile),
26 # which redirects STDOUT to a suitable file, such as:
27 #
28 #    perl5.def   OS/2
29 #    perldll.def Windows
30 #    perl.exp    AIX
31 #    perl.imp    NetWare
32 #    makedef.lis VMS
33
34 BEGIN { unshift @INC, "lib" }
35 use Config;
36 use strict;
37
38 use vars qw($PLATFORM $CCTYPE $FILETYPE $TARG_DIR);
39
40 $CCTYPE = 'MSVC';
41 $TARG_DIR = '';
42
43 my (%define, %ordinal);
44
45 while (@ARGV) {
46     my $flag = shift;
47     if ($flag =~ s/^CC_FLAGS=/ /) {
48         for my $fflag ($flag =~ /(?:^|\s)-D(\S+)/g) {
49             $fflag     .= '=1' unless $fflag =~ /^(\w+)=/;
50             $define{$1} = $2   if $fflag =~ /^(\w+)=(.+)$/;
51         }
52         next;
53     }
54     $define{$1} = 1 if ($flag =~ /^-D(\w+)$/);
55     $define{$1} = $2 if ($flag =~ /^-D(\w+)=(.+)$/);
56     $CCTYPE   = $1 if ($flag =~ /^CCTYPE=(\w+)$/);
57     $PLATFORM = $1 if ($flag =~ /^PLATFORM=(\w+)$/);
58     $FILETYPE = $1 if ($flag =~ /^FILETYPE=(\w+)$/);
59     $TARG_DIR = $1 if $flag =~ /^TARG_DIR=(.+)$/;
60 }
61
62 my @PLATFORM = qw(aix win32 wince os2 netware vms);
63 my %PLATFORM;
64 @PLATFORM{@PLATFORM} = ();
65
66 defined $PLATFORM || die "PLATFORM undefined, must be one of: @PLATFORM\n";
67 exists $PLATFORM{$PLATFORM} || die "PLATFORM must be one of: @PLATFORM\n";
68
69 # Add the compile-time options that miniperl was built with to %define.
70 # On Win32 these are not the same options as perl itself will be built
71 # with since miniperl is built with a canned config (one of the win32/
72 # config_H.*) and none of the BUILDOPT's that are set in the makefiles,
73 # but they do include some #define's that are hard-coded in various
74 # source files and header files and don't include any BUILDOPT's that
75 # the user might have chosen to disable because the canned configs are
76 # minimal configs that don't include any of those options.
77
78 my @options = sort(Config::bincompat_options(), Config::non_bincompat_options());
79 print STDERR "Options: (@options)\n";
80 $define{$_} = 1 foreach @options;
81
82 my %exportperlmalloc =
83     (
84        Perl_malloc              =>      "malloc",
85        Perl_mfree               =>      "free",
86        Perl_realloc             =>      "realloc",
87        Perl_calloc              =>      "calloc",
88     );
89
90 my $exportperlmalloc = $PLATFORM eq 'os2';
91
92 my $config_sh   = "config.sh";
93 my $config_h    = "config.h";
94 my $intrpvar_h  = "intrpvar.h";
95 my $perlvars_h  = "perlvars.h";
96 my $global_sym  = "global.sym";
97 my $globvar_sym = "globvar.sym";
98 my $perlio_sym  = "perlio.sym";
99 my $static_ext = "";
100
101 my %skip;
102 # All platforms export boot_DynaLoader unconditionally.
103 my %export = ( boot_DynaLoader => 1 );
104
105 s/^/$TARG_DIR/ foreach($intrpvar_h, $perlvars_h, $global_sym, $globvar_sym,
106                        $perlio_sym, $config_sh);
107
108 unless ($PLATFORM eq 'win32' || $PLATFORM eq 'wince' || $PLATFORM eq 'netware') {
109     open(CFG,$config_sh) || die "Cannot open $config_sh: $!\n";
110     while (<CFG>) {
111         if (/^(?:ccflags|optimize)='(.+)'$/) {
112             $_ = $1;
113             $define{$1} = 1 while /-D(\w+)/g;
114         }
115         $define{$1} = $2
116             if /^(config_args|archname|perl_patchlevel)='(.+)'$/;
117     }
118     close(CFG);
119 }
120 if ($PLATFORM eq 'win32' || $PLATFORM eq 'wince') {
121     open(CFG, '<', $config_sh) || die "Cannot open $config_sh: $!\n";
122     if ((join '', <CFG>) =~ /^static_ext='(.*)'$/m) {
123         $static_ext = $1;
124     }
125     close(CFG);
126 }
127
128 open(CFG,$config_h) || die "Cannot open $config_h: $!\n";
129 while (<CFG>) {
130     $define{$1} = 1 if /^\s*\#\s*define\s+(MYMALLOC|MULTIPLICITY
131                                            |SPRINTF_RETURNS_STRLEN
132                                            |(?:PERL|USE|HAS)_\w+)\b/x;
133 }
134 close(CFG);
135
136 # perl.h logic duplication begins
137
138 if ($define{PERL_IMPLICIT_SYS}) {
139     $define{PL_OP_SLAB_ALLOC} = 1;
140 }
141
142 if ($define{USE_ITHREADS}) {
143     if (!$define{MULTIPLICITY}) {
144         $define{MULTIPLICITY} = 1;
145     }
146 }
147
148 $define{PERL_IMPLICIT_CONTEXT} ||=
149     $define{USE_ITHREADS} ||
150     $define{MULTIPLICITY} ;
151
152 if ($define{USE_ITHREADS} && $PLATFORM ne 'win32' && $^O ne 'darwin') {
153     $define{USE_REENTRANT_API} = 1;
154 }
155
156 # perl.h logic duplication ends
157
158 my $sym_ord = 0;
159
160 print STDERR "Defines: (" . join(' ', sort keys %define) . ")\n";
161
162 if ($PLATFORM =~ /^win(?:32|ce)$/) {
163     (my $dll = ($define{PERL_DLL} || "perl515")) =~ s/\.dll$//i;
164     print "LIBRARY $dll\n";
165     # The DESCRIPTION module definition file statement is not supported
166     # by VC7 onwards.
167     if ($CCTYPE =~ /^(?:MSVC60|GCC|BORLAND)$/) {
168         print "DESCRIPTION 'Perl interpreter'\n";
169     }
170     print "EXPORTS\n";
171 }
172 elsif ($PLATFORM eq 'os2') {
173     if (open my $fh, '<', 'perl5.def') {
174       while (<$fh>) {
175         last if /^\s*EXPORTS\b/;
176       }
177       while (<$fh>) {
178         $ordinal{$1} = $2 if /^\s*"(\w+)"\s*(?:=\s*"\w+"\s*)?\@(\d+)\s*$/;
179         # This allows skipping ordinals which were used in older versions
180         $sym_ord = $1 if /^\s*;\s*LAST_ORDINAL\s*=\s*(\d+)\s*$/;
181       }
182       $sym_ord < $_ and $sym_ord = $_ for values %ordinal; # Take the max
183     }
184     (my $v = $]) =~ s/(\d\.\d\d\d)(\d\d)$/$1_$2/;
185     $v .= '-thread' if $define{archname} =~ /-thread/;
186     (my $dll = $define{PERL_DLL}) =~ s/\.dll$//i;
187     $v .= "\@$define{perl_patchlevel}" if $define{perl_patchlevel};
188     my $d = "DESCRIPTION '\@#perl5-porters\@perl.org:$v#\@ Perl interpreter, configured as $define{config_args}'";
189     $d = substr($d, 0, 249) . "...'" if length $d > 253;
190     print <<"---EOP---";
191 LIBRARY '$dll' INITINSTANCE TERMINSTANCE
192 $d
193 STACKSIZE 32768
194 CODE LOADONCALL
195 DATA LOADONCALL NONSHARED MULTIPLE
196 EXPORTS
197 ---EOP---
198 }
199 elsif ($PLATFORM eq 'aix') {
200     my $OSVER = `uname -v`;
201     chop $OSVER;
202     my $OSREL = `uname -r`;
203     chop $OSREL;
204     if ($OSVER > 4 || ($OSVER == 4 && $OSREL >= 3)) {
205         print "#! ..\n";
206     } else {
207         print "#!\n";
208     }
209 }
210 elsif ($PLATFORM eq 'netware') {
211         if ($FILETYPE eq 'def') {
212         print "LIBRARY perl515\n";
213         print "DESCRIPTION 'Perl interpreter for NetWare'\n";
214         print "EXPORTS\n";
215         }
216 }
217
218 sub emit_symbols {
219     my $list = shift;
220     foreach my $symbol (@$list) {
221         my $skipsym = $symbol;
222         # XXX hack
223         if ($define{MULTIPLICITY}) {
224             $skipsym =~ s/^Perl_[GIT](\w+)_ptr$/PL_$1/;
225         }
226         ++$export{$symbol} unless exists $skip{$skipsym};
227     }
228 }
229
230 if ($PLATFORM ne 'os2') {
231     ++$skip{$_} foreach qw(
232                      PL_cryptseen
233                      PL_opsave
234                      Perl_GetVars
235                      Perl_dump_fds
236                      Perl_my_bcopy
237                      Perl_my_bzero
238                      Perl_my_chsize
239                      Perl_my_htonl
240                      Perl_my_memcmp
241                      Perl_my_memset
242                      Perl_my_ntohl
243                      Perl_my_swap
244                          );
245     if ($PLATFORM eq 'vms') {
246         ++$skip{PL_statusvalue_posix};
247     } else {
248         ++$skip{PL_statusvalue_vms};
249         if ($PLATFORM ne 'aix') {
250             ++$skip{$_} foreach qw(
251                                 PL_DBcv
252                                 PL_generation
253                                 PL_lastgotoprobe
254                                 PL_modcount
255                                 PL_timesbuf
256                                 main
257                                  );
258         }
259     }
260 }
261
262 if ($PLATFORM ne 'vms') {
263     # VMS does its own thing for these symbols.
264     ++$skip{$_} foreach qw(
265                         PL_sig_handlers_initted
266                         PL_sig_ignoring
267                         PL_sig_defaulting
268                          );
269     if ($PLATFORM ne 'win32') {
270         ++$skip{$_} foreach qw(
271                             Perl_do_spawn
272                             Perl_do_spawn_nowait
273                             Perl_do_aspawn
274                              );
275     }
276 }
277
278 if ($PLATFORM eq 'os2') {
279     emit_symbols([qw(
280                     ctermid
281                     get_sysinfo
282                     Perl_OS2_init
283                     Perl_OS2_init3
284                     Perl_OS2_term
285                     OS2_Perl_data
286                     dlopen
287                     dlsym
288                     dlerror
289                     dlclose
290                     dup2
291                     dup
292                     my_tmpfile
293                     my_tmpnam
294                     my_flock
295                     my_rmdir
296                     my_mkdir
297                     my_getpwuid
298                     my_getpwnam
299                     my_getpwent
300                     my_setpwent
301                     my_endpwent
302                     fork_with_resources
303                     croak_with_os2error
304                     setgrent
305                     endgrent
306                     getgrent
307                     malloc_mutex
308                     threads_mutex
309                     nthreads
310                     nthreads_cond
311                     os2_cond_wait
312                     os2_stat
313                     os2_execname
314                     async_mssleep
315                     msCounter
316                     InfoTable
317                     pthread_join
318                     pthread_create
319                     pthread_detach
320                     XS_Cwd_change_drive
321                     XS_Cwd_current_drive
322                     XS_Cwd_extLibpath
323                     XS_Cwd_extLibpath_set
324                     XS_Cwd_sys_abspath
325                     XS_Cwd_sys_chdir
326                     XS_Cwd_sys_cwd
327                     XS_Cwd_sys_is_absolute
328                     XS_Cwd_sys_is_relative
329                     XS_Cwd_sys_is_rooted
330                     XS_DynaLoader_mod2fname
331                     XS_File__Copy_syscopy
332                     Perl_Register_MQ
333                     Perl_Deregister_MQ
334                     Perl_Serve_Messages
335                     Perl_Process_Messages
336                     init_PMWIN_entries
337                     PMWIN_entries
338                     Perl_hab_GET
339                     loadByOrdinal
340                     pExtFCN
341                     os2error
342                     ResetWinError
343                     CroakWinError
344                     PL_do_undump
345                     )]);
346     emit_symbols([qw(os2_cond_wait
347                      pthread_join
348                      pthread_create
349                      pthread_detach
350                     )])
351       if $define{'USE_5005THREADS'} or $define{'USE_ITHREADS'};
352 }
353 elsif ($PLATFORM eq 'vms') {
354     emit_symbols([qw(
355                         Perl_cando
356                         Perl_cando_by_name
357                         Perl_closedir
358                         Perl_csighandler_init
359                         Perl_do_rmdir
360                         Perl_fileify_dirspec
361                         Perl_fileify_dirspec_ts
362                         Perl_fileify_dirspec_utf8
363                         Perl_fileify_dirspec_utf8_ts
364                         Perl_flex_fstat
365                         Perl_flex_lstat
366                         Perl_flex_stat
367                         Perl_kill_file
368                         Perl_my_chdir
369                         Perl_my_chmod
370                         Perl_my_crypt
371                         Perl_my_endpwent
372                         Perl_my_fclose
373                         Perl_my_fdopen
374                         Perl_my_fgetname
375                         Perl_my_flush
376                         Perl_my_fwrite
377                         Perl_my_gconvert
378                         Perl_my_getenv
379                         Perl_my_getenv_len
380                         Perl_my_getlogin
381                         Perl_my_getpwnam
382                         Perl_my_getpwuid
383                         Perl_my_gmtime
384                         Perl_my_kill
385                         Perl_my_localtime
386                         Perl_my_mkdir
387                         Perl_my_sigaction 
388                         Perl_my_symlink
389                         Perl_my_time
390                         Perl_my_tmpfile
391                         Perl_my_trnlnm
392                         Perl_my_utime
393                         Perl_my_waitpid
394                         Perl_opendir
395                         Perl_pathify_dirspec
396                         Perl_pathify_dirspec_ts
397                         Perl_pathify_dirspec_utf8
398                         Perl_pathify_dirspec_utf8_ts
399                         Perl_readdir
400                         Perl_readdir_r
401                         Perl_rename
402                         Perl_rmscopy
403                         Perl_rmsexpand
404                         Perl_rmsexpand_ts
405                         Perl_rmsexpand_utf8
406                         Perl_rmsexpand_utf8_ts
407                         Perl_seekdir
408                         Perl_sig_to_vmscondition
409                         Perl_telldir
410                         Perl_tounixpath
411                         Perl_tounixpath_ts
412                         Perl_tounixpath_utf8
413                         Perl_tounixpath_utf8_ts
414                         Perl_tounixspec
415                         Perl_tounixspec_ts
416                         Perl_tounixspec_utf8
417                         Perl_tounixspec_utf8_ts
418                         Perl_tovmspath
419                         Perl_tovmspath_ts
420                         Perl_tovmspath_utf8
421                         Perl_tovmspath_utf8_ts
422                         Perl_tovmsspec
423                         Perl_tovmsspec_ts
424                         Perl_tovmsspec_utf8
425                         Perl_tovmsspec_utf8_ts
426                         Perl_trim_unixpath
427                         Perl_vms_case_tolerant
428                         Perl_vms_do_aexec
429                         Perl_vms_do_exec
430                         Perl_vms_image_init
431                         Perl_vms_realpath
432                         Perl_vmssetenv
433                         Perl_vmssetuserlnm
434                         Perl_vmstrnenv
435                         PerlIO_openn
436                      )]);
437 }
438
439 unless ($define{UNLINK_ALL_VERSIONS}) {
440     ++$skip{Perl_unlnk};
441 }
442
443 unless ($define{'DEBUGGING'}) {
444     ++$skip{$_} foreach qw(
445                     Perl_debop
446                     Perl_debprofdump
447                     Perl_debstack
448                     Perl_debstackptrs
449                     Perl_pad_sv
450                     Perl_pad_setsv
451                     Perl_hv_assert
452                     PL_block_type
453                     PL_watchaddr
454                     PL_watchok
455                     PL_watch_pvx
456                          );
457 }
458
459 if ($define{'PERL_IMPLICIT_SYS'}) {
460     ++$skip{$_} foreach qw(
461                     Perl_my_popen
462                     Perl_my_pclose
463                          );
464     ++$export{$_} foreach qw(perl_get_host_info perl_alloc_override);
465     ++$export{perl_clone_host} if $define{USE_ITHREADS};
466 }
467 else {
468     ++$skip{$_} foreach qw(
469                     PL_Mem
470                     PL_MemShared
471                     PL_MemParse
472                     PL_Env
473                     PL_StdIO
474                     PL_LIO
475                     PL_Dir
476                     PL_Sock
477                     PL_Proc
478                     perl_alloc_using
479                     perl_clone_using
480                          );
481 }
482
483 unless ($define{'PERL_OLD_COPY_ON_WRITE'}) {
484     ++$skip{Perl_sv_setsv_cow};
485 }
486
487 unless ($define{'USE_REENTRANT_API'}) {
488     ++$skip{PL_reentrant_buffer};
489 }
490
491 if ($define{'MYMALLOC'}) {
492     emit_symbols [qw(
493                     Perl_dump_mstats
494                     Perl_get_mstats
495                     Perl_strdup
496                     Perl_putenv
497                     MallocCfg_ptr
498                     MallocCfgP_ptr
499                     )];
500     if ($define{'USE_ITHREADS'}) {
501         emit_symbols [qw(
502                         PL_malloc_mutex
503                         )];
504     }
505     else {
506         ++$skip{PL_malloc_mutex};
507     }
508 }
509 else {
510     ++$skip{$_} foreach qw(
511                     PL_malloc_mutex
512                     Perl_dump_mstats
513                     Perl_get_mstats
514                     MallocCfg_ptr
515                     MallocCfgP_ptr
516                          );
517 }
518
519 if ($define{'PERL_USE_SAFE_PUTENV'}) {
520     ++$skip{PL_use_safe_putenv};
521 }
522
523 unless ($define{'USE_ITHREADS'}) {
524     ++$skip{PL_thr_key};
525 }
526
527 # USE_5005THREADS symbols. Kept as reference for easier removal
528 ++$skip{$_} foreach qw(
529                     PL_sv_mutex
530                     PL_strtab_mutex
531                     PL_svref_mutex
532                     PL_cred_mutex
533                     PL_eval_mutex
534                     PL_fdpid_mutex
535                     PL_sv_lock_mutex
536                     PL_eval_cond
537                     PL_eval_owner
538                     PL_threads_mutex
539                     PL_nthreads
540                     PL_nthreads_cond
541                     PL_threadnum
542                     PL_threadsv_names
543                     PL_thrsv
544                     PL_vtbl_mutex
545                     Perl_condpair_magic
546                     Perl_new_struct_thread
547                     Perl_per_thread_magicals
548                     Perl_thread_create
549                     Perl_find_threadsv
550                     Perl_unlock_condpair
551                     Perl_magic_mutexfree
552                     Perl_sv_lock
553                      );
554
555 unless ($define{'USE_ITHREADS'}) {
556     ++$skip{$_} foreach qw(
557                     PL_op_mutex
558                     PL_regex_pad
559                     PL_regex_padav
560                     PL_dollarzero_mutex
561                     PL_hints_mutex
562                     PL_my_ctx_mutex
563                     PL_perlio_mutex
564                     Perl_clone_params_del
565                     Perl_clone_params_new
566                     Perl_parser_dup
567                     Perl_dirp_dup
568                     Perl_cx_dup
569                     Perl_si_dup
570                     Perl_any_dup
571                     Perl_ss_dup
572                     Perl_fp_dup
573                     Perl_gp_dup
574                     Perl_he_dup
575                     Perl_mg_dup
576                     Perl_re_dup_guts
577                     Perl_sv_dup
578                     Perl_sv_dup_inc
579                     Perl_rvpv_dup
580                     Perl_hek_dup
581                     Perl_sys_intern_dup
582                     perl_clone
583                     perl_clone_using
584                     Perl_stashpv_hvname_match
585                     Perl_regdupe_internal
586                     Perl_newPADOP
587                          );
588 }
589
590 unless ($define{'PERL_IMPLICIT_CONTEXT'}) {
591     ++$skip{$_} foreach qw(
592                     PL_my_cxt_index
593                     PL_my_cxt_list
594                     PL_my_cxt_size
595                     PL_my_cxt_keys
596                     Perl_croak_nocontext
597                     Perl_die_nocontext
598                     Perl_deb_nocontext
599                     Perl_form_nocontext
600                     Perl_load_module_nocontext
601                     Perl_mess_nocontext
602                     Perl_warn_nocontext
603                     Perl_warner_nocontext
604                     Perl_newSVpvf_nocontext
605                     Perl_sv_catpvf_nocontext
606                     Perl_sv_setpvf_nocontext
607                     Perl_sv_catpvf_mg_nocontext
608                     Perl_sv_setpvf_mg_nocontext
609                     Perl_my_cxt_init
610                     Perl_my_cxt_index
611                          );
612 }
613
614 unless ($define{'PL_OP_SLAB_ALLOC'}) {
615     ++$skip{$_} foreach qw(
616                      PL_OpPtr
617                      PL_OpSlab
618                      PL_OpSpace
619                      Perl_Slab_Alloc
620                      Perl_Slab_Free
621                          );
622 }
623
624 unless ($define{'PERL_DEBUG_READONLY_OPS'}) {
625     ++$skip{$_} foreach qw(
626                     PL_slab_count
627                     PL_slabs
628                          );
629 }
630
631 unless ($define{'THREADS_HAVE_PIDS'}) {
632     ++$skip{PL_ppid};
633 }
634
635 unless ($define{'PERL_NEED_APPCTX'}) {
636     ++$skip{PL_appctx};
637 }
638
639 unless ($define{'PERL_NEED_TIMESBASE'}) {
640     ++$skip{PL_timesbase};
641 }
642
643 unless ($define{'DEBUG_LEAKING_SCALARS'}) {
644     ++$skip{PL_sv_serial};
645 }
646
647 unless ($define{'DEBUG_LEAKING_SCALARS_FORK_DUMP'}) {
648     ++$skip{PL_dumper_fd};
649 }
650
651 unless ($define{'PERL_DONT_CREATE_GVSV'}) {
652     ++$skip{Perl_gv_SVadd};
653 }
654
655 if ($define{'SPRINTF_RETURNS_STRLEN'}) {
656     ++$skip{Perl_my_sprintf};
657 }
658
659 unless ($define{'PERL_USES_PL_PIDSTATUS'}) {
660     ++$skip{PL_pidstatus};
661 }
662
663 unless ($define{'PERL_TRACK_MEMPOOL'}) {
664     ++$skip{PL_memory_debug_header};
665 }
666
667 unless ($define{PERL_MAD}) {
668     ++$skip{$_} foreach qw(
669                     PL_madskills
670                     PL_xmlfp
671                          );
672 }
673
674 unless ($define{'MULTIPLICITY'}) {
675     ++$skip{$_} foreach qw(
676                     PL_interp_size
677                     PL_interp_size_5_16_0
678                          );
679 }
680
681 unless ($define{'PERL_GLOBAL_STRUCT'}) {
682     ++$skip{PL_global_struct_size};
683 }
684
685 unless ($define{'PERL_GLOBAL_STRUCT_PRIVATE'}) {
686     ++$skip{$_} foreach qw(
687                     PL_my_cxt_keys
688                     Perl_my_cxt_index
689                          );
690 }
691
692 unless ($define{HAS_MMAP}) {
693     ++$skip{PL_mmap_page_size};
694 }
695
696 if ($define{HAS_SIGACTION}) {
697     ++$skip{PL_sig_trapped};
698 }
699
700 unless ($define{USE_LOCALE_COLLATE}) {
701     ++$skip{$_} foreach qw(
702                     PL_collation_ix
703                     PL_collation_name
704                     PL_collation_standard
705                     PL_collxfrm_base
706                     PL_collxfrm_mult
707                     Perl_sv_collxfrm
708                     Perl_sv_collxfrm_flags
709                          );
710 }
711
712 unless ($define{USE_LOCALE_NUMERIC}) {
713     ++$skip{$_} foreach qw(
714                     PL_numeric_local
715                     PL_numeric_name
716                     PL_numeric_radix_sv
717                     PL_numeric_standard
718                          );
719 }
720
721 unless ($define{HAVE_INTERP_INTERN}) {
722     ++$skip{$_} foreach qw(
723                     Perl_sys_intern_clear
724                     Perl_sys_intern_dup
725                     Perl_sys_intern_init
726                     PL_sys_intern
727                          );
728 }
729
730 if ($define{HAS_SIGNBIT}) {
731     ++$skip{Perl_signbit};
732 }
733
734 sub readvar {
735     my $file = shift;
736     my $proc = shift || sub { "PL_$_[2]" };
737     open my $vars, '<', $file or die die "Cannot open $file: $!\n";
738
739     # All symbols have a Perl_ prefix because that's what embed.h sticks
740     # in front of them.  The A?I?S?C? is strictly speaking wrong.
741     map {/\bPERLVAR(A?I?S?C?)\(([IGT])(\w+)/ ? &$proc($1,$2,$3) : ()} <$vars>;
742 }
743
744 if ($define{'PERL_GLOBAL_STRUCT'}) {
745     ++$skip{$_} foreach readvar($perlvars_h);
746     ++$export{Perl_GetVars};
747     emit_symbols [qw(PL_Vars PL_VarsPtr)] unless $CCTYPE eq 'GCC';
748 } else {
749     ++$skip{$_} foreach qw(Perl_init_global_struct Perl_free_global_struct);
750 }
751
752 # functions from *.sym files
753
754 my @syms = ($global_sym, $globvar_sym);
755
756 # Symbols that are the public face of the PerlIO layers implementation
757 # These are in _addition to_ the public face of the abstraction
758 # and need to be exported to allow XS modules to implement layers
759 my @layer_syms = qw(
760                     PerlIOBase_binmode
761                     PerlIOBase_clearerr
762                     PerlIOBase_close
763                     PerlIOBase_dup
764                     PerlIOBase_eof
765                     PerlIOBase_error
766                     PerlIOBase_fileno
767                     PerlIOBase_noop_fail
768                     PerlIOBase_noop_ok
769                     PerlIOBase_popped
770                     PerlIOBase_pushed
771                     PerlIOBase_read
772                     PerlIOBase_setlinebuf
773                     PerlIOBase_unread
774                     PerlIOBuf_bufsiz
775                     PerlIOBuf_close
776                     PerlIOBuf_dup
777                     PerlIOBuf_fill
778                     PerlIOBuf_flush
779                     PerlIOBuf_get_base
780                     PerlIOBuf_get_cnt
781                     PerlIOBuf_get_ptr
782                     PerlIOBuf_open
783                     PerlIOBuf_popped
784                     PerlIOBuf_pushed
785                     PerlIOBuf_read
786                     PerlIOBuf_seek
787                     PerlIOBuf_set_ptrcnt
788                     PerlIOBuf_tell
789                     PerlIOBuf_unread
790                     PerlIOBuf_write
791                     PerlIO_allocate
792                     PerlIO_apply_layera
793                     PerlIO_apply_layers
794                     PerlIO_arg_fetch
795                     PerlIO_debug
796                     PerlIO_define_layer
797                     PerlIO_find_layer
798                     PerlIO_isutf8
799                     PerlIO_layer_fetch
800                     PerlIO_list_alloc
801                     PerlIO_list_free
802                     PerlIO_modestr
803                     PerlIO_parse_layers
804                     PerlIO_pending
805                     PerlIO_perlio
806                     PerlIO_pop
807                     PerlIO_push
808                     PerlIO_sv_dup
809                     Perl_PerlIO_clearerr
810                     Perl_PerlIO_close
811                     Perl_PerlIO_context_layers
812                     Perl_PerlIO_eof
813                     Perl_PerlIO_error
814                     Perl_PerlIO_fileno
815                     Perl_PerlIO_fill
816                     Perl_PerlIO_flush
817                     Perl_PerlIO_get_base
818                     Perl_PerlIO_get_bufsiz
819                     Perl_PerlIO_get_cnt
820                     Perl_PerlIO_get_ptr
821                     Perl_PerlIO_read
822                     Perl_PerlIO_seek
823                     Perl_PerlIO_set_cnt
824                     Perl_PerlIO_set_ptrcnt
825                     Perl_PerlIO_setlinebuf
826                     Perl_PerlIO_stderr
827                     Perl_PerlIO_stdin
828                     Perl_PerlIO_stdout
829                     Perl_PerlIO_tell
830                     Perl_PerlIO_unread
831                     Perl_PerlIO_write
832 );
833 if ($PLATFORM eq 'netware') {
834     push(@layer_syms,'PL_def_layerlist','PL_known_layers','PL_perlio');
835 }
836
837 if ($define{'USE_PERLIO'}) {
838     # Export the symols that make up the PerlIO abstraction, regardless
839     # of its implementation - read from a file
840     push @syms, $perlio_sym;
841
842     # This part is then dependent on how the abstraction is implemented
843     if ($define{'USE_SFIO'}) {
844         # Old legacy non-stdio "PerlIO"
845         ++$skip{$_} foreach @layer_syms;
846         ++$skip{perlsio_binmode};
847         # SFIO defines most of the PerlIO routines as macros
848         # So undo most of what $perlio_sym has just done - d'oh !
849         # Perhaps it would be better to list the ones which do exist
850         # And emit them
851         ++$skip{$_} foreach qw(
852                          PerlIO_canset_cnt
853                          PerlIO_clearerr
854                          PerlIO_close
855                          PerlIO_eof
856                          PerlIO_error
857                          PerlIO_exportFILE
858                          PerlIO_fast_gets
859                          PerlIO_fdopen
860                          PerlIO_fileno
861                          PerlIO_findFILE
862                          PerlIO_flush
863                          PerlIO_get_base
864                          PerlIO_get_bufsiz
865                          PerlIO_get_cnt
866                          PerlIO_get_ptr
867                          PerlIO_getc
868                          PerlIO_getname
869                          PerlIO_has_base
870                          PerlIO_has_cntptr
871                          PerlIO_importFILE
872                          PerlIO_open
873                          PerlIO_printf
874                          PerlIO_putc
875                          PerlIO_puts
876                          PerlIO_read
877                          PerlIO_releaseFILE
878                          PerlIO_reopen
879                          PerlIO_rewind
880                          PerlIO_seek
881                          PerlIO_set_cnt
882                          PerlIO_set_ptrcnt
883                          PerlIO_setlinebuf
884                          PerlIO_sprintf
885                          PerlIO_stderr
886                          PerlIO_stdin
887                          PerlIO_stdout
888                          PerlIO_stdoutf
889                          PerlIO_tell
890                          PerlIO_ungetc
891                          PerlIO_vprintf
892                          PerlIO_write
893                          PerlIO_perlio
894                          Perl_PerlIO_clearerr
895                          Perl_PerlIO_close
896                          Perl_PerlIO_eof
897                          Perl_PerlIO_error
898                          Perl_PerlIO_fileno
899                          Perl_PerlIO_fill
900                          Perl_PerlIO_flush
901                          Perl_PerlIO_get_base
902                          Perl_PerlIO_get_bufsiz
903                          Perl_PerlIO_get_cnt
904                          Perl_PerlIO_get_ptr
905                          Perl_PerlIO_read
906                          Perl_PerlIO_seek
907                          Perl_PerlIO_set_cnt
908                          Perl_PerlIO_set_ptrcnt
909                          Perl_PerlIO_setlinebuf
910                          Perl_PerlIO_stderr
911                          Perl_PerlIO_stdin
912                          Perl_PerlIO_stdout
913                          Perl_PerlIO_tell
914                          Perl_PerlIO_unread
915                          Perl_PerlIO_write
916                          PL_def_layerlist
917                          PL_known_layers
918                          PL_perlio
919                              );
920     }
921     else {
922         # PerlIO with layers - export implementation
923         emit_symbols \@layer_syms;
924         emit_symbols [qw(perlsio_binmode)];
925     }
926     if ($define{'USE_ITHREADS'}) {
927         emit_symbols [qw(
928                         PL_perlio_mutex
929                         )];
930     }
931     else {
932         ++$skip{PL_perlio_mutex};
933     }
934 } else {
935         # -Uuseperlio
936         # Skip the PerlIO layer symbols - although
937         # nothing should have exported them anyway.
938         ++$skip{$_} foreach @layer_syms;
939         ++$skip{$_} foreach qw(
940                         perlsio_binmode
941                         PL_def_layerlist
942                         PL_known_layers
943                         PL_perlio
944                         PL_perlio_debug_fd
945                         PL_perlio_fd_refcnt
946                         PL_perlio_fd_refcnt_size
947                              );
948
949         # Also do NOT add abstraction symbols from $perlio_sym
950         # abstraction is done as #define to stdio
951         # Remaining remnants that _may_ be functions are handled below.
952 }
953
954 for my $syms (@syms) {
955     open (GLOBAL, "<$syms") || die "failed to open $syms: $!\n";
956     while (<GLOBAL>) {
957         next if (!/^[A-Za-z]/);
958         # Functions have a Perl_ prefix
959         # Variables have a PL_ prefix
960         chomp($_);
961         my $symbol = ($syms =~ /var\.sym$/i ? "PL_" : "");
962         $symbol .= $_;
963         ++$export{$symbol} unless exists $skip{$symbol};
964     }
965     close(GLOBAL);
966 }
967
968 # variables
969
970 if ($define{'MULTIPLICITY'} && $define{PERL_GLOBAL_STRUCT}) {
971     for my $f ($perlvars_h) {
972         emit_symbols [readvar($f, sub { "Perl_" . $_[1] . $_[2] . "_ptr" })];
973     }
974     # XXX AIX seems to want the perlvars.h symbols, for some reason
975     if ($PLATFORM eq 'aix' or $PLATFORM eq 'os2') {     # OS/2 needs PL_thr_key
976         emit_symbols [readvar($perlvars_h)];
977     }
978 }
979 else {
980     unless ($define{'PERL_GLOBAL_STRUCT'}) {
981         emit_symbols [readvar($perlvars_h)];
982     }
983     unless ($define{MULTIPLICITY}) {
984         emit_symbols [readvar($intrpvar_h)];
985     }
986 }
987
988 sub try_symbol {
989     my $symbol = shift;
990     ++$export{$symbol} unless $skip{$symbol};
991 }
992
993 # Oddities from PerlIO
994 emit_symbols([qw(
995                     PerlIO_binmode
996                     PerlIO_getpos
997                     PerlIO_init
998                     PerlIO_setpos
999                     PerlIO_sprintf
1000                     PerlIO_sv_dup
1001                     PerlIO_tmpfile
1002                     PerlIO_vsprintf
1003                )]);
1004
1005 if ($PLATFORM eq 'win32') {
1006     try_symbol($_) foreach qw(
1007                                  setgid
1008                                  setuid
1009                                  win32_free_childdir
1010                                  win32_free_childenv
1011                                  win32_get_childdir
1012                                  win32_get_childenv
1013                                  win32_spawnvp
1014                             );
1015 }
1016
1017 if ($PLATFORM =~ /^win(?:32|ce)$/) {
1018     foreach my $symbol (qw(
1019                             Perl_init_os_extras
1020                             Perl_thread_create
1021                             Perl_win32_init
1022                             Perl_win32_term
1023                             RunPerl
1024                             win32_async_check
1025                             win32_errno
1026                             win32_environ
1027                             win32_abort
1028                             win32_fstat
1029                             win32_stat
1030                             win32_pipe
1031                             win32_popen
1032                             win32_pclose
1033                             win32_rename
1034                             win32_setmode
1035                             win32_chsize
1036                             win32_lseek
1037                             win32_tell
1038                             win32_dup
1039                             win32_dup2
1040                             win32_open
1041                             win32_close
1042                             win32_eof
1043                             win32_isatty
1044                             win32_read
1045                             win32_write
1046                             win32_mkdir
1047                             win32_rmdir
1048                             win32_chdir
1049                             win32_flock
1050                             win32_execv
1051                             win32_execvp
1052                             win32_htons
1053                             win32_ntohs
1054                             win32_htonl
1055                             win32_ntohl
1056                             win32_inet_addr
1057                             win32_inet_ntoa
1058                             win32_socket
1059                             win32_bind
1060                             win32_listen
1061                             win32_accept
1062                             win32_connect
1063                             win32_send
1064                             win32_sendto
1065                             win32_recv
1066                             win32_recvfrom
1067                             win32_shutdown
1068                             win32_closesocket
1069                             win32_ioctlsocket
1070                             win32_setsockopt
1071                             win32_getsockopt
1072                             win32_getpeername
1073                             win32_getsockname
1074                             win32_gethostname
1075                             win32_gethostbyname
1076                             win32_gethostbyaddr
1077                             win32_getprotobyname
1078                             win32_getprotobynumber
1079                             win32_getservbyname
1080                             win32_getservbyport
1081                             win32_select
1082                             win32_endhostent
1083                             win32_endnetent
1084                             win32_endprotoent
1085                             win32_endservent
1086                             win32_getnetent
1087                             win32_getnetbyname
1088                             win32_getnetbyaddr
1089                             win32_getprotoent
1090                             win32_getservent
1091                             win32_sethostent
1092                             win32_setnetent
1093                             win32_setprotoent
1094                             win32_setservent
1095                             win32_getenv
1096                             win32_putenv
1097                             win32_perror
1098                             win32_malloc
1099                             win32_calloc
1100                             win32_realloc
1101                             win32_free
1102                             win32_sleep
1103                             win32_times
1104                             win32_access
1105                             win32_alarm
1106                             win32_chmod
1107                             win32_open_osfhandle
1108                             win32_get_osfhandle
1109                             win32_ioctl
1110                             win32_link
1111                             win32_unlink
1112                             win32_utime
1113                             win32_gettimeofday
1114                             win32_uname
1115                             win32_wait
1116                             win32_waitpid
1117                             win32_kill
1118                             win32_str_os_error
1119                             win32_opendir
1120                             win32_readdir
1121                             win32_telldir
1122                             win32_seekdir
1123                             win32_rewinddir
1124                             win32_closedir
1125                             win32_longpath
1126                             win32_ansipath
1127                             win32_os_id
1128                             win32_getpid
1129                             win32_crypt
1130                             win32_dynaload
1131                             win32_clearenv
1132                             win32_stdin
1133                             win32_stdout
1134                             win32_stderr
1135                             win32_ferror
1136                             win32_feof
1137                             win32_strerror
1138                             win32_fprintf
1139                             win32_printf
1140                             win32_vfprintf
1141                             win32_vprintf
1142                             win32_fread
1143                             win32_fwrite
1144                             win32_fopen
1145                             win32_fdopen
1146                             win32_freopen
1147                             win32_fclose
1148                             win32_fputs
1149                             win32_fputc
1150                             win32_ungetc
1151                             win32_getc
1152                             win32_fileno
1153                             win32_clearerr
1154                             win32_fflush
1155                             win32_ftell
1156                             win32_fseek
1157                             win32_fgetpos
1158                             win32_fsetpos
1159                             win32_rewind
1160                             win32_tmpfile
1161                             win32_setbuf
1162                             win32_setvbuf
1163                             win32_flushall
1164                             win32_fcloseall
1165                             win32_fgets
1166                             win32_gets
1167                             win32_fgetc
1168                             win32_putc
1169                             win32_puts
1170                             win32_getchar
1171                             win32_putchar
1172                            ))
1173     {
1174         try_symbol($symbol);
1175     }
1176     if ($CCTYPE eq "BORLAND") {
1177         try_symbol('_matherr');
1178     }
1179 }
1180 elsif ($PLATFORM eq 'os2') {
1181     my (%mapped, @missing);
1182     open MAP, 'miniperl.map' or die 'Cannot read miniperl.map';
1183     /^\s*[\da-f:]+\s+(\w+)/i and $mapped{$1}++ foreach <MAP>;
1184     close MAP or die 'Cannot close miniperl.map';
1185
1186     @missing = grep { !exists $mapped{$_} }
1187                     keys %export;
1188     @missing = grep { !exists $exportperlmalloc{$_} } @missing;
1189     delete $export{$_} foreach @missing;
1190 }
1191 elsif ($PLATFORM eq 'netware') {
1192 foreach my $symbol (qw(
1193                         Perl_init_os_extras
1194                         Perl_thread_create
1195                         Perl_nw5_init
1196                         RunPerl
1197                         AllocStdPerl
1198                         FreeStdPerl
1199                         do_spawn2
1200                         do_aspawn
1201                         nw_uname
1202                         nw_stdin
1203                         nw_stdout
1204                         nw_stderr
1205                         nw_feof
1206                         nw_ferror
1207                         nw_fopen
1208                         nw_fclose
1209                         nw_clearerr
1210                         nw_getc
1211                         nw_fgets
1212                         nw_fputc
1213                         nw_fputs
1214                         nw_fflush
1215                         nw_ungetc
1216                         nw_fileno
1217                         nw_fdopen
1218                         nw_freopen
1219                         nw_fread
1220                         nw_fwrite
1221                         nw_setbuf
1222                         nw_setvbuf
1223                         nw_vfprintf
1224                         nw_ftell
1225                         nw_fseek
1226                         nw_rewind
1227                         nw_tmpfile
1228                         nw_fgetpos
1229                         nw_fsetpos
1230                         nw_dup
1231                         nw_access
1232                         nw_chmod
1233                         nw_chsize
1234                         nw_close
1235                         nw_dup2
1236                         nw_flock
1237                         nw_isatty
1238                         nw_link
1239                         nw_lseek
1240                         nw_stat
1241                         nw_mktemp
1242                         nw_open
1243                         nw_read
1244                         nw_rename
1245                         nw_setmode
1246                         nw_unlink
1247                         nw_utime
1248                         nw_write
1249                         nw_chdir
1250                         nw_rmdir
1251                         nw_closedir
1252                         nw_opendir
1253                         nw_readdir
1254                         nw_rewinddir
1255                         nw_seekdir
1256                         nw_telldir
1257                         nw_htonl
1258                         nw_htons
1259                         nw_ntohl
1260                         nw_ntohs
1261                         nw_accept
1262                         nw_bind
1263                         nw_connect
1264                         nw_endhostent
1265                         nw_endnetent
1266                         nw_endprotoent
1267                         nw_endservent
1268                         nw_gethostbyaddr
1269                         nw_gethostbyname
1270                         nw_gethostent
1271                         nw_gethostname
1272                         nw_getnetbyaddr
1273                         nw_getnetbyname
1274                         nw_getnetent
1275                         nw_getpeername
1276                         nw_getprotobyname
1277                         nw_getprotobynumber
1278                         nw_getprotoent
1279                         nw_getservbyname
1280                         nw_getservbyport
1281                         nw_getservent
1282                         nw_getsockname
1283                         nw_getsockopt
1284                         nw_inet_addr
1285                         nw_listen
1286                         nw_socket
1287                         nw_recv
1288                         nw_recvfrom
1289                         nw_select
1290                         nw_send
1291                         nw_sendto
1292                         nw_sethostent
1293                         nw_setnetent
1294                         nw_setprotoent
1295                         nw_setservent
1296                         nw_setsockopt
1297                         nw_inet_ntoa
1298                         nw_shutdown
1299                         nw_crypt
1300                         nw_execvp
1301                         nw_kill
1302                         nw_Popen
1303                         nw_Pclose
1304                         nw_Pipe
1305                         nw_times
1306                         nw_waitpid
1307                         nw_getpid
1308                         nw_spawnvp
1309                         nw_os_id
1310                         nw_open_osfhandle
1311                         nw_get_osfhandle
1312                         nw_abort
1313                         nw_sleep
1314                         nw_wait
1315                         nw_dynaload
1316                         nw_strerror
1317                         fnFpSetMode
1318                         fnInsertHashListAddrs
1319                         fnGetHashListAddrs
1320                         Perl_deb
1321                         Perl_sv_setsv
1322                         Perl_sv_catsv
1323                         Perl_sv_catpvn
1324                         Perl_sv_2pv
1325                         nw_freeenviron
1326                         Remove_Thread_Ctx
1327                            ))
1328     {
1329         try_symbol($symbol);
1330     }
1331 }
1332
1333 # records of type boot_module for statically linked modules (except Dynaloader)
1334 $static_ext =~ s/\//__/g;
1335 $static_ext =~ s/\bDynaLoader\b//;
1336 my @stat_mods = map {"boot_$_"} grep {/\S/} split /\s+/, $static_ext;
1337 foreach my $symbol (@stat_mods)
1338     {
1339         try_symbol($symbol);
1340     }
1341
1342 try_symbol("init_Win32CORE") if $static_ext =~ /\bWin32CORE\b/;
1343
1344 # Now all symbols should be defined because
1345 # next we are going to output them.
1346
1347 foreach my $symbol (sort keys %export) {
1348     output_symbol($symbol);
1349 }
1350
1351 if ($PLATFORM eq 'os2') {
1352         print <<EOP;
1353     dll_perlmain=main
1354     fill_extLibpath
1355     dir_subst
1356     Perl_OS2_handler_install
1357
1358 ; LAST_ORDINAL=$sym_ord
1359 EOP
1360 }
1361
1362 sub output_symbol {
1363     my $symbol = shift;
1364     if ($PLATFORM =~ /^win(?:32|ce)$/) {
1365         $symbol = "_$symbol" if $CCTYPE eq 'BORLAND';
1366         print "\t$symbol\n";
1367 # XXX: binary compatibility between compilers is an exercise
1368 # in frustration :-(
1369 #        if ($CCTYPE eq "BORLAND") {
1370 #           # workaround Borland quirk by exporting both the straight
1371 #           # name and a name with leading underscore.  Note the
1372 #           # alias *must* come after the symbol itself, if both
1373 #           # are to be exported. (Linker bug?)
1374 #           print "\t_$symbol\n";
1375 #           print "\t$symbol = _$symbol\n";
1376 #       }
1377 #       elsif ($CCTYPE eq 'GCC') {
1378 #           # Symbols have leading _ whole process is $%@"% slow
1379 #           # so skip aliases for now
1380 #           nprint "\t$symbol\n";
1381 #       }
1382 #       else {
1383 #           # for binary coexistence, export both the symbol and
1384 #           # alias with leading underscore
1385 #           print "\t$symbol\n";
1386 #           print "\t_$symbol = $symbol\n";
1387 #       }
1388     }
1389     elsif ($PLATFORM eq 'os2') {
1390         printf qq(    %-31s \@%s\n),
1391           qq("$symbol"), $ordinal{$symbol} || ++$sym_ord;
1392         printf qq(    %-31s \@%s\n),
1393           qq("$exportperlmalloc{$symbol}" = "$symbol"),
1394           $ordinal{$exportperlmalloc{$symbol}} || ++$sym_ord
1395           if $exportperlmalloc and exists $exportperlmalloc{$symbol};
1396     }
1397     elsif ($PLATFORM eq 'aix' || $PLATFORM eq 'vms') {
1398         print "$symbol\n";
1399     }
1400         elsif ($PLATFORM eq 'netware') {
1401         print "\t$symbol,\n";
1402         }
1403 }
1404
1405 1;