xref: /openbsd-src/gnu/usr.bin/perl/makedef.pl (revision 3d61058aa5c692477b6d18acfbbdb653a9930ff9)
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 -Duseshrplib is in effect,
7# and by VMS for creating perlshr.exe.
8#
9# Reads from information stored in
10#
11#    %Config::Config (ie config.sh)
12#    config.h
13#    embed.fnc
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#    regen/opcodes
21#
22# plus long lists of function names hard-coded directly in this script.
23#
24# Writes the result to STDOUT.
25#
26# Normally this script is invoked from a makefile (e.g. win32/Makefile),
27# which redirects STDOUT to a suitable file, such as:
28#
29#    perl5.def   OS/2
30#    perldll.def Windows
31#    perl.exp    AIX
32#    makedef.lis VMS
33
34use strict;
35use Config;
36use warnings;
37
38my $fold;
39my %ARGS;
40my %define;
41BEGIN {
42    %ARGS = (CCTYPE => 'MSVC', TARG_DIR => '');
43
44    sub process_cc_flags {
45	foreach (map {split /\s+/, $_} @_) {
46	    $define{$1} = $2 // 1 if /^-D(\w+)(?:=(.+))?/;
47	}
48    }
49
50    while (@ARGV) {
51	my $flag = shift;
52	if ($flag =~ /^(?:CC_FLAGS=)?(-D\w.*)/) {
53	    process_cc_flags($1);
54	} elsif ($flag =~ /^(CCTYPE|FILETYPE|PLATFORM|TARG_DIR|CONFIG_H)=(.+)$/) {
55	    $ARGS{$1} = $2;
56	} elsif ($flag eq '--sort-fold') {
57	    ++$fold;
58	}
59    }
60    my @PLATFORM = qw(aix win32 os2 vms test);
61    my %PLATFORM;
62    @PLATFORM{@PLATFORM} = ();
63
64    die "PLATFORM undefined, must be one of: @PLATFORM\n"
65	unless defined $ARGS{PLATFORM};
66    die "PLATFORM must be one of: @PLATFORM\n"
67	unless exists $PLATFORM{$ARGS{PLATFORM}};
68}
69
70use constant PLATFORM => $ARGS{PLATFORM};
71
72# This makes us able to use, e.g., $define{WIN32}, so you don't have to
73# remember what things came from %ARGS.
74$define{uc $ARGS{'PLATFORM'}} = 1;
75
76require "./$ARGS{TARG_DIR}regen/embed_lib.pl";
77
78# Is the following guard strictly necessary? Added during refactoring
79# to keep the same behaviour when merging other code into here.
80process_cc_flags(@Config{qw(ccflags optimize)})
81    if PLATFORM ne 'win32';
82
83# Add the compile-time options that miniperl was built with to %define.
84# On Win32 these are not the same options as perl itself will be built
85# with since miniperl is built with a canned config (one of the win32/
86# config_H.*) and none of the BUILDOPT's that are set in the makefiles,
87# but they do include some #define's that are hard-coded in various
88# source files and header files and don't include any BUILDOPT's that
89# the user might have chosen to disable because the canned configs are
90# minimal configs that don't include any of those options.
91
92my @options = sort(Config::bincompat_options(), Config::non_bincompat_options());
93print STDERR "Options: (@options)\n" unless PLATFORM eq 'test';
94$define{$_} = 1 foreach @options;
95
96my %exportperlmalloc =
97    (
98       Perl_malloc		=>	"malloc",
99       Perl_mfree		=>	"free",
100       Perl_realloc		=>	"realloc",
101       Perl_calloc		=>	"calloc",
102    );
103
104my $exportperlmalloc = PLATFORM eq 'os2';
105
106my $config_h = $ARGS{CONFIG_H} || "config.h";
107open(CFG, '<', $config_h) || die "Cannot open $config_h: $!\n";
108while (<CFG>) {
109    $define{$1} = 1 if /^\s*\#\s*define\s+(MYMALLOC|MULTIPLICITY
110                                           |KILL_BY_SIGPRC
111                                           |(?:PERL|USE|HAS)_\w+)\b/x;
112}
113close(CFG);
114
115if ($define{WIN32_USE_FAKE_OLD_MINGW_LOCALES}) {
116    $define{NO_POSIX_2008_LOCALE} = 1;
117}
118
119#==========================================================================
120# perl.h logic duplication begins
121
122
123if ($define{USE_THREADS}) {
124    if (!$define{MULTIPLICITY}) {
125        $define{MULTIPLICITY} = 1;
126    }
127}
128
129$define{MULTIPLICITY} ||= $define{PERL_IMPLICIT_CONTEXT} ;
130
131if ($define{MULTIPLICITY} && ! $define{WIN32}) {
132    $define{USE_REENTRANT_API} = 1;
133}
134
135if (! $define{NO_LOCALE}) {
136    if ( ! $define{NO_POSIX_2008_LOCALE}
137        && $define{HAS_NEWLOCALE}
138        && $define{HAS_USELOCALE}
139        && $define{HAS_DUPLOCALE}
140        && $define{HAS_FREELOCALE})
141    {
142        $define{HAS_POSIX_2008_LOCALE} = 1;
143        $define{USE_LOCALE} = 1;
144    }
145    elsif ($define{HAS_SETLOCALE}) {
146        $define{USE_LOCALE} = 1;
147    }
148}
149
150# https://en.wikipedia.org/wiki/Microsoft_Visual_C%2B%2B#Internal_version_numbering
151my $cctype = $ARGS{CCTYPE} =~ s/MSVC//r;
152if (   $define{USE_THREADS}
153    && $define{USE_LOCALE}
154    && ! $define{NO_LOCALE_THREADS})
155{
156    $define{USE_LOCALE_THREADS} = 1;
157}
158
159if (   $define{HAS_POSIX_2008_LOCALE}
160    && $define{USE_LOCALE}
161    && (! $define{HAS_SETLOCALE} || (     $define{USE_LOCALE_THREADS}
162                                     && ! $define{NO_POSIX_2008_LOCALE})
163                                     && ! $define{NO_THREAD_SAFE_LOCALE}))
164{
165    $define{USE_POSIX_2008_LOCALE} = 1;
166}
167
168if ($define{USE_LOCALE_THREADS} && ! $define{NO_THREAD_SAFE_LOCALE}) {
169    if (    $define{USE_POSIX_2008_LOCALE}
170        || ($define{WIN32} && (   $cctype !~ /\D/
171                               && $cctype >= 80)))
172    {
173        $define{USE_THREAD_SAFE_LOCALE} = 1;
174    }
175}
176
177if (    $define{USE_POSIX_2008_LOCALE}
178    && (   $define{HAS_QUERYLOCALE}
179        || (     $Config{cppsymbols} =~ /__GLIBC__/
180            &&   $define{HAS_NL_LANGINFO_L}
181            && ! $define{SETLOCALE_ACCEPTS_ANY_LOCALE_NAME})))
182{
183    $define{USE_QUERYLOCALE} = 1;
184}
185
186if ($define{USE_POSIX_2008_LOCALE} && ! $define{USE_QUERYLOCALE})
187{
188    $define{USE_PL_CURLOCALES} = 1;
189}
190
191if ($define{WIN32})
192{
193    if ($define{USE_THREAD_SAFE_LOCALE})
194    {
195        $define{USE_PL_CUR_LC_ALL} = 1;
196    }
197
198    if ($cctype < 140) {
199        $define{TS_W32_BROKEN_LOCALECONV} = 1;
200    }
201}
202
203if ($define{MULTIPLICITY} && (   $define{USE_POSIX_2008_LOCALE}
204                              || (   $define{WIN32}
205                                  && $define{USE_THREAD_SAFE_LOCALE})))
206{
207    $define{USE_PERL_SWITCH_LOCALE_CONTEXT} = 1;
208}
209
210# perl.h logic duplication ends
211#==========================================================================
212
213print STDERR "Defines: (" . join(' ', sort keys %define) . ")\n"
214     unless PLATFORM eq 'test';
215
216my $sym_ord = 0;
217my %ordinal;
218
219if (PLATFORM eq 'os2') {
220    if (open my $fh, '<', 'perl5.def') {
221      while (<$fh>) {
222	last if /^\s*EXPORTS\b/;
223      }
224      while (<$fh>) {
225	$ordinal{$1} = $2 if /^\s*"(\w+)"\s*(?:=\s*"\w+"\s*)?\@(\d+)\s*$/;
226	# This allows skipping ordinals which were used in older versions
227	$sym_ord = $1 if /^\s*;\s*LAST_ORDINAL\s*=\s*(\d+)\s*$/;
228      }
229      $sym_ord < $_ and $sym_ord = $_ for values %ordinal; # Take the max
230    }
231}
232
233my %skip;
234# All platforms export boot_DynaLoader unconditionally.
235my %export = ( boot_DynaLoader => 1 );
236
237# d_thread_local not perl_thread_local - see hints/darwin.sh
238++$export{PL_current_context}
239    if defined $Config{d_thread_local} && $define{USE_ITHREADS};
240
241sub try_symbols {
242    foreach my $symbol (@_) {
243	++$export{$symbol} unless exists $skip{$symbol};
244    }
245}
246
247sub readvar {
248    # $hash is the hash that we're adding to. For one of our callers, it will
249    # actually be the skip hash but that doesn't affect the intent of what
250    # we're doing, as in that case we skip adding something to the skip hash
251    # for the second time.
252
253    my $file = $ARGS{TARG_DIR} . shift;
254    my $hash = shift;
255    my $proc = shift;
256    open my $vars, '<', $file or die "Cannot open $file: $!\n";
257
258    while (<$vars>) {
259	# All symbols have a Perl_ prefix because that's what embed.h sticks
260	# in front of them.  The A?I?S?C? is strictly speaking wrong.
261	next unless /\bPERLVAR(A?I?S?C?)\(([IGT]),\s*(\w+)/;
262
263	my $var = "PL_$3";
264	my $symbol = $proc ? &$proc($1,$2,$3) : $var;
265	++$hash->{$symbol} unless exists $skip{$var};
266    }
267}
268
269if (PLATFORM ne 'os2') {
270    ++$skip{$_} foreach qw(
271		     PL_opsave
272		     Perl_dump_fds
273		     Perl_my_bcopy
274		     Perl_my_bzero
275		     Perl_my_chsize
276		     Perl_my_htonl
277		     Perl_my_memcmp
278		     Perl_my_memset
279		     Perl_my_ntohl
280		     Perl_my_swap
281			 );
282    if (PLATFORM eq 'vms') {
283	++$skip{PL_statusvalue_posix};
284        # This is a wrapper if we have symlink, not a replacement
285        # if we don't.
286        ++$skip{Perl_my_symlink} unless $Config{d_symlink};
287    } else {
288	++$skip{PL_statusvalue_vms};
289	++$skip{PL_perllib_sep};
290	if (PLATFORM ne 'aix') {
291	    ++$skip{$_} foreach qw(
292				PL_DBcv
293				PL_generation
294				PL_lastgotoprobe
295				PL_modcount
296				main
297				 );
298	}
299    }
300}
301
302if (PLATFORM ne 'vms') {
303    # VMS does its own thing for these symbols.
304    ++$skip{$_} foreach qw(
305			PL_sig_handlers_initted
306			PL_sig_ignoring
307			PL_sig_defaulting
308			 );
309    if (PLATFORM ne 'win32') {
310	++$skip{$_} foreach qw(
311			    Perl_do_spawn
312			    Perl_do_spawn_nowait
313			    Perl_do_aspawn
314			     );
315    }
316}
317
318if (PLATFORM ne 'win32') {
319    ++$skip{$_} foreach qw(
320		    Perl_get_context
321		    Perl_get_win32_message_utf8ness
322		    Perl_Win_utf8_string_to_wstring
323		    Perl_Win_wstring_to_utf8_string
324			 );
325}
326
327unless ($define{UNLINK_ALL_VERSIONS}) {
328    ++$skip{Perl_unlnk};
329}
330
331unless ($define{'DEBUGGING'}) {
332    ++$skip{$_} foreach qw(
333		    Perl_debop
334		    Perl_debprofdump
335		    Perl_debstack
336		    Perl_debstackptrs
337		    Perl_pad_sv
338		    Perl_pad_setsv
339		    Perl_set_padlist
340		    Perl_hv_assert
341		    PL_watchaddr
342		    PL_watchok
343			 );
344}
345
346if ($define{'PERL_IMPLICIT_SYS'}) {
347    ++$skip{$_} foreach qw(
348		    Perl_my_popen
349		    Perl_my_pclose
350			 );
351    ++$export{$_} foreach qw(perl_get_host_info perl_alloc_override);
352    ++$export{perl_clone_host} if $define{USE_ITHREADS};
353}
354else {
355    ++$skip{$_} foreach qw(
356		    PL_Mem
357		    PL_MemShared
358		    PL_MemParse
359		    PL_Env
360		    PL_StdIO
361		    PL_LIO
362		    PL_Dir
363		    PL_Sock
364		    PL_Proc
365		    perl_alloc_using
366		    perl_clone_using
367			 );
368}
369
370if (!$define{'PERL_COPY_ON_WRITE'} || $define{'PERL_NO_COW'}) {
371    ++$skip{Perl_sv_setsv_cow};
372}
373
374unless ($define{PERL_SAWAMPERSAND}) {
375    ++$skip{PL_sawampersand};
376}
377
378unless ($define{'USE_REENTRANT_API'}) {
379    ++$skip{PL_reentrant_buffer};
380}
381
382if ($define{'MYMALLOC'}) {
383    try_symbols(qw(
384		    Perl_dump_mstats
385		    Perl_get_mstats
386		    Perl_strdup
387		    Perl_putenv
388		    MallocCfg_ptr
389		    MallocCfgP_ptr
390		    ));
391    unless ($define{USE_ITHREADS}) {
392	++$skip{PL_malloc_mutex}
393    }
394}
395else {
396    ++$skip{$_} foreach qw(
397		    PL_malloc_mutex
398		    Perl_dump_mstats
399		    Perl_get_mstats
400		    MallocCfg_ptr
401		    MallocCfgP_ptr
402			 );
403}
404
405unless ($define{'USE_ITHREADS'}) {
406    ++$skip{PL_thr_key};
407    ++$skip{PL_user_prop_mutex};
408    ++$skip{PL_user_def_props_aTHX};
409}
410
411unless ($define{'USE_ITHREADS'}) {
412    ++$skip{$_} foreach qw(
413                    PL_keyword_plugin_mutex
414		    PL_check_mutex
415		    PL_op_mutex
416		    PL_regex_pad
417		    PL_regex_padav
418		    PL_dollarzero_mutex
419		    PL_env_mutex
420		    PL_hints_mutex
421		    PL_locale_mutex
422		    PL_locale_mutex_depth
423		    PL_my_ctx_mutex
424		    PL_perlio_mutex
425		    PL_stashpad
426		    PL_stashpadix
427		    PL_stashpadmax
428                    PL_veto_switch_non_tTHX_context
429		    Perl_alloccopstash
430		    Perl_allocfilegv
431		    Perl_clone_params_del
432		    Perl_clone_params_new
433		    Perl_parser_dup
434		    Perl_dirp_dup
435		    Perl_cx_dup
436		    Perl_si_dup
437		    Perl_any_dup
438		    Perl_ss_dup
439		    Perl_fp_dup
440		    Perl_gp_dup
441		    Perl_he_dup
442		    Perl_mg_dup
443		    Perl_re_dup_guts
444		    Perl_sv_dup
445		    Perl_sv_dup_inc
446		    Perl_rvpv_dup
447		    Perl_hek_dup
448		    Perl_sys_intern_dup
449		    perl_clone
450		    perl_clone_using
451		    Perl_stashpv_hvname_match
452		    Perl_regdupe_internal
453		    Perl_newPADOP
454			 );
455}
456
457unless ($define{'USE_THREADS'}) {
458    ++$skip{Perl_thread_locale_init};
459    ++$skip{Perl_thread_locale_term};
460}
461
462unless ($define{USE_POSIX_2008_LOCALE})
463{
464    ++$skip{$_} foreach qw(
465        PL_C_locale_obj
466        PL_scratch_locale_obj
467        PL_cur_locale_obj
468    );
469}
470unless ($define{USE_PL_CURLOCALES})
471{
472    ++$skip{$_} foreach qw(
473        PL_curlocales
474    );
475}
476
477unless ($define{USE_PL_CUR_LC_ALL})
478{
479    ++$skip{$_} foreach qw(
480        PL_cur_LC_ALL
481    );
482}
483
484unless ($define{USE_PERL_SWITCH_LOCALE_CONTEXT})
485{
486    ++$skip{$_} foreach qw(
487        Perl_switch_locale_context
488    );
489}
490
491unless ($define{'MULTIPLICITY'}) {
492    ++$skip{$_} foreach qw(
493                    PL_cur_locale_obj
494		    PL_my_cxt_index
495		    PL_my_cxt_list
496		    PL_my_cxt_size
497		    PL_my_cxt_keys
498		    PL_my_cxt_keys_size
499		    Perl_croak_nocontext
500		    Perl_die_nocontext
501		    Perl_deb_nocontext
502		    Perl_form_nocontext
503		    Perl_load_module_nocontext
504		    Perl_mess_nocontext
505		    Perl_warn_nocontext
506		    Perl_warner_nocontext
507		    Perl_newSVpvf_nocontext
508		    Perl_sv_catpvf_nocontext
509		    Perl_sv_setpvf_nocontext
510		    Perl_sv_catpvf_mg_nocontext
511		    Perl_sv_setpvf_mg_nocontext
512		    Perl_my_cxt_init
513		    Perl_my_cxt_index
514			 );
515}
516
517unless ($define{'USE_DTRACE'}) {
518    ++$skip{$_} foreach qw(
519                    Perl_dtrace_probe_call
520                    Perl_dtrace_probe_load
521                    Perl_dtrace_probe_op
522                    Perl_dtrace_probe_phase
523                );
524}
525
526unless ($define{'DEBUG_LEAKING_SCALARS'}) {
527    ++$skip{PL_sv_serial};
528}
529
530unless ($define{'DEBUG_LEAKING_SCALARS_FORK_DUMP'}) {
531    ++$skip{PL_dumper_fd};
532}
533
534unless ($define{'PERL_DONT_CREATE_GVSV'}) {
535    ++$skip{Perl_gv_SVadd};
536}
537
538unless ($define{'PERL_USES_PL_PIDSTATUS'}) {
539    ++$skip{PL_pidstatus};
540}
541
542unless ($define{'PERL_TRACK_MEMPOOL'}) {
543    ++$skip{PL_memory_debug_header};
544}
545
546unless ($define{'PERL_MEM_LOG'}) {
547    ++$skip{$_} foreach qw(
548                    PL_mem_log
549                    Perl_mem_log_alloc
550                    Perl_mem_log_realloc
551                    Perl_mem_log_free
552                    Perl_mem_log_new_sv
553                    Perl_mem_log_del_sv
554                );
555}
556
557unless ($define{'MULTIPLICITY'}) {
558    ++$skip{$_} foreach qw(
559		    PL_interp_size
560		    PL_interp_size_5_18_0
561                    PL_sv_yes
562                    PL_sv_undef
563                    PL_sv_no
564                    PL_sv_zero
565			 );
566}
567
568unless ($define{HAS_MMAP}) {
569    ++$skip{PL_mmap_page_size};
570}
571
572if ($define{HAS_SIGACTION}) {
573    ++$skip{PL_sig_trapped};
574
575    if (PLATFORM eq 'vms') {
576        # FAKE_PERSISTENT_SIGNAL_HANDLERS defined as !defined(HAS_SIGACTION)
577        ++$skip{PL_sig_ignoring};
578        ++$skip{PL_sig_handlers_initted} unless $define{KILL_BY_SIGPRC};
579    }
580}
581
582if (PLATFORM eq 'vms' && !$define{KILL_BY_SIGPRC}) {
583    # FAKE_DEFAULT_SIGNAL_HANDLERS defined as KILL_BY_SIGPRC
584    ++$skip{Perl_csighandler_init};
585    ++$skip{Perl_my_kill};
586    ++$skip{Perl_sig_to_vmscondition};
587    ++$skip{PL_sig_defaulting};
588    ++$skip{PL_sig_handlers_initted} unless !$define{HAS_SIGACTION};
589}
590
591if ($define{'HAS_STRNLEN'})
592{
593    ++$skip{Perl_my_strnlen};
594}
595
596unless ($define{USE_LOCALE_COLLATE}) {
597    ++$skip{$_} foreach qw(
598		    PL_collation_ix
599		    PL_collation_name
600		    PL_collation_standard
601		    PL_collxfrm_base
602		    PL_collxfrm_mult
603		    Perl_sv_collxfrm
604		    Perl_sv_collxfrm_flags
605                    PL_strxfrm_NUL_replacement
606                    PL_strxfrm_is_behaved
607                    PL_strxfrm_max_cp
608		    PL_in_utf8_COLLATE_locale
609			 );
610}
611
612unless ($define{USE_LOCALE_THREADS} && ! $define{USE_THREAD_SAFE_LOCALE}) {
613    ++$skip{$_} foreach qw(
614                           PL_less_dicey_locale_buf
615                           PL_less_dicey_locale_bufsize
616			  );
617}
618
619unless ($define{USE_LOCALE_CTYPE}) {
620    ++$skip{$_} foreach qw(
621		    PL_ctype_name
622                    PL_in_utf8_CTYPE_locale
623                    PL_in_utf8_turkic_locale
624			 );
625}
626
627unless (   ! $define{HAS_NL_LANGINFO}
628        &&   $define{USE_LOCALE_CTYPE}
629        && ! $define{WIN32}
630        && ! $define{HAS_MBTOWC}
631        && ! $define{HAS_MBRTOWC})
632    {
633        ++$skip{$_} foreach qw(
634                                PL_langinfo_recursed
635                              );
636    }
637
638unless ($define{'USE_C_BACKTRACE'}) {
639    ++$skip{Perl_get_c_backtrace_dump};
640    ++$skip{Perl_dump_c_backtrace};
641}
642
643unless ($define{HAVE_INTERP_INTERN}) {
644    ++$skip{$_} foreach qw(
645		    Perl_sys_intern_clear
646		    Perl_sys_intern_dup
647		    Perl_sys_intern_init
648		    PL_sys_intern
649			 );
650}
651
652if ($define{HAS_SIGNBIT}) {
653    ++$skip{Perl_signbit};
654}
655
656++$skip{PL_op_exec_cnt}
657    unless $define{PERL_TRACE_OPS};
658
659++$skip{PL_hash_chars}
660    unless $define{PERL_USE_SINGLE_CHAR_HASH_CACHE};
661
662unless ($define{PERL_RC_STACK}) {
663    ++$skip{$_} foreach qw(
664		    Perl_pp_wrap
665		    Perl_xs_wrap
666                    Perl_runops_wrap
667			 );
668}
669
670# functions from *.sym files
671
672my @syms = qw(globvar.sym);
673
674# Symbols that are the public face of the PerlIO layers implementation
675# These are in _addition to_ the public face of the abstraction
676# and need to be exported to allow XS modules to implement layers
677my @layer_syms = qw(
678		    PerlIOBase_binmode
679		    PerlIOBase_clearerr
680		    PerlIOBase_close
681		    PerlIOBase_dup
682		    PerlIOBase_eof
683		    PerlIOBase_error
684		    PerlIOBase_fileno
685		    PerlIOBase_open
686		    PerlIOBase_noop_fail
687		    PerlIOBase_noop_ok
688		    PerlIOBase_popped
689		    PerlIOBase_pushed
690		    PerlIOBase_read
691		    PerlIOBase_setlinebuf
692		    PerlIOBase_unread
693		    PerlIOBuf_bufsiz
694		    PerlIOBuf_close
695		    PerlIOBuf_dup
696		    PerlIOBuf_fill
697		    PerlIOBuf_flush
698		    PerlIOBuf_get_base
699		    PerlIOBuf_get_cnt
700		    PerlIOBuf_get_ptr
701		    PerlIOBuf_open
702		    PerlIOBuf_popped
703		    PerlIOBuf_pushed
704		    PerlIOBuf_read
705		    PerlIOBuf_seek
706		    PerlIOBuf_set_ptrcnt
707		    PerlIOBuf_tell
708		    PerlIOBuf_unread
709		    PerlIOBuf_write
710		    PerlIO_allocate
711		    PerlIO_apply_layera
712		    PerlIO_apply_layers
713		    PerlIO_arg_fetch
714		    PerlIO_debug
715		    PerlIO_define_layer
716		    PerlIO_find_layer
717		    PerlIO_isutf8
718		    PerlIO_layer_fetch
719		    PerlIO_list_alloc
720		    PerlIO_list_free
721		    PerlIO_modestr
722		    PerlIO_parse_layers
723		    PerlIO_pending
724		    PerlIO_perlio
725		    PerlIO_pop
726		    PerlIO_push
727		    PerlIO_sv_dup
728		    Perl_PerlIO_clearerr
729		    Perl_PerlIO_close
730		    Perl_PerlIO_context_layers
731		    Perl_PerlIO_eof
732		    Perl_PerlIO_error
733		    Perl_PerlIO_fileno
734		    Perl_PerlIO_fill
735		    Perl_PerlIO_flush
736		    Perl_PerlIO_get_base
737		    Perl_PerlIO_get_bufsiz
738		    Perl_PerlIO_get_cnt
739		    Perl_PerlIO_get_ptr
740		    Perl_PerlIO_read
741		    Perl_PerlIO_restore_errno
742		    Perl_PerlIO_save_errno
743		    Perl_PerlIO_seek
744		    Perl_PerlIO_set_cnt
745		    Perl_PerlIO_set_ptrcnt
746		    Perl_PerlIO_setlinebuf
747		    Perl_PerlIO_stderr
748		    Perl_PerlIO_stdin
749		    Perl_PerlIO_stdout
750		    Perl_PerlIO_tell
751		    Perl_PerlIO_unread
752		    Perl_PerlIO_write
753);
754
755# Export the symbols that make up the PerlIO abstraction, regardless
756# of its implementation - read from a file
757push @syms, 'perlio.sym';
758
759# PerlIO with layers - export implementation
760try_symbols(@layer_syms, 'perlsio_binmode');
761
762
763unless ($define{'USE_QUADMATH'}) {
764  ++$skip{Perl_quadmath_format_needed};
765  ++$skip{Perl_quadmath_format_single};
766}
767
768unless ($Config{d_mbrlen}) {
769    ++$skip{PL_mbrlen_ps};
770}
771
772unless ($Config{d_mbrtowc}) {
773    ++$skip{PL_mbrtowc_ps};
774}
775
776unless ($Config{d_wcrtomb}) {
777    ++$skip{PL_wcrtomb_ps};
778}
779
780###############################################################################
781
782# At this point all skip lists should be completed, as we are about to test
783# many symbols against them.
784
785{
786    my %seen;
787    my ($embed_array) = setup_embed($ARGS{TARG_DIR});
788    my $excludedre = $define{'NO_MATHOMS'} ? qr/[emiIsb]/ : qr/[emiIs]/;
789
790    foreach (@$embed_array) {
791        my $embed= $_->{embed}
792            or next;
793	my ($flags, $retval, $func, $args) = @{$embed}{qw(flags return_type name args)};
794	next unless $func;
795	if (($flags =~ /[AXC]/ && $flags !~ $excludedre)
796            || (!$define{'NO_MATHOMS'} && $flags =~ /b/))
797        {
798	    # public API, so export
799
800	    # If a function is defined twice, for example before and after
801	    # an #else, only export its name once. Important to do this test
802	    # within the block, as the *first* definition may have flags which
803	    # mean "don't export"
804	    next if $seen{$func}++;
805	    # Should we also skip adding the Perl_ prefix if $flags =~ /o/ ?
806	    $func = "Perl_$func" if ($flags =~ /[psX]/ && $func !~ /^Perl_/);
807	    ++$export{$func} unless exists $skip{$func};
808	}
809    }
810}
811
812foreach (@syms) {
813    my $syms = $ARGS{TARG_DIR} . $_;
814    open my $global, '<', $syms or die "failed to open $syms: $!\n";
815    while (<$global>) {
816	next unless /^([A-Za-z].*)/;
817	my $symbol = "$1";
818	++$export{$symbol} unless exists $skip{$symbol};
819    }
820}
821
822# variables
823
824readvar('perlvars.h', \%export);
825unless ($define{MULTIPLICITY}) {
826    readvar('intrpvar.h', \%export);
827}
828
829# Oddities from PerlIO
830# All have alternate implementations in perlio.c, so always exist.
831# Should they be considered to be part of the API?
832try_symbols(qw(
833		    PerlIO_binmode
834		    PerlIO_getpos
835		    PerlIO_init
836		    PerlIO_setpos
837		    PerlIO_tmpfile
838	     ));
839
840if (PLATFORM eq 'win32') {
841    try_symbols(qw(
842		    win32_free_childdir
843		    win32_free_childenv
844		    win32_get_childdir
845		    win32_get_childenv
846		    win32_spawnvp
847		    Perl_init_os_extras
848		    Perl_win32_init
849		    Perl_win32_term
850		    RunPerl
851		    win32_async_check
852		    win32_errno
853		    win32_environ
854		    win32_abort
855		    win32_fstat
856		    win32_stat
857		    win32_pipe
858		    win32_popen
859		    win32_pclose
860		    win32_rename
861		    win32_setmode
862		    win32_chsize
863		    win32_lseek
864		    win32_tell
865		    win32_dup
866		    win32_dup2
867		    win32_open
868		    win32_close
869		    win32_eof
870		    win32_isatty
871		    win32_read
872		    win32_write
873		    win32_mkdir
874		    win32_rmdir
875		    win32_chdir
876		    win32_flock
877		    win32_execv
878		    win32_execvp
879		    win32_htons
880		    win32_ntohs
881		    win32_htonl
882		    win32_ntohl
883		    win32_inet_addr
884		    win32_inet_ntoa
885		    win32_socket
886		    win32_bind
887		    win32_listen
888		    win32_accept
889		    win32_connect
890		    win32_send
891		    win32_sendto
892		    win32_recv
893		    win32_recvfrom
894		    win32_shutdown
895		    win32_closesocket
896		    win32_ioctlsocket
897		    win32_setsockopt
898		    win32_getsockopt
899		    win32_getpeername
900		    win32_getsockname
901		    win32_gethostname
902		    win32_gethostbyname
903		    win32_gethostbyaddr
904		    win32_getprotobyname
905		    win32_getprotobynumber
906		    win32_getservbyname
907		    win32_getservbyport
908		    win32_select
909		    win32_endhostent
910		    win32_endnetent
911		    win32_endprotoent
912		    win32_endservent
913		    win32_getnetent
914		    win32_getnetbyname
915		    win32_getnetbyaddr
916		    win32_getprotoent
917		    win32_getservent
918		    win32_sethostent
919		    win32_setnetent
920		    win32_setprotoent
921		    win32_setservent
922		    win32_getenv
923		    win32_putenv
924		    win32_perror
925		    win32_malloc
926		    win32_calloc
927		    win32_realloc
928		    win32_free
929		    win32_sleep
930		    win32_pause
931		    win32_times
932		    win32_access
933		    win32_alarm
934		    win32_chmod
935		    win32_open_osfhandle
936		    win32_get_osfhandle
937		    win32_ioctl
938		    win32_link
939		    win32_unlink
940		    win32_utime
941		    win32_gettimeofday
942		    win32_uname
943		    win32_wait
944		    win32_waitpid
945		    win32_kill
946		    win32_str_os_error
947		    win32_opendir
948		    win32_readdir
949		    win32_telldir
950		    win32_seekdir
951		    win32_rewinddir
952		    win32_closedir
953		    win32_longpath
954		    win32_ansipath
955		    win32_os_id
956		    win32_getpid
957		    win32_crypt
958		    win32_dynaload
959		    win32_clearenv
960		    win32_stdin
961		    win32_stdout
962		    win32_stderr
963		    win32_ferror
964		    win32_feof
965		    win32_strerror
966		    win32_fprintf
967		    win32_printf
968		    win32_vfprintf
969		    win32_vprintf
970		    win32_fread
971		    win32_fwrite
972		    win32_fopen
973		    win32_fdopen
974		    win32_freopen
975		    win32_fclose
976		    win32_fputs
977		    win32_fputc
978		    win32_ungetc
979		    win32_getc
980		    win32_fileno
981		    win32_clearerr
982		    win32_fflush
983		    win32_ftell
984		    win32_fseek
985		    win32_fgetpos
986		    win32_fsetpos
987		    win32_rewind
988		    win32_tmpfile
989		    win32_setbuf
990		    win32_setvbuf
991		    win32_flushall
992		    win32_fcloseall
993		    win32_fgets
994		    win32_gets
995		    win32_fgetc
996		    win32_putc
997		    win32_puts
998		    win32_getchar
999		    win32_putchar
1000                    win32_symlink
1001                    win32_lstat
1002                    win32_readlink
1003		 ));
1004}
1005elsif (PLATFORM eq 'vms') {
1006    try_symbols(qw(
1007		      Perl_cando
1008		      Perl_cando_by_name
1009		      Perl_closedir
1010		      Perl_csighandler_init
1011		      Perl_do_rmdir
1012		      Perl_fileify_dirspec
1013		      Perl_fileify_dirspec_ts
1014		      Perl_fileify_dirspec_utf8
1015		      Perl_fileify_dirspec_utf8_ts
1016		      Perl_flex_fstat
1017		      Perl_flex_lstat
1018		      Perl_flex_stat
1019		      Perl_kill_file
1020		      Perl_my_chdir
1021		      Perl_my_chmod
1022		      Perl_my_crypt
1023		      Perl_my_endpwent
1024		      Perl_my_fclose
1025		      Perl_my_fdopen
1026		      Perl_my_fgetname
1027		      Perl_my_flush
1028		      Perl_my_fwrite
1029		      Perl_my_gconvert
1030		      Perl_my_getenv
1031		      Perl_my_getenv_len
1032		      Perl_my_getpwnam
1033		      Perl_my_getpwuid
1034		      Perl_my_gmtime
1035		      Perl_my_kill
1036		      Perl_my_killpg
1037		      Perl_my_localtime
1038		      Perl_my_mkdir
1039		      Perl_my_sigaction
1040		      Perl_my_symlink
1041		      Perl_my_time
1042		      Perl_my_tmpfile
1043		      Perl_my_trnlnm
1044		      Perl_my_utime
1045		      Perl_my_waitpid
1046		      Perl_opendir
1047		      Perl_pathify_dirspec
1048		      Perl_pathify_dirspec_ts
1049		      Perl_pathify_dirspec_utf8
1050		      Perl_pathify_dirspec_utf8_ts
1051		      Perl_readdir
1052		      Perl_readdir_r
1053		      Perl_rename
1054		      Perl_rmscopy
1055		      Perl_rmsexpand
1056		      Perl_rmsexpand_ts
1057		      Perl_rmsexpand_utf8
1058		      Perl_rmsexpand_utf8_ts
1059		      Perl_seekdir
1060		      Perl_sig_to_vmscondition
1061		      Perl_telldir
1062		      Perl_tounixpath
1063		      Perl_tounixpath_ts
1064		      Perl_tounixpath_utf8
1065		      Perl_tounixpath_utf8_ts
1066		      Perl_tounixspec
1067		      Perl_tounixspec_ts
1068		      Perl_tounixspec_utf8
1069		      Perl_tounixspec_utf8_ts
1070		      Perl_tovmspath
1071		      Perl_tovmspath_ts
1072		      Perl_tovmspath_utf8
1073		      Perl_tovmspath_utf8_ts
1074		      Perl_tovmsspec
1075		      Perl_tovmsspec_ts
1076		      Perl_tovmsspec_utf8
1077		      Perl_tovmsspec_utf8_ts
1078		      Perl_trim_unixpath
1079		      Perl_vms_case_tolerant
1080		      Perl_vms_do_aexec
1081		      Perl_vms_do_exec
1082		      Perl_vms_image_init
1083		      Perl_vms_realpath
1084		      Perl_vmssetenv
1085		      Perl_vmssetuserlnm
1086		      Perl_vmstrnenv
1087		      PerlIO_openn
1088		 ));
1089}
1090elsif (PLATFORM eq 'os2') {
1091    try_symbols(qw(
1092		      ctermid
1093		      get_sysinfo
1094		      Perl_OS2_init
1095		      Perl_OS2_init3
1096		      Perl_OS2_term
1097		      OS2_Perl_data
1098		      dlopen
1099		      dlsym
1100		      dlerror
1101		      dlclose
1102		      dup2
1103		      dup
1104		      my_tmpfile
1105		      my_tmpnam
1106		      my_flock
1107		      my_rmdir
1108		      my_mkdir
1109		      my_getpwuid
1110		      my_getpwnam
1111		      my_getpwent
1112		      my_setpwent
1113		      my_endpwent
1114		      fork_with_resources
1115		      croak_with_os2error
1116		      setgrent
1117		      endgrent
1118		      getgrent
1119		      malloc_mutex
1120		      threads_mutex
1121		      nthreads
1122		      nthreads_cond
1123		      os2_cond_wait
1124		      os2_stat
1125		      os2_execname
1126		      async_mssleep
1127		      msCounter
1128		      InfoTable
1129		      pthread_join
1130		      pthread_create
1131		      pthread_detach
1132		      XS_Cwd_change_drive
1133		      XS_Cwd_current_drive
1134		      XS_Cwd_extLibpath
1135		      XS_Cwd_extLibpath_set
1136		      XS_Cwd_sys_abspath
1137		      XS_Cwd_sys_chdir
1138		      XS_Cwd_sys_cwd
1139		      XS_Cwd_sys_is_absolute
1140		      XS_Cwd_sys_is_relative
1141		      XS_Cwd_sys_is_rooted
1142		      XS_DynaLoader_mod2fname
1143		      XS_File__Copy_syscopy
1144		      Perl_Register_MQ
1145		      Perl_Deregister_MQ
1146		      Perl_Serve_Messages
1147		      Perl_Process_Messages
1148		      init_PMWIN_entries
1149		      PMWIN_entries
1150		      Perl_hab_GET
1151		      loadByOrdinal
1152		      pExtFCN
1153		      os2error
1154		      ResetWinError
1155		      CroakWinError
1156		      PL_do_undump
1157		 ));
1158}
1159
1160# When added this code was only run for Win32 (and WinCE at the time)
1161# Currently only Win32 links static extensions into the shared library.
1162# For *nix (and presumably OS/2) with a shared libperl, Makefile.SH compiles
1163# static extensions with -fPIC, but links them to perl, not libperl.so
1164# The VMS build scripts don't yet implement static extensions at all.
1165
1166if (PLATFORM eq 'win32') {
1167    # records of type boot_module for statically linked modules (except Dynaloader)
1168    my $static_ext = $Config{static_ext} // "";
1169    $static_ext =~ s/\//__/g;
1170    $static_ext =~ s/\bDynaLoader\b//;
1171    try_symbols(map {"boot_$_"} grep {/\S/} split /\s+/, $static_ext);
1172    try_symbols("init_Win32CORE") if $static_ext =~ /\bWin32CORE\b/;
1173}
1174
1175if (PLATFORM eq 'os2') {
1176    my (%mapped, @missing);
1177    open MAP, '<', 'miniperl.map' or die 'Cannot read miniperl.map';
1178    /^\s*[\da-f:]+\s+(\w+)/i and $mapped{$1}++ foreach <MAP>;
1179    close MAP or die 'Cannot close miniperl.map';
1180
1181    @missing = grep { !exists $mapped{$_} }
1182		    keys %export;
1183    @missing = grep { !exists $exportperlmalloc{$_} } @missing;
1184    delete $export{$_} foreach @missing;
1185}
1186
1187###############################################################################
1188
1189# Now all symbols should be defined because next we are going to output them.
1190
1191# Start with platform specific headers:
1192
1193if (PLATFORM eq 'win32') {
1194    my $dll = $define{PERL_DLL} ? $define{PERL_DLL} =~ s/\.dll$//ir
1195	: "perl$Config{api_revision}$Config{api_version}";
1196    print "LIBRARY $dll\n";
1197    # The DESCRIPTION module definition file statement is not supported
1198    # by VC7 onwards.
1199    if ($ARGS{CCTYPE} eq 'GCC') {
1200	print "DESCRIPTION 'Perl interpreter'\n";
1201    }
1202    print "EXPORTS\n";
1203}
1204elsif (PLATFORM eq 'os2') {
1205    (my $v = $]) =~ s/(\d\.\d\d\d)(\d\d)$/$1_$2/;
1206    $v .= '-thread' if $Config{archname} =~ /-thread/;
1207    (my $dll = $define{PERL_DLL}) =~ s/\.dll$//i;
1208    $v .= "\@$Config{perl_patchlevel}" if $Config{perl_patchlevel};
1209    my $d = "DESCRIPTION '\@#perl5-porters\@perl.org:$v#\@ Perl interpreter, configured as $Config{config_args}'";
1210    $d = substr($d, 0, 249) . "...'" if length $d > 253;
1211    print <<"---EOP---";
1212LIBRARY '$dll' INITINSTANCE TERMINSTANCE
1213$d
1214STACKSIZE 32768
1215CODE LOADONCALL
1216DATA LOADONCALL NONSHARED MULTIPLE
1217EXPORTS
1218---EOP---
1219}
1220elsif (PLATFORM eq 'aix') {
1221    my $OSVER = `uname -v`;
1222    chop $OSVER;
1223    my $OSREL = `uname -r`;
1224    chop $OSREL;
1225    if ($OSVER > 4 || ($OSVER == 4 && $OSREL >= 3)) {
1226	print "#! ..\n";
1227    } else {
1228	print "#!\n";
1229    }
1230}
1231
1232# Then the symbols
1233
1234my @symbols = $fold ? sort {lc $a cmp lc $b} keys %export : sort keys %export;
1235foreach my $symbol (@symbols) {
1236    if (PLATFORM eq 'win32') {
1237	# Remembering the origin file of each symbol is an alternative to PL_ matching
1238	if (substr($symbol, 0, 3) eq 'PL_') {
1239	    print "\t$symbol DATA\n";
1240	}
1241	else {
1242	    print "\t$symbol\n";
1243	}
1244    }
1245    elsif (PLATFORM eq 'os2') {
1246	printf qq(    %-31s \@%s\n),
1247	  qq("$symbol"), $ordinal{$symbol} || ++$sym_ord;
1248	printf qq(    %-31s \@%s\n),
1249	  qq("$exportperlmalloc{$symbol}" = "$symbol"),
1250	  $ordinal{$exportperlmalloc{$symbol}} || ++$sym_ord
1251	  if $exportperlmalloc and exists $exportperlmalloc{$symbol};
1252    } else {
1253	print "$symbol\n";
1254    }
1255}
1256
1257# Then platform specific footers.
1258
1259if (PLATFORM eq 'os2') {
1260    print <<EOP;
1261    dll_perlmain=main
1262    fill_extLibpath
1263    dir_subst
1264    Perl_OS2_handler_install
1265
1266; LAST_ORDINAL=$sym_ord
1267EOP
1268}
1269
12701;
1271