<commit_before>#!/usr/bin/perl
# Copyright 2009 The Go Authors. All rights reserved.
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.

# This program reads a file containing function prototypes
# (like syscall_darwin.go) and generates system call bodies.
# The prototypes are marked by lines beginning with "//sys"
# and read like func declarations if //sys is replaced by func, but:
#	* The parameter lists must give a name for each argument.
#	  This includes return parameters.
#	* The parameter lists must give a type for each argument:
#	  the (x, y, z int) shorthand is not allowed.
#	* If the return parameter is an error number, it must be named errno.
#	* If go func name needs to be different from it's winapi dll name,
#	  the winapi name could be specified at the end, after "=" sign, like
#	  //sys LoadLibrary(libname string) (handle uint32, errno int) = LoadLibraryA
#	* Each function, that returns errno, needs to supply a condition,
#	  that return value of winapi will be tested against to
#	  detect failure. This would set errno to windows "last-error",
#	  otherwise it will be 0. The value can be provided
#	  at end of //sys declaration, like
#	  //sys LoadLibrary(libname string) (handle uint32, errno int) [failretval==-1] = LoadLibraryA
#	  and is [failretval==0] by default.

$cmdline = "mksyscall_windows.pl " . join(' ', @ARGV);
$errors = 0;
$_32bit = "";

if($ARGV[0] eq "-b32") {
	$_32bit = "big-endian";
	shift;
} elsif($ARGV[0] eq "-l32") {
	$_32bit = "little-endian";
	shift;
}

if($ARGV[0] =~ /^-/) {
	print STDERR "usage: mksyscall_windows.pl [-b32 | -l32] [file ...]\n";
	exit 1;
}

sub parseparamlist($) {
	my ($list) = @_;
	$list =~ s/^\s*//;
	$list =~ s/\s*$//;
	if($list eq "") {
		return ();
	}
	return split(/\s*,\s*/, $list);
}

sub parseparam($) {
	my ($p) = @_;
	if($p !~ /^(\S*) (\S*)$/) {
		print STDERR "$ARGV:$.: malformed parameter: $p\n";
		$errors = 1;
		return ("xx", "int");
	}
	return ($1, $2);
}

