From 8f4a00e3ce8fc7fd475f128bb1868bd0c0c411dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carl-Henrik=20Sk=C3=A5rstedt?= Date: Fri, 23 Dec 2016 13:56:57 -0800 Subject: [PATCH] Fixing label pools * label pools don't go out of scope so they can be declared in an include file and used by the includer file * label pool labels can be either global or local * code fixes * updated struse * updated binaries --- README.md | 2 + struse.h | 420 ++++++++++++++++++++++++++++++++++++++++++++++-------- x65.cpp | 83 +++++------ 3 files changed, 398 insertions(+), 107 deletions(-) diff --git a/README.md b/README.md index ceb4dd0..f2dc93a 100644 --- a/README.md +++ b/README.md @@ -101,6 +101,8 @@ Primarily tested with personal archive of sources written for Kick assmebler, DA * irp (indefinite repeat) **FIXED** +* Label Pools were destroyed after each scope so they did not work in include files which defeated their purpose. Label pools are now persistent through scopes. +* Labels reserved from label pools now distinguish between global and local. Use [.!@$] as a prefix to reserve a local label from a label pool (previously always local) * Merlin macro parameters are not required on the MAC line, scope braces ('{', '}') can be used in the first column in Merlin. * First line of a Merlin macro was sometimes ignored, two sequential subtractions were ignored in expressions. * Pushing source contexts (macro, rept, include etc.) will always increment the scope depth. diff --git a/struse.h b/struse.h index d31ec7a..97be4b0 100644 --- a/struse.h +++ b/struse.h @@ -35,7 +35,7 @@ Add this #define to *one* C++ file before #include "struse.h" to create the impl #ifndef __STRUSE_H__ #define __STRUSE_H__ -#include +#include // uint8_t etc. #include // memcpy, memmove #include // printf, vsnprintf #include // va_list @@ -90,6 +90,7 @@ public: strl_t get_len() const { return length; } char get_first() const { return (string && length) ? *string : 0; } char get_last() const { return (string && length) ? string[length-1] : 0; } + char pop_first() { if (length && string) { char c = *string++; --length; return c; } return 0; } strl_t limit_pos(strl_t pos) { return pos=0) return strref(string+o+1, length-o-1); return strref(); } + strref after_last(char c, char d) const { int o = find_last(c, d); if (o>=0) + return strref(string+o+1, length-o-1); return strref(); } + strref get_alphanumeric() const { strref r(*this); r.skip_whitespace(); if (strl_t l = r.len_alphanumeric()) return strref(string, l); return strref(); } @@ -558,25 +569,26 @@ public: if (e>=0) return get_substr(strl_t(s+1), strl_t(e-s-1)); } return strref(); } // tokenization - strref split(strl_t pos) { pos = limit_pos(pos); strref ret = strref(string, pos); *this += pos; return ret; } - strref split(int pos) { split(strl_t(pos)); } - strref split_token(char c) { int t = find(c); if (t<0) t = (int)length; strref r = strref(string, strl_t(t)); *this += t+1; return r; } - strref split_token_any(const strref chars) { strref r; int t = find_any_char_of(chars); - if (t>=0) { r = strref(string, t); *this += t; } return r; } - strref split_token_trim(char c) { strref r = split_token(c); skip_whitespace(); r.trim_whitespace(); return r; } - strref split_token_any_trim(const strref chars) { int t = find_any_char_of(chars); - if (t<0) t = (int)length; strref r = strref(string, t); *this += t+1; r.trim_whitespace(); return r; } - strref split_range(const strref range, strl_t pos=0) { int t = find_any_char_or_range(range, pos); - if (t<0) t = (int)length; strref r = strref(string, t); *this += t; return r; } - strref split_range_trim(const strref range, strl_t pos=0) { int t = find_any_char_or_range(range, pos); - if (t<0) t = (int)length; strref r = strref(string, t); *this += t; r.trim_whitespace(); trim_whitespace(); return r; } - strref split_label() { skip_whitespace(); strref r(string, len_label()); *this += r.length; skip_whitespace(); return r; } + strref split(strl_t pos); + strref split(int pos); + strref split_token(char c); + strref split_token_any(const strref chars); + strref split_token_trim(char c); + strref split_token_any_trim(const strref chars); + strref split_range(const strref range, strl_t pos=0); + strref split_range_trim(const strref range, strl_t pos=0); + strref split_label(); + strref split_lang(); + + // get a snippet, previous and full current line around a position + strref get_snippet( strl_t pos ); // grab a block of text starting with (, [ or { and end with the corresponding number of ), ] or } strref scoped_block_skip(); // scoped_block_skip with C style comments - strref scoped_block_comment_skip(bool include = false); + strl_t scoped_block_comment_len(); + strref scoped_block_comment_skip(bool include = false) { strref ret = split(scoped_block_comment_len()); if (!include) { ++ret; ret.clip(1); } return ret; } // check matching characters that are terminated by any character in term or ends strl_t match_chars_str(const strref match, const strref term = strref()); @@ -614,8 +626,6 @@ strl_t _strmod_copy(char *string, strl_t cap, const char *str); strl_t _strmod_copy(char *string, strl_t cap, strref str); strl_t _strmod_append(char *string, strl_t length, strl_t cap, const char *str); strl_t _strmod_append(char *string, strl_t length, strl_t cap, strref str); -strl_t _strmod_relativize_path(char *string, strl_t cap, strref base_path, strref target_path); -strl_t _strown_absolutize_path(char *string, strl_t cap, strref base_path, strref relative_path); strl_t _strmod_insert(char *string, strl_t length, strl_t cap, const strref sub, strl_t pos); strl_t _strmod_utf8_tolower(char *string, strl_t length, strl_t cap); void _strmod_substrcopy(char *string, strl_t length, strl_t cap, strl_t src, strl_t dst, strl_t chars); @@ -625,6 +635,8 @@ strl_t _strmod_format_insert(char *string, strl_t length, strl_t cap, strl_t pos strl_t _strmod_remove(char *string, strl_t length, char a); strl_t _strmod_remove(char *string, strl_t length, strl_t start, strl_t len); strl_t _strmod_exchange(char *string, strl_t length, strl_t cap, strl_t start, strl_t size, const strref insert); +strl_t _strmod_cleanup_path(char *file, strl_t len); +strl_t _strmod_relative_path(char *out, strl_t cap, strref orig, strref target); // intermediate template class to support writeable string classes. use strown or strovl which inherits from this. template class strmod : public B { @@ -731,14 +743,14 @@ public: int find_after_last(char a, char b) const { return get_strref().find_after_last(a, b); } int find_after_last(char a1, char a2, char b) const { return get_strref().find_after_last(a1, a2, b); } int find(const strref str) const { return get_strref().find(str); } - int find(const char *str) const { return get_strref().find(str); } + int find(const strref str, strl_t pos) const { get_strref().find(str, pos); } + int find(const char *str, strl_t pos = 0) const { return get_strref().find(str, pos); } int find_case(const strref str) const { return get_strref().find_case(str); } int find_case(const char *str) const { return get_strref().find_case(str); } int find_last(const strref str) const { return get_strref().find_last(str); } int find_last(const char *str) const { return get_strref().find_last(str); } int find_last_case(const strref str) const { return get_strref().find_last_case(str); } int substr_count(const strref p) const { return get_strref().substr_count(p); } - int find(const strref str, strl_t pos) const { get_strref().find(str, pos); } // rolling hash string search int find_rh(strref str) const { return get_strref().find_rh(str); } @@ -869,8 +881,8 @@ public: strmod& operator<<(strref str) { return append(str); } // append a character repeatedly - void append_to(char c, strl_t pos) { if (len() >= pos) set_len_int(pos); else { - strl_t ol = len(); set_len(pos); for (strl_t p = ol; p < len(); ++p) charstr()[p] = c; } } + strmod& pad_to(char c, strl_t pos) { if (len() >= pos) set_len_int(pos); else { + strl_t ol = len(); set_len(pos); for (strl_t p = ol; p < len(); ++p) charstr()[p] = c; } return *this; } // prepend this string with a substring void prepend(const strref o) { insert(o, 0); } @@ -951,6 +963,17 @@ public: void erase(strl_t pos, strl_t length) { if (poslen()) length = len()-pos; if (length) { for (strl_t i = 0; i class strown_base { @@ -1398,6 +1421,14 @@ unsigned int strref::fnv1a(unsigned int seed) const return hash; } +// get 16 bit fnv1a hash of a string, this is officially done by xor folding +unsigned short strref::fnv1a_16(unsigned int seed) const +{ + unsigned int hash = fnv1a(seed); + return (unsigned short)(hash ^ (hash>>16)); +} + + uint64_t strref::fnv1a_64(uint64_t seed) const { uint64_t hash = seed; @@ -1405,7 +1436,7 @@ uint64_t strref::fnv1a_64(uint64_t seed) const unsigned const char *scan = (unsigned const char*)string; strl_t left = length; while (left--) - hash = (*scan++ ^ hash) * 0x100000001b3ULL; + hash = (*scan++ ^ hash) * 1099511628211; } return hash; } @@ -1431,7 +1462,7 @@ unsigned int strref::fnv1a_ws(unsigned int seed) const uint8_t c = *scan++; if (c<' ') c = ' '; - hash = (*scan++ ^ hash) * 16777619; + hash = (c ^ hash) * 16777619; if (c==' ') { while (left && *scan<=0x20) { left--; @@ -1468,17 +1499,19 @@ uint64_t strref::atoui() const { if (string) { const unsigned char *s = get_u(); - const unsigned char *e = s + length; - while (s!=e && *s<=0x20) s++; - if (s'9') break; - v = c-'0' + v*10; - } - return v; + strl_t left = length; + + while (left && *s<=0x20) { s++; left--; } + if (left>=2 && *s=='0' && s[1]=='x' ) { return ahextou64(); } + + uint64_t v = 0; + while (left) { + unsigned char c = *s++; + if (c<'0' || c>'9') break; + v = c-'0' + v*10; + --left; } + return v; } return 0; } @@ -1561,7 +1594,37 @@ size_t strref::ahextoui() const } // convert a hexadecimal string to an unsigned integer -size_t strref::ahextoui_skip() +uint64_t strref::ahextou64() const +{ + const char *scan = string; + strl_t left = length; + while (*scan<=0x20 && left) { + scan++; + left--; + } + if (!left) + return 0; + if (left>2 && *scan=='0' && (scan[1]=='x' || scan[1]=='X')) { + scan += 2; + left -= 2; + } + uint64_t hex = 0; + while (left) { + char c = *scan++; + left--; + if (c>='0' && c<='9') + hex = (hex<<4) | (c-'0'); + else if (c>='a' && c<='f') + hex = (hex<<4) | (c-'a'+10); + else if (c>='A' && c<='F') + hex = (hex<<4) | (c-'A'+10); + else + break; + } + return hex; +} +// convert a hexadecimal string to an unsigned integer +uint64_t strref::ahextoui_skip() { const char *scan = string; strl_t left = length; @@ -1575,7 +1638,8 @@ size_t strref::ahextoui_skip() scan += 2; left -= 2; } - strl_t hex = 0; + if( left > 16 ) { left = 16; } + uint64_t hex = 0; while (left) { char c = *scan; if (c>='0' && c<='9') @@ -1665,6 +1729,17 @@ int strref::count_char(char c) const return count; } +// skip bom header of a utf-8 file if detected +strref strref::skip_bom() +{ + const uint8_t* buf = get_u(); + if( length >= 3 && buf && buf[ 0 ] == 0xef && buf[ 1 ] == 0xbb && buf[ 2 ] == 0xbf ) + { + return strref( string + 3, length - 3 ); + } + return *this; +} + // find a character in a string static int int_find_char(char c, const char *scan, strl_t length) { @@ -2446,9 +2521,9 @@ int strref::find_esc(const strref str, strl_t pos) const } // find a substring within a string case ignored -int strref::find(const char *str) const +int strref::find(const char *str, strl_t pos) const { - if (!str || !valid()) + if (!str || !valid() || pos>=length) return -1; const uint8_t *stru = (const uint8_t*)str; @@ -2456,10 +2531,10 @@ int strref::find(const char *str) const if (!c) return 0; - const uint8_t *scan = get_u(); + const uint8_t *scan = get_u() + pos; const uint8_t *compare = stru; - strl_t l = length; + strl_t l = length - pos; while (l) { if (int_tolower_ascii7(*scan++)==c) { bool equal = true; @@ -3135,6 +3210,42 @@ int strref::count_lines() const { return count; } +strl_t strref::prev_line_pos( strl_t pos ) +{ + if( !pos || !length ) { return pos; } + + const char *start = string; + pos = pos < length ? pos : length; + --pos; + char c = start[pos]; + if( c==0x0a || c==0x0d ) --pos; + if(pos && ((c==0x0a && start[pos]==0x0d) || (c==0x0d && start[pos]==0x0a))) --pos; + while( pos && start[pos-1]!=0x0a && start[pos-1]!=0x0d ) --pos; + return pos; +} + +strl_t strref::start_line_pos( strl_t pos ) +{ + if( !pos || !length ) { return pos; } + + const char *start = string; + pos = pos < length ? pos : length; + --pos; + while( pos && start[pos-1]!=0x0a && start[pos-1]!=0x0d ) --pos; + return pos; +} + +strl_t strref::end_line_pos( strl_t pos ) +{ + const char *start = string; + if( pos > length ) { return length; } + while( pos < length ) { + if (start[pos]==0x0a || start[pos] == 0x0d) { return pos; } + ++pos; + } + return pos; +} + // find any char from str in this string at position // (does not check for escape codes or ranges) @@ -3956,6 +4067,115 @@ int strref::find_quoted(char d) const return -1; } +strref strref::split( strl_t pos ) { + pos = limit_pos( pos ); + strref ret = strref( string, pos ); + *this += pos; + return ret; +} + +strref strref::split( int pos ) { + return split( strl_t( pos ) ); +} + +strref strref::split_token( char c ) { + int t = find( c ); + if ( t < 0 ) t = ( int )length; + strref r = strref( string, strl_t( t ) ); + *this += t + 1; + return r; +} + +strref strref::split_token_any( const strref chars ) +{ + strref r; int t = find_any_char_of( chars ); + if ( t >= 0 ) { + r = strref( string, t ); + *this += t; + } + return r; +} + +strref strref::split_token_trim( char c ) { + strref r = split_token( c ); + skip_whitespace(); + r.trim_whitespace(); + return r; +} + +strref strref::split_token_any_trim( const strref chars ) +{ + int t = find_any_char_of( chars ); + if ( t < 0 ) t = ( int )length; + strref r = strref( string, t ); + *this += t + 1; + r.trim_whitespace(); + return r; +} + +strref strref::split_range( const strref range, strl_t pos ) +{ + int t = find_any_char_or_range( range, pos ); + if ( t < 0 ) t = ( int )length; + strref r = strref( string, t ); + *this += t; + return r; +} +strref strref::split_range_trim( const strref range, strl_t pos ) +{ + int t = find_any_char_or_range( range, pos ); + if ( t < 0 ) t = ( int )length; + strref r = strref( string, t ); + *this += t; + r.trim_whitespace(); + trim_whitespace(); + return r; +} + +strref strref::split_label() { + skip_whitespace(); + strref r( string, len_label() ); + *this += r.length; + skip_whitespace(); + return r; +} + +// split string based on common programming tokens (words, quotes, scopes, numbers) +strref strref::split_lang() +{ + skip_whitespace(); + char c = get_first(); + strl_t l = 1; + if (c == '"') + { + int f = find_after('"', 1); + l = f >= 0 ? (strl_t)(f+1) : get_len(); + } + else if (c == '{' || c=='(') + { + strref f2(*this); + l = f2.scoped_block_comment_skip(true).get_len(); + } + else if (strref::is_number(c) || c == '-') + { + if ((c == '0' && string[1] == 'x') || string[1] == 'X') + l = 2 + (*this + 2).len_hex(); + else + l = len_float_number(); + } + else + l = len_grayspace(); + strref r = split(l); // control character + return r; +} + +strref strref::get_snippet( strl_t pos ) +{ + strref snippet(string, end_line_pos(pos)); + snippet.skip(snippet.prev_line_pos(snippet.start_line_pos(pos))); + return snippet; +} + // grab a block of text starting with (, [ or { and end with the corresponding number of ), ] or } strref strref::scoped_block_skip() { @@ -3987,12 +4207,12 @@ strref strref::scoped_block_skip() } // scoped_block_skip with C style comments -strref strref::scoped_block_comment_skip(bool include) +strl_t strref::scoped_block_comment_len() { char scope = get_first(); - if (length && (scope == '(' || scope == '[' || scope == '{')) + if (length && (scope == '(' || scope == '[' || scope == '{' || scope == '<')) { - char close = scope == '(' ? ')' : (scope == '[' ? ']' : '}'); + char close = scope == '<' ? '>' : (scope == '(' ? ')' : (scope == '[' ? ']' : '}')); const char *scan = string; strl_t depth = 0; strl_t left = length; @@ -4010,21 +4230,14 @@ strref strref::scoped_block_comment_skip(bool include) else if (c == close) depth--; } while (depth && left); - if (!depth) { - strl_t block_len = strl_t(scan - string); - strref block = strref(string, block_len); - if (!include) { - block.string++; - block.length -= 2; - } - string += block_len; - length -= block_len; - return block; - } + if (!depth) + return strl_t(scan-string); } - return strref(); + return 0; } + + // return the current line of text and move this string ahead to the next. // note: supports all known line feed configurations. strref strref::next_line() @@ -4153,6 +4366,16 @@ strl_t strref::len_float_number() const return has_value ? length-left : 0; } +// count number of valid hexadecimal characters, leading 0x not valid +strl_t strref::len_hex() const +{ + for (strl_t i = 0; i < length; i++) { + if (!is_hex((uint8_t)string[i])) + return i; + } + return length; +} + // insert a substring into a string strl_t _strmod_insert(char *string, strl_t length, strl_t cap, const strref sub, strl_t pos) { @@ -4776,6 +4999,81 @@ strl_t _strmod_utf8_toupper(char *string, strl_t length, strl_t cap) { return (strl_t)(end-string); } +strl_t _strmod_cleanup_path(char *file, strl_t len) +{ + strl_t pos = 0; + char *trg = file; + while (len) { + len--; + char c = *file++; + if (c=='/') + c='\\'; + trg[pos] = c; + if ((c=='/' || c=='\\') && len>=3 && *file=='.' && file[1]=='.' && (file[2] =='/' || file[2]=='\\') && pos) { + // attempt to rewind + strl_t rew = pos-1; + while (rew) { + if (trg[rew-1] == '/' || trg[rew-1]=='\\') + break; + --rew; + } + pos = rew; + file += 3; + len -= 3; + } else { + ++pos; + } + } + return pos; +} + +// determine a +strl_t _strmod_relative_path(char *out, strl_t cap, strref orig, strref target) +{ + // remove trailing folder separator from source + char c = orig.get_last(); + if (c=='/' || c=='\\') + orig.clip(1); + + // skip as many characters as matches at start of path + strl_t same_count = orig.prefix_len(target, '/', '\\'); + + // make sure that prior character is a folder (sub paths may share a prefix) + if (same_count != orig.get_len()) { + while( same_count ) { + c = orig.get()[same_count-1]; + if (c == '/' || c=='\\') + break; + --same_count; + } + } + + // orig may be a path without ending in a folder separator + if (same_count == orig.get_len() && target.get_len() > same_count && (target.get()[same_count] == '/' || target.get()[same_count]=='\\')) + ++same_count; + + // skip the path of the path that is the same + orig += same_count; + target += same_count; + + // count the number of folders to step up (number of folder separators) + strl_t step_up = orig.count_char('/') + orig.count_char('\\'); + strl_t len = 0; + while (step_up-- && cap) { + strl_t add = _strmod_copy(out, cap, "../"); + out += add; + len += add; + cap -= add; + } + c = target.get_first(); + if (c=='/' || c=='\\') + ++target; + + if (cap) + len += _strmod_copy(out, cap, target); + return len; +} + #endif // STRUSE_IMPLEMENTATION /* revision history diff --git a/x65.cpp b/x65.cpp index 1376f49..e6b3e45 100644 --- a/x65.cpp +++ b/x65.cpp @@ -1590,7 +1590,6 @@ public: LabelPool* GetLabelPool(strref pool_name); StatusCode AddLabelPool(strref name, strref args); StatusCode AssignPoolLabel(LabelPool &pool, strref args); - void FlushLabelPools(int scope_exit); // Late expression evaluation void AddLateEval(int target, int pc, int scope_pc, strref expression, @@ -2070,16 +2069,16 @@ uint8_t* Asm::BuildExport(strref append, int &file_size, int &addr) int start_block = FixedExport[f]->address; int end_block = FixedExport[f + 1]->start_address; if ((end_block - start_block) >= (i->address - i->start_address)) { - int addr = start_block; + int addr_block = start_block; int sec = id; while (sec >= 0) { Section &s = allSections[sec]; - addr += s.align_address <= 1 ? 0 : - (s.align_address - (addr % s.align_address)) % s.align_address; - addr += s.address - s.start_address; + addr_block += s.align_address <= 1 ? 0 : + (s.align_address - (addr_block % s.align_address)) % s.align_address; + addr_block += s.address - s.start_address; sec = s.next_group; } - if (addr <= end_block) { + if (addr_block <= end_block) { insert_after = f; break; } @@ -2681,7 +2680,6 @@ StatusCode Asm::ExitScope() StatusCode error = FlushLocalLabels(scope_depth); if (error >= FIRST_ERROR) return error; - FlushLabelPools(scope_depth); --scope_depth; if (scope_depth<0) return ERROR_UNBALANCED_SCOPE_CLOSURE; @@ -2886,17 +2884,17 @@ StatusCode Asm::BuildMacro(Macro &m, strref arg_list) if (tag) { strref match("]*{0-9}"); strl_t pos = 0; - while (strref tag = macexp.find_wildcard(match, pos)) { + while (strref tag_mac = macexp.find_wildcard(match, pos)) { bool success = false; - strl_t offs = strl_t(tag.get() - macexp.get()); + strl_t offs = strl_t(tag_mac.get() - macexp.get()); if (!offs || !strref::is_valid_label(macexp[offs])) { - int t = (int)(tag + 1).atoi(); + int t = (int)(tag_mac + 1).atoi(); strref args = arg; if (t > 0) { for (int skip = 1; skip < t; skip++) args.split_token_trim(';'); strref a = args.split_token_trim(';'); - macexp.exchange(offs, tag.get_len(), a); + macexp.exchange(offs, tag_mac.get_len(), a); pos += a.get_len(); success = true; } @@ -2981,7 +2979,7 @@ StatusCode Asm::BuildEnum(strref name, strref declaration) while (strref line = declaration.line()) { line = line.before_or_full(','); line.trim_whitespace(); - strref name = line.split_token_trim('='); + strref member_name = line.split_token_trim('='); line = line.before_or_full(';').before_or_full(c_comment).get_trimmed_ws(); if (line) { StatusCode error = EvalExpression(line, etx, value); @@ -2992,7 +2990,7 @@ StatusCode Asm::BuildEnum(strref name, strref declaration) } struct MemberOffset member; member.offset = (uint16_t)value; - member.name = name; + member.name = member_name; member.name_hash = member.name.fnv1a(); member.sub_struct = strref(); structMembers.push_back(member); @@ -3898,18 +3896,6 @@ LabelPool* Asm::GetLabelPool(strref pool_name) return nullptr; } -// When going out of scope, label pools are deleted. -void Asm::FlushLabelPools(int scope_exit) -{ - uint32_t i = 0; - while (i= scope_exit) - labelPools.remove(i); - else - ++i; - } -} - // Add a label pool StatusCode Asm::AddLabelPool(strref name, strref args) { @@ -3970,16 +3956,19 @@ StatusCode Asm::AddLabelPool(strref name, strref args) StatusCode Asm::AssignPoolLabel(LabelPool &pool, strref label) { strref type = label; - label = type.split_token('.'); int bytes = 1; - switch (strref::tolower(type.get_first())) { - case 'l': bytes = 4; break; - case 't': bytes = 3; break; - case 'd': - case 'w': bytes = 2; break; + int sz = label.find_at( '.', 1 ); + if (sz > 0) { + label = type.split( sz ); + ++type; + switch (strref::tolower(type.get_first())) { + case 'l': bytes = 4; break; + case 't': bytes = 3; break; + case 'd': + case 'w': bytes = 2; break; + } } - if (GetLabel(label)) - return ERROR_POOL_LABEL_ALREADY_DEFINED; + if (GetLabel(label)) { return ERROR_POOL_LABEL_ALREADY_DEFINED; } uint32_t addr; StatusCode error = pool.Reserve(bytes, addr); if (error != STATUS_OK) @@ -3997,7 +3986,9 @@ StatusCode Asm::AssignPoolLabel(LabelPool &pool, strref label) pLabel->external = false; pLabel->reference = false; - MarkLabelLocal(label, true); + if (label[ 0 ] == '.' || label[ 0 ] == '@' || label[ 0 ] == '!' || label[ 0 ] == ':' || label.get_last() == '$') { + MarkLabelLocal( label, true ); + } LabelAdded(pLabel, !!pool.scopeDepth); return error; } @@ -5998,7 +5989,7 @@ bool Asm::List(strref filename) if (line_fix[pos] == '\t') line_fix.exchange(pos, 1, pos & 1 ? strref(" ") : strref(" ")); } - out.append_to(' ', aCPUs[cpu].timing ? 40 : 33); + out.pad_to(' ', aCPUs[cpu].timing ? 40 : 33); out.append(line_fix.get_strref()); fprintf(f, STRREF_FMT "\n", STRREF_ARG(out)); out.clear(); @@ -6018,10 +6009,10 @@ bool Asm::List(strref filename) } if (lst.startClock() && cycles_depth%d", cycles_depth); + out.pad_to(' ', 6); out.sprintf_append("c>%d", cycles_depth); } if (lst.stopClock()) { - out.append_to(' ', 6); + out.pad_to(' ', 6); if (cycles[cycles_depth].complex()) out.sprintf_append("c<%d = %d + m%d + i%d + d%d", cycles_depth, cycles[cycles_depth].base, cycles[cycles_depth].a16, @@ -6035,7 +6026,7 @@ bool Asm::List(strref filename) } } if (lst.size && lst.wasMnemonic()) { - out.append_to(' ', 18); + out.pad_to(' ', 18); uint8_t *buf = si->output + lst.address; uint8_t op = mnemonic[*buf]; uint8_t am = addrmode[*buf]; @@ -6065,7 +6056,7 @@ bool Asm::List(strref filename) out.sprintf_append(fmt, opcode_table[op].instr, buf[1]); if (aCPUs[cpu].timing) { cycles[cycles_depth].add(aCPUs[cpu].timing[*buf]); - out.append_to(' ', 33); + out.pad_to(' ', 33); if (cycleCnt::sum_plus(aCPUs[cpu].timing[*buf])==1) out.sprintf_append("%d+", cycleCnt::get_base(aCPUs[cpu].timing[*buf])); else if (cycleCnt::sum_plus(aCPUs[cpu].timing[*buf])) @@ -6076,7 +6067,7 @@ bool Asm::List(strref filename) } } - out.append_to(' ', aCPUs[cpu].timing ? 40 : 33); + out.pad_to(' ', aCPUs[cpu].timing ? 40 : 33); strref line = lst.code.get_skipped(lst.line_offs).get_line(); line.clip_trailing_whitespace(); strown<128> line_fix(line); @@ -7138,19 +7129,19 @@ int main(int argc, char **argv) file.append(aAppendNames[e]); file.append('.'); file.append(ext); - int size; + int size_export; int addr; - if (uint8_t *buf = assembler.BuildExport(aAppendNames[e], size, addr)) { + if (uint8_t *buf = assembler.BuildExport(aAppendNames[e], size_export, addr)) { if (FILE *f = fopen(file.c_str(), "wb")) { if (load_header) { uint8_t load_addr[2] = { (uint8_t)addr, (uint8_t)(addr >> 8) }; fwrite(load_addr, 2, 1, f); } if (size_header) { - uint8_t byte_size[2] = { (uint8_t)size, (uint8_t)(size >> 8) }; + uint8_t byte_size[2] = { (uint8_t)size_export, (uint8_t)(size_export >> 8) }; fwrite(byte_size, 2, 1, f); } - fwrite(buf, size, 1, f); + fwrite(buf, size_export, 1, f); fclose(f); } free(buf); @@ -7169,8 +7160,8 @@ int main(int argc, char **argv) (int)i, STRREF_ARG(s.name), s.dummySection ? "yes" : "no", s.IsRelativeSection() ? "yes" : "no", s.IsMergedSection() ? "yes" : "no", s.start_address, s.address); if (s.pRelocs) { - for (relocList::iterator i = s.pRelocs->begin(); i != s.pRelocs->end(); ++i) - printf("\tReloc value $%x at offs $%x section %d\n", i->base_value, i->section_offset, i->target_section); + for (relocList::iterator rel = s.pRelocs->begin(); rel != s.pRelocs->end(); ++rel) + printf("\tReloc value $%x at offs $%x section %d\n", rel->base_value, rel->section_offset, rel->target_section); } } }