refactored a bit to prepare for backslash escaping

git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@175 4df02467-bbd4-4a76-a152-e7ce94205b78
This commit is contained in:
marcobaye 2020-05-19 11:09:46 +00:00
parent 3448cda3df
commit beaf86da5b
3 changed files with 70 additions and 38 deletions

View File

@ -379,35 +379,35 @@ static void parse_quoted_character(char closing_quote)
{
intval_t value;
// FIXME - this will fail with backslash escaping!
// this can be used later on for real strings as well {
DYNABUF_CLEAR(GlobalDynaBuf);
if (Input_quoted_to_dynabuf(closing_quote))
goto fail; // unterminated or escaping error
// read character to parse - make sure not at end of statement
if (GetQuotedByte() == CHAR_EOS) {
alu_state = STATE_ERROR;
return;
}
// on empty string, complain
if (GotByte == closing_quote) {
// eat closing quote
GetByte();
// now convert to unescaped version
if (Input_unescape_dynabuf())
goto fail; // escaping error
// }
// too short?
if (GlobalDynaBuf->size == 0) {
Throw_error(exception_missing_string);
alu_state = STATE_ERROR;
return;
goto fail;
}
// too long?
if (GlobalDynaBuf->size != 1)
Throw_error("There's more than one character.");
// parse character
value = (intval_t) encoding_encode_char(GotByte);
// Read closing quote (hopefully)
if (GetQuotedByte() == closing_quote) {
GetByte(); // if length == 1, proceed with next byte
} else {
if (GotByte) {
// if longer than one character
Throw_error("There's more than one character.");
alu_state = STATE_ERROR;
}
}
value = (intval_t) encoding_encode_char(GLOBALDYNABUF_CURRENT[0]);
PUSH_INT_ARG(value, NUMBER_IS_DEFINED | NUMBER_FITS_BYTE, 0);
// Now GotByte = char following closing quote (or CHAR_EOS on error)
return;
fail:
PUSH_INT_ARG(0, NUMBER_IS_DEFINED | NUMBER_FITS_BYTE, 0); // dummy
alu_state = STATE_ERROR;
}

View File

@ -347,10 +347,38 @@ void Input_ensure_EOS(void) // Now GotByte = first char to test
}
}
// read string to dynabuf until closing quote is found
// returns 1 on errors (unterminated, escaping error)
int Input_quoted_to_dynabuf(char closing_quote)
{
//DYNABUF_CLEAR(GlobalDynaBuf); // do not clear, caller might want to append to existing contents (TODO - check!)
for (;;) {
GetQuotedByte();
// FIXME - this will fail with backslash escaping!
// it's not enough to check the previous char for backslash, because it might be an escaped backslash...
if (GotByte == closing_quote)
return 0; // ok
if (GotByte == CHAR_EOS)
return 1; // unterminated string constant (GetQuotedByte will have complained already)
DYNABUF_APPEND(GlobalDynaBuf, GotByte);
}
}
// process backslash escapes in GlobalDynaBuf (so size might shrink)
// returns 1 on errors (escaping errors)
int Input_unescape_dynabuf(void)
{
// FIXME - implement backslash escaping!
// TODO - shorten GlobalDynaBuf->size accordingly
return 0;
}
// Skip or store block (starting with next byte, so call directly after
// reading opening brace).
// If "Store" is TRUE, the block is read into GlobalDynaBuf, then a copy
// is made and a pointer to that is returned.
// the block is read into GlobalDynaBuf.
// If "Store" is TRUE, then a copy is made and a pointer to that is returned.
// If "Store" is FALSE, NULL is returned.
// After calling this function, GotByte holds '}'. Unless EOF was found first,
// but then a serious error would have been thrown.
@ -364,9 +392,8 @@ char *Input_skip_or_store_block(boolean store)
DYNABUF_CLEAR(GlobalDynaBuf);
do {
byte = GetByte();
// if wanted, store
if (store)
DYNABUF_APPEND(GlobalDynaBuf, byte);
// store
DYNABUF_APPEND(GlobalDynaBuf, byte);
// now check for some special characters
switch (byte) {
case CHAR_EOF: // End-of-file in block? Sorry, no way.
@ -374,13 +401,8 @@ char *Input_skip_or_store_block(boolean store)
case '"': // Quotes? Okay, read quoted stuff.
case '\'':
do {
GetQuotedByte();
// if wanted, store
if (store)
DYNABUF_APPEND(GlobalDynaBuf, GotByte);
// it's not enough to check the previous char for backslash, because it might be an escaped backslash...
} while ((GotByte != CHAR_EOS) && (GotByte != byte)); // FIXME - this would fail with backslash escaping!
Input_quoted_to_dynabuf(byte);
DYNABUF_APPEND(GlobalDynaBuf, GotByte); // add closing quote
break;
case CHAR_SOB:
++depth;
@ -419,7 +441,8 @@ void Input_until_terminator(char terminator)
// Okay, read quoted stuff.
GetQuotedByte(); // throws error on EOS
DYNABUF_APPEND(GlobalDynaBuf, GotByte);
} while ((GotByte != CHAR_EOS) && (GotByte != byte)); // FIXME - this would fail with backslash escaping!
// FIXME - this would fail with backslash escaping!
} while ((GotByte != CHAR_EOS) && (GotByte != byte));
// on error, exit now, before calling GetByte()
if (GotByte != byte)
return;
@ -551,7 +574,7 @@ int Input_read_filename(boolean allow_library, boolean *uses_lib)
return TRUE;
}
// FIXME - this will fail with backslash escaping!
// FIXME - this will fail with backslash escaping!
// read characters until closing quote (or EOS) is reached
// append platform-converted characters to current string
while ((GotByte != CHAR_EOS) && (GotByte != end_quote)) {

View File

@ -72,10 +72,19 @@ extern void Input_skip_remainder(void);
// Ensure that the remainder of the current statement is empty, for example
// after mnemonics using implied addressing.
extern void Input_ensure_EOS(void);
// read string to dynabuf until closing quote is found
// returns 1 on errors (unterminated, escaping error)
extern int Input_quoted_to_dynabuf(char closing_quote);
// process backslash escapes in GlobalDynaBuf (so size might shrink)
// returns 1 on errors (escaping errors)
extern int Input_unescape_dynabuf(void);
// Skip or store block (starting with next byte, so call directly after
// reading opening brace).
// If "Store" is TRUE, the block is read into GlobalDynaBuf, then a copy
// is made and a pointer to that is returned.
// the block is read into GlobalDynaBuf.
// If "Store" is TRUE, then a copy is made and a pointer to that is returned.
// If "Store" is FALSE, NULL is returned.
// After calling this function, GotByte holds '}'. Unless EOF was found first,
// but then a serious error would have been thrown.