mirror of https://gitlab.com/nakst/essence
ini files: move name to separate key in drivers and fonts
This commit is contained in:
parent
aa4b656bbd
commit
d2aea44158
|
@ -2535,14 +2535,7 @@ void ConfigurationWriteSectionsToBuffer(const char *section, bool includeComment
|
||||||
|
|
||||||
for (uintptr_t i = 0; i < api.systemConfigurationGroups.Length(); i++) {
|
for (uintptr_t i = 0; i < api.systemConfigurationGroups.Length(); i++) {
|
||||||
SystemConfigurationGroup *group = &api.systemConfigurationGroups[i];
|
SystemConfigurationGroup *group = &api.systemConfigurationGroups[i];
|
||||||
|
if (section && EsStringCompareRaw(group->section, group->sectionBytes, section, -1)) continue;
|
||||||
if (section) {
|
|
||||||
if (section[EsCStringLength(section) - 1] == ':') {
|
|
||||||
if (group->sectionBytes <= EsCStringLength(section) || EsMemoryCompare(group->section, section, EsCStringLength(section))) continue;
|
|
||||||
} else {
|
|
||||||
if (EsStringCompareRaw(group->section, group->sectionBytes, section, -1)) continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
EsINIState s = {};
|
EsINIState s = {};
|
||||||
s.section = group->section, s.sectionBytes = group->sectionBytes;
|
s.section = group->section, s.sectionBytes = group->sectionBytes;
|
||||||
|
@ -2902,7 +2895,7 @@ bool /* returns false on fatal error */ DesktopSyscall(EsObjectID windowID, Appl
|
||||||
EsBufferWrite(pipe, &desktop.clipboardInformation, sizeof(desktop.clipboardInformation));
|
EsBufferWrite(pipe, &desktop.clipboardInformation, sizeof(desktop.clipboardInformation));
|
||||||
EsBufferWrite(pipe, &fileHandle, sizeof(fileHandle));
|
EsBufferWrite(pipe, &fileHandle, sizeof(fileHandle));
|
||||||
} else if (buffer[0] == DESKTOP_MSG_SYSTEM_CONFIGURATION_GET && pipe) {
|
} else if (buffer[0] == DESKTOP_MSG_SYSTEM_CONFIGURATION_GET && pipe) {
|
||||||
ConfigurationWriteSectionsToBuffer("font:", false, pipe);
|
ConfigurationWriteSectionsToBuffer("font", false, pipe);
|
||||||
ConfigurationWriteSectionsToBuffer("ui_fonts", false, pipe);
|
ConfigurationWriteSectionsToBuffer("ui_fonts", false, pipe);
|
||||||
|
|
||||||
if (application->permissions & APPLICATION_PERMISSION_ALL_FILES) {
|
if (application->permissions & APPLICATION_PERMISSION_ALL_FILES) {
|
||||||
|
|
|
@ -587,36 +587,17 @@ void FontInitialise() {
|
||||||
for (uintptr_t i = 0; i < api.systemConfigurationGroups.Length(); i++) {
|
for (uintptr_t i = 0; i < api.systemConfigurationGroups.Length(); i++) {
|
||||||
SystemConfigurationGroup *g = &api.systemConfigurationGroups[i];
|
SystemConfigurationGroup *g = &api.systemConfigurationGroups[i];
|
||||||
|
|
||||||
if (g->sectionBytes > 5 && 0 == EsMemoryCompare(g->section, "font:", 5)) {
|
if (0 == EsStringCompareRaw(g->section, g->sectionBytes, EsLiteral("font"))) {
|
||||||
const char *name = g->section + 5;
|
|
||||||
size_t nameBytes = g->sectionBytes - 5;
|
|
||||||
|
|
||||||
if (0 == EsStringCompareRaw(name, nameBytes, EsLiteral(fontManagement.sansName))) {
|
|
||||||
fontManagement.sans = fontManagement.database.Length();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (0 == EsStringCompareRaw(name, nameBytes, EsLiteral(fontManagement.serifName))) {
|
|
||||||
fontManagement.serif = fontManagement.database.Length();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (0 == EsStringCompareRaw(name, nameBytes, EsLiteral(fontManagement.monospacedName))) {
|
|
||||||
fontManagement.monospaced = fontManagement.database.Length();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (0 == EsStringCompareRaw(name, nameBytes, EsLiteral(fontManagement.fallbackName))) {
|
|
||||||
fontManagement.fallback = fontManagement.database.Length();
|
|
||||||
}
|
|
||||||
|
|
||||||
FontDatabaseEntry entry = {};
|
FontDatabaseEntry entry = {};
|
||||||
|
const char *name = nullptr;
|
||||||
entry.nameBytes = MinimumInteger(nameBytes, sizeof(entry.name));
|
size_t nameBytes = 0;
|
||||||
EsMemoryCopy(entry.name, name, entry.nameBytes);
|
|
||||||
entry.id = fontManagement.database.Length();
|
|
||||||
|
|
||||||
for (uintptr_t i = 0; i < g->itemCount; i++) {
|
for (uintptr_t i = 0; i < g->itemCount; i++) {
|
||||||
SystemConfigurationItem *item = g->items + i;
|
SystemConfigurationItem *item = g->items + i;
|
||||||
|
|
||||||
if (0 == EsStringCompareRaw(item->key, item->keyBytes, EsLiteral("category"))) {
|
if (0 == EsStringCompareRaw(item->key, item->keyBytes, EsLiteral("name"))) {
|
||||||
|
name = item->value, nameBytes = item->valueBytes;
|
||||||
|
} else if (0 == EsStringCompareRaw(item->key, item->keyBytes, EsLiteral("category"))) {
|
||||||
entry.categoryBytes = MinimumInteger(item->valueBytes, sizeof(entry.category));
|
entry.categoryBytes = MinimumInteger(item->valueBytes, sizeof(entry.category));
|
||||||
EsMemoryCopy(entry.category, item->value, entry.categoryBytes);
|
EsMemoryCopy(entry.category, item->value, entry.categoryBytes);
|
||||||
} else if (0 == EsStringCompareRaw(item->key, item->keyBytes, EsLiteral("scripts"))) {
|
} else if (0 == EsStringCompareRaw(item->key, item->keyBytes, EsLiteral("scripts"))) {
|
||||||
|
@ -643,6 +624,26 @@ void FontInitialise() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (0 == EsStringCompareRaw(name, nameBytes, EsLiteral(fontManagement.sansName))) {
|
||||||
|
fontManagement.sans = fontManagement.database.Length();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0 == EsStringCompareRaw(name, nameBytes, EsLiteral(fontManagement.serifName))) {
|
||||||
|
fontManagement.serif = fontManagement.database.Length();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0 == EsStringCompareRaw(name, nameBytes, EsLiteral(fontManagement.monospacedName))) {
|
||||||
|
fontManagement.monospaced = fontManagement.database.Length();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0 == EsStringCompareRaw(name, nameBytes, EsLiteral(fontManagement.fallbackName))) {
|
||||||
|
fontManagement.fallback = fontManagement.database.Length();
|
||||||
|
}
|
||||||
|
|
||||||
|
entry.nameBytes = MinimumInteger(nameBytes, sizeof(entry.name));
|
||||||
|
EsMemoryCopy(entry.name, name, entry.nameBytes);
|
||||||
|
entry.id = fontManagement.database.Length();
|
||||||
|
|
||||||
fontManagement.database.Add(entry);
|
fontManagement.database.Add(entry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -148,8 +148,9 @@ Each `[driver]` section should contain:
|
||||||
- `source` The source file of the driver. This must be C/C++.
|
- `source` The source file of the driver. This must be C/C++.
|
||||||
- `builtin` Set to 1 if the driver should be linked directly into the kernel. Set to 0 if the driver should be built as a loadable module.
|
- `builtin` Set to 1 if the driver should be linked directly into the kernel. Set to 0 if the driver should be built as a loadable module.
|
||||||
|
|
||||||
`[font:<name>]` sections specify the fonts that are to be bundled in the desktop executable. Each section should contain:
|
`[font]` sections specify the fonts that are to be bundled in the desktop executable. Each section should contain:
|
||||||
|
|
||||||
|
- `name` The name of the font.
|
||||||
- `category` One of `Sans`, `Serif` or `Mono`. More categories will likely be added in the future.
|
- `category` One of `Sans`, `Serif` or `Mono`. More categories will likely be added in the future.
|
||||||
- `scripts` The scripts supported by the font. See `hb_script_t` in `bin/harfbuzz/src/hb-common.h` for a list of scripts. Separate each script with a `,`.
|
- `scripts` The scripts supported by the font. See `hb_script_t` in `bin/harfbuzz/src/hb-common.h` for a list of scripts. Separate each script with a `,`.
|
||||||
- `license` The license file to bundle. This is a path relative to `res/Fonts/`.
|
- `license` The license file to bundle. This is a path relative to `res/Fonts/`.
|
||||||
|
|
|
@ -1,49 +1,58 @@
|
||||||
[driver:Root]
|
[driver]
|
||||||
|
name=Root
|
||||||
builtin=1
|
builtin=1
|
||||||
|
|
||||||
; Subsystems.
|
; Subsystems.
|
||||||
|
|
||||||
[driver:Networking]
|
[driver]
|
||||||
|
name=Networking
|
||||||
parent=Root
|
parent=Root
|
||||||
builtin=1
|
builtin=1
|
||||||
|
|
||||||
[driver:USB]
|
[driver]
|
||||||
|
name=USB
|
||||||
source=drivers/usb.cpp
|
source=drivers/usb.cpp
|
||||||
parent=Root
|
parent=Root
|
||||||
builtin=1
|
builtin=1
|
||||||
|
|
||||||
; Architectures.
|
; Architectures.
|
||||||
|
|
||||||
[driver:ACPI]
|
[driver]
|
||||||
|
name=ACPI
|
||||||
arch=x86_common
|
arch=x86_common
|
||||||
parent=Root
|
parent=Root
|
||||||
builtin=1
|
builtin=1
|
||||||
|
|
||||||
; Base devices.
|
; Base devices.
|
||||||
|
|
||||||
[driver:PCI]
|
[driver]
|
||||||
|
name=PCI
|
||||||
source=drivers/pci.cpp
|
source=drivers/pci.cpp
|
||||||
arch=x86_common
|
arch=x86_common
|
||||||
builtin=1
|
builtin=1
|
||||||
|
|
||||||
[driver:SVGA]
|
[driver]
|
||||||
|
name=SVGA
|
||||||
source=drivers/svga.cpp
|
source=drivers/svga.cpp
|
||||||
arch=x86_common
|
arch=x86_common
|
||||||
builtin=1
|
builtin=1
|
||||||
|
|
||||||
[driver:PS2]
|
[driver]
|
||||||
|
name=PS2
|
||||||
source=drivers/ps2.cpp
|
source=drivers/ps2.cpp
|
||||||
arch=x86_common
|
arch=x86_common
|
||||||
builtin=1
|
builtin=1
|
||||||
|
|
||||||
[driver:RTC]
|
[driver]
|
||||||
|
name=RTC
|
||||||
source=drivers/rtc.cpp
|
source=drivers/rtc.cpp
|
||||||
arch=x86_common
|
arch=x86_common
|
||||||
builtin=1
|
builtin=1
|
||||||
|
|
||||||
; PCI devices.
|
; PCI devices.
|
||||||
|
|
||||||
[driver:IDE]
|
[driver]
|
||||||
|
name=IDE
|
||||||
source=drivers/ide.cpp
|
source=drivers/ide.cpp
|
||||||
builtin=1
|
builtin=1
|
||||||
arch=x86_common
|
arch=x86_common
|
||||||
|
@ -51,14 +60,16 @@ parent=PCI
|
||||||
classCode=0x01
|
classCode=0x01
|
||||||
subclassCode=0x01
|
subclassCode=0x01
|
||||||
|
|
||||||
[driver:AHCI]
|
[driver]
|
||||||
|
name=AHCI
|
||||||
source=drivers/ahci.cpp
|
source=drivers/ahci.cpp
|
||||||
builtin=1
|
builtin=1
|
||||||
parent=PCI
|
parent=PCI
|
||||||
classCode=0x01
|
classCode=0x01
|
||||||
subclassCode=0x06
|
subclassCode=0x06
|
||||||
|
|
||||||
[driver:NVMe]
|
[driver]
|
||||||
|
name=NVMe
|
||||||
source=drivers/nvme.cpp
|
source=drivers/nvme.cpp
|
||||||
builtin=1
|
builtin=1
|
||||||
parent=PCI
|
parent=PCI
|
||||||
|
@ -66,7 +77,8 @@ classCode=0x01
|
||||||
subclassCode=0x08
|
subclassCode=0x08
|
||||||
progIF=0x02
|
progIF=0x02
|
||||||
|
|
||||||
[driver:HDAudio]
|
[driver]
|
||||||
|
name=HDAudio
|
||||||
name=HDAudio
|
name=HDAudio
|
||||||
source=drivers/hda.cpp
|
source=drivers/hda.cpp
|
||||||
builtin=1
|
builtin=1
|
||||||
|
@ -74,7 +86,8 @@ parent=PCI
|
||||||
classCode=0x04
|
classCode=0x04
|
||||||
subclassCode=0x03
|
subclassCode=0x03
|
||||||
|
|
||||||
[driver:xHCI]
|
[driver]
|
||||||
|
name=xHCI
|
||||||
source=drivers/xhci.cpp
|
source=drivers/xhci.cpp
|
||||||
builtin=1
|
builtin=1
|
||||||
parent=PCI
|
parent=PCI
|
||||||
|
@ -82,14 +95,16 @@ classCode=0x0C
|
||||||
subclassCode=0x03
|
subclassCode=0x03
|
||||||
progIF=0x30
|
progIF=0x30
|
||||||
|
|
||||||
[driver:BGA]
|
[driver]
|
||||||
|
name=BGA
|
||||||
source=drivers/bga.cpp
|
source=drivers/bga.cpp
|
||||||
builtin=1
|
builtin=1
|
||||||
parent=PCI
|
parent=PCI
|
||||||
deviceID=0xBEEF80EE
|
deviceID=0xBEEF80EE
|
||||||
deviceID=0x11111234
|
deviceID=0x11111234
|
||||||
|
|
||||||
[driver:I8254x]
|
[driver]
|
||||||
|
name=I8254x
|
||||||
source=drivers/i8254x.cpp
|
source=drivers/i8254x.cpp
|
||||||
builtin=1
|
builtin=1
|
||||||
parent=PCI
|
parent=PCI
|
||||||
|
@ -97,13 +112,15 @@ deviceID=0x100E8086
|
||||||
|
|
||||||
; USB devices.
|
; USB devices.
|
||||||
|
|
||||||
[driver:USBHID]
|
[driver]
|
||||||
|
name=USBHID
|
||||||
source=drivers/usb_hid.cpp
|
source=drivers/usb_hid.cpp
|
||||||
builtin=1
|
builtin=1
|
||||||
parent=USB
|
parent=USB
|
||||||
classCode=0x03
|
classCode=0x03
|
||||||
|
|
||||||
[driver:USBBulk]
|
[driver]
|
||||||
|
name=USBBulk
|
||||||
source=drivers/usb_bulk.cpp
|
source=drivers/usb_bulk.cpp
|
||||||
builtin=1
|
builtin=1
|
||||||
parent=USB
|
parent=USB
|
||||||
|
@ -113,14 +130,16 @@ protocol=0x50
|
||||||
|
|
||||||
; File systems.
|
; File systems.
|
||||||
|
|
||||||
[driver:EssenceFS]
|
[driver]
|
||||||
|
name=EssenceFS
|
||||||
source=drivers/esfs2.cpp
|
source=drivers/esfs2.cpp
|
||||||
builtin=1
|
builtin=1
|
||||||
parent=Files
|
parent=Files
|
||||||
signature_offset=0x2000
|
signature_offset=0x2000
|
||||||
signature=!EssenceFS2-----
|
signature=!EssenceFS2-----
|
||||||
|
|
||||||
[driver:FAT]
|
[driver]
|
||||||
|
name=FAT
|
||||||
source=drivers/fat.cpp
|
source=drivers/fat.cpp
|
||||||
builtin=1
|
builtin=1
|
||||||
parent=Files
|
parent=Files
|
||||||
|
@ -129,21 +148,24 @@ signature=)
|
||||||
signature_offset=0x42
|
signature_offset=0x42
|
||||||
signature=)
|
signature=)
|
||||||
|
|
||||||
[driver:ISO9660]
|
[driver]
|
||||||
|
name=ISO9660
|
||||||
source=drivers/iso9660.cpp
|
source=drivers/iso9660.cpp
|
||||||
builtin=1
|
builtin=1
|
||||||
parent=Files
|
parent=Files
|
||||||
signature_offset=0x8001
|
signature_offset=0x8001
|
||||||
signature=CD001
|
signature=CD001
|
||||||
|
|
||||||
[driver:NTFS]
|
[driver]
|
||||||
|
name=NTFS
|
||||||
source=drivers/ntfs.cpp
|
source=drivers/ntfs.cpp
|
||||||
builtin=1
|
builtin=1
|
||||||
parent=Files
|
parent=Files
|
||||||
signature_offset=3
|
signature_offset=3
|
||||||
signature=NTFS
|
signature=NTFS
|
||||||
|
|
||||||
[driver:Ext2]
|
[driver]
|
||||||
|
name=Ext2
|
||||||
source=drivers/ext2.cpp
|
source=drivers/ext2.cpp
|
||||||
builtin=1
|
builtin=1
|
||||||
parent=Files
|
parent=Files
|
||||||
|
@ -152,6 +174,7 @@ signature=S
|
||||||
|
|
||||||
; ACPI devices.
|
; ACPI devices.
|
||||||
|
|
||||||
[driver:ACPIThermal]
|
[driver]
|
||||||
|
name=ACPIThermal
|
||||||
source=drivers/acpi_thermal.cpp
|
source=drivers/acpi_thermal.cpp
|
||||||
builtin=1
|
builtin=1
|
||||||
|
|
10
util/build.c
10
util/build.c
|
@ -287,12 +287,8 @@ void Compile(uint32_t flags, int partitionSize, const char *volumeLabel) {
|
||||||
while (EsINIParse(&s)) {
|
while (EsINIParse(&s)) {
|
||||||
EsINIZeroTerminate(&s);
|
EsINIZeroTerminate(&s);
|
||||||
|
|
||||||
if (memcmp(s.section, "driver:", 7)) {
|
if (strcmp(s.section, "driver")) continue;
|
||||||
continue;
|
if (0 == strcmp(s.key, "name")) name = s.value;
|
||||||
}
|
|
||||||
|
|
||||||
name = s.section + 7;
|
|
||||||
|
|
||||||
if (0 == strcmp(s.key, "source")) source = s.value;
|
if (0 == strcmp(s.key, "source")) source = s.value;
|
||||||
if (0 == strcmp(s.key, "builtin")) builtin = !!atoi(s.value);
|
if (0 == strcmp(s.key, "builtin")) builtin = !!atoi(s.value);
|
||||||
|
|
||||||
|
@ -336,7 +332,7 @@ void Compile(uint32_t flags, int partitionSize, const char *volumeLabel) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(f, "[font:%s]\ncategory=%s\nscripts=%s\nlicense=%s\n", font->name, font->category, font->scripts, font->license);
|
fprintf(f, "[font]\nname=%s\ncategory=%s\nscripts=%s\nlicense=%s\n", font->name, font->category, font->scripts, font->license);
|
||||||
fileIndex = 0;
|
fileIndex = 0;
|
||||||
|
|
||||||
while (font->files[fileIndex].path) {
|
while (font->files[fileIndex].path) {
|
||||||
|
|
|
@ -1007,17 +1007,15 @@ void ParseKernelConfiguration() {
|
||||||
s.buffer = (char *) kernelConfig;
|
s.buffer = (char *) kernelConfig;
|
||||||
s.bytes = kernelConfigBytes;
|
s.bytes = kernelConfigBytes;
|
||||||
|
|
||||||
EsINIState previous = s;
|
char *moduleName = NULL, *parentName = NULL, *dataStart = s.buffer;
|
||||||
|
size_t moduleNameBytes = 0, parentNameBytes = 0;
|
||||||
|
bool builtin = false;
|
||||||
|
bool foundMatchingArchitecture = false, anyArchitecturesListed = false;
|
||||||
|
|
||||||
while (EsINIParse(&s)) {
|
while (EsINIParse(&s)) {
|
||||||
if (!(s.sectionBytes > 7 && 0 == memcmp(s.section, "driver:", 7))
|
if (!IsStringEqual(s.section, s.sectionBytes, "driver")) continue;
|
||||||
|| (previous.sectionBytes == s.sectionBytes && 0 == memcmp(previous.section, s.section, s.sectionBytes))
|
if (IsStringEqual(s.key, s.keyBytes, "name")) moduleName = s.value, moduleNameBytes = s.valueBytes;
|
||||||
|| !IsModuleEnabled(s.section + 7, s.sectionBytes - 7)) {
|
if (!EsINIPeek(&s) || !s.keyBytes) FilePrintFormat(f, "extern \"C\" KDriver driver%.*s;\n", (int) moduleNameBytes, moduleName);
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
FilePrintFormat(f, "extern \"C\" KDriver driver%.*s;\n", (int) s.sectionBytes - 7, s.section + 7);
|
|
||||||
previous = s;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FilePrintFormat(f, "#ifdef K_IN_CORE_KERNEL\n");
|
FilePrintFormat(f, "#ifdef K_IN_CORE_KERNEL\n");
|
||||||
|
@ -1026,18 +1024,14 @@ void ParseKernelConfiguration() {
|
||||||
s.buffer = (char *) kernelConfig;
|
s.buffer = (char *) kernelConfig;
|
||||||
s.bytes = kernelConfigBytes;
|
s.bytes = kernelConfigBytes;
|
||||||
|
|
||||||
char *moduleName = NULL, *parentName = NULL, *dataStart = s.buffer;
|
|
||||||
size_t moduleNameBytes = 0, parentNameBytes = 0;
|
|
||||||
bool builtin = false;
|
|
||||||
bool foundMatchingArchitecture = false, anyArchitecturesListed = false;
|
|
||||||
|
|
||||||
while (EsINIParse(&s)) {
|
while (EsINIParse(&s)) {
|
||||||
if (!(s.sectionBytes > 7 && 0 == memcmp(s.section, "driver:", 7))) {
|
if (!IsStringEqual(s.section, s.sectionBytes, "driver")) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
moduleName = s.section + 7;
|
if (IsStringEqual(s.key, s.keyBytes, "name")) {
|
||||||
moduleNameBytes = s.sectionBytes - 7;
|
moduleName = s.value, moduleNameBytes = s.valueBytes;
|
||||||
|
}
|
||||||
|
|
||||||
if (IsStringEqual(s.key, s.keyBytes, "parent")) {
|
if (IsStringEqual(s.key, s.keyBytes, "parent")) {
|
||||||
parentName = s.value, parentNameBytes = s.valueBytes;
|
parentName = s.value, parentNameBytes = s.valueBytes;
|
||||||
|
@ -1469,7 +1463,7 @@ int main(int argc, char **argv) {
|
||||||
} else if (0 == strcmp(s.key, "partition_size")) {
|
} else if (0 == strcmp(s.key, "partition_size")) {
|
||||||
partitionSize = atoi(s.value) * 1048576UL;
|
partitionSize = atoi(s.value) * 1048576UL;
|
||||||
}
|
}
|
||||||
} else if (0 == memcmp(s.section, "font:", 5)) {
|
} else if (0 == strcmp(s.section, "font")) {
|
||||||
arrput(fontLines, s);
|
arrput(fontLines, s);
|
||||||
} else if (0 == strcmp(s.section, "driver")) {
|
} else if (0 == strcmp(s.section, "driver")) {
|
||||||
if (0 == strcmp(s.key, "name")) driverName = s.value;
|
if (0 == strcmp(s.key, "name")) driverName = s.value;
|
||||||
|
|
Loading…
Reference in New Issue