~ubuntu-branches/debian/experimental/apt/experimental

« back to all changes in this revision

Viewing changes to abicheck/abi-compliance-checker.pl

  • Committer: Bazaar Package Importer
  • Author(s): Michael Vogt
  • Date: 2010-02-18 22:07:23 UTC
  • mfrom: (9.1.7 sid)
  • Revision ID: james.westby@ubuntu.com-20100218220723-zb7zdh6fmsmp30tr
Tags: 0.7.26~exp2
fix crash when LANGUAGE is not set

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/perl
 
2
###########################################################################
 
3
# ABI-compliance-checker v1.13, lightweight tool for statically checking
 
4
# backward binary compatibility of shared C/C++ libraries in Linux.
 
5
# Copyright (C) The Linux Foundation
 
6
# Copyright (C) Institute for System Programming, RAS
 
7
# Author: Andrey Ponomarenko
 
8
#
 
9
# This program is free software: you can redistribute it and/or modify
 
10
# it under the terms of the GNU General Public License as published by
 
11
# the Free Software Foundation, either version 2 of the License, or
 
12
# (at your option) any later version.
 
13
#
 
14
# This program is distributed in the hope that it will be useful,
 
15
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
16
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
17
# GNU General Public License for more details.
 
18
#
 
19
# You should have received a copy of the GNU General Public License
 
20
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
21
###########################################################################
 
22
use Getopt::Long;
 
23
Getopt::Long::Configure ("posix_default", "no_ignore_case");
 
24
use Data::Dumper;
 
25
 
 
26
my $ABI_COMPLIANCE_CHECKER_VERSION = "1.13";
 
27
my ($Help, $ShowVersion, %Descriptor, $TargetLibraryName, $HeaderCheckingMode_Separately, $GenerateDescriptor, $TestSystem, $DumpInfo_DescriptorPath, $CheckHeadersOnly, $InterfacesListPath, $AppPath, $ShowExpendTime);
 
28
 
 
29
my $CmdName = get_FileName($0);
 
30
GetOptions("h|help!" => \$Help,
 
31
  "v|version!" => \$ShowVersion,
 
32
#general options
 
33
  "l|library=s" => \$TargetLibraryName,
 
34
  "d1|descriptor1=s" => \$Descriptor{1}{"Path"},
 
35
  "d2|descriptor2=s" => \$Descriptor{2}{"Path"},
 
36
#extra options
 
37
  "app|application=s" => \$AppPath,
 
38
  "symbols_list|int_list=s" => \$InterfacesListPath,
 
39
  "dump_abi|dump_info=s" => \$DumpInfo_DescriptorPath,
 
40
  "headers_only!" => \$CheckHeadersOnly,
 
41
#other options
 
42
  "d|descriptor_template!" => \$GenerateDescriptor,
 
43
  "separately!" => \$HeaderCheckingMode_Separately,
 
44
  "test!" => \$TestSystem,
 
45
  "time!" => \$ShowExpendTime
 
46
) or exit(1);
 
47
 
 
48
sub HELP_MESSAGE()
 
49
{
 
50
    print STDERR <<"EOM"
 
51
 
 
52
NAME:
 
53
  $CmdName - check ABI compatibility of shared C/C++ library versions
 
54
 
 
55
DESCRIPTION:
 
56
  Lightweight tool for statically checking backward binary compatibility of shared C/C++ libraries
 
57
  in Linux. It checks header files along with shared objects in two library versions and searches
 
58
  for ABI changes that may lead to incompatibility. Breakage of the binary compatibility may result
 
59
  in crashing or incorrect behavior of applications built with an old version of a library when
 
60
  it is running with a new one.
 
61
 
 
62
  ABI Compliance Checker was intended for library developers that are interested in ensuring
 
63
  backward binary compatibility. Also it can be used for checking forward binary compatibility
 
64
  and checking applications portability to the new library version.
 
65
  
 
66
  This tool is free software: you can redistribute it and/or modify it under the terms of the GNU GPL.
 
67
 
 
68
USAGE:
 
69
  $CmdName [options]
 
70
 
 
71
EXAMPLE OF USE:
 
72
  $CmdName -l <library_name> -d1 <1st_version_descriptor> -d2 <2nd_version_descriptor>
 
73
 
 
74
GENERAL OPTIONS:
 
75
  -h|-help
 
76
      Print this help.
 
77
 
 
78
  -v|-version
 
79
      Print version.
 
80
 
 
81
  -l|-library <name>
 
82
      Library name (without version).
 
83
      It affects only on the path and the title of the report.
 
84
 
 
85
  -d1|-descriptor1 <path>
 
86
      Path to descriptor of 1st library version.
 
87
 
 
88
  -d2|-descriptor2 <path>
 
89
      Path to descriptor of 2nd library version.
 
90
 
 
91
EXTRA OPTIONS:
 
92
  -app|-application <path>
 
93
      This option allow to specify the application that should be tested for portability
 
94
      to the new library version.
 
95
 
 
96
  -dump_abi|-dump_info <descriptor_path>
 
97
      Dump library ABI information using specified descriptor.
 
98
      This command will create '<library>_<ver1>.abi.tar.gz' file in the directory 'abi_dumps/<library>/'.
 
99
      You can transfer it anywhere and pass instead of library descriptor.
 
100
 
 
101
  -headers_only
 
102
      Check header files without shared objects. It is easy to run, but may provide
 
103
      a low quality ABI compliance report with false positives and without
 
104
      detecting of added/withdrawn interfaces.
 
105
 
 
106
  -symbols_list|-int_list <path>
 
107
      This option allow to specify a file with a list of interfaces (mangled names in C++)
 
108
      that should be checked, other library interfaces will not be checked.
 
109
 
 
110
OTHER OPTIONS:
 
111
  -d|-descriptor_template
 
112
      Create library descriptor template 'library-descriptor.xml' in the current directory.
 
113
 
 
114
  -separately
 
115
      Check headers individually. This mode requires more time for checking ABI compliance,
 
116
      but possible compiler errors in one header can't affect others.
 
117
 
 
118
  -test
 
119
      Run internal tests (create two binary-incompatible versions of an artificial library
 
120
      and run ABI-Compliance-Checker on it).
 
121
 
 
122
DESCRIPTOR EXAMPLE:
 
123
  <version>
 
124
     1.28.0
 
125
  </version>
 
126
 
 
127
  <headers>
 
128
     /usr/local/atk/atk-1.28.0/include/
 
129
  </headers>
 
130
 
 
131
  <libs>
 
132
     /usr/local/atk/atk-1.28.0/lib/libatk-1.0.so
 
133
  </libs>
 
134
 
 
135
  <include_paths>
 
136
     /usr/include/glib-2.0/
 
137
     /usr/lib/glib-2.0/include/
 
138
  </include_paths>
 
139
 
 
140
 
 
141
Report bugs to <abi-compliance-checker\@linuxtesting.org>
 
142
For more information, please see: http://ispras.linux-foundation.org/index.php/ABI_compliance_checker
 
143
EOM
 
144
      ;
 
145
}
 
146
 
 
147
my $Descriptor_Template = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
 
148
<descriptor>
 
149
 
 
150
<!-- Template for the library version descriptor -->
 
151
 
 
152
<!--
 
153
     Necessary sections  
 
154
                        -->
 
155
 
 
156
<version>
 
157
    <!-- Version of the library -->
 
158
</version>
 
159
 
 
160
<headers>
 
161
    <!-- The list of paths to header files and/or
 
162
         directories with header files, one per line -->
 
163
</headers>
 
164
 
 
165
<libs>
 
166
    <!-- The list of paths to shared objects and/or
 
167
         directories with shared objects, one per line -->
 
168
</libs>
 
169
 
 
170
<!--
 
171
     Additional sections
 
172
                         -->
 
173
 
 
174
<include_paths>
 
175
    <!-- The list of paths to be searched for header files
 
176
         needed for compiling of library headers, one per line -->
 
177
</include_paths>
 
178
 
 
179
<gcc_options>
 
180
    <!-- Additional gcc options, one per line -->
 
181
</gcc_options>
 
182
 
 
183
<opaque_types>
 
184
    <!-- The list of opaque types, one per line -->
 
185
</opaque_types>
 
186
 
 
187
<skip_interfaces>
 
188
    <!-- The list of functions (mangled/symbol names in C++)
 
189
         that should be skipped while testing, one per line -->
 
190
</skip_interfaces>
 
191
 
 
192
<include_preamble>
 
193
    <!-- The list of header files that should be included before other headers, one per line.
 
194
         For example, it is a tree.h for libxml2 and ft2build.h for freetype2 -->
 
195
</include_preamble>
 
196
 
 
197
</descriptor>";
 
198
 
 
199
my %Operator_Indication = (
 
200
"not" => "~",
 
201
"assign" => "=",
 
202
"andassign" => "&=",
 
203
"orassign" => "|=",
 
204
"xorassign" => "^=",
 
205
"or" => "|",
 
206
"xor" => "^",
 
207
"addr" => "&",
 
208
"and" => "&",
 
209
"lnot" => "!",
 
210
"eq" => "==",
 
211
"ne" => "!=",
 
212
"lt" => "<",
 
213
"lshift" => "<<",
 
214
"lshiftassign" => "<<=",
 
215
"rshiftassign" => ">>=",
 
216
"call" => "()",
 
217
"mod" => "%",
 
218
"modassign" => "%=",
 
219
"subs" => "[]",
 
220
"land" => "&&",
 
221
"lor" => "||",
 
222
"rshift" => ">>",
 
223
"ref" => "->",
 
224
"le" => "<=",
 
225
"deref" => "*",
 
226
"mult" => "*",
 
227
"preinc" => "++",
 
228
"delete" => " delete",
 
229
"vecnew" => " new[]",
 
230
"vecdelete" => " delete[]",
 
231
"predec" => "--",
 
232
"postinc" => "++",
 
233
"postdec" => "--",
 
234
"plusassign" => "+=",
 
235
"plus" => "+",
 
236
"minus" => "-",
 
237
"minusassign" => "-=",
 
238
"gt" => ">",
 
239
"ge" => ">=",
 
240
"new" => " new",
 
241
"multassign" => "*=",
 
242
"divassign" => "/=",
 
243
"div" => "/",
 
244
"neg" => "-",
 
245
"pos" => "+",
 
246
"memref" => "->*",
 
247
"compound" => ","
 
248
);
 
249
 
 
250
sub num_to_str($)
 
251
{
 
252
    my $Number = $_[0];
 
253
    if(int($Number)>3)
 
254
    {
 
255
        return $Number."th";
 
256
    }
 
257
    elsif(int($Number)==1)
 
258
    {
 
259
        return "1st";
 
260
    }
 
261
    elsif(int($Number)==2)
 
262
    {
 
263
        return "2nd";
 
264
    }
 
265
    elsif(int($Number)==3)
 
266
    {
 
267
        return "3rd";
 
268
    }
 
269
    else
 
270
    {
 
271
        return "";
 
272
    }
 
273
}
 
274
 
 
275
#Global variables
 
276
my $REPORT_PATH;
 
277
my %ERR_PATH;
 
278
my $POINTER_SIZE;
 
279
my $MAX_COMMAND_LINE_ARGUMENTS = 4096;
 
280
my %Cache;
 
281
my %FuncAttr;
 
282
my %LibInfo;
 
283
my %HeaderCompileError;
 
284
my $StartTime;
 
285
my %CompilerOptions;
 
286
my %AddedInt;
 
287
my %WithdrawnInt;
 
288
my @RecurLib;
 
289
my %CheckedSoLib;
 
290
 
 
291
#Constants checking
 
292
my %ConstantsSrc;
 
293
my %Constants;
 
294
 
 
295
#Types
 
296
my %TypeDescr;
 
297
my %TemplateInstance_Func;
 
298
my %TemplateInstance;
 
299
my %OpaqueTypes;
 
300
my %Tid_TDid;
 
301
my %CheckedTypes;
 
302
my %Typedef_BaseName;
 
303
my %StdCxxTypedef;
 
304
my %TName_Tid;
 
305
my %EnumMembName_Id;
 
306
 
 
307
#Interfaces
 
308
my %FuncDescr;
 
309
my %ClassFunc;
 
310
my %ClassVirtFunc;
 
311
my %ClassIdVirtFunc;
 
312
my %ClassId;
 
313
my %tr_name;
 
314
my %mangled_name;
 
315
my %InternalInterfaces;
 
316
my %InterfacesList;
 
317
my %InterfacesList_App;
 
318
my %CheckedInterfaces;
 
319
my %DepInterfaces;
 
320
 
 
321
#Headers
 
322
my %Include_Preamble;
 
323
my %Headers;
 
324
my %HeaderName_Destinations;
 
325
my %Header_Dependency;
 
326
 
 
327
#Shared objects
 
328
my %SoLib_DefaultPath;
 
329
 
 
330
#Merging
 
331
my %CompleteSignature;
 
332
my @RecurTypes;
 
333
my %Interface_Library;
 
334
my %Library_Interface;
 
335
my %Language;
 
336
my %SoNames_All;
 
337
my $Version;
 
338
 
 
339
#Symbols versioning
 
340
my %SymVer;
 
341
 
 
342
#Problem descriptions
 
343
my %CompatProblems;
 
344
my %ConstantProblems;
 
345
 
 
346
#Rerorts
 
347
my $ContentID = 1;
 
348
my $ContentSpanStart = "<span class=\"section\" onclick=\"javascript:showContent(this, 'CONTENT_ID')\">\n";
 
349
my $ContentSpanEnd = "</span>\n";
 
350
my $ContentDivStart = "<div id=\"CONTENT_ID\" style=\"display:none;\">\n";
 
351
my $ContentDivEnd = "</div>\n";
 
352
my $Content_Counter = 0;
 
353
 
 
354
sub readDescriptor($)
 
355
{
 
356
    my $LibVersion = $_[0];
 
357
    if(not -e $Descriptor{$LibVersion}{"Path"})
 
358
    {
 
359
        return;
 
360
    }
 
361
    my $Descriptor_File = readFile($Descriptor{$LibVersion}{"Path"});
 
362
    $Descriptor_File =~ s/\/\*(.|\n)+?\*\///g;
 
363
    $Descriptor_File =~ s/<\!--(.|\n)+?-->//g;
 
364
    if(not $Descriptor_File)
 
365
    {
 
366
        print "ERROR: descriptor d$LibVersion is empty\n";
 
367
        exit(1);
 
368
    }
 
369
    $Descriptor{$LibVersion}{"Version"} = parseTag(\$Descriptor_File, "version");
 
370
    if(not $Descriptor{$LibVersion}{"Version"})
 
371
    {
 
372
        print "ERROR: version in the descriptor d$LibVersion was not specified (section <version>)\n\n";
 
373
        exit(1);
 
374
    }
 
375
    $Descriptor{$LibVersion}{"Headers"} = parseTag(\$Descriptor_File, "headers");
 
376
    if(not $Descriptor{$LibVersion}{"Headers"})
 
377
    {
 
378
        print "ERROR: header files in the descriptor d$LibVersion were not specified (section <headers>)\n";
 
379
        exit(1);
 
380
    }
 
381
    if(not $CheckHeadersOnly)
 
382
    {
 
383
        $Descriptor{$LibVersion}{"Libs"} = parseTag(\$Descriptor_File, "libs");
 
384
        if(not $Descriptor{$LibVersion}{"Libs"})
 
385
        {
 
386
            print "ERROR: shared objects in the descriptor d$LibVersion were not specified (section <libs>)\n";
 
387
            exit(1);
 
388
        }
 
389
    }
 
390
    $Descriptor{$LibVersion}{"Include_Paths"} = parseTag(\$Descriptor_File, "include_paths");
 
391
    $Descriptor{$LibVersion}{"Gcc_Options"} = parseTag(\$Descriptor_File, "gcc_options");
 
392
    foreach my $Option (split("\n", $Descriptor{$LibVersion}{"Gcc_Options"}))
 
393
    {
 
394
        $Option =~ s/\A\s+|\s+\Z//g;
 
395
        next if(not $Option);
 
396
        $CompilerOptions{$LibVersion} .= " ".$Option;
 
397
    }
 
398
    $Descriptor{$LibVersion}{"Opaque_Types"} = parseTag(\$Descriptor_File, "opaque_types");
 
399
    foreach my $Type_Name (split("\n", $Descriptor{$LibVersion}{"Opaque_Types"}))
 
400
    {
 
401
        $Type_Name =~ s/\A\s+|\s+\Z//g;
 
402
        next if(not $Type_Name);
 
403
        $OpaqueTypes{$LibVersion}{$Type_Name} = 1;
 
404
    }
 
405
    $Descriptor{$LibVersion}{"Skip_interfaces"} = parseTag(\$Descriptor_File, "skip_interfaces");
 
406
    foreach my $Interface_Name (split("\n", $Descriptor{$LibVersion}{"Skip_interfaces"}))
 
407
    {
 
408
        $Interface_Name =~ s/\A\s+|\s+\Z//g;
 
409
        next if(not $Interface_Name);
 
410
        $InternalInterfaces{$LibVersion}{$Interface_Name} = 1;
 
411
    }
 
412
    $Descriptor{$LibVersion}{"Include_Preamble"} = parseTag(\$Descriptor_File, "include_preamble");
 
413
    my $Position = 0;
 
414
    foreach my $Header_Name (split("\n", $Descriptor{$LibVersion}{"Include_Preamble"}))
 
415
    {
 
416
        $Header_Name =~ s/\A\s+|\s+\Z//g;
 
417
        next if(not $Header_Name);
 
418
        $Include_Preamble{$LibVersion}{$Header_Name}{"Position"} = $Position;
 
419
        $Position+=1;
 
420
    }
 
421
    my $Descriptors_Dir = "descriptors_storage/$TargetLibraryName";
 
422
    system("mkdir", "-p", $Descriptors_Dir);
 
423
    my $Descriptor_Name = $TargetLibraryName."_".$Descriptor{$LibVersion}{"Version"}.".desc";
 
424
    if($Descriptor{$LibVersion}{"Path"} ne $Descriptors_Dir."/".$Descriptor_Name)
 
425
    {
 
426
        system("cp", "-f", $Descriptor{$LibVersion}{"Path"}, $Descriptors_Dir."/".$Descriptor_Name);
 
427
    }
 
428
    $ERR_PATH{$LibVersion} = "header_compile_errors/$TargetLibraryName/".$Descriptor{$LibVersion}{"Version"};
 
429
}
 
430
 
 
431
sub parseTag($$)
 
432
{
 
433
    my ($CodeRef, $Tag) = @_;
 
434
    return "" if(not $CodeRef or not ${$CodeRef} or not $Tag);
 
435
    if(${$CodeRef} =~ s/\<$Tag\>((.|\n)+?)\<\/$Tag\>//)
 
436
    {
 
437
        my $Content = $1;
 
438
        $Content=~s/(\A\s+|\s+\Z)//g;
 
439
        return $Content;
 
440
    }
 
441
    else
 
442
    {
 
443
        return "";
 
444
    }
 
445
}
 
446
 
 
447
my %check_node=(
 
448
"array_type"=>1,
 
449
"binfo"=>1,
 
450
"boolean_type"=>1,
 
451
"complex_type"=>1,
 
452
"const_decl"=>1,
 
453
"enumeral_type"=>1,
 
454
"field_decl"=>1,
 
455
"function_decl"=>1,
 
456
"function_type"=>1,
 
457
"identifier_node"=>1,
 
458
"integer_cst"=>1,
 
459
"integer_type"=>1,
 
460
"method_type"=>1,
 
461
"namespace_decl"=>1,
 
462
"parm_decl"=>1,
 
463
"pointer_type"=>1,
 
464
"real_cst"=>1,
 
465
"real_type"=>1,
 
466
"record_type"=>1,
 
467
"reference_type"=>1,
 
468
"string_cst"=>1,
 
469
"template_decl"=>1,
 
470
"template_type_parm"=>1,
 
471
"tree_list"=>1,
 
472
"tree_vec"=>1,
 
473
"type_decl"=>1,
 
474
"union_type"=>1,
 
475
"var_decl"=>1,
 
476
"void_type"=>1);
 
477
 
 
478
sub getInfo($)
 
479
{
 
480
        my $InfoPath = $_[0];
 
481
    return if(not $InfoPath or not -f $InfoPath);
 
482
    my $InfoPath_New = $InfoPath.".1";
 
483
    #my $Keywords = join("\\|", keys(%check_node));#|grep "$Keywords"
 
484
    system("sed ':a;N;\$!ba;s/\\n[^\@]//g' ".esc($InfoPath)."|sed 's/ [ ]\\+/  /g' > ".esc($InfoPath_New));
 
485
    system("rm", "-fr", $InfoPath);
 
486
    #getting info
 
487
    open(INFO, $InfoPath_New) || die ("can't open file '\$InfoPath_New\': $!\n");
 
488
    while(<INFO>)
 
489
    {
 
490
        chomp;
 
491
        if(/\A@([0-9]+)[ ]+([a-zA-Z_]+)[ ]+(.*)\Z/)
 
492
        {
 
493
            next if(not $check_node{$2});
 
494
            $LibInfo{$Version}{$1}{"info_type"}=$2;
 
495
            $LibInfo{$Version}{$1}{"info"}=$3;
 
496
        }
 
497
    }
 
498
    close(INFO);
 
499
    system("rm", "-fr", $InfoPath_New);
 
500
    #processing info
 
501
        setTemplateParams_All();
 
502
        getTypeDescr_All();
 
503
        getFuncDescr_All();
 
504
        getVarDescr_All();
 
505
    %LibInfo = ();
 
506
    %TemplateInstance = ();
 
507
}
 
508
 
 
509
sub setTemplateParams_All()
 
510
{
 
511
    foreach (keys(%{$LibInfo{$Version}}))
 
512
    {
 
513
        if($LibInfo{$Version}{$_}{"info_type"} eq "template_decl")
 
514
        {
 
515
            setTemplateParams($_);
 
516
        }
 
517
    }
 
518
}
 
519
 
 
520
sub setTemplateParams($)
 
521
{
 
522
    my $TypeInfoId = $_[0];
 
523
    my $Info = $LibInfo{$Version}{$TypeInfoId}{"info"};
 
524
    if($Info =~ /(inst|spcs)[ ]*:[ ]*@([0-9]+) /)
 
525
    {
 
526
        my $TmplInst_InfoId = $2;
 
527
        setTemplateInstParams($TmplInst_InfoId);
 
528
        my $TmplInst_Info = $LibInfo{$Version}{$TmplInst_InfoId}{"info"};
 
529
        while($TmplInst_Info =~ /chan[ ]*:[ ]*@([0-9]+) /)
 
530
        {
 
531
            $TmplInst_InfoId = $1;
 
532
            $TmplInst_Info = $LibInfo{$Version}{$TmplInst_InfoId}{"info"};
 
533
            setTemplateInstParams($TmplInst_InfoId);
 
534
        }
 
535
    }
 
536
}
 
537
 
 
538
sub setTemplateInstParams($)
 
539
{
 
540
    my $TmplInst_Id = $_[0];
 
541
    my $Info = $LibInfo{$Version}{$TmplInst_Id}{"info"};
 
542
    my ($Params_InfoId, $ElemId) = ();
 
543
    if($Info =~ /purp[ ]*:[ ]*@([0-9]+) /)
 
544
    {
 
545
        $Params_InfoId = $1;
 
546
    }
 
547
    if($Info =~ /valu[ ]*:[ ]*@([0-9]+) /)
 
548
    {
 
549
        $ElemId = $1;
 
550
    }
 
551
    if($Params_InfoId and $ElemId)
 
552
    {
 
553
        my $Params_Info = $LibInfo{$Version}{$Params_InfoId}{"info"};
 
554
        while($Params_Info =~ s/ ([0-9]+)[ ]*:[ ]*@([0-9]+) //)
 
555
        {
 
556
            my ($Param_Pos, $Param_TypeId) = ($1, $2);
 
557
            return if($LibInfo{$Version}{$Param_TypeId}{"info_type"} eq "template_type_parm");
 
558
            if($LibInfo{$ElemId}{"info_type"} eq "function_decl")
 
559
            {
 
560
                $TemplateInstance_Func{$Version}{$ElemId}{$Param_Pos} = $Param_TypeId;
 
561
            }
 
562
            else
 
563
            {
 
564
                $TemplateInstance{$Version}{getTypeDeclId($ElemId)}{$ElemId}{$Param_Pos} = $Param_TypeId;
 
565
            }
 
566
        }
 
567
    }
 
568
}
 
569
 
 
570
sub getTypeDeclId($)
 
571
{
 
572
        my $TypeInfo = $LibInfo{$Version}{$_[0]}{"info"};
 
573
        if($TypeInfo =~ /name[ ]*:[ ]*@([0-9]+)/)
 
574
    {
 
575
        return $1;
 
576
    }
 
577
    else
 
578
    {
 
579
        return "";
 
580
    }
 
581
}
 
582
 
 
583
sub isFuncPtr($)
 
584
{
 
585
    my $Ptd = pointTo($_[0]);
 
586
        if($Ptd)
 
587
        {
 
588
                if(($LibInfo{$Version}{$_[0]}{"info"} =~ m/unql[ ]*:/) and not ($LibInfo{$Version}{$_[0]}{"info"} =~ m/qual[ ]*:/))
 
589
                {
 
590
                        return 0;
 
591
                }
 
592
                elsif(($LibInfo{$Version}{$_[0]}{"info_type"} eq "pointer_type") and ($LibInfo{$Version}{$Ptd}{"info_type"} eq "function_type" or $LibInfo{$Version}{$Ptd}{"info_type"} eq "method_type"))
 
593
                {
 
594
                        return 1;
 
595
                }
 
596
                else
 
597
                {
 
598
                        return 0;
 
599
                }
 
600
        }
 
601
        else
 
602
        {
 
603
                return 0;
 
604
        }
 
605
}
 
606
 
 
607
sub pointTo($)
 
608
{
 
609
        my $TypeInfo = $LibInfo{$Version}{$_[0]}{"info"};
 
610
        if($TypeInfo =~ /ptd[ ]*:[ ]*@([0-9]+)/)
 
611
    {
 
612
            return $1;
 
613
    }
 
614
    else
 
615
    {
 
616
        return "";
 
617
    }
 
618
}
 
619
 
 
620
sub getTypeDescr_All()
 
621
{
 
622
    foreach (sort {int($a)<=>int($b)} keys(%{$LibInfo{$Version}}))
 
623
    {
 
624
        if($LibInfo{$Version}{$_}{"info_type"}=~/_type\Z/ and $LibInfo{$Version}{$_}{"info_type"}!~/function_type|method_type/)
 
625
        {
 
626
            getTypeDescr(getTypeDeclId($_), $_);
 
627
        }
 
628
    }
 
629
    $TypeDescr{$Version}{""}{-1}{"Name"} = "...";
 
630
    $TypeDescr{$Version}{""}{-1}{"Type"} = "Intrinsic";
 
631
    $TypeDescr{$Version}{""}{-1}{"Tid"} = -1;
 
632
}
 
633
 
 
634
sub getTypeDescr($$)
 
635
{
 
636
    my ($TypeDeclId, $TypeId) = @_;
 
637
    $Tid_TDid{$Version}{$TypeId} = $TypeDeclId;
 
638
    %{$TypeDescr{$Version}{$TypeDeclId}{$TypeId}} = getTypeAttr($TypeDeclId, $TypeId);
 
639
    if(not $TypeDescr{$Version}{$TypeDeclId}{$TypeId}{"Name"})
 
640
    {
 
641
        delete($TypeDescr{$Version}{$TypeDeclId}{$TypeId});
 
642
        return;
 
643
    }
 
644
    if(not $TName_Tid{$Version}{$TypeDescr{$Version}{$TypeDeclId}{$TypeId}{"Name"}})
 
645
    {
 
646
        $TName_Tid{$Version}{$TypeDescr{$Version}{$TypeDeclId}{$TypeId}{"Name"}} = $TypeId;
 
647
    }
 
648
}
 
649
 
 
650
sub getTypeAttr($$)
 
651
{
 
652
    my ($TypeDeclId, $TypeId) = @_;
 
653
    my ($BaseTypeSpec, %TypeAttr) = ();
 
654
    if($TypeDescr{$Version}{$TypeDeclId}{$TypeId}{"Name"})
 
655
    {
 
656
        return %{$TypeDescr{$Version}{$TypeDeclId}{$TypeId}};
 
657
    }
 
658
    $TypeAttr{"Tid"} = $TypeId;
 
659
    $TypeAttr{"TDid"} = $TypeDeclId;
 
660
    $TypeAttr{"Type"} = getTypeType($TypeDeclId, $TypeId);
 
661
    if($TypeAttr{"Type"} eq "Unknown")
 
662
    {
 
663
        return ();
 
664
    }
 
665
    elsif($TypeAttr{"Type"} eq "FuncPtr")
 
666
    {
 
667
        %{$TypeDescr{$Version}{$TypeDeclId}{$TypeId}} = getFuncPtrAttr(pointTo($TypeId), $TypeDeclId, $TypeId);
 
668
        $TName_Tid{$Version}{$TypeDescr{$Version}{$TypeDeclId}{$TypeId}{"Name"}} = $TypeId;
 
669
        return %{$TypeDescr{$Version}{$TypeDeclId}{$TypeId}};
 
670
    }
 
671
    elsif($TypeAttr{"Type"} eq "Array")
 
672
    {
 
673
        ($TypeAttr{"BaseType"}{"Tid"}, $TypeAttr{"BaseType"}{"TDid"}, $BaseTypeSpec) = selectBaseType($TypeDeclId, $TypeId);
 
674
        my %BaseTypeAttr = getTypeAttr($TypeAttr{"BaseType"}{"TDid"}, $TypeAttr{"BaseType"}{"Tid"});
 
675
        my $ArrayElemNum = getSize($TypeId)/8;
 
676
        $ArrayElemNum = $ArrayElemNum/$BaseTypeAttr{"Size"} if($BaseTypeAttr{"Size"});
 
677
        $TypeAttr{"Size"} = $ArrayElemNum;
 
678
        if($ArrayElemNum)
 
679
        {
 
680
            $TypeAttr{"Name"} = $BaseTypeAttr{"Name"}."[".$ArrayElemNum."]";
 
681
        }
 
682
        else
 
683
        {
 
684
            $TypeAttr{"Name"} = $BaseTypeAttr{"Name"}."[]";
 
685
        }
 
686
        $TypeAttr{"Name"} = correctName($TypeAttr{"Name"});
 
687
        $TypeAttr{"Library"} = $BaseTypeAttr{"Library"};
 
688
        $TypeAttr{"Header"} = $BaseTypeAttr{"Header"};
 
689
        %{$TypeDescr{$Version}{$TypeDeclId}{$TypeId}} = %TypeAttr;
 
690
        $TName_Tid{$Version}{$TypeDescr{$Version}{$TypeDeclId}{$TypeId}{"Name"}} = $TypeId;
 
691
        return %TypeAttr;
 
692
    }
 
693
    elsif($TypeAttr{"Type"} =~ /Intrinsic|Union|Struct|Enum|Class/)
 
694
    {
 
695
        if($TemplateInstance{$Version}{$TypeDeclId}{$TypeId})
 
696
        {
 
697
            my @Template_Params = ();
 
698
            foreach my $Param_Pos (sort {int($a)<=>int($b)} keys(%{$TemplateInstance{$Version}{$TypeDeclId}{$TypeId}}))
 
699
            {
 
700
                my $Type_Id = $TemplateInstance{$Version}{$TypeDeclId}{$TypeId}{$Param_Pos};
 
701
                my $Param = get_TemplateParam($Type_Id);
 
702
                if($Param eq "")
 
703
                {
 
704
                    return ();
 
705
                }
 
706
                @Template_Params = (@Template_Params, $Param);
 
707
            }
 
708
            %{$TypeDescr{$Version}{$TypeDeclId}{$TypeId}} = getTrivialTypeAttr($TypeDeclId, $TypeId);
 
709
            $TypeDescr{$Version}{$TypeDeclId}{$TypeId}{"Name"} = $TypeDescr{$Version}{$TypeDeclId}{$TypeId}{"Name"}."< ".join(", ", @Template_Params)." >";
 
710
            $TypeDescr{$Version}{$TypeDeclId}{$TypeId}{"Name"} = correctName($TypeDescr{$Version}{$TypeDeclId}{$TypeId}{"Name"});
 
711
            $TName_Tid{$Version}{$TypeDescr{$Version}{$TypeDeclId}{$TypeId}{"Name"}} = $TypeId;
 
712
            return %{$TypeDescr{$Version}{$TypeDeclId}{$TypeId}};
 
713
        }
 
714
        else
 
715
        {
 
716
            %{$TypeDescr{$Version}{$TypeDeclId}{$TypeId}} = getTrivialTypeAttr($TypeDeclId, $TypeId);
 
717
            return %{$TypeDescr{$Version}{$TypeDeclId}{$TypeId}};
 
718
        }
 
719
    }
 
720
    else
 
721
    {
 
722
        ($TypeAttr{"BaseType"}{"Tid"}, $TypeAttr{"BaseType"}{"TDid"}, $BaseTypeSpec) = selectBaseType($TypeDeclId, $TypeId);
 
723
        my %BaseTypeAttr = getTypeAttr($TypeAttr{"BaseType"}{"TDid"}, $TypeAttr{"BaseType"}{"Tid"});
 
724
        if($BaseTypeSpec and $BaseTypeAttr{"Name"})
 
725
        {
 
726
            if(($TypeAttr{"Type"} eq "Pointer") and $BaseTypeAttr{"Name"}=~/\([\*]+\)/)
 
727
            {
 
728
                $TypeAttr{"Name"} = $BaseTypeAttr{"Name"};
 
729
                $TypeAttr{"Name"} =~ s/\(([*]+)\)/($1*)/g;
 
730
            }
 
731
            else
 
732
            {
 
733
                $TypeAttr{"Name"} = $BaseTypeAttr{"Name"}." ".$BaseTypeSpec;
 
734
            }
 
735
        }
 
736
        elsif($BaseTypeAttr{"Name"})
 
737
        {
 
738
            $TypeAttr{"Name"} = $BaseTypeAttr{"Name"};
 
739
        }
 
740
        if($TypeAttr{"Type"} eq "Typedef")
 
741
        {
 
742
            $TypeAttr{"Name"} = getNameByInfo($TypeDeclId);
 
743
            $TypeAttr{"NameSpace"} = getNameSpace($TypeDeclId);
 
744
            if($TypeAttr{"NameSpace"})
 
745
            {
 
746
                $TypeAttr{"Name"} = $TypeAttr{"NameSpace"}."::".$TypeAttr{"Name"};
 
747
            }
 
748
            ($TypeAttr{"Header"}, $TypeAttr{"Line"}) = getLocation($TypeDeclId);
 
749
            if($TypeAttr{"NameSpace"}=~/\Astd(::|\Z)/ and $BaseTypeAttr{"NameSpace"}=~/\Astd(::|\Z)/)
 
750
            {
 
751
                $StdCxxTypedef{$Version}{$BaseTypeAttr{"Name"}} = $TypeAttr{"Name"};
 
752
            }
 
753
            $Typedef_BaseName{$Version}{$TypeAttr{"Name"}} = $BaseTypeAttr{"Name"};
 
754
        }
 
755
        if(not $TypeAttr{"Size"})
 
756
        {
 
757
            if($TypeAttr{"Type"} eq "Pointer")
 
758
            {
 
759
                $TypeAttr{"Size"} = $POINTER_SIZE;
 
760
            }
 
761
            else
 
762
            {
 
763
                $TypeAttr{"Size"} = $BaseTypeAttr{"Size"};
 
764
            }
 
765
        }
 
766
        $TypeAttr{"Name"} = correctName($TypeAttr{"Name"});
 
767
        $TypeAttr{"Library"} = $BaseTypeAttr{"Library"};
 
768
        $TypeAttr{"Header"} = $BaseTypeAttr{"Header"} if(not $TypeAttr{"Header"});
 
769
        %{$TypeDescr{$Version}{$TypeDeclId}{$TypeId}} = %TypeAttr;
 
770
        $TName_Tid{$Version}{$TypeDescr{$Version}{$TypeDeclId}{$TypeId}{"Name"}} = $TypeId;
 
771
        return %TypeAttr;
 
772
    }
 
773
}
 
774
 
 
775
sub get_TemplateParam($)
 
776
{
 
777
    my $Type_Id = $_[0];
 
778
    if(getNodeType($Type_Id) eq "integer_cst")
 
779
    {
 
780
        return getNodeIntCst($Type_Id);
 
781
    }
 
782
    elsif(getNodeType($Type_Id) eq "string_cst")
 
783
    {
 
784
        return getNodeStrCst($Type_Id);
 
785
    }
 
786
    else
 
787
    {
 
788
        my $Type_DId = getTypeDeclId($Type_Id);
 
789
        my %ParamAttr = getTypeAttr($Type_DId, $Type_Id);
 
790
        if(not $ParamAttr{"Name"})
 
791
        {
 
792
            return "";
 
793
        }
 
794
        if($ParamAttr{"Name"}=~/\>/)
 
795
        {
 
796
            if($StdCxxTypedef{$Version}{$ParamAttr{"Name"}})
 
797
            {
 
798
                return $StdCxxTypedef{$Version}{$ParamAttr{"Name"}};
 
799
            }
 
800
            elsif(my $Covered = cover_stdcxx_typedef($ParamAttr{"Name"}))
 
801
            {
 
802
                return $Covered;
 
803
            }
 
804
            else
 
805
            {
 
806
                return $ParamAttr{"Name"};
 
807
            }
 
808
        }
 
809
        else
 
810
        {
 
811
            return $ParamAttr{"Name"};
 
812
        }
 
813
    }
 
814
}
 
815
 
 
816
sub cover_stdcxx_typedef($)
 
817
{
 
818
    my $TypeName = $_[0];
 
819
    my $TypeName_Covered = $TypeName;
 
820
    while($TypeName=~s/>[ ]*(const|volatile|restrict| |\*|\&)\Z/>/g){};
 
821
    if(my $Cover = $StdCxxTypedef{$Version}{$TypeName})
 
822
    {
 
823
        $TypeName = esc_l($TypeName);
 
824
        $TypeName_Covered=~s/$TypeName/$Cover /g;
 
825
    }
 
826
    return correctName($TypeName_Covered);
 
827
}
 
828
 
 
829
sub getNodeType($)
 
830
{
 
831
    return $LibInfo{$Version}{$_[0]}{"info_type"};
 
832
}
 
833
 
 
834
sub getNodeIntCst($)
 
835
{
 
836
    my $CstId = $_[0];
 
837
    my $CstTypeId = getTreeAttr($CstId, "type");
 
838
    if($EnumMembName_Id{$Version}{$CstId})
 
839
    {
 
840
        return $EnumMembName_Id{$Version}{$CstId};
 
841
    }
 
842
    elsif($LibInfo{$Version}{$_[0]}{"info"} =~ /low[ ]*:[ ]*([^ ]+) /)
 
843
    {
 
844
        if($1 eq "0")
 
845
        {
 
846
            if(getNodeType($CstTypeId) eq "boolean_type")
 
847
            {
 
848
                return "false";
 
849
            }
 
850
            else
 
851
            {
 
852
                return "0";
 
853
            }
 
854
        }
 
855
        elsif($1 eq "1")
 
856
        {
 
857
            if(getNodeType($CstTypeId) eq "boolean_type")
 
858
            {
 
859
                return "true";
 
860
            }
 
861
            else
 
862
            {
 
863
                return "1";
 
864
            }
 
865
        }
 
866
        else
 
867
        {
 
868
            return $1;
 
869
        }
 
870
    }
 
871
    else
 
872
    {
 
873
        return "";
 
874
    }
 
875
}
 
876
 
 
877
sub getNodeStrCst($)
 
878
{
 
879
    if($LibInfo{$Version}{$_[0]}{"info"} =~ /low[ ]*:[ ]*(.+)[ ]+lngt/)
 
880
    {
 
881
        return $1;
 
882
    }
 
883
    else
 
884
    {
 
885
        return "";
 
886
    }
 
887
}
 
888
 
 
889
sub esc_l($)
 
890
{
 
891
    my $String = $_[0];
 
892
    $String=~s/([()*])/\\$1/g;
 
893
    return $String;
 
894
}
 
895
 
 
896
sub getFuncPtrAttr($$$)
 
897
{
 
898
    my ($FuncTypeId, $TypeDeclId, $TypeId) = @_;
 
899
    my $FuncInfo = $LibInfo{$Version}{$FuncTypeId}{"info"};
 
900
    my $FuncInfo_Type = $LibInfo{$Version}{$FuncTypeId}{"info_type"};
 
901
    my $FuncPtrCorrectName = "";
 
902
    my %TypeAttr = ("Size"=>$POINTER_SIZE, "Type"=>"FuncPtr", "TDid"=>$TypeDeclId, "Tid"=>$TypeId);
 
903
    my @ParamTypeName;
 
904
    if($FuncInfo =~ /retn[ ]*:[ ]*\@([0-9]+) /)
 
905
    {
 
906
        my $ReturnTypeId = $1;
 
907
        my %ReturnAttr = getTypeAttr(getTypeDeclId($ReturnTypeId), $ReturnTypeId);
 
908
        $FuncPtrCorrectName .= $ReturnAttr{"Name"};
 
909
        $TypeAttr{"Return"} = $ReturnTypeId;
 
910
    }
 
911
    if($FuncInfo =~ /prms[ ]*:[ ]*@([0-9]+) /)
 
912
    {
 
913
        my $ParamTypeInfoId = $1;
 
914
        my $Position = 0;
 
915
        while($ParamTypeInfoId)
 
916
        {
 
917
            my $ParamTypeInfo = $LibInfo{$Version}{$ParamTypeInfoId}{"info"};
 
918
            last if($ParamTypeInfo !~ /valu[ ]*:[ ]*@([0-9]+) /);
 
919
            my $ParamTypeId = $1;
 
920
            my %ParamAttr = getTypeAttr(getTypeDeclId($ParamTypeId), $ParamTypeId);
 
921
            last if($ParamAttr{"Name"} eq "void");
 
922
            $TypeAttr{"Memb"}{$Position}{"type"} = $ParamTypeId;
 
923
            push(@ParamTypeName, $ParamAttr{"Name"});
 
924
            last if($ParamTypeInfo !~ /chan[ ]*:[ ]*@([0-9]+) /);
 
925
            $ParamTypeInfoId = $1;
 
926
            $Position+=1;
 
927
        }
 
928
    }
 
929
    if($FuncInfo_Type eq "function_type")
 
930
    {
 
931
        $FuncPtrCorrectName .= " (*) (".join(", ", @ParamTypeName).")";
 
932
    }
 
933
    elsif($FuncInfo_Type eq "method_type")
 
934
    {
 
935
        if($FuncInfo =~ /clas[ ]*:[ ]*@([0-9]+) /)
 
936
        {
 
937
            my $ClassId = $1;
 
938
            my $ClassName = $TypeDescr{$Version}{getTypeDeclId($ClassId)}{$ClassId}{"Name"};
 
939
            if($ClassName)
 
940
            {
 
941
                $FuncPtrCorrectName .= " ($ClassName\:\:*) (".join(", ", @ParamTypeName).")";
 
942
            }
 
943
            else
 
944
            {
 
945
                $FuncPtrCorrectName .= " (*) (".join(", ", @ParamTypeName).")";
 
946
            }
 
947
        }
 
948
        else
 
949
        {
 
950
            $FuncPtrCorrectName .= " (*) (".join(", ", @ParamTypeName).")";
 
951
        }
 
952
    }
 
953
    $TypeAttr{"Name"} = correctName($FuncPtrCorrectName);
 
954
    return %TypeAttr;
 
955
}
 
956
 
 
957
sub getTypeName($)
 
958
{
 
959
        my $Info = $LibInfo{$Version}{$_[0]}{"info"};
 
960
        if($Info =~ /name[ ]*:[ ]*@([0-9]+) /)
 
961
        {
 
962
                return getNameByInfo($1);
 
963
        }
 
964
        else
 
965
        {
 
966
                if($LibInfo{$Version}{$_[0]}{"info_type"} eq "integer_type")
 
967
                {
 
968
                        if($LibInfo{$Version}{$_[0]}{"info"} =~ /unsigned/)
 
969
                        {
 
970
                                return "unsigned int";
 
971
                        }
 
972
                        else
 
973
                        {
 
974
                                return "int";
 
975
                        }
 
976
                }
 
977
                else
 
978
                {
 
979
                        return "";
 
980
                }
 
981
        }
 
982
}
 
983
 
 
984
sub selectBaseType($$)
 
985
{
 
986
        my ($TypeDeclId, $TypeId) = @_;
 
987
        my $TypeInfo = $LibInfo{$Version}{$TypeId}{"info"};
 
988
        my $BaseTypeDeclId;
 
989
    my $Type_Type = getTypeType($TypeDeclId, $TypeId);
 
990
        #qualifications
 
991
        if(($LibInfo{$Version}{$TypeId}{"info"} =~ /qual[ ]*:[ ]*c /) and ($LibInfo{$Version}{$TypeId}{"info"} =~ /unql[ ]*:[ ]*\@([0-9]+) /))
 
992
        {
 
993
                return ($1, getTypeDeclId($1), "const");
 
994
        }
 
995
        elsif(($LibInfo{$Version}{$TypeId}{"info"} =~ /qual[ ]*:[ ]*r /) and ($LibInfo{$Version}{$TypeId}{"info"} =~ /unql[ ]*:[ ]*\@([0-9]+) /))
 
996
        {
 
997
                return ($1, getTypeDeclId($1), "restrict");
 
998
        }
 
999
        elsif(($LibInfo{$Version}{$TypeId}{"info"} =~ /qual[ ]*:[ ]*v /) and ($LibInfo{$Version}{$TypeId}{"info"} =~ /unql[ ]*:[ ]*\@([0-9]+) /))
 
1000
        {
 
1001
                return ($1, getTypeDeclId($1), "volatile");
 
1002
        }
 
1003
        elsif((not ($LibInfo{$Version}{$TypeId}{"info"} =~ /qual[ ]*:/)) and ($LibInfo{$Version}{$TypeId}{"info"} =~ /unql[ ]*:[ ]*\@([0-9]+) /))
 
1004
        {#typedefs
 
1005
                return ($1, getTypeDeclId($1), "");
 
1006
        }
 
1007
        elsif($LibInfo{$Version}{$TypeId}{"info_type"} eq "reference_type")
 
1008
        {
 
1009
                if($TypeInfo =~ /refd[ ]*:[ ]*@([0-9]+) /)
 
1010
        {
 
1011
                    return ($1, getTypeDeclId($1), "&");
 
1012
        }
 
1013
        else
 
1014
        {
 
1015
            return (0, 0, "");
 
1016
        }
 
1017
        }
 
1018
        elsif($LibInfo{$Version}{$TypeId}{"info_type"} eq "array_type")
 
1019
        {
 
1020
                if($TypeInfo =~ /elts[ ]*:[ ]*@([0-9]+) /)
 
1021
        {
 
1022
                    return ($1, getTypeDeclId($1), "");
 
1023
        }
 
1024
        else
 
1025
        {
 
1026
            return (0, 0, "");
 
1027
        }
 
1028
        }
 
1029
        elsif($LibInfo{$Version}{$TypeId}{"info_type"} eq "pointer_type")
 
1030
        {
 
1031
                if($TypeInfo =~ /ptd[ ]*:[ ]*@([0-9]+) /)
 
1032
        {
 
1033
                    return ($1, getTypeDeclId($1), "*");
 
1034
        }
 
1035
        else
 
1036
        {
 
1037
            return (0, 0, "");
 
1038
        }
 
1039
        }
 
1040
        else
 
1041
        {
 
1042
                return (0, 0, "");
 
1043
        }
 
1044
}
 
1045
 
 
1046
sub getFuncDescr_All()
 
1047
{
 
1048
        foreach (sort {int($b)<=>int($a)} keys(%{$LibInfo{$Version}}))
 
1049
        {
 
1050
                if($LibInfo{$Version}{$_}{"info_type"} eq "function_decl")
 
1051
                {
 
1052
                        getFuncDescr($_);
 
1053
                }
 
1054
        }
 
1055
}
 
1056
 
 
1057
sub getVarDescr_All()
 
1058
{
 
1059
        foreach (sort {int($b)<=>int($a)} keys(%{$LibInfo{$Version}}))
 
1060
        {
 
1061
                if($LibInfo{$Version}{$_}{"info_type"} eq "var_decl")
 
1062
                {
 
1063
                        getVarDescr($_);
 
1064
                }
 
1065
        }
 
1066
}
 
1067
 
 
1068
sub getVarDescr($)
 
1069
{
 
1070
        my $FuncInfoId = $_[0];
 
1071
    if($LibInfo{$Version}{getNameSpaceId($FuncInfoId)}{"info_type"} eq "function_decl")
 
1072
    {
 
1073
        return;
 
1074
    }
 
1075
    ($FuncDescr{$Version}{$FuncInfoId}{"Header"}, $FuncDescr{$Version}{$FuncInfoId}{"Line"}) = getLocation($FuncInfoId);
 
1076
    if((not $FuncDescr{$Version}{$FuncInfoId}{"Header"}) or ($FuncDescr{$Version}{$FuncInfoId}{"Header"}=~/\<built\-in\>|\<internal\>/))
 
1077
    {
 
1078
        delete($FuncDescr{$Version}{$FuncInfoId});
 
1079
        return;
 
1080
    }
 
1081
    $FuncDescr{$Version}{$FuncInfoId}{"ShortName"} = getNameByInfo($FuncInfoId);
 
1082
    $FuncDescr{$Version}{$FuncInfoId}{"MnglName"} = getFuncMnglName($FuncInfoId);
 
1083
    if($FuncDescr{$Version}{$FuncInfoId}{"MnglName"} and $FuncDescr{$Version}{$FuncInfoId}{"MnglName"}!~/\A_Z/)
 
1084
    {
 
1085
        delete($FuncDescr{$Version}{$FuncInfoId});
 
1086
        return;
 
1087
    }
 
1088
    if(not $FuncDescr{$Version}{$FuncInfoId}{"MnglName"})
 
1089
    {
 
1090
        $FuncDescr{$Version}{$FuncInfoId}{"Name"} = $FuncDescr{$Version}{$FuncInfoId}{"ShortName"};
 
1091
        $FuncDescr{$Version}{$FuncInfoId}{"MnglName"} = $FuncDescr{$Version}{$FuncInfoId}{"ShortName"};
 
1092
    }
 
1093
    if(not is_in_library($FuncDescr{$Version}{$FuncInfoId}{"MnglName"}, $Version) and not $CheckHeadersOnly)
 
1094
    {
 
1095
        delete $FuncDescr{$Version}{$FuncInfoId};
 
1096
        return;
 
1097
    }
 
1098
        $FuncDescr{$Version}{$FuncInfoId}{"Return"} = getTypeId($FuncInfoId);
 
1099
    delete($FuncDescr{$Version}{$FuncInfoId}{"Return"}) if(not $FuncDescr{$Version}{$FuncInfoId}{"Return"});
 
1100
        $FuncDescr{$Version}{$FuncInfoId}{"Data"} = 1;
 
1101
        set_Class_And_Namespace($FuncInfoId);
 
1102
        setFuncAccess($FuncInfoId);
 
1103
        if($FuncDescr{$Version}{$FuncInfoId}{"MnglName"} =~ /\A_ZTV/)
 
1104
    {
 
1105
        delete($FuncDescr{$Version}{$FuncInfoId}{"Return"});
 
1106
    }
 
1107
    if($FuncDescr{$Version}{$FuncInfoId}{"ShortName"} =~ /\A_Z/)
 
1108
    {
 
1109
        delete($FuncDescr{$Version}{$FuncInfoId}{"ShortName"});
 
1110
    }
 
1111
}
 
1112
 
 
1113
sub getTrivialTypeAttr($$)
 
1114
{
 
1115
        my ($TypeInfoId, $TypeId) = @_;
 
1116
    my %TypeAttr = ();
 
1117
    return if(getTypeTypeByTypeId($TypeId)!~/Intrinsic|Union|Struct|Enum/);
 
1118
        setTypeAccess($TypeId, \%TypeAttr);
 
1119
        ($TypeAttr{"Header"}, $TypeAttr{"Line"}) = getLocation($TypeInfoId);
 
1120
        if(($TypeAttr{"Header"} eq "<built-in>") or ($TypeAttr{"Header"} eq "<internal>"))
 
1121
        {
 
1122
        delete($TypeAttr{"Header"});
 
1123
        }
 
1124
    $TypeAttr{"Name"} = getNameByInfo($TypeInfoId);
 
1125
    $TypeAttr{"Name"} = getTypeName($TypeId) if(not $TypeAttr{"Name"});
 
1126
    my $NameSpaceId = getNameSpaceId($TypeInfoId);
 
1127
    if($NameSpaceId ne $TypeId)
 
1128
    {
 
1129
        $TypeAttr{"NameSpace"} = getNameSpace($TypeInfoId);
 
1130
    }
 
1131
    if($TypeAttr{"NameSpace"} and isNotAnon($TypeAttr{"Name"}))
 
1132
    {
 
1133
        $TypeAttr{"Name"} = $TypeAttr{"NameSpace"}."::".$TypeAttr{"Name"};
 
1134
    }
 
1135
    $TypeAttr{"Name"} = correctName($TypeAttr{"Name"});
 
1136
        if(isAnon($TypeAttr{"Name"}))
 
1137
        {
 
1138
                $TypeAttr{"Name"} = "anon-";
 
1139
                $TypeAttr{"Name"} .= $TypeAttr{"Header"}."-".$TypeAttr{"Line"};
 
1140
        }
 
1141
        $TypeAttr{"Size"} = getSize($TypeId)/8;
 
1142
        $TypeAttr{"Type"} = getTypeType($TypeInfoId, $TypeId);
 
1143
    if($TypeAttr{"Type"} eq "Struct" and has_methods($TypeId))
 
1144
    {
 
1145
        $TypeAttr{"Type"} = "Class";
 
1146
    }
 
1147
    if(($TypeAttr{"Type"} eq "Struct") or ($TypeAttr{"Type"} eq "Class"))
 
1148
    {
 
1149
        setBaseClasses($TypeInfoId, $TypeId, \%TypeAttr);
 
1150
    }
 
1151
        setTypeMemb($TypeInfoId, $TypeId, \%TypeAttr);
 
1152
    $TypeAttr{"Tid"} = $TypeId;
 
1153
    $TypeAttr{"TDid"} = $TypeInfoId;
 
1154
    $Tid_TDid{$Version}{$TypeId} = $TypeInfoId;
 
1155
    if(not $TName_Tid{$Version}{$TypeAttr{"Name"}})
 
1156
    {
 
1157
        $TName_Tid{$Version}{$TypeAttr{"Name"}} = $TypeId;
 
1158
    }
 
1159
    return %TypeAttr;
 
1160
}
 
1161
 
 
1162
sub has_methods($)
 
1163
{
 
1164
    my $TypeId = $_[0];
 
1165
    my $Info = $LibInfo{$Version}{$TypeId}{"info"};
 
1166
    return ($Info=~/(fncs)[ ]*:[ ]*@([0-9]+) /);
 
1167
}
 
1168
 
 
1169
sub setBaseClasses($$$)
 
1170
{
 
1171
    my ($TypeInfoId, $TypeId, $TypeAttr) = @_;
 
1172
    my $Info = $LibInfo{$Version}{$TypeId}{"info"};
 
1173
    if($Info =~ /binf[ ]*:[ ]*@([0-9]+) /)
 
1174
    {
 
1175
        $Info = $LibInfo{$Version}{$1}{"info"};
 
1176
        while($Info =~ /accs[ ]*:[ ]*([a-z]+) /)
 
1177
        {
 
1178
            last if($Info !~ s/accs[ ]*:[ ]*([a-z]+) //);
 
1179
            my $Access = $1;
 
1180
            last if($Info !~ s/binf[ ]*:[ ]*@([0-9]+) //);
 
1181
            my $BInfoId = $1;
 
1182
            my $ClassId = getBinfClassId($BInfoId);
 
1183
            if($Access eq "pub")
 
1184
            {
 
1185
                $TypeAttr->{"BaseClass"}{$ClassId} = "public";
 
1186
            }
 
1187
            elsif($Access eq "prot")
 
1188
            {
 
1189
                $TypeAttr->{"BaseClass"}{$ClassId} = "protected";
 
1190
            }
 
1191
            elsif($Access eq "priv")
 
1192
            {
 
1193
                $TypeAttr->{"BaseClass"}{$ClassId} = "private";
 
1194
            }
 
1195
            else
 
1196
            {
 
1197
                $TypeAttr->{"BaseClass"}{$ClassId} = "private";
 
1198
            }
 
1199
        }
 
1200
    }
 
1201
}
 
1202
 
 
1203
sub getBinfClassId($)
 
1204
{
 
1205
    my $Info = $LibInfo{$Version}{$_[0]}{"info"};
 
1206
    $Info =~ /type[ ]*:[ ]*@([0-9]+) /;
 
1207
    return $1;
 
1208
}
 
1209
 
 
1210
sub get_func_signature($)
 
1211
{
 
1212
    my $FuncInfoId = $_[0];
 
1213
    my $PureSignature = $FuncDescr{$Version}{$FuncInfoId}{"ShortName"};
 
1214
    my @ParamTypes = ();
 
1215
    foreach my $ParamPos (sort {int($a) <=> int($b)} keys(%{$FuncDescr{$Version}{$FuncInfoId}{"Param"}}))
 
1216
    {#checking parameters
 
1217
        my $ParamType_Id = $FuncDescr{$Version}{$FuncInfoId}{"Param"}{$ParamPos}{"type"};
 
1218
        my $ParamType_Name = uncover_typedefs($TypeDescr{$Version}{getTypeDeclId($ParamType_Id)}{$ParamType_Id}{"Name"});
 
1219
        @ParamTypes = (@ParamTypes, $ParamType_Name);
 
1220
    }
 
1221
    $PureSignature = $PureSignature."(".join(", ", @ParamTypes).")";
 
1222
    $PureSignature = delete_keywords($PureSignature);
 
1223
    return correctName($PureSignature);
 
1224
}
 
1225
 
 
1226
sub delete_keywords($)
 
1227
{
 
1228
    my $TypeName = $_[0];
 
1229
    $TypeName =~ s/(\W|\A)(enum |struct |union |class )/$1/g;
 
1230
    return $TypeName;
 
1231
}
 
1232
 
 
1233
sub uncover_typedefs($)
 
1234
{
 
1235
    my $TypeName = $_[0];
 
1236
    return "" if(not $TypeName);
 
1237
    return $Cache{"uncover_typedefs"}{$Version}{$TypeName} if(defined $Cache{"uncover_typedefs"}{$Version}{$TypeName});
 
1238
    my ($TypeName_New, $TypeName_Pre) = (correctName($TypeName), "");
 
1239
    while($TypeName_New ne $TypeName_Pre)
 
1240
    {
 
1241
        $TypeName_Pre = $TypeName_New;
 
1242
        my $TypeName_Copy = $TypeName_New;
 
1243
        my %Words = ();
 
1244
        while($TypeName_Copy=~s/(\W|\A)([a-z_][\w:]*)(\W|\Z)//io)
 
1245
        {
 
1246
            my $Word = $2;
 
1247
            next if(not $Word or $Word=~/\A(true|false|const|int|long|void|short|float|unsigned|char|double|class|struct|union|enum)\Z/);
 
1248
            $Words{$Word} = 1;
 
1249
        }
 
1250
        foreach my $Word (keys(%Words))
 
1251
        {
 
1252
            my $BaseType_Name = $Typedef_BaseName{$Version}{$Word};
 
1253
            next if($TypeName_New=~/(\W|\A)(struct $Word|union $Word|enum $Word)(\W|\Z)/);
 
1254
            next if(not $BaseType_Name);
 
1255
            if($BaseType_Name=~/\([*]+\)/)
 
1256
            {
 
1257
                $TypeName_New =~ /$Word(.*)\Z/;
 
1258
                my $Type_Suffix = $1;
 
1259
                $TypeName_New = $BaseType_Name;
 
1260
                if($TypeName_New =~ s/\(([*]+)\)/($1 $Type_Suffix)/)
 
1261
                {
 
1262
                    $TypeName_New = correctName($TypeName_New);
 
1263
                }
 
1264
            }
 
1265
            else
 
1266
            {
 
1267
                if($TypeName_New =~ s/(\W|\A)$Word(\W|\Z)/$1$BaseType_Name$2/g)
 
1268
                {
 
1269
                    $TypeName_New = correctName($TypeName_New);
 
1270
                }
 
1271
            }
 
1272
        }
 
1273
    }
 
1274
    $Cache{"uncover_typedefs"}{$Version}{$TypeName} = $TypeName_New;
 
1275
    return $TypeName_New;
 
1276
}
 
1277
 
 
1278
sub isInternal($)
 
1279
{
 
1280
    my $FuncInfoId = $_[0];
 
1281
    my $FuncInfo = $LibInfo{$Version}{$_[0]}{"info"};
 
1282
    return 0 if($FuncInfo !~ /mngl[ ]*:[ ]*@([0-9]+) /);
 
1283
    my $FuncMnglNameInfoId = $1;
 
1284
    return ($LibInfo{$Version}{$FuncMnglNameInfoId}{"info"} =~ /\*[ ]*INTERNAL[ ]*\*/);
 
1285
}
 
1286
 
 
1287
sub set_Class_And_Namespace($)
 
1288
{
 
1289
    my $FuncInfoId = $_[0];
 
1290
    my $FuncInfo = $LibInfo{$Version}{$FuncInfoId}{"info"};
 
1291
    if($FuncInfo =~ /scpe[ ]*:[ ]*@([0-9]+) /)
 
1292
    {
 
1293
        my $NameSpaceInfoId = $1;
 
1294
        if($LibInfo{$Version}{$NameSpaceInfoId}{"info_type"} eq "namespace_decl")
 
1295
        {
 
1296
            my $NameSpaceInfo = $LibInfo{$Version}{$NameSpaceInfoId}{"info"};
 
1297
            if($NameSpaceInfo =~ /name[ ]*:[ ]*@([0-9]+) /)
 
1298
            {
 
1299
                my $NameSpaceId = $1;
 
1300
                my $NameSpaceIdentifier = $LibInfo{$Version}{$NameSpaceId}{"info"};
 
1301
                if($NameSpaceIdentifier =~ /strg[ ]*:[ ]*(.*)[ ]+lngt/)
 
1302
                {
 
1303
                    my $NameSpace = $1;
 
1304
                    $NameSpace =~ s/[ ]+\Z//g;
 
1305
                    $FuncDescr{$Version}{$FuncInfoId}{"NameSpace"} = $NameSpace;
 
1306
                }
 
1307
            }
 
1308
        }
 
1309
        elsif($LibInfo{$Version}{$NameSpaceInfoId}{"info_type"} eq "record_type")
 
1310
        {
 
1311
            $FuncDescr{$Version}{$FuncInfoId}{"Class"} = $NameSpaceInfoId;
 
1312
        }
 
1313
    }
 
1314
}
 
1315
 
 
1316
sub getFuncDescr($)
 
1317
{
 
1318
        my $FuncInfoId = $_[0];
 
1319
    return if(isInternal($FuncInfoId));
 
1320
    ($FuncDescr{$Version}{$FuncInfoId}{"Header"}, $FuncDescr{$Version}{$FuncInfoId}{"Line"}) = getLocation($FuncInfoId);
 
1321
    if(not $FuncDescr{$Version}{$FuncInfoId}{"Header"} or $FuncDescr{$Version}{$FuncInfoId}{"Header"}=~/\<built\-in\>|\<internal\>/)
 
1322
    {
 
1323
        delete($FuncDescr{$Version}{$FuncInfoId});
 
1324
        return;
 
1325
    }
 
1326
    setFuncAccess($FuncInfoId);
 
1327
        setFuncKind($FuncInfoId);
 
1328
        if($FuncDescr{$Version}{$FuncInfoId}{"PseudoTemplate"})
 
1329
    {
 
1330
        delete($FuncDescr{$Version}{$FuncInfoId});
 
1331
        return;
 
1332
    }
 
1333
    $FuncDescr{$Version}{$FuncInfoId}{"Type"} = getFuncType($FuncInfoId);
 
1334
    $FuncDescr{$Version}{$FuncInfoId}{"Return"} = getFuncReturn($FuncInfoId);
 
1335
    delete($FuncDescr{$Version}{$FuncInfoId}{"Return"}) if(not $FuncDescr{$Version}{$FuncInfoId}{"Return"});
 
1336
    $FuncDescr{$Version}{$FuncInfoId}{"ShortName"} = getFuncShortName(getFuncOrig($FuncInfoId));
 
1337
    if($FuncDescr{$Version}{$FuncInfoId}{"ShortName"} =~ /\._/)
 
1338
    {
 
1339
        delete($FuncDescr{$Version}{$FuncInfoId});
 
1340
        return;
 
1341
    }
 
1342
    if(defined $TemplateInstance_Func{$Version}{$FuncInfoId})
 
1343
    {
 
1344
        my @TmplParams = ();
 
1345
        foreach my $ParamPos (sort {int($a) <=> int($b)} keys(%{$TemplateInstance_Func{$Version}{$FuncInfoId}}))
 
1346
        {
 
1347
            my $Param = get_TemplateParam($TemplateInstance_Func{$Version}{$FuncInfoId}{$ParamPos});
 
1348
            if($Param eq "")
 
1349
            {
 
1350
                delete($FuncDescr{$Version}{$FuncInfoId});
 
1351
                return;
 
1352
            }
 
1353
            push(@TmplParams, $Param);
 
1354
        }
 
1355
        $FuncDescr{$Version}{$FuncInfoId}{"ShortName"} .= "<".join(", ", @TmplParams).">";
 
1356
    }
 
1357
    setFuncParams($FuncInfoId);
 
1358
    $FuncDescr{$Version}{$FuncInfoId}{"MnglName"} = getFuncMnglName($FuncInfoId);
 
1359
    if($FuncDescr{$Version}{$FuncInfoId}{"MnglName"} and $FuncDescr{$Version}{$FuncInfoId}{"MnglName"}!~/\A_Z/)
 
1360
    {
 
1361
        delete($FuncDescr{$Version}{$FuncInfoId});
 
1362
        return;
 
1363
    }
 
1364
    
 
1365
    if((is_in_library($FuncDescr{$Version}{$FuncInfoId}{"ShortName"}, $Version) or $CheckHeadersOnly) and not $FuncDescr{$Version}{$FuncInfoId}{"MnglName"} and ($FuncDescr{$Version}{$FuncInfoId}{"Type"} eq "Function"))
 
1366
    {
 
1367
        $FuncDescr{$Version}{$FuncInfoId}{"MnglName"} = $FuncDescr{$Version}{$FuncInfoId}{"ShortName"};
 
1368
    }
 
1369
    set_Class_And_Namespace($FuncInfoId);
 
1370
    if(not $FuncDescr{$Version}{$FuncInfoId}{"MnglName"} and not $FuncDescr{$Version}{$FuncInfoId}{"Class"})
 
1371
    {#this section only for c++ functions without class that have not been mangled in the tree
 
1372
        $FuncDescr{$Version}{$FuncInfoId}{"MnglName"} = $mangled_name{get_func_signature($FuncInfoId)};
 
1373
    }
 
1374
    if(not is_in_library($FuncDescr{$Version}{$FuncInfoId}{"MnglName"}, $Version) and not $CheckHeadersOnly)
 
1375
    {#src only
 
1376
        delete($FuncDescr{$Version}{$FuncInfoId});
 
1377
        return;
 
1378
    }
 
1379
    if($FuncDescr{$Version}{$FuncInfoId}{"Constructor"} or $FuncDescr{$Version}{$FuncInfoId}{"Destructor"})
 
1380
    {
 
1381
        delete($FuncDescr{$Version}{$FuncInfoId}{"Return"});
 
1382
    }
 
1383
    my $FuncBody = getFuncBody($FuncInfoId);
 
1384
    if($FuncBody eq "defined")
 
1385
    {
 
1386
        $FuncDescr{$Version}{$FuncInfoId}{"InLine"} = 1;
 
1387
    }
 
1388
    if($CheckHeadersOnly and $FuncDescr{$Version}{$FuncInfoId}{"InLine"})
 
1389
    {
 
1390
        delete($FuncDescr{$Version}{$FuncInfoId});
 
1391
        return;
 
1392
    }
 
1393
    if(($FuncDescr{$Version}{$FuncInfoId}{"Type"} eq "Method") or $FuncDescr{$Version}{$FuncInfoId}{"Constructor"} or $FuncDescr{$Version}{$FuncInfoId}{"Destructor"})
 
1394
    {
 
1395
        if($FuncDescr{$Version}{$FuncInfoId}{"MnglName"}!~/\A_Z/)
 
1396
        {
 
1397
            delete($FuncDescr{$Version}{$FuncInfoId});
 
1398
            return;
 
1399
        }
 
1400
    }
 
1401
        if(getFuncSpec($FuncInfoId) eq "Virt")
 
1402
        {#virtual methods
 
1403
                $FuncDescr{$Version}{$FuncInfoId}{"Virt"} = 1;
 
1404
        }
 
1405
        if(getFuncSpec($FuncInfoId) eq "PureVirt")
 
1406
        {#pure virtual methods
 
1407
                $FuncDescr{$Version}{$FuncInfoId}{"PureVirt"} = 1;
 
1408
        }
 
1409
    if($FuncDescr{$Version}{$FuncInfoId}{"MnglName"} =~ /\A_Z/ and $FuncDescr{$Version}{$FuncInfoId}{"Class"})
 
1410
    {
 
1411
            if($FuncDescr{$Version}{$FuncInfoId}{"Type"} eq "Function")
 
1412
            {#static methods
 
1413
                    $FuncDescr{$Version}{$FuncInfoId}{"Static"} = 1;
 
1414
            }
 
1415
    }
 
1416
        if(getFuncLink($FuncInfoId) eq "Static")
 
1417
    {
 
1418
        $FuncDescr{$Version}{$FuncInfoId}{"Static"} = 1;
 
1419
    }
 
1420
    delete($FuncDescr{$Version}{$FuncInfoId}{"Type"});
 
1421
}
 
1422
 
 
1423
sub getFuncBody($)
 
1424
{
 
1425
    my $FuncInfo = $LibInfo{$Version}{$_[0]}{"info"};
 
1426
    if($FuncInfo =~ /body[ ]*:[ ]*undefined(\ |\Z)/i)
 
1427
    {
 
1428
        return "undefined";
 
1429
    }
 
1430
    elsif($FuncInfo =~ /body[ ]*:[ ]*@([0-9]+)(\ |\Z)/i)
 
1431
    {
 
1432
        return "defined";
 
1433
    }
 
1434
    else
 
1435
    {
 
1436
        return "";
 
1437
    }
 
1438
}
 
1439
 
 
1440
sub getTypeShortName($)
 
1441
{
 
1442
        my $TypeName = $_[0];
 
1443
        $TypeName =~ s/\<.*\>//g;
 
1444
        $TypeName =~ s/.*\:\://g;
 
1445
        return $TypeName;
 
1446
}
 
1447
 
 
1448
sub getBackRef($)
 
1449
{
 
1450
        my $TypeInfo = $LibInfo{$Version}{$_[0]}{"info"};
 
1451
        if($TypeInfo =~ /name[ ]*:[ ]*@([0-9]+) /)
 
1452
    {
 
1453
            return $1;
 
1454
    }
 
1455
    else
 
1456
    {
 
1457
        return "";
 
1458
    }
 
1459
}
 
1460
 
 
1461
sub getTypeId($)
 
1462
{
 
1463
        my $TypeInfo = $LibInfo{$Version}{$_[0]}{"info"};
 
1464
        if($TypeInfo =~ /type[ ]*:[ ]*@([0-9]+) /)
 
1465
    {
 
1466
            return $1;
 
1467
    }
 
1468
    else
 
1469
    {
 
1470
        return "";
 
1471
    }
 
1472
}
 
1473
 
 
1474
sub getFuncId($)
 
1475
{
 
1476
        my $FuncInfo = $LibInfo{$Version}{$_[0]}{"info"};
 
1477
        if($FuncInfo =~ /type[ ]*:[ ]*@([0-9]+) /)
 
1478
    {
 
1479
            return $1;
 
1480
    }
 
1481
    else
 
1482
    {
 
1483
        return "";
 
1484
    }
 
1485
}
 
1486
 
 
1487
sub setTypeMemb($$)
 
1488
{
 
1489
    my ($TypeDeclId, $TypeId, $TypeAttr) = @_;
 
1490
        my $TypeInfo = $LibInfo{$Version}{$TypeId}{"info"};
 
1491
        my $TypeMembInfoId;
 
1492
        my $TypeType = $TypeAttr->{"Type"};
 
1493
        my $Position = 0;
 
1494
    my $BasePosition = 0;
 
1495
        my $TypeTypeInfoId;
 
1496
        my $StructMembName;
 
1497
        if($TypeType eq "Enum")
 
1498
        {
 
1499
                $TypeMembInfoId = getEnumMembInfoId($TypeId);
 
1500
                while($TypeMembInfoId)
 
1501
                {
 
1502
                        $TypeAttr->{"Memb"}{$Position}{"value"} = getEnumMembVal($TypeMembInfoId);
 
1503
            my $MembName = getEnumMembName($TypeMembInfoId);
 
1504
                        $TypeAttr->{"Memb"}{$Position}{"name"} = getEnumMembName($TypeMembInfoId);
 
1505
            $EnumMembName_Id{$Version}{getTreeAttr($TypeMembInfoId, "valu")} = ($TypeAttr->{"NameSpace"})?$TypeAttr->{"NameSpace"}."::".$MembName:$MembName;
 
1506
                        $TypeMembInfoId = getNextMembInfoId($TypeMembInfoId);
 
1507
                        $Position += 1;
 
1508
                }
 
1509
        }
 
1510
        elsif(($TypeType eq "Struct") or ($TypeType eq "Class") or ($TypeType eq "Union"))
 
1511
        {
 
1512
                $TypeMembInfoId = getStructMembInfoId($TypeId);
 
1513
                while($TypeMembInfoId)
 
1514
                {
 
1515
            if($LibInfo{$Version}{$TypeMembInfoId}{"info_type"} ne "field_decl")
 
1516
            {
 
1517
                $TypeMembInfoId = getNextStructMembInfoId($TypeMembInfoId);
 
1518
                next;
 
1519
            }
 
1520
            $StructMembName = getStructMembName($TypeMembInfoId);
 
1521
            if($StructMembName =~ /_vptr\./)
 
1522
            {#virtual tables
 
1523
                $TypeMembInfoId = getNextStructMembInfoId($TypeMembInfoId);
 
1524
                next;
 
1525
            }
 
1526
            if(not $StructMembName)
 
1527
            {#base classes
 
1528
                #$TypeAttr->{"Base"}{$BasePosition}{"type"} = getStructMembType($TypeMembInfoId);
 
1529
                #$TypeAttr->{"Base"}{$BasePosition}{"access"} = getStructMembAccess($TypeMembInfoId);
 
1530
                $BasePosition += 1;
 
1531
                $TypeMembInfoId = getNextStructMembInfoId($TypeMembInfoId);
 
1532
                next;
 
1533
            }
 
1534
            $TypeAttr->{"Memb"}{$Position}{"type"} = getStructMembType($TypeMembInfoId);
 
1535
            $TypeAttr->{"Memb"}{$Position}{"name"} = $StructMembName;
 
1536
            $TypeAttr->{"Memb"}{$Position}{"access"} = getStructMembAccess($TypeMembInfoId);
 
1537
            $TypeAttr->{"Memb"}{$Position}{"bitfield"} = getStructMembBitFieldSize($TypeMembInfoId);
 
1538
            
 
1539
                        $TypeMembInfoId = getNextStructMembInfoId($TypeMembInfoId);
 
1540
                        $Position += 1;
 
1541
                }
 
1542
        }
 
1543
}
 
1544
 
 
1545
sub setFuncParams($)
 
1546
{
 
1547
        my $FuncInfoId = $_[0];
 
1548
        my $ParamInfoId = getFuncParamInfoId($FuncInfoId);
 
1549
        my $FunctionType = getFuncType($FuncInfoId);
 
1550
        if($FunctionType eq "Method")
 
1551
        {
 
1552
                $ParamInfoId = getNextElem($ParamInfoId);
 
1553
        }
 
1554
    my $Position = 0;
 
1555
        while($ParamInfoId)
 
1556
        {
 
1557
                my $ParamTypeId = getFuncParamType($ParamInfoId);
 
1558
                last if($TypeDescr{$Version}{getTypeDeclId($ParamTypeId)}{$ParamTypeId}{"Name"} eq "void");
 
1559
                if($TypeDescr{$Version}{getTypeDeclId($ParamTypeId)}{$ParamTypeId}{"Type"} eq "Restrict")
 
1560
                {#delete restrict spec
 
1561
                        $ParamTypeId = getRestrictBase($ParamTypeId);
 
1562
                }
 
1563
                $FuncDescr{$Version}{$FuncInfoId}{"Param"}{$Position}{"type"} = $ParamTypeId;
 
1564
                $FuncDescr{$Version}{$FuncInfoId}{"Param"}{$Position}{"name"} = getFuncParamName($ParamInfoId);
 
1565
        if(not $FuncDescr{$Version}{$FuncInfoId}{"Param"}{$Position}{"name"})
 
1566
        {
 
1567
            $FuncDescr{$Version}{$FuncInfoId}{"Param"}{$Position}{"name"} = "p".($Position+1);
 
1568
        }
 
1569
                $ParamInfoId = getNextElem($ParamInfoId);
 
1570
                $Position += 1;
 
1571
        }
 
1572
    if(detect_nolimit_args($FuncInfoId))
 
1573
    {
 
1574
        $FuncDescr{$Version}{$FuncInfoId}{"Param"}{$Position}{"type"} = -1;
 
1575
    }
 
1576
}
 
1577
 
 
1578
sub detect_nolimit_args($)
 
1579
{
 
1580
    my $FuncInfoId = $_[0];
 
1581
    my $FuncTypeId = getFuncTypeId($FuncInfoId);
 
1582
    my $ParamListElemId = getFuncParamTreeListId($FuncTypeId);
 
1583
    my $HaveVoid = 0;
 
1584
    my $Position = 0;
 
1585
    while($ParamListElemId)
 
1586
    {
 
1587
        my $ParamTypeId = getTreeAttr($ParamListElemId, "valu");
 
1588
        if($TypeDescr{$Version}{getTypeDeclId($ParamTypeId)}{$ParamTypeId}{"Name"} eq "void")
 
1589
        {
 
1590
            $HaveVoid = 1;
 
1591
            last;
 
1592
        }
 
1593
        $ParamListElemId = getNextElem($ParamListElemId);
 
1594
        $Position += 1;
 
1595
    }
 
1596
    return ($Position>=1 and not $HaveVoid);
 
1597
}
 
1598
 
 
1599
sub getFuncParamTreeListId($)
 
1600
{
 
1601
    my $FuncTypeId = $_[0];
 
1602
    if($LibInfo{$Version}{$FuncTypeId}{"info"} =~ /prms[ ]*:[ ]*@([0-9]+) /)
 
1603
    {
 
1604
        return $1;
 
1605
    }
 
1606
    else
 
1607
    {
 
1608
        return "";
 
1609
    }
 
1610
}
 
1611
 
 
1612
sub getTreeAttr($$)
 
1613
{
 
1614
    my ($Id, $Attr) = @_;
 
1615
    if($LibInfo{$Version}{$Id}{"info"} =~ /$Attr[ ]*:[ ]*@([0-9]+) /)
 
1616
    {
 
1617
        return $1;
 
1618
    }
 
1619
    else
 
1620
    {
 
1621
        return "";
 
1622
    }
 
1623
}
 
1624
 
 
1625
sub getRestrictBase($)
 
1626
{
 
1627
        my $TypeId = $_[0];
 
1628
        my $TypeDeclId = getTypeDeclId($TypeId);
 
1629
        my $BaseTypeId = $TypeDescr{$Version}{$TypeDeclId}{$TypeId}{"BaseType"}{"Tid"};
 
1630
        my $BaseTypeDeclId = $TypeDescr{$Version}{$TypeDeclId}{$TypeId}{"BaseType"}{"TDid"};
 
1631
        return $BaseTypeId;
 
1632
}
 
1633
 
 
1634
sub setFuncAccess($)
 
1635
{
 
1636
        my $FuncInfoId = $_[0];
 
1637
    if($LibInfo{$Version}{$FuncInfoId}{"info"} =~ /accs[ ]*:[ ]*([a-zA-Z]+) /)
 
1638
    {
 
1639
        my $Access = $1;
 
1640
        if($Access eq "prot")
 
1641
        {
 
1642
            $FuncDescr{$Version}{$FuncInfoId}{"Protected"} = 1;
 
1643
        }
 
1644
        elsif($Access eq "priv")
 
1645
        {
 
1646
            $FuncDescr{$Version}{$FuncInfoId}{"Private"} = 1;
 
1647
        }
 
1648
    }
 
1649
}
 
1650
 
 
1651
sub setTypeAccess($$)
 
1652
{
 
1653
    my ($TypeId, $TypeAttr) = @_;
 
1654
        my $TypeInfo = $LibInfo{$Version}{$TypeId}{"info"};
 
1655
        if($TypeInfo =~ /accs[ ]*:[ ]*([a-zA-Z]+) /)
 
1656
    {
 
1657
            my $Access = $1;
 
1658
            if($Access eq "prot")
 
1659
            {
 
1660
                    $TypeAttr->{"Protected"} = 1;
 
1661
            }
 
1662
            elsif($Access eq "priv")
 
1663
            {
 
1664
                    $TypeAttr->{"Private"} = 1;
 
1665
            }
 
1666
    }
 
1667
}
 
1668
 
 
1669
sub setFuncKind($)
 
1670
{
 
1671
        my $FuncInfoId = $_[0];
 
1672
    if($LibInfo{$Version}{$FuncInfoId}{"info"} =~ /pseudo tmpl/)
 
1673
    {
 
1674
        $FuncDescr{$Version}{$FuncInfoId}{"PseudoTemplate"} = 1;
 
1675
    }
 
1676
    elsif($LibInfo{$Version}{$FuncInfoId}{"info"} =~ /note[ ]*:[ ]*constructor /)
 
1677
    {
 
1678
        $FuncDescr{$Version}{$FuncInfoId}{"Constructor"} = 1;
 
1679
    }
 
1680
    elsif($LibInfo{$Version}{$FuncInfoId}{"info"} =~ /note[ ]*:[ ]*destructor /)
 
1681
    {
 
1682
        $FuncDescr{$Version}{$FuncInfoId}{"Destructor"} = 1;
 
1683
    }
 
1684
}
 
1685
 
 
1686
sub getFuncSpec($)
 
1687
{
 
1688
        my $FuncInfoId = $_[0];
 
1689
        my $FuncInfo = $LibInfo{$Version}{$FuncInfoId}{"info"};
 
1690
        if($FuncInfo =~ m/spec[ ]*:[ ]*pure /)
 
1691
        {
 
1692
                return "PureVirt";
 
1693
        }
 
1694
        elsif($FuncInfo =~ m/spec[ ]*:[ ]*virt /)
 
1695
        {
 
1696
                return "Virt";
 
1697
        }
 
1698
        else
 
1699
        {
 
1700
                if($FuncInfo =~ /spec[ ]*:[ ]*([a-zA-Z]+) /)
 
1701
        {
 
1702
                    return $1;
 
1703
        }
 
1704
        else
 
1705
        {
 
1706
            return "";
 
1707
        }
 
1708
        }
 
1709
}
 
1710
 
 
1711
sub getFuncClass($)
 
1712
{
 
1713
        my $FuncInfoId = $_[0];
 
1714
        my $FuncInfo = $LibInfo{$Version}{$FuncInfoId}{"info"};
 
1715
        if($FuncInfo =~ /scpe[ ]*:[ ]*@([0-9]+) /)
 
1716
    {
 
1717
        return $1;
 
1718
    }
 
1719
    else
 
1720
    {
 
1721
        return "";
 
1722
    }
 
1723
}
 
1724
 
 
1725
sub getFuncLink($)
 
1726
{
 
1727
        my $FuncInfoId = $_[0];
 
1728
        my $FuncInfo = $LibInfo{$Version}{$FuncInfoId}{"info"};
 
1729
        if($FuncInfo =~ /link[ ]*:[ ]*static /)
 
1730
        {
 
1731
                return "Static";
 
1732
        }
 
1733
        else
 
1734
        {
 
1735
                if($FuncInfo =~ /link[ ]*:[ ]*([a-zA-Z]+) /)
 
1736
        {
 
1737
            return $1;
 
1738
        }
 
1739
        else
 
1740
        {
 
1741
            return "";
 
1742
        }
 
1743
        }
 
1744
}
 
1745
 
 
1746
sub getNextElem($)
 
1747
{
 
1748
        my $FuncInfoId = $_[0];
 
1749
        my $FuncInfo = $LibInfo{$Version}{$FuncInfoId}{"info"};
 
1750
        if($FuncInfo =~ /chan[ ]*:[ ]*@([0-9]+) /)
 
1751
    {
 
1752
        return $1;
 
1753
    }
 
1754
    else
 
1755
    {
 
1756
        return "";
 
1757
    }
 
1758
}
 
1759
 
 
1760
sub getFuncParamInfoId($)
 
1761
{
 
1762
        my $FuncInfoId = $_[0];
 
1763
        my $FuncInfo = $LibInfo{$Version}{$FuncInfoId}{"info"};
 
1764
        if($FuncInfo =~ /args[ ]*:[ ]*@([0-9]+) /)
 
1765
    {
 
1766
        return $1;
 
1767
    }
 
1768
    else
 
1769
    {
 
1770
        return "";
 
1771
    }
 
1772
}
 
1773
 
 
1774
sub getFuncParamType($)
 
1775
{
 
1776
        my $ParamInfoId = $_[0];
 
1777
        my $ParamInfo = $LibInfo{$Version}{$ParamInfoId}{"info"};
 
1778
        if($ParamInfo =~ /type[ ]*:[ ]*@([0-9]+) /)
 
1779
    {
 
1780
        return $1;
 
1781
    }
 
1782
    else
 
1783
    {
 
1784
        return "";
 
1785
    }
 
1786
}
 
1787
 
 
1788
sub getFuncParamName($)
 
1789
{
 
1790
        my $ParamInfoId = $_[0];
 
1791
        my $ParamInfo = $LibInfo{$Version}{$ParamInfoId}{"info"};
 
1792
        return "" if($ParamInfo !~ /name[ ]*:[ ]*@([0-9]+) /);
 
1793
        my $NameInfoId = $1;
 
1794
        return "" if($LibInfo{$Version}{$NameInfoId}{"info"} !~ /strg[ ]*:[ ]*(.*)[ ]+lngt/);
 
1795
        my $FuncParamName = $1;
 
1796
        $FuncParamName =~ s/[ ]+\Z//g;
 
1797
        return $FuncParamName;
 
1798
}
 
1799
 
 
1800
sub getEnumMembInfoId($)
 
1801
{
 
1802
        my $TypeInfoId = $_[0];
 
1803
        my $TypeInfo = $LibInfo{$Version}{$TypeInfoId}{"info"};
 
1804
        if($TypeInfo =~ /csts[ ]*:[ ]*@([0-9]+) /)
 
1805
    {
 
1806
        return $1;
 
1807
    }
 
1808
    else
 
1809
    {
 
1810
        return "";
 
1811
    }
 
1812
}
 
1813
 
 
1814
sub getStructMembInfoId($)
 
1815
{
 
1816
        my $TypeInfoId = $_[0];
 
1817
        my $TypeInfo = $LibInfo{$Version}{$TypeInfoId}{"info"};
 
1818
        if($TypeInfo =~ /flds[ ]*:[ ]*@([0-9]+) /)
 
1819
    {
 
1820
        return $1;
 
1821
    }
 
1822
    else
 
1823
    {
 
1824
        return "";
 
1825
    }
 
1826
}
 
1827
 
 
1828
sub getNameSpace($)
 
1829
{
 
1830
    my $TypeInfoId = $_[0];
 
1831
    my $TypeInfo = $LibInfo{$Version}{$TypeInfoId}{"info"};
 
1832
    return "" if($TypeInfo !~ /scpe[ ]*:[ ]*@([0-9]+) /);
 
1833
    my $NameSpaceInfoId = $1;
 
1834
    if($LibInfo{$Version}{$NameSpaceInfoId}{"info_type"} eq "namespace_decl")
 
1835
    {
 
1836
        my $NameSpaceInfo = $LibInfo{$Version}{$NameSpaceInfoId}{"info"};
 
1837
        if($NameSpaceInfo =~ /name[ ]*:[ ]*@([0-9]+) /)
 
1838
        {
 
1839
            my $NameSpaceId = $1;
 
1840
            my $NameSpaceIdentifier = $LibInfo{$Version}{$NameSpaceId}{"info"};
 
1841
            return "" if($NameSpaceIdentifier !~ /strg[ ]*:[ ]*(.*)[ ]+lngt/);
 
1842
            my $NameSpace = $1;
 
1843
            $NameSpace =~ s/[ ]+\Z//g;
 
1844
            my $BaseNameSpace = getNameSpace($NameSpaceInfoId);
 
1845
            $NameSpace = $BaseNameSpace."::".$NameSpace if($BaseNameSpace);
 
1846
            return $NameSpace;
 
1847
        }
 
1848
        else
 
1849
        {
 
1850
            return "";
 
1851
        }
 
1852
    }
 
1853
    elsif($LibInfo{$Version}{$NameSpaceInfoId}{"info_type"} eq "record_type")
 
1854
    {
 
1855
        my %NameSpaceAttr = getTypeAttr(getTypeDeclId($NameSpaceInfoId), $NameSpaceInfoId);
 
1856
        return $NameSpaceAttr{"Name"};
 
1857
    }
 
1858
    else
 
1859
    {
 
1860
        return "";
 
1861
    }
 
1862
}
 
1863
 
 
1864
sub getNameSpaceId($)
 
1865
{
 
1866
        my $TypeInfoId = $_[0];
 
1867
        my $TypeInfo = $LibInfo{$Version}{$TypeInfoId}{"info"};
 
1868
        if($TypeInfo =~ /scpe[ ]*:[ ]*@([0-9]+) /)
 
1869
    {
 
1870
            return $1;
 
1871
    }
 
1872
    else
 
1873
    {
 
1874
        return "";
 
1875
    }
 
1876
}
 
1877
 
 
1878
sub getEnumMembName($)
 
1879
{
 
1880
        my $TypeMembInfoId = $_[0];
 
1881
        return "" if($LibInfo{$Version}{$TypeMembInfoId}{"info"} !~ /purp[ ]*:[ ]*@([0-9]+)/);
 
1882
        my $Purp = $1;
 
1883
        return "" if($LibInfo{$Version}{$Purp}{"info"} !~ /strg[ ]*:[ ]*(.*)[ ]+lngt/);
 
1884
        my $EnumMembName = $1;
 
1885
        $EnumMembName =~ s/[ ]+\Z//g;
 
1886
        return $EnumMembName;
 
1887
}
 
1888
 
 
1889
sub getStructMembName($)
 
1890
{
 
1891
        my $TypeMembInfoId = $_[0];
 
1892
        return "" if($LibInfo{$Version}{$TypeMembInfoId}{"info"} !~ /name[ ]*:[ ]*@([0-9]+) /);
 
1893
        my $NameInfoId = $1;
 
1894
        return "" if($LibInfo{$Version}{$NameInfoId}{"info"} !~ /strg[ ]*:[ ]*(.*)[ ]+lngt/);
 
1895
        my $StructMembName = $1;
 
1896
        $StructMembName =~ s/[ ]+\Z//g;
 
1897
        return $StructMembName;
 
1898
}
 
1899
 
 
1900
sub getEnumMembVal($)
 
1901
{
 
1902
        my $TypeMembInfoId = $_[0];
 
1903
        return "" if($LibInfo{$Version}{$TypeMembInfoId}{"info"} !~ /valu[ ]*:[ ]*@([0-9]+) /);
 
1904
        my $Valu = $1;
 
1905
        if($LibInfo{$Version}{$Valu}{"info"} =~ /low[ ]*:[ ]*(-?[0-9]+) /)
 
1906
    {
 
1907
        return $1;
 
1908
    }
 
1909
    else
 
1910
    {
 
1911
        return "";
 
1912
    }
 
1913
}
 
1914
 
 
1915
sub getSize($)
 
1916
{
 
1917
        my $Info = $LibInfo{$Version}{$_[0]}{"info"};
 
1918
        if($Info =~ /size[ ]*:[ ]*@([0-9]+) /)
 
1919
        {
 
1920
        my $SizeInfoId = $1;
 
1921
                if($LibInfo{$Version}{$SizeInfoId}{"info"} =~ /low[ ]*:[ ]*(-?[0-9]+) /)
 
1922
        {
 
1923
                    return $1;
 
1924
        }
 
1925
        else
 
1926
        {
 
1927
            return "";
 
1928
        }
 
1929
        }
 
1930
        else
 
1931
        {
 
1932
                return 0;
 
1933
        }
 
1934
}
 
1935
 
 
1936
sub getStructMembType($)
 
1937
{
 
1938
        my $TypeMembInfoId = $_[0];
 
1939
        if($LibInfo{$Version}{$TypeMembInfoId}{"info"} =~ /type[ ]*:[ ]*@([0-9]+) /)
 
1940
    {
 
1941
        return $1;
 
1942
    }
 
1943
    else
 
1944
    {
 
1945
        return "";
 
1946
    }
 
1947
}
 
1948
 
 
1949
sub getStructMembBitFieldSize($)
 
1950
{
 
1951
        my $TypeMembInfoId = $_[0];
 
1952
        if($LibInfo{$Version}{$TypeMembInfoId}{"info"} =~ / bitfield /)
 
1953
        {
 
1954
                return getSize($TypeMembInfoId);
 
1955
        }
 
1956
        else
 
1957
        {
 
1958
                return 0;
 
1959
        }
 
1960
}
 
1961
 
 
1962
sub getStructMembAccess($)
 
1963
{
 
1964
        my $MembInfo = $LibInfo{$Version}{$_[0]}{"info"};
 
1965
        if($MembInfo =~ /accs[ ]*:[ ]*([a-zA-Z]+) /)
 
1966
    {
 
1967
            my $Access = $1;
 
1968
            if($Access eq "prot")
 
1969
            {
 
1970
                    return "protected";
 
1971
            }
 
1972
            elsif($Access eq "priv")
 
1973
            {
 
1974
                    return "private";
 
1975
            }
 
1976
            else
 
1977
            {
 
1978
                    return "public";
 
1979
            }
 
1980
    }
 
1981
    else
 
1982
    {
 
1983
        return "public";
 
1984
    }
 
1985
}
 
1986
 
 
1987
sub getNextMembInfoId($)
 
1988
{
 
1989
        my $TypeMembInfoId = $_[0];
 
1990
        if($LibInfo{$Version}{$TypeMembInfoId}{"info"} =~ /chan[ ]*:[ ]*@([0-9]+) /)
 
1991
    {
 
1992
        return $1;
 
1993
    }
 
1994
    else
 
1995
    {
 
1996
        return "";
 
1997
    }
 
1998
}
 
1999
 
 
2000
sub getNextStructMembInfoId($)
 
2001
{
 
2002
        my $TypeMembInfoId = $_[0];
 
2003
        if($LibInfo{$Version}{$TypeMembInfoId}{"info"} =~ /chan[ ]*:[ ]*@([0-9]+) /)
 
2004
    {
 
2005
        return $1;
 
2006
    }
 
2007
    else
 
2008
    {
 
2009
        return "";
 
2010
    }
 
2011
}
 
2012
 
 
2013
sub fieldHasName($)
 
2014
{
 
2015
        my $TypeMembInfoId = $_[0];
 
2016
        if($LibInfo{$Version}{$TypeMembInfoId}{"info_type"} eq "field_decl")
 
2017
        {
 
2018
                if($LibInfo{$Version}{$TypeMembInfoId}{"info"} =~ /name[ ]*:[ ]*@([0-9]+) /)
 
2019
        {
 
2020
            return $1;
 
2021
        }
 
2022
        else
 
2023
        {
 
2024
            return "";
 
2025
        }
 
2026
        }
 
2027
        else
 
2028
        {
 
2029
                return 0;
 
2030
        }
 
2031
}
 
2032
 
 
2033
sub getTypeHeader($)
 
2034
{
 
2035
        my $TypeInfo = $LibInfo{$Version}{$_[0]}{"info"};
 
2036
        if($TypeInfo =~ /srcp[ ]*:[ ]*([0-9a-zA-Z\_\-\<\>\.\+]+):([0-9]+) /)
 
2037
    {
 
2038
        return ($1, $2);
 
2039
    }
 
2040
    else
 
2041
    {
 
2042
        return ();
 
2043
    }
 
2044
}
 
2045
 
 
2046
sub register_header($$$)
 
2047
{
 
2048
    my ($Destination, $Position, $LibVersion) = @_;
 
2049
    return if(not $Destination);
 
2050
    if($Destination=~/\A\// and not -f $Destination)
 
2051
    {
 
2052
        print "\nERROR: specified header \'$Destination\' does not exist\n";
 
2053
        return;
 
2054
    }
 
2055
    my $Header_Name = get_FileName($Destination);
 
2056
    $Headers{$LibVersion}{$Destination}{"Name"} = $Header_Name;
 
2057
    $Headers{$LibVersion}{$Destination}{"Position"} = $Position;
 
2058
    $Headers{$LibVersion}{$Destination}{"Identity"} = $Destination;
 
2059
    $HeaderName_Destinations{$LibVersion}{$Header_Name}{$Destination} = 1;
 
2060
}
 
2061
 
 
2062
sub headerSearch($)
 
2063
{
 
2064
    my $LibVersion = $_[0];
 
2065
    foreach my $Dest (split("\n", $Descriptor{$LibVersion}{"Include_Paths"}))
 
2066
    {
 
2067
        $Dest =~ s/\A\s+|\s+\Z//g;
 
2068
        next if(not $Dest);
 
2069
        if(not -e $Dest)
 
2070
        {
 
2071
            print "ERROR: can't access \'$Dest\'\n";
 
2072
        }
 
2073
        $Header_Dependency{$LibVersion}{$Dest} = 1;
 
2074
    }
 
2075
    foreach my $Dest (split("\n", $Descriptor{$LibVersion}{"Headers"}))
 
2076
    {#fill %Header_Dependency
 
2077
        if(-d $Dest)
 
2078
        {
 
2079
            foreach my $Dir (cmd_find($Dest,"d",""))
 
2080
            {
 
2081
                chomp($Dir);
 
2082
                $Header_Dependency{$LibVersion}{$Dir} = 1;
 
2083
            }
 
2084
        }
 
2085
        elsif(-f $Dest)
 
2086
        {
 
2087
            $Header_Dependency{$LibVersion}{get_Dir($Dest)} = 1;
 
2088
        }
 
2089
    }
 
2090
    my $Position = 0;
 
2091
        foreach my $Dest (split("\n", $Descriptor{$LibVersion}{"Headers"}))
 
2092
        {
 
2093
        $Dest =~ s/\A\s+|\s+\Z//g;
 
2094
        next if(not $Dest);
 
2095
        if(is_header($Dest, $LibVersion))
 
2096
        {
 
2097
            register_header($Dest, $Position, $LibVersion);
 
2098
            $Position += 1;
 
2099
        }
 
2100
        elsif(-d $Dest)
 
2101
        {
 
2102
            foreach my $Destination (sort {lc($a) cmp lc($b)} (cmd_find($Dest,"f","")))
 
2103
            {
 
2104
                chomp($Destination);
 
2105
                next if(not is_header($Destination, $LibVersion));
 
2106
                register_header($Destination, $Position, $LibVersion);
 
2107
                $Position += 1;
 
2108
            }
 
2109
        }
 
2110
        else
 
2111
        {
 
2112
            print "WARNING: \'$Dest\' was not found in the specified include paths\n";
 
2113
            register_header($Dest, $Position, $LibVersion);
 
2114
            $Position += 1;
 
2115
        }
 
2116
        }
 
2117
    if(keys(%{$Headers{$LibVersion}})==1)
 
2118
    {
 
2119
        my $Destination = (keys(%{$Headers{$LibVersion}}))[0];
 
2120
        $Headers{$LibVersion}{$Destination}{"Identity"} = $Headers{$LibVersion}{$Destination}{"Name"};
 
2121
    }
 
2122
    foreach my $Header_Name (keys(%{$HeaderName_Destinations{$LibVersion}}))
 
2123
    {#set relative paths (for dublicates)
 
2124
        if(keys(%{$HeaderName_Destinations{$LibVersion}{$Header_Name}})>1)
 
2125
        {
 
2126
            my $FirstDest = (keys(%{$HeaderName_Destinations{$LibVersion}{$Header_Name}}))[0];
 
2127
            my $Prefix = get_Dir($FirstDest);
 
2128
            while($Prefix =~ /\A(.+)\/[^\/]+\Z/)
 
2129
            {
 
2130
                my $NewPrefix = $1;
 
2131
                my $Changes_Number = 0;
 
2132
                my %Identity = ();
 
2133
                foreach my $Dest (keys(%{$HeaderName_Destinations{$LibVersion}{$Header_Name}}))
 
2134
                {
 
2135
                    if($Dest =~ /\A$Prefix\/(.*)\Z/)
 
2136
                    {
 
2137
                        $Identity{$Dest} = $1;
 
2138
                        $Changes_Number+=1;
 
2139
                    }
 
2140
                }
 
2141
                if($Changes_Number eq keys(%{$HeaderName_Destinations{$LibVersion}{$Header_Name}}))
 
2142
                {
 
2143
                    foreach my $Dest (keys(%{$HeaderName_Destinations{$LibVersion}{$Header_Name}}))
 
2144
                    {
 
2145
                        $Headers{$LibVersion}{$Dest}{"Identity"} = $Identity{$Dest};
 
2146
                    }
 
2147
                    last;
 
2148
                }
 
2149
                $Prefix = $NewPrefix;
 
2150
            }
 
2151
        }
 
2152
    }
 
2153
    if(not keys(%{$Headers{$LibVersion}}))
 
2154
    {
 
2155
        print "ERROR: header files were not found\n";
 
2156
        exit(1);
 
2157
    }
 
2158
}
 
2159
 
 
2160
sub get_FileName($)
 
2161
{
 
2162
    my $Path = $_[0];
 
2163
    if($Path =~ /\A(.*\/)([^\/]*)\Z/)
 
2164
    {
 
2165
        return $2;
 
2166
    }
 
2167
    else
 
2168
    {
 
2169
        return $Path;
 
2170
    }
 
2171
}
 
2172
 
 
2173
sub get_Dir($)
 
2174
{
 
2175
    my $Path = $_[0];
 
2176
    return "" if($Path =~ m*\A\./*);
 
2177
    if($Path =~ /\A(.*)\/([^\/]*)\Z/)
 
2178
    {
 
2179
        return $1;
 
2180
    }
 
2181
    else
 
2182
    {
 
2183
        return "";
 
2184
    }
 
2185
}
 
2186
 
 
2187
sub esc($)
 
2188
{
 
2189
        my $Str = $_[0];
 
2190
        $Str =~ s/([()\[\]{}$ &'"`;,<>])/\\$1/g;
 
2191
        return $Str;
 
2192
}
 
2193
 
 
2194
sub getLocation($)
 
2195
{
 
2196
        my $TypeInfo = $LibInfo{$Version}{$_[0]}{"info"};
 
2197
        if($TypeInfo =~ /srcp[ ]*:[ ]*([0-9a-zA-Z\_\-\<\>\.\+]+):([0-9]+) /)
 
2198
    {
 
2199
            return ($1, $2);
 
2200
    }
 
2201
    else
 
2202
    {
 
2203
        return ();
 
2204
    }
 
2205
}
 
2206
 
 
2207
sub getHeader($)
 
2208
{
 
2209
    my $TypeInfo = $LibInfo{$Version}{$_[0]}{"info"};
 
2210
    if($TypeInfo =~ /srcp[ ]*:[ ]*([0-9a-zA-Z\_\-\<\>\.\+]+):([0-9]+) /)
 
2211
    {
 
2212
        return $1;
 
2213
    }
 
2214
    else
 
2215
    {
 
2216
        return "";
 
2217
    }
 
2218
}
 
2219
 
 
2220
sub getLine($)
 
2221
{
 
2222
    my $TypeInfo = $LibInfo{$Version}{$_[0]}{"info"};
 
2223
    if($TypeInfo =~ /srcp[ ]*:[ ]*([0-9a-zA-Z\_\-\<\>\.\+]+):([0-9]+) /)
 
2224
    {
 
2225
        return $2;
 
2226
    }
 
2227
    else
 
2228
    {
 
2229
        return "";
 
2230
    }
 
2231
}
 
2232
 
 
2233
sub getTypeType($$)
 
2234
{
 
2235
        my ($TypeDeclId, $TypeId) = @_;
 
2236
        return "Const" if($LibInfo{$Version}{$TypeId}{"info"} =~ /qual[ ]*:[ ]*c / and $LibInfo{$Version}{$TypeId}{"info"} =~ /unql[ ]*:[ ]*\@/);
 
2237
        return "Typedef" if($LibInfo{$Version}{$TypeId}{"info"} =~ /unql[ ]*:/ and $LibInfo{$Version}{$TypeId}{"info"} !~ /qual[ ]*:/);
 
2238
        return "Volatile" if($LibInfo{$Version}{$TypeId}{"info"} =~ /qual[ ]*:[ ]*v / and $LibInfo{$Version}{$TypeId}{"info"} =~ /unql[ ]*:[ ]*\@/);
 
2239
        return "Restrict" if($LibInfo{$Version}{$TypeId}{"info"} =~ /qual[ ]*:[ ]*r / and $LibInfo{$Version}{$TypeId}{"info"} =~ /unql[ ]*:[ ]*\@/);
 
2240
        my $TypeType = getTypeTypeByTypeId($TypeId);
 
2241
        if($TypeType eq "Struct")
 
2242
        {
 
2243
                if($TypeDeclId and $LibInfo{$Version}{$TypeDeclId}{"info_type"} eq "template_decl")
 
2244
        {
 
2245
            return "Template";
 
2246
        }
 
2247
        else
 
2248
        {
 
2249
            return "Struct";
 
2250
        }
 
2251
        }
 
2252
        else
 
2253
        {
 
2254
                return $TypeType;
 
2255
        }
 
2256
        
 
2257
}
 
2258
 
 
2259
sub getTypeTypeByTypeId($)
 
2260
{
 
2261
        my $TypeId = $_[0];
 
2262
        my $TypeType = $LibInfo{$Version}{$TypeId}{"info_type"};
 
2263
        if($TypeType =~ /integer_type|real_type|boolean_type|void_type|complex_type/)
 
2264
        {
 
2265
                return "Intrinsic";
 
2266
        }
 
2267
        elsif(isFuncPtr($TypeId))
 
2268
        {
 
2269
                return "FuncPtr";
 
2270
        }
 
2271
        elsif($TypeType eq "pointer_type")
 
2272
        {
 
2273
                return "Pointer";
 
2274
        }
 
2275
        elsif($TypeType eq "reference_type")
 
2276
        {
 
2277
                return "Ref";
 
2278
        }
 
2279
        elsif($TypeType eq "union_type")
 
2280
        {
 
2281
                return "Union";
 
2282
        }
 
2283
        elsif($TypeType eq "enumeral_type")
 
2284
        {
 
2285
                return "Enum";
 
2286
        }
 
2287
        elsif($TypeType eq "record_type")
 
2288
        {
 
2289
                return "Struct";
 
2290
        }
 
2291
        elsif($TypeType eq "array_type")
 
2292
        {
 
2293
                return "Array";
 
2294
        }
 
2295
        elsif($TypeType eq "complex_type")
 
2296
        {
 
2297
                return "Intrinsic";
 
2298
        }
 
2299
        elsif($TypeType eq "function_type")
 
2300
        {
 
2301
                return "FunctionType";
 
2302
        }
 
2303
    elsif($TypeType eq "method_type")
 
2304
    {
 
2305
        return "MethodType";
 
2306
    }
 
2307
        else
 
2308
        {
 
2309
                return "Unknown";
 
2310
        }
 
2311
}
 
2312
 
 
2313
sub getNameByInfo($)
 
2314
{
 
2315
        my $TypeInfo = $LibInfo{$Version}{$_[0]}{"info"};
 
2316
        return "" if($TypeInfo !~ /name[ ]*:[ ]*@([0-9]+) /);
 
2317
        my $TypeNameInfoId = $1;
 
2318
        return "" if($LibInfo{$Version}{$TypeNameInfoId}{"info"} !~ /strg[ ]*:[ ]*(.*)[ ]+lngt/);
 
2319
        my $TypeName = $1;
 
2320
        $TypeName =~ s/[ ]+\Z//g;
 
2321
        return $TypeName;
 
2322
}
 
2323
 
 
2324
sub getFuncShortName($)
 
2325
{
 
2326
        my $FuncInfo = $LibInfo{$Version}{$_[0]}{"info"};
 
2327
    if($FuncInfo =~ / operator /)
 
2328
    {
 
2329
        if($FuncInfo =~ /note[ ]*:[ ]*conversion /)
 
2330
        {
 
2331
            return "operator ".get_TypeName($FuncDescr{$Version}{$_[0]}{"Return"});
 
2332
        }
 
2333
        else
 
2334
        {
 
2335
            return "" if($FuncInfo !~ / operator[ ]+([a-zA-Z]+) /);
 
2336
            return "operator".$Operator_Indication{$1};
 
2337
        }
 
2338
    }
 
2339
    else
 
2340
    {
 
2341
        return "" if($FuncInfo !~ /name[ ]*:[ ]*@([0-9]+) /);
 
2342
        my $FuncNameInfoId = $1;
 
2343
        return "" if($LibInfo{$Version}{$FuncNameInfoId}{"info"} !~ /strg[ ]*:[ ]*([^ ]*)[ ]+lngt/);
 
2344
        return $1;
 
2345
    }
 
2346
}
 
2347
 
 
2348
sub getFuncMnglName($)
 
2349
{
 
2350
        my $FuncInfo = $LibInfo{$Version}{$_[0]}{"info"};
 
2351
        return "" if($FuncInfo !~ /mngl[ ]*:[ ]*@([0-9]+) /);
 
2352
        my $FuncMnglNameInfoId = $1;
 
2353
        return "" if($LibInfo{$Version}{$FuncMnglNameInfoId}{"info"} !~ /strg[ ]*:[ ]*([^ ]*)[ ]+/);
 
2354
        my $FuncMnglName = $1;
 
2355
        $FuncMnglName =~ s/[ ]+\Z//g;
 
2356
        return $FuncMnglName;
 
2357
}
 
2358
 
 
2359
sub getFuncReturn($)
 
2360
{
 
2361
        my $FuncInfo = $LibInfo{$Version}{$_[0]}{"info"};
 
2362
        return "" if($FuncInfo !~ /type[ ]*:[ ]*@([0-9]+) /);
 
2363
        my $FuncTypeInfoId = $1;
 
2364
        return "" if($LibInfo{$Version}{$FuncTypeInfoId}{"info"} !~ /retn[ ]*:[ ]*@([0-9]+) /);
 
2365
        my $FuncReturnTypeId = $1;
 
2366
        if($TypeDescr{$Version}{getTypeDeclId($FuncReturnTypeId)}{$FuncReturnTypeId}{"Type"} eq "Restrict")
 
2367
        {#delete restrict spec
 
2368
                $FuncReturnTypeId = getRestrictBase($FuncReturnTypeId);
 
2369
        }
 
2370
        return $FuncReturnTypeId;
 
2371
}
 
2372
 
 
2373
sub getFuncOrig($)
 
2374
{
 
2375
        my $FuncInfo = $LibInfo{$Version}{$_[0]}{"info"};
 
2376
        if($FuncInfo =~ /orig[ ]*:[ ]*@([0-9]+) /)
 
2377
    {
 
2378
            return $1;
 
2379
    }
 
2380
    else
 
2381
    {
 
2382
        return $_[0];
 
2383
    }
 
2384
}
 
2385
 
 
2386
sub unmangleArray(@)
 
2387
{
 
2388
    if($#_>$MAX_COMMAND_LINE_ARGUMENTS)
 
2389
    {
 
2390
        my @Half = splice(@_, 0, ($#_+1)/2);
 
2391
        return (unmangleArray(@Half), unmangleArray(@_))
 
2392
    }
 
2393
    else
 
2394
    {
 
2395
        my $UnmangleCommand = "c++filt ".join(" ", @_);
 
2396
        return split("\n", `$UnmangleCommand`);
 
2397
    }
 
2398
}
 
2399
 
 
2400
sub get_Signature($$)
 
2401
{
 
2402
        my ($Interface, $LibVersion) = @_;
 
2403
    return $Cache{"get_Signature"}{$Interface}{$LibVersion} if($Cache{"get_Signature"}{$Interface}{$LibVersion});
 
2404
    my ($MnglName, $SymbolVersion) = ($Interface, "");
 
2405
    if($Interface =~ /\A([^@]+)[\@]+([^@]+)\Z/)
 
2406
    {
 
2407
        ($MnglName, $SymbolVersion) = ($1, $2);
 
2408
    }
 
2409
    if($MnglName =~ /\A(_ZGV|_ZTI|_ZTS|_ZTT|_ZTV|_ZThn|_ZTv0_n)/)
 
2410
    {
 
2411
        $Cache{"get_Signature"}{$Interface}{$LibVersion} = $tr_name{$MnglName}.(($SymbolVersion)?"\@".$SymbolVersion:"");
 
2412
        return $Cache{"get_Signature"}{$Interface}{$LibVersion};
 
2413
    }
 
2414
    if(not $CompleteSignature{$LibVersion}{$Interface})
 
2415
    {
 
2416
        if($Interface =~ /\A_Z/)
 
2417
        {
 
2418
            $Cache{"get_Signature"}{$Interface}{$LibVersion} = $tr_name{$MnglName}.(($SymbolVersion)?"\@".$SymbolVersion:"");
 
2419
            return $Cache{"get_Signature"}{$Interface}{$LibVersion};
 
2420
        }
 
2421
        else
 
2422
        {
 
2423
            $Cache{"get_Signature"}{$Interface}{$LibVersion} = $Interface;
 
2424
            return $Interface;
 
2425
        }
 
2426
    }
 
2427
    my ($Func_Signature, @Param_Types_FromUnmangledName) = ();
 
2428
    my $ShortName = $CompleteSignature{$LibVersion}{$Interface}{"ShortName"};
 
2429
    if($Interface =~ /\A_Z/)
 
2430
    {
 
2431
        if($CompleteSignature{$LibVersion}{$Interface}{"Class"})
 
2432
        {
 
2433
            $Func_Signature = get_TypeName($CompleteSignature{$LibVersion}{$Interface}{"Class"}, $LibVersion)."::".(($CompleteSignature{$LibVersion}{$Interface}{"Destructor"})?"~":"").$ShortName;
 
2434
        }
 
2435
        else
 
2436
        {
 
2437
            $Func_Signature = $ShortName;
 
2438
        }
 
2439
        @Param_Types_FromUnmangledName = get_Signature_Parts($tr_name{$MnglName}, 0);
 
2440
    }
 
2441
    else
 
2442
    {
 
2443
        $Func_Signature = $MnglName;
 
2444
    }
 
2445
    my @ParamArray = ();
 
2446
    foreach my $Pos (sort {int($a) <=> int($b)} keys(%{$CompleteSignature{$LibVersion}{$Interface}{"Param"}}))
 
2447
    {
 
2448
        next if($Pos eq "");
 
2449
        my $ParamTypeId = $CompleteSignature{$LibVersion}{$Interface}{"Param"}{$Pos}{"type"};
 
2450
        my $ParamTypeName = $TypeDescr{$LibVersion}{$Tid_TDid{$LibVersion}{$ParamTypeId}}{$ParamTypeId}{"Name"};
 
2451
        $ParamTypeName = $Param_Types_FromUnmangledName[$Pos] if(not $ParamTypeName);
 
2452
        if(my $ParamName = $CompleteSignature{$LibVersion}{$Interface}{"Param"}{$Pos}{"name"})
 
2453
        {
 
2454
            if($ParamTypeName=~/\([*]+\)/)
 
2455
            {
 
2456
                $ParamTypeName=~s/\(([*]+)\)/\($1$ParamName\)/;
 
2457
                push(@ParamArray, $ParamTypeName);
 
2458
            }
 
2459
            else
 
2460
            {
 
2461
                push(@ParamArray, $ParamTypeName." ".$ParamName);
 
2462
            }
 
2463
        }
 
2464
        else
 
2465
        {
 
2466
            push(@ParamArray, $ParamTypeName);
 
2467
        }
 
2468
    }
 
2469
    if(not $CompleteSignature{$LibVersion}{$Interface}{"Data"})
 
2470
    {
 
2471
        if($Interface=~/\A_Z/)
 
2472
        {
 
2473
            if($CompleteSignature{$LibVersion}{$Interface}{"Constructor"})
 
2474
            {
 
2475
                if($Interface=~/C1/)
 
2476
                {
 
2477
                    $Func_Signature .= " [in-charge]";
 
2478
                }
 
2479
                elsif($Interface=~/C2/)
 
2480
                {
 
2481
                    $Func_Signature .= " [not-in-charge]";
 
2482
                }
 
2483
            }
 
2484
            elsif($CompleteSignature{$LibVersion}{$Interface}{"Destructor"})
 
2485
            {
 
2486
                if($Interface=~/D1/)
 
2487
                {
 
2488
                    $Func_Signature .= " [in-charge]";
 
2489
                }
 
2490
                elsif($Interface=~/D2/)
 
2491
                {
 
2492
                    $Func_Signature .= " [not-in-charge]";
 
2493
                }
 
2494
                elsif($Interface=~/D0/)
 
2495
                {
 
2496
                    $Func_Signature .= " [in-charge-deleting]";
 
2497
                }
 
2498
            }
 
2499
        }
 
2500
        $Func_Signature .= " (".join(", ", @ParamArray).")";
 
2501
    }
 
2502
    if($Interface=~/\A_ZNK/)
 
2503
    {
 
2504
        $Func_Signature .= " const";
 
2505
    }
 
2506
    $Func_Signature .= "\@".$SymbolVersion if($SymbolVersion);
 
2507
    $Cache{"get_Signature"}{$Interface}{$LibVersion} = $Func_Signature;
 
2508
    return $Func_Signature;
 
2509
}
 
2510
 
 
2511
sub getVarNameByAttr($)
 
2512
{
 
2513
        my $FuncInfoId = $_[0];
 
2514
        my $VarName;
 
2515
        return "" if(not $FuncDescr{$Version}{$FuncInfoId}{"ShortName"});
 
2516
        if($FuncDescr{$Version}{$FuncInfoId}{"Class"})
 
2517
        {
 
2518
                $VarName .= $TypeDescr{$Version}{getTypeDeclId($FuncDescr{$Version}{$FuncInfoId}{"Class"})}{$FuncDescr{$Version}{$FuncInfoId}{"Class"}}{"Name"};
 
2519
                $VarName .= "::";
 
2520
        }
 
2521
        $VarName .= $FuncDescr{$Version}{$FuncInfoId}{"ShortName"};
 
2522
        return $VarName;
 
2523
}
 
2524
 
 
2525
sub mangleFuncName($)
 
2526
{
 
2527
        my $FuncId = $_[0];
 
2528
}
 
2529
 
 
2530
sub getFuncType($)
 
2531
{
 
2532
        my $FuncInfo = $LibInfo{$Version}{$_[0]}{"info"};
 
2533
        return "" if($FuncInfo !~ /type[ ]*:[ ]*@([0-9]+) /);
 
2534
        my $FuncTypeInfoId = $1;
 
2535
        my $FunctionType = $LibInfo{$Version}{$FuncTypeInfoId}{"info_type"};
 
2536
        if($FunctionType eq "method_type")
 
2537
        {
 
2538
                return "Method";
 
2539
        }
 
2540
        elsif($FunctionType eq "function_type")
 
2541
        {
 
2542
                return "Function";
 
2543
        }
 
2544
        else
 
2545
        {
 
2546
                return $FunctionType;
 
2547
        }
 
2548
}
 
2549
 
 
2550
sub getFuncTypeId($)
 
2551
{
 
2552
    my $FuncInfo = $LibInfo{$Version}{$_[0]}{"info"};
 
2553
    if($FuncInfo =~ /type[ ]*:[ ]*@([0-9]+)( |\Z)/)
 
2554
    {
 
2555
        return $1;
 
2556
    }
 
2557
    else
 
2558
    {
 
2559
        return 0;
 
2560
    }
 
2561
}
 
2562
 
 
2563
sub isNotAnon($)
 
2564
{
 
2565
        return (not isAnon($_[0]));
 
2566
}
 
2567
 
 
2568
sub isAnon($)
 
2569
{
 
2570
        return (($_[0] =~ m/\.\_[0-9]+/) or ($_[0] =~ m/anon-/));
 
2571
}
 
2572
 
 
2573
sub unmangled_Compact($$)
 
2574
#Removes all non-essential (for C++ language) whitespace from a string.  If 
 
2575
#the whitespace is essential it will be replaced with exactly one ' ' 
 
2576
#character. Works correctly only for unmangled names.
 
2577
#If level > 1 is supplied, can relax its intent to compact the string.
 
2578
{
 
2579
  my $result=$_[0];
 
2580
  my $level = $_[1] || 1;
 
2581
  my $o1 = ($level>1)?' ':'';
 
2582
  #First, we reduce all spaces that we can
 
2583
  my $coms='[-()<>:*&~!|+=%@~"?.,/[^'."']";
 
2584
  my $coms_nobr='[-()<:*&~!|+=%@~"?.,'."']";
 
2585
  my $clos='[),;:\]]';
 
2586
  $result=~s/^\s+//gm;
 
2587
  $result=~s/\s+$//gm;
 
2588
  $result=~s/((?!\n)\s)+/ /g;
 
2589
  $result=~s/(\w+)\s+($coms+)/$1$o1$2/gm;
 
2590
  #$result=~s/(\w)(\()/$1$o1$2/gm if $o1;
 
2591
  $result=~s/($coms+)\s+(\w+)/$1$o1$2/gm;
 
2592
  $result=~s/(\()\s+(\w)/$1$2/gm if $o1;
 
2593
  $result=~s/(\w)\s+($clos)/$1$2/gm;
 
2594
  $result=~s/($coms+)\s+($coms+)/$1 $2/gm;
 
2595
  $result=~s/($coms_nobr+)\s+($coms+)/$1$o1$2/gm;
 
2596
  $result=~s/($coms+)\s+($coms_nobr+)/$1$o1$2/gm;
 
2597
  #don't forget about >> and <:.  In unmangled names global-scope modifier 
 
2598
  #is not used, so <: will always be a digraph and requires no special treatment.
 
2599
  #We also try to remove other parts that are better to be removed here than in other places
 
2600
  #double-cv
 
2601
  $result=~s/\bconst\s+const\b/const/gm;
 
2602
  $result=~s/\bvolatile\s+volatile\b/volatile/gm;
 
2603
  $result=~s/\bconst\s+volatile\b\s+const\b/const volatile/gm;
 
2604
  $result=~s/\bvolatile\s+const\b\s+volatile\b/const volatile/gm;
 
2605
  #Place cv in proper order
 
2606
  $result=~s/\bvolatile\s+const\b/const volatile/gm;
 
2607
  return $result;
 
2608
}
 
2609
 
 
2610
sub unmangled_PostProcess($)
 
2611
{
 
2612
  my $result = $_[0];
 
2613
  #s/\bunsigned int\b/unsigned/g;
 
2614
  $result =~ s/\bshort unsigned int\b/unsigned short/g;
 
2615
  $result =~ s/\bshort int\b/short/g;
 
2616
  $result =~ s/\blong long unsigned int\b/unsigned long long/g;
 
2617
  $result =~ s/\blong unsigned int\b/unsigned long/g;
 
2618
  $result =~ s/\blong long int\b/long long/g;
 
2619
  $result =~ s/\blong int\b/long/g;
 
2620
  $result =~ s/\)const\b/\) const/g;
 
2621
  $result =~ s/\blong long unsigned\b/unsigned long long/g;
 
2622
  $result =~ s/\blong unsigned\b/unsigned long/g;
 
2623
  return $result;
 
2624
}
 
2625
 
 
2626
# From libtodb2/libtodb.pm
 
2627
# Trim string spaces.
 
2628
sub trim($)
 
2629
{
 
2630
        my $string = shift;
 
2631
        $string =~ s/^\s+//;
 
2632
        $string =~ s/\s+$//;
 
2633
        return $string;
 
2634
}
 
2635
 
 
2636
sub correctName($)
 
2637
{#type name correction
 
2638
    my $CorrectName = $_[0];
 
2639
    $CorrectName = unmangled_Compact($CorrectName, 1);
 
2640
    $CorrectName = unmangled_PostProcess($CorrectName);
 
2641
        return $CorrectName;
 
2642
}
 
2643
 
 
2644
sub getDump_AllInOne()
 
2645
{
 
2646
    return if(not keys(%Headers));
 
2647
    `mkdir -p temp && rm -f temp/*`;
 
2648
        my $Header_Depend = "";
 
2649
    foreach my $Dep (sort {length($a) <=> length($b)} keys(%{$Header_Dependency{$Version}}))
 
2650
    {
 
2651
        $Header_Depend .= " -I".esc($Dep);
 
2652
    }
 
2653
    my $Lib_VersionName = esc($TargetLibraryName)."_v".$Version;
 
2654
    open(LIB_HEADER, ">temp/$TargetLibraryName"."_v$Version.h");
 
2655
    foreach my $Preamble_Header (sort {int($Include_Preamble{$Version}{$a}{"Position"})<=>int($Include_Preamble{$Version}{$b}{"Position"})} keys(%{$Include_Preamble{$Version}}))
 
2656
    {
 
2657
        print LIB_HEADER "#include <$Preamble_Header>\n";
 
2658
    }
 
2659
        foreach my $Destination (sort {int($Headers{$Version}{$a}{"Position"})<=>int($Headers{$Version}{$b}{"Position"})} keys(%{$Headers{$Version}}))
 
2660
        {
 
2661
        my $HName = get_FileName($Destination);
 
2662
        next if($Include_Preamble{$Version}{$Destination} or ($Include_Preamble{$Version}{$HName} and $HeaderName_Destinations{$Version}{$HName} and keys(%{$HeaderName_Destinations{$Version}{$HName}})==1));
 
2663
                print LIB_HEADER "#include <$Destination>\n";
 
2664
        }
 
2665
        close(LIB_HEADER);
 
2666
        system("g++ >".esc($ERR_PATH{$Version})." 2>&1 -fdump-translation-unit temp/$Lib_VersionName.h $CompilerOptions{$Version} $Header_Depend");
 
2667
    if($?)
 
2668
    {
 
2669
        print "WARNING: some errors have occured while compiling header(s), fix it first!\nyou can see compilation errors in the file \'$ERR_PATH{$Version}\'\n";
 
2670
    }
 
2671
    $ConstantsSrc{$Version} = cmd_preprocessor("temp/$Lib_VersionName.h", $CompilerOptions{$Version}." ".$Header_Depend, "define\\ \\|undef\\ \\|#[ ]\\+[0-9]\\+ \".*\"");
 
2672
    system("mkdir", "-p", "header_compile_errors/$TargetLibraryName/temp/");
 
2673
    system("cp", "-f", "temp/$TargetLibraryName"."_v$Version.h", "header_compile_errors/$TargetLibraryName/temp/");
 
2674
        return (split("\n", `find . -maxdepth 1 -name "$Lib_VersionName\.h*\.tu"`))[0];
 
2675
}
 
2676
 
 
2677
sub getDump_Separately($)
 
2678
{
 
2679
    `mkdir -p temp`;
 
2680
    `rm -f temp/*`;
 
2681
        my $Destination = $_[0];
 
2682
        my $Header_Depend = "";
 
2683
    foreach my $Dep (sort {length($a) <=> length($b)} keys(%{$Header_Dependency{$Version}}))
 
2684
    {
 
2685
        $Header_Depend .= " -I".esc($Dep);
 
2686
    }
 
2687
    my $Lib_VersionName = esc($TargetLibraryName)."_v".$Version;
 
2688
        open(LIB_HEADER, ">temp/$TargetLibraryName"."_v$Version.h");
 
2689
    foreach my $Preamble_Header (sort {int($Include_Preamble{$Version}{$a}{"Position"})<=>int($Include_Preamble{$Version}{$b}{"Position"})} keys(%{$Include_Preamble{$Version}}))
 
2690
    {
 
2691
        print LIB_HEADER "#include <$Preamble_Header>\n";
 
2692
    }
 
2693
    my $Destination_HName = get_FileName($Destination);
 
2694
    if(not ( $Include_Preamble{$Version}{$Destination} or ($Include_Preamble{$Version}{$Destination_HName} and $HeaderName_Destinations{$Version}{$Destination_HName} and keys(%{$HeaderName_Destinations{$Version}{$Destination_HName}})==1) ))
 
2695
    {
 
2696
        print LIB_HEADER "#include <$Destination>\n";
 
2697
    }
 
2698
        close(LIB_HEADER);
 
2699
        system("g++ >>".esc($ERR_PATH{$Version})." 2>&1 -fdump-translation-unit temp/$Lib_VersionName.h $CompilerOptions{$Version} $Header_Depend");
 
2700
    if($?)
 
2701
    {
 
2702
        $HeaderCompileError{get_FileName($Destination)} = 1;
 
2703
    }
 
2704
    $ConstantsSrc{$Version} .= cmd_preprocessor("temp/$Lib_VersionName.h", $CompilerOptions{$Version}." ".$Header_Depend, "define\\ \\|undef\\ \\|#[ ]\\+[0-9]\\+ \".*\"");
 
2705
        return (split("\n", `find . -maxdepth 1 -name "$Lib_VersionName\.h*\.tu"`))[0];
 
2706
}
 
2707
 
 
2708
sub cmd_file($)
 
2709
{
 
2710
    my $Path = $_[0];
 
2711
    return "" if(not $Path or not -e $Path);
 
2712
    my $Cmd = "file ".esc($Path);
 
2713
    my $Cmd_Out = `$Cmd`;
 
2714
    return $Cmd_Out;
 
2715
}
 
2716
 
 
2717
sub cmd_preprocessor($$$)
 
2718
{
 
2719
    my ($Path, $AddOpt, $Grep) = @_;
 
2720
    return "" if(not $Path or not -f $Path);
 
2721
    my $Cmd = "g++ -dD -E -x c++-header ".esc($Path)." 2>/dev/null $AddOpt";
 
2722
    if($Grep)
 
2723
    {
 
2724
        $Cmd .= " | grep \"$Grep\"";
 
2725
    }
 
2726
    my $Cmd_Out = `$Cmd`;
 
2727
    return $Cmd_Out;
 
2728
}
 
2729
 
 
2730
sub cmd_cat($$)
 
2731
{
 
2732
    my ($Path, $Grep) = @_;
 
2733
    return "" if(not $Path or not -e $Path);
 
2734
    my $Cmd = "cat ".esc($Path);
 
2735
    if($Grep)
 
2736
    {
 
2737
        $Cmd .= " | grep \"$Grep\"";
 
2738
    }
 
2739
    my $Cmd_Out = `$Cmd`;
 
2740
    return $Cmd_Out;
 
2741
}
 
2742
 
 
2743
sub cmd_find($$$)
 
2744
{
 
2745
    my ($Path, $Type, $Name) = @_;
 
2746
    return () if(not $Path or not -e $Path);
 
2747
    my $Cmd = "find ".esc($Path);
 
2748
    if($Type)
 
2749
    {
 
2750
        $Cmd .= " -type $Type";
 
2751
    }
 
2752
    if($Name)
 
2753
    {
 
2754
        $Cmd .= " -name \"$Name\"";
 
2755
    }
 
2756
    return split("\n", `$Cmd`);
 
2757
}
 
2758
 
 
2759
sub cmd_tar($)
 
2760
{
 
2761
    my $Path = $_[0];
 
2762
    return "" if(not $Path or not -e $Path);
 
2763
    my $Cmd = "tar -xvzf ".esc($Path);
 
2764
    my $Cmd_Out = `$Cmd`;
 
2765
    return $Cmd_Out;
 
2766
}
 
2767
 
 
2768
sub is_header($$)
 
2769
{
 
2770
        my ($Destination, $LibVersion) = @_;
 
2771
    return 0 if(-d $Destination);
 
2772
    return 1 if($Destination =~ /\.(h|hh|hhh|hpp|tcc)\Z/i);
 
2773
    return 0 if($Destination =~ /\.\w+\Z/i);#cpp|c|gch|tu|fs|pas
 
2774
    if($Destination =~ /\A\//)
 
2775
    {
 
2776
        return (cmd_file($Destination) =~ /:[ ]*ASCII C[\+]* program text/);
 
2777
    }
 
2778
    else
 
2779
    {
 
2780
        foreach my $Prefix (keys(%{$Header_Dependency{$LibVersion}}))
 
2781
        {
 
2782
            my $Path = $Prefix."/".$Destination;
 
2783
            if(-f $Path)
 
2784
            {
 
2785
                if(cmd_file($Path) =~ /:[ ]*ASCII C[\+]* program text/)
 
2786
                {
 
2787
                    return 1;
 
2788
                }
 
2789
            }
 
2790
        }
 
2791
        return 0;
 
2792
    }
 
2793
}
 
2794
 
 
2795
sub parseHeaders_AllInOne($)
 
2796
{
 
2797
    $Version = $_[0];
 
2798
    print "checking header(s) ".$Descriptor{$Version}{"Version"}." ...\n";
 
2799
    system("mkdir", "-p", "header_compile_errors/".$TargetLibraryName);
 
2800
    system("rm", "-fr", $ERR_PATH{$Version});
 
2801
        my $DumpPath = getDump_AllInOne();
 
2802
        if(not $DumpPath)
 
2803
        {
 
2804
                print "\nERROR: can't create gcc syntax tree for header(s)\nyou can see compilation errors in the file '$ERR_PATH{$Version}'\n";
 
2805
                exit(1);
 
2806
        }
 
2807
        getInfo($DumpPath);
 
2808
    parse_constants();
 
2809
    system("rm", "-fr", "temp");
 
2810
}
 
2811
 
 
2812
sub parseHeader($)
 
2813
{
 
2814
        my $Destination = $_[0];
 
2815
        my $DumpPath = getDump_Separately($Destination);
 
2816
        if(not $DumpPath)
 
2817
        {
 
2818
                print "ERROR: can't create gcc syntax tree for header\nyou can see compilation errors in the file '$ERR_PATH{$Version}'\n";
 
2819
                exit(1);
 
2820
        }
 
2821
        getInfo($DumpPath);
 
2822
    parse_constants();
 
2823
    system("rm", "-fr", "temp");
 
2824
}
 
2825
 
 
2826
sub is_in_library($$)
 
2827
{
 
2828
    my ($MnglName, $LibVersion) = @_;
 
2829
    return ($Interface_Library{$LibVersion}{$MnglName} or ($SymVer{$LibVersion}{$MnglName} and $Interface_Library{$LibVersion}{$SymVer{$LibVersion}{$MnglName}}));
 
2830
}
 
2831
 
 
2832
sub prepareInterfaces($)
 
2833
{
 
2834
        my $LibVersion = $_[0];
 
2835
    my (@MnglNames, @UnMnglNames) = ();
 
2836
    if($CheckHeadersOnly)
 
2837
    {
 
2838
        foreach my $FuncInfoId (sort keys(%{$FuncDescr{$LibVersion}}))
 
2839
        {
 
2840
            if($FuncDescr{$LibVersion}{$FuncInfoId}{"MnglName"} =~ /\A_Z/)
 
2841
            {
 
2842
                push(@MnglNames, $FuncDescr{$LibVersion}{$FuncInfoId}{"MnglName"});
 
2843
            }
 
2844
        }
 
2845
        if($#MnglNames > -1)
 
2846
        {
 
2847
            @UnMnglNames = reverse(unmangleArray(@MnglNames));
 
2848
            foreach my $FuncInfoId (sort keys(%{$FuncDescr{$LibVersion}}))
 
2849
            {
 
2850
                if($FuncDescr{$LibVersion}{$FuncInfoId}{"MnglName"} =~ /\A_Z/)
 
2851
                {
 
2852
                    my $UnmangledName = pop(@UnMnglNames);
 
2853
                    $tr_name{$FuncDescr{$LibVersion}{$FuncInfoId}{"MnglName"}} = $UnmangledName;
 
2854
                }
 
2855
            }
 
2856
        }
 
2857
    }
 
2858
    my (%NotMangled_Int, %Mangled_Int) = ();
 
2859
    foreach my $FuncInfoId (keys(%{$FuncDescr{$LibVersion}}))
 
2860
    {
 
2861
        my $MnglName = $FuncDescr{$LibVersion}{$FuncInfoId}{"MnglName"};
 
2862
        if($MnglName=~/\A_Z/)
 
2863
        {
 
2864
            $Mangled_Int{$FuncInfoId} = $MnglName;
 
2865
        }
 
2866
        else
 
2867
        {
 
2868
            $NotMangled_Int{$FuncInfoId} = $MnglName;
 
2869
        }
 
2870
        next if(not $MnglName or not is_in_library($MnglName, $LibVersion) and not $CheckHeadersOnly);
 
2871
        next if($MnglName =~ /\A_Z/ and $tr_name{$MnglName} =~ /\.\_[0-9]/);
 
2872
        next if(not $FuncDescr{$LibVersion}{$FuncInfoId}{"Header"});
 
2873
        %{$CompleteSignature{$LibVersion}{$MnglName}} = %{$FuncDescr{$LibVersion}{$FuncInfoId}};
 
2874
        #interface and its symlink have same signatures
 
2875
        if($SymVer{$LibVersion}{$MnglName})
 
2876
        {
 
2877
            %{$CompleteSignature{$LibVersion}{$SymVer{$LibVersion}{$MnglName}}} = %{$FuncDescr{$LibVersion}{$FuncInfoId}};
 
2878
        }
 
2879
        delete($FuncDescr{$LibVersion}{$FuncInfoId});
 
2880
    }
 
2881
    if(keys(%Mangled_Int))
 
2882
    {
 
2883
        foreach my $Interface_Id (keys(%NotMangled_Int))
 
2884
        {
 
2885
            delete($CompleteSignature{$LibVersion}{$NotMangled_Int{$Interface_Id}});
 
2886
        }
 
2887
    }
 
2888
}
 
2889
 
 
2890
my %UsedType;
 
2891
sub cleanData($)
 
2892
{
 
2893
    my $LibVersion = $_[0];
 
2894
    foreach my $FuncInfoId (keys(%{$FuncDescr{$LibVersion}}))
 
2895
    {
 
2896
        my $MnglName = $FuncDescr{$LibVersion}{$FuncInfoId}{"MnglName"};
 
2897
        if(not $MnglName or not is_in_library($MnglName, $LibVersion) and not $CheckHeadersOnly)
 
2898
        {
 
2899
            delete($FuncDescr{$LibVersion}{$FuncInfoId});
 
2900
            next;
 
2901
        }
 
2902
        if(defined $InterfacesListPath and not $InterfacesList{$MnglName})
 
2903
        {
 
2904
            delete($FuncDescr{$LibVersion}{$FuncInfoId});
 
2905
            next;
 
2906
        }
 
2907
        if(defined $AppPath and not $InterfacesList_App{$MnglName})
 
2908
        {
 
2909
            delete($FuncDescr{$LibVersion}{$FuncInfoId});
 
2910
            next;
 
2911
        }
 
2912
        my %FuncInfo = %{$FuncDescr{$LibVersion}{$FuncInfoId}};
 
2913
        detect_TypeUsing($Tid_TDid{$LibVersion}{$FuncInfo{"Return"}}, $FuncInfo{"Return"}, $LibVersion);
 
2914
        detect_TypeUsing($Tid_TDid{$LibVersion}{$FuncInfo{"Class"}}, $FuncInfo{"Class"}, $LibVersion);
 
2915
        foreach my $Param_Pos (keys(%{$FuncInfo{"Param"}}))
 
2916
        {
 
2917
            my $Param_TypeId = $FuncInfo{"Param"}{$Param_Pos}{"type"};
 
2918
            detect_TypeUsing($Tid_TDid{$LibVersion}{$Param_TypeId}, $Param_TypeId, $LibVersion);
 
2919
        }
 
2920
    }
 
2921
    foreach my $TDid (keys(%{$TypeDescr{$LibVersion}}))
 
2922
    {
 
2923
        foreach my $Tid (keys(%{$TypeDescr{$LibVersion}{$TDid}}))
 
2924
        {
 
2925
            if(not $UsedType{$LibVersion}{$TDid}{$Tid})
 
2926
            {
 
2927
                delete($TypeDescr{$LibVersion}{$TDid}{$Tid});
 
2928
                if(not keys(%{$TypeDescr{$LibVersion}{$TDid}}))
 
2929
                {
 
2930
                    delete($TypeDescr{$LibVersion}{$TDid});
 
2931
                }
 
2932
                delete($Tid_TDid{$LibVersion}{$Tid}) if($Tid_TDid{$LibVersion}{$Tid} eq $TDid);
 
2933
            }
 
2934
        }
 
2935
    }
 
2936
}
 
2937
 
 
2938
sub detect_TypeUsing($$$)
 
2939
{
 
2940
    my ($TypeDeclId, $TypeId, $LibVersion) = @_;
 
2941
    return if($UsedType{$LibVersion}{$TypeDeclId}{$TypeId});
 
2942
    my %Type = get_Type($TypeDeclId, $TypeId, $LibVersion);
 
2943
    if($Type{"Type"} =~ /Struct|Union|Class|FuncPtr|Enum/)
 
2944
    {
 
2945
        $UsedType{$LibVersion}{$TypeDeclId}{$TypeId} = 1;
 
2946
        foreach my $Memb_Pos (keys(%{$Type{"Memb"}}))
 
2947
        {
 
2948
            my $Member_TypeId = $Type{"Memb"}{$Memb_Pos}{"type"};
 
2949
            detect_TypeUsing($Tid_TDid{$LibVersion}{$Member_TypeId}, $Member_TypeId, $LibVersion);
 
2950
        }
 
2951
        if($Type{"Type"} eq "FuncPtr")
 
2952
        {
 
2953
            my $ReturnType = $Type{"Return"};
 
2954
            detect_TypeUsing($Tid_TDid{$LibVersion}{$ReturnType}, $ReturnType, $LibVersion);
 
2955
        }
 
2956
    }
 
2957
    elsif($Type{"Type"} =~ /Const|Pointer|Ref|Volatile|Restrict|Array|/)
 
2958
    {
 
2959
        $UsedType{$LibVersion}{$TypeDeclId}{$TypeId} = 1;
 
2960
        detect_TypeUsing($Type{"BaseType"}{"TDid"}, $Type{"BaseType"}{"Tid"}, $LibVersion);
 
2961
    }
 
2962
    elsif($Type{"Type"} eq "Intrinsic")
 
2963
    {
 
2964
        $UsedType{$LibVersion}{$TypeDeclId}{$TypeId} = 1;
 
2965
    }
 
2966
    else
 
2967
    {
 
2968
        delete($TypeDescr{$LibVersion}{$TypeDeclId}{$TypeId});
 
2969
        if(not keys(%{$TypeDescr{$LibVersion}{$TypeDeclId}}))
 
2970
        {
 
2971
            delete($TypeDescr{$LibVersion}{$TypeDeclId});
 
2972
        }
 
2973
        delete($Tid_TDid{$LibVersion}{$TypeId}) if($Tid_TDid{$LibVersion}{$TypeId} eq $TypeDeclId);
 
2974
    }
 
2975
}
 
2976
 
 
2977
sub initializeClassVirtFunc($)
 
2978
{
 
2979
    my $LibVersion = $_[0];
 
2980
    foreach my $Interface (keys(%{$CompleteSignature{$LibVersion}}))
 
2981
    {
 
2982
        if($CompleteSignature{$LibVersion}{$Interface}{"Virt"})
 
2983
        {
 
2984
            my $ClassName = $TypeDescr{$LibVersion}{$Tid_TDid{$LibVersion}{$CompleteSignature{$LibVersion}{$Interface}{"Class"}}}{$CompleteSignature{$LibVersion}{$Interface}{"Class"}}{"Name"};
 
2985
            $ClassVirtFunc{$LibVersion}{$ClassName}{$Interface} = 1;
 
2986
            $ClassIdVirtFunc{$LibVersion}{$CompleteSignature{$LibVersion}{$Interface}{"Class"}}{$Interface} = 1;
 
2987
            $ClassId{$LibVersion}{$ClassName} = $CompleteSignature{$LibVersion}{$Interface}{"Class"};
 
2988
        }
 
2989
    }
 
2990
}
 
2991
 
 
2992
sub checkVirtFuncRedefinitions($)
 
2993
{
 
2994
    my $LibVersion = $_[0];
 
2995
    foreach my $Class_Name (keys(%{$ClassVirtFunc{$LibVersion}}))
 
2996
    {
 
2997
        $CheckedTypes{$Class_Name} = 1;
 
2998
        foreach my $VirtFuncName (keys(%{$ClassVirtFunc{$LibVersion}{$Class_Name}}))
 
2999
        {
 
3000
            $CompleteSignature{$LibVersion}{$VirtFuncName}{"VirtualRedefine"} = find_virtual_method_in_base_classes($VirtFuncName, $ClassId{$LibVersion}{$Class_Name}, $LibVersion);
 
3001
        }
 
3002
    }
 
3003
}
 
3004
 
 
3005
sub setVirtFuncPositions($)
 
3006
{
 
3007
    my $LibVersion = $_[0];
 
3008
    foreach my $Class_Name (keys(%{$ClassVirtFunc{$LibVersion}}))
 
3009
    {
 
3010
        $CheckedTypes{$Class_Name} = 1;
 
3011
        my $Position = 0;
 
3012
        foreach my $VirtFuncName (sort {int($CompleteSignature{$LibVersion}{$a}{"Line"}) <=> int($CompleteSignature{$LibVersion}{$b}{"Line"})} keys(%{$ClassVirtFunc{$LibVersion}{$Class_Name}}))
 
3013
        {
 
3014
            if($ClassVirtFunc{1}{$Class_Name}{$VirtFuncName} and $ClassVirtFunc{2}{$Class_Name}{$VirtFuncName} and not $CompleteSignature{1}{$VirtFuncName}{"VirtualRedefine"} and not $CompleteSignature{2}{$VirtFuncName}{"VirtualRedefine"})
 
3015
            {
 
3016
                $CompleteSignature{$LibVersion}{$VirtFuncName}{"Position"} = $Position;
 
3017
                $Position += 1;
 
3018
            }
 
3019
        }
 
3020
    }
 
3021
}
 
3022
 
 
3023
sub check_VirtualTable($$)
 
3024
{
 
3025
    my ($TargetFunction, $LibVersion) = @_;
 
3026
    my $Class_Id = $CompleteSignature{$LibVersion}{$TargetFunction}{"Class"};
 
3027
    my $Class_DId = $Tid_TDid{$LibVersion}{$Class_Id};
 
3028
    my %Class_Type = get_Type($Class_DId, $Class_Id, $LibVersion);
 
3029
    $CheckedTypes{$Class_Type{"Name"}} = 1;
 
3030
    foreach my $VirtFuncName (keys(%{$ClassVirtFunc{2}{$Class_Type{"Name"}}}))
 
3031
    {#Added
 
3032
        if($ClassId{1}{$Class_Type{"Name"}} and not $ClassVirtFunc{1}{$Class_Type{"Name"}}{$VirtFuncName} and $AddedInt{$VirtFuncName})
 
3033
        {
 
3034
            if($CompleteSignature{2}{$VirtFuncName}{"VirtualRedefine"})
 
3035
            {
 
3036
                if($TargetFunction eq $VirtFuncName)
 
3037
                {
 
3038
                    my $BaseClass_Id = $CompleteSignature{2}{$CompleteSignature{2}{$VirtFuncName}{"VirtualRedefine"}}{"Class"};
 
3039
                    my %BaseClass_Type = get_Type($Tid_TDid{2}{$BaseClass_Id}, $BaseClass_Id, 2);
 
3040
                    my $BaseClass_Name = $BaseClass_Type{"Name"};
 
3041
                    %{$CompatProblems{$TargetFunction}{"Virtual_Function_Redefinition"}{$tr_name{$CompleteSignature{2}{$VirtFuncName}{"VirtualRedefine"}}}}=(
 
3042
                        "Type_Name"=>$Class_Type{"Name"},
 
3043
                        "Type_Type"=>$Class_Type{"Type"},
 
3044
                        "Header"=>$CompleteSignature{2}{$TargetFunction}{"Header"},
 
3045
                        "Line"=>$CompleteSignature{2}{$TargetFunction}{"Line"},
 
3046
                        "Target"=>$tr_name{$CompleteSignature{2}{$VirtFuncName}{"VirtualRedefine"}},
 
3047
                        "Signature"=>$tr_name{$TargetFunction},
 
3048
                        "Old_Value"=>$tr_name{$CompleteSignature{2}{$VirtFuncName}{"VirtualRedefine"}},
 
3049
                        "New_Value"=>$tr_name{$TargetFunction},
 
3050
                        "Old_SoName"=>$Interface_Library{1}{$TargetFunction},
 
3051
                        "New_SoName"=>$Interface_Library{2}{$TargetFunction}  );
 
3052
                }
 
3053
            }
 
3054
            elsif($TargetFunction ne $VirtFuncName)
 
3055
            {
 
3056
                %{$CompatProblems{$TargetFunction}{"Added_Virtual_Function"}{$tr_name{$VirtFuncName}}}=(
 
3057
                "Type_Name"=>$Class_Type{"Name"},
 
3058
                "Type_Type"=>$Class_Type{"Type"},
 
3059
                "Header"=>$Class_Type{"Header"},
 
3060
                "Line"=>$Class_Type{"Line"},
 
3061
                "Target"=>$tr_name{$VirtFuncName},
 
3062
                "Signature"=>$tr_name{$TargetFunction},
 
3063
                "Old_SoName"=>$Interface_Library{1}{$TargetFunction},
 
3064
                "New_SoName"=>$Interface_Library{2}{$TargetFunction}  );
 
3065
            }
 
3066
        }
 
3067
    }
 
3068
    foreach my $VirtFuncName (keys(%{$ClassVirtFunc{1}{$Class_Type{"Name"}}}))
 
3069
    {#Withdrawn
 
3070
        if($ClassId{2}{$Class_Type{"Name"}} and not $ClassVirtFunc{2}{$Class_Type{"Name"}}{$VirtFuncName} and $WithdrawnInt{$VirtFuncName})
 
3071
        {
 
3072
            if($CompleteSignature{1}{$VirtFuncName}{"VirtualRedefine"})
 
3073
            {
 
3074
                if($TargetFunction eq $VirtFuncName)
 
3075
                {
 
3076
                    my $BaseClass_Id = $CompleteSignature{1}{$CompleteSignature{1}{$VirtFuncName}{"VirtualRedefine"}}{"Class"};
 
3077
                    my $BaseClass_Name = $TypeDescr{1}{$Tid_TDid{1}{$BaseClass_Id}}{$BaseClass_Id}{"Name"};
 
3078
                    %{$CompatProblems{$TargetFunction}{"Virtual_Function_Redefinition_B"}{$tr_name{$CompleteSignature{1}{$VirtFuncName}{"VirtualRedefine"}}}}=(
 
3079
                        "Type_Name"=>$Class_Type{"Name"},
 
3080
                        "Type_Type"=>$Class_Type{"Type"},
 
3081
                        "Header"=>$CompleteSignature{2}{$TargetFunction}{"Header"},
 
3082
                        "Line"=>$CompleteSignature{2}{$TargetFunction}{"Line"},
 
3083
                        "Target"=>$tr_name{$CompleteSignature{1}{$VirtFuncName}{"VirtualRedefine"}},
 
3084
                        "Signature"=>$tr_name{$TargetFunction},
 
3085
                        "Old_Value"=>$tr_name{$TargetFunction},
 
3086
                        "New_Value"=>$tr_name{$CompleteSignature{1}{$VirtFuncName}{"VirtualRedefine"}},
 
3087
                        "Old_SoName"=>$Interface_Library{1}{$TargetFunction},
 
3088
                        "New_SoName"=>$Interface_Library{2}{$TargetFunction}  );
 
3089
                }
 
3090
            }
 
3091
            else
 
3092
            {
 
3093
                %{$CompatProblems{$TargetFunction}{"Withdrawn_Virtual_Function"}{$tr_name{$VirtFuncName}}}=(
 
3094
                "Type_Name"=>$Class_Type{"Name"},
 
3095
                "Type_Type"=>$Class_Type{"Type"},
 
3096
                "Header"=>$Class_Type{"Header"},
 
3097
                "Line"=>$Class_Type{"Line"},
 
3098
                "Target"=>$tr_name{$VirtFuncName},
 
3099
                "Signature"=>$tr_name{$TargetFunction},
 
3100
                "Old_SoName"=>$Interface_Library{1}{$TargetFunction},
 
3101
                "New_SoName"=>$Interface_Library{2}{$TargetFunction}  );
 
3102
            }
 
3103
        }
 
3104
    }
 
3105
}
 
3106
 
 
3107
sub find_virtual_method_in_base_classes($$$)
 
3108
{
 
3109
    my ($VirtFuncName, $Checked_ClassId, $LibVersion) = @_;
 
3110
    foreach my $BaseClass_Id (keys(%{$TypeDescr{$LibVersion}{$Tid_TDid{$LibVersion}{$Checked_ClassId}}{$Checked_ClassId}{"BaseClass"}}))
 
3111
    {
 
3112
        my $VirtMethodInClass = find_virtual_method_in_class($VirtFuncName, $BaseClass_Id, $LibVersion);
 
3113
        if($VirtMethodInClass)
 
3114
        {
 
3115
            return $VirtMethodInClass;
 
3116
        }
 
3117
        my $VirtMethodInBaseClasses = find_virtual_method_in_base_classes($VirtFuncName, $BaseClass_Id, $LibVersion);
 
3118
        if($VirtMethodInBaseClasses)
 
3119
        {
 
3120
            return $VirtMethodInBaseClasses;
 
3121
        }
 
3122
    }
 
3123
    return "";
 
3124
}
 
3125
 
 
3126
sub find_virtual_method_in_class($$$)
 
3127
{
 
3128
    my ($VirtFuncName, $Checked_ClassId, $LibVersion) = @_;
 
3129
    my $Suffix = getFuncSuffix($VirtFuncName, $LibVersion);
 
3130
    foreach my $Checked_VirtFuncName (keys(%{$ClassIdVirtFunc{$LibVersion}{$Checked_ClassId}}))
 
3131
    {
 
3132
        if($Suffix eq getFuncSuffix($Checked_VirtFuncName, $LibVersion)
 
3133
            and ((not $CompleteSignature{$LibVersion}{$VirtFuncName}{"Constructor"} and not $CompleteSignature{$LibVersion}{$VirtFuncName}{"Destructor"} and $CompleteSignature{$LibVersion}{$VirtFuncName}{"ShortName"} eq $CompleteSignature{$LibVersion}{$Checked_VirtFuncName}{"ShortName"}) or ($CompleteSignature{$LibVersion}{$VirtFuncName}{"Constructor"} or $CompleteSignature{$LibVersion}{$VirtFuncName}{"Destructor"})))
 
3134
        {
 
3135
            return $Checked_VirtFuncName;
 
3136
        }
 
3137
    }
 
3138
    return "";
 
3139
}
 
3140
 
 
3141
sub getFuncSuffix($$)
 
3142
{
 
3143
    my ($FuncName, $LibVersion) = @_;
 
3144
    my $ClassId = $CompleteSignature{$LibVersion}{$FuncName}{"Class"};
 
3145
    my $ClassName = $TypeDescr{$LibVersion}{$Tid_TDid{$LibVersion}{$ClassId}}{$ClassId}{"Name"};
 
3146
    my $ShortName = $CompleteSignature{$LibVersion}{$FuncName}{"ShortName"};
 
3147
    my $Suffix = $tr_name{$FuncName};
 
3148
    $Suffix =~ s/\A$ClassName\:\:[~]*$ShortName[ ]*//g;
 
3149
    return $Suffix;
 
3150
}
 
3151
 
 
3152
sub isRecurType($$$$)
 
3153
{
 
3154
        foreach (@RecurTypes)
 
3155
        {
 
3156
                if($_->{"Tid1"} eq $_[0]
 
3157
            and $_->{"TDid1"} eq $_[1]
 
3158
            and $_->{"Tid2"} eq $_[2]
 
3159
            and $_->{"TDid2"} eq $_[3])
 
3160
                {
 
3161
                        return 1;
 
3162
                }
 
3163
        }
 
3164
        return 0;
 
3165
}
 
3166
 
 
3167
sub find_MemberPair_Pos_byName($$)
 
3168
{
 
3169
    my ($Member_Name, $Pair_Type) = @_;
 
3170
    foreach my $MemberPair_Pos (sort keys(%{$Pair_Type->{"Memb"}}))
 
3171
    {
 
3172
        if($Pair_Type->{"Memb"}{$MemberPair_Pos}{"name"} eq $Member_Name)
 
3173
        {
 
3174
            return $MemberPair_Pos;
 
3175
        }
 
3176
    }
 
3177
    return "lost";
 
3178
}
 
3179
 
 
3180
sub getBitfieldSum($$)
 
3181
{
 
3182
    my ($Member_Pos, $Pair_Type) = @_;
 
3183
    my $BitfieldSum = 0;
 
3184
    while($Member_Pos>-1)
 
3185
    {
 
3186
        return $BitfieldSum if(not $Pair_Type->{"Memb"}{$Member_Pos}{"bitfield"});
 
3187
        $BitfieldSum += $Pair_Type->{"Memb"}{$Member_Pos}{"bitfield"};
 
3188
        $Member_Pos -= 1;
 
3189
    }
 
3190
    return $BitfieldSum;
 
3191
}
 
3192
 
 
3193
sub find_MemberPair_Pos_byVal($$)
 
3194
{
 
3195
    my ($Member_Value, $Pair_Type) = @_;
 
3196
    foreach my $MemberPair_Pos (sort keys(%{$Pair_Type->{"Memb"}}))
 
3197
    {
 
3198
        if($Pair_Type->{"Memb"}{$MemberPair_Pos}{"value"} eq $Member_Value)
 
3199
        {
 
3200
            return $MemberPair_Pos;
 
3201
        }
 
3202
    }
 
3203
    return "lost";
 
3204
}
 
3205
 
 
3206
my %Priority_Value=(
 
3207
"High"=>3,
 
3208
"Medium"=>2,
 
3209
"Low"=>1
 
3210
);
 
3211
 
 
3212
sub max_priority($$)
 
3213
{
 
3214
    my ($Priority1, $Priority2) = @_;
 
3215
    if(cmp_priority($Priority1, $Priority2))
 
3216
    {
 
3217
        return $Priority1;
 
3218
    }
 
3219
    else
 
3220
    {
 
3221
        return $Priority2;
 
3222
    }
 
3223
}
 
3224
 
 
3225
sub cmp_priority($$)
 
3226
{
 
3227
    my ($Priority1, $Priority2) = @_;
 
3228
    return ($Priority_Value{$Priority1}>$Priority_Value{$Priority2});
 
3229
}
 
3230
 
 
3231
sub set_Problems_Priority()
 
3232
{
 
3233
    foreach my $InterfaceName (sort keys(%CompatProblems))
 
3234
    {
 
3235
        foreach my $Kind (sort keys(%{$CompatProblems{$InterfaceName}}))
 
3236
        {
 
3237
            foreach my $Location (sort keys(%{$CompatProblems{$InterfaceName}{$Kind}}))
 
3238
            {
 
3239
                my $IsInTypeInternals = $CompatProblems{$InterfaceName}{$Kind}{$Location}{"IsInTypeInternals"};
 
3240
                my $InitialType_Type = $CompatProblems{$InterfaceName}{$Kind}{$Location}{"InitialType_Type"};
 
3241
                if($Kind eq "Function_Become_Static")
 
3242
                {
 
3243
                    $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "High";
 
3244
                }
 
3245
                elsif($Kind eq "Function_Become_NonStatic")
 
3246
                {
 
3247
                    $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "High";
 
3248
                }
 
3249
                elsif($Kind eq "Parameter_Type_And_Size")
 
3250
                {
 
3251
                    $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "High";
 
3252
                }
 
3253
                elsif($Kind eq "Parameter_Type")
 
3254
                {
 
3255
                    $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
 
3256
                }
 
3257
                elsif($Kind eq "Withdrawn_Parameter")
 
3258
                {
 
3259
                    $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Medium";
 
3260
                }
 
3261
                elsif($Kind eq "Added_Parameter")
 
3262
                {
 
3263
                    $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Medium";
 
3264
                }
 
3265
                elsif($Kind eq "Parameter_BaseType_And_Size")
 
3266
                {
 
3267
                    if($InitialType_Type eq "Pointer")
 
3268
                    {
 
3269
                        $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
 
3270
                    }
 
3271
                    else
 
3272
                    {
 
3273
                        $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "High";
 
3274
                    }
 
3275
                }
 
3276
                elsif($Kind eq "Parameter_BaseType")
 
3277
                {
 
3278
                    $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
 
3279
                }
 
3280
                elsif($Kind eq "Parameter_PointerLevel")
 
3281
                {
 
3282
                    $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "High";
 
3283
                }
 
3284
                elsif($Kind eq "Return_Type_And_Size")
 
3285
                {
 
3286
                    $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Medium";
 
3287
                }
 
3288
                elsif($Kind eq "Return_Type")
 
3289
                {
 
3290
                    $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
 
3291
                }
 
3292
                elsif($Kind eq "Return_BaseType_And_Size")
 
3293
                {
 
3294
                    $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Medium";
 
3295
                }
 
3296
                elsif($Kind eq "Return_BaseType")
 
3297
                {
 
3298
                    $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
 
3299
                }
 
3300
                elsif($Kind eq "Return_PointerLevel")
 
3301
                {
 
3302
                    $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
 
3303
                }
 
3304
                if($Kind eq "Added_Virtual_Function")
 
3305
                {
 
3306
                    $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "High";
 
3307
                }
 
3308
                elsif($Kind eq "Withdrawn_Virtual_Function")
 
3309
                {
 
3310
                    $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "High";
 
3311
                }
 
3312
                elsif($Kind eq "Virtual_Function_Position")
 
3313
                {
 
3314
                    $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "High";
 
3315
                }
 
3316
                elsif($Kind eq "Virtual_Function_Redefinition")
 
3317
                {
 
3318
                    $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
 
3319
                }
 
3320
                elsif($Kind eq "Virtual_Function_Redefinition_B")
 
3321
                {
 
3322
                    $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
 
3323
                }
 
3324
                elsif($Kind eq "Size")
 
3325
                {
 
3326
                    if(($InitialType_Type eq "Pointer") or ($InitialType_Type eq "Array"))
 
3327
                    {
 
3328
                        $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
 
3329
                    }
 
3330
                    else
 
3331
                    {
 
3332
                        if($IsInTypeInternals)
 
3333
                        {
 
3334
                            $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Medium";
 
3335
                        }
 
3336
                        else
 
3337
                        {
 
3338
                            $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "High";
 
3339
                        }
 
3340
                    }
 
3341
                }
 
3342
                elsif($Kind eq "BaseType")
 
3343
                {
 
3344
                    $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
 
3345
                }
 
3346
                elsif($Kind eq "Added_Member_And_Size")
 
3347
                {
 
3348
                    $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
 
3349
                }
 
3350
                elsif($Kind eq "Added_Middle_Member_And_Size")
 
3351
                {
 
3352
                    $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Medium";
 
3353
                }
 
3354
                elsif($Kind eq "Withdrawn_Member_And_Size")
 
3355
                {
 
3356
                    $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Medium";
 
3357
                }
 
3358
                elsif($Kind eq "Withdrawn_Member")
 
3359
                {
 
3360
                    $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
 
3361
                }
 
3362
                elsif($Kind eq "Withdrawn_Middle_Member_And_Size")
 
3363
                {
 
3364
                    if($IsInTypeInternals)
 
3365
                    {
 
3366
                        $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Medium";
 
3367
                    }
 
3368
                    else
 
3369
                    {
 
3370
                        $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "High";
 
3371
                    }
 
3372
                }
 
3373
                elsif($Kind eq "Withdrawn_Middle_Member")
 
3374
                {
 
3375
                    $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Medium";
 
3376
                }
 
3377
                elsif($Kind eq "Member_Rename")
 
3378
                {
 
3379
                    $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
 
3380
                }
 
3381
                elsif($Kind eq "Enum_Member_Value")
 
3382
                {
 
3383
                    $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Medium";
 
3384
                }
 
3385
                elsif($Kind eq "Enum_Member_Name")
 
3386
                {
 
3387
                    $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
 
3388
                }
 
3389
                elsif($Kind eq "Member_Type_And_Size")
 
3390
                {
 
3391
                    if(($InitialType_Type eq "Pointer") or ($InitialType_Type eq "Array"))
 
3392
                    {
 
3393
                        $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
 
3394
                    }
 
3395
                    else
 
3396
                    {
 
3397
                        if($IsInTypeInternals)
 
3398
                        {
 
3399
                            $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
 
3400
                        }
 
3401
                        else
 
3402
                        {
 
3403
                            $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "High";
 
3404
                        }
 
3405
                    }
 
3406
                }
 
3407
                elsif($Kind eq "Member_Type")
 
3408
                {
 
3409
                    $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
 
3410
                }
 
3411
                elsif($Kind eq "Member_BaseType_And_Size")
 
3412
                {
 
3413
                    if(($InitialType_Type eq "Pointer") or ($InitialType_Type eq "Array"))
 
3414
                    {
 
3415
                        $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
 
3416
                    }
 
3417
                    else
 
3418
                    {
 
3419
                        if($IsInTypeInternals)
 
3420
                        {
 
3421
                            $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
 
3422
                        }
 
3423
                        else
 
3424
                        {
 
3425
                            $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "High";
 
3426
                        }
 
3427
                    }
 
3428
                }
 
3429
                elsif($Kind eq "Member_BaseType")
 
3430
                {
 
3431
                    $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
 
3432
                }
 
3433
                elsif($Kind eq "Member_PointerLevel")
 
3434
                {
 
3435
                    if(($InitialType_Type eq "Pointer") or ($InitialType_Type eq "Array"))
 
3436
                    {
 
3437
                        $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
 
3438
                    }
 
3439
                    else
 
3440
                    {
 
3441
                        if($IsInTypeInternals)
 
3442
                        {
 
3443
                            $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
 
3444
                        }
 
3445
                        else
 
3446
                        {
 
3447
                            $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Medium";
 
3448
                        }
 
3449
                    }
 
3450
                }
 
3451
            }
 
3452
        }
 
3453
    }
 
3454
}
 
3455
 
 
3456
sub pushType($$$$)
 
3457
{
 
3458
    my %TypeDescriptor=(
 
3459
        "Tid1"  => $_[0],
 
3460
        "TDid1" => $_[1],
 
3461
        "Tid2"  => $_[2],
 
3462
        "TDid2" => $_[3]  );
 
3463
    push(@RecurTypes, \%TypeDescriptor);
 
3464
}
 
3465
 
 
3466
sub mergeTypes($$$$)
 
3467
{
 
3468
    my ($Type1_Id, $Type1_DId, $Type2_Id, $Type2_DId) = @_;
 
3469
    my (%Sub_SubProblems, %SubProblems) = ();
 
3470
    if((not $Type1_Id and not $Type1_DId) or (not $Type2_Id and not $Type2_DId))
 
3471
    {#Not Empty Inputs Only
 
3472
        return ();
 
3473
    }
 
3474
    if($Cache{"mergeTypes"}{$Type1_Id}{$Type1_DId}{$Type2_Id}{$Type2_DId})
 
3475
    {#Already Merged
 
3476
        return %{$Cache{"mergeTypes"}{$Type1_Id}{$Type1_DId}{$Type2_Id}{$Type2_DId}};
 
3477
    }
 
3478
    my %Type1 = get_Type($Type1_DId, $Type1_Id, 1);
 
3479
    my %Type2 = get_Type($Type2_DId, $Type2_Id, 2);
 
3480
        my %Type1_Pure = get_PureType($Type1_DId, $Type1_Id, 1);
 
3481
    my %Type2_Pure = get_PureType($Type2_DId, $Type2_Id, 2);
 
3482
    return () if(not $Type1_Pure{"Size"} or not $Type2_Pure{"Size"});
 
3483
    if(isRecurType($Type1_Pure{"Tid"}, $Type1_Pure{"TDid"}, $Type2_Pure{"Tid"}, $Type2_Pure{"TDid"}))
 
3484
    {#Recursive Declarations
 
3485
        return ();
 
3486
    }
 
3487
    return if(not $Type1_Pure{"Name"} or not $Type2_Pure{"Name"});
 
3488
    return if($OpaqueTypes{1}{$Type1_Pure{"Name"}} or $OpaqueTypes{2}{$Type1_Pure{"Name"}} or $OpaqueTypes{1}{$Type1{"Name"}} or $OpaqueTypes{2}{$Type1{"Name"}});
 
3489
    
 
3490
    my %Typedef_1 = goToFirst($Type1{"TDid"}, $Type1{"Tid"}, 1, "Typedef");
 
3491
    my %Typedef_2 = goToFirst($Type2{"TDid"}, $Type2{"Tid"}, 2, "Typedef");
 
3492
    if($Typedef_1{"Type"} eq "Typedef" and $Typedef_2{"Type"} eq "Typedef" and $Typedef_1{"Name"} eq $Typedef_2{"Name"})
 
3493
    {
 
3494
        my %Base_1 = get_OneStep_BaseType($Typedef_1{"TDid"}, $Typedef_1{"Tid"}, 1);
 
3495
        my %Base_2 = get_OneStep_BaseType($Typedef_2{"TDid"}, $Typedef_2{"Tid"}, 2);
 
3496
        if($Base_1{"Name"}!~/anon\-/ and $Base_2{"Name"}!~/anon\-/
 
3497
            and ($Base_1{"Name"} ne $Base_2{"Name"}))
 
3498
        {
 
3499
            %{$SubProblems{"BaseType"}{$Typedef_1{"Name"}}}=(
 
3500
                "Type_Name"=>$Typedef_1{"Name"},
 
3501
                "Type_Type"=>"Typedef",
 
3502
                "Header"=>$Typedef_2{"Header"},
 
3503
                "Line"=>$Typedef_2{"Line"},
 
3504
                "Old_Value"=>$Base_1{"Name"},
 
3505
                "New_Value"=>$Base_2{"Name"}  );
 
3506
        }
 
3507
    }
 
3508
    
 
3509
    if(($Type1_Pure{"Name"} ne $Type2_Pure{"Name"}) and ($Type1_Pure{"Type"} ne "Pointer") and $Type1_Pure{"Name"}!~/anon\-/)
 
3510
    {#Different types
 
3511
        return ();
 
3512
    }
 
3513
    
 
3514
        pushType($Type1_Pure{"Tid"}, $Type1_Pure{"TDid"}, $Type2_Pure{"Tid"}, $Type2_Pure{"TDid"});
 
3515
        if(($Type1_Pure{"Name"} eq $Type2_Pure{"Name"}) and ($Type1_Pure{"Type"} =~ /Struct|Class|Union/))
 
3516
        {#Check Size
 
3517
                if($Type1_Pure{"Size"} ne $Type2_Pure{"Size"})
 
3518
                {
 
3519
            %{$SubProblems{"Size"}{$Type1_Pure{"Name"}}}=(
 
3520
                "Type_Name"=>$Type1_Pure{"Name"},
 
3521
                "Type_Type"=>$Type1_Pure{"Type"},
 
3522
                "Header"=>$Type2_Pure{"Header"},
 
3523
                "Line"=>$Type2_Pure{"Line"},
 
3524
                "Old_Value"=>$Type1_Pure{"Size"},
 
3525
                "New_Value"=>$Type2_Pure{"Size"}  );
 
3526
                }
 
3527
        }
 
3528
    if($Type1_Pure{"Name"} and $Type2_Pure{"Name"} and ($Type1_Pure{"Name"} ne $Type2_Pure{"Name"}) and ($Type1_Pure{"Name"} !~ /\Avoid[ ]*\*/) and ($Type2_Pure{"Name"} =~ /\Avoid[ ]*\*/))
 
3529
    {#Check "void *"
 
3530
        pop(@RecurTypes);
 
3531
        return ();
 
3532
    }
 
3533
        if($Type1_Pure{"BaseType"}{"Tid"} and $Type2_Pure{"BaseType"}{"Tid"})
 
3534
        {#Check Base Types
 
3535
                %Sub_SubProblems = &mergeTypes($Type1_Pure{"BaseType"}{"Tid"}, $Type1_Pure{"BaseType"}{"TDid"}, $Type2_Pure{"BaseType"}{"Tid"}, $Type2_Pure{"BaseType"}{"TDid"});
 
3536
        foreach my $Sub_SubProblemType (keys(%Sub_SubProblems))
 
3537
        {
 
3538
            foreach my $Sub_SubLocation (keys(%{$Sub_SubProblems{$Sub_SubProblemType}}))
 
3539
            {
 
3540
                %{$SubProblems{$Sub_SubProblemType}{$Sub_SubLocation}} = %{$Sub_SubProblems{$Sub_SubProblemType}{$Sub_SubLocation}};
 
3541
                $SubProblems{$Sub_SubProblemType}{$Sub_SubLocation}{"InitialType_Type"} = $Type1_Pure{"Type"};
 
3542
            }
 
3543
        }
 
3544
        }
 
3545
    foreach my $Member_Pos (sort keys(%{$Type1_Pure{"Memb"}}))
 
3546
    {#Check Members
 
3547
        next if($Type1_Pure{"Memb"}{$Member_Pos}{"access"} eq "private");
 
3548
        my $Member_Name = $Type1_Pure{"Memb"}{$Member_Pos}{"name"};
 
3549
        next if(not $Member_Name);
 
3550
        my $Member_Location = $Member_Name;
 
3551
        my $MemberPair_Pos = find_MemberPair_Pos_byName($Member_Name, \%Type2_Pure);
 
3552
        if(($MemberPair_Pos eq "lost") and (($Type2_Pure{"Type"} eq "Struct") or ($Type2_Pure{"Type"} eq "Class")))
 
3553
        {#Withdrawn_Member
 
3554
            if($Member_Pos > keys(%{$Type2_Pure{"Memb"}}) - 1)
 
3555
            {
 
3556
                if($Type1_Pure{"Size"} ne $Type2_Pure{"Size"})
 
3557
                {
 
3558
                    %{$SubProblems{"Withdrawn_Member_And_Size"}{$Member_Name}}=(
 
3559
                        "Target"=>$Member_Name,
 
3560
                        "Type_Name"=>$Type1_Pure{"Name"},
 
3561
                        "Type_Type"=>$Type1_Pure{"Type"},
 
3562
                        "Header"=>$Type2_Pure{"Header"},
 
3563
                        "Line"=>$Type2_Pure{"Line"},
 
3564
                        "Old_Size"=>$Type1_Pure{"Size"},
 
3565
                        "New_Size"=>$Type2_Pure{"Size"}  );
 
3566
                }
 
3567
                else
 
3568
                {
 
3569
                    %{$SubProblems{"Withdrawn_Member"}{$Member_Name}}=(
 
3570
                        "Target"=>$Member_Name,
 
3571
                        "Type_Name"=>$Type1_Pure{"Name"},
 
3572
                        "Type_Type"=>$Type1_Pure{"Type"},
 
3573
                        "Header"=>$Type2_Pure{"Header"},
 
3574
                        "Line"=>$Type2_Pure{"Line"}  );
 
3575
                }
 
3576
                next;
 
3577
            }
 
3578
            elsif($Member_Pos < keys(%{$Type1_Pure{"Memb"}}) - 1)
 
3579
            {
 
3580
                my $MemberType_Id = $Type1_Pure{"Memb"}{$Member_Pos}{"type"};
 
3581
                my %MemberType_Pure = get_PureType($Tid_TDid{1}{$MemberType_Id}, $MemberType_Id, 1);
 
3582
                my $MemberStraightPairType_Id = $Type2_Pure{"Memb"}{$Member_Pos}{"type"};
 
3583
                my %MemberStraightPairType_Pure = get_PureType($Tid_TDid{2}{$MemberStraightPairType_Id}, $MemberStraightPairType_Id, 2);
 
3584
                
 
3585
                if(($MemberType_Pure{"Size"} eq $MemberStraightPairType_Pure{"Size"}) and find_MemberPair_Pos_byName($Type2_Pure{"Memb"}{$Member_Pos}{"name"}, \%Type1_Pure) eq "lost")
 
3586
                {
 
3587
                    %{$SubProblems{"Member_Rename"}{$Member_Name}}=(
 
3588
                        "Target"=>$Member_Name,
 
3589
                        "Type_Name"=>$Type1_Pure{"Name"},
 
3590
                        "Type_Type"=>$Type1_Pure{"Type"},
 
3591
                        "Header"=>$Type2_Pure{"Header"},
 
3592
                        "Line"=>$Type2_Pure{"Line"},
 
3593
                        "Old_Value"=>$Type1_Pure{"Memb"}{$Member_Pos}{"name"},
 
3594
                        "New_Value"=>$Type2_Pure{"Memb"}{$Member_Pos}{"name"}  );
 
3595
                    $MemberPair_Pos = $Member_Pos;
 
3596
                }
 
3597
                else
 
3598
                {
 
3599
                    if($Type1_Pure{"Memb"}{$Member_Pos}{"bitfield"})
 
3600
                    {
 
3601
                        my $BitfieldSum = getBitfieldSum($Member_Pos-1, \%Type1_Pure)%($POINTER_SIZE*8);
 
3602
                        if($BitfieldSum and $BitfieldSum-$Type2_Pure{"Memb"}{$Member_Pos}{"bitfield"}>=0)
 
3603
                        {
 
3604
                            %{$SubProblems{"Withdrawn_Middle_Member"}{$Member_Name}}=(
 
3605
                            "Target"=>$Member_Name,
 
3606
                            "Type_Name"=>$Type1_Pure{"Name"},
 
3607
                            "Type_Type"=>$Type1_Pure{"Type"},
 
3608
                            "Header"=>$Type2_Pure{"Header"},
 
3609
                            "Line"=>$Type2_Pure{"Line"}  );
 
3610
                            next;
 
3611
                        }
 
3612
                    }
 
3613
                    %{$SubProblems{"Withdrawn_Middle_Member_And_Size"}{$Member_Name}}=(
 
3614
                        "Target"=>$Member_Name,
 
3615
                        "Type_Name"=>$Type1_Pure{"Name"},
 
3616
                        "Type_Type"=>$Type1_Pure{"Type"},
 
3617
                        "Header"=>$Type2_Pure{"Header"},
 
3618
                        "Line"=>$Type2_Pure{"Line"}  );
 
3619
                    next;
 
3620
                }
 
3621
            }
 
3622
        }
 
3623
        if($Type1_Pure{"Type"} eq "Enum")
 
3624
        {
 
3625
            my $Member_Value1 = $Type1_Pure{"Memb"}{$Member_Pos}{"value"};
 
3626
            next if(not $Member_Value1);
 
3627
            my $Member_Value2 = $Type2_Pure{"Memb"}{$MemberPair_Pos}{"value"};
 
3628
            if($MemberPair_Pos eq "lost")
 
3629
            {
 
3630
                $MemberPair_Pos = find_MemberPair_Pos_byVal($Member_Value1, \%Type2_Pure);
 
3631
                if($MemberPair_Pos ne "lost")
 
3632
                {
 
3633
                    %{$SubProblems{"Enum_Member_Name"}{$Type1_Pure{"Memb"}{$Member_Pos}{"value"}}}=(
 
3634
                        "Target"=>$Type1_Pure{"Memb"}{$Member_Pos}{"value"},
 
3635
                        "Type_Name"=>$Type1_Pure{"Name"},
 
3636
                        "Type_Type"=>"Enum",
 
3637
                        "Header"=>$Type2_Pure{"Header"},
 
3638
                        "Line"=>$Type2_Pure{"Line"},
 
3639
                        "Old_Value"=>$Type1_Pure{"Memb"}{$Member_Pos}{"name"},
 
3640
                        "New_Value"=>$Type2_Pure{"Memb"}{$MemberPair_Pos}{"name"}  );
 
3641
                }
 
3642
            }
 
3643
            else
 
3644
            {
 
3645
                if($Member_Value1 ne "" and $Member_Value2 ne "")
 
3646
                {
 
3647
                    if($Member_Value1 ne $Member_Value2)
 
3648
                    {
 
3649
                        %{$SubProblems{"Enum_Member_Value"}{$Member_Name}}=(
 
3650
                            "Target"=>$Member_Name,
 
3651
                            "Type_Name"=>$Type1_Pure{"Name"},
 
3652
                            "Type_Type"=>"Enum",
 
3653
                            "Header"=>$Type2_Pure{"Header"},
 
3654
                            "Line"=>$Type2_Pure{"Line"},
 
3655
                            "Old_Value"=>$Type1_Pure{"Memb"}{$Member_Pos}{"value"},
 
3656
                            "New_Value"=>$Type2_Pure{"Memb"}{$MemberPair_Pos}{"value"}  );
 
3657
                    }
 
3658
                }
 
3659
            }
 
3660
            next;
 
3661
        }
 
3662
        my $MemberType1_Id = $Type1_Pure{"Memb"}{$Member_Pos}{"type"};
 
3663
        my $MemberType2_Id = $Type2_Pure{"Memb"}{$MemberPair_Pos}{"type"};
 
3664
        %Sub_SubProblems = detectTypeChange($MemberType1_Id, $MemberType2_Id, "Member");
 
3665
        foreach my $Sub_SubProblemType (keys(%Sub_SubProblems))
 
3666
        {
 
3667
            %{$SubProblems{$Sub_SubProblemType}{$Member_Name}}=(
 
3668
                "Target"=>$Member_Name,
 
3669
                "Member_Position"=>$Member_Pos,
 
3670
                "Type_Name"=>$Type1_Pure{"Name"},
 
3671
                "Type_Type"=>$Type1_Pure{"Type"},
 
3672
                "Header"=>$Type2_Pure{"Header"},
 
3673
                "Line"=>$Type2_Pure{"Line"});
 
3674
            @{$SubProblems{$Sub_SubProblemType}{$Member_Name}}{keys(%{$Sub_SubProblems{$Sub_SubProblemType}})} = values %{$Sub_SubProblems{$Sub_SubProblemType}};
 
3675
        }
 
3676
        if($MemberType1_Id and $MemberType2_Id)
 
3677
        {#checking member type change (replace)
 
3678
            %Sub_SubProblems = &mergeTypes($MemberType1_Id, $Tid_TDid{1}{$MemberType1_Id}, $MemberType2_Id, $Tid_TDid{2}{$MemberType2_Id});
 
3679
            foreach my $Sub_SubProblemType (keys(%Sub_SubProblems))
 
3680
            {
 
3681
                foreach my $Sub_SubLocation (keys(%{$Sub_SubProblems{$Sub_SubProblemType}}))
 
3682
                {
 
3683
                    my $NewLocation = ($Sub_SubLocation)?$Member_Location."->".$Sub_SubLocation:$Member_Location;
 
3684
                    %{$SubProblems{$Sub_SubProblemType}{$NewLocation}}=(
 
3685
                        "IsInTypeInternals"=>"Yes");
 
3686
                    @{$SubProblems{$Sub_SubProblemType}{$NewLocation}}{keys(%{$Sub_SubProblems{$Sub_SubProblemType}{$Sub_SubLocation}})} = values %{$Sub_SubProblems{$Sub_SubProblemType}{$Sub_SubLocation}};
 
3687
                    if($Sub_SubLocation !~ /\-\>/)
 
3688
                    {
 
3689
                        $SubProblems{$Sub_SubProblemType}{$NewLocation}{"Member_Type_Name"} = get_TypeName($MemberType1_Id, 1);
 
3690
                        $SubProblems{$Sub_SubProblemType}{$NewLocation}{"Start_Type_Name"} = get_TypeName($MemberType1_Id, 1);
 
3691
                    }
 
3692
                }
 
3693
            }
 
3694
        }
 
3695
    }
 
3696
    if(($Type2_Pure{"Type"} eq "Struct") or ($Type2_Pure{"Type"} eq "Class"))
 
3697
    {
 
3698
        foreach my $Member_Pos (sort keys(%{$Type2_Pure{"Memb"}}))
 
3699
        {#checking added members
 
3700
            next if(not $Type2_Pure{"Memb"}{$Member_Pos}{"name"});
 
3701
            my $MemberPair_Pos = find_MemberPair_Pos_byName($Type2_Pure{"Memb"}{$Member_Pos}{"name"}, \%Type1_Pure);
 
3702
            if($MemberPair_Pos eq "lost")
 
3703
            {#Added_Member
 
3704
                if($Member_Pos > keys(%{$Type1_Pure{"Memb"}}) - 1)
 
3705
                {
 
3706
                    if($Type1_Pure{"Size"} ne $Type2_Pure{"Size"})
 
3707
                    {
 
3708
                        if($Type2_Pure{"Memb"}{$Member_Pos}{"bitfield"})
 
3709
                        {
 
3710
                            my $BitfieldSum = getBitfieldSum($Member_Pos-1, \%Type2_Pure)%($POINTER_SIZE*8);
 
3711
                            next if($BitfieldSum and $BitfieldSum<=$POINTER_SIZE*8-$Type2_Pure{"Memb"}{$Member_Pos}{"bitfield"});
 
3712
                        }
 
3713
                        %{$SubProblems{"Added_Member_And_Size"}{$Type2_Pure{"Memb"}{$Member_Pos}{"name"}}}=(
 
3714
                            "Target"=>$Type2_Pure{"Memb"}{$Member_Pos}{"name"},
 
3715
                            "Type_Name"=>$Type1_Pure{"Name"},
 
3716
                            "Type_Type"=>$Type1_Pure{"Type"},
 
3717
                            "Header"=>$Type2_Pure{"Header"},
 
3718
                            "Line"=>$Type2_Pure{"Line"}  );
 
3719
                    }
 
3720
                }
 
3721
                else
 
3722
                {
 
3723
                    my $MemberType_Id = $Type2_Pure{"Memb"}{$Member_Pos}{"type"};
 
3724
                    my $MemberType_DId = $Tid_TDid{2}{$MemberType_Id};
 
3725
                    my %MemberType_Pure = get_PureType($MemberType_DId, $MemberType_Id, 2);
 
3726
                    
 
3727
                    my $MemberStraightPairType_Id = $Type1_Pure{"Memb"}{$Member_Pos}{"type"};
 
3728
                    my %MemberStraightPairType_Pure = get_PureType($Tid_TDid{1}{$MemberStraightPairType_Id}, $MemberStraightPairType_Id, 1);
 
3729
                    
 
3730
                    if(($MemberType_Pure{"Size"} eq $MemberStraightPairType_Pure{"Size"}) and find_MemberPair_Pos_byName($Type1_Pure{"Memb"}{$Member_Pos}{"name"}, \%Type2_Pure) eq "lost")
 
3731
                    {
 
3732
                        next if($Type1_Pure{"Memb"}{$Member_Pos}{"access"} eq "private");
 
3733
                        %{$SubProblems{"Member_Rename"}{$Type2_Pure{"Memb"}{$Member_Pos}{"name"}}}=(
 
3734
                            "Target"=>$Type1_Pure{"Memb"}{$Member_Pos}{"name"},
 
3735
                            "Type_Name"=>$Type1_Pure{"Name"},
 
3736
                            "Type_Type"=>$Type1_Pure{"Type"},
 
3737
                            "Header"=>$Type2_Pure{"Header"},
 
3738
                            "Line"=>$Type2_Pure{"Line"},
 
3739
                            "Old_Value"=>$Type1_Pure{"Memb"}{$Member_Pos}{"name"},
 
3740
                            "New_Value"=>$Type2_Pure{"Memb"}{$Member_Pos}{"name"}  );
 
3741
                    }
 
3742
                    else
 
3743
                    {
 
3744
                        if($Type1_Pure{"Size"} ne $Type2_Pure{"Size"})
 
3745
                        {
 
3746
                            if($Type2_Pure{"Memb"}{$Member_Pos}{"bitfield"})
 
3747
                            {
 
3748
                                my $BitfieldSum = getBitfieldSum($Member_Pos-1, \%Type2_Pure)%($POINTER_SIZE*8);
 
3749
                                next if($BitfieldSum and $BitfieldSum<=$POINTER_SIZE*8-$Type2_Pure{"Memb"}{$Member_Pos}{"bitfield"});
 
3750
                            }
 
3751
                            %{$SubProblems{"Added_Middle_Member_And_Size"}{$Type2_Pure{"Memb"}{$Member_Pos}{"name"}}}=(
 
3752
                                "Target"=>$Type2_Pure{"Memb"}{$Member_Pos}{"name"},
 
3753
                                "Type_Name"=>$Type1_Pure{"Name"},
 
3754
                                "Type_Type"=>$Type1_Pure{"Type"},
 
3755
                                "Header"=>$Type2_Pure{"Header"},
 
3756
                                "Line"=>$Type2_Pure{"Line"}  );
 
3757
                        }
 
3758
                    }
 
3759
                }
 
3760
            }
 
3761
        }
 
3762
    }
 
3763
    %{$Cache{"mergeTypes"}{$Type1_Id}{$Type1_DId}{$Type2_Id}{$Type2_DId}} = %SubProblems;
 
3764
        pop(@RecurTypes);
 
3765
    return %SubProblems;
 
3766
}
 
3767
 
 
3768
sub get_TypeName($$)
 
3769
{
 
3770
    my ($TypeId, $LibVersion) = @_;
 
3771
    return $TypeDescr{$LibVersion}{$Tid_TDid{$LibVersion}{$TypeId}}{$TypeId}{"Name"};
 
3772
}
 
3773
 
 
3774
sub goToFirst($$$$)
 
3775
{
 
3776
    my ($TypeDId, $TypeId, $LibVersion, $Type_Type) = @_;
 
3777
    if(defined $Cache{"goToFirst"}{$TypeDId}{$TypeId}{$LibVersion}{$Type_Type})
 
3778
    {
 
3779
        return %{$Cache{"goToFirst"}{$TypeDId}{$TypeId}{$LibVersion}{$Type_Type}};
 
3780
    }
 
3781
    return () if(not $TypeDescr{$LibVersion}{$TypeDId}{$TypeId});
 
3782
    my %Type = %{$TypeDescr{$LibVersion}{$TypeDId}{$TypeId}};
 
3783
    return () if(not $Type{"Type"});
 
3784
    if($Type{"Type"} ne $Type_Type)
 
3785
    {
 
3786
        return () if(not $Type{"BaseType"}{"TDid"} and not $Type{"BaseType"}{"Tid"});
 
3787
        %Type = goToFirst($Type{"BaseType"}{"TDid"}, $Type{"BaseType"}{"Tid"}, $LibVersion, $Type_Type);
 
3788
    }
 
3789
    $Cache{"goToFirst"}{$TypeDId}{$TypeId}{$LibVersion}{$Type_Type} = \%Type;
 
3790
    return %Type;
 
3791
}
 
3792
 
 
3793
my %TypeSpecAttributes = (
 
3794
    "Ref" => 1,
 
3795
    "Const" => 1,
 
3796
    "Volatile" => 1,
 
3797
    "Restrict" => 1,
 
3798
    "Typedef" => 1
 
3799
);
 
3800
 
 
3801
sub get_PureType($$$)
 
3802
{
 
3803
    my ($TypeDId, $TypeId, $LibVersion) = @_;
 
3804
    return "" if(not $TypeId);
 
3805
    if(defined $Cache{"get_PureType"}{$TypeDId}{$TypeId}{$LibVersion})
 
3806
    {
 
3807
        return %{$Cache{"get_PureType"}{$TypeDId}{$TypeId}{$LibVersion}};
 
3808
    }
 
3809
    return "" if(not $TypeDescr{$LibVersion}{$TypeDId}{$TypeId});
 
3810
    my %Type = %{$TypeDescr{$LibVersion}{$TypeDId}{$TypeId}};
 
3811
    if($Type{"Type"} =~ /Struct|Union|Typedef|Class|Enum/)
 
3812
    {
 
3813
        $CheckedTypes{$Type{"Name"}} = 1;
 
3814
    }
 
3815
    return %Type if(not $Type{"BaseType"}{"TDid"} and not $Type{"BaseType"}{"Tid"});
 
3816
    if($TypeSpecAttributes{$Type{"Type"}})
 
3817
    {
 
3818
        %Type = get_PureType($Type{"BaseType"}{"TDid"}, $Type{"BaseType"}{"Tid"}, $LibVersion);
 
3819
    }
 
3820
    $Cache{"get_PureType"}{$TypeDId}{$TypeId}{$LibVersion} = \%Type;
 
3821
    return %Type;
 
3822
}
 
3823
 
 
3824
sub get_PointerLevel($$$)
 
3825
{
 
3826
    my ($TypeDId, $TypeId, $LibVersion) = @_;
 
3827
    return "" if(not $TypeId);
 
3828
    if(defined $Cache{"get_PointerLevel"}{$TypeDId}{$TypeId}{$LibVersion})
 
3829
    {
 
3830
        return $Cache{"get_PointerLevel"}{$TypeDId}{$TypeId}{$LibVersion};
 
3831
    }
 
3832
    return "" if(not $TypeDescr{$LibVersion}{$TypeDId}{$TypeId});
 
3833
    my %Type = %{$TypeDescr{$LibVersion}{$TypeDId}{$TypeId}};
 
3834
    return 0 if(not $Type{"BaseType"}{"TDid"} and not $Type{"BaseType"}{"Tid"});
 
3835
    my $PointerLevel = 0;
 
3836
    if($Type{"Type"} eq "Pointer")
 
3837
    {
 
3838
        $PointerLevel += 1;
 
3839
    }
 
3840
    $PointerLevel += get_PointerLevel($Type{"BaseType"}{"TDid"}, $Type{"BaseType"}{"Tid"}, $LibVersion);
 
3841
    $Cache{"get_PointerLevel"}{$TypeDId}{$TypeId}{$LibVersion} = $PointerLevel;
 
3842
    return $PointerLevel;
 
3843
}
 
3844
 
 
3845
sub get_BaseType($$$)
 
3846
{
 
3847
    my ($TypeDId, $TypeId, $LibVersion) = @_;
 
3848
    return "" if(not $TypeId);
 
3849
    if(defined $Cache{"get_BaseType"}{$TypeDId}{$TypeId}{$LibVersion})
 
3850
    {
 
3851
        return %{$Cache{"get_BaseType"}{$TypeDId}{$TypeId}{$LibVersion}};
 
3852
    }
 
3853
    return "" if(not $TypeDescr{$LibVersion}{$TypeDId}{$TypeId});
 
3854
    my %Type = %{$TypeDescr{$LibVersion}{$TypeDId}{$TypeId}};
 
3855
    if($Type{"Type"} =~ /Struct|Union|Typedef|Class|Enum/)
 
3856
    {
 
3857
        $CheckedTypes{$Type{"Name"}} = 1;
 
3858
    }
 
3859
    return %Type if(not $Type{"BaseType"}{"TDid"} and not $Type{"BaseType"}{"Tid"});
 
3860
    %Type = get_BaseType($Type{"BaseType"}{"TDid"}, $Type{"BaseType"}{"Tid"}, $LibVersion);
 
3861
    $Cache{"get_BaseType"}{$TypeDId}{$TypeId}{$LibVersion} = \%Type;
 
3862
    return %Type;
 
3863
}
 
3864
 
 
3865
sub get_OneStep_BaseType($$$)
 
3866
{
 
3867
    my ($TypeDId, $TypeId, $LibVersion) = @_;
 
3868
    return "" if(not $TypeId);
 
3869
    return "" if(not $TypeDescr{$LibVersion}{$TypeDId}{$TypeId});
 
3870
    my %Type = %{$TypeDescr{$LibVersion}{$TypeDId}{$TypeId}};
 
3871
    return %Type if(not $Type{"BaseType"}{"TDid"} and not $Type{"BaseType"}{"Tid"});
 
3872
    return get_Type($Type{"BaseType"}{"TDid"}, $Type{"BaseType"}{"Tid"}, $LibVersion);
 
3873
}
 
3874
 
 
3875
sub get_Type($$$)
 
3876
{
 
3877
    my ($TypeDId, $TypeId, $LibVersion) = @_;
 
3878
    return "" if(not $TypeId);
 
3879
    return "" if(not $TypeDescr{$LibVersion}{$TypeDId}{$TypeId});
 
3880
    return %{$TypeDescr{$LibVersion}{$TypeDId}{$TypeId}};
 
3881
}
 
3882
 
 
3883
sub mergeLibs()
 
3884
{
 
3885
    foreach my $Interface (sort keys(%AddedInt))
 
3886
    {#checking added interfaces
 
3887
        next if($InternalInterfaces{1}{$Interface} or $InternalInterfaces{2}{$Interface});
 
3888
        next if(defined $InterfacesListPath and not $InterfacesList{$Interface});
 
3889
        next if(defined $AppPath and not $InterfacesList_App{$Interface});
 
3890
        next if($FuncAttr{2}{$Interface}{"Private"});
 
3891
        next if(not $FuncAttr{2}{$Interface}{"Header"});
 
3892
        %{$CompatProblems{$Interface}{"Added_Interface"}{"SharedLibrary"}}=(
 
3893
            "Header"=>$FuncAttr{2}{$Interface}{"Header"},
 
3894
            "Line"=>$FuncAttr{2}{$Interface}{"Line"},
 
3895
            "Signature"=>$FuncAttr{2}{$Interface}{"Signature"},
 
3896
            "New_SoName"=>$Interface_Library{2}{$Interface}  );
 
3897
    }
 
3898
    foreach my $Interface (sort keys(%WithdrawnInt))
 
3899
    {#checking withdrawn interfaces
 
3900
        next if($InternalInterfaces{1}{$Interface} or $InternalInterfaces{2}{$Interface});
 
3901
        next if(defined $InterfacesListPath and not $InterfacesList{$Interface});
 
3902
        next if(defined $AppPath and not $InterfacesList_App{$Interface});
 
3903
        next if($FuncAttr{1}{$Interface}{"Private"});
 
3904
        next if(not $FuncAttr{1}{$Interface}{"Header"});
 
3905
        %{$CompatProblems{$Interface}{"Withdrawn_Interface"}{"SharedLibrary"}}=(
 
3906
            "Header"=>$FuncAttr{1}{$Interface}{"Header"},
 
3907
            "Line"=>$FuncAttr{1}{$Interface}{"Line"},
 
3908
            "Signature"=>$FuncAttr{1}{$Interface}{"Signature"},
 
3909
            "Old_SoName"=>$Interface_Library{1}{$Interface}  );
 
3910
    }
 
3911
}
 
3912
 
 
3913
sub mergeSignatures()
 
3914
{
 
3915
    my %SubProblems = ();
 
3916
    
 
3917
        prepareInterfaces(1);
 
3918
        prepareInterfaces(2);
 
3919
    %FuncDescr=();
 
3920
    
 
3921
    initializeClassVirtFunc(1);
 
3922
    initializeClassVirtFunc(2);
 
3923
    
 
3924
    checkVirtFuncRedefinitions(1);
 
3925
    checkVirtFuncRedefinitions(2);
 
3926
    
 
3927
    setVirtFuncPositions(1);
 
3928
    setVirtFuncPositions(2);
 
3929
    
 
3930
    foreach my $Interface (sort keys(%AddedInt))
 
3931
    {#collecting the attributes of added interfaces
 
3932
        next if($CheckedInterfaces{$Interface});
 
3933
        if($CompleteSignature{2}{$Interface})
 
3934
        {
 
3935
            if($CompleteSignature{2}{$Interface}{"Private"})
 
3936
            {
 
3937
                $FuncAttr{2}{$Interface}{"Private"} = 1;
 
3938
            }
 
3939
            if($CompleteSignature{2}{$Interface}{"Protected"})
 
3940
            {
 
3941
                $FuncAttr{2}{$Interface}{"Protected"} = 1;
 
3942
            }
 
3943
            if($CompleteSignature{2}{$Interface}{"Header"})
 
3944
            {
 
3945
                $FuncAttr{2}{$Interface}{"Header"} = $CompleteSignature{2}{$Interface}{"Header"};
 
3946
            }
 
3947
            if($CompleteSignature{2}{$Interface}{"Line"})
 
3948
            {
 
3949
                $FuncAttr{2}{$Interface}{"Line"} = $CompleteSignature{2}{$Interface}{"Line"};
 
3950
            }
 
3951
            $FuncAttr{2}{$Interface}{"Signature"} = get_Signature($Interface, 2);
 
3952
            foreach my $ParamPos (keys(%{$CompleteSignature{2}{$Interface}{"Param"}}))
 
3953
            {
 
3954
                my $ParamType_Id = $CompleteSignature{2}{$Interface}{"Param"}{$ParamPos}{"type"};
 
3955
                my $ParamType_DId = $Tid_TDid{2}{$ParamType_Id};
 
3956
                my %ParamType = get_Type($ParamType_DId, $ParamType_Id, 2);
 
3957
            }
 
3958
            #checking virtual table
 
3959
            check_VirtualTable($Interface, 2);
 
3960
            $CheckedInterfaces{$Interface} = 1;
 
3961
        }
 
3962
    }
 
3963
    foreach my $Interface (sort keys(%WithdrawnInt))
 
3964
    {#collecting the attributes of withdrawn interfaces
 
3965
        next if($CheckedInterfaces{$Interface});
 
3966
        if($CompleteSignature{1}{$Interface})
 
3967
        {
 
3968
            if($CompleteSignature{1}{$Interface}{"Private"})
 
3969
            {
 
3970
                $FuncAttr{1}{$Interface}{"Private"} = 1;
 
3971
            }
 
3972
            if($CompleteSignature{1}{$Interface}{"Protected"})
 
3973
            {
 
3974
                $FuncAttr{1}{$Interface}{"Protected"} = 1;
 
3975
            }
 
3976
            if($CompleteSignature{1}{$Interface}{"Header"})
 
3977
            {
 
3978
                $FuncAttr{1}{$Interface}{"Header"} = $CompleteSignature{1}{$Interface}{"Header"};
 
3979
            }
 
3980
            if($CompleteSignature{1}{$Interface}{"Line"})
 
3981
            {
 
3982
                $FuncAttr{1}{$Interface}{"Line"} = $CompleteSignature{1}{$Interface}{"Line"};
 
3983
            }
 
3984
            $FuncAttr{1}{$Interface}{"Signature"} = get_Signature($Interface, 1);
 
3985
            foreach my $ParamPos (keys(%{$CompleteSignature{1}{$Interface}{"Param"}}))
 
3986
            {
 
3987
                my $ParamType_Id = $CompleteSignature{1}{$Interface}{"Param"}{$ParamPos}{"type"};
 
3988
                my $ParamType_DId = $Tid_TDid{1}{$ParamType_Id};
 
3989
                my %ParamType = get_Type($ParamType_DId, $ParamType_Id, 1);
 
3990
            }
 
3991
            #checking virtual table
 
3992
            check_VirtualTable($Interface, 1);
 
3993
            $CheckedInterfaces{$Interface} = 1;
 
3994
        }
 
3995
    }
 
3996
    
 
3997
        foreach my $Interface (sort keys(%{$CompleteSignature{1}}))
 
3998
        {#checking interfaces
 
3999
        if(($Interface !~ /\@/) and ($SymVer{1}{$Interface} =~ /\A(.*)[\@]+/))
 
4000
        {
 
4001
            next if($1 eq $Interface);
 
4002
        }
 
4003
        my ($MnglName, $SymbolVersion) = ($Interface, "");
 
4004
        if($Interface =~ /\A([^@]+)[\@]+([^@]+)\Z/)
 
4005
        {
 
4006
            ($MnglName, $SymbolVersion) = ($1, $2);
 
4007
        }
 
4008
        next if($InternalInterfaces{1}{$Interface} or $InternalInterfaces{2}{$Interface});
 
4009
        next if(defined $InterfacesListPath and not $InterfacesList{$Interface});
 
4010
        next if(defined $AppPath and not $InterfacesList_App{$Interface});
 
4011
        next if($CheckedInterfaces{$Interface});
 
4012
        next if($CompleteSignature{1}{$Interface}{"Private"});
 
4013
        next if(not $CompleteSignature{1}{$Interface}{"Header"} or not $CompleteSignature{2}{$Interface}{"Header"});
 
4014
                next if(not $CompleteSignature{1}{$Interface}{"MnglName"} or not $CompleteSignature{2}{$Interface}{"MnglName"});
 
4015
        next if((not $CompleteSignature{1}{$Interface}{"PureVirt"} and $CompleteSignature{2}{$Interface}{"PureVirt"}) or ($CompleteSignature{1}{$Interface}{"PureVirt"} and not $CompleteSignature{2}{$Interface}{"PureVirt"}));
 
4016
        $CheckedInterfaces{$Interface} = 1;
 
4017
        #checking virtual table
 
4018
        check_VirtualTable($Interface, 1);
 
4019
        #checking attributes
 
4020
                if($CompleteSignature{2}{$Interface}{"Static"} and not $CompleteSignature{1}{$Interface}{"Static"})
 
4021
                {
 
4022
            %{$CompatProblems{$Interface}{"Function_Become_Static"}{"Attributes"}}=(
 
4023
                "Header"=>$CompleteSignature{1}{$Interface}{"Header"},
 
4024
                "Line"=>$CompleteSignature{1}{$Interface}{"Line"},
 
4025
                "Signature"=>get_Signature($Interface, 1),
 
4026
                "Old_SoName"=>$Interface_Library{1}{$Interface},
 
4027
                "New_SoName"=>$Interface_Library{2}{$Interface}  );
 
4028
                }
 
4029
                elsif(not $CompleteSignature{2}{$Interface}{"Static"} and $CompleteSignature{1}{$Interface}{"Static"})
 
4030
                {
 
4031
            %{$CompatProblems{$Interface}{"Function_Become_NonStatic"}{"Attributes"}}=(
 
4032
                "Header"=>$CompleteSignature{1}{$Interface}{"Header"},
 
4033
                "Line"=>$CompleteSignature{1}{$Interface}{"Line"},
 
4034
                "Signature"=>get_Signature($Interface, 1),
 
4035
                "Old_SoName"=>$Interface_Library{1}{$Interface},
 
4036
                "New_SoName"=>$Interface_Library{2}{$Interface}  );
 
4037
                }
 
4038
        if($CompleteSignature{1}{$Interface}{"Virt"} and $CompleteSignature{2}{$Interface}{"Virt"})
 
4039
        {
 
4040
            if($CompleteSignature{1}{$Interface}{"Position"}!=$CompleteSignature{2}{$Interface}{"Position"})
 
4041
            {
 
4042
                my $Class_Id = $CompleteSignature{1}{$Interface}{"Class"};
 
4043
                my $Class_DId = $Tid_TDid{1}{$Class_Id};
 
4044
                my %Class_Type = get_Type($Class_DId, $Class_Id, 1);
 
4045
                %{$CompatProblems{$Interface}{"Virtual_Function_Position"}{$tr_name{$MnglName}}}=(
 
4046
                "Type_Name"=>$Class_Type{"Name"},
 
4047
                "Type_Type"=>$Class_Type{"Type"},
 
4048
                "Header"=>$Class_Type{"Header"},
 
4049
                "Line"=>$Class_Type{"Line"},
 
4050
                "Old_Value"=>$CompleteSignature{1}{$Interface}{"Position"},
 
4051
                "New_Value"=>$CompleteSignature{2}{$Interface}{"Position"},
 
4052
                "Signature"=>get_Signature($Interface, 1),
 
4053
                "Target"=>$tr_name{$MnglName},
 
4054
                "Old_SoName"=>$Interface_Library{1}{$Interface},
 
4055
                "New_SoName"=>$Interface_Library{2}{$Interface}  );
 
4056
            }
 
4057
        }
 
4058
        foreach my $ParamPos (sort {int($a) <=> int($b)} keys(%{$CompleteSignature{2}{$Interface}{"Param"}}))
 
4059
        {#checking added parameters
 
4060
            last if($Interface=~/\A_Z/);
 
4061
            if(not defined $CompleteSignature{1}{$Interface}{"Param"}{$ParamPos})
 
4062
            {#checking withdrawn parameters
 
4063
                my $ParamType2_Id = $CompleteSignature{2}{$Interface}{"Param"}{$ParamPos}{"type"};
 
4064
                my $Parameter_Name = $CompleteSignature{2}{$Interface}{"Param"}{$ParamPos}{"name"};
 
4065
                last if(get_TypeName($ParamType2_Id, 2) eq "...");
 
4066
                %{$CompatProblems{$Interface}{"Added_Parameter"}{num_to_str($ParamPos+1)." Parameter"}}=(
 
4067
                    "Target"=>$Parameter_Name,
 
4068
                    "Parameter_Position"=>$ParamPos,
 
4069
                    "Signature"=>get_Signature($Interface, 1),
 
4070
                    "Header"=>$CompleteSignature{1}{$Interface}{"Header"},
 
4071
                    "Line"=>$CompleteSignature{1}{$Interface}{"Line"},
 
4072
                    "Old_SoName"=>$Interface_Library{1}{$Interface},
 
4073
                    "New_SoName"=>$Interface_Library{2}{$Interface});
 
4074
            }
 
4075
        }
 
4076
                foreach my $ParamPos (sort {int($a) <=> int($b)} keys(%{$CompleteSignature{1}{$Interface}{"Param"}}))
 
4077
                {#checking parameters
 
4078
            my $ParamType1_Id = $CompleteSignature{1}{$Interface}{"Param"}{$ParamPos}{"type"};
 
4079
            my $Parameter_Name = $CompleteSignature{1}{$Interface}{"Param"}{$ParamPos}{"name"};
 
4080
            if(not defined $CompleteSignature{2}{$Interface}{"Param"}{$ParamPos} and get_TypeName($ParamType1_Id, 1) ne "..." and $Interface!~/\A_Z/)
 
4081
            {#checking withdrawn parameters
 
4082
                %{$CompatProblems{$Interface}{"Withdrawn_Parameter"}{num_to_str($ParamPos+1)." Parameter"}}=(
 
4083
                    "Target"=>$Parameter_Name,
 
4084
                    "Parameter_Position"=>$ParamPos,
 
4085
                    "Signature"=>get_Signature($Interface, 1),
 
4086
                    "Header"=>$CompleteSignature{1}{$Interface}{"Header"},
 
4087
                    "Line"=>$CompleteSignature{1}{$Interface}{"Line"},
 
4088
                    "Old_SoName"=>$Interface_Library{1}{$Interface},
 
4089
                    "New_SoName"=>$Interface_Library{2}{$Interface});
 
4090
                next;
 
4091
            }
 
4092
                        my $ParamType2_Id = $CompleteSignature{2}{$Interface}{"Param"}{$ParamPos}{"type"};
 
4093
            next if(not $ParamType1_Id or not $ParamType2_Id);
 
4094
            my $Parameter_Location = ($Parameter_Name)?$Parameter_Name:num_to_str($ParamPos+1)." Parameter";
 
4095
            
 
4096
            #checking type change(replace)
 
4097
            %SubProblems = detectTypeChange($ParamType1_Id, $ParamType2_Id, "Parameter");
 
4098
            foreach my $SubProblemType (keys(%SubProblems))
 
4099
            {
 
4100
                %{$CompatProblems{$Interface}{$SubProblemType}{$Parameter_Location}}=(
 
4101
                    "Target"=>$Parameter_Name,
 
4102
                    "Parameter_Position"=>$ParamPos,
 
4103
                    "Signature"=>get_Signature($Interface, 1),
 
4104
                    "Header"=>$CompleteSignature{1}{$Interface}{"Header"},
 
4105
                    "Line"=>$CompleteSignature{1}{$Interface}{"Line"},
 
4106
                    "Old_SoName"=>$Interface_Library{1}{$Interface},
 
4107
                    "New_SoName"=>$Interface_Library{2}{$Interface});
 
4108
                @{$CompatProblems{$Interface}{$SubProblemType}{$Parameter_Location}}{keys(%{$SubProblems{$SubProblemType}})} = values %{$SubProblems{$SubProblemType}};
 
4109
            }
 
4110
            @RecurTypes = ();
 
4111
            #checking type definition changes
 
4112
            %SubProblems = mergeTypes($ParamType1_Id, $Tid_TDid{1}{$ParamType1_Id}, $ParamType2_Id, $Tid_TDid{2}{$ParamType2_Id});
 
4113
            foreach my $SubProblemType (keys(%SubProblems))
 
4114
            {
 
4115
                foreach my $SubLocation (keys(%{$SubProblems{$SubProblemType}}))
 
4116
                {
 
4117
                    my $NewLocation = ($SubLocation)?$Parameter_Location."->".$SubLocation:$Parameter_Location;
 
4118
                    %{$CompatProblems{$Interface}{$SubProblemType}{$NewLocation}}=(
 
4119
                        "Signature"=>get_Signature($Interface, 1),
 
4120
                        "Header"=>$CompleteSignature{1}{$Interface}{"Header"},
 
4121
                        "Line"=>$CompleteSignature{1}{$Interface}{"Line"},
 
4122
                        "Old_SoName"=>$Interface_Library{1}{$Interface},
 
4123
                        "New_SoName"=>$Interface_Library{2}{$Interface},
 
4124
                        "Parameter_Type_Name"=>get_TypeName($ParamType1_Id, 1),
 
4125
                        "Parameter_Position"=>$ParamPos,
 
4126
                        "Parameter_Name"=>$Parameter_Name);
 
4127
                    @{$CompatProblems{$Interface}{$SubProblemType}{$NewLocation}}{keys(%{$SubProblems{$SubProblemType}{$SubLocation}})} = values %{$SubProblems{$SubProblemType}{$SubLocation}};
 
4128
                    if($SubLocation !~ /\-\>/)
 
4129
                    {
 
4130
                        $CompatProblems{$Interface}{$SubProblemType}{$NewLocation}{"Start_Type_Name"} = get_TypeName($ParamType1_Id, 1);
 
4131
                    }
 
4132
                }
 
4133
            }
 
4134
                }
 
4135
                #checking return type
 
4136
                my $ReturnType1_Id = $CompleteSignature{1}{$Interface}{"Return"};
 
4137
                my $ReturnType2_Id = $CompleteSignature{2}{$Interface}{"Return"};
 
4138
        %SubProblems = detectTypeChange($ReturnType1_Id, $ReturnType2_Id, "Return");
 
4139
        foreach my $SubProblemType (keys(%SubProblems))
 
4140
        {
 
4141
            %{$CompatProblems{$Interface}{$SubProblemType}{"RetVal"}}=(
 
4142
                "Signature"=>get_Signature($Interface, 1),
 
4143
                "Header"=>$CompleteSignature{1}{$Interface}{"Header"},
 
4144
                "Line"=>$CompleteSignature{1}{$Interface}{"Line"},
 
4145
                "Old_SoName"=>$Interface_Library{1}{$Interface},
 
4146
                "New_SoName"=>$Interface_Library{2}{$Interface});
 
4147
            @{$CompatProblems{$Interface}{$SubProblemType}{"RetVal"}}{keys(%{$SubProblems{$SubProblemType}})} = values %{$SubProblems{$SubProblemType}};
 
4148
        }
 
4149
        if($ReturnType1_Id and $ReturnType2_Id)
 
4150
        {
 
4151
            @RecurTypes = ();
 
4152
            %SubProblems = mergeTypes($ReturnType1_Id, $Tid_TDid{1}{$ReturnType1_Id}, $ReturnType2_Id, $Tid_TDid{2}{$ReturnType2_Id});
 
4153
            foreach my $SubProblemType (keys(%SubProblems))
 
4154
            {
 
4155
                foreach my $SubLocation (keys(%{$SubProblems{$SubProblemType}}))
 
4156
                {
 
4157
                    my $NewLocation = ($SubLocation)?"RetVal->".$SubLocation:"RetVal";
 
4158
                    %{$CompatProblems{$Interface}{$SubProblemType}{$NewLocation}}=(
 
4159
                        "Signature"=>get_Signature($Interface, 1),
 
4160
                        "Header"=>$CompleteSignature{1}{$Interface}{"Header"},
 
4161
                        "Line"=>$CompleteSignature{1}{$Interface}{"Line"},
 
4162
                        "Old_SoName"=>$Interface_Library{1}{$Interface},
 
4163
                        "New_SoName"=>$Interface_Library{2}{$Interface},
 
4164
                        "Return_Type_Name"=>get_TypeName($ReturnType1_Id, 1) );
 
4165
                    @{$CompatProblems{$Interface}{$SubProblemType}{$NewLocation}}{keys(%{$SubProblems{$SubProblemType}{$SubLocation}})} = values %{$SubProblems{$SubProblemType}{$SubLocation}};
 
4166
                    if($SubLocation !~ /\-\>/)
 
4167
                    {
 
4168
                        $CompatProblems{$Interface}{$SubProblemType}{$NewLocation}{"Start_Type_Name"} = get_TypeName($ReturnType1_Id, 1);
 
4169
                    }
 
4170
                }
 
4171
            }
 
4172
        }
 
4173
        
 
4174
                #checking object type
 
4175
                my $ObjectType1_Id = $CompleteSignature{1}{$Interface}{"Class"};
 
4176
                my $ObjectType2_Id = $CompleteSignature{2}{$Interface}{"Class"};
 
4177
        if($ObjectType1_Id and $ObjectType2_Id)
 
4178
        {
 
4179
            my $ThisType1_Id = getTypeIdByName(get_TypeName($ObjectType1_Id, 1)."*const", 1);
 
4180
            my $ThisType2_Id = getTypeIdByName(get_TypeName($ObjectType2_Id, 2)."*const", 2);
 
4181
            if($ThisType1_Id and $ThisType2_Id)
 
4182
            {
 
4183
                @RecurTypes = ();
 
4184
                        %SubProblems = mergeTypes($ThisType1_Id, $Tid_TDid{1}{$ThisType1_Id}, $ThisType2_Id, $Tid_TDid{2}{$ThisType2_Id});
 
4185
                foreach my $SubProblemType (keys(%SubProblems))
 
4186
                {
 
4187
                    foreach my $SubLocation (keys(%{$SubProblems{$SubProblemType}}))
 
4188
                    {
 
4189
                        my $NewLocation = ($SubLocation)?"Obj->".$SubLocation:"Obj";
 
4190
                        %{$CompatProblems{$Interface}{$SubProblemType}{$NewLocation}}=(
 
4191
                            "Signature"=>get_Signature($Interface, 1),
 
4192
                            "Header"=>$CompleteSignature{1}{$Interface}{"Header"},
 
4193
                            "Line"=>$CompleteSignature{1}{$Interface}{"Line"},
 
4194
                            "Old_SoName"=>$Interface_Library{1}{$Interface},
 
4195
                            "New_SoName"=>$Interface_Library{2}{$Interface},
 
4196
                            "Object_Type_Name"=>get_TypeName($ObjectType1_Id, 1) );
 
4197
                        @{$CompatProblems{$Interface}{$SubProblemType}{$NewLocation}}{keys(%{$SubProblems{$SubProblemType}{$SubLocation}})} = values %{$SubProblems{$SubProblemType}{$SubLocation}};
 
4198
                        if($SubLocation !~ /\-\>/)
 
4199
                        {
 
4200
                            $CompatProblems{$Interface}{$SubProblemType}{$NewLocation}{"Start_Type_Name"} = get_TypeName($ObjectType1_Id, 1);
 
4201
                        }
 
4202
                    }
 
4203
                }
 
4204
            }
 
4205
        }
 
4206
        }
 
4207
    set_Problems_Priority();
 
4208
}
 
4209
 
 
4210
sub getTypeIdByName($$)
 
4211
{
 
4212
    my ($TypeName, $Version) = @_;
 
4213
    return $TName_Tid{$Version}{correctName($TypeName)};
 
4214
}
 
4215
 
 
4216
sub detectTypeChange($$$)
 
4217
{
 
4218
    my ($Type1_Id, $Type2_Id, $Prefix) = @_;
 
4219
    my %LocalProblems = ();
 
4220
    my $Type1_DId = $Tid_TDid{1}{$Type1_Id};
 
4221
    my $Type2_DId = $Tid_TDid{2}{$Type2_Id};
 
4222
    my %Type1 = get_Type($Type1_DId, $Type1_Id, 1);
 
4223
    my %Type2 = get_Type($Type2_DId, $Type2_Id, 2);
 
4224
    my %Type1_Base = get_BaseType($Type1_DId, $Type1_Id, 1);
 
4225
    my %Type2_Base = get_BaseType($Type2_DId, $Type2_Id, 2);
 
4226
    my %Type1_Pure = get_PureType($Type1_DId, $Type1_Id, 1);
 
4227
    my %Type2_Pure = get_PureType($Type2_DId, $Type2_Id, 2);
 
4228
    my $Type1_PointerLevel = get_PointerLevel($Type1_DId, $Type1_Id, 1);
 
4229
    my $Type2_PointerLevel = get_PointerLevel($Type2_DId, $Type2_Id, 2);
 
4230
    return () if(not $Type1{"Name"} or not $Type2{"Name"} or not $Type1{"Size"} or not $Type2{"Size"} or not $Type1_Pure{"Size"} or not $Type2_Pure{"Size"} or not $Type1_Base{"Name"} or not $Type2_Base{"Name"} or not $Type1_Base{"Size"} or not $Type2_Base{"Size"} or $Type1_PointerLevel eq "" or $Type2_PointerLevel eq "");
 
4231
    if($Type1_Base{"Name"} ne $Type2_Base{"Name"})
 
4232
    {#base type change
 
4233
        if($Type1_Base{"Name"}!~/anon\-/ and $Type2_Base{"Name"}!~/anon\-/)
 
4234
        {
 
4235
            if($Type1_Base{"Size"}!=$Type2_Base{"Size"})
 
4236
            {
 
4237
                %{$LocalProblems{$Prefix."_BaseType_And_Size"}}=(
 
4238
                    "Old_Value"=>$Type1_Base{"Name"},
 
4239
                    "New_Value"=>$Type2_Base{"Name"},
 
4240
                    "Old_Size"=>$Type1_Base{"Size"},
 
4241
                    "New_Size"=>$Type2_Base{"Size"},
 
4242
                    "InitialType_Type"=>$Type1_Pure{"Type"});
 
4243
            }
 
4244
            else
 
4245
            {
 
4246
                %{$LocalProblems{$Prefix."_BaseType"}}=(
 
4247
                    "Old_Value"=>$Type1_Base{"Name"},
 
4248
                    "New_Value"=>$Type2_Base{"Name"},
 
4249
                    "InitialType_Type"=>$Type1_Pure{"Type"});
 
4250
            }
 
4251
        }
 
4252
    }
 
4253
    elsif($Type1{"Name"} ne $Type2{"Name"})
 
4254
    {#type change
 
4255
        if($Type1{"Name"}!~/anon\-/ and $Type2{"Name"}!~/anon\-/)
 
4256
        {
 
4257
            if($Type1{"Size"}!=$Type2{"Size"})
 
4258
            {
 
4259
                %{$LocalProblems{$Prefix."_Type_And_Size"}}=(
 
4260
                    "Old_Value"=>$Type1{"Name"},
 
4261
                    "New_Value"=>$Type2{"Name"},
 
4262
                    "Old_Size"=>($Type1{"Type"} eq "Array")?$Type1{"Size"}*$Type1_Base{"Size"}:$Type1{"Size"},
 
4263
                    "New_Size"=>($Type2{"Type"} eq "Array")?$Type2{"Size"}*$Type2_Base{"Size"}:$Type2{"Size"},
 
4264
                    "InitialType_Type"=>$Type1_Pure{"Type"});
 
4265
            }
 
4266
            else
 
4267
            {
 
4268
                %{$LocalProblems{$Prefix."_Type"}}=(
 
4269
                    "Old_Value"=>$Type1{"Name"},
 
4270
                    "New_Value"=>$Type2{"Name"},
 
4271
                    "InitialType_Type"=>$Type1_Pure{"Type"});
 
4272
            }
 
4273
        }
 
4274
    }
 
4275
    
 
4276
    if($Type1_PointerLevel!=$Type2_PointerLevel)
 
4277
    {
 
4278
        %{$LocalProblems{$Prefix."_PointerLevel"}}=(
 
4279
            "Old_Value"=>$Type1_PointerLevel,
 
4280
            "New_Value"=>$Type2_PointerLevel);
 
4281
    }
 
4282
    return %LocalProblems;
 
4283
}
 
4284
 
 
4285
sub htmlSpecChars($)
 
4286
{
 
4287
    my $Str = $_[0];
 
4288
    $Str =~ s/\&([^#])/&amp;$1/g;
 
4289
    $Str =~ s/</&lt;/g;
 
4290
    $Str =~ s/>/&gt;/g;
 
4291
    $Str =~ s/([^ ])( )([^ ])/$1\@ALONE_SP\@$3/g;
 
4292
    $Str =~ s/ /&nbsp;/g;
 
4293
    $Str =~ s/\@ALONE_SP\@/ /g;
 
4294
    $Str =~ s/\n/<br\/>/g;
 
4295
    return $Str;
 
4296
}
 
4297
 
 
4298
sub highLight_Signature($)
 
4299
{
 
4300
    my $Signature = $_[0];
 
4301
    return highLight_Signature_PPos_Italic($Signature, "", 0, 0);
 
4302
}
 
4303
 
 
4304
sub highLight_Signature_Italic($)
 
4305
{
 
4306
    my $Signature = $_[0];
 
4307
    return highLight_Signature_PPos_Italic($Signature, "", 1, 0);
 
4308
}
 
4309
 
 
4310
sub highLight_Signature_Italic_Color($)
 
4311
{
 
4312
    my $Signature = $_[0];
 
4313
    return highLight_Signature_PPos_Italic($Signature, "", 1, 1);
 
4314
}
 
4315
 
 
4316
sub highLight_Signature_PPos_Italic($$$$)
 
4317
{
 
4318
    my ($FullSignature, $Parameter_Position, $ItalicParams, $ColorParams) = @_;
 
4319
    my ($Signature, $SymbolVersion) = ($FullSignature, "");
 
4320
    if($FullSignature =~ /\A(.+)[\@]+(.+)\Z/)
 
4321
    {
 
4322
        ($Signature, $SymbolVersion) = ($1, $2);
 
4323
    }
 
4324
    if($Signature=~/\Atypeinfo\W/)
 
4325
    {
 
4326
        return $Signature.(($SymbolVersion)?"<span class='symver'> \@ $SymbolVersion</span>":"");
 
4327
    }
 
4328
    if($Signature!~/\)(| const)\Z/)
 
4329
    {
 
4330
        return $Signature.(($SymbolVersion)?"<span class='symver'> \@ $SymbolVersion</span>":"");
 
4331
    }
 
4332
    $Signature =~ /(.+?)\(.*\)(| const)\Z/;
 
4333
    my ($Begin, $End) = ($1, $2);
 
4334
    my @Parts = ();
 
4335
    my $Part_Num = 0;
 
4336
    foreach my $Part (get_Signature_Parts($Signature, 1))
 
4337
    {
 
4338
        $Part =~ s/\A\s+|\s+\Z//g;
 
4339
        my ($Part_Styled, $ParamName) = ($Part, "");
 
4340
        if($Part=~/\([\*]+(\w+)\)/i)
 
4341
        {#func-ptr
 
4342
            $ParamName = $1;
 
4343
        }
 
4344
        elsif($Part=~/(\w+)[\,\)]*\Z/i)
 
4345
        {
 
4346
            $ParamName = $1;
 
4347
        }
 
4348
        if(not $ParamName)
 
4349
        {
 
4350
            push(@Parts, $Part);
 
4351
            next;
 
4352
        }
 
4353
        if($ItalicParams and not $TName_Tid{1}{$Part} and not $TName_Tid{2}{$Part})
 
4354
        {
 
4355
            if(($Parameter_Position ne "") and ($Part_Num == $Parameter_Position))
 
4356
            {
 
4357
                $Part_Styled =~ s!(\W)$ParamName([\,\)]|\Z)!$1<span class='focus_param'>$ParamName</span>$2!ig;
 
4358
            }
 
4359
            elsif($ColorParams)
 
4360
            {
 
4361
                $Part_Styled =~ s!(\W)$ParamName([\,\)]|\Z)!$1<span class='color_param'>$ParamName</span>$2!ig;
 
4362
            }
 
4363
            else
 
4364
            {
 
4365
                $Part_Styled =~ s!(\W)$ParamName([\,\)]|\Z)!$1<span style='font-style:italic;'>$ParamName</span>$2!ig;
 
4366
            }
 
4367
        }
 
4368
        $Part_Styled = "<span style='white-space:nowrap;'>".$Part_Styled."</span>";
 
4369
        push(@Parts, $Part_Styled);
 
4370
        $Part_Num += 1;
 
4371
    }
 
4372
    $Signature = $Begin."<span class='int_p'>"."(".join(" ", @Parts).")"."</span>".$End;
 
4373
    $Signature =~ s!\[\]![<span style='padding-left:2px;'>]</span>!g;
 
4374
    $Signature =~ s!operator=!operator<span style='padding-left:2px'>=</span>!g;
 
4375
    $Signature =~ s!(\[in-charge\]|\[not-in-charge\]|\[in-charge-deleting\])!<span style='color:Black;font-weight:normal;'>$1</span>!g;
 
4376
    return $Signature.(($SymbolVersion)?"<span class='symver'> \@ $SymbolVersion</span>":"");
 
4377
}
 
4378
 
 
4379
sub get_Signature_Parts($$)
 
4380
{
 
4381
    my ($Signature, $Comma) = @_;
 
4382
    my @Parts = ();
 
4383
    my $Bracket_Num = 0;
 
4384
    my $Bracket2_Num = 0;
 
4385
    my $Parameters = $Signature;
 
4386
    if($Signature=~/&gt;|&lt;/)
 
4387
    {
 
4388
        $Parameters=~s/&gt;/>/g;
 
4389
        $Parameters=~s/&lt;/</g;
 
4390
    }
 
4391
    my $Part_Num = 0;
 
4392
    if($Parameters =~ s/.+?\((.*)\)(| const)\Z/$1/)
 
4393
    {
 
4394
        foreach my $Pos (0 .. length($Parameters) - 1)
 
4395
        {
 
4396
            my $Symbol = substr($Parameters, $Pos, 1);
 
4397
            $Bracket_Num += 1 if($Symbol eq "(");
 
4398
            $Bracket_Num -= 1 if($Symbol eq ")");
 
4399
            $Bracket2_Num += 1 if($Symbol eq "<");
 
4400
            $Bracket2_Num -= 1 if($Symbol eq ">");
 
4401
            if($Symbol eq "," and $Bracket_Num==0 and $Bracket2_Num==0)
 
4402
            {
 
4403
                $Parts[$Part_Num] .= $Symbol if($Comma);
 
4404
                $Part_Num += 1;
 
4405
            }
 
4406
            else
 
4407
            {
 
4408
                $Parts[$Part_Num] .= $Symbol;
 
4409
            }
 
4410
        }
 
4411
        if($Signature=~/&gt;|&lt;/)
 
4412
        {
 
4413
            foreach my $Part (@Parts)
 
4414
            {
 
4415
                $Part=~s/\>/&gt;/g;
 
4416
                $Part=~s/\</&lt;/g;
 
4417
            }
 
4418
        }
 
4419
        return @Parts;
 
4420
    }
 
4421
    else
 
4422
    {
 
4423
        return ();
 
4424
    }
 
4425
}
 
4426
 
 
4427
my %TypeProblems_Kind=(
 
4428
    "Added_Virtual_Function"=>1,
 
4429
    "Withdrawn_Virtual_Function"=>1,
 
4430
    "Virtual_Function_Position"=>1,
 
4431
    "Virtual_Function_Redefinition"=>1,
 
4432
    "Virtual_Function_Redefinition_B"=>1,
 
4433
    "Size"=>1,
 
4434
    "Added_Member_And_Size"=>1,
 
4435
    "Added_Middle_Member_And_Size"=>1,
 
4436
    "Withdrawn_Member_And_Size"=>1,
 
4437
    "Withdrawn_Member"=>1,
 
4438
    "Withdrawn_Middle_Member_And_Size"=>1,
 
4439
    "Member_Rename"=>1,
 
4440
    "Enum_Member_Value"=>1,
 
4441
    "Enum_Member_Name"=>1,
 
4442
    "Member_Type_And_Size"=>1,
 
4443
    "Member_Type"=>1,
 
4444
    "Member_BaseType_And_Size"=>1,
 
4445
    "Member_BaseType"=>1,
 
4446
    "Member_PointerLevel"=>1,
 
4447
    "BaseType"=>1
 
4448
);
 
4449
 
 
4450
my %InterfaceProblems_Kind=(
 
4451
    "Added_Interface"=>1,
 
4452
    "Withdrawn_Interface"=>1,
 
4453
    "Function_Become_Static"=>1,
 
4454
    "Function_Become_NonStatic"=>1,
 
4455
    "Parameter_Type_And_Size"=>1,
 
4456
    "Parameter_Type"=>1,
 
4457
    "Parameter_BaseType_And_Size"=>1,
 
4458
    "Parameter_BaseType"=>1,
 
4459
    "Parameter_PointerLevel"=>1,
 
4460
    "Return_Type_And_Size"=>1,
 
4461
    "Return_Type"=>1,
 
4462
    "Return_BaseType_And_Size"=>1,
 
4463
    "Return_BaseType"=>1,
 
4464
    "Return_PointerLevel"=>1,
 
4465
    "Withdrawn_Parameter"=>1,
 
4466
    "Added_Parameter"=>1
 
4467
);
 
4468
 
 
4469
sub testSystem_cpp()
 
4470
{
 
4471
    print "testing for C++ library changes\n";
 
4472
    my (@DataDefs_v1, @Sources_v1, @DataDefs_v2, @Sources_v2) = ();
 
4473
    
 
4474
    #Withdrawn_Parameter
 
4475
    @DataDefs_v1 = (@DataDefs_v1, "int func_withdrawn_parameter(int param, int withdrawn_param);");
 
4476
    @Sources_v1 = (@Sources_v1, "int func_withdrawn_parameter(int param, int withdrawn_param)\n{\n    return 0;\n}");
 
4477
    
 
4478
    @DataDefs_v2 = (@DataDefs_v2, "int func_withdrawn_parameter(int param);");
 
4479
    @Sources_v2 = (@Sources_v2, "int func_withdrawn_parameter(int param)\n{\n    return 0;\n}");
 
4480
    
 
4481
    #Added_Parameter
 
4482
    @DataDefs_v1 = (@DataDefs_v1, "int func_added_parameter(int param);");
 
4483
    @Sources_v1 = (@Sources_v1, "int func_added_parameter(int param)\n{\n    return 0;\n}");
 
4484
    
 
4485
    @DataDefs_v2 = (@DataDefs_v2, "int func_added_parameter(int param, int added_param);");
 
4486
    @Sources_v2 = (@Sources_v2, "int func_added_parameter(int param, int added_param)\n{\n    return 0;\n}");
 
4487
    
 
4488
    #Added_Virtual_Function
 
4489
    @DataDefs_v1 = (@DataDefs_v1, "class type_test_added_virtual_function\n{\npublic:\n    int func1(int param);\n    virtual int func2(int param);\n};");
 
4490
    @Sources_v1 = (@Sources_v1, "int type_test_added_virtual_function::func1(int param)\n{\n    return param;\n}");
 
4491
    @Sources_v1 = (@Sources_v1, "int type_test_added_virtual_function::func2(int param)\n{\n    return param;\n}");
 
4492
    
 
4493
    @DataDefs_v2 = (@DataDefs_v2, "class type_test_added_virtual_function\n{\npublic:\n    virtual int func1(int param);\n    virtual int func2(int param);\n};");
 
4494
    @Sources_v2 = (@Sources_v2, "int type_test_added_virtual_function::func1(int param)\n{\n    return param;\n}");
 
4495
    @Sources_v2 = (@Sources_v2, "int type_test_added_virtual_function::func2(int param)\n{\n    return param;\n}");
 
4496
    
 
4497
    #added simple function
 
4498
    @DataDefs_v2 = (@DataDefs_v2, "typedef int (*FUNCPTR_TYPE)(int a, int b);\nint added_function_param_funcptr(FUNCPTR_TYPE*const** f);");
 
4499
    @Sources_v2 = (@Sources_v2, "int added_function_param_funcptr(FUNCPTR_TYPE*const** f)\n{\n    return 0;\n}");
 
4500
    
 
4501
    #Withdrawn_Virtual_Function
 
4502
    @DataDefs_v1 = (@DataDefs_v1, "class type_test_withdrawn_virtual_function\n{\npublic:\n    virtual int func1(int param);\n    virtual int func2(int param);\n};");
 
4503
    @Sources_v1 = (@Sources_v1, "int type_test_withdrawn_virtual_function::func1(int param)\n{\n    return param;\n}");
 
4504
    @Sources_v1 = (@Sources_v1, "int type_test_withdrawn_virtual_function::func2(int param)\n{\n    return param;\n}");
 
4505
    
 
4506
    @DataDefs_v2 = (@DataDefs_v2, "class type_test_withdrawn_virtual_function\n{\npublic:\n    int func1(int param);\n    virtual int func2(int param);\n};");
 
4507
    @Sources_v2 = (@Sources_v2, "int type_test_withdrawn_virtual_function::func1(int param)\n{\n    return param;\n}");
 
4508
    @Sources_v2 = (@Sources_v2, "int type_test_withdrawn_virtual_function::func2(int param)\n{\n    return param;\n}");
 
4509
    
 
4510
    #Virtual_Function_Position
 
4511
    @DataDefs_v1 = (@DataDefs_v1, "class type_test_virtual_function_position\n{\npublic:\n    virtual int func1(int param);\n    virtual int func2(int param);\n};");
 
4512
    @Sources_v1 = (@Sources_v1, "int type_test_virtual_function_position::func1(int param)\n{\n    return param;\n}");
 
4513
    @Sources_v1 = (@Sources_v1, "int type_test_virtual_function_position::func2(int param)\n{\n    return param;\n}");
 
4514
    
 
4515
    @DataDefs_v2 = (@DataDefs_v2, "class type_test_virtual_function_position\n{\npublic:\n    virtual int func2(int param);\n    virtual int func1(int param);\n};");
 
4516
    @Sources_v2 = (@Sources_v2, "int type_test_virtual_function_position::func1(int param)\n{\n    return param;\n}");
 
4517
    @Sources_v2 = (@Sources_v2, "int type_test_virtual_function_position::func2(int param)\n{\n    return param;\n}");
 
4518
    
 
4519
    #virtual functions safe replace
 
4520
    @DataDefs_v1 = (@DataDefs_v1, "class type_test_virtual_function_position_safe_replace_base\n{\npublic:\n    virtual int func1(int param);\n    virtual int func2(int param);\n};");
 
4521
    @Sources_v1 = (@Sources_v1, "int type_test_virtual_function_position_safe_replace_base::func1(int param)\n{\n    return param;\n}");
 
4522
    @Sources_v1 = (@Sources_v1, "int type_test_virtual_function_position_safe_replace_base::func2(int param)\n{\n    return param;\n}");
 
4523
    
 
4524
    @DataDefs_v2 = (@DataDefs_v2, "class type_test_virtual_function_position_safe_replace_base\n{\npublic:\n    virtual int func1(int param);\n    virtual int func2(int param);\n};");
 
4525
    @Sources_v2 = (@Sources_v2, "int type_test_virtual_function_position_safe_replace_base::func1(int param)\n{\n    return param;\n}");
 
4526
    @Sources_v2 = (@Sources_v2, "int type_test_virtual_function_position_safe_replace_base::func2(int param)\n{\n    return param;\n}");
 
4527
    
 
4528
    @DataDefs_v1 = (@DataDefs_v1, "class type_test_virtual_function_position_safe_replace:public type_test_virtual_function_position_safe_replace_base\n{\npublic:\n    virtual int func1(int param);\n    virtual int func2(int param);\n};");
 
4529
    @Sources_v1 = (@Sources_v1, "int type_test_virtual_function_position_safe_replace::func1(int param)\n{\n    return param;\n}");
 
4530
    @Sources_v1 = (@Sources_v1, "int type_test_virtual_function_position_safe_replace::func2(int param)\n{\n    return param;\n}");
 
4531
    
 
4532
    @DataDefs_v2 = (@DataDefs_v2, "class type_test_virtual_function_position_safe_replace:public type_test_virtual_function_position_safe_replace_base\n{\npublic:\n    virtual int func2(int param);\n    virtual int func1(int param);\n};");
 
4533
    @Sources_v2 = (@Sources_v2, "int type_test_virtual_function_position_safe_replace::func1(int param)\n{\n    return param;\n}");
 
4534
    @Sources_v2 = (@Sources_v2, "int type_test_virtual_function_position_safe_replace::func2(int param)\n{\n    return param;\n}");
 
4535
    
 
4536
    #virtual table changes
 
4537
    @DataDefs_v1 = (@DataDefs_v1, "class type_test_virtual_table_base\n{\npublic:\n    virtual int func1(int param);\n    virtual int func2(int param);\n};");
 
4538
    @DataDefs_v1 = (@DataDefs_v1, "class type_test_virtual_table:public type_test_virtual_table_base\n{\npublic:\n    virtual int func1(int param);\n    virtual int func2(int param);\n};");
 
4539
    @Sources_v1 = (@Sources_v1, "int type_test_virtual_table_base::func1(int param)\n{\n    return param;\n}");
 
4540
    @Sources_v1 = (@Sources_v1, "int type_test_virtual_table_base::func2(int param)\n{\n    return param;\n}");
 
4541
    @Sources_v1 = (@Sources_v1, "int type_test_virtual_table::func1(int param)\n{\n    return param;\n}");
 
4542
    @Sources_v1 = (@Sources_v1, "int type_test_virtual_table::func2(int param)\n{\n    return param;\n}");
 
4543
    
 
4544
    @DataDefs_v2 = (@DataDefs_v2, "class type_test_virtual_table_base\n{\npublic:\n    virtual int func1(int param);\n    virtual int func2(int param);\n};");
 
4545
    @DataDefs_v2 = (@DataDefs_v2, "class type_test_virtual_table:public type_test_virtual_table_base\n{\npublic:\n    virtual int func2(int param);\n    virtual int func1(int param);\n};");
 
4546
    @Sources_v2 = (@Sources_v2, "int type_test_virtual_table_base::func1(int param)\n{\n    return param;\n}");
 
4547
    @Sources_v2 = (@Sources_v2, "int type_test_virtual_table_base::func2(int param)\n{\n    return param;\n}");
 
4548
    @Sources_v2 = (@Sources_v2, "int type_test_virtual_table::func1(int param)\n{\n    return param;\n}");
 
4549
    @Sources_v2 = (@Sources_v2, "int type_test_virtual_table::func2(int param)\n{\n    return param;\n}");
 
4550
    
 
4551
    #Virtual_Function_Redefinition
 
4552
    @DataDefs_v1 = (@DataDefs_v1, "class type_test_virtual_function_redefinition_base\n{\npublic:\n    virtual int func1(int param);\n    virtual int func2(int param);\n};");
 
4553
    @DataDefs_v1 = (@DataDefs_v1, "class type_test_virtual_function_redefinition:public type_test_virtual_function_redefinition_base\n{\npublic:\n    virtual int func3(int param);\n};");
 
4554
    @Sources_v1 = (@Sources_v1, "int type_test_virtual_function_redefinition_base::func1(int param)\n{\n    return param;\n}");
 
4555
    @Sources_v1 = (@Sources_v1, "int type_test_virtual_function_redefinition_base::func2(int param)\n{\n    return param;\n}");
 
4556
    @Sources_v1 = (@Sources_v1, "int type_test_virtual_function_redefinition::func3(int param)\n{\n    return param;\n}");
 
4557
    
 
4558
    @DataDefs_v2 = (@DataDefs_v2, "class type_test_virtual_function_redefinition_base\n{\npublic:\n    virtual int func1(int param);\n    virtual int func2(int param);\n};");
 
4559
    @DataDefs_v2 = (@DataDefs_v2, "class type_test_virtual_function_redefinition:public type_test_virtual_function_redefinition_base\n{\npublic:\n    virtual int func2(int param);\n    virtual int func3(int param);\n};");
 
4560
    @Sources_v2 = (@Sources_v2, "int type_test_virtual_function_redefinition_base::func1(int param){\n    return param;\n}");
 
4561
    @Sources_v2 = (@Sources_v2, "int type_test_virtual_function_redefinition_base::func2(int param){\n    return param;\n}");
 
4562
    @Sources_v2 = (@Sources_v2, "int type_test_virtual_function_redefinition::func2(int param)\n{\n    return param;\n}");
 
4563
    @Sources_v2 = (@Sources_v2, "int type_test_virtual_function_redefinition::func3(int param)\n{\n    return param;\n}");
 
4564
    
 
4565
    #size change
 
4566
    @DataDefs_v1 = (@DataDefs_v1, "struct type_test_size\n{\npublic:\n    virtual type_test_size func1(type_test_size param);\n    int i;\n    long j;\n    double k;\n    type_test_size* p;\n};");
 
4567
    @Sources_v1 = (@Sources_v1, "type_test_size type_test_size::func1(type_test_size param)\n{\n    return param;\n}");
 
4568
    
 
4569
    @DataDefs_v2 = (@DataDefs_v2, "struct type_test_size\n{\npublic:\n    virtual type_test_size func1(type_test_size param);\n    int i;\n    long j;\n    double k;\n    type_test_size* p;\n    int added_member;\n};");
 
4570
    @Sources_v2 = (@Sources_v2, "type_test_size type_test_size::func1(type_test_size param)\n{\n    return param;\n}");
 
4571
    
 
4572
    #Added_Member_And_Size
 
4573
    @DataDefs_v1 = (@DataDefs_v1, "struct type_test_added_member\n{\npublic:\n    virtual type_test_added_member func1(type_test_added_member param);\n    int i;\n    long j;\n    double k;\n    type_test_added_member* p;\n};");
 
4574
    @Sources_v1 = (@Sources_v1, "type_test_added_member type_test_added_member::func1(type_test_added_member param)\n{\n    return param;\n}");
 
4575
    
 
4576
    @DataDefs_v2 = (@DataDefs_v2, "struct type_test_added_member\n{\npublic:\n    virtual type_test_added_member func1(type_test_added_member param);\n    int i;\n    long j;\n    double k;\n    type_test_added_member* p;\n    int added_member;\n};");
 
4577
    @Sources_v2 = (@Sources_v2, "type_test_added_member type_test_added_member::func1(type_test_added_member param)\n{\n    return param;\n}");
 
4578
    
 
4579
    #Method object changes
 
4580
    @DataDefs_v1 = (@DataDefs_v1, "class type_test_object_added_member\n{\npublic:\n    virtual int func1(int param);\n    int i;\n    long j;\n    double k;\n    type_test_added_member* p;\n};");
 
4581
    @Sources_v1 = (@Sources_v1, "int type_test_object_added_member::func1(int param)\n{\n    return param;\n}");
 
4582
    
 
4583
    @DataDefs_v2 = (@DataDefs_v2, "class type_test_object_added_member\n{\npublic:\n    virtual int func1(int param);\n    int i;\n    long j;\n    double k;\n    type_test_added_member* p;\n    int added_member;\n};");
 
4584
    @Sources_v2 = (@Sources_v2, "int type_test_object_added_member::func1(int param)\n{\n    return param;\n}");
 
4585
    
 
4586
    #added bitfield
 
4587
    @DataDefs_v1 = (@DataDefs_v1, "struct type_test_added_bitfield\n{\npublic:\n    virtual type_test_added_bitfield func1(type_test_added_bitfield param);\n    int i;\n    long j;\n    double k;\n    int b1 : 32;\n    int b2 : 31;\n    type_test_added_bitfield* p;\n};");
 
4588
    @Sources_v1 = (@Sources_v1, "type_test_added_bitfield type_test_added_bitfield::func1(type_test_added_bitfield param)\n{\n    return param;\n}");
 
4589
    
 
4590
    @DataDefs_v2 = (@DataDefs_v2, "struct type_test_added_bitfield\n{\npublic:\n    virtual type_test_added_bitfield func1(type_test_added_bitfield param);\n    int i;\n    long j;\n    double k;\n    int b1 : 32;\n    int b2 : 31;\n    int added_bitfield : 1;\n    type_test_added_bitfield* p;\n};");
 
4591
    @Sources_v2 = (@Sources_v2, "type_test_added_bitfield type_test_added_bitfield::func1(type_test_added_bitfield param)\n{\n    return param;\n}");
 
4592
    
 
4593
    #withdrawn bitfield
 
4594
    @DataDefs_v1 = (@DataDefs_v1, "struct type_test_withdrawn_bitfield\n{\npublic:\n    virtual type_test_withdrawn_bitfield func1(type_test_withdrawn_bitfield param);\n    int i;\n    long j;\n    double k;\n    int b1 : 32;\n    int b2 : 31;\n    int withdrawn_bitfield : 1;\n    type_test_withdrawn_bitfield* p;\n};");
 
4595
    @Sources_v1 = (@Sources_v1, "type_test_withdrawn_bitfield type_test_withdrawn_bitfield::func1(type_test_withdrawn_bitfield param)\n{\n    return param;\n}");
 
4596
    
 
4597
    @DataDefs_v2 = (@DataDefs_v2, "struct type_test_withdrawn_bitfield\n{\npublic:\n    virtual type_test_withdrawn_bitfield func1(type_test_withdrawn_bitfield param);\n    int i;\n    long j;\n    double k;\n    int b1 : 32;\n    int b2 : 31;\n    type_test_withdrawn_bitfield* p;\n};");
 
4598
    @Sources_v2 = (@Sources_v2, "type_test_withdrawn_bitfield type_test_withdrawn_bitfield::func1(type_test_withdrawn_bitfield param)\n{\n    return param;\n}");
 
4599
    
 
4600
    #Added_Middle_Member_And_Size
 
4601
    @DataDefs_v1 = (@DataDefs_v1, "struct type_test_added_middle_member\n{\npublic:\n    virtual type_test_added_middle_member func1(type_test_added_middle_member param);\n    int i;\n    long j;\n    double k;\n    type_test_added_middle_member* p;\n};");
 
4602
    @Sources_v1 = (@Sources_v1, "type_test_added_middle_member type_test_added_middle_member::func1(type_test_added_middle_member param)\n{\n    return param;\n}");
 
4603
    
 
4604
    @DataDefs_v2 = (@DataDefs_v2, "struct type_test_added_middle_member\n{\npublic:\n    virtual type_test_added_middle_member func1(type_test_added_middle_member param);\n    int i;\n    int added_middle_member;\n    long j;\n    double k;\n    type_test_added_middle_member* p;\n};");
 
4605
    @Sources_v2 = (@Sources_v2, "type_test_added_middle_member type_test_added_middle_member::func1(type_test_added_middle_member param)\n{\n    return param;\n}");
 
4606
    
 
4607
    #Member_Rename
 
4608
    @DataDefs_v1 = (@DataDefs_v1, "struct type_test_member_rename\n{\npublic:\n    virtual type_test_member_rename func1(type_test_member_rename param);\n    long i;\n    long j;\n    double k;\n    type_test_member_rename* p;\n};");
 
4609
    @Sources_v1 = (@Sources_v1, "type_test_member_rename type_test_member_rename::func1(type_test_member_rename param)\n{\n    return param;\n}");
 
4610
    
 
4611
    @DataDefs_v2 = (@DataDefs_v2, "struct type_test_member_rename\n{\npublic:\n    virtual type_test_member_rename func1(type_test_member_rename param);\n    long renamed_member;\n    long j;\n    double k;\n    type_test_member_rename* p;\n};");
 
4612
    @Sources_v2 = (@Sources_v2, "type_test_member_rename type_test_member_rename::func1(type_test_member_rename param)\n{\n    return param;\n}");
 
4613
    
 
4614
    #Withdrawn_Member_And_Size
 
4615
    @DataDefs_v1 = (@DataDefs_v1, "struct type_test_withdrawn_member\n{\npublic:\n    virtual type_test_withdrawn_member func1(type_test_withdrawn_member param);\n    int i;\n    long j;\n    double k;\n    type_test_withdrawn_member* p;\n    int withdrawn_member;\n};");
 
4616
    @Sources_v1 = (@Sources_v1, "type_test_withdrawn_member type_test_withdrawn_member::func1(type_test_withdrawn_member param)\n{\n    return param;\n}");
 
4617
    
 
4618
    @DataDefs_v2 = (@DataDefs_v2, "struct type_test_withdrawn_member\n{\npublic:\n    virtual type_test_withdrawn_member func1(type_test_withdrawn_member param);\n    int i;\n    long j;\n    double k;\n    type_test_withdrawn_member* p;\n};");
 
4619
    @Sources_v2 = (@Sources_v2, "type_test_withdrawn_member type_test_withdrawn_member::func1(type_test_withdrawn_member param)\n{\n    return param;\n}");
 
4620
    
 
4621
    #Withdrawn_Middle_Member_And_Size
 
4622
    @DataDefs_v1 = (@DataDefs_v1, "struct type_test_withdrawn_middle_member\n{\npublic:\n    virtual type_test_withdrawn_middle_member func1(type_test_withdrawn_middle_member param);\n    int i;\n    int withdrawn_middle_member;\n    long j;\n    double k;\n    type_test_withdrawn_middle_member* p;\n};");
 
4623
    @Sources_v1 = (@Sources_v1, "type_test_withdrawn_middle_member type_test_withdrawn_middle_member::func1(type_test_withdrawn_middle_member param)\n{\n    return param;\n}");
 
4624
    
 
4625
    @DataDefs_v2 = (@DataDefs_v2, "struct type_test_withdrawn_middle_member\n{\npublic:\n    virtual type_test_withdrawn_middle_member func1(type_test_withdrawn_middle_member param);\n    int i;\n    long j;\n    double k;\n    type_test_withdrawn_middle_member* p;\n};");
 
4626
    @Sources_v2 = (@Sources_v2, "type_test_withdrawn_middle_member type_test_withdrawn_middle_member::func1(type_test_withdrawn_middle_member param)\n{\n    return param;\n}");
 
4627
    
 
4628
    #Enum_Member_Value
 
4629
    @DataDefs_v1 = (@DataDefs_v1, "enum type_test_enum_member_value_change\n{\n    MEMBER_1=1,\n    MEMBER_2=2\n};");
 
4630
    @DataDefs_v1 = (@DataDefs_v1, "int func_test_enum_member_value_change(enum type_test_enum_member_value_change param);");
 
4631
    @Sources_v1 = (@Sources_v1,
 
4632
"int func_test_enum_member_value_change(enum type_test_enum_member_value_change param)
 
4633
{
 
4634
    switch(param)
 
4635
    {
 
4636
        case 1:
 
4637
            return 1;
 
4638
        case 2:
 
4639
            return 2;
 
4640
    }
 
4641
    return 0;
 
4642
}");
 
4643
    
 
4644
    @DataDefs_v2 = (@DataDefs_v2, "enum type_test_enum_member_value_change\n{\n    MEMBER_1=2,\n    MEMBER_2=1\n};");
 
4645
    @DataDefs_v2 = (@DataDefs_v2, "int func_test_enum_member_value_change(enum type_test_enum_member_value_change param);");
 
4646
    @Sources_v2 = (@Sources_v2,
 
4647
"int func_test_enum_member_value_change(enum type_test_enum_member_value_change param)
 
4648
{
 
4649
    switch(param)
 
4650
    {
 
4651
        case 1:
 
4652
            return 1;
 
4653
        case 2:
 
4654
            return 2;
 
4655
    }
 
4656
    return 0;
 
4657
}");
 
4658
    
 
4659
    #Enum_Member_Name
 
4660
    @DataDefs_v1 = (@DataDefs_v1, "enum type_test_enum_member_rename\n{\n    BRANCH_1=1,\n    BRANCH_2=2\n};");
 
4661
    @DataDefs_v1 = (@DataDefs_v1, "int func_test_enum_member_rename(enum type_test_enum_member_rename param);");
 
4662
    @Sources_v1 = (@Sources_v1,
 
4663
"int func_test_enum_member_rename(enum type_test_enum_member_rename param)
 
4664
{
 
4665
    switch(param)
 
4666
    {
 
4667
        case 1:
 
4668
            return 1;
 
4669
        case 2:
 
4670
            return 2;
 
4671
    }
 
4672
    return 0;
 
4673
}");
 
4674
    
 
4675
    @DataDefs_v2 = (@DataDefs_v2, "enum type_test_enum_member_rename\n{\n    BRANCH_FIRST=1,\n    BRANCH_SECOND=1\n};");
 
4676
    @DataDefs_v2 = (@DataDefs_v2, "int func_test_enum_member_rename(enum type_test_enum_member_rename param);");
 
4677
    @Sources_v2 = (@Sources_v2,
 
4678
"int func_test_enum_member_rename(enum type_test_enum_member_rename param)
 
4679
{
 
4680
    switch(param)
 
4681
    {
 
4682
        case 1:
 
4683
            return 1;
 
4684
        case 2:
 
4685
            return 2;
 
4686
    }
 
4687
    return 0;
 
4688
}");
 
4689
    
 
4690
    #Member_Type_And_Size
 
4691
    @DataDefs_v1 = (@DataDefs_v1, "struct type_test_member_type_and_size\n{\npublic:\n    type_test_member_type_and_size func1(type_test_member_type_and_size param);\n    int i;\n    long j;\n    double k;\n    type_test_member_type_and_size* p;\n};");
 
4692
    @Sources_v1 = (@Sources_v1, "type_test_member_type_and_size type_test_member_type_and_size::func1(type_test_member_type_and_size param)\n{\n    return param;\n}");
 
4693
    
 
4694
    @DataDefs_v2 = (@DataDefs_v2, "struct type_test_member_type_and_size\n{\npublic:\n    type_test_member_type_and_size func1(type_test_member_type_and_size param);\n    long long i;\n    long j;\n    double k;\n    type_test_member_type_and_size* p;\n};");
 
4695
    @Sources_v2 = (@Sources_v2, "type_test_member_type_and_size type_test_member_type_and_size::func1(type_test_member_type_and_size param)\n{\n    return param;\n}");
 
4696
    
 
4697
    #Member_Type
 
4698
    @DataDefs_v1 = (@DataDefs_v1, "struct type_test_member_type\n{\npublic:\n    type_test_member_type func1(type_test_member_type param);\n    int i;\n    long j;\n    double k;\n    type_test_member_type* p;\n};");
 
4699
    @Sources_v1 = (@Sources_v1, "type_test_member_type type_test_member_type::func1(type_test_member_type param)\n{\n    return param;\n}");
 
4700
    
 
4701
    @DataDefs_v2 = (@DataDefs_v2, "struct type_test_member_type\n{\npublic:\n    type_test_member_type func1(type_test_member_type param);\n    float i;\n    long j;\n    double k;\n    type_test_member_type* p;\n};");
 
4702
    @Sources_v2 = (@Sources_v2, "type_test_member_type type_test_member_type::func1(type_test_member_type param)\n{\n    return param;\n}");
 
4703
    
 
4704
    #Member_BaseType
 
4705
    @DataDefs_v1 = (@DataDefs_v1, "struct type_test_member_basetype\n{\npublic:\n    type_test_member_basetype func1(type_test_member_basetype param);\n    int *i;\n    long j;\n    double k;\n    type_test_member_basetype* p;\n};");
 
4706
    @Sources_v1 = (@Sources_v1, "type_test_member_basetype type_test_member_basetype::func1(type_test_member_basetype param)\n{\n    return param;\n}");
 
4707
    
 
4708
    @DataDefs_v2 = (@DataDefs_v2, "struct type_test_member_basetype\n{\npublic:\n    type_test_member_basetype func1(type_test_member_basetype param);\n    long long *i;\n    long j;\n    double k;\n    type_test_member_basetype* p;\n};");
 
4709
    @Sources_v2 = (@Sources_v2, "type_test_member_basetype type_test_member_basetype::func1(type_test_member_basetype param)\n{\n    return param;\n}");
 
4710
    
 
4711
    #Member_PointerLevel_And_Size
 
4712
    @DataDefs_v1 = (@DataDefs_v1, "struct type_test_member_pointerlevel_and_size\n{\npublic:\n    type_test_member_pointerlevel_and_size func1(type_test_member_pointerlevel_and_size param);\n    long long i;\n    long j;\n    double k;\n    type_test_member_pointerlevel_and_size* p;\n};");
 
4713
    @Sources_v1 = (@Sources_v1, "type_test_member_pointerlevel_and_size type_test_member_pointerlevel_and_size::func1(type_test_member_pointerlevel_and_size param)\n{\n    return param;\n}");
 
4714
    
 
4715
    @DataDefs_v2 = (@DataDefs_v2, "struct type_test_member_pointerlevel_and_size\n{\npublic:\n    type_test_member_pointerlevel_and_size func1(type_test_member_pointerlevel_and_size param);\n    long long *i;\n    long j;\n    double k;\n    type_test_member_pointerlevel_and_size* p;\n};");
 
4716
    @Sources_v2 = (@Sources_v2, "type_test_member_pointerlevel_and_size type_test_member_pointerlevel_and_size::func1(type_test_member_pointerlevel_and_size param)\n{\n    return param;\n}");
 
4717
    
 
4718
    #Member_PointerLevel
 
4719
    @DataDefs_v1 = (@DataDefs_v1, "struct type_test_member_pointerlevel\n{\npublic:\n    type_test_member_pointerlevel func1(type_test_member_pointerlevel param);\n    int **i;\n    long j;\n    double k;\n    type_test_member_pointerlevel* p;\n};");
 
4720
    @Sources_v1 = (@Sources_v1, "type_test_member_pointerlevel type_test_member_pointerlevel::func1(type_test_member_pointerlevel param)\n{\n    return param;\n}");
 
4721
    
 
4722
    @DataDefs_v2 = (@DataDefs_v2, "struct type_test_member_pointerlevel\n{\npublic:\n    type_test_member_pointerlevel func1(type_test_member_pointerlevel param);\n    int *i;\n    long j;\n    double k;\n    type_test_member_pointerlevel* p;\n};");
 
4723
    @Sources_v2 = (@Sources_v2, "type_test_member_pointerlevel type_test_member_pointerlevel::func1(type_test_member_pointerlevel param)\n{\n    return param;\n}");
 
4724
    
 
4725
    #Added_Interface (function)
 
4726
    @DataDefs_v1 = (@DataDefs_v1, "struct type_test_added_interface\n{\npublic:\n    type_test_added_interface func1(type_test_added_interface param);\n    int i;\n    long j;\n    double k;\n    type_test_added_interface* p;\n};");
 
4727
    @Sources_v1 = (@Sources_v1, "type_test_added_interface type_test_added_interface::func1(type_test_added_interface param)\n{\n    return param;\n}");
 
4728
    
 
4729
    @DataDefs_v2 = (@DataDefs_v2, "struct type_test_added_interface\n{\npublic:\n    type_test_added_interface func1(type_test_added_interface param);\n    type_test_added_interface added_func(type_test_added_interface param);\n    int i;\n    long j;\n    double k;\n    type_test_added_interface* p;\n};");
 
4730
    @DataDefs_v2 = (@DataDefs_v2, "int added_func_2(void *** param);");
 
4731
    @Sources_v2 = (@Sources_v2, "type_test_added_interface type_test_added_interface::func1(type_test_added_interface param)\n{\n    return param;\n}");
 
4732
    @Sources_v2 = (@Sources_v2, "type_test_added_interface type_test_added_interface::added_func(type_test_added_interface param)\n{\n    return param;\n}");
 
4733
    @Sources_v2 = (@Sources_v2, "int added_func_2(void *** param)\n{\n    return 0;\n}");
 
4734
    
 
4735
    #Added_Interface (global variable)
 
4736
    @DataDefs_v1 = (@DataDefs_v1, "struct type_test_added_variable\n{\npublic:\n    int func1(type_test_added_variable param);\n    int i;\n    long j;\n    double k;\n    type_test_added_variable* p;\n};");
 
4737
    @Sources_v1 = (@Sources_v1, "int type_test_added_variable::func1(type_test_added_variable param)\n{\n    return i;\n}");
 
4738
    
 
4739
    @DataDefs_v2 = (@DataDefs_v2, "struct type_test_added_variable\n{\npublic:\n    int func1(type_test_added_variable param);\n    static int i;\n    long j;\n    double k;\n    type_test_added_variable* p;\n};");
 
4740
    @Sources_v2 = (@Sources_v2, "int type_test_added_variable::func1(type_test_added_variable param)\n{\n    return type_test_added_variable::i;\n}");
 
4741
    @Sources_v2 = (@Sources_v2, "int type_test_added_variable::i=0;");
 
4742
    
 
4743
    #Withdrawn_Interface
 
4744
    @DataDefs_v1 = (@DataDefs_v1, "struct type_test_withdrawn_interface\n{\npublic:\n    type_test_withdrawn_interface func1(type_test_withdrawn_interface param);\n    type_test_withdrawn_interface withdrawn_func(type_test_withdrawn_interface param);\n    int i;\n    long j;\n    double k;\n    type_test_withdrawn_interface* p;\n};");
 
4745
    @DataDefs_v1 = (@DataDefs_v1, "int withdrawn_func_2(void *** param);");
 
4746
    @Sources_v1 = (@Sources_v1, "type_test_withdrawn_interface type_test_withdrawn_interface::func1(type_test_withdrawn_interface param)\n{\n    return param;\n}");
 
4747
    @Sources_v1 = (@Sources_v1, "type_test_withdrawn_interface type_test_withdrawn_interface::withdrawn_func(type_test_withdrawn_interface param)\n{\n    return param;\n}");
 
4748
    @Sources_v1 = (@Sources_v1, "int withdrawn_func_2(void *** param)\n{\n    return 0;\n}");
 
4749
    
 
4750
    @DataDefs_v2 = (@DataDefs_v2, "struct type_test_withdrawn_interface\n{\npublic:\n    type_test_withdrawn_interface func1(type_test_withdrawn_interface param);\n    int i;\n    long j;\n    double k;\n    type_test_withdrawn_interface* p;\n};");
 
4751
    @Sources_v2 = (@Sources_v2, "type_test_withdrawn_interface type_test_withdrawn_interface::func1(type_test_withdrawn_interface param)\n{\n    return param;\n}");
 
4752
    
 
4753
    #Function_Become_Static
 
4754
    @DataDefs_v1 = (@DataDefs_v1, "struct type_test_become_static\n{\npublic:\n    type_test_become_static func_become_static(type_test_become_static param);\n    int **i;\n    long j;\n    double k;\n    type_test_become_static* p;\n};");
 
4755
    @Sources_v1 = (@Sources_v1, "type_test_become_static type_test_become_static::func_become_static(type_test_become_static param)\n{\n    return param;\n}");
 
4756
    
 
4757
    @DataDefs_v2 = (@DataDefs_v2, "struct type_test_become_static\n{\npublic:\n    static type_test_become_static func_become_static(type_test_become_static param);\n    int **i;\n    long j;\n    double k;\n    type_test_become_static* p;\n};");
 
4758
    @Sources_v2 = (@Sources_v2, "type_test_become_static type_test_become_static::func_become_static(type_test_become_static param)\n{\n    return param;\n}");
 
4759
    
 
4760
    #Function_Become_NonStatic
 
4761
    @DataDefs_v1 = (@DataDefs_v1, "struct type_test_become_nonstatic\n{\npublic:\n    static type_test_become_nonstatic func_become_nonstatic(type_test_become_nonstatic param);\n    int **i;\n    long j;\n    double k;\n    type_test_become_nonstatic* p;\n};");
 
4762
    @Sources_v1 = (@Sources_v1, "type_test_become_nonstatic type_test_become_nonstatic::func_become_nonstatic(type_test_become_nonstatic param)\n{\n    return param;\n}");
 
4763
    
 
4764
    @DataDefs_v2 = (@DataDefs_v2, "struct type_test_become_nonstatic\n{\npublic:\n    type_test_become_nonstatic func_become_nonstatic(type_test_become_nonstatic param);\n    int **i;\n    long j;\n    double k;\n    type_test_become_nonstatic* p;\n};");
 
4765
    @Sources_v2 = (@Sources_v2, "type_test_become_nonstatic type_test_become_nonstatic::func_become_nonstatic(type_test_become_nonstatic param)\n{\n    return param;\n}");
 
4766
    
 
4767
    #Parameter_Type_And_Size
 
4768
    @DataDefs_v1 = (@DataDefs_v1, "int func_parameter_type_and_size(int param, int other_param);");
 
4769
    @Sources_v1 = (@Sources_v1, "int func_parameter_type_and_size(int param, int other_param)\n{\n    return other_param;\n}");
 
4770
    
 
4771
    @DataDefs_v2 = (@DataDefs_v2, "int func_parameter_type_and_size(long long param, int other_param);");
 
4772
    @Sources_v2 = (@Sources_v2, "int func_parameter_type_and_size(long long param, int other_param)\n{\n    return other_param;\n}");
 
4773
    
 
4774
    #Parameter_Type
 
4775
    @DataDefs_v1 = (@DataDefs_v1, "int func_parameter_type(int param, int other_param);");
 
4776
    @Sources_v1 = (@Sources_v1, "int func_parameter_type(int param, int other_param)\n{\n    return other_param;\n}");
 
4777
    
 
4778
    @DataDefs_v2 = (@DataDefs_v2, "int func_parameter_type(float param, int other_param);");
 
4779
    @Sources_v2 = (@Sources_v2, "int func_parameter_type(float param, int other_param)\n{\n    return other_param;\n}");
 
4780
    
 
4781
    #Parameter_BaseType
 
4782
    @DataDefs_v1 = (@DataDefs_v1, "int func_parameter_basetypechange(int *param);");
 
4783
    @Sources_v1 = (@Sources_v1, "int func_parameter_basetypechange(int *param)\n{\n    return sizeof(*param);\n}");
 
4784
    
 
4785
    @DataDefs_v2 = (@DataDefs_v2, "int func_parameter_basetypechange(long long *param);");
 
4786
    @Sources_v2 = (@Sources_v2, "int func_parameter_basetypechange(long long *param)\n{\n    return sizeof(*param);\n}");
 
4787
    
 
4788
    #Parameter_PointerLevel_And_Size
 
4789
    @DataDefs_v1 = (@DataDefs_v1, "long long func_parameter_pointerlevel_and_size(long long param);");
 
4790
    @Sources_v1 = (@Sources_v1, "long long func_parameter_pointerlevel_and_size(long long param)\n{\n    return param;\n}");
 
4791
    
 
4792
    @DataDefs_v2 = (@DataDefs_v2, "long long func_parameter_pointerlevel_and_size(long long *param);");
 
4793
    @Sources_v2 = (@Sources_v2, "long long func_parameter_pointerlevel_and_size(long long *param)\n{\n    return param[5];\n}");
 
4794
    
 
4795
    #Parameter_PointerLevel
 
4796
    @DataDefs_v1 = (@DataDefs_v1, "int func_parameter_pointerlevel(int *param);");
 
4797
    @Sources_v1 = (@Sources_v1, "int func_parameter_pointerlevel(int *param)\n{\n    return param[5];\n}");
 
4798
    
 
4799
    @DataDefs_v2 = (@DataDefs_v2, "int func_parameter_pointerlevel(int **param);");
 
4800
    @Sources_v2 = (@Sources_v2, "int func_parameter_pointerlevel(int **param)\n{\n    return param[5][5];\n}");
 
4801
    
 
4802
    #Return_Type_And_Size
 
4803
    @DataDefs_v1 = (@DataDefs_v1, "int func_return_type_and_size(int param);");
 
4804
    @Sources_v1 = (@Sources_v1, "int func_return_type_and_size(int param)\n{\n    return 2^(sizeof(int)*8-1)-1;\n}");
 
4805
    
 
4806
    @DataDefs_v2 = (@DataDefs_v2, "long long func_return_type_and_size(int param);");
 
4807
    @Sources_v2 = (@Sources_v2, "long long func_return_type_and_size(int param)\n{\n    return 2^(sizeof(long long)*8-1)-1;\n}");
 
4808
    
 
4809
    #Return_Type
 
4810
    @DataDefs_v1 = (@DataDefs_v1, "int func_return_type(int param);");
 
4811
    @Sources_v1 = (@Sources_v1, "int func_return_type(int param)\n{\n    return 2^(sizeof(int)*8-1)-1;\n}");
 
4812
    
 
4813
    @DataDefs_v2 = (@DataDefs_v2, "float func_return_type(int param);");
 
4814
    @Sources_v2 = (@Sources_v2, "float func_return_type(int param)\n{\n    return 0.7;\n}");
 
4815
    
 
4816
    #Return_BaseType
 
4817
    @DataDefs_v1 = (@DataDefs_v1, "int *func_return_basetype(int param);");
 
4818
    @Sources_v1 = (@Sources_v1, "int *func_return_basetype(int param)\n{\n    int *x = new int[10];\n    return x;\n}");
 
4819
    
 
4820
    @DataDefs_v2 = (@DataDefs_v2, "long long *func_return_basetype(int param);");
 
4821
    @Sources_v2 = (@Sources_v2, "long long *func_return_basetype(int param)\n{\n    long long *x = new long long[10];\n    return x;\n}");
 
4822
    
 
4823
    #Return_PointerLevel_And_Size
 
4824
    @DataDefs_v1 = (@DataDefs_v1, "long long func_return_pointerlevel_and_size(int param);");
 
4825
    @Sources_v1 = (@Sources_v1, "long long func_return_pointerlevel_and_size(int param)\n{\n    return 100;\n}");
 
4826
    
 
4827
    @DataDefs_v2 = (@DataDefs_v2, "long long *func_return_pointerlevel_and_size(int param);");
 
4828
    @Sources_v2 = (@Sources_v2, "long long *func_return_pointerlevel_and_size(int param)\n{\n    long long* x = new long long[10];\n    return x;\n}");
 
4829
    
 
4830
    #Return_PointerLevel
 
4831
    @DataDefs_v1 = (@DataDefs_v1, "int* func_return_pointerlevel(int param);");
 
4832
    @Sources_v1 = (@Sources_v1, "int* func_return_pointerlevel(int param)\n{\n    int* x = new int[10];\n    return x;\n}");
 
4833
    
 
4834
    @DataDefs_v2 = (@DataDefs_v2, "int **func_return_pointerlevel(int param);");
 
4835
    @Sources_v2 = (@Sources_v2, "int **func_return_pointerlevel(int param)\n{\n    int** x = new int*[10];\n    return x;\n}");
 
4836
    
 
4837
    #typedef to anon struct
 
4838
    @DataDefs_v1 = (@DataDefs_v1, "
 
4839
typedef struct
 
4840
{
 
4841
public:
 
4842
    int i;
 
4843
    long j;
 
4844
    double k;
 
4845
} type_test_anon_typedef;
 
4846
int func_test_anon_typedef(type_test_anon_typedef param);");
 
4847
    @Sources_v1 = (@Sources_v1, "int func_test_anon_typedef(type_test_anon_typedef param)\n{\n    return 0;\n}");
 
4848
    
 
4849
    @DataDefs_v2 = (@DataDefs_v2, "
 
4850
typedef struct
 
4851
{
 
4852
public:
 
4853
    int i;
 
4854
    long j;
 
4855
    double k;
 
4856
    union {
 
4857
        int dummy[256];
 
4858
        struct {
 
4859
            char q_skiptable[256];
 
4860
            const char *p;
 
4861
            int l;
 
4862
        } p;
 
4863
    };
 
4864
} type_test_anon_typedef;
 
4865
int func_test_anon_typedef(type_test_anon_typedef param);");
 
4866
    @Sources_v2 = (@Sources_v2, "int func_test_anon_typedef(type_test_anon_typedef param)\n{\n    return 0;\n}");
 
4867
    
 
4868
    #opaque type
 
4869
    @DataDefs_v1 = (@DataDefs_v1, "struct type_test_opaque\n{\npublic:\n    virtual type_test_opaque func1(type_test_opaque param);\n    int i;\n    long j;\n    double k;\n    type_test_opaque* p;\n};");
 
4870
    @Sources_v1 = (@Sources_v1, "type_test_opaque type_test_opaque::func1(type_test_opaque param)\n{\n    return param;\n}");
 
4871
    
 
4872
    @DataDefs_v2 = (@DataDefs_v2, "struct type_test_opaque\n{\npublic:\n    virtual type_test_opaque func1(type_test_opaque param);\n    int i;\n    long j;\n    double k;\n    type_test_opaque* p;\n    int added_member;\n};");
 
4873
    @Sources_v2 = (@Sources_v2, "type_test_opaque type_test_opaque::func1(type_test_opaque param)\n{\n    return param;\n}");
 
4874
    
 
4875
    #internal function
 
4876
    @DataDefs_v1 = (@DataDefs_v1, "struct type_test_internal\n{\npublic:\n    virtual type_test_internal func1(type_test_internal param);\n    int i;\n    long j;\n    double k;\n    type_test_internal* p;\n};");
 
4877
    @Sources_v1 = (@Sources_v1, "type_test_internal type_test_internal::func1(type_test_internal param)\n{\n    return param;\n}");
 
4878
    
 
4879
    @DataDefs_v2 = (@DataDefs_v2, "struct type_test_internal\n{\npublic:\n    virtual type_test_internal func1(type_test_internal param);\n    int i;\n    long j;\n    double k;\n    type_test_internal* p;\n    int added_member;\n};");
 
4880
    @Sources_v2 = (@Sources_v2, "type_test_internal type_test_internal::func1(type_test_internal param)\n{\n    return param;\n}");
 
4881
    
 
4882
    #starting versioning
 
4883
    @DataDefs_v1 = (@DataDefs_v1, "int func_return_type_and_start_versioning(int param);");
 
4884
    @Sources_v1 = (@Sources_v1, "int func_return_type_and_start_versioning(int param)\n{\n    return 2^(sizeof(int)*8-1)-1;\n}");
 
4885
    
 
4886
    @DataDefs_v2 = (@DataDefs_v2, "int func_return_type_and_start_versioning(int param);");
 
4887
    @Sources_v2 = (@Sources_v2, "int func_return_type_and_start_versioning(int param)\n{\n    return 2^(sizeof(int)*8-1)-1;\n}\n__asm__(\".symver _Z37func_return_type_and_start_versioningi,_Z37func_return_type_and_start_versioningi\@TEST_2.0\");");
 
4888
    
 
4889
    #Return_Type And Good Versioning
 
4890
    @DataDefs_v1 = (@DataDefs_v1, "int func_return_type_and_good_versioning(int param);");
 
4891
    @Sources_v1 = (@Sources_v1, "int func_return_type_and_good_versioning(int param)\n{\n    return 2^(sizeof(int)*8-1)-1;\n}\n__asm__(\".symver _Z36func_return_type_and_good_versioningi,_Z36func_return_type_and_good_versioningi\@TEST_1.0\");");
 
4892
    
 
4893
    @DataDefs_v2 = (@DataDefs_v2, "int func_return_type_and_good_versioning_old(int param);");
 
4894
    @Sources_v2 = (@Sources_v2, "int func_return_type_and_good_versioning_old(int param)\n{\n    return 2^(sizeof(int)*8-1)-1;\n}\n__asm__(\".symver _Z40func_return_type_and_good_versioning_oldi,_Z36func_return_type_and_good_versioningi\@TEST_1.0\");");
 
4895
    
 
4896
    @DataDefs_v2 = (@DataDefs_v2, "float func_return_type_and_good_versioning(int param);");
 
4897
    @Sources_v2 = (@Sources_v2, "float func_return_type_and_good_versioning(int param)\n{\n    return 0.7;\n}\n__asm__(\".symver _Z36func_return_type_and_good_versioningi,_Z36func_return_type_and_good_versioningi\@TEST_2.0\");");
 
4898
    
 
4899
    #Return_Type and bad versioning
 
4900
    @DataDefs_v1 = (@DataDefs_v1, "int func_return_type_and_bad_versioning(int param);");
 
4901
    @Sources_v1 = (@Sources_v1, "int func_return_type_and_bad_versioning(int param)\n{\n    return 2^(sizeof(int)*8-1)-1;\n}\n__asm__(\".symver _Z35func_return_type_and_bad_versioningi,_Z35func_return_type_and_bad_versioningi\@TEST_1.0\");");
 
4902
    
 
4903
    @DataDefs_v2 = (@DataDefs_v2, "float func_return_type_and_bad_versioning_old(int param);");
 
4904
    @Sources_v2 = (@Sources_v2, "float func_return_type_and_bad_versioning_old(int param)\n{\n    return 0.7;\n}\n__asm__(\".symver _Z39func_return_type_and_bad_versioning_oldi,_Z35func_return_type_and_bad_versioningi\@TEST_1.0\");");
 
4905
    
 
4906
    @DataDefs_v2 = (@DataDefs_v2, "float func_return_type_and_bad_versioning(int param);");
 
4907
    @Sources_v2 = (@Sources_v2, "float func_return_type_and_bad_versioning(int param)\n{\n    return 0.7;\n}\n__asm__(\".symver _Z35func_return_type_and_bad_versioningi,_Z35func_return_type_and_bad_versioningi\@TEST_2.0\");");
 
4908
    
 
4909
    #unnamed struct fields within structs
 
4910
    @DataDefs_v1 = (@DataDefs_v1, "
 
4911
typedef struct {
 
4912
  int a;
 
4913
  struct {
 
4914
    int b;
 
4915
    float c;
 
4916
  };
 
4917
  int d;
 
4918
} type_test_unnamed;
 
4919
int func_test_unnamed(type_test_unnamed param);");
 
4920
    @Sources_v1 = (@Sources_v1, "int func_test_unnamed(type_test_unnamed param)\n{\n    return 0;\n}");
 
4921
    
 
4922
    @DataDefs_v2 = (@DataDefs_v2, "
 
4923
typedef struct {
 
4924
  int a;
 
4925
  struct {
 
4926
    long double b;
 
4927
    float c;
 
4928
  };
 
4929
  int d;
 
4930
} type_test_unnamed;
 
4931
int func_test_unnamed(type_test_unnamed param);");
 
4932
    @Sources_v2 = (@Sources_v2, "int func_test_unnamed(type_test_unnamed param)\n{\n    return 0;\n}");
 
4933
    
 
4934
    #constants
 
4935
    @DataDefs_v1 = (@DataDefs_v1, "#define TEST_PUBLIC_CONSTANT \"old_value\"");
 
4936
    @DataDefs_v2 = (@DataDefs_v2, "#define TEST_PUBLIC_CONSTANT \"new_value\"");
 
4937
    
 
4938
    @DataDefs_v1 = (@DataDefs_v1, "#define TEST_PRIVATE_CONSTANT \"old_value\"\n#undef TEST_PRIVATE_CONSTANT");
 
4939
    @DataDefs_v2 = (@DataDefs_v2, "#define TEST_PRIVATE_CONSTANT \"new_value\"\n#undef TEST_PRIVATE_CONSTANT");
 
4940
    
 
4941
    #unions
 
4942
    @DataDefs_v1 = (@DataDefs_v1, "
 
4943
union type_test_union {
 
4944
  int a;
 
4945
  struct {
 
4946
    int b;
 
4947
    float c;
 
4948
  };
 
4949
  int d;
 
4950
};
 
4951
int func_test_union(type_test_union param);");
 
4952
    @Sources_v1 = (@Sources_v1, "int func_test_union(type_test_union param)\n{\n    return 0;\n}");
 
4953
    
 
4954
    @DataDefs_v2 = (@DataDefs_v2, "
 
4955
union type_test_union {
 
4956
  int a;
 
4957
  long double new_member;
 
4958
  struct {
 
4959
    int b;
 
4960
    float c;
 
4961
  };
 
4962
  int d;
 
4963
};
 
4964
int func_test_union(type_test_union param);");
 
4965
    @Sources_v2 = (@Sources_v2, "int func_test_union(type_test_union param)\n{\n    return 0;\n}");
 
4966
    
 
4967
    #typedefs
 
4968
    @DataDefs_v1 = (@DataDefs_v1, "typedef float TYPEDEF_TYPE;\nint func_parameter_typedef_change(TYPEDEF_TYPE param);");
 
4969
    @Sources_v1 = (@Sources_v1, "int func_parameter_typedef_change(TYPEDEF_TYPE param)\n{\n    return 1;\n}");
 
4970
    
 
4971
    @DataDefs_v2 = (@DataDefs_v2, "typedef int TYPEDEF_TYPE;\nint func_parameter_typedef_change(TYPEDEF_TYPE param);");
 
4972
    @Sources_v2 = (@Sources_v2, "int func_parameter_typedef_change(TYPEDEF_TYPE param)\n{\n    return 1;\n}");
 
4973
    
 
4974
    #typedefs in member type
 
4975
    @DataDefs_v1 = (@DataDefs_v1, "typedef float TYPEDEF_TYPE_2;\nstruct type_test_member_typedef_change{\n    public:\nTYPEDEF_TYPE_2 m;};\nint func_test_member_typedef_change(type_test_member_typedef_change param);");
 
4976
    @Sources_v1 = (@Sources_v1, "int func_test_member_typedef_change(type_test_member_typedef_change param)\n{\n    return 1;\n}");
 
4977
    
 
4978
    @DataDefs_v2 = (@DataDefs_v2, "typedef int TYPEDEF_TYPE_2;\nstruct type_test_member_typedef_change{\n    public:\nTYPEDEF_TYPE_2 m;};\nint func_test_member_typedef_change(type_test_member_typedef_change param);");
 
4979
    @Sources_v2 = (@Sources_v2, "int func_test_member_typedef_change(type_test_member_typedef_change param)\n{\n    return 1;\n}");
 
4980
    
 
4981
    create_TestSuite("abi_changes_test_cpp", "C++", join("\n\n", @DataDefs_v1), join("\n\n", @Sources_v1), join("\n\n", @DataDefs_v2), join("\n\n", @Sources_v2), "type_test_opaque", "_ZN18type_test_internal5func1ES_");
 
4982
}
 
4983
 
 
4984
sub testSystem_c()
 
4985
{
 
4986
    print "\ntesting for C library changes\n";
 
4987
    my (@DataDefs_v1, @Sources_v1, @DataDefs_v2, @Sources_v2) = ();
 
4988
    
 
4989
    #Withdrawn_Parameter
 
4990
    @DataDefs_v1 = (@DataDefs_v1, "int func_withdrawn_parameter(int param, int withdrawn_param);");
 
4991
    @Sources_v1 = (@Sources_v1, "int func_withdrawn_parameter(int param, int withdrawn_param)\n{\n    return 0;\n}");
 
4992
    
 
4993
    @DataDefs_v2 = (@DataDefs_v2, "int func_withdrawn_parameter(int param);");
 
4994
    @Sources_v2 = (@Sources_v2, "int func_withdrawn_parameter(int param)\n{\n    return 0;\n}");
 
4995
    
 
4996
    #Added_Parameter
 
4997
    @DataDefs_v1 = (@DataDefs_v1, "int func_added_parameter(int param);");
 
4998
    @Sources_v1 = (@Sources_v1, "int func_added_parameter(int param)\n{\n    return 0;\n}");
 
4999
    
 
5000
    @DataDefs_v2 = (@DataDefs_v2, "int func_added_parameter(int param, int added_param);");
 
5001
    @Sources_v2 = (@Sources_v2, "int func_added_parameter(int param, int added_param)\n{\n    return 0;\n}");
 
5002
    
 
5003
    #added function with typedef funcptr parameter
 
5004
    @DataDefs_v2 = (@DataDefs_v2, "typedef int (*FUNCPTR_TYPE)(int a, int b);\nint added_function_param_typedef_funcptr(FUNCPTR_TYPE*const** f);");
 
5005
    @Sources_v2 = (@Sources_v2, "int added_function_param_typedef_funcptr(FUNCPTR_TYPE*const** f)\n{\n    return 0;\n}");
 
5006
    
 
5007
    #added function with funcptr parameter
 
5008
    @DataDefs_v2 = (@DataDefs_v2, "int added_function_param_funcptr(int(*func)(int, int));");
 
5009
    @Sources_v2 = (@Sources_v2, "int added_function_param_funcptr(int(*func)(int, int))\n{\n    return 0;\n}");
 
5010
    
 
5011
    #added function with no limited parameters
 
5012
    @DataDefs_v2 = (@DataDefs_v2, "int added_function_nolimit_param(float p1, ...);");
 
5013
    @Sources_v2 = (@Sources_v2, "int added_function_nolimit_param(float p1, ...)\n{\n    return 0;\n}");
 
5014
    
 
5015
    #size change
 
5016
    @DataDefs_v1 = (@DataDefs_v1, "struct type_test_size\n{\n    long long i[5];\n    long j;\n    double k;\n    struct type_test_size* p;\n};");
 
5017
    @DataDefs_v1 = (@DataDefs_v1, "int func_test_type_size(struct type_test_size param, int param_2);");
 
5018
    @Sources_v1 = (@Sources_v1, "int func_test_type_size(struct type_test_size param, int param_2)\n{\n    return param_2;\n}");
 
5019
    
 
5020
    @DataDefs_v2 = (@DataDefs_v2, "struct type_test_size\n{\n    long long i[5];\n    long long j;\n    double k;\n    struct type_test_size* p;\n};");
 
5021
    @DataDefs_v2 = (@DataDefs_v2, "int func_test_type_size(struct type_test_size param, int param_2);");
 
5022
    @Sources_v2 = (@Sources_v2, "int func_test_type_size(struct type_test_size param, int param_2)\n{\n    return param_2;\n}");
 
5023
    
 
5024
    #Added_Member_And_Size
 
5025
    @DataDefs_v1 = (@DataDefs_v1, "struct type_test_added_member\n{\n    int i;\n    long j;\n    double k;\n    struct type_test_added_member* p;\n};");
 
5026
    @DataDefs_v1 = (@DataDefs_v1, "int func_test_added_member(struct type_test_added_member param, int param_2);");
 
5027
    @Sources_v1 = (@Sources_v1, "int func_test_added_member(struct type_test_added_member param, int param_2)\n{\n    return param_2;\n}");
 
5028
    
 
5029
    @DataDefs_v2 = (@DataDefs_v2, "struct type_test_added_member\n{\n    int i;\n    long j;\n    double k;\n    struct type_test_added_member* p;\n    int added_member;\n};");
 
5030
    @DataDefs_v2 = (@DataDefs_v2, "int func_test_added_member(struct type_test_added_member param, int param_2);");
 
5031
    @Sources_v2 = (@Sources_v2, "int func_test_added_member(struct type_test_added_member param, int param_2)\n{\n    return param_2;\n}");
 
5032
    
 
5033
    #Added_Middle_Member_And_Size
 
5034
    @DataDefs_v1 = (@DataDefs_v1, "struct type_test_added_middle_member\n{\n    int i;\n    long j;\n    double k;\n    struct type_test_added_member* p;\n};");
 
5035
    @DataDefs_v1 = (@DataDefs_v1, "int func_test_added_middle_member(struct type_test_added_middle_member param, int param_2);");
 
5036
    @Sources_v1 = (@Sources_v1, "int func_test_added_middle_member(struct type_test_added_middle_member param, int param_2)\n{\n    return param_2;\n}");
 
5037
    
 
5038
    @DataDefs_v2 = (@DataDefs_v2, "struct type_test_added_middle_member\n{\n    int i;\n    int added_middle_member;\n    long j;\n    double k;\n    struct type_test_added_member* p;\n};");
 
5039
    @DataDefs_v2 = (@DataDefs_v2, "int func_test_added_middle_member(struct type_test_added_middle_member param, int param_2);");
 
5040
    @Sources_v2 = (@Sources_v2, "int func_test_added_middle_member(struct type_test_added_middle_member param, int param_2)\n{\n    return param_2;\n}");
 
5041
    
 
5042
    #Member_Rename
 
5043
    @DataDefs_v1 = (@DataDefs_v1, "struct type_test_member_rename\n{\n    long i;\n    long j;\n    double k;\n    struct type_test_member_rename* p;\n};");
 
5044
    @DataDefs_v1 = (@DataDefs_v1, "int func_test_member_rename(struct type_test_member_rename param, int param_2);");
 
5045
    @Sources_v1 = (@Sources_v1, "int func_test_member_rename(struct type_test_member_rename param, int param_2)\n{\n    return param_2;\n}");
 
5046
    
 
5047
    @DataDefs_v2 = (@DataDefs_v2, "struct type_test_member_rename\n{\n    long renamed_member;\n    long j;\n    double k;\n    struct type_test_member_rename* p;\n};");
 
5048
    @DataDefs_v2 = (@DataDefs_v2, "int func_test_member_rename(struct type_test_member_rename param, int param_2);");
 
5049
    @Sources_v2 = (@Sources_v2, "int func_test_member_rename(struct type_test_member_rename param, int param_2)\n{\n    return param_2;\n}");
 
5050
    
 
5051
    #Withdrawn_Member_And_Size
 
5052
    @DataDefs_v1 = (@DataDefs_v1, "struct type_test_withdrawn_member\n{\n    int i;\n    long j;\n    double k;\n    struct type_test_withdrawn_member* p;\n    int withdrawn_member;\n};");
 
5053
    @DataDefs_v1 = (@DataDefs_v1, "int func_test_withdrawn_member(struct type_test_withdrawn_member param, int param_2);");
 
5054
    @Sources_v1 = (@Sources_v1, "int func_test_withdrawn_member(struct type_test_withdrawn_member param, int param_2)\n{\n    return param_2;\n}");
 
5055
    
 
5056
    @DataDefs_v2 = (@DataDefs_v2, "struct type_test_withdrawn_member\n{\n    int i;\n    long j;\n    double k;\n    struct type_test_withdrawn_member* p;\n};");
 
5057
    @DataDefs_v2 = (@DataDefs_v2, "int func_test_withdrawn_member(struct type_test_withdrawn_member param, int param_2);");
 
5058
    @Sources_v2 = (@Sources_v2, "int func_test_withdrawn_member(struct type_test_withdrawn_member param, int param_2)\n{\n    return param_2;\n}");
 
5059
    
 
5060
    #Withdrawn_Middle_Member
 
5061
    @DataDefs_v1 = (@DataDefs_v1, "struct type_test_withdrawn_middle_member\n{\n    int i;\n    int withdrawn_middle_member;\n    long j;\n    double k;\n    struct type_test_withdrawn_middle_member* p;\n};");
 
5062
    @DataDefs_v1 = (@DataDefs_v1, "int func_test_withdrawn_middle_member(struct type_test_withdrawn_middle_member param, int param_2);");
 
5063
    @Sources_v1 = (@Sources_v1, "int func_test_withdrawn_middle_member(struct type_test_withdrawn_middle_member param, int param_2)\n{\n    return param_2;\n}");
 
5064
    
 
5065
    @DataDefs_v2 = (@DataDefs_v2, "struct type_test_withdrawn_middle_member\n{\n    int i;\n    long j;\n    double k;\n    struct type_test_withdrawn_middle_member* p;\n};");
 
5066
    @DataDefs_v2 = (@DataDefs_v2, "int func_test_withdrawn_middle_member(struct type_test_withdrawn_middle_member param, int param_2);");
 
5067
    @Sources_v2 = (@Sources_v2, "int func_test_withdrawn_middle_member(struct type_test_withdrawn_middle_member param, int param_2)\n{\n    return param_2;\n}");
 
5068
    
 
5069
    #Enum_Member_Value
 
5070
    @DataDefs_v1 = (@DataDefs_v1, "enum type_test_enum_member_value_change\n{\n    MEMBER_1=1,\n    MEMBER_2=2\n};");
 
5071
    @DataDefs_v1 = (@DataDefs_v1, "int func_test_enum_member_value_change(enum type_test_enum_member_value_change param);");
 
5072
    @Sources_v1 = (@Sources_v1,
 
5073
"int func_test_enum_member_value_change(enum type_test_enum_member_value_change param)
 
5074
{
 
5075
    switch(param)
 
5076
    {
 
5077
        case 1:
 
5078
            return 1;
 
5079
        case 2:
 
5080
            return 2;
 
5081
    }
 
5082
    return 0;
 
5083
}");
 
5084
    
 
5085
    @DataDefs_v2 = (@DataDefs_v2, "enum type_test_enum_member_value_change\n{\n    MEMBER_1=2,\n    MEMBER_2=1\n};");
 
5086
    @DataDefs_v2 = (@DataDefs_v2, "int func_test_enum_member_value_change(enum type_test_enum_member_value_change param);");
 
5087
    @Sources_v2 = (@Sources_v2,
 
5088
"int func_test_enum_member_value_change(enum type_test_enum_member_value_change param)
 
5089
{
 
5090
    switch(param)
 
5091
    {
 
5092
        case 1:
 
5093
            return 1;
 
5094
        case 2:
 
5095
            return 2;
 
5096
    }
 
5097
    return 0;
 
5098
}");
 
5099
    
 
5100
    #Enum_Member_Name
 
5101
    @DataDefs_v1 = (@DataDefs_v1, "enum type_test_enum_member_rename\n{\n    BRANCH_1=1,\n    BRANCH_2=2\n};");
 
5102
    @DataDefs_v1 = (@DataDefs_v1, "int func_test_enum_member_rename(enum type_test_enum_member_rename param);");
 
5103
    @Sources_v1 = (@Sources_v1,
 
5104
"int func_test_enum_member_rename(enum type_test_enum_member_rename param)
 
5105
{
 
5106
    switch(param)
 
5107
    {
 
5108
        case 1:
 
5109
            return 1;
 
5110
        case 2:
 
5111
            return 2;
 
5112
    }
 
5113
    return 0;
 
5114
}");
 
5115
    
 
5116
    @DataDefs_v2 = (@DataDefs_v2, "enum type_test_enum_member_rename\n{\n    BRANCH_FIRST=1,\n    BRANCH_SECOND=1\n};");
 
5117
    @DataDefs_v2 = (@DataDefs_v2, "int func_test_enum_member_rename(enum type_test_enum_member_rename param);");
 
5118
    @Sources_v2 = (@Sources_v2,
 
5119
"int func_test_enum_member_rename(enum type_test_enum_member_rename param)
 
5120
{
 
5121
    switch(param)
 
5122
    {
 
5123
        case 1:
 
5124
            return 1;
 
5125
        case 2:
 
5126
            return 2;
 
5127
    }
 
5128
    return 0;
 
5129
}");
 
5130
    
 
5131
    #Member_Type_And_Size
 
5132
    @DataDefs_v1 = (@DataDefs_v1, "struct type_test_member_type_and_size\n{\n    int i;\n    long j;\n    double k;\n    struct type_test_member_type_and_size* p;\n};");
 
5133
    @DataDefs_v1 = (@DataDefs_v1, "int func_test_member_type_and_size(struct type_test_member_type_and_size param, int param_2);");
 
5134
    @Sources_v1 = (@Sources_v1, "int func_test_member_type_and_size(struct type_test_member_type_and_size param, int param_2)\n{\n    return param_2;\n}");
 
5135
    
 
5136
    @DataDefs_v2 = (@DataDefs_v2, "struct type_test_member_type_and_size\n{\n    int i;\n    long j;\n    long double k;\n    struct type_test_member_type_and_size* p;\n};");
 
5137
    @DataDefs_v2 = (@DataDefs_v2, "int func_test_member_type_and_size(struct type_test_member_type_and_size param, int param_2);");
 
5138
    @Sources_v2 = (@Sources_v2, "int func_test_member_type_and_size(struct type_test_member_type_and_size param, int param_2)\n{\n    return param_2;\n}");
 
5139
    
 
5140
    #Member_Type
 
5141
    @DataDefs_v1 = (@DataDefs_v1, "struct type_test_member_type\n{\n    int i;\n    long j;\n    double k;\n    struct type_test_member_type* p;\n};");
 
5142
    @DataDefs_v1 = (@DataDefs_v1, "int func_test_member_type(struct type_test_member_type param, int param_2);");
 
5143
    @Sources_v1 = (@Sources_v1, "int func_test_member_type(struct type_test_member_type param, int param_2)\n{\n    return param_2;\n}");
 
5144
    
 
5145
    @DataDefs_v2 = (@DataDefs_v2, "struct type_test_member_type\n{\n    float i;\n    long j;\n    double k;\n    struct type_test_member_type* p;\n};");
 
5146
    @DataDefs_v2 = (@DataDefs_v2, "int func_test_member_type(struct type_test_member_type param, int param_2);");
 
5147
    @Sources_v2 = (@Sources_v2, "int func_test_member_type(struct type_test_member_type param, int param_2)\n{\n    return param_2;\n}");
 
5148
    
 
5149
    #Member_BaseType
 
5150
    @DataDefs_v1 = (@DataDefs_v1, "struct type_test_member_basetype\n{\n    int i;\n    long *j;\n    double k;\n    struct type_test_member_basetype* p;\n};");
 
5151
    @DataDefs_v1 = (@DataDefs_v1, "int func_test_member_basetype(struct type_test_member_basetype param, int param_2);");
 
5152
    @Sources_v1 = (@Sources_v1, "int func_test_member_basetype(struct type_test_member_basetype param, int param_2)\n{\n    return param_2;\n}");
 
5153
    
 
5154
    @DataDefs_v2 = (@DataDefs_v2, "struct type_test_member_basetype\n{\n    int i;\n    long long *j;\n    double k;\n    struct type_test_member_basetype* p;\n};");
 
5155
    @DataDefs_v2 = (@DataDefs_v2, "int func_test_member_basetype(struct type_test_member_basetype param, int param_2);");
 
5156
    @Sources_v2 = (@Sources_v2, "int func_test_member_basetype(struct type_test_member_basetype param, int param_2)\n{\n    return param_2;\n}");
 
5157
    
 
5158
    #Member_PointerLevel_And_Size
 
5159
    @DataDefs_v1 = (@DataDefs_v1, "struct type_test_member_pointerlevel_and_size\n{\n    int i;\n    long long j;\n    double k;\n    struct type_test_member_pointerlevel_and_size* p;\n};");
 
5160
    @DataDefs_v1 = (@DataDefs_v1, "int func_test_member_pointerlevel_and_size(struct type_test_member_pointerlevel_and_size param, int param_2);");
 
5161
    @Sources_v1 = (@Sources_v1, "int func_test_member_pointerlevel_and_size(struct type_test_member_pointerlevel_and_size param, int param_2)\n{\n    return param_2;\n}");
 
5162
    
 
5163
    @DataDefs_v2 = (@DataDefs_v2, "struct type_test_member_pointerlevel_and_size\n{\n    int i;\n    long long *j;\n    double k;\n    struct type_test_member_pointerlevel_and_size* p;\n};");
 
5164
    @DataDefs_v2 = (@DataDefs_v2, "int func_test_member_pointerlevel_and_size(struct type_test_member_pointerlevel_and_size param, int param_2);");
 
5165
    @Sources_v2 = (@Sources_v2, "int func_test_member_pointerlevel_and_size(struct type_test_member_pointerlevel_and_size param, int param_2)\n{\n    return param_2;\n}");
 
5166
    
 
5167
    #Member_PointerLevel
 
5168
    @DataDefs_v1 = (@DataDefs_v1, "struct type_test_member_pointerlevel\n{\n    int i;\n    long *j;\n    double k;\n    struct type_test_member_pointerlevel* p;\n};");
 
5169
    @DataDefs_v1 = (@DataDefs_v1, "int func_test_member_pointerlevel(struct type_test_member_pointerlevel param, int param_2);");
 
5170
    @Sources_v1 = (@Sources_v1, "int func_test_member_pointerlevel(struct type_test_member_pointerlevel param, int param_2)\n{\n    return param_2;\n}");
 
5171
    
 
5172
    @DataDefs_v2 = (@DataDefs_v2, "struct type_test_member_pointerlevel\n{\n    int i;\n    long **j;\n    double k;\n    struct type_test_member_pointerlevel* p;\n};");
 
5173
    @DataDefs_v2 = (@DataDefs_v2, "int func_test_member_pointerlevel(struct type_test_member_pointerlevel param, int param_2);");
 
5174
    @Sources_v2 = (@Sources_v2, "int func_test_member_pointerlevel(struct type_test_member_pointerlevel param, int param_2)\n{\n    return param_2;\n}");
 
5175
    
 
5176
    #Added_Interface
 
5177
    @DataDefs_v2 = (@DataDefs_v2, "int added_func(int param);");
 
5178
    @Sources_v2 = (@Sources_v2, "int added_func(int param)\n{\n    return param;\n}");
 
5179
    
 
5180
    #Withdrawn_Interface
 
5181
    @DataDefs_v1 = (@DataDefs_v1, "int withdrawn_func(int param);");
 
5182
    @Sources_v1 = (@Sources_v1, "int withdrawn_func(int param)\n{\n    return param;\n}");
 
5183
    
 
5184
    #Parameter_Type_And_Size
 
5185
    @DataDefs_v1 = (@DataDefs_v1, "int func_parameter_type_and_size(int param, int other_param);");
 
5186
    @Sources_v1 = (@Sources_v1, "int func_parameter_type_and_size(int param, int other_param)\n{\n    return other_param;\n}");
 
5187
    
 
5188
    @DataDefs_v2 = (@DataDefs_v2, "int func_parameter_type_and_size(long long param, int other_param);");
 
5189
    @Sources_v2 = (@Sources_v2, "int func_parameter_type_and_size(long long param, int other_param)\n{\n    return other_param;\n}");
 
5190
    
 
5191
    #Parameter_Type
 
5192
    @DataDefs_v1 = (@DataDefs_v1, "int func_parameter_type(int param, int other_param);");
 
5193
    @Sources_v1 = (@Sources_v1, "int func_parameter_type(int param, int other_param)\n{\n    return other_param;\n}");
 
5194
    
 
5195
    @DataDefs_v2 = (@DataDefs_v2, "int func_parameter_type(float param, int other_param);");
 
5196
    @Sources_v2 = (@Sources_v2, "int func_parameter_type(float param, int other_param)\n{\n    return other_param;\n}");
 
5197
    
 
5198
    #Parameter_BaseType (Typedef)
 
5199
    @DataDefs_v1 = (@DataDefs_v1, "typedef int* PARAM_TYPEDEF;\nint func_parameter_basetypechange_typedef(PARAM_TYPEDEF param);");
 
5200
    @Sources_v1 = (@Sources_v1, "int func_parameter_basetypechange_typedef(PARAM_TYPEDEF param)\n{\n    return 0;\n}");
 
5201
    
 
5202
    @DataDefs_v2 = (@DataDefs_v2, "typedef const int* PARAM_TYPEDEF;\nint func_parameter_basetypechange_typedef(PARAM_TYPEDEF param);");
 
5203
    @Sources_v2 = (@Sources_v2, "int func_parameter_basetypechange_typedef(PARAM_TYPEDEF param)\n{\n    return 0;\n}");
 
5204
    
 
5205
    #Parameter_BaseType
 
5206
    @DataDefs_v1 = (@DataDefs_v1, "int func_parameter_basetypechange(int *param);");
 
5207
    @Sources_v1 = (@Sources_v1, "int func_parameter_basetypechange(int *param)\n{\n    return sizeof(*param);\n}");
 
5208
    
 
5209
    @DataDefs_v2 = (@DataDefs_v2, "int func_parameter_basetypechange(long long *param);");
 
5210
    @Sources_v2 = (@Sources_v2, "int func_parameter_basetypechange(long long *param)\n{\n    return sizeof(*param);\n}");
 
5211
    
 
5212
    #Parameter_PointerLevel_And_Size
 
5213
    @DataDefs_v1 = (@DataDefs_v1, "long long func_parameter_pointerlevel_and_size(long long param);");
 
5214
    @Sources_v1 = (@Sources_v1, "long long func_parameter_pointerlevel_and_size(long long param)\n{\n    return param;\n}");
 
5215
    
 
5216
    @DataDefs_v2 = (@DataDefs_v2, "long long func_parameter_pointerlevel_and_size(long long *param);");
 
5217
    @Sources_v2 = (@Sources_v2, "long long func_parameter_pointerlevel_and_size(long long *param)\n{\n    return param[5];\n}");
 
5218
    
 
5219
    #Parameter_PointerLevel
 
5220
    @DataDefs_v1 = (@DataDefs_v1, "int func_parameter_pointerlevel(int *param);");
 
5221
    @Sources_v1 = (@Sources_v1, "int func_parameter_pointerlevel(int *param)\n{\n    return param[5];\n}");
 
5222
    
 
5223
    @DataDefs_v2 = (@DataDefs_v2, "int func_parameter_pointerlevel(int **param);");
 
5224
    @Sources_v2 = (@Sources_v2, "int func_parameter_pointerlevel(int **param)\n{\n    return param[5][5];\n}");
 
5225
    
 
5226
    #Return_Type_And_Size
 
5227
    @DataDefs_v1 = (@DataDefs_v1, "int func_return_type_and_size(int param);");
 
5228
    @Sources_v1 = (@Sources_v1, "int func_return_type_and_size(int param)\n{\n    return 2^(sizeof(int)*8-1)-1;\n}");
 
5229
    
 
5230
    @DataDefs_v2 = (@DataDefs_v2, "long long func_return_type_and_size(int param);");
 
5231
    @Sources_v2 = (@Sources_v2, "long long func_return_type_and_size(int param)\n{\n    return 2^(sizeof(long long)*8-1)-1;\n}");
 
5232
    
 
5233
    #Return_Type
 
5234
    @DataDefs_v1 = (@DataDefs_v1, "int func_return_type(int param);");
 
5235
    @Sources_v1 = (@Sources_v1, "int func_return_type(int param)\n{\n    return 2^(sizeof(int)*8-1)-1;\n}");
 
5236
    
 
5237
    @DataDefs_v2 = (@DataDefs_v2, "float func_return_type(int param);");
 
5238
    @Sources_v2 = (@Sources_v2, "float func_return_type(int param)\n{\n    return 0.7;\n}");
 
5239
    
 
5240
    #Return_BaseType
 
5241
    @DataDefs_v1 = (@DataDefs_v1, "int *func_return_basetypechange(int param);");
 
5242
    @Sources_v1 = (@Sources_v1, "int *func_return_basetypechange(int param)\n{\n    int *x = (int*)malloc(10*sizeof(int));\n    *x = 2^(sizeof(int)*8-1)-1;\n    return x;\n}");
 
5243
    
 
5244
    @DataDefs_v2 = (@DataDefs_v2, "long long *func_return_basetypechange(int param);");
 
5245
    @Sources_v2 = (@Sources_v2, "long long *func_return_basetypechange(int param)\n{\n    long long *x = (long long*)malloc(10*sizeof(long long));\n    *x = 2^(sizeof(long long)*8-1)-1;\n    return x;\n}");
 
5246
    
 
5247
    #Return_PointerLevel_And_Size
 
5248
    @DataDefs_v1 = (@DataDefs_v1, "long long func_return_pointerlevel_and_size(int param);");
 
5249
    @Sources_v1 = (@Sources_v1, "long long func_return_pointerlevel_and_size(int param)\n{\n    return 100;\n}");
 
5250
    
 
5251
    @DataDefs_v2 = (@DataDefs_v2, "long long *func_return_pointerlevel_and_size(int param);");
 
5252
    @Sources_v2 = (@Sources_v2, "long long *func_return_pointerlevel_and_size(int param)\n{\n    long long *x = (long long*)malloc(10*sizeof(long long));\n    *x = 2^(sizeof(long long)*8-1)-1;\n    return x;\n}");
 
5253
    
 
5254
    #Return_PointerLevel
 
5255
    @DataDefs_v1 = (@DataDefs_v1, "long long *func_return_pointerlevel(int param);");
 
5256
    @Sources_v1 = (@Sources_v1, "long long *func_return_pointerlevel(int param)\n{\n    long long *x = (long long*)malloc(10*sizeof(long long));\n    *x = 2^(sizeof(long long)*8-1)-1;\n    return x;\n}");
 
5257
    
 
5258
    @DataDefs_v2 = (@DataDefs_v2, "long long **func_return_pointerlevel(int param);");
 
5259
    @Sources_v2 = (@Sources_v2, "long long **func_return_pointerlevel(int param)\n{\n    long long *x = (long long*)malloc(10*sizeof(long long));\n    *x = 2^(sizeof(long long)*8-1)-1;\n    long *y = (long*)malloc(sizeof(long long));\n    *y=(long)&x;\n    return (long long **)y;\n}");
 
5260
    
 
5261
    #typedef to anon struct
 
5262
    @DataDefs_v1 = (@DataDefs_v1, "
 
5263
typedef struct
 
5264
{
 
5265
    int i;
 
5266
    long j;
 
5267
    double k;
 
5268
} type_test_anon_typedef;
 
5269
int func_test_anon_typedef(type_test_anon_typedef param);");
 
5270
    @Sources_v1 = (@Sources_v1, "int func_test_anon_typedef(type_test_anon_typedef param)\n{\n    return 0;\n}");
 
5271
    
 
5272
    @DataDefs_v2 = (@DataDefs_v2, "
 
5273
typedef struct
 
5274
{
 
5275
    int i;
 
5276
    long j;
 
5277
    double k;
 
5278
    union {
 
5279
        int dummy[256];
 
5280
        struct {
 
5281
            char q_skiptable[256];
 
5282
            const char *p;
 
5283
            int l;
 
5284
        } p;
 
5285
    };
 
5286
} type_test_anon_typedef;
 
5287
int func_test_anon_typedef(type_test_anon_typedef param);");
 
5288
    @Sources_v2 = (@Sources_v2, "int func_test_anon_typedef(type_test_anon_typedef param)\n{\n    return 0;\n}");
 
5289
    
 
5290
    #opaque type
 
5291
    @DataDefs_v1 = (@DataDefs_v1, "struct type_test_opaque\n{\n    long long i[5];\n    long j;\n    double k;\n    struct type_test_opaque* p;\n};");
 
5292
    @DataDefs_v1 = (@DataDefs_v1, "int func_test_opaque(struct type_test_opaque param, int param_2);");
 
5293
    @Sources_v1 = (@Sources_v1, "int func_test_opaque(struct type_test_opaque param, int param_2)\n{\n    return param_2;\n}");
 
5294
    
 
5295
    @DataDefs_v2 = (@DataDefs_v2, "struct type_test_opaque\n{\n    long long i[5];\n    long long j;\n    double k;\n    struct type_test_opaque* p;\n};");
 
5296
    @DataDefs_v2 = (@DataDefs_v2, "int func_test_opaque(struct type_test_opaque param, int param_2);");
 
5297
    @Sources_v2 = (@Sources_v2, "int func_test_opaque(struct type_test_opaque param, int param_2)\n{\n    return param_2;\n}");
 
5298
    
 
5299
    #internal function
 
5300
    @DataDefs_v1 = (@DataDefs_v1, "struct type_test_internal\n{\n    long long i[5];\n    long j;\n    double k;\n    struct type_test_internal* p;\n};");
 
5301
    @DataDefs_v1 = (@DataDefs_v1, "int func_test_internal(struct type_test_internal param, int param_2);");
 
5302
    @Sources_v1 = (@Sources_v1, "int func_test_internal(struct type_test_internal param, int param_2)\n{\n    return param_2;\n}");
 
5303
    
 
5304
    @DataDefs_v2 = (@DataDefs_v2, "struct type_test_internal\n{\n    long long i[5];\n    long long j;\n    double k;\n    struct type_test_internal* p;\n};");
 
5305
    @DataDefs_v2 = (@DataDefs_v2, "int func_test_internal(struct type_test_internal param, int param_2);");
 
5306
    @Sources_v2 = (@Sources_v2, "int func_test_internal(struct type_test_internal param, int param_2)\n{\n    return param_2;\n}");
 
5307
    
 
5308
    #starting versioning
 
5309
    @DataDefs_v1 = (@DataDefs_v1, "int func_return_type_and_start_versioning(int param);");
 
5310
    @Sources_v1 = (@Sources_v1, "int func_return_type_and_start_versioning(int param)\n{\n    return 2^(sizeof(int)*8-1)-1;\n}");
 
5311
    
 
5312
    @DataDefs_v2 = (@DataDefs_v2, "int func_return_type_and_start_versioning(int param);");
 
5313
    @Sources_v2 = (@Sources_v2, "int func_return_type_and_start_versioning(int param)\n{\n    return 2^(sizeof(int)*8-1)-1;\n}\n__asm__(\".symver func_return_type_and_start_versioning,func_return_type_and_start_versioning\@TEST_2.0\");");
 
5314
    
 
5315
    #Return_Type and good versioning
 
5316
    @DataDefs_v1 = (@DataDefs_v1, "int func_return_type_and_good_versioning(int param);");
 
5317
    @Sources_v1 = (@Sources_v1, "int func_return_type_and_good_versioning(int param)\n{\n    return 2^(sizeof(int)*8-1)-1;\n}\n__asm__(\".symver func_return_type_and_good_versioning,func_return_type_and_good_versioning\@TEST_1.0\");");
 
5318
    
 
5319
    @DataDefs_v2 = (@DataDefs_v2, "int func_return_type_and_good_versioning_old(int param);");
 
5320
    @Sources_v2 = (@Sources_v2, "int func_return_type_and_good_versioning_old(int param)\n{\n    return 2^(sizeof(int)*8-1)-1;\n}\n__asm__(\".symver func_return_type_and_good_versioning_old,func_return_type_and_good_versioning\@TEST_1.0\");");
 
5321
    
 
5322
    @DataDefs_v2 = (@DataDefs_v2, "float func_return_type_and_good_versioning(int param);");
 
5323
    @Sources_v2 = (@Sources_v2, "float func_return_type_and_good_versioning(int param)\n{\n    return 0.7;\n}\n__asm__(\".symver func_return_type_and_good_versioning,func_return_type_and_good_versioning\@TEST_2.0\");");
 
5324
    
 
5325
    #Return_Type and bad versioning
 
5326
    @DataDefs_v1 = (@DataDefs_v1, "int func_return_type_and_bad_versioning(int param);");
 
5327
    @Sources_v1 = (@Sources_v1, "int func_return_type_and_bad_versioning(int param)\n{\n    return 2^(sizeof(int)*8-1)-1;\n}\n__asm__(\".symver func_return_type_and_bad_versioning,func_return_type_and_bad_versioning\@TEST_1.0\");");
 
5328
    
 
5329
    @DataDefs_v2 = (@DataDefs_v2, "float func_return_type_and_bad_versioning_old(int param);");
 
5330
    @Sources_v2 = (@Sources_v2, "float func_return_type_and_bad_versioning_old(int param)\n{\n    return 0.7;\n}\n__asm__(\".symver func_return_type_and_bad_versioning_old,func_return_type_and_bad_versioning\@TEST_1.0\");");
 
5331
    
 
5332
    @DataDefs_v2 = (@DataDefs_v2, "float func_return_type_and_bad_versioning(int param);");
 
5333
    @Sources_v2 = (@Sources_v2, "float func_return_type_and_bad_versioning(int param)\n{\n    return 0.7;\n}\n__asm__(\".symver func_return_type_and_bad_versioning,func_return_type_and_bad_versioning\@TEST_2.0\");");
 
5334
    
 
5335
    #unnamed struct/union fields within structs/unions
 
5336
    @DataDefs_v1 = (@DataDefs_v1, "
 
5337
typedef struct {
 
5338
  int a;
 
5339
  union {
 
5340
    int b;
 
5341
    float c;
 
5342
  };
 
5343
  int d;
 
5344
} type_test_unnamed;
 
5345
int func_test_unnamed(type_test_unnamed param);");
 
5346
    @Sources_v1 = (@Sources_v1, "int func_test_unnamed(type_test_unnamed param)\n{\n    return 0;\n}");
 
5347
    
 
5348
    @DataDefs_v2 = (@DataDefs_v2, "
 
5349
typedef struct {
 
5350
  int a;
 
5351
  union {
 
5352
    long double b;
 
5353
    float c;
 
5354
  };
 
5355
  int d;
 
5356
} type_test_unnamed;
 
5357
int func_test_unnamed(type_test_unnamed param);");
 
5358
    @Sources_v2 = (@Sources_v2, "int func_test_unnamed(type_test_unnamed param)\n{\n    return 0;\n}");
 
5359
    
 
5360
    #constants
 
5361
    @DataDefs_v1 = (@DataDefs_v1, "#define TEST_PUBLIC_CONSTANT \"old_value\"");
 
5362
    @DataDefs_v2 = (@DataDefs_v2, "#define TEST_PUBLIC_CONSTANT \"new_value\"");
 
5363
    
 
5364
    @DataDefs_v1 = (@DataDefs_v1, "#define TEST_PRIVATE_CONSTANT \"old_value\"\n#undef TEST_PRIVATE_CONSTANT");
 
5365
    @DataDefs_v2 = (@DataDefs_v2, "#define TEST_PRIVATE_CONSTANT \"new_value\"\n#undef TEST_PRIVATE_CONSTANT");
 
5366
    
 
5367
    #anon ptr typedef
 
5368
    @DataDefs_v1 = (@DataDefs_v1, "
 
5369
#ifdef __cplusplus
 
5370
extern \"C\" {
 
5371
#endif
 
5372
typedef struct {
 
5373
  int a;
 
5374
} *type_test_anonptr_typedef;
 
5375
extern __attribute__ ((visibility(\"default\"))) int func_test_anonptr_typedef(type_test_anonptr_typedef param);
 
5376
#ifdef __cplusplus
 
5377
}
 
5378
#endif");
 
5379
    @Sources_v1 = (@Sources_v1, "__attribute__ ((visibility(\"default\"))) int func_test_anonptr_typedef(type_test_anonptr_typedef param)\n{\n    return 0;\n}");
 
5380
    
 
5381
    @DataDefs_v2 = (@DataDefs_v2, "
 
5382
#ifdef __cplusplus
 
5383
extern \"C\" {
 
5384
#endif
 
5385
typedef struct {
 
5386
  float a;
 
5387
} *type_test_anonptr_typedef;
 
5388
extern __attribute__ ((visibility(\"default\"))) int func_test_anonptr_typedef(type_test_anonptr_typedef param);
 
5389
#ifdef __cplusplus
 
5390
}
 
5391
#endif");
 
5392
    @Sources_v2 = (@Sources_v2, "__attribute__ ((visibility(\"default\"))) int func_test_anonptr_typedef(type_test_anonptr_typedef param)\n{\n    return 0;\n}");
 
5393
    
 
5394
    #typedefs
 
5395
    @DataDefs_v1 = (@DataDefs_v1, "typedef float TYPEDEF_TYPE;\nint func_parameter_typedef_change(TYPEDEF_TYPE param);");
 
5396
    @Sources_v1 = (@Sources_v1, "int func_parameter_typedef_change(TYPEDEF_TYPE param)\n{\n    return 1.0;\n}");
 
5397
    
 
5398
    @DataDefs_v2 = (@DataDefs_v2, "typedef int TYPEDEF_TYPE;\nint func_parameter_typedef_change(TYPEDEF_TYPE param);");
 
5399
    @Sources_v2 = (@Sources_v2, "int func_parameter_typedef_change(TYPEDEF_TYPE param)\n{\n    return 1;\n}");
 
5400
    
 
5401
    #typedefs in member type
 
5402
    @DataDefs_v1 = (@DataDefs_v1, "typedef float TYPEDEF_TYPE_2;\nstruct type_test_member_typedef_change{\nTYPEDEF_TYPE_2 m;};\nint func_test_member_typedef_change(struct type_test_member_typedef_change param);");
 
5403
    @Sources_v1 = (@Sources_v1, "int func_test_member_typedef_change(struct type_test_member_typedef_change param)\n{\n    return 1;\n}");
 
5404
    
 
5405
    @DataDefs_v2 = (@DataDefs_v2, "typedef int TYPEDEF_TYPE_2;\nstruct type_test_member_typedef_change{\nTYPEDEF_TYPE_2 m;};\nint func_test_member_typedef_change(struct type_test_member_typedef_change param);");
 
5406
    @Sources_v2 = (@Sources_v2, "int func_test_member_typedef_change(struct type_test_member_typedef_change param)\n{\n    return 1;\n}");
 
5407
    
 
5408
    create_TestSuite("abi_changes_test_c", "C", join("\n\n", @DataDefs_v1), join("\n\n", @Sources_v1), join("\n\n", @DataDefs_v2), join("\n\n", @Sources_v2), "type_test_opaque", "func_test_internal");
 
5409
}
 
5410
 
 
5411
sub create_TestSuite($$$$$$$$)
 
5412
{
 
5413
    my ($Dir, $Lang, $DataDefs_v1, $Sources_v1, $DataDefs_v2, $Sources_v2, $Opaque, $Private) = @_;
 
5414
    my $Ext = ($Lang eq "C++")?"cpp":"c";
 
5415
    my $Gcc = ($Lang eq "C++")?"g++":"gcc";
 
5416
    #creating test suite
 
5417
    my $Path_v1 = "$Dir/lib_abi_changes_test.v1";
 
5418
    my $Path_v2 = "$Dir/lib_abi_changes_test.v2";
 
5419
    
 
5420
    system("rm", "-fr", $Path_v1, $Path_v2);
 
5421
    system("mkdir", "-p", $Path_v1, $Path_v2);
 
5422
    
 
5423
    writeFile("$Path_v1/version", "TEST_1.0 {\n};\nTEST_2.0 {\n};\n");
 
5424
    writeFile("$Path_v1/lib_abi_changes_test.h", "#include <stdlib.h>\n".$DataDefs_v1."\n");
 
5425
    writeFile("$Path_v1/lib_abi_changes_test.$Ext", "#include \"lib_abi_changes_test.h\"\n".$Sources_v1."\n");
 
5426
    writeFile("$Dir/descriptor.v1", "<version>\n    1.0.0\n</version>\n\n<headers>\n    ".$ENV{"PWD"}."/$Path_v1/\n</headers>\n\n<libs>\n    ".$ENV{"PWD"}."/$Path_v1/\n</libs>\n\n<opaque_types>\n    $Opaque\n</opaque_types>\n\n<skip_interfaces>\n    $Private\n</skip_interfaces>\n\n<include_paths>\n    ".$ENV{"PWD"}."/$Path_v1\n</include_paths>\n");
 
5427
    
 
5428
    writeFile("$Path_v2/version", "TEST_1.0 {\n};\nTEST_2.0 {\n};\n");
 
5429
    writeFile("$Path_v2/lib_abi_changes_test.h", "#include <stdlib.h>\n".$DataDefs_v2."\n");
 
5430
    writeFile("$Path_v2/lib_abi_changes_test.$Ext", "#include \"lib_abi_changes_test.h\"\n".$Sources_v2."\n");
 
5431
    writeFile("$Dir/descriptor.v2", "<version>\n    2.0.0\n</version>\n\n<headers>\n    ".$ENV{"PWD"}."/$Path_v2/\n</headers>\n\n<libs>\n    ".$ENV{"PWD"}."/$Path_v2/\n</libs>\n\n<opaque_types>\n    $Opaque\n</opaque_types>\n\n<skip_interfaces>\n    $Private\n</skip_interfaces>\n\n<include_paths>\n    ".$ENV{"PWD"}."/$Path_v2\n</include_paths>\n");
 
5432
    
 
5433
    system("$Gcc $Path_v1/lib_abi_changes_test.h");
 
5434
    if($?)
 
5435
    {
 
5436
        print "ERROR: can't compile \'$Path_v1/lib_abi_changes_test.h\'\n";
 
5437
        return;
 
5438
    }
 
5439
    system("$Gcc -Wl,--version-script $Path_v1/version -shared $Path_v1/lib_abi_changes_test.$Ext -o $Path_v1/lib_abi_changes_test.so");
 
5440
    if($?)
 
5441
    {
 
5442
        print "ERROR: can't compile \'$Path_v1/lib_abi_changes_test.$Ext\'\n";
 
5443
        return;
 
5444
    }
 
5445
    system("$Gcc $Path_v2/lib_abi_changes_test.h");
 
5446
    if($?)
 
5447
    {
 
5448
        print "ERROR: can't compile \'$Path_v2/lib_abi_changes_test.h\'\n";
 
5449
        return;
 
5450
    }
 
5451
    system("$Gcc -Wl,--version-script $Path_v2/version -shared $Path_v2/lib_abi_changes_test.$Ext -o $Path_v2/lib_abi_changes_test.so");
 
5452
    if($?)
 
5453
    {
 
5454
        print "ERROR: can't compile \'$Path_v2/lib_abi_changes_test.$Ext\'\n";
 
5455
        return;
 
5456
    }
 
5457
    
 
5458
    #running abi-compliance-checker
 
5459
    system("$0 -l lib_$Dir -d1 $Dir/descriptor.v1 -d2 $Dir/descriptor.v2");
 
5460
}
 
5461
 
 
5462
sub writeFile($$)
 
5463
{
 
5464
    my ($Path, $Content) = @_;
 
5465
    return if(not $Path);
 
5466
    open (FILE, ">".$Path) || die ("Can't open file $Path\n");
 
5467
    print FILE $Content;
 
5468
    close(FILE);
 
5469
}
 
5470
 
 
5471
sub readFile($)
 
5472
{
 
5473
    my $Path = $_[0];
 
5474
    return "" if(not $Path or not -f $Path);
 
5475
    open (FILE, $Path);
 
5476
    my $Content = join("\n", <FILE>);
 
5477
    close(FILE);
 
5478
    return toUnix($Content);
 
5479
}
 
5480
 
 
5481
sub toUnix($)
 
5482
{
 
5483
    my $Text = $_[0];
 
5484
    $Text=~s/\r//g;
 
5485
    return $Text;
 
5486
}
 
5487
 
 
5488
sub getArch()
 
5489
{
 
5490
    my $Arch = $ENV{"CPU"};
 
5491
    if(not $Arch)
 
5492
    {
 
5493
        $Arch = `uname -m`;
 
5494
        chomp($Arch);
 
5495
    }
 
5496
    if(not $Arch)
 
5497
    {
 
5498
        $Arch = `uname -p`;
 
5499
        chomp($Arch);
 
5500
    }
 
5501
    $Arch = "x86" if($Arch =~ /i[3-7]86/);
 
5502
    return $Arch;
 
5503
}
 
5504
 
 
5505
sub get_Report_Header()
 
5506
{
 
5507
    my $Report_Header = "<h1>ABI compliance report for the library <span style='color:Blue;white-space:nowrap;'>$TargetLibraryName </span> from version <span style='color:Red;white-space:nowrap;'>".$Descriptor{1}{"Version"}."</span> to <span style='color:Red;white-space:nowrap;'>".$Descriptor{2}{"Version"}."</span> on <span style='color:Blue;'>".getArch()."</span> ".(($AppPath)?"relating to the portability of application <span style='color:Blue;'>".get_FileName($AppPath)."</span>":"")."</h1>\n";
 
5508
    return "<!--Header-->\n".$Report_Header."<!--Header_End-->\n";
 
5509
}
 
5510
 
 
5511
sub get_SourceInfo()
 
5512
{
 
5513
    my $CheckedHeaders = "<!--Checked_Headers-->\n<a name='Checked_Headers'></a><h2 style='margin-bottom:0px;padding-bottom:0px;'>Checked header files (".keys(%{$Headers{1}}).")</h2><hr/>\n";
 
5514
    foreach my $Header_Dest (sort {lc($Headers{1}{$a}{"Name"}) cmp lc($Headers{1}{$b}{"Name"})} keys(%{$Headers{1}}))
 
5515
    {
 
5516
        my $Header_Name = $Headers{1}{$Header_Dest}{"Name"};
 
5517
        my $Dest_Count = keys(%{$HeaderName_Destinations{1}{$Header_Name}});
 
5518
        my $Identity = $Headers{1}{$Header_Dest}{"Identity"};
 
5519
        my $Dest_Comment = ($Dest_Count>1 and $Identity=~/\//)?" ($Identity)":"";
 
5520
        $CheckedHeaders .= "<span class='header_list_elem'>$Header_Name"."$Dest_Comment</span><br/>\n";
 
5521
    }
 
5522
    $CheckedHeaders .= "<!--Checked_Headers_End--><br/><a style='font-size:11px;' href='#Top'>to the top</a><br/>\n";
 
5523
    my $CheckedLibs = "<!--Checked_Libs-->\n<a name='Checked_Libs'></a><h2 style='margin-bottom:0px;padding-bottom:0px;'>Checked shared objects (".keys(%{$SoNames_All{1}}).")</h2><hr/>\n";
 
5524
    foreach my $Library (sort {lc($a) cmp lc($b)}  keys(%{$SoNames_All{1}}))
 
5525
    {
 
5526
        $CheckedLibs .= "<span class='solib_list_elem'>$Library</span><br/>\n";
 
5527
    }
 
5528
    $CheckedLibs .= "<!--Checked_Libs_End--><br/><a style='font-size:11px;' href='#Top'>to the top</a><br/>\n";
 
5529
    return $CheckedHeaders.$CheckedLibs;
 
5530
}
 
5531
 
 
5532
sub get_TypeProblems_Count($$)
 
5533
{
 
5534
    my ($TypeChanges, $TargetPriority) = @_;
 
5535
    my $Type_Problems_Count = 0;
 
5536
    foreach my $TypeName (sort keys(%{$TypeChanges}))
 
5537
    {
 
5538
        my %Kinds_Target = ();
 
5539
        foreach my $Kind (keys(%{$TypeChanges->{$TypeName}}))
 
5540
        {
 
5541
            foreach my $Location (keys(%{$TypeChanges->{$TypeName}{$Kind}}))
 
5542
            {
 
5543
                my $Priority = $TypeChanges->{$TypeName}{$Kind}{$Location}{"Priority"};
 
5544
                next if($Priority ne $TargetPriority);
 
5545
                my $Target = $TypeChanges->{$TypeName}{$Kind}{$Location}{"Target"};
 
5546
                next if($Kinds_Target{$Kind}{$Target});
 
5547
                $Kinds_Target{$Kind}{$Target} = 1;
 
5548
                $Type_Problems_Count += 1;
 
5549
            }
 
5550
        }
 
5551
    }
 
5552
    return $Type_Problems_Count;
 
5553
}
 
5554
 
 
5555
sub get_Summary()
 
5556
{
 
5557
    my ($Added, $Withdrawn, $I_Problems_High, $I_Problems_Medium, $I_Problems_Low, $T_Problems_High, $T_Problems_Medium, $T_Problems_Low) = (0,0,0,0,0,0,0,0);
 
5558
    foreach my $Interface (sort keys(%CompatProblems))
 
5559
    {
 
5560
        foreach my $Kind (sort keys(%{$CompatProblems{$Interface}}))
 
5561
        {
 
5562
            if($InterfaceProblems_Kind{$Kind})
 
5563
            {
 
5564
                foreach my $Location (sort keys(%{$CompatProblems{$Interface}{$Kind}}))
 
5565
                {
 
5566
                    if($Kind eq "Added_Interface")
 
5567
                    {
 
5568
                        $Added += 1;
 
5569
                    }
 
5570
                    elsif($Kind eq "Withdrawn_Interface")
 
5571
                    {
 
5572
                        $Withdrawn += 1;
 
5573
                    }
 
5574
                    else
 
5575
                    {
 
5576
                        if($CompatProblems{$Interface}{$Kind}{$Location}{"Priority"} eq "High")
 
5577
                        {
 
5578
                            $I_Problems_High += 1;
 
5579
                        }
 
5580
                        elsif($CompatProblems{$Interface}{$Kind}{$Location}{"Priority"} eq "Medium")
 
5581
                        {
 
5582
                            $I_Problems_Medium += 1;
 
5583
                        }
 
5584
                        elsif($CompatProblems{$Interface}{$Kind}{$Location}{"Priority"} eq "Low")
 
5585
                        {
 
5586
                            $I_Problems_Low += 1;
 
5587
                        }
 
5588
                    }
 
5589
                }
 
5590
            }
 
5591
        }
 
5592
    }
 
5593
    
 
5594
    my (%TypeChanges, %Type_MaxPriority);
 
5595
    foreach my $Interface (sort keys(%CompatProblems))
 
5596
    {
 
5597
        foreach my $Kind (keys(%{$CompatProblems{$Interface}}))
 
5598
        {
 
5599
            if($TypeProblems_Kind{$Kind})
 
5600
            {
 
5601
                foreach my $Location (keys(%{$CompatProblems{$Interface}{$Kind}}))
 
5602
                {
 
5603
                    my $Type_Name = $CompatProblems{$Interface}{$Kind}{$Location}{"Type_Name"};
 
5604
                    my $Priority = $CompatProblems{$Interface}{$Kind}{$Location}{"Priority"};
 
5605
                    %{$TypeChanges{$Type_Name}{$Kind}{$Location}} = %{$CompatProblems{$Interface}{$Kind}{$Location}};
 
5606
                    $Type_MaxPriority{$Type_Name}{$Kind} = max_priority($Type_MaxPriority{$Type_Name}{$Kind}, $Priority);
 
5607
                }
 
5608
            }
 
5609
        }
 
5610
    }
 
5611
    
 
5612
    foreach my $Type_Name (keys(%TypeChanges))
 
5613
    {
 
5614
        foreach my $Kind (keys(%{$TypeChanges{$Type_Name}}))
 
5615
        {
 
5616
            foreach my $Location (keys(%{$TypeChanges{$Type_Name}{$Kind}}))
 
5617
            {
 
5618
                my $Priority = $TypeChanges{$Type_Name}{$Kind}{$Location}{"Priority"};
 
5619
                if(cmp_priority($Type_MaxPriority{$Type_Name}{$Kind}, $Priority))
 
5620
                {
 
5621
                    delete($TypeChanges{$Type_Name}{$Kind}{$Location});
 
5622
                }
 
5623
            }
 
5624
        }
 
5625
    }
 
5626
    
 
5627
    $T_Problems_High = get_TypeProblems_Count(\%TypeChanges, "High");
 
5628
    $T_Problems_Medium = get_TypeProblems_Count(\%TypeChanges, "Medium");
 
5629
    $T_Problems_Low = get_TypeProblems_Count(\%TypeChanges, "Low");
 
5630
    
 
5631
    #summary
 
5632
    my $Summary = "<h2 style='margin-bottom:0px;padding-bottom:0px;'>Summary</h2><hr/>";
 
5633
    $Summary .= "<table cellpadding='3' border='1' style='border-collapse:collapse;'>";
 
5634
    
 
5635
    
 
5636
    my $Checked_Headers_Link = "0";
 
5637
    $Checked_Headers_Link = "<a href='#Checked_Headers' style='color:Blue;'>".keys(%{$Headers{1}})."</a>" if(keys(%{$Headers{1}})>0);
 
5638
    $Summary .= "<tr><td class='table_header summary_item'>Total header files checked</td><td class='summary_item_value'>$Checked_Headers_Link</td></tr>";
 
5639
    
 
5640
    my $Checked_Libs_Link = "0";
 
5641
    $Checked_Libs_Link = "<a href='#Checked_Libs' style='color:Blue;'>".keys(%{$SoNames_All{1}})."</a>" if(keys(%{$SoNames_All{1}})>0);
 
5642
    $Summary .= "<tr><td class='table_header summary_item'>Total shared objects checked</td><td class='summary_item_value'>$Checked_Libs_Link</td></tr>";
 
5643
    $Summary .= "<tr><td class='table_header summary_item'>Total interfaces / types checked</td><td class='summary_item_value'>".keys(%CheckedInterfaces)." / ".keys(%CheckedTypes)."</td></tr>";
 
5644
    
 
5645
    my $Verdict = "<span style='color:Green;'><b>Compatible</b></span>";
 
5646
    $Verdict = "<span style='color:Red;'><b>Incompatible</b></span>" if(($Withdrawn>0) or ($I_Problems_High>0) or ($T_Problems_High>0));
 
5647
    $Summary .= "<tr><td class='table_header summary_item'>Verdict</td><td class='summary_item_value'>$Verdict</td></tr>";
 
5648
    
 
5649
    $Summary .= "</table>\n";
 
5650
    
 
5651
    #problem summary
 
5652
    my $Problem_Summary = "<h2 style='margin-bottom:0px;padding-bottom:0px;'>Problem Summary</h2><hr/>";
 
5653
    $Problem_Summary .= "<table cellpadding='3' border='1' style='border-collapse:collapse;'>";
 
5654
    
 
5655
    my $Added_Link = "0";
 
5656
    $Added_Link = "<a href='#Added' style='color:Blue;'>$Added</a>" if($Added>0);
 
5657
    $Problem_Summary .= "<tr><td class='table_header summary_item' colspan='2'>Added interfaces</td><td class='summary_item_value'>$Added_Link</td></tr>";
 
5658
    
 
5659
    my $WIthdrawn_Link = "0";
 
5660
    $WIthdrawn_Link = "<a href='#Withdrawn' style='color:Blue;'>$Withdrawn</a>" if($Withdrawn>0);
 
5661
    $Problem_Summary .= "<tr><td class='table_header summary_item' colspan='2'>Withdrawn interfaces</td><td class='summary_item_value'>$WIthdrawn_Link</td></tr>";
 
5662
    
 
5663
    my $TH_Link = "0";
 
5664
    $TH_Link = "<a href='#Type_Problems_High' style='color:Blue;'>$T_Problems_High</a>" if($T_Problems_High>0);
 
5665
    $Problem_Summary .= "<tr><td class='table_header summary_item' rowspan='3'>Problems in<br/>Data Types</td><td class='table_header summary_item' style='color:Red;'>High risk</td><td align='right' class='summary_item_value'>$TH_Link</td></tr>";
 
5666
    
 
5667
    my $TM_Link = "0";
 
5668
    $TM_Link = "<a href='#Type_Problems_Medium' style='color:Blue;'>$T_Problems_Medium</a>" if($T_Problems_Medium>0);
 
5669
    $Problem_Summary .= "<tr><td class='table_header summary_item'>Medium risk</td><td class='summary_item_value'>$TM_Link</td></tr>";
 
5670
    
 
5671
    my $TL_Link = "0";
 
5672
    $TL_Link = "<a href='#Type_Problems_Low' style='color:Blue;'>$T_Problems_Low</a>" if($T_Problems_Low>0);
 
5673
    $Problem_Summary .= "<tr><td class='table_header summary_item'>Low risk</td><td class='summary_item_value'>$TL_Link</td></tr>";
 
5674
    
 
5675
    my $IH_Link = "0";
 
5676
    $IH_Link = "<a href='#Interface_Problems_High' style='color:Blue;'>$I_Problems_High</a>" if($I_Problems_High>0);
 
5677
    $Problem_Summary .= "<tr><td class='table_header summary_item' rowspan='3'>Interface<br/>problems</td><td class='table_header summary_item' style='color:Red;'>High risk</td><td class='summary_item_value'>$IH_Link</td></tr>";
 
5678
    
 
5679
    my $IM_Link = "0";
 
5680
    $IM_Link = "<a href='#Interface_Problems_Medium' style='color:Blue;'>$I_Problems_Medium</a>" if($I_Problems_Medium>0);
 
5681
    $Problem_Summary .= "<tr><td class='table_header summary_item'>Medium risk</td><td class='summary_item_value'>$IM_Link</td></tr>";
 
5682
    
 
5683
    my $IL_Link = "0";
 
5684
    $IL_Link = "<a href='#Interface_Problems_Low' style='color:Blue;'>$I_Problems_Low</a>" if($I_Problems_Low>0);
 
5685
    $Problem_Summary .= "<tr><td class='table_header summary_item'>Low risk</td><td class='summary_item_value'>$IL_Link</td></tr>";
 
5686
    
 
5687
    my $ChangedConstants_Link = "0";
 
5688
    $ChangedConstants_Link = "<a href='#Constants' style='color:Blue;'>".keys(%ConstantProblems)."</a>" if(keys(%ConstantProblems)>0);
 
5689
    $Problem_Summary .= "<tr><td class='table_header summary_item' colspan='2'>Constants Problems</td><td class='summary_item_value'>$ChangedConstants_Link</td></tr>";
 
5690
    
 
5691
    $Problem_Summary .= "</table>\n";
 
5692
    return "<!--Summary-->\n".$Summary.$Problem_Summary."<!--Summary_End-->\n";
 
5693
}
 
5694
 
 
5695
sub get_Report_ChangedConstants()
 
5696
{
 
5697
    my ($CHANGED_CONSTANTS, %HeaderConstant);
 
5698
    foreach my $Name (keys(%ConstantProblems))
 
5699
    {
 
5700
        $HeaderConstant{$ConstantProblems{$Name}{"Header"}}{$Name} = 1;
 
5701
    }
 
5702
    my $Constants_Number = 0;
 
5703
    foreach my $HeaderName (sort {lc($a) cmp lc($b)} keys(%HeaderConstant))
 
5704
    {
 
5705
        $CHANGED_CONSTANTS .= "<span class='header_name'>$HeaderName</span><br/>\n";
 
5706
        foreach my $Name (sort {lc($a) cmp lc($b)} keys(%{$HeaderConstant{$HeaderName}}))
 
5707
        {
 
5708
            $Constants_Number += 1;
 
5709
            my $Old_Value = htmlSpecChars($ConstantProblems{$Name}{"Old_Value"});
 
5710
            my $New_Value = htmlSpecChars($ConstantProblems{$Name}{"New_Value"});
 
5711
            my $Incompatibility = "The value of constant <b>$Name</b> has been changed from <span style='white-space:nowrap;'><b>$Old_Value</b></span> to <span style='white-space:nowrap;'><b>$New_Value</b></span>.";
 
5712
            my $Effect = "If application uses this constant as a parameter of some interface than its execution may change.";
 
5713
            my $ConstantProblemsReport = "<tr><td align='center' valign='top' class='table_header'><span class='problem_num'>1</span></td><td align='left' valign='top'><span class='problem_body'>".$Incompatibility."</span></td><td align='left' valign='top'><span class='problem_body'>$Effect</span></td></tr>\n";
 
5714
            $CHANGED_CONSTANTS .= $ContentSpanStart."<span class='extension'>[+]</span> ".$Name.$ContentSpanEnd."<br/>\n$ContentDivStart<table width='900px' cellpadding='3' cellspacing='0' class='problems_table'><tr><td align='center' width='2%' class='table_header'><span class='problem_title' style='white-space:nowrap;'></span></td><td width='47%' align='center' class='table_header'><span class='problem_sub_title'>Incompatibility</span></td><td align='center' class='table_header'><span class='problem_sub_title'>Effect</span></td></tr>$ConstantProblemsReport</table><br/>$ContentDivEnd\n";
 
5715
            $CHANGED_CONSTANTS = insertIDs($CHANGED_CONSTANTS);
 
5716
        }
 
5717
        $CHANGED_CONSTANTS .= "<br/>\n";
 
5718
    }
 
5719
    if($CHANGED_CONSTANTS)
 
5720
    {
 
5721
        $CHANGED_CONSTANTS = "<a name='Constants'></a><h2 style='margin-bottom:0px;padding-bottom:0px;'>Constants Problems ($Constants_Number)</h2><hr/>\n"."<!--Changed_Constants-->\n".$CHANGED_CONSTANTS."<!--Changed_Constants_End-->\n"."<input id='Changed_Constants_Count' type='hidden' value=\'$Constants_Number\' /><a style='font-size:11px;' href='#Top'>to the top</a><br/>\n";
 
5722
    }
 
5723
    return $CHANGED_CONSTANTS;
 
5724
}
 
5725
 
 
5726
sub get_Report_Added()
 
5727
{
 
5728
    my $ADDED_INTERFACES;
 
5729
    #added interfaces
 
5730
    my %FuncAddedInHeaderLib;
 
5731
    foreach my $Interface (sort keys(%CompatProblems))
 
5732
    {
 
5733
        foreach my $Kind (sort keys(%{$CompatProblems{$Interface}}))
 
5734
        {
 
5735
            foreach my $Location (sort keys(%{$CompatProblems{$Interface}{$Kind}}))
 
5736
            {
 
5737
                if($Kind eq "Added_Interface")
 
5738
                {
 
5739
                    $FuncAddedInHeaderLib{$CompatProblems{$Interface}{$Kind}{$Location}{"Header"}}{$CompatProblems{$Interface}{$Kind}{$Location}{"New_SoName"}}{$Interface} = 1;
 
5740
                    last;
 
5741
                }
 
5742
            }
 
5743
        }
 
5744
    }
 
5745
    my $Added_Number = 0;
 
5746
    foreach my $HeaderName (sort {lc($a) cmp lc($b)} keys(%FuncAddedInHeaderLib))
 
5747
    {
 
5748
        foreach my $SoName (sort {lc($a) cmp lc($b)} keys(%{$FuncAddedInHeaderLib{$HeaderName}}))
 
5749
        {
 
5750
            if($HeaderName)
 
5751
            {
 
5752
                $ADDED_INTERFACES .= "<span class='header_name'>$HeaderName</span>, <span class='solib_name'>$SoName</span><br/>\n";
 
5753
            }
 
5754
            else
 
5755
            {
 
5756
                $ADDED_INTERFACES .= "<span class='solib_name'>$SoName</span><br/>\n";
 
5757
            }
 
5758
            foreach my $Interface (sort {lc($CompatProblems{$a}{"Added_Interface"}{"SharedLibrary"}{"Signature"}) cmp lc($CompatProblems{$b}{"Added_Interface"}{"SharedLibrary"}{"Signature"})} keys(%{$FuncAddedInHeaderLib{$HeaderName}{$SoName}}))
 
5759
            {
 
5760
                $Added_Number += 1;
 
5761
                my $SubReport = "";
 
5762
                my $Signature = $CompatProblems{$Interface}{"Added_Interface"}{"SharedLibrary"}{"Signature"};
 
5763
                if($Interface =~ /\A_Z/)
 
5764
                {
 
5765
                    if($Signature)
 
5766
                    {
 
5767
                        $SubReport = insertIDs($ContentSpanStart.highLight_Signature_Italic_Color(htmlSpecChars($Signature)).$ContentSpanEnd."<br/>\n".$ContentDivStart."<span class='mangled'>[ symbol: <b>$Interface</b> ]</span><br/><br/>".$ContentDivEnd."\n");
 
5768
                    }
 
5769
                    else
 
5770
                    {
 
5771
                        $SubReport = "<span class=\"interface_name\">".$Interface."</span>"."<br/>\n";
 
5772
                    }
 
5773
                }
 
5774
                else
 
5775
                {
 
5776
                    if($Signature)
 
5777
                    {
 
5778
                        $SubReport = "<span class=\"interface_name\">".highLight_Signature_Italic_Color($Signature)."</span>"."<br/>\n";
 
5779
                    }
 
5780
                    else
 
5781
                    {
 
5782
                        $SubReport = "<span class=\"interface_name\">".$Interface."</span>"."<br/>\n";
 
5783
                    }
 
5784
                }
 
5785
                $ADDED_INTERFACES .= $SubReport;
 
5786
            }
 
5787
            $ADDED_INTERFACES .= "<br/>\n";
 
5788
        }
 
5789
    }
 
5790
    if($ADDED_INTERFACES)
 
5791
    {
 
5792
        $ADDED_INTERFACES = "<a name='Added'></a><h2 style='margin-bottom:0px;padding-bottom:0px;'>Added Interfaces ($Added_Number)</h2><hr/>\n"."<!--Added_Interfaces-->\n".$ADDED_INTERFACES."<!--Added_Interfaces_End-->\n"."<input id='Added_Interfaces_Count' type='hidden' value=\'$Added_Number\' /><a style='font-size:11px;' href='#Top'>to the top</a><br/>\n";
 
5793
    }
 
5794
    return $ADDED_INTERFACES;
 
5795
}
 
5796
 
 
5797
sub get_Report_Withdrawn()
 
5798
{
 
5799
    my $WITHDRAWN_INTERFACES;
 
5800
    #withdrawn interfaces
 
5801
    my %FuncWithdrawnFromHeaderLib;
 
5802
    foreach my $Interface (sort keys(%CompatProblems))
 
5803
    {
 
5804
        foreach my $Kind (sort keys(%{$CompatProblems{$Interface}}))
 
5805
        {
 
5806
            foreach my $Location (sort keys(%{$CompatProblems{$Interface}{$Kind}}))
 
5807
            {
 
5808
                if($Kind eq "Withdrawn_Interface")
 
5809
                {
 
5810
                    $FuncWithdrawnFromHeaderLib{$CompatProblems{$Interface}{$Kind}{$Location}{"Header"}}{$CompatProblems{$Interface}{$Kind}{$Location}{"Old_SoName"}}{$Interface} = 1;
 
5811
                    last;
 
5812
                }
 
5813
            }
 
5814
        }
 
5815
    }
 
5816
    my $Withdrawn_Number = 0;
 
5817
    foreach my $HeaderName (sort {lc($a) cmp lc($b)} keys(%FuncWithdrawnFromHeaderLib))
 
5818
    {
 
5819
        foreach my $SoName (sort {lc($a) cmp lc($b)} keys(%{$FuncWithdrawnFromHeaderLib{$HeaderName}}))
 
5820
        {
 
5821
            if($HeaderName)
 
5822
            {
 
5823
                $WITHDRAWN_INTERFACES .= "<span class='header_name'>$HeaderName</span>, <span class='solib_name'>$SoName</span><br/>\n";
 
5824
            }
 
5825
            else
 
5826
            {
 
5827
                $WITHDRAWN_INTERFACES .= "<span class='solib_name'>$SoName</span><br/>\n";
 
5828
            }
 
5829
            foreach my $Interface (sort {lc($CompatProblems{$a}{"Withdrawn_Interface"}{"SharedLibrary"}{"Signature"}) cmp lc($CompatProblems{$b}{"Withdrawn_Interface"}{"SharedLibrary"}{"Signature"})} keys(%{$FuncWithdrawnFromHeaderLib{$HeaderName}{$SoName}}))
 
5830
            {
 
5831
                $Withdrawn_Number += 1;
 
5832
                my $SubReport = "";
 
5833
                my $Signature = $CompatProblems{$Interface}{"Withdrawn_Interface"}{"SharedLibrary"}{"Signature"};
 
5834
                if($Interface =~ /\A_Z/)
 
5835
                {
 
5836
                    if($Signature)
 
5837
                    {
 
5838
                        $SubReport = insertIDs($ContentSpanStart.highLight_Signature_Italic_Color(htmlSpecChars($Signature)).$ContentSpanEnd."<br/>\n".$ContentDivStart."<span class='mangled'>[ symbol: <b>$Interface</b> ]</span><br/><br/>".$ContentDivEnd."\n");
 
5839
                    }
 
5840
                    else
 
5841
                    {
 
5842
                        $SubReport = "<span class=\"interface_name\">".$Interface."</span>"."<br/>\n";
 
5843
                    }
 
5844
                }
 
5845
                else
 
5846
                {
 
5847
                    if($Signature)
 
5848
                    {
 
5849
                        $SubReport = "<span class=\"interface_name\">".highLight_Signature_Italic_Color($Signature)."</span>"."<br/>\n";
 
5850
                    }
 
5851
                    else
 
5852
                    {
 
5853
                        $SubReport = "<span class=\"interface_name\">".$Interface."</span>"."<br/>\n";
 
5854
                    }
 
5855
                }
 
5856
                $WITHDRAWN_INTERFACES .= $SubReport;
 
5857
            }
 
5858
            $WITHDRAWN_INTERFACES .= "<br/>\n";
 
5859
        }
 
5860
    }
 
5861
    if($WITHDRAWN_INTERFACES)
 
5862
    {
 
5863
        $WITHDRAWN_INTERFACES = "<a name='Withdrawn'></a><h2 style='margin-bottom:0px;padding-bottom:0px;'>Withdrawn Interfaces ($Withdrawn_Number)</h2><hr/>\n"."<!--Withdrawn_Interfaces-->\n".$WITHDRAWN_INTERFACES."<!--Withdrawn_Interfaces_End-->\n"."<input id='Withdrawn_Interfaces_Count' type='hidden' value=\'$Withdrawn_Number\' /><a style='font-size:11px;' href='#Top'>to the top</a><br/>\n";
 
5864
    }
 
5865
    return $WITHDRAWN_INTERFACES;
 
5866
}
 
5867
 
 
5868
sub get_Report_InterfaceProblems($)
 
5869
{
 
5870
    my $TargetPriority = $_[0];
 
5871
    my ($INTERFACE_PROBLEMS, %FuncHeaderLib);
 
5872
    foreach my $Interface (sort keys(%CompatProblems))
 
5873
    {
 
5874
        foreach my $Kind (sort keys(%{$CompatProblems{$Interface}}))
 
5875
        {
 
5876
            if($InterfaceProblems_Kind{$Kind} and ($Kind ne "Added_Interface") and ($Kind ne "Withdrawn_Interface"))
 
5877
            {
 
5878
                foreach my $Location (sort keys(%{$CompatProblems{$Interface}{$Kind}}))
 
5879
                {
 
5880
                    my $SoName = $CompatProblems{$Interface}{$Kind}{$Location}{"Old_SoName"};
 
5881
                    my $HeaderName = $CompatProblems{$Interface}{$Kind}{$Location}{"Header"};
 
5882
                    $FuncHeaderLib{$HeaderName}{$SoName}{$Interface} = 1;
 
5883
                    last;
 
5884
                }
 
5885
            }
 
5886
        }
 
5887
    }
 
5888
    my $Problems_Number = 0;
 
5889
    #interface problems
 
5890
    foreach my $HeaderName (sort {lc($a) cmp lc($b)} keys(%FuncHeaderLib))
 
5891
    {
 
5892
        foreach my $SoName (sort {lc($a) cmp lc($b)} keys(%{$FuncHeaderLib{$HeaderName}}))
 
5893
        {
 
5894
            my $HEADER_LIB_REPORT = "";
 
5895
            foreach my $Interface (sort {lc($tr_name{$a}) cmp lc($tr_name{$b})} keys(%{$FuncHeaderLib{$HeaderName}{$SoName}}))
 
5896
            {
 
5897
                my $Signature = "";
 
5898
                my $InterfaceProblemsReport = "";
 
5899
                my $ProblemNum = 1;
 
5900
                foreach my $Kind (keys(%{$CompatProblems{$Interface}}))
 
5901
                {
 
5902
                    foreach my $Location (keys(%{$CompatProblems{$Interface}{$Kind}}))
 
5903
                    {
 
5904
                        my $Incompatibility = "";
 
5905
                        my $Effect = "";
 
5906
                        my $Old_Value = htmlSpecChars($CompatProblems{$Interface}{$Kind}{$Location}{"Old_Value"});
 
5907
                        my $New_Value = htmlSpecChars($CompatProblems{$Interface}{$Kind}{$Location}{"New_Value"});
 
5908
                        my $Priority = $CompatProblems{$Interface}{$Kind}{$Location}{"Priority"};
 
5909
                        my $Target = $CompatProblems{$Interface}{$Kind}{$Location}{"Target"};
 
5910
                        my $Old_Size = $CompatProblems{$Interface}{$Kind}{$Location}{"Old_Size"};
 
5911
                        my $New_Size = $CompatProblems{$Interface}{$Kind}{$Location}{"New_Size"};
 
5912
                        my $InitialType_Type = $CompatProblems{$Interface}{$Kind}{$Location}{"InitialType_Type"};
 
5913
                        my $Parameter_Position = $CompatProblems{$Interface}{$Kind}{$Location}{"Parameter_Position"};
 
5914
                        my $Parameter_Position_Str = num_to_str($Parameter_Position + 1);
 
5915
                        $Signature = $CompatProblems{$Interface}{$Kind}{$Location}{"Signature"} if(not $Signature);
 
5916
                        next if($Priority ne $TargetPriority);
 
5917
                        if($Kind eq "Function_Become_Static")
 
5918
                        {
 
5919
                            $Incompatibility = "Function become <b>static</b>.\n";
 
5920
                            $Effect = "Layout of parameter's stack has been changed and therefore parameters in higher positions in the stack may be incorrectly initialized by applications.";
 
5921
                        }
 
5922
                        elsif($Kind eq "Function_Become_NonStatic")
 
5923
                        {
 
5924
                            $Incompatibility = "Function become <b>non-static</b>.\n";
 
5925
                            $Effect = "Layout of parameter's stack has been changed and therefore parameters in higher positions in the stack may be incorrectly initialized by applications.";
 
5926
                        }
 
5927
                        elsif($Kind eq "Parameter_Type_And_Size")
 
5928
                        {
 
5929
                            $Incompatibility = "Type of $Parameter_Position_Str parameter <b>$Target</b> has been changed from <span style='white-space:nowrap;'><b>$Old_Value</b> (<b>$Old_Size</b> bytes)</span> to <span style='white-space:nowrap;'><b>$New_Value</b> (<b>$New_Size</b> bytes)</span>.\n";
 
5930
                            $Effect = "Layout of parameter's stack has been changed and therefore parameters in higher positions in the stack may be incorrectly initialized by applications.";
 
5931
                        }
 
5932
                        elsif($Kind eq "Parameter_Type")
 
5933
                        {
 
5934
                            $Incompatibility = "Type of $Parameter_Position_Str parameter <b>$Target</b> has been changed from <span style='white-space:nowrap;'><b>$Old_Value</b></span> to <span style='white-space:nowrap;'><b>$New_Value</b></span>.\n";
 
5935
                            $Effect = "Replacement of parameter data type may indicate a change in the semantic meaning of this parameter.";
 
5936
                        }
 
5937
                        elsif($Kind eq "Withdrawn_Parameter")
 
5938
                        {
 
5939
                            $Incompatibility = "$Parameter_Position_Str parameter <b>$Target</b> has been withdrawn from the interface signature.\n";
 
5940
                            $Effect = "This parameter will be ignored by the interface.";
 
5941
                        }
 
5942
                        elsif($Kind eq "Added_Parameter")
 
5943
                        {
 
5944
                            $Incompatibility = "$Parameter_Position_Str parameter <b>$Target</b> has been added to the interface signature.\n";
 
5945
                            $Effect = "This parameter will not be initialized by applications.";
 
5946
                        }
 
5947
                        elsif($Kind eq "Parameter_BaseType_And_Size")
 
5948
                        {
 
5949
                            if($InitialType_Type eq "Pointer")
 
5950
                            {
 
5951
                                $Incompatibility = "Base type of $Parameter_Position_Str parameter <b>$Target</b> (pointer) has been changed from <span style='white-space:nowrap;'><b>$Old_Value</b> (<b>$Old_Size</b> bytes)</span> to <span style='white-space:nowrap;'><b>$New_Value</b> (<b>$New_Size</b> bytes)</span>.\n";
 
5952
                                $Effect = "Memory stored by pointer may be incorrectly initialized by applications.";
 
5953
                            }
 
5954
                            else
 
5955
                            {
 
5956
                                $Incompatibility = "Base type of $Parameter_Position_Str parameter <b>$Target</b> has been changed from <span style='white-space:nowrap;'><b>$Old_Value</b> (<b>$Old_Size</b> bytes)</span> to <span style='white-space:nowrap;'><b>$New_Value</b> (<b>$New_Size</b> bytes)</span>.\n";
 
5957
                                $Effect = "Layout of parameter's stack has been changed and therefore parameters in higher positions in the stack may be incorrectly initialized by applications.";
 
5958
                            }
 
5959
                        }
 
5960
                        elsif($Kind eq "Parameter_BaseType")
 
5961
                        {
 
5962
                            if($InitialType_Type eq "Pointer")
 
5963
                            {
 
5964
                                $Incompatibility = "Base type of $Parameter_Position_Str parameter <b>$Target</b> (pointer) has been changed from <span style='white-space:nowrap;'><b>$Old_Value</b></span> to <span style='white-space:nowrap;'><b>$New_Value</b></span>.\n";
 
5965
                                $Effect = "Memory stored by pointer may be incorrectly initialized by applications.";
 
5966
                            }
 
5967
                            else
 
5968
                            {
 
5969
                                $Incompatibility = "Base type of $Parameter_Position_Str parameter <b>$Target</b> has been changed from <span style='white-space:nowrap;'><b>$Old_Value</b></span> to <span style='white-space:nowrap;'><b>$New_Value</b></span>.\n";
 
5970
                                $Effect = "Replacement of parameter base type may indicate a change in the semantic meaning of this parameter.";
 
5971
                            }
 
5972
                        }
 
5973
                        elsif($Kind eq "Parameter_PointerLevel")
 
5974
                        {
 
5975
                            $Incompatibility = "Type pointer level of $Parameter_Position_Str parameter <b>$Target</b> has been changed from <b>$Old_Value</b> to <b>$New_Value</b>.\n";
 
5976
                            $Effect = "Possible incorrect initialization of $Parameter_Position_Str parameter <b>$Target</b> by applications.";
 
5977
                        }
 
5978
                        elsif($Kind eq "Return_Type_And_Size")
 
5979
                        {
 
5980
                            $Incompatibility = "Type of return value has been changed from <span style='white-space:nowrap;'><b>$Old_Value</b> (<b>$Old_Size</b> bytes)</span> to <span style='white-space:nowrap;'><b>$New_Value</b> (<b>$New_Size</b> bytes)</span>.\n";
 
5981
                            $Effect = "Applications will get a different return value and execution may change.";
 
5982
                        }
 
5983
                        elsif($Kind eq "Return_Type")
 
5984
                        {
 
5985
                            $Incompatibility = "Type of return value has been changed from <span style='white-space:nowrap;'><b>$Old_Value</b></span> to <span style='white-space:nowrap;'><b>$New_Value</b></span>.\n";
 
5986
                            $Effect = "Replacement of return type may indicate a change in its semantic meaning.";
 
5987
                        }
 
5988
                        elsif($Kind eq "Return_BaseType_And_Size")
 
5989
                        {
 
5990
                            $Incompatibility = "Base type of return value has been changed from <span style='white-space:nowrap;'><b>$Old_Value</b> (<b>$Old_Size</b> bytes)</span> to <span style='white-space:nowrap;'><b>$New_Value</b> (<b>$New_Size</b> bytes)</span>.\n";
 
5991
                            $Effect = "Applications will get a different return value and execution may change.";
 
5992
                        }
 
5993
                        elsif($Kind eq "Return_BaseType")
 
5994
                        {
 
5995
                            $Incompatibility = "Base type of return value has been changed from <span style='white-space:nowrap;'><b>$Old_Value</b></span> to <span style='white-space:nowrap;'><b>$New_Value</b></span>.\n";
 
5996
                            $Effect = "Replacement of return base type may indicate a change in its semantic meaning.";
 
5997
                        }
 
5998
                        elsif($Kind eq "Return_PointerLevel")
 
5999
                        {
 
6000
                            $Incompatibility = "Type pointer level of return value has been changed from <b>$Old_Value</b> to <b>$New_Value</b>.\n";
 
6001
                            $Effect = "Applications will get a different return value and execution may change.";
 
6002
                        }
 
6003
                        if($Incompatibility)
 
6004
                        {
 
6005
                            $InterfaceProblemsReport .= "<tr><td align='center' class='table_header'><span class='problem_num'>$ProblemNum</span></td><td align='left' valign='top'><span class='problem_body'>".$Incompatibility."</span></td><td align='left' valign='top'><span class='problem_body'>".$Effect."</span></td></tr>\n";
 
6006
                            $ProblemNum += 1;
 
6007
                            $Problems_Number += 1;
 
6008
                        }
 
6009
                    }
 
6010
                }
 
6011
                $ProblemNum -= 1;
 
6012
                if($InterfaceProblemsReport)
 
6013
                {
 
6014
                    if($Interface =~ /\A_Z/)
 
6015
                    {
 
6016
                        if($Signature)
 
6017
                        {
 
6018
                            $HEADER_LIB_REPORT .= $ContentSpanStart."<span class='extension'>[+]</span> ".highLight_Signature_Italic_Color(htmlSpecChars($Signature))." ($ProblemNum)".$ContentSpanEnd."<br/>\n$ContentDivStart<span class='mangled'>[ symbol: <b>$Interface</b> ]</span><br/>\n";
 
6019
                        }
 
6020
                        else
 
6021
                        {
 
6022
                            $HEADER_LIB_REPORT .= $ContentSpanStart."<span class='extension'>[+]</span> ".$Interface." ($ProblemNum)".$ContentSpanEnd."<br/>\n$ContentDivStart\n";
 
6023
                        }
 
6024
                    }
 
6025
                    else
 
6026
                    {
 
6027
                        if($Signature)
 
6028
                        {
 
6029
                            $HEADER_LIB_REPORT .= $ContentSpanStart."<span class='extension'>[+]</span> ".highLight_Signature_Italic_Color(htmlSpecChars($Signature))." ($ProblemNum)".$ContentSpanEnd."<br/>\n$ContentDivStart\n";
 
6030
                        }
 
6031
                        else
 
6032
                        {
 
6033
                            $HEADER_LIB_REPORT .= $ContentSpanStart."<span class='extension'>[+]</span> ".$Interface." ($ProblemNum)".$ContentSpanEnd."<br/>\n$ContentDivStart\n";
 
6034
                        }
 
6035
                    }
 
6036
                    $HEADER_LIB_REPORT .= "<table width='900px' cellpadding='3' cellspacing='0' class='problems_table'><tr><td align='center' width='2%' class='table_header'><span class='problem_title' style='white-space:nowrap;'></span></td><td width='47%' align='center' class='table_header'><span class='problem_sub_title'>Incompatibility</span></td><td align='center' class='table_header'><span class='problem_sub_title'>Effect</span></td></tr>$InterfaceProblemsReport</table><br/>$ContentDivEnd\n";
 
6037
                    $HEADER_LIB_REPORT = insertIDs($HEADER_LIB_REPORT);
 
6038
                }
 
6039
            }
 
6040
            if($HEADER_LIB_REPORT)
 
6041
            {
 
6042
                $INTERFACE_PROBLEMS .= "<span class='header_name'>$HeaderName</span>, <span class='solib_name'>$SoName</span><br/>\n".$HEADER_LIB_REPORT."<br/>";
 
6043
            }
 
6044
        }
 
6045
    }
 
6046
    if($INTERFACE_PROBLEMS)
 
6047
    {
 
6048
        $INTERFACE_PROBLEMS = "<a name=\'Interface_Problems_$TargetPriority\'></a>\n<h2 style='margin-bottom:0px;padding-bottom:0px;'>Interface problems, $TargetPriority risk ($Problems_Number)</h2><hr/>\n"."<!--Interface_Problems_".$TargetPriority."-->\n".$INTERFACE_PROBLEMS."<!--Interface_Problems_".$TargetPriority."_End-->\n"."<input id=\'Interface_Problems_$TargetPriority"."_Count"."\' type='hidden' value=\'$Problems_Number\' /><a style='font-size:11px;' href='#Top'>to the top</a><br/>\n";
 
6049
    }
 
6050
    return $INTERFACE_PROBLEMS;
 
6051
}
 
6052
 
 
6053
sub get_Report_TypeProblems($)
 
6054
{
 
6055
    my $TargetPriority = $_[0];
 
6056
    my ($TYPE_PROBLEMS, %TypeHeader, %TypeChanges, %Type_MaxPriority) = ();
 
6057
    foreach my $Interface (sort keys(%CompatProblems))
 
6058
    {
 
6059
        foreach my $Kind (keys(%{$CompatProblems{$Interface}}))
 
6060
        {
 
6061
            if($TypeProblems_Kind{$Kind})
 
6062
            {
 
6063
                foreach my $Location (keys(%{$CompatProblems{$Interface}{$Kind}}))
 
6064
                {
 
6065
                    my $Type_Name = $CompatProblems{$Interface}{$Kind}{$Location}{"Type_Name"};
 
6066
                    my $Priority = $CompatProblems{$Interface}{$Kind}{$Location}{"Priority"};
 
6067
                    my $Type_Header = $CompatProblems{$Interface}{$Kind}{$Location}{"Header"};
 
6068
                    %{$TypeChanges{$Type_Name}{$Kind}{$Location}} = %{$CompatProblems{$Interface}{$Kind}{$Location}};
 
6069
                    $TypeHeader{$Type_Header}{$Type_Name} = 1;
 
6070
                    $Type_MaxPriority{$Type_Name}{$Kind} = max_priority($Type_MaxPriority{$Type_Name}{$Kind}, $Priority);
 
6071
                }
 
6072
            }
 
6073
        }
 
6074
    }
 
6075
    foreach my $Type_Name (keys(%TypeChanges))
 
6076
    {
 
6077
        foreach my $Kind (keys(%{$TypeChanges{$Type_Name}}))
 
6078
        {
 
6079
            foreach my $Location (keys(%{$TypeChanges{$Type_Name}{$Kind}}))
 
6080
            {
 
6081
                my $Priority = $TypeChanges{$Type_Name}{$Kind}{$Location}{"Priority"};
 
6082
                if(cmp_priority($Type_MaxPriority{$Type_Name}{$Kind}, $Priority))
 
6083
                {
 
6084
                    delete($TypeChanges{$Type_Name}{$Kind}{$Location});
 
6085
                }
 
6086
            }
 
6087
        }
 
6088
    }
 
6089
    my $Problems_Number = 0;
 
6090
    foreach my $HeaderName (sort {lc($a) cmp lc($b)} keys(%TypeHeader))
 
6091
    {
 
6092
        my $HEADER_REPORT = "";
 
6093
        foreach my $TypeName (sort {lc($a) cmp lc($b)} keys(%{$TypeHeader{$HeaderName}}))
 
6094
        {
 
6095
            my $ProblemNum = 1;
 
6096
            my $TypeProblemsReport = "";
 
6097
            my %Kinds_Locations = ();
 
6098
            my %Kinds_Target = ();
 
6099
            foreach my $Kind (keys(%{$TypeChanges{$TypeName}}))
 
6100
            {
 
6101
                foreach my $Location (keys(%{$TypeChanges{$TypeName}{$Kind}}))
 
6102
                {
 
6103
                    my $Priority = $TypeChanges{$TypeName}{$Kind}{$Location}{"Priority"};
 
6104
                    next if($Priority ne $TargetPriority);
 
6105
                    $Kinds_Locations{$Kind}{$Location} = 1;
 
6106
                    my $Incompatibility = "";
 
6107
                    my $Effect = "";
 
6108
                    my $Target = $TypeChanges{$TypeName}{$Kind}{$Location}{"Target"};
 
6109
                    next if($Kinds_Target{$Kind}{$Target});
 
6110
                    $Kinds_Target{$Kind}{$Target} = 1;
 
6111
                    my $Old_Value = htmlSpecChars($TypeChanges{$TypeName}{$Kind}{$Location}{"Old_Value"});
 
6112
                    my $New_Value = htmlSpecChars($TypeChanges{$TypeName}{$Kind}{$Location}{"New_Value"});
 
6113
                    my $Old_Size = $TypeChanges{$TypeName}{$Kind}{$Location}{"Old_Size"};
 
6114
                    my $New_Size = $TypeChanges{$TypeName}{$Kind}{$Location}{"New_Size"};
 
6115
                    my $Type_Type = $TypeChanges{$TypeName}{$Kind}{$Location}{"Type_Type"};
 
6116
                    my $InitialType_Type = $TypeChanges{$TypeName}{$Kind}{$Location}{"InitialType_Type"};
 
6117
                    
 
6118
                    if($Kind eq "Added_Virtual_Function")
 
6119
                    {
 
6120
                        $Incompatibility = "Virtual method "."<span class='interface_name_black'>".highLight_Signature(htmlSpecChars($Target))."</span>"." has been added to this class and therefore the layout of virtual table has been changed.";
 
6121
                        $Effect = "Call of any virtual method in this class or its subclasses will result in crash of application.";
 
6122
                    }
 
6123
                    elsif($Kind eq "Withdrawn_Virtual_Function")
 
6124
                    {
 
6125
                        $Incompatibility = "Virtual method "."<span class='interface_name_black'>".highLight_Signature(htmlSpecChars($Target))."</span>"." has been withdrawn from this class and therefore the layout of virtual table has been changed.";
 
6126
                        $Effect = "Call of any virtual method in this class or its subclasses will result in crash of application.";
 
6127
                    }
 
6128
                    elsif($Kind eq "Virtual_Function_Position")
 
6129
                    {
 
6130
                        $Incompatibility = "The relative position of virtual method "."<span class='interface_name_black'>".highLight_Signature(htmlSpecChars($Target))."</span>"." has been changed from <b>$Old_Value</b> to <b>$New_Value</b> and therefore the layout of virtual table has been changed.";
 
6131
                        $Effect = "Call of this virtual method will result in crash of application.";
 
6132
                    }
 
6133
                    elsif($Kind eq "Virtual_Function_Redefinition")
 
6134
                    {
 
6135
                        $Incompatibility = "Virtual method "."<span class='interface_name_black'>".highLight_Signature(htmlSpecChars($Old_Value))."</span>"." has been redefined by "."<span class='interface_name_black'>".highLight_Signature(htmlSpecChars($New_Value))."</span>";
 
6136
                        $Effect = "Method <span class='interface_name_black'>".highLight_Signature(htmlSpecChars($New_Value))."</span> will be called instead of <span class='interface_name_black'>".highLight_Signature(htmlSpecChars($Old_Value))."</span>";
 
6137
                    }
 
6138
                    elsif($Kind eq "Virtual_Function_Redefinition_B")
 
6139
                    {
 
6140
                        $Incompatibility = "Virtual method "."<span class='interface_name_black'>".highLight_Signature(htmlSpecChars($New_Value))."</span>"." has been redefined by "."<span class='interface_name_black'>".highLight_Signature(htmlSpecChars($Old_Value))."</span>";
 
6141
                        $Effect = "Method <span class='interface_name_black'>".highLight_Signature(htmlSpecChars($Old_Value))."</span> will be called instead of <span class='interface_name_black'>".highLight_Signature(htmlSpecChars($New_Value))."</span>";
 
6142
                    }
 
6143
                    elsif($Kind eq "Size")
 
6144
                    {
 
6145
                        $Incompatibility = "Size of this type has been changed from <b>$Old_Value</b> to <b>$New_Value</b> bytes.";
 
6146
                        $Effect = "Change of type size may lead to different effects in different contexts. $ContentSpanStart"."<span style='color:Black'>[+] ...</span>"."$ContentSpanEnd <label id=\"CONTENT_ID\" style=\"display:none;\"> In the context of function parameters, this change affects the parameter's stack layout and may lead to incorrect initialization of parameters in higher positions in the stack. In the context of structure members, this change affects the member's layout and may lead to incorrect attempts to access members in higher positions. Other effects are possible.</label>";
 
6147
                    }
 
6148
                    elsif($Kind eq "BaseType")
 
6149
                    {
 
6150
                        $Incompatibility = "Base of this type has been changed from <b>$Old_Value</b> to <b>$New_Value</b>.";
 
6151
                        $Effect = "Possible incorrect initialization of interface parameters by applications.";
 
6152
                    }
 
6153
                    elsif($Kind eq "Added_Member_And_Size")
 
6154
                    {
 
6155
                        $Incompatibility = "Member <b>$Target</b> has been added to this type.";
 
6156
                        $Effect = "The size of the inclusive type has been changed.";
 
6157
                    }
 
6158
                    elsif($Kind eq "Added_Middle_Member_And_Size")
 
6159
                    {
 
6160
                        $Incompatibility = "Member <b>$Target</b> has been added between the first member and the last member of this structural type.";
 
6161
                        $Effect = "1) Layout of structure members has been changed and therefore members in higher positions in the structure definition may be incorrectly accessed by applications.<br/>2) The size of the inclusive type will also be affected.";
 
6162
                    }
 
6163
                    elsif($Kind eq "Member_Rename")
 
6164
                    {
 
6165
                        $Incompatibility = "Member <b>$Target</b> has been renamed to <b>$New_Value</b>.";
 
6166
                        $Effect = "Renaming of a member in a structural data type may indicate a change in the semantic meaning of the member.";
 
6167
                    }
 
6168
                    elsif($Kind eq "Withdrawn_Member_And_Size")
 
6169
                    {
 
6170
                        $Incompatibility = "Member <b>$Target</b> has been withdrawn from this type.";
 
6171
                        $Effect = "1) Applications will access incorrect memory when attempting to access this member.<br/>2) The size of the inclusive type will also be affected.";
 
6172
                    }
 
6173
                    elsif($Kind eq "Withdrawn_Member")
 
6174
                    {
 
6175
                        $Incompatibility = "Member <b>$Target</b> has been withdrawn from this type.";
 
6176
                        $Effect = "Applications will access incorrect memory when attempting to access this member.";
 
6177
                    }
 
6178
                    elsif($Kind eq "Withdrawn_Middle_Member_And_Size")
 
6179
                    {
 
6180
                        $Incompatibility = "Member <b>$Target</b> has been withdrawn from this structural type between the first member and the last member.";
 
6181
                        $Effect = "1) Layout of structure members has been changed and therefore members in higher positions in the structure definition may be incorrectly accessed by applications.<br/>2) Previous accesses of applications to the withdrawn member will be incorrect.";
 
6182
                    }
 
6183
                    elsif($Kind eq "Withdrawn_Middle_Member")
 
6184
                    {
 
6185
                        $Incompatibility = "Member <b>$Target</b> has been withdrawn from this structural type between the first member and the last member.";
 
6186
                        $Effect = "1) Layout of structure members has been changed and therefore members in higher positions in the structure definition may be incorrectly accessed by applications.<br/>2) Applications will access incorrect memory when attempting to access this member.";
 
6187
                    }
 
6188
                    elsif($Kind eq "Enum_Member_Value")
 
6189
                    {
 
6190
                        $Incompatibility = "Value of member <b>$Target</b> has been changed from <b>$Old_Value</b> to <b>$New_Value</b>.";
 
6191
                        $Effect = "Applications may execute another branch of library code.";
 
6192
                    }
 
6193
                    elsif($Kind eq "Enum_Member_Name")
 
6194
                    {
 
6195
                        $Incompatibility = "Name of member with value <b>$Target</b> has been changed from <b>$Old_Value</b> to <b>$New_Value</b>.";
 
6196
                        $Effect = "Applications may execute another branch of library code.";
 
6197
                    }
 
6198
                    elsif($Kind eq "Member_Type_And_Size")
 
6199
                    {
 
6200
                        $Incompatibility = "Type of member <b>$Target</b> has been changed from <span style='white-space:nowrap;'><b>$Old_Value</b> (<b>$Old_Size</b> bytes)</span> to <span style='white-space:nowrap;'><b>$New_Value</b> (<b>$New_Size</b> bytes)</span>.";
 
6201
                        $Effect = "Layout of structure members has been changed and therefore members in higher positions in the structure definition may be incorrectly accessed by applications.";
 
6202
                    }
 
6203
                    elsif($Kind eq "Member_Type")
 
6204
                    {
 
6205
                        $Incompatibility = "Type of member <b>$Target</b> has been changed from <span style='white-space:nowrap;'><b>$Old_Value</b></span> to <span style='white-space:nowrap;'><b>$New_Value</b></span>.";
 
6206
                        $Effect = "Replacement of the member data type may indicate a change in the semantic meaning of the member.";
 
6207
                    }
 
6208
                    elsif($Kind eq "Member_BaseType_And_Size")
 
6209
                    {
 
6210
                        if($InitialType_Type eq "Pointer")
 
6211
                        {
 
6212
                            $Incompatibility = "Base type of member <b>$Target</b> (pointer) has been changed from <span style='white-space:nowrap;'><b>$Old_Value</b> (<b>$Old_Size</b> bytes)</span> to <span style='white-space:nowrap;'><b>$New_Value</b> (<b>$New_Size</b> bytes)</span>.";
 
6213
                            $Effect = "Possible access of applications to incorrect memory via member pointer.";
 
6214
                        }
 
6215
                        else
 
6216
                        {
 
6217
                            $Incompatibility = "Base type of member <b>$Target</b> has been changed from <span style='white-space:nowrap;'><b>$Old_Value</b> (<b>$Old_Size</b> bytes)</span> to <span style='white-space:nowrap;'><b>$New_Value</b> (<b>$New_Size</b> bytes)</span>.";
 
6218
                            $Effect = "Layout of structure members has been changed and therefore members in higher positions in structure definition may be incorrectly accessed by applications.";
 
6219
                        }
 
6220
                    }
 
6221
                    elsif($Kind eq "Member_BaseType")
 
6222
                    {
 
6223
                        if($InitialType_Type eq "Pointer")
 
6224
                        {
 
6225
                            $Incompatibility = "Base type of member <b>$Target</b> (pointer) has been changed from <span style='white-space:nowrap;'><b>$Old_Value</b></span> to <span style='white-space:nowrap;'><b>$New_Value</b></span>.";
 
6226
                            $Effect = "Possible access of applications to incorrect memory via member pointer.";
 
6227
                        }
 
6228
                        else
 
6229
                        {
 
6230
                            $Incompatibility = "Base type of member <b>$Target</b> has been changed from <span style='white-space:nowrap;'><b>$Old_Value</b></span> to <span style='white-space:nowrap;'><b>$New_Value</b></span>.";
 
6231
                            $Effect = "Replacement of member base type may indicate a change in the semantic meaning of this member.";
 
6232
                        }
 
6233
                    }
 
6234
                    elsif($Kind eq "Member_PointerLevel")
 
6235
                    {
 
6236
                        $Incompatibility = "Type pointer level of member <b>$Target</b> has been changed from <b>$Old_Value</b> to <b>$New_Value</b>.";
 
6237
                        $Effect = "Possible incorrect initialization of member <b>$Target</b> by applications.";
 
6238
                    }
 
6239
                    if($Incompatibility)
 
6240
                    {
 
6241
                        $TypeProblemsReport .= "<tr><td align='center' valign='top' class='table_header'><span class='problem_num'>$ProblemNum</span></td><td align='left' valign='top'><span class='problem_body'>".$Incompatibility."</span></td><td align='left' valign='top'><span class='problem_body'>$Effect</span></td></tr>\n";
 
6242
                        $ProblemNum += 1;
 
6243
                        $Problems_Number += 1;
 
6244
                        $Kinds_Locations{$Kind}{$Location} = 1;
 
6245
                    }
 
6246
                }
 
6247
            }
 
6248
            $ProblemNum -= 1;
 
6249
            if($TypeProblemsReport)
 
6250
            {
 
6251
                my ($Affected_Interfaces_Header, $Affected_Interfaces) = getAffectedInterfaces($TypeName, \%Kinds_Locations);
 
6252
                $HEADER_REPORT .= $ContentSpanStart."<span class='extension'>[+]</span> ".htmlSpecChars($TypeName)." ($ProblemNum)".$ContentSpanEnd."<br/>\n$ContentDivStart<table width='900px' cellpadding='3' cellspacing='0' class='problems_table'><tr><td align='center' width='2%' class='table_header'><span class='problem_title' style='white-space:nowrap;'></span></td><td width='47%' align='center' class='table_header'><span class='problem_sub_title'>Incompatibility</span></td><td align='center' class='table_header'><span class='problem_sub_title'>Effect</span></td></tr>$TypeProblemsReport</table>"."<span style='padding-left:10px'>$Affected_Interfaces_Header</span>$Affected_Interfaces<br/><br/>$ContentDivEnd\n";
 
6253
                $HEADER_REPORT = insertIDs($HEADER_REPORT);
 
6254
            }
 
6255
        }
 
6256
        if($HEADER_REPORT)
 
6257
        {
 
6258
            $TYPE_PROBLEMS .= "<span class='header_name'>$HeaderName</span><br/>\n".$HEADER_REPORT."<br/>";
 
6259
        }
 
6260
    }
 
6261
    if($TYPE_PROBLEMS)
 
6262
    {
 
6263
        my $Notations = "";
 
6264
        if($TYPE_PROBLEMS =~ /'RetVal|'Obj/)
 
6265
        {
 
6266
            my @Notations_Array = ();
 
6267
            if($TYPE_PROBLEMS =~ /'RetVal/)
 
6268
            {
 
6269
                @Notations_Array = (@Notations_Array, "<span style='color:#444444;padding-left:5px;'><b>RetVal</b></span> - function's return value");
 
6270
            }
 
6271
            if($TYPE_PROBLEMS =~ /'Obj/)
 
6272
            {
 
6273
                @Notations_Array = (@Notations_Array, "<span style='color:#444444;'><b>Obj</b></span> - method's object (C++)");
 
6274
            }
 
6275
            $Notations = "Shorthand notations: ".join("; ", @Notations_Array).".<br/>\n";
 
6276
        }
 
6277
        $TYPE_PROBLEMS = "<a name=\'Type_Problems_$TargetPriority\'></a>\n<h2 style='margin-bottom:0px;padding-bottom:0px;'>Problems in Data Types, $TargetPriority risk ($Problems_Number)</h2><hr/>\n".$Notations."<!--Type_Problems_".$TargetPriority."-->\n".$TYPE_PROBLEMS."<!--Type_Problems_".$TargetPriority."_End-->\n"."<input id=\'Type_Problems_$TargetPriority"."_Count"."\' type='hidden' value=\'$Problems_Number\' /><a style='font-size:11px;' href='#Top'>to the top</a><br/>\n";
 
6278
    }
 
6279
    return $TYPE_PROBLEMS;
 
6280
}
 
6281
 
 
6282
my $ContentSpanStart_2 = "<span style='line-height:25px;' class=\"section_2\" onclick=\"javascript:showContent(this, 'CONTENT_ID')\">\n";
 
6283
 
 
6284
sub getAffectedInterfaces($$)
 
6285
{
 
6286
    my ($Target_TypeName, $Kinds_Locations) = @_;
 
6287
    my ($Affected_Interfaces_Header, $Affected_Interfaces, %FunctionNumber) = ();
 
6288
    foreach my $Interface (sort {lc($tr_name{$a}) cmp lc($tr_name{$b})} keys(%CompatProblems))
 
6289
    {
 
6290
        next if(($Interface =~ /C2/) or ($Interface =~ /D2/) or ($Interface =~ /D0/));
 
6291
        next if(keys(%FunctionNumber)>1000);
 
6292
        my $FunctionProblem = "";
 
6293
        my $MinPath_Length = "";
 
6294
        my $MaxPriority = 0;
 
6295
        my $Location_Last = "";
 
6296
        foreach my $Kind (keys(%{$CompatProblems{$Interface}}))
 
6297
        {
 
6298
            foreach my $Location (keys(%{$CompatProblems{$Interface}{$Kind}}))
 
6299
            {
 
6300
                next if(not $Kinds_Locations->{$Kind}{$Location});
 
6301
                my $Type_Name = $CompatProblems{$Interface}{$Kind}{$Location}{"Type_Name"};
 
6302
                my $Signature = $CompatProblems{$Interface}{$Kind}{$Location}{"Signature"};
 
6303
                my $Parameter_Position = $CompatProblems{$Interface}{$Kind}{$Location}{"Parameter_Position"};
 
6304
                my $Priority = $CompatProblems{$Interface}{$Kind}{$Location}{"Priority"};
 
6305
                if($Type_Name eq $Target_TypeName)
 
6306
                {
 
6307
                    $FunctionNumber{$Interface} = 1;
 
6308
                    my $Path_Length = 0;
 
6309
                    while($Location =~ /\-\>/g){$Path_Length += 1;}
 
6310
                    if(($MinPath_Length eq "") or ($Path_Length<$MinPath_Length and $Priority_Value{$Priority}>$MaxPriority) or (($Location_Last =~ /RetVal/ or $Location_Last =~ /Obj/) and $Location !~ /RetVal|Obj/ and $Location !~ /\-\>/) or ($Location_Last =~ /RetVal|Obj/ and $Location_Last =~ /\-\>/ and $Location !~ /RetVal|Obj/ and $Location =~ /\-\>/))
 
6311
                    {
 
6312
                        $MinPath_Length = $Path_Length;
 
6313
                        $MaxPriority = $Priority_Value{$Priority};
 
6314
                        $Location_Last = $Location;
 
6315
                        my $Description = get_AffectDescription($Interface, $Kind, $Location);
 
6316
                        $FunctionProblem = "<span class='interface_name_black' style='padding-left:20px;'>".highLight_Signature_PPos_Italic(htmlSpecChars($Signature), $Parameter_Position, 1, 0)."</span>:<br/>"."<span class='affect_description'>".addArrows($Description)."</span><br/><div style='height:4px;'>&nbsp;</div>\n";
 
6317
                    }
 
6318
                }
 
6319
            }
 
6320
        }
 
6321
        $Affected_Interfaces .= $FunctionProblem;
 
6322
    }
 
6323
    $Affected_Interfaces .= "and other...<br/>" if(keys(%FunctionNumber)>5000);
 
6324
    if($Affected_Interfaces)
 
6325
    {
 
6326
        $Affected_Interfaces_Header = $ContentSpanStart_2."[+] affected interfaces (".keys(%FunctionNumber).")".$ContentSpanEnd;
 
6327
        $Affected_Interfaces =  $ContentDivStart.$Affected_Interfaces.$ContentDivEnd;
 
6328
    }
 
6329
    return ($Affected_Interfaces_Header, $Affected_Interfaces);
 
6330
}
 
6331
 
 
6332
my %Kind_TypeStructureChanged=(
 
6333
    "Size"=>1,
 
6334
    "Added_Member_And_Size"=>1,
 
6335
    "Added_Middle_Member_And_Size"=>1,
 
6336
    "Member_Rename"=>1,
 
6337
    "Withdrawn_Member_And_Size"=>1,
 
6338
    "Withdrawn_Member"=>1,
 
6339
    "Withdrawn_Middle_Member_And_Size"=>1,
 
6340
    "Enum_Member_Value"=>1,
 
6341
    "Enum_Member_Name"=>1,
 
6342
    "Member_Type_And_Size"=>1,
 
6343
    "Member_Type"=>1,
 
6344
    "Member_BaseType_And_Size"=>1,
 
6345
    "Member_BaseType"=>1,
 
6346
    "Member_PointerLevel"=>1,
 
6347
    "BaseType"=>1
 
6348
);
 
6349
 
 
6350
my %Kind_VirtualTableChanged=(
 
6351
    "Added_Virtual_Function"=>1,
 
6352
    "Withdrawn_Virtual_Function"=>1,
 
6353
    "Virtual_Function_Position"=>1,
 
6354
    "Virtual_Function_Redefinition"=>1,
 
6355
    "Virtual_Function_Redefinition_B"=>1
 
6356
);
 
6357
 
 
6358
sub get_AffectDescription($$$)
 
6359
{
 
6360
    my ($Interface, $Kind, $Location) = @_;
 
6361
    my $Target = $CompatProblems{$Interface}{$Kind}{$Location}{"Target"};
 
6362
    my $Old_Value = $CompatProblems{$Interface}{$Kind}{$Location}{"Old_Value"};
 
6363
    my $New_Value = $CompatProblems{$Interface}{$Kind}{$Location}{"New_Value"};
 
6364
    my $Type_Name = $CompatProblems{$Interface}{$Kind}{$Location}{"Type_Name"};
 
6365
    my $Parameter_Position = $CompatProblems{$Interface}{$Kind}{$Location}{"Parameter_Position"};
 
6366
    my $Parameter_Name = $CompatProblems{$Interface}{$Kind}{$Location}{"Parameter_Name"};
 
6367
    my $Parameter_Type_Name = $CompatProblems{$Interface}{$Kind}{$Location}{"Parameter_Type_Name"};
 
6368
    my $Member_Type_Name = $CompatProblems{$Interface}{$Kind}{$Location}{"Member_Type_Name"};
 
6369
    my $Object_Type_Name = $CompatProblems{$Interface}{$Kind}{$Location}{"Object_Type_Name"};
 
6370
    my $Return_Type_Name = $CompatProblems{$Interface}{$Kind}{$Location}{"Return_Type_Name"};
 
6371
    my $Start_Type_Name = $CompatProblems{$Interface}{$Kind}{$Location}{"Start_Type_Name"};
 
6372
    my $InitialType_Type = $CompatProblems{$Interface}{$Kind}{$Location}{"InitialType_Type"};
 
6373
    my $Parameter_Position_Str = num_to_str($Parameter_Position + 1);
 
6374
    my @Sentence_Parts = ();
 
6375
    my $Location_To_Type = $Location;
 
6376
    $Location_To_Type =~ s/\-\>[^>]+?\Z//;
 
6377
    if($Kind_VirtualTableChanged{$Kind})
 
6378
    {
 
6379
        if($Kind eq "Virtual_Function_Redefinition")
 
6380
        {
 
6381
            @Sentence_Parts = (@Sentence_Parts, "This method become virtual and will be called instead of redefined method '".highLight_Signature(htmlSpecChars($Old_Value))."'.");
 
6382
        }
 
6383
        elsif($Kind eq "Virtual_Function_Redefinition_B")
 
6384
        {
 
6385
            @Sentence_Parts = (@Sentence_Parts, "This method become non-virtual and redefined method '".highLight_Signature(htmlSpecChars($Old_Value))."' will be called instead of it.");
 
6386
        }
 
6387
        else
 
6388
        {
 
6389
            @Sentence_Parts = (@Sentence_Parts, "Call of this virtual method will result in crash of application because the layout of virtual table has been changed.");
 
6390
        }
 
6391
    }
 
6392
    elsif($Kind_TypeStructureChanged{$Kind})
 
6393
    {
 
6394
        if($Location_To_Type =~ /RetVal/)
 
6395
        {#return value
 
6396
            if($Location_To_Type =~ /\-\>/)
 
6397
            {
 
6398
                @Sentence_Parts = (@Sentence_Parts, "Member \'$Location_To_Type\' in return value");
 
6399
            }
 
6400
            else
 
6401
            {
 
6402
                @Sentence_Parts = (@Sentence_Parts, "Return value");
 
6403
            }
 
6404
        }
 
6405
        elsif($Location_To_Type =~ /Obj/)
 
6406
        {#object
 
6407
            if($Location_To_Type =~ /\-\>/)
 
6408
            {
 
6409
                @Sentence_Parts = (@Sentence_Parts, "Member \'$Location_To_Type\' in the object of this method");
 
6410
            }
 
6411
            else
 
6412
            {
 
6413
                @Sentence_Parts = (@Sentence_Parts, "Object");
 
6414
            }
 
6415
        }
 
6416
        else
 
6417
        {#parameters
 
6418
            if($Location_To_Type =~ /\-\>/)
 
6419
            {
 
6420
                @Sentence_Parts = (@Sentence_Parts, "Member \'$Location_To_Type\' of $Parameter_Position_Str parameter");
 
6421
            }
 
6422
            else
 
6423
            {
 
6424
                @Sentence_Parts = (@Sentence_Parts, "$Parameter_Position_Str parameter");
 
6425
            }
 
6426
            if($Parameter_Name)
 
6427
            {
 
6428
                @Sentence_Parts = (@Sentence_Parts, "\'$Parameter_Name\'");
 
6429
            }
 
6430
            if($InitialType_Type eq "Pointer")
 
6431
            {
 
6432
                @Sentence_Parts = (@Sentence_Parts, "(pointer)");
 
6433
            }
 
6434
        }
 
6435
        if($Start_Type_Name eq $Type_Name)
 
6436
        {
 
6437
            @Sentence_Parts = (@Sentence_Parts, "has type \'$Type_Name\'.");
 
6438
        }
 
6439
        else
 
6440
        {
 
6441
            @Sentence_Parts = (@Sentence_Parts, "has base type \'$Type_Name\'.");
 
6442
        }
 
6443
    }
 
6444
    return join(" ", @Sentence_Parts);
 
6445
}
 
6446
 
 
6447
sub create_HtmlReport()
 
6448
{
 
6449
    my $CssStyles = "<style type=\"text/css\">
 
6450
    body{font-family:Arial;}
 
6451
    hr{color:Black;background-color:Black;height:1px;border:0;}
 
6452
    span.section{font-weight:bold;cursor:pointer;margin-left:7px;font-size:16px;font-family:Arial;color:#003E69;}
 
6453
    span:hover.section{color:#336699;}
 
6454
    span.section_2{cursor:pointer;margin-left:7px;font-size:14px;font-family:Arial;color:#cc3300;}
 
6455
    span.extension{font-weight:100;font-size:16px;}
 
6456
    span.problem_exact_location{color:Red;font-size:14px;}
 
6457
    span.header_name{color:#cc3300;font-size:14px;font-family:Arial;font-weight:bold;}
 
6458
    span.header_list_elem{padding-left:10px;color:#333333;font-size:15px;font-family:Arial;}
 
6459
    span.solib_list_elem{padding-left:10px;color:#333333;font-size:15px;font-family:Arial;}
 
6460
    span.solib_name{color:Green;font-size:14px;font-family:Arial;font-weight:bold;}
 
6461
    span.interface_name{font-weight:bold;font-size:16px;font-family:Arial;color:#003E69;margin-left:7px;}
 
6462
    span.interface_name_black{font-weight:bold;font-size:15px;font-family:Arial;color:#333333;}
 
6463
    span.problem_title{color:#333333;font-weight:bold;font-size:13px;font-family:Verdana;}
 
6464
    span.problem_sub_title{color:#333333;text-decoration:none;font-weight:bold;font-size:13px;font-family:Verdana;}
 
6465
    span.problem_body{color:Black;font-size:14px;}
 
6466
    span.int_p{font-weight:normal;}
 
6467
    span.affect_description{padding-left:30px;font-size:14px;font-style:italic;line-height:13px;}
 
6468
    table.problems_table{line-height:16px;margin-left:15px;margin-top:3px;border-collapse:collapse;}
 
6469
    table.problems_table td{border-style:solid;border-color:Gray;border-width:1px;}
 
6470
    td.table_header{background-color:#eeeeee;}
 
6471
    td.summary_item{font-size:15px;font-family:Arial;text-align:left;}
 
6472
    td.summary_item_value{padding-left:5px;padding-right:5px;width:35px;text-align:right;}
 
6473
    span.problem_num{color:#333333;font-weight:bold;font-size:13px;font-family:Verdana;}
 
6474
    span.mangled{padding-left:15px;font-size:13px;cursor:text;color:#444444;}
 
6475
    span.symver{color:#555555;font-size:13px;white-space:nowrap;}
 
6476
    span.color_param{font-style:italic;color:Brown;}
 
6477
    span.focus_param{font-style:italic;color:Red;}</style>";
 
6478
    
 
6479
    my $JScripts = "<script type=\"text/javascript\" language=\"JavaScript\">
 
6480
    function showContent(header, id)   {
 
6481
        e = document.getElementById(id);
 
6482
        if(e.style.display == 'none')
 
6483
        {
 
6484
            e.style.display = '';
 
6485
            e.style.visibility = 'visible';
 
6486
            header.innerHTML = header.innerHTML.replace(/\\\[[^0-9 ]\\\]/gi,\"[&minus;]\");
 
6487
        }
 
6488
        else
 
6489
        {
 
6490
            e.style.display = 'none';
 
6491
            e.style.visibility = 'hidden';
 
6492
            header.innerHTML = header.innerHTML.replace(/\\\[[^0-9 ]\\\]/gi,\"[+]\");
 
6493
        }
 
6494
    }</script>";
 
6495
    
 
6496
    writeFile("$REPORT_PATH/abi_compat_report.html", "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />
 
6497
    <title>ABI compliance report for the library $TargetLibraryName from version ".$Descriptor{1}{"Version"}." to ".$Descriptor{2}{"Version"}." on ".getArch()."\n</title>\n<!--Styles-->\n".$CssStyles."\n<!--Styles_End-->\n"."<!--JScripts-->\n".$JScripts."\n<!--JScripts_End-->\n</head>\n<body>\n<div><a name='Top'></a>\n".get_Report_Header()."<br/>\n".get_Summary()."<br/>\n".get_Report_Added().get_Report_Withdrawn().get_Report_TypeProblems("High").get_Report_TypeProblems("Medium").get_Report_TypeProblems("Low").get_Report_InterfaceProblems("High").get_Report_InterfaceProblems("Medium").get_Report_InterfaceProblems("Low").get_Report_ChangedConstants().get_SourceInfo()."</div>\n"."<br/><br/><br/><hr/><div style='width:100%;font-family:Arial;font-size:11px;' align='right'><i>Generated on ".(localtime time)." for <span style='font-weight:bold'>$TargetLibraryName</span> by <a href='http://ispras.linux-foundation.org/index.php/ABI_compliance_checker'>ABI-compliance-checker</a> $ABI_COMPLIANCE_CHECKER_VERSION &nbsp;</i></div>\n<div style='height:999px;'></div>\n</body></html>");
 
6498
}
 
6499
 
 
6500
sub trivialCmp($$)
 
6501
{
 
6502
    if(int($_[0]) > int($_[1]))
 
6503
    {
 
6504
        return 1;
 
6505
    }
 
6506
    elsif($_[0] eq $_[1])
 
6507
    {
 
6508
        return 0;
 
6509
    }
 
6510
    else
 
6511
    {
 
6512
        return -1;
 
6513
    }
 
6514
}
 
6515
 
 
6516
sub addArrows($)
 
6517
{
 
6518
    my $Text = $_[0];
 
6519
    #$Text =~ s/\-\>/&#8594;/g;
 
6520
    $Text =~ s/\-\>/&minus;&gt;/g;
 
6521
    return $Text;
 
6522
}
 
6523
 
 
6524
sub insertIDs($)
 
6525
{
 
6526
    my $Text = $_[0];
 
6527
    while($Text =~ /CONTENT_ID/)
 
6528
    {
 
6529
        if(int($Content_Counter)%2)
 
6530
        {
 
6531
            $ContentID -= 1;
 
6532
        }
 
6533
        $Text =~ s/CONTENT_ID/c_$ContentID/;
 
6534
        $ContentID += 1;
 
6535
        $Content_Counter += 1;
 
6536
    }
 
6537
    return $Text;
 
6538
}
 
6539
 
 
6540
sub restrict_num_decimal_digits
 
6541
{
 
6542
  my $num=shift;
 
6543
  my $digs_to_cut=shift;
 
6544
 
 
6545
  if ($num=~/\d+\.(\d){$digs_to_cut,}/)
 
6546
  {
 
6547
    $num=sprintf("%.".($digs_to_cut-1)."f", $num);
 
6548
  }
 
6549
  return $num;
 
6550
}
 
6551
 
 
6552
sub parse_constants()
 
6553
{
 
6554
    my $CurHeader = "";
 
6555
    foreach my $String (split("\n", $ConstantsSrc{$Version}))
 
6556
    {#detecting public and private constants using sources
 
6557
        if($String=~/#[ \t]+\d+[ \t]+\"(.+)\"/)
 
6558
        {
 
6559
            $CurHeader=$1;
 
6560
        }
 
6561
        if($String=~/\#[ \t]*define[ \t]+([_A-Z]+)[ \t]+(.*)[ \t]*\Z/)
 
6562
        {
 
6563
            my ($Name, $Value) = ($1, $2);
 
6564
            if(not $Constants{$Version}{$Name}{"Access"})
 
6565
            {
 
6566
                $Constants{$Version}{$Name}{"Access"} = "public";
 
6567
                $Constants{$Version}{$Name}{"Value"} = $Value;
 
6568
                $Constants{$Version}{$Name}{"Header"} = get_FileName($CurHeader);
 
6569
            }
 
6570
        }
 
6571
        elsif($String=~/\#[ \t]*undef[ \t]+([_A-Z]+)[ \t]*/)
 
6572
        {
 
6573
            my $Name = $1;
 
6574
            $Constants{$Version}{$Name}{"Access"} = "private";
 
6575
        }
 
6576
    }
 
6577
    foreach my $Constant (keys(%{$Constants{$Version}}))
 
6578
    {
 
6579
        if(($Constants{$Version}{$Constant}{"Access"} eq "private") or not $Constants{$Version}{$Constant}{"Value"}
 
6580
        or $Constant=~/_h\Z/i)
 
6581
        {
 
6582
            delete($Constants{$Version}{$Constant});
 
6583
        }
 
6584
        else
 
6585
        {
 
6586
            delete($Constants{$Version}{$Constant}{"Access"});
 
6587
        }
 
6588
    }
 
6589
}
 
6590
 
 
6591
sub mergeConstants()
 
6592
{
 
6593
    return if(defined $AppPath);
 
6594
    foreach my $Constant (keys(%{$Constants{1}}))
 
6595
    {
 
6596
        my $Old_Value = $Constants{1}{$Constant}{"Value"};
 
6597
        my $New_Value = $Constants{2}{$Constant}{"Value"};
 
6598
        my $Header = $Constants{1}{$Constant}{"Header"};
 
6599
        if($New_Value and $Old_Value and ($New_Value ne $Old_Value))
 
6600
        {
 
6601
            %{$ConstantProblems{$Constant}} = (
 
6602
                "Old_Value"=>$Old_Value,
 
6603
                "New_Value"=>$New_Value,
 
6604
                "Header"=>$Header
 
6605
            );
 
6606
        }
 
6607
    }
 
6608
}
 
6609
 
 
6610
sub mergeHeaders_Separately()
 
6611
{
 
6612
    system("mkdir", "-p", "header_compile_errors/".$TargetLibraryName);
 
6613
    system("rm", "-fr", $ERR_PATH{1}, $ERR_PATH{2});
 
6614
    my ($Header_Num, $Prev_Header_Length) = (0, 0);
 
6615
    my $All_Count = keys(%{$Headers{1}});
 
6616
        foreach my $Header_Dest (sort {int($Headers{1}{$a}{"Position"})<=>int($Headers{1}{$b}{"Position"})} keys(%{$Headers{1}}))
 
6617
        {
 
6618
        my $Header_Name = $Headers{1}{$Header_Dest}{"Name"};
 
6619
        my $Dest_Count = keys(%{$HeaderName_Destinations{1}{$Header_Name}});
 
6620
        my $Identity = $Headers{1}{$Header_Dest}{"Identity"};
 
6621
        my $Dest_Comment = ($Dest_Count>1 and $Identity=~/\//)?" ($Identity)":"";
 
6622
        print get_one_step_title($Header_Name.$Dest_Comment, $Header_Num, $All_Count, $Prev_Header_Length, 1)."\r";
 
6623
                %TypeDescr = ();
 
6624
                %FuncDescr = ();
 
6625
                %ClassFunc = ();
 
6626
        %ClassVirtFunc = ();
 
6627
                %LibInfo = ();
 
6628
        %CompleteSignature = ();
 
6629
        %Cache = ();
 
6630
        $Version = 1;
 
6631
                parseHeader($Header_Dest);
 
6632
        $Version = 2;
 
6633
        my $PairHeaderDest = find_pair_header($Header_Dest);
 
6634
        if(not $PairHeaderDest)
 
6635
        {
 
6636
            $Header_Num += 1;
 
6637
            next;
 
6638
        }
 
6639
        parseHeader($PairHeaderDest);
 
6640
        mergeSignatures();
 
6641
        mergeConstants();
 
6642
        $Header_Num += 1;
 
6643
        $Prev_Header_Length = length($Header_Name.$Dest_Comment);
 
6644
        }
 
6645
    print get_one_step_title("", $All_Count, $All_Count, $Prev_Header_Length, 0)."\n";
 
6646
}
 
6647
 
 
6648
sub get_one_step_title($$$$$)
 
6649
{
 
6650
    my ($Header_Name, $Num, $All_Count, $SpacesAtTheEnd, $ShowCurrent) = @_;
 
6651
    my ($Spaces_1, $Spaces_2, $Title) = ();
 
6652
    my $Title_1 = "checking headers: $Num/$All_Count [".restrict_num_decimal_digits($Num*100/$All_Count, 3)."%]".(($ShowCurrent)?",":"");
 
6653
    foreach (0 .. length("checking headers: ")+length($All_Count)*2+11 - length($Title_1))
 
6654
    {
 
6655
        $Spaces_1 .= " ";
 
6656
    }
 
6657
    $Title .= $Title_1.$Spaces_1;
 
6658
    if($ShowCurrent)
 
6659
    {
 
6660
        my $Title_2 = "current: $Header_Name";
 
6661
        foreach (0 .. $SpacesAtTheEnd - length($Header_Name)-1)
 
6662
        {
 
6663
            $Spaces_2 .= " ";
 
6664
        }
 
6665
        $Title .= $Title_2.$Spaces_2;
 
6666
    }
 
6667
    else
 
6668
    {
 
6669
        foreach (0 .. $SpacesAtTheEnd + length(" current: ") - 1)
 
6670
        {
 
6671
            $Title .= " ";
 
6672
        }
 
6673
    }
 
6674
    return $Title."\r";
 
6675
}
 
6676
 
 
6677
sub find_pair_header($)
 
6678
{
 
6679
    my $Header_Dest = $_[0];
 
6680
    my $Header_Name = $Headers{1}{$Header_Dest}{"Name"};
 
6681
    my $Identity = $Headers{1}{$Header_Dest}{"Identity"};
 
6682
    my @Pair_Dest = keys(%{$HeaderName_Destinations{2}{$Header_Name}});
 
6683
    if($#Pair_Dest==0)
 
6684
    {
 
6685
        return $Pair_Dest[0];
 
6686
    }
 
6687
    elsif($#Pair_Dest==-1)
 
6688
    {
 
6689
        return "";
 
6690
    }
 
6691
    else
 
6692
    {
 
6693
        foreach my $Pair_Dest (@Pair_Dest)
 
6694
        {
 
6695
            my $Pair_Identity = $Headers{2}{$Pair_Dest}{"Identity"};
 
6696
            if($Identity eq $Pair_Identity)
 
6697
            {
 
6698
                return $Pair_Dest;
 
6699
            }
 
6700
        }
 
6701
        return "";
 
6702
    }
 
6703
}
 
6704
 
 
6705
sub getSymbols($)
 
6706
{
 
6707
    my $LibVersion = $_[0];
 
6708
    my @SoLibPaths = getSoPaths($LibVersion);
 
6709
    if($#SoLibPaths eq -1 and not $CheckHeadersOnly)
 
6710
    {
 
6711
        print "ERROR: shared objects were not found\n";
 
6712
        exit(1);
 
6713
    }
 
6714
    foreach my $SoLibPath (@SoLibPaths)
 
6715
    {
 
6716
        getSymbols_Lib($LibVersion, $SoLibPath, 0);
 
6717
    }
 
6718
}
 
6719
 
 
6720
sub separatePath($)
 
6721
{
 
6722
    return ("", $_[0])if($_[0] !~ /\//);
 
6723
    if($_[0] =~ /\A(.*\/)([^\/]*)\Z/)
 
6724
    {
 
6725
        return ($1, $2);
 
6726
    }
 
6727
    else
 
6728
    {
 
6729
        return ("", $_[0]);
 
6730
    }
 
6731
}
 
6732
 
 
6733
sub translateSymbols($)
 
6734
{
 
6735
    my $LibVersion = $_[0];
 
6736
    my (@MnglNames, @UnMnglNames) = ();
 
6737
    foreach my $Interface (sort keys(%{$Interface_Library{$LibVersion}}))
 
6738
    {
 
6739
        if($Interface =~ /\A_Z/)
 
6740
        {
 
6741
            $Interface =~ s/[\@]+(.*)\Z//;
 
6742
            push(@MnglNames, $Interface);
 
6743
        }
 
6744
        else
 
6745
        {
 
6746
            $tr_name{$Interface} = $Interface;
 
6747
            $mangled_name{$tr_name{$Interface}} = $Interface;
 
6748
        }
 
6749
    }
 
6750
    if($#MnglNames > -1)
 
6751
    {
 
6752
        @UnMnglNames = reverse(unmangleArray(@MnglNames));
 
6753
        foreach my $Interface (sort keys(%{$Interface_Library{$LibVersion}}))
 
6754
        {
 
6755
            if($Interface =~ /\A_Z/)
 
6756
            {
 
6757
                $Interface =~ s/[\@]+(.*)\Z//;
 
6758
                $tr_name{$Interface} = pop(@UnMnglNames);
 
6759
                $mangled_name{correctName($tr_name{$Interface})} = $Interface;
 
6760
            }
 
6761
        }
 
6762
    }
 
6763
}
 
6764
 
 
6765
sub detectAdded()
 
6766
{
 
6767
    #detecting added
 
6768
    foreach my $Interface (keys(%{$Interface_Library{2}}))
 
6769
    {
 
6770
        if(not $Interface_Library{1}{$Interface})
 
6771
        {
 
6772
            $AddedInt{$Interface} = 1;
 
6773
            my ($MnglName, $SymbolVersion) = ($Interface, "");
 
6774
            if($Interface =~ /\A(.+)[\@]+(.+)\Z/)
 
6775
            {
 
6776
                ($MnglName, $SymbolVersion) = ($1, $2);
 
6777
            }
 
6778
            $FuncAttr{2}{$Interface}{"Signature"} = $tr_name{$MnglName}.(($SymbolVersion)?"\@".$SymbolVersion:"");
 
6779
        }
 
6780
    }
 
6781
}
 
6782
 
 
6783
sub detectWithdrawn()
 
6784
{
 
6785
    #detecting withdrawn
 
6786
    foreach my $Interface (keys(%{$Interface_Library{1}}))
 
6787
    {
 
6788
        if(not $Interface_Library{2}{$Interface} and not $Interface_Library{2}{$SymVer{2}{$Interface}})
 
6789
        {
 
6790
            next if($DepInterfaces{2}{$Interface});
 
6791
            $WithdrawnInt{$Interface} = 1;
 
6792
            my ($MnglName, $SymbolVersion) = ($Interface, "");
 
6793
            if($Interface =~ /\A(.+)[\@]+(.+)\Z/)
 
6794
            {
 
6795
                ($MnglName, $SymbolVersion) = ($1, $2);
 
6796
            }
 
6797
            $FuncAttr{1}{$Interface}{"Signature"} = $tr_name{$MnglName}.(($SymbolVersion)?"\@".$SymbolVersion:"");
 
6798
        }
 
6799
    }
 
6800
}
 
6801
 
 
6802
sub isRecurLib($)
 
6803
{
 
6804
    my $LibName = $_[0];
 
6805
    foreach my $LibNameInStack (@RecurLib)
 
6806
    {
 
6807
        if($LibName eq $LibNameInStack)
 
6808
        {
 
6809
            return 1;
 
6810
        }
 
6811
    }
 
6812
    return 0;
 
6813
}
 
6814
 
 
6815
sub getSymbols_App($)
 
6816
{
 
6817
    my $Path = $_[0];
 
6818
    return () if(not $Path or not -f $Path);
 
6819
    my @Ints = ();
 
6820
    open(APP, "readelf -WhlSsdA $Path |");
 
6821
    my $symtab=0;#indicates that we are processing 'symtab' section of 'readelf' output
 
6822
    while(<APP>)
 
6823
    {
 
6824
        if($symtab == 1) {
 
6825
            #do nothing with symtab (but there are some plans for the future)
 
6826
            next;
 
6827
        }
 
6828
        if( /'.dynsym'/ ) {
 
6829
            $symtab=0;
 
6830
        }
 
6831
        elsif( /'.symtab'/ ) {
 
6832
            $symtab=1;
 
6833
        }
 
6834
        elsif(my ($fullname, $idx, $Ndx) = readlile_ELF($_)) {
 
6835
            if( $Ndx eq "UND" ) {
 
6836
                #only exported interfaces
 
6837
                push(@Ints, $fullname);
 
6838
            }
 
6839
        }
 
6840
    }
 
6841
    close(APP);
 
6842
    return @Ints;
 
6843
}
 
6844
 
 
6845
sub readlile_ELF($)
 
6846
{
 
6847
    if($_[0]=~/\s*\d+:\s+(\w*)\s+\w+\s+(\w+)\s+(\w+)\s+(\w+)\s+(\w+)\s((\w|@|\.)+)/)
 
6848
    {#the line of 'readelf' output corresponding to the interface
 
6849
        my ($value, $type, $bind, $vis, $Ndx, $fullname)=($1, $2, $3, $4, $5, $6);
 
6850
        if(($bind ne "WEAK") and ($bind ne "GLOBAL")) {
 
6851
            return ();
 
6852
        }
 
6853
        if(($type ne "FUNC") and ($type ne "OBJECT") and ($type ne "COMMON")) {
 
6854
            return ();
 
6855
        }
 
6856
        if($vis ne "DEFAULT") {
 
6857
            return ();
 
6858
        }
 
6859
        if(($Ndx eq "ABS") and ($value !~ /\D|1|2|3|4|5|6|7|8|9/)) {
 
6860
            return ();
 
6861
        }
 
6862
        return ($fullname, $value, $Ndx);
 
6863
    }
 
6864
    else
 
6865
    {
 
6866
        return ();
 
6867
    }
 
6868
}
 
6869
 
 
6870
sub getSymbols_Lib($$$)
 
6871
{
 
6872
    my ($LibVersion, $Lib_Path, $IsNeededLib) = @_;
 
6873
    return if(not $Lib_Path or not -f $Lib_Path);
 
6874
    my ($Lib_Dir, $Lib_SoName) = separatePath($Lib_Path);
 
6875
    return if($CheckedSoLib{$LibVersion}{$Lib_SoName} and $IsNeededLib);
 
6876
    return if(isRecurLib($Lib_SoName) or $#RecurLib>=1);
 
6877
    $CheckedSoLib{$LibVersion}{$Lib_SoName} = 1;
 
6878
    push(@RecurLib, $Lib_SoName);
 
6879
    my (%Value_Interface, %Interface_Value, %NeededLib) = ();
 
6880
    if(not $IsNeededLib)
 
6881
    {
 
6882
        $SoNames_All{$LibVersion}{$Lib_SoName} = 1;
 
6883
    }
 
6884
    open(SOLIB, "readelf -WhlSsdA $Lib_Path |");
 
6885
    my $symtab=0;#indicates that we are processing 'symtab' section of 'readelf' output
 
6886
    while(<SOLIB>)
 
6887
    {
 
6888
        if($symtab == 1) {
 
6889
            #do nothing with symtab (but there are some plans for the future)
 
6890
            next;
 
6891
        }
 
6892
        if(/'.dynsym'/) {
 
6893
            $symtab=0;
 
6894
        }
 
6895
        elsif(/'.symtab'/) {
 
6896
            $symtab=1;
 
6897
        }
 
6898
        elsif(/NEEDED.+\[([^\[\]]+)\]/)
 
6899
        {
 
6900
            $NeededLib{$1} = 1;
 
6901
        }
 
6902
        elsif(my ($fullname, $idx, $Ndx) = readlile_ELF($_)) {
 
6903
            if( $Ndx eq "UND" ) {
 
6904
                #ignore interfaces that are exported form somewhere else
 
6905
                next;
 
6906
            }
 
6907
            my ($realname, $version) = ($fullname, "");
 
6908
            if($fullname =~ /\A([^@]+)[\@]+([^@]+)\Z/)
 
6909
            {
 
6910
                ($realname, $version) = ($1, $2);
 
6911
            }
 
6912
            next if(defined $InterfacesListPath and not $InterfacesList{$realname});
 
6913
            next if(defined $AppPath and not $InterfacesList_App{$realname});
 
6914
            if($IsNeededLib)
 
6915
            {
 
6916
                $DepInterfaces{$LibVersion}{$fullname} = 1;
 
6917
            }
 
6918
            if(not $IsNeededLib or (defined $InterfacesListPath and $InterfacesList{$realname}) or (defined $AppPath and $InterfacesList_App{$realname}))
 
6919
            {
 
6920
                $Interface_Library{$LibVersion}{$fullname} = $Lib_SoName;
 
6921
                $Library_Interface{$LibVersion}{$Lib_SoName}{$fullname} = 1;
 
6922
                $Interface_Value{$LibVersion}{$fullname} = $idx;
 
6923
                $Value_Interface{$LibVersion}{$idx}{$fullname} = 1;
 
6924
                if(not $Language{$LibVersion}{$Lib_SoName})
 
6925
                {
 
6926
                    if($fullname =~ /\A_Z[A-Z]*[0-9]+/)
 
6927
                    {
 
6928
                        $Language{$LibVersion}{$Lib_SoName} = "C++";
 
6929
                    }
 
6930
                }
 
6931
            }
 
6932
        }
 
6933
    }
 
6934
    close(SOLIB);
 
6935
    if(not $IsNeededLib)
 
6936
    {
 
6937
        foreach my $Interface_Name (keys(%{$Interface_Library{$LibVersion}}))
 
6938
        {
 
6939
            next if($Interface_Name !~ /\@/);
 
6940
            my $Interface_SymName = "";
 
6941
            foreach my $InterfaceName_SameValue (keys(%{$Value_Interface{$LibVersion}{$Interface_Value{$LibVersion}{$Interface_Name}}}))
 
6942
            {
 
6943
                if($InterfaceName_SameValue ne $Interface_Name)
 
6944
                {
 
6945
                    $SymVer{$LibVersion}{$InterfaceName_SameValue} = $Interface_Name;
 
6946
                    $Interface_SymName = $InterfaceName_SameValue;
 
6947
                    last;
 
6948
                }
 
6949
            }
 
6950
            if(not $Interface_SymName)
 
6951
            {
 
6952
                if($Interface_Name =~ /\A([^@]*)[\@]+([^@]*)\Z/ and not $SymVer{$LibVersion}{$1})
 
6953
                {
 
6954
                    $SymVer{$LibVersion}{$1} = $Interface_Name;
 
6955
                }
 
6956
            }
 
6957
        }
 
6958
    }
 
6959
    foreach my $SoLib (keys(%NeededLib))
 
6960
    {
 
6961
        getSymbols_Lib($LibVersion, find_solib_path($Lib_Dir, $SoLib), 1);
 
6962
    }
 
6963
    pop(@RecurLib);
 
6964
}
 
6965
 
 
6966
sub find_solib_path($$)
 
6967
{
 
6968
    my ($Dir, $SoName) = @_;
 
6969
    $Dir=~s/\/\Z//g;
 
6970
    if(-f $Dir."/".$SoName)
 
6971
    {
 
6972
        return $Dir."/".$SoName;
 
6973
    }
 
6974
    else
 
6975
    {
 
6976
        return $SoLib_DefaultPath{$SoName};
 
6977
    }
 
6978
}
 
6979
 
 
6980
sub symbols_Preparation($)
 
6981
{#recreate %SoNames and %Language using info from *.abi file
 
6982
    my $LibVersion = $_[0];
 
6983
    foreach my $Lib_SoName (keys(%{$Library_Interface{$LibVersion}}))
 
6984
    {
 
6985
        foreach my $Interface_Name (keys(%{$Library_Interface{$LibVersion}{$Lib_SoName}}))
 
6986
        {
 
6987
            $Interface_Library{$LibVersion}{$Interface_Name} = $Lib_SoName;
 
6988
            $SoNames_All{$LibVersion}{$Lib_SoName} = 1;
 
6989
            if(not $Language{$LibVersion}{$Lib_SoName})
 
6990
            {
 
6991
                if($Interface_Name =~ /\A_Z[A-Z]*[0-9]+/)
 
6992
                {
 
6993
                    $Language{$LibVersion}{$Lib_SoName} = "C++";
 
6994
                }
 
6995
            }
 
6996
        }
 
6997
    }
 
6998
}
 
6999
 
 
7000
sub getSoPaths($)
 
7001
{
 
7002
    my $LibVersion = $_[0];
 
7003
    my @SoPaths = ();
 
7004
    foreach my $Dest (split("\n", $Descriptor{$LibVersion}{"Libs"}))
 
7005
    {
 
7006
        $Dest =~ s/\A\s+|\s+\Z//g;
 
7007
        next if(not $Dest);
 
7008
        if(not -e $Dest)
 
7009
        {
 
7010
            print "ERROR: can't access \'$Dest\'\n";
 
7011
        }
 
7012
        my @SoPaths_Dest = getSOPaths_Dest($Dest);
 
7013
        foreach (@SoPaths_Dest)
 
7014
        {
 
7015
            push(@SoPaths, $_);
 
7016
        }
 
7017
    }
 
7018
    return @SoPaths;
 
7019
}
 
7020
 
 
7021
sub getSOPaths_Dest($)
 
7022
{
 
7023
    my $Dest = $_[0];
 
7024
    if(-f $Dest)
 
7025
    {
 
7026
        return $Dest;
 
7027
    }
 
7028
    my @AllObjects = cmd_find($Dest,"f","*\.so*");
 
7029
    my @SOPaths = ();
 
7030
    foreach my $SharedObject (@AllObjects)
 
7031
    {
 
7032
        if(cmd_file($SharedObject) =~ /shared object/)
 
7033
        {
 
7034
            @SOPaths = (@SOPaths, $SharedObject);
 
7035
        }
 
7036
    }
 
7037
    return @SOPaths;
 
7038
}
 
7039
 
 
7040
sub genDescriptorTemplate()
 
7041
{
 
7042
    writeFile("library-descriptor.xml", $Descriptor_Template."\n");
 
7043
    print "descriptor template named 'library-descriptor.xml' has been generated in the current directory\n";
 
7044
}
 
7045
 
 
7046
sub detectPointerSize()
 
7047
{
 
7048
    `mkdir -p temp`;
 
7049
    writeFile("temp/get_pointer_size.c", "#include <stdio.h>
 
7050
int main()
 
7051
{
 
7052
    printf(\"\%d\", sizeof(int*));
 
7053
    return 0;
 
7054
}\n");
 
7055
    system("gcc temp/get_pointer_size.c -o temp/get_pointer_size");
 
7056
    $POINTER_SIZE = `./temp/get_pointer_size`;
 
7057
    `rm -fr temp`;
 
7058
}
 
7059
 
 
7060
sub data_Preparation($)
 
7061
{
 
7062
    my $LibVersion = $_[0];
 
7063
    if($Descriptor{$LibVersion}{"Path"} =~ /\.abi\.tar\.gz/)
 
7064
    {
 
7065
        my $FileName = cmd_tar($Descriptor{$LibVersion}{"Path"});
 
7066
        if($FileName =~ /\.abi/)
 
7067
        {
 
7068
            chomp($FileName);
 
7069
            my $LibraryABI = eval readFile($FileName);
 
7070
            system("rm", "-f", $FileName);
 
7071
            $TypeDescr{$LibVersion} = $LibraryABI->{"TypeDescr"};
 
7072
            $FuncDescr{$LibVersion} = $LibraryABI->{"FuncDescr"};
 
7073
            $Library_Interface{$LibVersion} = $LibraryABI->{"Interfaces"};
 
7074
            $SymVer{$LibVersion} = $LibraryABI->{"SymVer"};
 
7075
            $Tid_TDid{$LibVersion} = $LibraryABI->{"Tid_TDid"};
 
7076
            $Descriptor{$LibVersion}{"Version"} = $LibraryABI->{"LibraryVersion"};
 
7077
            $OpaqueTypes{$LibVersion} = $LibraryABI->{"OpaqueTypes"};
 
7078
            $InternalInterfaces{$LibVersion} = $LibraryABI->{"InternalInterfaces"};
 
7079
            $Headers{$LibVersion} = $LibraryABI->{"Headers"};
 
7080
            $SoNames_All{$LibVersion} = $LibraryABI->{"SharedObjects"};
 
7081
            $Constants{$LibVersion} = $LibraryABI->{"Constants"};
 
7082
            if($LibraryABI->{"ABI_COMPLIANCE_CHECKER_VERSION"} ne $ABI_COMPLIANCE_CHECKER_VERSION)
 
7083
            {
 
7084
                print "ERROR: incompatible version of specified ABI dump (allowed only $ABI_COMPLIANCE_CHECKER_VERSION)\n";
 
7085
                exit(1);
 
7086
            }
 
7087
            foreach my $Destination (keys(%{$Headers{$LibVersion}}))
 
7088
            {
 
7089
                my $Header = get_FileName($Destination);
 
7090
                $HeaderName_Destinations{$LibVersion}{$Header}{$Destination} = 1;
 
7091
            }
 
7092
            symbols_Preparation($LibVersion);
 
7093
        }
 
7094
    }
 
7095
    elsif($Descriptor{$LibVersion}{"Path"} =~ /\.tar\.gz\Z/)
 
7096
    {
 
7097
        print "ERROR: descriptor must be an XML file or '*.abi.tar.gz' ABI dump\n";
 
7098
        exit(1);
 
7099
    }
 
7100
    else
 
7101
    {
 
7102
        readDescriptor($LibVersion);
 
7103
        if(not $CheckHeadersOnly)
 
7104
        {
 
7105
            getSymbols($LibVersion);
 
7106
        }
 
7107
        headerSearch($LibVersion);
 
7108
    }
 
7109
}
 
7110
 
 
7111
sub dump_sorting($)
 
7112
{
 
7113
    my $hash = $_[0];
 
7114
    if((keys(%{$hash}))[0] =~ /\A[0-9]+\Z/)
 
7115
    {
 
7116
        return [sort {int($a) <=> int($b)} keys %{$hash}];
 
7117
    }
 
7118
    else
 
7119
    {
 
7120
        return [sort {$a cmp $b} keys %{$hash}];
 
7121
    }
 
7122
}
 
7123
 
 
7124
sub get_solib_default_paths()
 
7125
{
 
7126
    foreach my $Line (split("\n", `ldconfig -p`))
 
7127
    {
 
7128
        if($Line=~/\A[ \t]*([^ \t]+) .* \=\> (.+)\Z/)
 
7129
        {
 
7130
            $SoLib_DefaultPath{$1} = $2;
 
7131
        }
 
7132
    }
 
7133
}
 
7134
 
 
7135
sub scenario()
 
7136
{
 
7137
    if(defined $Help)
 
7138
    {
 
7139
        HELP_MESSAGE();
 
7140
        exit(0);
 
7141
    }
 
7142
    if(defined $ShowVersion)
 
7143
    {
 
7144
        print "ABI Compliance Checker $ABI_COMPLIANCE_CHECKER_VERSION\nCopyright (C) The Linux Foundation\nCopyright (C) Institute for System Programming, RAS\nLicense GPLv2: GNU GPL version 2 <http://www.gnu.org/licenses/>\nThis program is free software: you can redistribute it and/or modify it.\n\nWritten by Andrey Ponomarenko.\n";
 
7145
        exit(0);
 
7146
    }
 
7147
    $Data::Dumper::Sortkeys = \&dump_sorting;
 
7148
    if(defined $TestSystem)
 
7149
    {
 
7150
        testSystem_cpp();
 
7151
        testSystem_c();
 
7152
        exit(0);
 
7153
    }
 
7154
    if($GenerateDescriptor)
 
7155
    {
 
7156
        genDescriptorTemplate();
 
7157
        exit(0);
 
7158
    }
 
7159
    if(not defined $TargetLibraryName)
 
7160
    {
 
7161
        print "select library name (option -l <name>)\n";
 
7162
        exit(1);
 
7163
    }
 
7164
    if(defined $InterfacesListPath)
 
7165
    {
 
7166
        if(not -f $InterfacesListPath)
 
7167
        {
 
7168
            print "ERROR: can't access file $InterfacesListPath\n";
 
7169
            exit(1);
 
7170
        }
 
7171
        foreach my $Interface (split("\n", readFile($InterfacesListPath)))
 
7172
        {
 
7173
            $InterfacesList{$Interface} = 1;
 
7174
        }
 
7175
    }
 
7176
    if($AppPath)
 
7177
    {
 
7178
        if(-f $AppPath)
 
7179
        {
 
7180
            foreach my $Interface (getSymbols_App($AppPath))
 
7181
            {
 
7182
                $InterfacesList_App{$Interface} = 1;
 
7183
            }
 
7184
        }
 
7185
        else
 
7186
        {
 
7187
            print "ERROR: can't access file \'$AppPath\'\n";
 
7188
            exit(1);
 
7189
        }
 
7190
    }
 
7191
    get_solib_default_paths();
 
7192
    if($DumpInfo_DescriptorPath)
 
7193
    {
 
7194
        if(not -f $DumpInfo_DescriptorPath)
 
7195
        {
 
7196
            print "ERROR: can't access file \'$DumpInfo_DescriptorPath\'\n";
 
7197
            exit(1);
 
7198
        }
 
7199
        $Descriptor{1}{"Path"} = $DumpInfo_DescriptorPath;
 
7200
        readDescriptor(1);
 
7201
        detectPointerSize();
 
7202
        getSymbols(1);
 
7203
        translateSymbols(1);
 
7204
        headerSearch(1);
 
7205
        parseHeaders_AllInOne(1);
 
7206
        cleanData(1);
 
7207
        my %LibraryABI = ();
 
7208
        print "creating library ABI info dump ...\n";
 
7209
        $LibraryABI{"TypeDescr"} = $TypeDescr{1};
 
7210
        $LibraryABI{"FuncDescr"} = $FuncDescr{1};
 
7211
        $LibraryABI{"Interfaces"} = $Library_Interface{1};
 
7212
        $LibraryABI{"SymVer"} = $SymVer{1};
 
7213
        $LibraryABI{"LibraryVersion"} = $Descriptor{1}{"Version"};
 
7214
        $LibraryABI{"Library"} = $TargetLibraryName;
 
7215
        $LibraryABI{"SharedObjects"} = $SoNames_All{1};
 
7216
        $LibraryABI{"Tid_TDid"} = $Tid_TDid{1};
 
7217
        $LibraryABI{"OpaqueTypes"} = $OpaqueTypes{1};
 
7218
        $LibraryABI{"InternalInterfaces"} = $InternalInterfaces{1};
 
7219
        $LibraryABI{"Headers"} = $Headers{1};
 
7220
        $LibraryABI{"Constants"} = $Constants{1};
 
7221
        $LibraryABI{"ABI_COMPLIANCE_CHECKER_VERSION"} = $ABI_COMPLIANCE_CHECKER_VERSION;
 
7222
        my $InfoDump_FilePath = "abi_dumps/$TargetLibraryName";
 
7223
        my $InfoDump_FileName = $TargetLibraryName."_".$Descriptor{1}{"Version"}.".abi";
 
7224
        system("mkdir", "-p", $InfoDump_FilePath);
 
7225
        system("rm", "-f", $InfoDump_FilePath."/".$InfoDump_FileName.".tar.gz");
 
7226
        writeFile("$InfoDump_FilePath/$InfoDump_FileName", Dumper(\%LibraryABI));
 
7227
        system("cd ".esc($InfoDump_FilePath)." && tar -cf ".esc($InfoDump_FileName).".tar ".esc($InfoDump_FileName));
 
7228
        system("cd ".esc($InfoDump_FilePath)." && gzip ".esc($InfoDump_FileName).".tar --best");
 
7229
        system("rm", "-f", $InfoDump_FilePath."/".$InfoDump_FileName);
 
7230
        if($?)
 
7231
        {
 
7232
            print "ERROR: can't create library ABI info dump\n";
 
7233
            exit(1);
 
7234
        }
 
7235
        else
 
7236
        {
 
7237
            print "see library ABI info dump in \'$InfoDump_FilePath/$InfoDump_FileName\.tar\.gz\': use it instead of library version descriptor on other machine\n";
 
7238
            exit(0);
 
7239
        }
 
7240
    }
 
7241
    if(not $Descriptor{1}{"Path"})
 
7242
    {
 
7243
        print "select 1st library descriptor (option -d1 <path>)\n";
 
7244
        exit(1);
 
7245
    }
 
7246
    if(not -f $Descriptor{1}{"Path"})
 
7247
    {
 
7248
        print "ERROR: descriptor d1 does not exist, incorrect file path '".$Descriptor{1}{"Path"}."'\n";
 
7249
        exit(1);
 
7250
    }
 
7251
    if(not $Descriptor{2}{"Path"})
 
7252
    {
 
7253
        print "select 2nd library descriptor (option -d2 <path>)\n";
 
7254
        exit(1);
 
7255
    }
 
7256
    if(not -f $Descriptor{2}{"Path"})
 
7257
    {
 
7258
        print "ERROR: descriptor d2 does not exist, incorrect file path '".$Descriptor{2}{"Path"}."'\n";
 
7259
        exit(1);
 
7260
    }
 
7261
    $StartTime = localtime time;
 
7262
    print "preparation...\n";
 
7263
    data_Preparation(1);
 
7264
    data_Preparation(2);
 
7265
    if($AppPath and not keys(%{$Interface_Library{1}}))
 
7266
    {
 
7267
        print "WARNING: symbols from the specified application were not found in the specified library shared objects\n";
 
7268
    }
 
7269
    $REPORT_PATH = "compat_reports/$TargetLibraryName/".$Descriptor{1}{"Version"}."_to_".$Descriptor{2}{"Version"};
 
7270
    system("mkdir", "-p", $REPORT_PATH);
 
7271
    system("rm", "-f", $REPORT_PATH."/abi_compat_report.html");
 
7272
    detectPointerSize();
 
7273
    translateSymbols(1);
 
7274
    translateSymbols(2);
 
7275
    if(not $CheckHeadersOnly)
 
7276
    {
 
7277
        detectAdded();
 
7278
        detectWithdrawn();
 
7279
    }
 
7280
    #headers merging
 
7281
    if($HeaderCheckingMode_Separately and $Descriptor{1}{"Path"} !~ /\.abi\.tar\.gz/ and $Descriptor{2}{"Path"} !~ /\.abi\.tar\.gz/)
 
7282
    {
 
7283
        mergeHeaders_Separately();
 
7284
    }
 
7285
    else
 
7286
    {
 
7287
        if($Descriptor{1}{"Path"} !~ /\.abi\.tar\.gz/)
 
7288
        {
 
7289
            parseHeaders_AllInOne(1);
 
7290
        }
 
7291
        if($Descriptor{2}{"Path"} !~ /\.abi\.tar\.gz/)
 
7292
        {
 
7293
            parseHeaders_AllInOne(2);
 
7294
        }
 
7295
        print "comparing headers ...\n";
 
7296
        mergeSignatures();
 
7297
        mergeConstants();
 
7298
    }
 
7299
    #libraries merging
 
7300
    if(not $CheckHeadersOnly)
 
7301
    {
 
7302
        print "comparing shared objects ...\n";
 
7303
        mergeLibs();
 
7304
    }
 
7305
    print "creating ABI compliance report ...\n";
 
7306
    create_HtmlReport();
 
7307
    if($HeaderCheckingMode_Separately)
 
7308
    {
 
7309
        if(keys(%HeaderCompileError))
 
7310
        {
 
7311
            print "\nWARNING: compilation errors in following headers:\n";
 
7312
            foreach my $Header (keys(%HeaderCompileError))
 
7313
            {
 
7314
                print $Header." ";
 
7315
            }
 
7316
            print "\nyou can see compilation errors in the following files:\n  '$ERR_PATH{1}'\n  '$ERR_PATH{2}'\n";
 
7317
        }
 
7318
    }
 
7319
    `rm -fr temp`;
 
7320
    print "\nstarted: $StartTime, finished: ".(localtime time)."\n" if($ShowExpendTime);
 
7321
    print "see the ABI compliance report in the file '$REPORT_PATH/abi_compat_report.html'\n";
 
7322
    exit(0);
 
7323
}
 
7324
 
 
7325
scenario();