1#!/usr/bin/perl -w
2#
3#  Copyright (c) 2003-2004, Artem B. Bityuckiy, SoftMine Corporation.
4#
5#  Redistribution and use in source and binary forms, with or without
6#  modification, are permitted provided that the following conditions
7#  are met:
8#  1. Redistributions of source code must retain the above copyright
9#     notice, this list of conditions and the following disclaimer.
10#  2. Redistributions in binary form must reproduce the above copyright
11#     notice, this list of conditions and the following disclaimer in the
12#     documentation and/or other materials provided with the distribution.
13#
14#  THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15#  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17#  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18#  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19#  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20#  OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21#  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22#  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23#  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24#  SUCH DAMAGE.
25#
26use integer;
27use Getopt::Std;
28use strict;
29
30sub err($);
31sub process_section_encodings($);
32sub process_section_cesdeps($);
33sub next_entry($$$);
34
35sub generate_cesbi_h($$);
36sub generate_encnames_h(@);
37sub generate_aliasesbi_c($);
38sub generate_encoding_aliases_c($);
39sub generate_cesdeps_h($);
40sub generate_ccsbi_h($);
41sub generate_cesbi_c($);
42sub generate_ccsnames_h($);
43
44# ==============================================================================
45#
46# GLOBAL VARIABLES
47#
48# ==============================================================================
49
50my $comment_automatic =
51"/*
52 * This file was automatically generated mkdeps.pl script. Don't edit.
53 */";
54
55my $macro_from_enc     = '_ICONV_FROM_ENCODING_';
56my $macro_to_enc       = '_ICONV_TO_ENCODING_';
57my $macro_from_ucs_ces = 'ICONV_FROM_UCS_CES_';
58my $macro_to_ucs_ces   = 'ICONV_TO_UCS_CES_';
59my $macro_from_ucs_ccs = 'ICONV_FROM_UCS_CCS_';
60my $macro_to_ucs_ccs   = 'ICONV_TO_UCS_CCS_';
61my $macro_enc_name     = 'ICONV_ENCODING_';
62my $macro_ccs_name     = 'ICONV_CCS_';
63
64my $var_from_ucs_handlers = '_iconv_from_ucs_ces_handlers_';
65my $var_to_ucs_handlers   = '_iconv_to_ucs_ces_handlers_';
66my $var_ccs       = '_iconv_ccs_';
67my $var_aliases   = '_iconv_aliases';
68my $var_ces_names = 'iconv_ces_names_';
69
70# ==============================================================================
71#
72# PARSE COMMAND-LINE OPTIONS.
73#
74# ==============================================================================
75
76my %options;
77
78# SUPPORTED OPTIONS.
79my $help_opt    = 'h';
80my $infile_opt  = 'i';
81my $verbose_opt = 'v';
82
83# Default input configuration file name
84my $default_infile = '../lib/encoding.deps';
85# Real input configuration file name
86my $infile;
87# Verbose flag (be verbose if not zero)
88my $verbose;
89
90{
91getopts ("${help_opt}${verbose_opt}${infile_opt}:", \%options)
92or err "getopts() failed: $!.";
93
94if ($options{$help_opt})
95{
96  # Output help message and exit.
97  print "Usage: $0 [-$infile_opt depfile] [-$help_opt]\n";
98  print "\t-$infile_opt - input file with configuration ($default_infile ";
99  print "file will be used by default)\n";
100  print "\t-$help_opt - this help message\n";
101  exit 0;
102}
103
104# Input file name.
105$infile = $options{$infile_opt} ? $options{$infile_opt} : $default_infile;
106$verbose = $options{$verbose_opt} ? 1 : 0;
107
108print "Debug: -$verbose_opt option found.\n" if $verbose;
109
110# ==============================================================================
111#
112# Find and fetch sections from input file
113#
114# ==============================================================================
115
116# Opening input file
117print "Debug: open \"$infile\" input file.\n" if $verbose;
118open (INFILE, '<', $infile) or err "Can't open \"$infile\" file for reading.\n"
119                                 . "System error message: $!.\n";
120
121# Configuration file markers
122my $marker_section = 'SECTION';
123my $marker_section_end = 'SECTION END';
124
125# File sections. Hash values are references to arrays with section contents
126my %sections;
127
128# Extract sections from file
129for (my $ln = 1; my $l = <INFILE>; $ln += 1)
130{
131  # Skip comments and empty lines
132  next if $l =~ m/^#.*$/ or $l =~ m/^\s*$/;
133
134  # Remove last CR symbol
135  $l =~ s/^(.*)\n$/$1/, $l =~ s/^(.*)\r$/$1/;
136
137  # Generate error if line isn't section begin marker
138  err "(input file line $ln) Unexpected marker: \"$l\". ${marker_section} "
139    . "is expected."
140  if $l !~ m/^$marker_section(\s+(\S*)\s*)?$/;
141
142  # Generate error if there is no section name
143  err "(input file line $ln) Section name isn't found"
144  if !$1 or !$2;
145
146  # Generate error if this is section end marker
147  err "(input file line $ln) Unexpected \"${marker_section_end}\" marker "
148    . "in input file."
149  if $2 eq $marker_section_end;
150
151  my $sect_name = $2;
152
153  # Extract section content
154  for (; $l = <INFILE>; $ln += 1)
155  {
156    # Skip comments and empty lines
157    next if $l =~ m/^#.*$/ or $l =~ m/^$/;
158    # Remove last CR symbol
159    $l =~ s/^(.*)\n$/$1/, $l =~ s/^(.*)\r$/$1/;
160
161    last if $l =~ m/^$marker_section_end$/;
162
163    push @{$sections{$sect_name}}, $l;
164  }
165
166  # Generate error if section wasn't ended
167  err "(input file line $ln) \"No $marker_section_end\" marker found"
168  if $l !~ m/^$marker_section_end$/;
169}
170
171close INFILE or err "Error while closing input file.";
172
173# =============================================================================
174#
175# Now sections are fetched. Each section is processed by separate function.
176# There are only three supported sections now: ENCODINGS, CES_DEPENDENCIES
177# and ENCODING_CCS_DEPENDENCIES.
178#
179# =============================================================================
180
181my $section_encodings = 'ENCODINGS';
182my $section_cesdeps   = 'CES_DEPENDENCIES';
183
184my $section;
185
186err "$section_encodings not found."
187if !defined $sections{$section_encodings};
188err "$section_cesdeps not found."
189if !defined $sections{$section_cesdeps};
190
191# Process sections
192print "Debug: process $section_encodings section.\n" if $verbose;
193process_section_encodings ($sections{$section_encodings});
194delete $sections{$section_encodings};
195
196print "Debug: process $section_cesdeps section.\n" if $verbose;
197process_section_cesdeps ($sections{$section_cesdeps});
198delete $sections{$section_cesdeps};
199
200print STDERR "Warning: section \"$_\" was ignored!\n"
201foreach (keys %sections);
202
203exit 0;
204}
205
206# =============================================================================
207#
208# Print error message and exit.
209#
210# Parameter 1: error message.
211#
212# =============================================================================
213sub err($)
214{
215  print STDERR "Error while running script.\n$_[0]\n";
216  exit 1;
217}
218
219
220# =============================================================================
221#
222# Process ENCODINGS section.
223#
224# Parameter 1 (input):  array reference with section content;
225#
226# =============================================================================
227sub process_section_encodings($)
228{
229  my $sect = $_[0];
230  my $lineidx = 0;
231  my @entry;
232  my $marker_encoding = 'ENCODING';
233  my $marker_ces      = 'CES';
234  my $marker_ccs      = 'CCS';
235  my $marker_aliases  = 'ALIASES';
236
237  # Keys: CES names. Values: array reference with encodings list.
238  my %cesenc;
239  # Keys: encodings. Values: CES converter names.
240  my %encces;
241  # Keys: CCS tables names. Values: array reference with encodings.
242  my %ccsenc;
243  # Keys: encodings. Values: aliases list.
244  my %encalias;
245
246  while (next_entry ($sect, \@entry, \$lineidx))
247  {
248    my $encoding;
249    my $ces;
250    my $ccs;
251    my $aliases;
252
253    foreach my $l (@entry)
254    {
255      if ($l =~ m/^($marker_encoding):\s*(\S*)\s*$/)
256      {
257        err "(process_section_encodings()) More than one $marker_encoding "
258          . "records found ($l)"
259        if defined $encoding;
260
261        $encoding = $2;
262      }
263      elsif ($l =~ m/^($marker_ces):\s*(\S*)\s*$/)
264      {
265        err "(process_section_encodings()) More than one $marker_ces "
266          . "records found ($l)"
267        if defined $ces;
268
269        $ces = $2;
270      }
271      elsif ($l =~ m/^($marker_aliases):\s*(.*)\s*$/)
272      {
273        err "(process_section_encodings()) More than one "
274          . "$marker_aliases records found ($l)"
275        if defined $aliases;
276
277        $aliases = $2;
278      }
279      elsif ($l =~ m/^($marker_ccs):\s*(.*)\s*$/)
280      {
281        err "(process_section_encodings()) More than one "
282          . "$marker_ccs records found ($l)"
283        if defined $ccs;
284
285        $ccs = $2;
286      }
287      else
288      {
289        err "(process_section_encodings()) Can't parse \"$l\"";
290      }
291    }
292
293    err "(process_section_encodings()) $encoding is defined twice"
294    if (defined $encces{$encoding});
295    err "(process_section_encodings()) ENCODING: field isn't found"
296    if not defined $encoding;
297
298    if (defined $ces)
299    {
300      push @{$cesenc{$ces}}, $encoding;
301      $encces{$encoding} = $ces;
302    }
303
304    if (defined $ccs)
305    {
306      my @ccs = split / /, $ccs;
307      push @{$ccsenc{$_}}, $encoding foreach (@ccs);
308    }
309    $encalias{$encoding} = $aliases;
310  }
311
312  # Generate cesbi.h header file
313  generate_cesbi_h (\%cesenc, \%encces);
314
315  # Generate encnames.h header file
316  generate_encnames_h (keys %encces);
317
318  # Generate aliasesbi.c file
319  generate_aliasesbi_c (\%encalias);
320
321  # Generate encoding.aliases file
322  generate_encoding_aliases (\%encalias);
323
324  # Generate ccsbi.h header file
325  generate_ccsbi_h (\%ccsenc);
326
327  # Generate cesbi.c file
328  generate_cesbi_c (\%cesenc);
329
330  # Generate ccsbi.c file
331  my @ccs = sort keys %ccsenc;
332  generate_ccsbi_c (\@ccs);
333
334  # Generate ccsnames.h header file
335  generate_ccsnames_h (\%ccsenc);
336
337  # Generate iconv.m4 file
338  my @encodings = sort keys %encalias;
339  generate_iconv_m4 (\@encodings);
340}
341
342# ==============================================================================
343#
344# Process CES_DEPENDENCIES section.
345#
346# Parameter 1: array reference with section content.
347#
348# ==============================================================================
349sub process_section_cesdeps($)
350{
351  my $sect = $_[0];
352  my $lineidx = 0;
353  my @entry;
354  my $marker_ces      = 'CES';
355  my $marker_used_ces = 'USED_CES';
356  my %cesdeps;
357
358  while (next_entry ($sect, \@entry, \$lineidx))
359  {
360    my $ces;
361    my $used_ces;
362
363    foreach my $l (@entry)
364    {
365      if ($l =~ m/^($marker_ces):\s*(\S*)\s*$/)
366      {
367        err "(process_section_cesdeps()) More than one $marker_ces "
368          . "records found ($l)"
369        if $ces;
370
371        $ces = $2;
372      }
373      elsif ($l =~ m/^($marker_used_ces):\s*(.*)\s*$/)
374      {
375        err "(process_section_cesdeps()) More than one $marker_used_ces "
376          . "records found ($l)"
377        if $used_ces;
378
379        $used_ces = $2;
380      }
381      else
382      {
383        err "(process_section_cesdeps()) Can't parse \"$l\"";
384      }
385    }
386
387    err "(process_section_esdeps()) $ces dependecties are defined twice"
388    if (defined $cesdeps{$ces});
389
390    # Split string
391    my @used_ces = split / /, $used_ces;
392
393    $cesdeps{$ces} = \@used_ces;
394  }
395
396  # Generate cesdeps.h header file
397  generate_cesdeps_h (\%cesdeps);
398}
399
400# ==============================================================================
401#
402# Extract next entry.
403#
404# Parameter 1 (input): array reference with entries;
405# Parameter 2 (output): array reference with entry content;
406# Parameter 3 (input/output): scalar reference with line index to process.
407#
408# Returns 1 is entry was found, 0 if thee is no more entries;
409#
410# ==============================================================================
411sub next_entry($$$)
412{
413  my $entries = $_[0];
414  my $entry   = $_[1];
415  my $idx     = $_[2];
416  my $marker_entry = 'ENTRY';
417  my $marker_entry_end = 'ENTRY END';
418  my $entry_flag = 0;
419
420  return 0 if not defined ${$entries}[${$idx}];
421
422  undef @{$entry};
423
424  for (; my $l = ${$entries}[${$idx}++];)
425  {
426    # Skip comments and empty lines
427    next if $l =~ m/^#.*$/ or $l =~ m/^\s*$/;
428
429    if ($l =~ m/^$marker_entry$/)
430    {
431      err "(next_entry()) $marker_entry marker appears twice"
432      if ($entry_flag == 1);
433      $entry_flag = 1;
434      $l = ${$entries}[${$idx}++]
435    }
436    else
437    {
438      # Generate error if line isn't entry begin marker
439      err "(next_entry()) Unexpected marker: \"$l\". ${marker_entry} "
440        . "is expected."
441      if ($entry_flag == 0)
442    }
443
444    last if $l =~ m/^$marker_entry_end$/;
445
446    push @{$entry}, $l;
447  }
448
449  return 1;
450}
451
452# ==============================================================================
453#
454# Generate cesbi.h file.
455#
456# Parameter 1 (input): hash reference with keys = CES Converters names and
457# values = array references with list of supported encodings.
458# Parameter 2 (input): hash reference with keys = encodings names and
459# values = CES converter names.
460#
461# ==============================================================================
462sub generate_cesbi_h($$)
463{
464  my %cesenc = %{$_[0]};
465  my %encces = %{$_[1]};
466  my @ces = sort keys %cesenc;
467
468  print "Debug: create \"cesbi.h\" file.\n" if $verbose;
469  open (CESBI_H, '>', "cesbi.h")
470  or err "Can't create \"cesbi.h\" file for writing.\nSystem error message: $!.\n";
471
472  print CESBI_H "$comment_automatic\n\n";
473  print CESBI_H "#ifndef __CESBI_H__\n";
474  print CESBI_H "#define __CESBI_H__\n\n";
475  print CESBI_H "#include \"../lib/encnames.h\"\n";
476  print CESBI_H "#include \"../lib/ucsconv.h\"\n\n";
477  print CESBI_H "/*\n";
478  print CESBI_H " * Enable CES converter if correspondent encoding is requested.\n";
479  print CESBI_H " * Defining ${macro_to_ucs_ces}XXX macro or ${macro_from_ucs_ces}XXX\n";
480  print CESBI_H " * macro is needed to enable \"XXX encoding -> UCS\" or \"UCS -> XXX encoding\"\n";
481  print CESBI_H " * part of UCS-based CES converter.\n";
482  print CESBI_H " */\n";
483
484  foreach my $ces (@ces)
485  {
486    my @encs = sort @{$cesenc{$ces}};
487    foreach my $encoding (@encs)
488    {
489      print CESBI_H $encoding eq $encs[0] ? "#if " : " || ";
490      print CESBI_H "defined ($macro_from_enc\U$encoding)";
491      print CESBI_H " \\" if $encoding ne $encs[$#encs];
492      print CESBI_H "\n";
493    }
494    print CESBI_H "#  define $macro_to_ucs_ces\U$ces\n";
495    print CESBI_H "#endif\n";
496
497    foreach my $encoding (@encs)
498    {
499      print CESBI_H $encoding eq $encs[0] ? "#if " : " || ";
500      print CESBI_H "defined ($macro_to_enc\U$encoding)";
501      print CESBI_H " \\" if $encoding ne $encs[$#encs];
502      print CESBI_H "\n";
503    }
504    print CESBI_H "#  define $macro_from_ucs_ces\U$ces\n";
505    print CESBI_H "#endif\n\n";
506  }
507
508  print CESBI_H "/*\n";
509  print CESBI_H " * Some encodings require another encodings to be enabled.\n";
510  print CESBI_H " * These dependencies are handled in cesdeps.h header file.\n";
511  print CESBI_H " */\n";
512  print CESBI_H "#include \"cesdeps.h\"\n\n";
513
514  print CESBI_H "/*\n";
515  print CESBI_H " * NLS uses iconv's capabilities and require one of encodings\n";
516  print CESBI_H " * to be enabled for internal wchar_t representation.\n";
517  print CESBI_H " */\n";
518  print CESBI_H "#include \"../lib/iconvnls.h\"\n\n";
519
520  print CESBI_H "/*\n";
521  print CESBI_H " * Forward declarations of CES converter handlers.\n";
522  print CESBI_H " * These handlers are actually defined in correspondent CES converter files.\n";
523  print CESBI_H " */\n";
524
525  foreach my $ces (@ces)
526  {
527    print CESBI_H "#ifdef $macro_to_ucs_ces\U$ces\n";
528    print CESBI_H "extern const iconv_to_ucs_ces_handlers_t\n";
529    print CESBI_H "$var_to_ucs_handlers$ces;\n";
530    print CESBI_H "#endif\n";
531
532    print CESBI_H "#ifdef $macro_from_ucs_ces\U$ces\n";
533    print CESBI_H "extern const iconv_from_ucs_ces_handlers_t\n";
534    print CESBI_H "$var_from_ucs_handlers$ces;\n";
535    print CESBI_H "#endif\n\n";
536  }
537
538  print CESBI_H "#endif /* !__CESBI_H__ */\n\n";
539  close CESBI_H or err "Error while closing cesbi.h file.";
540}
541
542# ==============================================================================
543#
544# Generate encnames.h header file.
545#
546# Parameters: array of supported encodings.
547#
548# ==============================================================================
549sub generate_encnames_h(@)
550{
551  print "Debug: create \"../lib/encnames.h\" file.\n" if $verbose;
552  open (ENCNAMES_H, '>', "../lib/encnames.h")
553  or err "Can't create \"../lib/encnames.h\" file for writing.\nSystem error message: $!.\n";
554
555  print ENCNAMES_H "$comment_automatic\n\n";
556  print ENCNAMES_H "#ifndef __ENCNAMES_H__\n";
557  print ENCNAMES_H "#define __ENCNAMES_H__\n\n";
558
559  print ENCNAMES_H "/*\n";
560  print ENCNAMES_H " * Encodings name macros.\n";
561  print ENCNAMES_H " */\n";
562
563  foreach my $enc (sort @_)
564  {
565    print ENCNAMES_H "#define $macro_enc_name\U$enc\E \"$enc\"\n";
566  }
567
568  print ENCNAMES_H "\n#endif /* !__ENCNAMES_H__ */\n\n";
569  close ENCNAMES_H or err "Error while closing ../lib/encnames.h file.";
570}
571
572# ==============================================================================
573#
574# Generate aliasesbi.c C source file.
575#
576# Parameters: hash reference with keys = encodings and values = aliases string.
577#
578# ==============================================================================
579sub generate_aliasesbi_c($)
580{
581  print "Debug: create \"../lib/aliasesbi.c\" file.\n" if $verbose;
582  open (ALIASESBI_C, '>', "../lib/aliasesbi.c")
583  or err "Can't create \"../lib/aliasesbi.c\" file for writing.\nSystem error message: $!.\n";
584
585  print ALIASESBI_C "$comment_automatic\n\n";
586  print ALIASESBI_C "#include \"encnames.h\"\n\n";
587  print ALIASESBI_C "const char\n";
588  print ALIASESBI_C "$var_aliases\[\] =\n";
589  print ALIASESBI_C "{\n";
590
591  foreach my $enc (sort keys %{$_[0]})
592  {
593    print ALIASESBI_C "#if defined ($macro_from_enc\U$enc) \\\n";
594    print ALIASESBI_C " || defined ($macro_to_enc\U$enc)\n";
595    print ALIASESBI_C "  $macro_enc_name\U$enc\E";
596    print ALIASESBI_C " \" ${$_[0]}{$enc}\\n\"" if defined ${$_[0]}{$enc};
597    print ALIASESBI_C "\n";
598    print ALIASESBI_C "#endif\n";
599  }
600  print ALIASESBI_C "  \"\"\n";
601  print ALIASESBI_C "};\n";
602
603  close ALIASESBI_C or err "Error while closing ../lib/aliasesbi.c file.";
604}
605
606# ==============================================================================
607#
608# Generate encoding.aliases file.
609#
610# Parameter 1: hash reference with keys = encodings and values = aliases string.
611#
612# ==============================================================================
613sub generate_encoding_aliases($)
614{
615  print "Debug: create \"../encoding.aliases\" file.\n" if $verbose;
616  open (ALIASES, '>', "../encoding.aliases")
617  or err "Can't create \"../encoding.aliases\" file for writing.\nSystem error message: $!.\n";
618
619  print ALIASES "#\n# This file was automatically generated. Don't edit.\n#\n\n";
620
621  foreach my $enc (sort keys %{$_[0]})
622  {
623    print ALIASES "$enc";
624    print ALIASES " ${$_[0]}{$enc}" if defined ${$_[0]}{$enc};
625    print ALIASES "\n";
626  }
627
628  print ALIASES "\n";
629
630  close ALIASES or err "Error while closing ./encoding.aliases file.";
631}
632
633# ==============================================================================
634#
635# Generate cesdeps.h header file.
636#
637# Parameter 1: hash reference with keys = CES converters and values = references
638# to arrays with list of CES converters which are needed by that CES converter
639# (defined by key).
640#
641# ==============================================================================
642sub generate_cesdeps_h($)
643{
644  my %cesdeps = %{$_[0]};
645
646  print "Debug: create \"cesdeps.h\" file.\n" if $verbose;
647  open (CESDEPS_H, '>', "cesdeps.h")
648  or err "Can't create \"cesdeps.h\" file for writing.\nSystem error message: $!.\n";
649
650  print CESDEPS_H "$comment_automatic\n\n";
651  print CESDEPS_H "#ifndef __CESDEPS_H__\n";
652  print CESDEPS_H "#define __CESDEPS_H__\n\n";
653
654  print CESDEPS_H "/*\n";
655  print CESDEPS_H " * Some CES converters use another CES converters and the following\n";
656  print CESDEPS_H " * is such dependencies description.\n";
657  print CESDEPS_H " */\n";
658
659  foreach my $ces (sort keys %cesdeps)
660  {
661    my @deps = sort @{$cesdeps{$ces}};
662
663    print CESDEPS_H "#ifdef $macro_to_ucs_ces\U$ces\n";
664
665    foreach my $dep (@deps)
666    {
667      print CESDEPS_H "#  ifndef $macro_to_ucs_ces\U$dep\n";
668      print CESDEPS_H "#    define $macro_to_ucs_ces\U$dep\n";
669      print CESDEPS_H "#  endif\n";
670    }
671    print CESDEPS_H "#endif\n";
672
673    print CESDEPS_H "#ifdef $macro_from_ucs_ces\U$ces\n";
674    foreach my $dep (@deps)
675    {
676      print CESDEPS_H "#  ifndef $macro_from_ucs_ces\U$dep\n";
677      print CESDEPS_H "#    define $macro_from_ucs_ces\U$dep\n";
678      print CESDEPS_H "#  endif\n";
679    }
680    print CESDEPS_H "#endif\n";
681  }
682
683  print CESDEPS_H "\n#endif /* !__CESDEPS_H__ */\n\n";
684  close CESDEPS_H or err "Error while closing cesdeps.h file.";
685}
686
687# ==============================================================================
688#
689# Generate ccsbi.h file.
690#
691# Parameter 1 (input): hash reference with keys = CCS tables names and
692# values = array references with list of encodings which need this CCS table.
693#
694# ==============================================================================
695sub generate_ccsbi_h($)
696{
697  my %ccsenc = %{$_[0]};
698  my @ccs = sort keys %ccsenc;
699
700  print "Debug: create \"../ccs/ccsbi.h\" file.\n" if $verbose;
701  open (CCSBI_H, '>', "../ccs/ccsbi.h")
702  or err "Can't create \"../ccs/ccsbi.h\" file for writing.\nSystem error message: $!.\n";
703
704  print CCSBI_H "$comment_automatic\n\n";
705  print CCSBI_H "#ifndef __CCSBI_H__\n";
706  print CCSBI_H "#define __CCSBI_H__\n\n";
707  print CCSBI_H "#include \"ccs.h\"\n\n";
708  print CCSBI_H "/*\n";
709  print CCSBI_H " * Enable CCS tables if encoding needs them.\n";
710  print CCSBI_H " * Defining ${macro_to_ucs_ccs}XXX macro or ${macro_from_ucs_ccs}XXX\n";
711  print CCSBI_H " * macro is needed to enable \"XXX encoding -> UCS\" or \"UCS -> XXX encoding\"\n";
712  print CCSBI_H " * part of CCS table.\n";
713  print CCSBI_H " * CCS tables aren't linked if Newlib was configuted to use external CCS tables.\n";
714  print CCSBI_H " */\n";
715
716  print CCSBI_H "#ifndef _ICONV_ENABLE_EXTERNAL_CCS\n\n";
717
718  foreach my $ccs (@ccs)
719  {
720    my @encs = sort @{$ccsenc{$ccs}};
721    foreach my $encoding (@encs)
722    {
723      print CCSBI_H $encoding eq $encs[0] ? "#if " : " || ";
724      print CCSBI_H "defined ($macro_from_enc\U$encoding)";
725      print CCSBI_H " \\" if $encoding ne $encs[$#encs];
726      print CCSBI_H "\n";
727    }
728    print CCSBI_H "#  define $macro_to_ucs_ccs\U$ccs\n";
729    print CCSBI_H "#endif\n";
730
731    foreach my $encoding (@encs)
732    {
733      print CCSBI_H $encoding eq $encs[0] ? "#if " : " || ";
734      print CCSBI_H "defined ($macro_to_enc\U$encoding)";
735      print CCSBI_H " \\" if $encoding ne $encs[$#encs];
736      print CCSBI_H "\n";
737    }
738    print CCSBI_H "#  define $macro_from_ucs_ccs\U$ccs\n";
739    print CCSBI_H "#endif\n\n";
740  }
741
742  print CCSBI_H "/*\n";
743  print CCSBI_H " * CCS table description structures forward declarations.\n";
744  print CCSBI_H " */\n";
745
746  foreach my $ccs (@ccs)
747  {
748    print CCSBI_H "#if defined ($macro_to_ucs_ccs\U$ccs) \\\n";
749    print CCSBI_H " || defined ($macro_from_ucs_ccs\U$ccs)\n";
750    print CCSBI_H "extern const iconv_ccs_t\n";
751    print CCSBI_H "$var_ccs$ccs;\n";
752    print CCSBI_H "#endif\n";
753  }
754
755  print CCSBI_H "\n#endif /* !_ICONV_ENABLE_EXTERNAL_CCS */\n\n";
756  print CCSBI_H "\n#endif /* __CCSBI_H__ */\n\n";
757  close CCSBI_H or err "Error while closing ../ccs/ccsbi.h file.";
758}
759
760# ==============================================================================
761#
762# Generate cesbi.c file.
763#
764# Parameter 1 (input): hash reference with keys = CES Converters names and
765# values = array references with list of supported encodings.
766#
767# ==============================================================================
768sub generate_cesbi_c($)
769{
770  my %cesenc = %{$_[0]};
771  my @ces = sort keys %cesenc;
772
773  print "Debug: create \"cesbi.c\" file.\n" if $verbose;
774  open (CESBI_C, '>', "cesbi.c")
775  or err "Can't create \"cesbi.c\" file for writing.\nSystem error message: $!.\n";
776
777  print CESBI_C "$comment_automatic\n\n";
778  print CESBI_C "#include \"../lib/ucsconv.h\"\n";
779  print CESBI_C "#include \"cesbi.h\"\n\n";
780  print CESBI_C "/*\n";
781  print CESBI_C " * Each CES converter provides the list of supported encodings.\n";
782  print CESBI_C " */\n";
783
784  foreach my $ces (@ces)
785  {
786    print CESBI_C "#if defined ($macro_to_ucs_ces\U$ces) \\\n";
787    print CESBI_C " || defined ($macro_from_ucs_ces\U$ces)\n";
788    print CESBI_C "static const char *\n";
789    print CESBI_C "$var_ces_names${ces}\[] =\n";
790    print CESBI_C "{\n";
791    my @encodings = sort @{$cesenc{$ces}};
792    foreach my $encoding (@encodings)
793    {
794      print CESBI_C "# if defined ($macro_from_enc\U$encoding) \\\n";
795      print CESBI_C "  || defined ($macro_to_enc\U$encoding)\n";
796      print CESBI_C "  $macro_enc_name\U$encoding,\n";
797      print CESBI_C "#endif\n";
798    }
799    print CESBI_C "  NULL\n";
800    print CESBI_C "};\n";
801    print CESBI_C "#endif\n\n";
802  }
803
804  print CESBI_C "/*\n";
805  print CESBI_C " * The following structure contains the list of \"to UCS\" linked-in CES converters.\n";
806  print CESBI_C " */\n";
807  print CESBI_C "const iconv_to_ucs_ces_t\n";
808  print CESBI_C "_iconv_to_ucs_ces[] =\n";
809  print CESBI_C "{\n";
810
811  foreach my $ces (@ces)
812  {
813    print CESBI_C "#ifdef $macro_to_ucs_ces\U$ces\n";
814    print CESBI_C "  {(const char **)$var_ces_names$ces,\n";
815    print CESBI_C "   &$var_to_ucs_handlers$ces},\n";
816    print CESBI_C "#endif\n";
817  }
818  print CESBI_C "  {(const char **)NULL,\n";
819  print CESBI_C "  (iconv_to_ucs_ces_handlers_t *)NULL}\n";
820  print CESBI_C "};\n\n";
821
822  print CESBI_C "/*\n";
823  print CESBI_C " * The following structure contains the list of \"from UCS\" linked-in CES converters.\n";
824  print CESBI_C " */\n";
825  print CESBI_C "const iconv_from_ucs_ces_t\n";
826  print CESBI_C "_iconv_from_ucs_ces[] =\n";
827  print CESBI_C "{\n";
828
829  foreach my $ces (@ces)
830  {
831    print CESBI_C "#ifdef $macro_from_ucs_ces\U$ces\n";
832    print CESBI_C "  {(const char **)$var_ces_names$ces,\n";
833    print CESBI_C "   &$var_from_ucs_handlers$ces},\n";
834    print CESBI_C "#endif\n";
835  }
836  print CESBI_C "  {(const char **)NULL,\n";
837  print CESBI_C "  (iconv_from_ucs_ces_handlers_t *)NULL}\n";
838  print CESBI_C "};\n";
839
840  close CESBI_C or err "Error while closing cesbi.c file.";
841}
842
843# ==============================================================================
844#
845# Generate ccsbi.c file.
846#
847# Parameter 1 (input): array reference with CCS tables names
848#
849# ==============================================================================
850sub generate_ccsbi_c($)
851{
852  my @ccs = @{$_[0]};
853
854  print "Debug: create \"../ccs/ccsbi.c\" file.\n" if $verbose;
855  open (CESBI_C, '>', "../ccs/ccsbi.c")
856  or err "Can't create \"../ccs/ccsbi.c\" file for writing.\nSystem error message: $!.\n";
857
858  print CESBI_C "$comment_automatic\n\n";
859  print CESBI_C "#include \"ccsbi.h\"\n\n";
860  print CESBI_C "/*\n";
861  print CESBI_C " * The following array contains the list of built-in CCS tables.\n";
862  print CESBI_C " */\n";
863
864  print CESBI_C "const iconv_ccs_t *\n";
865  print CESBI_C "_iconv_ccs[] =\n";
866  print CESBI_C "{\n";
867
868  foreach my $ccs (@ccs)
869  {
870    print CESBI_C "#if defined ($macro_to_ucs_ccs\U$ccs) \\\n";
871    print CESBI_C " || defined ($macro_from_ucs_ccs\U$ccs)\n";
872    print CESBI_C "  &$var_ccs$ccs,\n";
873    print CESBI_C "#endif\n";
874  }
875  print CESBI_C "  NULL\n";
876  print CESBI_C "};\n";
877
878  close CESBI_C or err "Error while closing ../ccs/ccsbi.c file.";
879}
880
881# ==============================================================================
882#
883# Generate ccsnames.h file.
884#
885# Parameter 1 (input): hash reference with keys = CCS tables names and
886# values = array references with list of encodings which need this CCS table.
887#
888# ==============================================================================
889sub generate_ccsnames_h($)
890{
891  my %ccsenc = %{$_[0]};
892  my @ccs = sort keys %ccsenc;
893
894  print "Debug: create \"../ccs/ccsnames.h\" file.\n" if $verbose;
895  open (CCSNAMES_H, '>', "../ccs/ccsnames.h")
896  or err "Can't create \"../ccs/ccsnames.h\" file for writing.\nSystem error message: $!.\n";
897
898  print CCSNAMES_H "$comment_automatic\n\n";
899  print CCSNAMES_H "#ifndef __CCSNAMES_H__\n";
900  print CCSNAMES_H "#define __CCSNAMES_H__\n\n";
901  print CCSNAMES_H "#include \"../lib/encnames.h\"\n\n";
902  print CCSNAMES_H "/*\n";
903  print CCSNAMES_H " * CCS tables names macros.\n";
904  print CCSNAMES_H " */\n";
905
906  foreach my $ccs (@ccs)
907  {
908    my @encs = @{$ccsenc{$ccs}};
909    my $flag;
910    foreach my $encoding (@encs)
911    {
912      print CCSNAMES_H "#define $macro_ccs_name\U$ccs ";
913      if ($encoding eq $ccs)
914      {
915        $flag = 1;
916        print CCSNAMES_H "$macro_enc_name\U$encoding\n";
917        last;
918      }
919    }
920    print CCSNAMES_H "\"$ccs\"\n" if !$flag;
921  }
922
923  print CCSNAMES_H "\n#endif /* !__CCSNAMES_H__ */\n\n";
924  close CCSNAMES_H or err "Error while closing ../ccs/ccsnames.h file.";
925}
926
927# ==============================================================================
928#
929# Generate iconv.m4 file.
930#
931# Parameter 1 (input): array reference with encoding names
932#
933# ==============================================================================
934sub generate_iconv_m4($)
935{
936  my @encodings = @{$_[0]};
937
938  print "Debug: create \"../../../iconv.m4\" file.\n" if $verbose;
939  open (ICONV_M4, '>', "../../../iconv.m4")
940  or err "Can't create \"../../../iconv.m4\" file for writing.\nSystem error message: $!.\n";
941
942  print ICONV_M4 "$comment_automatic\n";
943  print ICONV_M4 "AC_DEFUN([NEWLIB_ICONV_DEFINES],[dnl\n";
944  foreach my $encoding (@encodings)
945  {
946    my $ucencoding = uc $encoding;
947
948    my $tovar = "_ICONV_TO_ENCODING_$ucencoding";
949    print ICONV_M4 "  if test \"\$$tovar\" = 1; then\n";
950    print ICONV_M4 "    AC_DEFINE($tovar, 1, [Support $encoding output encoding.])\n";
951    print ICONV_M4 "  fi\n";
952
953    my $fromvar = "_ICONV_FROM_ENCODING_$ucencoding";
954    print ICONV_M4 "  if test \"\$$fromvar\" = 1; then\n";
955    print ICONV_M4 "    AC_DEFINE($fromvar, 1, [Support $encoding input encoding.])\n";
956    print ICONV_M4 "  fi\n";
957  }
958  print ICONV_M4 "])\n";
959
960  close ICONV_M4 or err "Error while closing ../../../iconv.m4 file.";
961}
962