Ñò ºµiVc @sdZddkZddkZddkZddkZddkZddkZddkZddkl Z ddk l Z de fd„ƒYZ defd„ƒYZd efd „ƒYZd efd „ƒYZd efd„ƒYZdefd„ƒYZdS(s/ menu.lst parser implementation for pybootmgmt iÿÿÿÿN(tBootmgmtConfigWriteError(t BootConfigt MenuLstErrorcBseZd„Zd„ZRS(cCs tt|ƒiƒ||_dS(N(tsuperRt__init__tmsg(tselfR((s/../../common/bootmgmt/backend/loader/menulst.pyR)scCs|iS(N(R(R((s/../../common/bootmgmt/backend/loader/menulst.pyt__str__-s(t__name__t __module__RR(((s/../../common/bootmgmt/backend/loader/menulst.pyR(s tMenuLstCommentcBs#eZd„Zd„Zd„ZRS(cCs ||_dS(N(t_comment(Rtcomment((s/../../common/bootmgmt/backend/loader/menulst.pyR2scCs ||_dS(N(R (RR ((s/../../common/bootmgmt/backend/loader/menulst.pytupdate_comment5scCs|iidƒS(Ns (R trstrip(R((s/../../common/bootmgmt/backend/loader/menulst.pyR8s(RR RR R(((s/../../common/bootmgmt/backend/loader/menulst.pyR 1s  tMenuLstCommandcBsGeZdZdd„Zd„Zd„Zd„Zd„Zd„Z RS(s;A menu.lst command and its arguments from the menu.lst filecCs||_|i|ƒdS(N(t_commandtset_args(Rtcommandtargs((s/../../common/bootmgmt/backend/loader/menulst.pyR?s cCs|iS(N(R(R((s/../../common/bootmgmt/backend/loader/menulst.pyt get_commandCscCs|iS(N(t_args(R((s/../../common/bootmgmt/backend/loader/menulst.pytget_argsFscCs|djo g|_ndt|tƒoJd}g}ti|ƒi|ƒD]}||dqM~}||_n ||_dS(NsJ([^ \t"]+"([^\\"]|\\.)*"[^ \t]*|([^ \t\\"]|\\.)*"[^"]*(?![^"]*")|[^ "\t]+)i(tNoneRt isinstancet basestringtretcompiletfindall(RRtpatternt_[1]tvtargv((s/../../common/bootmgmt/backend/loader/menulst.pyRIs  7 cCs\|idj o,|idj o|iddi|iƒS|idj o|iSdSdS(Nt t(RRRtjoin(R((s/../../common/bootmgmt/backend/loader/menulst.pyRYs  cCs,dt|iƒdt|iƒd}|S(Nt(t,t)(treprRR(Rtostr((s/../../common/bootmgmt/backend/loader/menulst.pyt__repr__as(N( RR t__doc__RRRRRRR)(((s/../../common/bootmgmt/backend/loader/menulst.pyR<s     tMenuLstMenuEntrycBsneZdZd d„Zd„Zd„Zd„Zd„Zd„Z e d„Z d„Z d „Z d „ZRS( sÝRepresentation of a menu.lst menu entry, which consists of a list of MenuLstCommand objects (the first of which must be the 'title' command). ._cmdlist = [MenuLstCommand #1, MenuLstCommand #2, ...] cCs-|djo g|_nt|ƒ|_dS(N(Rt_cmdlisttlist(RR((s/../../common/bootmgmt/backend/loader/menulst.pyRns  cCs|iit|ƒƒdS(N(R,tappendR (RR ((s/../../common/bootmgmt/backend/loader/menulst.pyt add_commenttscCsÒ|iƒdjo<|idƒ}|djo|ii|d|ƒdSnp|iƒdjo\|idƒ}|djo|idƒ}n|djo|ii|d|ƒdSn|ii|ƒdS(Ntfindrootttitleiÿÿÿÿitbootfs(Rt_find_command_indexR,tinsertR.(Rtmlcmdtidx((s/../../common/bootmgmt/backend/loader/menulst.pyt add_commandws     cCs]xVt|iƒD]E\}}t|tƒpqn||iƒjo|i|=dSqWdS(N(t enumerateR,RRR(RtcmdR6t_cmd((s/../../common/bootmgmt/backend/loader/menulst.pytdelete_commandŠs  cCs@x9|iD].}t|tƒo||iƒjo|Sq WdS(N(R,RRRR(RtnameR9((s/../../common/bootmgmt/backend/loader/menulst.pyt find_command’s  # cCsLxEt|iƒD]4\}}t|tƒo||iƒjo|SqWdS(Niÿÿÿÿ(R8R,RRR(RR<R6R9((s/../../common/bootmgmt/backend/loader/menulst.pyR3˜s  # cCsX|i|ƒ}|dj o|i|ƒn(|tjo|it||ƒƒndS(N(R=RRtTrueR7R(RR9Rtcreatetentity((s/../../common/bootmgmt/backend/loader/menulst.pytupdate_commandžs   cCs9g}|iD]$}t|ƒtjo ||qq~S(N(R,ttypeR(RRR9((s/../../common/bootmgmt/backend/loader/menulst.pytcommands¥scCsDd}x.|iD]#}|t|ƒidƒd7}qW|idƒS(NR"s (R,tstrR(RR(R9((s/../../common/bootmgmt/backend/loader/menulst.pyR¨s  !cCs¨d}d}t|iƒdjoCx@tt|iƒdƒD]!}|t|i|ƒd7}q<Wnt|iƒdjo|t|i|dƒ7}n|d7}|S(NsMenuLstMenuEntry = [iis, it](tlenR,trangeR'(RR(ti((s/../../common/bootmgmt/backend/loader/menulst.pyR)®s# N(RR R*RRR/R7R;R=R3tFalseRARCRR)(((s/../../common/bootmgmt/backend/loader/menulst.pyR+gs         t MenuDotLstcBszeZd„Zd„Zd„Zd„Zd„Zd„Zd„Zd„Z d„Z d „Z e d „ƒZ d „ZRS( cCs;||_d|_d|_g|_||_|iƒdS(NiR"(ttargett_linet_lastt _entitylistt _filenamet_parse(Rtfilename((s/../../common/bootmgmt/backend/loader/menulst.pyR¼s      cCs t|iƒS(s‹Return a list of entities encapsulated by this MenuDotLst. A new list is returned so that deletions can occur in for-loop. (R-RN(R((s/../../common/bootmgmt/backend/loader/menulst.pytentitiesÄscCs@x9t|iƒD](\}}||jo|i|=dSqWdS(N(R8RN(RR@R6tcur((s/../../common/bootmgmt/backend/loader/menulst.pyt delete_entityÊs    cCs|iit|ƒƒdS(N(RNR.R (RR ((s/../../common/bootmgmt/backend/loader/menulst.pyR/ÑscCs|ii|ƒdS(s:Add a MenuLstCommand or MenuLstMenuEntry to the entitylistN(RNR.(RR9((s/../../common/bootmgmt/backend/loader/menulst.pyR7ÔscCs˜d}x2t|iƒD]!\}}t|tƒoPqqW|iddƒ}t|ƒdjo|d}nd}|ii|t|d|ƒƒdS(s=Add a command & args to the end of the global command sectioniR!iN( R8RNRR+tsplitRFRR4R(Rt cmd_plus_argsR6titemR R((s/../../common/bootmgmt/backend/loader/menulst.pyt add_globalØs  cCs2d}x%|iD]}|t|ƒd7}qW|S(NR"s (RNRD(RR(R@((s/../../common/bootmgmt/backend/loader/menulst.pyRæs  cCs t|iƒS(N(R'RN(R((s/../../common/bootmgmt/backend/loader/menulst.pyR)ìscCsZt|iƒ}z/x|D]}|i|ƒqW|idƒWd|iƒX|iƒdS(sParse the menu.lst fileN(topenROt _parse_lineRtcloset_analyze_syntax(Rtfileobjtline((s/../../common/bootmgmt/backend/loader/menulst.pyRPïs cCsdS(s2This can be overridden in child classes, if neededN((R((s/../../common/bootmgmt/backend/loader/menulst.pyR\ûscCsd}t}xwtt|ƒƒD]c}||djo)||ddjot}|d7}q||djo|||7}qqW||fS(NR"s\is R!(RIRGRFR>(tistrtrestnewline_escapedR6((s/../../common/bootmgmt/backend/loader/menulst.pyt_process_escapesÿs&c Cs·|djo%|idjotdƒ‚ndS|id7_|iƒ}|djp|ddjo|ii|ƒdSy|i|ƒ\}}Wntj otdƒ‚nX|o|i|7_dS|i|}d|_d}g}t i |ƒi |ƒD]}||dq~}t |ƒdjow|ddjo#t ƒ|_|ii|iƒn|did dƒ|d}|iit|d|dƒƒndS( sParses a line of a menu.lst configuration file. The grammar of the menu.lst configuration file is simple: Comments are lines that begin with '#' (with or without preceeding whitespace), and commands are non-comments that include one or more non-whitespace character sequences, separated by whitespace. The commands are not checked for semantic correctness. They're just stored for later analysis. The parser works as follows: If the line is None, parsing is complete, so save the last entry processed to the statement list. If the line (stripped of any leading whitespace) starts with '#', then it's a comment, so save it and return. Split the line into a command portion and an optional argument(s) portion, taking care to process escape sequences (including the special escape of the newline) If the line begins with the 'title' keyword, then a new entry is created and saved so that future commands can be added to it. If an entry is active (if we're parsing after a title command), add the current command and arguments to the current entry. If an entry is not active, add the command and arguments to the statement list. The configuration file entity list contains commands and entries:: [(MenuLstCommand|CommentString)*, (MenuLstMenuEntry|CommentString)*] Comments and blank space is stored as a plain string. R"sDangling backslash detectedNiit#sJ([^ \t"]+"([^\\"]|\\.)*"[^ \t]*|([^ \t\\"]|\\.)*"[^"]*(?![^"]*")|[^ "\t]+)R1t=(RRMRRLtstripRKR/Rbt IndexErrorRRRRFR+RNR.RUR7R(RtnextlinetstrippedRaRRRR ((s/../../common/bootmgmt/backend/loader/menulst.pyRZs4(    7 (RR RRRRTR/R7RXRR)RPR\t staticmethodRbRZ(((s/../../common/bootmgmt/backend/loader/menulst.pyRJºs         tMenuLstBootLoaderMixIncBseZdd„ZRS(cCsÔ|djoB|}|d}y'|idƒd}ti|dƒWn<tj o0}|itijo|id|ƒqƒnXyPt|dƒi i ƒ}z-|~} |i | |ƒ|id|ƒWdQXWnst j o} t d|| ƒ‚nMyti|ƒWn.tj o"} |id || ifƒnX‚nXy$ti||ƒ|id |ƒWnpt j od} yti|ƒWn.tj o"} |id || ifƒnXt d ||f| ƒ‚nXy?ti|d ƒti|tid ƒitidƒiƒWn(tj o} t d|| ƒ‚nXdSy6tid|dtƒ} |i | |ƒ| iƒWn€t j o} t d| ƒ‚n^y| oti| iƒnWn1tj o%} |id | i| ifƒnX‚nX|dtii |ƒ} yti| i| ƒWnyt j om} yti| iƒWn1tj o%} |id | i| ifƒnXt d | i| f| ƒ‚nXt!i"| d|d dd fgS(Ns.newt/iiís(Error while making dirs for menu.lst: %stwsmenu.lst written to %ssCouldn't write to %ss#Error while trying to remove %s: %ssmenu.lst moved into place as %ssCouldn't move %s to %si¤troottsyssCouldn't set mode/perms on tdirtdeletes-Couldn't create a temporary file for menu.lst(#Rt rpartitiontostmakedirstOSErrorterrnotEEXISTt_debugRYt__exit__t __enter__t_write_menu_lsttIOErrorRtremovetstrerrortshutiltmovetchmodtchowntpwdtgetpwnamtpw_uidtgrptgetgrnamtgr_gidttempfiletNamedTemporaryFileRIR[R<tpathtbasenameRtOUTPUT_TYPE_FILE(Rtbasepatht menu_lst_pathtaccessortrealmenuttempmenutmenu_lst_parenttoseRtoutfileterrtoserrttmpfiletintermediate_name((s/../../common/bootmgmt/backend/loader/menulst.pyt_write_config_genericmsš   &     N(RR RR™(((s/../../common/bootmgmt/backend/loader/menulst.pyRjls(R*RuR…RrR‚RR~RˆtbootmgmtRtbootmgmt.bootconfigRt ExceptionRtobjectR RR+RJRj(((s/../../common/bootmgmt/backend/loader/menulst.pyts         +S²