6 from pakfire
.constants
import *
7 from pakfire
.i18n
import _
12 #log = logging.getLogger("pakfire.lexer")
13 log
= logging
.getLogger("pakfire")
15 class LexerError(Exception):
19 class LexerUnhandledLine(LexerError
):
23 class EndOfFileError(LexerError
):
27 class LexerUndefinedVariableError(LexerError
):
31 LEXER_VALID_PACKAGE_NAME
= re
.compile(r
"[A-Za-z][A-Za-z0-9\_\-\+]")
33 # XXX need to build check
34 LEXER_VALID_SCRIPTLET_NAME
= re
.compile(r
"((pre|post|pretrans|posttrans)(in|un|up))")
36 LEXER_COMMENT_CHAR
= "#"
37 LEXER_COMMENT
= re
.compile(r
"^\s*#")
39 LEXER_EMPTY_LINE
= re
.compile(r
"^\s*$")
41 LEXER_DEFINITION
= re
.compile(r
"^([A-Za-z0-9_\-]+)\s*([\+\:])?=\s*(.+)?$")
43 LEXER_BLOCK_LINE_INDENT
= "\t"
44 LEXER_BLOCK_LINE
= re
.compile(r
"^\t(.*)$")
45 LEXER_BLOCK_END
= re
.compile(r
"^end$")
47 LEXER_DEFINE_BEGIN
= re
.compile(r
"^(def)?\s?([A-Za-z0-9_\-]+)$")
48 LEXER_DEFINE_LINE
= LEXER_BLOCK_LINE
49 LEXER_DEFINE_END
= LEXER_BLOCK_END
51 LEXER_PACKAGE_BEGIN
= re
.compile(r
"^package ([A-Za-z0-9_\-\+\%\{\}]+)$")
52 LEXER_PACKAGE_LINE
= LEXER_BLOCK_LINE
53 LEXER_PACKAGE_END
= LEXER_BLOCK_END
54 LEXER_PACKAGE_INHERIT
= re
.compile(r
"^template ([A-Z0-9]+)$")
56 LEXER_SCRIPTLET_BEGIN
= re
.compile(r
"^script ([a-z]+)\s?(shell|python)?$")
57 LEXER_SCRIPTLET_LINE
= LEXER_BLOCK_LINE
58 LEXER_SCRIPTLET_END
= LEXER_BLOCK_END
60 LEXER_TEMPLATE_BEGIN
= re
.compile(r
"^template ([A-Z0-9]+)$")
61 LEXER_TEMPLATE_LINE
= LEXER_BLOCK_LINE
62 LEXER_TEMPLATE_END
= LEXER_BLOCK_END
64 LEXER_BUILD_BEGIN
= re
.compile(r
"^build$")
65 LEXER_BUILD_LINE
= LEXER_BLOCK_LINE
66 LEXER_BUILD_END
= LEXER_BLOCK_END
68 LEXER_DEPS_BEGIN
= re
.compile(r
"^dependencies$")
69 LEXER_DEPS_LINE
= LEXER_BLOCK_LINE
70 LEXER_DEPS_END
= LEXER_BLOCK_END
72 LEXER_DISTRO_BEGIN
= re
.compile(r
"^distribution$")
73 LEXER_DISTRO_LINE
= LEXER_BLOCK_LINE
74 LEXER_DISTRO_END
= LEXER_BLOCK_END
76 LEXER_PACKAGES_BEGIN
= re
.compile(r
"^packages$")
77 LEXER_PACKAGES_LINE
= LEXER_BLOCK_LINE
78 LEXER_PACKAGES_END
= LEXER_BLOCK_END
80 LEXER_PACKAGE2_BEGIN
= re
.compile(r
"^package$")
81 LEXER_PACKAGE2_LINE
= LEXER_BLOCK_LINE
82 LEXER_PACKAGE2_END
= LEXER_BLOCK_END
84 LEXER_QUALITY_AGENT_BEGIN
= re
.compile(r
"^quality-agent$")
85 LEXER_QUALITY_AGENT_LINE
= LEXER_BLOCK_LINE
86 LEXER_QUALITY_AGENT_END
= LEXER_BLOCK_END
89 LEXER_EXPORT
= re
.compile(r
"^export\s+([A-Za-z0-9_\-]+)\s*(\+)?=\s*(.+)?$")
90 LEXER_EXPORT2
= re
.compile(r
"^export\s+([A-Za-z0-9_\-]+)$")
91 LEXER_UNEXPORT
= re
.compile(r
"^unexport\s+([A-Za-z0-9_\-]+)$")
92 LEXER_INCLUDE
= re
.compile(r
"^include\s+(.+)$")
94 LEXER_VARIABLE
= re
.compile(r
"\%\{([A-Za-z0-9_\-]+)\}")
95 LEXER_SHELL
= re
.compile(r
"\%\((.*)\)")
97 LEXER_IF_IF
= re
.compile(r
"^if\s+(.*)\s+(==|!=)\s+(.*)\s*")
98 LEXER_IF_ELIF
= re
.compile(r
"^elif\s+(.*)\s*(==|!=)\s*(.*)\s*")
99 LEXER_IF_ELSE
= re
.compile(r
"^else")
100 LEXER_IF_LINE
= LEXER_BLOCK_LINE
101 LEXER_IF_END
= LEXER_BLOCK_END
104 def __init__(self
, lines
=[], parent
=None, environ
=None):
110 # A place to store all definitions.
111 self
._definitions
= {}
113 # Init function that can be overwritten by child classes.
119 def inherit(self
, other
):
121 Inherit everything from other lexer.
123 self
._definitions
.update(other
._definitions
)
126 def definitions(self
):
130 definitions
.update(self
.parent
.definitions
)
132 definitions
.update(self
._definitions
)
137 def open(cls
, filename
, *args
, **kwargs
):
138 log
.debug("Opening file for parsing: %s" % filename
)
141 lines
= f
.readlines()
144 return cls(lines
, *args
, **kwargs
)
148 return self
._lineno
+ 1
153 return self
.parent
.root
157 def get_line(self
, no
, raw
=False):
159 line
= self
.lines
[no
]
164 line
= line
.rstrip("\n")
172 # strip comments - caution: quotations
174 if line
.startswith(LEXER_COMMENT_CHAR
):
177 # XXX fix removing of comments in lines
182 #for i in range(length):
185 # if s in LEXER_QUOTES:
191 # if s == LEXER_COMMENT_CHAR:
196 def line_is_empty(self
):
197 line
= self
.get_line(self
._lineno
)
199 m
= re
.match(LEXER_EMPTY_LINE
, line
)
205 def expand_string(self
, s
):
209 # First run all embedded commands.
211 m
= re
.search(LEXER_SHELL
, s
)
216 result
= self
.exec_command(command
)
218 s
= s
.replace("%%(%s)" % command
, result
or "")
220 # Then expand the variables.
222 m
= re
.search(LEXER_VARIABLE
, s
)
227 s
= s
.replace("%%{%s}" % var
, self
.get_var(var
))
231 def exec_command(self
, command
):
232 # Expand all variables in the command.
233 command
= self
.expand_string(command
)
235 # If the command is empty, we don't do anything.
239 # Do we need to chroot and change personality?
240 shellenv
= pakfire
.shell
.ShellExecuteEnvironment(command
,
241 shell
=True, record_output
=True, log_output
=False, record_stderr
=False)
246 except ShellEnvironmentError
:
251 return shellenv
.output
.rstrip("\n")
253 return shellenv
.output
255 def get_var(self
, key
, default
=None, raw
=False):
257 definitions
.update(self
.root
.definitions
)
259 definitions
.update(self
.parent
.definitions
)
260 definitions
.update(self
.definitions
)
264 val
= definitions
[key
]
274 return self
.expand_string(val
)
276 def init(self
, environ
):
279 def get_default_parsers(self
):
281 (LEXER_COMMENT
, self
.parse_comment
),
282 (LEXER_DEFINITION
, self
.parse_definition
),
283 (LEXER_DEFINE_BEGIN
, self
.parse_define
),
284 (LEXER_IF_IF
, self
.parse_if
),
287 def get_parsers(self
):
290 def parse_line(self
):
292 if self
.line_is_empty():
296 line
= self
.get_line(self
._lineno
)
298 parsers
= self
.get_parsers() + self
.get_default_parsers()
301 for pattern
, func
in parsers
:
302 m
= re
.match(pattern
, line
)
304 # Hey, I found a match, we parse it with the subparser function.
311 raise LexerUnhandledLine
, "%d: %s" % (self
.lineno
, line
)
313 def read_block(self
, pattern_start
=None, pattern_line
=None, pattern_end
=None,
319 line
= self
.get_line(self
._lineno
)
321 m
= re
.match(pattern_start
, line
)
325 # Go in to next line.
332 line
= self
.get_line(self
._lineno
, raw
=raw
)
334 m
= re
.match(pattern_end
, line
)
339 m
= re
.match(pattern_line
, line
)
341 lines
.append(m
.group(1))
345 m
= re
.match(LEXER_EMPTY_LINE
, line
)
351 if not line
.startswith(LEXER_BLOCK_LINE_INDENT
):
352 raise LexerError
, "Line has not the right indentation: %d: %s" \
353 % (self
.lineno
, line
)
355 raise LexerUnhandledLine
, "%d: %s" % (self
.lineno
, line
)
357 return (groups
, lines
)
360 while self
._lineno
< len(self
.lines
):
363 def parse_comment(self
):
364 line
= self
.get_line(self
._lineno
)
369 raise LexerUnhandledLine
, "%d: %s" % (self
.lineno
, line
)
371 DEP_DEFINITIONS
= ("prerequires", "requires", "provides", "conflicts", "obsoletes", "recommends", "suggests")
373 def parse_definition(self
, pattern
=LEXER_DEFINITION
):
374 line
= self
.get_line(self
._lineno
)
376 m
= re
.match(pattern
, line
)
378 raise LexerError
, "Not a definition: %s" % line
380 # Line was correctly parsed, can go on.
386 prev
= self
.get_var(k
, default
=None, raw
=True)
388 # Add a newline for all dependencies.
389 if k
in self
.DEP_DEFINITIONS
:
392 v
= " ".join((prev
or "", v
.strip()))
395 # Expand the value immediately and save it.
396 v
= self
.expand_string(v
)
399 while v
and v
.endswith("\\"):
400 line
= self
.get_line(self
._lineno
)
405 self
._definitions
[k
] = v
409 def parse_define(self
):
410 line
= self
.get_line(self
._lineno
)
412 m
= re
.match(LEXER_DEFINE_BEGIN
, line
)
414 raise Exception, "XXX not a define"
416 # Check content of next line.
420 line
= self
.get_line(self
._lineno
+ i
)
423 empty
= re
.match(LEXER_EMPTY_LINE
, line
)
428 for pattern
in (LEXER_DEFINE_LINE
, LEXER_DEFINE_END
):
429 found
= re
.match(pattern
, line
)
437 line
= self
.get_line(self
._lineno
)
438 raise LexerUnhandledLine
, "%d: %s" % (self
.lineno
, line
)
440 # Go in to next line.
448 line
= self
.get_line(self
._lineno
)
450 m
= re
.match(LEXER_DEFINE_END
, line
)
455 m
= re
.match(LEXER_DEFINE_LINE
, line
)
458 value
.append(m
.group(1))
461 m
= re
.match(LEXER_EMPTY_LINE
, line
)
467 raise LexerError
, "Unhandled line: %s" % line
469 self
._definitions
[key
] = "\n".join(value
)
471 def _parse_if_block(self
, first
=True):
472 line
= self
.get_line(self
._lineno
)
477 m
= re
.match(LEXER_IF_IF
, line
)
481 m
= re
.match(LEXER_IF_ELIF
, line
)
485 m
= re
.match(LEXER_IF_ELSE
, line
)
490 raise LexerError
, "No valid begin of if statement: %d: %s" \
491 % (self
.lineno
, line
)
498 while len(self
.lines
) >= self
._lineno
:
499 line
= self
.get_line(self
._lineno
)
501 for pattern
in (LEXER_IF_END
, LEXER_IF_ELIF
, LEXER_IF_ELSE
):
502 m
= re
.match(pattern
, line
)
510 m
= re
.match(LEXER_IF_LINE
, line
)
513 lines
.append("%s" % m
.groups())
516 m
= re
.match(LEXER_EMPTY_LINE
, line
)
522 raise LexerUnhandledLine
, "%d: %s" % (self
.lineno
, line
)
525 raise LexerError
, "Unclosed if block"
527 return (clause
, lines
)
531 blocks
.append(self
._parse
_if
_block
(first
=True))
533 while len(self
.lines
) >= self
._lineno
:
534 line
= self
.get_line(self
._lineno
)
537 for pattern
in (LEXER_IF_ELIF
, LEXER_IF_ELSE
,):
538 m
= re
.match(pattern
, line
)
540 # Found another block.
542 blocks
.append(self
._parse
_if
_block
(first
=False))
549 line
= self
.get_line(self
._lineno
)
550 m
= re
.match(LEXER_IF_END
, line
)
552 raise LexerError
, "Unclosed if clause"
556 # Read in all blocks, now we evaluate each clause.
557 for clause
, lines
in blocks
:
563 # Remove leading and trailing "s and 's.
564 a
= a
.lstrip("\"'").rstrip("\"'")
565 b
= b
.lstrip("\"'").rstrip("\"'")
567 a
= self
.expand_string(a
)
568 b
= self
.expand_string(b
)
575 raise LexerError
, "Unknown operator: %s" % op
578 # Else is always true.
581 # If any clause is true, we can parse the block.
583 lexer
= self
.__class
__(lines
, parent
=self
)
588 class DefaultLexer(Lexer
):
590 A lexer which only knows about simple definitions.
595 class QualityAgentLexer(DefaultLexer
):
597 A lexer to read quality agent exceptions.
603 # Check if we permit full relro.
604 if self
.get_var("permit_not_full_relro"):
605 exports
["QUALITY_AGENT_PERMIT_NOT_FULL_RELRO"] = \
606 self
.get_var("permit_not_full_relro")
608 # Check if we permit $ORIGIN in rpath.
609 if self
.get_var("rpath_allow_origin"):
610 exports
["QUALITY_AGENT_RPATH_ALLOW_ORIGIN"] = \
611 self
.get_var("rpath_allow_origin")
613 # Load execstack whitelist.
614 if self
.get_var("whitelist_execstack"):
615 exports
["QUALITY_AGENT_WHITELIST_EXECSTACK"] = \
616 self
.get_var("whitelist_execstack")
619 if self
.get_var("whitelist_nx"):
620 exports
["QUALITY_AGENT_WHITELIST_NX"] = \
621 self
.get_var("whitelist_nx")
623 # Load rpath whitelist.
624 if self
.get_var("whitelist_rpath"):
625 exports
["QUALITY_AGENT_WHITELIST_RPATH"] = \
626 self
.get_var("whitelist_rpath")
628 # Load symlink whitelist
629 if self
.get_var("whitelist_symlink"):
630 exports
["QUALITY_AGENT_WHITELIST_SYMLINK"] = \
631 self
.get_var("whitelist_symlink")
636 class TemplateLexer(DefaultLexer
):
637 def init(self
, environ
):
638 # A place to store the scriptlets.
641 def inherit(self
, other
):
642 DefaultLexer
.inherit(self
, other
)
644 # Inherit all scriptlets.
645 self
.scriptlets
.update(other
.scriptlets
)
647 def get_parsers(self
):
649 (LEXER_SCRIPTLET_BEGIN
, self
.parse_scriptlet
),
652 def parse_scriptlet(self
):
653 line
= self
.get_line(self
._lineno
)
655 m
= re
.match(LEXER_SCRIPTLET_BEGIN
, line
)
657 raise Exception, "Not a scriptlet"
663 # check if scriptlet was already defined.
664 if self
.scriptlets
.has_key(name
):
665 raise Exception, "Scriptlet %s is already defined" % name
667 lang
= m
.group(2) or "shell"
669 "#<lang: %s>" % lang
,
673 line
= self
.get_line(self
._lineno
, raw
=True)
675 m
= re
.match(LEXER_SCRIPTLET_END
, line
)
680 m
= re
.match(LEXER_SCRIPTLET_LINE
, line
)
682 lines
.append(m
.group(1))
686 m
= re
.match(LEXER_EMPTY_LINE
, line
)
692 raise LexerUnhandledLine
, "%d: %s" % (self
.lineno
, line
)
694 self
.scriptlets
[name
] = {
696 "scriptlet" : self
.expand_string("\n".join(lines
)),
699 def get_scriptlet(self
, name
):
700 return self
.scriptlets
.get(name
, None)
703 class PackageLexer(TemplateLexer
):
704 def init(self
, environ
):
705 TemplateLexer
.init(self
, environ
)
707 self
._template
= "MAIN"
709 assert isinstance(self
.parent
, PackagesLexer
) or \
710 isinstance(self
.parent
, PackageLexer
), self
.parent
713 def definitions(self
):
717 definitions
.update(self
.parent
.definitions
)
720 definitions
.update(self
.template
.definitions
)
722 definitions
.update(self
._definitions
)
728 if not self
._template
:
731 # Get template from parent (if exists).
732 templates
= getattr(self
.parent
, "templates", None)
734 return templates
.get(self
._template
, None)
736 def get_parsers(self
):
738 (LEXER_PACKAGE_INHERIT
, self
.parse_inherit
),
739 ] + TemplateLexer
.get_parsers(self
)
743 def parse_inherit(self
):
744 line
= self
.get_line(self
._lineno
)
746 m
= re
.match(LEXER_PACKAGE_INHERIT
, line
)
748 raise LexerError
, "Not a template inheritance: %s" % line
752 self
._template
= m
.group(1)
754 # Check if template exists.
755 if not self
.template
:
756 log
.warning(_("Template does not exist: %s") % self
._template
)
758 def get_scriptlet(self
, name
):
759 scriptlet
= self
.scriptlets
.get(name
, None)
761 if scriptlet
is None and self
.template
:
762 scriptlet
= self
.template
.get_scriptlet(name
)
764 if scriptlet
and scriptlet
["lang"] == "shell":
765 scriptlet
["scriptlet"] = \
766 self
.expand_string(scriptlet
["scriptlet"])
771 class ExportLexer(DefaultLexer
):
774 if not hasattr(self
.parent
, "exports"):
778 for export
in self
._exports
+ self
.parent
.exports
:
779 exports
.append(export
)
783 def init(self
, environ
):
784 # A list of variables that should be exported in the build
789 def get_parsers(self
):
791 (LEXER_EXPORT
, self
.parse_export
),
792 (LEXER_EXPORT2
, self
.parse_export2
),
793 (LEXER_UNEXPORT
, self
.parse_unexport
),
796 def inherit(self
, other
):
797 DefaultLexer
.inherit(self
, other
)
799 # Try to remove all unexported variables.
800 for unexport
in other
._unexports
:
802 self
._exports
.remove(unexport
)
806 for export
in other
._exports
:
807 if not export
in self
._exports
:
808 self
._exports
.append(export
)
810 def parse_export(self
):
811 k
, v
= self
.parse_definition(pattern
=LEXER_EXPORT
)
813 if k
and not k
in self
.exports
:
814 self
._exports
.append(k
)
816 def parse_export2(self
):
817 line
= self
.get_line(self
._lineno
)
820 m
= re
.match(LEXER_EXPORT2
, line
)
823 if k
and k
in self
.exports
:
824 self
._exports
.append(k
)
826 def parse_unexport(self
):
827 line
= self
.get_line(self
._lineno
)
830 m
= re
.match(LEXER_UNEXPORT
, line
)
833 if k
and k
in self
.exports
:
834 self
._exports
.remove(k
)
835 self
._unexports
.append(k
)
838 class BuildLexer(ExportLexer
):
841 return self
.definitions
844 class RootLexer(ExportLexer
):
845 def init(self
, environ
):
846 ExportLexer
.init(self
, environ
)
848 # Import all environment variables.
850 for k
, v
in environ
.items():
851 self
._definitions
[k
] = v
853 self
.exports
.append(k
)
855 # Place for build instructions
856 self
.build
= BuildLexer([], parent
=self
)
858 # A place to store all packages and templates.
859 # The parent of this is the build block because a lot
860 # of relevant variables are set there and need to be used
861 # later. That keeps us the root lexer a bit more clean.
862 self
.packages
= PackagesLexer([], parent
=self
.build
)
864 # Place for quality-agent exceptions
865 self
.quality_agent
= QualityAgentLexer([], parent
=self
)
867 # Include all macros.
869 self
.include_macros()
871 def include_macros(self
):
872 log
.debug("Including all macros...")
874 for file in sorted(os
.listdir(MACRO_FILE_DIR
)):
875 if not file.endswith(MACRO_EXTENSION
):
878 file = os
.path
.join(MACRO_FILE_DIR
, file)
881 def include(self
, filename
):
882 log
.debug("Including file: %s" % filename
)
884 # Create a new lexer, and parse the whole file.
885 include
= RootLexer
.open(filename
, parent
=self
)
887 # Copy all data from the included file.
888 self
.inherit(include
)
890 def inherit(self
, other
):
892 Inherit everything from other lexer.
894 ExportLexer
.inherit(self
, other
)
896 self
._definitions
.update(other
._definitions
)
898 self
.build
.inherit(other
.build
)
899 self
.packages
.inherit(other
.packages
)
900 self
.quality_agent
.inherit(other
.quality_agent
)
904 return self
.packages
.templates
906 def get_parsers(self
):
907 parsers
= ExportLexer
.get_parsers(self
)
909 (LEXER_INCLUDE
, self
.parse_include
),
910 (LEXER_PACKAGES_BEGIN
, self
.parse_packages
),
911 (LEXER_BUILD_BEGIN
, self
.parse_build
),
912 (LEXER_QUALITY_AGENT_BEGIN
, self
.parse_quality_agent
),
917 def parse_build(self
):
918 line
= self
.get_line(self
._lineno
)
920 m
= re
.match(LEXER_BUILD_BEGIN
, line
)
922 raise LexerError
, "Not a build statement: %s" % line
929 line
= self
.get_line(self
._lineno
)
931 m
= re
.match(LEXER_BUILD_END
, line
)
936 m
= re
.match(LEXER_BUILD_LINE
, line
)
938 lines
.append(m
.group(1))
941 # Accept empty lines.
942 m
= re
.match(LEXER_EMPTY_LINE
, line
)
948 build
= BuildLexer(lines
, parent
=self
.build
)
949 self
.build
.inherit(build
)
951 def parse_include(self
):
952 line
= self
.get_line(self
._lineno
)
954 m
= re
.match(LEXER_INCLUDE
, line
)
956 raise LexerError
, "Not an include statement: %s" % line
958 # Get the filename from the line.
960 file = self
.expand_string(file)
962 # Include the content of the file.
965 # Go on to next line.
968 def parse_packages(self
):
969 keys
, lines
= self
.read_block(
970 pattern_start
=LEXER_PACKAGES_BEGIN
,
971 pattern_line
=LEXER_PACKAGES_LINE
,
972 pattern_end
=LEXER_PACKAGES_END
,
976 pkgs
= PackagesLexer(lines
, parent
=self
.packages
)
977 self
.packages
.inherit(pkgs
)
979 def parse_quality_agent(self
):
980 keys
, lines
= self
.read_block(
981 pattern_start
=LEXER_QUALITY_AGENT_BEGIN
,
982 pattern_line
=LEXER_QUALITY_AGENT_LINE
,
983 pattern_end
=LEXER_QUALITY_AGENT_END
,
987 qa
= QualityAgentLexer(lines
, parent
=self
.quality_agent
)
988 self
.quality_agent
.inherit(qa
)
991 class PackagesLexer(DefaultLexer
):
992 def init(self
, environ
):
993 # A place to store all templates.
996 # A place to store all packages.
1000 def templates(self
):
1003 if self
.parent
and hasattr(self
.parent
, "templates"):
1004 templates
.update(self
.parent
.templates
)
1006 templates
.update(self
._templates
)
1010 def inherit(self
, other
):
1011 DefaultLexer
.inherit(self
, other
)
1013 # Copy all templates and packages but make sure
1014 # to update the parent lexer (for accessing each other).
1015 for name
, template
in other
.templates
.items():
1016 template
.parent
= self
1017 self
._templates
[name
] = template
1019 for pkg
in other
.packages
:
1021 self
.packages
.append(pkg
)
1024 return iter(self
.packages
)
1026 def get_parsers(self
):
1028 (LEXER_TEMPLATE_BEGIN
, self
.parse_template
),
1029 (LEXER_PACKAGE_BEGIN
, self
.parse_package
),
1032 def parse_template(self
):
1033 line
= self
.get_line(self
._lineno
)
1035 m
= re
.match(LEXER_TEMPLATE_BEGIN
, line
)
1037 raise Exception, "Not a template"
1039 # Line was correctly parsed, can go on.
1046 line
= self
.get_line(self
._lineno
)
1048 m
= re
.match(LEXER_TEMPLATE_END
, line
)
1053 m
= re
.match(LEXER_TEMPLATE_LINE
, line
)
1055 lines
.append(m
.group(1))
1058 # Accept empty lines.
1059 m
= re
.match(LEXER_EMPTY_LINE
, line
)
1065 self
._templates
[name
] = TemplateLexer(lines
, parent
=self
)
1067 def parse_package(self
):
1068 line
= self
.get_line(self
._lineno
)
1070 m
= re
.match(LEXER_PACKAGE_BEGIN
, line
)
1072 raise Exception, "Not a package: %s" %line
1077 name
= self
.expand_string(name
)
1079 m
= re
.match(LEXER_VALID_PACKAGE_NAME
, name
)
1081 raise LexerError
, "Invalid package name: %s" % name
1083 lines
= ["_name = %s" % name
]
1086 while len(self
.lines
) > self
._lineno
:
1087 line
= self
.get_line(self
._lineno
)
1089 m
= re
.match(LEXER_PACKAGE_END
, line
)
1095 m
= re
.match(LEXER_PACKAGE_LINE
, line
)
1098 lines
.append(m
.group(1))
1102 # Accept empty lines.
1103 m
= re
.match(LEXER_EMPTY_LINE
, line
)
1109 # If there is an unhandled line in a block, we raise an error.
1111 raise Exception, "XXX unhandled line in package block: %s" % line
1113 # If the block was never opened, we just go on.
1118 raise LexerError
, "Unclosed package block '%s'." % name
1120 package
= PackageLexer(lines
, parent
=self
)
1121 self
.packages
.append(package
)
1124 class FileLexer(DefaultLexer
):
1125 def init(self
, environ
):
1126 self
.build
= DefaultLexer()
1127 self
.deps
= DefaultLexer()
1128 self
.distro
= DefaultLexer()
1129 self
.package
= DefaultLexer()
1131 def get_parsers(self
):
1133 (LEXER_BUILD_BEGIN
, self
.parse_build
),
1134 (LEXER_DISTRO_BEGIN
, self
.parse_distro
),
1135 (LEXER_PACKAGE2_BEGIN
, self
.parse_package
),
1136 (LEXER_DEPS_BEGIN
, self
.parse_deps
),
1139 def parse_build(self
):
1140 keys
, lines
= self
.read_block(
1141 pattern_start
=LEXER_BUILD_BEGIN
,
1142 pattern_line
=LEXER_BUILD_LINE
,
1143 pattern_end
=LEXER_BUILD_END
,
1147 build
= DefaultLexer(lines
)
1148 self
.build
.inherit(build
)
1150 def parse_distro(self
):
1151 keys
, lines
= self
.read_block(
1152 pattern_start
=LEXER_DISTRO_BEGIN
,
1153 pattern_line
=LEXER_DISTRO_LINE
,
1154 pattern_end
=LEXER_DISTRO_END
,
1158 distro
= DefaultLexer(lines
)
1159 self
.distro
.inherit(distro
)
1161 def parse_package(self
):
1162 keys
, lines
= self
.read_block(
1163 pattern_start
=LEXER_PACKAGE2_BEGIN
,
1164 pattern_line
=LEXER_PACKAGE2_LINE
,
1165 pattern_end
=LEXER_PACKAGE2_END
,
1169 pkg
= DefaultLexer(lines
)
1170 self
.package
.inherit(pkg
)
1172 def parse_deps(self
):
1173 keys
, lines
= self
.read_block(
1174 pattern_start
=LEXER_DEPS_BEGIN
,
1175 pattern_line
=LEXER_DEPS_LINE
,
1176 pattern_end
=LEXER_DEPS_END
,
1180 deps
= DefaultLexer(lines
)
1181 self
.deps
.inherit(deps
)