$text = "";
$vars = "";
$mods = "";
$modnames = "";
while(<>) {
	chomp;
	s/\s+/ /g;
	s/^\s+//;
	s/\s+$//;
	next if !/^\/\/sys /;

	# Line must be of the form
	#	func Open(path string, mode int, perm int) (fd int, errno int)
	# Split into name, in params, out params.
	if(!/^\/\/sys (\w+)\(([^()]*)\)\s*(?:\(([^()]+)\))?\s*(?:\[failretval(.*)\])?\s*(?:=\s*(?:(\w*)\.)?(\w*))?$/) {
		print STDERR "$ARGV:$.: malformed //sys declaration\n";
		$errors = 1;
		next;
	}
	my ($func, $in, $out, $failcond, $modname, $sysname) = ($1, $2, $3, $4, $5, $6);

	# Split argument lists on comma.
	my @in = parseparamlist($in);
	my @out = parseparamlist($out);

	# Dll file name.
	if($modname eq "") {
		$modname = "kernel32";
	}
	$modvname = "mod$modname";
	if($modnames !~ /$modname/) {
		$modnames .= ".$modname";
		$mods .= "\t$modvname = loadDll(\"$modname.dll\")\n";
	}

	# System call name.
	if($sysname eq "") {
		$sysname = "$func";
	}

	# System call pointer variable name.
	$sysvarname = "proc$sysname";

	# Returned value when failed
	if($failcond eq "") {
		$failcond = "== 0";
	}

	# Decide which version of api is used: ascii or unicode.
	if($sysname !~ /W$/) {
		$strconvfunc = "StringBytePtr";
	} else {
		$strconvfunc = "StringToUTF16Ptr";
	}

	# Winapi proc address variable.
	$vars .= sprintf "\t%s = getSysProcAddr(%s, \"%s\")\n", $sysvarname, $modvname, $sysname;

	# Go function header.
	my $out = join(', ', @out);
	if($out ne "") {
		$out = " ($out)";
	}
	if($text ne "") {
		$text .= "\n"
	}
	$text .= sprintf "func %s(%s)%s {\n", $func, join(', ', @in), $out;

	# Prepare arguments to Syscall.
	my @args = ();
	my $n = 0;
	my @pin= ();
	foreach my $p (@in) {
		my ($name, $type) = parseparam($p);
		if($type =~ /^\*/) {
			push @args, "uintptr(unsafe.Pointer($name))";
		} elsif($type eq "string") {
			push @args, "uintptr(unsafe.Pointer($strconvfunc($name)))";
		} elsif($type =~ /^\[\](.*)/) {
			# Convert slice into pointer, length.
			# Have to be careful not to take address of &a[0] if len == 0:
			# pass nil in that case.
			$text .= "\tvar _p$n *$1\n";
			$text .= "\tif len($name) > 0 {\n\t\t_p$n = \&$name\[0]\n\t}\n";
			push @args, "uintptr(unsafe.Pointer(_p$n))", "uintptr(len($name))";
			$n++;
		} elsif($type eq "int64" && $_32bit ne "") {
			if($_32bit eq "big-endian") {
				push @args, "uintptr($name >> 32)", "uintptr($name)";
			} else {
				push @args, "uintptr($name)", "uintptr($name >> 32)";
			}
		} elsif($type eq "bool") {
 			$text .= "\tvar _p$n uint32\n";
			$text .= "\tif $name {\n\t\t_p$n = 1\n\t} else {\n\t\t_p$n = 0\n\t}\n";
			push @args, "uintptr(_p$n)";
		} else {
			push @args, "uintptr($name)";
		}
		push @pin, sprintf "\"%s=\", %s, ", $name, $name;
	}
	my $nargs = @args;

	# Determine which form to use; pad args with zeros.
	my $asm = "Syscall";
	if(@args <= 3) {
		while(@args < 3) {
			push @args, "0";
		}
	} elsif(@args <= 6) {
		$asm = "Syscall6";
		while(@args < 6) {
			push @args, "0";
		}
	} elsif(@args <= 9) {
		$asm = "Syscall9";
		while(@args < 9) {
			push @args, "0";
		}
	} elsif(@args <= 12) {
		$asm = "Syscall12";
		while(@args < 12) {
			push @args, "0";
		}
	} else {<commit_msg>syscall: fix bug in mksyscall_windows.pl<commit_after>#!/usr/bin/perl
# Copyright 2009 The Go Authors. All rights reserved.
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.

# This program reads a file containing function prototypes
# (like syscall_darwin.go) and generates system call bodies.
# The prototypes are marked by lines beginning with "//sys"
# and read like func declarations if //sys is replaced by func, but:
#	* The parameter lists must give a name for each argument.
#	  This includes return parameters.
#	* The parameter lists must give a type for each argument:
#	  the (x, y, z int) shorthand is not allowed.
#	* If the return parameter is an error number, it must be named errno.
#	* If go func name needs to be different from it's winapi dll name,
#	  the winapi name could be specified at the end, after "=" sign, like
#	  //sys LoadLibrary(libname string) (handle uint32, errno int) = LoadLibraryA
#	* Each function, that returns errno, needs to supply a condition,
#	  that return value of winapi will be tested against to
#	  detect failure. This would set errno to windows "last-error",
#	  otherwise it will be 0. The value can be provided
#	  at end of //sys declaration, like
#	  //sys LoadLibrary(libname string) (handle uint32, errno int) [failretval==-1] = LoadLibraryA
#	  and is [failretval==0] by default.

$cmdline = "mksyscall_windows.pl " . join(' ', @ARGV);
$errors = 0;
$_32bit = "";

if($ARGV[0] eq "-b32") {
	$_32bit = "big-endian";
	shift;
} elsif($ARGV[0] eq "-l32") {
	$_32bit = "little-endian";
	shift;
}

if($ARGV[0] =~ /^-/) {
	print STDERR "usage: mksyscall_windows.pl [-b32 | -l32] [file ...]\n";
	exit 1;
}

sub parseparamlist($) {
	my ($list) = @_;
	$list =~ s/^\s*//;
	$list =~ s/\s*$//;
	if($list eq "") {
		return ();
	}
	return split(/\s*,\s*/, $list);
}

sub parseparam($) {
	my ($p) = @_;
	if($p !~ /^(\S*) (\S*)$/) {
		print STDERR "$ARGV:$.: malformed parameter: $p\n";
		$errors = 1;
		return ("xx", "int");
	}
	return ($1, $2);
}

$text = "";
$vars = "";
$mods = "";
$modnames = "";
while(<>) {
	chomp;
	s/\s+/ /g;
	s/^\s+//;
	s/\s+$//;
	next if !/^\/\/sys /;

	# Line must be of the form
	#	func Open(path string, mode int, perm int) (fd int, errno int)
	# Split into name, in params, out params.
	if(!/^\/\/sys (\w+)\(([^()]*)\)\s*(?:\(([^()]+)\))?\s*(?:\[failretval(.*)\])?\s*(?:=\s*(?:(\w*)\.)?(\w*))?$/) {
		print STDERR "$ARGV:$.: malformed //sys declaration\n";
		$errors = 1;
		next;
	}
	my ($func, $in, $out, $failcond, $modname, $sysname) = ($1, $2, $3, $4, $5, $6);

	# Split argument lists on comma.
	my @in = parseparamlist($in);
	my @out = parseparamlist($out);

	# Dll file name.
	if($modname eq "") {
		$modname = "kernel32";
	}
	$modvname = "mod$modname";
	if($modnames !~ /$modname/) {
		$modnames .= ".$modname";
		$mods .= "\t$modvname = loadDll(\"$modname.dll\")\n";
	}

	# System call name.
	if($sysname eq "") {
		$sysname = "$func";
	}

	# System call pointer variable name.
	$sysvarname = "proc$sysname";

	# Returned value when failed
	if($failcond eq "") {
		$failcond = "== 0";
	}

	# Decide which version of api is used: ascii or unicode.
	if($sysname !~ /W$/) {
		$strconvfunc = "StringBytePtr";
	} else {
		$strconvfunc = "StringToUTF16Ptr";
	}

	# Winapi proc address variable.
	$vars .= sprintf "\t%s = getSysProcAddr(%s, \"%s\")\n", $sysvarname, $modvname, $sysname;

	# Go function header.
	my $out = join(', ', @out);
	if($out ne "") {
		$out = " ($out)";
	}
	if($text ne "") {
		$text .= "\n"
	}
	$text .= sprintf "func %s(%s)%s {\n", $func, join(', ', @in), $out;

	# Prepare arguments to Syscall.
	my @args = ();
	my $n = 0;
	my @pin= ();
	foreach my $p (@in) {
		my ($name, $type) = parseparam($p);
		if($type =~ /^\*/) {
			push @args, "uintptr(unsafe.Pointer($name))";
		} elsif($type eq "string") {
			push @args, "uintptr(unsafe.Pointer($strconvfunc($name)))";
		} elsif($type =~ /^\[\](.*)/) {
			# Convert slice into pointer, length.
			# Have to be careful not to take address of &a[0] if len == 0:
			# pass nil in that case.
			$text .= "\tvar _p$n *$1\n";
			$text .= "\tif len($name) > 0 {\n\t\t_p$n = \&$name\[0]\n\t}\n";
			push @args, "uintptr(unsafe.Pointer(_p$n))", "uintptr(len($name))";
			$n++;
		} elsif($type eq "int64" && $_32bit ne "") {
			if($_32bit eq "big-endian") {
				push @args, "uintptr($name >> 32)", "uintptr($name)";
			} else {
				push @args, "uintptr($name)", "uintptr($name >> 32)";
			}
		} elsif($type eq "bool") {
 			$text .= "\tvar _p$n uint32\n";
			$text .= "\tif $name {\n\t\t_p$n = 1\n\t} else {\n\t\t_p$n = 0\n\t}\n";
			push @args, "uintptr(_p$n)";
			$n++;
		} else {
			push @args, "uintptr($name)";
		}
		push @pin, sprintf "\"%s=\", %s, ", $name, $name;
	}
	my $nargs = @args;

	# Determine which form to use; pad args with zeros.
	my $asm = "Syscall";
	if(@args <= 3) {
		while(@args < 3) {
			push @args, "0";
		}
	} elsif(@args <= 6) {
		$asm = "Syscall6";
		while(@args < 6) {
			push @args, "0";
		}
	} elsif(@args <= 9) {
		$asm = "Syscall9";
		while(@args < 9) {
			push @args, "0";
		}
	} elsif(@args <= 12) {
		$asm = "Syscall12";
		while(@args < 12) {
			push @args, "0";
		}
	} else {
{'fraction_non_alphanumeric': 0.21750867720786735, 'fraction_numerical': 0.01600462784419591, 'mean_word_length': 3.1692122186495175, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4135556', 'n_tokens_mistral': 4487, 'n_tokens_neox': 4116, 'n_words': 1197}