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 <newlib.h>\n";
476  print CESBI_H "#include <_ansi.h>\n";
477  print CESBI_H "#include \"../lib/encnames.h\"\n";
478  print CESBI_H "#include \"../lib/ucsconv.h\"\n\n";
479  print CESBI_H "/*\n";
480  print CESBI_H " * Enable CES converter if correspondent encoding is requested.\n";
481  print CESBI_H " * Defining ${macro_to_ucs_ces}XXX macro or ${macro_from_ucs_ces}XXX\n";
482  print CESBI_H " * macro is needed to enable \"XXX encoding -> UCS\" or \"UCS -> XXX encoding\"\n";
483  print CESBI_H " * part of UCS-based CES converter.\n";
484  print CESBI_H " */\n";
485
486  foreach my $ces (@ces)
487  {
488    my @encs = sort @{$cesenc{$ces}};
489    foreach my $encoding (@encs)
490    {
491      print CESBI_H $encoding eq $encs[0] ? "#if " : " || ";
492      print CESBI_H "defined ($macro_from_enc\U$encoding)";
493      print CESBI_H " \\" if $encoding ne $encs[$#encs];
494      print CESBI_H "\n";
495    }
496    print CESBI_H "#  define $macro_to_ucs_ces\U$ces\n";
497    print CESBI_H "#endif\n";
498
499    foreach my $encoding (@encs)
500    {
501      print CESBI_H $encoding eq $encs[0] ? "#if " : " || ";
502      print CESBI_H "defined ($macro_to_enc\U$encoding)";
503      print CESBI_H " \\" if $encoding ne $encs[$#encs];
504      print CESBI_H "\n";
505    }
506    print CESBI_H "#  define $macro_from_ucs_ces\U$ces\n";
507    print CESBI_H "#endif\n\n";
508  }
509
510  print CESBI_H "/*\n";
511  print CESBI_H " * Some encodings require another encodings to be enabled.\n";
512  print CESBI_H " * These dependencies are handled in cesdeps.h header file.\n";
513  print CESBI_H " */\n";
514  print CESBI_H "#include \"cesdeps.h\"\n\n";
515
516  print CESBI_H "/*\n";
517  print CESBI_H " * NLS uses iconv's capabilities and require one of encodings\n";
518  print CESBI_H " * to be enabled for internal wchar_t representation.\n";
519  print CESBI_H " */\n";
520  print CESBI_H "#include \"../lib/iconvnls.h\"\n\n";
521
522  print CESBI_H "/*\n";
523  print CESBI_H " * Forward declarations of CES converter handlers.\n";
524  print CESBI_H " * These handlers are actually defined in correspondent CES converter files.\n";
525  print CESBI_H " */\n";
526
527  foreach my $ces (@ces)
528  {
529    print CESBI_H "#ifdef $macro_to_ucs_ces\U$ces\n";
530    print CESBI_H "extern const iconv_to_ucs_ces_handlers_t\n";
531    print CESBI_H "$var_to_ucs_handlers$ces;\n";
532    print CESBI_H "#endif\n";
533
534    print CESBI_H "#ifdef $macro_from_ucs_ces\U$ces\n";
535    print CESBI_H "extern const iconv_from_ucs_ces_handlers_t\n";
536    print CESBI_H "$var_from_ucs_handlers$ces;\n";
537    print CESBI_H "#endif\n\n";
538  }
539
540  print CESBI_H "#endif /* !__CESBI_H__ */\n\n";
541  close CESBI_H or err "Error while closing cesbi.h file.";
542}
543
544# ==============================================================================
545#
546# Generate encnames.h header file.
547#
548# Parameters: array of supported encodings.
549#
550# ==============================================================================
551sub generate_encnames_h(@)
552{
553  print "Debug: create \"../lib/encnames.h\" file.\n" if $verbose;
554  open (ENCNAMES_H, '>', "../lib/encnames.h")
555  or err "Can't create \"../lib/encnames.h\" file for writing.\nSystem error message: $!.\n";
556
557  print ENCNAMES_H "$comment_automatic\n\n";
558  print ENCNAMES_H "#ifndef __ENCNAMES_H__\n";
559  print ENCNAMES_H "#define __ENCNAMES_H__\n\n";
560
561  print ENCNAMES_H "/*\n";
562  print ENCNAMES_H " * Encodings name macros.\n";
563  print ENCNAMES_H " */\n";
564
565  foreach my $enc (sort @_)
566  {
567    print ENCNAMES_H "#define $macro_enc_name\U$enc\E \"$enc\"\n";
568  }
569
570  print ENCNAMES_H "\n#endif /* !__ENCNAMES_H__ */\n\n";
571  close ENCNAMES_H or err "Error while closing ../lib/encnames.h file.";
572}
573
574# ==============================================================================
575#
576# Generate aliasesbi.c C source file.
577#
578# Parameters: hash reference with keys = encodings and values = aliases string.
579#
580# ==============================================================================
581sub generate_aliasesbi_c($)
582{
583  print "Debug: create \"../lib/aliasesbi.c\" file.\n" if $verbose;
584  open (ALIASESBI_C, '>', "../lib/aliasesbi.c")
585  or err "Can't create \"../lib/aliasesbi.c\" file for writing.\nSystem error message: $!.\n";
586
587  print ALIASESBI_C "$comment_automatic\n\n";
588  print ALIASESBI_C "#include <_ansi.h>\n";
589  print ALIASESBI_C "#include \"encnames.h\"\n\n";
590  print ALIASESBI_C "const char\n";
591  print ALIASESBI_C "$var_aliases\[\] =\n";
592  print ALIASESBI_C "{\n";
593
594  foreach my $enc (sort keys %{$_[0]})
595  {
596    print ALIASESBI_C "#if defined ($macro_from_enc\U$enc) \\\n";
597    print ALIASESBI_C " || defined ($macro_to_enc\U$enc)\n";
598    print ALIASESBI_C "  $macro_enc_name\U$enc\E";
599    print ALIASESBI_C " \" ${$_[0]}{$enc}\\n\"" if defined ${$_[0]}{$enc};
600    print ALIASESBI_C "\n";
601    print ALIASESBI_C "#endif\n";
602  }
603  print ALIASESBI_C "  \"\"\n";
604  print ALIASESBI_C "};\n";
605
606  close ALIASESBI_C or err "Error while closing ../lib/aliasesbi.c file.";
607}
608
609# ==============================================================================
610#
611# Generate encoding.aliases file.
612#
613# Parameter 1: hash reference with keys = encodings and values = aliases string.
614#
615# ==============================================================================
616sub generate_encoding_aliases($)
617{
618  print "Debug: create \"../encoding.aliases\" file.\n" if $verbose;
619  open (ALIASES, '>', "../encoding.aliases")
620  or err "Can't create \"../encoding.aliases\" file for writing.\nSystem error message: $!.\n";
621
622  print ALIASES "#\n# This file was automatically generated. Don't edit.\n#\n\n";
623
624  foreach my $enc (sort keys %{$_[0]})
625  {
626    print ALIASES "$enc";
627    print ALIASES " ${$_[0]}{$enc}" if defined ${$_[0]}{$enc};
628    print ALIASES "\n";
629  }
630
631  print ALIASES "\n";
632
633  close ALIASES or err "Error while closing ./encoding.aliases file.";
634}
635
636# ==============================================================================
637#
638# Generate cesdeps.h header file.
639#
640# Parameter 1: hash reference with keys = CES converters and values = references
641# to arrays with list of CES converters which are needed by that CES converter
642# (defined by key).
643#
644# ==============================================================================
645sub generate_cesdeps_h($)
646{
647  my %cesdeps = %{$_[0]};
648
649  print "Debug: create \"cesdeps.h\" file.\n" if $verbose;
650  open (CESDEPS_H, '>', "cesdeps.h")
651  or err "Can't create \"cesdeps.h\" file for writing.\nSystem error message: $!.\n";
652
653  print CESDEPS_H "$comment_automatic\n\n";
654  print CESDEPS_H "#ifndef __CESDEPS_H__\n";
655  print CESDEPS_H "#define __CESDEPS_H__\n\n";
656
657  print CESDEPS_H "/*\n";
658  print CESDEPS_H " * Some CES converters use another CES converters and the following\n";
659  print CESDEPS_H " * is such dependencies description.\n";
660  print CESDEPS_H " */\n";
661
662  foreach my $ces (sort keys %cesdeps)
663  {
664    my @deps = sort @{$cesdeps{$ces}};
665
666    print CESDEPS_H "#ifdef $macro_to_ucs_ces\U$ces\n";
667
668    foreach my $dep (@deps)
669    {
670      print CESDEPS_H "#  ifndef $macro_to_ucs_ces\U$dep\n";
671      print CESDEPS_H "#    define $macro_to_ucs_ces\U$dep\n";
672      print CESDEPS_H "#  endif\n";
673    }
674    print CESDEPS_H "#endif\n";
675
676    print CESDEPS_H "#ifdef $macro_from_ucs_ces\U$ces\n";
677    foreach my $dep (@deps)
678    {
679      print CESDEPS_H "#  ifndef $macro_from_ucs_ces\U$dep\n";
680      print CESDEPS_H "#    define $macro_from_ucs_ces\U$dep\n";
681      print CESDEPS_H "#  endif\n";
682    }
683    print CESDEPS_H "#endif\n";
684  }
685
686  print CESDEPS_H "\n#endif /* !__CESDEPS_H__ */\n\n";
687  close CESDEPS_H or err "Error while closing cesdeps.h file.";
688}
689
690# ==============================================================================
691#
692# Generate ccsbi.h file.
693#
694# Parameter 1 (input): hash reference with keys = CCS tables names and
695# values = array references with list of encodings which need this CCS table.
696#
697# ==============================================================================
698sub generate_ccsbi_h($)
699{
700  my %ccsenc = %{$_[0]};
701  my @ccs = sort keys %ccsenc;
702
703  print "Debug: create \"../ccs/ccsbi.h\" file.\n" if $verbose;
704  open (CCSBI_H, '>', "../ccs/ccsbi.h")
705  or err "Can't create \"../ccs/ccsbi.h\" file for writing.\nSystem error message: $!.\n";
706
707  print CCSBI_H "$comment_automatic\n\n";
708  print CCSBI_H "#ifndef __CCSBI_H__\n";
709  print CCSBI_H "#define __CCSBI_H__\n\n";
710  print CCSBI_H "#include <newlib.h>\n";
711  print CCSBI_H "#include <_ansi.h>\n";
712  print CCSBI_H "#include \"ccs.h\"\n\n";
713  print CCSBI_H "/*\n";
714  print CCSBI_H " * Enable CCS tables if encoding needs them.\n";
715  print CCSBI_H " * Defining ${macro_to_ucs_ccs}XXX macro or ${macro_from_ucs_ccs}XXX\n";
716  print CCSBI_H " * macro is needed to enable \"XXX encoding -> UCS\" or \"UCS -> XXX encoding\"\n";
717  print CCSBI_H " * part of CCS table.\n";
718  print CCSBI_H " * CCS tables aren't linked if Newlib was configuted to use external CCS tables.\n";
719  print CCSBI_H " */\n";
720
721  print CCSBI_H "#ifndef _ICONV_ENABLE_EXTERNAL_CCS\n\n";
722
723  foreach my $ccs (@ccs)
724  {
725    my @encs = sort @{$ccsenc{$ccs}};
726    foreach my $encoding (@encs)
727    {
728      print CCSBI_H $encoding eq $encs[0] ? "#if " : " || ";
729      print CCSBI_H "defined ($macro_from_enc\U$encoding)";
730      print CCSBI_H " \\" if $encoding ne $encs[$#encs];
731      print CCSBI_H "\n";
732    }
733    print CCSBI_H "#  define $macro_to_ucs_ccs\U$ccs\n";
734    print CCSBI_H "#endif\n";
735
736    foreach my $encoding (@encs)
737    {
738      print CCSBI_H $encoding eq $encs[0] ? "#if " : " || ";
739      print CCSBI_H "defined ($macro_to_enc\U$encoding)";
740      print CCSBI_H " \\" if $encoding ne $encs[$#encs];
741      print CCSBI_H "\n";
742    }
743    print CCSBI_H "#  define $macro_from_ucs_ccs\U$ccs\n";
744    print CCSBI_H "#endif\n\n";
745  }
746
747  print CCSBI_H "/*\n";
748  print CCSBI_H " * CCS table description structures forward declarations.\n";
749  print CCSBI_H " */\n";
750
751  foreach my $ccs (@ccs)
752  {
753    print CCSBI_H "#if defined ($macro_to_ucs_ccs\U$ccs) \\\n";
754    print CCSBI_H " || defined ($macro_from_ucs_ccs\U$ccs)\n";
755    print CCSBI_H "extern const iconv_ccs_t\n";
756    print CCSBI_H "$var_ccs$ccs;\n";
757    print CCSBI_H "#endif\n";
758  }
759
760  print CCSBI_H "\n#endif /* !_ICONV_ENABLE_EXTERNAL_CCS */\n\n";
761  print CCSBI_H "\n#endif /* __CCSBI_H__ */\n\n";
762  close CCSBI_H or err "Error while closing ../ccs/ccsbi.h file.";
763}
764
765# ==============================================================================
766#
767# Generate cesbi.c file.
768#
769# Parameter 1 (input): hash reference with keys = CES Converters names and
770# values = array references with list of supported encodings.
771#
772# ==============================================================================
773sub generate_cesbi_c($)
774{
775  my %cesenc = %{$_[0]};
776  my @ces = sort keys %cesenc;
777
778  print "Debug: create \"cesbi.c\" file.\n" if $verbose;
779  open (CESBI_C, '>', "cesbi.c")
780  or err "Can't create \"cesbi.c\" file for writing.\nSystem error message: $!.\n";
781
782  print CESBI_C "$comment_automatic\n\n";
783  print CESBI_C "#include <_ansi.h>\n";
784  print CESBI_C "#include <newlib.h>\n";
785  print CESBI_C "#include \"../lib/ucsconv.h\"\n";
786  print CESBI_C "#include \"cesbi.h\"\n\n";
787  print CESBI_C "/*\n";
788  print CESBI_C " * Each CES converter provides the list of supported encodings.\n";
789  print CESBI_C " */\n";
790
791  foreach my $ces (@ces)
792  {
793    print CESBI_C "#if defined ($macro_to_ucs_ces\U$ces) \\\n";
794    print CESBI_C " || defined ($macro_from_ucs_ces\U$ces)\n";
795    print CESBI_C "static const char *\n";
796    print CESBI_C "$var_ces_names${ces}\[] =\n";
797    print CESBI_C "{\n";
798    my @encodings = sort @{$cesenc{$ces}};
799    foreach my $encoding (@encodings)
800    {
801      print CESBI_C "# if defined ($macro_from_enc\U$encoding) \\\n";
802      print CESBI_C "  || defined ($macro_to_enc\U$encoding)\n";
803      print CESBI_C "  $macro_enc_name\U$encoding,\n";
804      print CESBI_C "#endif\n";
805    }
806    print CESBI_C "  NULL\n";
807    print CESBI_C "};\n";
808    print CESBI_C "#endif\n\n";
809  }
810
811  print CESBI_C "/*\n";
812  print CESBI_C " * The following structure contains the list of \"to UCS\" linked-in CES converters.\n";
813  print CESBI_C " */\n";
814  print CESBI_C "const iconv_to_ucs_ces_t\n";
815  print CESBI_C "_iconv_to_ucs_ces[] =\n";
816  print CESBI_C "{\n";
817
818  foreach my $ces (@ces)
819  {
820    print CESBI_C "#ifdef $macro_to_ucs_ces\U$ces\n";
821    print CESBI_C "  {(const char **)$var_ces_names$ces,\n";
822    print CESBI_C "   &$var_to_ucs_handlers$ces},\n";
823    print CESBI_C "#endif\n";
824  }
825  print CESBI_C "  {(const char **)NULL,\n";
826  print CESBI_C "  (iconv_to_ucs_ces_handlers_t *)NULL}\n";
827  print CESBI_C "};\n\n";
828
829  print CESBI_C "/*\n";
830  print CESBI_C " * The following structure contains the list of \"from UCS\" linked-in CES converters.\n";
831  print CESBI_C " */\n";
832  print CESBI_C "const iconv_from_ucs_ces_t\n";
833  print CESBI_C "_iconv_from_ucs_ces[] =\n";
834  print CESBI_C "{\n";
835
836  foreach my $ces (@ces)
837  {
838    print CESBI_C "#ifdef $macro_from_ucs_ces\U$ces\n";
839    print CESBI_C "  {(const char **)$var_ces_names$ces,\n";
840    print CESBI_C "   &$var_from_ucs_handlers$ces},\n";
841    print CESBI_C "#endif\n";
842  }
843  print CESBI_C "  {(const char **)NULL,\n";
844  print CESBI_C "  (iconv_from_ucs_ces_handlers_t *)NULL}\n";
845  print CESBI_C "};\n";
846
847  close CESBI_C or err "Error while closing cesbi.c file.";
848}
849
850# ==============================================================================
851#
852# Generate ccsbi.c file.
853#
854# Parameter 1 (input): array reference with CCS tables names
855#
856# ==============================================================================
857sub generate_ccsbi_c($)
858{
859  my @ccs = @{$_[0]};
860
861  print "Debug: create \"../ccs/ccsbi.c\" file.\n" if $verbose;
862  open (CESBI_C, '>', "../ccs/ccsbi.c")
863  or err "Can't create \"../ccs/ccsbi.c\" file for writing.\nSystem error message: $!.\n";
864
865  print CESBI_C "$comment_automatic\n\n";
866  print CESBI_C "#include <_ansi.h>\n";
867  print CESBI_C "#include \"ccsbi.h\"\n\n";
868  print CESBI_C "/*\n";
869  print CESBI_C " * The following array contains the list of built-in CCS tables.\n";
870  print CESBI_C " */\n";
871
872  print CESBI_C "const iconv_ccs_t *\n";
873  print CESBI_C "_iconv_ccs[] =\n";
874  print CESBI_C "{\n";
875
876  foreach my $ccs (@ccs)
877  {
878    print CESBI_C "#if defined ($macro_to_ucs_ccs\U$ccs) \\\n";
879    print CESBI_C " || defined ($macro_from_ucs_ccs\U$ccs)\n";
880    print CESBI_C "  &$var_ccs$ccs,\n";
881    print CESBI_C "#endif\n";
882  }
883  print CESBI_C "  NULL\n";
884  print CESBI_C "};\n";
885
886  close CESBI_C or err "Error while closing ../ccs/ccsbi.c file.";
887}
888
889# ==============================================================================
890#
891# Generate ccsnames.h file.
892#
893# Parameter 1 (input): hash reference with keys = CCS tables names and
894# values = array references with list of encodings which need this CCS table.
895#
896# ==============================================================================
897sub generate_ccsnames_h($)
898{
899  my %ccsenc = %{$_[0]};
900  my @ccs = sort keys %ccsenc;
901
902  print "Debug: create \"../ccs/ccsnames.h\" file.\n" if $verbose;
903  open (CCSNAMES_H, '>', "../ccs/ccsnames.h")
904  or err "Can't create \"../ccs/ccsnames.h\" file for writing.\nSystem error message: $!.\n";
905
906  print CCSNAMES_H "$comment_automatic\n\n";
907  print CCSNAMES_H "#ifndef __CCSNAMES_H__\n";
908  print CCSNAMES_H "#define __CCSNAMES_H__\n\n";
909  print CCSNAMES_H "#include \"../lib/encnames.h\"\n\n";
910  print CCSNAMES_H "/*\n";
911  print CCSNAMES_H " * CCS tables names macros.\n";
912  print CCSNAMES_H " */\n";
913
914  foreach my $ccs (@ccs)
915  {
916    my @encs = @{$ccsenc{$ccs}};
917    my $flag;
918    foreach my $encoding (@encs)
919    {
920      print CCSNAMES_H "#define $macro_ccs_name\U$ccs ";
921      if ($encoding eq $ccs)
922      {
923        $flag = 1;
924        print CCSNAMES_H "$macro_enc_name\U$encoding\n";
925        last;
926      }
927    }
928    print CCSNAMES_H "\"$ccs\"\n" if !$flag;
929  }
930
931  print CCSNAMES_H "\n#endif /* !__CCSNAMES_H__ */\n\n";
932  close CCSNAMES_H or err "Error while closing ../ccs/ccsnames.h file.";
933}
934
935# ==============================================================================
936#
937# Generate iconv.m4 file.
938#
939# Parameter 1 (input): array reference with encoding names
940#
941# ==============================================================================
942sub generate_iconv_m4($)
943{
944  my @encodings = @{$_[0]};
945
946  print "Debug: create \"../../../iconv.m4\" file.\n" if $verbose;
947  open (ICONV_M4, '>', "../../../iconv.m4")
948  or err "Can't create \"../../../iconv.m4\" file for writing.\nSystem error message: $!.\n";
949
950  print ICONV_M4 "$comment_automatic\n";
951  print ICONV_M4 "AC_DEFUN([NEWLIB_ICONV_DEFINES],[dnl\n";
952  foreach my $encoding (@encodings)
953  {
954    my $ucencoding = uc $encoding;
955
956    my $tovar = "_ICONV_TO_ENCODING_$ucencoding";
957    print ICONV_M4 "  if test \"\$$tovar\" = 1; then\n";
958    print ICONV_M4 "    AC_DEFINE($tovar, 1, [Support $encoding output encoding.])\n";
959    print ICONV_M4 "  fi\n";
960
961    my $fromvar = "_ICONV_FROM_ENCODING_$ucencoding";
962    print ICONV_M4 "  if test \"\$$fromvar\" = 1; then\n";
963    print ICONV_M4 "    AC_DEFINE($fromvar, 1, [Support $encoding input encoding.])\n";
964    print ICONV_M4 "  fi\n";
965  }
966  print ICONV_M4 "])\n";
967
968  close ICONV_M4 or err "Error while closing ../../../iconv.m4 file.";
969}
970