diff options
| author | GriffinR <griffin.g.richards@gmail.com> | 2021-07-31 13:30:40 -0400 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-07-31 13:30:40 -0400 | 
| commit | 3e60a7840653e50845abf10bb02cd1b519dcd80f (patch) | |
| tree | cb4a0d227a238ebdeb3b6cb9fdb92781bcc4f5e7 /tools/preproc | |
| parent | 602855ea99d8015ef5b7709f6fb1e9fd167239e2 (diff) | |
| parent | d391486247cc9f29d85787d6711f7cb993cf6585 (diff) | |
Merge branch 'master' into doc-frontierpass2
Diffstat (limited to 'tools/preproc')
| -rw-r--r-- | tools/preproc/Makefile | 10 | ||||
| -rw-r--r-- | tools/preproc/c_file.cpp | 55 | ||||
| -rw-r--r-- | tools/preproc/c_file.h | 5 | ||||
| -rw-r--r-- | tools/preproc/preproc.cpp | 22 | 
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; | 
