@@ -45,7 +45,7 @@ public class BaseNoGui {
4545 static private File toolsFolder ;
4646
4747 // maps #included files to their library folder
48- public static Map <String , UserLibrary > importToLibraryTable ;
48+ public static Map <String , LibraryList > importToLibraryTable ;
4949
5050 // maps library name to their library folder
5151 static private LibraryList libraries ;
@@ -771,14 +771,24 @@ static private void createToolPreferences(ContributionsIndexer indexer) {
771771 }
772772
773773 static public void populateImportToLibraryTable () {
774- // Populate importToLibraryTable
775- importToLibraryTable = new HashMap <String , UserLibrary >();
774+ // Populate importToLibraryTable. Each header filename maps to
775+ // a list of libraries. Compiler.java will use only the first
776+ // library on each list. The others are used only to advise
777+ // user of ambiguously matched and duplicate libraries.
778+ importToLibraryTable = new HashMap <String , LibraryList >();
776779 for (UserLibrary lib : librariesIndexer .getInstalledLibraries ()) {
777780 try {
778781 String headers [] = headerListFromIncludePath (lib .getSrcFolder ());
779782 for (String header : headers ) {
780- UserLibrary old = importToLibraryTable .get (header );
781- if (old != null ) {
783+ LibraryList list = importToLibraryTable .get (header );
784+ if (list == null ) {
785+ // This is the first library found with this header
786+ list = new LibraryList ();
787+ list .addFirst (lib );
788+ importToLibraryTable .put (header , list );
789+ } else {
790+ UserLibrary old = list .peekFirst ();
791+ boolean useThisLib = true ;
782792 // This is the case where 2 libraries have a .h header
783793 // with the same name. We must decide which library to
784794 // use when a sketch has #include "name.h"
@@ -796,58 +806,81 @@ static public void populateImportToLibraryTable() {
796806 String oldName = old .getInstalledFolder ().getName (); // just the library folder name
797807 String libName = lib .getInstalledFolder ().getName (); // just the library folder name
798808 //System.out.println("name conflict: " + name);
799- //System.out.println(" old = " + oldName + " -> " + old.getFolder ().getPath());
800- //System.out.println(" new = " + libName + " -> " + lib.getFolder ().getPath());
809+ //System.out.println(" old = " + oldName + " -> " + old.getInstalledFolder ().getPath());
810+ //System.out.println(" new = " + libName + " -> " + lib.getInstalledFolder ().getPath());
801811 String name_lc = name .toLowerCase ();
802812 String oldName_lc = oldName .toLowerCase ();
803813 String libName_lc = libName .toLowerCase ();
804814 // always favor a perfect name match
805815 if (libName .equals (name )) {
806816 } else if (oldName .equals (name )) {
807- continue ;
817+ useThisLib = false ;
808818 // check for "-master" appended (zip file from github)
809819 } else if (libName .equals (name +"-master" )) {
810820 } else if (oldName .equals (name +"-master" )) {
811- continue ;
821+ useThisLib = false ;
812822 // next, favor a match with other stuff appended
813823 } else if (libName .startsWith (name )) {
814824 } else if (oldName .startsWith (name )) {
815- continue ;
825+ useThisLib = false ;
816826 // otherwise, favor a match with stuff prepended
817827 } else if (libName .endsWith (name )) {
818828 } else if (oldName .endsWith (name )) {
819- continue ;
829+ useThisLib = false ;
820830 // as a last resort, match if stuff prepended and appended
821831 } else if (libName .contains (name )) {
822832 } else if (oldName .contains (name )) {
823- continue ;
833+ useThisLib = false ;
824834 // repeat all the above tests, with case insensitive matching
825835 } else if (libName_lc .equals (name_lc )) {
826836 } else if (oldName_lc .equals (name_lc )) {
827- continue ;
837+ useThisLib = false ;
828838 } else if (libName_lc .equals (name_lc +"-master" )) {
829839 } else if (oldName_lc .equals (name_lc +"-master" )) {
830- continue ;
840+ useThisLib = false ;
831841 } else if (libName_lc .startsWith (name_lc )) {
832842 } else if (oldName_lc .startsWith (name_lc )) {
833- continue ;
843+ useThisLib = false ;
834844 } else if (libName_lc .endsWith (name_lc )) {
835845 } else if (oldName_lc .endsWith (name_lc )) {
836- continue ;
846+ useThisLib = false ;
837847 } else if (libName_lc .contains (name_lc )) {
838848 } else if (oldName_lc .contains (name_lc )) {
839- continue ;
849+ useThisLib = false ;
840850 } else {
841851 // none of these tests matched, so just default to "libName".
842852 }
853+ if (useThisLib ) {
854+ list .addFirst (lib );
855+ } else {
856+ list .addLast (lib );
857+ }
843858 }
844- importToLibraryTable .put (header , lib );
845859 }
846860 } catch (IOException e ) {
847861 showWarning (_ ("Error" ), I18n
848862 .format ("Unable to list header files in {0}" , lib .getSrcFolder ()), e );
849863 }
850864 }
865+ // repeat for ALL libraries, to pick up duplicates not visible normally.
866+ // any new libraries found here are NEVER used, but they are added to the
867+ // end of already-found headers, to allow Compiler to report them if
868+ // the sketch tries to use them.
869+ for (UserLibrary lib : librariesIndexer .getInstalledLibrariesWithDuplicates ()) {
870+ try {
871+ String headers [] = headerListFromIncludePath (lib .getSrcFolder ());
872+ for (String header : headers ) {
873+ LibraryList list = importToLibraryTable .get (header );
874+ if (list != null ) {
875+ if (!(list .hasLibrary (lib ))) {
876+ list .addLast (lib );
877+ //System.out.println(" duplicate lib: " + lib.getInstalledFolder().getPath());
878+ }
879+ }
880+ }
881+ } catch (IOException e ) {
882+ }
883+ }
851884 }
852885
853886 static public void initParameters (String args []) {
0 commit comments