コード例 #1
0
ファイル: input.c プロジェクト: JackStrongPL/CheeseCutter
// 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.
// 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.
char* Input_skip_or_store_block(bool store) {
	char	byte;
	int	depth	= 1;	// to find matching block end

	// prepare global dynamic buffer
	DYNABUF_CLEAR(GlobalDynaBuf);
	do {
		byte = GetByte();
		// if wanted, store
		if(store)
			DYNABUF_APPEND(GlobalDynaBuf, byte);
		// now check for some special characters
		switch(byte) {

			case CHAR_EOF:	// End-of-file in block? Sorry, no way.
			Throw_serious_error(exception_no_right_brace);

			case '"':	// Quotes? Okay, read quoted stuff.
			case '\'':
			do {
				GetQuotedByte();
				// if wanted, store
				if(store)
					DYNABUF_APPEND(GlobalDynaBuf, GotByte);
			} while((GotByte != CHAR_EOS) && (GotByte != byte));
			break;

			case CHAR_SOB:
			depth++;
			break;

			case CHAR_EOB:
			depth--;
			break;

		}
	} while(depth);
	// in case of skip, return now
	if(!store)
		return(NULL);
	// otherwise, prepare to return copy of block
	// add EOF, just to make sure block is never read too far
	DynaBuf_append(GlobalDynaBuf, CHAR_EOS);
	DynaBuf_append(GlobalDynaBuf, CHAR_EOF);
	// return pointer to copy
	return(DynaBuf_get_copy(GlobalDynaBuf));
}
コード例 #2
0
ファイル: macro.c プロジェクト: lhz/acme
// Check for comma. If there, append to GlobalDynaBuf.
static int pipe_comma(void)
{
    int	result;

    result = Input_accept_comma();
    if (result)
        DYNABUF_APPEND(GlobalDynaBuf, ',');
    return result;
}
コード例 #3
0
ファイル: input.c プロジェクト: JackStrongPL/CheeseCutter
// Try to read a file name. If "allow_library" is TRUE, library access by using
// <...> quoting is possible as well. The file name given in the assembler
// source code is converted from UNIX style to platform style.
// Returns whether error occurred (TRUE on error). Filename in GlobalDynaBuf.
// Errors are handled and reported, but caller should call
// Input_skip_remainder() then.
bool Input_read_filename(bool allow_library) {
	char	*lib_prefix,
		end_quote;

	DYNABUF_CLEAR(GlobalDynaBuf);
	SKIPSPACE();
	// check for library access
	if(GotByte == '<') {
		// if library access forbidden, complain
		if(allow_library == FALSE) {
			Throw_error("Writing to library not supported.");
			return(TRUE);
		}
		// read platform's lib prefix
		lib_prefix = PLATFORM_LIBPREFIX;
#ifndef NO_NEED_FOR_ENV_VAR
		// if lib prefix not set, complain
		if(lib_prefix == NULL) {
			Throw_error("\"ACME\" environment variable not found.");
			return(TRUE);
		}
#endif
		// copy lib path and set quoting char
		DynaBuf_add_string(GlobalDynaBuf, lib_prefix);
		end_quote = '>';
	} else {
		if(GotByte == '"')
			end_quote = '"';
		else {
			Throw_error("File name quotes not found (\"\" or <>).");
			return(TRUE);
		}
	}
	// read first character, complain if closing quote
	if(GetQuotedByte() == end_quote) {
		Throw_error("No file name given.");
		return(TRUE);
	}
	// read characters until closing quote (or EOS) is reached
	// append platform-converted characters to current string
	while((GotByte != CHAR_EOS) && (GotByte != end_quote)) {
		DYNABUF_APPEND(GlobalDynaBuf, PLATFORM_CONVERTPATHCHAR(GotByte));
		GetQuotedByte();
	}
	// on error, return
	if(GotByte == CHAR_EOS)
		return(TRUE);
	GetByte();	// fetch next to forget closing quote
	// terminate string
	DynaBuf_append(GlobalDynaBuf, '\0');	// add terminator
	return(FALSE);	// no error
}
コード例 #4
0
ファイル: input.c プロジェクト: JackStrongPL/CheeseCutter
// Append to GlobalDynaBuf while characters are legal for keywords.
// Throws "missing string" error if none.
// Returns number of characters added.
int Input_append_keyword_to_global_dynabuf(void) {
	int	length	= 0;

	// add characters to buffer until an illegal one comes along
	while(BYTEFLAGS(GotByte) & CONTS_KEYWORD) {
		DYNABUF_APPEND(GlobalDynaBuf, GotByte);
		length++;
		GetByte();
	}
	if(length == 0)
		Throw_error(exception_missing_string);
	return(length);
}
コード例 #5
0
ファイル: input.c プロジェクト: JackStrongPL/CheeseCutter
// Read bytes and add to GlobalDynaBuf until the given terminator (or CHAR_EOS)
// is found. Act upon single and double quotes by entering (and leaving) quote
// mode as needed (So the terminator does not terminate when inside quotes).
void Input_until_terminator(char terminator) {
	char	byte	= GotByte;

	do {
		// Terminator? Exit. EndOfStatement? Exit.
		if((byte == terminator) || (byte == CHAR_EOS))
			return;
		// otherwise, append to GlobalDynaBuf and check for quotes
		DYNABUF_APPEND(GlobalDynaBuf, byte);
		if((byte == '"') || (byte == '\'')) {
			do {
				// Okay, read quoted stuff.
				GetQuotedByte();// throws error on EOS
				DYNABUF_APPEND(GlobalDynaBuf, GotByte);
			} while((GotByte != CHAR_EOS) && (GotByte != byte));
			// on error, exit now, before calling GetByte()
			if(GotByte != byte)
				return;
		}
		byte = GetByte();
	} while(TRUE);
}
コード例 #6
0
ファイル: basics.c プロジェクト: martinpiper/ACME
// show user-defined message
static enum eos_t throw_string(const char prefix[], void (*fn)(const char*)) {
	result_t	result;

