xref: /Universal-ctags/misc/optlib2c (revision af10eb0b814559bac24ecb5abaaaffd981226601)
128a3d08fSMasatake YAMATO#!/usr/bin/env perl
2ec2a6441SMasatake YAMATO#
3ec2a6441SMasatake YAMATO# optlib2c - a tool translating ctags option file to C
4ec2a6441SMasatake YAMATO#
528a3d08fSMasatake YAMATO# Copyright (C) 2016 Masatake YAMATO
628a3d08fSMasatake YAMATO# Copyright (C) 2016 Red Hat Inc.
7ec2a6441SMasatake YAMATO#
8ec2a6441SMasatake YAMATO# This program is free software; you can redistribute it and/or modify
9ec2a6441SMasatake YAMATO# it under the terms of the GNU General Public License as published by
10ec2a6441SMasatake YAMATO# the Free Software Foundation; either version 2 of the License, or
11ec2a6441SMasatake YAMATO# (at your option) any later version.
12ec2a6441SMasatake YAMATO#
13ec2a6441SMasatake YAMATO# This program is distributed in the hope that it will be useful,
14ec2a6441SMasatake YAMATO# but WITHOUT ANY WARRANTY; without even the implied warranty of
15ec2a6441SMasatake YAMATO# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16ec2a6441SMasatake YAMATO# GNU General Public License for more details.
17ec2a6441SMasatake YAMATO#
18ec2a6441SMasatake YAMATO# You should have received a copy of the GNU General Public License
19ec2a6441SMasatake YAMATO# along with this program.  If not, see <http://www.gnu.org/licenses/>.
20ec2a6441SMasatake YAMATO#
21ec2a6441SMasatake YAMATO
2228a3d08fSMasatake YAMATOuse strict;
2328a3d08fSMasatake YAMATOuse warnings;
2489c588f7SMasatake YAMATO#use Data::Dumper;
2589c588f7SMasatake YAMATO#print Dumper(X);
26ec2a6441SMasatake YAMATO
2728a3d08fSMasatake YAMATOsub show_help {
2828a3d08fSMasatake YAMATO    print<<EOF;
2928a3d08fSMasatake YAMATOUsage:
3028a3d08fSMasatake YAMATO	$0 --help
313e7e9e07SMasatake YAMATO	$0 FILE.ctags > FILE.c
3228a3d08fSMasatake YAMATOEOF
33ec2a6441SMasatake YAMATO}
34ec2a6441SMasatake YAMATO
3528a3d08fSMasatake YAMATO
3628a3d08fSMasatake YAMATO########################################################################
3728a3d08fSMasatake YAMATO#
3828a3d08fSMasatake YAMATO# PARSE
3928a3d08fSMasatake YAMATO#
4028a3d08fSMasatake YAMATO########################################################################
4128a3d08fSMasatake YAMATOmy $options =
4228a3d08fSMasatake YAMATO    [
4328a3d08fSMasatake YAMATO     [ qr/^--options=(.*)/, sub {
4428a3d08fSMasatake YAMATO	   parse_optlib ($1, $_[0]);
452d9e0a35SMasatake YAMATO	   return 1;
4628a3d08fSMasatake YAMATO       } ],
47c48fee31SMasatake YAMATO     [ qr/^--__selector-(.*)=(.*)/, sub {
48c48fee31SMasatake YAMATO	 die "Don't use --__selector-<LANG>= option before defining the language"
49c48fee31SMasatake YAMATO	     if (! defined $_[0]->{'langdef'});
50c48fee31SMasatake YAMATO	 $_[0]->{'selector'} = $2;
51c48fee31SMasatake YAMATO	 return 1;
52c48fee31SMasatake YAMATO       } ],
53951dba0fSMasatake YAMATO     #
5442b74d5dSMasatake YAMATO     # TODO: We should not assume the order of flags.
55951dba0fSMasatake YAMATO     #
56951dba0fSMasatake YAMATO     [ qr/^--langdef=([^\{]+)(((\{base=([^\{]+)\})(\{(dedicated|shared|bidirectional)\})?)?)(\{_autoFQTag\})?/, sub {
5754fa68c3SMasatake YAMATO	   die "LANG is already defined as $_[0]->{'langdef'}: $1"
5828a3d08fSMasatake YAMATO	       if (defined $_[0]->{'langdef'});
592baef0d3SMasatake YAMATO	   die "Don't use \"all\" as a language name. It is reserved word."
602baef0d3SMasatake YAMATO	       if ($1 eq "all");
610278c2a1SMasatake YAMATO
6228a3d08fSMasatake YAMATO	   $_[0]->{'langdef'} = $1;
633edff4edSMasatake YAMATO	   $_[0]->{'base'} = $5 if defined $5;
643edff4edSMasatake YAMATO	   $_[0]->{'direction'} = $7 if defined $7;
65951dba0fSMasatake YAMATO	   $_[0]->{'autoFQTag'} = (defined $8)? 1: 0;
660278c2a1SMasatake YAMATO
6702bfae7fSMasatake YAMATO	   die "Don't use a character as a language name other than alphanumeric, # and +: "
6802bfae7fSMasatake YAMATO	       . $_[0]->{'langdef'} unless ($_[0]->{'langdef'} =~ /^[a-zA-Z0-9#+]+$/);
6902bfae7fSMasatake YAMATO	   return 1;
7028a3d08fSMasatake YAMATO       } ],
7137e580eeSMasatake YAMATO     [ qr/^--kinddef-(.*)=([^,]),([^,]+),([^\{]+)(\{_refonly\})?/, sub {
721de3f27aSMasatake YAMATO	 die "Don't use --kinddef-<LANG>=+ option before defining the language"
7354fa68c3SMasatake YAMATO	     if (! defined $_[0]->{'langdef'});
7454fa68c3SMasatake YAMATO	 die "Adding a kind is allowed only to the language specified with --langdef: $1"
7554fa68c3SMasatake YAMATO	     unless ($_[0]->{'langdef'} eq $1);
764493f78fSMasatake YAMATO
774493f78fSMasatake YAMATO	 my $letter = $2;
784493f78fSMasatake YAMATO	 my $name = $3;
794493f78fSMasatake YAMATO	 my $desc = $4;
8073fd0d8fSMasatake YAMATO	 my $refonly = 0;
8173fd0d8fSMasatake YAMATO	 $refonly = 1 if defined $5;
824493f78fSMasatake YAMATO
834493f78fSMasatake YAMATO	 die "'F' as a kind letter is reserved for file kind."
844493f78fSMasatake YAMATO	     if ($letter eq 'F');
854493f78fSMasatake YAMATO	 die "unacceptable character is used for kind letter: $letter"
864493f78fSMasatake YAMATO	     unless ($letter =~ /^[a-zA-EG-Z]$/);
874493f78fSMasatake YAMATO
884493f78fSMasatake YAMATO	 die "'file' as a kind name is reserved"
894493f78fSMasatake YAMATO	     if ($name eq 'file');
904493f78fSMasatake YAMATO	 die "The initial letter of kind name must be alphabetic character: $name"
914493f78fSMasatake YAMATO	     unless (substr ($name, 0, 1) =~ /[a-zA-Z]/);
924493f78fSMasatake YAMATO	 die "Letters used in kind name other than initial letter must be alphanumeric characters: $name"
934493f78fSMasatake YAMATO	     unless (substr ($name, 1) =~ /^[a-zA-Z0-9]+$/);
944493f78fSMasatake YAMATO
954493f78fSMasatake YAMATO	 push @{$_[0]->{'kinddefs'}}, { enabled => 1, letter => $letter, name => $name, desc => $desc,
96d14b4a65SMasatake YAMATO					refonly => $refonly, roles => [], seps => [] };
972d9e0a35SMasatake YAMATO	 return 1;
9854fa68c3SMasatake YAMATO       } ],
99443cf30eSMasatake YAMATO     [ qr/^--_extradef-(.*)=([^,]+),([^\{]+)/, sub {
1002d422213SMasatake YAMATO	 die "Don't use --_extradef-<LANG>=+ option before defining the language"
1012b6707b2SMasatake YAMATO	     if (! defined $_[0]->{'langdef'});
1022b6707b2SMasatake YAMATO	 die "Adding an extra is allowed only to the language specified with --langdef: $1"
1032b6707b2SMasatake YAMATO	     unless ($_[0]->{'langdef'} eq $1);
104084188cbSMasatake YAMATO
105084188cbSMasatake YAMATO	 my $name = $2;
106084188cbSMasatake YAMATO	 my $desc = $3;
107084188cbSMasatake YAMATO
108084188cbSMasatake YAMATO	 die "unacceptable character is used for extra name: $name"
109084188cbSMasatake YAMATO	     unless ($name =~ /^[a-zA-Z0-9]+$/);
110084188cbSMasatake YAMATO
111084188cbSMasatake YAMATO	 push @{$_[0]->{'extradefs'}}, { name => $name, desc => $desc };
1122d9e0a35SMasatake YAMATO	 return 1;
1132b6707b2SMasatake YAMATO       } ],
114443cf30eSMasatake YAMATO     [ qr/^--_fielddef-(.*)=([^,]+),([^\{]+)/, sub {
1157c42e9eeSMasatake YAMATO	 die "Don't use --_fielddef-<LANG>=+ option before defining the language"
1167c42e9eeSMasatake YAMATO	     if (! defined $_[0]->{'langdef'});
1177c42e9eeSMasatake YAMATO	 die "Adding a field is allowed only to the language specified with --langdef: $1"
1187c42e9eeSMasatake YAMATO	     unless ($_[0]->{'langdef'} eq $1);
1198d58bcb6SMasatake YAMATO
1208d58bcb6SMasatake YAMATO	 my $name = $2;
1218d58bcb6SMasatake YAMATO	 my $desc = $3;
1228d58bcb6SMasatake YAMATO	 die "unacceptable character is used for field name: $name"
1238d58bcb6SMasatake YAMATO	     unless ($name =~ /^[a-zA-Z]+$/);
1248d58bcb6SMasatake YAMATO
1258d58bcb6SMasatake YAMATO	 push @{$_[0]->{'fielddefs'}}, { name => $name, desc => $desc };
1262d9e0a35SMasatake YAMATO	 return 1;
1277c42e9eeSMasatake YAMATO       } ],
12897d2a121SMasatake YAMATO     [ qr/^--_roledef-([^.]*)\.(?:([a-zA-Z])|\{([a-zA-Z][a-zA-Z0-9]*)\})=([a-zA-Z0-9]+),([^\{]+)/, sub {
12997d2a121SMasatake YAMATO	   die "Don't use --_roledef-<LANG>.<KNID>=+ option before defining the language"
130dff7c6b0SMasatake YAMATO	     if (! defined $_[0]->{'langdef'});
131dff7c6b0SMasatake YAMATO	   die "Adding a field is allowed only to the language specified with --langdef: $1"
132dff7c6b0SMasatake YAMATO	     unless ($_[0]->{'langdef'} eq $1);
133dff7c6b0SMasatake YAMATO
134dff7c6b0SMasatake YAMATO	   my $kind_found = 0;
135dff7c6b0SMasatake YAMATO	   for (@{$_[0]->{'kinddefs'}}) {
13697d2a121SMasatake YAMATO	       if ((defined $2 && $_->{'letter'} eq $2)
13797d2a121SMasatake YAMATO		   || (defined $3 && $_->{'name'} eq $3)) {
13897d2a121SMasatake YAMATO		   my $role = { name => $4, desc => $5, owner => $_ };
139dff7c6b0SMasatake YAMATO		   push @{$_->{'roles'}}, $role;
140dff7c6b0SMasatake YAMATO		   $kind_found = 1;
141dff7c6b0SMasatake YAMATO		   last;
142dff7c6b0SMasatake YAMATO	       }
143dff7c6b0SMasatake YAMATO	   }
144dff7c6b0SMasatake YAMATO	   die "no such kind, \"$2\" where role \"$3\" is attached to" if (! $kind_found);
1452d9e0a35SMasatake YAMATO	   return 1;
146dff7c6b0SMasatake YAMATO       } ],
14728a3d08fSMasatake YAMATO     [ qr/^--languages=-(.*)/, sub {
1481de3f27aSMasatake YAMATO	   die "Don't use --languages=- option before defining the language"
14928a3d08fSMasatake YAMATO	       if (! defined $_[0]->{'langdef'});
15028a3d08fSMasatake YAMATO	   die "Only language specified with --langdef can be disabled: $1"
15128a3d08fSMasatake YAMATO	       unless ($_[0]->{'langdef'} eq $1);
1528372dc35SMasatake YAMATO	   $_[0]->{'disabled'} = 1;
1532d9e0a35SMasatake YAMATO	   return 1;
15428a3d08fSMasatake YAMATO       } ],
15528a3d08fSMasatake YAMATO     [ qr/^--language=(.*)/, sub {
15628a3d08fSMasatake YAMATO	   die "--languages can be used only for disabling a language defined with --langdef: $1";
15728a3d08fSMasatake YAMATO       } ],
15828a3d08fSMasatake YAMATO     [ qr/^--map-([^=]*)=\+(.*)/, sub {
1591de3f27aSMasatake YAMATO	   die "Don't use --map-<LANG>=+ option before defining the language"
16028a3d08fSMasatake YAMATO	       if (! defined $_[0]->{'langdef'});
16128a3d08fSMasatake YAMATO	   die "Adding a map is allowed only to the language specified with --langdef: $1"
16228a3d08fSMasatake YAMATO	       unless ($_[0]->{'langdef'} eq $1);
16328a3d08fSMasatake YAMATO	   my $spec = $2;
16428a3d08fSMasatake YAMATO	   if ($spec =~ /\((.*)\)/) {
16528a3d08fSMasatake YAMATO	       push @{$_[0]->{'patterns'}}, $1;
16628a3d08fSMasatake YAMATO	   } elsif ($spec =~ /\.(.*)/) {
16728a3d08fSMasatake YAMATO	       push @{$_[0]->{'extensions'}}, $1;
16828a3d08fSMasatake YAMATO	   } else {
16928a3d08fSMasatake YAMATO	       die "Unexpected notation is used in the argument for --map-$1= option";
17028a3d08fSMasatake YAMATO	   }
1712d9e0a35SMasatake YAMATO	   return 1;
17228a3d08fSMasatake YAMATO       } ],
17328a3d08fSMasatake YAMATO     [ qr/^--map-([^=]*)=[^+].*/, sub {
17428a3d08fSMasatake YAMATO	   die "map manipulation other than the appending(--map-<LANG>=+...) is not supported";
17528a3d08fSMasatake YAMATO       } ],
17628a3d08fSMasatake YAMATO     [ qr /^--alias-([^=]*)=\+(.*)/, sub {
1771de3f27aSMasatake YAMATO	   die "Don't use --alias-<LANG>=+ option before defining the language"
17828a3d08fSMasatake YAMATO	       if (! defined $_[0]->{'langdef'});
17928a3d08fSMasatake YAMATO	   die "Adding an alias is allowed only to the language specified with --langdef: $1"
18028a3d08fSMasatake YAMATO	       unless ($_[0]->{'langdef'} eq $1);
18128a3d08fSMasatake YAMATO	   push @{$_[0]->{'aliases'}}, $2;
1822d9e0a35SMasatake YAMATO	   return 1;
18328a3d08fSMasatake YAMATO       } ],
18428a3d08fSMasatake YAMATO     [ qr/^--alias-([^=]*)=[^+].*/, sub {
18528a3d08fSMasatake YAMATO	   die "alias manipulation other than the appending(--alias-<LANG>=+...) is not supported";
18628a3d08fSMasatake YAMATO       } ],
18728a3d08fSMasatake YAMATO     [ qr/^--regex-([^=]*)=(.*)/, sub {
1881de3f27aSMasatake YAMATO	   die "Don't use --regex-<LANG>= option before defining the language"
18928a3d08fSMasatake YAMATO	       if (! defined $_[0]->{'langdef'});
19028a3d08fSMasatake YAMATO	   die "Adding a regex is allowed only to the language specified with --langdef: $1"
19128a3d08fSMasatake YAMATO	       unless ($_[0]->{'langdef'} eq $1);
1922d9e0a35SMasatake YAMATO	   return parse_regex ($2, $_[0], 0);
19328a3d08fSMasatake YAMATO       } ],
194641e337aSMasatake YAMATO     [ qr/^--mline-regex-([^=]*)=(.*)/, sub {
195641e337aSMasatake YAMATO	   die "Don't use --mline-regex-<LANG>= option before defining the language"
196641e337aSMasatake YAMATO	       if (! defined $_[0]->{'langdef'});
197641e337aSMasatake YAMATO	   die "Adding a multiline regex is allowed only to the language specified with --langdef: $1"
198641e337aSMasatake YAMATO	       unless ($_[0]->{'langdef'} eq $1);
1992d9e0a35SMasatake YAMATO	   return parse_regex ($2, $_[0], 1);
200641e337aSMasatake YAMATO       } ],
20128a3d08fSMasatake YAMATO     [ qr/^--kinds-([^=]*)=-(.*)/, sub {
2024e87c902SMasatake YAMATO	   die "Don't use --kinds-<LANG>= option before defining the language"
20328a3d08fSMasatake YAMATO	       if (! defined $_[0]->{'langdef'});
20428a3d08fSMasatake YAMATO	   parse_kinds ($2, $_[0]);
2052d9e0a35SMasatake YAMATO	   return 1;
20628a3d08fSMasatake YAMATO       } ],
20728a3d08fSMasatake YAMATO     [ qr/^--kinds-([^=]*)=(.*)/, sub {
20828a3d08fSMasatake YAMATO	   die "--kinds-<LANG>= can be used only for disabling a kind: $1";
20928a3d08fSMasatake YAMATO       } ],
2102b6707b2SMasatake YAMATO     [ qr/^--extras-([^=]*)=([-+])\{(.+)\}$/, sub {
2114e87c902SMasatake YAMATO	   die "Don't use --extras-<LANG>= option before defining the language"
2122b6707b2SMasatake YAMATO	       if (! defined $_[0]->{'langdef'});
2132b6707b2SMasatake YAMATO	   die "Enabling/disabling an extra is allowed only to the language specified with --langdef: $1"
2142b6707b2SMasatake YAMATO	       unless ($_[0]->{'langdef'} eq $1);
2152b6707b2SMasatake YAMATO	   die "Specifing multiple extras in one --extras-... is not handled: {$3}"
2162b6707b2SMasatake YAMATO	       if ( index ($3, '{') != -1 );
2172b6707b2SMasatake YAMATO	   parse_extras ($2, $3, $_[0]);
2182d9e0a35SMasatake YAMATO	   return 1;
2192b6707b2SMasatake YAMATO       } ],
2202b6707b2SMasatake YAMATO     [ qr/^--extras-([^=]*)=\{/, sub {
2212b6707b2SMasatake YAMATO	 die "--extras-<LANG>= can be used only for enabling or disabling an extra: $1";
2222b6707b2SMasatake YAMATO       } ],
2232b6707b2SMasatake YAMATO     [ qr/^--extras-([^=]*)=(.)\{/, sub {
2242b6707b2SMasatake YAMATO	 die "Unknown flag($2) is passed to --extras-<LANG>= option";
2252b6707b2SMasatake YAMATO       } ],
2267c42e9eeSMasatake YAMATO     [ qr/^--fields-([^=]*)=([-+])\{(.+)\}$/, sub {
2277c42e9eeSMasatake YAMATO	   die "Don't use --fields-<LANG>= option before defining the language"
2287c42e9eeSMasatake YAMATO	       if (! defined $_[0]->{'langdef'});
2297c42e9eeSMasatake YAMATO	   die "Enabling/disabling a field is allowed only to the language specified with --langdef: $1"
2307c42e9eeSMasatake YAMATO	       unless ($_[0]->{'langdef'} eq $1);
2317c42e9eeSMasatake YAMATO	   die "Specifing multiple fields in one --fields-... is not handled: {$3}"
2327c42e9eeSMasatake YAMATO	       if ( index ($3, '{') != -1 );
2337c42e9eeSMasatake YAMATO	   parse_fields ($2, $3, $_[0]);
2342d9e0a35SMasatake YAMATO	   return 1;
2357c42e9eeSMasatake YAMATO       } ],
2367c42e9eeSMasatake YAMATO     [ qr/^--fields-([^=]*)=\{/, sub {
2377c42e9eeSMasatake YAMATO	 die "--fields-<LANG>= can be used only for enabling or disabling a field: $1";
2387c42e9eeSMasatake YAMATO       } ],
2397c42e9eeSMasatake YAMATO     [ qr/^--fields-([^=]*)=(.)\{/, sub {
2407c42e9eeSMasatake YAMATO	 die "Unknown flag($2) is passed to --fields-<LANG>= option";
2417c42e9eeSMasatake YAMATO       } ],
24228a3d08fSMasatake YAMATO     [ qr/^--langmap=.*/, sub {
24328a3d08fSMasatake YAMATO	 die "Use --map-<LANG> option instead of --langmap";
24428a3d08fSMasatake YAMATO       } ],
24589c588f7SMasatake YAMATO     [ qr/^--_tabledef-([^=]*)=(.*)/, sub {
24689c588f7SMasatake YAMATO	 die "Don't use --_tabledef-<LANG>= option before defining the language"
24789c588f7SMasatake YAMATO	   if (! defined $_[0]->{'langdef'});
24889c588f7SMasatake YAMATO	 die "Adding a table is allowed only to the language specified with --langdef: $1"
24989c588f7SMasatake YAMATO	   unless ($_[0]->{'langdef'} eq $1);
25089c588f7SMasatake YAMATO	 $_[0]->{'tabledefs'}->{$2} = [];
25189c588f7SMasatake YAMATO	 push @{$_[0]->{'tablenames'}}, "$2";
2522d9e0a35SMasatake YAMATO	 return 1;
25389c588f7SMasatake YAMATO       } ],
25489c588f7SMasatake YAMATO     [ qr/^--_mtable-regex-([^=]*)=([^\/]+)(\/.*)/, sub {
25589c588f7SMasatake YAMATO	 die "Don't use --_mtable-regex-<LANG>= option before defining the language"
25689c588f7SMasatake YAMATO	   if (! defined $_[0]->{'langdef'});
25789c588f7SMasatake YAMATO	 die "Adding a multitable regex is allowed only to the language specified with --langdef: $1"
25889c588f7SMasatake YAMATO	   unless ($_[0]->{'langdef'} eq $1);
2592d9e0a35SMasatake YAMATO	 return parse_regex ($3, $_[0], 1, $2);
26089c588f7SMasatake YAMATO       } ],
26189c588f7SMasatake YAMATO     [ qr/^--_mtable-extend-([^=]*)=(.*)\+(.*)/, sub {
26289c588f7SMasatake YAMATO	 die "Don't use --_mline-extend-<LANG>= option before defining the language"
26389c588f7SMasatake YAMATO	   if (! defined $_[0]->{'langdef'});
26489c588f7SMasatake YAMATO	 die "Extending a multitable regex is allowed only to the language specified with --langdef: $1"
26589c588f7SMasatake YAMATO	   unless ($_[0]->{'langdef'} eq $1);
26689c588f7SMasatake YAMATO	 extend_table($_[0], $2, $3);
2672d9e0a35SMasatake YAMATO	 return 1;
2682d9e0a35SMasatake YAMATO     } ],
2691409a195SMasatake YAMATO     [ qr/^--_(prelude|sequel)-([^=]*)=(\{\{)$/, sub {
2702d9e0a35SMasatake YAMATO	 die "Don't use --_mtable-regex-<LANG>= option before defining the language"
2712d9e0a35SMasatake YAMATO	   if (! defined $_[0]->{'langdef'});
2722d9e0a35SMasatake YAMATO
2731409a195SMasatake YAMATO	 my $hook = $_[0]->{$1};
2741409a195SMasatake YAMATO	 my $slot = @$hook;
2751409a195SMasatake YAMATO	 push @$hook, $3;
2762d9e0a35SMasatake YAMATO	 return sub {
2771409a195SMasatake YAMATO	   $hook->[$slot] = $hook->[$slot] . $_[0];
2782d9e0a35SMasatake YAMATO	 }
2792d9e0a35SMasatake YAMATO       }],
2801409a195SMasatake YAMATO     [ qr/^--_(prelude|sequel)-([^=]*)=(\{\{.*\}\})$/, sub {
2812d9e0a35SMasatake YAMATO	 die "Don't use --_mtable-regex-<LANG>= option before defining the language"
2822d9e0a35SMasatake YAMATO	   if (! defined $_[0]->{'langdef'});
2832d9e0a35SMasatake YAMATO
2841409a195SMasatake YAMATO	 my $hook = $_[0]->{$1};
2851409a195SMasatake YAMATO	 my $slot = @$hook;
2861409a195SMasatake YAMATO	 push @$hook, $3;
2872d9e0a35SMasatake YAMATO	 return 1;
28889c588f7SMasatake YAMATO       }],
289d14b4a65SMasatake YAMATO     [ qr/^--_scopesep-([^=]*)=([^,]?)\/([^:]+):(.+)/, sub {
290d14b4a65SMasatake YAMATO	 die "Don't use --_scopesep-<LANG>= option before defining the language"
291d14b4a65SMasatake YAMATO	   if (! defined $_[0]->{'langdef'});
292d14b4a65SMasatake YAMATO	 die "Specifying a scope separator is allowed only to the language specified with --langdef: $1"
293d14b4a65SMasatake YAMATO	   unless ($_[0]->{'langdef'} eq $1);
294d14b4a65SMasatake YAMATO	 scopesep($_[0], $2, $3, $4);
2952d9e0a35SMasatake YAMATO	 return 1;
296d14b4a65SMasatake YAMATO       } ],
29728a3d08fSMasatake YAMATO     [ qr/^-.*/, sub {
2985d4741edSMasatake YAMATO	 die "Unhandled option: \"$&\"";
29928a3d08fSMasatake YAMATO       } ],
30028a3d08fSMasatake YAMATO     [ qr/.*/, sub {
3015d4741edSMasatake YAMATO	 die "Unhandled argument: \"$&\"";
30228a3d08fSMasatake YAMATO       } ],
30328a3d08fSMasatake YAMATO    ];
30428a3d08fSMasatake YAMATO
30528a3d08fSMasatake YAMATOsub parse_line {
30628a3d08fSMasatake YAMATO    my ($line, $opts) = @_;
30728a3d08fSMasatake YAMATO    my $r = 0;
30828a3d08fSMasatake YAMATO
30928a3d08fSMasatake YAMATO    for (@{$options}) {
31028a3d08fSMasatake YAMATO	my ($pat, $action) = @{$_};
31128a3d08fSMasatake YAMATO	if ($line =~ $pat) {
3122d9e0a35SMasatake YAMATO	    $r = $action -> ($opts);
31328a3d08fSMasatake YAMATO	    last;
31428a3d08fSMasatake YAMATO	}
31528a3d08fSMasatake YAMATO    }
31628a3d08fSMasatake YAMATO    $r;
317ec2a6441SMasatake YAMATO}
318ec2a6441SMasatake YAMATO
31928a3d08fSMasatake YAMATOsub gather_chars {
32028a3d08fSMasatake YAMATO    my $input = shift;
32128a3d08fSMasatake YAMATO    my $output = "";
322ec2a6441SMasatake YAMATO
32328a3d08fSMasatake YAMATO    my $escape = 0;
32428a3d08fSMasatake YAMATO    my $c;
325ec2a6441SMasatake YAMATO
32689c588f7SMasatake YAMATO    # See scanSeparators() of lregex.c.
32728a3d08fSMasatake YAMATO    while (defined ($c = shift @{$input})) {
32828a3d08fSMasatake YAMATO	if ($escape) {
32989c588f7SMasatake YAMATO	    if ($c eq '/') {
33028a3d08fSMasatake YAMATO		$output = $output . $c;
33189c588f7SMasatake YAMATO	    } elsif ($c eq 't') {
33289c588f7SMasatake YAMATO		$output = $output . '\\' . 't';
33389c588f7SMasatake YAMATO	    } elsif ($c eq 'n') {
33489c588f7SMasatake YAMATO		$output = $output . '\\' . 'n';
335f19c7d5cSHadriel Kaplan	    } elsif ($c eq '\\') {
336f19c7d5cSHadriel Kaplan		$output = $output . '\\\\' . '\\\\';
33728a3d08fSMasatake YAMATO	    } else {
338f19c7d5cSHadriel Kaplan		$output = $output . '\\\\' . $c;
33928a3d08fSMasatake YAMATO	    }
34089c588f7SMasatake YAMATO	    $escape = 0;
341aa75fda4SMasatake YAMATO	} elsif ($c eq '"') {
342aa75fda4SMasatake YAMATO	    $output = $output . '\\' . $c;
34389c588f7SMasatake YAMATO	} elsif ($c eq '\\') {
34489c588f7SMasatake YAMATO	    $escape = 1;
34589c588f7SMasatake YAMATO	} elsif ($c eq '/') {
34689c588f7SMasatake YAMATO	    last;
34728a3d08fSMasatake YAMATO	} else {
34828a3d08fSMasatake YAMATO	    $output = $output . $c;
34928a3d08fSMasatake YAMATO	}
350ec2a6441SMasatake YAMATO    }
351ec2a6441SMasatake YAMATO
35228a3d08fSMasatake YAMATO    return ($output, (defined $c)? $c: "");
353ec2a6441SMasatake YAMATO}
354ec2a6441SMasatake YAMATO
35528a3d08fSMasatake YAMATOsub parse_regex {
35689c588f7SMasatake YAMATO    my ($regspec, $opts, $mline, $table) = @_;
357ec2a6441SMasatake YAMATO
35828a3d08fSMasatake YAMATO    my @chars = split //, $regspec;
359ec2a6441SMasatake YAMATO
360641e337aSMasatake YAMATO    # TODO:
361641e337aSMasatake YAMATO    #	ctags allows using a char other than '/'
362641e337aSMasatake YAMATO    #
36328a3d08fSMasatake YAMATO    if (! ($chars[0] eq '/')) {
364641e337aSMasatake YAMATO	if (!$mline) {
36528a3d08fSMasatake YAMATO	    die "--regex-<LANG>= option is not started from /: $regspec";
366641e337aSMasatake YAMATO	} else {
367641e337aSMasatake YAMATO	    die "--mline-regex-<LANG>= option is not started from /: $regspec";
368641e337aSMasatake YAMATO	}
369ec2a6441SMasatake YAMATO    }
370ec2a6441SMasatake YAMATO
37128a3d08fSMasatake YAMATO    shift @chars;
37228a3d08fSMasatake YAMATO    my $last_char;
373ec2a6441SMasatake YAMATO
37428a3d08fSMasatake YAMATO    my $regex;
37528a3d08fSMasatake YAMATO    ($regex, $last_char) = gather_chars (\@chars);
37628a3d08fSMasatake YAMATO    if (! ($last_char eq '/')) {
377641e337aSMasatake YAMATO	if (!$mline) {
37828a3d08fSMasatake YAMATO	    die "The pattern in --regex-<LANG>= option is not ended with /: $regspec";
379641e337aSMasatake YAMATO	} else {
380641e337aSMasatake YAMATO	    die "The pattern in --mline-regex-<LANG>= option is not ended with /: $regspec";
381641e337aSMasatake YAMATO	}
382ec2a6441SMasatake YAMATO    }
383ec2a6441SMasatake YAMATO
38428a3d08fSMasatake YAMATO    my $name;
38528a3d08fSMasatake YAMATO    ($name, $last_char) = gather_chars (\@chars);
38628a3d08fSMasatake YAMATO    if (! ($last_char eq '/')) {
38728a3d08fSMasatake YAMATO	die "Wrong kind/flags syntax: $regspec";
388ec2a6441SMasatake YAMATO    }
389ec2a6441SMasatake YAMATO
39028a3d08fSMasatake YAMATO    my $tmp;
39128a3d08fSMasatake YAMATO    ($tmp, $last_char) = gather_chars (\@chars);
39228a3d08fSMasatake YAMATO    my $kind = "";
39328a3d08fSMasatake YAMATO    my $flags;
39428a3d08fSMasatake YAMATO
39528a3d08fSMasatake YAMATO    if ( (! @chars) && (! ($last_char eq '/'))) {
39628a3d08fSMasatake YAMATO	$flags = $tmp;
39728a3d08fSMasatake YAMATO
39828a3d08fSMasatake YAMATO    } else {
39928a3d08fSMasatake YAMATO	$kind = $tmp;
40028a3d08fSMasatake YAMATO    }
40128a3d08fSMasatake YAMATO
40228a3d08fSMasatake YAMATO    if ($last_char eq '/') {
40328a3d08fSMasatake YAMATO	($flags, $last_char) = gather_chars (\@chars);
40428a3d08fSMasatake YAMATO    }
40528a3d08fSMasatake YAMATO
4062d9e0a35SMasatake YAMATO    my $optscript = '';
4072d9e0a35SMasatake YAMATO    if ($flags =~ /(.*)\{\{$/) {
4082d9e0a35SMasatake YAMATO	$flags = $1;
4092d9e0a35SMasatake YAMATO	$optscript = "{{\n";
4102d9e0a35SMasatake YAMATO    }
4112d9e0a35SMasatake YAMATO
4122d9e0a35SMasatake YAMATO    my $entry;
41389c588f7SMasatake YAMATO    if (defined $table) {
41489c588f7SMasatake YAMATO
41589c588f7SMasatake YAMATO      if (! (substr ($regex, 0, 1) eq '^')) {
41689c588f7SMasatake YAMATO	$regex = '^' . $regex;
41789c588f7SMasatake YAMATO      }
4182d9e0a35SMasatake YAMATO      $entry = { 'regex' => $regex,
41989c588f7SMasatake YAMATO		 'name'  => $name,
42089c588f7SMasatake YAMATO		 'kind'  => $kind,
42189c588f7SMasatake YAMATO		 'flags' => $flags,
42289c588f7SMasatake YAMATO		 'mline' => $mline,
4232d9e0a35SMasatake YAMATO		 'optscript' => $optscript,
42489c588f7SMasatake YAMATO	       };
4252d9e0a35SMasatake YAMATO      push @{$opts->{'tabledefs'}->{"$table"}}, $entry;
42689c588f7SMasatake YAMATO    } else {
4272d9e0a35SMasatake YAMATO      $entry = { 'regex' => $regex,
42828a3d08fSMasatake YAMATO		 'name'  => $name,
42928a3d08fSMasatake YAMATO		 'kind'  => $kind,
43028a3d08fSMasatake YAMATO		 'flags' => $flags,
431641e337aSMasatake YAMATO		 'mline' => $mline,
4322d9e0a35SMasatake YAMATO		 'optscript' => $optscript,
43328a3d08fSMasatake YAMATO	       };
4342d9e0a35SMasatake YAMATO      push @{$opts->{'regexs'}}, $entry;
43528a3d08fSMasatake YAMATO    }
436377dfe59SMasatake YAMATO
4372d9e0a35SMasatake YAMATO    if ($flags =~ '{scope=' || $optscript) {
438377dfe59SMasatake YAMATO	$opts->{'useCork'} = 1;
439377dfe59SMasatake YAMATO    }
4402d9e0a35SMasatake YAMATO
4412d9e0a35SMasatake YAMATO    return $optscript
4422d9e0a35SMasatake YAMATO	? sub {
4432d9e0a35SMasatake YAMATO	    $entry->{'optscript'} = $entry->{'optscript'} . $_[0];
4442d9e0a35SMasatake YAMATO	}
4452d9e0a35SMasatake YAMATO	: 1;
44689c588f7SMasatake YAMATO}
44789c588f7SMasatake YAMATO
44889c588f7SMasatake YAMATOsub extend_table {
44989c588f7SMasatake YAMATO  my ($opts, $dist, $src) = @_;
45089c588f7SMasatake YAMATO
45189c588f7SMasatake YAMATO  for (@{$opts->{'tabledefs'}->{$src}}) {
45289c588f7SMasatake YAMATO    push @{$opts->{'tabledefs'}->{$dist}}, $_;
45389c588f7SMasatake YAMATO  }
45489c588f7SMasatake YAMATO}
45528a3d08fSMasatake YAMATO
45628a3d08fSMasatake YAMATOsub parse_kinds {
45728a3d08fSMasatake YAMATO    my ($kinds, $opts) = @_;
4581a827775SMasatake YAMATO    for my $letter (split //, $kinds) {
459fd51425fSMasatake YAMATO	for (@{$opts->{'kinddefs'}}) {
460fd51425fSMasatake YAMATO	    if ($_->{'letter'} eq $letter) {
461fd51425fSMasatake YAMATO		$_->{'enabled'} = 0;
462fd51425fSMasatake YAMATO	    }
463fd51425fSMasatake YAMATO	}
46428a3d08fSMasatake YAMATO    }
46528a3d08fSMasatake YAMATO}
46628a3d08fSMasatake YAMATO
46728a3d08fSMasatake YAMATOsub parse_optlib {
46828a3d08fSMasatake YAMATO    my ($optlib, $opts) = @_;
46928a3d08fSMasatake YAMATO
47028a3d08fSMasatake YAMATO    open(my $optlibfh, "<", $optlib)
47128a3d08fSMasatake YAMATO	or die "cannot open the optlib file: \"$optlib\"";
47228a3d08fSMasatake YAMATO
4732d9e0a35SMasatake YAMATO    my $receiver = 0;
47428a3d08fSMasatake YAMATO    while (<$optlibfh>) {
47528a3d08fSMasatake YAMATO	chomp;
4762d9e0a35SMasatake YAMATO
4772d9e0a35SMasatake YAMATO	if (/^\}\}$/ && $receiver && ($receiver != 1)) {
4782d9e0a35SMasatake YAMATO	    $receiver->('}}');
4792d9e0a35SMasatake YAMATO	    $receiver = 1;
4802d9e0a35SMasatake YAMATO	}
4812d9e0a35SMasatake YAMATO	elsif ($receiver && $receiver != 1) {
4822d9e0a35SMasatake YAMATO	    my $str = escape_as_cstr ($_);
4832d9e0a35SMasatake YAMATO	    $receiver->($str);
4842d9e0a35SMasatake YAMATO	    $receiver->("\n");
485*af10eb0bSMasatake YAMATO	} elsif ( /^[[:blank:]]*#.*/ ) {
48628a3d08fSMasatake YAMATO	    next;
48728a3d08fSMasatake YAMATO	} else {
48828a3d08fSMasatake YAMATO	    s/^\s*//;
48928a3d08fSMasatake YAMATO	    next if ( /^\s*$/ );
4902d9e0a35SMasatake YAMATO	    $receiver = parse_line ($_, $opts);
4912d9e0a35SMasatake YAMATO	    if (! $receiver) {
49228a3d08fSMasatake YAMATO		return undef;
49328a3d08fSMasatake YAMATO	    }
49428a3d08fSMasatake YAMATO	}
49528a3d08fSMasatake YAMATO    }
49628a3d08fSMasatake YAMATO    return $opts;
49728a3d08fSMasatake YAMATO}
49828a3d08fSMasatake YAMATO
499079b3137SMasatake YAMATOsub parse_extras {
500079b3137SMasatake YAMATO    my ($flag, $extra, $opts) = @_;
501079b3137SMasatake YAMATO
502079b3137SMasatake YAMATO    $flag = ( $flag eq '+' )?1: 0;
503079b3137SMasatake YAMATO
504079b3137SMasatake YAMATO    # TODO: Hash table should be used for manage 'extradefs'.
505079b3137SMasatake YAMATO    for (@{$opts->{'extradefs'}}) {
506079b3137SMasatake YAMATO	if ($_->{'name'} eq $extra)
507079b3137SMasatake YAMATO	{
508079b3137SMasatake YAMATO	    $_->{'enabled'} = $flag;
509079b3137SMasatake YAMATO	}
510079b3137SMasatake YAMATO    }
511079b3137SMasatake YAMATO}
512079b3137SMasatake YAMATO
5137c42e9eeSMasatake YAMATOsub parse_fields {
5147c42e9eeSMasatake YAMATO    my ($flag, $field, $opts) = @_;
5157c42e9eeSMasatake YAMATO
5167c42e9eeSMasatake YAMATO    $flag = ( $flag eq '+' )?1: 0;
5177c42e9eeSMasatake YAMATO
5187c42e9eeSMasatake YAMATO    # TODO: Hash table should be used for manage 'fielddefs'.
5197c42e9eeSMasatake YAMATO    for (@{$opts->{'fielddefs'}}) {
5207c42e9eeSMasatake YAMATO	if ($_->{'name'} eq $field)
5217c42e9eeSMasatake YAMATO	{
5227c42e9eeSMasatake YAMATO	    $_->{'enabled'} = $flag;
5237c42e9eeSMasatake YAMATO	}
5247c42e9eeSMasatake YAMATO    }
5257c42e9eeSMasatake YAMATO}
5267c42e9eeSMasatake YAMATO
527d14b4a65SMasatake YAMATOsub scopesep {
528d14b4a65SMasatake YAMATO    my ($opts, $parent_kletter, $kletter, $sep) = @_;
529d14b4a65SMasatake YAMATO
530d14b4a65SMasatake YAMATO    if ($kletter eq '*') {
531d14b4a65SMasatake YAMATO	if ($parent_kletter eq '*') {
532d14b4a65SMasatake YAMATO	    $opts->{'defaultScopeSeparator'} = $sep;
533d14b4a65SMasatake YAMATO	} elsif (!$parent_kletter) {
534d14b4a65SMasatake YAMATO	    $opts->{'defaultRootScopeSeparator'} = $sep;
535d14b4a65SMasatake YAMATO	} else {
536d14b4a65SMasatake YAMATO	    die "Unhandled kind letter during parsing --_scopsesep option: $parent_kletter";
537d14b4a65SMasatake YAMATO	}
538d14b4a65SMasatake YAMATO    } elsif ($kletter =~ /[a-zA-Z]/) {
539d14b4a65SMasatake YAMATO	my $kind;
540d14b4a65SMasatake YAMATO	for (@{$opts->{'kinddefs'}}) {
541d14b4a65SMasatake YAMATO	    if ($_->{'letter'} eq $kletter) {
542d14b4a65SMasatake YAMATO		$kind = $_;
543d14b4a65SMasatake YAMATO		last;
544d14b4a65SMasatake YAMATO	    }
545d14b4a65SMasatake YAMATO	}
546d14b4a65SMasatake YAMATO	die "Unknown kind letter in --_scopsesep option: $kletter"
547d14b4a65SMasatake YAMATO	  unless defined $kind;
548d14b4a65SMasatake YAMATO
549d14b4a65SMasatake YAMATO	if ($parent_kletter eq '*') {
550d14b4a65SMasatake YAMATO	    push @{$kind->{'seps'}}, { parentKindIndex => 'KIND_WILDCARD_INDEX',
551d14b4a65SMasatake YAMATO				       sep => $sep };
552d14b4a65SMasatake YAMATO	} elsif (!$parent_kletter) {
553d14b4a65SMasatake YAMATO	    push @{$kind->{'seps'}}, { parentKindIndex => 'KIND_GHOST_INDEX',
554d14b4a65SMasatake YAMATO				       sep => $sep };
555d14b4a65SMasatake YAMATO	} elsif ($parent_kletter =~ /[a-zA-Z]/) {
556d14b4a65SMasatake YAMATO	    my $parent_kind;
557d14b4a65SMasatake YAMATO	    for (@{$opts->{'kinddefs'}}) {
558d14b4a65SMasatake YAMATO		if ($_->{'letter'} == $parent_kletter) {
559d14b4a65SMasatake YAMATO		    $parent_kind = $_;
560d14b4a65SMasatake YAMATO		    last;
561d14b4a65SMasatake YAMATO		}
562d14b4a65SMasatake YAMATO	    }
563d14b4a65SMasatake YAMATO	    die "Unknown kind letter in --_scopsesep option: $parent_kletter"
564d14b4a65SMasatake YAMATO	      unless defined $parent_kind;
565d14b4a65SMasatake YAMATO	    push @{$kind->{'seps'}}, { parentKindIndex => 'K_' . (uc $parent_kind->{'name'}),
566d14b4a65SMasatake YAMATO				       sep => $sep };
567d14b4a65SMasatake YAMATO	}
568d14b4a65SMasatake YAMATO    } else {
569d14b4a65SMasatake YAMATO	die "Unhandled kind letter during parsing --_scopsesep option: $kletter";
570d14b4a65SMasatake YAMATO    }
571d14b4a65SMasatake YAMATO
572d14b4a65SMasatake YAMATO    $opts->{'hasSepSpeicifer'} = 1;
573d14b4a65SMasatake YAMATO}
574d14b4a65SMasatake YAMATO
57568303253SMasatake YAMATO
57668303253SMasatake YAMATO########################################################################
57768303253SMasatake YAMATO#
57868303253SMasatake YAMATO# EMIT
57968303253SMasatake YAMATO#
58068303253SMasatake YAMATO########################################################################
58168303253SMasatake YAMATO
58228a3d08fSMasatake YAMATOsub emit_header {
58352b9d1f4SMasatake YAMATO    my ($optlib, $opts) = @_;
58428a3d08fSMasatake YAMATO
58528a3d08fSMasatake YAMATO    print <<EOF;
586ec2a6441SMasatake YAMATO/*
58728a3d08fSMasatake YAMATO * Generated by $0 from ${optlib}, Don't edit this manually.
588ec2a6441SMasatake YAMATO */
589ec2a6441SMasatake YAMATO#include "general.h"
590ec2a6441SMasatake YAMATO#include "parse.h"
591ec2a6441SMasatake YAMATO#include "routines.h"
5920d502ef0SMasatake YAMATO#include "field.h"
5930d502ef0SMasatake YAMATO#include "xtag.h"
59452b9d1f4SMasatake YAMATOEOF
59552b9d1f4SMasatake YAMATO
59652b9d1f4SMasatake YAMATO    if (defined $opts->{'base'}) {
59752b9d1f4SMasatake YAMATO	print <<EOF;
59852b9d1f4SMasatake YAMATO#include "subparser.h"
59952b9d1f4SMasatake YAMATOEOF
60052b9d1f4SMasatake YAMATO    }
601c48fee31SMasatake YAMATO    if (defined $opts->{'selector'}) {
602c48fee31SMasatake YAMATO	print <<EOF;
603c48fee31SMasatake YAMATO#include "selectors.h"
604c48fee31SMasatake YAMATOEOF
605c48fee31SMasatake YAMATO    }
60652b9d1f4SMasatake YAMATO    print <<EOF;
607ec2a6441SMasatake YAMATO
60828a3d08fSMasatake YAMATO
609ec2a6441SMasatake YAMATOEOF
610ec2a6441SMasatake YAMATO}
611ec2a6441SMasatake YAMATO
61228a3d08fSMasatake YAMATOsub emit_initializer {
61328a3d08fSMasatake YAMATO    my $opts = shift;
614fd51425fSMasatake YAMATO    my $may_unused = $opts->{'tablenames'} ? "": " CTAGS_ATTR_UNUSED";
615c5dc92b6SMasatake YAMATO
61628a3d08fSMasatake YAMATO    print <<EOF;
617e1eed005SMasatake YAMATOstatic void initialize$opts->{'Clangdef'}Parser (const langType language$may_unused)
618ec2a6441SMasatake YAMATO{
619ec2a6441SMasatake YAMATOEOF
6202d9e0a35SMasatake YAMATO    for (@{$opts->{'prelude'}}) {
6212d9e0a35SMasatake YAMATO	my $prelude = "";
6222d9e0a35SMasatake YAMATO	for my $frag (split /\n/, $_) {
6232d9e0a35SMasatake YAMATO	    $prelude = $prelude . "\n\t\t\"" . $frag . ($frag =~ /.*\}\}$/
6242d9e0a35SMasatake YAMATO							? '"'
6252d9e0a35SMasatake YAMATO							: '\n"');
6262d9e0a35SMasatake YAMATO	}
6272d9e0a35SMasatake YAMATO	print <<EOF;
628b6124a60SMasatake YAMATO	addLanguageOptscriptToHook (language, SCRIPT_HOOK_PRELUDE,$prelude);
6292d9e0a35SMasatake YAMATOEOF
6302d9e0a35SMasatake YAMATO    }
6311409a195SMasatake YAMATO    for (@{$opts->{'sequel'}}) {
6321409a195SMasatake YAMATO	my $sequel = "";
6331409a195SMasatake YAMATO	for my $frag (split /\n/, $_) {
6341409a195SMasatake YAMATO	    $sequel = $sequel . "\n\t\t\"" . $frag . ($frag =~ /.*\}\}$/
6351409a195SMasatake YAMATO							? '"'
6361409a195SMasatake YAMATO							: '\n"');
6371409a195SMasatake YAMATO	}
6381409a195SMasatake YAMATO	print <<EOF;
639b6124a60SMasatake YAMATO	addLanguageOptscriptToHook (language, SCRIPT_HOOK_SEQUEL,$sequel);
6401409a195SMasatake YAMATOEOF
6411409a195SMasatake YAMATO    }
64289c588f7SMasatake YAMATO    if ($opts->{'tablenames'}) {
64389c588f7SMasatake YAMATO      print "\n";
64489c588f7SMasatake YAMATO
64589c588f7SMasatake YAMATO      for (@{$opts->{'tablenames'}}) {
64689c588f7SMasatake YAMATO	print <<EOF;
64789c588f7SMasatake YAMATO	addLanguageRegexTable (language, "$_");
64889c588f7SMasatake YAMATOEOF
64989c588f7SMasatake YAMATO      }
65089c588f7SMasatake YAMATO
65189c588f7SMasatake YAMATO      print "\n";
65289c588f7SMasatake YAMATO
6531a827775SMasatake YAMATO      for my $table (@{$opts->{'tablenames'}}) {
65489c588f7SMasatake YAMATO	for (@{$opts->{'tabledefs'}->{"$table"}}) {
6552d9e0a35SMasatake YAMATO	  my $optscript = "";
6562d9e0a35SMasatake YAMATO	  if ($_-> {'optscript'}) {
6572d9e0a35SMasatake YAMATO	    for my $frag (split /\n/, $_-> {'optscript'}) {
6582d9e0a35SMasatake YAMATO	      $optscript = $optscript . "\n\t\t\"" . $frag . ($frag =~ /.*\}\}$/
6592d9e0a35SMasatake YAMATO							      ? '"'
6602d9e0a35SMasatake YAMATO							      : '\n"');
6612d9e0a35SMasatake YAMATO	    }
6622d9e0a35SMasatake YAMATO	  }
66389c588f7SMasatake YAMATO	  print <<EOF;
66489c588f7SMasatake YAMATO	addLanguageTagMultiTableRegex (language, "$table",
66589c588f7SMasatake YAMATO	                               "$_->{'regex'}",
6662d9e0a35SMasatake YAMATO	                               "$_->{'name'}", "$_->{'kind'}", "$_->{'flags'}"$optscript, NULL);
66789c588f7SMasatake YAMATOEOF
66889c588f7SMasatake YAMATO	}
66989c588f7SMasatake YAMATO      }
67089c588f7SMasatake YAMATO    }
67128a3d08fSMasatake YAMATO    print <<EOF;
672ec2a6441SMasatake YAMATO}
673ec2a6441SMasatake YAMATO
674ec2a6441SMasatake YAMATOEOF
67528a3d08fSMasatake YAMATO    0;
67628a3d08fSMasatake YAMATO}
677ec2a6441SMasatake YAMATO
67828a3d08fSMasatake YAMATOsub emit_list {
67928a3d08fSMasatake YAMATO    my ($opts, $key) = @_;
68028a3d08fSMasatake YAMATO
68128a3d08fSMasatake YAMATO    print <<EOF;
68228a3d08fSMasatake YAMATO	static const char *const $key [] = {
68328a3d08fSMasatake YAMATOEOF
68428a3d08fSMasatake YAMATO    for (@{$opts->{$key}}) {
68528a3d08fSMasatake YAMATO	print <<EOF;
68628a3d08fSMasatake YAMATO		\"$_\",
68728a3d08fSMasatake YAMATOEOF
68828a3d08fSMasatake YAMATO    }
68928a3d08fSMasatake YAMATO
69028a3d08fSMasatake YAMATO    print <<EOF;
691ec2a6441SMasatake YAMATO		NULL
692ec2a6441SMasatake YAMATO	};
69328a3d08fSMasatake YAMATO
694ec2a6441SMasatake YAMATOEOF
695ec2a6441SMasatake YAMATO}
696ec2a6441SMasatake YAMATO
69728a3d08fSMasatake YAMATOsub emit_aliases {
69828a3d08fSMasatake YAMATO    emit_list $_[0], "aliases";
69928a3d08fSMasatake YAMATO}
700ec2a6441SMasatake YAMATO
70128a3d08fSMasatake YAMATOsub emit_extensions {
70228a3d08fSMasatake YAMATO    emit_list $_[0], "extensions";
70328a3d08fSMasatake YAMATO}
70428a3d08fSMasatake YAMATO
70528a3d08fSMasatake YAMATOsub emit_patterns {
70628a3d08fSMasatake YAMATO    emit_list $_[0], "patterns";
70728a3d08fSMasatake YAMATO}
70828a3d08fSMasatake YAMATO
70916469a82SMasatake YAMATO# TODO: handling '\'
71016469a82SMasatake YAMATOsub escape_as_cstr {
711352a49a0SMasatake YAMATO    my $input = shift;
712352a49a0SMasatake YAMATO    my $output = "";
713352a49a0SMasatake YAMATO
7141a827775SMasatake YAMATO    for my $c (split //, $input) {
715352a49a0SMasatake YAMATO	if ($c eq '"') {
716352a49a0SMasatake YAMATO	    $output = $output . '\\' . '"';
71701b15601SMasatake YAMATO	} elsif ($c eq '\\') {
71801b15601SMasatake YAMATO	    $output = $output . '\\' . '\\';
719352a49a0SMasatake YAMATO	} else {
720352a49a0SMasatake YAMATO	    $output = $output . $c;
721352a49a0SMasatake YAMATO	}
722352a49a0SMasatake YAMATO    }
723352a49a0SMasatake YAMATO
724352a49a0SMasatake YAMATO    return $output;
725352a49a0SMasatake YAMATO}
726352a49a0SMasatake YAMATO
727dff7c6b0SMasatake YAMATOsub emit_roledefs {
728dff7c6b0SMasatake YAMATO    my $opts = shift;
729dff7c6b0SMasatake YAMATO
730dff7c6b0SMasatake YAMATO
731dff7c6b0SMasatake YAMATO    for (@{$opts->{'kinddefs'}}) {
732dff7c6b0SMasatake YAMATO	next unless @{$_->{'roles'}};
733dff7c6b0SMasatake YAMATO	my $Kind = capitalize($_->{'name'});
734dff7c6b0SMasatake YAMATO	print <<EOF;
735dff7c6b0SMasatake YAMATO	static roleDefinition $opts->{'Clangdef'}${Kind}RoleTable [] = {
736dff7c6b0SMasatake YAMATOEOF
737dff7c6b0SMasatake YAMATO	for (@{$_->{'roles'}}) {
73816469a82SMasatake YAMATO	    my $desc = escape_as_cstr $_->{'desc'};
739dff7c6b0SMasatake YAMATO	    print <<EOF;
740352a49a0SMasatake YAMATO		{ true, "$_->{'name'}", "$desc" },
741dff7c6b0SMasatake YAMATOEOF
742dff7c6b0SMasatake YAMATO	}
743dff7c6b0SMasatake YAMATO
744dff7c6b0SMasatake YAMATO	print <<EOF;
745dff7c6b0SMasatake YAMATO	};
746dff7c6b0SMasatake YAMATOEOF
747dff7c6b0SMasatake YAMATO    }
748dff7c6b0SMasatake YAMATO    print <<EOF;
749dff7c6b0SMasatake YAMATOEOF
750dff7c6b0SMasatake YAMATO}
751dff7c6b0SMasatake YAMATO
752d14b4a65SMasatake YAMATOsub emit_kinddef_enums {
753d14b4a65SMasatake YAMATO    my $opts = shift;
754d14b4a65SMasatake YAMATO
755d14b4a65SMasatake YAMATO    return if (! @{$opts->{'kinddefs'}});
756d14b4a65SMasatake YAMATO
757d14b4a65SMasatake YAMATO    print <<EOF;
758d14b4a65SMasatake YAMATOtypedef enum {
759d14b4a65SMasatake YAMATOEOF
760d14b4a65SMasatake YAMATO    for (@{$opts->{'kinddefs'}}) {
761d14b4a65SMasatake YAMATO	my $e = uc($_->{'name'});
762d14b4a65SMasatake YAMATO	print <<EOF;
763d14b4a65SMasatake YAMATO	K_$e,
764d14b4a65SMasatake YAMATOEOF
765d14b4a65SMasatake YAMATO    }
766d14b4a65SMasatake YAMATO    print <<EOF;
767d14b4a65SMasatake YAMATO} $opts->{'Clangdef'}Kind;
768d14b4a65SMasatake YAMATO
769d14b4a65SMasatake YAMATO
770d14b4a65SMasatake YAMATOEOF
771d14b4a65SMasatake YAMATO}
772d14b4a65SMasatake YAMATO
773d14b4a65SMasatake YAMATOsub emit_scopeseps {
774d14b4a65SMasatake YAMATO    my $opts = shift;
775d14b4a65SMasatake YAMATO
776d14b4a65SMasatake YAMATO    return if (! @{$opts->{'kinddefs'}});
777d14b4a65SMasatake YAMATO
778d14b4a65SMasatake YAMATO    for (@{$opts->{'kinddefs'}}) {
779d14b4a65SMasatake YAMATO	my $seps = $_->{'seps'};
780d14b4a65SMasatake YAMATO	if (@{$seps}) {
781d14b4a65SMasatake YAMATO	    my $Kind = capitalize ($_->{'name'});
782d14b4a65SMasatake YAMATO	    print <<EOF;
783d14b4a65SMasatake YAMATO	static scopeSeparator $opts->{'Clangdef'}${Kind}Separators [] = {
784d14b4a65SMasatake YAMATOEOF
785d14b4a65SMasatake YAMATO	    for (@{$seps}) {
786d14b4a65SMasatake YAMATO	    print <<EOF;
787d14b4a65SMasatake YAMATO		{ $_->{'parentKindIndex'}, "$_->{'sep'}" },
788d14b4a65SMasatake YAMATOEOF
789d14b4a65SMasatake YAMATO	    }
790d14b4a65SMasatake YAMATO	    print <<EOF;
791d14b4a65SMasatake YAMATO	};
792d14b4a65SMasatake YAMATO
793d14b4a65SMasatake YAMATOEOF
794d14b4a65SMasatake YAMATO	}
795d14b4a65SMasatake YAMATO    }
796d14b4a65SMasatake YAMATO}
797d14b4a65SMasatake YAMATO
79854fa68c3SMasatake YAMATOsub emit_kinddefs {
79954fa68c3SMasatake YAMATO    my $opts = shift;
80054fa68c3SMasatake YAMATO
80154fa68c3SMasatake YAMATO    return if (! @{$opts->{'kinddefs'}});
80254fa68c3SMasatake YAMATO
80354fa68c3SMasatake YAMATO    print <<EOF;
80454fa68c3SMasatake YAMATO	static kindDefinition $opts->{'Clangdef'}KindTable [] = {
80554fa68c3SMasatake YAMATOEOF
80654fa68c3SMasatake YAMATO    for (@{$opts->{'kinddefs'}}) {
807fd51425fSMasatake YAMATO      my $enabled = $_->{"enabled"}? "true": "false";
80854fa68c3SMasatake YAMATO      print <<EOF;
809dff7c6b0SMasatake YAMATO		{
810dff7c6b0SMasatake YAMATOEOF
81116469a82SMasatake YAMATO      my $desc = escape_as_cstr $_->{'desc'};
812dff7c6b0SMasatake YAMATO      print <<EOF;
813352a49a0SMasatake YAMATO		  $enabled, \'$_->{'letter'}\', "$_->{'name'}", "$desc",
814dff7c6b0SMasatake YAMATOEOF
815dff7c6b0SMasatake YAMATO      if ($_->{'refonly'}) {
816dff7c6b0SMasatake YAMATO	  print <<EOF;
817dff7c6b0SMasatake YAMATO		  .referenceOnly = true,
818dff7c6b0SMasatake YAMATOEOF
819dff7c6b0SMasatake YAMATO      }
820dff7c6b0SMasatake YAMATO      my $Kind = capitalize($_->{'name'});
821dff7c6b0SMasatake YAMATO      if (@{$_->{'roles'}}) {
822dff7c6b0SMasatake YAMATO	  print <<EOF;
823dff7c6b0SMasatake YAMATO		  ATTACH_ROLES($opts->{'Clangdef'}${Kind}RoleTable),
824dff7c6b0SMasatake YAMATOEOF
825dff7c6b0SMasatake YAMATO      }
826d14b4a65SMasatake YAMATO      if (@{$_->{'seps'}}) {
827d14b4a65SMasatake YAMATO	  print <<EOF;
828d14b4a65SMasatake YAMATO		  ATTACH_SEPARATORS($opts->{'Clangdef'}${Kind}Separators),
829d14b4a65SMasatake YAMATOEOF
830d14b4a65SMasatake YAMATO      }
831dff7c6b0SMasatake YAMATO      print <<EOF;
832dff7c6b0SMasatake YAMATO		},
83354fa68c3SMasatake YAMATOEOF
83454fa68c3SMasatake YAMATO    }
83554fa68c3SMasatake YAMATO    print <<EOF;
83654fa68c3SMasatake YAMATO	};
83754fa68c3SMasatake YAMATOEOF
83854fa68c3SMasatake YAMATO}
83954fa68c3SMasatake YAMATO
84028a3d08fSMasatake YAMATOsub emit_regexs {
84128a3d08fSMasatake YAMATO    my $opts = shift;
84228a3d08fSMasatake YAMATO
84328a3d08fSMasatake YAMATO    return if (! @{$opts->{'regexs'}});
84428a3d08fSMasatake YAMATO
84528a3d08fSMasatake YAMATO    print <<EOF;
8465654c1fbSMasatake YAMATO	static tagRegexTable $opts->{'Clangdef'}TagRegexTable [] = {
847ec2a6441SMasatake YAMATOEOF
84828a3d08fSMasatake YAMATO    for (@{$opts->{'regexs'}}) {
8492d9e0a35SMasatake YAMATO	my $flags;
8502d9e0a35SMasatake YAMATO	if ($_-> {'flags'}) {
8512d9e0a35SMasatake YAMATO	    $flags = '"' . $_-> {'flags'} . '"';
8522d9e0a35SMasatake YAMATO	    if ($_-> {'optscript'}) {
8532d9e0a35SMasatake YAMATO		for my $frag (split /\n/, $_-> {'optscript'}) {
8542d9e0a35SMasatake YAMATO		    $flags = $flags . "\n\t\t\"" . $frag . ($frag =~ /.*\}\}$/
8552d9e0a35SMasatake YAMATO							    ? '"'
8562d9e0a35SMasatake YAMATO							    : '\n"');
8572d9e0a35SMasatake YAMATO		}
8582d9e0a35SMasatake YAMATO	    }
8592d9e0a35SMasatake YAMATO	} else {
8602d9e0a35SMasatake YAMATO	    if ($_-> {'optscript'}) {
8612d9e0a35SMasatake YAMATO		$flags = '""';
8622d9e0a35SMasatake YAMATO		for my $frag (split /\n/, $_-> {'optscript'}) {
8632d9e0a35SMasatake YAMATO		    $flags = $flags . "\n\t\t\"" . $frag . ($frag =~ /.*\}\}$/
8642d9e0a35SMasatake YAMATO							    ? '"'
8652d9e0a35SMasatake YAMATO							    : '\n"');
8662d9e0a35SMasatake YAMATO		}
8672d9e0a35SMasatake YAMATO	    } else {
8682d9e0a35SMasatake YAMATO		$flags = 'NULL';
8692d9e0a35SMasatake YAMATO	    }
8702d9e0a35SMasatake YAMATO	}
871641e337aSMasatake YAMATO	my $mline = $_-> {'mline'}? "true": "false";
87228a3d08fSMasatake YAMATO	print <<EOF;
87328a3d08fSMasatake YAMATO		{"$_->{'regex'}", "$_->{'name'}",
874641e337aSMasatake YAMATO		"$_->{'kind'}", $flags, NULL, $mline},
87528a3d08fSMasatake YAMATOEOF
87628a3d08fSMasatake YAMATO    }
87728a3d08fSMasatake YAMATO    print <<EOF;
878ec2a6441SMasatake YAMATO	};
87928a3d08fSMasatake YAMATO
880ec2a6441SMasatake YAMATOEOF
881ec2a6441SMasatake YAMATO}
882ec2a6441SMasatake YAMATO
88352b9d1f4SMasatake YAMATOsub emit_dependencies {
88452b9d1f4SMasatake YAMATO    my $opts = shift;
88552b9d1f4SMasatake YAMATO
88652b9d1f4SMasatake YAMATO    return if (! defined $opts->{'base'});
88752b9d1f4SMasatake YAMATO
8883edff4edSMasatake YAMATO    my $direction = "SUBPARSER_BASE_RUNS_SUB";
8893edff4edSMasatake YAMATO
8903edff4edSMasatake YAMATO    if (defined $opts->{'direction'})
8913edff4edSMasatake YAMATO    {
8923edff4edSMasatake YAMATO	if ($opts->{'direction'} eq 'shared')
8933edff4edSMasatake YAMATO	{
8943edff4edSMasatake YAMATO	    $direction = "SUBPARSER_BASE_RUNS_SUB";
8953edff4edSMasatake YAMATO	} elsif ($opts->{'direction'} eq 'dedicated')
8963edff4edSMasatake YAMATO	{
8973edff4edSMasatake YAMATO	    $direction = "SUBPARSER_SUB_RUNS_BASE";
8983edff4edSMasatake YAMATO	} elsif ($opts->{'direction'} eq 'bidirectional')
8993edff4edSMasatake YAMATO	{
9003edff4edSMasatake YAMATO	    $direction = "SUBPARSER_BI_DIRECTION";
9013edff4edSMasatake YAMATO	}
9023edff4edSMasatake YAMATO    }
9033edff4edSMasatake YAMATO
90452b9d1f4SMasatake YAMATO    print <<EOF;
90552b9d1f4SMasatake YAMATO	static subparser $opts->{'Clangdef'}Subparser = {
9063edff4edSMasatake YAMATO		.direction = $direction,
90752b9d1f4SMasatake YAMATO	};
90852b9d1f4SMasatake YAMATO	static parserDependency $opts->{'Clangdef'}Dependencies [] = {
90952b9d1f4SMasatake YAMATO		[0] = { DEPTYPE_SUBPARSER, "$opts->{'base'}", &$opts->{'Clangdef'}Subparser },
91052b9d1f4SMasatake YAMATO	};
91152b9d1f4SMasatake YAMATOEOF
91252b9d1f4SMasatake YAMATO
91352b9d1f4SMasatake YAMATO}
91452b9d1f4SMasatake YAMATO
9152b6707b2SMasatake YAMATOsub emit_xtags {
9162b6707b2SMasatake YAMATO    my $opts = shift;
9172b6707b2SMasatake YAMATO
9182b6707b2SMasatake YAMATO    return if (! @{$opts->{'extradefs'}});
9192b6707b2SMasatake YAMATO
9202b6707b2SMasatake YAMATO    print <<EOF;
9212b6707b2SMasatake YAMATO	static xtagDefinition $opts->{'Clangdef'}XtagTable [] = {
9222b6707b2SMasatake YAMATOEOF
9232b6707b2SMasatake YAMATO    for (@{$opts->{'extradefs'}}) {
924079b3137SMasatake YAMATO      my $enabled = $_->{"enabled"}? "true": "false";
92516469a82SMasatake YAMATO      my $desc = escape_as_cstr $_->{'desc'};
9262b6707b2SMasatake YAMATO      print <<EOF;
9272b6707b2SMasatake YAMATO		{
928079b3137SMasatake YAMATO		  .enabled     = $enabled,
9292b6707b2SMasatake YAMATO		  .name        = "$_->{'name'}",
930352a49a0SMasatake YAMATO		  .description = "$desc",
9312b6707b2SMasatake YAMATO		},
9322b6707b2SMasatake YAMATOEOF
9332b6707b2SMasatake YAMATO    }
9342b6707b2SMasatake YAMATO    print <<EOF;
9352b6707b2SMasatake YAMATO	};
9362b6707b2SMasatake YAMATOEOF
9372b6707b2SMasatake YAMATO}
9382b6707b2SMasatake YAMATO
9397c42e9eeSMasatake YAMATOsub emit_fields {
9407c42e9eeSMasatake YAMATO    my $opts = shift;
9417c42e9eeSMasatake YAMATO
9427c42e9eeSMasatake YAMATO    return if (! @{$opts->{'fielddefs'}});
9437c42e9eeSMasatake YAMATO
9447c42e9eeSMasatake YAMATO    print <<EOF;
9457c42e9eeSMasatake YAMATO	static fieldDefinition $opts->{'Clangdef'}FieldTable [] = {
9467c42e9eeSMasatake YAMATOEOF
9477c42e9eeSMasatake YAMATO    for (@{$opts->{'fielddefs'}}) {
9487c42e9eeSMasatake YAMATO      my $enabled = $_->{"enabled"}? "true": "false";
94916469a82SMasatake YAMATO      my $desc = escape_as_cstr $_->{'desc'};
9507c42e9eeSMasatake YAMATO      print <<EOF;
9517c42e9eeSMasatake YAMATO		{
9527c42e9eeSMasatake YAMATO		  .enabled     = $enabled,
9537c42e9eeSMasatake YAMATO		  .name        = "$_->{'name'}",
954352a49a0SMasatake YAMATO		  .description = "$desc",
9557c42e9eeSMasatake YAMATO		},
9567c42e9eeSMasatake YAMATOEOF
9577c42e9eeSMasatake YAMATO    }
9587c42e9eeSMasatake YAMATO    print <<EOF;
9597c42e9eeSMasatake YAMATO	};
9607c42e9eeSMasatake YAMATOEOF
9617c42e9eeSMasatake YAMATO}
9627c42e9eeSMasatake YAMATO
963c48fee31SMasatake YAMATOsub emit_selector {
964c48fee31SMasatake YAMATO    my $opts = shift;
965c48fee31SMasatake YAMATO
966c48fee31SMasatake YAMATO    if (defined $opts->{'selector'}) {
967c48fee31SMasatake YAMATO	print <<EOF;
968c48fee31SMasatake YAMATO	static selectLanguage selectors[] = { $opts->{'selector'}, NULL };
969c48fee31SMasatake YAMATOEOF
970c48fee31SMasatake YAMATO    }
971c48fee31SMasatake YAMATO}
972c48fee31SMasatake YAMATO
97328a3d08fSMasatake YAMATOsub emit_fields_initialization {
97428a3d08fSMasatake YAMATO    my $opts = shift;
975ce990805SThomas Braun    my $enabled = $opts->{"disabled"} ? "false": "true";
97628a3d08fSMasatake YAMATO    my $method;
9778a534dc5SMasatake YAMATO    my $sep;
978ec2a6441SMasatake YAMATO
97928a3d08fSMasatake YAMATO    $method  = "METHOD_NOT_CRAFTED";
98089c588f7SMasatake YAMATO    if (@{$opts->{"regexs"}} || $opts->{'tablenames'}) {
98128a3d08fSMasatake YAMATO	$method = "${method}|METHOD_REGEX";
98228a3d08fSMasatake YAMATO    }
983ec2a6441SMasatake YAMATO
98428a3d08fSMasatake YAMATO    print <<EOF;
985ec2a6441SMasatake YAMATO	def->enabled       = ${enabled};
986ec2a6441SMasatake YAMATO	def->extensions    = extensions;
987ec2a6441SMasatake YAMATO	def->patterns      = patterns;
988ec2a6441SMasatake YAMATO	def->aliases       = aliases;
989c48fee31SMasatake YAMATOEOF
990c48fee31SMasatake YAMATO    if (defined $opts->{'selector'}) {
991c48fee31SMasatake YAMATO	print <<EOF;
992c48fee31SMasatake YAMATO	def->selectLanguage= selectors;
993c48fee31SMasatake YAMATOEOF
994c48fee31SMasatake YAMATO    }
995c48fee31SMasatake YAMATOprint <<EOF;
996ec2a6441SMasatake YAMATO	def->method        = ${method};
997ec2a6441SMasatake YAMATOEOF
998ec2a6441SMasatake YAMATO
999377dfe59SMasatake YAMATO    if ($opts->{'useCork'}) {
1000377dfe59SMasatake YAMATO	print <<EOF;
10016b1a862eSMasatake YAMATO	def->useCork       = CORK_QUEUE;
1002377dfe59SMasatake YAMATOEOF
1003377dfe59SMasatake YAMATO    }
100454fa68c3SMasatake YAMATO    if (@{$opts->{'kinddefs'}}) {
100554fa68c3SMasatake YAMATO	print <<EOF;
100654fa68c3SMasatake YAMATO	def->kindTable     = $opts->{'Clangdef'}KindTable;
100754fa68c3SMasatake YAMATO	def->kindCount     = ARRAY_SIZE($opts->{'Clangdef'}KindTable);
100854fa68c3SMasatake YAMATOEOF
100954fa68c3SMasatake YAMATO    }
101054fa68c3SMasatake YAMATO
10117c42e9eeSMasatake YAMATO    if (@{$opts->{'fielddefs'}}) {
10127c42e9eeSMasatake YAMATO	print <<EOF;
10137c42e9eeSMasatake YAMATO	def->fieldTable    = $opts->{'Clangdef'}FieldTable;
10147c42e9eeSMasatake YAMATO	def->fieldCount    = ARRAY_SIZE($opts->{'Clangdef'}FieldTable);
10157c42e9eeSMasatake YAMATOEOF
10167c42e9eeSMasatake YAMATO    }
10177c42e9eeSMasatake YAMATO
10182b6707b2SMasatake YAMATO    if (@{$opts->{'extradefs'}}) {
10192b6707b2SMasatake YAMATO	print <<EOF;
10202b6707b2SMasatake YAMATO	def->xtagTable     = $opts->{'Clangdef'}XtagTable;
10212b6707b2SMasatake YAMATO	def->xtagCount     = ARRAY_SIZE($opts->{'Clangdef'}XtagTable);
10222b6707b2SMasatake YAMATOEOF
10232b6707b2SMasatake YAMATO    }
10242b6707b2SMasatake YAMATO
102528a3d08fSMasatake YAMATO    if (@{$opts->{'regexs'}}) {
102628a3d08fSMasatake YAMATO	print <<EOF;
102728a3d08fSMasatake YAMATO	def->tagRegexTable = $opts->{'Clangdef'}TagRegexTable;
102828a3d08fSMasatake YAMATO	def->tagRegexCount = ARRAY_SIZE($opts->{'Clangdef'}TagRegexTable);
1029ec2a6441SMasatake YAMATOEOF
1030ec2a6441SMasatake YAMATO    }
1031ec2a6441SMasatake YAMATO
103252b9d1f4SMasatake YAMATO    if (defined $opts->{'base'}) {
103352b9d1f4SMasatake YAMATO	print <<EOF;
103452b9d1f4SMasatake YAMATO	def->dependencies    = $opts->{'Clangdef'}Dependencies;
103552b9d1f4SMasatake YAMATO	def->dependencyCount = ARRAY_SIZE($opts->{'Clangdef'}Dependencies);
103652b9d1f4SMasatake YAMATOEOF
103752b9d1f4SMasatake YAMATO    }
103852b9d1f4SMasatake YAMATO
1039951dba0fSMasatake YAMATO    if ($opts->{'autoFQTag'}) {
1040951dba0fSMasatake YAMATO	print <<EOF;
1041951dba0fSMasatake YAMATO	def->requestAutomaticFQTag = true;
1042951dba0fSMasatake YAMATOEOF
1043951dba0fSMasatake YAMATO    }
1044d14b4a65SMasatake YAMATO
1045d14b4a65SMasatake YAMATO    if ($opts->{'defaultScopeSeparator'}) {
10468a534dc5SMasatake YAMATO	$sep = "$opts->{'defaultScopeSeparator'}";
104716469a82SMasatake YAMATO	$sep = escape_as_cstr "$sep";
1048d14b4a65SMasatake YAMATO	print <<EOF;
10498a534dc5SMasatake YAMATO	def->defaultScopeSeparator = "$sep";
1050d14b4a65SMasatake YAMATOEOF
1051d14b4a65SMasatake YAMATO    }
1052d14b4a65SMasatake YAMATO    if ($opts->{'defaultRootScopeSeparator'}) {
10538a534dc5SMasatake YAMATO	$sep = $opts->{'defaultRootScopeSeparator'};
105416469a82SMasatake YAMATO	$sep = escape_as_cstr "$sep";
1055d14b4a65SMasatake YAMATO	print <<EOF;
10568a534dc5SMasatake YAMATO	def->defaultRootScopeSeparator = "$sep";
1057d14b4a65SMasatake YAMATOEOF
1058d14b4a65SMasatake YAMATO    }
105928a3d08fSMasatake YAMATO    print <<EOF;
106028a3d08fSMasatake YAMATO	def->initialize    = initialize$opts->{'Clangdef'}Parser;
1061ec2a6441SMasatake YAMATO
1062ec2a6441SMasatake YAMATOEOF
1063ec2a6441SMasatake YAMATO}
1064ec2a6441SMasatake YAMATO
106528a3d08fSMasatake YAMATOsub emit {
106628a3d08fSMasatake YAMATO    my ($optlib, $opts) = @_;
106728a3d08fSMasatake YAMATO
106852b9d1f4SMasatake YAMATO    emit_header ($optlib, $opts);
1069d14b4a65SMasatake YAMATO
1070d14b4a65SMasatake YAMATO    if ($opts->{'hasSepSpeicifer'}) {
1071d14b4a65SMasatake YAMATO	emit_kinddef_enums   $opts;
1072d14b4a65SMasatake YAMATO    };
107328a3d08fSMasatake YAMATO    emit_initializer $opts;
107428a3d08fSMasatake YAMATO
107528a3d08fSMasatake YAMATO    print <<EOF;
107628a3d08fSMasatake YAMATOextern parserDefinition* $opts->{'Clangdef'}Parser (void)
1077ec2a6441SMasatake YAMATO{
107828a3d08fSMasatake YAMATOEOF
1079ec2a6441SMasatake YAMATO
108028a3d08fSMasatake YAMATO    emit_extensions      $opts;
108128a3d08fSMasatake YAMATO    emit_aliases         $opts;
108228a3d08fSMasatake YAMATO    emit_patterns        $opts;
1083dff7c6b0SMasatake YAMATO    emit_roledefs        $opts;
1084d14b4a65SMasatake YAMATO    emit_scopeseps       $opts;
108554fa68c3SMasatake YAMATO    emit_kinddefs        $opts;
10867c42e9eeSMasatake YAMATO    emit_fields          $opts;
10872b6707b2SMasatake YAMATO    emit_xtags           $opts;
108828a3d08fSMasatake YAMATO    emit_regexs          $opts;
108952b9d1f4SMasatake YAMATO    emit_dependencies    $opts;
1090c48fee31SMasatake YAMATO    emit_selector         $opts;
1091ec2a6441SMasatake YAMATO
109228a3d08fSMasatake YAMATO    print "\n";
1093ec2a6441SMasatake YAMATO
109428a3d08fSMasatake YAMATO    print <<EOF;
109528a3d08fSMasatake YAMATO	parserDefinition* const def = parserNew ("$opts->{'langdef'}");
109628a3d08fSMasatake YAMATO
109728a3d08fSMasatake YAMATOEOF
109828a3d08fSMasatake YAMATO
109928a3d08fSMasatake YAMATO    emit_fields_initialization $opts;
110028a3d08fSMasatake YAMATO
110128a3d08fSMasatake YAMATO    print <<EOF;
110228a3d08fSMasatake YAMATO	return def;
110328a3d08fSMasatake YAMATO}
110428a3d08fSMasatake YAMATOEOF
1105ec2a6441SMasatake YAMATO}
1106ec2a6441SMasatake YAMATO
110728a3d08fSMasatake YAMATO########################################################################
110828a3d08fSMasatake YAMATO#
110928a3d08fSMasatake YAMATO# REARRANGE
111028a3d08fSMasatake YAMATO#
111128a3d08fSMasatake YAMATO########################################################################
111228a3d08fSMasatake YAMATO
1113a6c7dca8SMasatake YAMATOsub capitalize {
1114a6c7dca8SMasatake YAMATO    my ($str) = $_[0];
1115a6c7dca8SMasatake YAMATO    my $c = substr ($str, 0, 1);
111628a3d08fSMasatake YAMATO
111728a3d08fSMasatake YAMATO    $c =~ tr/a-z/A-Z/;
111828a3d08fSMasatake YAMATO
1119a6c7dca8SMasatake YAMATO    return $c . substr($str, 1);
1120a6c7dca8SMasatake YAMATO}
1121a6c7dca8SMasatake YAMATO
1122a6c7dca8SMasatake YAMATOsub rearrange {
1123a6c7dca8SMasatake YAMATO    my ($opts) = @_;
1124a6c7dca8SMasatake YAMATO    my $langdef = $opts -> {'langdef'};
1125a6c7dca8SMasatake YAMATO    $opts -> {'Clangdef'} = capitalize ($langdef);
112628a3d08fSMasatake YAMATO}
112728a3d08fSMasatake YAMATO
112828a3d08fSMasatake YAMATO
112928a3d08fSMasatake YAMATO########################################################################
113028a3d08fSMasatake YAMATO#
113128a3d08fSMasatake YAMATO# MAIN
113228a3d08fSMasatake YAMATO#
113328a3d08fSMasatake YAMATO########################################################################
113428a3d08fSMasatake YAMATO
113528a3d08fSMasatake YAMATOsub main {
113628a3d08fSMasatake YAMATO    my $optlib;
113728a3d08fSMasatake YAMATO    my %opts = (langdef  => undef,
113828a3d08fSMasatake YAMATO		Clangdef => undef,
113928a3d08fSMasatake YAMATO		disabled => 0,
114028a3d08fSMasatake YAMATO		patterns => [],
114128a3d08fSMasatake YAMATO		extensions => [],
114228a3d08fSMasatake YAMATO		aliases => [],
11432d9e0a35SMasatake YAMATO		regexs => [# { regex => "", name => "", kind => "", flags => "", mline => 1|0, optscript => "" },
114428a3d08fSMasatake YAMATO			  ],
1145d14b4a65SMasatake YAMATO		kinddefs => [# { letter => '', name => "", desc => "",
1146d14b4a65SMasatake YAMATO			     #   seps => [ {parentKindIndex => "", sep => "" } ]
1147d14b4a65SMasatake YAMATO			     # },
114854fa68c3SMasatake YAMATO			    ],
11492b6707b2SMasatake YAMATO		extradefs => [ # { name => "", desc => "", enabled => 1|0 },
11502b6707b2SMasatake YAMATO			     ],
11517c42e9eeSMasatake YAMATO		fielddefs => [ # { name => "", desc => "", enabled => 1|0 },
11527c42e9eeSMasatake YAMATO			      ],
115352b9d1f4SMasatake YAMATO		base => undef,
115489c588f7SMasatake YAMATO		tableNames => [ # ""
115589c588f7SMasatake YAMATO			       ],
115689c588f7SMasatake YAMATO		tabledefs => { # "" => [{ regex => "", name => "", kind => "", flags => "" }...],
115789c588f7SMasatake YAMATO			     },
115889c588f7SMasatake YAMATO		useCork   => 0,
1159d14b4a65SMasatake YAMATO		defaultScopeSeparator => undef,
1160d14b4a65SMasatake YAMATO		defaultRootScopeSeparator => undef,
1161d14b4a65SMasatake YAMATO		hasSepSpeicifer => 0,
11622d9e0a35SMasatake YAMATO		prelude => [ # ""
11632d9e0a35SMasatake YAMATO			   ],
11641409a195SMasatake YAMATO		sequel =>  [ # ""
11651409a195SMasatake YAMATO			   ],
1166c48fee31SMasatake YAMATO		selector => undef,
116728a3d08fSMasatake YAMATO	       );
116828a3d08fSMasatake YAMATO
116928a3d08fSMasatake YAMATO    for (@_) {
117028a3d08fSMasatake YAMATO	if ( ($_ eq '-h') || ($_ eq '--help') ) {
117128a3d08fSMasatake YAMATO	    show_help;
117228a3d08fSMasatake YAMATO	    exit 0;
117328a3d08fSMasatake YAMATO	} elsif ( /^-.*/ ) {
117428a3d08fSMasatake YAMATO	    die "unrecongnized option: $_";
117528a3d08fSMasatake YAMATO	} else {
117628a3d08fSMasatake YAMATO	    if ($optlib) {
117728a3d08fSMasatake YAMATO		die "Too man input files: @_";
117828a3d08fSMasatake YAMATO	    }
117928a3d08fSMasatake YAMATO	    $optlib=$_;
118028a3d08fSMasatake YAMATO	}
118128a3d08fSMasatake YAMATO    }
118228a3d08fSMasatake YAMATO
118328a3d08fSMasatake YAMATO    if (! $optlib) {
118428a3d08fSMasatake YAMATO	die "No optlib file name is given";
118528a3d08fSMasatake YAMATO    }
118628a3d08fSMasatake YAMATO
118728a3d08fSMasatake YAMATO    if (! parse_optlib ($optlib, \%opts)) {
118828a3d08fSMasatake YAMATO	exit 1;
118928a3d08fSMasatake YAMATO    }
119028a3d08fSMasatake YAMATO
11913e7e9e07SMasatake YAMATO    rearrange (\%opts);
119228a3d08fSMasatake YAMATO
119328a3d08fSMasatake YAMATO    if (! emit ($optlib, \%opts) ) {
119428a3d08fSMasatake YAMATO	exit 1;
119528a3d08fSMasatake YAMATO    }
119628a3d08fSMasatake YAMATO    0;
119728a3d08fSMasatake YAMATO}
119828a3d08fSMasatake YAMATO
119928a3d08fSMasatake YAMATOmain @ARGV;
120028a3d08fSMasatake YAMATO
120128a3d08fSMasatake YAMATO# optlib2c ends here.
1202