<commit_before>package Gtk2::CodeGen;
#
# Copyright (c) 2003 by the gtk2-perl team (see the file AUTHORS)
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Library General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Library General Public License for more details.
#
# You should have received a copy of the GNU Library General Public
# License along with this library; if not, write to the 
# Free Software Foundation, Inc., 59 Temple Place - Suite 330, 
# Boston, MA  02111-1307  USA.
#
# $Header$

use strict;
use warnings;
use Carp;
use IO::File;

=item Gtk2::CodeGen->write_boot (FILENAME, GREP_FILE_ARG)

Many GObject-based libraries to be bound to perl will be too large to put in
a single XS file; however, a single PM file typically only bootstraps one
XS file's code.

This function looks for a "MODULE = ..." line (matching the grep pattern
"^MODULE") in each of the files specified by GREP_FILE_ARG.  Each unique
name is added to a list of names to be mangled into boot code symbols.  The
function then writes an XS include file which calls each of those boot symbols
via GPERL_CALL_BOOT.  If FILENAME is not specified, 'build/boot.xsh' will be
used.


If GREP_FILE_ARG is not defined, the glob 'xs/*.xs' is used.  GREP_FILE_ARG is
passed directly to grep (the shell command), so you may have to experiment if
you want to do something out of the ordinary.


What is this all about, you ask?  In order to bind an XSub to perl, the 
C function must be registered with the interpreter.  This is the function
of the "boot" code, which is typically called in the bootstrapping process.
However, when multiple XS files are used, some mechanism must call the boot
code from each XS file before any of the function therein will be available.

A typical setup for a multiple-XS, single-PM module will be to call the 
various bits of boot code from the boot code for the toplevel module.

To use Gtk2 as an example, when you do 'use Gtk2', Gtk2.pm calls bootstrap
on Gtk2, which calls the C function boot_Gtk2.  This function calls the
boot symbols for all the other xs files in the module.  The distinction
is that the toplevel module, Gtk2, has no colons in its name.



xsubpp generates the boot function's name by replacing the 
colons in the MODULE name with underscores and prepending "boot_".
we need to be careful not to include the boot code for the toplevel module,
(say Toplevel, or Gtk2, or whatever) because the bootstrap code in 
Toplevel.pm will call boot_Toplevel when loaded, and boot_Toplevel
should actually includes the file we are creating here.

=cut
sub write_boot {
	my $class = shift;
	my $filename = shift || 'build/boot.xsh';
	my $glob = shift || 'xs/*.xs';

	my $file = IO::File->new (">$filename")
		or carp "Cannot write $filename: $!"; 

	print $file "\n\n/* This file is automatically generated, any changes made here will be lost! */\n\n";

	my %boot=();
	foreach (`grep ^MODULE $glob`) {
		my @F = split;
		# the toplevel module is the only one without :'s in its name.
		if ($F[2] =~ s/:/_/g) {
			my $sym = "boot_$F[2]";
			print $file "GPERL_CALL_BOOT ($sym);\n"
				unless $boot{$sym};
			$boot{$sym}++;
		}
	}

	close $file;
}<commit_msg>reworked write_boot to solve some limitations<commit_after>package Gtk2::CodeGen;
#
# Copyright (c) 2003 by the gtk2-perl team (see the file AUTHORS)
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Library General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Library General Public License for more details.
#
# You should have received a copy of the GNU Library General Public
# License along with this library; if not, write to the 
# Free Software Foundation, Inc., 59 Temple Place - Suite 330, 
# Boston, MA  02111-1307  USA.
#
# $Header$

use strict;
use warnings;
use Carp;
use IO::File;

=item Gtk2::CodeGen->write_boot (FILENAME, GREP_FILE_ARG)

Many GObject-based libraries to be bound to perl will be too large to put in
a single XS file; however, a single PM file typically only bootstraps one
XS file's code.

This function looks for a "MODULE = ..." line (matching the grep pattern
"^MODULE") in each of the files specified by GREP_FILE_ARG.  Each unique
name is added to a list of names to be mangled into boot code symbols.  The
function then writes an XS include file which calls each of those boot symbols
via GPERL_CALL_BOOT.  If FILENAME is not specified, 'build/boot.xsh' will be
used.


If GREP_FILE_ARG is not defined, the glob 'xs/*.xs' is used.  GREP_FILE_ARG is
passed directly to grep (the shell command), so you may have to experiment if
you want to do something out of the ordinary.


What is this all about, you ask?  In order to bind an XSub to perl, the 
C function must be registered with the interpreter.  This is the function
of the "boot" code, which is typically called in the bootstrapping process.
However, when multiple XS files are used, some mechanism must call the boot
code from each XS file before any of the function therein will be available.

A typical setup for a multiple-XS, single-PM module will be to call the 
various bits of boot code from the boot code for the toplevel module.

To use Gtk2 as an example, when you do 'use Gtk2', Gtk2.pm calls bootstrap
on Gtk2, which calls the C function boot_Gtk2.  This function calls the
boot symbols for all the other xs files in the module.  The distinction
is that the toplevel module, Gtk2, has no colons in its name.



xsubpp generates the boot function's name by replacing the 
colons in the MODULE name with underscores and prepending "boot_".
we need to be careful not to include the boot code for the toplevel module,
(say Toplevel, or Gtk2, or whatever) because the bootstrap code in 
Toplevel.pm will call boot_Toplevel when loaded, and boot_Toplevel
should actually includes the file we are creating here.

=cut
sub write_boot {
	my $class = shift;
	my %opts = (
		ignore => '^[^:]+$',	# ignore package with no colons in it
		filename => 'build/boot.xsh',
		'glob' => 'xs/*.xs',
		@_,
	);
	my $filename = $opts{filename};
	my $glob = $opts{'glob'};
	my $ignore = $opts{ignore};

	my $file = IO::File->new (">$filename")
		or carp "Cannot write $filename: $!"; 

	print $file "\n\n/* This file is automatically generated, any changes made here will be lost! */\n\n";

	my %boot=();

	foreach my $xsfile (glob $glob) {
		my $in = IO::File->new ($xsfile)
				or die "can't open $xsfile: $!\n";

		while (<$in>) {
			next unless m/^MODULE/;

			my @F = split;

			next if $F[2] =~ m/$ignore/;

			$F[2] =~ s/:/_/g;
			my $sym = "boot_$F[2]";
			print $file "GPERL_CALL_BOOT ($sym);\n"
				unless $boot{$sym};
			$boot{$sym}++;
		}

		close $in;
	}

	close $file;
}
{'fraction_non_alphanumeric': 0.08070223189983669, 'fraction_numerical': 0.008573761567773544, 'mean_word_length': 3.8960692871419056, 'pattern_counts': {'":': 0, '<': 4, '<?xml version=': 0, '>': 14, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4682367', 'n_tokens_mistral': 2352, 'n_tokens_neox': 2198, 'n_words': 1135}