@@ -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 ;
@@ -787,14 +787,24 @@ static private void createToolPreferences(ContributionsIndexer indexer) {
787787 }
788788
789789 static public void populateImportToLibraryTable () {
790- // Populate importToLibraryTable
791- importToLibraryTable = new HashMap <String , UserLibrary >();
790+ // Populate importToLibraryTable. Each header filename maps to
791+ // a list of libraries. Compiler.java will use only the first
792+ // library on each list. The others are used only to advise
793+ // user of ambiguously matched and duplicate libraries.
794+ importToLibraryTable = new HashMap <String , LibraryList >();
792795 for (UserLibrary lib : librariesIndexer .getInstalledLibraries ()) {
793796 try {
794797 String headers [] = headerListFromIncludePath (lib .getSrcFolder ());
795798 for (String header : headers ) {
796- UserLibrary old = importToLibraryTable .get (header );
797- if (old != null ) {
799+ LibraryList list = importToLibraryTable .get (header );
800+ if (list == null ) {
801+ // This is the first library found with this header
802+ list = new LibraryList ();
803+ list .addFirst (lib );
804+ importToLibraryTable .put (header , list );
805+ } else {
806+ UserLibrary old = list .peekFirst ();
807+ boolean useThisLib = true ;
798808 // This is the case where 2 libraries have a .h header
799809 // with the same name. We must decide which library to
800810 // use when a sketch has #include "name.h"
@@ -812,58 +822,81 @@ static public void populateImportToLibraryTable() {
812822 String oldName = old .getInstalledFolder ().getName (); // just the library folder name
813823 String libName = lib .getInstalledFolder ().getName (); // just the library folder name
814824 //System.out.println("name conflict: " + name);
815- //System.out.println(" old = " + oldName + " -> " + old.getFolder ().getPath());
816- //System.out.println(" new = " + libName + " -> " + lib.getFolder ().getPath());
825+ //System.out.println(" old = " + oldName + " -> " + old.getInstalledFolder ().getPath());
826+ //System.out.println(" new = " + libName + " -> " + lib.getInstalledFolder ().getPath());
817827 String name_lc = name .toLowerCase ();
818828 String oldName_lc = oldName .toLowerCase ();
819829 String libName_lc = libName .toLowerCase ();
820830 // always favor a perfect name match
821831 if (libName .equals (name )) {
822832 } else if (oldName .equals (name )) {
823- continue ;
833+ useThisLib = false ;
824834 // check for "-master" appended (zip file from github)
825835 } else if (libName .equals (name +"-master" )) {
826836 } else if (oldName .equals (name +"-master" )) {
827- continue ;
837+ useThisLib = false ;
828838 // next, favor a match with other stuff appended
829839 } else if (libName .startsWith (name )) {
830840 } else if (oldName .startsWith (name )) {
831- continue ;
841+ useThisLib = false ;
832842 // otherwise, favor a match with stuff prepended
833843 } else if (libName .endsWith (name )) {
834844 } else if (oldName .endsWith (name )) {
835- continue ;
845+ useThisLib = false ;
836846 // as a last resort, match if stuff prepended and appended
837847 } else if (libName .contains (name )) {
838848 } else if (oldName .contains (name )) {
839- continue ;
849+ useThisLib = false ;
840850 // repeat all the above tests, with case insensitive matching
841851 } else if (libName_lc .equals (name_lc )) {
842852 } else if (oldName_lc .equals (name_lc )) {
843- continue ;
853+ useThisLib = false ;
844854 } else if (libName_lc .equals (name_lc +"-master" )) {
845855 } else if (oldName_lc .equals (name_lc +"-master" )) {
846- continue ;
856+ useThisLib = false ;
847857 } else if (libName_lc .startsWith (name_lc )) {
848858 } else if (oldName_lc .startsWith (name_lc )) {
849- continue ;
859+ useThisLib = false ;
850860 } else if (libName_lc .endsWith (name_lc )) {
851861 } else if (oldName_lc .endsWith (name_lc )) {
852- continue ;
862+ useThisLib = false ;
853863 } else if (libName_lc .contains (name_lc )) {
854864 } else if (oldName_lc .contains (name_lc )) {
855- continue ;
865+ useThisLib = false ;
856866 } else {
857867 // none of these tests matched, so just default to "libName".
858868 }
869+ if (useThisLib ) {
870+ list .addFirst (lib );
871+ } else {
872+ list .addLast (lib );
873+ }
859874 }
860- importToLibraryTable .put (header , lib );
861875 }
862876 } catch (IOException e ) {
863877 showWarning (_ ("Error" ), I18n
864878 .format ("Unable to list header files in {0}" , lib .getSrcFolder ()), e );
865879 }
866880 }
881+ // repeat for ALL libraries, to pick up duplicates not visible normally.
882+ // any new libraries found here are NEVER used, but they are added to the
883+ // end of already-found headers, to allow Compiler to report them if
884+ // the sketch tries to use them.
885+ for (UserLibrary lib : librariesIndexer .getInstalledLibrariesWithDuplicates ()) {
886+ try {
887+ String headers [] = headerListFromIncludePath (lib .getSrcFolder ());
888+ for (String header : headers ) {
889+ LibraryList list = importToLibraryTable .get (header );
890+ if (list != null ) {
891+ if (!(list .hasLibrary (lib ))) {
892+ list .addLast (lib );
893+ //System.out.println(" duplicate lib: " + lib.getInstalledFolder().getPath());
894+ }
895+ }
896+ }
897+ } catch (IOException e ) {
898+ }
899+ }
867900 }
868901
869902 static public void initParameters (String args []) {
0 commit comments