summaryrefslogtreecommitdiff
path: root/tools/preproc
diff options
context:
space:
mode:
authorGriffinR <griffin.g.richards@gmail.com>2021-07-31 13:30:40 -0400
committerGitHub <noreply@github.com>2021-07-31 13:30:40 -0400
commit3e60a7840653e50845abf10bb02cd1b519dcd80f (patch)
treecb4a0d227a238ebdeb3b6cb9fdb92781bcc4f5e7 /tools/preproc
parent602855ea99d8015ef5b7709f6fb1e9fd167239e2 (diff)
parentd391486247cc9f29d85787d6711f7cb993cf6585 (diff)
Merge branch 'master' into doc-frontierpass2
Diffstat (limited to 'tools/preproc')
-rw-r--r--tools/preproc/Makefile10
-rw-r--r--tools/preproc/c_file.cpp55
-rw-r--r--tools/preproc/c_file.h5
-rw-r--r--tools/preproc/preproc.cpp22
4 files changed, 69 insertions, 23 deletions
diff --git a/tools/preproc/Makefile b/tools/preproc/Makefile
index 8c48afea2..1507c973f 100644
--- a/tools/preproc/Makefile
+++ b/tools/preproc/Makefile
@@ -8,12 +8,18 @@ SRCS := asm_file.cpp c_file.cpp charmap.cpp preproc.cpp string_parser.cpp \
HEADERS := asm_file.h c_file.h char_util.h charmap.h preproc.h string_parser.h \
utf8.h
+ifeq ($(OS),Windows_NT)
+EXE := .exe
+else
+EXE :=
+endif
+
.PHONY: all clean
-all: preproc
+all: preproc$(EXE)
@:
-preproc: $(SRCS) $(HEADERS)
+preproc$(EXE): $(SRCS) $(HEADERS)
$(CXX) $(CXXFLAGS) $(SRCS) -o $@ $(LDFLAGS)
clean:
diff --git a/tools/preproc/c_file.cpp b/tools/preproc/c_file.cpp
index b996a048c..17a08cc9f 100644
--- a/tools/preproc/c_file.cpp
+++ b/tools/preproc/c_file.cpp
@@ -23,32 +23,59 @@
#include <stdexcept>
#include <string>
#include <memory>
+#include <cstring>
+#include <cerrno>
#include "preproc.h"
#include "c_file.h"
#include "char_util.h"
#include "utf8.h"
#include "string_parser.h"
-CFile::CFile(std::string filename) : m_filename(filename)
+CFile::CFile(const char * filenameCStr, bool isStdin)
{
- FILE *fp = std::fopen(filename.c_str(), "rb");
+ FILE *fp;
+
+ if (isStdin) {
+ fp = stdin;
+ m_filename = std::string{"<stdin>/"}.append(filenameCStr);
+ } else {
+ fp = std::fopen(filenameCStr, "rb");
+ m_filename = std::string(filenameCStr);
+ }
+
+ std::string& filename = m_filename;
if (fp == NULL)
FATAL_ERROR("Failed to open \"%s\" for reading.\n", filename.c_str());
- std::fseek(fp, 0, SEEK_END);
-
- m_size = std::ftell(fp);
+ m_size = 0;
+ m_buffer = (char *)malloc(CHUNK_SIZE + 1);
+ if (m_buffer == NULL) {
+ FATAL_ERROR("Failed to allocate memory to process file \"%s\"!", filename.c_str());
+ }
- if (m_size < 0)
- FATAL_ERROR("File size of \"%s\" is less than zero.\n", filename.c_str());
+ std::size_t numAllocatedBytes = CHUNK_SIZE + 1;
+ std::size_t bufferOffset = 0;
+ std::size_t count;
- m_buffer = new char[m_size + 1];
+ while ((count = std::fread(m_buffer + bufferOffset, 1, CHUNK_SIZE, fp)) != 0) {
+ if (!std::ferror(fp)) {
+ m_size += count;
- std::rewind(fp);
+ if (std::feof(fp)) {
+ break;
+ }
- if (std::fread(m_buffer, m_size, 1, fp) != 1)
- FATAL_ERROR("Failed to read \"%s\".\n", filename.c_str());
+ numAllocatedBytes += CHUNK_SIZE;
+ bufferOffset += CHUNK_SIZE;
+ m_buffer = (char *)realloc(m_buffer, numAllocatedBytes);
+ if (m_buffer == NULL) {
+ FATAL_ERROR("Failed to allocate memory to process file \"%s\"!", filename.c_str());
+ }
+ } else {
+ FATAL_ERROR("Failed to read \"%s\". (error: %s)", filename.c_str(), std::strerror(errno));
+ }
+ }
m_buffer[m_size] = 0;
@@ -56,6 +83,7 @@ CFile::CFile(std::string filename) : m_filename(filename)
m_pos = 0;
m_lineNum = 1;
+ m_isStdin = isStdin;
}
CFile::CFile(CFile&& other) : m_filename(std::move(other.m_filename))
@@ -64,13 +92,14 @@ CFile::CFile(CFile&& other) : m_filename(std::move(other.m_filename))
m_pos = other.m_pos;
m_size = other.m_size;
m_lineNum = other.m_lineNum;
+ m_isStdin = other.m_isStdin;
- other.m_buffer = nullptr;
+ other.m_buffer = NULL;
}
CFile::~CFile()
{
- delete[] m_buffer;
+ free(m_buffer);
}
void CFile::Preproc()
diff --git a/tools/preproc/c_file.h b/tools/preproc/c_file.h
index 7369aba85..49e633a18 100644
--- a/tools/preproc/c_file.h
+++ b/tools/preproc/c_file.h
@@ -30,7 +30,7 @@
class CFile
{
public:
- CFile(std::string filename);
+ CFile(const char * filenameCStr, bool isStdin);
CFile(CFile&& other);
CFile(const CFile&) = delete;
~CFile();
@@ -42,6 +42,7 @@ private:
long m_size;
long m_lineNum;
std::string m_filename;
+ bool m_isStdin;
bool ConsumeHorizontalWhitespace();
bool ConsumeNewline();
@@ -55,4 +56,6 @@ private:
void RaiseWarning(const char* format, ...);
};
+#define CHUNK_SIZE 4096
+
#endif // C_FILE_H
diff --git a/tools/preproc/preproc.cpp b/tools/preproc/preproc.cpp
index c9c6042df..eb2d4c8a2 100644
--- a/tools/preproc/preproc.cpp
+++ b/tools/preproc/preproc.cpp
@@ -103,9 +103,9 @@ void PreprocAsmFile(std::string filename)
}
}
-void PreprocCFile(std::string filename)
+void PreprocCFile(const char * filename, bool isStdin)
{
- CFile cFile(filename);
+ CFile cFile(filename, isStdin);
cFile.Preproc();
}
@@ -132,9 +132,9 @@ char* GetFileExtension(char* filename)
int main(int argc, char **argv)
{
- if (argc != 3)
+ if (argc < 3 || argc > 4)
{
- std::fprintf(stderr, "Usage: %s SRC_FILE CHARMAP_FILE", argv[0]);
+ std::fprintf(stderr, "Usage: %s SRC_FILE CHARMAP_FILE [-i]\nwhere -i denotes if input is from stdin\n", argv[0]);
return 1;
}
@@ -147,9 +147,17 @@ int main(int argc, char **argv)
if ((extension[0] == 's') && extension[1] == 0)
PreprocAsmFile(argv[1]);
- else if ((extension[0] == 'c' || extension[0] == 'i') && extension[1] == 0)
- PreprocCFile(argv[1]);
- else
+ else if ((extension[0] == 'c' || extension[0] == 'i') && extension[1] == 0) {
+ if (argc == 4) {
+ if (argv[3][0] == '-' && argv[3][1] == 'i' && argv[3][2] == '\0') {
+ PreprocCFile(argv[1], true);
+ } else {
+ FATAL_ERROR("unknown argument flag \"%s\".\n", argv[3]);
+ }
+ } else {
+ PreprocCFile(argv[1], false);
+ }
+ } else
FATAL_ERROR("\"%s\" has an unknown file extension of \"%s\".\n", argv[1], extension);
return 0;