@@ -134,7 +134,7 @@ solv_vercmp_conda(const char *s1, const char *q1, const char *s2, const char *q2
134134 return -1 ;
135135 if (s1p - s1 > s2p - s2 )
136136 return 1 ;
137- r = s1p - s1 ? strncmp (s1 , s2 , s1p - s1 ) : 0 ;
137+ r = ( s1p - s1 ) ? strncmp (s1 , s2 , s1p - s1 ) : 0 ;
138138 if (r )
139139 return r ;
140140 }
@@ -678,3 +678,166 @@ pool_conda_matchspec(Pool *pool, const char *name)
678678 return pool_rel2id (pool , nameid , evrid , REL_CONDA , 1 );
679679}
680680
681+ int find_lower_upper_bound (const char * c ,
682+ char * lower , int * lowerflag , char * upper , int * upperflag )
683+ {
684+ lower [0 ] = '\0' ;
685+ upper [0 ] = '\0' ;
686+ * lowerflag = 0 ;
687+ * upperflag = 0 ;
688+
689+ if (!c )
690+ {
691+ // Infinity bound => lower[0] == '\0' && flag == REL_GT | REL_EQ
692+ // return infinity lower & upper
693+ * lowerflag = REL_GT | REL_EQ ;
694+ * upperflag = REL_GT | REL_EQ ;
695+ return 1 ;
696+ }
697+
698+ int len = strlen (c );
699+ const char * lowerbegin = NULL ;
700+ const char * lowerend ;
701+ const char * upperbegin = NULL ;
702+ const char * upperend ;
703+ const char * p ;
704+ const char * * toend = NULL ;
705+ int has_star = 0 ;
706+
707+ for (int i = 0 ; i < len ; ++ i )
708+ {
709+ if (c [i ] == ' ' ) break ;
710+ if (c [i ] == '>' )
711+ {
712+ * lowerflag = REL_GT ;
713+ ++ i ;
714+ if (len > i && c [i ] == '=' )
715+ {
716+ * lowerflag |= REL_EQ ;
717+ ++ i ;
718+ }
719+ p = lowerbegin = & c [i ];
720+ toend = & lowerend ;
721+ }
722+ else if (c [i ] == '<' )
723+ {
724+ * upperflag = REL_LT ;
725+ ++ i ;
726+ if (len > i && c [i ] == '=' )
727+ {
728+ * upperflag |= REL_EQ ;
729+ ++ i ;
730+ }
731+ p = upperbegin = & c [i ];
732+ toend = & upperend ;
733+ }
734+ else if (c [i ] == '=' )
735+ {
736+ ++ i ;
737+ if (c [i ] == '=' )
738+ {
739+ ++ i ;
740+ * lowerflag = REL_EQ ;
741+ * upperflag = REL_EQ ;
742+ }
743+ else
744+ {
745+ * lowerflag = REL_EQ | REL_LT | REL_GT ;
746+ * upperflag = REL_EQ | REL_LT | REL_GT ;
747+ has_star = 1 ;
748+ }
749+ p = lowerbegin = & c [i ];
750+ toend = & lowerend ;
751+ }
752+ else if (c [i ] == ',' || c [i ] == '|' )
753+ {
754+ // ignore
755+ }
756+ else
757+ {
758+ * lowerflag = REL_EQ ;
759+ * upperflag = REL_EQ ;
760+ p = lowerbegin = & c [i ];
761+ toend = & lowerend ;
762+ }
763+ if (toend )
764+ {
765+ while (* p && * p != ',' && * p != '|' && * p != ' ' )
766+ ++ p , ++ i ;
767+ * toend = p ;
768+ toend = NULL ;
769+ if (* p == ' ' ) break ;
770+ }
771+ }
772+
773+ if (!upperbegin )
774+ {
775+ if (* (lowerend - 1 ) == '*' || has_star )
776+ {
777+ * upperflag = REL_GT | REL_LT | REL_EQ ;
778+ * lowerflag = REL_GT | REL_LT | REL_EQ ;
779+ const char * p = lowerend - 1 ;
780+ while (p > lowerbegin && (* p == '*' || * p == '.' )) p -- ;
781+ lowerend = p + 1 ;
782+ }
783+ upperbegin = lowerbegin ;
784+ upperend = lowerend ;
785+ }
786+
787+ if (lowerbegin != NULL )
788+ strncat (lower , lowerbegin , lowerend - lowerbegin );
789+
790+ if (upperbegin != NULL && upperbegin != upper )
791+ strncat (upper , upperbegin , upperend - upperbegin );
792+
793+ printf ("\nLower: %s\nUpper: %s\nFlags: %d\n" , lower , upper , * upperflag );
794+ return 1 ;
795+ }
796+
797+ int conda_compare_bounds (const char * b1 , const char * b2 )
798+ {
799+ if (!b1 || !b2 )
800+ {
801+ if (!b1 && !b2 ) return 0 ;
802+ if (b1 && !b2 ) return 1 ;
803+ if (!b1 && b2 ) return -1 ;
804+ }
805+
806+ // TODO handle infty bounds
807+ int lf1 , uf1 , lf2 , uf2 ;
808+ char l1 [100 ] = "" , u1 [100 ] = "" ;
809+ char l2 [100 ] = "" , u2 [100 ] = "" ;
810+ find_lower_upper_bound (b1 , l1 , & lf1 , u1 , & uf1 );
811+ find_lower_upper_bound (b2 , l2 , & lf2 , u2 , & uf2 );
812+
813+ // if lower bound different, prefer package with higher lower bound
814+ // if upper bound different, prefer package with higher upper bound
815+
816+ // edge cases `=3.7, >=3.7 --> lower bound equal, upper bound different
817+ // edge cases `==3.7, =3.7 --> lower bound equal, upper bound different
818+
819+ // both lower pin with * at end
820+ if (lf1 == lf2 )
821+ {
822+ int l_evr_cmp = pool_evrcmp_conda (NULL , l1 , l2 , 0 );
823+ if (l_evr_cmp != 0 )
824+ {
825+ return - l_evr_cmp ;
826+ }
827+ }
828+ else
829+ {
830+ int l_evr_cmp = pool_evrcmp_conda (NULL , l1 , l2 , 0 );
831+ // TODO
832+ // need some logic here to normalize the bounds
833+ // depending on the comparison function
834+ return - l_evr_cmp ;
835+ }
836+
837+ int u_evr_cmp = pool_evrcmp_conda (NULL , u1 , u2 , 0 );
838+ if (u_evr_cmp != 0 )
839+ {
840+ return u_evr_cmp ;
841+ }
842+ return u_evr_cmp ;
843+ }
0 commit comments