Index: trunk/tools/japicc/modules/Internals/APIDump.pm
===================================================================
--- trunk/tools/japicc/modules/Internals/APIDump.pm	(revision 12872)
+++ trunk/tools/japicc/modules/Internals/APIDump.pm	(revision 13595)
@@ -2,20 +2,22 @@
 # A module to create API dump from disassembled code
 #
-# Copyright (C) 2016-2017 Andrey Ponomarenko's ABI Laboratory
+# Copyright (C) 2016-2018 Andrey Ponomarenko's ABI Laboratory
 #
 # Written by Andrey Ponomarenko
 #
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License or the GNU Lesser
-# General Public License as published by the Free Software Foundation.
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
 #
-# This program is distributed in the hope that it will be useful,
+# This library is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
 #
-# You should have received a copy of the GNU General Public License
-# and the GNU Lesser General Public License along with this program.
-# If not, see <http://www.gnu.org/licenses/>.
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA  02110-1301  USA.
 ###########################################################################
 use strict;
@@ -110,10 +112,28 @@
 { # 1, 2 - library, 0 - client
     my ($LVer, $Path) = @_;
-    
     $Path = getAbsPath($Path);
-    my $JarCmd = getCmdPath("jar");
-    if(not $JarCmd) {
-        exitStatus("Not_Found", "can't find \"jar\" command");
-    }
+    
+    my $ExtractCmd = undef;
+    
+    if($Path=~/\.jar\Z/)
+    {
+        $ExtractCmd = getCmdPath("jar");
+        if(not $ExtractCmd) {
+            exitStatus("Not_Found", "can't find \"jar\" command");
+        }
+        $ExtractCmd .= " -xf \"$Path\"";
+    }
+    elsif($Path=~/\.jmod\Z/)
+    {
+        $ExtractCmd = getCmdPath("jmod");
+        if(not $ExtractCmd) {
+            exitStatus("Not_Found", "can't find \"jmod\" command");
+        }
+        $ExtractCmd .= " extract \"$Path\"";
+    }
+    else {
+        exitStatus("Error", "unknown format of \'$Path\'");
+    }
+    
     my $ExtractPath = join_P($In::Opt{"Tmp"}, $ExtractCounter);
     if(-d $ExtractPath) {
@@ -121,10 +141,12 @@
     }
     mkpath($ExtractPath);
+    
     chdir($ExtractPath);
-    system($JarCmd." -xf \"$Path\"");
+    system($ExtractCmd);
     if($?) {
         exitStatus("Error", "can't extract \'$Path\'");
     }
     chdir($In::Opt{"OrigDir"});
+    
     my @Classes = ();
     foreach my $ClassPath (cmdFind($ExtractPath, "", "*\\.class"))
@@ -177,4 +199,9 @@
     {
         foreach my $SubArchive (cmdFind($ExtractPath, "", "*\\.jar"))
+        { # recursive step
+            readArchive($LVer, $SubArchive);
+        }
+        
+        foreach my $SubArchive (cmdFind($ExtractPath, "", "*\\.jmod"))
         { # recursive step
             readArchive($LVer, $SubArchive);
@@ -305,4 +332,14 @@
     
     my $TmpDir = $In::Opt{"Tmp"};
+    my $DumpFile = undef;
+    
+    if(defined $In::Opt{"Debug"})
+    {
+        if(my $DebugDir = getDebugDir($LVer))
+        {
+            mkpath($DebugDir);
+            $DumpFile = $DebugDir."/class-dump.txt";
+        }
+    }
     
     # ! private info should be processed
@@ -315,6 +352,18 @@
     
     chdir($TmpDir."/".$ExtractCounter);
+    
+    my ($Err, $ErrMsg) = ();
+    
     my $Pid = open3(*IN, *OUT, *ERR, @Cmd);
+    ($Err, $ErrMsg) = ($?, $!);
+    
     close(IN);
+    close(ERR);
+    
+    chdir($In::Opt{"OrigDir"});
+    
+    if($Err==-1 and $Err>>8 and $ErrMsg) {
+        exitStatus("Error", "failed to run javap (".$ErrMsg.")");
+    }
     
     my (%TypeAttr, $CurrentMethod, $CurrentPackage, $CurrentClass, $CurrentClass_Short) = ();
@@ -324,6 +373,7 @@
     my $InAnnotations_Class = undef;
     my $InAnnotations_Method = undef;
-    my %AnnotationName = ();
+    my %ConstantTypeName = ();
     my %AnnotationNum = (); # support for Java 7
+    my %ConstantName = ();
     
     my ($ParamPos, $FieldPos) = (0, 0);
@@ -331,5 +381,4 @@
     
     my $DContent = "";
-    my $Debug = (defined $In::Opt{"Debug"});
     
     while($Run)
@@ -343,5 +392,5 @@
             }
             
-            if($Debug) {
+            if(defined $In::Opt{"Debug"}) {
                 $DContent .= $LINE;
             }
@@ -463,5 +512,5 @@
                     $AName=~s/\//./g;
                     
-                    $AnnotationName{$CNum} = $AName;
+                    $ConstantTypeName{$CNum} = $AName;
                     
                     if(defined $AnnotationNum{$CNum})
@@ -471,4 +520,13 @@
                         }
                         delete($AnnotationNum{$CNum});
+                    }
+                }
+                elsif($LINE=~/=\s*(Utf8|Integer|Long|Float|Double)\s+(.*?)\Z/)
+                {
+                    if($1 eq "Utf8") {
+                        $ConstantName{$CNum} = "\"".$2."\"";
+                    }
+                    else {
+                        $ConstantName{$CNum} = $2;
                     }
                 }
