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; 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 // eat closing quote
if (GetQuotedByte() == CHAR_EOS) { GetByte();
alu_state = STATE_ERROR; // now convert to unescaped version
return; if (Input_unescape_dynabuf())
} goto fail; // escaping error
// }
// on empty string, complain // too short?
if (GotByte == closing_quote) { if (GlobalDynaBuf->size == 0) {
Throw_error(exception_missing_string); Throw_error(exception_missing_string);
alu_state = STATE_ERROR; goto fail;
return;
} }
// too long?
if (GlobalDynaBuf->size != 1)
Throw_error("There's more than one character.");
// parse character // parse character
value = (intval_t) encoding_encode_char(GotByte); value = (intval_t) encoding_encode_char(GLOBALDYNABUF_CURRENT[0]);
// 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;
}
}
PUSH_INT_ARG(value, NUMBER_IS_DEFINED | NUMBER_FITS_BYTE, 0); PUSH_INT_ARG(value, NUMBER_IS_DEFINED | NUMBER_FITS_BYTE, 0);
// Now GotByte = char following closing quote (or CHAR_EOS on error) // 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 // Skip or store block (starting with next byte, so call directly after
// reading opening brace). // reading opening brace).
// If "Store" is TRUE, the block is read into GlobalDynaBuf, then a copy // the block is read into GlobalDynaBuf.
// is made and a pointer to that is returned. // If "Store" is TRUE, then a copy is made and a pointer to that is returned.
// If "Store" is FALSE, NULL is returned. // If "Store" is FALSE, NULL is returned.
// After calling this function, GotByte holds '}'. Unless EOF was found first, // After calling this function, GotByte holds '}'. Unless EOF was found first,
// but then a serious error would have been thrown. // but then a serious error would have been thrown.
@ -364,9 +392,8 @@ char *Input_skip_or_store_block(boolean store)
DYNABUF_CLEAR(GlobalDynaBuf); DYNABUF_CLEAR(GlobalDynaBuf);
do { do {
byte = GetByte(); byte = GetByte();
// if wanted, store // store
if (store) DYNABUF_APPEND(GlobalDynaBuf, byte);
DYNABUF_APPEND(GlobalDynaBuf, byte);
// now check for some special characters // now check for some special characters
switch (byte) { switch (byte) {
case CHAR_EOF: // End-of-file in block? Sorry, no way. 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 '"': // Quotes? Okay, read quoted stuff.
case '\'': case '\'':
do { Input_quoted_to_dynabuf(byte);
GetQuotedByte(); DYNABUF_APPEND(GlobalDynaBuf, GotByte); // add closing quote
// 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!
break; break;
case CHAR_SOB: case CHAR_SOB:
++depth; ++depth;
@ -419,7 +441,8 @@ void Input_until_terminator(char terminator)
// Okay, read quoted stuff. // Okay, read quoted stuff.
GetQuotedByte(); // throws error on EOS GetQuotedByte(); // throws error on EOS
DYNABUF_APPEND(GlobalDynaBuf, GotByte); 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() // on error, exit now, before calling GetByte()
if (GotByte != byte) if (GotByte != byte)
return; return;
@ -551,7 +574,7 @@ int Input_read_filename(boolean allow_library, boolean *uses_lib)
return TRUE; 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 // read characters until closing quote (or EOS) is reached
// append platform-converted characters to current string // append platform-converted characters to current string
while ((GotByte != CHAR_EOS) && (GotByte != end_quote)) { 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 // Ensure that the remainder of the current statement is empty, for example
// after mnemonics using implied addressing. // after mnemonics using implied addressing.
extern void Input_ensure_EOS(void); 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 // Skip or store block (starting with next byte, so call directly after
// reading opening brace). // reading opening brace).
// If "Store" is TRUE, the block is read into GlobalDynaBuf, then a copy // the block is read into GlobalDynaBuf.
// is made and a pointer to that is returned. // If "Store" is TRUE, then a copy is made and a pointer to that is returned.
// If "Store" is FALSE, NULL is returned. // If "Store" is FALSE, NULL is returned.
// After calling this function, GotByte holds '}'. Unless EOF was found first, // After calling this function, GotByte holds '}'. Unless EOF was found first,
// but then a serious error would have been thrown. // but then a serious error would have been thrown.