	DYNABUF_CLEAR(user_message);
	DynaBuf_add_string(user_message, prefix);
	do {
		if(GotByte == '"') {
			// parse string
			GetQuotedByte();	// read initial character
			// send characters until closing quote is reached
			while(GotByte && (GotByte != '"')) {
				DYNABUF_APPEND(user_message, GotByte);
				GetQuotedByte();
			}
			if(GotByte == CHAR_EOS)
				return(AT_EOS_ANYWAY);
			// after closing quote, proceed with next char
			GetByte();
		} else {
			// parse value
			ALU_any_result(&result);
			if(result.flags & MVALUE_IS_FP) {
				// floating point
				if(result.flags & MVALUE_DEFINED)
					DynaBuf_add_double(
						user_message,
						result.val.fpval);
				else
					DynaBuf_add_string(
						user_message,
						"<UNDEFINED FLOAT>");
			} else {
				// integer
				if(result.flags & MVALUE_DEFINED)
					DynaBuf_add_signed_long(
						user_message,
						result.val.intval);
				else
					DynaBuf_add_string(
						user_message,
						"<UNDEFINED INT>");
			}
		}
	} while(Input_accept_comma());
	DynaBuf_append(user_message, '\0');
	fn(user_message->buffer);
	return(ENSURE_EOS);
}
コード例 #7
0
ファイル: label.c プロジェクト: actraiser/dust-bundle-c64-mac
// fix name of anonymous forward label (held in DynaBuf, NOT TERMINATED!) so it
// references the *next* anonymous forward label definition. The tricky bit is,
// each name length would need its own counter. But hey, ACME's real quick in
// finding labels, so I'll just abuse the label system to store those counters.
struct label_t *Label_fix_forward_name(void)
{
	struct label_t	*counter_label;
	unsigned long	number;

	// terminate name, find "counter" label and read value
	DynaBuf_append(GlobalDynaBuf, '\0');
	counter_label = Label_find(Section_now->zone, 0);
	// make sure it gets reset to zero in each new pass
	if (counter_label->pass != pass_count) {
		counter_label->pass = pass_count;
		counter_label->result.val.intval = 0;
	}
	number = (unsigned long) counter_label->result.val.intval;
	// now append to the name to make it unique
	GlobalDynaBuf->size--;	// forget terminator, we want to append
	do {
		DYNABUF_APPEND(GlobalDynaBuf, 'a' + (number & 15));
		number >>= 4;
	} while (number);
	DynaBuf_append(GlobalDynaBuf, '\0');
	return counter_label;
}
コード例 #8
0
ファイル: dynabuf.c プロジェクト: Jedzia/acm3
// Append string to buffer (without terminator)
void DynaBuf_add_string(dynabuf_t* db, const char* string) {
	char	byte;

	while((byte = *string++))
		DYNABUF_APPEND(db, byte);
}
コード例 #9
0
ファイル: dynabuf.c プロジェクト: Jedzia/acm3
// add char to buffer
void DynaBuf_append(dynabuf_t* db, char byte) {
	DYNABUF_APPEND(db, byte);
}