diff options
author | Cameron Hall <camthesaxman@users.noreply.github.com> | 2017-10-08 23:40:46 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-10-08 23:40:46 -0500 |
commit | b60f7cb66b1bcd293babbd95e56d26d61f309ee0 (patch) | |
tree | be0dadd4cb3a6c36e27233836a6f104359d49949 /tools/scaninc/c_file.cpp | |
parent | 3776a9fb4f0531535b0b5879dab7b3b6bd231736 (diff) | |
parent | b0d49dbbfbfcf39c2a9f88572437b6af77c8f709 (diff) |
Merge pull request #388 from yenatch/scaninc
[dont merge] scaninc: read C includes and add -I
Diffstat (limited to 'tools/scaninc/c_file.cpp')
-rw-r--r-- | tools/scaninc/c_file.cpp | 173 |
1 files changed, 91 insertions, 82 deletions
diff --git a/tools/scaninc/c_file.cpp b/tools/scaninc/c_file.cpp index b82276dd6..c55ca9a8c 100644 --- a/tools/scaninc/c_file.cpp +++ b/tools/scaninc/c_file.cpp @@ -45,8 +45,6 @@ CFile::CFile(std::string path) m_pos = 0; m_lineNum = 1; - - RemoveComments(); } CFile::~CFile() @@ -54,71 +52,6 @@ CFile::~CFile() delete[] m_buffer; } -// Removes comments to simplify further processing. -// It stops upon encountering a null character, -// which may or may not be the end of file marker. -// If it's not, the error will be caught later. -void CFile::RemoveComments() -{ - long pos = 0; - char stringChar = 0; - - for (;;) - { - if (m_buffer[pos] == 0) - return; - - if (stringChar != 0) - { - if (m_buffer[pos] == '\\' && m_buffer[pos + 1] == stringChar) - { - pos += 2; - } - else - { - if (m_buffer[pos] == stringChar) - stringChar = 0; - pos++; - } - } - else if (m_buffer[pos] == '/' && m_buffer[pos + 1] == '/') - { - while (m_buffer[pos] != '\n' && m_buffer[pos] != 0) - m_buffer[pos++] = ' '; - } - else if (m_buffer[pos] == '/' && m_buffer[pos + 1] == '*') - { - m_buffer[pos++] = ' '; - m_buffer[pos++] = ' '; - - for (;;) - { - if (m_buffer[pos] == 0) - return; - - if (m_buffer[pos] == '*' && m_buffer[pos + 1] == '/') - { - m_buffer[pos++] = ' '; - m_buffer[pos++] = ' '; - break; - } - else - { - if (m_buffer[pos] != '\n') - m_buffer[pos] = ' '; - pos++; - } - } - } - else - { - if (m_buffer[pos] == '"' || m_buffer[pos] == '\'') - stringChar = m_buffer[pos]; - pos++; - } - } -} - void CFile::FindIncbins() { char stringChar = 0; @@ -145,6 +78,8 @@ void CFile::FindIncbins() } else { + SkipWhitespace(); + CheckInclude(); CheckIncbin(); if (m_pos >= m_size) @@ -177,6 +112,13 @@ bool CFile::ConsumeHorizontalWhitespace() bool CFile::ConsumeNewline() { + if (m_buffer[m_pos] == '\n') + { + m_pos++; + m_lineNum++; + return true; + } + if (m_buffer[m_pos] == '\r' && m_buffer[m_pos + 1] == '\n') { m_pos += 2; @@ -184,10 +126,31 @@ bool CFile::ConsumeNewline() return true; } - if (m_buffer[m_pos] == '\n') + return false; +} + +bool CFile::ConsumeComment() +{ + if (m_buffer[m_pos] == '/' && m_buffer[m_pos + 1] == '*') { - m_pos++; - m_lineNum++; + m_pos += 2; + while (m_buffer[m_pos] != '*' && m_buffer[m_pos + 1] != '/') + { + if (!ConsumeNewline()) + { + m_pos++; + } + } + m_pos += 2; + return true; + } + else if (m_buffer[m_pos] == '/' && m_buffer[m_pos + 1] == '/') + { + m_pos += 2; + while (!ConsumeNewline()) + { + m_pos++; + } return true; } @@ -196,7 +159,7 @@ bool CFile::ConsumeNewline() void CFile::SkipWhitespace() { - while (ConsumeHorizontalWhitespace() || ConsumeNewline()) + while (ConsumeHorizontalWhitespace() || ConsumeNewline() || ConsumeComment()) ; } @@ -211,8 +174,43 @@ bool CFile::CheckIdentifier(const std::string& ident) return (i == ident.length()); } +void CFile::CheckInclude() +{ + if (m_buffer[m_pos] != '#') + return; + + std::string ident = "#include"; + + if (!CheckIdentifier(ident)) + { + return; + } + + m_pos += ident.length(); + + ConsumeHorizontalWhitespace(); + + std::string path = ReadPath(); + + if (!path.empty()) { + m_includes.emplace(path); + } +} + void CFile::CheckIncbin() { + // Optimization: assume most lines are not incbins + if (!(m_buffer[m_pos+0] == 'I' + && m_buffer[m_pos+1] == 'N' + && m_buffer[m_pos+2] == 'C' + && m_buffer[m_pos+3] == 'B' + && m_buffer[m_pos+4] == 'I' + && m_buffer[m_pos+5] == 'N' + && m_buffer[m_pos+6] == '_')) + { + return; + } + std::string idents[6] = { "INCBIN_S8", "INCBIN_U8", "INCBIN_S16", "INCBIN_U16", "INCBIN_S32", "INCBIN_U32" }; int incbinType = -1; @@ -246,8 +244,28 @@ void CFile::CheckIncbin() SkipWhitespace(); + std::string path = ReadPath(); + + SkipWhitespace(); + + if (m_buffer[m_pos] != ')') + FATAL_INPUT_ERROR("expected ')'"); + + m_pos++; + + m_incbins.emplace(path); +} + +std::string CFile::ReadPath() +{ if (m_buffer[m_pos] != '"') - FATAL_INPUT_ERROR("expected double quote"); + { + if (m_buffer[m_pos] == '<') + { + return std::string(); + } + FATAL_INPUT_ERROR("expected '\"' or '<'"); + } m_pos++; @@ -272,16 +290,7 @@ void CFile::CheckIncbin() m_pos++; } - std::string path(&m_buffer[startPos], m_pos - startPos); - - m_pos++; - - SkipWhitespace(); - - if (m_buffer[m_pos] != ')') - FATAL_INPUT_ERROR("expected ')'"); - m_pos++; - m_incbins.emplace(path); + return std::string(m_buffer + startPos, m_pos - 1 - startPos); } |