📄 mkdeps.pl
字号:
#!/usr/bin/perl -w## Copyright (c) 2003-2004, Artem B. Bityuckiy, SoftMine Corporation.## Redistribution and use in source and binary forms, with or without# modification, are permitted provided that the following conditions# are met:# 1. Redistributions of source code must retain the above copyright# notice, this list of conditions and the following disclaimer.# 2. Redistributions in binary form must reproduce the above copyright# notice, this list of conditions and the following disclaimer in the# documentation and/or other materials provided with the distribution.## THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF# SUCH DAMAGE.#use integer;use Getopt::Std;use strict;sub err($);sub process_section_encodings($);sub process_section_cesdeps($);sub next_entry($$$);sub generate_cesbi_h($$);sub generate_encnames_h(@);sub generate_aliasesbi_c($);sub generate_encoding_aliases_c($);sub generate_cesdeps_h($);sub generate_ccsbi_h($);sub generate_cesbi_c($);sub generate_ccsnames_h($);# ==============================================================================## GLOBAL VARIABLES## ==============================================================================my $comment_automatic ="/* * This file was automatically generated mkdeps.pl script. Don't edit. */";my $macro_from_enc = '_ICONV_FROM_ENCODING_';my $macro_to_enc = '_ICONV_TO_ENCODING_';my $macro_from_ucs_ces = 'ICONV_FROM_UCS_CES_';my $macro_to_ucs_ces = 'ICONV_TO_UCS_CES_';my $macro_from_ucs_ccs = 'ICONV_FROM_UCS_CCS_';my $macro_to_ucs_ccs = 'ICONV_TO_UCS_CCS_';my $macro_enc_name = 'ICONV_ENCODING_';my $macro_ccs_name = 'ICONV_CCS_';my $var_from_ucs_handlers = '_iconv_from_ucs_ces_handlers_';my $var_to_ucs_handlers = '_iconv_to_ucs_ces_handlers_';my $var_ccs = '_iconv_ccs_';my $var_aliases = '_iconv_aliases';my $var_ces_names = 'iconv_ces_names_';# ==============================================================================## PARSE COMMAND-LINE OPTIONS.## ==============================================================================my %options;# SUPPORTED OPTIONS.my $help_opt = 'h';my $infile_opt = 'i';my $verbose_opt = 'v';# Default input configuration file namemy $default_infile = '../lib/encoding.deps';# Real input configuration file namemy $infile;# Verbose flag (be verbose if not zero)my $verbose;{getopts ("${help_opt}${verbose_opt}${infile_opt}:", \%options)or err "getopts() failed: $!.";if ($options{$help_opt}){ # Output help message and exit. print "Usage: $0 [-$infile_opt depfile] [-$help_opt]\n"; print "\t-$infile_opt - input file with configuration ($default_infile "; print "file will be used by default)\n"; print "\t-$help_opt - this help message\n"; exit 0;}# Input file name.$infile = $options{$infile_opt} ? $options{$infile_opt} : $default_infile;$verbose = $options{$verbose_opt} ? 1 : 0;print "Debug: -$verbose_opt option found.\n" if $verbose;# ==============================================================================## Find and fetch sections from input file## ==============================================================================# Opening input fileprint "Debug: open \"$infile\" input file.\n" if $verbose;open (INFILE, '<', $infile) or err "Can't open \"$infile\" file for reading.\n" . "System error message: $!.\n";# Configuration file markersmy $marker_section = 'SECTION';my $marker_section_end = 'SECTION END';# File sections. Hash values are references to arrays with section contentsmy %sections;# Extract sections from filefor (my $ln = 1; my $l = <INFILE>; $ln += 1){ # Skip comments and empty lines next if $l =~ m/^#.*$/ or $l =~ m/^\s*$/; # Remove last CR symbol $l =~ s/^(.*)\n$/$1/, $l =~ s/^(.*)\r$/$1/; # Generate error if line isn't section begin marker err "(input file line $ln) Unexpected marker: \"$l\". ${marker_section} " . "is expected." if $l !~ m/^$marker_section(\s+(\S*)\s*)?$/; # Generate error if there is no section name err "(input file line $ln) Section name isn't found" if !$1 or !$2; # Generate error if this is section end marker err "(input file line $ln) Unexpected \"${marker_section_end}\" marker " . "in input file." if $2 eq $marker_section_end; my $sect_name = $2; # Extract section content for (; $l = <INFILE>; $ln += 1) { # Skip comments and empty lines next if $l =~ m/^#.*$/ or $l =~ m/^$/; # Remove last CR symbol $l =~ s/^(.*)\n$/$1/, $l =~ s/^(.*)\r$/$1/; last if $l =~ m/^$marker_section_end$/; push @{$sections{$sect_name}}, $l; } # Generate error if section wasn't ended err "(input file line $ln) \"No $marker_section_end\" marker found" if $l !~ m/^$marker_section_end$/;}close INFILE or err "Error while closing input file.";# =============================================================================## Now sections are fetched. Each section is processed by separate function.# There are only three supported sections now: ENCODINGS, CES_DEPENDENCIES# and ENCODING_CCS_DEPENDENCIES.## =============================================================================my $section_encodings = 'ENCODINGS';my $section_cesdeps = 'CES_DEPENDENCIES';my $section;err "$section_encodings not found."if !defined $sections{$section_encodings};err "$section_cesdeps not found."if !defined $sections{$section_cesdeps};# Process sectionsprint "Debug: process $section_encodings section.\n" if $verbose;process_section_encodings ($sections{$section_encodings});delete $sections{$section_encodings};print "Debug: process $section_cesdeps section.\n" if $verbose;process_section_cesdeps ($sections{$section_cesdeps});delete $sections{$section_cesdeps};print STDERR "Warning: section \"$_\" was ignored!\n"foreach (keys %sections);exit 1;}# =============================================================================## Print error message and exit.## Parameter 1: error message.## =============================================================================sub err($){ print STDERR "Error while running script.\n$_[0]\n"; exit 0;}# =============================================================================## Process ENCODINGS section.## Parameter 1 (input): array reference with section content;## =============================================================================sub process_section_encodings($){ my $sect = $_[0]; my $lineidx = 0; my @entry; my $marker_encoding = 'ENCODING'; my $marker_ces = 'CES'; my $marker_ccs = 'CCS'; my $marker_aliases = 'ALIASES'; # Keys: CES names. Values: array reference with encodings list. my %cesenc; # Keys: encodings. Values: CES converter names. my %encces; # Keys: CCS tables names. Values: array reference with encodings. my %ccsenc; # Keys: encodings. Values: aliases list. my %encalias; while (next_entry ($sect, \@entry, \$lineidx)) { my $encoding; my $ces; my $ccs; my $aliases; foreach my $l (@entry) { if ($l =~ m/^($marker_encoding):\s*(\S*)\s*$/) { err "(process_section_encodings()) More than one $marker_encoding " . "records found ($l)" if defined $encoding; $encoding = $2; } elsif ($l =~ m/^($marker_ces):\s*(\S*)\s*$/) { err "(process_section_encodings()) More than one $marker_ces " . "records found ($l)" if defined $ces; $ces = $2; } elsif ($l =~ m/^($marker_aliases):\s*(.*)\s*$/) { err "(process_section_encodings()) More than one " . "$marker_aliases records found ($l)" if defined $aliases; $aliases = $2; } elsif ($l =~ m/^($marker_ccs):\s*(.*)\s*$/) { err "(process_section_encodings()) More than one " . "$marker_ccs records found ($l)" if defined $ccs; $ccs = $2; } else { err "(process_section_encodings()) Can't parse \"$l\""; } } err "(process_section_encodings()) $encoding is defined twice" if (defined $encces{$encoding}); err "(process_section_encodings()) ENCODING: field isn't found" if not defined $encoding; if (defined $ces) { push @{$cesenc{$ces}}, $encoding; $encces{$encoding} = $ces; } if (defined $ccs) { my @ccs = split / /, $ccs; push @{$ccsenc{$_}}, $encoding foreach (@ccs); } $encalias{$encoding} = $aliases; } # Generate cesbi.h header file generate_cesbi_h (\%cesenc, \%encces); # Generate encnames.h header file generate_encnames_h (keys %encces); # Generate aliasesbi.c file generate_aliasesbi_c (\%encalias); # Generate encoding.aliases file generate_encoding_aliases (\%encalias); # Generate ccsbi.h header file generate_ccsbi_h (\%ccsenc); # Generate cesbi.c file generate_cesbi_c (\%cesenc); # Generate ccsbi.c file my @ccs = keys %ccsenc; generate_ccsbi_c (\@ccs); # Generate ccsnames.h header file generate_ccsnames_h (\%ccsenc);}# ==============================================================================## Process CES_DEPENDENCIES section.## Parameter 1: array reference with section content.## ==============================================================================sub process_section_cesdeps($){ my $sect = $_[0]; my $lineidx = 0; my @entry; my $marker_ces = 'CES'; my $marker_used_ces = 'USED_CES'; my %cesdeps; while (next_entry ($sect, \@entry, \$lineidx)) { my $ces; my $used_ces; foreach my $l (@entry) { if ($l =~ m/^($marker_ces):\s*(\S*)\s*$/) { err "(process_section_cesdeps()) More than one $marker_ces " . "records found ($l)" if $ces; $ces = $2; } elsif ($l =~ m/^($marker_used_ces):\s*(.*)\s*$/) { err "(process_section_cesdeps()) More than one $marker_used_ces " . "records found ($l)" if $used_ces; $used_ces = $2; } else { err "(process_section_cesdeps()) Can't parse \"$l\""; } } err "(process_section_esdeps()) $ces dependecties are defined twice" if (defined $cesdeps{$ces}); # Split string my @used_ces = split / /, $used_ces; $cesdeps{$ces} = \@used_ces; } # Generate cesdeps.h header file generate_cesdeps_h (\%cesdeps);}# ==============================================================================## Extract next entry.## Parameter 1 (input): array reference with entries;# Parameter 2 (output): array reference with entry content;# Parameter 3 (input/output): scalar reference with line index to process.## Returns 1 is entry was found, 0 if thee is no more entries;## ==============================================================================sub next_entry($$$){ my $entries = $_[0]; my $entry = $_[1]; my $idx = $_[2]; my $marker_entry = 'ENTRY'; my $marker_entry_end = 'ENTRY END'; my $entry_flag = 0; return 0 if not defined ${$entries}[${$idx}]; undef @{$entry}; for (; my $l = ${$entries}[${$idx}++];) { # Skip comments and empty lines next if $l =~ m/^#.*$/ or $l =~ m/^\s*$/; if ($l =~ m/^$marker_entry$/) { err "(next_entry()) $marker_entry marker appears twice" if ($entry_flag == 1); $entry_flag = 1; $l = ${$entries}[${$idx}++] } else { # Generate error if line isn't entry begin marker err "(next_entry()) Unexpected marker: \"$l\". ${marker_entry} " . "is expected." if ($entry_flag == 0) } last if $l =~ m/^$marker_entry_end$/; push @{$entry}, $l; } return 1;}# ==============================================================================## Generate cesbi.h file.## Parameter 1 (input): hash reference with keys = CES Converters names and# values = array references with list of supported encodings.# Parameter 2 (input): hash reference with keys = encodings names and# values = CES converter names.## ==============================================================================sub generate_cesbi_h($$){ my %cesenc = %{$_[0]}; my %encces = %{$_[1]}; my @ces = sort keys %cesenc; print "Debug: create \"cesbi.h\" file.\n" if $verbose; open (CESBI_H, '>', "cesbi.h")
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -