Bare-bones for now, more tests needed.
=== parse_config
Parse string as if it was read from a config file.
+Always call parse_config_errors afterwards to check for any parsing errors.
Example:
nh.parse_config("OPTIONS=color");
+=== parse_config_errors
+
+Returns any errors found when parsing a config file string with parse_config.
+
+Example:
+
+ local errors = nh.parse_config("OPTIONS=color\nOPTIONS=!color");
+ nh.pline("Line: " .. errors[1].line .. ", " .. errors[1].error);
+
+
=== pline
Show the text in the message area.
/* ### files.c ### */
+#if !defined(CROSSCOMPILE) || defined(CROSSCOMPILE_TARGET)
+extern int l_get_config_errors(lua_State *);
+#endif
extern char *fname_encode(const char *, char, char *, char *, int);
extern char *fname_decode(char, char *, char *, int);
extern const char *fqname(const char *, int, int);
}
#endif /* USER_SOUNDS */
+struct _config_error_errmsg {
+ int line_num;
+ char *errormsg;
+ struct _config_error_errmsg *next;
+};
+
struct _config_error_frame {
int line_num;
int num_errors;
};
static struct _config_error_frame *config_error_data = 0;
+static struct _config_error_errmsg *config_error_msg = 0;
void
config_error_init(boolean from_file, const char *sourcename, boolean secure)
return TRUE;
}
+int
+l_get_config_errors(lua_State *L)
+{
+ struct _config_error_errmsg *dat = config_error_msg;
+ struct _config_error_errmsg *tmp;
+ int idx = 1;
+
+ lua_newtable(L);
+
+ while (dat) {
+ lua_pushinteger(L, idx++);
+ lua_newtable(L);
+ nhl_add_table_entry_int(L, "line", dat->line_num);
+ nhl_add_table_entry_str(L, "error", dat->errormsg);
+ lua_settable(L, -3);
+ tmp = dat->next;
+ free(dat->errormsg);
+ dat->errormsg = (char *) 0;
+ free(dat);
+ dat = tmp;
+ }
+ config_error_msg = (struct _config_error_errmsg *) 0;
+
+ return 1;
+}
+
/* varargs 'config_error_add()' moved to pline.c */
void
config_erradd(const char *buf)
if (!buf || !*buf)
buf = "Unknown error";
+ if (iflags.in_lua) {
+ struct _config_error_errmsg *dat = (struct _config_error_errmsg *) alloc(sizeof (struct _config_error_errmsg));
+
+ dat->next = config_error_msg;
+ dat->line_num = config_error_data->line_num;
+ dat->errormsg = dupstr(buf);
+ config_error_msg = dat;
+ return;
+ }
+
if (!config_error_data) {
/* either very early, where pline() will use raw_print(), or
player gave bad value when prompted by interactive 'O' command */
{"level_difficulty", nhl_level_difficulty},
{"parse_config", nhl_parse_config},
{"get_config", nhl_get_config},
+ {"get_config_errors", l_get_config_errors},
{NULL, NULL}
};
--- /dev/null
+
+local configtests = {
+ { test = "OPTIONS=color", -- config string to parse
+ result = { }, -- errors, result of parsing the config string
+ extra = function() return nh.get_config("color") == "true" end -- optional, function that returns boolean, and false means the test failed.
+ },
+ { test = "OPTIONS=!color",
+ result = { },
+ extra = function() return nh.get_config("color") == "false" end
+ },
+ { test = "OPTIONS=!color\nOPTIONS=color",
+ result = { { line = 2, error = "boolean option specified multiple times: color" } }
+ },
+};
+
+
+function testtable(t1, t2)
+ if type(t1) ~= type(t2) then return false end
+
+ for k1, v1 in pairs(t1) do
+ if type(v1) == "table" and type(t2[k1]) == "table" then
+ if not testtable(v1, t2[k1]) then return false end
+ else
+ if v1 ~= t2[k1] then return false end
+ end
+ end
+
+ return true
+end
+
+
+
+for k, v in pairs(configtests) do
+ local cnf = configtests[k].test;
+ local err = configtests[k].result;
+ nh.parse_config(cnf);
+ local res = nh.get_config_errors();
+
+ if not testtable(err, res) then
+ error("Config: Results don't match");
+ end
+
+ if (type(configtests[k].extra) == "function") then
+ if configtests[k].extra() == "false" then
+ error("Config: Failed extra test.");
+ end
+ end
+
+end