Started expanding what were scanner.cpp and scanner.hpp into a more flexible library for tool writing. Also decided to go with separate POSIX and Windows implementations.

This commit is contained in:
Pietro Gagliardi 2018-05-25 21:07:45 -04:00
parent ca11bf1e42
commit 472476392c
4 changed files with 215 additions and 63 deletions

View File

@ -11,33 +11,75 @@
#define readtype int
#define closefunc _close
#else
#include <fcntl.h>
#include <unistd.h>
#define openfunc open
#define openflags (O_RDONLY)
#define openmode 0644
#define readfunc read
#define readtype ssize_t
#define closefunc close
#endif
#include <errno.h>
#include "scanner.hpp"
#include <typeinfo>
#include "lib.hpp"
class eofError : public Error {
public:
virtual ~eofError(void);
virtual const char *String(void) const;
};
virtual ~eofError::eofError(void)
{
// do nothing
}
virtual const char *eofError::String(void) const
{
return "EOF";
}
class shortWriteError : public Error {
public:
virtual ~shortWriteError(void);
virtual const char *String(void) const;
};
virtual ~shortWriteError::shortWriteError(void)
{
// do nothing
}
virtual const char *shortWriteError::String(void) const
{
return "short write";
}
Error *NewEOF(void)
{
return new eofError;
}
Error *NewErrShortWrite(void)
{
return new shortWriteError;
}
bool IsEOF(Error *e)
{
return typeid (e) == typeid (eofError *);
}
#define nbuf 1024
Scanner::Scanner(int fd)
Scanner::Scanner(ReadCloser *r)
{
this->fd = fd;
this->r = r;
this->buf = new char[nbuf];
this->p = this->buf;
this->n = 0;
this->line = new std::vector<char>;
this->eof = false;
this->error = 0;
this->error = NULL;
}
Scanner::~Scanner(void)
{
if (this->err != NULL)
delete this->err;
delete this->line;
delete[] this->buf;
}
@ -46,7 +88,7 @@ bool Scanner::Scan(void)
{
readtype n;
if (this->eof || this->error != 0)
if (this->err != NULL)
return false;
this->line->clear();
for (;;) {
@ -72,15 +114,9 @@ bool Scanner::Scan(void)
// otherwise, the buffer was exhausted in the middle of a line, so fall through
}
// need to refill the buffer
n = readfunc(this->fd, this->buf, nbuf * sizeof (char));
if (n < 0) {
this->error = errno;
this->err = this->r->Read(this->buf, nbuf * sizeof (char), &n);
if (this->err != NULL)
return false;
}
if (n == 0) {
this->eof = true;
return false;
}
this->p = this->buf;
this->n = n;
}
@ -96,22 +132,9 @@ size_t Scanner::Len(void) const
return this->line->size();
}
int Scanner::Error(void) const
int Scanner::Err(void) const
{
return this->error;
}
int OpenForScanner(const char *filename, int *fd)
{
*fd = openfunc(filename, openflags, openmode);
if (*fd < 0)
return errno;
return 0;
}
int CloseForScanner(int fd)
{
if (closefunc(fd) < 0)
return errno;
return 0;
if (!IsEOF(this->err))
return this->err;
return NULL;
}

46
windows/tools/lib.hpp Normal file
View File

@ -0,0 +1,46 @@
// 21 may 2018
#include <vector>
class Error {
public:
virtual ~Error(void);
virtual const char *String(void) const = 0;
};
extern Error *NewEOF(void);
extern Error *NewErrShortWrite(void);
extern bool IsEOF(Error *e);
class ReadCloser {
public:
virtual ~ReadCloser(void);
virtual Error *Read(void *buf, size_t n, size_t *actual) = 0;
};
class WriteCloser {
public:
virtual ~WriteCloser(void);
virtual Error *Write(void *buf, size_t n) = 0;
};
extern Error *OpenRead(const char *filename, ReadCloser **r);
class Scanner {
ReadCloser *r;
char *buf;
const char *p;
size_t n;
std::vector<char> *line;
Error *err;
public:
Scanner(ReadCloser *r);
~Scanner(void);
bool Scan(void);
const char *Bytes(void) const;
size_t Len(void) const;
Error *Err(void) const;
};

106
windows/tools/lib_posix.cpp Normal file
View File

@ -0,0 +1,106 @@
// 25 may 2018
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include "lib.hpp"
class posixError : public Error {
int error;
public:
posixError(int error);
virtual ~posixError(void);
virtual const char *String(void) const;
};
posixError::posixError(int error)
{
this->error = error;
}
virtual posixError::~posixError(void)
{
// do nothing
}
virtual const char *posixError::String(void) const
{
return strerror(this->error);
}
class posixReadCloser : public ReadCloser {
int fd;
public:
posixReadCloser(int fd);
virtual ~posixReadCloser(void);
virtual Error *Read(void *buf, size_t n, size_t *actual);
};
posixReadCloser::posixReadCloser(int fd)
{
this->fd = fd;
}
virtual posixReadCloser::~posixReadCloser(void)
{
close(this->fd);
}
virtual Error *posixReadCloser::Read(void *buf, size_t n, size_t *actual)
{
ssize_t ret;
*actual = 0;
ret = read(this->fd, buf, n);
if (ret < 0)
return new posixError(errno);
if (ret == 0)
return NewEOF(void);
*actual = ret;
return NULL;
}
class posixWriteCloser : public WriteCloser {
int fd;
public:
posixWriteCloser(int fd);
virtual ~posixWriteCloser(void);
virtual Error *Write(void *buf, size_t n, size_t *actual);
};
posixWriteCloser::posixWriteCloser(int fd)
{
this->fd = fd;
}
virtual posixWriteCloser::~posixWriteCloser(void)
{
close(this->fd);
}
virtual Error *posixWriteCloser::Write(void *buf, size_t n)
{
ssize_t ret;
ret = write(this->fd, buf, n);
if (ret < 0)
return new posixError(errno);
if (ret != n)
return NewErrShortWrite(void);
return NULL;
}
Error *OpenRead(const char *filename, ReadCloser **r)
{
int fd;
*r = NULL;
fd = open(filename, O_RDONLY, 0644);
if (fd < 0)
return new posixError(errno);
*r = new posixReadCloser(fd);
return NULL;
}

View File

@ -1,23 +0,0 @@
// 21 may 2018
#include <vector>
class Scanner {
int fd;
char *buf;
const char *p;
size_t n;
std::vector<char> *line;
bool eof;
int error;
public:
Scanner(int fd);
~Scanner(void);
bool Scan(void);
const char *Bytes(void) const;
size_t Len(void) const;
int Error(void) const;
};
extern int OpenForScanner(const char *filename, int *fd);
extern int CloseForScanner(int fd);