ó ºµiVc@sdZddlZddlZddlZddlZddlZddlZddlZddlm Z ddl m 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|ƒjƒ||_dS(N(tsuperRt__init__tmsg(tselfR((s/../../common/bootmgmt/backend/loader/menulst.pyR)scCs|jS(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|jjdƒ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||_|j|ƒdS(N(t_commandtset_args(Rtcommandtargs((s/../../common/bootmgmt/backend/loader/menulst.pyR?s cCs|jS(N(R(R((s/../../common/bootmgmt/backend/loader/menulst.pyt get_commandCscCs|jS(N(t_args(R((s/../../common/bootmgmt/backend/loader/menulst.pytget_argsFscCsu|dkrg|_nYt|tƒrhd}gtj|ƒj|ƒD]}|d^qF}||_n ||_dS(NsJ([^ \t"]+"([^\\"]|\\.)*"[^ \t]*|([^ \t\\"]|\\.)*"[^"]*(?![^"]*")|[^ "\t]+)i(tNoneRt isinstancet basestringtretcompiletfindall(RRtpatterntvtargv((s/../../common/bootmgmt/backend/loader/menulst.pyRIs  / cCsW|jdk r9|jdk r9|jddj|jƒS|jdk rO|jSdSdS(Nt t(RRRtjoin(R((s/../../common/bootmgmt/backend/loader/menulst.pyRYs cCs,dt|jƒdt|jƒ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+|dkrg|_nt|ƒ|_dS(N(Rt_cmdlisttlist(RR((s/../../common/bootmgmt/backend/loader/menulst.pyRns  cCs|jjt|ƒƒdS(N(R+tappendR (RR ((s/../../common/bootmgmt/backend/loader/menulst.pyt add_commenttscCsÈ|jƒdkrK|jdƒ}|dkr´|jj|d|ƒdSni|jƒdkr´|jdƒ}|dkrŠ|jdƒ}n|dkr´|jj|d|ƒdSn|jj|ƒdS(Ntfindrootttitleiÿÿÿÿitbootfs(Rt_find_command_indexR+tinsertR-(Rtmlcmdtidx((s/../../common/bootmgmt/backend/loader/menulst.pyt add_commandws   cCsYxRt|jƒD]A\}}t|tƒs1qn||jƒkr|j|=dSqWdS(N(t enumerateR+RRR(RtcmdR5t_cmd((s/../../common/bootmgmt/backend/loader/menulst.pytdelete_commandŠs  cCs=x6|jD]+}t|tƒr ||jƒkr |Sq WdS(N(R+RRRR(RtnameR8((s/../../common/bootmgmt/backend/loader/menulst.pyt find_command’s!cCsIxBt|jƒD]1\}}t|tƒr||jƒkr|SqWdS(Niÿÿÿÿ(R7R+RRR(RR;R5R8((s/../../common/bootmgmt/backend/loader/menulst.pyR2˜s!cCsT|j|ƒ}|dk r+|j|ƒn%|tkrP|jt||ƒƒndS(N(R<RRtTrueR6R(RR8Rtcreatetentity((s/../../common/bootmgmt/backend/loader/menulst.pytupdate_commandžs   cCs,g|jD]}t|ƒtkr |^q S(N(R+ttypeR(RR8((s/../../common/bootmgmt/backend/loader/menulst.pytcommands¥scCsDd}x.|jD]#}|t|ƒjdƒd7}qW|jdƒS(NR!s (R+tstrR(RR'R8((s/../../common/bootmgmt/backend/loader/menulst.pyR¨s!cCs¤d}d}t|jƒdkrcx?tt|jƒdƒD]!}|t|j|ƒd7}q;Wnt|jƒdkr–|t|j|dƒ7}n|d7}|S(NsMenuLstMenuEntry = [iis, it](tlenR+trangeR&(RR'ti((s/../../common/bootmgmt/backend/loader/menulst.pyR(®s " N(RR R)RRR.R6R:R<R2tFalseR@RBRR((((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|_||_|jƒdS(NiR!(ttargett_linet_lastt _entitylistt _filenamet_parse(Rtfilename((s/../../common/bootmgmt/backend/loader/menulst.pyR¼s      cCs t|jƒ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,RM(R((s/../../common/bootmgmt/backend/loader/menulst.pytentitiesÄscCs>x7t|jƒD]&\}}||kr|j|=dSqWdS(N(R7RM(RR?R5tcur((s/../../common/bootmgmt/backend/loader/menulst.pyt delete_entityÊs  cCs|jjt|ƒƒdS(N(RMR-R (RR ((s/../../common/bootmgmt/backend/loader/menulst.pyR.ÑscCs|jj|ƒdS(s:Add a MenuLstCommand or MenuLstMenuEntry to the entitylistN(RMR-(RR8((s/../../common/bootmgmt/backend/loader/menulst.pyR6ÔscCs”d}x0t|jƒD]\}}t|tƒrPqqW|jddƒ}t|ƒdkrj|d}nd}|jj|t|d|ƒƒdS(s=Add a command & args to the end of the global command sectioniR iN( R7RMRR*tsplitRERR3R(Rt cmd_plus_argsR5titemRR((s/../../common/bootmgmt/backend/loader/menulst.pyt add_globalØs cCs2d}x%|jD]}|t|ƒd7}qW|S(NR!s (RMRC(RR'R?((s/../../common/bootmgmt/backend/loader/menulst.pyRæscCs t|jƒS(N(R&RM(R((s/../../common/bootmgmt/backend/loader/menulst.pyR(ìscCsZt|jƒ}z/x|D]}|j|ƒqW|jdƒWd|jƒX|jƒdS(sParse the menu.lst fileN(topenRNt _parse_lineRtcloset_analyze_syntax(Rtfileobjtline((s/../../common/bootmgmt/backend/loader/menulst.pyROïs  cCsdS(s2This can be overridden in child classes, if neededN((R((s/../../common/bootmgmt/backend/loader/menulst.pyR[ûscCs‹d}t}xrtt|ƒƒD]^}||dkr\||ddkr\t}|d7}q||dkr|||7}qqW||fS(NR!s\is R (RHRFRER=(tistrtrestnewline_escapedR5((s/../../common/bootmgmt/backend/loader/menulst.pyt_process_escapesÿs$ cCs |dkr.|jdkr*tdƒ‚ndS|jd7_|jƒ}|dkse|ddkry|jj|ƒdSy|j|ƒ\}}Wntk r±tdƒ‚nX|rË|j|7_dS|j|}d|_d}gt j |ƒj |ƒD]}|d^q}t |ƒdkrœ|ddkrZt ƒ|_|jj|jƒn|djd dƒ|d}|jjt|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]+)R0t=(RRLRRKtstripRJR.Rat IndexErrorRRRRER*RMR-RTR6R(RtnextlinetstrippedR`RRR((s/../../common/bootmgmt/backend/loader/menulst.pyRYs4(     / (RR RRQRSR.R6RWRR(ROR[t staticmethodRaRY(((s/../../common/bootmgmt/backend/loader/menulst.pyRIºs         tMenuLstBootLoaderMixIncBseZdd„ZRS(c Cs¦|dkr+|}|d}y'|jdƒd}tj|dƒWn8tk r}}|jtjkr~|jd|ƒq~nXy<t|dƒ'}|j ||ƒ|jd|ƒWdQXWnot k râ} t d|| ƒ‚nJytj |ƒWn,tk r$} |jd || j fƒnX‚nXy$tj||ƒ|jd |ƒWnlt k r¾} ytj |ƒWn,tk r¡} |jd || j fƒnXt d ||f| ƒ‚nXy?tj|d ƒtj|tjd ƒjtjdƒjƒWn&tk r&} t d|| ƒ‚nXdSy6tjd|dtƒ} |j | |ƒ| jƒWnzt k r…} t d| ƒ‚nYy| r¤tj | jƒnWn/tk rÖ} |jd | j| j fƒnX‚nX|dtjj|ƒ} ytj| j| ƒWnut k r†} ytj | jƒWn/tk rf} |jd | j| j fƒnXt d | j| f| ƒ‚nXtj | 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_debugRXt_write_menu_lsttIOErrorRtremovetstrerrortshutiltmovetchmodtchowntpwdtgetpwnamtpw_uidtgrptgetgrnamtgr_gidttempfiletNamedTemporaryFileRHRZR;tpathtbasenameRtOUTPUT_TYPE_FILE( Rtbasepatht menu_lst_pathtaccessortrealmenuttempmenutmenu_lst_parenttosetoutfileterrtoserrttmpfiletintermediate_name((s/../../common/bootmgmt/backend/loader/menulst.pyt_write_config_genericmsš        N(RR RR–(((s/../../common/bootmgmt/backend/loader/menulst.pyRils(R)RtR‚RqRRR{R…tbootmgmtRtbootmgmt.bootconfigRt ExceptionRtobjectR RR*RIRi(((s/../../common/bootmgmt/backend/loader/menulst.pyts         +S²