|
|
@@ -1,5 +1,98 @@
|
|
|
+import pathlib
|
|
|
+import _io
|
|
|
+
|
|
|
from .pini_exception import pini_exception
|
|
|
+from .pini import pini
|
|
|
+from .key import key
|
|
|
+from .section import section
|
|
|
|
|
|
class parser:
|
|
|
-
|
|
|
+ def __init__(self, target: str | _io.TextIOWrapper | pathlib.Path):
|
|
|
+ self.__config = pini()
|
|
|
+ self.__section = section()
|
|
|
+
|
|
|
+ if type(target) is str:
|
|
|
+ target = pathlib.Path(target)
|
|
|
+
|
|
|
+ if isinstance(target, pathlib.Path):
|
|
|
+ if not target.is_file():
|
|
|
+ raise pini_exception("File " + str(target) + "not exists.")
|
|
|
+
|
|
|
+ with target.open(mode = "r", encoding = "utf-8") as file:
|
|
|
+ self.__read_file(file)
|
|
|
+ return
|
|
|
+
|
|
|
+ if type(target) is _io.TextIOWrapper:
|
|
|
+ self.__read_file(file)
|
|
|
+ return
|
|
|
+
|
|
|
+ raise TypeError("Target to parse must be str file, path, or file.")
|
|
|
+
|
|
|
+ def __read_file(self, file: _io.TextIOWrapper) -> None:
|
|
|
+ while True:
|
|
|
+ line = file.readline()
|
|
|
+
|
|
|
+ if len(line) == 0:
|
|
|
+ break
|
|
|
+
|
|
|
+ self.__parse_line(line)
|
|
|
+
|
|
|
+ def __parse_line(self, line: str) -> None:
|
|
|
+ line = line.lstrip()
|
|
|
+
|
|
|
+ if line[0:3] == "###":
|
|
|
+ self.__parse_key(line)
|
|
|
+ return
|
|
|
|
|
|
+ if line[0] == "#":
|
|
|
+ self.__parse_comment(line)
|
|
|
+ return
|
|
|
+
|
|
|
+ if line[0] == "[":
|
|
|
+ self.__parse_section(line)
|
|
|
+ return
|
|
|
+
|
|
|
+ if line.find("="):
|
|
|
+ self.__parse_key(line)
|
|
|
+ return
|
|
|
+
|
|
|
+ def __parse_section(self, line: str) -> None:
|
|
|
+ name_position = line.find("=")
|
|
|
+ name = line[:name_position].strip()
|
|
|
+ value = line[name_position + 1:].lstrip()
|
|
|
+ value, comment = self.__parse_value(value)
|
|
|
+
|
|
|
+ def __parse_value(self, value: str) -> [str | int | float, str | None]:
|
|
|
+ if value[0] == "'" or value == "\"":
|
|
|
+ return self.__parse_string(value)
|
|
|
+
|
|
|
+ comment_split = value.split("#")
|
|
|
+
|
|
|
+ if len(comment_split) == 1:
|
|
|
+ pass
|
|
|
+
|
|
|
+ def __parse_string(self, value: str) -> [str | int | float, str | None]:
|
|
|
+ tag = value[0]
|
|
|
+ end = value.find(tag, 1)
|
|
|
+ content = value[1:end]
|
|
|
+
|
|
|
+ comment = value[end + 1:].lstrip()
|
|
|
+
|
|
|
+ if comment[0] != "#" and len(comment) > 0:
|
|
|
+ raise pine_syntax("Chars after string close. " + comment)
|
|
|
+
|
|
|
+ if len(comment) == 0:
|
|
|
+ return content, None
|
|
|
+
|
|
|
+ if comment[0] == "#":
|
|
|
+ comment = comment[1:]
|
|
|
+
|
|
|
+ if comment[0] == " ":
|
|
|
+ comment = comment[1:]
|
|
|
+
|
|
|
+ if len(comment) == 0:
|
|
|
+ comment = None
|
|
|
+
|
|
|
+ return content, comment
|
|
|
+
|
|
|
+
|