7 from pakfire
.constants
import *
9 class LexerError(Exception):
13 class LexerUnhandledLine(LexerError
):
17 class EndOfFileError(LexerError
):
21 class LexerUndefinedVariableError(LexerError
):
25 LEXER_VALID_PACKAGE_NAME
= re
.compile(r
"[A-Za-z][A-Za-z0-9\_\-\+]")
27 # XXX need to build check
28 LEXER_VALID_SCRIPTLET_NAME
= re
.compile(r
"((pre|post|posttrans)(in|un|up))")
30 LEXER_COMMENT_CHAR
= "#"
31 LEXER_COMMENT
= re
.compile(r
"^\s*#")
33 LEXER_EMPTY_LINE
= re
.compile(r
"^\s*$")
35 LEXER_DEFINITION
= re
.compile(r
"^([A-Za-z0-9_\-]+)\s*(\+)?=\s*(.+)?$")
37 LEXER_BLOCK_LINE_INDENT
= "\t"
38 LEXER_BLOCK_LINE
= re
.compile(r
"^\t(.*)$")
39 LEXER_BLOCK_END
= re
.compile(r
"^end$")
41 LEXER_DEFINE_BEGIN
= re
.compile(r
"^(def)?\s?([A-Za-z0-9_\-]+)$")
42 LEXER_DEFINE_LINE
= LEXER_BLOCK_LINE
43 LEXER_DEFINE_END
= LEXER_BLOCK_END
45 LEXER_PACKAGE_BEGIN
= re
.compile(r
"^package ([A-Za-z0-9_\-\+\%\{\}]+)$")
46 LEXER_PACKAGE_LINE
= LEXER_BLOCK_LINE
47 LEXER_PACKAGE_END
= LEXER_BLOCK_END
48 LEXER_PACKAGE_INHERIT
= re
.compile(r
"^template ([A-Z]+)$")
50 LEXER_SCRIPTLET_BEGIN
= re
.compile(r
"^script ([a-z]+)\s?(/[A-Za-z0-9\-\_/]+)?$")
51 LEXER_SCRIPTLET_LINE
= LEXER_BLOCK_LINE
52 LEXER_SCRIPTLET_END
= LEXER_BLOCK_END
54 LEXER_TEMPLATE_BEGIN
= re
.compile(r
"^template ([A-Z]+)$")
55 LEXER_TEMPLATE_LINE
= LEXER_BLOCK_LINE
56 LEXER_TEMPLATE_END
= LEXER_BLOCK_END
58 LEXER_BUILD_BEGIN
= re
.compile(r
"^build$")
59 LEXER_BUILD_LINE
= LEXER_BLOCK_LINE
60 LEXER_BUILD_END
= LEXER_BLOCK_END
62 LEXER_DEPS_BEGIN
= re
.compile(r
"^dependencies$")
63 LEXER_DEPS_LINE
= LEXER_BLOCK_LINE
64 LEXER_DEPS_END
= LEXER_BLOCK_END
66 LEXER_DISTRO_BEGIN
= re
.compile(r
"^distribution$")
67 LEXER_DISTRO_LINE
= LEXER_BLOCK_LINE
68 LEXER_DISTRO_END
= LEXER_BLOCK_END
70 LEXER_PACKAGES_BEGIN
= re
.compile(r
"^packages$")
71 LEXER_PACKAGES_LINE
= LEXER_BLOCK_LINE
72 LEXER_PACKAGES_END
= LEXER_BLOCK_END
74 LEXER_PACKAGE2_BEGIN
= re
.compile(r
"^package$")
75 LEXER_PACKAGE2_LINE
= LEXER_BLOCK_LINE
76 LEXER_PACKAGE2_END
= LEXER_BLOCK_END
78 LEXER_QUALITY_AGENT_BEGIN
= re
.compile(r
"^quality-agent$")
79 LEXER_QUALITY_AGENT_LINE
= LEXER_BLOCK_LINE
80 LEXER_QUALITY_AGENT_END
= LEXER_BLOCK_END
83 LEXER_EXPORT
= re
.compile(r
"^export\s+([A-Za-z0-9_\-]+)\s*(\+)?=\s*(.+)?$")
84 LEXER_EXPORT2
= re
.compile(r
"^export\s+([A-Za-z0-9_\-]+)$")
85 LEXER_UNEXPORT
= re
.compile(r
"^unexport\s+([A-Za-z0-9_\-]+)$")
86 LEXER_INCLUDE
= re
.compile(r
"^include\s+(.+)$")
88 LEXER_VARIABLE
= re
.compile(r
"\%\{([A-Za-z0-9_\-]+)\}")
89 LEXER_SHELL
= re
.compile(r
"\%\(.*\)")
91 LEXER_IF_IF
= re
.compile(r
"^if\s+(.*)\s+(==|!=)\s+(.*)\s*")
92 LEXER_IF_ELIF
= re
.compile(r
"^elif\s+(.*)\s*(==|!=)\s*(.*)\s*")
93 LEXER_IF_ELSE
= re
.compile(r
"^else")
94 LEXER_IF_LINE
= LEXER_BLOCK_LINE
95 LEXER_IF_END
= LEXER_BLOCK_END
98 def __init__(self
, lines
=[], parent
=None, environ
=None):
104 # A place to store all definitions.
105 self
._definitions
= {}
107 # Init function that can be overwritten by child classes.
113 def inherit(self
, other
):
115 Inherit everything from other lexer.
117 self
._definitions
.update(other
._definitions
)
120 def definitions(self
):
121 return self
._definitions
124 def open(cls
, filename
, *args
, **kwargs
):
126 lines
= f
.readlines()
129 return cls(lines
, *args
, **kwargs
)
133 return self
._lineno
+ 1
138 return self
.parent
.root
142 def get_line(self
, no
, raw
=False):
144 line
= self
.lines
[no
]
149 line
= line
.rstrip("\n")
157 # strip comments - caution: quotations
159 if line
.startswith(LEXER_COMMENT_CHAR
):
162 # XXX fix removing of comments in lines
167 #for i in range(length):
170 # if s in LEXER_QUOTES:
176 # if s == LEXER_COMMENT_CHAR:
181 def line_is_empty(self
):
182 line
= self
.get_line(self
._lineno
)
184 m
= re
.match(LEXER_EMPTY_LINE
, line
)
190 def expand_string(self
, s
):
195 m
= re
.search(LEXER_VARIABLE
, s
)
200 s
= s
.replace("%%{%s}" % var
, self
.get_var(var
))
204 def get_var(self
, key
, default
=None, raw
=False):
206 definitions
.update(self
.root
.definitions
)
208 definitions
.update(self
.parent
.definitions
)
209 definitions
.update(self
.definitions
)
213 val
= definitions
[key
]
223 return self
.expand_string(val
)
225 def init(self
, environ
):
228 def get_default_parsers(self
):
230 (LEXER_COMMENT
, self
.parse_comment
),
231 (LEXER_DEFINITION
, self
.parse_definition
),
232 (LEXER_DEFINE_BEGIN
, self
.parse_define
),
233 (LEXER_IF_IF
, self
.parse_if
),
236 def get_parsers(self
):
239 def parse_line(self
):
241 if self
.line_is_empty():
245 line
= self
.get_line(self
._lineno
)
247 parsers
= self
.get_parsers() + self
.get_default_parsers()
250 for pattern
, func
in parsers
:
251 m
= re
.match(pattern
, line
)
253 # Hey, I found a match, we parse it with the subparser function.
260 raise LexerUnhandledLine
, "%d: %s" % (self
.lineno
, line
)
262 def read_block(self
, pattern_start
=None, pattern_line
=None, pattern_end
=None,
268 line
= self
.get_line(self
._lineno
)
270 m
= re
.match(pattern_start
, line
)
274 # Go in to next line.
281 line
= self
.get_line(self
._lineno
, raw
=raw
)
283 m
= re
.match(pattern_end
, line
)
288 m
= re
.match(pattern_line
, line
)
290 lines
.append(m
.group(1))
294 m
= re
.match(LEXER_EMPTY_LINE
, line
)
300 if not line
.startswith(LEXER_BLOCK_LINE_INDENT
):
301 raise LexerError
, "Line has not the right indentation: %d: %s" \
302 % (self
.lineno
, line
)
304 raise LexerUnhandledLine
, "%d: %s" % (self
.lineno
, line
)
306 return (groups
, lines
)
309 while self
._lineno
< len(self
.lines
):
312 def parse_comment(self
):
313 line
= self
.get_line(self
._lineno
)
318 raise LexerUnhandledLine
, "%d: %s" % (self
.lineno
, line
)
320 def parse_definition(self
, pattern
=LEXER_DEFINITION
):
321 line
= self
.get_line(self
._lineno
)
323 m
= re
.match(pattern
, line
)
325 raise LexerError
, "Not a definition: %s" % line
327 # Line was correctly parsed, can go on.
333 prev
= self
.get_var(k
, default
=None, raw
=True)
335 v
= " ".join((prev
or "", v
))
338 while v
and v
.endswith("\\"):
339 line
= self
.get_line(self
._lineno
)
344 self
._definitions
[k
] = v
348 def parse_define(self
):
349 line
= self
.get_line(self
._lineno
)
351 m
= re
.match(LEXER_DEFINE_BEGIN
, line
)
353 raise Exception, "XXX not a define"
355 # Check content of next line.
359 line
= self
.get_line(self
._lineno
+ i
)
362 empty
= re
.match(LEXER_EMPTY_LINE
, line
)
367 for pattern
in (LEXER_DEFINE_LINE
, LEXER_DEFINE_END
):
368 found
= re
.match(pattern
, line
)
376 line
= self
.get_line(self
._lineno
)
377 raise LexerUnhandledLine
, "%d: %s" % (self
.lineno
, line
)
379 # Go in to next line.
387 line
= self
.get_line(self
._lineno
)
389 m
= re
.match(LEXER_DEFINE_END
, line
)
394 m
= re
.match(LEXER_DEFINE_LINE
, line
)
397 value
.append(m
.group(1))
400 m
= re
.match(LEXER_EMPTY_LINE
, line
)
406 raise LexerError
, "Unhandled line: %s" % line
408 self
._definitions
[key
] = "\n".join(value
)
410 def _parse_if_block(self
, first
=True):
411 line
= self
.get_line(self
._lineno
)
416 m
= re
.match(LEXER_IF_IF
, line
)
420 m
= re
.match(LEXER_IF_ELIF
, line
)
424 m
= re
.match(LEXER_IF_ELSE
, line
)
429 raise LexerError
, "No valid begin of if statement: %d: %s" \
430 % (self
.lineno
, line
)
437 while len(self
.lines
) >= self
._lineno
:
438 line
= self
.get_line(self
._lineno
)
440 for pattern
in (LEXER_IF_END
, LEXER_IF_ELIF
, LEXER_IF_ELSE
):
441 m
= re
.match(pattern
, line
)
449 m
= re
.match(LEXER_IF_LINE
, line
)
452 lines
.append("%s" % m
.groups())
455 raise LexerUnhandledLine
, "%d: %s" % (self
.lineno
, line
)
458 raise LexerError
, "Unclosed if block"
460 return (clause
, lines
)
464 blocks
.append(self
._parse
_if
_block
(first
=True))
466 while len(self
.lines
) >= self
._lineno
:
467 line
= self
.get_line(self
._lineno
)
470 for pattern
in (LEXER_IF_ELIF
, LEXER_IF_ELSE
,):
471 m
= re
.match(pattern
, line
)
473 # Found another block.
475 blocks
.append(self
._parse
_if
_block
(first
=False))
482 line
= self
.get_line(self
._lineno
)
483 m
= re
.match(LEXER_IF_END
, line
)
485 raise LexerError
, "Unclosed if clause"
489 # Read in all blocks, now we evaluate each clause.
490 for clause
, lines
in blocks
:
496 # Remove leading and trailing "s and 's.
497 a
= a
.lstrip("\"'").rstrip("\"'")
498 b
= b
.lstrip("\"'").rstrip("\"'")
500 a
= self
.expand_string(a
)
501 b
= self
.expand_string(b
)
508 raise LexerError
, "Unknown operator: %s" % op
511 # Else is always true.
514 # If any clause is true, we can parse the block.
516 lexer
= self
.__class
__(lines
, parent
=self
)
521 class DefaultLexer(Lexer
):
523 A lexer which only knows about simple definitions.
528 class QualityAgentLexer(DefaultLexer
):
530 A lexer to read quality agent exceptions.
536 # Check if we permit full relro.
537 if self
.get_var("permit_not_full_relro"):
538 exports
["QUALITY_AGENT_PERMIT_NOT_FULL_RELRO"] = \
539 self
.get_var("permit_not_full_relro")
541 # Check if we permit $ORIGIN in rpath.
542 if self
.get_var("rpath_allow_origin"):
543 exports
["QUALITY_AGENT_RPATH_ALLOW_ORIGIN"] = \
544 self
.get_var("rpath_allow_origin")
546 # Load execstack whitelist.
547 if self
.get_var("whitelist_execstack"):
548 exports
["QUALITY_AGENT_WHITELIST_EXECSTACK"] = \
549 self
.get_var("whitelist_execstack")
552 if self
.get_var("whitelist_nx"):
553 exports
["QUALITY_AGENT_WHITELIST_NX"] = \
554 self
.get_var("whitelist_nx")
556 # Load rpath whitelist.
557 if self
.get_var("whitelist_rpath"):
558 exports
["QUALITY_AGENT_WHITELIST_RPATH"] = \
559 self
.get_var("whitelist_rpath")
561 # Load symlink whitelist
562 if self
.get_var("whitelist_symlink"):
563 exports
["QUALITY_AGENT_WHITELIST_SYMLINK"] = \
564 self
.get_var("whitelist_symlink")
569 class TemplateLexer(DefaultLexer
):
570 def init(self
, environ
):
571 # A place to store the scriptlets.
575 def definitions(self
):
579 definitions
.update(self
.parent
.definitions
)
580 definitions
.update(self
._definitions
)
584 def get_parsers(self
):
586 (LEXER_SCRIPTLET_BEGIN
, self
.parse_scriptlet
),
589 def parse_scriptlet(self
):
590 line
= self
.get_line(self
._lineno
)
592 m
= re
.match(LEXER_SCRIPTLET_BEGIN
, line
)
594 raise Exception, "Not a scriptlet"
600 # check if scriptlet was already defined.
601 if self
.scriptlets
.has_key(name
):
602 raise Exception, "Scriptlet %s is already defined" % name
606 self
.scriptlets
[name
] = {
608 "path" : self
.expand_string(path
),
614 line
= self
.get_line(self
._lineno
, raw
=True)
616 m
= re
.match(LEXER_SCRIPTLET_END
, line
)
621 m
= re
.match(LEXER_SCRIPTLET_LINE
, line
)
623 lines
.append(m
.group(1))
627 m
= re
.match(LEXER_EMPTY_LINE
, line
)
633 raise LexerUnhandledLine
, "%d: %s" % (self
.lineno
, line
)
635 self
.scriptlets
[name
] = {
637 "scriptlet" : "\n".join(lines
),
641 class PackageLexer(TemplateLexer
):
642 def init(self
, environ
):
643 TemplateLexer
.init(self
, environ
)
645 self
._template
= "MAIN"
647 assert isinstance(self
.parent
, PackagesLexer
) or \
648 isinstance(self
.parent
, PackageLexer
), self
.parent
651 def definitions(self
):
655 definitions
.update(self
.template
.definitions
)
657 definitions
.update(self
._definitions
)
663 if not self
._template
:
666 # Get template from parent.
668 return self
.root
.templates
[self
._template
]
670 raise LexerError
, "Template does not exist: %s" % self
._template
672 def get_parsers(self
):
674 (LEXER_PACKAGE_INHERIT
, self
.parse_inherit
),
675 ] + TemplateLexer
.get_parsers(self
)
679 def parse_inherit(self
):
680 line
= self
.get_line(self
._lineno
)
682 m
= re
.match(LEXER_PACKAGE_INHERIT
, line
)
684 raise LexerError
, "Not a template inheritance: %s" % line
688 self
._template
= m
.group(1)
690 # Check if template exists.
694 class ExportLexer(DefaultLexer
):
697 if not hasattr(self
.parent
, "exports"):
701 for export
in self
._exports
+ self
.parent
.exports
:
702 exports
.append(export
)
706 def init(self
, environ
):
707 # A list of variables that should be exported in the build
712 def get_parsers(self
):
714 (LEXER_EXPORT
, self
.parse_export
),
715 (LEXER_EXPORT2
, self
.parse_export2
),
716 (LEXER_UNEXPORT
, self
.parse_unexport
),
719 def inherit(self
, other
):
720 DefaultLexer
.inherit(self
, other
)
722 # Try to remove all unexported variables.
723 for unexport
in other
._unexports
:
725 self
._exports
.remove(unexport
)
729 for export
in other
._exports
:
730 if not export
in self
._exports
:
731 self
._exports
.append(export
)
733 def parse_export(self
):
734 k
, v
= self
.parse_definition(pattern
=LEXER_EXPORT
)
736 if k
and not k
in self
.exports
:
737 self
._exports
.append(k
)
739 def parse_export2(self
):
740 line
= self
.get_line(self
._lineno
)
743 m
= re
.match(LEXER_EXPORT2
, line
)
746 if k
and k
in self
.exports
:
747 self
._exports
.append(k
)
749 def parse_unexport(self
):
750 line
= self
.get_line(self
._lineno
)
753 m
= re
.match(LEXER_UNEXPORT
, line
)
756 if k
and k
in self
.exports
:
757 self
._exports
.remove(k
)
758 self
._unexports
.append(k
)
761 class BuildLexer(ExportLexer
):
764 return self
.definitions
767 class RootLexer(ExportLexer
):
768 def init(self
, environ
):
769 ExportLexer
.init(self
, environ
)
771 # A place to store all packages and templates.
772 self
.packages
= PackagesLexer([], parent
=self
)
774 # Import all environment variables.
776 for k
, v
in environ
.items():
777 self
._definitions
[k
] = v
779 self
.exports
.append(k
)
781 # Place for build instructions
782 self
.build
= BuildLexer([], parent
=self
)
784 # Place for quality-agent exceptions
785 self
.quality_agent
= QualityAgentLexer([], parent
=self
)
787 # Include all macros.
789 for macro
in MACRO_FILES
:
792 def include(self
, file):
793 # Create a new lexer, and parse the whole file.
794 include
= RootLexer
.open(file, parent
=self
)
796 # Copy all data from the included file.
797 self
.inherit(include
)
799 def inherit(self
, other
):
801 Inherit everything from other lexer.
803 ExportLexer
.inherit(self
, other
)
805 self
._definitions
.update(other
._definitions
)
807 self
.build
.inherit(other
.build
)
808 self
.packages
.inherit(other
.packages
)
809 self
.quality_agent
.inherit(other
.quality_agent
)
813 return self
.packages
.templates
815 def get_parsers(self
):
816 parsers
= ExportLexer
.get_parsers(self
)
818 (LEXER_INCLUDE
, self
.parse_include
),
819 (LEXER_PACKAGES_BEGIN
, self
.parse_packages
),
820 (LEXER_BUILD_BEGIN
, self
.parse_build
),
821 (LEXER_QUALITY_AGENT_BEGIN
, self
.parse_quality_agent
),
826 def parse_build(self
):
827 line
= self
.get_line(self
._lineno
)
829 m
= re
.match(LEXER_BUILD_BEGIN
, line
)
831 raise LexerError
, "Not a build statement: %s" % line
838 line
= self
.get_line(self
._lineno
)
840 m
= re
.match(LEXER_BUILD_END
, line
)
845 m
= re
.match(LEXER_BUILD_LINE
, line
)
847 lines
.append(m
.group(1))
850 # Accept empty lines.
851 m
= re
.match(LEXER_EMPTY_LINE
, line
)
857 build
= BuildLexer(lines
, parent
=self
.build
)
858 self
.build
.inherit(build
)
860 def parse_include(self
):
861 line
= self
.get_line(self
._lineno
)
863 m
= re
.match(LEXER_INCLUDE
, line
)
865 raise LexerError
, "Not an include statement: %s" % line
867 # Get the filename from the line.
869 file = self
.expand_string(file)
871 # Include the content of the file.
874 # Go on to next line.
877 def parse_packages(self
):
878 keys
, lines
= self
.read_block(
879 pattern_start
=LEXER_PACKAGES_BEGIN
,
880 pattern_line
=LEXER_PACKAGES_LINE
,
881 pattern_end
=LEXER_PACKAGES_END
,
885 pkgs
= PackagesLexer(lines
, parent
=self
.packages
)
886 self
.packages
.inherit(pkgs
)
888 def parse_quality_agent(self
):
889 keys
, lines
= self
.read_block(
890 pattern_start
=LEXER_QUALITY_AGENT_BEGIN
,
891 pattern_line
=LEXER_QUALITY_AGENT_LINE
,
892 pattern_end
=LEXER_QUALITY_AGENT_END
,
896 qa
= QualityAgentLexer(lines
, parent
=self
.quality_agent
)
897 self
.quality_agent
.inherit(qa
)
900 class PackagesLexer(DefaultLexer
):
901 def init(self
, environ
):
902 # A place to store all templates.
905 # A place to store all packages.
908 def inherit(self
, other
):
909 # Copy all templates and packages but make sure
910 # to update the parent lexer (for accessing each other).
911 for name
, template
in other
.templates
.items():
912 template
.parent
= self
913 self
.templates
[name
] = template
915 for pkg
in other
.packages
:
917 self
.packages
.append(pkg
)
920 return iter(self
.packages
)
922 def get_parsers(self
):
924 (LEXER_TEMPLATE_BEGIN
, self
.parse_template
),
925 (LEXER_PACKAGE_BEGIN
, self
.parse_package
),
928 def parse_template(self
):
929 line
= self
.get_line(self
._lineno
)
931 m
= re
.match(LEXER_TEMPLATE_BEGIN
, line
)
933 raise Exception, "Not a template"
935 # Line was correctly parsed, can go on.
942 line
= self
.get_line(self
._lineno
)
944 m
= re
.match(LEXER_TEMPLATE_END
, line
)
949 m
= re
.match(LEXER_TEMPLATE_LINE
, line
)
951 lines
.append(m
.group(1))
954 # Accept empty lines.
955 m
= re
.match(LEXER_EMPTY_LINE
, line
)
961 template
= TemplateLexer(lines
, parent
=self
)
962 self
.templates
[name
] = template
964 def parse_package(self
):
965 line
= self
.get_line(self
._lineno
)
967 m
= re
.match(LEXER_PACKAGE_BEGIN
, line
)
969 raise Exception, "Not a package: %s" %line
974 name
= self
.expand_string(name
)
976 m
= re
.match(LEXER_VALID_PACKAGE_NAME
, name
)
978 raise LexerError
, "Invalid package name: %s" % name
980 lines
= ["_name = %s" % name
]
983 while len(self
.lines
) > self
._lineno
:
984 line
= self
.get_line(self
._lineno
)
986 m
= re
.match(LEXER_PACKAGE_END
, line
)
992 m
= re
.match(LEXER_PACKAGE_LINE
, line
)
995 lines
.append(m
.group(1))
999 # Accept empty lines.
1000 m
= re
.match(LEXER_EMPTY_LINE
, line
)
1006 # If there is an unhandled line in a block, we raise an error.
1008 raise Exception, "XXX unhandled line in package block: %s" % line
1010 # If the block was never opened, we just go on.
1015 raise LexerError
, "Unclosed package block '%s'." % name
1017 package
= PackageLexer(lines
, parent
=self
)
1018 self
.packages
.append(package
)
1021 class FileLexer(DefaultLexer
):
1022 def init(self
, environ
):
1023 self
.build
= DefaultLexer()
1024 self
.deps
= DefaultLexer()
1025 self
.distro
= DefaultLexer()
1026 self
.package
= DefaultLexer()
1028 def get_parsers(self
):
1030 (LEXER_BUILD_BEGIN
, self
.parse_build
),
1031 (LEXER_DISTRO_BEGIN
, self
.parse_distro
),
1032 (LEXER_PACKAGE2_BEGIN
, self
.parse_package
),
1033 (LEXER_DEPS_BEGIN
, self
.parse_deps
),
1036 def parse_build(self
):
1037 keys
, lines
= self
.read_block(
1038 pattern_start
=LEXER_BUILD_BEGIN
,
1039 pattern_line
=LEXER_BUILD_LINE
,
1040 pattern_end
=LEXER_BUILD_END
,
1044 build
= DefaultLexer(lines
)
1045 self
.build
.inherit(build
)
1047 def parse_distro(self
):
1048 keys
, lines
= self
.read_block(
1049 pattern_start
=LEXER_DISTRO_BEGIN
,
1050 pattern_line
=LEXER_DISTRO_LINE
,
1051 pattern_end
=LEXER_DISTRO_END
,
1055 distro
= DefaultLexer(lines
)
1056 self
.distro
.inherit(distro
)
1058 def parse_package(self
):
1059 keys
, lines
= self
.read_block(
1060 pattern_start
=LEXER_PACKAGE2_BEGIN
,
1061 pattern_line
=LEXER_PACKAGE2_LINE
,
1062 pattern_end
=LEXER_PACKAGE2_END
,
1066 pkg
= DefaultLexer(lines
)
1067 self
.package
.inherit(pkg
)
1069 def parse_deps(self
):
1070 keys
, lines
= self
.read_block(
1071 pattern_start
=LEXER_DEPS_BEGIN
,
1072 pattern_line
=LEXER_DEPS_LINE
,
1073 pattern_end
=LEXER_DEPS_END
,
1077 deps
= DefaultLexer(lines
)
1078 self
.deps
.inherit(deps
)