summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/ramscrgen/main.cpp26
-rw-r--r--tools/ramscrgen/sym_file.cpp67
-rw-r--r--tools/ramscrgen/sym_file.h3
3 files changed, 85 insertions, 11 deletions
diff --git a/tools/ramscrgen/main.cpp b/tools/ramscrgen/main.cpp
index 5c803c31f..6c4f4bbd7 100644
--- a/tools/ramscrgen/main.cpp
+++ b/tools/ramscrgen/main.cpp
@@ -25,7 +25,7 @@
#include "sym_file.h"
#include "elf.h"
-void HandleCommonInclude(std::string filename, std::string sourcePath, std::string symOrderPath)
+void HandleCommonInclude(std::string filename, std::string sourcePath, std::string symOrderPath, std::string lang)
{
auto commonSymbols = GetCommonSymbols(sourcePath + "/" + filename);
@@ -40,6 +40,8 @@ void HandleCommonInclude(std::string filename, std::string sourcePath, std::stri
while (!symFile.IsAtEnd())
{
+ symFile.HandleLangConditional(lang);
+
std::string label = symFile.GetLabel(false);
if (label.length() == 0)
@@ -71,12 +73,14 @@ void HandleCommonInclude(std::string filename, std::string sourcePath, std::stri
}
}
-void ConvertSymFile(std::string filename, std::string sectionName, bool common, std::string sourcePath, std::string commonSymPath)
+void ConvertSymFile(std::string filename, std::string sectionName, std::string lang, bool common, std::string sourcePath, std::string commonSymPath)
{
SymFile symFile(filename);
while (!symFile.IsAtEnd())
{
+ symFile.HandleLangConditional(lang);
+
Directive directive = symFile.GetDirective();
switch (directive)
@@ -87,10 +91,9 @@ void ConvertSymFile(std::string filename, std::string sectionName, bool common,
symFile.ExpectEmptyRestOfLine();
printf(". = ALIGN(4);\n");
if (common)
- HandleCommonInclude(incFilename, sourcePath, commonSymPath);
+ HandleCommonInclude(incFilename, sourcePath, commonSymPath, lang);
else
printf("%s(%s);\n", incFilename.c_str(), sectionName.c_str());
- printf(". = ALIGN(4);\n");
break;
}
case Directive::Space:
@@ -133,28 +136,29 @@ void ConvertSymFile(std::string filename, std::string sectionName, bool common,
int main(int argc, char **argv)
{
- if (argc < 3)
+ if (argc < 4)
{
- fprintf(stderr, "Usage: %s SECTION_NAME SYM_FILE [-c SRC_PATH,COMMON_SYM_PATH]", argv[0]);
+ fprintf(stderr, "Usage: %s SECTION_NAME SYM_FILE LANG [-c SRC_PATH,COMMON_SYM_PATH]", argv[0]);
return 1;
}
bool common = false;
std::string sectionName = std::string(argv[1]);
std::string symFileName = std::string(argv[2]);
+ std::string lang = std::string(argv[3]);
std::string sourcePath;
std::string commonSymPath;
- if (argc > 3)
+ if (argc > 4)
{
- if (std::strcmp(argv[3], "-c") != 0)
+ if (std::strcmp(argv[4], "-c") != 0)
FATAL_ERROR("error: unrecognized argument \"%s\"\n", argv[4]);
- if (argc < 5)
+ if (argc < 6)
FATAL_ERROR("error: missing SRC_PATH,COMMON_SYM_PATH after \"-c\"\n");
common = true;
- std::string paths = std::string(argv[4]);
+ std::string paths = std::string(argv[5]);
std::size_t commaPos = paths.find(',');
if (commaPos == std::string::npos)
@@ -164,6 +168,6 @@ int main(int argc, char **argv)
commonSymPath = paths.substr(commaPos + 1);
}
- ConvertSymFile(symFileName, sectionName, common, sourcePath, commonSymPath);
+ ConvertSymFile(symFileName, sectionName, lang, common, sourcePath, commonSymPath);
return 0;
}
diff --git a/tools/ramscrgen/sym_file.cpp b/tools/ramscrgen/sym_file.cpp
index 9d9e4a064..5379bd93f 100644
--- a/tools/ramscrgen/sym_file.cpp
+++ b/tools/ramscrgen/sym_file.cpp
@@ -53,6 +53,7 @@ SymFile::SymFile(std::string filename) : m_filename(filename)
m_pos = 0;
m_lineNum = 1;
m_lineStart = 0;
+ m_inLangConditional = false;
RemoveComments();
}
@@ -387,12 +388,78 @@ void SymFile::ExpectEmptyRestOfLine()
}
}
+
+void SymFile::SkipLine()
+{
+ while (m_buffer[m_pos] != 0 && m_buffer[m_pos] != '\n')
+ m_pos++;
+
+ if (m_buffer[m_pos] == '\n')
+ m_pos++;
+}
+
// Checks if we're at the end of the file.
bool SymFile::IsAtEnd()
{
return (m_pos >= m_size);
}
+void SymFile::HandleLangConditional(std::string lang)
+{
+ if (m_buffer[m_pos] != '#')
+ return;
+
+ m_pos++;
+
+ if (CheckForDirective("begin"))
+ {
+ if (m_inLangConditional)
+ RaiseError("already inside language conditional");
+
+ SkipWhitespace();
+
+ std::string label = GetLabel(false);
+
+ if (label.length() == 0)
+ RaiseError("no language name after #begin");
+
+ ExpectEmptyRestOfLine();
+
+ if (lang == label)
+ {
+ m_inLangConditional = true;
+ }
+ else
+ {
+ while (!IsAtEnd() && m_buffer[m_pos] != '#')
+ SkipLine();
+
+ if (m_buffer[m_pos] != '#')
+ RaiseError("unterminated language conditional");
+
+ m_pos++;
+
+ if (!CheckForDirective("end"))
+ RaiseError("expected #end");
+
+ ExpectEmptyRestOfLine();
+ }
+ }
+ else if (CheckForDirective("end"))
+ {
+ if (!m_inLangConditional)
+ RaiseError("not inside language conditional");
+
+ m_inLangConditional = false;
+
+ ExpectEmptyRestOfLine();
+ }
+ else
+ {
+ RaiseError("unknown # directive");
+ }
+}
+
// Reports a diagnostic message.
void SymFile::ReportDiagnostic(const char* type, const char* format, std::va_list args)
{
diff --git a/tools/ramscrgen/sym_file.h b/tools/ramscrgen/sym_file.h
index 5b3cedb3b..bb0c8038d 100644
--- a/tools/ramscrgen/sym_file.h
+++ b/tools/ramscrgen/sym_file.h
@@ -46,7 +46,9 @@ public:
std::string ReadPath();
bool ReadInteger(unsigned long& value);
void ExpectEmptyRestOfLine();
+ void SkipLine();
bool IsAtEnd();
+ void HandleLangConditional(std::string lang);
void RaiseError(const char* format, ...);
void RaiseWarning(const char* format, ...);
@@ -57,6 +59,7 @@ private:
long m_lineNum;
long m_lineStart;
std::string m_filename;
+ bool m_inLangConditional;
bool ConsumeComma();
void RemoveComments();