📄 file_generator.pl
字号:
#!/usr/bin/perl### This file is part of the aMule Project#### Copyright (c) 2007-2008 Angel Vidal (Kry) ( kry@amule.org )## Copyright (c) 2007-2008 aMule Project ( http://www.amule-project.net )#### This program is free software; you can redistribute it and/or## modify it under the terms of the GNU General Public License## as published by the Free Software Foundation; either## version 2 of the License, or (at your option) any later version.#### This program 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 General Public License for more details.#### You should have received a copy of the GNU General Public License## along with this program; if not, write to the Free Software## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA# Gimme a break, it's my second perl app... (Kry)use File::Copy;use warnings; use strict;use POSIX;my $exit_with_help;if ($#ARGV < 1) { print "You must specify at least the folder and one abstract file.\n"; $exit_with_help = "true";}if ($exit_with_help) { die "Usage: file_generator file.abstract [file2.abstract ...]\n";}my $folder = $ARGV[0] . "/";my $numArgs = $#ARGV;print "Parsing $numArgs files\n";foreach my $argnum (1 .. $#ARGV) { generate_files($folder, $ARGV[$argnum]);}sub generate_files { my $folder = $_[0]; my $input_file = $_[1]; open(INFO, $folder . $input_file) or die "Cannot open input file " . $input_file . " for reading: $!"; # Open the file my $line="no"; while ($line !~ /^\[Section Definition\]$/) { $line = <INFO>; if (!($line)) { die $input_file . " seems not to have a Section Definition\n"; } chop $line; } #We're at the start of the Section Definition. # Read the Definition Section. my $filename = ""; my $nameline = <INFO>; if ($nameline =~ /^FileName\s+(.+)$/) { $filename = $1; } else { die "Section Definition must start with FileName item."; } my $filecontent = ""; my $contentline = <INFO>; if ($contentline =~ /^FileContent\s+(.+)$/) { $filecontent = $1; } else { die "Section Definition must have a FileContent after the FileName item."; } #Skip the rest of the section, allow for extensions later. $line = ""; while ($line && ($line !~ /^\[\/Section\]$/)) { $line = <INFO>; } print "FileName: " . $filename . "\n"; print "FileContent: " . $filecontent . "\n"; #Open language output files open(CPPFILE," > " . $folder . "cpp/$filename" . ".h"); #Open language output files open(JAVAFILE," > " . $folder . "java/$filename" . ".java"); open(CDASHFILE, ">${folder}/c#/${filename}.cs"); # Print license on top. write_license_header($folder, *CPPFILE, "// ", "", $filecontent); write_license_header($folder, *CDASHFILE, "// ", "", $filecontent); write_license_header($folder, *JAVAFILE, "// ", "", $filecontent); #Example for a language that needs start/end: #write_license_header($folder, *CFILE, "/* ", " */", $filecontent); #Add top guards for each language write_cpp_top_guard(*CPPFILE, $filename); write_cdash_top_guard(*CDASHFILE); # JAVA doesn't need guards, but needs file type declaration print JAVAFILE "public interface " . $filename . " {\n\n"; ##Add other language guards read_content(*INFO, *CPPFILE, *JAVAFILE, *CDASHFILE); #Add bottom guards for each language write_cpp_bottom_guard(*CPPFILE, $filename); write_cdash_bottom_guard(*CDASHFILE); # JAVA doesn't need guards, but we have to close the interface print JAVAFILE "}\n"; ##Add other language guards # Close language files close(CPPFILE); close(JAVAFILE); print "All info parsed\n"; close(INFO);}################ Generic Subroutines #####################sub read_content { local (*INFO) = $_[0]; local (*CPPFILE) = $_[1]; local (*JAVAFILE) = $_[2]; local (*CDASHFILE) = $_[3]; my $stop = ""; while (!($stop)) { my $line="no"; #Skip till Content while (!(eof(INFO)) && $line !~ /^\[Section Content\]$/) { $line = <INFO>; chop $line; } if ($line =~ /^\[Section Content\]$/) { print "Reading content section...\n"; read_content_section(*INFO, *CPPFILE, *JAVAFILE, *CDASHFILE); print CPPFILE "\n"; print JAVAFILE "\n"; } else { print "No more content sections\n"; $stop = "yes"; } }}sub read_content_section { local (*INFO) = $_[0]; local (*CPPOUTPUT) = $_[1]; local (*JAVAOUTPUT) = $_[2]; local (*CDASHFILE) = $_[3]; my $line = <INFO>; my $datatype = ""; if ($line =~ /^Type\s+(.+)$/) { $datatype = $1; print "\tDatatype: " . $datatype . "\n"; } else { die "Content section has a non-typed data stream\n"; } if ($datatype eq "Define") { read_define_content(*INFO, *CPPOUTPUT, *JAVAOUTPUT, *CDASHFILE); } elsif ($datatype eq "Enum") { read_enum_content(*INFO, *CPPOUTPUT, *JAVAOUTPUT, *CDASHFILE); } elsif ($datatype eq "TypeDef") { read_typedef_content(*INFO, *CPPOUTPUT, *JAVAOUTPUT, *CDASHFILE); } else { die "Unknown type on content section\n"; } }sub read_define_content { local (*INFO) = $_[0]; local (*CPPOUTPUT) = $_[1]; local (*JAVAOUTPUT) = $_[2]; local (*CDASHFILE) = $_[3]; my $line = <INFO>; while (!(eof) && ($line !~ /^\[\/Section\]$/)) { if ($line !~ /^(#.*|\s*)$/) { if ($line =~ /^(.+)\s+(.+)$/) { write_cpp_define_line(*CPPOUTPUT, $1, $2); write_java_define_line(*JAVAOUTPUT, $1, $2); write_cdash_define_line(*CDASHFILE, $1, $2); } else { die "Malformed content section define line\n"; } } $line = <INFO>; }}sub read_typedef_content { local (*INFO) = $_[0]; local (*CPPOUTPUT) = $_[1]; local (*JAVAOUTPUT) = $_[2]; my $line = <INFO>; while (!(eof) && ($line !~ /^\[\/Section\]$/)) { if ($line !~ /^(#.*|\s*)$/) { if ($line =~ /^(.+)\s+(.+)$/) { write_cpp_typedef_line(*CPPOUTPUT, $1, $2); # Java doesn't support typedefs, ignore it. #write_java_typedef_line(*JAVAOUTPUT, $1, $2); # c# doesn't support typedefs either (AFAIK) } else { die "Malformed content section typedef line\n"; } } $line = <INFO>; }}sub read_enum_content { local (*INFO) = $_[0]; local (*CPPOUTPUT) = $_[1]; local (*JAVAOUTPUT) = $_[2]; local (*CDASHFILE) = $_[3]; my $line = <INFO>; my $dataname = ""; if ($line =~ /^Name\s+(.+)$/) { $dataname = $1; print "\tDataname: " . $dataname . "\n"; } else { die "Content section has a non-named data stream\n"; } $line = <INFO>; my $datatype = ""; if ($line =~ /^DataType\s+(.+)$/) { $datatype = $1; print "\tDataType: " . $datatype . "\n"; } else { die "Content section has a enum stream with no data type\n"; } my $first = "yes"; $line = <INFO>; while (!(eof) && ($line !~ /^\[\/Section\]$/)) { if ($line !~ /^(#.*|\s*)$/) { if ($line =~ /^(.+)\s+(.+)$/) { my $firstoperand = $1; my $secondoperand = $2; if ($first) { write_cpp_enum_start(*CPPOUTPUT, $dataname); write_cdash_enum_start(*CDASHFILE, $dataname); } write_cpp_enum_line(*CPPOUTPUT, $firstoperand, $secondoperand, $first); write_java_define_line(*JAVAOUTPUT, $firstoperand, $secondoperand, $datatype); write_cdash_enum_line(*CDASHFILE, $firstoperand, $secondoperand, $first); if ($first) { $first = ""; } } else { die "Malformed content section enum line\n"; } } $line = <INFO>; } write_cpp_enum_end(*CPPOUTPUT); write_cdash_enum_end(*CDASHFILE);}# Takes a file handle, and the comment start/end character for that languagesub write_license_header { my $folder = $_[0]; local (*OUTPUT) = $_[1]; open(LICENSE, $folder . "abstracts/License.abstract") or die "Cannot open license file"; my $line = <LICENSE>; while (!(eof)) { printf OUTPUT $_[2] . $line . $_[3]; $line = <LICENSE>; } print OUTPUT "\n"; print OUTPUT $_[2] . "Purpose:" . $_[3] . "\n" . $_[2] . $_[4] . $_[3] . "\n\n"; close(LICENSE);}################ C# Specific Subroutines #####################sub write_cdash_top_guard { local (*OUTPUT) = $_[0]; print OUTPUT "namespace amule.net\n{\n";}sub write_cdash_bottom_guard { local (*OUTPUT) = $_[0]; print OUTPUT "}\n";}sub write_cdash_enum_start { local (*OUTPUT) = $_[0]; print OUTPUT "public enum " . $_[1] . " {\n";}sub write_cdash_enum_end { local (*OUTPUT) = $_[0]; print OUTPUT "\n};\n"}sub write_cdash_enum_line { local (*OUTPUT) = $_[0]; if ($_[3] !~ "yes") { print OUTPUT ",\n" } # looks like c# can't handle such values as enums if ( not (POSIX::strtod($_[2]) & 0x8000000) ) { print OUTPUT "\t" . $_[1] . " = " . $_[2]; }}sub write_cdash_define_line { local (*OUTPUT) = $_[0]; die "ERROR: c# have no 'define' directive $_[1] $_[2]"}################ CPP Specific Subroutines #####################sub write_cpp_top_guard { local (*OUTPUT) = $_[0]; my $guardname = uc($_[1]); print OUTPUT "#ifndef __" . $guardname . "_H__\n"; print OUTPUT "#define __" . $guardname . "_H__\n\n";}sub write_cpp_bottom_guard { local (*OUTPUT) = $_[0]; my $guardname = uc($_[1]); print OUTPUT "#endif // __" . $guardname . "_H__\n";}sub write_cpp_enum_start { local (*OUTPUT) = $_[0]; print OUTPUT "enum " . $_[1] . " {\n";}sub write_cpp_enum_end { local (*OUTPUT) = $_[0]; print OUTPUT "\n};\n"}sub write_cpp_enum_line { local (*OUTPUT) = $_[0]; if ($_[3] !~ "yes") { print OUTPUT ",\n" } print OUTPUT "\t" . $_[1] . " = " . $_[2];}sub write_cpp_define_line { local (*OUTPUT) = $_[0]; print OUTPUT "#define " . $_[1] . " " . $_[2] . "\n";}sub write_cpp_typedef_line { local (*OUTPUT) = $_[0]; my $translated_type; my $preamble = ""; my $datatype = $_[2]; if ($datatype) { if ($datatype =~ /^u?int(8|16|32|64)$/) { $translated_type = $datatype . "_t"; } elsif ($datatype eq "string") { $translated_type = "std::string" } else { $preamble = "// "; $translated_type = $datatype; } } else { die "No data type on abstract"; } print OUTPUT $preamble . "typedef " . $translated_type . " " . $_[1] . ";\n";}################ JAVA Specific Subroutines #####################sub write_java_define_line { local (*OUTPUT) = $_[0]; my $datatype = "int"; my $first = $_[1]; my $second = $_[2]; if ($_[3]) { if ($_[3] =~ /int8/) { $datatype = "byte"; } elsif ($_[3] =~ /(uint8|int16)/) { $datatype = "short"; } elsif ($_[3] =~ /(uint16|int32)/) { $datatype = "int"; } elsif ($_[3] =~ /(uint32|int64)/) { $datatype = "long"; } else { die "Unknown data type on abstract: " . $_[3]; } } else { if ($second =~ /^\".*\"$/) { $datatype = "String"; } } print OUTPUT "public final static " . $datatype . " " . $first . " = " . $second . ";\n";}sub write_java_typedef_line { die "Typedef not supported on java";}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -