mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-09 01:18:00 +00:00
f80955488a
The immediate usefulness of this is in pterm.exe: when the user uses -e to specify a command to run in the pterm, we retrieve the command in Unicode, store it in CONF_remote_cmd as UTF-8, and then in conpty.c we can extract it in the same form and convert it back to Unicode to pass losslessly to CreateProcessW. So now non-ACP Unicode works in that part of the pterm command line.
1053 lines
40 KiB
C
1053 lines
40 KiB
C
#define SUPERSEDE_FONTSPEC_FOR_TESTING
|
|
|
|
#include "putty.h"
|
|
#include "storage.h"
|
|
|
|
void modalfatalbox(const char *p, ...)
|
|
{
|
|
va_list ap;
|
|
fprintf(stderr, "FATAL ERROR: ");
|
|
va_start(ap, p);
|
|
vfprintf(stderr, p, ap);
|
|
va_end(ap);
|
|
fputc('\n', stderr);
|
|
exit(1);
|
|
}
|
|
|
|
char *platform_default_s(const char *name)
|
|
{ return NULL; }
|
|
bool platform_default_b(const char *name, bool def)
|
|
{ return def; }
|
|
int platform_default_i(const char *name, int def)
|
|
{ return def; }
|
|
FontSpec *platform_default_fontspec(const char *name)
|
|
{ return fontspec_new_default(); }
|
|
Filename *platform_default_filename(const char *name)
|
|
{ return filename_from_str(""); }
|
|
char *platform_get_x_display(void) { return NULL; }
|
|
|
|
void read_random_seed(noise_consumer_t consumer) {}
|
|
void write_random_seed(void *data, int len)
|
|
{ unreachable("no random seed in this application"); }
|
|
bool have_ssh_host_key(const char *hostname, int port,
|
|
const char *keytype) { return false; }
|
|
int check_stored_host_key(const char *hostname, int port,
|
|
const char *keytype, const char *key) { return 1; }
|
|
void store_host_key(Seat *seat, const char *hostname, int port,
|
|
const char *keytype, const char *key)
|
|
{ unreachable("no actual host keys in this application"); }
|
|
|
|
host_ca_enum *enum_host_ca_start(void) { return NULL; }
|
|
bool enum_host_ca_next(host_ca_enum *handle, strbuf *out) { return false; }
|
|
void enum_host_ca_finish(host_ca_enum *handle) {}
|
|
host_ca *host_ca_load(const char *name) { return NULL; }
|
|
|
|
void old_keyfile_warning(void) { }
|
|
|
|
const bool share_can_be_upstream = false;
|
|
const bool share_can_be_downstream = false;
|
|
|
|
struct FontSpec {
|
|
char *name;
|
|
};
|
|
|
|
FontSpec *fontspec_new(const char *name)
|
|
{
|
|
FontSpec *f = snew(FontSpec);
|
|
f->name = dupstr(name);
|
|
return f;
|
|
}
|
|
|
|
FontSpec *fontspec_new_default(void)
|
|
{
|
|
return fontspec_new("");
|
|
}
|
|
|
|
FontSpec *fontspec_copy(const FontSpec *f)
|
|
{
|
|
return fontspec_new(f->name);
|
|
}
|
|
|
|
void fontspec_free(FontSpec *f)
|
|
{
|
|
sfree(f->name);
|
|
sfree(f);
|
|
}
|
|
|
|
void fontspec_serialise(BinarySink *bs, FontSpec *f)
|
|
{
|
|
put_asciz(bs, f->name);
|
|
}
|
|
|
|
FontSpec *fontspec_deserialise(BinarySource *src)
|
|
{
|
|
return fontspec_new(get_asciz(src));
|
|
}
|
|
|
|
#define MAXKEY 16
|
|
|
|
typedef enum {
|
|
SAVE_UNSET, SAVE_S, SAVE_I, SAVE_FONTSPEC, SAVE_FILENAME
|
|
} SaveType;
|
|
|
|
typedef struct SaveItem {
|
|
const char *key;
|
|
SaveType type;
|
|
union {
|
|
char sval[4096];
|
|
int ival;
|
|
};
|
|
} SaveItem;
|
|
|
|
struct settings_w {
|
|
size_t n;
|
|
SaveItem si[MAXKEY];
|
|
};
|
|
|
|
settings_w *open_settings_w(const char *sessionname, char **errmsg)
|
|
{ return NULL; }
|
|
void close_settings_w(settings_w *sw)
|
|
{ unreachable("we don't open and close in this test program"); }
|
|
settings_r *open_settings_r(const char *sessionname)
|
|
{ return NULL; }
|
|
void close_settings_r(settings_r *sr) { }
|
|
|
|
/* Work around lack of true snprintf before VS2015 */
|
|
#if defined _WINDOWS && \
|
|
!defined __MINGW32__ && \
|
|
!defined __WINE__ && \
|
|
_MSC_VER < 1900
|
|
#define snprintf _snprintf
|
|
#endif
|
|
|
|
void write_setting_s(settings_w *sw, const char *key, const char *value)
|
|
{
|
|
for (size_t i = 0; i < sw->n; i++) {
|
|
if (!strcmp(key, sw->si[i].key)) {
|
|
sw->si[i].type = SAVE_S;
|
|
snprintf(sw->si[i].sval, sizeof(sw->si[i].sval), "%s", value);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void write_setting_i(settings_w *sw, const char *key, int value)
|
|
{
|
|
for (size_t i = 0; i < sw->n; i++) {
|
|
if (!strcmp(key, sw->si[i].key)) {
|
|
sw->si[i].type = SAVE_I;
|
|
sw->si[i].ival = value;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void write_setting_fontspec(settings_w *sw, const char *key, FontSpec *fs)
|
|
{
|
|
for (size_t i = 0; i < sw->n; i++) {
|
|
if (!strcmp(key, sw->si[i].key)) {
|
|
sw->si[i].type = SAVE_FONTSPEC;
|
|
snprintf(sw->si[i].sval, sizeof(sw->si[i].sval), "%s", fs->name);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void write_setting_filename(settings_w *sw, const char *key, Filename *fn)
|
|
{
|
|
for (size_t i = 0; i < sw->n; i++) {
|
|
if (!strcmp(key, sw->si[i].key)) {
|
|
sw->si[i].type = SAVE_FILENAME;
|
|
snprintf(sw->si[i].sval, sizeof(sw->si[i].sval), "%s",
|
|
filename_to_str(fn));
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
struct settings_r {
|
|
size_t n;
|
|
SaveItem si[MAXKEY];
|
|
};
|
|
|
|
char *read_setting_s(settings_r *sr, const char *key)
|
|
{
|
|
if (sr)
|
|
for (size_t i = 0; i < sr->n; i++)
|
|
if (!strcmp(key, sr->si[i].key) && sr->si[i].type == SAVE_S)
|
|
return dupstr(sr->si[i].sval);
|
|
return NULL;
|
|
}
|
|
|
|
int read_setting_i(settings_r *sr, const char *key, int defvalue)
|
|
{
|
|
if (sr)
|
|
for (size_t i = 0; i < sr->n; i++)
|
|
if (!strcmp(key, sr->si[i].key) && sr->si[i].type == SAVE_I)
|
|
return sr->si[i].ival;
|
|
return defvalue;
|
|
}
|
|
|
|
FontSpec *read_setting_fontspec(settings_r *sr, const char *key)
|
|
{
|
|
if (sr)
|
|
for (size_t i = 0; i < sr->n; i++)
|
|
if (!strcmp(key, sr->si[i].key) && sr->si[i].type == SAVE_FONTSPEC)
|
|
return fontspec_new(sr->si[i].sval);
|
|
return NULL;
|
|
}
|
|
|
|
Filename *read_setting_filename(settings_r *sr, const char *key)
|
|
{
|
|
if (sr)
|
|
for (size_t i = 0; i < sr->n; i++)
|
|
if (!strcmp(key, sr->si[i].key) && sr->si[i].type == SAVE_FILENAME)
|
|
return filename_from_str(sr->si[i].sval);
|
|
return NULL;
|
|
}
|
|
|
|
void del_settings(const char *sessionname) {}
|
|
|
|
settings_e *enum_settings_start(void)
|
|
{ return NULL; }
|
|
bool enum_settings_next(settings_e *handle, strbuf *out)
|
|
{ unreachable("where did you get a settings_e from?"); }
|
|
void enum_settings_finish(settings_e *handle)
|
|
{ unreachable("where did you get a settings_e from?"); }
|
|
|
|
static int nfails = 0;
|
|
|
|
void test_str_simple(int confid, const char *saveid, const char *defexp)
|
|
{
|
|
Conf *conf = conf_new();
|
|
|
|
do_defaults(NULL, conf);
|
|
const char *defgot = conf_get_str(conf, confid);
|
|
if (0 != strcmp(defgot, defexp)) {
|
|
printf("fail test_str_simple(%s): default = '%s', expected '%s'\n",
|
|
saveid, defgot, defexp);
|
|
nfails++;
|
|
}
|
|
|
|
for (int i = 0; i < 2; i++) {
|
|
settings_w sw = {
|
|
.n = 1,
|
|
.si[0].key = saveid,
|
|
.si[0].type = SAVE_UNSET,
|
|
};
|
|
static const char *const teststrings[] = { "foo", "bar" };
|
|
const char *teststring = teststrings[i];
|
|
conf_set_str(conf, confid, teststring);
|
|
save_open_settings(&sw, conf);
|
|
if (sw.si[0].type != SAVE_S) {
|
|
printf("fail test_str_simple(%s): saved type = %d, expected %d\n",
|
|
saveid, sw.si[0].type, SAVE_S);
|
|
nfails++;
|
|
} else if (0 != strcmp(sw.si[0].sval, teststring)) {
|
|
printf("fail test_str_simple(%s): "
|
|
"saved string = '%s', expected '%s'\n",
|
|
saveid, sw.si[0].sval, teststring);
|
|
nfails++;
|
|
}
|
|
|
|
conf_clear(conf);
|
|
settings_r sr = {
|
|
.n = 1,
|
|
.si[0].key = saveid,
|
|
.si[0].type = SAVE_S,
|
|
};
|
|
snprintf(sr.si[0].sval, sizeof(sr.si[0].sval), "%s", teststring);
|
|
load_open_settings(&sr, conf);
|
|
const char *loaded = conf_get_str(conf, confid);
|
|
if (0 != strcmp(loaded, teststring)) {
|
|
printf("fail test_str_simple(%s): "
|
|
"loaded string = '%s', expected '%s'\n",
|
|
saveid, loaded, teststring);
|
|
nfails++;
|
|
}
|
|
}
|
|
|
|
conf_free(conf);
|
|
}
|
|
|
|
void test_utf8_simple(int confid, const char *saveid, const char *defexp)
|
|
{
|
|
Conf *conf = conf_new();
|
|
|
|
do_defaults(NULL, conf);
|
|
const char *defgot = conf_get_utf8(conf, confid);
|
|
if (0 != strcmp(defgot, defexp)) {
|
|
printf("fail test_utf8_simple(%s): default = '%s', expected '%s'\n",
|
|
saveid, defgot, defexp);
|
|
nfails++;
|
|
}
|
|
|
|
for (int i = 0; i < 2; i++) {
|
|
settings_w sw = {
|
|
.n = 1,
|
|
.si[0].key = saveid,
|
|
.si[0].type = SAVE_UNSET,
|
|
};
|
|
static const char *const teststrings[] = { "foo", "bar" };
|
|
const char *teststring = teststrings[i];
|
|
conf_set_utf8(conf, confid, teststring);
|
|
save_open_settings(&sw, conf);
|
|
if (sw.si[0].type != SAVE_S) {
|
|
printf("fail test_utf8_simple(%s): saved type = %d, expected %d\n",
|
|
saveid, sw.si[0].type, SAVE_S);
|
|
nfails++;
|
|
} else if (0 != strcmp(sw.si[0].sval, teststring)) {
|
|
printf("fail test_utf8_simple(%s): "
|
|
"saved string = '%s', expected '%s'\n",
|
|
saveid, sw.si[0].sval, teststring);
|
|
nfails++;
|
|
}
|
|
|
|
conf_clear(conf);
|
|
settings_r sr = {
|
|
.n = 1,
|
|
.si[0].key = saveid,
|
|
.si[0].type = SAVE_S,
|
|
};
|
|
snprintf(sr.si[0].sval, sizeof(sr.si[0].sval), "%s", teststring);
|
|
load_open_settings(&sr, conf);
|
|
const char *loaded = conf_get_utf8(conf, confid);
|
|
if (0 != strcmp(loaded, teststring)) {
|
|
printf("fail test_utf8_simple(%s): "
|
|
"loaded string = '%s', expected '%s'\n",
|
|
saveid, loaded, teststring);
|
|
nfails++;
|
|
}
|
|
}
|
|
|
|
conf_free(conf);
|
|
}
|
|
|
|
void test_str_ambi_simple(int confid, const char *saveid,
|
|
const char *defexp, bool defutf8)
|
|
{
|
|
Conf *conf = conf_new();
|
|
bool utf8;
|
|
|
|
do_defaults(NULL, conf);
|
|
const char *defgot = conf_get_str_ambi(conf, confid, &utf8);
|
|
if (0 != strcmp(defgot, defexp) || utf8 != defutf8) {
|
|
printf("fail test_str_ambi_simple(%s): "
|
|
"default = '%s' (%s), expected '%s' (%s)\n",
|
|
saveid, defgot, utf8 ? "native" : "UTF-8",
|
|
defexp, defutf8 ? "native" : "UTF-8");
|
|
nfails++;
|
|
}
|
|
|
|
for (int i = 0; i < 2; i++) {
|
|
settings_w sw = {
|
|
.n = 1,
|
|
.si[0].key = saveid,
|
|
.si[0].type = SAVE_UNSET,
|
|
};
|
|
static const char *const teststrings[] = { "foo", "bar" };
|
|
const char *teststring = teststrings[i];
|
|
conf_set_str(conf, confid, teststring);
|
|
save_open_settings(&sw, conf);
|
|
if (sw.si[0].type != SAVE_S) {
|
|
printf("fail test_str_ambi_simple(%s): "
|
|
"saved type = %d, expected %d\n",
|
|
saveid, sw.si[0].type, SAVE_S);
|
|
nfails++;
|
|
} else if (0 != strcmp(sw.si[0].sval, teststring)) {
|
|
printf("fail test_str_ambi_simple(%s): "
|
|
"saved string = '%s', expected '%s'\n",
|
|
saveid, sw.si[0].sval, teststring);
|
|
nfails++;
|
|
}
|
|
|
|
conf_clear(conf);
|
|
settings_r sr = {
|
|
.n = 1,
|
|
.si[0].key = saveid,
|
|
.si[0].type = SAVE_S,
|
|
};
|
|
snprintf(sr.si[0].sval, sizeof(sr.si[0].sval), "%s", teststring);
|
|
load_open_settings(&sr, conf);
|
|
const char *loaded = conf_get_str_ambi(conf, confid, &utf8);
|
|
if (0 != strcmp(loaded, teststring) || utf8) {
|
|
printf("fail test_str_ambi_simple(%s): "
|
|
"loaded string = '%s' (%s), expected '%s' (native)\n",
|
|
saveid, loaded, utf8 ? "native" : "UTF-8", teststring);
|
|
nfails++;
|
|
}
|
|
}
|
|
|
|
conf_free(conf);
|
|
}
|
|
|
|
void test_int_simple(int confid, const char *saveid, int defexp)
|
|
{
|
|
Conf *conf = conf_new();
|
|
|
|
do_defaults(NULL, conf);
|
|
int defgot = conf_get_int(conf, confid);
|
|
if (defgot != defexp) {
|
|
printf("fail test_int_simple(%s): default = %d, expected %d\n",
|
|
saveid, defgot, defexp);
|
|
nfails++;
|
|
}
|
|
|
|
for (int i = 0; i < 2; i++) {
|
|
settings_w sw = {
|
|
.n = 1,
|
|
.si[0].key = saveid,
|
|
.si[0].type = SAVE_UNSET,
|
|
};
|
|
static const int testints[] = { 12345, 54321 };
|
|
int testint = testints[i];
|
|
conf_set_int(conf, confid, testint);
|
|
save_open_settings(&sw, conf);
|
|
if (sw.si[0].type != SAVE_I) {
|
|
printf("fail test_int_simple(%s): saved type = %d, expected %d\n",
|
|
saveid, sw.si[0].type, SAVE_I);
|
|
nfails++;
|
|
} else if (sw.si[0].ival != testint) {
|
|
printf("fail test_int_simple(%s): "
|
|
"saved integer = %d, expected %d\n",
|
|
saveid, sw.si[0].ival, testint);
|
|
nfails++;
|
|
}
|
|
|
|
conf_clear(conf);
|
|
settings_r sr = {
|
|
.n = 1,
|
|
.si[0].key = saveid,
|
|
.si[0].type = SAVE_I,
|
|
.si[0].ival = testint,
|
|
};
|
|
load_open_settings(&sr, conf);
|
|
int loaded = conf_get_int(conf, confid);
|
|
if (loaded != testint) {
|
|
printf("fail test_int_simple(%s): "
|
|
"loaded integer = %d, expected %d\n",
|
|
saveid, loaded, testint);
|
|
nfails++;
|
|
}
|
|
}
|
|
|
|
conf_free(conf);
|
|
}
|
|
|
|
void test_int_translated_internal(
|
|
int confid, const char *saveid, bool test_save, bool test_load,
|
|
void (*load_prepare)(settings_r *), int defexp, va_list ap)
|
|
{
|
|
Conf *conf = conf_new();
|
|
|
|
do_defaults(NULL, conf);
|
|
int defgot = conf_get_int(conf, confid);
|
|
if (defgot != defexp) {
|
|
printf("fail test_int_translated(%s): default = %d, expected %d\n",
|
|
saveid, defgot, defexp);
|
|
nfails++;
|
|
}
|
|
|
|
int confval = va_arg(ap, int);
|
|
while (confval != -1) {
|
|
int storageval = va_arg(ap, int);
|
|
|
|
if (test_save) {
|
|
settings_w sw = {
|
|
.n = 1,
|
|
.si[0].key = saveid,
|
|
.si[0].type = SAVE_UNSET,
|
|
};
|
|
conf_set_int(conf, confid, confval);
|
|
save_open_settings(&sw, conf);
|
|
if (sw.si[0].type != SAVE_I) {
|
|
printf("fail test_int_translated(%s): "
|
|
"saved type = %d, expected %d\n",
|
|
saveid, sw.si[0].type, SAVE_I);
|
|
nfails++;
|
|
} else if (sw.si[0].ival != storageval) {
|
|
printf("fail test_int_translated(%s.%d.%d): "
|
|
"saved integer = %d, expected %d\n",
|
|
saveid, confval, storageval, sw.si[0].ival, storageval);
|
|
nfails++;
|
|
}
|
|
}
|
|
|
|
if (test_load) {
|
|
conf_clear(conf);
|
|
settings_r sr = {
|
|
.n = 1,
|
|
.si[0].key = saveid,
|
|
.si[0].type = SAVE_I,
|
|
.si[0].ival = storageval,
|
|
};
|
|
if (load_prepare)
|
|
load_prepare(&sr);
|
|
load_open_settings(&sr, conf);
|
|
int loaded = conf_get_int(conf, confid);
|
|
if (loaded != confval) {
|
|
printf("fail test_int_translated(%s.%d.%d): "
|
|
"loaded integer = %d, expected %d\n",
|
|
saveid, confval, storageval, loaded, confval);
|
|
nfails++;
|
|
}
|
|
}
|
|
|
|
confval = va_arg(ap, int);
|
|
}
|
|
|
|
conf_free(conf);
|
|
}
|
|
|
|
void test_int_translated(int confid, const char *saveid, int defexp, ...)
|
|
{
|
|
va_list ap;
|
|
va_start(ap, defexp);
|
|
test_int_translated_internal(confid, saveid, true, true, NULL, defexp, ap);
|
|
va_end(ap);
|
|
}
|
|
|
|
void test_int_translated_load_legacy(
|
|
int confid, const char *saveid, void (*load_prepare)(settings_r *),
|
|
int defexp, ...)
|
|
{
|
|
va_list ap;
|
|
va_start(ap, defexp);
|
|
test_int_translated_internal(confid, saveid, false, true, load_prepare,
|
|
defexp, ap);
|
|
va_end(ap);
|
|
}
|
|
|
|
void test_bool_simple(int confid, const char *saveid, bool defexp)
|
|
{
|
|
Conf *conf = conf_new();
|
|
|
|
do_defaults(NULL, conf);
|
|
bool defgot = conf_get_bool(conf, confid);
|
|
if (defgot != defexp) {
|
|
printf("fail test_bool_simple(%s): default = %d, expected %d\n",
|
|
saveid, defgot, defexp);
|
|
nfails++;
|
|
}
|
|
|
|
for (int i = 0; i < 2; i++) {
|
|
settings_w sw = {
|
|
.n = 1,
|
|
.si[0].key = saveid,
|
|
.si[0].type = SAVE_UNSET,
|
|
};
|
|
static const bool testbools[] = { false, true };
|
|
bool testbool = testbools[i];
|
|
conf_set_bool(conf, confid, testbool);
|
|
save_open_settings(&sw, conf);
|
|
if (sw.si[0].type != SAVE_I) {
|
|
printf("fail test_bool_simple(%s): saved type = %d, expected %d\n",
|
|
saveid, sw.si[0].type, SAVE_I);
|
|
nfails++;
|
|
} else if (sw.si[0].ival != testbool) {
|
|
printf("fail test_bool_simple(%s): "
|
|
"saved integer = %d, expected %d\n",
|
|
saveid, sw.si[0].ival, testbool);
|
|
nfails++;
|
|
}
|
|
|
|
conf_clear(conf);
|
|
settings_r sr = {
|
|
.n = 1,
|
|
.si[0].key = saveid,
|
|
.si[0].type = SAVE_I,
|
|
.si[0].ival = testbool,
|
|
};
|
|
load_open_settings(&sr, conf);
|
|
bool loaded = conf_get_bool(conf, confid);
|
|
if (loaded != testbool) {
|
|
printf("fail test_bool_simple(%s): "
|
|
"loaded boolean = %d, expected %d\n",
|
|
saveid, loaded, testbool);
|
|
nfails++;
|
|
}
|
|
}
|
|
|
|
conf_free(conf);
|
|
}
|
|
|
|
void test_file_simple(int confid, const char *saveid)
|
|
{
|
|
Conf *conf = conf_new();
|
|
|
|
do_defaults(NULL, conf);
|
|
|
|
for (int i = 0; i < 2; i++) {
|
|
settings_w sw = {
|
|
.n = 1,
|
|
.si[0].key = saveid,
|
|
.si[0].type = SAVE_UNSET,
|
|
};
|
|
static const char *const teststrings[] = { "foo", "bar" };
|
|
const char *teststring = teststrings[i];
|
|
Filename *testfn = filename_from_str(teststring);
|
|
conf_set_filename(conf, confid, testfn);
|
|
filename_free(testfn);
|
|
save_open_settings(&sw, conf);
|
|
if (sw.si[0].type != SAVE_FILENAME) {
|
|
printf("fail test_file_simple(%s): saved type = %d, expected %d\n",
|
|
saveid, sw.si[0].type, SAVE_FILENAME);
|
|
nfails++;
|
|
} else if (0 != strcmp(sw.si[0].sval, teststring)) {
|
|
printf("fail test_file_simple(%s): "
|
|
"saved string = '%s', expected '%s'\n",
|
|
saveid, sw.si[0].sval, teststring);
|
|
nfails++;
|
|
}
|
|
|
|
conf_clear(conf);
|
|
settings_r sr = {
|
|
.n = 1,
|
|
.si[0].key = saveid,
|
|
.si[0].type = SAVE_FILENAME,
|
|
};
|
|
snprintf(sr.si[0].sval, sizeof(sr.si[0].sval), "%s", teststring);
|
|
load_open_settings(&sr, conf);
|
|
const char *loaded = filename_to_str(conf_get_filename(conf, confid));
|
|
if (0 != strcmp(loaded, teststring)) {
|
|
printf("fail test_file_simple(%s): "
|
|
"loaded string = '%s', expected '%s'\n",
|
|
saveid, loaded, teststring);
|
|
nfails++;
|
|
}
|
|
}
|
|
|
|
conf_free(conf);
|
|
}
|
|
|
|
void test_font_simple(int confid, const char *saveid)
|
|
{
|
|
Conf *conf = conf_new();
|
|
|
|
do_defaults(NULL, conf);
|
|
|
|
for (int i = 0; i < 2; i++) {
|
|
settings_w sw = {
|
|
.n = 1,
|
|
.si[0].key = saveid,
|
|
.si[0].type = SAVE_UNSET,
|
|
};
|
|
static const char *const teststrings[] = { "foo", "bar" };
|
|
const char *teststring = teststrings[i];
|
|
FontSpec *testfs = fontspec_new(teststring);
|
|
conf_set_fontspec(conf, confid, testfs);
|
|
fontspec_free(testfs);
|
|
save_open_settings(&sw, conf);
|
|
if (sw.si[0].type != SAVE_FONTSPEC) {
|
|
printf("fail test_font_simple(%s): saved type = %d, expected %d\n",
|
|
saveid, sw.si[0].type, SAVE_FONTSPEC);
|
|
nfails++;
|
|
} else if (0 != strcmp(sw.si[0].sval, teststring)) {
|
|
printf("fail test_font_simple(%s): "
|
|
"saved string = '%s', expected '%s'\n",
|
|
saveid, sw.si[0].sval, teststring);
|
|
nfails++;
|
|
}
|
|
|
|
conf_clear(conf);
|
|
settings_r sr = {
|
|
.n = 1,
|
|
.si[0].key = saveid,
|
|
.si[0].type = SAVE_FONTSPEC,
|
|
};
|
|
snprintf(sr.si[0].sval, sizeof(sr.si[0].sval), "%s", teststring);
|
|
load_open_settings(&sr, conf);
|
|
const char *loaded = conf_get_fontspec(conf, confid)->name;
|
|
if (0 != strcmp(loaded, teststring)) {
|
|
printf("fail test_file_simple(%s): "
|
|
"loaded string = '%s', expected '%s'\n",
|
|
saveid, loaded, teststring);
|
|
nfails++;
|
|
}
|
|
}
|
|
|
|
conf_free(conf);
|
|
}
|
|
|
|
static void load_prepare_socks4(settings_r *sr)
|
|
{
|
|
size_t pos = sr->n++;
|
|
sr->si[pos].key = "ProxySOCKSVersion";
|
|
sr->si[pos].type = SAVE_I;
|
|
sr->si[pos].ival = 4;
|
|
}
|
|
|
|
void test_simple(void)
|
|
{
|
|
test_str_simple(CONF_host, "HostName", "");
|
|
test_int_translated(CONF_addressfamily, "AddressFamily", ADDRTYPE_UNSPEC,
|
|
ADDRTYPE_UNSPEC, 0, ADDRTYPE_IPV4, 1,
|
|
ADDRTYPE_IPV6, 2, -1);
|
|
test_bool_simple(CONF_warn_on_close, "WarnOnClose", true);
|
|
test_bool_simple(CONF_tcp_nodelay, "TCPNoDelay", true);
|
|
test_bool_simple(CONF_tcp_keepalives, "TCPKeepalives", false);
|
|
test_str_simple(CONF_loghost, "LogHost", "");
|
|
test_str_simple(CONF_proxy_exclude_list, "ProxyExcludeList", "");
|
|
test_bool_simple(CONF_even_proxy_localhost, "ProxyLocalhost", false);
|
|
test_str_simple(CONF_proxy_host, "ProxyHost", "proxy");
|
|
test_int_simple(CONF_proxy_port, "ProxyPort", 80);
|
|
test_str_simple(CONF_proxy_username, "ProxyUsername", "");
|
|
test_str_simple(CONF_proxy_password, "ProxyPassword", "");
|
|
test_str_simple(CONF_proxy_telnet_command, "ProxyTelnetCommand", "connect %host %port\\n");
|
|
test_int_translated(CONF_proxy_log_to_term, "ProxyLogToTerm", FORCE_OFF,
|
|
FORCE_ON, 0, FORCE_OFF, 1, AUTO, 2, -1);
|
|
test_str_ambi_simple(CONF_remote_cmd, "RemoteCommand", "", false);
|
|
test_bool_simple(CONF_nopty, "NoPTY", false);
|
|
test_bool_simple(CONF_compression, "Compression", false);
|
|
test_bool_simple(CONF_ssh_prefer_known_hostkeys, "PreferKnownHostKeys", true);
|
|
test_int_simple(CONF_ssh_rekey_time, "RekeyTime", 60);
|
|
test_str_simple(CONF_ssh_rekey_data, "RekeyBytes", "1G");
|
|
test_bool_simple(CONF_tryagent, "TryAgent", true);
|
|
test_bool_simple(CONF_agentfwd, "AgentFwd", false);
|
|
test_bool_simple(CONF_change_username, "ChangeUsername", false);
|
|
test_file_simple(CONF_keyfile, "PublicKeyFile");
|
|
test_file_simple(CONF_detached_cert, "DetachedCertificate");
|
|
test_str_simple(CONF_auth_plugin, "AuthPlugin", "");
|
|
test_bool_simple(CONF_ssh2_des_cbc, "SSH2DES", false);
|
|
test_bool_simple(CONF_ssh_no_userauth, "SshNoAuth", false);
|
|
test_bool_simple(CONF_ssh_no_trivial_userauth, "SshNoTrivialAuth", false);
|
|
test_bool_simple(CONF_ssh_show_banner, "SshBanner", true);
|
|
test_bool_simple(CONF_try_tis_auth, "AuthTIS", false);
|
|
test_bool_simple(CONF_try_ki_auth, "AuthKI", true);
|
|
test_bool_simple(CONF_ssh_no_shell, "SshNoShell", false);
|
|
test_str_simple(CONF_termtype, "TerminalType", "xterm");
|
|
test_str_simple(CONF_termspeed, "TerminalSpeed", "38400,38400");
|
|
test_str_ambi_simple(CONF_username, "UserName", "", false);
|
|
test_bool_simple(CONF_username_from_env, "UserNameFromEnvironment", false);
|
|
test_str_simple(CONF_localusername, "LocalUserName", "");
|
|
test_bool_simple(CONF_rfc_environ, "RFCEnviron", false);
|
|
test_bool_simple(CONF_passive_telnet, "PassiveTelnet", false);
|
|
test_str_simple(CONF_serline, "SerialLine", "");
|
|
test_int_simple(CONF_serspeed, "SerialSpeed", 9600);
|
|
test_int_simple(CONF_serdatabits, "SerialDataBits", 8);
|
|
test_int_simple(CONF_serstopbits, "SerialStopHalfbits", 2);
|
|
test_int_translated(CONF_serparity, "SerialParity", SER_PAR_NONE,
|
|
SER_PAR_NONE, 0, SER_PAR_ODD, 1, SER_PAR_EVEN, 2,
|
|
SER_PAR_MARK, 3, SER_PAR_SPACE, 4, -1);
|
|
test_int_translated(CONF_serflow, "SerialFlowControl", SER_FLOW_XONXOFF,
|
|
SER_FLOW_NONE, 0, SER_FLOW_XONXOFF, 1,
|
|
SER_FLOW_RTSCTS, 2, SER_FLOW_DSRDTR, 3, -1);
|
|
test_str_simple(CONF_supdup_location, "SUPDUPLocation", "The Internet");
|
|
test_int_translated(CONF_supdup_ascii_set, "SUPDUPCharset",
|
|
SUPDUP_CHARSET_ASCII,
|
|
SUPDUP_CHARSET_ASCII, 0,
|
|
SUPDUP_CHARSET_ITS, 1,
|
|
SUPDUP_CHARSET_WAITS, 2, -1);
|
|
test_bool_simple(CONF_supdup_more, "SUPDUPMoreProcessing", false);
|
|
test_bool_simple(CONF_supdup_scroll, "SUPDUPScrolling", false);
|
|
test_bool_simple(CONF_bksp_is_delete, "BackspaceIsDelete", true);
|
|
test_bool_simple(CONF_rxvt_homeend, "RXVTHomeEnd", false);
|
|
test_int_translated(CONF_funky_type, "LinuxFunctionKeys", FUNKY_TILDE,
|
|
FUNKY_TILDE, 0, FUNKY_LINUX, 1, FUNKY_XTERM, 2,
|
|
FUNKY_VT400, 3, FUNKY_VT100P, 4, FUNKY_SCO, 5,
|
|
FUNKY_XTERM_216, 6, -1);
|
|
test_int_translated(CONF_sharrow_type, "ShiftedArrowKeys",
|
|
SHARROW_APPLICATION,
|
|
SHARROW_APPLICATION, 0, SHARROW_BITMAP, 1, -1);
|
|
test_bool_simple(CONF_no_applic_c, "NoApplicationCursors", false);
|
|
test_bool_simple(CONF_no_applic_k, "NoApplicationKeys", false);
|
|
test_bool_simple(CONF_no_mouse_rep, "NoMouseReporting", false);
|
|
test_bool_simple(CONF_no_remote_resize, "NoRemoteResize", false);
|
|
test_bool_simple(CONF_no_alt_screen, "NoAltScreen", false);
|
|
test_bool_simple(CONF_no_remote_wintitle, "NoRemoteWinTitle", false);
|
|
test_bool_simple(CONF_no_remote_clearscroll, "NoRemoteClearScroll", false);
|
|
test_bool_simple(CONF_no_dbackspace, "NoDBackspace", false);
|
|
test_bool_simple(CONF_no_remote_charset, "NoRemoteCharset", false);
|
|
/* note we have no test for CONF_remote_qtitle_action because no default */
|
|
test_bool_simple(CONF_app_cursor, "ApplicationCursorKeys", false);
|
|
test_bool_simple(CONF_app_keypad, "ApplicationKeypad", false);
|
|
test_bool_simple(CONF_nethack_keypad, "NetHackKeypad", false);
|
|
test_bool_simple(CONF_telnet_keyboard, "TelnetKey", false);
|
|
test_bool_simple(CONF_telnet_newline, "TelnetRet", true);
|
|
test_bool_simple(CONF_alt_f4, "AltF4", true);
|
|
test_bool_simple(CONF_alt_space, "AltSpace", false);
|
|
test_bool_simple(CONF_alt_only, "AltOnly", false);
|
|
test_int_translated(CONF_localecho, "LocalEcho", AUTO,
|
|
FORCE_ON, 0, FORCE_OFF, 1, AUTO, 2, -1);
|
|
test_int_translated(CONF_localedit, "LocalEdit", AUTO,
|
|
FORCE_ON, 0, FORCE_OFF, 1, AUTO, 2, -1);
|
|
test_bool_simple(CONF_alwaysontop, "AlwaysOnTop", false);
|
|
test_bool_simple(CONF_fullscreenonaltenter, "FullScreenOnAltEnter", false);
|
|
test_bool_simple(CONF_scroll_on_key, "ScrollOnKey", false);
|
|
test_bool_simple(CONF_scroll_on_disp, "ScrollOnDisp", true);
|
|
test_bool_simple(CONF_erase_to_scrollback, "EraseToScrollback", true);
|
|
test_bool_simple(CONF_compose_key, "ComposeKey", false);
|
|
test_bool_simple(CONF_ctrlaltkeys, "CtrlAltKeys", true);
|
|
test_str_simple(CONF_wintitle, "WinTitle", "");
|
|
test_int_simple(CONF_savelines, "ScrollbackLines", 2000);
|
|
test_bool_simple(CONF_dec_om, "DECOriginMode", false);
|
|
test_bool_simple(CONF_wrap_mode, "AutoWrapMode", true);
|
|
test_bool_simple(CONF_lfhascr, "LFImpliesCR", false);
|
|
test_int_translated(CONF_cursor_type, "CurType", CURSOR_BLOCK,
|
|
CURSOR_BLOCK, 0, CURSOR_UNDERLINE, 1,
|
|
CURSOR_VERTICAL_LINE, 2, -1);
|
|
test_bool_simple(CONF_blink_cur, "BlinkCur", false);
|
|
test_int_translated(CONF_beep, "Beep", 1,
|
|
BELL_DISABLED, 0, BELL_DEFAULT, 1, BELL_VISUAL, 2,
|
|
BELL_WAVEFILE, 3, BELL_PCSPEAKER, 4, -1);
|
|
test_int_translated(CONF_beep_ind, "BeepInd", 0,
|
|
B_IND_DISABLED, 0, B_IND_FLASH, 1, B_IND_STEADY, 2, -1);
|
|
test_bool_simple(CONF_bellovl, "BellOverload", true);
|
|
test_int_simple(CONF_bellovl_n, "BellOverloadN", 5);
|
|
test_file_simple(CONF_bell_wavefile, "BellWaveFile");
|
|
test_bool_simple(CONF_scrollbar, "ScrollBar", true);
|
|
test_bool_simple(CONF_scrollbar_in_fullscreen, "ScrollBarFullScreen", false);
|
|
test_int_translated(CONF_resize_action, "LockSize", RESIZE_TERM,
|
|
RESIZE_TERM, 0, RESIZE_DISABLED, 1, RESIZE_FONT, 2,
|
|
RESIZE_EITHER, 3, -1);
|
|
test_bool_simple(CONF_bce, "BCE", true);
|
|
test_bool_simple(CONF_blinktext, "BlinkText", false);
|
|
test_bool_simple(CONF_win_name_always, "WinNameAlways", true);
|
|
test_int_simple(CONF_width, "TermWidth", 80);
|
|
test_int_simple(CONF_height, "TermHeight", 24);
|
|
test_font_simple(CONF_font, "Font");
|
|
test_int_translated(CONF_font_quality, "FontQuality", FQ_DEFAULT,
|
|
FQ_DEFAULT, 0, FQ_ANTIALIASED, 1, FQ_NONANTIALIASED, 2,
|
|
FQ_CLEARTYPE, 3, -1);
|
|
test_file_simple(CONF_logfilename, "LogFileName");
|
|
test_int_translated(CONF_logtype, "LogType", LGTYP_NONE,
|
|
LGTYP_NONE, 0, LGTYP_ASCII, 1, LGTYP_DEBUG, 2,
|
|
LGTYP_PACKETS, 3, LGTYP_SSHRAW, 4, -1);
|
|
/* FIXME: this won't work because -1 is also the terminator, darn */
|
|
test_int_translated(CONF_logxfovr, "LogFileClash", LGXF_ASK,
|
|
LGXF_OVR, 1, LGXF_APN, 0, LGXF_ASK, -1, -1);
|
|
test_bool_simple(CONF_logflush, "LogFlush", true);
|
|
test_bool_simple(CONF_logheader, "LogHeader", true);
|
|
test_bool_simple(CONF_logomitpass, "SSHLogOmitPasswords", true);
|
|
test_bool_simple(CONF_logomitdata, "SSHLogOmitData", false);
|
|
test_bool_simple(CONF_hide_mouseptr, "HideMousePtr", false);
|
|
test_bool_simple(CONF_sunken_edge, "SunkenEdge", false);
|
|
test_int_simple(CONF_window_border, "WindowBorder", 1);
|
|
test_str_simple(CONF_answerback, "Answerback", "PuTTY");
|
|
test_str_simple(CONF_printer, "Printer", "");
|
|
test_bool_simple(CONF_no_arabicshaping, "DisableArabicShaping", false);
|
|
test_bool_simple(CONF_no_bidi, "DisableBidi", false);
|
|
test_bool_simple(CONF_ansi_colour, "ANSIColour", true);
|
|
test_bool_simple(CONF_xterm_256_colour, "Xterm256Colour", true);
|
|
test_bool_simple(CONF_true_colour, "TrueColour", true);
|
|
test_bool_simple(CONF_system_colour, "UseSystemColours", false);
|
|
test_bool_simple(CONF_try_palette, "TryPalette", false);
|
|
test_int_translated(CONF_mouse_is_xterm, "MouseIsXterm", 0,
|
|
MOUSE_COMPROMISE, 0, MOUSE_XTERM, 1,
|
|
MOUSE_WINDOWS, 2, -1);
|
|
test_bool_simple(CONF_rect_select, "RectSelect", false);
|
|
test_bool_simple(CONF_paste_controls, "PasteControls", false);
|
|
test_bool_simple(CONF_rawcnp, "RawCNP", false);
|
|
test_bool_simple(CONF_utf8linedraw, "UTF8linedraw", false);
|
|
test_bool_simple(CONF_rtf_paste, "PasteRTF", false);
|
|
test_bool_simple(CONF_mouse_override, "MouseOverride", true);
|
|
test_bool_simple(CONF_mouseautocopy, "MouseAutocopy", CLIPUI_DEFAULT_AUTOCOPY);
|
|
test_int_translated(CONF_vtmode, "FontVTMode", VT_UNICODE,
|
|
VT_XWINDOWS, 0,
|
|
VT_OEMANSI, 1,
|
|
VT_OEMONLY, 2,
|
|
VT_POORMAN, 3,
|
|
VT_UNICODE, 4,
|
|
-1);
|
|
test_str_simple(CONF_line_codepage, "LineCodePage", "");
|
|
test_bool_simple(CONF_cjk_ambig_wide, "CJKAmbigWide", false);
|
|
test_bool_simple(CONF_utf8_override, "UTF8Override", true);
|
|
test_bool_simple(CONF_xlat_capslockcyr, "CapsLockCyr", false);
|
|
test_bool_simple(CONF_x11_forward, "X11Forward", false);
|
|
test_str_simple(CONF_x11_display, "X11Display", "");
|
|
test_int_translated(CONF_x11_auth, "X11AuthType", X11_MIT,
|
|
X11_NO_AUTH, 0, X11_MIT, 1, X11_XDM, 2, -1);
|
|
test_file_simple(CONF_xauthfile, "X11AuthFile");
|
|
test_bool_simple(CONF_lport_acceptall, "LocalPortAcceptAll", false);
|
|
test_bool_simple(CONF_rport_acceptall, "RemotePortAcceptAll", false);
|
|
test_bool_simple(CONF_ssh_connection_sharing, "ConnectionSharing", false);
|
|
test_bool_simple(CONF_ssh_connection_sharing_upstream, "ConnectionSharingUpstream", true);
|
|
test_bool_simple(CONF_ssh_connection_sharing_downstream, "ConnectionSharingDownstream", true);
|
|
test_bool_simple(CONF_stamp_utmp, "StampUtmp", true);
|
|
test_bool_simple(CONF_login_shell, "LoginShell", true);
|
|
test_bool_simple(CONF_scrollbar_on_left, "ScrollbarOnLeft", false);
|
|
test_bool_simple(CONF_shadowbold, "ShadowBold", false);
|
|
test_font_simple(CONF_boldfont, "BoldFont");
|
|
test_font_simple(CONF_widefont, "WideFont");
|
|
test_font_simple(CONF_wideboldfont, "WideBoldFont");
|
|
test_int_simple(CONF_shadowboldoffset, "ShadowBoldOffset", 1);
|
|
test_bool_simple(CONF_crhaslf, "CRImpliesLF", false);
|
|
test_str_simple(CONF_winclass, "WindowClass", "");
|
|
test_int_translated(CONF_close_on_exit, "CloseOnExit", AUTO,
|
|
FORCE_OFF, 0, AUTO, 1, FORCE_ON, 2, -1);
|
|
test_int_translated(CONF_proxy_dns, "ProxyDNS", AUTO,
|
|
FORCE_OFF, 0, AUTO, 1, FORCE_ON, 2, -1);
|
|
test_int_translated(CONF_bold_style, "BoldAsColour", AUTO,
|
|
1, 0, 2, 1, 3, 2, -1);
|
|
test_int_translated(CONF_sshbug_ignore1, "BugIgnore1", AUTO,
|
|
AUTO, 0, FORCE_OFF, 1, FORCE_ON, 2, -1);
|
|
test_int_translated(CONF_sshbug_plainpw1, "BugPlainPW1", AUTO,
|
|
AUTO, 0, FORCE_OFF, 1, FORCE_ON, 2, -1);
|
|
test_int_translated(CONF_sshbug_rsa1, "BugRSA1", AUTO,
|
|
AUTO, 0, FORCE_OFF, 1, FORCE_ON, 2, -1);
|
|
test_int_translated(CONF_sshbug_ignore2, "BugIgnore2", AUTO,
|
|
AUTO, 0, FORCE_OFF, 1, FORCE_ON, 2, -1);
|
|
test_int_translated(CONF_sshbug_derivekey2, "BugDeriveKey2", AUTO,
|
|
AUTO, 0, FORCE_OFF, 1, FORCE_ON, 2, -1);
|
|
test_int_translated(CONF_sshbug_rsapad2, "BugRSAPad2", AUTO,
|
|
AUTO, 0, FORCE_OFF, 1, FORCE_ON, 2, -1);
|
|
test_int_translated(CONF_sshbug_pksessid2, "BugPKSessID2", AUTO,
|
|
AUTO, 0, FORCE_OFF, 1, FORCE_ON, 2, -1);
|
|
test_int_translated(CONF_sshbug_rekey2, "BugRekey2", AUTO,
|
|
AUTO, 0, FORCE_OFF, 1, FORCE_ON, 2, -1);
|
|
test_int_translated(CONF_sshbug_maxpkt2, "BugMaxPkt2", AUTO,
|
|
AUTO, 0, FORCE_OFF, 1, FORCE_ON, 2, -1);
|
|
test_int_translated(CONF_sshbug_oldgex2, "BugOldGex2", AUTO,
|
|
AUTO, 0, FORCE_OFF, 1, FORCE_ON, 2, -1);
|
|
test_int_translated(CONF_sshbug_winadj, "BugWinadj", AUTO,
|
|
AUTO, 0, FORCE_OFF, 1, FORCE_ON, 2, -1);
|
|
test_int_translated(CONF_sshbug_chanreq, "BugChanReq", AUTO,
|
|
AUTO, 0, FORCE_OFF, 1, FORCE_ON, 2, -1);
|
|
test_int_translated(CONF_sshbug_dropstart, "BugDropStart", FORCE_OFF,
|
|
FORCE_OFF, 1, FORCE_ON, 2, -1);
|
|
test_int_translated(CONF_sshbug_filter_kexinit, "BugFilterKexinit", FORCE_OFF,
|
|
FORCE_OFF, 1, FORCE_ON, 2, -1);
|
|
test_int_translated(CONF_sshbug_rsa_sha2_cert_userauth, "BugRSASHA2CertUserauth", AUTO,
|
|
AUTO, 0, FORCE_OFF, 1, FORCE_ON, 2, -1);
|
|
test_int_translated(CONF_proxy_type, "ProxyMethod", PROXY_NONE,
|
|
PROXY_NONE, 0, PROXY_SOCKS4, 1, PROXY_SOCKS5, 2,
|
|
PROXY_HTTP, 3, PROXY_TELNET, 4, PROXY_CMD, 5,
|
|
PROXY_SSH_TCPIP, 6, PROXY_SSH_EXEC, 7,
|
|
PROXY_SSH_SUBSYSTEM, 8, -1);
|
|
test_int_translated_load_legacy(
|
|
CONF_proxy_type, "ProxyType", NULL, PROXY_NONE,
|
|
PROXY_HTTP, 1, PROXY_SOCKS5, 2, PROXY_TELNET, 3, PROXY_CMD, 4, -1);
|
|
test_int_translated_load_legacy(
|
|
CONF_proxy_type, "ProxyType", load_prepare_socks4, PROXY_NONE,
|
|
PROXY_HTTP, 1, PROXY_SOCKS4, 2, PROXY_TELNET, 3, PROXY_CMD, 4, -1);
|
|
test_int_translated(CONF_remote_qtitle_action, "RemoteQTitleAction", TITLE_EMPTY,
|
|
TITLE_NONE, 0, TITLE_EMPTY, 1, TITLE_REAL, 2, -1);
|
|
test_int_translated_load_legacy(
|
|
CONF_remote_qtitle_action, "NoRemoteQTitle", NULL, TITLE_EMPTY,
|
|
TITLE_REAL, 0, TITLE_EMPTY, 1, -1);
|
|
}
|
|
|
|
void test_conf_key_info(void)
|
|
{
|
|
struct test_data {
|
|
const char *name;
|
|
bool got_value_type : 1;
|
|
bool got_subkey_type : 1;
|
|
bool got_default : 1;
|
|
bool got_default_int : 1;
|
|
bool got_default_str : 1;
|
|
bool got_default_bool : 1;
|
|
bool got_save_keyword : 1;
|
|
bool got_storage_enum : 1;
|
|
bool save_custom : 1;
|
|
bool load_custom : 1;
|
|
bool not_saved : 1;
|
|
};
|
|
|
|
#define CONF_OPTION(id, ...) { .name = "CONF_" #id, __VA_ARGS__ },
|
|
#define VALUE_TYPE(x) .got_value_type = true
|
|
#define SUBKEY_TYPE(x) .got_subkey_type = true
|
|
#define DEFAULT_INT(x) .got_default_int = true, .got_default = true
|
|
#define DEFAULT_STR(x) .got_default_str = true, .got_default = true
|
|
#define DEFAULT_BOOL(x) .got_default_bool = true, .got_default = true
|
|
#define SAVE_KEYWORD(x) .got_save_keyword = true
|
|
#define STORAGE_ENUM(x) .got_storage_enum = true
|
|
#define SAVE_CUSTOM .save_custom = true
|
|
#define LOAD_CUSTOM .load_custom = true
|
|
#define NOT_SAVED .not_saved = true
|
|
|
|
static const struct test_data conf_key_test_data[] = {
|
|
#include "conf.h"
|
|
};
|
|
|
|
for (size_t key = 0; key < N_CONFIG_OPTIONS; key++) {
|
|
const ConfKeyInfo *info = &conf_key_info[key];
|
|
const struct test_data *td = &conf_key_test_data[key];
|
|
|
|
if (!td->got_value_type) {
|
|
fprintf(stderr, "%s: no value type\n", td->name);
|
|
nfails++;
|
|
}
|
|
|
|
if (td->got_default && info->subkey_type != CONF_TYPE_NONE) {
|
|
fprintf(stderr, "%s: is a mapping but has a default\n", td->name);
|
|
nfails++;
|
|
}
|
|
|
|
if ((td->got_default_int && info->value_type != CONF_TYPE_INT) ||
|
|
(td->got_default_str &&
|
|
(info->value_type != CONF_TYPE_STR &&
|
|
info->value_type != CONF_TYPE_STR_AMBI &&
|
|
info->value_type != CONF_TYPE_UTF8)) ||
|
|
(td->got_default_bool && info->value_type != CONF_TYPE_BOOL)) {
|
|
fprintf(stderr, "%s: default doesn't match type\n", td->name);
|
|
nfails++;
|
|
}
|
|
|
|
if (td->got_storage_enum && info->value_type != CONF_TYPE_INT) {
|
|
fprintf(stderr, "%s: has STORAGE_ENUM but isn't an int\n",
|
|
td->name);
|
|
nfails++;
|
|
}
|
|
|
|
if (td->not_saved) {
|
|
if (!td->got_default && info->subkey_type == CONF_TYPE_NONE) {
|
|
fprintf(stderr, "%s: simple unsaved setting but has no "
|
|
"default\n", td->name);
|
|
nfails++;
|
|
}
|
|
|
|
if (td->got_save_keyword) {
|
|
fprintf(stderr, "%s: not saved but has SAVE_KEYWORD\n",
|
|
td->name);
|
|
nfails++;
|
|
}
|
|
|
|
if (td->save_custom) {
|
|
fprintf(stderr, "%s: not saved but has SAVE_CUSTOM\n",
|
|
td->name);
|
|
nfails++;
|
|
}
|
|
|
|
if (td->load_custom) {
|
|
fprintf(stderr, "%s: not saved but has LOAD_CUSTOM\n",
|
|
td->name);
|
|
nfails++;
|
|
}
|
|
|
|
if (td->got_storage_enum) {
|
|
fprintf(stderr, "%s: not saved but has STORAGE_ENUM\n",
|
|
td->name);
|
|
nfails++;
|
|
}
|
|
|
|
} else {
|
|
if (td->load_custom && td->save_custom) {
|
|
if (td->got_save_keyword) {
|
|
fprintf(stderr, "%s: no automatic save or load but has "
|
|
"SAVE_KEYWORD\n", td->name);
|
|
nfails++;
|
|
}
|
|
|
|
if (td->got_storage_enum) {
|
|
fprintf(stderr, "%s: no automatic save or load but has "
|
|
"STORAGE_ENUM\n", td->name);
|
|
nfails++;
|
|
}
|
|
} else {
|
|
if (!td->got_save_keyword) {
|
|
fprintf(stderr, "%s: missing SAVE_KEYWORD\n", td->name);
|
|
nfails++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
int main(void)
|
|
{
|
|
test_conf_key_info();
|
|
test_simple();
|
|
return nfails != 0;
|
|
}
|