aboutsummaryrefslogtreecommitdiff
path: root/engines/glk
diff options
context:
space:
mode:
authorPaul Gilbert2019-09-23 21:15:25 -0700
committerPaul Gilbert2019-09-25 20:13:28 -0700
commit97686a7c030a685146bdb10e32f6cd8e4eb52d1e (patch)
treed9592eb6ba4e67a68bb9ddaaa374e93c518323af /engines/glk
parentf6f4d3ee11d81ef08d51d35cdf3055137374886e (diff)
downloadscummvm-rg350-97686a7c030a685146bdb10e32f6cd8e4eb52d1e.tar.gz
scummvm-rg350-97686a7c030a685146bdb10e32f6cd8e4eb52d1e.tar.bz2
scummvm-rg350-97686a7c030a685146bdb10e32f6cd8e4eb52d1e.zip
GLK: ADRIFT: Refactor TAF file parser to not use longjmp
Diffstat (limited to 'engines/glk')
-rw-r--r--engines/glk/adrift/sctafpar.cpp156
1 files changed, 78 insertions, 78 deletions
diff --git a/engines/glk/adrift/sctafpar.cpp b/engines/glk/adrift/sctafpar.cpp
index 6c2dcda2ae..7dd7edfb4d 100644
--- a/engines/glk/adrift/sctafpar.cpp
+++ b/engines/glk/adrift/sctafpar.cpp
@@ -22,6 +22,7 @@
#include "glk/adrift/scare.h"
#include "glk/adrift/scprotos.h"
+#include "glk/jumps.h"
namespace Glk {
namespace Adrift {
@@ -685,9 +686,6 @@ static const sc_char *parse_get_string_property(void) {
}
-/* Parse error jump buffer. */
-static jmp_buf parse_taf_error;
-
/* Pushback line, and pushback requested flag. */
static const sc_char *parse_pushback_line = NULL;
static sc_bool parse_use_pushback = FALSE;
@@ -702,7 +700,7 @@ static sc_bool parse_use_pushback = FALSE;
* the line content into an integer or boolean, and a function for effective
* TAF line pushback.
*/
-static const sc_char *parse_get_taf_string(void) {
+static const sc_char *parse_get_taf_string(CONTEXT) {
const sc_char *line;
/* If pushback requested, use that instead of reading. */
@@ -718,7 +716,7 @@ static const sc_char *parse_get_taf_string(void) {
sc_error("parse_get_taf_string:"
" out of TAF data at line %ld\n", parse_tafline);
parse_stack_backtrace();
- longjmp(parse_taf_error, 1);
+ LONG_JUMP0;
}
/* Note this line for possible pushback. */
@@ -733,23 +731,23 @@ static const sc_char *parse_get_taf_string(void) {
return line;
}
-static sc_int parse_get_taf_integer(void) {
+static sc_int parse_get_taf_integer(CONTEXT) {
const sc_char *line;
sc_int integer;
/* Get line, and scan for a single integer; return it. */
- line = parse_get_taf_string();
+ R0FUNC0(parse_get_taf_string, line);
if (sscanf(line, "%ld", &integer) != 1) {
sc_error("parse_get_taf_integer:"
" invalid integer at line %ld\n", parse_tafline - 1);
parse_stack_backtrace();
- longjmp(parse_taf_error, 1);
+ LONG_JUMP0;
}
return integer;
}
-static sc_bool parse_get_taf_boolean(void) {
+static sc_bool parse_get_taf_boolean(CONTEXT) {
const sc_char *line;
sc_uint boolean;
@@ -757,12 +755,12 @@ static sc_bool parse_get_taf_boolean(void) {
* Get line, and scan for a single integer; check it's a valid-looking flag,
* and return it.
*/
- line = parse_get_taf_string();
+ R0FUNC0(parse_get_taf_string, line);
if (sscanf(line, "%lu", &boolean) != 1) {
sc_error("parse_get_taf_boolean:"
" invalid boolean at line %ld\n", parse_tafline - 1);
parse_stack_backtrace();
- longjmp(parse_taf_error, 1);
+ LONG_JUMP0;
}
if (boolean != 0 && boolean != 1) {
sc_error("parse_get_taf_boolean:"
@@ -811,16 +809,16 @@ enum {
};
/* Forward declarations of parse functions for recursion. */
-static void parse_element(const sc_char *element);
-static void parse_class(const sc_char *class_);
-static void parse_descriptor(const sc_char *descriptor);
+static void parse_element(CONTEXT, const sc_char *element);
+static void parse_class(CONTEXT, const sc_char *class_);
+static void parse_descriptor(CONTEXT, const sc_char *descriptor);
/*
* parse_array()
*
* Parse a descriptor [] array.
*/
-static void parse_array(const sc_char *array) {
+static void parse_array(CONTEXT, const sc_char *array) {
sc_int count, index_;
sc_char element[PARSE_TEMP_LENGTH];
@@ -838,7 +836,7 @@ static void parse_array(const sc_char *array) {
vt_key.integer = index_;
parse_push_key(vt_key, PROP_KEY_INTEGER);
- parse_element(element);
+ CALL1(parse_element, element);
parse_pop_key();
}
@@ -855,7 +853,7 @@ static void parse_array(const sc_char *array) {
*
* Parse a variable-length vector of properties.
*/
-static void parse_vector_common(const sc_char *vector, sc_int count) {
+static void parse_vector_common(CONTEXT, const sc_char *vector, sc_int count) {
sc_int index_;
/* Parse the vector property count times, pushing a key on each. */
@@ -865,35 +863,35 @@ static void parse_vector_common(const sc_char *vector, sc_int count) {
vt_key.integer = index_;
parse_push_key(vt_key, PROP_KEY_INTEGER);
- parse_element(vector + 1);
+ CALL1(parse_element, vector + 1);
parse_pop_key();
}
}
-static void parse_vector(const sc_char *vector) {
+static void parse_vector(CONTEXT, const sc_char *vector) {
sc_int count;
if (parse_trace)
sc_trace("Parse: entering vector %s\n", vector);
/* Find the count of elements in the vector, and parse. */
- count = parse_get_taf_integer();
- parse_vector_common(vector, count);
+ FUNC0(parse_get_taf_integer, count);
+ CALL2(parse_vector_common, vector, count);
if (parse_trace)
sc_trace("Parse: leaving vector %s\n", vector);
}
-static void parse_vector_alternate(const sc_char *vector) {
+static void parse_vector_alternate(CONTEXT, const sc_char *vector) {
sc_int count;
if (parse_trace)
sc_trace("Parse: entering alternate vector %s\n", vector);
/* Element count, this is a vector described by size - 1. */
- count = parse_get_taf_integer() + 1;
- parse_vector_common(vector, count);
+ FUNC0(parse_get_taf_integer, count) + 1;
+ CALL2(parse_vector_common, vector, count);
if (parse_trace)
sc_trace("Parse: leaving alternate vector %s\n", vector);
@@ -965,7 +963,7 @@ static sc_bool parse_test_expression(const sc_char *test_expression) {
return retval;
}
-static void parse_expression(const sc_char *expression) {
+static void parse_expression(CONTEXT, const sc_char *expression) {
sc_char test_expression[PARSE_TEMP_LENGTH];
sc_bool is_present;
@@ -994,7 +992,7 @@ static void parse_expression(const sc_char *expression) {
sc_fatal("parse_expression: bad list, %s\n", expression + next);
/* Parse this isolated element. */
- parse_element(element);
+ CALL1(parse_element, element);
/* Advance to the start of the next element. */
next += strlen(element);
@@ -1013,7 +1011,7 @@ static void parse_expression(const sc_char *expression) {
* Helper for parse_terminal(), reads in a multiline string. The return
* string is malloc'ed, and the caller needs to handle that.
*/
-static sc_char *parse_read_multiline(void) {
+static sc_char *parse_read_multiline(CONTEXT) {
const sc_byte *separator = NULL;
const sc_char *line;
sc_char *multiline;
@@ -1035,18 +1033,18 @@ static sc_char *parse_read_multiline(void) {
}
/* Take a simple copy of the first line. */
- line = parse_get_taf_string();
+ R0FUNC0(parse_get_taf_string, line);
multiline = (sc_char *)sc_malloc(strlen(line) + 1);
strcpy(multiline, line);
/* Now concatenate until separator found. */
- line = parse_get_taf_string();
+ R0FUNC0(parse_get_taf_string, line);
while (memcmp(line, separator, SEPARATOR_SIZE) != 0) {
multiline = (sc_char *)sc_realloc(multiline,
strlen(multiline) + strlen(line) + 2);
strcat(multiline, "\n");
strcat(multiline, line);
- line = parse_get_taf_string();
+ R0FUNC0(parse_get_taf_string, line);
}
return multiline;
@@ -1058,7 +1056,7 @@ static sc_char *parse_read_multiline(void) {
*
* Common handler for string, integer, boolean, and multiline parse terminals.
*/
-static void parse_terminal(const sc_char *terminal) {
+static void parse_terminal(CONTEXT, const sc_char *terminal) {
sc_vartype_t vt_key, vt_value;
if (parse_trace)
@@ -1071,7 +1069,7 @@ static void parse_terminal(const sc_char *terminal) {
/* Retrieve, or invent, then store the value. */
switch (terminal[0]) {
case PARSE_INTEGER:
- vt_value.integer = parse_get_taf_integer();
+ FUNC0(parse_get_taf_integer, vt_value.integer);
parse_put_property(vt_value, PROP_INTEGER);
break;
case PARSE_DEFAULT_ZERO:
@@ -1080,7 +1078,7 @@ static void parse_terminal(const sc_char *terminal) {
break;
case PARSE_BOOLEAN:
- vt_value.boolean = parse_get_taf_boolean();
+ FUNC0(parse_get_taf_boolean, vt_value.boolean);
parse_put_property(vt_value, PROP_BOOLEAN);
break;
case PARSE_DEFAULT_FALSE:
@@ -1090,7 +1088,7 @@ static void parse_terminal(const sc_char *terminal) {
break;
case PARSE_STRING:
- vt_value.string = parse_get_taf_string();
+ FUNC0(parse_get_taf_string, vt_value.string);
parse_put_property(vt_value, PROP_STRING);
break;
case PARSE_DEFAULT_EMPTY:
@@ -1100,7 +1098,7 @@ static void parse_terminal(const sc_char *terminal) {
case PARSE_MULTILINE:
/* Assign to and adopt mutable string rather than const string. */
- vt_value.mutable_string = parse_read_multiline();
+ FUNC0(parse_read_multiline, vt_value.mutable_string);
parse_put_property(vt_value, PROP_STRING);
assert(parse_bundle);
@@ -1108,13 +1106,13 @@ static void parse_terminal(const sc_char *terminal) {
break;
case PARSE_IGNORE_INTEGER:
- (void) parse_get_taf_integer();
+ CALL0(parse_get_taf_integer);
break;
case PARSE_IGNORE_BOOLEAN:
- (void) parse_get_taf_boolean();
+ CALL0(parse_get_taf_boolean);
break;
case PARSE_IGNORE_STRING:
- (void) parse_get_taf_string();
+ CALL0(parse_get_taf_string);
break;
default:
@@ -1365,7 +1363,7 @@ static void parse_handle_v400_resources(sc_bool has_sound, sc_bool has_graphics)
* Handler for special items that can't be described accurately, and
* therefore need careful treatment.
*/
-static void parse_special(const sc_char *special) {
+static void parse_special(CONTEXT, const sc_char *special) {
if (parse_trace)
sc_trace("Parse: entering special %s\n", special);
@@ -1391,10 +1389,10 @@ static void parse_special(const sc_char *special) {
sc_int flag;
/* Get next flag, and if true, pushback and parse. */
- flag = parse_get_taf_integer();
+ FUNC0(parse_get_taf_integer, flag);
if (flag != 0) {
parse_taf_pushback();
- parse_descriptor("#Dest #Var1 #Var2 #Var3");
+ CALL1(parse_descriptor, "#Dest #Var1 #Var2 #Var3");
}
}
@@ -1404,10 +1402,10 @@ static void parse_special(const sc_char *special) {
sc_int flag;
/* Get next flag, and if true, pushback and parse. */
- flag = parse_get_taf_integer();
+ FUNC0(parse_get_taf_integer, flag);
if (flag != 0) {
parse_taf_pushback();
- parse_descriptor("#Dest #Var1 #Var2 ZVar3");
+ CALL1(parse_descriptor, "#Dest #Var1 #Var2 ZVar3");
}
}
@@ -1432,7 +1430,7 @@ static void parse_special(const sc_char *special) {
case ROOMLIST_ONE_ROOM:
/* Store this room as the single list entry. */
- parse_element("#Room");
+ CALL1(parse_element, "#Room");
break;
case ROOMLIST_SOME_ROOMS:
@@ -1452,7 +1450,7 @@ static void parse_special(const sc_char *special) {
sc_bool this_room;
/* Get flag for this room. */
- this_room = parse_get_taf_boolean();
+ FUNC0(parse_get_taf_boolean, this_room);
/* Store flag directly. */
vt_key.integer = index_;
@@ -1484,8 +1482,9 @@ static void parse_special(const sc_char *special) {
parse_pop_key();
/* Get Parent if the object is part of an NPC. */
- if (type == ROOMLIST_NPC_PART)
- parse_element("#Parent");
+ if (type == ROOMLIST_NPC_PART) {
+ CALL1(parse_element, "#Parent");
+ }
}
/* Parse a list of rooms and times for a walk. */
@@ -1509,7 +1508,7 @@ static void parse_special(const sc_char *special) {
vt_key.integer = index_;
parse_push_key(vt_key, PROP_KEY_INTEGER);
- room = parse_get_taf_integer();
+ FUNC0(parse_get_taf_integer, room);
vt_value.integer = room;
parse_put_property(vt_value, PROP_INTEGER);
@@ -1522,7 +1521,7 @@ static void parse_special(const sc_char *special) {
vt_key.integer = index_;
parse_push_key(vt_key, PROP_KEY_INTEGER);
- time = parse_get_taf_integer();
+ FUNC0(parse_get_taf_integer, time);
vt_value.integer = time;
parse_put_property(vt_value, PROP_INTEGER);
@@ -1544,7 +1543,7 @@ static void parse_special(const sc_char *special) {
/* Read a boolean for each room. */
l2index_ = 0;
for (index_ = 0; index_ < num_rooms; index_++) {
- in_group = parse_get_taf_boolean();
+ FUNC0(parse_get_taf_boolean, in_group);
/* Store raw flag as List[index_]. */
vt_key.string = "List";
@@ -1923,7 +1922,7 @@ static void parse_fixup_v390_v380_room_alts(void) {
* Handler for fixup special items to help with conversions from TAF version
* 3.9 format into version 4.0.
*/
-static void parse_fixup_v390(const sc_char *fixup) {
+static void parse_fixup_v390(CONTEXT, const sc_char *fixup) {
if (parse_trace)
sc_trace("Parse: entering version 3.9 fixup %s\n", fixup);
@@ -1956,10 +1955,11 @@ static void parse_fixup_v390(const sc_char *fixup) {
var2 = parse_get_integer_property();
parse_pop_key();
- if (var2 == 5)
- parse_descriptor("$Expr ZVar5");
- else
- parse_descriptor("EExpr #Var5");
+ if (var2 == 5) {
+ CALL1(parse_descriptor, "$Expr ZVar5");
+ } else {
+ CALL1(parse_descriptor, "EExpr #Var5");
+ }
}
/*
@@ -2964,7 +2964,7 @@ static void parse_fixup_v380(const sc_char *fixup) {
* Handler for fixup special items to help with conversions from TAF version
* 3.9 and version 3.8 formats into version 4.0.
*/
-static void parse_fixup(const sc_char *fixup) {
+static void parse_fixup(CONTEXT, const sc_char *fixup) {
/*
* Pick a fixup handler specific to the TAF version. This helps keep
* fixup code separate, rather than glommed into one large function.
@@ -2974,7 +2974,7 @@ static void parse_fixup(const sc_char *fixup) {
sc_fatal("parse_fixup: unexpected call\n");
break;
case TAF_VERSION_390:
- parse_fixup_v390(fixup);
+ CALL1(parse_fixup_v390, fixup);
break;
case TAF_VERSION_380:
parse_fixup_v380(fixup);
@@ -2991,32 +2991,32 @@ static void parse_fixup(const sc_char *fixup) {
*
* Parse a class descriptor element.
*/
-static void parse_element(const sc_char *element) {
+static void parse_element(CONTEXT, const sc_char *element) {
if (parse_trace)
sc_trace("Parse: entering element %s\n", element);
/* Determine the element type from the first character. */
switch (element[0]) {
case PARSE_ARRAY:
- parse_array(element);
+ CALL1(parse_array, element);
break;
case PARSE_VECTOR:
- parse_vector(element);
+ CALL1(parse_vector, element);
break;
case PARSE_VECTOR_ALTERNATE:
- parse_vector_alternate(element);
+ CALL1(parse_vector_alternate, element);
break;
case PARSE_CLASS:
- parse_class(element);
+ CALL1(parse_class, element);
break;
case PARSE_EXPRESSION:
- parse_expression(element);
+ CALL1(parse_expression, element);
break;
case PARSE_SPECIAL:
- parse_special(element);
+ CALL1(parse_special, element);
break;
case PARSE_FIXUP:
- parse_fixup(element);
+ CALL1(parse_fixup, element);
break;
case PARSE_INTEGER:
@@ -3030,7 +3030,7 @@ static void parse_element(const sc_char *element) {
case PARSE_IGNORE_BOOLEAN:
case PARSE_IGNORE_STRING:
case PARSE_MULTILINE:
- parse_terminal(element);
+ CALL1(parse_terminal, element);
break;
default:
sc_fatal("parse_element: bad type, %c\n", element[0]);
@@ -3046,7 +3046,7 @@ static void parse_element(const sc_char *element) {
*
* Parse a class's properties descriptor list.
*/
-static void parse_descriptor(const sc_char *descriptor) {
+static void parse_descriptor(CONTEXT, const sc_char *descriptor) {
sc_int next;
/* Find and parse each element in the descriptor. */
@@ -3058,7 +3058,7 @@ static void parse_descriptor(const sc_char *descriptor) {
sc_fatal("parse_element: no element, %s\n", descriptor + next);
/* Parse this isolated element. */
- parse_element(element);
+ CALL1(parse_element, element);
/* Advance over the element and any trailing whitespace. */
next += strlen(element);
@@ -3072,7 +3072,7 @@ static void parse_descriptor(const sc_char *descriptor) {
*
* Parse a class of properties.
*/
-static void parse_class(const sc_char *class_) {
+static void parse_class(CONTEXT, const sc_char *class_) {
sc_char class_name[PARSE_TEMP_LENGTH];
sc_int index_;
sc_vartype_t vt_key;
@@ -3102,7 +3102,7 @@ static void parse_class(const sc_char *class_) {
}
/* Parse each element in the descriptor. */
- parse_descriptor(parse_schema[index_].descriptor);
+ CALL1(parse_descriptor, parse_schema[index_].descriptor);
/* Pop a key if the class tag was pushed above. */
if (index_ > 0)
@@ -3354,6 +3354,7 @@ static void parse_add_version(sc_prop_setref_t bundle, sc_tafref_t taf) {
*/
sc_bool parse_game(sc_tafref_t taf, sc_prop_setref_t bundle) {
assert(taf && bundle);
+ Context context;
/* Store the TAF to read from, and the bundle to store into. */
parse_taf = taf;
@@ -3361,14 +3362,13 @@ sc_bool parse_game(sc_tafref_t taf, sc_prop_setref_t bundle) {
parse_schema = parse_select_schema(parse_taf);
parse_depth = 0;
- /* Try parsing, and catch errors from longjmp. */
- if (setjmp(parse_taf_error) == 0) {
- /* Parse a complete game. */
- taf_first_line(parse_taf);
- parse_tafline = 0;
- parse_class("<_GAME_>");
- } else {
- /* Error with one of the TAF file lines. */
+ // Try parsing a complete game
+ taf_first_line(parse_taf);
+ parse_tafline = 0;
+ parse_class(context, "<_GAME_>");
+
+ if (context._break) {
+ // Error with one of the TAF file lines
parse_clear_v400_resources_table();
parse_taf = NULL;
parse_bundle = NULL;