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

View file

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

View file

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

View file

@ -34,19 +34,6 @@
#include "QF/dstring.h" #include "QF/dstring.h"
#include "QF/script.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 * VISIBLE script_t *
Script_New (void) Script_New (void)
{ {
@ -69,11 +56,16 @@ Script_Start (script_t *script, const char *file, const char *data)
script->file = file; script->file = file;
script->p = data; script->p = data;
script->unget = false; script->unget = false;
script->error = 0;
} }
VISIBLE qboolean VISIBLE qboolean
Script_TokenAvailable (script_t *script, qboolean crossline) Script_TokenAvailable (script_t *script, qboolean crossline)
{ {
if (script->error) {
return false;
}
if (script->unget) if (script->unget)
return true; return true;
skipspace: skipspace:
@ -111,6 +103,10 @@ Script_GetToken (script_t *script, qboolean crossline)
{ {
const char *token_p; const char *token_p;
if (script->error) {
return false;
}
if (script->unget) { // is a token allready waiting? if (script->unget) { // is a token allready waiting?
script->unget = false; script->unget = false;
return true; return true;
@ -118,10 +114,7 @@ Script_GetToken (script_t *script, qboolean crossline)
if (!Script_TokenAvailable (script, crossline)) { if (!Script_TokenAvailable (script, crossline)) {
if (!crossline) { if (!crossline) {
if (script->error) script->error = "line is incomplete";
script->error (script, "line is incomplete");
else
script_error (script, "line is incomplete");
} }
return false; return false;
} }
@ -134,18 +127,13 @@ Script_GetToken (script_t *script, qboolean crossline)
while (*script->p != '"') { while (*script->p != '"') {
if (!*script->p) { if (!*script->p) {
script->line = start_line; script->line = start_line;
if (script->error) script->error = "EOF inside quoted token";
script->error (script, "EOF inside quoted token");
else
script_error (script, "EOF inside quoted token");
return false; return false;
} }
if (*script->p == '\n') { if (*script->p == '\n') {
if (script->no_quote_lines) { if (script->no_quote_lines) {
if (script->error) script->error = "EOL inside quoted token";
script->error (script, "EOL inside quoted token"); return false;
else
script_error (script, "EOL inside quoted token");
} }
script->line++; script->line++;
} }
@ -175,11 +163,16 @@ Script_GetToken (script_t *script, qboolean crossline)
VISIBLE void VISIBLE void
Script_UngetToken (script_t *script) Script_UngetToken (script_t *script)
{ {
script->unget = true; if (!script->error) {
script->unget = true;
}
} }
VISIBLE const char * VISIBLE const char *
Script_Token (script_t *script) Script_Token (script_t *script)
{ {
if (script->error) {
return 0;
}
return script->token->str; return script->token->str;
} }