Make script much friendlier to use

It now simply sets an error message pointer and returns false if there's
an error.
This commit is contained in:
Bill Currie 2020-02-26 09:39:03 +09:00
parent 4c1b6ce76c
commit 42713cad8b
4 changed files with 28 additions and 46 deletions

View file

@ -41,8 +41,9 @@ typedef struct script_s {
/// line number of the file being processed. used only for error reporting
/// but updated internally.
int line;
/// if set, will be called instead of the internal error handler
void (*error)(struct script_s *script, const char *msg);
/// contains last error message or null if no error
/// if set, no tokens will be parsed.
const char *error;
/// if set, multi line quoted tokens will be treated as errors
int no_quote_lines;
/// if set, characters in this string will always be lexed as single
@ -65,6 +66,7 @@ void Script_Delete (script_t *script);
/** Prepare a script_t object for parsing.
The caller is responsible for freeing the memory associated with file and
data when parsing is complete.
Resets \a script->error
\param script The script_t object being parsed
\param file Name of the file being parsed. used only for error reporting
\param data The script to be parsed

View file

@ -197,12 +197,6 @@ source_path_f (cvar_t *var)
source_paths[i] = 0;
}
static void
pr_debug_expression_error (script_t *script, const char *msg)
{
Sys_Printf ("%s\n", msg);
}
#define RUP(x,a) (((x) + ((a) - 1)) & ~((a) - 1))
static pr_short_t __attribute__((pure))
pr_debug_type_size (const progs_t *pr, const qfot_type_t *type)
@ -266,7 +260,6 @@ parse_expression (progs_t *pr, const char *expr, int conditional)
d.type = ev_invalid;
d.name = 0;
es = Script_New ();
es->error = pr_debug_expression_error;
Script_Start (es, "<console>", expr);
expr_ptr = 0;
es->single = "{}()':[].";
@ -323,6 +316,9 @@ parse_expression (progs_t *pr, const char *expr, int conditional)
Sys_Printf ("ignoring tail\n");
}
error:
if (es->error) {
Sys_Printf (es->error);
}
Script_Delete (es);
return d;
}

View file

@ -48,7 +48,6 @@ typedef struct {
script_t script;
string_t dstr;
progs_t *pr;
string_t err_msg;
} rua_script_t;
typedef struct {
@ -92,13 +91,6 @@ bi_script_clear (progs_t *pr, void *data)
script_reset (res);
}
static void
bi_script_error (script_t *_script, const char *msg)
{
rua_script_t *script = (rua_script_t *)_script;
script->err_msg = PR_SetString (script->pr, msg);
}
static void
bi_Script_New (progs_t *pr)
{
@ -110,7 +102,6 @@ bi_Script_New (progs_t *pr)
script->dstr = PR_NewMutableString (pr);
script->script.token = PR_GetMutableString (pr, script->dstr);
script->script.error = bi_script_error;
script->pr = pr;
R_INT (pr) = script_index (res, script);
}
@ -180,8 +171,8 @@ bi_Script_Error (progs_t *pr)
if (!script)
PR_RunError (pr, "invalid script handle");
R_STRING (pr) = script->err_msg;
script->err_msg = 0;
R_STRING (pr) = PR_SetString (pr, script->script.error);
script->script.error = 0;
}
static void

View file

@ -34,19 +34,6 @@
#include "QF/dstring.h"
#include "QF/script.h"
static void __attribute__ ((format (printf, 2, 3), noreturn))
script_error (script_t *script, const char *fmt, ...)
{
va_list args;
va_start (args, fmt);
fprintf (stderr, "%s:%d: ", script->file, script->line);
vfprintf (stderr, fmt, args);
fprintf (stderr, "\n");
va_end (args);
exit (1);
}
VISIBLE script_t *
Script_New (void)
{
@ -69,11 +56,16 @@ Script_Start (script_t *script, const char *file, const char *data)
script->file = file;
script->p = data;
script->unget = false;
script->error = 0;
}
VISIBLE qboolean
Script_TokenAvailable (script_t *script, qboolean crossline)
{
if (script->error) {
return false;
}
if (script->unget)
return true;
skipspace:
@ -111,6 +103,10 @@ Script_GetToken (script_t *script, qboolean crossline)
{
const char *token_p;
if (script->error) {
return false;
}
if (script->unget) { // is a token allready waiting?
script->unget = false;
return true;
@ -118,10 +114,7 @@ Script_GetToken (script_t *script, qboolean crossline)
if (!Script_TokenAvailable (script, crossline)) {
if (!crossline) {
if (script->error)
script->error (script, "line is incomplete");
else
script_error (script, "line is incomplete");
script->error = "line is incomplete";
}
return false;
}
@ -134,18 +127,13 @@ Script_GetToken (script_t *script, qboolean crossline)
while (*script->p != '"') {
if (!*script->p) {
script->line = start_line;
if (script->error)
script->error (script, "EOF inside quoted token");
else
script_error (script, "EOF inside quoted token");
script->error = "EOF inside quoted token";
return false;
}
if (*script->p == '\n') {
if (script->no_quote_lines) {
if (script->error)
script->error (script, "EOL inside quoted token");
else
script_error (script, "EOL inside quoted token");
script->error = "EOL inside quoted token";
return false;
}
script->line++;
}
@ -175,11 +163,16 @@ Script_GetToken (script_t *script, qboolean crossline)
VISIBLE void
Script_UngetToken (script_t *script)
{
script->unget = true;
if (!script->error) {
script->unget = true;
}
}
VISIBLE const char *
Script_Token (script_t *script)
{
if (script->error) {
return 0;
}
return script->token->str;
}