m RDc@s9dZdklZdkTeedeeddbZdefd YZd Z d Z hd e <d e Z8d?Z9d@Z:dAZ;dBZ<dCZ=dDZ>e"Z?e#Z@dEZAdFZBydkCTe,p eDZ+nWqeEj oqXndGZ0dHZFdIZ5dJZ7dKZ9dLZ:dMZ;dNZ<dOZ=e&iGi>Z>e&iGiAZAdPZ?dQZ@dRZ8dSZBeHdTZIdUeJfdVYZKdWdadXZLdYZMdadeHdZZNdd[ZOdad\ZPd]ZQd^ZRdaaSd_ZTd`ZUdaS(cs util.py - Mercurial utility functions and platform specfic implementations Copyright 2005 K. Thananchayan This software may be used and distributed according to the terms of the GNU General Public License, incorporated herein by reference. This contains helper routines that are independent of the SCM core and hide platform-specific details from the core. (sgettext(t*s5cStringIO errno getpass popen2 re shutil sys tempfilesos threading times%Y-%m-%d %H:%M:%Ss%Y-%m-%d %H:%Ms%a %b %d %H:%M:%S %YtSignalInterruptcBstZdZRS(s'Exception raised on SIGTERM and SIGHUP.(t__name__t __module__t__doc__(((t2/usr/lib/python2.4/site-packages/mercurial/util.pyRs csjti|dd\}d}tid|}|i|i }|i |i |S(s9filter string S through command CMD, returning its outputitbcsQyiiWn/tj o#}|itijoqMnXdS(N(tpintwritetstclosetIOErrortinstterrnotEPIPE(R (R R(Rtwriters  ttargetN( tpopen2tcmdtpoutRRt threadingtThreadtwtstarttreadtfR tjoin(R RRRRRR((R RRt pipefilters     cCs=d \}}ztidd\}}ti|d}|i ||i tidd\}}ti ||id|}|id|}ti|}|o&ttd|t|fnt|diSWd y|oti|nWnnXy|oti|nWnnXXd S( sfilter string S through a pair of temporary files with CMD. CMD is used as a template to create the real command to be run, with the strings INFILE and OUTFILE replaced by the real names of the temporary files generated.tprefixs hg-filter-in-twbshg-filter-out-tINFILEtOUTFILEscommand '%s' failed: %strbN(NN(tNonetinnametoutnamettempfiletmkstemptinfdtostfdopentfpRR R toutfdRtreplacetsystemtcodetAbortt_t explain_exittopenRtunlink(R RR)R&R"R-R#R*((Rt tempfilter-s4    &s tempfile:spipe:cCs[xKtiD]=\}}|i|o!|||t|iSq q Wt ||S(sIfilter a string through a command that transforms its input to its outputN( t filtertablet iteritemstnametfnRt startswithR tlentlstripR(R RR6R7((RtfilterMs  %cCskt|to|iti}nx>|D]6}tii||}tii |o|Sq-q-W|S(sfind name in search path. path can be string (will be split with os.pathsep), or iterable thing that returns strings. if name found, return path to name. else return default.N( t isinstancetpathtstrtsplitR'tpathseptpRR6tp_nametexiststdefault(R6R=RDRBRA((Rt find_in_pathTs c Cstdtiiddd}tid|||f}h}x[|D]S}|i }|i d||ido t|}|i|dqJqJW|i}|o$ttd t|d n|iS( s]apply the patch to the working directory. a list of patched files is returnedtgpatchtPATHttpatchs%s -p%d < "%s"s%s spatching file ispatch command failed: %siN(RER'tenvirontgettpatchertpopentstript patchnameR)tfilestlinetrstriptuitstatusR8tparse_patch_outputtpft setdefaultR R-R.R/R0tkeys( RNRORSR)RPR-RLRVRQ((RRI`s!   $cCs$|od|d jotSntS(s=return true if a string is binary data using diff's heuristictiN(R tTruetFalse(R ((Rtbinaryqsccs:h}x-|D]%}||jod||<|Vq q WdS(s&return the uniq elements of iterable giN(tseentgR(R^R]R((Rtuniquews  R.cBstZdZRS(s5Raised if a command needs to print an error and exit.(RRR(((RR.s cCstS(N(RZ(R7((RtalwaysscCstS(N(R[(R7((RtneverstglobcCsCx6d D].}|i|do|iddSqqW||fS( sOSplit a string into an optional pattern kind prefix and the actual pattern.treRbR=trelglobtrelpathtrelret:iN(sresglobspathsrelglobsrelpathsrelre(RR6R8R?tdflt_pat(R6RhR((Rtpatkinds t^t$c sdtd}t} d}xZjoL}d|djo6|djod7|d7}q|d7}q4|djo|d 7}q4|d jo}|jo|d jo|d7}nx-|jo|d jo|d7}qW|jo|d 7}q|!i dd} |d| ddjod| d} n | ddjod| } nd|| f}q4|djot } |d7}q4|djo| o|d7}t} q4|djo| o|d7}q4|djoH|} | o!d7|ti| 7}q|ti|7}q4|ti|7}q4W|||S(s$convert a glob pattern into a regexpiRHcsjoS(N(titntpat((RlRnRm(RtpeeksiRs.*s[^/]*t?t.t[s!]t]s\[s\s\\t!Rjs%s[%s]t{s(?:t}t)t,t|N(R9RnRlRmtresR[tgroupRotctjR+tstuffRZRARctescapetheadttail( RnRRRoRlRzR}R|RmRAR~R{((RnRlRmRtglobres`               RriRuRRpcCs|pt|Sn|id|id}}|i|ix<|o4|o-|d|djo|i|iqKW|iti i dgt ||S(s}return the relative path from one place to another. this returns a path in the form used by the local filesystem, not hg.t/is..N( tn1t localpathtn2R?taRtreversetpopR'tsepRR9(RRRR((Rtpathtos  #  c Cs|tijo ti}n+|itio |}n|ti}|}tii|ptii |||}ntii |}||jo8|i |o(|t |}t|t|Sn||jodSnti|}g}xtoyti|}Wntj oPnXt||o4|itii |}t|t|Sntii|\} }|i|| |joPn| }qWtd|dS(s7return the canonical path of myname, given cwd and rootRHs%s not under rootN(trootR'RtrootseptendswithtmynameR6R=tisabsRtcwdtnormpathR8R9t audit_pathtpconverttstattroot_sttrelRZtname_sttOSErrortsamestatRR?tdirnametbasenametappendR.( RRRR6RRRRRR((Rt canonpathsF          RHRqc Cst||||||d|S(NRb(t_matchert canonrootRtnamestinctexcRtsrc(RRRRRRR((Rtmatchersc Cs?tidjo d}nd}t||||||||S(NtntRbRe( R'R6RhRRRRRRRR(RRRRRRRRh((Rt cmdmatchers c scd dd} d}ggg} xg} |D]}| t ||qP~ D]\}}|djo3t|||}|djod\}}qn|djoi||fn|djo(||}|o| i|qCqm|djo$i||f| i|qmqmW|d pt|d ptt|oFg} |D]}| t t|||q~ }||d nd |oFg} |D]}| t t|||q~ } || d n| d|p|podgjotfS(s*build a function to match a set of file patterns arguments: canonroot - the canonical root of the tree you're matching against cwd - the current working directory, if relevant names - patterns to find inc - patterns to include exc - patterns to exclude head - a regex to prepend to patterns to control whether a match is rooted a pattern is one of: 'glob:' 're:' 'path:' 'relglob:' 'relpath:' 'relre:' '' returns: a 3-tuple containing - list of explicit non-pattern names passed in - a bool match(filename) function - a bool indicating if any patterns were passed in todo: make head regex a rooted bool cCs*x#|D]}|tjotSqqWtS(N(R6R|t _globcharsRZR[(R6R|((Rt contains_glob$s  cs|djo|Sn|djodti|dSn}|djot|d|SnX|djoti||Sn2|djo$|ido|Snd |Snt|d |S( s+convert a pattern into a regular expressionRcR=Rjs(?:/|$)Rds(?:|.*/)ReRfs.*RHN(tkindR6RcRRRRR8(RR6R(R(Rtregex)s      cs|pdSngx|D]\}}y3d|||}iti |i Wqti j oAot d||fqt d||fqXqWd}|S(s0build a matching function from a set of patternsNs(?:%s)s%s: invalid pattern (%s): %ssinvalid pattern (%s): %scs0x)D]!}||}|o|SqqWdS(N(tmatchestmttexttr(RRR(R(RtbuildfnFs  (tpatsRtkRARRRnRRctcompiletmatchterrorRR.R(RRRnRRRRA(RR(RRtmatchfn9s  csOg}x9|itiD]%}|oPn|i|qWdi|S(s7return the non-glob prefix of a path, e.g. foo/* -> fooRN( RRnR?R'RRARRR(RnRRA(R(Rt globprefixNs RbReRHs**R=RcRks(?:/|$)cCstS(N(R[(R7((Rtmscs`|oS| oE|idp5 o p%o |po |S(NR(tincmatchR7texcmatchRRRPtpatmatcht filematch(R7(RPRRRRR(RRssN(sglobsrelpath(sglobs**(sglobspathsre(sglobs**(RRRRRRPtrootst_[1]RRARiRhRR6RRRRRR`RRRRRltinckindsRRtxtexckindsRZ(RRRRRRRhRRRRRRRRRPRRRRR6RRlRRRARR(( RRRRPRRRRRRRRsD   +       3 3c Csd}h}x$|D]} tii| || (R((Rtpy2shells  s%s %siis%s: %ss N(RtoldenvRJRR'RKRR!tgetcwdtoldcwdR5tvtchdirR,RtrctonerrR=RR?R0terrmsgt errprefixtwarntAttributeError( RRJRRRRRRRRRR((RR,zs@   6  cCsyti||Wntj o{}tidtii |pd\}}ti |ti |ti||ti |ti||nXdS(sforcibly rename a filetdirRqN(R'trenameRtdstRterrR$R%R=RtfdttempR R2(RRRRR((RRs+   cCsDti|ytitii|Wntj onXdS(s.unlink and remove the directory if it is emptyN(R'R2Rt removedirsR=RR(R((RR2s  cCs|djo4ti|ititii|ij}ntii |oeti |xti |D]@}tii ||}tii ||}t|||qqWn_|oGyt||Wqttfj ot}ti||qXnti||dS(s1Copy a directory tree using hardlinks if possibleN(thardlinkR!R'RRtst_devR=RRtisdirtmkdirtlistdirR6Rtsrcnametdstnamet copyfilestos_linkR RR[tshutiltcopy(RRRR6RR((RRs" 4 cCsttii|iti}tii|dp!|ddjpti|jott d|ndS(s+Abort if path contains dangerous componentsis.hgRHs$path contains illegal component: %s N(s.hgRH( R'R=tnormcaseR?Rtpartst splitdrivetpardirR.R/(R=R((RRs8cCsDti|titiBtiB}ti||ti |dS(N( R'R1tpathnametO_CREATtO_WRONLYtO_EXCLtldRtinfoR (RRR((Rt_makelock_files#cCst|iS(N(t posixfileRR(R((Rt_readlock_filescCsti|iS(s.Return number of hardlinks for the given file.N(R'tlstatRtst_nlink(R((RtnlinksstlinkcCstdtddS(NisHardlinks not supported(RR/(RR((RRscCsAyti|iSWn#tj oti|iSnXdS(s1stat file object that may not have fileno method.N(R'tfstatR)tfilenoRRR6(R)((RRs cCs[ytiddjSWn<tj o0tidjodtiiddjSnXdS(s+return true if run on windows 95, 98 or me.iiRtcommandtcomspecRHN(tsystgetwindowsversionRR'R6RJRK(((Rt is_win_9xs cCsLytiSWn%tj oto tSq6nXttddS(sreturn name of current users;user name not available - set USERNAME environment variableN(tgetpasstgetusert ImportErrortgetuser_fallbackR.R/(((RRsRtmsvcrtsNUL:t winstdoutcBs2tZdZdZdZdZdZRS(s3stdout on windows misbehaves if sent through a pipecCs ||_dS(N(R)tself(RR)((Rt__init__scCst|i|S(N(tgetattrRR)tkey(RR((Rt __getattr__scCsy|iiWnnXdS(N(RR)R (R((RR scCscy|ii|SWnHtj o<}|idjon|ittidnXdS(Nis Broken pipe( RR)RR R R R R R(RR R ((RR"s (RRRRRR R(((RRs    cCs y tSWndgSnXdS(Nsc:\mercurial\mercurial.ini(tsystem_rcpath_win32(((Rt system_rcpath,s cCsVt}|ittiid}|o |itii|dn|S(s+return default os-specific hgrc search patht USERPROFILEs mercurial.iniN( RR=Rt user_rcpathR'RJRKt userprofileR(R=R ((Rt os_rcpath2s  cCstiitiiddS(s3return os-specific hgrc search path to the user dirt~s mercurial.iniN(R'R=Rt expanduser(((RR ;scCs0|d}|ddjo|dd!}n|S(s=parses the output produced by patch and returns the file nameiit`iiN(t output_lineRV(RRV((RRU?s  cCstS(s6return False if pid dead, True if running or not knownN(RZ(tpid((RttestpidFscCs|S(N(tlast(RR((Rtis_execJscCsdS(N((Rtmode((Rtset_execMscCsti|itidS(N(RtsetmodeRRR'tO_BINARY(R((Rt set_binaryPscCs|iddS(Ns\R(R=R+(R=((RRSscCs|iddS(NRs\(R=R+(R=((RRVscCsttii|S(N(RR'R=R(R=((RRYscCstS(N(R[(ts1ts2((RR_scCstd||fS(Nsexited with status %d(R/R-(R-((RR0bss /dev/nullcCstii|dg}tii|d}yX|ig}ti|D]0}|i do|tii||qJqJ~Wnt j o }nX|S(Nthgrcshgrc.ds.rc( R'R=RtrcstrcdirtextendRRRRRR (R=RRRR R((RtrcfilespsXcCsg}tttdgdjo.|ittiitiddn|itd|i tii dg}|D]}|tii |q~}|S(s+return default os-specific hgrc search pathtargvis/../etc/mercurials/etc/mercurials~/.hgrcN(R=R9RRRRR'RR RR RRR(RRR=((RR ys.-cCsL|d}|ido.|idod|jo|dd!}n|S(s=parses the output produced by patch and returns the file nameit't iiN(RRVR8R(RRV((RRUs  -cCsti|id@djS(s"check whether a file is executablei@iN(R'RRtst_mode(RR((RRscCsti|i}|d@dj|jodSn|oAtid}ti|ti|||d@d?|@Bnti||d@dS(Ni@ii$ii(R'RRR#R Rtumasktchmod(RRR$R ((RRs %cCsdS(N((R((RRscCs|S(N(R=(R=((RRscCs|S(N(R=(R=((RRscCsWyti||Wn<tj o0}|itijoqSt||nXdS(N( R'tsymlinkRRRtwhyR tEEXISTR(RRR'((Rtmakelocks cCsQyti|SWn9tj o-}|itijot|SqMnXdS(N(R'treadlinkRRR'R tEINVALR(RR'((Rtreadlocks cCsDyti|dtSWn%tj o}|itijSnXdS(s5return False if pid dead, True if running or not sureiN(R'tkillRRZRR R tESRCH(RR ((RRs cCsti|o'ti|}td||fSnoti|o'ti|}td||fSn8ti|o'ti |}td||fSnt tddS(s;return a 2-tuple (desc, code) describing a process's statussexited with status %dskilled by signal %dsstopped by signal %dsinvalid exit codeN( R't WIFEXITEDR-t WEXITSTATUSRR/t WIFSIGNALEDtWTERMSIGt WIFSTOPPEDtWSTOPSIGt ValueError(R-R((RR0sc so||ddtfdYdfdYdtttd}|S( s return a function that opens files relative to base this function is used to hide the details of COW semantics and remote file access from higher level code. c Cs.tii|\} }tidd|d| \}}ti |t |d}yyt |d}Wn8tj o,}t|ddp ||_nnXx!t|D]}|i|qW|i |i Wn%yti|WnnXnXti|}ti||i|S(NRs.%s-RRR tfilename(R'R=R?R6tdR7R$R%RRR RtofptifpR R RR!R6t filechunkitertchunkRR2RtstR%R#( R6RR;R R<R8RR9R7R7((Rt mktempcopys2"    tatomictempfilecs,tZdZdZdZdZRS(s2the file will only be copied when rename is calledcs2||_||_ti||i|dS(N(R6Rt_atomictempfile__nameR=RRRR(RR6R(R=(RRs cCs8|ip*ti|t|it|indS(N(RtclosedRR RRRR?(R((RRs  cCs=|ip/yti|iWnnXti|ndS(N(RR@R'R2RRR (R((Rt__del__s  (RRRRRRA((R=(RR>s   t atomicfilecs,tZdZdZdZdZRS(s%the file will only be copied on closecsi|||dS(N(R>RRR6R(RR6R(R>(RRscCs|idS(N(RR(R((RR scCs|idS(N(RR(R((RRA s(RRRRR RA((R>(RRBs   Rcsot|ntii|}|p|d7}n|ddjoyt |}WnIt j o=tii |}tii|pti|qqX|o||Sn|o||Sn|djot||qnt||S(NRiRi(taudit_pRR=R'RRARRRRtnlinkRRR7RtmakedirstatomicRBt atomictempR>RR=R(R=RRRFRGRR7RD(R>RCR=RARB(Rto s& N( tbaseRAtauditRCR=RR>RBR[RH(RIRJR>RCRHRARBR=((R>RCRARBR=Rtopeners  $t chunkbuffercBs0tZdZdddZdZdZRS(soAllow arbitrary sized chunks of data to be efficiently read from an iterator over chunks of arbitrary size.iicCs^t||_d|_t||_|idjottd|nt|_ dS(szin_iter is the iterator that's iterating over the input chunks. targetsize is how big a buffer to try to maintain.RHis)targetsize must be greater than 0, was %dN( titertin_iterRtbuftintt targetsizeR5R/R[t iterempty(RRNRQ((RR*s cCsg|ipYti}|i|ix|iD]}|i|q0W|i |_t |_ndS(s?Ignore target size; read every chunk from iterator until empty.N( RRRt cStringIOtStringIOt collectorRRORNtchtgetvalueRZ(RRVRU((Rtfillbuf5s   cCs|t|ijo|i o|i||id}ti}|i |it|i}x@|i D]5}|i ||t|7}||joPqnqnW||jo t |_n|i|_n|i| t|i|}|_|S(suRead L bytes of data from the iterator of chunks of data. Returns less than L bytes if the iterator runs dry.iN(tlR9RRORRRQRSRTRURt collectedRNR;RZRWtbufferR (RRYRQR RZRUR;((RR?s"!       #(RRRRRXR(((RRL&s  iccs|djpt|djp|djptxstok|djo |}nt||}|o |i|}|pPn|o|t |8}n|Vq8WdS(sXCreate a generator that produces the data in the file size (default 65536) bytes at a time, up to optional limit (default is to read all data). Chunks may be less than size bytes if the chunk is the last chunk in the file, or the file is a socket or some other type of file that sometimes reads less data than is requested.iN( tsizetAssertionErrortlimitR!RZtnbytestminRRR R9(RR\R^R R_((RR:Ss! cCsPti}|ddjotio ti}n ti}ti||fS(Nii(ttimet localtimetlttdaylighttaltzonettzttimezonetmktime(RcRf((Rtmakedateds    cCsl|pt\}}ti|tit||}|o&|d| d| ddf7}n|S(srepresent a (unixtime, offset) tuple as a localized time. unixtime is seconds since the epoch, and offset is the time zone's number of seconds away from UTC. if timezone is false, do not append time zone to string.s %+03d%02dii<N( tdateRittRfRatstrftimetformattgmtimetfloatR Rg(RjRmRgRfR Rk((Rtdatestrls %&cCsd}||o?|d |d}}t|}d|dd|d}n|d}}ttiti|||}||fS( s~parse a localized time string and return a (unixtime, offset) tuple. if the string cannot be parsed, ValueError is raised.cCsA|dio0|ddjp|ddjo|diS(Niit+t-i(tstringtisdigittisspace(Rs((Rt hastimezonezsiiiidi<iN( RvRsRjRfRPtoffsetRaRhtstrptimeRmtwhen(RsRmRfRyRvRwRj((Rtstrdatews    %cCs |p t}ny"tt|id\}}Wnjtj o^xY|D]6}yt ||\}}Wntj oqKXPqKWtt d|nXt |djott d|n|djp |djott d|n||fS( sparse a localized time string and return a (unixtime, offset) tuple. The date may be a "unixtime offset" string or in one of the specified formats.R"sinvalid date: %risdate exceeds 32 bits: %di ;isimpossible time zone offset: %dN( tformatstdefaultdateformatstmapRPRsR?RyRwR5RmRzR/tabs(RsR{RmRyRw((Rt parsedates& "cCs\|id}|djo|| }n|id}|djo||d}n|S(s>Return a short representation of a user name or email address.t@ittdfddd>tdfddd>tdfddd>td fddd>td fddd>td fddd>td fddd>td fddd>tdfddtdff }x>|D]6\}}}|||jo||t|SqqW|dd|S(s:return byte count formatted as readable string, with unitsidiis%.0f GBi s%.1f GBs%.2f GBis%.0f MBs%.1f MBs%.2f MBs%.0f KBs%.1f KBs%.2f KBs %.0f bytesiiN(R/tunitst multipliertdivisorRmR_Ro(R_RRmRR((Rt bytecounts N(s%Y-%m-%d %H:%M:%Ss%Y-%m-%d %H:%Ms%a %b %d %H:%M:%S %Y(VRti18ntgettextR/t demandloadtglobalsR|t ExceptionRRR3R4R;R!RERIR\R_R.R`RaRiRRRRRRRR,RR2RRRRRthasattrR'RRRtfileRRRRR6tnulldevRRtstdoutRR R RURRRRRRRR)R,RR0t util_win32t posixfile_ntRRR=RZRKtobjectRLR:RiRpRzRRRRRR(ARRRRRURiR,RRzRRLRRR\R2R:RR,RRERR RRRRRpRRRRR0RRiRR4RRaRRRRKR RR3R_RR/R|RRRRR`RRRIR;RRR.RRRR)((RRp s          4* - t,                                  V-