Skip to content

Commit a769f33

Browse files
committed
initial ordering by reldep and reldep-trackfeatures for conda
1 parent e2ed3f2 commit a769f33

4 files changed

Lines changed: 371 additions & 41 deletions

File tree

src/conda.c

Lines changed: 164 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -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+
}

src/conda.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ int pool_evrcmp_conda(const Pool *pool, const char *evr1, const char *evr2, int
1717
int solvable_conda_matchversion(Solvable *s, const char *version);
1818
Id pool_addrelproviders_conda(Pool *pool, Id name, Id evr, Queue *plist);
1919
Id pool_conda_matchspec(Pool *pool, const char *name);
20+
int conda_compare_bounds(const char* b1, const char* b2);
2021

2122
#endif /* LIBSOLV_CONDA_H */
2223

0 commit comments

Comments
 (0)