summaryrefslogtreecommitdiffstats
path: root/bitbake/lib/bb/utils.py
diff options
context:
space:
mode:
authorChris Larson <clarson@kergoth.com>2009-07-19 10:05:52 -0700
committerRichard Purdie <rpurdie@linux.intel.com>2010-03-22 14:54:42 +0000
commitf8c6db95d7734e3f4fc7eaf82eda6d59721b3fbb (patch)
tree18e1882916586b69460252a3465cce9ccdbbbb04 /bitbake/lib/bb/utils.py
parentb7d175a18a0fab65ff4022e15c68e079296c8e82 (diff)
downloadpoky-f8c6db95d7734e3f4fc7eaf82eda6d59721b3fbb.tar.gz
Move most utility functions from bb into bb.utils.
(Bitbake rev: ff720ec59b30671c951dbf3b96df10ef56b8b505) Signed-off-by: Chris Larson <clarson@kergoth.com> Signed-off-by: Richard Purdie <rpurdie@linux.intel.com>
Diffstat (limited to 'bitbake/lib/bb/utils.py')
-rw-r--r--bitbake/lib/bb/utils.py759
1 files changed, 759 insertions, 0 deletions
diff --git a/bitbake/lib/bb/utils.py b/bitbake/lib/bb/utils.py
index 3b7ea2e83c..9776c48245 100644
--- a/bitbake/lib/bb/utils.py
+++ b/bitbake/lib/bb/utils.py
@@ -429,3 +429,762 @@ def prune_suffix(var, suffixes, d):
429 if var.endswith(suffix): 429 if var.endswith(suffix):
430 return var.replace(suffix, "") 430 return var.replace(suffix, "")
431 return var 431 return var
432
433def mkdirhier(dir):
434 """Create a directory like 'mkdir -p', but does not complain if
435 directory already exists like os.makedirs
436 """
437
438 debug(3, "mkdirhier(%s)" % dir)
439 try:
440 os.makedirs(dir)
441 debug(2, "created " + dir)
442 except OSError, e:
443 if e.errno != 17: raise e
444
445import stat
446
447def movefile(src,dest,newmtime=None,sstat=None):
448 """Moves a file from src to dest, preserving all permissions and
449 attributes; mtime will be preserved even when moving across
450 filesystems. Returns true on success and false on failure. Move is
451 atomic.
452 """
453
454 #print "movefile("+src+","+dest+","+str(newmtime)+","+str(sstat)+")"
455 try:
456 if not sstat:
457 sstat=os.lstat(src)
458 except Exception, e:
459 print "movefile: Stating source file failed...", e
460 return None
461
462 destexists=1
463 try:
464 dstat=os.lstat(dest)
465 except:
466 dstat=os.lstat(os.path.dirname(dest))
467 destexists=0
468
469 if destexists:
470 if stat.S_ISLNK(dstat[stat.ST_MODE]):
471 try:
472 os.unlink(dest)
473 destexists=0
474 except Exception, e:
475 pass
476
477 if stat.S_ISLNK(sstat[stat.ST_MODE]):
478 try:
479 target=os.readlink(src)
480 if destexists and not stat.S_ISDIR(dstat[stat.ST_MODE]):
481 os.unlink(dest)
482 os.symlink(target,dest)
483 #os.lchown(dest,sstat[stat.ST_UID],sstat[stat.ST_GID])
484 os.unlink(src)
485 return os.lstat(dest)
486 except Exception, e:
487 print "movefile: failed to properly create symlink:", dest, "->", target, e
488 return None
489
490 renamefailed=1
491 if sstat[stat.ST_DEV]==dstat[stat.ST_DEV]:
492 try:
493 ret=os.rename(src,dest)
494 renamefailed=0
495 except Exception, e:
496 import errno
497 if e[0]!=errno.EXDEV:
498 # Some random error.
499 print "movefile: Failed to move", src, "to", dest, e
500 return None
501 # Invalid cross-device-link 'bind' mounted or actually Cross-Device
502
503 if renamefailed:
504 didcopy=0
505 if stat.S_ISREG(sstat[stat.ST_MODE]):
506 try: # For safety copy then move it over.
507 shutil.copyfile(src,dest+"#new")
508 os.rename(dest+"#new",dest)
509 didcopy=1
510 except Exception, e:
511 print 'movefile: copy', src, '->', dest, 'failed.', e
512 return None
513 else:
514 #we don't yet handle special, so we need to fall back to /bin/mv
515 a=getstatusoutput("/bin/mv -f "+"'"+src+"' '"+dest+"'")
516 if a[0]!=0:
517 print "movefile: Failed to move special file:" + src + "' to '" + dest + "'", a
518 return None # failure
519 try:
520 if didcopy:
521 missingos.lchown(dest,sstat[stat.ST_UID],sstat[stat.ST_GID])
522 os.chmod(dest, stat.S_IMODE(sstat[stat.ST_MODE])) # Sticky is reset on chown
523 os.unlink(src)
524 except Exception, e:
525 print "movefile: Failed to chown/chmod/unlink", dest, e
526 return None
527
528 if newmtime:
529 os.utime(dest,(newmtime,newmtime))
530 else:
531 os.utime(dest, (sstat[stat.ST_ATIME], sstat[stat.ST_MTIME]))
532 newmtime=sstat[stat.ST_MTIME]
533 return newmtime
534
535def copyfile(src,dest,newmtime=None,sstat=None):
536 """
537 Copies a file from src to dest, preserving all permissions and
538 attributes; mtime will be preserved even when moving across
539 filesystems. Returns true on success and false on failure.
540 """
541 import os, stat, shutil
542
543 #print "copyfile("+src+","+dest+","+str(newmtime)+","+str(sstat)+")"
544 try:
545 if not sstat:
546 sstat=os.lstat(src)
547 except Exception, e:
548 print "copyfile: Stating source file failed...", e
549 return False
550
551 destexists=1
552 try:
553 dstat=os.lstat(dest)
554 except:
555 dstat=os.lstat(os.path.dirname(dest))
556 destexists=0
557
558 if destexists:
559 if stat.S_ISLNK(dstat[stat.ST_MODE]):
560 try:
561 os.unlink(dest)
562 destexists=0
563 except Exception, e:
564 pass
565
566 if stat.S_ISLNK(sstat[stat.ST_MODE]):
567 try:
568 target=os.readlink(src)
569 if destexists and not stat.S_ISDIR(dstat[stat.ST_MODE]):
570 os.unlink(dest)
571 os.symlink(target,dest)
572 #os.lchown(dest,sstat[stat.ST_UID],sstat[stat.ST_GID])
573 return os.lstat(dest)
574 except Exception, e:
575 print "copyfile: failed to properly create symlink:", dest, "->", target, e
576 return False
577
578 if stat.S_ISREG(sstat[stat.ST_MODE]):
579 try: # For safety copy then move it over.
580 shutil.copyfile(src,dest+"#new")
581 os.rename(dest+"#new",dest)
582 except Exception, e:
583 print 'copyfile: copy', src, '->', dest, 'failed.', e
584 return False
585 else:
586 #we don't yet handle special, so we need to fall back to /bin/mv
587 a=getstatusoutput("/bin/cp -f "+"'"+src+"' '"+dest+"'")
588 if a[0]!=0:
589 print "copyfile: Failed to copy special file:" + src + "' to '" + dest + "'", a
590 return False # failure
591 try:
592 os.lchown(dest,sstat[stat.ST_UID],sstat[stat.ST_GID])
593 os.chmod(dest, stat.S_IMODE(sstat[stat.ST_MODE])) # Sticky is reset on chown
594 except Exception, e:
595 print "copyfile: Failed to chown/chmod/unlink", dest, e
596 return False
597
598 if newmtime:
599 os.utime(dest,(newmtime,newmtime))
600 else:
601 os.utime(dest, (sstat[stat.ST_ATIME], sstat[stat.ST_MTIME]))
602 newmtime=sstat[stat.ST_MTIME]
603 return newmtime
604
605def which(path, item, direction = 0):
606 """
607 Locate a file in a PATH
608 """
609
610 paths = (path or "").split(':')
611 if direction != 0:
612 paths.reverse()
613
614 for p in (path or "").split(':'):
615 next = os.path.join(p, item)
616 if os.path.exists(next):
617 return next
618
619 return ""
620
621whitespace = '\t\n\x0b\x0c\r '
622lowercase = 'abcdefghijklmnopqrstuvwxyz'
623
624def tokenize(mystring):
625 """Breaks a string like 'foo? (bar) oni? (blah (blah))' into (possibly embedded) lists:
626
627 >>> tokenize("x")
628 ['x']
629 >>> tokenize("x y")
630 ['x', 'y']
631 >>> tokenize("(x y)")
632 [['x', 'y']]
633 >>> tokenize("(x y) b c")
634 [['x', 'y'], 'b', 'c']
635 >>> tokenize("foo? (bar) oni? (blah (blah))")
636 ['foo?', ['bar'], 'oni?', ['blah', ['blah']]]
637 >>> tokenize("sys-apps/linux-headers nls? (sys-devel/gettext)")
638 ['sys-apps/linux-headers', 'nls?', ['sys-devel/gettext']]
639 """
640
641 newtokens = []
642 curlist = newtokens
643 prevlists = []
644 level = 0
645 accum = ""
646 for x in mystring:
647 if x=="(":
648 if accum:
649 curlist.append(accum)
650 accum=""
651 prevlists.append(curlist)
652 curlist=[]
653 level=level+1
654 elif x==")":
655 if accum:
656 curlist.append(accum)
657 accum=""
658 if level==0:
659 print "!!! tokenizer: Unmatched left parenthesis in:\n'"+mystring+"'"
660 return None
661 newlist=curlist
662 curlist=prevlists.pop()
663 curlist.append(newlist)
664 level=level-1
665 elif x in whitespace:
666 if accum:
667 curlist.append(accum)
668 accum=""
669 else:
670 accum=accum+x
671 if accum:
672 curlist.append(accum)
673 if (level!=0):
674 print "!!! tokenizer: Exiting with unterminated parenthesis in:\n'"+mystring+"'"
675 return None
676 return newtokens
677
678def evaluate(tokens,mydefines,allon=0):
679 """Removes tokens based on whether conditional definitions exist or not.
680 Recognizes !
681
682 >>> evaluate(['sys-apps/linux-headers', 'nls?', ['sys-devel/gettext']], {})
683 ['sys-apps/linux-headers']
684
685 Negate the flag:
686
687 >>> evaluate(['sys-apps/linux-headers', '!nls?', ['sys-devel/gettext']], {})
688 ['sys-apps/linux-headers', ['sys-devel/gettext']]
689
690 Define 'nls':
691
692 >>> evaluate(['sys-apps/linux-headers', 'nls?', ['sys-devel/gettext']], {"nls":1})
693 ['sys-apps/linux-headers', ['sys-devel/gettext']]
694
695 Turn allon on:
696
697 >>> evaluate(['sys-apps/linux-headers', 'nls?', ['sys-devel/gettext']], {}, True)
698 ['sys-apps/linux-headers', ['sys-devel/gettext']]
699 """
700
701 if tokens == None:
702 return None
703 mytokens = tokens + [] # this copies the list
704 pos = 0
705 while pos < len(mytokens):
706 if type(mytokens[pos]) == types.ListType:
707 evaluate(mytokens[pos], mydefines)
708 if not len(mytokens[pos]):
709 del mytokens[pos]
710 continue
711 elif mytokens[pos][-1] == "?":
712 cur = mytokens[pos][:-1]
713 del mytokens[pos]
714 if allon:
715 if cur[0] == "!":
716 del mytokens[pos]
717 else:
718 if cur[0] == "!":
719 if (cur[1:] in mydefines) and (pos < len(mytokens)):
720 del mytokens[pos]
721 continue
722 elif (cur not in mydefines) and (pos < len(mytokens)):
723 del mytokens[pos]
724 continue
725 pos = pos + 1
726 return mytokens
727
728def flatten(mytokens):
729 """Converts nested arrays into a flat arrays:
730
731 >>> flatten([1,[2,3]])
732 [1, 2, 3]
733 >>> flatten(['sys-apps/linux-headers', ['sys-devel/gettext']])
734 ['sys-apps/linux-headers', 'sys-devel/gettext']
735 """
736
737 newlist=[]
738 for x in mytokens:
739 if type(x)==types.ListType:
740 newlist.extend(flatten(x))
741 else:
742 newlist.append(x)
743 return newlist
744
745_package_weights_ = {"pre":-2,"p":0,"alpha":-4,"beta":-3,"rc":-1} # dicts are unordered
746_package_ends_ = ["pre", "p", "alpha", "beta", "rc", "cvs", "bk", "HEAD" ] # so we need ordered list
747
748def relparse(myver):
749 """Parses the last elements of a version number into a triplet, that can
750 later be compared:
751
752 >>> relparse('1.2_pre3')
753 [1.2, -2, 3.0]
754 >>> relparse('1.2b')
755 [1.2, 98, 0]
756 >>> relparse('1.2')
757 [1.2, 0, 0]
758 """
759
760 number = 0
761 p1 = 0
762 p2 = 0
763 mynewver = myver.split('_')
764 if len(mynewver)==2:
765 # an _package_weights_
766 number = float(mynewver[0])
767 match = 0
768 for x in _package_ends_:
769 elen = len(x)
770 if mynewver[1][:elen] == x:
771 match = 1
772 p1 = _package_weights_[x]
773 try:
774 p2 = float(mynewver[1][elen:])
775 except:
776 p2 = 0
777 break
778 if not match:
779 # normal number or number with letter at end
780 divider = len(myver)-1
781 if myver[divider:] not in "1234567890":
782 # letter at end
783 p1 = ord(myver[divider:])
784 number = float(myver[0:divider])
785 else:
786 number = float(myver)
787 else:
788 # normal number or number with letter at end
789 divider = len(myver)-1
790 if myver[divider:] not in "1234567890":
791 #letter at end
792 p1 = ord(myver[divider:])
793 number = float(myver[0:divider])
794 else:
795 number = float(myver)
796 return [number,p1,p2]
797
798__ververify_cache__ = {}
799
800def ververify(myorigval,silent=1):
801 """Returns 1 if given a valid version string, els 0. Valid versions are in the format
802
803 <v1>.<v2>...<vx>[a-z,_{_package_weights_}[vy]]
804
805 >>> ververify('2.4.20')
806 1
807 >>> ververify('2.4..20') # two dots
808 0
809 >>> ververify('2.x.20') # 'x' is not numeric
810 0
811 >>> ververify('2.4.20a')
812 1
813 >>> ververify('2.4.20cvs') # only one trailing letter
814 0
815 >>> ververify('1a')
816 1
817 >>> ververify('test_a') # no version at all
818 0
819 >>> ververify('2.4.20_beta1')
820 1
821 >>> ververify('2.4.20_beta')
822 1
823 >>> ververify('2.4.20_wrongext') # _wrongext is no valid trailer
824 0
825 """
826
827 # Lookup the cache first
828 try:
829 return __ververify_cache__[myorigval]
830 except KeyError:
831 pass
832
833 if len(myorigval) == 0:
834 if not silent:
835 error("package version is empty")
836 __ververify_cache__[myorigval] = 0
837 return 0
838 myval = myorigval.split('.')
839 if len(myval)==0:
840 if not silent:
841 error("package name has empty version string")
842 __ververify_cache__[myorigval] = 0
843 return 0
844 # all but the last version must be a numeric
845 for x in myval[:-1]:
846 if not len(x):
847 if not silent:
848 error("package version has two points in a row")
849 __ververify_cache__[myorigval] = 0
850 return 0
851 try:
852 foo = int(x)
853 except:
854 if not silent:
855 error("package version contains non-numeric '"+x+"'")
856 __ververify_cache__[myorigval] = 0
857 return 0
858 if not len(myval[-1]):
859 if not silent:
860 error("package version has trailing dot")
861 __ververify_cache__[myorigval] = 0
862 return 0
863 try:
864 foo = int(myval[-1])
865 __ververify_cache__[myorigval] = 1
866 return 1
867 except:
868 pass
869
870 # ok, our last component is not a plain number or blank, let's continue
871 if myval[-1][-1] in lowercase:
872 try:
873 foo = int(myval[-1][:-1])
874 return 1
875 __ververify_cache__[myorigval] = 1
876 # 1a, 2.0b, etc.
877 except:
878 pass
879 # ok, maybe we have a 1_alpha or 1_beta2; let's see
880 ep=string.split(myval[-1],"_")
881 if len(ep)!= 2:
882 if not silent:
883 error("package version has more than one letter at then end")
884 __ververify_cache__[myorigval] = 0
885 return 0
886 try:
887 foo = string.atoi(ep[0])
888 except:
889 # this needs to be numeric, i.e. the "1" in "1_alpha"
890 if not silent:
891 error("package version must have numeric part before the '_'")
892 __ververify_cache__[myorigval] = 0
893 return 0
894
895 for mye in _package_ends_:
896 if ep[1][0:len(mye)] == mye:
897 if len(mye) == len(ep[1]):
898 # no trailing numeric is ok
899 __ververify_cache__[myorigval] = 1
900 return 1
901 else:
902 try:
903 foo = string.atoi(ep[1][len(mye):])
904 __ververify_cache__[myorigval] = 1
905 return 1
906 except:
907 # if no _package_weights_ work, *then* we return 0
908 pass
909 if not silent:
910 error("package version extension after '_' is invalid")
911 __ververify_cache__[myorigval] = 0
912 return 0
913
914def isjustname(mypkg):
915 myparts = string.split(mypkg,'-')
916 for x in myparts:
917 if ververify(x):
918 return 0
919 return 1
920
921_isspecific_cache_={}
922
923def isspecific(mypkg):
924 "now supports packages with no category"
925 try:
926 return __isspecific_cache__[mypkg]
927 except:
928 pass
929
930 mysplit = string.split(mypkg,"/")
931 if not isjustname(mysplit[-1]):
932 __isspecific_cache__[mypkg] = 1
933 return 1
934 __isspecific_cache__[mypkg] = 0
935 return 0
936
937__pkgsplit_cache__={}
938
939def pkgsplit(mypkg, silent=1):
940
941 """This function can be used as a package verification function. If
942 it is a valid name, pkgsplit will return a list containing:
943 [pkgname, pkgversion(norev), pkgrev ].
944
945 >>> pkgsplit('')
946 >>> pkgsplit('x')
947 >>> pkgsplit('x-')
948 >>> pkgsplit('-1')
949 >>> pkgsplit('glibc-1.2-8.9-r7')
950 >>> pkgsplit('glibc-2.2.5-r7')
951 ['glibc', '2.2.5', 'r7']
952 >>> pkgsplit('foo-1.2-1')
953 >>> pkgsplit('Mesa-3.0')
954 ['Mesa', '3.0', 'r0']
955 """
956
957 try:
958 return __pkgsplit_cache__[mypkg]
959 except KeyError:
960 pass
961
962 myparts = string.split(mypkg,'-')
963 if len(myparts) < 2:
964 if not silent:
965 error("package name without name or version part")
966 __pkgsplit_cache__[mypkg] = None
967 return None
968 for x in myparts:
969 if len(x) == 0:
970 if not silent:
971 error("package name with empty name or version part")
972 __pkgsplit_cache__[mypkg] = None
973 return None
974 # verify rev
975 revok = 0
976 myrev = myparts[-1]
977 ververify(myrev, silent)
978 if len(myrev) and myrev[0] == "r":
979 try:
980 string.atoi(myrev[1:])
981 revok = 1
982 except:
983 pass
984 if revok:
985 if ververify(myparts[-2]):
986 if len(myparts) == 2:
987 __pkgsplit_cache__[mypkg] = None
988 return None
989 else:
990 for x in myparts[:-2]:
991 if ververify(x):
992 __pkgsplit_cache__[mypkg]=None
993 return None
994 # names can't have versiony looking parts
995 myval=[string.join(myparts[:-2],"-"),myparts[-2],myparts[-1]]
996 __pkgsplit_cache__[mypkg]=myval
997 return myval
998 else:
999 __pkgsplit_cache__[mypkg] = None
1000 return None
1001
1002 elif ververify(myparts[-1],silent):
1003 if len(myparts)==1:
1004 if not silent:
1005 print "!!! Name error in",mypkg+": missing name part."
1006 __pkgsplit_cache__[mypkg]=None
1007 return None
1008 else:
1009 for x in myparts[:-1]:
1010 if ververify(x):
1011 if not silent: error("package name has multiple version parts")
1012 __pkgsplit_cache__[mypkg] = None
1013 return None
1014 myval = [string.join(myparts[:-1],"-"), myparts[-1],"r0"]
1015 __pkgsplit_cache__[mypkg] = myval
1016 return myval
1017 else:
1018 __pkgsplit_cache__[mypkg] = None
1019 return None
1020
1021__catpkgsplit_cache__ = {}
1022
1023def catpkgsplit(mydata,silent=1):
1024 """returns [cat, pkgname, version, rev ]
1025
1026 >>> catpkgsplit('sys-libs/glibc-1.2-r7')
1027 ['sys-libs', 'glibc', '1.2', 'r7']
1028 >>> catpkgsplit('glibc-1.2-r7')
1029 [None, 'glibc', '1.2', 'r7']
1030 """
1031
1032 try:
1033 return __catpkgsplit_cache__[mydata]
1034 except KeyError:
1035 pass
1036
1037 cat = os.path.basename(os.path.dirname(mydata))
1038 mydata = os.path.join(cat, os.path.basename(mydata))
1039 if mydata[-3:] == '.bb':
1040 mydata = mydata[:-3]
1041
1042 mysplit = mydata.split("/")
1043 p_split = None
1044 splitlen = len(mysplit)
1045 if splitlen == 1:
1046 retval = [None]
1047 p_split = pkgsplit(mydata,silent)
1048 else:
1049 retval = [mysplit[splitlen - 2]]
1050 p_split = pkgsplit(mysplit[splitlen - 1],silent)
1051 if not p_split:
1052 __catpkgsplit_cache__[mydata] = None
1053 return None
1054 retval.extend(p_split)
1055 __catpkgsplit_cache__[mydata] = retval
1056 return retval
1057
1058def pkgcmp(pkg1,pkg2):
1059 """ Compares two packages, which should have been split via
1060 pkgsplit(). if the return value val is less than zero, then pkg2 is
1061 newer than pkg1, zero if equal and positive if older.
1062
1063 >>> pkgcmp(['glibc', '2.2.5', 'r7'], ['glibc', '2.2.5', 'r7'])
1064 0
1065 >>> pkgcmp(['glibc', '2.2.5', 'r4'], ['glibc', '2.2.5', 'r7'])
1066 -1
1067 >>> pkgcmp(['glibc', '2.2.5', 'r7'], ['glibc', '2.2.5', 'r2'])
1068 1
1069 """
1070
1071 mycmp = vercmp(pkg1[1],pkg2[1])
1072 if mycmp > 0:
1073 return 1
1074 if mycmp < 0:
1075 return -1
1076 r1=string.atoi(pkg1[2][1:])
1077 r2=string.atoi(pkg2[2][1:])
1078 if r1 > r2:
1079 return 1
1080 if r2 > r1:
1081 return -1
1082 return 0
1083
1084def dep_parenreduce(mysplit, mypos=0):
1085 """Accepts a list of strings, and converts '(' and ')' surrounded items to sub-lists:
1086
1087 >>> dep_parenreduce([''])
1088 ['']
1089 >>> dep_parenreduce(['1', '2', '3'])
1090 ['1', '2', '3']
1091 >>> dep_parenreduce(['1', '(', '2', '3', ')', '4'])
1092 ['1', ['2', '3'], '4']
1093 """
1094
1095 while mypos < len(mysplit):
1096 if mysplit[mypos] == "(":
1097 firstpos = mypos
1098 mypos = mypos + 1
1099 while mypos < len(mysplit):
1100 if mysplit[mypos] == ")":
1101 mysplit[firstpos:mypos+1] = [mysplit[firstpos+1:mypos]]
1102 mypos = firstpos
1103 break
1104 elif mysplit[mypos] == "(":
1105 # recurse
1106 mysplit = dep_parenreduce(mysplit,mypos)
1107 mypos = mypos + 1
1108 mypos = mypos + 1
1109 return mysplit
1110
1111def dep_opconvert(mysplit, myuse):
1112 "Does dependency operator conversion"
1113
1114 mypos = 0
1115 newsplit = []
1116 while mypos < len(mysplit):
1117 if type(mysplit[mypos]) == types.ListType:
1118 newsplit.append(dep_opconvert(mysplit[mypos],myuse))
1119 mypos += 1
1120 elif mysplit[mypos] == ")":
1121 # mismatched paren, error
1122 return None
1123 elif mysplit[mypos]=="||":
1124 if ((mypos+1)>=len(mysplit)) or (type(mysplit[mypos+1])!=types.ListType):
1125 # || must be followed by paren'd list
1126 return None
1127 try:
1128 mynew = dep_opconvert(mysplit[mypos+1],myuse)
1129 except Exception, e:
1130 error("unable to satisfy OR dependancy: " + string.join(mysplit," || "))
1131 raise e
1132 mynew[0:0] = ["||"]
1133 newsplit.append(mynew)
1134 mypos += 2
1135 elif mysplit[mypos][-1] == "?":
1136 # use clause, i.e "gnome? ( foo bar )"
1137 # this is a quick and dirty hack so that repoman can enable all USE vars:
1138 if (len(myuse) == 1) and (myuse[0] == "*"):
1139 # enable it even if it's ! (for repoman) but kill it if it's
1140 # an arch variable that isn't for this arch. XXX Sparc64?
1141 if (mysplit[mypos][:-1] not in settings.usemask) or \
1142 (mysplit[mypos][:-1]==settings["ARCH"]):
1143 enabled=1
1144 else:
1145 enabled=0
1146 else:
1147 if mysplit[mypos][0] == "!":
1148 myusevar = mysplit[mypos][1:-1]
1149 enabled = not myusevar in myuse
1150 #if myusevar in myuse:
1151 # enabled = 0
1152 #else:
1153 # enabled = 1
1154 else:
1155 myusevar=mysplit[mypos][:-1]
1156 enabled = myusevar in myuse
1157 #if myusevar in myuse:
1158 # enabled=1
1159 #else:
1160 # enabled=0
1161 if (mypos +2 < len(mysplit)) and (mysplit[mypos+2] == ":"):
1162 # colon mode
1163 if enabled:
1164 # choose the first option
1165 if type(mysplit[mypos+1]) == types.ListType:
1166 newsplit.append(dep_opconvert(mysplit[mypos+1],myuse))
1167 else:
1168 newsplit.append(mysplit[mypos+1])
1169 else:
1170 # choose the alternate option
1171 if type(mysplit[mypos+1]) == types.ListType:
1172 newsplit.append(dep_opconvert(mysplit[mypos+3],myuse))
1173 else:
1174 newsplit.append(mysplit[mypos+3])
1175 mypos += 4
1176 else:
1177 # normal use mode
1178 if enabled:
1179 if type(mysplit[mypos+1]) == types.ListType:
1180 newsplit.append(dep_opconvert(mysplit[mypos+1],myuse))
1181 else:
1182 newsplit.append(mysplit[mypos+1])
1183 # otherwise, continue
1184 mypos += 2
1185 else:
1186 # normal item
1187 newsplit.append(mysplit[mypos])
1188 mypos += 1
1189 return newsplit
1190