⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 make_tables

📁 OTP是开放电信平台的简称
💻
字号:
#!/usr/bin/env perl # ``The contents of this file are subject to the Erlang Public License,# Version 1.1, (the "License"); you may not use this file except in# compliance with the License. You should have received a copy of the# Erlang Public License along with this software. If not, it can be# retrieved via the world wide web at http://www.erlang.org/.# # Software distributed under the License is distributed on an "AS IS"# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See# the License for the specific language governing rights and limitations# under the License.# # The Initial Developer of the Original Code is Ericsson Utvecklings AB.# Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings# AB. All Rights Reserved.''# #     $Id$#use strict;use File::Basename;## Description:#   Creates tables for BIFs and atoms.## Usage:#    make_tables [ Options ] file...## Options:#    -src directory	Where to write generated C source files (default ".").#    -include directory Where to generate generated C header files (default ".").## Output:#    <-src>/erl_am.c#    <-src>/erl_bif_table.c#    <-src>/erl_bif_wrap.c#    <-src>/erl_pbifs.c#    <-include>/erl_atom_table.h#    <-include>/erl_bif_table.h## Author: Bjorn Gustavsson#my $progname = basename($0);my $src = '.';my $include = '.';my @atom;my %atom;my %atom_alias;my %aliases;my $auto_alias_num = 0;my @bif;my @implementation;my @pbif;while (@ARGV && $ARGV[0] =~ /^-(\w+)/) {    my $opt = shift;    if ($opt eq '-src') {	$src = shift;	die "No directory for -src argument specified"	    unless defined $src;    } elsif($opt eq '-include') {	$include = shift;	die "No directory for -include argument specified"	    unless defined $include;    } else {	usage("bad option: $opt");    }}while (<>) {    next if /^#/;    next if /^\s*$/;    my($type, @args) = split;    if ($type eq 'atom') {	save_atoms(@args);    } elsif ($type eq 'bif' or $type eq 'ubif') {	my($bif,$alias,$alias2) = (@args);	$bif =~ m@^([a-z_.'0-9]+):(.*)/(\d)$@ or error("invalid BIF");	my($mod,$name,$arity) = ($1,$2,$3);	save_atoms($mod, $name);	unless (defined $alias) {	    $alias = "";	    $alias = "${mod}_" unless $mod eq 'erlang';	    $alias .= "${name}_$arity";	}	my $wrapper;	$wrapper = "wrap_$alias" if $type eq 'bif';	$wrapper = $alias if $type eq 'ubif';	push(@bif, ["am_$atom_alias{$mod}","am_$atom_alias{$name}",$arity,		    $alias,$wrapper]);        push(@pbif, $bif =~ m/^'/ && $alias =~ m/^ebif_/);        push(@implementation, $alias2);    } else {	error("invalid line");    }} continue {    close ARGV if eof;}## Generate the atom header file.#open_file("$include/erl_atom_table.h");print <<EOF;#ifndef __ERL_ATOM_TABLE_H__#define __ERL_ATOM_TABLE_H__extern char* erl_atom_names[];EOFmy $i;for ($i = 0; $i < @atom; $i++) {    my $alias = $atom_alias{$atom[$i]};    print "#define am_$alias make_atom($i)\n"	if defined $alias;}print "#endif\n";## Generate the atom table file.#open_file("$src/erl_atom_table.c");my $i;print "char* erl_atom_names[] = {\n";for ($i = 0; $i < @atom; $i++) {    print '  "', $atom[$i], '",', "\n";}print "  0\n";print "};\n";## Generate the generic bif list file.#open_file("$include/erl_bif_list.h");my $i;for ($i = 0; $i < @bif; $i++) {    # module atom, function atom, arity, C function, table index    print "BIF_LIST($bif[$i]->[0],$bif[$i]->[1],$bif[$i]->[2],$bif[$i]->[3],$i)\n";}## Generate the bif header file.#open_file("$include/erl_bif_table.h");my $bif_size = @bif;print <<EOF;#ifndef __ERL_BIF_TABLE_H__#define __ERL_BIF_TABLE_H__typedef void *BifFunction;typedef struct bif_entry {    Eterm module;    Eterm name;    int arity;    BifFunction f;    BifFunction traced;} BifEntry;extern BifEntry bif_table[];extern Export* bif_export[];extern unsigned char erts_bif_trace_flags[];#define BIF_SIZE $bif_sizeEOFmy $i;for ($i = 0; $i < @bif; $i++) {    print "#define BIF_$bif[$i]->[3] $i\n";}print "\n";for ($i = 0; $i < @bif; $i++) {    my $arity = $bif[$i]->[2];    my $args = join(', ', 'Process*', ('Eterm') x $arity);    print "Eterm $bif[$i]->[3]($args);\n";    print "Eterm wrap_$bif[$i]->[3]($args, Uint *I);\n";}print "#endif\n";## Generate the bif table file.#open_file("$src/erl_bif_table.c");my $i;includes("export.h", "sys.h", "erl_vm.h", "erl_process.h", "bif.h",	 "erl_bif_table.h", "erl_atom_table.h");print "\nExport* bif_export[BIF_SIZE];\n";print "unsigned char erts_bif_trace_flags[BIF_SIZE];\n\n";print "BifEntry bif_table[] = {\n";for ($i = 0; $i < @bif; $i++) {    my $func = $bif[$i]->[3];    print "  {", join(', ', @{$bif[$i]}), "},\n";}print "};\n\n";## Generate the bif wrappers file.#open_file("$src/erl_bif_wrap.c");my $i;includes("export.h", "sys.h", "erl_vm.h", "global.h", "erl_process.h", "bif.h",	 "erl_bif_table.h", "erl_atom_table.h");for ($i = 0; $i < @bif; $i++) {    next if $bif[$i]->[3] eq $bif[$i]->[4]; # Skip unwrapped bifs    my $arity = $bif[$i]->[2];    my $func = $bif[$i]->[3];    my $arg;    print "Eterm\n";    print "wrap_$func(Process* p";    for ($arg = 1; $arg <= $arity; $arg++) {	print ", Eterm arg$arg";    }    print ", Uint *I)\n";    print "{\n";    print "    return erts_bif_trace($i, p";    for ($arg = 1; $arg <= 3; $arg++) {	if ($arg <= $arity) {	    print ", arg$arg";	} elsif ($arg == ($arity + 1)) { 	    # Place I in correct position	    print ", (Eterm) I";	} else {	    print ", 0";	}    }    # I is always last, as well as in the correct position    # Note that "last" and "correct position" may be the same...    print ", I);\n";    print "}\n\n";}## Generate the package bif file.#open_file("$src/erl_pbifs.c");my $i;includes("export.h", "sys.h", "erl_vm.h", "global.h", "erl_process.h", "bif.h",	 "erl_bif_table.h", "erl_atom_table.h");for ($i = 0; $i < @bif; $i++) {    my $arity = $bif[$i]->[2];    my $func = $bif[$i]->[3];    my $arg;    next unless $pbif[$i];    next unless $func =~ m/^ebif_(.*)/;    my $orig_func = $1;    $orig_func = $implementation[$i] if $implementation[$i];    print "Eterm\n";    print "$func(Process* p";    for ($arg = 1; $arg <= $arity; $arg++) {	print ", Eterm arg$arg";    }    print ")\n";    print "{\n";    print "    return $orig_func(p";    for ($arg = 1; $arg <= 3; $arg++) {	if ($arg <= $arity) {	    print ", arg$arg";        }    }    print ");\n";    print "}\n\n";}sub open_file {			# or die    my($name) = @_;    open(FILE, ">$name") or die "$0: Failed to create $name: $!\n";    select(FILE);    comment('C');}sub includes {    print "#ifdef HAVE_CONFIG_H\n";    print "#  include \"config.h\"\n";    print "#endif /* HAVE_CONFIG_H */\n";    print map { "#include \"$_\"\n"; } @_;    print "\n";}sub save_atoms {    my $atom;    my $alias;    foreach $atom (@_) {	if ($atom =~ /^\w+$/) {	    error("$atom: an atom must start with a lowercase letter\n",		  "  (use an alias like this: $atom='$atom')")		unless $atom =~ /^[a-z]/;	    $alias = $atom;	} elsif ($atom =~ /^'(.*)'$/) {	    $atom = $1;	    $alias = "_AtomAlias$auto_alias_num";	    $auto_alias_num++;	} elsif ($atom =~ /^(\w+)='(.*)'$/) {	    $alias = $1;	    $atom = $2;	    error("$alias: an alias must start with an uppercase letter")		unless $alias =~ /^[A-Z]/;	} else {	    error("invalid atom: $atom");	}	next if $atom{$atom};	push(@atom, $atom);	$atom{$atom} = 1;	if (defined $alias) {	    error("$alias: this alias is already in use")		if defined $aliases{$alias} && $aliases{$alias} ne $atom;	    $aliases{$alias} = $atom;	    $atom_alias{$atom} = $alias;	}    }}sub usage {    warn "$progname: ", @_, "\n";    die "usage: $progname -src source-dir -include include-dir file...\n";}sub error {    die "$ARGV($.): ", @_, "\n";}sub comment {    my($lang, @comments) = @_;    my($prefix);    if ($lang eq 'C') {	print "/*\n";	$prefix = " * ";    } elsif ($lang eq 'erlang') {	$prefix = '%% ';    } else {	$prefix = '# ';    }    my(@prog) = split('/', $0);    my($prog) = $prog[$#prog];    if (@comments) {	my $line;	foreach $line (@comments) {	    print "$prefix$line\n";	}    } else {	print "$prefix Warning: Do not edit this file.  It was automatically\n";	print "$prefix generated by '$progname' on ", (scalar localtime), ".\n";    }    if ($lang eq 'C') {	print " */\n";    }    print "\n";}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -