| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159 |
- import pathlib
- import _io
- from .pini_exception import pini_exception
- from .pini_exception import pini_syntax
- from .pini import pini
- from .key import key
- from .section import section
- class parser():
- def __init__(self, target: str | pathlib.Path):
- if target isinstance str:
- target = pathlib.Path(target)
- if not target.is_file():
- raise pini_exception("File " + str(target) + " not exists.")
- self.__current = None
- self.__path = target
- self.__config = pini()
- self.__process()
- def __get_section(self) -> section:
- if self.__current is None:
- self.__current = section()
- return self.__get_section()
- return self.__current
- def __new_section(self, name: str) -> section:
- if type(name) is not str:
- raise TypeError("New section name must be str.")
- name = name.strip()
- if len(name) == 0:
- raise pini_syntax("New section name can not be empty.")
- if self.__current is not None:
- self.__config.add(self.__current)
- self.__current = section()
- self.__current.name = name
- def __process(self) -> None:
- with self.__path.open() as file:
- for line in file:
- self.__parse_line(line)
- def __parse_line(self, line: str) -> None:
- line = line.lstrip()
- if len(line) == 0:
- return
- first = line[0]
- if first == "[":
- self.__parse_section(line)
- return
- if first == "#":
- if len(line) >= 3 and line[0:3] == "###":
- self.__parse_unactive_key(line)
- return
- self.__parse_comment(line)
- return
- self.__parse_key(line)
- def __split_comment(self, line: str) -> [str | None , str | None]:
- position = line.find("#")
- if position == -1:
- return line.strip(), None
- content = line[:position].strip()
- comment = line[position + 1:]
- if len(comment) > 0 and comment[0] == " ":
- comment = comment[1:]
-
- if len(content) == 0:
- content = None
- if len(comment) == 0:
- comment = None
- return content, comment
- def __parse_unactive_key(self, line: str) -> None:
- line = line[3:]
- if line[0] == " ":
- line = line[1:]
- content, comment = self.__split_comment(line)
- if content is None:
- if comment is None:
- return
- self.__get_section().add_comment(comment)
- position = content.find("=")
- target = key()
- target.value = None
- target.name = content.strip()
- target.comment = comment
- def __parse_key(self, line: str) -> None:
- content, comment = self.__split_comment(line)
- if content is None and comment is not None:
- self.__parse_comment("#" + comment)
- return
- if content.count("=") != 1:
- raise pini_syntax(""
- def __parse_section(self, line: str) -> None:
- content, comment = self.__split_comment(line)
- if content.count("[") != 1 or content.count("]") != 1:
- raise pini_syntax("Section name must start with [ and end with ].")
- start = content.find("[") + 1
- end = content.find("]")
- name = content[start:end].strip()
- if len(name) == 0:
- raise pini_syntax("Section name can not be empty.")
- if name.count(" ") > 0 or name.count("\t") > 0:
- raise pini_syntax("Section name can not contain white chars.")
- self.__new_section(name)
- if comment is not None:
- self.__get_section().add_comment(comment)
- def __parse_comment(self, line: str) -> None:
- if line[0] != "#":
- return
- line = line[1:]
- if len(line) == 0:
- self.__get_section().add_comment("")
- return
- if line[0] == " ":
- line = line[1:]
- self.__get_section().add_comment(line)
|