newlib-cygwin/winsup/cygwin/gendevices

163 lines
3.9 KiB
Plaintext
Raw Normal View History

#!/usr/bin/perl
#
# This file is part of Cygwin.
#
# This software is a copyrighted work licensed under the terms of the
# Cygwin license. Please consult the file "CYGWIN_LICENSE" for
# details.
#
use File::Basename;
use Cwd;
my $cwd = getcwd;
use strict;
use integer;
sub devsort;
my $input = shift;
my $output = shift;
my $base = "/tmp/" . basename($input, '.in') . '.' . $$;
my $c = $base . '.c';
my $shilka = $base . '.shilka';
open(INPUT, $input) or die "$0: couldn't open '$input' - $!\n";
my @lines = ();
my $storage_ix = -1;
my @storage = ();
my %pointers = ();
my @patterns = ();
my $patterns_ix = -1;
while (<INPUT>) {
if (/%storage_here/) {
$storage_ix = @lines;
} elsif (/^"([^"]+)",\s*(.*)$/o) {
push(@patterns, [$1, $2]);
next;
}
if (@patterns) {
for my $f (sort devsort @patterns) {
my $x = $f->[0];
my $rest = $f->[1];
my ($dev, $devrest) = ($x =~ /([^%]+)(%.*)?$/o);
$rest .= ', ' . (($dev =~ m%/dev/%o) ? 'true' : 'false');
push(@lines, generate($dev, $devrest, $rest, []));
}
@patterns = ();
}
push(@lines, $_);
}
close INPUT;
# @storage = sort devsort @storage;
chop $storage[$#storage];
chop $storage[$#storage];
$storage[$#storage] .= "\n";
splice(@lines, $storage_ix, 1,
"const _RDATA _device dev_storage[] =\n", "{\n",
@storage, "};\n\n",
sort {$a cmp $b} values %pointers);
open(SHILKA, '>', $shilka);
print SHILKA @lines;
close SHILKA;
chdir '/tmp';
system qw'shilka -length -strip -no-definitions', $shilka;
if ($? == -1) {
die "$0: shilka command missing? - $!\n";
} else {
exit $? if $?;
}
chdir $cwd;
unlink $shilka;
open(C, '<', $c) or die "$0: couldn't open $c - $!\n";
@lines = <C>;
close C;
unlink $c;
splice(@lines, 0, 3);
my $ign_until_brace = 0;
for (my $i = 0; $i < @lines; $i++) {
$_ = $lines[$i];
$ign_until_brace = 1 if /(?:KR_reset|KR_output_statistics).*\)\s*$/o;
if ($ign_until_brace || /(?:#\s*line|(?:KR_reset|KR_output_statistics).*;)/) {
$ign_until_brace = 0 if $ign_until_brace && /}/o;
splice(@lines, $i, 1);
redo;
};
}
Eliminate use of sigframe and sigthread throughout. * Makefile.in (DLL_OFILES): Add sigfe.o. Remove reliance on cygwin.def from cygwin0.dll dependency since dependence on sigfe.o implies that. Generate def file on the fly using 'gendef'. * configure.in: Don't auto-generate cygwin.def. * configure: Regenerate. * cygwin.din: Add SIGFE stuff where appropriate. * dcrt0.cc (dll_crt0_1): Initialize cygwin tls early in process startup. Set _main_tls to address of the main thread's cygwin tls. * debug.h: Remove now unneeded WFSO and WFMO declarations. * exceptions.cc (_last_thread): Define. (set_thread_state_for_signals): New function. (reset_thread_exception_for_signals): Ditto. (init_thread_for_signals): Ditto. (delete_thread_for_signals): Ditto. (capture_thread_for_signals): Ditto. (handle_exceptions): Set return address explicitly for exceptions prior to calling sig_send. (interrupt_on_return): Eliminate. (setup_handler): Add preliminary implementation for dealing with thread-specific signals by querying _main_tls. (signal_exit): Use cygthread::main_thread_id instead of mainthread.id. (call_signal_handler_now): For now, just handle the main thread. * fork.cc (vfork): Save and restore main _my_tls. * gendef: New file. Generates def file and sigfe.s file. * gentls_offsets: New file. Generates offsets for perl to use in sigfe.s. * how-signals-work.txt: Mention that info is obsolete. * init.cc (dll_entry): Initialize cygwin tls storage here. * miscfuncs.cc (low_priority_sleep): Make a C function for easier calling from asm. * perthread.h (vfork_save::tls): New element. * signal.cc (nanosleep): Replace previous use of sigframe.call_signal_handler_now with straight call to call_signal_handler_now. (abort): Ditto. * syscalls.cc (readv): Ditto. * termios.cc (tcsetattr): Ditto. * wait.cc (wait4): Ditto. * sigproc.cc (sig_dispatch_pending): Ditto. (sig_send): Ditto. * sigproc.h: Declare call_signal_handler_now. * thread.cc (pthread::thread_init_wrapper): Initialize cygwin tls. Remove obsolete and unworking signal stuff. * thread.h (verifyable_object::sigs): Eliminate. (verifyable_object::sigmask): Eliminate. (verifyable_object::sigtodo): Eliminate. (verifyable_object::exit): Make attribute noreturn. (verifyable_object::thread_init_wrapper): Ditto. (pthread_null::exit): Ditto. * winbase.h (__stackbase): Always define. * winsup.h (low_priority_sleep): Declare as a "C" function. * include/cygwin/version.h: Bump API version to reflect sigwait export. * include/sys/queue.h: Protect SLIST_ENTRY from previous declaration. * signal.cc (sigwait): Implement. * select.cc (fhandler_base::ready_for_read): Add debugging output. * devices.h: Define more device pointers via their storage. * devices.in: Don't parse things like /dev/inet/tcp, as they really have no meaning. * devices.cc: Regenerate. * gendevices: Set proper protection for output file. * cygtls.h: New file. * gendef: New file. * gentls_offsets: New file. * tlsoffsets.h: New file. Autogenerated. * config/i386/longjmp.c: Remove. File subsumed by gendef output. * config/i386/makefrag: Remove obsolete file. * fhandler.cc: Remove spurious access_worker declaration. * spawn.cc (spawnve): Make debugging output more accurate. * cygwin-gperf: Remove. * devices.cc: Remove.
2003-11-29 04:55:59 +08:00
open(OUTPUT, '>', $output) or do {{
if (chmod(0664, $output)) {
open(OUTPUT, '>', $output);
last;
}
die "$0: couldn't open $output - $!\n";
}};
print OUTPUT @lines;
close OUTPUT;
sub generate {
my $dev = shift;
my $devrest = shift;
my $rest = shift;
my $vars = shift;
my $res;
my @lines = ();
if ($devrest) {
my ($a, $low, $high, $fmt, $b) = ($devrest =~ /%([\({])([^-]+)-([^\)}]+)[\)}](.)(.*)/o);
my ($middle, $devrest0) = ($b =~ /^([^%]*)(%.*)?$/);
$fmt = "%$fmt";
my $vars_ix = @{$vars};
for my $f ($low .. $high) {
$vars->[$vars_ix] = $f;
$#{$vars} = $vars_ix;
my $dev0 = $dev . sprintf($fmt, $f) . $middle;
push(@lines, generate($dev0, $devrest0, $rest, $vars));
}
} else {
my $fh = $dev;
$fh =~ s%/%_%og;
$fh =~ s%^:%__%o;
my $shilka_id = $fh;
my $storage_str = $fh . '_storage';
$fh =~ s/^_dev_/FH_/o;
$fh = uc $fh;
$shilka_id =~ s/^_dev_//o;
$storage_str =~ s/^_dev/dev/o;
my $storage_loc = "dev_storage + " . @storage;
@lines = ('"' . $dev . '"' . " = $shilka_id {return $storage_loc;}\n");
$rest = "$fh, $rest" if $rest =~ /^"/o;
$rest = fixup($rest, $vars);
if ($rest =~ /^(.*), =(\S*_dev)\b\s*(.*)$/) {
$pointers{$2} ||= "const _device *$2 = $storage_loc;\n";
$rest = $1 . $3;
}
push(@storage, " {\"$dev\", " . $rest . "},\n");
}
return @lines;
}
sub fixup {
my $rest = shift;
my $vars = shift;
0 while $rest =~ s/{([^}]*)}/evalit($1, $vars)/eg;
return $rest;
}
sub evalit {
my $what = shift;
my $vars = shift;
$what =~ s/\$(\d+)/'$vars->[$1-1]'/g;
my $res = eval $what;
return $res;
}
sub devsort {
my $a0 = $a->[0];
my $b0 = $b->[0];
$a0 =~ s/(\D)(\d+)/"$1" . sprintf "%05d", $2/e;
$b0 =~ s/(\D)(\d+)/"$1" . sprintf "%05d", $2/e;
$a0 =~ s%^//%:%o;
$b0 =~ s%^//%:%o;
return $a0 cmp $b0;
}