2022-09-10 13:32:46 +02:00
|
|
|
/*
|
|
|
|
|
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
2022-11-13 16:37:58 -05:00
|
|
|
* running old operating systems and software designed for IBM
|
|
|
|
|
* PC systems and compatibles from 1981 through fairly recent
|
|
|
|
|
* system designs based on the PCI bus.
|
2022-09-10 13:32:46 +02:00
|
|
|
*
|
2022-11-13 16:37:58 -05:00
|
|
|
* This file is part of the 86Box distribution.
|
2022-09-10 13:32:46 +02:00
|
|
|
*
|
2022-11-13 16:37:58 -05:00
|
|
|
* Configuration file handler.
|
2022-09-10 13:32:46 +02:00
|
|
|
*
|
|
|
|
|
*
|
|
|
|
|
*
|
2023-01-06 15:36:29 -05:00
|
|
|
* Authors: Sarah Walker, <https://pcem-emulator.co.uk/>
|
2022-11-13 16:37:58 -05:00
|
|
|
* Miran Grca, <mgrca8@gmail.com>
|
|
|
|
|
* Fred N. van Kempen, <decwiz@yahoo.com>
|
|
|
|
|
* Overdoze,
|
|
|
|
|
* David Hrdlička, <hrdlickadavid@outlook.com>
|
2022-09-10 13:32:46 +02:00
|
|
|
*
|
2022-11-13 16:37:58 -05:00
|
|
|
* Copyright 2008-2019 Sarah Walker.
|
|
|
|
|
* Copyright 2016-2019 Miran Grca.
|
|
|
|
|
* Copyright 2017-2019 Fred N. van Kempen.
|
2023-01-06 15:36:29 -05:00
|
|
|
* Copyright 2018-2019 David Hrdlička.
|
2022-09-10 13:32:46 +02:00
|
|
|
*
|
|
|
|
|
* NOTE: Forcing config files to be in Unicode encoding breaks
|
2022-11-13 16:37:58 -05:00
|
|
|
* it on Windows XP, and possibly also Vista. Use the
|
|
|
|
|
* -DANSI_CFG for use on these systems.
|
2022-09-10 13:32:46 +02:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include <inttypes.h>
|
|
|
|
|
#include <stdarg.h>
|
|
|
|
|
#include <stdint.h>
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#include <wchar.h>
|
2025-03-10 17:31:18 +01:00
|
|
|
#include <wctype.h>
|
2022-09-10 13:32:46 +02:00
|
|
|
#define HAVE_STDARG_H
|
|
|
|
|
#include <86box/86box.h>
|
|
|
|
|
#include <86box/ini.h>
|
|
|
|
|
#include <86box/plat.h>
|
|
|
|
|
|
|
|
|
|
typedef struct _list_ {
|
|
|
|
|
struct _list_ *next;
|
|
|
|
|
} list_t;
|
|
|
|
|
|
2023-06-28 13:46:28 -04:00
|
|
|
typedef struct section_t {
|
2022-09-10 13:32:46 +02:00
|
|
|
list_t list;
|
|
|
|
|
|
|
|
|
|
char name[128];
|
|
|
|
|
|
|
|
|
|
list_t entry_head;
|
|
|
|
|
} section_t;
|
|
|
|
|
|
2023-06-28 13:46:28 -04:00
|
|
|
typedef struct entry_t {
|
2022-09-10 13:32:46 +02:00
|
|
|
list_t list;
|
|
|
|
|
|
|
|
|
|
char name[128];
|
|
|
|
|
char data[512];
|
|
|
|
|
wchar_t wdata[512];
|
|
|
|
|
} entry_t;
|
|
|
|
|
|
|
|
|
|
#define list_add(new, head) \
|
|
|
|
|
{ \
|
|
|
|
|
list_t *next = head; \
|
|
|
|
|
\
|
|
|
|
|
while (next->next != NULL) \
|
|
|
|
|
next = next->next; \
|
|
|
|
|
\
|
|
|
|
|
(next)->next = new; \
|
|
|
|
|
(new)->next = NULL; \
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#define list_delete(old, head) \
|
|
|
|
|
{ \
|
|
|
|
|
list_t *next = head; \
|
|
|
|
|
\
|
|
|
|
|
while ((next)->next != old) { \
|
|
|
|
|
next = (next)->next; \
|
|
|
|
|
} \
|
|
|
|
|
\
|
|
|
|
|
(next)->next = (old)->next; \
|
|
|
|
|
if ((next) == (head)) \
|
|
|
|
|
(head)->next = (old)->next; \
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef ENABLE_INI_LOG
|
|
|
|
|
int ini_do_log = ENABLE_INI_LOG;
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
ini_log(const char *fmt, ...)
|
|
|
|
|
{
|
|
|
|
|
va_list ap;
|
|
|
|
|
|
|
|
|
|
if (ini_do_log) {
|
|
|
|
|
va_start(ap, fmt);
|
|
|
|
|
pclog_ex(fmt, ap);
|
|
|
|
|
va_end(ap);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#else
|
|
|
|
|
# define ini_log(fmt, ...)
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
static section_t *
|
2023-04-18 16:14:44 -03:00
|
|
|
find_section(list_t *head, const char *name)
|
2022-09-10 13:32:46 +02:00
|
|
|
{
|
|
|
|
|
section_t *sec = (section_t *) head->next;
|
2023-04-18 16:14:44 -03:00
|
|
|
const char blank[] = "";
|
2022-09-10 13:32:46 +02:00
|
|
|
|
|
|
|
|
if (name == NULL)
|
|
|
|
|
name = blank;
|
|
|
|
|
|
|
|
|
|
while (sec != NULL) {
|
|
|
|
|
if (!strncmp(sec->name, name, sizeof(sec->name)))
|
2023-05-11 03:02:36 -04:00
|
|
|
return sec;
|
2022-09-10 13:32:46 +02:00
|
|
|
|
|
|
|
|
sec = (section_t *) sec->list.next;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ini_section_t
|
2023-04-18 16:14:44 -03:00
|
|
|
ini_find_section(ini_t ini, const char *name)
|
2022-09-10 13:32:46 +02:00
|
|
|
{
|
|
|
|
|
if (ini == NULL)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
return (ini_section_t) find_section((list_t *) ini, name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2023-04-18 16:14:44 -03:00
|
|
|
ini_rename_section(ini_section_t section, const char *name)
|
2022-09-10 13:32:46 +02:00
|
|
|
{
|
|
|
|
|
section_t *sec = (section_t *) section;
|
|
|
|
|
|
|
|
|
|
if (sec == NULL)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
memset(sec->name, 0x00, sizeof(sec->name));
|
|
|
|
|
memcpy(sec->name, name, MIN(128, strlen(name) + 1));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static entry_t *
|
2022-11-06 15:55:16 -05:00
|
|
|
find_entry(section_t *section, const char *name)
|
2022-09-10 13:32:46 +02:00
|
|
|
{
|
|
|
|
|
entry_t *ent;
|
|
|
|
|
|
|
|
|
|
ent = (entry_t *) section->entry_head.next;
|
|
|
|
|
|
|
|
|
|
while (ent != NULL) {
|
|
|
|
|
if (!strncmp(ent->name, name, sizeof(ent->name)))
|
2023-05-11 03:02:36 -04:00
|
|
|
return ent;
|
2022-09-10 13:32:46 +02:00
|
|
|
|
|
|
|
|
ent = (entry_t *) ent->list.next;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return (NULL);
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-08 02:13:14 +06:00
|
|
|
int
|
|
|
|
|
ini_has_entry(ini_section_t self, const char *name)
|
|
|
|
|
{
|
|
|
|
|
section_t *section = (section_t *) self;
|
|
|
|
|
const entry_t *entry;
|
|
|
|
|
|
|
|
|
|
if (section == NULL)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
entry = find_entry(section, name);
|
|
|
|
|
if (entry == NULL)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
2022-09-10 13:32:46 +02:00
|
|
|
static int
|
|
|
|
|
entries_num(section_t *section)
|
|
|
|
|
{
|
|
|
|
|
entry_t *ent;
|
|
|
|
|
int i = 0;
|
|
|
|
|
|
|
|
|
|
ent = (entry_t *) section->entry_head.next;
|
|
|
|
|
|
|
|
|
|
while (ent != NULL) {
|
|
|
|
|
if (strlen(ent->name) > 0)
|
|
|
|
|
i++;
|
|
|
|
|
|
|
|
|
|
ent = (entry_t *) ent->list.next;
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-11 03:02:36 -04:00
|
|
|
return i;
|
2022-09-10 13:32:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
delete_section_if_empty(list_t *head, section_t *section)
|
|
|
|
|
{
|
|
|
|
|
if (section == NULL)
|
|
|
|
|
return;
|
|
|
|
|
|
2024-11-03 02:13:17 +01:00
|
|
|
int n = entries_num(section);
|
|
|
|
|
|
|
|
|
|
if (n > 0) {
|
|
|
|
|
int i = 0;
|
|
|
|
|
entry_t *i_ent = (entry_t *) section->entry_head.next;
|
|
|
|
|
|
|
|
|
|
while (i_ent != NULL) {
|
|
|
|
|
int i_nlen = strlen(i_ent->name);
|
|
|
|
|
entry_t* i_next = (entry_t *) i_ent->list.next;
|
|
|
|
|
|
|
|
|
|
if (i_nlen > 0) {
|
|
|
|
|
int j = 0;
|
|
|
|
|
entry_t *j_ent = (entry_t *) section->entry_head.next;
|
|
|
|
|
|
|
|
|
|
while (j_ent != NULL) {
|
|
|
|
|
int j_nlen = strlen(j_ent->name);
|
|
|
|
|
entry_t* j_next = (entry_t *) j_ent->list.next;
|
|
|
|
|
if (j_nlen > 0) {
|
|
|
|
|
if ((j != i) && (strcmp(j_ent->name, i_ent->name) > 0)) {
|
|
|
|
|
entry_t t_ent = { 0 };
|
|
|
|
|
memcpy(&t_ent, j_ent, sizeof(entry_t));
|
|
|
|
|
/* J: Contents of I, list of J */
|
|
|
|
|
memcpy(j_ent->name, i_ent->name, sizeof(entry_t) - sizeof(i_ent->list));
|
|
|
|
|
/* I: Contents of J, list of I */
|
|
|
|
|
memcpy(i_ent->name, t_ent.name, sizeof(entry_t) - sizeof(i_ent->list));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
j++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
j_ent = (entry_t *) j_next;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
i++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
i_ent = (entry_t *) i_next;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
2022-09-10 13:32:46 +02:00
|
|
|
list_delete(§ion->list, head);
|
|
|
|
|
free(section);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
ini_delete_section_if_empty(ini_t ini, ini_section_t section)
|
|
|
|
|
{
|
|
|
|
|
if (ini == NULL || section == NULL)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
delete_section_if_empty((list_t *) ini, (section_t *) section);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static section_t *
|
2023-04-18 16:14:44 -03:00
|
|
|
create_section(list_t *head, const char *name)
|
2022-09-10 13:32:46 +02:00
|
|
|
{
|
2025-03-09 23:58:54 +06:00
|
|
|
section_t *ns = calloc(1, sizeof(section_t));
|
2022-09-10 13:32:46 +02:00
|
|
|
|
|
|
|
|
memcpy(ns->name, name, strlen(name) + 1);
|
|
|
|
|
list_add(&ns->list, head);
|
|
|
|
|
|
2023-05-11 03:02:36 -04:00
|
|
|
return ns;
|
2022-09-10 13:32:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ini_section_t
|
2023-04-18 16:14:44 -03:00
|
|
|
ini_find_or_create_section(ini_t ini, const char *name)
|
2022-09-10 13:32:46 +02:00
|
|
|
{
|
|
|
|
|
if (ini == NULL)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
section_t *section = find_section((list_t *) ini, name);
|
|
|
|
|
if (section == NULL)
|
|
|
|
|
section = create_section((list_t *) ini, name);
|
|
|
|
|
|
|
|
|
|
return (ini_section_t) section;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static entry_t *
|
2022-11-06 15:55:16 -05:00
|
|
|
create_entry(section_t *section, const char *name)
|
2022-09-10 13:32:46 +02:00
|
|
|
{
|
2025-03-09 23:58:54 +06:00
|
|
|
entry_t *ne = calloc(1, sizeof(entry_t));
|
2022-09-10 13:32:46 +02:00
|
|
|
|
|
|
|
|
memcpy(ne->name, name, strlen(name) + 1);
|
|
|
|
|
list_add(&ne->list, §ion->entry_head);
|
|
|
|
|
|
2023-05-11 03:02:36 -04:00
|
|
|
return ne;
|
2022-09-10 13:32:46 +02:00
|
|
|
}
|
|
|
|
|
|
2022-09-10 13:47:36 +02:00
|
|
|
void
|
2022-09-10 13:32:46 +02:00
|
|
|
ini_close(ini_t ini)
|
|
|
|
|
{
|
2023-05-11 03:02:36 -04:00
|
|
|
section_t *sec;
|
|
|
|
|
section_t *ns;
|
2022-09-10 13:32:46 +02:00
|
|
|
entry_t *ent;
|
|
|
|
|
list_t *list = (list_t *) ini;
|
|
|
|
|
|
|
|
|
|
if (list == NULL)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
sec = (section_t *) list->next;
|
|
|
|
|
while (sec != NULL) {
|
2022-09-18 17:11:43 -04:00
|
|
|
ns = (section_t *) sec->list.next;
|
2022-09-10 13:32:46 +02:00
|
|
|
ent = (entry_t *) sec->entry_head.next;
|
|
|
|
|
|
|
|
|
|
while (ent != NULL) {
|
|
|
|
|
entry_t *nent = (entry_t *) ent->list.next;
|
|
|
|
|
|
|
|
|
|
free(ent);
|
|
|
|
|
ent = nent;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
free(sec);
|
|
|
|
|
sec = ns;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
free(list);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
2023-04-18 16:14:44 -03:00
|
|
|
ini_detect_bom(const char *fn)
|
2022-09-10 13:32:46 +02:00
|
|
|
{
|
2023-08-21 20:25:33 -04:00
|
|
|
FILE *fp;
|
2022-09-10 13:32:46 +02:00
|
|
|
unsigned char bom[4] = { 0, 0, 0, 0 };
|
|
|
|
|
|
|
|
|
|
#if defined(ANSI_CFG) || !defined(_WIN32)
|
2023-08-21 20:25:33 -04:00
|
|
|
fp = plat_fopen(fn, "rt");
|
2022-09-10 13:32:46 +02:00
|
|
|
#else
|
2023-08-21 20:25:33 -04:00
|
|
|
fp = plat_fopen(fn, "rt, ccs=UTF-8");
|
2022-09-10 13:32:46 +02:00
|
|
|
#endif
|
2023-08-21 20:25:33 -04:00
|
|
|
if (fp == NULL)
|
2023-05-11 03:02:36 -04:00
|
|
|
return 0;
|
2023-08-21 20:25:33 -04:00
|
|
|
(void) !fread(bom, 1, 3, fp);
|
2022-09-10 13:32:46 +02:00
|
|
|
if (bom[0] == 0xEF && bom[1] == 0xBB && bom[2] == 0xBF) {
|
2023-08-21 20:25:33 -04:00
|
|
|
fclose(fp);
|
2022-09-10 13:32:46 +02:00
|
|
|
return 1;
|
|
|
|
|
}
|
2023-08-21 20:25:33 -04:00
|
|
|
fclose(fp);
|
2022-09-10 13:32:46 +02:00
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef __HAIKU__
|
|
|
|
|
/* Local version of fgetws to avoid a crash */
|
|
|
|
|
static wchar_t *
|
|
|
|
|
ini_fgetws(wchar_t *str, int count, FILE *stream)
|
|
|
|
|
{
|
|
|
|
|
int i = 0;
|
|
|
|
|
if (feof(stream))
|
|
|
|
|
return NULL;
|
|
|
|
|
for (i = 0; i < count; i++) {
|
|
|
|
|
wint_t curChar = fgetwc(stream);
|
|
|
|
|
if (curChar == WEOF) {
|
|
|
|
|
if (i + 1 < count)
|
|
|
|
|
str[i + 1] = 0;
|
|
|
|
|
return feof(stream) ? str : NULL;
|
|
|
|
|
}
|
|
|
|
|
str[i] = curChar;
|
|
|
|
|
if (curChar == '\n')
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (i + 1 < count)
|
|
|
|
|
str[i + 1] = 0;
|
|
|
|
|
return str;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/* Read and parse the configuration file into memory. */
|
|
|
|
|
ini_t
|
2023-04-18 16:14:44 -03:00
|
|
|
ini_read(const char *fn)
|
2022-09-10 13:32:46 +02:00
|
|
|
{
|
2023-05-11 03:02:36 -04:00
|
|
|
char sname[128];
|
|
|
|
|
char ename[128];
|
2022-09-10 13:32:46 +02:00
|
|
|
wchar_t buff[1024];
|
2023-05-11 03:02:36 -04:00
|
|
|
section_t *sec;
|
|
|
|
|
section_t *ns;
|
2022-09-10 13:32:46 +02:00
|
|
|
entry_t *ne;
|
2023-05-11 03:02:36 -04:00
|
|
|
int c;
|
|
|
|
|
int d;
|
|
|
|
|
int bom;
|
2023-08-21 20:25:33 -04:00
|
|
|
FILE *fp;
|
2022-09-10 13:32:46 +02:00
|
|
|
list_t *head;
|
|
|
|
|
|
|
|
|
|
bom = ini_detect_bom(fn);
|
|
|
|
|
#if defined(ANSI_CFG) || !defined(_WIN32)
|
2023-08-21 20:25:33 -04:00
|
|
|
fp = plat_fopen(fn, "rt");
|
2022-09-10 13:32:46 +02:00
|
|
|
#else
|
2023-08-21 20:25:33 -04:00
|
|
|
fp = plat_fopen(fn, "rt, ccs=UTF-8");
|
2022-09-10 13:32:46 +02:00
|
|
|
#endif
|
2023-08-21 20:25:33 -04:00
|
|
|
if (fp == NULL)
|
2022-09-10 13:32:46 +02:00
|
|
|
return NULL;
|
|
|
|
|
|
2025-03-09 23:58:54 +06:00
|
|
|
head = calloc(1, sizeof(list_t));
|
|
|
|
|
sec = calloc(1, sizeof(section_t));
|
2022-09-10 13:32:46 +02:00
|
|
|
|
|
|
|
|
list_add(&sec->list, head);
|
|
|
|
|
if (bom)
|
2023-08-21 20:25:33 -04:00
|
|
|
fseek(fp, 3, SEEK_SET);
|
2022-09-10 13:32:46 +02:00
|
|
|
|
|
|
|
|
while (1) {
|
|
|
|
|
memset(buff, 0x00, sizeof(buff));
|
|
|
|
|
#ifdef __HAIKU__
|
2023-09-26 04:51:59 -04:00
|
|
|
ini_fgetws(buff, sizeof_w(buff), fp);
|
2022-09-10 13:32:46 +02:00
|
|
|
#else
|
2023-08-21 20:25:33 -04:00
|
|
|
(void) !fgetws(buff, sizeof_w(buff), fp);
|
2022-09-10 13:32:46 +02:00
|
|
|
#endif
|
2023-08-21 20:25:33 -04:00
|
|
|
if (feof(fp))
|
2022-09-10 13:32:46 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
/* Make sure there are no stray newlines or hard-returns in there. */
|
|
|
|
|
if (wcslen(buff) > 0)
|
|
|
|
|
if (buff[wcslen(buff) - 1] == L'\n')
|
|
|
|
|
buff[wcslen(buff) - 1] = L'\0';
|
|
|
|
|
if (wcslen(buff) > 0)
|
|
|
|
|
if (buff[wcslen(buff) - 1] == L'\r')
|
|
|
|
|
buff[wcslen(buff) - 1] = L'\0';
|
|
|
|
|
|
|
|
|
|
/* Skip any leading whitespace. */
|
|
|
|
|
c = 0;
|
|
|
|
|
while ((buff[c] == L' ') || (buff[c] == L'\t'))
|
|
|
|
|
c++;
|
|
|
|
|
|
|
|
|
|
/* Skip empty lines. */
|
|
|
|
|
if (buff[c] == L'\0')
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
/* Skip lines that (only) have a comment. */
|
|
|
|
|
if ((buff[c] == L'#') || (buff[c] == L';'))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
if (buff[c] == L'[') { /*Section*/
|
|
|
|
|
c++;
|
|
|
|
|
d = 0;
|
|
|
|
|
while (buff[c] != L']' && buff[c])
|
|
|
|
|
(void) !wctomb(&(sname[d++]), buff[c++]);
|
|
|
|
|
sname[d] = L'\0';
|
|
|
|
|
|
|
|
|
|
/* Is the section name properly terminated? */
|
|
|
|
|
if (buff[c] != L']')
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
/* Create a new section and insert it. */
|
|
|
|
|
ns = malloc(sizeof(section_t));
|
|
|
|
|
memset(ns, 0x00, sizeof(section_t));
|
|
|
|
|
memcpy(ns->name, sname, 128);
|
|
|
|
|
list_add(&ns->list, head);
|
|
|
|
|
|
|
|
|
|
/* New section is now the current one. */
|
|
|
|
|
sec = ns;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Get the variable name. */
|
|
|
|
|
d = 0;
|
|
|
|
|
while ((buff[c] != L'=') && (buff[c] != L' ') && buff[c])
|
|
|
|
|
(void) !wctomb(&(ename[d++]), buff[c++]);
|
|
|
|
|
ename[d] = L'\0';
|
|
|
|
|
|
|
|
|
|
/* Skip incomplete lines. */
|
|
|
|
|
if (buff[c] == L'\0')
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
/* Look for =, skip whitespace. */
|
|
|
|
|
while ((buff[c] == L'=' || buff[c] == L' ') && buff[c])
|
|
|
|
|
c++;
|
|
|
|
|
|
|
|
|
|
/* Skip incomplete lines. */
|
|
|
|
|
if (buff[c] == L'\0')
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
/* This is where the value part starts. */
|
|
|
|
|
d = c;
|
|
|
|
|
|
|
|
|
|
/* Allocate a new variable entry.. */
|
2025-03-09 23:58:54 +06:00
|
|
|
ne = calloc(1, sizeof(entry_t));
|
2022-09-10 13:32:46 +02:00
|
|
|
memset(ne, 0x00, sizeof(entry_t));
|
|
|
|
|
memcpy(ne->name, ename, 128);
|
|
|
|
|
wcsncpy(ne->wdata, &buff[d], sizeof_w(ne->wdata) - 1);
|
|
|
|
|
ne->wdata[sizeof_w(ne->wdata) - 1] = L'\0';
|
|
|
|
|
#ifdef _WIN32 /* Make sure the string is converted to UTF-8 rather than a legacy codepage */
|
|
|
|
|
c16stombs(ne->data, ne->wdata, sizeof(ne->data));
|
|
|
|
|
#else
|
|
|
|
|
wcstombs(ne->data, ne->wdata, sizeof(ne->data));
|
|
|
|
|
#endif
|
|
|
|
|
ne->data[sizeof(ne->data) - 1] = '\0';
|
|
|
|
|
|
|
|
|
|
/* .. and insert it. */
|
|
|
|
|
list_add(&ne->list, &sec->entry_head);
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-21 20:25:33 -04:00
|
|
|
(void) fclose(fp);
|
2022-09-10 13:32:46 +02:00
|
|
|
|
|
|
|
|
return (ini_t) head;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Write the in-memory configuration to disk. */
|
|
|
|
|
void
|
2023-04-18 16:14:44 -03:00
|
|
|
ini_write(ini_t ini, const char *fn)
|
2022-09-10 13:32:46 +02:00
|
|
|
{
|
|
|
|
|
wchar_t wtemp[512];
|
|
|
|
|
list_t *list = (list_t *) ini;
|
|
|
|
|
section_t *sec;
|
2023-08-21 20:25:33 -04:00
|
|
|
FILE *fp;
|
2022-09-10 13:32:46 +02:00
|
|
|
int fl = 0;
|
|
|
|
|
|
|
|
|
|
if (list == NULL)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
sec = (section_t *) list->next;
|
|
|
|
|
|
|
|
|
|
#if defined(ANSI_CFG) || !defined(_WIN32)
|
2023-08-21 20:25:33 -04:00
|
|
|
fp = plat_fopen(fn, "wt");
|
2022-09-10 13:32:46 +02:00
|
|
|
#else
|
2023-08-21 20:25:33 -04:00
|
|
|
fp = plat_fopen(fn, "wt, ccs=UTF-8");
|
2022-09-10 13:32:46 +02:00
|
|
|
#endif
|
2023-08-21 20:25:33 -04:00
|
|
|
if (fp == NULL)
|
2022-09-10 13:32:46 +02:00
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
while (sec != NULL) {
|
|
|
|
|
entry_t *ent;
|
|
|
|
|
|
|
|
|
|
if (sec->name[0]) {
|
|
|
|
|
mbstowcs(wtemp, sec->name, strlen(sec->name) + 1);
|
|
|
|
|
if (fl)
|
2023-08-21 20:25:33 -04:00
|
|
|
fwprintf(fp, L"\n[%ls]\n", wtemp);
|
2022-09-10 13:32:46 +02:00
|
|
|
else
|
2023-08-21 20:25:33 -04:00
|
|
|
fwprintf(fp, L"[%ls]\n", wtemp);
|
2022-09-10 13:32:46 +02:00
|
|
|
fl++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ent = (entry_t *) sec->entry_head.next;
|
|
|
|
|
while (ent != NULL) {
|
|
|
|
|
if (ent->name[0] != '\0') {
|
|
|
|
|
mbstowcs(wtemp, ent->name, 128);
|
|
|
|
|
if (ent->wdata[0] == L'\0')
|
2023-08-21 20:25:33 -04:00
|
|
|
fwprintf(fp, L"%ls = \n", wtemp);
|
2022-09-10 13:32:46 +02:00
|
|
|
else
|
2023-08-21 20:25:33 -04:00
|
|
|
fwprintf(fp, L"%ls = %ls\n", wtemp, ent->wdata);
|
2022-09-10 13:32:46 +02:00
|
|
|
fl++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ent = (entry_t *) ent->list.next;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sec = (section_t *) sec->list.next;
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-21 20:25:33 -04:00
|
|
|
(void) fclose(fp);
|
2022-09-10 13:32:46 +02:00
|
|
|
}
|
|
|
|
|
|
2025-03-10 20:54:25 +06:00
|
|
|
/* Wide-character version of "trim" */
|
2025-03-10 12:37:50 +06:00
|
|
|
wchar_t *
|
|
|
|
|
trim_w(wchar_t *str)
|
|
|
|
|
{
|
|
|
|
|
size_t len = 0;
|
|
|
|
|
wchar_t *frontp = str;
|
|
|
|
|
wchar_t *endp = NULL;
|
|
|
|
|
|
|
|
|
|
if (str == NULL) {
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
if (str[0] == L'\0') {
|
|
|
|
|
return str;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
len = wcslen(str);
|
|
|
|
|
endp = str + len;
|
|
|
|
|
|
|
|
|
|
/* Move the front and back pointers to address the first non-whitespace
|
|
|
|
|
* characters from each end.
|
|
|
|
|
*/
|
|
|
|
|
while (iswspace((wint_t) *frontp)) {
|
|
|
|
|
++frontp;
|
|
|
|
|
}
|
|
|
|
|
if (endp != frontp) {
|
|
|
|
|
while (iswspace((wint_t) *(--endp)) && endp != frontp) { }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (frontp != str && endp == frontp)
|
|
|
|
|
*str = L'\0';
|
|
|
|
|
else if ((str + len - 1) != endp)
|
|
|
|
|
*(endp + 1) = L'\0';
|
|
|
|
|
|
|
|
|
|
/* Shift the string so that it starts at str so that if it's dynamically
|
|
|
|
|
* allocated, we can still free it on the returned pointer. Note the reuse
|
|
|
|
|
* of endp to mean the front of the string buffer now.
|
|
|
|
|
*/
|
|
|
|
|
endp = str;
|
|
|
|
|
if (frontp != str) {
|
|
|
|
|
while (*frontp) {
|
|
|
|
|
*endp++ = *frontp++;
|
|
|
|
|
}
|
|
|
|
|
*endp = L'\0';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return str;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
extern char* trim(char* str);
|
|
|
|
|
|
2025-03-09 23:58:54 +06:00
|
|
|
void
|
|
|
|
|
ini_strip_quotes(ini_t ini)
|
|
|
|
|
{
|
|
|
|
|
list_t *list = (list_t *) ini;
|
|
|
|
|
section_t *sec;
|
|
|
|
|
|
|
|
|
|
sec = (section_t *) list->next;
|
|
|
|
|
|
|
|
|
|
while (sec != NULL) {
|
|
|
|
|
entry_t *ent;
|
|
|
|
|
|
|
|
|
|
ent = (entry_t *) sec->entry_head.next;
|
|
|
|
|
while (ent != NULL) {
|
|
|
|
|
if (ent->name[0] != '\0') {
|
2025-03-10 02:00:24 +06:00
|
|
|
int trailing_hash = strcspn(ent->data, "#");
|
|
|
|
|
int trailing_quote;
|
|
|
|
|
ent->wdata[trailing_hash] = 0;
|
|
|
|
|
ent->data[trailing_hash] = 0;
|
2025-03-09 23:58:54 +06:00
|
|
|
if (ent->wdata[0] == L'\"') {
|
|
|
|
|
memmove(ent->wdata, &ent->wdata[1], sizeof(ent->wdata) - sizeof(wchar_t));
|
|
|
|
|
}
|
|
|
|
|
if (ent->wdata[wcslen(ent->wdata) - 1] == L'\"') {
|
|
|
|
|
ent->wdata[wcslen(ent->wdata) - 1] = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ent->data[0] == '\"') {
|
|
|
|
|
memmove(ent->data, &ent->data[1], sizeof(ent->data) - sizeof(char));
|
|
|
|
|
}
|
|
|
|
|
if (ent->data[strlen(ent->data) - 1] == '\"') {
|
|
|
|
|
ent->data[strlen(ent->data) - 1] = 0;
|
|
|
|
|
}
|
2025-03-10 02:00:24 +06:00
|
|
|
|
|
|
|
|
trailing_quote = strcspn(ent->data, "\"");
|
|
|
|
|
ent->wdata[trailing_quote] = 0;
|
|
|
|
|
ent->data[trailing_quote] = 0;
|
2025-03-10 12:37:50 +06:00
|
|
|
|
|
|
|
|
trim_w(ent->wdata);
|
|
|
|
|
trim(ent->data);
|
2025-03-09 23:58:54 +06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ent = (entry_t *) ent->list.next;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sec = (section_t *) sec->list.next;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-09-10 13:32:46 +02:00
|
|
|
ini_t
|
2022-11-17 22:44:06 +01:00
|
|
|
ini_new(void)
|
2022-09-10 13:32:46 +02:00
|
|
|
{
|
|
|
|
|
ini_t ini = malloc(sizeof(list_t));
|
|
|
|
|
memset(ini, 0, sizeof(list_t));
|
|
|
|
|
return ini;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
ini_dump(ini_t ini)
|
|
|
|
|
{
|
|
|
|
|
section_t *sec = (section_t *) ini;
|
|
|
|
|
while (sec != NULL) {
|
|
|
|
|
entry_t *ent;
|
|
|
|
|
|
|
|
|
|
if (sec->name[0])
|
|
|
|
|
ini_log("[%s]\n", sec->name);
|
|
|
|
|
|
|
|
|
|
ent = (entry_t *) sec->entry_head.next;
|
|
|
|
|
while (ent != NULL) {
|
|
|
|
|
ini_log("%s = %s\n", ent->name, ent->data);
|
|
|
|
|
|
|
|
|
|
ent = (entry_t *) ent->list.next;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sec = (section_t *) sec->list.next;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2023-04-18 16:14:44 -03:00
|
|
|
ini_section_delete_var(ini_section_t self, const char *name)
|
2022-09-10 13:32:46 +02:00
|
|
|
{
|
|
|
|
|
section_t *section = (section_t *) self;
|
|
|
|
|
entry_t *entry;
|
|
|
|
|
|
|
|
|
|
if (section == NULL)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
entry = find_entry(section, name);
|
|
|
|
|
if (entry != NULL) {
|
|
|
|
|
list_delete(&entry->list, §ion->entry_head);
|
|
|
|
|
free(entry);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
2023-04-18 16:14:44 -03:00
|
|
|
ini_section_get_int(ini_section_t self, const char *name, int def)
|
2022-09-10 13:32:46 +02:00
|
|
|
{
|
2023-07-20 18:58:26 -04:00
|
|
|
section_t *section = (section_t *) self;
|
|
|
|
|
const entry_t *entry;
|
2024-06-11 20:06:04 -04:00
|
|
|
int value = 0;
|
2022-09-10 13:32:46 +02:00
|
|
|
|
|
|
|
|
if (section == NULL)
|
2023-05-11 03:02:36 -04:00
|
|
|
return def;
|
2022-09-10 13:32:46 +02:00
|
|
|
|
|
|
|
|
entry = find_entry(section, name);
|
|
|
|
|
if (entry == NULL)
|
2023-05-11 03:02:36 -04:00
|
|
|
return def;
|
2022-09-10 13:32:46 +02:00
|
|
|
|
2025-03-08 02:13:14 +06:00
|
|
|
if (stricmp(entry->data, "true") == 0)
|
|
|
|
|
return 1;
|
|
|
|
|
if (stricmp(entry->data, "false") == 0)
|
|
|
|
|
return 0;
|
|
|
|
|
|
2022-09-10 13:32:46 +02:00
|
|
|
sscanf(entry->data, "%i", &value);
|
|
|
|
|
|
2023-05-11 03:02:36 -04:00
|
|
|
return value;
|
2022-09-10 13:32:46 +02:00
|
|
|
}
|
|
|
|
|
|
2023-10-13 15:34:00 -04:00
|
|
|
uint32_t
|
|
|
|
|
ini_section_get_uint(ini_section_t self, const char *name, uint32_t def)
|
|
|
|
|
{
|
|
|
|
|
section_t *section = (section_t *) self;
|
|
|
|
|
const entry_t *entry;
|
2024-06-11 20:06:04 -04:00
|
|
|
uint32_t value = 0;
|
2023-10-13 15:34:00 -04:00
|
|
|
|
|
|
|
|
if (section == NULL)
|
|
|
|
|
return def;
|
|
|
|
|
|
|
|
|
|
entry = find_entry(section, name);
|
|
|
|
|
if (entry == NULL)
|
|
|
|
|
return def;
|
|
|
|
|
|
|
|
|
|
sscanf(entry->data, "%u", &value);
|
|
|
|
|
|
|
|
|
|
return value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
|
float
|
|
|
|
|
ini_section_get_float(ini_section_t self, const char *name, float def)
|
|
|
|
|
{
|
|
|
|
|
section_t *section = (section_t *) self;
|
|
|
|
|
const entry_t *entry;
|
2024-06-11 20:06:04 -04:00
|
|
|
float value = 0;
|
2023-10-13 15:34:00 -04:00
|
|
|
|
|
|
|
|
if (section == NULL)
|
|
|
|
|
return def;
|
|
|
|
|
|
|
|
|
|
entry = find_entry(section, name);
|
|
|
|
|
if (entry == NULL)
|
|
|
|
|
return def;
|
|
|
|
|
|
|
|
|
|
sscanf(entry->data, "%g", &value);
|
|
|
|
|
|
|
|
|
|
return value;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
2022-09-10 13:32:46 +02:00
|
|
|
double
|
2023-04-18 16:14:44 -03:00
|
|
|
ini_section_get_double(ini_section_t self, const char *name, double def)
|
2022-09-10 13:32:46 +02:00
|
|
|
{
|
2023-07-20 18:58:26 -04:00
|
|
|
section_t *section = (section_t *) self;
|
2025-03-29 01:18:37 +06:00
|
|
|
entry_t *entry;
|
|
|
|
|
double value = 0;
|
|
|
|
|
int res = 0;
|
2022-09-10 13:32:46 +02:00
|
|
|
|
|
|
|
|
if (section == NULL)
|
2023-05-11 03:02:36 -04:00
|
|
|
return def;
|
2022-09-10 13:32:46 +02:00
|
|
|
|
|
|
|
|
entry = find_entry(section, name);
|
|
|
|
|
if (entry == NULL)
|
2023-05-11 03:02:36 -04:00
|
|
|
return def;
|
2022-09-10 13:32:46 +02:00
|
|
|
|
2025-03-29 01:18:37 +06:00
|
|
|
res = sscanf(entry->data, "%lg", &value);
|
|
|
|
|
if (res == EOF || res <= 0) {
|
|
|
|
|
int i = 0;
|
|
|
|
|
for (i = 0; i < strlen(entry->data); i++) {
|
|
|
|
|
if (entry->data[i] == ',') {
|
|
|
|
|
entry->data[i] = '.';
|
|
|
|
|
entry->wdata[i] = L'.';
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
(void)sscanf(entry->data, "%lg", &value);
|
|
|
|
|
}
|
2022-09-10 13:32:46 +02:00
|
|
|
|
2023-05-11 03:02:36 -04:00
|
|
|
return value;
|
2022-09-10 13:32:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
2023-04-18 16:14:44 -03:00
|
|
|
ini_section_get_hex16(ini_section_t self, const char *name, int def)
|
2022-09-10 13:32:46 +02:00
|
|
|
{
|
2023-07-20 18:58:26 -04:00
|
|
|
section_t *section = (section_t *) self;
|
|
|
|
|
const entry_t *entry;
|
2024-06-11 20:06:04 -04:00
|
|
|
unsigned int value = 0;
|
2022-09-10 13:32:46 +02:00
|
|
|
|
|
|
|
|
if (section == NULL)
|
2023-05-11 03:02:36 -04:00
|
|
|
return def;
|
2022-09-10 13:32:46 +02:00
|
|
|
|
|
|
|
|
entry = find_entry(section, name);
|
|
|
|
|
if (entry == NULL)
|
2023-05-11 03:02:36 -04:00
|
|
|
return def;
|
2022-09-10 13:32:46 +02:00
|
|
|
|
|
|
|
|
sscanf(entry->data, "%04X", &value);
|
|
|
|
|
|
2023-05-11 03:02:36 -04:00
|
|
|
return value;
|
2022-09-10 13:32:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
2023-04-18 16:14:44 -03:00
|
|
|
ini_section_get_hex20(ini_section_t self, const char *name, int def)
|
2022-09-10 13:32:46 +02:00
|
|
|
{
|
2023-07-20 18:58:26 -04:00
|
|
|
section_t *section = (section_t *) self;
|
|
|
|
|
const entry_t *entry;
|
2024-06-11 20:06:04 -04:00
|
|
|
unsigned int value = 0;
|
2022-09-10 13:32:46 +02:00
|
|
|
|
|
|
|
|
if (section == NULL)
|
2023-05-11 03:02:36 -04:00
|
|
|
return def;
|
2022-09-10 13:32:46 +02:00
|
|
|
|
|
|
|
|
entry = find_entry(section, name);
|
|
|
|
|
if (entry == NULL)
|
2023-05-11 03:02:36 -04:00
|
|
|
return def;
|
2022-09-10 13:32:46 +02:00
|
|
|
|
|
|
|
|
sscanf(entry->data, "%05X", &value);
|
|
|
|
|
|
2023-05-11 03:02:36 -04:00
|
|
|
return value;
|
2022-09-10 13:32:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
2023-04-18 16:14:44 -03:00
|
|
|
ini_section_get_mac(ini_section_t self, const char *name, int def)
|
2022-09-10 13:32:46 +02:00
|
|
|
{
|
2023-07-20 18:58:26 -04:00
|
|
|
section_t *section = (section_t *) self;
|
|
|
|
|
const entry_t *entry;
|
|
|
|
|
unsigned int val0 = 0;
|
|
|
|
|
unsigned int val1 = 0;
|
|
|
|
|
unsigned int val2 = 0;
|
2022-09-10 13:32:46 +02:00
|
|
|
|
|
|
|
|
if (section == NULL)
|
2023-05-11 03:02:36 -04:00
|
|
|
return def;
|
2022-09-10 13:32:46 +02:00
|
|
|
|
|
|
|
|
entry = find_entry(section, name);
|
|
|
|
|
if (entry == NULL)
|
2023-05-11 03:02:36 -04:00
|
|
|
return def;
|
2022-09-10 13:32:46 +02:00
|
|
|
|
|
|
|
|
sscanf(entry->data, "%02x:%02x:%02x", &val0, &val1, &val2);
|
|
|
|
|
|
|
|
|
|
return ((val0 << 16) + (val1 << 8) + val2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
char *
|
2023-04-18 16:14:44 -03:00
|
|
|
ini_section_get_string(ini_section_t self, const char *name, char *def)
|
2022-09-10 13:32:46 +02:00
|
|
|
{
|
|
|
|
|
section_t *section = (section_t *) self;
|
|
|
|
|
entry_t *entry;
|
|
|
|
|
|
|
|
|
|
if (section == NULL)
|
2023-05-11 03:02:36 -04:00
|
|
|
return def;
|
2022-09-10 13:32:46 +02:00
|
|
|
|
|
|
|
|
entry = find_entry(section, name);
|
|
|
|
|
if (entry == NULL)
|
2023-05-11 03:02:36 -04:00
|
|
|
return def;
|
2022-09-10 13:32:46 +02:00
|
|
|
|
|
|
|
|
return (entry->data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
wchar_t *
|
2023-04-18 16:14:44 -03:00
|
|
|
ini_section_get_wstring(ini_section_t self, const char *name, wchar_t *def)
|
2022-09-10 13:32:46 +02:00
|
|
|
{
|
|
|
|
|
section_t *section = (section_t *) self;
|
|
|
|
|
entry_t *entry;
|
|
|
|
|
|
|
|
|
|
if (section == NULL)
|
2023-05-11 03:02:36 -04:00
|
|
|
return def;
|
2022-09-10 13:32:46 +02:00
|
|
|
|
|
|
|
|
entry = find_entry(section, name);
|
|
|
|
|
if (entry == NULL)
|
2023-05-11 03:02:36 -04:00
|
|
|
return def;
|
2022-09-10 13:32:46 +02:00
|
|
|
|
|
|
|
|
return (entry->wdata);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2023-04-18 16:14:44 -03:00
|
|
|
ini_section_set_int(ini_section_t self, const char *name, int val)
|
2022-09-10 13:32:46 +02:00
|
|
|
{
|
|
|
|
|
section_t *section = (section_t *) self;
|
|
|
|
|
entry_t *ent;
|
|
|
|
|
|
|
|
|
|
if (section == NULL)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
ent = find_entry(section, name);
|
|
|
|
|
if (ent == NULL)
|
|
|
|
|
ent = create_entry(section, name);
|
|
|
|
|
|
|
|
|
|
sprintf(ent->data, "%i", val);
|
|
|
|
|
mbstowcs(ent->wdata, ent->data, 512);
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-13 15:34:00 -04:00
|
|
|
void
|
|
|
|
|
ini_section_set_uint(ini_section_t self, const char *name, uint32_t val)
|
|
|
|
|
{
|
|
|
|
|
section_t *section = (section_t *) self;
|
|
|
|
|
entry_t *ent;
|
|
|
|
|
|
|
|
|
|
if (section == NULL)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
ent = find_entry(section, name);
|
|
|
|
|
if (ent == NULL)
|
|
|
|
|
ent = create_entry(section, name);
|
|
|
|
|
|
|
|
|
|
sprintf(ent->data, "%i", val);
|
|
|
|
|
mbstowcs(ent->wdata, ent->data, 512);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
|
void
|
|
|
|
|
ini_section_set_float(ini_section_t self, const char *name, float val)
|
|
|
|
|
{
|
|
|
|
|
section_t *section = (section_t *) self;
|
|
|
|
|
entry_t *ent;
|
|
|
|
|
|
|
|
|
|
if (section == NULL)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
ent = find_entry(section, name);
|
|
|
|
|
if (ent == NULL)
|
|
|
|
|
ent = create_entry(section, name);
|
|
|
|
|
|
|
|
|
|
sprintf(ent->data, "%g", val);
|
|
|
|
|
mbstowcs(ent->wdata, ent->data, 512);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
2022-09-10 13:32:46 +02:00
|
|
|
void
|
2023-04-18 16:14:44 -03:00
|
|
|
ini_section_set_double(ini_section_t self, const char *name, double val)
|
2022-09-10 13:32:46 +02:00
|
|
|
{
|
|
|
|
|
section_t *section = (section_t *) self;
|
|
|
|
|
entry_t *ent;
|
|
|
|
|
|
|
|
|
|
if (section == NULL)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
ent = find_entry(section, name);
|
|
|
|
|
if (ent == NULL)
|
|
|
|
|
ent = create_entry(section, name);
|
|
|
|
|
|
|
|
|
|
sprintf(ent->data, "%lg", val);
|
|
|
|
|
mbstowcs(ent->wdata, ent->data, 512);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2023-04-18 16:14:44 -03:00
|
|
|
ini_section_set_hex16(ini_section_t self, const char *name, int val)
|
2022-09-10 13:32:46 +02:00
|
|
|
{
|
|
|
|
|
section_t *section = (section_t *) self;
|
|
|
|
|
entry_t *ent;
|
|
|
|
|
|
|
|
|
|
if (section == NULL)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
ent = find_entry(section, name);
|
|
|
|
|
if (ent == NULL)
|
|
|
|
|
ent = create_entry(section, name);
|
|
|
|
|
|
|
|
|
|
sprintf(ent->data, "%04X", val);
|
|
|
|
|
mbstowcs(ent->wdata, ent->data, sizeof_w(ent->wdata));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2023-04-18 16:14:44 -03:00
|
|
|
ini_section_set_hex20(ini_section_t self, const char *name, int val)
|
2022-09-10 13:32:46 +02:00
|
|
|
{
|
|
|
|
|
section_t *section = (section_t *) self;
|
|
|
|
|
entry_t *ent;
|
|
|
|
|
|
|
|
|
|
if (section == NULL)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
ent = find_entry(section, name);
|
|
|
|
|
if (ent == NULL)
|
|
|
|
|
ent = create_entry(section, name);
|
|
|
|
|
|
|
|
|
|
sprintf(ent->data, "%05X", val);
|
|
|
|
|
mbstowcs(ent->wdata, ent->data, sizeof_w(ent->wdata));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2023-04-18 16:14:44 -03:00
|
|
|
ini_section_set_mac(ini_section_t self, const char *name, int val)
|
2022-09-10 13:32:46 +02:00
|
|
|
{
|
|
|
|
|
section_t *section = (section_t *) self;
|
|
|
|
|
entry_t *ent;
|
|
|
|
|
|
|
|
|
|
if (section == NULL)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
ent = find_entry(section, name);
|
|
|
|
|
if (ent == NULL)
|
|
|
|
|
ent = create_entry(section, name);
|
|
|
|
|
|
|
|
|
|
sprintf(ent->data, "%02x:%02x:%02x",
|
|
|
|
|
(val >> 16) & 0xff, (val >> 8) & 0xff, val & 0xff);
|
|
|
|
|
mbstowcs(ent->wdata, ent->data, 512);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2022-11-06 15:55:16 -05:00
|
|
|
ini_section_set_string(ini_section_t self, const char *name, const char *val)
|
2022-09-10 13:32:46 +02:00
|
|
|
{
|
|
|
|
|
section_t *section = (section_t *) self;
|
|
|
|
|
entry_t *ent;
|
|
|
|
|
|
|
|
|
|
if (section == NULL)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
ent = find_entry(section, name);
|
|
|
|
|
if (ent == NULL)
|
|
|
|
|
ent = create_entry(section, name);
|
|
|
|
|
|
|
|
|
|
if ((strlen(val) + 1) <= sizeof(ent->data))
|
|
|
|
|
memcpy(ent->data, val, strlen(val) + 1);
|
|
|
|
|
else
|
|
|
|
|
memcpy(ent->data, val, sizeof(ent->data));
|
|
|
|
|
#ifdef _WIN32 /* Make sure the string is converted from UTF-8 rather than a legacy codepage */
|
|
|
|
|
mbstoc16s(ent->wdata, ent->data, sizeof_w(ent->wdata));
|
|
|
|
|
#else
|
|
|
|
|
mbstowcs(ent->wdata, ent->data, sizeof_w(ent->wdata));
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2023-04-18 16:14:44 -03:00
|
|
|
ini_section_set_wstring(ini_section_t self, const char *name, wchar_t *val)
|
2022-09-10 13:32:46 +02:00
|
|
|
{
|
|
|
|
|
section_t *section = (section_t *) self;
|
|
|
|
|
entry_t *ent;
|
|
|
|
|
|
|
|
|
|
if (section == NULL)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
ent = find_entry(section, name);
|
|
|
|
|
if (ent == NULL)
|
|
|
|
|
ent = create_entry(section, name);
|
|
|
|
|
|
|
|
|
|
memcpy(ent->wdata, val, sizeof_w(ent->wdata));
|
|
|
|
|
#ifdef _WIN32 /* Make sure the string is converted to UTF-8 rather than a legacy codepage */
|
|
|
|
|
c16stombs(ent->data, ent->wdata, sizeof(ent->data));
|
|
|
|
|
#else
|
|
|
|
|
wcstombs(ent->data, ent->wdata, sizeof(ent->data));
|
|
|
|
|
#endif
|
|
|
|
|
}
|