You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

133 lines
5.0 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# vim: fileencoding=utf-8
#
from .base_format import Format
from ..template_engine import ParametersContainer
from collections import OrderedDict
from pyparsing import Word, Literal, alphanums, originalTextFor,\
OneOrMore, ParseException, restOfLine, Group, Optional,\
Regex
class KernelFormat(Format):
FORMAT = 'kernel'
EXECUTABLE = False
_initialized = False
comment_symbol = '#'
def __new__(cls, *args, **kwargs):
if not cls._initialized:
cls._initialize_parser()
return super().__new__(cls)
def __init__(self, document_text: str,
template_path,
ignore_comments=False,
join_before=False,
add_header=False,
already_changed=False,
**kwargs):
processing_methods = [self._parse_comment_line,
self._parse_parameter_line,
self._parse_to_delete_line]
super().__init__(processing_methods)
self._ignore_comments = ignore_comments
self._join_before = join_before
self._comments_processing = True
self._last_comments_list = []
if add_header and not ignore_comments:
self.header, document_text = self._get_header_and_document_text(
document_text,
template_path,
already_changed=already_changed)
else:
self.header = ''
document_text = document_text.strip()
if document_text == '':
self._document_dictionary = OrderedDict()
else:
documentLines = self._get_list_of_logic_lines(document_text)
self._lines_to_dictionary(documentLines)
@classmethod
def _initialize_parser(cls):
'''Метод для инициализации парсеров.'''
parameter_name = Word(alphanums+'_')('parameter_name')
parameter_value = originalTextFor(Regex(r'\S+(\s+\S+)*')
)('parameter_value')
action_symbols = (Literal('!') | Literal('-'))
cls._parameter_line = (Group(Optional(action_symbols,
default='')('action')
+ parameter_name('name')
)('parameter_name')
+ Literal('=').suppress()
+ parameter_value('parameter_value'))
cls._parameter_to_delete = (Group(action_symbols('action')
+ parameter_name('name')
)('parameter_name')
+ restOfLine.suppress())
cls._comment_line = originalTextFor(
Literal(cls.comment_symbol).suppress()
+ Regex(r'.*'))('Comment')
cls._initialized = True
def _parse_parameter_line(self, line):
'''Метод для парсинга строк содержащих параметр.'''
try:
self._item_to_add = OrderedDict()
parsing_result = self._parameter_line.parseString(line)
key_value = tuple(parsing_result.parameter_name.asList())
parameter_value = parsing_result.parameter_value
parameter_value = self._last_comments_list + [parameter_value]
self._last_comments_list = []
self._item_to_add[key_value] = parameter_value
self._ready_to_update = True
self._match = True
except ParseException:
return
def _parse_to_delete_line(self, line):
'''Метод для парсинга строк, подлежащих удалению, т.е. для которых
указано имя параметра со знаком !, и опционально присутствует значение
параметра.'''
try:
self._item_to_add = OrderedDict()
parsing_result = self._parameter_to_delete.parseString(line)
if parsing_result.action == '-':
return
key_value = (parsing_result.parameter_name.action,
parsing_result.parameter_name.name.upper())
parameter_value = self._last_comments_list
self._last_comments_list = []
self._item_to_add[key_value] = parameter_value
self._ready_to_update = True
self._match = True
except ParseException:
return
def _parse_comment_line(self, line):
'''Метод для парсинга строк содержащих комментарий.'''
try:
result = self._comment_line.parseString(line)
self._match = True
if not self._ignore_comments:
self._last_comments_list.append(result.Comment)
except ParseException:
return