parent
e8b933ff8c
commit
9c9c03346b
@ -0,0 +1,15 @@ |
||||
|
||||
USE_CLANG = 1
|
||||
|
||||
ifdef USE_CLANG |
||||
CC = clang++
|
||||
CFLAGS = -std=c++1y -stdlib=libc++ -g
|
||||
else |
||||
CC = g++
|
||||
CFLAGS = -std=c++1y -g
|
||||
endif |
||||
|
||||
all: peglint |
||||
|
||||
peglint : peglint.cc ../peglib.h |
||||
$(CC) -o peglint $(CFLAGS) -I.. peglint.cc
|
@ -0,0 +1,149 @@ |
||||
|
||||
#ifndef _MMAP_H_ |
||||
#define _MMAP_H_ |
||||
|
||||
#if defined(_MSC_VER) |
||||
#include <windows.h> |
||||
#else |
||||
#include <fcntl.h> |
||||
#include <unistd.h> |
||||
#include <sys/mman.h> |
||||
#include <sys/stat.h> |
||||
#endif |
||||
|
||||
class MemoryMappedFile |
||||
{ |
||||
public: |
||||
MemoryMappedFile(const char* path); |
||||
~MemoryMappedFile(); |
||||
|
||||
bool is_open() const; |
||||
size_t size() const; |
||||
const char* data() const; |
||||
|
||||
private: |
||||
void cleanup(); |
||||
|
||||
#if defined(_MSC_VER) |
||||
HANDLE hFile_; |
||||
HANDLE hMapping_; |
||||
#else |
||||
int fd_; |
||||
#endif |
||||
size_t size_; |
||||
void* addr_; |
||||
}; |
||||
|
||||
#if defined(_MSC_VER) |
||||
#define MAP_FAILED NULL |
||||
#endif |
||||
|
||||
inline MemoryMappedFile::MemoryMappedFile(const char* path) |
||||
#if defined(_MSC_VER) |
||||
: hFile_(NULL) |
||||
, hMapping_(NULL) |
||||
#else |
||||
: fd_(-1) |
||||
#endif |
||||
, size_(0) |
||||
, addr_(MAP_FAILED) |
||||
{ |
||||
#if defined(_MSC_VER) |
||||
hFile_ = ::CreateFileA( |
||||
path, |
||||
GENERIC_READ, |
||||
FILE_SHARE_READ, |
||||
NULL, |
||||
OPEN_EXISTING, |
||||
FILE_ATTRIBUTE_NORMAL, |
||||
NULL); |
||||
|
||||
if (hFile_ == INVALID_HANDLE_VALUE) { |
||||
std::runtime_error(""); |
||||
} |
||||
|
||||
size_ = ::GetFileSize(hFile_, NULL); |
||||
|
||||
hMapping_ = ::CreateFileMapping(hFile_, NULL, PAGE_READONLY, 0, 0, NULL); |
||||
|
||||
if (hMapping_ == NULL) { |
||||
cleanup(); |
||||
std::runtime_error(""); |
||||
} |
||||
|
||||
addr_ = ::MapViewOfFile(hMapping_, FILE_MAP_READ, 0, 0, 0); |
||||
#else |
||||
fd_ = open(path, O_RDONLY); |
||||
if (fd_ == -1) { |
||||
std::runtime_error(""); |
||||
} |
||||
|
||||
struct stat sb; |
||||
if (fstat(fd_, &sb) == -1) { |
||||
cleanup(); |
||||
std::runtime_error(""); |
||||
} |
||||
size_ = sb.st_size; |
||||
|
||||
addr_ = mmap(NULL, size_, PROT_READ, MAP_PRIVATE, fd_, 0); |
||||
#endif |
||||
|
||||
if (addr_ == MAP_FAILED) { |
||||
cleanup(); |
||||
std::runtime_error(""); |
||||
} |
||||
} |
||||
|
||||
inline MemoryMappedFile::~MemoryMappedFile() |
||||
{ |
||||
cleanup(); |
||||
} |
||||
|
||||
inline bool MemoryMappedFile::is_open() const |
||||
{ |
||||
return addr_ != MAP_FAILED; |
||||
} |
||||
|
||||
inline size_t MemoryMappedFile::size() const |
||||
{ |
||||
return size_; |
||||
} |
||||
|
||||
inline const char* MemoryMappedFile::data() const |
||||
{ |
||||
return (const char*)addr_; |
||||
} |
||||
|
||||
inline void MemoryMappedFile::cleanup() |
||||
{ |
||||
#if defined(_MSC_VER) |
||||
if (addr_) { |
||||
::UnmapViewOfFile(addr_); |
||||
addr_ = MAP_FAILED; |
||||
} |
||||
|
||||
if (hMapping_) { |
||||
::CloseHandle(hMapping_); |
||||
hMapping_ = NULL; |
||||
} |
||||
|
||||
if (hFile_ != INVALID_HANDLE_VALUE) { |
||||
::CloseHandle(hFile_); |
||||
hFile_ = INVALID_HANDLE_VALUE; |
||||
} |
||||
#else |
||||
if (addr_ != MAP_FAILED) { |
||||
munmap(addr_, size_); |
||||
addr_ = MAP_FAILED; |
||||
} |
||||
|
||||
if (fd_ != -1) { |
||||
close(fd_); |
||||
fd_ = -1; |
||||
} |
||||
#endif |
||||
} |
||||
|
||||
#endif // _MMAP_H_
|
||||
|
||||
// vim: et ts=4 sw=4 cin cino={1s ff=unix
|
@ -0,0 +1,65 @@ |
||||
//
|
||||
// peglint.cc
|
||||
//
|
||||
// Copyright (c) 2015 Yuji Hirose. All rights reserved.
|
||||
// MIT License
|
||||
//
|
||||
|
||||
#include <peglib.h> |
||||
#include <iostream> |
||||
#include "mmap.h" |
||||
|
||||
using namespace peglib; |
||||
using namespace std; |
||||
|
||||
int main(int argc, const char** argv) |
||||
{ |
||||
if (argc < 2 || string("--help") == argv[1]) { |
||||
cerr << "usage: peglint [grammar file path] [source file path]" << endl; |
||||
return 1; |
||||
} |
||||
|
||||
// Check PEG grammar
|
||||
cerr << "checking grammar file..." << endl; |
||||
|
||||
MemoryMappedFile syntax(argv[1]); |
||||
if (!syntax.is_open()) { |
||||
cerr << "can't open the grammar file." << endl; |
||||
return -1; |
||||
} |
||||
|
||||
auto parser = make_parser(syntax.data(), syntax.size(), [](size_t ln, size_t col, const string& msg) { |
||||
cerr << ln << ":" << col << ": " << msg << endl; |
||||
}); |
||||
|
||||
if (parser) { |
||||
cerr << "success" << endl; |
||||
} else { |
||||
cerr << "invalid grammar file." << endl; |
||||
return -1; |
||||
} |
||||
|
||||
if (argc < 3) { |
||||
return 0; |
||||
} |
||||
|
||||
// Check source
|
||||
cerr << "checking source file..." << endl; |
||||
|
||||
MemoryMappedFile source(argv[2]); |
||||
if (!source.is_open()) { |
||||
cerr << "can't open the source file." << endl; |
||||
return -1; |
||||
} |
||||
|
||||
auto m = parser.lint(source.data(), source.size()); |
||||
|
||||
if (m.ret) { |
||||
cerr << "success" << endl; |
||||
} else { |
||||
auto info = line_info(source.data(), m.ptr); |
||||
cerr << info.first << ":" << info.second << ": syntax error" << endl; |
||||
} |
||||
} |
||||
|
||||
// vim: et ts=4 sw=4 cin cino={1s ff=unix
|
Loading…
Reference in new issue