test_conf.c 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053
  1. #define SUPERSEDE_FONTSPEC_FOR_TESTING
  2. #include "putty.h"
  3. #include "storage.h"
  4. void modalfatalbox(const char *p, ...)
  5. {
  6. va_list ap;
  7. fprintf(stderr, "FATAL ERROR: ");
  8. va_start(ap, p);
  9. vfprintf(stderr, p, ap);
  10. va_end(ap);
  11. fputc('\n', stderr);
  12. exit(1);
  13. }
  14. char *platform_default_s(const char *name)
  15. { return NULL; }
  16. bool platform_default_b(const char *name, bool def)
  17. { return def; }
  18. int platform_default_i(const char *name, int def)
  19. { return def; }
  20. FontSpec *platform_default_fontspec(const char *name)
  21. { return fontspec_new_default(); }
  22. Filename *platform_default_filename(const char *name)
  23. { return filename_from_str(""); }
  24. char *platform_get_x_display(void) { return NULL; }
  25. void read_random_seed(noise_consumer_t consumer) {}
  26. void write_random_seed(void *data, int len)
  27. { unreachable("no random seed in this application"); }
  28. bool have_ssh_host_key(const char *hostname, int port,
  29. const char *keytype) { return false; }
  30. int check_stored_host_key(const char *hostname, int port,
  31. const char *keytype, const char *key) { return 1; }
  32. void store_host_key(Seat *seat, const char *hostname, int port,
  33. const char *keytype, const char *key)
  34. { unreachable("no actual host keys in this application"); }
  35. host_ca_enum *enum_host_ca_start(void) { return NULL; }
  36. bool enum_host_ca_next(host_ca_enum *handle, strbuf *out) { return false; }
  37. void enum_host_ca_finish(host_ca_enum *handle) {}
  38. host_ca *host_ca_load(const char *name) { return NULL; }
  39. void old_keyfile_warning(void) { }
  40. const bool share_can_be_upstream = false;
  41. const bool share_can_be_downstream = false;
  42. struct FontSpec {
  43. char *name;
  44. };
  45. FontSpec *fontspec_new(const char *name)
  46. {
  47. FontSpec *f = snew(FontSpec);
  48. f->name = dupstr(name);
  49. return f;
  50. }
  51. FontSpec *fontspec_new_default(void)
  52. {
  53. return fontspec_new("");
  54. }
  55. FontSpec *fontspec_copy(const FontSpec *f)
  56. {
  57. return fontspec_new(f->name);
  58. }
  59. void fontspec_free(FontSpec *f)
  60. {
  61. sfree(f->name);
  62. sfree(f);
  63. }
  64. void fontspec_serialise(BinarySink *bs, FontSpec *f)
  65. {
  66. put_asciz(bs, f->name);
  67. }
  68. FontSpec *fontspec_deserialise(BinarySource *src)
  69. {
  70. return fontspec_new(get_asciz(src));
  71. }
  72. #define MAXKEY 16
  73. typedef enum {
  74. SAVE_UNSET, SAVE_S, SAVE_I, SAVE_FONTSPEC, SAVE_FILENAME
  75. } SaveType;
  76. typedef struct SaveItem {
  77. const char *key;
  78. SaveType type;
  79. union {
  80. char sval[4096];
  81. int ival;
  82. };
  83. } SaveItem;
  84. struct settings_w {
  85. size_t n;
  86. SaveItem si[MAXKEY];
  87. };
  88. settings_w *open_settings_w(const char *sessionname, char **errmsg)
  89. { return NULL; }
  90. void close_settings_w(settings_w *sw)
  91. { unreachable("we don't open and close in this test program"); }
  92. settings_r *open_settings_r(const char *sessionname)
  93. { return NULL; }
  94. void close_settings_r(settings_r *sr) { }
  95. /* Work around lack of true snprintf before VS2015 */
  96. #if defined _WINDOWS && \
  97. !defined __MINGW32__ && \
  98. !defined __WINE__ && \
  99. _MSC_VER < 1900
  100. #define snprintf _snprintf
  101. #endif
  102. void write_setting_s(settings_w *sw, const char *key, const char *value)
  103. {
  104. for (size_t i = 0; i < sw->n; i++) {
  105. if (!strcmp(key, sw->si[i].key)) {
  106. sw->si[i].type = SAVE_S;
  107. snprintf(sw->si[i].sval, sizeof(sw->si[i].sval), "%s", value);
  108. break;
  109. }
  110. }
  111. }
  112. void write_setting_i(settings_w *sw, const char *key, int value)
  113. {
  114. for (size_t i = 0; i < sw->n; i++) {
  115. if (!strcmp(key, sw->si[i].key)) {
  116. sw->si[i].type = SAVE_I;
  117. sw->si[i].ival = value;
  118. break;
  119. }
  120. }
  121. }
  122. void write_setting_fontspec(settings_w *sw, const char *key, FontSpec *fs)
  123. {
  124. for (size_t i = 0; i < sw->n; i++) {
  125. if (!strcmp(key, sw->si[i].key)) {
  126. sw->si[i].type = SAVE_FONTSPEC;
  127. snprintf(sw->si[i].sval, sizeof(sw->si[i].sval), "%s", fs->name);
  128. break;
  129. }
  130. }
  131. }
  132. void write_setting_filename(settings_w *sw, const char *key, Filename *fn)
  133. {
  134. for (size_t i = 0; i < sw->n; i++) {
  135. if (!strcmp(key, sw->si[i].key)) {
  136. sw->si[i].type = SAVE_FILENAME;
  137. snprintf(sw->si[i].sval, sizeof(sw->si[i].sval), "%s",
  138. filename_to_str(fn));
  139. break;
  140. }
  141. }
  142. }
  143. struct settings_r {
  144. size_t n;
  145. SaveItem si[MAXKEY];
  146. };
  147. char *read_setting_s(settings_r *sr, const char *key)
  148. {
  149. if (sr)
  150. for (size_t i = 0; i < sr->n; i++)
  151. if (!strcmp(key, sr->si[i].key) && sr->si[i].type == SAVE_S)
  152. return dupstr(sr->si[i].sval);
  153. return NULL;
  154. }
  155. int read_setting_i(settings_r *sr, const char *key, int defvalue)
  156. {
  157. if (sr)
  158. for (size_t i = 0; i < sr->n; i++)
  159. if (!strcmp(key, sr->si[i].key) && sr->si[i].type == SAVE_I)
  160. return sr->si[i].ival;
  161. return defvalue;
  162. }
  163. FontSpec *read_setting_fontspec(settings_r *sr, const char *key)
  164. {
  165. if (sr)
  166. for (size_t i = 0; i < sr->n; i++)
  167. if (!strcmp(key, sr->si[i].key) && sr->si[i].type == SAVE_FONTSPEC)
  168. return fontspec_new(sr->si[i].sval);
  169. return NULL;
  170. }
  171. Filename *read_setting_filename(settings_r *sr, const char *key)
  172. {
  173. if (sr)
  174. for (size_t i = 0; i < sr->n; i++)
  175. if (!strcmp(key, sr->si[i].key) && sr->si[i].type == SAVE_FILENAME)
  176. return filename_from_str(sr->si[i].sval);
  177. return NULL;
  178. }
  179. void del_settings(const char *sessionname) {}
  180. settings_e *enum_settings_start(void)
  181. { return NULL; }
  182. bool enum_settings_next(settings_e *handle, strbuf *out)
  183. { unreachable("where did you get a settings_e from?"); }
  184. void enum_settings_finish(settings_e *handle)
  185. { unreachable("where did you get a settings_e from?"); }
  186. static int nfails = 0;
  187. void test_str_simple(int confid, const char *saveid, const char *defexp)
  188. {
  189. Conf *conf = conf_new();
  190. do_defaults(NULL, conf);
  191. const char *defgot = conf_get_str(conf, confid);
  192. if (0 != strcmp(defgot, defexp)) {
  193. printf("fail test_str_simple(%s): default = '%s', expected '%s'\n",
  194. saveid, defgot, defexp);
  195. nfails++;
  196. }
  197. for (int i = 0; i < 2; i++) {
  198. settings_w sw = {
  199. .n = 1,
  200. .si[0].key = saveid,
  201. .si[0].type = SAVE_UNSET,
  202. };
  203. static const char *const teststrings[] = { "foo", "bar" };
  204. const char *teststring = teststrings[i];
  205. conf_set_str(conf, confid, teststring);
  206. save_open_settings(&sw, conf);
  207. if (sw.si[0].type != SAVE_S) {
  208. printf("fail test_str_simple(%s): saved type = %d, expected %d\n",
  209. saveid, sw.si[0].type, SAVE_S);
  210. nfails++;
  211. } else if (0 != strcmp(sw.si[0].sval, teststring)) {
  212. printf("fail test_str_simple(%s): "
  213. "saved string = '%s', expected '%s'\n",
  214. saveid, sw.si[0].sval, teststring);
  215. nfails++;
  216. }
  217. conf_clear(conf);
  218. settings_r sr = {
  219. .n = 1,
  220. .si[0].key = saveid,
  221. .si[0].type = SAVE_S,
  222. };
  223. snprintf(sr.si[0].sval, sizeof(sr.si[0].sval), "%s", teststring);
  224. load_open_settings(&sr, conf);
  225. const char *loaded = conf_get_str(conf, confid);
  226. if (0 != strcmp(loaded, teststring)) {
  227. printf("fail test_str_simple(%s): "
  228. "loaded string = '%s', expected '%s'\n",
  229. saveid, loaded, teststring);
  230. nfails++;
  231. }
  232. }
  233. conf_free(conf);
  234. }
  235. void test_utf8_simple(int confid, const char *saveid, const char *defexp)
  236. {
  237. Conf *conf = conf_new();
  238. do_defaults(NULL, conf);
  239. const char *defgot = conf_get_utf8(conf, confid);
  240. if (0 != strcmp(defgot, defexp)) {
  241. printf("fail test_utf8_simple(%s): default = '%s', expected '%s'\n",
  242. saveid, defgot, defexp);
  243. nfails++;
  244. }
  245. for (int i = 0; i < 2; i++) {
  246. settings_w sw = {
  247. .n = 1,
  248. .si[0].key = saveid,
  249. .si[0].type = SAVE_UNSET,
  250. };
  251. static const char *const teststrings[] = { "foo", "bar" };
  252. const char *teststring = teststrings[i];
  253. conf_set_utf8(conf, confid, teststring);
  254. save_open_settings(&sw, conf);
  255. if (sw.si[0].type != SAVE_S) {
  256. printf("fail test_utf8_simple(%s): saved type = %d, expected %d\n",
  257. saveid, sw.si[0].type, SAVE_S);
  258. nfails++;
  259. } else if (0 != strcmp(sw.si[0].sval, teststring)) {
  260. printf("fail test_utf8_simple(%s): "
  261. "saved string = '%s', expected '%s'\n",
  262. saveid, sw.si[0].sval, teststring);
  263. nfails++;
  264. }
  265. conf_clear(conf);
  266. settings_r sr = {
  267. .n = 1,
  268. .si[0].key = saveid,
  269. .si[0].type = SAVE_S,
  270. };
  271. snprintf(sr.si[0].sval, sizeof(sr.si[0].sval), "%s", teststring);
  272. load_open_settings(&sr, conf);
  273. const char *loaded = conf_get_utf8(conf, confid);
  274. if (0 != strcmp(loaded, teststring)) {
  275. printf("fail test_utf8_simple(%s): "
  276. "loaded string = '%s', expected '%s'\n",
  277. saveid, loaded, teststring);
  278. nfails++;
  279. }
  280. }
  281. conf_free(conf);
  282. }
  283. void test_str_ambi_simple(int confid, const char *saveid,
  284. const char *defexp, bool defutf8)
  285. {
  286. Conf *conf = conf_new();
  287. bool utf8;
  288. do_defaults(NULL, conf);
  289. const char *defgot = conf_get_str_ambi(conf, confid, &utf8);
  290. if (0 != strcmp(defgot, defexp) || utf8 != defutf8) {
  291. printf("fail test_str_ambi_simple(%s): "
  292. "default = '%s' (%s), expected '%s' (%s)\n",
  293. saveid, defgot, utf8 ? "native" : "UTF-8",
  294. defexp, defutf8 ? "native" : "UTF-8");
  295. nfails++;
  296. }
  297. for (int i = 0; i < 2; i++) {
  298. settings_w sw = {
  299. .n = 1,
  300. .si[0].key = saveid,
  301. .si[0].type = SAVE_UNSET,
  302. };
  303. static const char *const teststrings[] = { "foo", "bar" };
  304. const char *teststring = teststrings[i];
  305. conf_set_str(conf, confid, teststring);
  306. save_open_settings(&sw, conf);
  307. if (sw.si[0].type != SAVE_S) {
  308. printf("fail test_str_ambi_simple(%s): "
  309. "saved type = %d, expected %d\n",
  310. saveid, sw.si[0].type, SAVE_S);
  311. nfails++;
  312. } else if (0 != strcmp(sw.si[0].sval, teststring)) {
  313. printf("fail test_str_ambi_simple(%s): "
  314. "saved string = '%s', expected '%s'\n",
  315. saveid, sw.si[0].sval, teststring);
  316. nfails++;
  317. }
  318. conf_clear(conf);
  319. settings_r sr = {
  320. .n = 1,
  321. .si[0].key = saveid,
  322. .si[0].type = SAVE_S,
  323. };
  324. snprintf(sr.si[0].sval, sizeof(sr.si[0].sval), "%s", teststring);
  325. load_open_settings(&sr, conf);
  326. const char *loaded = conf_get_str_ambi(conf, confid, &utf8);
  327. if (0 != strcmp(loaded, teststring) || utf8) {
  328. printf("fail test_str_ambi_simple(%s): "
  329. "loaded string = '%s' (%s), expected '%s' (native)\n",
  330. saveid, loaded, utf8 ? "native" : "UTF-8", teststring);
  331. nfails++;
  332. }
  333. }
  334. conf_free(conf);
  335. }
  336. void test_int_simple(int confid, const char *saveid, int defexp)
  337. {
  338. Conf *conf = conf_new();
  339. do_defaults(NULL, conf);
  340. int defgot = conf_get_int(conf, confid);
  341. if (defgot != defexp) {
  342. printf("fail test_int_simple(%s): default = %d, expected %d\n",
  343. saveid, defgot, defexp);
  344. nfails++;
  345. }
  346. for (int i = 0; i < 2; i++) {
  347. settings_w sw = {
  348. .n = 1,
  349. .si[0].key = saveid,
  350. .si[0].type = SAVE_UNSET,
  351. };
  352. static const int testints[] = { 12345, 54321 };
  353. int testint = testints[i];
  354. conf_set_int(conf, confid, testint);
  355. save_open_settings(&sw, conf);
  356. if (sw.si[0].type != SAVE_I) {
  357. printf("fail test_int_simple(%s): saved type = %d, expected %d\n",
  358. saveid, sw.si[0].type, SAVE_I);
  359. nfails++;
  360. } else if (sw.si[0].ival != testint) {
  361. printf("fail test_int_simple(%s): "
  362. "saved integer = %d, expected %d\n",
  363. saveid, sw.si[0].ival, testint);
  364. nfails++;
  365. }
  366. conf_clear(conf);
  367. settings_r sr = {
  368. .n = 1,
  369. .si[0].key = saveid,
  370. .si[0].type = SAVE_I,
  371. .si[0].ival = testint,
  372. };
  373. load_open_settings(&sr, conf);
  374. int loaded = conf_get_int(conf, confid);
  375. if (loaded != testint) {
  376. printf("fail test_int_simple(%s): "
  377. "loaded integer = %d, expected %d\n",
  378. saveid, loaded, testint);
  379. nfails++;
  380. }
  381. }
  382. conf_free(conf);
  383. }
  384. void test_int_translated_internal(
  385. int confid, const char *saveid, bool test_save, bool test_load,
  386. void (*load_prepare)(settings_r *), int defexp, va_list ap)
  387. {
  388. Conf *conf = conf_new();
  389. do_defaults(NULL, conf);
  390. int defgot = conf_get_int(conf, confid);
  391. if (defgot != defexp) {
  392. printf("fail test_int_translated(%s): default = %d, expected %d\n",
  393. saveid, defgot, defexp);
  394. nfails++;
  395. }
  396. int confval = va_arg(ap, int);
  397. while (confval != -1) {
  398. int storageval = va_arg(ap, int);
  399. if (test_save) {
  400. settings_w sw = {
  401. .n = 1,
  402. .si[0].key = saveid,
  403. .si[0].type = SAVE_UNSET,
  404. };
  405. conf_set_int(conf, confid, confval);
  406. save_open_settings(&sw, conf);
  407. if (sw.si[0].type != SAVE_I) {
  408. printf("fail test_int_translated(%s): "
  409. "saved type = %d, expected %d\n",
  410. saveid, sw.si[0].type, SAVE_I);
  411. nfails++;
  412. } else if (sw.si[0].ival != storageval) {
  413. printf("fail test_int_translated(%s.%d.%d): "
  414. "saved integer = %d, expected %d\n",
  415. saveid, confval, storageval, sw.si[0].ival, storageval);
  416. nfails++;
  417. }
  418. }
  419. if (test_load) {
  420. conf_clear(conf);
  421. settings_r sr = {
  422. .n = 1,
  423. .si[0].key = saveid,
  424. .si[0].type = SAVE_I,
  425. .si[0].ival = storageval,
  426. };
  427. if (load_prepare)
  428. load_prepare(&sr);
  429. load_open_settings(&sr, conf);
  430. int loaded = conf_get_int(conf, confid);
  431. if (loaded != confval) {
  432. printf("fail test_int_translated(%s.%d.%d): "
  433. "loaded integer = %d, expected %d\n",
  434. saveid, confval, storageval, loaded, confval);
  435. nfails++;
  436. }
  437. }
  438. confval = va_arg(ap, int);
  439. }
  440. conf_free(conf);
  441. }
  442. void test_int_translated(int confid, const char *saveid, int defexp, ...)
  443. {
  444. va_list ap;
  445. va_start(ap, defexp);
  446. test_int_translated_internal(confid, saveid, true, true, NULL, defexp, ap);
  447. va_end(ap);
  448. }
  449. void test_int_translated_load_legacy(
  450. int confid, const char *saveid, void (*load_prepare)(settings_r *),
  451. int defexp, ...)
  452. {
  453. va_list ap;
  454. va_start(ap, defexp);
  455. test_int_translated_internal(confid, saveid, false, true, load_prepare,
  456. defexp, ap);
  457. va_end(ap);
  458. }
  459. void test_bool_simple(int confid, const char *saveid, bool defexp)
  460. {
  461. Conf *conf = conf_new();
  462. do_defaults(NULL, conf);
  463. bool defgot = conf_get_bool(conf, confid);
  464. if (defgot != defexp) {
  465. printf("fail test_bool_simple(%s): default = %d, expected %d\n",
  466. saveid, defgot, defexp);
  467. nfails++;
  468. }
  469. for (int i = 0; i < 2; i++) {
  470. settings_w sw = {
  471. .n = 1,
  472. .si[0].key = saveid,
  473. .si[0].type = SAVE_UNSET,
  474. };
  475. static const bool testbools[] = { false, true };
  476. bool testbool = testbools[i];
  477. conf_set_bool(conf, confid, testbool);
  478. save_open_settings(&sw, conf);
  479. if (sw.si[0].type != SAVE_I) {
  480. printf("fail test_bool_simple(%s): saved type = %d, expected %d\n",
  481. saveid, sw.si[0].type, SAVE_I);
  482. nfails++;
  483. } else if (sw.si[0].ival != testbool) {
  484. printf("fail test_bool_simple(%s): "
  485. "saved integer = %d, expected %d\n",
  486. saveid, sw.si[0].ival, testbool);
  487. nfails++;
  488. }
  489. conf_clear(conf);
  490. settings_r sr = {
  491. .n = 1,
  492. .si[0].key = saveid,
  493. .si[0].type = SAVE_I,
  494. .si[0].ival = testbool,
  495. };
  496. load_open_settings(&sr, conf);
  497. bool loaded = conf_get_bool(conf, confid);
  498. if (loaded != testbool) {
  499. printf("fail test_bool_simple(%s): "
  500. "loaded boolean = %d, expected %d\n",
  501. saveid, loaded, testbool);
  502. nfails++;
  503. }
  504. }
  505. conf_free(conf);
  506. }
  507. void test_file_simple(int confid, const char *saveid)
  508. {
  509. Conf *conf = conf_new();
  510. do_defaults(NULL, conf);
  511. for (int i = 0; i < 2; i++) {
  512. settings_w sw = {
  513. .n = 1,
  514. .si[0].key = saveid,
  515. .si[0].type = SAVE_UNSET,
  516. };
  517. static const char *const teststrings[] = { "foo", "bar" };
  518. const char *teststring = teststrings[i];
  519. Filename *testfn = filename_from_str(teststring);
  520. conf_set_filename(conf, confid, testfn);
  521. filename_free(testfn);
  522. save_open_settings(&sw, conf);
  523. if (sw.si[0].type != SAVE_FILENAME) {
  524. printf("fail test_file_simple(%s): saved type = %d, expected %d\n",
  525. saveid, sw.si[0].type, SAVE_FILENAME);
  526. nfails++;
  527. } else if (0 != strcmp(sw.si[0].sval, teststring)) {
  528. printf("fail test_file_simple(%s): "
  529. "saved string = '%s', expected '%s'\n",
  530. saveid, sw.si[0].sval, teststring);
  531. nfails++;
  532. }
  533. conf_clear(conf);
  534. settings_r sr = {
  535. .n = 1,
  536. .si[0].key = saveid,
  537. .si[0].type = SAVE_FILENAME,
  538. };
  539. snprintf(sr.si[0].sval, sizeof(sr.si[0].sval), "%s", teststring);
  540. load_open_settings(&sr, conf);
  541. const char *loaded = filename_to_str(conf_get_filename(conf, confid));
  542. if (0 != strcmp(loaded, teststring)) {
  543. printf("fail test_file_simple(%s): "
  544. "loaded string = '%s', expected '%s'\n",
  545. saveid, loaded, teststring);
  546. nfails++;
  547. }
  548. }
  549. conf_free(conf);
  550. }
  551. void test_font_simple(int confid, const char *saveid)
  552. {
  553. Conf *conf = conf_new();
  554. do_defaults(NULL, conf);
  555. for (int i = 0; i < 2; i++) {
  556. settings_w sw = {
  557. .n = 1,
  558. .si[0].key = saveid,
  559. .si[0].type = SAVE_UNSET,
  560. };
  561. static const char *const teststrings[] = { "foo", "bar" };
  562. const char *teststring = teststrings[i];
  563. FontSpec *testfs = fontspec_new(teststring);
  564. conf_set_fontspec(conf, confid, testfs);
  565. fontspec_free(testfs);
  566. save_open_settings(&sw, conf);
  567. if (sw.si[0].type != SAVE_FONTSPEC) {
  568. printf("fail test_font_simple(%s): saved type = %d, expected %d\n",
  569. saveid, sw.si[0].type, SAVE_FONTSPEC);
  570. nfails++;
  571. } else if (0 != strcmp(sw.si[0].sval, teststring)) {
  572. printf("fail test_font_simple(%s): "
  573. "saved string = '%s', expected '%s'\n",
  574. saveid, sw.si[0].sval, teststring);
  575. nfails++;
  576. }
  577. conf_clear(conf);
  578. settings_r sr = {
  579. .n = 1,
  580. .si[0].key = saveid,
  581. .si[0].type = SAVE_FONTSPEC,
  582. };
  583. snprintf(sr.si[0].sval, sizeof(sr.si[0].sval), "%s", teststring);
  584. load_open_settings(&sr, conf);
  585. const char *loaded = conf_get_fontspec(conf, confid)->name;
  586. if (0 != strcmp(loaded, teststring)) {
  587. printf("fail test_file_simple(%s): "
  588. "loaded string = '%s', expected '%s'\n",
  589. saveid, loaded, teststring);
  590. nfails++;
  591. }
  592. }
  593. conf_free(conf);
  594. }
  595. static void load_prepare_socks4(settings_r *sr)
  596. {
  597. size_t pos = sr->n++;
  598. sr->si[pos].key = "ProxySOCKSVersion";
  599. sr->si[pos].type = SAVE_I;
  600. sr->si[pos].ival = 4;
  601. }
  602. void test_simple(void)
  603. {
  604. test_str_simple(CONF_host, "HostName", "");
  605. test_int_translated(CONF_addressfamily, "AddressFamily", ADDRTYPE_UNSPEC,
  606. ADDRTYPE_UNSPEC, 0, ADDRTYPE_IPV4, 1,
  607. ADDRTYPE_IPV6, 2, -1);
  608. test_bool_simple(CONF_warn_on_close, "WarnOnClose", true);
  609. test_bool_simple(CONF_tcp_nodelay, "TCPNoDelay", true);
  610. test_bool_simple(CONF_tcp_keepalives, "TCPKeepalives", false);
  611. test_str_simple(CONF_loghost, "LogHost", "");
  612. test_str_simple(CONF_proxy_exclude_list, "ProxyExcludeList", "");
  613. test_bool_simple(CONF_even_proxy_localhost, "ProxyLocalhost", false);
  614. test_str_simple(CONF_proxy_host, "ProxyHost", "proxy");
  615. test_int_simple(CONF_proxy_port, "ProxyPort", 80);
  616. test_str_simple(CONF_proxy_username, "ProxyUsername", "");
  617. test_str_simple(CONF_proxy_password, "ProxyPassword", "");
  618. test_str_simple(CONF_proxy_telnet_command, "ProxyTelnetCommand", "connect %host %port\\n");
  619. test_int_translated(CONF_proxy_log_to_term, "ProxyLogToTerm", FORCE_OFF,
  620. FORCE_ON, 0, FORCE_OFF, 1, AUTO, 2, -1);
  621. test_str_ambi_simple(CONF_remote_cmd, "RemoteCommand", "", false);
  622. test_bool_simple(CONF_nopty, "NoPTY", false);
  623. test_bool_simple(CONF_compression, "Compression", false);
  624. test_bool_simple(CONF_ssh_prefer_known_hostkeys, "PreferKnownHostKeys", true);
  625. test_int_simple(CONF_ssh_rekey_time, "RekeyTime", 60);
  626. test_str_simple(CONF_ssh_rekey_data, "RekeyBytes", "1G");
  627. test_bool_simple(CONF_tryagent, "TryAgent", true);
  628. test_bool_simple(CONF_agentfwd, "AgentFwd", false);
  629. test_bool_simple(CONF_change_username, "ChangeUsername", false);
  630. test_file_simple(CONF_keyfile, "PublicKeyFile");
  631. test_file_simple(CONF_detached_cert, "DetachedCertificate");
  632. test_str_simple(CONF_auth_plugin, "AuthPlugin", "");
  633. test_bool_simple(CONF_ssh2_des_cbc, "SSH2DES", false);
  634. test_bool_simple(CONF_ssh_no_userauth, "SshNoAuth", false);
  635. test_bool_simple(CONF_ssh_no_trivial_userauth, "SshNoTrivialAuth", false);
  636. test_bool_simple(CONF_ssh_show_banner, "SshBanner", true);
  637. test_bool_simple(CONF_try_tis_auth, "AuthTIS", false);
  638. test_bool_simple(CONF_try_ki_auth, "AuthKI", true);
  639. test_bool_simple(CONF_ssh_no_shell, "SshNoShell", false);
  640. test_str_simple(CONF_termtype, "TerminalType", "xterm");
  641. test_str_simple(CONF_termspeed, "TerminalSpeed", "38400,38400");
  642. test_str_ambi_simple(CONF_username, "UserName", "", false);
  643. test_bool_simple(CONF_username_from_env, "UserNameFromEnvironment", false);
  644. test_str_simple(CONF_localusername, "LocalUserName", "");
  645. test_bool_simple(CONF_rfc_environ, "RFCEnviron", false);
  646. test_bool_simple(CONF_passive_telnet, "PassiveTelnet", false);
  647. test_str_simple(CONF_serline, "SerialLine", "");
  648. test_int_simple(CONF_serspeed, "SerialSpeed", 9600);
  649. test_int_simple(CONF_serdatabits, "SerialDataBits", 8);
  650. test_int_simple(CONF_serstopbits, "SerialStopHalfbits", 2);
  651. test_int_translated(CONF_serparity, "SerialParity", SER_PAR_NONE,
  652. SER_PAR_NONE, 0, SER_PAR_ODD, 1, SER_PAR_EVEN, 2,
  653. SER_PAR_MARK, 3, SER_PAR_SPACE, 4, -1);
  654. test_int_translated(CONF_serflow, "SerialFlowControl", SER_FLOW_XONXOFF,
  655. SER_FLOW_NONE, 0, SER_FLOW_XONXOFF, 1,
  656. SER_FLOW_RTSCTS, 2, SER_FLOW_DSRDTR, 3, -1);
  657. test_str_simple(CONF_supdup_location, "SUPDUPLocation", "The Internet");
  658. test_int_translated(CONF_supdup_ascii_set, "SUPDUPCharset",
  659. SUPDUP_CHARSET_ASCII,
  660. SUPDUP_CHARSET_ASCII, 0,
  661. SUPDUP_CHARSET_ITS, 1,
  662. SUPDUP_CHARSET_WAITS, 2, -1);
  663. test_bool_simple(CONF_supdup_more, "SUPDUPMoreProcessing", false);
  664. test_bool_simple(CONF_supdup_scroll, "SUPDUPScrolling", false);
  665. test_bool_simple(CONF_bksp_is_delete, "BackspaceIsDelete", true);
  666. test_bool_simple(CONF_rxvt_homeend, "RXVTHomeEnd", false);
  667. test_int_translated(CONF_funky_type, "LinuxFunctionKeys", FUNKY_TILDE,
  668. FUNKY_TILDE, 0, FUNKY_LINUX, 1, FUNKY_XTERM, 2,
  669. FUNKY_VT400, 3, FUNKY_VT100P, 4, FUNKY_SCO, 5,
  670. FUNKY_XTERM_216, 6, -1);
  671. test_int_translated(CONF_sharrow_type, "ShiftedArrowKeys",
  672. SHARROW_APPLICATION,
  673. SHARROW_APPLICATION, 0, SHARROW_BITMAP, 1, -1);
  674. test_bool_simple(CONF_no_applic_c, "NoApplicationCursors", false);
  675. test_bool_simple(CONF_no_applic_k, "NoApplicationKeys", false);
  676. test_bool_simple(CONF_no_mouse_rep, "NoMouseReporting", false);
  677. test_bool_simple(CONF_no_remote_resize, "NoRemoteResize", false);
  678. test_bool_simple(CONF_no_alt_screen, "NoAltScreen", false);
  679. test_bool_simple(CONF_no_remote_wintitle, "NoRemoteWinTitle", false);
  680. test_bool_simple(CONF_no_remote_clearscroll, "NoRemoteClearScroll", false);
  681. test_bool_simple(CONF_no_dbackspace, "NoDBackspace", false);
  682. test_bool_simple(CONF_no_remote_charset, "NoRemoteCharset", false);
  683. /* note we have no test for CONF_remote_qtitle_action because no default */
  684. test_bool_simple(CONF_app_cursor, "ApplicationCursorKeys", false);
  685. test_bool_simple(CONF_app_keypad, "ApplicationKeypad", false);
  686. test_bool_simple(CONF_nethack_keypad, "NetHackKeypad", false);
  687. test_bool_simple(CONF_telnet_keyboard, "TelnetKey", false);
  688. test_bool_simple(CONF_telnet_newline, "TelnetRet", true);
  689. test_bool_simple(CONF_alt_f4, "AltF4", true);
  690. test_bool_simple(CONF_alt_space, "AltSpace", false);
  691. test_bool_simple(CONF_alt_only, "AltOnly", false);
  692. test_int_translated(CONF_localecho, "LocalEcho", AUTO,
  693. FORCE_ON, 0, FORCE_OFF, 1, AUTO, 2, -1);
  694. test_int_translated(CONF_localedit, "LocalEdit", AUTO,
  695. FORCE_ON, 0, FORCE_OFF, 1, AUTO, 2, -1);
  696. test_bool_simple(CONF_alwaysontop, "AlwaysOnTop", false);
  697. test_bool_simple(CONF_fullscreenonaltenter, "FullScreenOnAltEnter", false);
  698. test_bool_simple(CONF_scroll_on_key, "ScrollOnKey", false);
  699. test_bool_simple(CONF_scroll_on_disp, "ScrollOnDisp", true);
  700. test_bool_simple(CONF_erase_to_scrollback, "EraseToScrollback", true);
  701. test_bool_simple(CONF_compose_key, "ComposeKey", false);
  702. test_bool_simple(CONF_ctrlaltkeys, "CtrlAltKeys", true);
  703. test_str_simple(CONF_wintitle, "WinTitle", "");
  704. test_int_simple(CONF_savelines, "ScrollbackLines", 2000);
  705. test_bool_simple(CONF_dec_om, "DECOriginMode", false);
  706. test_bool_simple(CONF_wrap_mode, "AutoWrapMode", true);
  707. test_bool_simple(CONF_lfhascr, "LFImpliesCR", false);
  708. test_int_translated(CONF_cursor_type, "CurType", CURSOR_BLOCK,
  709. CURSOR_BLOCK, 0, CURSOR_UNDERLINE, 1,
  710. CURSOR_VERTICAL_LINE, 2, -1);
  711. test_bool_simple(CONF_blink_cur, "BlinkCur", false);
  712. test_int_translated(CONF_beep, "Beep", 1,
  713. BELL_DISABLED, 0, BELL_DEFAULT, 1, BELL_VISUAL, 2,
  714. BELL_WAVEFILE, 3, BELL_PCSPEAKER, 4, -1);
  715. test_int_translated(CONF_beep_ind, "BeepInd", 0,
  716. B_IND_DISABLED, 0, B_IND_FLASH, 1, B_IND_STEADY, 2, -1);
  717. test_bool_simple(CONF_bellovl, "BellOverload", true);
  718. test_int_simple(CONF_bellovl_n, "BellOverloadN", 5);
  719. test_file_simple(CONF_bell_wavefile, "BellWaveFile");
  720. test_bool_simple(CONF_scrollbar, "ScrollBar", true);
  721. test_bool_simple(CONF_scrollbar_in_fullscreen, "ScrollBarFullScreen", false);
  722. test_int_translated(CONF_resize_action, "LockSize", RESIZE_TERM,
  723. RESIZE_TERM, 0, RESIZE_DISABLED, 1, RESIZE_FONT, 2,
  724. RESIZE_EITHER, 3, -1);
  725. test_bool_simple(CONF_bce, "BCE", true);
  726. test_bool_simple(CONF_blinktext, "BlinkText", false);
  727. test_bool_simple(CONF_win_name_always, "WinNameAlways", true);
  728. test_int_simple(CONF_width, "TermWidth", 80);
  729. test_int_simple(CONF_height, "TermHeight", 24);
  730. test_font_simple(CONF_font, "Font");
  731. test_int_translated(CONF_font_quality, "FontQuality", FQ_DEFAULT,
  732. FQ_DEFAULT, 0, FQ_ANTIALIASED, 1, FQ_NONANTIALIASED, 2,
  733. FQ_CLEARTYPE, 3, -1);
  734. test_file_simple(CONF_logfilename, "LogFileName");
  735. test_int_translated(CONF_logtype, "LogType", LGTYP_NONE,
  736. LGTYP_NONE, 0, LGTYP_ASCII, 1, LGTYP_DEBUG, 2,
  737. LGTYP_PACKETS, 3, LGTYP_SSHRAW, 4, -1);
  738. /* FIXME: this won't work because -1 is also the terminator, darn */
  739. test_int_translated(CONF_logxfovr, "LogFileClash", LGXF_ASK,
  740. LGXF_OVR, 1, LGXF_APN, 0, LGXF_ASK, -1, -1);
  741. test_bool_simple(CONF_logflush, "LogFlush", true);
  742. test_bool_simple(CONF_logheader, "LogHeader", true);
  743. test_bool_simple(CONF_logomitpass, "SSHLogOmitPasswords", true);
  744. test_bool_simple(CONF_logomitdata, "SSHLogOmitData", false);
  745. test_bool_simple(CONF_hide_mouseptr, "HideMousePtr", false);
  746. test_bool_simple(CONF_sunken_edge, "SunkenEdge", false);
  747. test_int_simple(CONF_window_border, "WindowBorder", 1);
  748. test_str_simple(CONF_answerback, "Answerback", "PuTTY");
  749. test_str_simple(CONF_printer, "Printer", "");
  750. test_bool_simple(CONF_no_arabicshaping, "DisableArabicShaping", false);
  751. test_bool_simple(CONF_no_bidi, "DisableBidi", false);
  752. test_bool_simple(CONF_ansi_colour, "ANSIColour", true);
  753. test_bool_simple(CONF_xterm_256_colour, "Xterm256Colour", true);
  754. test_bool_simple(CONF_true_colour, "TrueColour", true);
  755. test_bool_simple(CONF_system_colour, "UseSystemColours", false);
  756. test_bool_simple(CONF_try_palette, "TryPalette", false);
  757. test_int_translated(CONF_mouse_is_xterm, "MouseIsXterm", 0,
  758. MOUSE_COMPROMISE, 0, MOUSE_XTERM, 1,
  759. MOUSE_WINDOWS, 2, -1);
  760. test_bool_simple(CONF_rect_select, "RectSelect", false);
  761. test_bool_simple(CONF_paste_controls, "PasteControls", false);
  762. test_bool_simple(CONF_rawcnp, "RawCNP", false);
  763. test_bool_simple(CONF_utf8linedraw, "UTF8linedraw", false);
  764. test_bool_simple(CONF_rtf_paste, "PasteRTF", false);
  765. test_bool_simple(CONF_mouse_override, "MouseOverride", true);
  766. test_bool_simple(CONF_mouseautocopy, "MouseAutocopy", CLIPUI_DEFAULT_AUTOCOPY);
  767. test_int_translated(CONF_vtmode, "FontVTMode", VT_UNICODE,
  768. VT_XWINDOWS, 0,
  769. VT_OEMANSI, 1,
  770. VT_OEMONLY, 2,
  771. VT_POORMAN, 3,
  772. VT_UNICODE, 4,
  773. -1);
  774. test_str_simple(CONF_line_codepage, "LineCodePage", "");
  775. test_bool_simple(CONF_cjk_ambig_wide, "CJKAmbigWide", false);
  776. test_bool_simple(CONF_utf8_override, "UTF8Override", true);
  777. test_bool_simple(CONF_xlat_capslockcyr, "CapsLockCyr", false);
  778. test_bool_simple(CONF_x11_forward, "X11Forward", false);
  779. test_str_simple(CONF_x11_display, "X11Display", "");
  780. test_int_translated(CONF_x11_auth, "X11AuthType", X11_MIT,
  781. X11_NO_AUTH, 0, X11_MIT, 1, X11_XDM, 2, -1);
  782. test_file_simple(CONF_xauthfile, "X11AuthFile");
  783. test_bool_simple(CONF_lport_acceptall, "LocalPortAcceptAll", false);
  784. test_bool_simple(CONF_rport_acceptall, "RemotePortAcceptAll", false);
  785. test_bool_simple(CONF_ssh_connection_sharing, "ConnectionSharing", false);
  786. test_bool_simple(CONF_ssh_connection_sharing_upstream, "ConnectionSharingUpstream", true);
  787. test_bool_simple(CONF_ssh_connection_sharing_downstream, "ConnectionSharingDownstream", true);
  788. test_bool_simple(CONF_stamp_utmp, "StampUtmp", true);
  789. test_bool_simple(CONF_login_shell, "LoginShell", true);
  790. test_bool_simple(CONF_scrollbar_on_left, "ScrollbarOnLeft", false);
  791. test_bool_simple(CONF_shadowbold, "ShadowBold", false);
  792. test_font_simple(CONF_boldfont, "BoldFont");
  793. test_font_simple(CONF_widefont, "WideFont");
  794. test_font_simple(CONF_wideboldfont, "WideBoldFont");
  795. test_int_simple(CONF_shadowboldoffset, "ShadowBoldOffset", 1);
  796. test_bool_simple(CONF_crhaslf, "CRImpliesLF", false);
  797. test_str_simple(CONF_winclass, "WindowClass", "");
  798. test_int_translated(CONF_close_on_exit, "CloseOnExit", AUTO,
  799. FORCE_OFF, 0, AUTO, 1, FORCE_ON, 2, -1);
  800. test_int_translated(CONF_proxy_dns, "ProxyDNS", AUTO,
  801. FORCE_OFF, 0, AUTO, 1, FORCE_ON, 2, -1);
  802. test_int_translated(CONF_bold_style, "BoldAsColour", AUTO,
  803. 1, 0, 2, 1, 3, 2, -1);
  804. test_int_translated(CONF_sshbug_ignore1, "BugIgnore1", AUTO,
  805. AUTO, 0, FORCE_OFF, 1, FORCE_ON, 2, -1);
  806. test_int_translated(CONF_sshbug_plainpw1, "BugPlainPW1", AUTO,
  807. AUTO, 0, FORCE_OFF, 1, FORCE_ON, 2, -1);
  808. test_int_translated(CONF_sshbug_rsa1, "BugRSA1", AUTO,
  809. AUTO, 0, FORCE_OFF, 1, FORCE_ON, 2, -1);
  810. test_int_translated(CONF_sshbug_ignore2, "BugIgnore2", AUTO,
  811. AUTO, 0, FORCE_OFF, 1, FORCE_ON, 2, -1);
  812. test_int_translated(CONF_sshbug_derivekey2, "BugDeriveKey2", AUTO,
  813. AUTO, 0, FORCE_OFF, 1, FORCE_ON, 2, -1);
  814. test_int_translated(CONF_sshbug_rsapad2, "BugRSAPad2", AUTO,
  815. AUTO, 0, FORCE_OFF, 1, FORCE_ON, 2, -1);
  816. test_int_translated(CONF_sshbug_pksessid2, "BugPKSessID2", AUTO,
  817. AUTO, 0, FORCE_OFF, 1, FORCE_ON, 2, -1);
  818. test_int_translated(CONF_sshbug_rekey2, "BugRekey2", AUTO,
  819. AUTO, 0, FORCE_OFF, 1, FORCE_ON, 2, -1);
  820. test_int_translated(CONF_sshbug_maxpkt2, "BugMaxPkt2", AUTO,
  821. AUTO, 0, FORCE_OFF, 1, FORCE_ON, 2, -1);
  822. test_int_translated(CONF_sshbug_oldgex2, "BugOldGex2", AUTO,
  823. AUTO, 0, FORCE_OFF, 1, FORCE_ON, 2, -1);
  824. test_int_translated(CONF_sshbug_winadj, "BugWinadj", AUTO,
  825. AUTO, 0, FORCE_OFF, 1, FORCE_ON, 2, -1);
  826. test_int_translated(CONF_sshbug_chanreq, "BugChanReq", AUTO,
  827. AUTO, 0, FORCE_OFF, 1, FORCE_ON, 2, -1);
  828. test_int_translated(CONF_sshbug_dropstart, "BugDropStart", FORCE_OFF,
  829. FORCE_OFF, 1, FORCE_ON, 2, -1);
  830. test_int_translated(CONF_sshbug_filter_kexinit, "BugFilterKexinit", FORCE_OFF,
  831. FORCE_OFF, 1, FORCE_ON, 2, -1);
  832. test_int_translated(CONF_sshbug_rsa_sha2_cert_userauth, "BugRSASHA2CertUserauth", AUTO,
  833. AUTO, 0, FORCE_OFF, 1, FORCE_ON, 2, -1);
  834. test_int_translated(CONF_proxy_type, "ProxyMethod", PROXY_NONE,
  835. PROXY_NONE, 0, PROXY_SOCKS4, 1, PROXY_SOCKS5, 2,
  836. PROXY_HTTP, 3, PROXY_TELNET, 4, PROXY_CMD, 5,
  837. PROXY_SSH_TCPIP, 6, PROXY_SSH_EXEC, 7,
  838. PROXY_SSH_SUBSYSTEM, 8, -1);
  839. test_int_translated_load_legacy(
  840. CONF_proxy_type, "ProxyType", NULL, PROXY_NONE,
  841. PROXY_HTTP, 1, PROXY_SOCKS5, 2, PROXY_TELNET, 3, PROXY_CMD, 4, -1);
  842. test_int_translated_load_legacy(
  843. CONF_proxy_type, "ProxyType", load_prepare_socks4, PROXY_NONE,
  844. PROXY_HTTP, 1, PROXY_SOCKS4, 2, PROXY_TELNET, 3, PROXY_CMD, 4, -1);
  845. test_int_translated(CONF_remote_qtitle_action, "RemoteQTitleAction", TITLE_EMPTY,
  846. TITLE_NONE, 0, TITLE_EMPTY, 1, TITLE_REAL, 2, -1);
  847. test_int_translated_load_legacy(
  848. CONF_remote_qtitle_action, "NoRemoteQTitle", NULL, TITLE_EMPTY,
  849. TITLE_REAL, 0, TITLE_EMPTY, 1, -1);
  850. }
  851. void test_conf_key_info(void)
  852. {
  853. struct test_data {
  854. const char *name;
  855. bool got_value_type : 1;
  856. bool got_subkey_type : 1;
  857. bool got_default : 1;
  858. bool got_default_int : 1;
  859. bool got_default_str : 1;
  860. bool got_default_bool : 1;
  861. bool got_save_keyword : 1;
  862. bool got_storage_enum : 1;
  863. bool save_custom : 1;
  864. bool load_custom : 1;
  865. bool not_saved : 1;
  866. };
  867. #define CONF_OPTION(id, ...) { .name = "CONF_" #id, __VA_ARGS__ },
  868. #define VALUE_TYPE(x) .got_value_type = true
  869. #define SUBKEY_TYPE(x) .got_subkey_type = true
  870. #define DEFAULT_INT(x) .got_default_int = true, .got_default = true
  871. #define DEFAULT_STR(x) .got_default_str = true, .got_default = true
  872. #define DEFAULT_BOOL(x) .got_default_bool = true, .got_default = true
  873. #define SAVE_KEYWORD(x) .got_save_keyword = true
  874. #define STORAGE_ENUM(x) .got_storage_enum = true
  875. #define SAVE_CUSTOM .save_custom = true
  876. #define LOAD_CUSTOM .load_custom = true
  877. #define NOT_SAVED .not_saved = true
  878. static const struct test_data conf_key_test_data[] = {
  879. #include "conf.h"
  880. };
  881. for (size_t key = 0; key < N_CONFIG_OPTIONS; key++) {
  882. const ConfKeyInfo *info = &conf_key_info[key];
  883. const struct test_data *td = &conf_key_test_data[key];
  884. if (!td->got_value_type) {
  885. fprintf(stderr, "%s: no value type\n", td->name);
  886. nfails++;
  887. }
  888. if (td->got_default && info->subkey_type != CONF_TYPE_NONE) {
  889. fprintf(stderr, "%s: is a mapping but has a default\n", td->name);
  890. nfails++;
  891. }
  892. if ((td->got_default_int && info->value_type != CONF_TYPE_INT) ||
  893. (td->got_default_str &&
  894. (info->value_type != CONF_TYPE_STR &&
  895. info->value_type != CONF_TYPE_STR_AMBI &&
  896. info->value_type != CONF_TYPE_UTF8)) ||
  897. (td->got_default_bool && info->value_type != CONF_TYPE_BOOL)) {
  898. fprintf(stderr, "%s: default doesn't match type\n", td->name);
  899. nfails++;
  900. }
  901. if (td->got_storage_enum && info->value_type != CONF_TYPE_INT) {
  902. fprintf(stderr, "%s: has STORAGE_ENUM but isn't an int\n",
  903. td->name);
  904. nfails++;
  905. }
  906. if (td->not_saved) {
  907. if (!td->got_default && info->subkey_type == CONF_TYPE_NONE) {
  908. fprintf(stderr, "%s: simple unsaved setting but has no "
  909. "default\n", td->name);
  910. nfails++;
  911. }
  912. if (td->got_save_keyword) {
  913. fprintf(stderr, "%s: not saved but has SAVE_KEYWORD\n",
  914. td->name);
  915. nfails++;
  916. }
  917. if (td->save_custom) {
  918. fprintf(stderr, "%s: not saved but has SAVE_CUSTOM\n",
  919. td->name);
  920. nfails++;
  921. }
  922. if (td->load_custom) {
  923. fprintf(stderr, "%s: not saved but has LOAD_CUSTOM\n",
  924. td->name);
  925. nfails++;
  926. }
  927. if (td->got_storage_enum) {
  928. fprintf(stderr, "%s: not saved but has STORAGE_ENUM\n",
  929. td->name);
  930. nfails++;
  931. }
  932. } else {
  933. if (td->load_custom && td->save_custom) {
  934. if (td->got_save_keyword) {
  935. fprintf(stderr, "%s: no automatic save or load but has "
  936. "SAVE_KEYWORD\n", td->name);
  937. nfails++;
  938. }
  939. if (td->got_storage_enum) {
  940. fprintf(stderr, "%s: no automatic save or load but has "
  941. "STORAGE_ENUM\n", td->name);
  942. nfails++;
  943. }
  944. } else {
  945. if (!td->got_save_keyword) {
  946. fprintf(stderr, "%s: missing SAVE_KEYWORD\n", td->name);
  947. nfails++;
  948. }
  949. }
  950. }
  951. }
  952. }
  953. int main(void)
  954. {
  955. test_conf_key_info();
  956. test_simple();
  957. return nfails != 0;
  958. }