@@ -557,5 +615,5 @@
                 if($LINE=~/\A\s*\d+\:\s*#(\d+)/)
                 {
-                    if(my $AName = $AnnotationName{$1})
+                    if(my $AName = $ConstantTypeName{$1})
                     {
                         if($InAnnotations_Class) {
@@ -678,5 +736,5 @@
             my $LINE_N = <OUT>;
             
-            if($Debug) {
+            if(defined $In::Opt{"Debug"}) {
                 $DContent .= $LINE_N;
             }
@@ -758,5 +816,5 @@
             
             my $LINE_NP = <OUT>;
-            if($Debug) {
+            if(defined $In::Opt{"Debug"}) {
                 $DContent .= $LINE_NP;
             }
@@ -773,5 +831,5 @@
             
             $LINE_NP = <OUT>;
-            if($Debug) {
+            if(defined $In::Opt{"Debug"}) {
                 $DContent .= $LINE_NP;
             }
@@ -780,5 +838,5 @@
             { # flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ANNOTATION
                 $LINE_NP = <OUT>;
-                if($Debug) {
+                if(defined $In::Opt{"Debug"}) {
                     $DContent .= $LINE_NP;
                 }
@@ -821,6 +879,7 @@
             
             %TypeAttr = ("Type"=>$2, "Name"=>$3); # reset previous class
-            %AnnotationName = (); # reset annotations of the class
+            %ConstantTypeName = (); # reset annotations of the class
             %AnnotationNum = (); # support for Java 7
+            %ConstantName = ();
             $InAnnotations_Class = 1;
             
@@ -923,4 +982,42 @@
             $InAnnotations = undef;
         }
+        elsif($CurrentMethod and index($LINE, "default_value")!=-1)
+        {
+            if($LINE=~/default_value:\s*[sISJBFDCZ]#(\d+)/)
+            {
+                if(defined $ConstantName{$1}) {
+                    $MethodInfo{$LVer}{$MName_Mid{$CurrentMethod}}{"Default"} = $ConstantName{$1};
+                }
+            }
+            elsif($LINE=~/default_value:\s*e#(\d+)\.#(\d+)/)
+            {
+                my ($ET, $EV) = ($1, $2);
+                if(defined $ConstantTypeName{$ET} and defined $ConstantName{$EV})
+                {
+                    $ET = $ConstantTypeName{$ET};
+                    $EV = $ConstantName{$EV};
+                    $EV=~s/\"//g;
+                    $MethodInfo{$LVer}{$MName_Mid{$CurrentMethod}}{"Default"} = $ET.".".$EV;
+                }
+            }
+            elsif($LINE=~/default_value:\s*\[(.*)\]/)
+            {
+                my $Arr = $1;
+                if($Arr)
+                {
+                    my @ArrU = ();
+                    foreach my $ArrP (split(/\s*,\s*/, $Arr))
+                    {
+                        if($ArrP=~/[sISJBFDCZ]#(\d+)/) {
+                            push(@ArrU, $ConstantName{$1});
+                        }
+                    }
+                    $MethodInfo{$LVer}{$MName_Mid{$CurrentMethod}}{"Default"} = "{".join(",", @ArrU)."}";
+                }
+                else {
+                    $MethodInfo{$LVer}{$MName_Mid{$CurrentMethod}}{"Default"} = "{}";
+                }
+            }
+        }
         else
         {
@@ -935,9 +1032,5 @@
     
     waitpid($Pid, 0);
-    chdir($In::Opt{"OrigDir"});
-    
-    if(my $Err = $?>>8) {
-        exitStatus("Error", "failed to run javap");
-    }
+    close(OUT);
     
     if(not $NonEmpty) {
@@ -945,6 +1038,6 @@
     }
     
-    if($Debug) {
-        appendFile(getDebugDir($LVer)."/class-dump.txt", $DContent);
+    if(defined $In::Opt{"Debug"}) {
+        appendFile($DumpFile, $DContent);
     }
 }
