binpac: Add pre-commit hooks and run clang-format on everything

This commit is contained in:
Tim Wojtulewicz 2022-07-07 11:49:24 -07:00
parent 090ac0a6e0
commit 090325df40
91 changed files with 3086 additions and 3665 deletions

View file

@ -1,27 +1,28 @@
#ifndef binpac_an_h
#define binpac_an_h
namespace binpac {
namespace binpac
{
// TODO: Add the Done() function
// The interface for a connection analyzer
class ConnectionAnalyzer {
class ConnectionAnalyzer
{
public:
virtual ~ConnectionAnalyzer() {}
virtual void NewData(bool is_orig,
const unsigned char* begin_of_data,
virtual ~ConnectionAnalyzer() { }
virtual void NewData(bool is_orig, const unsigned char* begin_of_data,
const unsigned char* end_of_data) = 0;
};
};
// The interface for a flow analyzer
class FlowAnalyzer {
class FlowAnalyzer
{
public:
virtual ~FlowAnalyzer() {}
virtual void NewData(const unsigned char* begin_of_data,
const unsigned char* end_of_data) = 0;
};
virtual ~FlowAnalyzer() { }
virtual void NewData(const unsigned char* begin_of_data, const unsigned char* end_of_data) = 0;
};
} // namespace binpac
} // namespace binpac
#endif // binpac_an_h
#endif // binpac_an_h

View file

@ -1,20 +1,22 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h> // for memcpy
#include <stdlib.h>
#include <string.h> // for memcpy
#define binpac_regex_h
#include "binpac.h"
#include "binpac_buffer.h"
namespace binpac {
namespace binpac
{
extern double network_time();
namespace {
const unsigned char CR = '\r';
const unsigned char LF = '\n';
}
namespace
{
const unsigned char CR = '\r';
const unsigned char LF = '\n';
}
binpac::FlowBuffer::Policy binpac::FlowBuffer::policy = {
// max_capacity
@ -67,9 +69,7 @@ void FlowBuffer::NewMessage()
switch ( mode_ )
{
case LINE_MODE:
bytes_to_advance = (frame_length_ +
(linebreak_style_ == STRICT_CRLF ?
2 : 1));
bytes_to_advance = (frame_length_ + (linebreak_style_ == STRICT_CRLF ? 2 : 1));
break;
case FRAME_MODE:
bytes_to_advance = frame_length_;
@ -118,14 +118,13 @@ void FlowBuffer::ExpandBuffer(int length)
if ( length > policy.max_capacity )
{
std::string reason = strfmt("expand past max capacity %d/%d",
length, policy.max_capacity);
std::string reason = strfmt("expand past max capacity %d/%d", length, policy.max_capacity);
throw ExceptionFlowBufferAlloc(reason.c_str());
}
// Allocate a new buffer and copy the existing contents
buffer_length_ = length;
unsigned char* new_buf = (unsigned char *) realloc(buffer_, buffer_length_);
unsigned char* new_buf = (unsigned char*)realloc(buffer_, buffer_length_);
if ( ! new_buf )
throw ExceptionFlowBufferAlloc("expand realloc OOM");
@ -139,7 +138,7 @@ void FlowBuffer::ContractBuffer()
return;
buffer_length_ = policy.min_capacity;
unsigned char* new_buf = (unsigned char *) realloc(buffer_, buffer_length_);
unsigned char* new_buf = (unsigned char*)realloc(buffer_, buffer_length_);
if ( ! new_buf )
throw ExceptionFlowBufferAlloc("contract realloc OOM");
@ -233,8 +232,7 @@ void FlowBuffer::NewData(const_byteptr begin, const_byteptr end)
ClearPreviousData();
BINPAC_ASSERT((buffer_n_ == 0 && message_complete_) ||
orig_data_begin_ == orig_data_end_);
BINPAC_ASSERT((buffer_n_ == 0 && message_complete_) || orig_data_begin_ == orig_data_end_);
orig_data_begin_ = begin;
orig_data_end_ = end;
@ -273,8 +271,7 @@ void FlowBuffer::ClearPreviousData()
{
if ( frame_length_ > 0 )
{
frame_length_ -=
(orig_data_end_ - orig_data_begin_);
frame_length_ -= (orig_data_end_ - orig_data_begin_);
}
orig_data_begin_ = orig_data_end_;
}
@ -320,14 +317,14 @@ Finite state automaton for CR_OR_LF:
(!--line is complete, *--add to buffer)
CR_OR_LF_0:
CR: CR_OR_LF_1 !
LF: CR_OR_LF_0 !
.: CR_OR_LF_0 *
CR: CR_OR_LF_1 !
LF: CR_OR_LF_0 !
.: CR_OR_LF_0 *
CR_OR_LF_1:
CR: CR_OR_LF_1 !
LF: CR_OR_LF_0
.: CR_OR_LF_0 *
CR: CR_OR_LF_1 !
LF: CR_OR_LF_0
.: CR_OR_LF_0 *
*/
void FlowBuffer::MarkOrCopyLine_CR_OR_LF()
@ -335,8 +332,7 @@ void FlowBuffer::MarkOrCopyLine_CR_OR_LF()
if ( ! (orig_data_begin_ && orig_data_end_) )
return;
if ( state_ == CR_OR_LF_1 &&
orig_data_begin_ < orig_data_end_ && *orig_data_begin_ == LF )
if ( state_ == CR_OR_LF_1 && orig_data_begin_ < orig_data_end_ && *orig_data_begin_ == LF )
{
state_ = CR_OR_LF_0;
++orig_data_begin_;
@ -378,9 +374,8 @@ found_end_of_line:
message_complete_ = true;
#if DEBUG_FLOW_BUFFER
fprintf(stderr, "%.6f Line complete: [%s]\n",
network_time(),
string((const char *) begin(), (const char *) end()).c_str());
fprintf(stderr, "%.6f Line complete: [%s]\n", network_time(),
string((const char*)begin(), (const char*)end()).c_str());
#endif
}
@ -389,14 +384,14 @@ Finite state automaton and STRICT_CRLF:
(!--line is complete, *--add to buffer)
STRICT_CRLF_0:
CR: STRICT_CRLF_1 *
LF: STRICT_CRLF_0 *
.: STRICT_CRLF_0 *
CR: STRICT_CRLF_1 *
LF: STRICT_CRLF_0 *
.: STRICT_CRLF_0 *
STRICT_CRLF_1:
CR: STRICT_CRLF_1 *
LF: STRICT_CRLF_0 ! (--buffer_n_)
.: STRICT_CRLF_0 *
CR: STRICT_CRLF_1 *
LF: STRICT_CRLF_0 ! (--buffer_n_)
.: STRICT_CRLF_0 *
*/
void FlowBuffer::MarkOrCopyLine_STRICT_CRLF()
@ -442,9 +437,8 @@ found_end_of_line:
message_complete_ = true;
#if DEBUG_FLOW_BUFFER
fprintf(stderr, "%.6f Line complete: [%s]\n",
network_time(),
string((const char *) begin(), (const char *) end()).c_str());
fprintf(stderr, "%.6f Line complete: [%s]\n", network_time(),
string((const char*)begin(), (const char*)end()).c_str());
#endif
}
@ -477,13 +471,11 @@ found_end_of_line:
message_complete_ = true;
#if DEBUG_FLOW_BUFFER
fprintf(stderr, "%.6f Line complete: [%s]\n",
network_time(),
string((const char *) begin(), (const char *) end()).c_str());
fprintf(stderr, "%.6f Line complete: [%s]\n", network_time(),
string((const char*)begin(), (const char*)end()).c_str());
#endif
}
// Invariants:
//
// When buffer_n_ == 0:
@ -494,8 +486,7 @@ found_end_of_line:
void FlowBuffer::MarkOrCopyFrame()
{
if ( mode_ == FRAME_MODE && state_ == CR_OR_LF_1 &&
orig_data_begin_ < orig_data_end_ )
if ( mode_ == FRAME_MODE && state_ == CR_OR_LF_1 && orig_data_begin_ < orig_data_end_ )
{
// Skip the lingering LF
if ( *orig_data_begin_ == LF )
@ -508,8 +499,7 @@ void FlowBuffer::MarkOrCopyFrame()
if ( buffer_n_ == 0 )
{
// If there is enough data
if ( frame_length_ >= 0 &&
orig_data_end_ - orig_data_begin_ >= frame_length_ )
if ( frame_length_ >= 0 && orig_data_end_ - orig_data_begin_ >= frame_length_ )
{
// Do nothing except setting the message complete flag
message_complete_ = true;
@ -518,15 +508,14 @@ void FlowBuffer::MarkOrCopyFrame()
{
if ( ! chunked_ )
{
AppendToBuffer(orig_data_begin_,
orig_data_end_ - orig_data_begin_);
AppendToBuffer(orig_data_begin_, orig_data_end_ - orig_data_begin_);
}
message_complete_ = false;
}
}
else
{
BINPAC_ASSERT(!chunked_);
BINPAC_ASSERT(! chunked_);
int bytes_to_copy = orig_data_end_ - orig_data_begin_;
message_complete_ = false;
if ( frame_length_ >= 0 && buffer_n_ + bytes_to_copy >= frame_length_ )
@ -540,10 +529,8 @@ void FlowBuffer::MarkOrCopyFrame()
#if DEBUG_FLOW_BUFFER
if ( message_complete_ )
{
fprintf(stderr, "%.6f frame complete: [%s]\n",
network_time(),
string((const char *) begin(),
(const char *) end()).c_str());
fprintf(stderr, "%.6f frame complete: [%s]\n", network_time(),
string((const char*)begin(), (const char*)end()).c_str());
}
#endif
}
@ -562,4 +549,4 @@ void FlowBuffer::AppendToBuffer(const_byteptr data, int len)
BINPAC_ASSERT(orig_data_begin_ <= orig_data_end_);
}
} // namespace binpac
} // namespace binpac

View file

@ -2,24 +2,29 @@
#define binpac_buffer_h
#include <sys/types.h>
#include "binpac.h"
namespace binpac {
namespace binpac
{
class FlowBuffer {
class FlowBuffer
{
public:
struct Policy {
struct Policy
{
int max_capacity;
int min_capacity;
int contract_threshold;
};
};
enum LineBreakStyle {
CR_OR_LF, // CR or LF or CRLF
STRICT_CRLF, // CR followed by LF
CR_LF_NUL, // CR or LF or CR-LF or CR-NUL
LINE_BREAKER, // User specified linebreaker
};
enum LineBreakStyle
{
CR_OR_LF, // CR or LF or CRLF
STRICT_CRLF, // CR followed by LF
CR_LF_NUL, // CR or LF or CR-LF or CR-NUL
LINE_BREAKER, // User specified linebreaker
};
FlowBuffer(LineBreakStyle linebreak_style = CR_OR_LF);
virtual ~FlowBuffer();
@ -39,13 +44,12 @@ public:
void DiscardData();
// Whether there is enough data for the frame
bool ready() const{ return message_complete_ || mode_ == UNKNOWN_MODE; }
bool ready() const { return message_complete_ || mode_ == UNKNOWN_MODE; }
inline const_byteptr begin() const
{
BINPAC_ASSERT(ready());
return ( buffer_n_ == 0 ) ?
orig_data_begin_ : buffer_;
return (buffer_n_ == 0) ? orig_data_begin_ : buffer_;
}
inline const_byteptr end() const
@ -67,15 +71,14 @@ public:
if ( buffer_n_ > 0 )
return buffer_n_;
if ( frame_length_ < 0 ||
orig_data_begin_ + frame_length_ > orig_data_end_ )
if ( frame_length_ < 0 || orig_data_begin_ + frame_length_ > orig_data_end_ )
return orig_data_end_ - orig_data_begin_;
else
return frame_length_;
}
inline bool data_available() const
{
{
return buffer_n_ > 0 || orig_data_end_ > orig_data_begin_;
}
@ -88,21 +91,19 @@ public:
int data_seq() const
{
int data_seq_at_orig_data_begin =
data_seq_at_orig_data_end_ -
(orig_data_end_ - orig_data_begin_);
int data_seq_at_orig_data_begin = data_seq_at_orig_data_end_ -
(orig_data_end_ - orig_data_begin_);
if ( buffer_n_ > 0 )
return data_seq_at_orig_data_begin;
else
return data_seq_at_orig_data_begin + data_length();
}
bool eof() const { return eof_; }
bool eof() const { return eof_; }
void set_eof();
bool have_pending_request() const { return have_pending_request_; }
static void init(Policy p)
{ policy = p; }
static void init(Policy p) { policy = p; }
protected:
// Reset the buffer for a new message
@ -140,41 +141,43 @@ protected:
void MarkOrCopyLine_STRICT_CRLF();
void MarkOrCopyLine_LINEBREAK();
int buffer_n_; // number of bytes in the buffer
int buffer_length_; // size of the buffer
int buffer_n_; // number of bytes in the buffer
int buffer_length_; // size of the buffer
unsigned char* buffer_;
bool message_complete_;
int frame_length_;
bool chunked_;
bool message_complete_;
int frame_length_;
bool chunked_;
const_byteptr orig_data_begin_, orig_data_end_;
LineBreakStyle linebreak_style_;
LineBreakStyle linebreak_style_default;
unsigned char linebreaker_;
unsigned char linebreaker_;
enum {
enum
{
UNKNOWN_MODE,
LINE_MODE,
FRAME_MODE,
} mode_;
} mode_;
enum {
enum
{
CR_OR_LF_0,
CR_OR_LF_1,
STRICT_CRLF_0,
STRICT_CRLF_1,
FRAME_0,
} state_;
} state_;
int data_seq_at_orig_data_end_;
bool eof_;
bool have_pending_request_;
int data_seq_at_orig_data_end_;
bool eof_;
bool have_pending_request_;
static Policy policy;
};
};
typedef FlowBuffer *flow_buffer_t;
typedef FlowBuffer* flow_buffer_t;
} // namespace binpac
} // namespace binpac
#endif // binpac_buffer_h

View file

@ -1,24 +1,25 @@
#define binpac_regex_h
#include <stdlib.h>
#include "binpac_bytestring.h"
#include <stdlib.h>
namespace binpac
{
std::string std_string(bytestring const *s)
{
return std::string((const char *) s->begin(), (const char *) s->end());
std::string std_string(bytestring const* s)
{
return std::string((const char*)s->begin(), (const char*)s->end());
}
int bytestring_to_int(bytestring const *s)
int bytestring_to_int(bytestring const* s)
{
return atoi((const char *) s->begin());
return atoi((const char*)s->begin());
}
double bytestring_to_double(bytestring const *s)
double bytestring_to_double(bytestring const* s)
{
return atof((const char *) s->begin());
return atof((const char*)s->begin());
}
} // namespace binpac
} // namespace binpac

View file

@ -3,155 +3,118 @@
#include <string.h>
#include <string>
#include "binpac.h"
namespace binpac
{
{
template<class T> class datastring;
template <class T> class datastring;
template <class T>
class const_datastring
{
template <class T> class const_datastring
{
public:
const_datastring()
: begin_(0), end_(0)
{
}
const_datastring() : begin_(0), end_(0) { }
const_datastring(T const *data, int length)
: begin_(data), end_(data + length)
{
}
const_datastring(T const* data, int length) : begin_(data), end_(data + length) { }
const_datastring(const T *begin, const T *end)
: begin_(begin), end_(end)
{
}
const_datastring(const T* begin, const T* end) : begin_(begin), end_(end) { }
const_datastring(datastring<T> const &s)
: begin_(s.begin()), end_(s.end())
{
}
const_datastring(datastring<T> const& s) : begin_(s.begin()), end_(s.end()) { }
void init(const T *data, int length)
void init(const T* data, int length)
{
begin_ = data;
end_ = data + length;
}
T const *begin() const { return begin_; }
T const *end() const { return end_; }
int length() const { return end_ - begin_; }
T const* begin() const { return begin_; }
T const* end() const { return end_; }
int length() const { return end_ - begin_; }
T const &operator[](int index) const
{
return begin()[index];
}
T const& operator[](int index) const { return begin()[index]; }
bool operator==(const_datastring<T> const &s)
bool operator==(const_datastring<T> const& s)
{
if ( length() != s.length() )
return false;
return memcmp((const void *) begin(), (const void *) s.begin(),
sizeof(T) * length()) == 0;
return memcmp((const void*)begin(), (const void*)s.begin(), sizeof(T) * length()) == 0;
}
void set_begin(T const *begin) { begin_ = begin; }
void set_end(T const *end) { end_ = end; }
void set_begin(T const* begin) { begin_ = begin; }
void set_end(T const* end) { end_ = end; }
private:
T const *begin_;
T const *end_;
};
T const* begin_;
T const* end_;
};
typedef const_datastring<uint8> const_bytestring;
typedef const_datastring<uint8> const_bytestring;
template<class T>
class datastring
{
template <class T> class datastring
{
public:
datastring()
{
clear();
}
datastring() { clear(); }
datastring(T *data, int len)
{
set(data, len);
}
datastring(T* data, int len) { set(data, len); }
datastring(T const *begin, T const *end)
{
set_const(begin, end - begin);
}
datastring(T const* begin, T const* end) { set_const(begin, end - begin); }
datastring(datastring<T> const &x)
: data_(x.data()), length_(x.length())
{
}
datastring(datastring<T> const& x) : data_(x.data()), length_(x.length()) { }
explicit datastring(const_datastring<T> const &x)
{
set_const(x.begin(), x.length());
}
explicit datastring(const_datastring<T> const& x) { set_const(x.begin(), x.length()); }
datastring const &operator=(datastring<T> const &x)
datastring const& operator=(datastring<T> const& x)
{
BINPAC_ASSERT(!data_);
BINPAC_ASSERT(! data_);
set(x.data(), x.length());
return *this;
}
void init(T const *begin, int length)
void init(T const* begin, int length)
{
BINPAC_ASSERT(!data_);
BINPAC_ASSERT(! data_);
set_const(begin, length);
}
void clear()
{
data_ = 0; length_ = 0;
data_ = 0;
length_ = 0;
}
void free()
{
if ( data_ )
delete [] data_;
delete[] data_;
clear();
}
void clone()
{
set_const(begin(), length());
}
void clone() { set_const(begin(), length()); }
datastring const &operator=(const_datastring<T> const &x)
datastring const& operator=(const_datastring<T> const& x)
{
BINPAC_ASSERT(!data_);
BINPAC_ASSERT(! data_);
set_const(x.begin(), x.length());
return *this;
}
T const &operator[](int index) const
{
return begin()[index];
}
T const& operator[](int index) const { return begin()[index]; }
T *data() const { return data_; }
int length() const { return length_; }
T* data() const { return data_; }
int length() const { return length_; }
T const *begin() const { return data_; }
T const *end() const { return data_ + length_; }
T const* begin() const { return data_; }
T const* end() const { return data_ + length_; }
private:
void set(T *data, int len)
void set(T* data, int len)
{
data_ = data;
length_ = len;
}
void set_const(T const *data, int len)
void set_const(T const* data, int len)
{
length_ = len;
data_ = new T[len + 1];
@ -159,41 +122,39 @@ private:
data_[len] = 0;
}
T * data_;
T* data_;
int length_;
};
};
typedef datastring<uint8> bytestring;
inline const char *c_str(bytestring const &s)
inline const char* c_str(bytestring const& s)
{
return (const char *) s.begin();
return (const char*)s.begin();
}
inline std::string std_str(const_bytestring const &s)
inline std::string std_str(const_bytestring const& s)
{
return std::string((const char *) s.begin(), (const char *) s.end());
return std::string((const char*)s.begin(), (const char*)s.end());
}
inline bool operator==(bytestring const &s1, const char *s2)
inline bool operator==(bytestring const& s1, const char* s2)
{
return strcmp(c_str(s1), s2) == 0;
}
inline void get_pointers(const_bytestring const &s,
uint8 const **pbegin, uint8 const **pend)
inline void get_pointers(const_bytestring const& s, uint8 const** pbegin, uint8 const** pend)
{
*pbegin = s.begin();
*pend = s.end();
}
inline void get_pointers(bytestring const *s,
uint8 const **pbegin, uint8 const **pend)
inline void get_pointers(bytestring const* s, uint8 const** pbegin, uint8 const** pend)
{
*pbegin = s->begin();
*pend = s->end();
}
} // namespace binpac
} // namespace binpac
#endif // binpac_bytestring_h
#endif // binpac_bytestring_h

View file

@ -1,133 +1,120 @@
#ifndef binpac_exception_h
#define binpac_exception_h
#include <stdint.h>
#include <inttypes.h>
#include <stdint.h>
namespace binpac {
namespace binpac
{
class Exception
{
{
public:
Exception(const char* m = 0)
: msg_("binpac exception: ")
Exception(const char* m = 0) : msg_("binpac exception: ")
{
if ( m )
append(m);
// abort();
}
void append(string m) { msg_ += m; }
string msg() const { return msg_; }
const char* c_msg() const { return msg_.c_str(); }
void append(string m) { msg_ += m; }
string msg() const { return msg_; }
const char* c_msg() const { return msg_.c_str(); }
protected:
string msg_;
};
};
class ExceptionEnforceViolation : public Exception
{
{
public:
ExceptionEnforceViolation(const char* where)
{
append(binpac_fmt("&enforce violation : %s", where));
}
};
};
class ExceptionOutOfBound : public Exception
{
{
public:
ExceptionOutOfBound(const char* where, int len_needed, int len_given)
{
append(binpac_fmt("out_of_bound: %s: %d > %d",
where, len_needed, len_given));
append(binpac_fmt("out_of_bound: %s: %d > %d", where, len_needed, len_given));
}
};
};
class ExceptionInvalidCase : public Exception
{
{
public:
ExceptionInvalidCase(const char* location,
int64_t index,
const char *expected)
: location_(location),
index_(index),
expected_(expected)
ExceptionInvalidCase(const char* location, int64_t index, const char* expected)
: location_(location), index_(index), expected_(expected)
{
append(binpac_fmt("invalid case: %s: %" PRIi64 " (%s)",
location, index, expected));
append(binpac_fmt("invalid case: %s: %" PRIi64 " (%s)", location, index, expected));
}
protected:
const char* location_;
int64_t index_;
string expected_;
};
};
class ExceptionInvalidCaseIndex : public Exception
{
{
public:
ExceptionInvalidCaseIndex(const char* location,
int64_t index)
: location_(location),
index_(index)
ExceptionInvalidCaseIndex(const char* location, int64_t index)
: location_(location), index_(index)
{
append(binpac_fmt("invalid index for case: %s: %" PRIi64,
location, index));
append(binpac_fmt("invalid index for case: %s: %" PRIi64, location, index));
}
protected:
const char* location_;
int64_t index_;
};
};
class ExceptionInvalidOffset : public Exception
{
{
public:
ExceptionInvalidOffset(const char* location,
int min_offset, int offset)
: location_(location),
min_offset_(min_offset), offset_(offset)
ExceptionInvalidOffset(const char* location, int min_offset, int offset)
: location_(location), min_offset_(min_offset), offset_(offset)
{
append(binpac_fmt("invalid offset: %s: min_offset = %d, offset = %d",
location, min_offset, offset));
append(binpac_fmt("invalid offset: %s: min_offset = %d, offset = %d", location, min_offset,
offset));
}
protected:
const char* location_;
int min_offset_, offset_;
};
};
class ExceptionStringMismatch : public Exception
{
{
public:
ExceptionStringMismatch(const char* location,
const char *expected, const char *actual_data)
ExceptionStringMismatch(const char* location, const char* expected, const char* actual_data)
{
append(binpac_fmt("string mismatch at %s: \nexpected pattern: \"%s\"\nactual data: \"%s\"",
location, expected, actual_data));
location, expected, actual_data));
}
};
};
class ExceptionInvalidStringLength : public Exception
{
{
public:
ExceptionInvalidStringLength(const char* location, int len)
{
append(binpac_fmt("invalid length string: %s: %d",
location, len));
append(binpac_fmt("invalid length string: %s: %d", location, len));
}
};
};
class ExceptionFlowBufferAlloc : public Exception
{
{
public:
ExceptionFlowBufferAlloc(const char* reason)
{
append(binpac_fmt("flowbuffer allocation failed: %s", reason));
}
};
};
}
}
#endif // binpac_exception_h
#endif // binpac_exception_h

View file

@ -3,8 +3,9 @@
class RE_Matcher;
namespace binpac {
namespace binpac
{
std::vector<RE_Matcher*>* uncompiled_re_matchers = 0;
}
}

View file

@ -1,13 +1,17 @@
#ifndef binpac_regex_h
#define binpac_regex_h
#include "binpac.h"
#include "zeek/RE.h"
namespace zeek { class RE_Matcher; }
#include "binpac.h"
namespace zeek
{
class RE_Matcher;
}
namespace binpac
{
{
// Must be called before any binpac functionality is used.
//
@ -19,10 +23,10 @@ inline void init(FlowBuffer::Policy* fbp = 0);
// Internal vector recording not yet compiled matchers.
extern std::vector<zeek::RE_Matcher*>* uncompiled_re_matchers;
class RegExMatcher {
class RegExMatcher
{
public:
RegExMatcher(const char *pattern)
: pattern_(pattern)
RegExMatcher(const char* pattern) : pattern_(pattern)
{
if ( ! uncompiled_re_matchers )
uncompiled_re_matchers = new std::vector<zeek::RE_Matcher*>;
@ -31,16 +35,10 @@ public:
uncompiled_re_matchers->push_back(re_matcher_);
}
~RegExMatcher()
{
delete re_matcher_;
}
~RegExMatcher() { delete re_matcher_; }
// Returns the length of longest match, or -1 on mismatch.
int MatchPrefix(const_byteptr data, int len)
{
return re_matcher_->MatchPrefix(data, len);
}
int MatchPrefix(const_byteptr data, int len) { return re_matcher_->MatchPrefix(data, len); }
private:
friend void ::binpac::init(FlowBuffer::Policy*);
@ -49,8 +47,8 @@ private:
static void init();
string pattern_;
zeek::RE_Matcher *re_matcher_;
};
zeek::RE_Matcher* re_matcher_;
};
inline void RegExMatcher::init()
{
@ -77,6 +75,6 @@ inline void init(FlowBuffer::Policy* fbp)
FlowBuffer::init(*fbp);
}
} // namespace binpac
} // namespace binpac
#endif // binpac_regex_h
#endif // binpac_regex_h

View file

@ -1,3 +1,5 @@
#include "pac_action.h"
#include "pac_embedded.h"
#include "pac_exception.h"
#include "pac_id.h"
@ -6,17 +8,8 @@
#include "pac_typedecl.h"
#include "pac_utils.h"
#include "pac_action.h"
AnalyzerAction::AnalyzerAction(ID *action_id,
When when,
ActionParam *param,
EmbeddedCode *code)
: AnalyzerElement(ACTION),
action_id_(action_id),
when_(when),
param_(param),
code_(code),
AnalyzerAction::AnalyzerAction(ID* action_id, When when, ActionParam* param, EmbeddedCode* code)
: AnalyzerElement(ACTION), action_id_(action_id), when_(when), param_(param), code_(code),
analyzer_(0)
{
}
@ -33,31 +26,25 @@ string AnalyzerAction::action_function() const
return strfmt("Action_%s", action_id_->Name());
}
void AnalyzerAction::InstallHook(AnalyzerDecl *analyzer)
void AnalyzerAction::InstallHook(AnalyzerDecl* analyzer)
{
ASSERT(0);
analyzer_ = analyzer;
// param_->MainDataType()->InstallAction(this);
}
void AnalyzerAction::GenCode(Output *out_h, Output *out_cc, AnalyzerDecl *decl)
void AnalyzerAction::GenCode(Output* out_h, Output* out_cc, AnalyzerDecl* decl)
{
Env action_func_env(decl->env(), this);
action_func_env.AddID(param_->id(),
TEMP_VAR,
param_->DataType());
action_func_env.AddID(param_->id(), TEMP_VAR, param_->DataType());
action_func_env.SetEvaluated(param_->id());
string action_func_proto =
strfmt("%s(%s)",
action_function().c_str(),
ParamDecls(&action_func_env).c_str());
string action_func_proto = strfmt("%s(%s)", action_function().c_str(),
ParamDecls(&action_func_env).c_str());
out_h->println("void %s;", action_func_proto.c_str());
out_cc->println("void %s::%s",
decl->class_name().c_str(),
action_func_proto.c_str());
out_cc->println("void %s::%s", decl->class_name().c_str(), action_func_proto.c_str());
out_cc->inc_indent();
out_cc->println("{");
@ -69,28 +56,27 @@ void AnalyzerAction::GenCode(Output *out_h, Output *out_cc, AnalyzerDecl *decl)
out_cc->println("");
}
string AnalyzerAction::ParamDecls(Env *env) const
string AnalyzerAction::ParamDecls(Env* env) const
{
return param_->DeclStr(env);
}
Type *ActionParam::MainDataType() const
Type* ActionParam::MainDataType() const
{
// Note: this is not equal to DataType()
Type *main_type = TypeDecl::LookUpType(type()->type_id());
Type* main_type = TypeDecl::LookUpType(type()->type_id());
if ( ! main_type )
{
throw Exception(type()->type_id(),
"type not defined");
throw Exception(type()->type_id(), "type not defined");
}
return main_type;
}
Type *ActionParam::DataType() const
Type* ActionParam::DataType() const
{
Type *main_type = MainDataType();
Type* main_type = MainDataType();
if ( ! type()->field_id() )
{
@ -98,22 +84,18 @@ Type *ActionParam::DataType() const
}
else
{
Type *member_type =
main_type->MemberDataType(type()->field_id());
Type* member_type = main_type->MemberDataType(type()->field_id());
if ( ! member_type )
{
throw Exception(type()->field_id(),
strfmt("cannot find member type for `%s.%s'",
type()->type_id()->Name(),
type()->field_id()->Name()));
strfmt("cannot find member type for `%s.%s'", type()->type_id()->Name(),
type()->field_id()->Name()));
}
return member_type;
}
}
string ActionParam::DeclStr(Env *env) const
string ActionParam::DeclStr(Env* env) const
{
return strfmt("%s %s",
DataType()->DataTypeStr().c_str(),
env->LValue(id()));
return strfmt("%s %s", DataType()->DataTypeStr().c_str(), env->LValue(id()));
}

View file

@ -3,72 +3,74 @@
// Classes representing analyzer actions.
#include "pac_common.h"
#include "pac_analyzer.h"
#include "pac_common.h"
class AnalyzerAction : public AnalyzerElement
{
{
public:
enum When { BEFORE, AFTER };
enum When
{
BEFORE,
AFTER
};
AnalyzerAction(ID *action_id,
When when,
ActionParam *param,
EmbeddedCode *code);
AnalyzerAction(ID* action_id, When when, ActionParam* param, EmbeddedCode* code);
~AnalyzerAction();
When when() const { return when_; }
ActionParam *param() const { return param_; }
AnalyzerDecl *analyzer() const { return analyzer_; }
When when() const { return when_; }
ActionParam* param() const { return param_; }
AnalyzerDecl* analyzer() const { return analyzer_; }
string action_function() const;
// Generate function prototype and code for the action
void GenCode(Output *out_h, Output *out_cc, AnalyzerDecl *decl);
void GenCode(Output* out_h, Output* out_cc, AnalyzerDecl* decl);
// Install the hook at the corresponding data type parsing
// function to invoke the action.
void InstallHook(AnalyzerDecl *analyzer);
void InstallHook(AnalyzerDecl* analyzer);
private:
string ParamDecls(Env *env) const;
string ParamDecls(Env* env) const;
ID *action_id_;
ID* action_id_;
When when_;
ActionParam *param_;
EmbeddedCode *code_;
AnalyzerDecl *analyzer_;
};
ActionParam* param_;
EmbeddedCode* code_;
AnalyzerDecl* analyzer_;
};
class ActionParam
{
{
public:
ActionParam(const ID *id, ActionParamType *type)
: id_(id), type_(type) {}
ActionParam(const ID* id, ActionParamType* type) : id_(id), type_(type) { }
const ID *id() const { return id_; }
ActionParamType *type() const { return type_; }
const ID* id() const { return id_; }
ActionParamType* type() const { return type_; }
Type *MainDataType() const;
Type *DataType() const;
string DeclStr(Env *env) const;
Type* MainDataType() const;
Type* DataType() const;
string DeclStr(Env* env) const;
private:
const ID *id_;
ActionParamType *type_;
};
const ID* id_;
ActionParamType* type_;
};
class ActionParamType
{
{
public:
ActionParamType(const ID *type_id, const ID *field_id = 0)
: type_id_(type_id), field_id_(field_id) {}
ActionParamType(const ID* type_id, const ID* field_id = 0)
: type_id_(type_id), field_id_(field_id)
{
}
const ID *type_id() const { return type_id_; }
const ID *field_id() const { return field_id_; }
const ID* type_id() const { return type_id_; }
const ID* field_id() const { return field_id_; }
protected:
const ID *type_id_, *field_id_;
};
};
#endif // pac_action_h
#endif // pac_action_h

View file

@ -1,3 +1,5 @@
#include "pac_analyzer.h"
#include "pac_action.h"
#include "pac_context.h"
#include "pac_embedded.h"
@ -12,11 +14,7 @@
#include "pac_type.h"
#include "pac_varfield.h"
#include "pac_analyzer.h"
AnalyzerDecl::AnalyzerDecl(ID *id,
DeclType decl_type,
ParamList *params)
AnalyzerDecl::AnalyzerDecl(ID* id, DeclType decl_type, ParamList* params)
: TypeDecl(id, params, new DummyType())
{
decl_type_ = decl_type;
@ -47,74 +45,66 @@ AnalyzerDecl::~AnalyzerDecl()
delete_list(AnalyzerHelperList, eof_helpers_);
}
void AnalyzerDecl::AddElements(AnalyzerElementList *elemlist)
void AnalyzerDecl::AddElements(AnalyzerElementList* elemlist)
{
ASSERT(! env_);
foreach(i, AnalyzerElementList, elemlist)
foreach (i, AnalyzerElementList, elemlist)
{
AnalyzerElement *elem = *i;
AnalyzerElement* elem = *i;
switch ( elem->type() )
{
case AnalyzerElement::STATE:
{
ASSERT(0);
AnalyzerState *state_elem =
(AnalyzerState *) elem;
statevars_->insert(
statevars_->end(),
state_elem->statevars()->begin(),
state_elem->statevars()->end());
AnalyzerState* state_elem = (AnalyzerState*)elem;
statevars_->insert(statevars_->end(), state_elem->statevars()->begin(),
state_elem->statevars()->end());
}
break;
case AnalyzerElement::ACTION:
{
ASSERT(0);
AnalyzerAction *action_elem =
(AnalyzerAction *) elem;
AnalyzerAction* action_elem = (AnalyzerAction*)elem;
actions_->push_back(action_elem);
}
break;
case AnalyzerElement::HELPER:
{
AnalyzerHelper *helper_elem =
(AnalyzerHelper *) elem;
AnalyzerHelper* helper_elem = (AnalyzerHelper*)elem;
switch ( helper_elem->helper_type() )
{
{
case AnalyzerHelper::INIT_CODE:
constructor_helpers_->push_back(helper_elem);
constructor_helpers_->push_back(helper_elem);
break;
case AnalyzerHelper::CLEANUP_CODE:
destructor_helpers_->push_back(helper_elem);
destructor_helpers_->push_back(helper_elem);
break;
case AnalyzerHelper::EOF_CODE:
eof_helpers_->push_back(helper_elem);
eof_helpers_->push_back(helper_elem);
break;
default:
helpers_->push_back(helper_elem);
helpers_->push_back(helper_elem);
}
}
break;
case AnalyzerElement::FUNCTION:
{
AnalyzerFunction *func_elem =
(AnalyzerFunction *) elem;
Function *func = func_elem->function();
AnalyzerFunction* func_elem = (AnalyzerFunction*)elem;
Function* func = func_elem->function();
func->set_analyzer_decl(this);
functions_->push_back(func);
}
break;
case AnalyzerElement::FLOW:
{
AnalyzerFlow *flow_elem =
(AnalyzerFlow *) elem;
AnalyzerFlow* flow_elem = (AnalyzerFlow*)elem;
ProcessFlowElement(flow_elem);
}
break;
case AnalyzerElement::DATAUNIT:
{
AnalyzerDataUnit *dataunit_elem =
(AnalyzerDataUnit *) elem;
AnalyzerDataUnit* dataunit_elem = (AnalyzerDataUnit*)elem;
ProcessDataUnitElement(dataunit_elem);
}
break;
@ -134,19 +124,19 @@ void AnalyzerDecl::Prepare()
ASSERT(statevars_->empty());
ASSERT(actions_->empty());
foreach(i, FunctionList, functions_)
foreach (i, FunctionList, functions_)
{
Function *function = *i;
Function* function = *i;
function->Prepare(env_);
}
foreach(i, StateVarList, statevars_)
foreach (i, StateVarList, statevars_)
{
StateVar *statevar = *i;
StateVar* statevar = *i;
env_->AddID(statevar->id(), STATE_VAR, statevar->type());
}
foreach(i, AnalyzerActionList, actions_)
foreach (i, AnalyzerActionList, actions_)
{
AnalyzerAction *action = *i;
AnalyzerAction* action = *i;
action->InstallHook(this);
}
}
@ -154,30 +144,30 @@ void AnalyzerDecl::Prepare()
void AnalyzerDecl::GenForwardDeclaration(Output* out_h)
{
out_h->println("class %s;", class_name().c_str());
foreach(i, FunctionList, functions_)
foreach (i, FunctionList, functions_)
{
Function *function = *i;
Function* function = *i;
function->GenForwardDeclaration(out_h);
}
}
void AnalyzerDecl::GenActions(Output *out_h, Output *out_cc)
void AnalyzerDecl::GenActions(Output* out_h, Output* out_cc)
{
foreach(i, AnalyzerActionList, actions_)
foreach (i, AnalyzerActionList, actions_)
{
(*i)->GenCode(out_h, out_cc, this);
}
}
void AnalyzerDecl::GenHelpers(Output *out_h, Output *out_cc)
void AnalyzerDecl::GenHelpers(Output* out_h, Output* out_cc)
{
foreach(i, AnalyzerHelperList, helpers_)
foreach (i, AnalyzerHelperList, helpers_)
{
(*i)->GenCode(out_h, out_cc, this);
}
}
void AnalyzerDecl::GenPubDecls(Output *out_h, Output *out_cc)
void AnalyzerDecl::GenPubDecls(Output* out_h, Output* out_cc)
{
TypeDecl::GenPubDecls(out_h, out_cc);
@ -196,7 +186,7 @@ void AnalyzerDecl::GenPubDecls(Output *out_h, Output *out_cc)
// TODO: export public state variables
}
void AnalyzerDecl::GenPrivDecls(Output *out_h, Output *out_cc)
void AnalyzerDecl::GenPrivDecls(Output* out_h, Output* out_cc)
{
TypeDecl::GenPrivDecls(out_h, out_cc);
@ -210,65 +200,65 @@ void AnalyzerDecl::GenPrivDecls(Output *out_h, Output *out_cc)
// TODO: declare state variables
}
void AnalyzerDecl::GenInitCode(Output *out_cc)
void AnalyzerDecl::GenInitCode(Output* out_cc)
{
TypeDecl::GenInitCode(out_cc);
foreach(i, AnalyzerHelperList, constructor_helpers_)
foreach (i, AnalyzerHelperList, constructor_helpers_)
{
(*i)->GenCode(0, out_cc, this);
}
}
void AnalyzerDecl::GenCleanUpCode(Output *out_cc)
void AnalyzerDecl::GenCleanUpCode(Output* out_cc)
{
TypeDecl::GenCleanUpCode(out_cc);
foreach(i, AnalyzerHelperList, destructor_helpers_)
foreach (i, AnalyzerHelperList, destructor_helpers_)
{
(*i)->GenCode(0, out_cc, this);
}
}
void AnalyzerDecl::GenStateVarDecls(Output *out_h)
void AnalyzerDecl::GenStateVarDecls(Output* out_h)
{
foreach(i, StateVarList, statevars_)
foreach (i, StateVarList, statevars_)
{
StateVar *var = *i;
StateVar* var = *i;
var->GenDecl(out_h, env_);
}
}
void AnalyzerDecl::GenStateVarSetFunctions(Output *out_h)
void AnalyzerDecl::GenStateVarSetFunctions(Output* out_h)
{
foreach(i, StateVarList, statevars_)
foreach (i, StateVarList, statevars_)
{
StateVar *var = *i;
StateVar* var = *i;
var->GenSetFunction(out_h, env_);
}
}
void AnalyzerDecl::GenStateVarInitCode(Output *out_cc)
void AnalyzerDecl::GenStateVarInitCode(Output* out_cc)
{
foreach(i, StateVarList, statevars_)
foreach (i, StateVarList, statevars_)
{
StateVar *var = *i;
StateVar* var = *i;
var->GenInitCode(out_cc, env_);
}
}
void AnalyzerDecl::GenStateVarCleanUpCode(Output *out_cc)
void AnalyzerDecl::GenStateVarCleanUpCode(Output* out_cc)
{
foreach(i, StateVarList, statevars_)
foreach (i, StateVarList, statevars_)
{
StateVar *var = *i;
StateVar* var = *i;
var->GenCleanUpCode(out_cc, env_);
}
}
void AnalyzerDecl::GenFunctions(Output *out_h, Output *out_cc)
void AnalyzerDecl::GenFunctions(Output* out_h, Output* out_cc)
{
foreach(i, FunctionList, functions_)
foreach (i, FunctionList, functions_)
{
Function *function = *i;
Function* function = *i;
function->GenCode(out_h, out_cc);
}
}
@ -285,9 +275,9 @@ AnalyzerHelper::~AnalyzerHelper()
delete code_;
}
void AnalyzerHelper::GenCode(Output *out_h, Output *out_cc, AnalyzerDecl *decl)
void AnalyzerHelper::GenCode(Output* out_h, Output* out_cc, AnalyzerDecl* decl)
{
Output *out = 0;
Output* out = 0;
switch ( helper_type_ )
{
case MEMBER_DECLS:
@ -303,22 +293,18 @@ void AnalyzerHelper::GenCode(Output *out_h, Output *out_cc, AnalyzerDecl *decl)
code()->GenCode(out, decl->env());
}
FlowField::FlowField(ID *flow_id, ParameterizedType *flow_type)
: Field(FLOW_FIELD,
TYPE_NOT_TO_BE_PARSED | CLASS_MEMBER | PUBLIC_READABLE,
flow_id, flow_type)
FlowField::FlowField(ID* flow_id, ParameterizedType* flow_type)
: Field(FLOW_FIELD, TYPE_NOT_TO_BE_PARSED | CLASS_MEMBER | PUBLIC_READABLE, flow_id, flow_type)
{
}
void FlowField::GenInitCode(Output *out_cc, Env *env)
void FlowField::GenInitCode(Output* out_cc, Env* env)
{
type_->GenPreParsing(out_cc, env);
}
AnalyzerFlow::AnalyzerFlow(Direction dir, ID *type_id, ExprList *params)
: AnalyzerElement(FLOW),
dir_(dir),
type_id_(type_id)
AnalyzerFlow::AnalyzerFlow(Direction dir, ID* type_id, ExprList* params)
: AnalyzerElement(FLOW), dir_(dir), type_id_(type_id)
{
if ( ! params )
params = new ExprList();
@ -326,9 +312,9 @@ AnalyzerFlow::AnalyzerFlow(Direction dir, ID *type_id, ExprList *params)
// Add "this" to the list of params
params->insert(params->begin(), new Expr(this_id->clone()));
ID *flow_id = ((dir == UP) ? upflow_id : downflow_id)->clone();
ID* flow_id = ((dir == UP) ? upflow_id : downflow_id)->clone();
ParameterizedType *flow_type = new ParameterizedType(type_id_, params);
ParameterizedType* flow_type = new ParameterizedType(type_id_, params);
flow_field_ = new FlowField(flow_id, flow_type);
@ -340,18 +326,17 @@ AnalyzerFlow::~AnalyzerFlow()
delete flow_field_;
}
FlowDecl *AnalyzerFlow::flow_decl()
FlowDecl* AnalyzerFlow::flow_decl()
{
DEBUG_MSG("Getting flow_decl for %s\n", type_id_->Name());
if ( ! flow_decl_ )
{
Decl *decl = Decl::LookUpDecl(type_id_);
Decl* decl = Decl::LookUpDecl(type_id_);
if ( decl && decl->decl_type() == Decl::FLOW )
flow_decl_ = static_cast<FlowDecl *>(decl);
flow_decl_ = static_cast<FlowDecl*>(decl);
if ( ! flow_decl_ )
{
throw Exception(this,
"cannot find the flow declaration");
throw Exception(this, "cannot find the flow declaration");
}
}
return flow_decl_;

View file

@ -7,162 +7,172 @@
class AnalyzerElement;
class AnalyzerState;
class AnalyzerAction; // defined in pac_action.h
class AnalyzerAction; // defined in pac_action.h
class AnalyzerHelper;
class AnalyzerFlow;
class AnalyzerDataUnit;
class AnalyzerFunction;
class ConnDecl;
class FlowDecl;
typedef vector<AnalyzerHelper *> AnalyzerHelperList;
typedef vector<Function *> FunctionList;
typedef vector<AnalyzerHelper*> AnalyzerHelperList;
typedef vector<Function*> FunctionList;
class AnalyzerDecl : public TypeDecl
{
{
public:
AnalyzerDecl(ID *id, DeclType decl_type, ParamList *params);
AnalyzerDecl(ID* id, DeclType decl_type, ParamList* params);
~AnalyzerDecl();
void AddElements(AnalyzerElementList *elemlist);
void AddElements(AnalyzerElementList* elemlist);
void Prepare();
void GenForwardDeclaration(Output *out_h);
void GenForwardDeclaration(Output* out_h);
// void GenCode(Output *out_h, Output *out_cc);
void GenInitCode(Output *out_cc);
void GenCleanUpCode(Output *out_cc);
void GenInitCode(Output* out_cc);
void GenCleanUpCode(Output* out_cc);
string class_name() const;
// string cookie_name() const;
protected:
virtual void ProcessFlowElement(AnalyzerFlow *flow_elem) = 0;
virtual void ProcessDataUnitElement(AnalyzerDataUnit *dataunit_elem) = 0;
virtual void ProcessFlowElement(AnalyzerFlow* flow_elem) = 0;
virtual void ProcessDataUnitElement(AnalyzerDataUnit* dataunit_elem) = 0;
// Generate public/private declarations for member functions and
// variables
void GenPubDecls(Output *out_h, Output *out_cc);
void GenPrivDecls(Output *out_h, Output *out_cc);
void GenPubDecls(Output* out_h, Output* out_cc);
void GenPrivDecls(Output* out_h, Output* out_cc);
// Generate the NewData() function
virtual void GenProcessFunc(Output *out_h, Output *out_cc) = 0;
virtual void GenProcessFunc(Output* out_h, Output* out_cc) = 0;
// Generate the NewGap() function
virtual void GenGapFunc(Output *out_h, Output *out_cc) = 0;
virtual void GenGapFunc(Output* out_h, Output* out_cc) = 0;
// Generate the FlowEOF() function
virtual void GenEOFFunc(Output *out_h, Output *out_cc) = 0;
virtual void GenEOFFunc(Output* out_h, Output* out_cc) = 0;
// Generate the functions
void GenFunctions(Output *out_h, Output *out_cc);
void GenFunctions(Output* out_h, Output* out_cc);
// Generate the action functions
void GenActions(Output *out_h, Output *out_cc);
void GenActions(Output* out_h, Output* out_cc);
// Generate the helper code segments
void GenHelpers(Output *out_h, Output *out_cc);
void GenHelpers(Output* out_h, Output* out_cc);
// Generate declarations for state variables and their set functions
void GenStateVarDecls(Output *out_h);
void GenStateVarSetFunctions(Output *out_h);
void GenStateVarDecls(Output* out_h);
void GenStateVarSetFunctions(Output* out_h);
// Generate code for initializing and cleaning up (including
// memory de-allocating) state variables
void GenStateVarInitCode(Output *out_cc);
void GenStateVarCleanUpCode(Output *out_cc);
void GenStateVarInitCode(Output* out_cc);
void GenStateVarCleanUpCode(Output* out_cc);
StateVarList *statevars_;
AnalyzerActionList *actions_;
AnalyzerHelperList *helpers_;
FunctionList *functions_;
StateVarList* statevars_;
AnalyzerActionList* actions_;
AnalyzerHelperList* helpers_;
FunctionList* functions_;
AnalyzerHelperList *constructor_helpers_;
AnalyzerHelperList *destructor_helpers_;
AnalyzerHelperList *eof_helpers_;
};
AnalyzerHelperList* constructor_helpers_;
AnalyzerHelperList* destructor_helpers_;
AnalyzerHelperList* eof_helpers_;
};
class AnalyzerElement : public Object
{
{
public:
enum ElementType { STATE, ACTION, FUNCTION, HELPER, FLOW, DATAUNIT };
AnalyzerElement(ElementType type)
: type_(type) {}
virtual ~AnalyzerElement() {}
enum ElementType
{
STATE,
ACTION,
FUNCTION,
HELPER,
FLOW,
DATAUNIT
};
AnalyzerElement(ElementType type) : type_(type) { }
virtual ~AnalyzerElement() { }
ElementType type() const { return type_; }
ElementType type() const { return type_; }
private:
ElementType type_;
};
};
// A collection of variables representing analyzer states.
class AnalyzerState : public AnalyzerElement
{
{
public:
AnalyzerState(StateVarList *statevars)
: AnalyzerElement(STATE),
statevars_(statevars) {}
AnalyzerState(StateVarList* statevars) : AnalyzerElement(STATE), statevars_(statevars) { }
~AnalyzerState();
StateVarList *statevars() const { return statevars_; }
StateVarList* statevars() const { return statevars_; }
private:
StateVarList *statevars_;
};
StateVarList* statevars_;
};
// A collection of embedded C++ code
class AnalyzerHelper : public AnalyzerElement
{
{
public:
enum Type {
enum Type
{
MEMBER_DECLS,
INIT_CODE,
CLEANUP_CODE,
EOF_CODE,
};
AnalyzerHelper(Type helper_type, EmbeddedCode *code)
: AnalyzerElement(HELPER),
helper_type_(helper_type),
code_(code) {}
};
AnalyzerHelper(Type helper_type, EmbeddedCode* code)
: AnalyzerElement(HELPER), helper_type_(helper_type), code_(code)
{
}
~AnalyzerHelper();
Type helper_type() const { return helper_type_; }
Type helper_type() const { return helper_type_; }
void GenCode(Output *out_h, Output *out_cc, AnalyzerDecl *decl);
void GenCode(Output* out_h, Output* out_cc, AnalyzerDecl* decl);
EmbeddedCode *code() const { return code_; }
EmbeddedCode* code() const { return code_; }
private:
Type helper_type_;
EmbeddedCode *code_;
};
EmbeddedCode* code_;
};
// The type and parameters of (uni-directional) flows of a connection.
class FlowField : public Field
{
{
public:
FlowField(ID *flow_id, ParameterizedType *flow_type);
void GenInitCode(Output *out, Env *env);
};
FlowField(ID* flow_id, ParameterizedType* flow_type);
void GenInitCode(Output* out, Env* env);
};
class AnalyzerFlow : public AnalyzerElement
{
{
public:
enum Direction { UP, DOWN };
AnalyzerFlow(Direction dir, ID *type_id, ExprList *params);
enum Direction
{
UP,
DOWN
};
AnalyzerFlow(Direction dir, ID* type_id, ExprList* params);
~AnalyzerFlow();
Direction dir() const { return dir_; }
FlowField *flow_field() const { return flow_field_; }
Direction dir() const { return dir_; }
FlowField* flow_field() const { return flow_field_; }
FlowDecl *flow_decl();
FlowDecl* flow_decl();
private:
Direction dir_;
ID *type_id_;
FlowField *flow_field_;
FlowDecl *flow_decl_;
};
ID* type_id_;
FlowField* flow_field_;
FlowDecl* flow_decl_;
};
#endif // pac_analyzer_h
#endif // pac_analyzer_h

View file

@ -1,3 +1,5 @@
#include "pac_array.h"
#include "pac_attr.h"
#include "pac_dataptr.h"
#include "pac_exception.h"
@ -9,9 +11,7 @@
#include "pac_utils.h"
#include "pac_varfield.h"
#include "pac_array.h"
ArrayType::ArrayType(Type *elemtype, Expr *length)
ArrayType::ArrayType(Type* elemtype, Expr* length)
: Type(ARRAY), elemtype_(elemtype), length_(length)
{
init();
@ -67,9 +67,9 @@ ArrayType::~ArrayType()
delete elem_dataptr_until_expr_;
}
Type *ArrayType::DoClone() const
Type* ArrayType::DoClone() const
{
Type *elemtype = elemtype_->Clone();
Type* elemtype = elemtype_->Clone();
if ( ! elemtype )
return 0;
return new ArrayType(elemtype, length_);
@ -85,45 +85,45 @@ string ArrayType::DataTypeStr() const
return datatype_str_;
}
Type *ArrayType::ElementDataType() const
Type* ArrayType::ElementDataType() const
{
return elemtype_;
}
string ArrayType::EvalElement(const string &array, const string &index) const
string ArrayType::EvalElement(const string& array, const string& index) const
{
if ( attr_transient_ )
throw Exception(this, "cannot access element in &transient array");
throw Exception(this, "cannot access element in &transient array");
return strfmt("(*(%s))[%s]", array.c_str(), index.c_str());
}
const ID *ArrayType::arraylength_var() const
const ID* ArrayType::arraylength_var() const
{
return arraylength_var_field_ ? arraylength_var_field_->id() : 0;
}
const ID *ArrayType::elem_it_var() const
const ID* ArrayType::elem_it_var() const
{
return elem_it_var_field_ ? elem_it_var_field_->id() : 0;
}
const ID *ArrayType::elem_var() const
const ID* ArrayType::elem_var() const
{
return elem_var_field_ ? elem_var_field_->id() : 0;
}
const ID *ArrayType::elem_dataptr_var() const
const ID* ArrayType::elem_dataptr_var() const
{
return elem_dataptr_var_field_ ? elem_dataptr_var_field_->id() : 0;
}
const ID *ArrayType::elem_input_var() const
const ID* ArrayType::elem_input_var() const
{
return elem_input_var_field_ ? elem_input_var_field_->id() : 0;
}
void ArrayType::ProcessAttr(Attr *a)
void ArrayType::ProcessAttr(Attr* a)
{
Type::ProcessAttr(a);
@ -133,15 +133,13 @@ void ArrayType::ProcessAttr(Attr *a)
{
if ( elemtype_->StaticSize(env()) != 1 )
{
throw Exception(elemtype_,
"&restofdata can be applied"
" to only byte arrays");
throw Exception(elemtype_, "&restofdata can be applied"
" to only byte arrays");
}
if ( length_ )
{
throw Exception(length_,
"&restofdata cannot be applied"
" to arrays with specified length");
throw Exception(length_, "&restofdata cannot be applied"
" to arrays with specified length");
}
attr_restofdata_ = true;
// As the array automatically extends to the end of
@ -161,17 +159,15 @@ void ArrayType::ProcessAttr(Attr *a)
bool ref_input = a->expr()->HasReference(input_macro_id);
if ( ref_element && ref_input )
{
throw Exception(a->expr(),
"cannot reference both $element and $input "
"in the same &until---please separate them.");
throw Exception(a->expr(), "cannot reference both $element and $input "
"in the same &until---please separate them.");
}
if ( ref_element )
{
if ( attr_until_element_expr_ )
{
throw Exception(a->expr(),
"multiple &until on $element");
throw Exception(a->expr(), "multiple &until on $element");
}
attr_until_element_expr_ = a->expr();
}
@ -179,8 +175,7 @@ void ArrayType::ProcessAttr(Attr *a)
{
if ( attr_until_input_expr_ )
{
throw Exception(a->expr(),
"multiple &until on $input");
throw Exception(a->expr(), "multiple &until on $input");
}
attr_until_input_expr_ = a->expr();
}
@ -188,8 +183,7 @@ void ArrayType::ProcessAttr(Attr *a)
{
if ( attr_generic_until_expr_ )
{
throw Exception(a->expr(),
"multiple &until condition");
throw Exception(a->expr(), "multiple &until condition");
}
attr_generic_until_expr_ = a->expr();
}
@ -201,51 +195,42 @@ void ArrayType::ProcessAttr(Attr *a)
}
}
void ArrayType::Prepare(Env *env, int flags)
void ArrayType::Prepare(Env* env, int flags)
{
if ( flags & TO_BE_PARSED )
{
ID *arraylength_var = new ID(strfmt("%s__arraylength", value_var()->Name()));
ID *elem_var = new ID(strfmt("%s__elem", value_var()->Name()));
ID *elem_it_var = new ID(strfmt("%s__it", elem_var->Name()));
ID* arraylength_var = new ID(strfmt("%s__arraylength", value_var()->Name()));
ID* elem_var = new ID(strfmt("%s__elem", value_var()->Name()));
ID* elem_it_var = new ID(strfmt("%s__it", elem_var->Name()));
elem_var_field_ =
new ParseVarField(Field::CLASS_MEMBER, elem_var, elemtype_);
elem_var_field_ = new ParseVarField(Field::CLASS_MEMBER, elem_var, elemtype_);
AddField(elem_var_field_);
if ( incremental_parsing() )
{
arraylength_var_field_ =
new PrivVarField(arraylength_var, extern_type_int->Clone());
elem_it_var_field_ =
new PrivVarField(elem_it_var, extern_type_int->Clone());
arraylength_var_field_ = new PrivVarField(arraylength_var, extern_type_int->Clone());
elem_it_var_field_ = new PrivVarField(elem_it_var, extern_type_int->Clone());
AddField(arraylength_var_field_);
AddField(elem_it_var_field_);
}
else
{
arraylength_var_field_ =
new TempVarField(arraylength_var, extern_type_int->Clone());
elem_it_var_field_ =
new TempVarField(elem_it_var, extern_type_int->Clone());
arraylength_var_field_ = new TempVarField(arraylength_var, extern_type_int->Clone());
elem_it_var_field_ = new TempVarField(elem_it_var, extern_type_int->Clone());
arraylength_var_field_->Prepare(env);
elem_it_var_field_->Prepare(env);
// Add elem_dataptr_var only when not parsing incrementally
ID *elem_dataptr_var =
new ID(strfmt("%s__dataptr", elem_var->Name()));
elem_dataptr_var_field_ = new TempVarField(
elem_dataptr_var,
extern_type_const_byteptr->Clone());
ID* elem_dataptr_var = new ID(strfmt("%s__dataptr", elem_var->Name()));
elem_dataptr_var_field_ = new TempVarField(elem_dataptr_var,
extern_type_const_byteptr->Clone());
elem_dataptr_var_field_->Prepare(env);
// until(dataptr >= end_of_data)
elem_dataptr_until_expr_ = new Expr(
Expr::EXPR_GE,
new Expr(elem_dataptr_var->clone()),
new Expr(end_of_data->clone()));
elem_dataptr_until_expr_ = new Expr(Expr::EXPR_GE, new Expr(elem_dataptr_var->clone()),
new Expr(end_of_data->clone()));
}
if ( attr_until_input_expr_ )
@ -259,7 +244,7 @@ void ArrayType::Prepare(Env *env, int flags)
Type::Prepare(env, flags);
}
void ArrayType::GenArrayLength(Output *out_cc, Env *env, const DataPtr& data)
void ArrayType::GenArrayLength(Output* out_cc, Env* env, const DataPtr& data)
{
if ( env->Evaluated(arraylength_var()) )
return;
@ -272,23 +257,17 @@ void ArrayType::GenArrayLength(Output *out_cc, Env *env, const DataPtr& data)
if ( length_ )
{
out_cc->println("%s = %s;",
env->LValue(arraylength_var()),
length_->EvalExpr(out_cc, env));
out_cc->println("%s = %s;", env->LValue(arraylength_var()), length_->EvalExpr(out_cc, env));
env->SetEvaluated(arraylength_var());
// Check negative array length
out_cc->println("if ( %s < 0 )",
env->LValue(arraylength_var()));
out_cc->println("if ( %s < 0 )", env->LValue(arraylength_var()));
out_cc->inc_indent();
out_cc->println("{");
out_cc->println("throw binpac::ExceptionOutOfBound(\"%s\",",
data_id_str_.c_str());
out_cc->println(" %s, (%s) - (%s));",
env->LValue(arraylength_var()),
env->RValue(end_of_data),
env->RValue(begin_of_data));
out_cc->println("throw binpac::ExceptionOutOfBound(\"%s\",", data_id_str_.c_str());
out_cc->println(" %s, (%s) - (%s));", env->LValue(arraylength_var()),
env->RValue(end_of_data), env->RValue(begin_of_data));
out_cc->println("}");
out_cc->dec_indent();
@ -305,15 +284,13 @@ void ArrayType::GenArrayLength(Output *out_cc, Env *env, const DataPtr& data)
// with it. Note that this check is *not* looking for whether the
// contents of the array will extend past the end of the data
// buffer.
out_cc->println("// Check array element quantity: %s",
data_id_str_.c_str());
out_cc->println("// Check array element quantity: %s", data_id_str_.c_str());
element_size = 1;
}
else
{
// Boundary check the entire array if elements have static size.
out_cc->println("// Check bounds for static-size array: %s",
data_id_str_.c_str());
out_cc->println("// Check bounds for static-size array: %s", data_id_str_.c_str());
elemtype_->SetBoundaryChecked();
element_size = elemtype_->StaticSize(env);
@ -325,66 +302,57 @@ void ArrayType::GenArrayLength(Output *out_cc, Env *env, const DataPtr& data)
// arbitrary number of empty records (i.e. cheap for them,
// but costly for us unless we have special optimization
// for this scenario to forgo the usual allocation).
throw Exception(this, "using an array of known-to-be-empty elements is possibly a bad idea");
throw Exception(
this, "using an array of known-to-be-empty elements is possibly a bad idea");
}
}
const char* array_ptr_expr = data.ptr_expr();
string max_elements_available = strfmt("((%s - %s) / %d)",
env->RValue(end_of_data),
array_ptr_expr,
element_size);
string max_elements_available = strfmt("((%s - %s) / %d)", env->RValue(end_of_data),
array_ptr_expr, element_size);
out_cc->println("if ( %s > %s )",
env->RValue(arraylength_var()),
out_cc->println("if ( %s > %s )", env->RValue(arraylength_var()),
max_elements_available.c_str());
out_cc->inc_indent();
out_cc->println("throw binpac::ExceptionOutOfBound(\"%s\",",
data_id_str_.c_str());
out_cc->println(" %s, (%s) - (%s));",
env->RValue(arraylength_var()),
env->RValue(end_of_data),
array_ptr_expr);
out_cc->println("throw binpac::ExceptionOutOfBound(\"%s\",", data_id_str_.c_str());
out_cc->println(" %s, (%s) - (%s));", env->RValue(arraylength_var()),
env->RValue(end_of_data), array_ptr_expr);
out_cc->dec_indent();
}
else if ( attr_restofdata_ )
{
ASSERT(elemtype_->StaticSize(env) == 1);
out_cc->println("%s = (%s) - (%s);",
env->LValue(arraylength_var()),
env->RValue(end_of_data),
data.ptr_expr());
out_cc->println("%s = (%s) - (%s);", env->LValue(arraylength_var()),
env->RValue(end_of_data), data.ptr_expr());
env->SetEvaluated(arraylength_var());
}
}
void ArrayType::GenPubDecls(Output *out_h, Env *env)
void ArrayType::GenPubDecls(Output* out_h, Env* env)
{
Type::GenPubDecls(out_h, env);
if ( declared_as_type() )
{
if ( attr_transient_ )
throw Exception(this, "cannot access element in &transient array");
throw Exception(this, "cannot access element in &transient array");
out_h->println("int size() const { return %s ? %s->size() : 0; }",
env->RValue(value_var()),
env->RValue(value_var()));
env->RValue(value_var()), env->RValue(value_var()));
out_h->println("%s operator[](int index) const { BINPAC_ASSERT(%s); return (*%s)[index]; }",
elemtype_->DataTypeConstRefStr().c_str(),
env->RValue(value_var()),
env->RValue(value_var()));
elemtype_->DataTypeConstRefStr().c_str(), env->RValue(value_var()),
env->RValue(value_var()));
}
}
void ArrayType::GenPrivDecls(Output *out_h, Env *env)
void ArrayType::GenPrivDecls(Output* out_h, Env* env)
{
ASSERT(elem_var_field_->type() == elemtype_);
ASSERT(elemtype_->value_var());
Type::GenPrivDecls(out_h, env);
}
void ArrayType::GenInitCode(Output *out_cc, Env *env)
void ArrayType::GenInitCode(Output* out_cc, Env* env)
{
// Do not initiate the array here
// out_cc->println("%s = new %s;", lvalue(), vector_str_.c_str());
@ -393,24 +361,19 @@ void ArrayType::GenInitCode(Output *out_cc, Env *env)
Type::GenInitCode(out_cc, env);
if ( incremental_parsing() )
{
out_cc->println("%s = -1;",
env->LValue(elem_it_var()));
out_cc->println("%s = -1;", env->LValue(elem_it_var()));
}
}
void ArrayType::GenCleanUpCode(Output *out_cc, Env *env)
void ArrayType::GenCleanUpCode(Output* out_cc, Env* env)
{
Type::GenCleanUpCode(out_cc, env);
if ( elemtype_->NeedsCleanUp() )
{
if ( ! elem_var_field_ )
{
ID *elem_var = new ID(strfmt("%s__elem", value_var()->Name()));
elem_var_field_ =
new ParseVarField(
Field::NOT_CLASS_MEMBER,
elem_var,
elemtype_);
ID* elem_var = new ID(strfmt("%s__elem", value_var()->Name()));
elem_var_field_ = new ParseVarField(Field::NOT_CLASS_MEMBER, elem_var, elemtype_);
elem_var_field_->Prepare(env);
}
@ -418,14 +381,11 @@ void ArrayType::GenCleanUpCode(Output *out_cc, Env *env)
out_cc->inc_indent();
out_cc->println("{");
out_cc->println("for ( int i = 0; i < (int) %s->size(); ++i )",
env->RValue(value_var()));
out_cc->println("for ( int i = 0; i < (int) %s->size(); ++i )", env->RValue(value_var()));
out_cc->inc_indent();
out_cc->println("{");
out_cc->println("%s %s = (*%s)[i];",
elemtype_->DataTypeStr().c_str(),
env->LValue(elem_var()),
lvalue());
out_cc->println("%s %s = (*%s)[i];", elemtype_->DataTypeStr().c_str(),
env->LValue(elem_var()), lvalue());
elemtype_->GenCleanUpCode(out_cc, env);
out_cc->println("}");
out_cc->dec_indent();
@ -436,28 +396,25 @@ void ArrayType::GenCleanUpCode(Output *out_cc, Env *env)
out_cc->println("delete %s;", lvalue());
}
string ArrayType::GenArrayInit(Output *out_cc, Env *env, bool known_array_length)
string ArrayType::GenArrayInit(Output* out_cc, Env* env, bool known_array_length)
{
string array_str;
array_str = lvalue();
if ( incremental_parsing() )
{
out_cc->println("if ( %s < 0 )",
env->LValue(elem_it_var()));
out_cc->println("if ( %s < 0 )", env->LValue(elem_it_var()));
out_cc->inc_indent();
out_cc->println("{");
out_cc->println("// Initialize only once");
out_cc->println("%s = 0;", env->LValue(elem_it_var()));
}
out_cc->println("%s = new %s;",
lvalue(), vector_str_.c_str());
out_cc->println("%s = new %s;", lvalue(), vector_str_.c_str());
if ( known_array_length )
{
out_cc->println("%s->reserve(%s);",
lvalue(), env->RValue(arraylength_var()));
out_cc->println("%s->reserve(%s);", lvalue(), env->RValue(arraylength_var()));
}
if ( incremental_parsing() )
@ -469,34 +426,29 @@ string ArrayType::GenArrayInit(Output *out_cc, Env *env, bool known_array_length
return array_str;
}
void ArrayType::GenElementAssignment(Output *out_cc, Env *env,
string const &array_str, bool use_vector)
void ArrayType::GenElementAssignment(Output* out_cc, Env* env, string const& array_str,
bool use_vector)
{
if ( attr_transient_ )
{
// Just discard.
out_cc->println("delete %s;", env->LValue(elem_var()));
return;
}
{
// Just discard.
out_cc->println("delete %s;", env->LValue(elem_var()));
return;
}
// Assign the element
if ( ! use_vector )
{
out_cc->println("%s[%s] = %s;",
array_str.c_str(),
env->LValue(elem_it_var()),
env->LValue(elem_var()));
out_cc->println("%s[%s] = %s;", array_str.c_str(), env->LValue(elem_it_var()),
env->LValue(elem_var()));
}
else
{
out_cc->println("%s->push_back(%s);",
array_str.c_str(),
env->LValue(elem_var()));
out_cc->println("%s->push_back(%s);", array_str.c_str(), env->LValue(elem_var()));
}
}
void ArrayType::DoGenParseCode(Output *out_cc, Env *env,
const DataPtr& data, int flags)
void ArrayType::DoGenParseCode(Output* out_cc, Env* env, const DataPtr& data, int flags)
{
GenArrayLength(out_cc, env, data);
@ -518,7 +470,7 @@ void ArrayType::DoGenParseCode(Output *out_cc, Env *env,
There are two cases when the input length can be determined:
1. The array has a static size;
2. The array length can be computed before parsing and
each element is of constant size.
each element is of constant size.
*/
bool compute_size_var = false;
@ -529,9 +481,8 @@ void ArrayType::DoGenParseCode(Output *out_cc, Env *env,
compute_size_var = false;
if ( ! incremental_parsing() &&
( StaticSize(env) >= 0 ||
( env->Evaluated(arraylength_var()) &&
elemtype_->StaticSize(env) >= 0 ) ) )
(StaticSize(env) >= 0 ||
(env->Evaluated(arraylength_var()) && elemtype_->StaticSize(env) >= 0)) )
{
GenBoundaryCheck(out_cc, env, data);
}
@ -552,22 +503,17 @@ void ArrayType::DoGenParseCode(Output *out_cc, Env *env,
if ( elem_dataptr_var() )
{
out_cc->println("const_byteptr %s = %s;",
env->LValue(elem_dataptr_var()), data.ptr_expr());
out_cc->println("const_byteptr %s = %s;", env->LValue(elem_dataptr_var()), data.ptr_expr());
env->SetEvaluated(elem_dataptr_var());
elem_data = DataPtr(env, elem_dataptr_var(), 0);
}
string for_condition = known_array_length ?
strfmt("%s < %s",
env->LValue(elem_it_var()),
env->RValue(arraylength_var())) :
"/* forever */";
string for_condition = known_array_length ? strfmt("%s < %s", env->LValue(elem_it_var()),
env->RValue(arraylength_var()))
: "/* forever */";
out_cc->println("for (; %s; ++%s)",
for_condition.c_str(),
env->LValue(elem_it_var()));
out_cc->println("for (; %s; ++%s)", for_condition.c_str(), env->LValue(elem_it_var()));
out_cc->inc_indent();
out_cc->println("{");
@ -597,8 +543,7 @@ void ArrayType::DoGenParseCode(Output *out_cc, Env *env,
if ( incremental_parsing() )
{
out_cc->println("if ( ! %s )",
elemtype_->parsing_complete(env).c_str());
out_cc->println("if ( ! %s )", elemtype_->parsing_complete(env).c_str());
out_cc->inc_indent();
out_cc->println("goto %s;", kNeedMoreData);
out_cc->dec_indent();
@ -608,12 +553,10 @@ void ArrayType::DoGenParseCode(Output *out_cc, Env *env,
if ( elem_dataptr_var() )
{
out_cc->println("%s += %s;",
env->LValue(elem_dataptr_var()),
elemtype_->DataSize(0, env, elem_data).c_str());
out_cc->println("BINPAC_ASSERT(%s <= %s);",
env->RValue(elem_dataptr_var()),
env->RValue(end_of_data));
out_cc->println("%s += %s;", env->LValue(elem_dataptr_var()),
elemtype_->DataSize(0, env, elem_data).c_str());
out_cc->println("BINPAC_ASSERT(%s <= %s);", env->RValue(elem_dataptr_var()),
env->RValue(end_of_data));
}
if ( attr_until_element_expr_ )
@ -632,55 +575,45 @@ void ArrayType::DoGenParseCode(Output *out_cc, Env *env,
if ( compute_size_var && elem_dataptr_var() && ! env->Evaluated(size_var()) )
{
// Compute the data size
out_cc->println("%s = %s - (%s);",
env->LValue(size_var()),
env->RValue(elem_dataptr_var()),
data.ptr_expr());
out_cc->println("%s = %s - (%s);", env->LValue(size_var()), env->RValue(elem_dataptr_var()),
data.ptr_expr());
env->SetEvaluated(size_var());
}
}
void ArrayType::GenUntilInputCheck(Output *out_cc, Env *env)
void ArrayType::GenUntilInputCheck(Output* out_cc, Env* env)
{
ID *elem_input_var_id = new ID(
strfmt("%s__elem_input", value_var()->Name()));
elem_input_var_field_ = new TempVarField(
elem_input_var_id, extern_type_const_bytestring->Clone());
ID* elem_input_var_id = new ID(strfmt("%s__elem_input", value_var()->Name()));
elem_input_var_field_ = new TempVarField(elem_input_var_id,
extern_type_const_bytestring->Clone());
elem_input_var_field_->Prepare(env);
out_cc->println("%s %s(%s, %s);",
extern_type_const_bytestring->DataTypeStr().c_str(),
env->LValue(elem_input_var()),
env->RValue(begin_of_data),
env->RValue(end_of_data));
out_cc->println("%s %s(%s, %s);", extern_type_const_bytestring->DataTypeStr().c_str(),
env->LValue(elem_input_var()), env->RValue(begin_of_data),
env->RValue(end_of_data));
env->SetEvaluated(elem_input_var());
GenUntilCheck(out_cc, env, attr_until_input_expr_, true);
}
void ArrayType::GenUntilCheck(Output *out_cc, Env *env,
Expr *until_expr, bool delete_elem)
void ArrayType::GenUntilCheck(Output* out_cc, Env* env, Expr* until_expr, bool delete_elem)
{
ASSERT(until_expr);
Env check_env(env, this);
check_env.AddMacro(element_macro_id,
new Expr(elem_var()->clone()));
check_env.AddMacro(element_macro_id, new Expr(elem_var()->clone()));
if ( elem_input_var() )
{
check_env.AddMacro(input_macro_id,
new Expr(elem_input_var()->clone()));
check_env.AddMacro(input_macro_id, new Expr(elem_input_var()->clone()));
}
out_cc->println("// Check &until(%s)", until_expr->orig());
out_cc->println("if ( %s )",
until_expr->EvalExpr(out_cc, &check_env));
out_cc->println("if ( %s )", until_expr->EvalExpr(out_cc, &check_env));
out_cc->inc_indent();
out_cc->println("{");
if ( parsing_complete_var() )
{
out_cc->println("%s = true;",
env->LValue(parsing_complete_var()));
out_cc->println("%s = true;", env->LValue(parsing_complete_var()));
}
if ( elemtype_->IsPointerType() )
@ -696,18 +629,14 @@ void ArrayType::GenUntilCheck(Output *out_cc, Env *env,
out_cc->dec_indent();
}
void ArrayType::GenDynamicSize(Output *out_cc, Env *env,
const DataPtr& data)
void ArrayType::GenDynamicSize(Output* out_cc, Env* env, const DataPtr& data)
{
ASSERT(! incremental_input());
DEBUG_MSG("Generating dynamic size for array `%s'\n",
value_var()->Name());
DEBUG_MSG("Generating dynamic size for array `%s'\n", value_var()->Name());
int elem_w = elemtype_->StaticSize(env);
if ( elem_w >= 0 &&
! attr_until_element_expr_ &&
! attr_until_input_expr_ &&
( length_ || attr_restofdata_ ) )
if ( elem_w >= 0 && ! attr_until_element_expr_ && ! attr_until_input_expr_ &&
(length_ || attr_restofdata_) )
{
// If the elements have a fixed size,
// we only need to compute the number of elements
@ -715,8 +644,8 @@ void ArrayType::GenDynamicSize(Output *out_cc, Env *env,
ASSERT(compute_size_var);
GenArrayLength(out_cc, env, data);
ASSERT(env->Evaluated(arraylength_var()));
out_cc->println("%s = %d * %s;",
env->LValue(size_var()), elem_w, env->RValue(arraylength_var()));
out_cc->println("%s = %d * %s;", env->LValue(size_var()), elem_w,
env->RValue(arraylength_var()));
env->SetEvaluated(size_var());
}
else
@ -726,7 +655,7 @@ void ArrayType::GenDynamicSize(Output *out_cc, Env *env,
}
}
int ArrayType::StaticSize(Env *env) const
int ArrayType::StaticSize(Env* env) const
{
int num = 0;
@ -737,8 +666,7 @@ int ArrayType::StaticSize(Env *env) const
if ( elem_w < 0 )
return -1;
DEBUG_MSG("static size of %s:%s = %d * %d\n",
decl_id()->Name(), lvalue(), elem_w, num);
DEBUG_MSG("static size of %s:%s = %d * %d\n", decl_id()->Name(), lvalue(), elem_w, num);
return num * elem_w;
}
@ -767,12 +695,11 @@ void ArrayType::DoMarkIncrementalInput()
bool ArrayType::RequiresAnalyzerContext()
{
return Type::RequiresAnalyzerContext() ||
( length_ && length_->RequiresAnalyzerContext() ) ||
return Type::RequiresAnalyzerContext() || (length_ && length_->RequiresAnalyzerContext()) ||
elemtype_->RequiresAnalyzerContext();
}
bool ArrayType::DoTraverse(DataDepVisitor *visitor)
bool ArrayType::DoTraverse(DataDepVisitor* visitor)
{
if ( ! Type::DoTraverse(visitor) )
return false;

View file

@ -7,86 +7,81 @@
// Fixed-length array and variable length sequence with an ending pattern
class ArrayType : public Type
{
{
public:
ArrayType(Type *arg_elemtype, Expr *arg_length = 0);
ArrayType(Type* arg_elemtype, Expr* arg_length = 0);
~ArrayType();
bool DefineValueVar() const;
string DataTypeStr() const;
string DefaultValue() const { return "0"; }
Type *ElementDataType() const;
string DefaultValue() const { return "0"; }
Type* ElementDataType() const;
string EvalElement(const string &array, const string &index) const;
string EvalElement(const string& array, const string& index) const;
void ProcessAttr(Attr *a);
void ProcessAttr(Attr* a);
void Prepare(Env *env, int flags);
void Prepare(Env* env, int flags);
void GenPubDecls(Output *out, Env *env);
void GenPrivDecls(Output *out, Env *env);
void GenPubDecls(Output* out, Env* env);
void GenPrivDecls(Output* out, Env* env);
void GenInitCode(Output *out, Env *env);
void GenCleanUpCode(Output *out, Env *env);
void GenInitCode(Output* out, Env* env);
void GenCleanUpCode(Output* out, Env* env);
int StaticSize(Env *env) const;
int StaticSize(Env* env) const;
void SetBoundaryChecked();
void GenUntilInputCheck(Output *out_cc, Env *env);
void GenUntilInputCheck(Output* out_cc, Env* env);
bool IsPointerType() const { return true; }
bool IsPointerType() const { return true; }
protected:
void init();
void DoGenParseCode(Output *out, Env *env, const DataPtr& data, int flags);
void GenDynamicSize(Output *out, Env *env, const DataPtr& data);
void GenArrayLength(Output *out_cc, Env *env, const DataPtr& data);
string GenArrayInit(Output *out_cc, Env *env, bool known_array_length);
void GenElementAssignment(Output *out_cc, Env *env,
string const &array_str, bool use_vector);
void GenUntilCheck(Output *out_cc, Env *env,
Expr *until_condition, bool delete_elem);
void DoGenParseCode(Output* out, Env* env, const DataPtr& data, int flags);
void GenDynamicSize(Output* out, Env* env, const DataPtr& data);
void GenArrayLength(Output* out_cc, Env* env, const DataPtr& data);
string GenArrayInit(Output* out_cc, Env* env, bool known_array_length);
void GenElementAssignment(Output* out_cc, Env* env, string const& array_str, bool use_vector);
void GenUntilCheck(Output* out_cc, Env* env, Expr* until_condition, bool delete_elem);
bool ByteOrderSensitive() const
{
return elemtype_->RequiresByteOrder();
}
bool ByteOrderSensitive() const { return elemtype_->RequiresByteOrder(); }
bool RequiresAnalyzerContext();
Type *DoClone() const;
Type* DoClone() const;
void DoMarkIncrementalInput();
const ID *arraylength_var() const;
const ID *elem_it_var() const;
const ID *elem_var() const;
const ID *elem_dataptr_var() const;
const ID *elem_input_var() const;
const ID* arraylength_var() const;
const ID* elem_it_var() const;
const ID* elem_var() const;
const ID* elem_dataptr_var() const;
const ID* elem_input_var() const;
protected:
bool DoTraverse(DataDepVisitor *visitor);
bool DoTraverse(DataDepVisitor* visitor);
private:
Type *elemtype_;
Expr *length_;
Type* elemtype_;
Expr* length_;
string vector_str_;
string datatype_str_;
string end_of_array_loop_label_;
Field *arraylength_var_field_;
Field *elem_it_var_field_;
Field *elem_var_field_;
Field *elem_dataptr_var_field_;
Field *elem_input_var_field_;
Field* arraylength_var_field_;
Field* elem_it_var_field_;
Field* elem_var_field_;
Field* elem_dataptr_var_field_;
Field* elem_input_var_field_;
// This does not come from &until, but is internally generated
Expr *elem_dataptr_until_expr_;
Expr* elem_dataptr_until_expr_;
Expr *attr_generic_until_expr_;
Expr *attr_until_element_expr_;
Expr *attr_until_input_expr_;
};
Expr* attr_generic_until_expr_;
Expr* attr_until_element_expr_;
Expr* attr_until_input_expr_;
};
#endif // pac_array_h
#endif // pac_array_h

View file

@ -1,7 +1,8 @@
#include "pac_attr.h"
#include "pac_expr.h"
bool Attr::DoTraverse(DataDepVisitor *visitor)
bool Attr::DoTraverse(DataDepVisitor* visitor)
{
if ( expr_ && ! expr_->Traverse(visitor) )
return false;
@ -20,23 +21,20 @@ void Attr::init()
delete_expr_ = false;
}
Attr::Attr(AttrType type)
: DataDepElement(DataDepElement::ATTR)
Attr::Attr(AttrType type) : DataDepElement(DataDepElement::ATTR)
{
type_ = type;
init();
}
Attr::Attr(AttrType type, Expr *expr)
: DataDepElement(DataDepElement::ATTR)
Attr::Attr(AttrType type, Expr* expr) : DataDepElement(DataDepElement::ATTR)
{
type_ = type;
init();
expr_ = expr;
}
Attr::Attr(AttrType type, ExprList *exprlist)
: DataDepElement(DataDepElement::ATTR)
Attr::Attr(AttrType type, ExprList* exprlist) : DataDepElement(DataDepElement::ATTR)
{
type_ = type;
init();
@ -44,8 +42,7 @@ Attr::Attr(AttrType type, ExprList *exprlist)
delete_expr_ = true;
}
Attr::Attr(AttrType type, SeqEnd *seqend)
: DataDepElement(DataDepElement::ATTR)
Attr::Attr(AttrType type, SeqEnd* seqend) : DataDepElement(DataDepElement::ATTR)
{
type_ = type;
init();
@ -58,8 +55,7 @@ Attr::~Attr()
delete expr_;
}
LetAttr::LetAttr(FieldList *letfields)
: Attr(ATTR_LET)
LetAttr::LetAttr(FieldList* letfields) : Attr(ATTR_LET)
{
letfields_ = letfields;
}

View file

@ -4,7 +4,8 @@
#include "pac_common.h"
#include "pac_datadep.h"
enum AttrType {
enum AttrType
{
ATTR_BYTEORDER,
ATTR_CHECK,
ATTR_CHUNKED,
@ -22,44 +23,44 @@ enum AttrType {
ATTR_RESTOFFLOW,
ATTR_TRANSIENT,
ATTR_UNTIL,
};
};
class Attr : public Object, public DataDepElement
{
{
public:
Attr(AttrType type);
Attr(AttrType type, Expr *expr);
Attr(AttrType type, ExprList *exprlist);
Attr(AttrType type, SeqEnd *seqend);
Attr(AttrType type, Expr* expr);
Attr(AttrType type, ExprList* exprlist);
Attr(AttrType type, SeqEnd* seqend);
virtual ~Attr();
AttrType type() const { return type_; }
Expr *expr() const { return expr_; }
SeqEnd *seqend() const { return seqend_; }
AttrType type() const { return type_; }
Expr* expr() const { return expr_; }
SeqEnd* seqend() const { return seqend_; }
bool RequiresAnalyzerContext() const;
protected:
bool DoTraverse(DataDepVisitor *visitor);
bool DoTraverse(DataDepVisitor* visitor);
protected:
void init();
AttrType type_;
Expr *expr_;
SeqEnd *seqend_;
Expr* expr_;
SeqEnd* seqend_;
bool delete_expr_;
};
};
class LetAttr : public Attr
{
{
public:
LetAttr(FieldList *letfields);
FieldList *letfields() const { return letfields_; }
LetAttr(FieldList* letfields);
FieldList* letfields() const { return letfields_; }
private:
FieldList *letfields_;
};
FieldList* letfields_;
};
#endif // pac_attr_h
#endif // pac_attr_h

View file

@ -1,9 +1,10 @@
#include "pac_btype.h"
#include "pac_dataptr.h"
#include "pac_id.h"
#include "pac_output.h"
Type *BuiltInType::DoClone() const
Type* BuiltInType::DoClone() const
{
return new BuiltInType(bit_type());
}
@ -11,20 +12,19 @@ Type *BuiltInType::DoClone() const
bool BuiltInType::IsNumericType() const
{
BITType t = bit_type();
return (t == INT8 || t == INT16 || t == INT32 || t == INT64 ||
t == UINT8 || t == UINT16 || t == UINT32 || t == UINT64);
return (t == INT8 || t == INT16 || t == INT32 || t == INT64 || t == UINT8 || t == UINT16 ||
t == UINT32 || t == UINT64);
}
bool BuiltInType::CompatibleBuiltInTypes(BuiltInType *type1,
BuiltInType *type2)
bool BuiltInType::CompatibleBuiltInTypes(BuiltInType* type1, BuiltInType* type2)
{
return type1->IsNumericType() && type2->IsNumericType();
}
static const char* basic_pactype_name[] = {
# define TYPE_DEF(name, pactype, ctype, size) pactype,
# include "pac_type.def"
# undef TYPE_DEF
#define TYPE_DEF(name, pactype, ctype, size) pactype,
#include "pac_type.def"
#undef TYPE_DEF
0,
};
@ -32,9 +32,7 @@ void BuiltInType::static_init()
{
for ( int bit_type = 0; basic_pactype_name[bit_type]; ++bit_type )
{
Type::AddPredefinedType(
basic_pactype_name[bit_type],
new BuiltInType((BITType) bit_type));
Type::AddPredefinedType(basic_pactype_name[bit_type], new BuiltInType((BITType)bit_type));
}
}
@ -48,9 +46,9 @@ int BuiltInType::LookUpByName(const char* name)
}
static const char* basic_ctype_name[] = {
# define TYPE_DEF(name, pactype, ctype, size) ctype,
# include "pac_type.def"
# undef TYPE_DEF
#define TYPE_DEF(name, pactype, ctype, size) ctype,
#include "pac_type.def"
#undef TYPE_DEF
0,
};
@ -66,12 +64,11 @@ string BuiltInType::DataTypeStr() const
int BuiltInType::StaticSize(Env* /* env */) const
{
static const size_t basic_type_size[] =
{
# define TYPE_DEF(name, pactype, ctype, size) size,
# include "pac_type.def"
# undef TYPE_DEF
};
static const size_t basic_type_size[] = {
#define TYPE_DEF(name, pactype, ctype, size) size,
#include "pac_type.def"
#undef TYPE_DEF
};
return basic_type_size[bit_type_];
}
@ -96,8 +93,7 @@ void BuiltInType::GenDynamicSize(Output* out_cc, Env* env, const DataPtr& data)
ASSERT(0);
}
void BuiltInType::DoGenParseCode(Output* out_cc, Env* env,
const DataPtr& data, int flags)
void BuiltInType::DoGenParseCode(Output* out_cc, Env* env, const DataPtr& data, int flags)
{
if ( bit_type_ == EMPTY )
return;
@ -118,8 +114,8 @@ void BuiltInType::DoGenParseCode(Output* out_cc, Env* env,
case INT8:
case UINT8:
out_cc->println("%s = *((%s const *) (%s));",
lvalue(), DataTypeStr().c_str(), data.ptr_expr());
out_cc->println("%s = *((%s const *) (%s));", lvalue(), DataTypeStr().c_str(),
data.ptr_expr());
break;
case INT16:
case UINT16:
@ -134,13 +130,10 @@ void BuiltInType::DoGenParseCode(Output* out_cc, Env* env,
data.ptr_expr(),
EvalByteOrder(out_cc, env).c_str());
#else
out_cc->println("%s = FixByteOrder(%s, *((%s const *) (%s)));",
lvalue(),
EvalByteOrder(out_cc, env).c_str(),
DataTypeStr().c_str(),
data.ptr_expr());
out_cc->println("%s = FixByteOrder(%s, *((%s const *) (%s)));", lvalue(),
EvalByteOrder(out_cc, env).c_str(), DataTypeStr().c_str(),
data.ptr_expr());
#endif
break;
}
}

View file

@ -4,49 +4,50 @@
#include "pac_type.h"
class BuiltInType : public Type
{
{
public:
enum BITType {
# define TYPE_DEF(name, pactype, ctype, size) name,
# include "pac_type.def"
# undef TYPE_DEF
};
enum BITType
{
#define TYPE_DEF(name, pactype, ctype, size) name,
#include "pac_type.def"
#undef TYPE_DEF
};
static int LookUpByName(const char *name);
static int LookUpByName(const char* name);
BuiltInType(BITType bit_type)
: Type(bit_type == BuiltInType::EMPTY ? Type::EMPTY : BUILTIN),
bit_type_(bit_type) {}
: Type(bit_type == BuiltInType::EMPTY ? Type::EMPTY : BUILTIN), bit_type_(bit_type)
{
}
BITType bit_type() const { return bit_type_; }
BITType bit_type() const { return bit_type_; }
bool IsNumericType() const;
bool DefineValueVar() const;
string DataTypeStr() const;
string DefaultValue() const { return "0"; }
string DefaultValue() const { return "0"; }
int StaticSize(Env *env) const;
int StaticSize(Env* env) const;
bool IsPointerType() const { return false; }
bool IsPointerType() const { return false; }
bool ByteOrderSensitive() const { return StaticSize(0) >= 2; }
void GenInitCode(Output *out_cc, Env *env);
void GenInitCode(Output* out_cc, Env* env);
void DoMarkIncrementalInput();
protected:
void DoGenParseCode(Output *out, Env *env, const DataPtr& data, int flags);
void GenDynamicSize(Output *out, Env *env, const DataPtr& data);
Type *DoClone() const;
void DoGenParseCode(Output* out, Env* env, const DataPtr& data, int flags);
void GenDynamicSize(Output* out, Env* env, const DataPtr& data);
Type* DoClone() const;
BITType bit_type_;
public:
static void static_init();
static bool CompatibleBuiltInTypes(BuiltInType *type1,
BuiltInType *type2);
};
static bool CompatibleBuiltInTypes(BuiltInType* type1, BuiltInType* type2);
};
#endif // pac_btype_h
#endif // pac_btype_h

View file

@ -1,3 +1,9 @@
#include "pac_case.h"
#include <stdint.h>
#include <limits>
#include "pac_btype.h"
#include "pac_exception.h"
#include "pac_expr.h"
#include "pac_exttype.h"
@ -5,18 +11,12 @@
#include "pac_output.h"
#include "pac_typedecl.h"
#include "pac_utils.h"
#include "pac_btype.h"
#include "pac_case.h"
#include <limits>
#include <stdint.h>
CaseType::CaseType(Expr* index_expr, CaseFieldList* cases)
: Type(CASE), index_expr_(index_expr), cases_(cases)
{
index_var_ = 0;
foreach(i, CaseFieldList, cases_)
foreach (i, CaseFieldList, cases_)
AddField(*i);
}
@ -27,10 +27,10 @@ CaseType::~CaseType()
delete cases_;
}
void CaseType::AddCaseField(CaseField *f)
void CaseType::AddCaseField(CaseField* f)
{
// All fields must be added before Prepare()
ASSERT(!env());
ASSERT(! env());
AddField(f);
cases_->push_back(f);
@ -47,11 +47,11 @@ string CaseType::DataTypeStr() const
return strfmt("%s *", type_decl()->class_name().c_str());
}
Type *CaseType::ValueType() const
Type* CaseType::ValueType() const
{
foreach (i, CaseFieldList, cases_)
{
CaseField *c = *i;
CaseField* c = *i;
return c->type();
}
ASSERT(0);
@ -73,13 +73,12 @@ void CaseType::Prepare(Env* env, int flags)
env->AddID(index_var_, MEMBER_VAR, 0);
// Sort the cases_ to put the default case at the end of the list
CaseFieldList::iterator default_case_it =
cases_->end(); // to avoid warning
CaseField *default_case = 0;
CaseFieldList::iterator default_case_it = cases_->end(); // to avoid warning
CaseField* default_case = 0;
foreach (i, CaseFieldList, cases_)
{
CaseField *c = *i;
CaseField* c = *i;
if ( ! c->index() )
{
if ( default_case )
@ -96,7 +95,7 @@ void CaseType::Prepare(Env* env, int flags)
foreach (i, CaseFieldList, cases_)
{
CaseField *c = *i;
CaseField* c = *i;
c->set_index_var(index_var_);
c->set_case_type(this);
}
@ -124,8 +123,8 @@ void CaseType::GenPubDecls(Output* out_h, Env* env)
if ( t->tot() != Type::BUILTIN )
t = extern_type_int;
out_h->println("%s %s const { return %s; }", t->DataTypeStr().c_str(),
env->RValue(index_var_), env->LValue(index_var_));
out_h->println("%s %s const { return %s; }", t->DataTypeStr().c_str(), env->RValue(index_var_),
env->LValue(index_var_));
Type::GenPubDecls(out_h, env);
}
@ -145,7 +144,7 @@ void CaseType::GenCleanUpCode(Output* out_cc, Env* env)
out_cc->println("{");
foreach (i, CaseFieldList, cases_)
{
CaseField *c = *i;
CaseField* c = *i;
c->GenCleanUpCode(out_cc, env);
}
out_cc->println("}");
@ -153,8 +152,7 @@ void CaseType::GenCleanUpCode(Output* out_cc, Env* env)
env->set_in_branch(false);
}
void CaseType::DoGenParseCode(Output* out_cc, Env* env,
const DataPtr& data, int flags)
void CaseType::DoGenParseCode(Output* out_cc, Env* env, const DataPtr& data, int flags)
{
if ( StaticSize(env) >= 0 )
GenBoundaryCheck(out_cc, env, data);
@ -164,8 +162,7 @@ void CaseType::DoGenParseCode(Output* out_cc, Env* env,
if ( ! incremental_input() )
compute_size_var = AddSizeVar(out_cc, env);
out_cc->println("%s = %s;",
env->LValue(index_var_), index_expr_->EvalExpr(out_cc, env));
out_cc->println("%s = %s;", env->LValue(index_var_), index_expr_->EvalExpr(out_cc, env));
env->SetEvaluated(index_var_);
env->set_in_branch(true);
@ -175,9 +172,8 @@ void CaseType::DoGenParseCode(Output* out_cc, Env* env,
bool has_default_case = false;
foreach (i, CaseFieldList, cases_)
{
CaseField *c = *i;
c->GenParseCode(out_cc, env, data,
compute_size_var ? size_var() : 0);
CaseField* c = *i;
c->GenParseCode(out_cc, env, data, compute_size_var ? size_var() : 0);
if ( c->IsDefaultCase() )
has_default_case = true;
}
@ -187,7 +183,7 @@ void CaseType::DoGenParseCode(Output* out_cc, Env* env,
out_cc->println("default:");
out_cc->inc_indent();
out_cc->println("throw binpac::ExceptionInvalidCaseIndex(\"%s\", (int64)%s);",
decl_id()->Name(), env->RValue(index_var_));
decl_id()->Name(), env->RValue(index_var_));
out_cc->println("break;");
out_cc->dec_indent();
}
@ -199,8 +195,7 @@ void CaseType::DoGenParseCode(Output* out_cc, Env* env,
env->SetEvaluated(size_var());
}
void CaseType::GenDynamicSize(Output* out_cc, Env* env,
const DataPtr& data)
void CaseType::GenDynamicSize(Output* out_cc, Env* env, const DataPtr& data)
{
GenParseCode(out_cc, env, data, 0);
}
@ -210,9 +205,9 @@ int CaseType::StaticSize(Env* env) const
int static_w = -1;
foreach (i, CaseFieldList, cases_)
{
CaseField *c = *i;
CaseField* c = *i;
int w = c->StaticSize(env);
if ( w < 0 || ( static_w >= 0 && w != static_w ) )
if ( w < 0 || (static_w >= 0 && w != static_w) )
return -1;
static_w = w;
}
@ -224,7 +219,7 @@ void CaseType::SetBoundaryChecked()
Type::SetBoundaryChecked();
foreach (i, CaseFieldList, cases_)
{
CaseField *c = *i;
CaseField* c = *i;
c->SetBoundaryChecked();
}
}
@ -233,7 +228,7 @@ void CaseType::DoMarkIncrementalInput()
{
foreach (i, CaseFieldList, cases_)
{
CaseField *c = *i;
CaseField* c = *i;
c->type()->MarkIncrementalInput();
}
}
@ -242,7 +237,7 @@ bool CaseType::ByteOrderSensitive() const
{
foreach (i, CaseFieldList, cases_)
{
CaseField *c = *i;
CaseField* c = *i;
if ( c->RequiresByteOrder() )
return true;
}
@ -250,10 +245,7 @@ bool CaseType::ByteOrderSensitive() const
}
CaseField::CaseField(ExprList* index, ID* id, Type* type)
: Field(CASE_FIELD,
TYPE_TO_BE_PARSED | CLASS_MEMBER | PUBLIC_READABLE,
id, type),
index_(index)
: Field(CASE_FIELD, TYPE_TO_BE_PARSED | CLASS_MEMBER | PUBLIC_READABLE, id, type), index_(index)
{
ASSERT(type_);
type_->set_value_var(id, MEMBER_VAR);
@ -266,13 +258,13 @@ CaseField::~CaseField()
delete_list(ExprList, index_);
}
void GenCaseStr(ExprList *index_list, Output *out_cc, Env *env, Type* switch_type)
void GenCaseStr(ExprList* index_list, Output* out_cc, Env* env, Type* switch_type)
{
if ( index_list )
{
foreach(i, ExprList, index_list)
foreach (i, ExprList, index_list)
{
Expr *index_expr = *i;
Expr* index_expr = *i;
Type* case_type = index_expr->DataType(env);
@ -338,8 +330,7 @@ void GenCaseStr(ExprList *index_list, Output *out_cc, Env *env, Type* switch_typ
// We're always using "int" for storage, so ok to just
// cast into the type used by the switch statement since
// some unsafe stuff is already checked above.
out_cc->println("case ((%s) %d):",
switch_type->DataTypeStr().c_str(), index_const);
out_cc->println("case ((%s) %d):", switch_type->DataTypeStr().c_str(), index_const);
}
}
else
@ -363,8 +354,7 @@ void CaseField::GenPubDecls(Output* out_h, Env* env)
if ( type_->DataTypeStr().empty() )
return;
out_h->println("%s %s const",
type_->DataTypeConstRefStr().c_str(), env->RValue(id_));
out_h->println("%s %s const", type_->DataTypeConstRefStr().c_str(), env->RValue(id_));
out_h->inc_indent();
out_h->println("{");
@ -383,11 +373,8 @@ void CaseField::GenPubDecls(Output* out_h, Env* env)
out_h->println("default:");
out_h->inc_indent();
out_h->println(
"throw binpac::ExceptionInvalidCase(\"%s\", (int64)%s, \"%s\");",
id_->LocName(),
env->RValue(index_var_),
OrigExprList(index_).c_str());
out_h->println("throw binpac::ExceptionInvalidCase(\"%s\", (int64)%s, \"%s\");",
id_->LocName(), env->RValue(index_var_), OrigExprList(index_).c_str());
out_h->println("break;");
out_h->dec_indent();
@ -426,47 +413,42 @@ void CaseField::GenCleanUpCode(Output* out_cc, Env* env)
out_cc->dec_indent();
}
void CaseField::GenParseCode(Output* out_cc, Env* env,
const DataPtr& data, const ID* size_var)
void CaseField::GenParseCode(Output* out_cc, Env* env, const DataPtr& data, const ID* size_var)
{
GenCaseStr(index_, out_cc, env, case_type()->IndexExpr()->DataType(env));
out_cc->inc_indent();
out_cc->println("// Parse \"%s\"", id_->Name());
out_cc->println("{");
{
Env case_env(env, this);
{
Env case_env(env, this);
type_->GenPreParsing(out_cc, &case_env);
type_->GenParseCode(out_cc, &case_env, data, 0);
if ( size_var )
{
out_cc->println("%s = %s;",
case_env.LValue(size_var),
type_->DataSize(out_cc, &case_env, data).c_str());
type_->GenPreParsing(out_cc, &case_env);
type_->GenParseCode(out_cc, &case_env, data, 0);
if ( size_var )
{
out_cc->println("%s = %s;", case_env.LValue(size_var),
type_->DataSize(out_cc, &case_env, data).c_str());
}
if ( type_->incremental_input() )
{
ASSERT(case_type()->parsing_complete_var());
out_cc->println("%s = %s;", case_env.LValue(case_type()->parsing_complete_var()),
case_env.RValue(type_->parsing_complete_var()));
}
out_cc->println("}");
}
if ( type_->incremental_input() )
{
ASSERT(case_type()->parsing_complete_var());
out_cc->println("%s = %s;",
case_env.LValue(case_type()->parsing_complete_var()),
case_env.RValue(type_->parsing_complete_var()));
}
out_cc->println("}");
}
out_cc->println("break;");
out_cc->dec_indent();
}
bool CaseField::DoTraverse(DataDepVisitor *visitor)
bool CaseField::DoTraverse(DataDepVisitor* visitor)
{
return Field::DoTraverse(visitor) &&
type()->Traverse(visitor);
return Field::DoTraverse(visitor) && type()->Traverse(visitor);
}
bool CaseField::RequiresAnalyzerContext() const
{
return Field::RequiresAnalyzerContext() ||
type()->RequiresAnalyzerContext();
return Field::RequiresAnalyzerContext() || type()->RequiresAnalyzerContext();
}

View file

@ -7,95 +7,94 @@
#include "pac_type.h"
class CaseType : public Type
{
{
public:
CaseType(Expr *index, CaseFieldList *cases);
CaseType(Expr* index, CaseFieldList* cases);
~CaseType();
void AddCaseField(CaseField *f);
void AddCaseField(CaseField* f);
bool DefineValueVar() const;
string DataTypeStr() const;
string DefaultValue() const;
void Prepare(Env *env, int flags);
void Prepare(Env* env, int flags);
void GenPubDecls(Output *out, Env *env);
void GenPrivDecls(Output *out, Env *env);
void GenPubDecls(Output* out, Env* env);
void GenPrivDecls(Output* out, Env* env);
void GenInitCode(Output *out, Env *env);
void GenCleanUpCode(Output *out, Env *env);
void GenInitCode(Output* out, Env* env);
void GenCleanUpCode(Output* out, Env* env);
int StaticSize(Env *env) const;
int StaticSize(Env* env) const;
void SetBoundaryChecked();
Type *ValueType() const;
Type* ValueType() const;
Expr* IndexExpr() const { return index_expr_; }
bool IsPointerType() const { return ValueType()->IsPointerType(); }
bool IsPointerType() const { return ValueType()->IsPointerType(); }
protected:
void DoGenParseCode(Output *out, Env *env, const DataPtr& data, int flags);
void GenDynamicSize(Output *out, Env *env, const DataPtr& data);
Type *DoClone() const { return 0; }
void DoGenParseCode(Output* out, Env* env, const DataPtr& data, int flags);
void GenDynamicSize(Output* out, Env* env, const DataPtr& data);
Type* DoClone() const { return 0; }
void DoMarkIncrementalInput();
bool ByteOrderSensitive() const;
Expr *index_expr_;
ID *index_var_;
CaseFieldList *cases_;
Expr* index_expr_;
ID* index_var_;
CaseFieldList* cases_;
typedef map<const ID*, CaseField*, ID_ptr_cmp> member_map_t;
member_map_t member_map_;
};
};
class CaseField : public Field
{
{
public:
CaseField(ExprList *index, ID *id, Type *type);
CaseField(ExprList* index, ID* id, Type* type);
~CaseField();
CaseType *case_type() const { return case_type_; }
void set_case_type(CaseType *t) { case_type_ = t; }
CaseType* case_type() const { return case_type_; }
void set_case_type(CaseType* t) { case_type_ = t; }
ExprList *index() const { return index_; }
ExprList* index() const { return index_; }
const char *lvalue() const { return type_->lvalue(); }
const char* lvalue() const { return type_->lvalue(); }
const char *CaseStr(Env *env);
void set_index_var(const ID *var) { index_var_ = var; }
const char* CaseStr(Env* env);
void set_index_var(const ID* var) { index_var_ = var; }
void Prepare(Env *env);
void Prepare(Env* env);
void GenPubDecls(Output *out, Env *env);
void GenPubDecls(Output* out, Env* env);
void GenInitCode(Output *out, Env *env);
void GenCleanUpCode(Output *out, Env *env);
void GenParseCode(Output *out, Env *env,
const DataPtr& data, const ID *size_var);
void GenInitCode(Output* out, Env* env);
void GenCleanUpCode(Output* out, Env* env);
void GenParseCode(Output* out, Env* env, const DataPtr& data, const ID* size_var);
int StaticSize(Env *env) const { return type_->StaticSize(env); }
int StaticSize(Env* env) const { return type_->StaticSize(env); }
bool IsDefaultCase() const { return ! index_; }
void SetBoundaryChecked() { type_->SetBoundaryChecked(); }
bool IsDefaultCase() const { return ! index_; }
void SetBoundaryChecked() { type_->SetBoundaryChecked(); }
bool RequiresByteOrder() const { return type_->RequiresByteOrder(); }
bool RequiresByteOrder() const { return type_->RequiresByteOrder(); }
bool RequiresAnalyzerContext() const;
protected:
bool DoTraverse(DataDepVisitor *visitor);
bool DoTraverse(DataDepVisitor* visitor);
protected:
CaseType *case_type_;
ExprList *index_;
const ID *index_var_;
};
CaseType* case_type_;
ExprList* index_;
const ID* index_var_;
};
// Generate a list of "case X:" lines from index_list. Each index
// expression must be constant foldable.
void GenCaseStr(ExprList *index_list, Output *out_cc, Env *env, Type* switch_type);
void GenCaseStr(ExprList* index_list, Output* out_cc, Env* env, Type* switch_type);
#endif // pac_case_h
#endif // pac_case_h

View file

@ -7,9 +7,9 @@ class CClassMethod;
class CType;
class CVariable;
typedef vector<CClassMember *> CClassMemberList;
typedef vector<CClassMethod *> CClassMethodList;
typedef vector<CVariable *> CVariableList;
typedef vector<CClassMember*> CClassMemberList;
typedef vector<CClassMethod*> CClassMethodList;
typedef vector<CVariable*> CVariableList;
#include "pac_common.h"
@ -25,57 +25,57 @@ typedef vector<CVariable *> CVariableList;
// 3. We do not check repeated names.
class CClass
{
{
public:
CClass(const string &class_name);
CClass(const string& class_name);
void AddMember(CClassMember *member);
void AddMethod(CClassMember *method);
void AddMember(CClassMember* member);
void AddMethod(CClassMember* method);
void GenForwardDeclaration(Output *out_h);
void GenCode(Output *out_h, Output *out_cc);
void GenForwardDeclaration(Output* out_h);
void GenCode(Output* out_h, Output* out_cc);
protected:
string class_name_;
CClassMemberList *members_;
CClassMethodList *methods_;
};
CClassMemberList* members_;
CClassMethodList* methods_;
};
class CVariable
{
{
public:
CClassMember(const string &name, CType *type);
CClassMember(const string& name, CType* type);
string name() const { return name_; }
CType *type() const { return type_; }
CType* type() const { return type_; }
protected:
string name_;
CType *type_;
};
CType* type_;
};
class CClassMember
{
{
public:
CClassMember(CVariable *var);
void GenCode(Output *out_h, Output *out_cc);
CClassMember(CVariable* var);
void GenCode(Output* out_h, Output* out_cc);
string decl() const;
protected:
CVariable *var_;
};
CVariable* var_;
};
class CClassMethod
{
{
public:
CClassMethod(CVariable *var, CVariableList *params);
CClassMethod(CVariable* var, CVariableList* params);
string decl() const;
protected:
CVariable *var_;
CVariableList *params_;
};
CVariable* var_;
CVariableList* params_;
};
#endif // pac_cclass_h
#endif // pac_cclass_h

View file

@ -1,13 +1,12 @@
#ifndef pac_common_h
#define pac_common_h
#include "pac_utils.h"
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <vector>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include "pac_utils.h"
using namespace std;
@ -22,7 +21,7 @@ extern int line_number;
// etc.
class Object
{
{
public:
Object()
{
@ -31,17 +30,15 @@ public:
location = strfmt("%s:%d", filename.c_str(), line_number);
}
~Object()
{
}
~Object() { }
const char* Location() const { return location.c_str(); }
const char* Location() const { return location.c_str(); }
protected:
string filename;
int line_num;
string location;
};
};
class ActionParam;
class ActionParamType;
@ -89,47 +86,47 @@ class WithInputField;
// The ID of the current declaration.
extern const ID* current_decl_id;
typedef vector<ActionParam*> ActionParamList;
typedef vector<AnalyzerAction*> AnalyzerActionList;
typedef vector<AnalyzerElement*> AnalyzerElementList;
typedef vector<Attr*> AttrList;
typedef vector<CaseExpr*> CaseExprList;
typedef vector<CaseField*> CaseFieldList;
typedef vector<ContextField*> ContextFieldList;
typedef vector<Decl*> DeclList;
typedef vector<Enum*> EnumList;
typedef vector<Expr*> ExprList;
typedef vector<Field*> FieldList;
typedef vector<LetField*> LetFieldList;
typedef vector<Number*> NumList;
typedef vector<Param*> ParamList;
typedef vector<RecordField*> RecordFieldList;
typedef vector<StateVar*> StateVarList;
typedef vector<ActionParam*> ActionParamList;
typedef vector<AnalyzerAction*> AnalyzerActionList;
typedef vector<AnalyzerElement*> AnalyzerElementList;
typedef vector<Attr*> AttrList;
typedef vector<CaseExpr*> CaseExprList;
typedef vector<CaseField*> CaseFieldList;
typedef vector<ContextField*> ContextFieldList;
typedef vector<Decl*> DeclList;
typedef vector<Enum*> EnumList;
typedef vector<Expr*> ExprList;
typedef vector<Field*> FieldList;
typedef vector<LetField*> LetFieldList;
typedef vector<Number*> NumList;
typedef vector<Param*> ParamList;
typedef vector<RecordField*> RecordFieldList;
typedef vector<StateVar*> StateVarList;
#define foreach(i, ct, pc) \
if ( pc ) \
#define foreach(i, ct, pc) \
if ( pc ) \
for ( ct::iterator i = (pc)->begin(); i != (pc)->end(); ++i )
#define delete_list(ct, pc) \
{ \
foreach(delete_list_i, ct, pc) \
delete *delete_list_i; \
delete pc; \
pc = 0; \
}
#define delete_list(ct, pc) \
{ \
foreach (delete_list_i, ct, pc) \
delete *delete_list_i; \
delete pc; \
pc = 0; \
}
// Constants
const char * const kComputeFrameLength = "compute_frame_length";
const char * const kFlowBufferClass = "FlowBuffer";
const char * const kFlowBufferVar = "flow_buffer";
const char * const kFlowEOF = "FlowEOF";
const char * const kFlowGap = "NewGap";
const char * const kInitialBufferLengthFunc = "initial_buffer_length";
const char * const kNeedMoreData = "need_more_data";
const char * const kNewData = "NewData";
const char * const kParseFuncWithBuffer = "ParseBuffer";
const char * const kParseFuncWithoutBuffer = "Parse";
const char * const kRefCountClass = "binpac::RefCount";
const char * const kTypeWithLengthClass = "binpac::TypeWithLength";
const char* const kComputeFrameLength = "compute_frame_length";
const char* const kFlowBufferClass = "FlowBuffer";
const char* const kFlowBufferVar = "flow_buffer";
const char* const kFlowEOF = "FlowEOF";
const char* const kFlowGap = "NewGap";
const char* const kInitialBufferLengthFunc = "initial_buffer_length";
const char* const kNeedMoreData = "need_more_data";
const char* const kNewData = "NewData";
const char* const kParseFuncWithBuffer = "ParseBuffer";
const char* const kParseFuncWithoutBuffer = "Parse";
const char* const kRefCountClass = "binpac::RefCount";
const char* const kTypeWithLengthClass = "binpac::TypeWithLength";
#endif // pac_common_h
#endif // pac_common_h

View file

@ -1,3 +1,5 @@
#include "pac_conn.h"
#include "pac_analyzer.h"
#include "pac_dataunit.h"
#include "pac_embedded.h"
@ -8,11 +10,7 @@
#include "pac_paramtype.h"
#include "pac_type.h"
#include "pac_conn.h"
ConnDecl::ConnDecl(ID *conn_id,
ParamList *params,
AnalyzerElementList *elemlist)
ConnDecl::ConnDecl(ID* conn_id, ParamList* params, AnalyzerElementList* elemlist)
: AnalyzerDecl(conn_id, CONN, params)
{
flows_[0] = flows_[1] = 0;
@ -27,12 +25,12 @@ ConnDecl::~ConnDecl()
delete data_type_;
}
void ConnDecl::AddBaseClass(vector<string> *base_classes) const
void ConnDecl::AddBaseClass(vector<string>* base_classes) const
{
base_classes->push_back("binpac::ConnectionAnalyzer");
}
void ConnDecl::ProcessFlowElement(AnalyzerFlow *flow_elem)
void ConnDecl::ProcessFlowElement(AnalyzerFlow* flow_elem)
{
int flow_index;
@ -44,19 +42,16 @@ void ConnDecl::ProcessFlowElement(AnalyzerFlow *flow_elem)
if ( flows_[flow_index] )
{
throw Exception(flow_elem,
strfmt("%sflow already defined",
flow_index == 0 ? "up" : "down"));
strfmt("%sflow already defined", flow_index == 0 ? "up" : "down"));
}
flows_[flow_index] = flow_elem;
type_->AddField(flow_elem->flow_field());
}
void ConnDecl::ProcessDataUnitElement(AnalyzerDataUnit *dataunit_elem)
void ConnDecl::ProcessDataUnitElement(AnalyzerDataUnit* dataunit_elem)
{
throw Exception(
dataunit_elem,
"dataunit should be defined in only a flow declaration");
throw Exception(dataunit_elem, "dataunit should be defined in only a flow declaration");
}
void ConnDecl::Prepare()
@ -67,17 +62,17 @@ void ConnDecl::Prepare()
flows_[1]->flow_decl()->set_conn_decl(this);
}
void ConnDecl::GenPubDecls(Output *out_h, Output *out_cc)
void ConnDecl::GenPubDecls(Output* out_h, Output* out_cc)
{
AnalyzerDecl::GenPubDecls(out_h, out_cc);
}
void ConnDecl::GenPrivDecls(Output *out_h, Output *out_cc)
void ConnDecl::GenPrivDecls(Output* out_h, Output* out_cc)
{
AnalyzerDecl::GenPrivDecls(out_h, out_cc);
}
void ConnDecl::GenEOFFunc(Output *out_h, Output *out_cc)
void ConnDecl::GenEOFFunc(Output* out_h, Output* out_cc)
{
string proto = strfmt("%s(bool is_orig)", kFlowEOF);
@ -89,17 +84,13 @@ void ConnDecl::GenEOFFunc(Output *out_h, Output *out_cc)
out_cc->println("if ( is_orig )");
out_cc->inc_indent();
out_cc->println("%s->%s();",
env_->LValue(upflow_id),
kFlowEOF);
out_cc->println("%s->%s();", env_->LValue(upflow_id), kFlowEOF);
out_cc->dec_indent();
out_cc->println("else");
out_cc->inc_indent();
out_cc->println("%s->%s();",
env_->LValue(downflow_id),
kFlowEOF);
out_cc->println("%s->%s();", env_->LValue(downflow_id), kFlowEOF);
foreach(i, AnalyzerHelperList, eof_helpers_)
foreach (i, AnalyzerHelperList, eof_helpers_)
{
(*i)->GenCode(0, out_cc, this);
}
@ -111,7 +102,7 @@ void ConnDecl::GenEOFFunc(Output *out_h, Output *out_cc)
out_cc->println("");
}
void ConnDecl::GenGapFunc(Output *out_h, Output *out_cc)
void ConnDecl::GenGapFunc(Output* out_h, Output* out_cc)
{
string proto = strfmt("%s(bool is_orig, int gap_length)", kFlowGap);
@ -123,15 +114,11 @@ void ConnDecl::GenGapFunc(Output *out_h, Output *out_cc)
out_cc->println("if ( is_orig )");
out_cc->inc_indent();
out_cc->println("%s->%s(gap_length);",
env_->LValue(upflow_id),
kFlowGap);
out_cc->println("%s->%s(gap_length);", env_->LValue(upflow_id), kFlowGap);
out_cc->dec_indent();
out_cc->println("else");
out_cc->inc_indent();
out_cc->println("%s->%s(gap_length);",
env_->LValue(downflow_id),
kFlowGap);
out_cc->println("%s->%s(gap_length);", env_->LValue(downflow_id), kFlowGap);
out_cc->dec_indent();
out_cc->println("}");
@ -139,11 +126,9 @@ void ConnDecl::GenGapFunc(Output *out_h, Output *out_cc)
out_cc->println("");
}
void ConnDecl::GenProcessFunc(Output *out_h, Output *out_cc)
void ConnDecl::GenProcessFunc(Output* out_h, Output* out_cc)
{
string proto =
strfmt("%s(bool is_orig, const_byteptr begin, const_byteptr end)",
kNewData);
string proto = strfmt("%s(bool is_orig, const_byteptr begin, const_byteptr end)", kNewData);
out_h->println("void %s;", proto.c_str());
@ -153,15 +138,11 @@ void ConnDecl::GenProcessFunc(Output *out_h, Output *out_cc)
out_cc->println("if ( is_orig )");
out_cc->inc_indent();
out_cc->println("%s->%s(begin, end);",
env_->LValue(upflow_id),
kNewData);
out_cc->println("%s->%s(begin, end);", env_->LValue(upflow_id), kNewData);
out_cc->dec_indent();
out_cc->println("else");
out_cc->inc_indent();
out_cc->println("%s->%s(begin, end);",
env_->LValue(downflow_id),
kNewData);
out_cc->println("%s->%s(begin, end);", env_->LValue(downflow_id), kNewData);
out_cc->dec_indent();
out_cc->println("}");

View file

@ -1,34 +1,34 @@
#ifndef pac_conn_h
#define pac_conn_h
#include "pac_decl.h"
#include "pac_analyzer.h"
#include "pac_decl.h"
class ConnDecl : public AnalyzerDecl
{
{
public:
ConnDecl(ID *conn_id, ParamList *params, AnalyzerElementList *elemlist);
ConnDecl(ID* conn_id, ParamList* params, AnalyzerElementList* elemlist);
~ConnDecl();
void Prepare();
Type* DataType() const { return data_type_; }
Type* DataType() const { return data_type_; }
protected:
void AddBaseClass(vector<string> *base_classes) const;
void AddBaseClass(vector<string>* base_classes) const;
void GenProcessFunc(Output *out_h, Output *out_cc);
void GenGapFunc(Output *out_h, Output *out_cc);
void GenEOFFunc(Output *out_h, Output *out_cc);
void GenProcessFunc(Output* out_h, Output* out_cc);
void GenGapFunc(Output* out_h, Output* out_cc);
void GenEOFFunc(Output* out_h, Output* out_cc);
void GenPubDecls(Output *out_h, Output *out_cc);
void GenPrivDecls(Output *out_h, Output *out_cc);
void GenPubDecls(Output* out_h, Output* out_cc);
void GenPrivDecls(Output* out_h, Output* out_cc);
void ProcessFlowElement(AnalyzerFlow *flow_elem);
void ProcessDataUnitElement(AnalyzerDataUnit *dataunit_elem);
void ProcessFlowElement(AnalyzerFlow* flow_elem);
void ProcessDataUnitElement(AnalyzerDataUnit* dataunit_elem);
AnalyzerFlow *flows_[2];
Type *data_type_;
};
AnalyzerFlow* flows_[2];
Type* data_type_;
};
#endif // pac_conn_h
#endif // pac_conn_h

View file

@ -1,3 +1,5 @@
#include "pac_context.h"
#include "pac_analyzer.h"
#include "pac_exception.h"
#include "pac_exttype.h"
@ -9,47 +11,38 @@
#include "pac_type.h"
#include "pac_utils.h"
#include "pac_context.h"
ContextField::ContextField(ID *id, Type *type)
: Field(CONTEXT_FIELD,
TYPE_NOT_TO_BE_PARSED | CLASS_MEMBER | PUBLIC_READABLE,
id, type)
ContextField::ContextField(ID* id, Type* type)
: Field(CONTEXT_FIELD, TYPE_NOT_TO_BE_PARSED | CLASS_MEMBER | PUBLIC_READABLE, id, type)
{
}
AnalyzerContextDecl *AnalyzerContextDecl::current_analyzer_context_ = 0;
AnalyzerContextDecl* AnalyzerContextDecl::current_analyzer_context_ = 0;
namespace {
ParamList *ContextFieldsToParams(ContextFieldList *context_fields)
namespace
{
ParamList* ContextFieldsToParams(ContextFieldList* context_fields)
{
// Convert context fields to parameters
ParamList* params = new ParamList();
foreach (i, ContextFieldList, context_fields)
{
// Convert context fields to parameters
ParamList *params = new ParamList();
foreach(i, ContextFieldList, context_fields)
{
ContextField *f = *i;
params->push_back(
new Param(f->id()->clone(),
f->type()));
}
return params;
ContextField* f = *i;
params->push_back(new Param(f->id()->clone(), f->type()));
}
} // namespace private
return params;
}
} // namespace private
AnalyzerContextDecl::AnalyzerContextDecl(
ID *id,
ContextFieldList *context_fields)
: TypeDecl(new ID(strfmt("Context%s", id->Name())),
ContextFieldsToParams(context_fields),
new DummyType())
AnalyzerContextDecl::AnalyzerContextDecl(ID* id, ContextFieldList* context_fields)
: TypeDecl(new ID(strfmt("Context%s", id->Name())), ContextFieldsToParams(context_fields),
new DummyType())
{
context_name_id_ = id;
if ( current_analyzer_context_ != 0 )
{
throw Exception(this,
strfmt("multiple declaration of analyzer context; "
"the previous one is `%s'",
current_analyzer_context_->id()->Name()));
throw Exception(this, strfmt("multiple declaration of analyzer context; "
"the previous one is `%s'",
current_analyzer_context_->id()->Name()));
}
else
current_analyzer_context_ = this;
@ -70,25 +63,25 @@ AnalyzerContextDecl::~AnalyzerContextDecl()
delete_list(ContextFieldList, context_fields_);
}
void AnalyzerContextDecl::GenForwardDeclaration(Output *out_h)
void AnalyzerContextDecl::GenForwardDeclaration(Output* out_h)
{
GenNamespaceBegin(out_h);
TypeDecl::GenForwardDeclaration(out_h);
}
void AnalyzerContextDecl::GenCode(Output *out_h, Output *out_cc)
void AnalyzerContextDecl::GenCode(Output* out_h, Output* out_cc)
{
GenNamespaceBegin(out_h);
GenNamespaceBegin(out_cc);
TypeDecl::GenCode(out_h, out_cc);
}
void AnalyzerContextDecl::GenNamespaceBegin(Output *out) const
void AnalyzerContextDecl::GenNamespaceBegin(Output* out) const
{
out->println("namespace %s {", context_name_id()->Name());
}
void AnalyzerContextDecl::GenNamespaceEnd(Output *out) const
void AnalyzerContextDecl::GenNamespaceEnd(Output* out) const
{
out->println("} // namespace %s", context_name_id()->Name());
}
@ -98,23 +91,19 @@ void AnalyzerContextDecl::AddFlowBuffer()
if ( flow_buffer_added_ )
return;
AddParam(new Param(
new ID(kFlowBufferVar),
FlowDecl::flow_buffer_type()->Clone()));
AddParam(new Param(new ID(kFlowBufferVar), FlowDecl::flow_buffer_type()->Clone()));
flow_buffer_added_ = true;
}
string AnalyzerContextDecl::mb_buffer(Env *env)
string AnalyzerContextDecl::mb_buffer(Env* env)
{
// A hack. The orthodox way would be to build an Expr of
// context.flow_buffer_var, and then EvalExpr.
return strfmt("%s->%s()",
env->RValue(analyzer_context_id),
kFlowBufferVar);
return strfmt("%s->%s()", env->RValue(analyzer_context_id), kFlowBufferVar);
}
Type *DummyType::DoClone() const
Type* DummyType::DoClone() const
{
// Fields will be copied in Type::Clone().
return new DummyType();

View file

@ -24,74 +24,80 @@
// ``binpac_context.connection''.
class ContextField : public Field
{
{
public:
ContextField(ID *id, Type *type);
};
ContextField(ID* id, Type* type);
};
class AnalyzerContextDecl : public TypeDecl
{
{
public:
AnalyzerContextDecl(ID *id, ContextFieldList *context_fields);
AnalyzerContextDecl(ID* id, ContextFieldList* context_fields);
~AnalyzerContextDecl();
void AddFlowBuffer();
const ID *context_name_id() const { return context_name_id_; }
const ID* context_name_id() const { return context_name_id_; }
// The type of analyzer context as a parameter
ParameterizedType *param_type() const { return param_type_; }
ParameterizedType* param_type() const { return param_type_; }
void GenForwardDeclaration(Output *out_h);
void GenCode(Output *out_h, Output *out_cc);
void GenForwardDeclaration(Output* out_h);
void GenCode(Output* out_h, Output* out_cc);
void GenNamespaceBegin(Output *out) const;
void GenNamespaceEnd(Output *out) const;
void GenNamespaceBegin(Output* out) const;
void GenNamespaceEnd(Output* out) const;
private:
ID *context_name_id_;
ContextFieldList *context_fields_;
ParameterizedType *param_type_;
ID* context_name_id_;
ContextFieldList* context_fields_;
ParameterizedType* param_type_;
bool flow_buffer_added_;
// static members
// static members
public:
static AnalyzerContextDecl *current_analyzer_context()
{
return current_analyzer_context_;
}
static AnalyzerContextDecl* current_analyzer_context() { return current_analyzer_context_; }
static string mb_buffer(Env *env);
static string mb_buffer(Env* env);
private:
static AnalyzerContextDecl *current_analyzer_context_;
};
static AnalyzerContextDecl* current_analyzer_context_;
};
class DummyType : public Type
{
{
public:
DummyType() : Type(DUMMY) {}
DummyType() : Type(DUMMY) { }
bool DefineValueVar() const { return false; }
string DataTypeStr() const { ASSERT(0); return ""; }
bool DefineValueVar() const { return false; }
string DataTypeStr() const
{
ASSERT(0);
return "";
}
int StaticSize(Env* env) const { ASSERT(0); return -1; }
int StaticSize(Env* env) const
{
ASSERT(0);
return -1;
}
bool ByteOrderSensitive() const { return false; }
bool IsPointerType() const { ASSERT(0); return false; }
bool IsPointerType() const
{
ASSERT(0);
return false;
}
void DoGenParseCode(Output* out, Env* env,
const DataPtr& data, int flags)
{ ASSERT(0); }
void DoGenParseCode(Output* out, Env* env, const DataPtr& data, int flags) { ASSERT(0); }
// Generate code for computing the dynamic size of the type
void GenDynamicSize(Output* out, Env* env, const DataPtr& data)
{ ASSERT(0); }
void GenDynamicSize(Output* out, Env* env, const DataPtr& data) { ASSERT(0); }
protected:
Type *DoClone() const;
void DoMarkIncrementalInput() { ASSERT(0); }
};
Type* DoClone() const;
void DoMarkIncrementalInput() { ASSERT(0); }
};
#endif // pac_context_h
#endif // pac_context_h

View file

@ -1,84 +1,95 @@
#include "pac_cstr.h"
#include "pac_dbg.h"
#include "pac_exception.h"
namespace {
namespace
{
class EscapeException
{
{
public:
explicit EscapeException(const string &s)
{
msg_ = s;
}
explicit EscapeException(const string& s) { msg_ = s; }
const string &msg() const { return msg_; }
const string& msg() const { return msg_; }
private:
string msg_;
};
};
// Copied from util.cc of Zeek
int expand_escape(const char*& s)
{
switch ( *(s++) ) {
case 'b': return '\b';
case 'f': return '\f';
case 'n': return '\n';
case 'r': return '\r';
case 't': return '\t';
case 'a': return '\a';
case 'v': return '\v';
switch ( *(s++) )
{
case 'b':
return '\b';
case 'f':
return '\f';
case 'n':
return '\n';
case 'r':
return '\r';
case 't':
return '\t';
case 'a':
return '\a';
case 'v':
return '\v';
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7':
{ // \<octal>{1,3}
--s; // put back the first octal digit
const char* start = s;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
{ // \<octal>{1,3}
--s; // put back the first octal digit
const char* start = s;
// Don't increment inside loop control
// because if isdigit() is a macro it might
// expand into multiple increments ...
// Don't increment inside loop control
// because if isdigit() is a macro it might
// expand into multiple increments ...
// Here we define a maximum length for escape sequence
// to allow easy handling of string like: "^H0" as
// "\0100".
// Here we define a maximum length for escape sequence
// to allow easy handling of string like: "^H0" as
// "\0100".
for ( int len = 0; len < 3 && isascii(*s) && isdigit(*s); ++s, ++len)
;
for ( int len = 0; len < 3 && isascii(*s) && isdigit(*s); ++s, ++len )
;
int result;
if ( sscanf(start, "%3o", &result) != 1 )
throw EscapeException(strfmt("bad octal escape: \"%s", start));
int result;
if ( sscanf(start, "%3o", &result) != 1 )
throw EscapeException(strfmt("bad octal escape: \"%s", start));
return result;
return result;
}
case 'x':
{ /* \x<hex> */
const char* start = s;
// Look at most 2 characters, so that "\x0ddir" -> "^Mdir".
for ( int len = 0; len < 2 && isascii(*s) && isxdigit(*s); ++s, ++len )
;
int result;
if ( sscanf(start, "%2x", &result) != 1 )
throw EscapeException(strfmt("bad hexadecimal escape: \"%s", start));
return result;
}
default:
return s[-1];
}
case 'x':
{ /* \x<hex> */
const char* start = s;
// Look at most 2 characters, so that "\x0ddir" -> "^Mdir".
for ( int len = 0; len < 2 && isascii(*s) && isxdigit(*s);
++s, ++len)
;
int result;
if ( sscanf(start, "%2x", &result) != 1 )
throw EscapeException(strfmt("bad hexadecimal escape: \"%s", start));
return result;
}
default:
return s[-1];
}
}
} // private namespace
} // private namespace
ConstString::ConstString(const string &s)
: str_(s)
ConstString::ConstString(const string& s) : str_(s)
{
// Copied from scan.l of Zeek
try
@ -94,9 +105,9 @@ ConstString::ConstString(const string &s)
{
if ( *text == '\\' )
{
++text; // skip '\'
++text; // skip '\'
new_s[i++] = expand_escape(text);
--text; // point to end of sequence
--text; // point to end of sequence
}
else
{
@ -106,16 +117,15 @@ ConstString::ConstString(const string &s)
ASSERT(i < len);
// Get rid of trailing quote.
ASSERT(new_s[i-1] == '"');
new_s[i-1] = '\0';
ASSERT(new_s[i - 1] == '"');
new_s[i - 1] = '\0';
unescaped_ = new_s;
delete [] new_s;
delete[] new_s;
}
catch(EscapeException const &e)
catch ( EscapeException const& e )
{
// Throw again with the object
throw Exception(this, e.msg().c_str());
}
}

View file

@ -4,20 +4,20 @@
#include "pac_common.h"
class ConstString : public Object
{
{
public:
ConstString(const string &s);
ConstString(const string& s);
// The string in its escaped form, with surrounding '"'s
const string &str() const { return str_; }
const char *c_str() const { return str_.c_str(); }
const string& str() const { return str_; }
const char* c_str() const { return str_.c_str(); }
// The unescaped string, without surrounding '"'s
const string &unescaped() const { return unescaped_; }
const string& unescaped() const { return unescaped_; }
private:
string str_;
string unescaped_;
};
};
#endif // pac_cstr_h
#endif // pac_cstr_h

View file

@ -1,21 +1,21 @@
#include "pac_ctype.h"
string CType::DeclareInstance(const string &var) const
string CType::DeclareInstance(const string& var) const
{
return strfmt("%s %s", name().c_str(), var.c_str());
}
string CType::DeclareConstReference(const string &var) const
string CType::DeclareConstReference(const string& var) const
{
return strfmt("%s const &%s", name().c_str(), var.c_str());
}
string CType::DeclareConstPointer(const string &var) const
string CType::DeclareConstPointer(const string& var) const
{
return strfmt("%s const *%s", name().c_str(), var.c_str());
}
string CType::DeclarePointer(const string &var) const
string CType::DeclarePointer(const string& var) const
{
return strfmt("%s *%s", name().c_str(), var.c_str());
}

View file

@ -5,19 +5,19 @@
// Represents a C++ type
class CType
{
{
public:
CType(const string &name);
CType(const string& name);
string name() const { return name_; }
string name() const { return name_; }
string DeclareInstance(const string &var) const;
string DeclareConstReference(const string &var) const;
string DeclareConstPointer(const string &var) const;
string DeclarePointer(const string &var) const;
string DeclareInstance(const string& var) const;
string DeclareConstReference(const string& var) const;
string DeclareConstPointer(const string& var) const;
string DeclarePointer(const string& var) const;
protected:
string name_;
};
};
#endif // pac_ctype_h
#endif // pac_ctype_h

View file

@ -1,14 +1,12 @@
#include "pac_datadep.h"
#include "pac_expr.h"
#include "pac_id.h"
#include "pac_type.h"
DataDepElement::DataDepElement(DDE_Type type)
: dde_type_(type), in_traversal(false)
{
}
DataDepElement::DataDepElement(DDE_Type type) : dde_type_(type), in_traversal(false) { }
bool DataDepElement::Traverse(DataDepVisitor *visitor)
bool DataDepElement::Traverse(DataDepVisitor* visitor)
{
// Avoid infinite loop
if ( in_traversal )
@ -27,17 +25,17 @@ bool DataDepElement::Traverse(DataDepVisitor *visitor)
return true;
}
Expr *DataDepElement::expr()
Expr* DataDepElement::expr()
{
return static_cast<Expr *>(this);
return static_cast<Expr*>(this);
}
Type *DataDepElement::type()
Type* DataDepElement::type()
{
return static_cast<Type *>(this);
return static_cast<Type*>(this);
}
bool RequiresAnalyzerContext::PreProcess(DataDepElement *element)
bool RequiresAnalyzerContext::PreProcess(DataDepElement* element)
{
switch ( element->dde_type() )
{
@ -52,23 +50,22 @@ bool RequiresAnalyzerContext::PreProcess(DataDepElement *element)
return ! requires_analyzer_context_;
}
bool RequiresAnalyzerContext::PostProcess(DataDepElement *element)
bool RequiresAnalyzerContext::PostProcess(DataDepElement* element)
{
return ! requires_analyzer_context_;
}
void RequiresAnalyzerContext::ProcessExpr(Expr *expr)
void RequiresAnalyzerContext::ProcessExpr(Expr* expr)
{
if ( expr->expr_type() == Expr::EXPR_ID )
{
requires_analyzer_context_ =
(requires_analyzer_context_ ||
*expr->id() == *analyzer_context_id ||
*expr->id() == *context_macro_id);
requires_analyzer_context_ = (requires_analyzer_context_ ||
*expr->id() == *analyzer_context_id ||
*expr->id() == *context_macro_id);
}
}
bool RequiresAnalyzerContext::compute(DataDepElement *element)
bool RequiresAnalyzerContext::compute(DataDepElement* element)
{
RequiresAnalyzerContext visitor;
element->Traverse(&visitor);

View file

@ -9,9 +9,11 @@
class DataDepVisitor;
class DataDepElement {
class DataDepElement
{
public:
enum DDE_Type {
enum DDE_Type
{
ATTR,
CASEEXPR,
EXPR,
@ -19,53 +21,52 @@ public:
INPUT_BUFFER,
PARAM,
TYPE,
};
};
DataDepElement(DDE_Type type);
virtual ~DataDepElement() {}
virtual ~DataDepElement() { }
// Returns whether to continue traversal
bool Traverse(DataDepVisitor *visitor);
bool Traverse(DataDepVisitor* visitor);
// Returns whether to continue traversal
virtual bool DoTraverse(DataDepVisitor *visitor) = 0;
virtual bool DoTraverse(DataDepVisitor* visitor) = 0;
DDE_Type dde_type() const { return dde_type_; }
Expr *expr();
Type *type();
DDE_Type dde_type() const { return dde_type_; }
Expr* expr();
Type* type();
protected:
DDE_Type dde_type_;
bool in_traversal;
};
};
class DataDepVisitor {
class DataDepVisitor
{
public:
virtual ~DataDepVisitor() {}
virtual ~DataDepVisitor() { }
// Returns whether to continue traversal
virtual bool PreProcess(DataDepElement *element) = 0;
virtual bool PostProcess(DataDepElement *element) = 0;
};
virtual bool PreProcess(DataDepElement* element) = 0;
virtual bool PostProcess(DataDepElement* element) = 0;
};
class RequiresAnalyzerContext : public DataDepVisitor {
class RequiresAnalyzerContext : public DataDepVisitor
{
public:
RequiresAnalyzerContext() : requires_analyzer_context_(false) {}
RequiresAnalyzerContext() : requires_analyzer_context_(false) { }
// Returns whether to continue traversal
bool PreProcess(DataDepElement *element);
bool PostProcess(DataDepElement *element);
bool PreProcess(DataDepElement* element);
bool PostProcess(DataDepElement* element);
bool requires_analyzer_context() const
{
return requires_analyzer_context_;
}
bool requires_analyzer_context() const { return requires_analyzer_context_; }
static bool compute(DataDepElement *element);
static bool compute(DataDepElement* element);
protected:
void ProcessExpr(Expr *expr);
void ProcessExpr(Expr* expr);
bool requires_analyzer_context_;
};
};
#endif // pac_datadep_h

View file

@ -1,12 +1,11 @@
#include "pac_dataptr.h"
#include "pac_exception.h"
#include "pac_id.h"
#include "pac_output.h"
#include "pac_utils.h"
#include "pac_dataptr.h"
DataPtr::DataPtr(Env* env, const ID* id, const int offset)
: id_(id), offset_(offset)
DataPtr::DataPtr(Env* env, const ID* id, const int offset) : id_(id), offset_(offset)
{
if ( id_ )
{
@ -24,7 +23,7 @@ DataPtr::DataPtr(Env* env, const ID* id, const int offset)
int DataPtr::AbsOffset(const ID* base_ptr) const
{
return ( id() == base_ptr ) ? offset() : -1;
return (id() == base_ptr) ? offset() : -1;
}
char* DataPtr::AbsOffsetExpr(Env* env, const ID* base_ptr) const
@ -35,19 +34,14 @@ char* DataPtr::AbsOffsetExpr(Env* env, const ID* base_ptr) const
return nfmt("(%s - %s)", ptr_expr(), env->RValue(base_ptr));
}
void DataPtr::GenBoundaryCheck(Output* out_cc, Env* env,
const char* data_size, const char* data_name) const
void DataPtr::GenBoundaryCheck(Output* out_cc, Env* env, const char* data_size,
const char* data_name) const
{
ASSERT(id_);
out_cc->println("// Checking out-of-bound for \"%s\"", data_name);
out_cc->println("if ( %s + (%s) > %s || %s + (%s) < %s )",
ptr_expr(),
data_size,
env->RValue(end_of_data),
ptr_expr(),
data_size,
ptr_expr());
out_cc->println("if ( %s + (%s) > %s || %s + (%s) < %s )", ptr_expr(), data_size,
env->RValue(end_of_data), ptr_expr(), data_size, ptr_expr());
out_cc->inc_indent();
out_cc->println("{");
@ -56,14 +50,11 @@ void DataPtr::GenBoundaryCheck(Output* out_cc, Env* env,
out_cc->println("// Handle out-of-bound condition");
out_cc->println("throw binpac::ExceptionOutOfBound(\"%s\",", data_name);
out_cc->println(" (%s) + (%s), ",
data_offset, data_size);
out_cc->println(" (%s) - (%s));",
env->RValue(end_of_data), env->RValue(begin_of_data));
out_cc->println(" (%s) + (%s), ", data_offset, data_size);
out_cc->println(" (%s) - (%s));", env->RValue(end_of_data), env->RValue(begin_of_data));
delete [] data_offset;
delete[] data_offset;
out_cc->println("}");
out_cc->dec_indent();
}

View file

@ -2,18 +2,20 @@
#define pac_dataptr_h
#include <string>
#include "pac_common.h"
#include "pac_dbg.h"
// A data pointer is represented by an data pointer variable
// plus a constant offset.
class DataPtr
{
{
public:
DataPtr(Env* env, const ID* arg_id, const int arg_off);
DataPtr(DataPtr const& x) { *this = x; }
DataPtr const &operator=(DataPtr const &x)
DataPtr const& operator=(DataPtr const& x)
{
id_ = x.id();
offset_ = x.offset();
@ -22,8 +24,8 @@ public:
return *this;
}
const ID* id() const { return id_; }
int offset() const { return offset_; }
const ID* id() const { return id_; }
int offset() const { return offset_; }
const char* ptr_expr() const
{
@ -34,15 +36,13 @@ public:
int AbsOffset(const ID* base_ptr) const;
char* AbsOffsetExpr(Env* env, const ID* base_ptr) const;
void GenBoundaryCheck(Output* out,
Env* env,
const char* data_size,
const char* data_name) const;
void GenBoundaryCheck(Output* out, Env* env, const char* data_size,
const char* data_name) const;
protected:
const ID* id_;
int offset_;
string ptr_expr_;
};
};
#endif // pac_dataptr_h
#endif // pac_dataptr_h

View file

@ -1,32 +1,21 @@
#include "pac_context.h"
#include "pac_dataunit.h"
#include "pac_context.h"
#include "pac_output.h"
#include "pac_paramtype.h"
#include "pac_varfield.h"
AnalyzerDataUnit::AnalyzerDataUnit(
DataUnitType type,
ID *id,
ExprList *type_params,
ExprList *context_params)
: AnalyzerElement(DATAUNIT),
type_(type),
id_(id),
type_params_(type_params),
AnalyzerDataUnit::AnalyzerDataUnit(DataUnitType type, ID* id, ExprList* type_params,
ExprList* context_params)
: AnalyzerElement(DATAUNIT), type_(type), id_(id), type_params_(type_params),
context_params_(context_params)
{
data_type_ = new ParameterizedType(id_, type_params_);
context_type_ = new ParameterizedType(
AnalyzerContextDecl::current_analyzer_context()->id()->clone(),
context_params_);
AnalyzerContextDecl::current_analyzer_context()->id()->clone(), context_params_);
dataunit_var_field_ = new ParseVarField(
Field::CLASS_MEMBER,
dataunit_id->clone(),
data_type());
context_var_field_ = new PrivVarField(
analyzer_context_id->clone(),
context_type());
dataunit_var_field_ = new ParseVarField(Field::CLASS_MEMBER, dataunit_id->clone(), data_type());
context_var_field_ = new PrivVarField(analyzer_context_id->clone(), context_type());
}
AnalyzerDataUnit::~AnalyzerDataUnit()
@ -35,26 +24,22 @@ AnalyzerDataUnit::~AnalyzerDataUnit()
delete context_var_field_;
}
void AnalyzerDataUnit::Prepare(Env *env)
void AnalyzerDataUnit::Prepare(Env* env)
{
dataunit_var_field_->Prepare(env);
context_var_field_->Prepare(env);
}
void AnalyzerDataUnit::GenNewDataUnit(Output *out_cc, Env *env)
void AnalyzerDataUnit::GenNewDataUnit(Output* out_cc, Env* env)
{
out_cc->println("%s = new %s(%s);",
env->LValue(dataunit_id),
data_type()->class_name().c_str(),
data_type()->EvalParameters(out_cc, env).c_str());
out_cc->println("%s = new %s(%s);", env->LValue(dataunit_id), data_type()->class_name().c_str(),
data_type()->EvalParameters(out_cc, env).c_str());
}
void AnalyzerDataUnit::GenNewContext(Output *out_cc, Env *env)
void AnalyzerDataUnit::GenNewContext(Output* out_cc, Env* env)
{
out_cc->println("%s = new %s(%s);",
env->LValue(analyzer_context_id),
context_type()->class_name().c_str(),
context_type()->EvalParameters(out_cc, env).c_str());
out_cc->println("%s = new %s(%s);", env->LValue(analyzer_context_id),
context_type()->class_name().c_str(),
context_type()->EvalParameters(out_cc, env).c_str());
env->SetEvaluated(analyzer_context_id);
}

View file

@ -7,43 +7,43 @@
// data unit of a DCE/RPC flow is DCE_RPC_PDU.
class AnalyzerDataUnit : public AnalyzerElement
{
{
public:
enum DataUnitType { DATAGRAM, FLOWUNIT };
AnalyzerDataUnit(
DataUnitType type,
ID *id,
ExprList *type_params,
ExprList *context_params);
enum DataUnitType
{
DATAGRAM,
FLOWUNIT
};
AnalyzerDataUnit(DataUnitType type, ID* id, ExprList* type_params, ExprList* context_params);
~AnalyzerDataUnit();
void Prepare(Env *env);
void Prepare(Env* env);
// Initializes dataunit_id
void GenNewDataUnit(Output *out_cc, Env *env);
void GenNewDataUnit(Output* out_cc, Env* env);
// Initializes analyzer_context_id
void GenNewContext(Output *out_cc, Env *env);
void GenNewContext(Output* out_cc, Env* env);
DataUnitType type() const { return type_; }
const ID *id() const { return id_; }
ExprList *type_params() const { return type_params_; }
ExprList *context_params() const { return context_params_; }
DataUnitType type() const { return type_; }
const ID* id() const { return id_; }
ExprList* type_params() const { return type_params_; }
ExprList* context_params() const { return context_params_; }
ParameterizedType *data_type() const { return data_type_; }
ParameterizedType *context_type() const { return context_type_; }
ParameterizedType* data_type() const { return data_type_; }
ParameterizedType* context_type() const { return context_type_; }
Field *dataunit_var_field() const { return dataunit_var_field_; }
Field *context_var_field() const { return context_var_field_; }
Field* dataunit_var_field() const { return dataunit_var_field_; }
Field* context_var_field() const { return context_var_field_; }
private:
DataUnitType type_;
ID *id_;
ExprList *type_params_;
ExprList *context_params_;
ParameterizedType *data_type_;
ParameterizedType *context_type_;
Field *dataunit_var_field_;
Field *context_var_field_;
};
ID* id_;
ExprList* type_params_;
ExprList* context_params_;
ParameterizedType* data_type_;
ParameterizedType* context_type_;
Field* dataunit_var_field_;
Field* context_var_field_;
};
#endif // pac_dataunit_h

View file

@ -6,7 +6,9 @@
extern bool FLAGS_pac_debug;
#define ASSERT(x) assert(x)
#define DEBUG_MSG(x...) if ( FLAGS_pac_debug ) fprintf(stderr, x)
#define ASSERT(x) assert(x)
#define DEBUG_MSG(x...) \
if ( FLAGS_pac_debug ) \
fprintf(stderr, x)
#endif /* pac_dbg_h */

View file

@ -3,4 +3,4 @@
#include "pac_id.h"
#endif // pac_decl_inl_h
#endif // pac_decl_inl_h

View file

@ -1,3 +1,5 @@
#include "pac_decl.h"
#include "pac_attr.h"
#include "pac_context.h"
#include "pac_dataptr.h"
@ -12,13 +14,10 @@
#include "pac_type.h"
#include "pac_utils.h"
#include "pac_decl.h"
DeclList *Decl::decl_list_ = 0;
DeclList* Decl::decl_list_ = 0;
Decl::DeclMap Decl::decl_map_;
Decl::Decl(ID* id, DeclType decl_type)
: id_(id), decl_type_(decl_type), attrlist_(0)
Decl::Decl(ID* id, DeclType decl_type) : id_(id), decl_type_(decl_type), attrlist_(0)
{
decl_map_[id_] = this;
if ( ! decl_list_ )
@ -42,44 +41,42 @@ void Decl::AddAttrs(AttrList* attrs)
return;
if ( ! attrlist_ )
attrlist_ = new AttrList();
foreach ( i, AttrList, attrs )
foreach (i, AttrList, attrs)
{
attrlist_->push_back(*i);
ProcessAttr(*i);
}
}
void Decl::ProcessAttr(Attr *attr)
void Decl::ProcessAttr(Attr* attr)
{
throw Exception(attr, "unhandled attribute");
}
void Decl::SetAnalyzerContext()
{
analyzer_context_ =
AnalyzerContextDecl::current_analyzer_context();
analyzer_context_ = AnalyzerContextDecl::current_analyzer_context();
if ( ! analyzer_context_ )
{
throw Exception(this,
"analyzer context not defined");
throw Exception(this, "analyzer context not defined");
}
}
void Decl::ProcessDecls(Output *out_h, Output *out_cc)
void Decl::ProcessDecls(Output* out_h, Output* out_cc)
{
if ( ! decl_list_ )
return;
foreach(i, DeclList, decl_list_)
foreach (i, DeclList, decl_list_)
{
Decl *decl = *i;
Decl* decl = *i;
current_decl_id = decl->id();
decl->Prepare();
}
foreach(i, DeclList, decl_list_)
foreach (i, DeclList, decl_list_)
{
Decl *decl = *i;
Decl* decl = *i;
current_decl_id = decl->id();
decl->GenExternDeclaration(out_h);
}
@ -87,12 +84,11 @@ void Decl::ProcessDecls(Output *out_h, Output *out_cc)
out_h->println("namespace binpac {\n");
out_cc->println("namespace binpac {\n");
AnalyzerContextDecl *analyzer_context =
AnalyzerContextDecl::current_analyzer_context();
AnalyzerContextDecl* analyzer_context = AnalyzerContextDecl::current_analyzer_context();
foreach(i, DeclList, decl_list_)
foreach (i, DeclList, decl_list_)
{
Decl *decl = *i;
Decl* decl = *i;
current_decl_id = decl->id();
decl->GenForwardDeclaration(out_h);
}
@ -102,9 +98,9 @@ void Decl::ProcessDecls(Output *out_h, Output *out_cc)
out_h->println("");
foreach(i, DeclList, decl_list_)
foreach (i, DeclList, decl_list_)
{
Decl *decl = *i;
Decl* decl = *i;
current_decl_id = decl->id();
decl->GenCode(out_h, out_cc);
}
@ -129,13 +125,9 @@ Decl* Decl::LookUpDecl(const ID* id)
int HelperDecl::helper_id_seq = 0;
HelperDecl::HelperDecl(HelperType helper_type,
ID* context_id,
EmbeddedCode* code)
: Decl(new ID(strfmt("helper_%d", ++helper_id_seq)), HELPER),
helper_type_(helper_type),
context_id_(context_id),
code_(code)
HelperDecl::HelperDecl(HelperType helper_type, ID* context_id, EmbeddedCode* code)
: Decl(new ID(strfmt("helper_%d", ++helper_id_seq)), HELPER), helper_type_(helper_type),
context_id_(context_id), code_(code)
{
}
@ -150,15 +142,15 @@ void HelperDecl::Prepare()
// Do nothing
}
void HelperDecl::GenExternDeclaration(Output *out_h)
void HelperDecl::GenExternDeclaration(Output* out_h)
{
if ( helper_type_ == EXTERN )
code_->GenCode(out_h, global_env());
}
void HelperDecl::GenCode(Output *out_h, Output *out_cc)
void HelperDecl::GenCode(Output* out_h, Output* out_cc)
{
Env *env = global_env();
Env* env = global_env();
#if 0
if ( context_id_ )

View file

@ -5,75 +5,92 @@
#include "pac_id.h"
class Decl : public Object
{
{
public:
// Note: ANALYZER is not for AnalyzerDecl (which is an
// abstract class) , but for AnalyzerContextDecl.
enum DeclType { ENUM, LET, TYPE, FUNC, CONN, FLOW, ANALYZER, HELPER, REGEX };
enum DeclType
{
ENUM,
LET,
TYPE,
FUNC,
CONN,
FLOW,
ANALYZER,
HELPER,
REGEX
};
Decl(ID *id, DeclType decl_type);
Decl(ID* id, DeclType decl_type);
virtual ~Decl();
const ID *id() const { return id_; }
DeclType decl_type() const { return decl_type_; }
AnalyzerContextDecl *analyzer_context() const
{ return analyzer_context_; }
const ID* id() const { return id_; }
DeclType decl_type() const { return decl_type_; }
AnalyzerContextDecl* analyzer_context() const { return analyzer_context_; }
// NULL except for TypeDecl or AnalyzerDecl
virtual Env *env() const { return 0; }
virtual Env* env() const { return 0; }
virtual void Prepare() = 0;
// Generate declarations out of the "binpac" namespace
virtual void GenExternDeclaration(Output *out_h) { /* do nothing */ }
virtual void GenExternDeclaration(Output* out_h)
{ /* do nothing */
}
// Generate declarations before definition of classes
virtual void GenForwardDeclaration(Output *out_h) = 0;
virtual void GenForwardDeclaration(Output* out_h) = 0;
virtual void GenCode(Output *out_h, Output *out_cc) = 0;
virtual void GenCode(Output* out_h, Output* out_cc) = 0;
void TakeExprList();
void AddAttrs(AttrList *attrlist);
void AddAttrs(AttrList* attrlist);
void SetAnalyzerContext();
protected:
virtual void ProcessAttr(Attr *a);
virtual void ProcessAttr(Attr* a);
ID *id_;
ID* id_;
DeclType decl_type_;
AttrList *attrlist_;
AnalyzerContextDecl *analyzer_context_;
AttrList* attrlist_;
AnalyzerContextDecl* analyzer_context_;
public:
static void ProcessDecls(Output *out_h, Output *out_cc);
static Decl *LookUpDecl(const ID *id);
static void ProcessDecls(Output* out_h, Output* out_cc);
static Decl* LookUpDecl(const ID* id);
private:
static DeclList *decl_list_;
typedef map<const ID *, Decl*, ID_ptr_cmp> DeclMap;
static DeclList* decl_list_;
typedef map<const ID*, Decl*, ID_ptr_cmp> DeclMap;
static DeclMap decl_map_;
};
};
class HelperDecl : public Decl
{
{
public:
enum HelperType {
HEADER, CODE, EXTERN,
};
HelperDecl(HelperType type, ID *context_id, EmbeddedCode *code);
enum HelperType
{
HEADER,
CODE,
EXTERN,
};
HelperDecl(HelperType type, ID* context_id, EmbeddedCode* code);
~HelperDecl();
void Prepare();
void GenExternDeclaration(Output *out_h);
void GenForwardDeclaration(Output *out_h) { /* do nothing */ }
void GenCode(Output *out_h, Output *out_cc);
void GenExternDeclaration(Output* out_h);
void GenForwardDeclaration(Output* out_h)
{ /* do nothing */
}
void GenCode(Output* out_h, Output* out_cc);
private:
HelperType helper_type_;
ID *context_id_;
EmbeddedCode *code_;
ID* context_id_;
EmbeddedCode* code_;
static int helper_id_seq;
};
};
#endif // pac_decl_h
#endif // pac_decl_h

View file

@ -1,27 +1,22 @@
#include "pac_id.h"
#include "pac_primitive.h"
#include "pac_output.h"
#include "pac_embedded.h"
EmbeddedCodeSegment::EmbeddedCodeSegment(const string &s)
: s_(s), primitive_(0)
{
}
#include "pac_id.h"
#include "pac_output.h"
#include "pac_primitive.h"
EmbeddedCodeSegment::EmbeddedCodeSegment(PacPrimitive *primitive)
: s_(""), primitive_(primitive)
{
}
EmbeddedCodeSegment::EmbeddedCodeSegment(const string& s) : s_(s), primitive_(0) { }
EmbeddedCodeSegment::EmbeddedCodeSegment(PacPrimitive* primitive)
: s_(""), primitive_(primitive) { }
EmbeddedCodeSegment::~EmbeddedCodeSegment()
{
delete primitive_;
}
string EmbeddedCodeSegment::ToCode(Env *env)
string EmbeddedCodeSegment::ToCode(Env* env)
{
if ( primitive_ && s_.empty() )
if ( primitive_ && s_.empty() )
s_ = primitive_->ToCode(env);
return s_;
}
@ -41,12 +36,12 @@ void EmbeddedCode::Append(int atom)
current_segment_ += static_cast<char>(atom);
}
void EmbeddedCode::Append(const char *str)
void EmbeddedCode::Append(const char* str)
{
current_segment_ += str;
}
void EmbeddedCode::Append(PacPrimitive *primitive)
void EmbeddedCode::Append(PacPrimitive* primitive)
{
if ( ! current_segment_.empty() )
{
@ -56,7 +51,7 @@ void EmbeddedCode::Append(PacPrimitive *primitive)
segments_->push_back(new EmbeddedCodeSegment(primitive));
}
void EmbeddedCode::GenCode(Output *out, Env *env)
void EmbeddedCode::GenCode(Output* out, Env* env)
{
if ( ! current_segment_.empty() )
{
@ -71,9 +66,9 @@ void EmbeddedCode::GenCode(Output *out, Env *env)
// ID's name is used as its RValue
env->set_allow_undefined_id(true);
foreach(i, EmbeddedCodeSegmentList, segments_)
foreach (i, EmbeddedCodeSegmentList, segments_)
{
EmbeddedCodeSegment *segment = *i;
EmbeddedCodeSegment* segment = *i;
out->print("%s", segment->ToCode(env).c_str());
}

View file

@ -4,39 +4,39 @@
#include "pac_common.h"
class EmbeddedCodeSegment
{
{
public:
explicit EmbeddedCodeSegment(const string &s);
explicit EmbeddedCodeSegment(PacPrimitive *primitive);
explicit EmbeddedCodeSegment(const string& s);
explicit EmbeddedCodeSegment(PacPrimitive* primitive);
~EmbeddedCodeSegment();
string ToCode(Env *env);
string ToCode(Env* env);
private:
string s_;
PacPrimitive *primitive_;
};
PacPrimitive* primitive_;
};
typedef vector<EmbeddedCodeSegment *> EmbeddedCodeSegmentList;
typedef vector<EmbeddedCodeSegment*> EmbeddedCodeSegmentList;
class EmbeddedCode : public Object
{
{
public:
EmbeddedCode();
~EmbeddedCode();
// Append a character
void Append(int atom);
void Append(const char *str);
void Append(const char* str);
// Append a PAC primitive
void Append(PacPrimitive *primitive);
void Append(PacPrimitive* primitive);
void GenCode(Output *out, Env *env);
void GenCode(Output* out, Env* env);
private:
string current_segment_;
EmbeddedCodeSegmentList *segments_;
};
EmbeddedCodeSegmentList* segments_;
};
#endif // pac_embedded_h
#endif // pac_embedded_h

View file

@ -1,14 +1,12 @@
#include "pac_exception.h"
#include "pac_enum.h"
#include "pac_exception.h"
#include "pac_expr.h"
#include "pac_exttype.h"
#include "pac_output.h"
#include "pac_typedecl.h"
Enum::Enum(ID* id, Expr* expr)
: id_(id), expr_(expr)
{
}
Enum::Enum(ID* id, Expr* expr) : id_(id), expr_(expr) { }
Enum::~Enum()
{
@ -16,7 +14,7 @@ Enum::~Enum()
delete expr_;
}
void Enum::GenHeader(Output* out_h, int *pval)
void Enum::GenHeader(Output* out_h, int* pval)
{
ASSERT(pval);
if ( expr_ )
@ -30,10 +28,9 @@ void Enum::GenHeader(Output* out_h, int *pval)
global_env()->AddConstID(id_, *pval);
}
EnumDecl::EnumDecl(ID *id, EnumList *enumlist)
: Decl(id, ENUM), enumlist_(enumlist)
EnumDecl::EnumDecl(ID* id, EnumList* enumlist) : Decl(id, ENUM), enumlist_(enumlist)
{
ID *type_id = id->clone();
ID* type_id = id->clone();
datatype_ = new ExternType(type_id, ExternType::NUMBER);
extern_typedecl_ = new TypeDecl(type_id, 0, datatype_);
}
@ -49,12 +46,12 @@ void EnumDecl::Prepare()
// Do nothing
}
void EnumDecl::GenForwardDeclaration(Output *out_h)
void EnumDecl::GenForwardDeclaration(Output* out_h)
{
out_h->println("enum %s {", id_->Name());
out_h->inc_indent();
int c = 0;
foreach(i, EnumList, enumlist_)
foreach (i, EnumList, enumlist_)
{
(*i)->GenHeader(out_h, &c);
++c;
@ -67,4 +64,3 @@ void EnumDecl::GenCode(Output* out_h, Output* /* out_cc */)
{
// Do nothing
}

View file

@ -4,34 +4,34 @@
#include "pac_decl.h"
class Enum
{
{
public:
Enum(ID *id, Expr *expr = 0);
Enum(ID* id, Expr* expr = 0);
~Enum();
void GenHeader(Output *out_h, int *pval);
void GenHeader(Output* out_h, int* pval);
private:
ID *id_;
Expr *expr_;
};
ID* id_;
Expr* expr_;
};
class EnumDecl : public Decl
{
{
public:
EnumDecl(ID *id, EnumList *enumlist);
EnumDecl(ID* id, EnumList* enumlist);
~EnumDecl();
Type *DataType() const { return datatype_; }
Type* DataType() const { return datatype_; }
void Prepare();
void GenForwardDeclaration(Output *out_h);
void GenCode(Output *out_h, Output *out_cc);
void GenForwardDeclaration(Output* out_h);
void GenCode(Output* out_h, Output* out_cc);
private:
EnumList *enumlist_;
Type *datatype_;
TypeDecl *extern_typedecl_;
};
EnumList* enumlist_;
Type* datatype_;
TypeDecl* extern_typedecl_;
};
#endif // pac_enum_h

View file

@ -1,4 +1,5 @@
#include "pac_exception.h"
#include "pac_expr.h"
#include "pac_id.h"
#include "pac_utils.h"
@ -20,52 +21,43 @@ Exception::Exception(const Object* o, string msg)
}
}
ExceptionIDNotFound::ExceptionIDNotFound(const ID* id)
: Exception(id), id_(id)
ExceptionIDNotFound::ExceptionIDNotFound(const ID* id) : Exception(id), id_(id)
{
append(strfmt("`%s' undeclared", id_->Name()));
}
ExceptionIDRedefinition::ExceptionIDRedefinition(const ID* id)
: Exception(id), id_(id)
ExceptionIDRedefinition::ExceptionIDRedefinition(const ID* id) : Exception(id), id_(id)
{
append(strfmt("`%s' redefined", id_->Name()));
}
ExceptionIDNotEvaluated::ExceptionIDNotEvaluated(const ID* id)
: Exception(id), id_(id)
ExceptionIDNotEvaluated::ExceptionIDNotEvaluated(const ID* id) : Exception(id), id_(id)
{
append(strfmt("ID `%s' not evaluated before used", id->Name()));
}
ExceptionIDNotField::ExceptionIDNotField(const ID* id)
: Exception(id), id_(id)
ExceptionIDNotField::ExceptionIDNotField(const ID* id) : Exception(id), id_(id)
{
append(strfmt("ID `%s' is not a field", id_->Name()));
}
ExceptionMemberNotFound::ExceptionMemberNotFound(const ID* type_id,
const ID *member_id)
ExceptionMemberNotFound::ExceptionMemberNotFound(const ID* type_id, const ID* member_id)
: Exception(member_id), type_id_(type_id), member_id_(member_id)
{
append(strfmt("type %s does not have member `%s'",
type_id_->Name(), member_id_->Name()));
append(strfmt("type %s does not have member `%s'", type_id_->Name(), member_id_->Name()));
}
ExceptionCyclicDependence::ExceptionCyclicDependence(const ID* id)
: Exception(id), id_(id)
ExceptionCyclicDependence::ExceptionCyclicDependence(const ID* id) : Exception(id), id_(id)
{
append(strfmt("cyclic dependence through `%s'", id_->Name()));
}
ExceptionPaddingError::ExceptionPaddingError(const Object* o, string msg)
: Exception(o)
ExceptionPaddingError::ExceptionPaddingError(const Object* o, string msg) : Exception(o)
{
append(msg.c_str());
}
ExceptionNonConstExpr::ExceptionNonConstExpr(const Expr* expr)
: Exception(expr), expr(expr)
ExceptionNonConstExpr::ExceptionNonConstExpr(const Expr* expr) : Exception(expr), expr(expr)
{
append(strfmt("Expression `%s' is not constant", expr->orig()));
}
@ -73,11 +65,14 @@ ExceptionNonConstExpr::ExceptionNonConstExpr(const Expr* expr)
ExceptionInvalidCaseSizeExpr::ExceptionInvalidCaseSizeExpr(const Expr* expr)
: Exception(expr), expr(expr)
{
append(strfmt("Expression `%s' is greater than the 32-bit limit for use as a case index", expr->orig()));
append(strfmt("Expression `%s' is greater than the 32-bit limit for use as a case index",
expr->orig()));
}
ExceptionInvalidCaseLimitExpr::ExceptionInvalidCaseLimitExpr(const Expr* expr)
: Exception(expr), expr(expr)
{
append(strfmt("Expression `%s' as a case index is outside the numeric limit of the type used for the switch expression", expr->orig()));
append(strfmt("Expression `%s' as a case index is outside the numeric limit of the type used "
"for the switch expression",
expr->orig()));
}

View file

@ -7,107 +7,107 @@ using namespace std;
#include "pac_common.h"
class Exception
{
{
public:
Exception(const Object* o, string msg = "");
const char* msg() const { return msg_.c_str(); }
void append(string s) { msg_ += s; }
const char* msg() const { return msg_.c_str(); }
void append(string s) { msg_ += s; }
private:
string msg_;
};
};
class ExceptionIDNotFound : public Exception
{
{
public:
ExceptionIDNotFound(const ID* id);
const ID* id() const { return id_; }
private:
const ID* id_;
};
};
class ExceptionIDRedefinition : public Exception
{
{
public:
ExceptionIDRedefinition(const ID* id);
const ID* id() const { return id_; }
private:
const ID* id_;
};
};
class ExceptionIDNotEvaluated : public Exception
{
{
public:
ExceptionIDNotEvaluated(const ID* id);
const ID* id() const { return id_; }
private:
const ID* id_;
};
};
class ExceptionCyclicDependence : public Exception
{
{
public:
ExceptionCyclicDependence(const ID* id);
const ID* id() const { return id_; }
private:
const ID* id_;
};
};
class ExceptionPaddingError : public Exception
{
{
public:
ExceptionPaddingError(const Object* o, string msg);
};
};
class ExceptionIDNotField : public Exception
{
{
public:
ExceptionIDNotField(const ID* id);
const ID* id() const { return id_; }
private:
const ID* id_;
};
};
class ExceptionMemberNotFound : public Exception
{
{
public:
ExceptionMemberNotFound(const ID* type_id, const ID *member_id);
ExceptionMemberNotFound(const ID* type_id, const ID* member_id);
private:
const ID *type_id_, *member_id_;
};
};
class ExceptionNonConstExpr : public Exception
{
{
public:
ExceptionNonConstExpr(const Expr* expr);
private:
const Expr *expr;
};
const Expr* expr;
};
class ExceptionInvalidCaseSizeExpr : public Exception
{
{
public:
ExceptionInvalidCaseSizeExpr(const Expr* expr);
private:
const Expr *expr;
};
const Expr* expr;
};
class ExceptionInvalidCaseLimitExpr : public Exception
{
{
public:
ExceptionInvalidCaseLimitExpr(const Expr* expr);
private:
const Expr *expr;
};
const Expr* expr;
};
#endif /* pac_exception_h */

View file

@ -1,7 +1,8 @@
#include "pac_expr.h"
#include "pac_case.h"
#include "pac_cstr.h"
#include "pac_exception.h"
#include "pac_expr.h"
#include "pac_exttype.h"
#include "pac_id.h"
#include "pac_number.h"
@ -12,13 +13,13 @@
#include "pac_typedecl.h"
#include "pac_utils.h"
string OrigExprList(ExprList *list)
string OrigExprList(ExprList* list)
{
bool first = true;
string str;
foreach(i, ExprList, list)
foreach (i, ExprList, list)
{
Expr *expr = *i;
Expr* expr = *i;
if ( first )
first = false;
else
@ -28,12 +29,12 @@ string OrigExprList(ExprList *list)
return str;
}
string EvalExprList(ExprList *exprlist, Output *out, Env *env)
string EvalExprList(ExprList* exprlist, Output* out, Env* env)
{
string val_list("");
bool first = true;
foreach(i, ExprList, exprlist)
foreach (i, ExprList, exprlist)
{
if ( ! first )
val_list += ", ";
@ -44,11 +45,10 @@ string EvalExprList(ExprList *exprlist, Output *out, Env *env)
return val_list;
}
static const char* expr_fmt[] =
{
# define EXPR_DEF(type, num_op, fmt) fmt,
# include "pac_expr.def"
# undef EXPR_DEF
static const char* expr_fmt[] = {
#define EXPR_DEF(type, num_op, fmt) fmt,
#include "pac_expr.def"
#undef EXPR_DEF
};
void Expr::init()
@ -65,8 +65,7 @@ void Expr::init()
cases_ = 0;
}
Expr::Expr(ID* arg_id)
: DataDepElement(EXPR)
Expr::Expr(ID* arg_id) : DataDepElement(EXPR)
{
init();
expr_type_ = EXPR_ID;
@ -75,8 +74,7 @@ Expr::Expr(ID* arg_id)
orig_ = strfmt("%s", id_->Name());
}
Expr::Expr(Number* arg_num)
: DataDepElement(EXPR)
Expr::Expr(Number* arg_num) : DataDepElement(EXPR)
{
init();
expr_type_ = EXPR_NUM;
@ -85,8 +83,7 @@ Expr::Expr(Number* arg_num)
orig_ = strfmt("((int) %s)", num_->Str());
}
Expr::Expr(ConstString *cstr)
: DataDepElement(EXPR)
Expr::Expr(ConstString* cstr) : DataDepElement(EXPR)
{
init();
expr_type_ = EXPR_CSTR;
@ -95,8 +92,7 @@ Expr::Expr(ConstString *cstr)
orig_ = cstr_->str();
}
Expr::Expr(RegEx *regex)
: DataDepElement(EXPR)
Expr::Expr(RegEx* regex) : DataDepElement(EXPR)
{
init();
expr_type_ = EXPR_REGEX;
@ -105,8 +101,7 @@ Expr::Expr(RegEx *regex)
orig_ = strfmt("/%s/", regex_->str().c_str());
}
Expr::Expr(ExprType arg_type, Expr* op1)
: DataDepElement(EXPR)
Expr::Expr(ExprType arg_type, Expr* op1) : DataDepElement(EXPR)
{
init();
expr_type_ = arg_type;
@ -115,8 +110,7 @@ Expr::Expr(ExprType arg_type, Expr* op1)
orig_ = strfmt(expr_fmt[expr_type_], op1->orig());
}
Expr::Expr(ExprType arg_type, Expr* op1, Expr* op2)
: DataDepElement(EXPR)
Expr::Expr(ExprType arg_type, Expr* op1, Expr* op2) : DataDepElement(EXPR)
{
init();
expr_type_ = arg_type;
@ -127,8 +121,7 @@ Expr::Expr(ExprType arg_type, Expr* op1, Expr* op2)
orig_ = strfmt(expr_fmt[expr_type_], op1->orig(), op2->orig());
}
Expr::Expr(ExprType arg_type, Expr* op1, Expr* op2, Expr* op3)
: DataDepElement(EXPR)
Expr::Expr(ExprType arg_type, Expr* op1, Expr* op2, Expr* op3) : DataDepElement(EXPR)
{
init();
expr_type_ = arg_type;
@ -139,8 +132,7 @@ Expr::Expr(ExprType arg_type, Expr* op1, Expr* op2, Expr* op3)
orig_ = strfmt(expr_fmt[expr_type_], op1->orig(), op2->orig(), op3->orig());
}
Expr::Expr(ExprList *args)
: DataDepElement(EXPR)
Expr::Expr(ExprList* args) : DataDepElement(EXPR)
{
init();
expr_type_ = EXPR_CALLARGS;
@ -150,8 +142,7 @@ Expr::Expr(ExprList *args)
orig_ = OrigExprList(args_);
}
Expr::Expr(Expr *index, CaseExprList *cases)
: DataDepElement(EXPR)
Expr::Expr(Expr* index, CaseExprList* cases) : DataDepElement(EXPR)
{
init();
expr_type_ = EXPR_CASE;
@ -160,12 +151,10 @@ Expr::Expr(Expr *index, CaseExprList *cases)
cases_ = cases;
orig_ = strfmt("case %s of { ", index->orig());
foreach(i, CaseExprList, cases_)
foreach (i, CaseExprList, cases_)
{
CaseExpr *c = *i;
orig_ += strfmt("%s => %s; ",
OrigExprList(c->index()).c_str(),
c->value()->orig());
CaseExpr* c = *i;
orig_ += strfmt("%s => %s; ", OrigExprList(c->index()).c_str(), c->value()->orig());
}
orig_ += "}";
}
@ -180,7 +169,7 @@ Expr::~Expr()
delete_list(CaseExprList, cases_);
}
void Expr::AddCaseExpr(CaseExpr *case_expr)
void Expr::AddCaseExpr(CaseExpr* case_expr)
{
ASSERT(str_.empty());
ASSERT(expr_type_ == EXPR_CASE);
@ -188,7 +177,7 @@ void Expr::AddCaseExpr(CaseExpr *case_expr)
cases_->push_back(case_expr);
}
void Expr::GenStrFromFormat(Env *env)
void Expr::GenStrFromFormat(Env* env)
{
// The format != "@custom@"
ASSERT(*expr_fmt[expr_type_] != '@');
@ -196,19 +185,14 @@ void Expr::GenStrFromFormat(Env *env)
switch ( num_operands_ )
{
case 1:
str_ = strfmt(expr_fmt[expr_type_],
operand_[0]->str());
str_ = strfmt(expr_fmt[expr_type_], operand_[0]->str());
break;
case 2:
str_ = strfmt(expr_fmt[expr_type_],
operand_[0]->str(),
operand_[1]->str());
str_ = strfmt(expr_fmt[expr_type_], operand_[0]->str(), operand_[1]->str());
break;
case 3:
str_ = strfmt(expr_fmt[expr_type_],
operand_[0]->str(),
operand_[1]->str(),
operand_[2]->str());
str_ = strfmt(expr_fmt[expr_type_], operand_[0]->str(), operand_[1]->str(),
operand_[2]->str());
break;
default:
DEBUG_MSG("num_operands_ = %d, orig = %s\n", num_operands_, orig());
@ -217,43 +201,41 @@ void Expr::GenStrFromFormat(Env *env)
}
}
namespace {
namespace
{
RecordField *GetRecordField(const ID *id, Env *env)
{
Field* field = env->GetField(id);
ASSERT(field);
if ( field->tof() != RECORD_FIELD &&
field->tof() != PADDING_FIELD )
throw Exception(id, "not a record field");
RecordField *r = static_cast<RecordField *>(field);
ASSERT(r);
return r;
}
RecordField* GetRecordField(const ID* id, Env* env)
{
Field* field = env->GetField(id);
ASSERT(field);
if ( field->tof() != RECORD_FIELD && field->tof() != PADDING_FIELD )
throw Exception(id, "not a record field");
RecordField* r = static_cast<RecordField*>(field);
ASSERT(r);
return r;
}
} // private namespace
} // private namespace
void Expr::GenCaseEval(Output *out_cc, Env *env)
void Expr::GenCaseEval(Output* out_cc, Env* env)
{
ASSERT(expr_type_ == EXPR_CASE);
ASSERT(operand_[0]);
ASSERT(cases_);
Type *val_type = DataType(env);
ID *val_var = env->AddTempID(val_type);
Type* val_type = DataType(env);
ID* val_var = env->AddTempID(val_type);
// DataType(env) can return a null pointer if an enum value is not
// defined.
if ( ! val_type )
throw Exception(this, "undefined case value");
out_cc->println("%s %s;",
val_type->DataTypeStr().c_str(),
env->LValue(val_var));
out_cc->println("%s %s;", val_type->DataTypeStr().c_str(), env->LValue(val_var));
// force evaluation of IDs appearing in case stmt
operand_[0]->ForceIDEval(out_cc, env);
foreach(i, CaseExprList, cases_)
operand_[0]->ForceIDEval(out_cc, env);
foreach (i, CaseExprList, cases_)
(*i)->value()->ForceIDEval(out_cc, env);
out_cc->println("switch ( %s )", operand_[0]->EvalExpr(out_cc, env));
@ -262,11 +244,11 @@ void Expr::GenCaseEval(Output *out_cc, Env *env)
out_cc->inc_indent();
out_cc->println("{");
CaseExpr *default_case = 0;
foreach(i, CaseExprList, cases_)
CaseExpr* default_case = 0;
foreach (i, CaseExprList, cases_)
{
CaseExpr *c = *i;
ExprList *index = c->index();
CaseExpr* c = *i;
ExprList* index = c->index();
if ( ! index )
{
if ( default_case )
@ -277,9 +259,7 @@ void Expr::GenCaseEval(Output *out_cc, Env *env)
{
GenCaseStr(index, out_cc, env, switch_type);
out_cc->inc_indent();
out_cc->println("%s = %s;",
env->LValue(val_var),
c->value()->EvalExpr(out_cc, env));
out_cc->println("%s = %s;", env->LValue(val_var), c->value()->EvalExpr(out_cc, env));
out_cc->println("break;");
out_cc->dec_indent();
}
@ -290,14 +270,13 @@ void Expr::GenCaseEval(Output *out_cc, Env *env)
out_cc->inc_indent();
if ( default_case )
{
out_cc->println("%s = %s;",
env->LValue(val_var),
out_cc->println("%s = %s;", env->LValue(val_var),
default_case->value()->EvalExpr(out_cc, env));
}
else
{
out_cc->println("throw binpac::ExceptionInvalidCaseIndex(\"%s\", (int64)%s);",
Location(), operand_[0]->EvalExpr(out_cc, env));
out_cc->println("throw binpac::ExceptionInvalidCaseIndex(\"%s\", (int64)%s);", Location(),
operand_[0]->EvalExpr(out_cc, env));
}
out_cc->println("break;");
out_cc->dec_indent();
@ -333,20 +312,17 @@ void Expr::GenEval(Output* out_cc, Env* env)
*/
operand_[0]->GenEval(out_cc, env);
Type *ty0 = operand_[0]->DataType(env);
Type* ty0 = operand_[0]->DataType(env);
if ( ty0 )
{
str_ = strfmt("%s%s",
operand_[0]->EvalExpr(out_cc, env),
str_ = strfmt("%s%s", operand_[0]->EvalExpr(out_cc, env),
ty0->EvalMember(operand_[1]->id()).c_str());
}
else
{
string tmp = strfmt("->%s()", operand_[1]->id()->Name());
str_ = strfmt("%s%s",
operand_[0]->EvalExpr(out_cc, env),
tmp.c_str());
str_ = strfmt("%s%s", operand_[0]->EvalExpr(out_cc, env), tmp.c_str());
}
}
break;
@ -359,7 +335,7 @@ void Expr::GenEval(Output* out_cc, Env* env)
string v0 = operand_[0]->EvalExpr(out_cc, env);
string v1 = operand_[1]->EvalExpr(out_cc, env);
Type *ty0 = operand_[0]->DataType(env);
Type* ty0 = operand_[0]->DataType(env);
if ( ty0 )
str_ = ty0->EvalElement(v0, v1);
else
@ -369,9 +345,9 @@ void Expr::GenEval(Output* out_cc, Env* env)
case EXPR_SIZEOF:
{
const ID *id = operand_[0]->id();
RecordField *rf;
Type *ty;
const ID* id = operand_[0]->id();
RecordField* rf;
Type* ty;
try
{
@ -380,7 +356,7 @@ void Expr::GenEval(Output* out_cc, Env* env)
str_ = strfmt("%s", rf->FieldSize(out_cc, env));
}
}
catch ( ExceptionIDNotFound &e )
catch ( ExceptionIDNotFound& e )
{
if ( (ty = TypeDecl::LookUpType(id)) != 0 )
{
@ -398,8 +374,8 @@ void Expr::GenEval(Output* out_cc, Env* env)
case EXPR_OFFSETOF:
{
const ID *id = operand_[0]->id();
RecordField *rf = GetRecordField(id, env);
const ID* id = operand_[0]->id();
RecordField* rf = GetRecordField(id, env);
str_ = strfmt("%s", rf->FieldOffset(out_cc, env));
}
break;
@ -423,7 +399,7 @@ void Expr::GenEval(Output* out_cc, Env* env)
}
void Expr::ForceIDEval(Output* out_cc, Env* env)
{
{
switch ( expr_type_ )
{
case EXPR_NUM:
@ -441,18 +417,18 @@ void Expr::ForceIDEval(Output* out_cc, Env* env)
break;
case EXPR_CALLARGS:
{
foreach(i, ExprList, args_)
(*i)->ForceIDEval(out_cc, env);
{
foreach (i, ExprList, args_)
(*i)->ForceIDEval(out_cc, env);
}
break;
case EXPR_CASE:
{
operand_[0]->ForceIDEval(out_cc, env);
foreach(i, CaseExprList, cases_)
{
operand_[0]->ForceIDEval(out_cc, env);
foreach (i, CaseExprList, cases_)
(*i)->value()->ForceIDEval(out_cc, env);
}
}
break;
default:
@ -464,16 +440,15 @@ void Expr::ForceIDEval(Output* out_cc, Env* env)
}
}
const char* Expr::EvalExpr(Output* out_cc, Env* env)
{
GenEval(out_cc, env);
return str();
}
Type *Expr::DataType(Env *env) const
Type* Expr::DataType(Env* env) const
{
Type *data_type;
Type* data_type;
switch ( expr_type_ )
{
@ -484,7 +459,7 @@ Type *Expr::DataType(Env *env) const
case EXPR_MEMBER:
{
// Get type of the parent
Type *parent_type = operand_[0]->DataType(env);
Type* parent_type = operand_[0]->DataType(env);
if ( ! parent_type )
return 0;
data_type = parent_type->MemberDataType(operand_[1]->id());
@ -494,7 +469,7 @@ Type *Expr::DataType(Env *env) const
case EXPR_SUBSCRIPT:
{
// Get type of the parent
Type *parent_type = operand_[0]->DataType(env);
Type* parent_type = operand_[0]->DataType(env);
data_type = parent_type->ElementDataType();
}
break;
@ -505,14 +480,13 @@ Type *Expr::DataType(Env *env) const
case EXPR_COND:
{
Type *type1 = operand_[1]->DataType(env);
Type *type2 = operand_[2]->DataType(env);
Type* type1 = operand_[1]->DataType(env);
Type* type2 = operand_[2]->DataType(env);
if ( ! Type::CompatibleTypes(type1, type2) )
{
throw Exception(this,
strfmt("type mismatch: %s vs %s",
type1->DataTypeStr().c_str(),
type2->DataTypeStr().c_str()));
strfmt("type mismatch: %s vs %s", type1->DataTypeStr().c_str(),
type2->DataTypeStr().c_str()));
}
data_type = type1;
}
@ -526,20 +500,17 @@ Type *Expr::DataType(Env *env) const
{
if ( cases_ && ! cases_->empty() )
{
Type *type1 =
cases_->front()->value()->DataType(env);
Type* type1 = cases_->front()->value()->DataType(env);
Type* numeric_with_largest_width = 0;
foreach(i, CaseExprList, cases_)
foreach (i, CaseExprList, cases_)
{
Type *type2 =
(*i)->value()->DataType(env);
Type* type2 = (*i)->value()->DataType(env);
if ( ! Type::CompatibleTypes(type1, type2) )
{
throw Exception(this,
strfmt("type mismatch: %s vs %s",
type1->DataTypeStr().c_str(),
type2->DataTypeStr().c_str()));
throw Exception(this, strfmt("type mismatch: %s vs %s",
type1->DataTypeStr().c_str(),
type2->DataTypeStr().c_str()));
}
if ( type1 == extern_type_nullptr )
type1 = type2;
@ -611,21 +582,19 @@ Type *Expr::DataType(Env *env) const
return data_type;
}
string Expr::DataTypeStr(Env *env) const
string Expr::DataTypeStr(Env* env) const
{
Type *type = DataType(env);
Type* type = DataType(env);
if ( ! type )
{
throw Exception(this,
strfmt("cannot find data type for expression `%s'",
orig()));
throw Exception(this, strfmt("cannot find data type for expression `%s'", orig()));
}
return type->DataTypeStr();
}
string Expr::SetFunc(Output *out, Env *env)
string Expr::SetFunc(Output* out, Env* env)
{
switch ( expr_type_ )
{
@ -635,15 +604,13 @@ string Expr::SetFunc(Output *out, Env *env)
{
// Evaluate the parent
string parent_val(operand_[0]->EvalExpr(out, env));
return parent_val
+ "->"
+ set_function(operand_[1]->id());
return parent_val + "->" + set_function(operand_[1]->id());
}
break;
default:
throw Exception(this,
strfmt("cannot generate set function "
"for expression `%s'", orig()));
throw Exception(this, strfmt("cannot generate set function "
"for expression `%s'",
orig()));
break;
}
}
@ -664,143 +631,141 @@ bool Expr::ConstFold(Env* env, int* pn) const
}
// TODO: build a generic data dependency extraction process
namespace {
namespace
{
// Maximum of two minimal header sizes
int mhs_max(int h1, int h2)
// Maximum of two minimal header sizes
int mhs_max(int h1, int h2)
{
if ( h1 < 0 || h2 < 0 )
return -1;
else
{
if ( h1 < 0 || h2 < 0 )
return -1;
else
// return max(h1, h2);
return h1 > h2 ? h1 : h2;
}
}
// MHS required to evaluate the field
int mhs_letfield(Env* env, LetField* field)
{
return field->expr()->MinimalHeaderSize(env);
}
int mhs_recordfield(Env* env, RecordField* field)
{
int offset = field->static_offset();
if ( offset < 0 ) // offset cannot be statically determined
return -1;
int size = field->StaticSize(env, offset);
if ( size < 0 ) // size cannot be statically determined
return -1;
return offset + size;
}
int mhs_casefield(Env* env, CaseField* field)
{
// TODO: deal with the index
int size = field->StaticSize(env);
if ( size < 0 ) // size cannot be statically determined
return -1;
return size;
}
int mhs_field(Env* env, Field* field)
{
int mhs = -1;
switch ( field->tof() )
{
case LET_FIELD:
{
// return max(h1, h2);
return h1 > h2 ? h1 : h2;
LetField* f = static_cast<LetField*>(field);
ASSERT(f);
mhs = mhs_letfield(env, f);
}
}
break;
// MHS required to evaluate the field
int mhs_letfield(Env* env, LetField* field)
{
return field->expr()->MinimalHeaderSize(env);
}
case CONTEXT_FIELD:
case FLOW_FIELD:
ASSERT(0);
break;
int mhs_recordfield(Env* env, RecordField* field)
{
int offset = field->static_offset();
if ( offset < 0 ) // offset cannot be statically determined
return -1;
int size = field->StaticSize(env, offset);
if ( size < 0 ) // size cannot be statically determined
return -1;
return offset + size;
}
case PARAM_FIELD:
mhs = 0;
break;
int mhs_casefield(Env* env, CaseField* field)
{
// TODO: deal with the index
int size = field->StaticSize(env);
if ( size < 0 ) // size cannot be statically determined
return -1;
return size;
}
int mhs_field(Env* env, Field* field)
{
int mhs = -1;
switch ( field->tof() )
case RECORD_FIELD:
case PADDING_FIELD:
{
case LET_FIELD:
{
LetField *f =
static_cast<LetField *>(field);
ASSERT(f);
mhs = mhs_letfield(env, f);
}
break;
case CONTEXT_FIELD:
case FLOW_FIELD:
ASSERT(0);
break;
case PARAM_FIELD:
mhs = 0;
break;
case RECORD_FIELD:
case PADDING_FIELD:
{
RecordField *f =
static_cast<RecordField *>(field);
ASSERT(f);
mhs = mhs_recordfield(env, f);
}
break;
case CASE_FIELD:
{
CaseField *f =
static_cast<CaseField *>(field);
ASSERT(f);
mhs = mhs_casefield(env, f);
}
break;
case PARSE_VAR_FIELD:
case PRIV_VAR_FIELD:
case PUB_VAR_FIELD:
case TEMP_VAR_FIELD:
mhs = 0;
break;
case WITHINPUT_FIELD:
{
// ### TODO: fix this
mhs = -1;
}
break;
RecordField* f = static_cast<RecordField*>(field);
ASSERT(f);
mhs = mhs_recordfield(env, f);
}
return mhs;
}
break;
int mhs_id(Env *env, const ID *id)
{
int mhs = -1;
switch ( env->GetIDType(id) )
case CASE_FIELD:
{
case CONST:
case GLOBAL_VAR:
case TEMP_VAR:
case STATE_VAR:
case FUNC_ID:
case FUNC_PARAM:
mhs = 0;
break;
case MEMBER_VAR:
case PRIV_MEMBER_VAR:
{
Field* field = env->GetField(id);
if ( ! field )
throw ExceptionIDNotField(id);
mhs = mhs_field(env, field);
}
break;
case UNION_VAR:
// TODO: deal with UNION_VAR
mhs = -1;
break;
case MACRO:
{
Expr *e = env->GetMacro(id);
mhs = e->MinimalHeaderSize(env);
}
break;
CaseField* f = static_cast<CaseField*>(field);
ASSERT(f);
mhs = mhs_casefield(env, f);
}
return mhs;
}
}
break;
int Expr::MinimalHeaderSize(Env *env)
case PARSE_VAR_FIELD:
case PRIV_VAR_FIELD:
case PUB_VAR_FIELD:
case TEMP_VAR_FIELD:
mhs = 0;
break;
case WITHINPUT_FIELD:
{
// ### TODO: fix this
mhs = -1;
}
break;
}
return mhs;
}
int mhs_id(Env* env, const ID* id)
{
int mhs = -1;
switch ( env->GetIDType(id) )
{
case CONST:
case GLOBAL_VAR:
case TEMP_VAR:
case STATE_VAR:
case FUNC_ID:
case FUNC_PARAM:
mhs = 0;
break;
case MEMBER_VAR:
case PRIV_MEMBER_VAR:
{
Field* field = env->GetField(id);
if ( ! field )
throw ExceptionIDNotField(id);
mhs = mhs_field(env, field);
}
break;
case UNION_VAR:
// TODO: deal with UNION_VAR
mhs = -1;
break;
case MACRO:
{
Expr* e = env->GetMacro(id);
mhs = e->MinimalHeaderSize(env);
}
break;
}
return mhs;
}
}
int Expr::MinimalHeaderSize(Env* env)
{
int mhs;
@ -826,11 +791,10 @@ int Expr::MinimalHeaderSize(Env *env)
case EXPR_SUBSCRIPT:
{
int index;
Type *array_type = operand_[0]->DataType(env);
Type *elem_type = array_type->ElementDataType();
Type* array_type = operand_[0]->DataType(env);
Type* elem_type = array_type->ElementDataType();
int elem_size = elem_type->StaticSize(env);
if ( elem_size >= 0 &&
operand_[1]->ConstFold(env, &index) )
if ( elem_size >= 0 && operand_[1]->ConstFold(env, &index) )
{
mhs = elem_size * index;
}
@ -845,8 +809,8 @@ int Expr::MinimalHeaderSize(Env *env)
{
const ID* id = operand_[0]->id();
ASSERT(id);
RecordField *rf;
Type *ty;
RecordField* rf;
Type* ty;
if ( (rf = GetRecordField(id, env)) != 0 )
{
@ -870,7 +834,7 @@ int Expr::MinimalHeaderSize(Env *env)
{
const ID* id = operand_[0]->id();
ASSERT(id);
RecordField *field = GetRecordField(id, env);
RecordField* field = GetRecordField(id, env);
mhs = field->static_offset();
if ( mhs < 0 )
@ -885,21 +849,21 @@ int Expr::MinimalHeaderSize(Env *env)
break;
case EXPR_CALLARGS:
{
mhs = 0;
{
mhs = 0;
if ( args_ )
for ( unsigned int i = 0; i < args_->size(); ++i )
for ( unsigned int i = 0; i < args_->size(); ++i )
mhs = mhs_max(mhs, (*args_)[i]->MinimalHeaderSize(env));
}
break;
break;
case EXPR_CASE:
{
mhs = operand_[0]->MinimalHeaderSize(env);
{
mhs = operand_[0]->MinimalHeaderSize(env);
for ( unsigned int i = 0; i < cases_->size(); ++i )
{
CaseExpr * ce = (*cases_)[i];
{
CaseExpr* ce = (*cases_)[i];
if ( ce->index() )
for ( unsigned int j = 0; j < ce->index()->size(); ++j )
for ( unsigned int j = 0; j < ce->index()->size(); ++j )
mhs = mhs_max(mhs, (*ce->index())[j]->MinimalHeaderSize(env));
mhs = mhs_max(mhs, ce->value()->MinimalHeaderSize(env));
}
@ -917,7 +881,7 @@ int Expr::MinimalHeaderSize(Env *env)
return mhs;
}
bool Expr::HasReference(const ID *id) const
bool Expr::HasReference(const ID* id) const
{
switch ( expr_type_ )
{
@ -929,7 +893,7 @@ bool Expr::HasReference(const ID *id) const
case EXPR_CALLARGS:
{
foreach(i, ExprList, args_)
foreach (i, ExprList, args_)
if ( (*i)->HasReference(id) )
return true;
}
@ -937,7 +901,7 @@ bool Expr::HasReference(const ID *id) const
case EXPR_CASE:
{
foreach(i, CaseExprList, cases_)
foreach (i, CaseExprList, cases_)
if ( (*i)->HasReference(id) )
return true;
}
@ -947,8 +911,7 @@ bool Expr::HasReference(const ID *id) const
// Evaluate every operand by default
for ( int i = 0; i < 3; ++i )
{
if ( operand_[i] &&
operand_[i]->HasReference(id) )
if ( operand_[i] && operand_[i]->HasReference(id) )
{
return true;
}
@ -957,7 +920,7 @@ bool Expr::HasReference(const ID *id) const
}
}
bool Expr::DoTraverse(DataDepVisitor *visitor)
bool Expr::DoTraverse(DataDepVisitor* visitor)
{
switch ( expr_type_ )
{
@ -977,7 +940,7 @@ bool Expr::DoTraverse(DataDepVisitor *visitor)
case EXPR_CALLARGS:
{
foreach(i, ExprList, args_)
foreach (i, ExprList, args_)
if ( ! (*i)->Traverse(visitor) )
return false;
}
@ -985,7 +948,7 @@ bool Expr::DoTraverse(DataDepVisitor *visitor)
case EXPR_CASE:
{
foreach(i, CaseExprList, cases_)
foreach (i, CaseExprList, cases_)
if ( ! (*i)->Traverse(visitor) )
return false;
}
@ -995,8 +958,7 @@ bool Expr::DoTraverse(DataDepVisitor *visitor)
// Evaluate every operand by default
for ( int i = 0; i < 3; ++i )
{
if ( operand_[i] &&
! operand_[i]->Traverse(visitor) )
if ( operand_[i] && ! operand_[i]->Traverse(visitor) )
{
return false;
}
@ -1025,7 +987,7 @@ bool Expr::RequiresAnalyzerContext() const
case EXPR_CALLARGS:
{
foreach(i, ExprList, args_)
foreach (i, ExprList, args_)
if ( (*i)->RequiresAnalyzerContext() )
return true;
}
@ -1033,7 +995,7 @@ bool Expr::RequiresAnalyzerContext() const
case EXPR_CASE:
{
foreach(i, CaseExprList, cases_)
foreach (i, CaseExprList, cases_)
if ( (*i)->RequiresAnalyzerContext() )
return true;
}
@ -1042,8 +1004,7 @@ bool Expr::RequiresAnalyzerContext() const
default:
// Evaluate every operand by default
for ( int i = 0; i < 3; ++i )
if ( operand_[i] &&
operand_[i]->RequiresAnalyzerContext() )
if ( operand_[i] && operand_[i]->RequiresAnalyzerContext() )
{
DEBUG_MSG("'%s' requires analyzer context\n", operand_[i]->orig());
return true;
@ -1052,9 +1013,8 @@ bool Expr::RequiresAnalyzerContext() const
}
}
CaseExpr::CaseExpr(ExprList *index, Expr *value)
: DataDepElement(DataDepElement::CASEEXPR),
index_(index), value_(value)
CaseExpr::CaseExpr(ExprList* index, Expr* value)
: DataDepElement(DataDepElement::CASEEXPR), index_(index), value_(value)
{
}
@ -1064,15 +1024,15 @@ CaseExpr::~CaseExpr()
delete value_;
}
bool CaseExpr::DoTraverse(DataDepVisitor *visitor)
bool CaseExpr::DoTraverse(DataDepVisitor* visitor)
{
foreach(i, ExprList, index_)
foreach (i, ExprList, index_)
if ( ! (*i)->Traverse(visitor) )
return false;
return value_->Traverse(visitor);
}
bool CaseExpr::HasReference(const ID *id) const
bool CaseExpr::HasReference(const ID* id) const
{
return value_->HasReference(id);
}

View file

@ -7,42 +7,43 @@
class CaseExpr;
class Expr : public Object, public DataDepElement
{
{
public:
enum ExprType {
# define EXPR_DEF(type, x, y) type,
# include "pac_expr.def"
# undef EXPR_DEF
};
enum ExprType
{
#define EXPR_DEF(type, x, y) type,
#include "pac_expr.def"
#undef EXPR_DEF
};
void init();
Expr(ID *id);
Expr(Number *num);
Expr(ConstString *s);
Expr(RegEx *regex);
Expr(ExprList *args); // for EXPR_CALLARGS
Expr(Expr *index, CaseExprList *cases);
Expr(ID* id);
Expr(Number* num);
Expr(ConstString* s);
Expr(RegEx* regex);
Expr(ExprList* args); // for EXPR_CALLARGS
Expr(Expr* index, CaseExprList* cases);
Expr(ExprType type, Expr *op1);
Expr(ExprType type, Expr *op1, Expr *op2);
Expr(ExprType type, Expr *op1, Expr *op2, Expr *op3);
Expr(ExprType type, Expr* op1);
Expr(ExprType type, Expr* op1, Expr* op2);
Expr(ExprType type, Expr* op1, Expr* op2, Expr* op3);
virtual ~Expr();
const char *orig() const { return orig_.c_str(); }
const ID *id() const { return id_; }
const char *str() const { return str_.c_str(); }
ExprType expr_type() const { return expr_type_; }
const char* orig() const { return orig_.c_str(); }
const ID* id() const { return id_; }
const char* str() const { return str_.c_str(); }
ExprType expr_type() const { return expr_type_; }
void AddCaseExpr(CaseExpr *case_expr);
void AddCaseExpr(CaseExpr* case_expr);
// Returns the data "type" of the expression. Here we only
// do a serious job for the EXPR_MEMBER and EXPR_SUBSCRIPT
// operators. For arithmetic operations, we fall back
// to "int".
Type *DataType(Env *env) const;
string DataTypeStr(Env *env) const;
Type* DataType(Env* env) const;
string DataTypeStr(Env* env) const;
// Note: EvalExpr() may generate C++ statements in order to evaluate
// variables in the expression, so the following is wrong:
@ -54,24 +55,24 @@ public:
//
// out->println("int x = %s", expr->EvalExpr(out, env));
//
const char *EvalExpr(Output *out, Env *env);
const char* EvalExpr(Output* out, Env* env);
// force evaulation of IDs contained in this expression;
// necessary with case expr and conditional let fields (&if)
// for correct parsing of fields
void ForceIDEval(Output *out_cc, Env *env);
void ForceIDEval(Output* out_cc, Env* env);
// Returns the set_* function of the expression.
// The expression must be of form ID or x.ID.
string SetFunc(Output *out, Env *env);
string SetFunc(Output* out, Env* env);
// Returns true if the expression folds to an integer
// constant with env, and puts the constant in *pn.
//
bool ConstFold(Env *env, int *pn) const;
bool ConstFold(Env* env, int* pn) const;
// Whether id is referenced in the expression
bool HasReference(const ID *id) const;
bool HasReference(const ID* id) const;
// Suppose the data for type might be incomplete, what is
// the minimal number of bytes from data head required to
@ -82,58 +83,58 @@ public:
//
// Returns -1 if the number is not a constant.
//
int MinimalHeaderSize(Env *env);
int MinimalHeaderSize(Env* env);
// Whether evaluation of the expression requires the analyzer context
bool RequiresAnalyzerContext() const;
protected:
bool DoTraverse(DataDepVisitor *visitor);
bool DoTraverse(DataDepVisitor* visitor);
private:
ExprType expr_type_;
int num_operands_;
Expr *operand_[3];
Expr* operand_[3];
ID *id_; // EXPR_ID
Number *num_; // EXPR_NUM
ConstString *cstr_; // EXPR_CSTR
RegEx *regex_; // EXPR_REGEX
ExprList *args_; // EXPR_CALLARGS
CaseExprList *cases_; // EXPR_CASE
ID* id_; // EXPR_ID
Number* num_; // EXPR_NUM
ConstString* cstr_; // EXPR_CSTR
RegEx* regex_; // EXPR_REGEX
ExprList* args_; // EXPR_CALLARGS
CaseExprList* cases_; // EXPR_CASE
string str_; // value string
string orig_; // original string for debugging info
string str_; // value string
string orig_; // original string for debugging info
void GenStrFromFormat(Env *env);
void GenEval(Output *out, Env *env);
void GenCaseEval(Output *out_cc, Env *env);
};
void GenStrFromFormat(Env* env);
void GenEval(Output* out, Env* env);
void GenCaseEval(Output* out_cc, Env* env);
};
string OrigExprList(ExprList *exprlist);
string EvalExprList(ExprList *exprlist, Output *out, Env *env);
string OrigExprList(ExprList* exprlist);
string EvalExprList(ExprList* exprlist, Output* out, Env* env);
// An entry of the case expression, consisting of one or more constant
// expressions for the case index and a value expression.
class CaseExpr : public Object, public DataDepElement
{
{
public:
CaseExpr(ExprList *index, Expr *value);
CaseExpr(ExprList* index, Expr* value);
virtual ~CaseExpr();
ExprList *index() const { return index_; }
Expr *value() const { return value_; }
ExprList* index() const { return index_; }
Expr* value() const { return value_; }
bool HasReference(const ID *id) const;
bool HasReference(const ID* id) const;
bool RequiresAnalyzerContext() const;
protected:
bool DoTraverse(DataDepVisitor *visitor);
bool DoTraverse(DataDepVisitor* visitor);
private:
ExprList *index_;
Expr *value_;
};
ExprList* index_;
Expr* value_;
};
#endif // pac_expr_h
#endif // pac_expr_h

View file

@ -1,6 +1,7 @@
#include "pac_exttype.h"
#include "pac_id.h"
#include "pac_decl.h"
#include "pac_id.h"
#include "pac_output.h"
bool ExternType::DefineValueVar() const
@ -34,11 +35,9 @@ bool ExternType::ByteOrderSensitive() const
return false;
}
string ExternType::EvalMember(const ID *member_id) const
string ExternType::EvalMember(const ID* member_id) const
{
return strfmt("%s%s",
ext_type_ == POINTER ? "->" : ".",
member_id->Name());
return strfmt("%s%s", ext_type_ == POINTER ? "->" : ".", member_id->Name());
}
void ExternType::GenInitCode(Output* out_cc, Env* env)
@ -58,26 +57,26 @@ void ExternType::GenDynamicSize(Output* out, Env* env, const DataPtr& data)
ASSERT(0);
}
Type *ExternType::DoClone() const
Type* ExternType::DoClone() const
{
return new ExternType(id_->clone(), ext_type_);
}
// Definitions of pre-defined external types
#define EXTERNTYPE(name, ctype, exttype) ExternType *extern_type_##name = 0;
#define EXTERNTYPE(name, ctype, exttype) ExternType* extern_type_##name = 0;
#include "pac_externtype.def"
#undef EXTERNTYPE
void ExternType::static_init()
{
ID *id;
ID* id;
// TypeDecl *decl;
// decl = new TypeDecl(id, 0, extern_type_##name);
#define EXTERNTYPE(name, ctype, exttype) \
id = new ID(#ctype); \
extern_type_##name = new ExternType(id, ExternType::exttype); \
#define EXTERNTYPE(name, ctype, exttype) \
id = new ID(#ctype); \
extern_type_##name = new ExternType(id, ExternType::exttype); \
Type::AddPredefinedType(#name, extern_type_##name);
#include "pac_externtype.def"
#undef EXTERNTYPE

View file

@ -9,41 +9,43 @@
// literally to the compiled code.
class ExternType : public Type
{
{
public:
enum EXTType { PLAIN, NUMBER, POINTER };
ExternType(const ID *id, EXTType ext_type)
: Type(EXTERN),
id_(id),
ext_type_(ext_type) {}
enum EXTType
{
PLAIN,
NUMBER,
POINTER
};
ExternType(const ID* id, EXTType ext_type) : Type(EXTERN), id_(id), ext_type_(ext_type) { }
bool DefineValueVar() const;
string DataTypeStr() const;
int StaticSize(Env *env) const;
int StaticSize(Env* env) const;
bool ByteOrderSensitive() const;
string EvalMember(const ID *member_id) const;
bool IsNumericType() const { return ext_type_ == NUMBER; }
bool IsPointerType() const { return ext_type_ == POINTER; }
string EvalMember(const ID* member_id) const;
bool IsNumericType() const { return ext_type_ == NUMBER; }
bool IsPointerType() const { return ext_type_ == POINTER; }
void GenInitCode(Output *out_cc, Env *env);
void GenInitCode(Output* out_cc, Env* env);
protected:
void DoGenParseCode(Output *out, Env *env, const DataPtr& data, int flags);
void GenDynamicSize(Output *out, Env *env, const DataPtr& data);
void DoGenParseCode(Output* out, Env* env, const DataPtr& data, int flags);
void GenDynamicSize(Output* out, Env* env, const DataPtr& data);
Type *DoClone() const;
Type* DoClone() const;
private:
const ID *id_;
const ID* id_;
EXTType ext_type_;
public:
static void static_init();
};
};
#define EXTERNTYPE(name, ctype, exttype) extern ExternType *extern_type_##name;
#define EXTERNTYPE(name, ctype, exttype) extern ExternType* extern_type_##name;
#include "pac_externtype.def"
#undef EXTERNTYPE
#endif // pac_exttype_h
#endif // pac_exttype_h

View file

@ -1,13 +1,13 @@
#include "pac_field.h"
#include "pac_attr.h"
#include "pac_common.h"
#include "pac_exception.h"
#include "pac_field.h"
#include "pac_id.h"
#include "pac_type.h"
Field::Field(FieldType tof, int flags, ID *id, Type *type)
: DataDepElement(DataDepElement::FIELD),
tof_(tof), flags_(flags), id_(id), type_(type)
Field::Field(FieldType tof, int flags, ID* id, Type* type)
: DataDepElement(DataDepElement::FIELD), tof_(tof), flags_(flags), id_(id), type_(type)
{
decl_id_ = current_decl_id;
field_id_str_ = strfmt("%s:%s", decl_id()->Name(), id_->Name());
@ -35,24 +35,22 @@ void Field::AddAttr(AttrList* attrs)
delete_attrs = true;
}
foreach(i, AttrList, attrs)
foreach (i, AttrList, attrs)
ProcessAttr(*i);
if ( delete_attrs )
delete attrs;
}
void Field::ProcessAttr(Attr *a)
void Field::ProcessAttr(Attr* a)
{
switch ( a->type() )
{
case ATTR_IF:
if ( tof() != LET_FIELD &&
tof() != WITHINPUT_FIELD )
if ( tof() != LET_FIELD && tof() != WITHINPUT_FIELD )
{
throw Exception(a,
"&if can only be applied to a "
"let field");
throw Exception(a, "&if can only be applied to a "
"let field");
}
break;
default:
@ -76,7 +74,7 @@ int Field::ValueVarType() const
return TEMP_VAR;
}
void Field::Prepare(Env *env)
void Field::Prepare(Env* env)
{
if ( type_ )
{
@ -86,9 +84,7 @@ void Field::Prepare(Env *env)
flags_ &= (~PUBLIC_READABLE);
type_->set_value_var(id(), ValueVarType());
type_->Prepare(env,
flags_ & TYPE_TO_BE_PARSED ?
Type::TO_BE_PARSED : 0);
type_->Prepare(env, flags_ & TYPE_TO_BE_PARSED ? Type::TO_BE_PARSED : 0);
env->SetField(id(), this);
}
}
@ -109,7 +105,7 @@ void Field::GenPrivDecls(Output* out_h, Env* env)
void Field::GenTempDecls(Output* out_h, Env* env)
{
// Generate temp field
if ( type_ && !(flags_ & CLASS_MEMBER) )
if ( type_ && ! (flags_ & CLASS_MEMBER) )
type_->GenPrivDecls(out_h, env);
}
@ -125,12 +121,12 @@ void Field::GenCleanUpCode(Output* out_cc, Env* env)
type_->GenCleanUpCode(out_cc, env);
}
bool Field::DoTraverse(DataDepVisitor *visitor)
bool Field::DoTraverse(DataDepVisitor* visitor)
{
// Check parameterized type
if ( type_ && ! type_->Traverse(visitor) )
return false;
foreach(i, AttrList, attrs_)
foreach (i, AttrList, attrs_)
if ( ! (*i)->Traverse(visitor) )
return false;
return true;
@ -141,7 +137,7 @@ bool Field::RequiresAnalyzerContext() const
// Check parameterized type
if ( type_ && type_->RequiresAnalyzerContext() )
return true;
foreach(i, AttrList, attrs_)
foreach (i, AttrList, attrs_)
if ( (*i)->RequiresAnalyzerContext() )
return true;
return false;

View file

@ -6,7 +6,8 @@
// A "field" is a member of class.
enum FieldType {
enum FieldType
{
CASE_FIELD,
CONTEXT_FIELD,
FLOW_FIELD,
@ -19,12 +20,12 @@ enum FieldType {
PUB_VAR_FIELD,
TEMP_VAR_FIELD,
WITHINPUT_FIELD,
};
};
class Field : public Object, public DataDepElement
{
{
public:
Field(FieldType tof, int flags, ID *id, Type *type);
Field(FieldType tof, int flags, ID* id, Type* type);
// Field flags
// Whether the field will be evaluated by calling the Parse()
@ -43,17 +44,17 @@ public:
virtual ~Field();
FieldType tof() const { return tof_; }
const ID* id() const { return id_; }
Type *type() const { return type_; }
const ID* decl_id() const { return decl_id_; }
FieldType tof() const { return tof_; }
const ID* id() const { return id_; }
Type* type() const { return type_; }
const ID* decl_id() const { return decl_id_; }
bool anonymous_field() const;
void AddAttr(AttrList* attrs);
// The field interface
virtual void ProcessAttr(Attr *attr);
virtual void ProcessAttr(Attr* attr);
virtual void Prepare(Env* env);
virtual void GenPubDecls(Output* out, Env* env);
@ -69,16 +70,16 @@ protected:
int ValueVarType() const;
bool ToBeParsed() const;
bool DoTraverse(DataDepVisitor *visitor);
bool DoTraverse(DataDepVisitor* visitor);
protected:
FieldType tof_;
int flags_;
ID* id_;
Type *type_;
Type* type_;
const ID* decl_id_;
string field_id_str_;
AttrList* attrs_;
};
};
#endif // pac_field_h
#endif // pac_field_h

View file

@ -1,3 +1,5 @@
#include "pac_flow.h"
#include "pac_analyzer.h"
#include "pac_conn.h"
#include "pac_context.h"
@ -7,17 +9,13 @@
#include "pac_exception.h"
#include "pac_expr.h"
#include "pac_exttype.h"
#include "pac_flow.h"
#include "pac_output.h"
#include "pac_param.h"
#include "pac_paramtype.h"
#include "pac_type.h"
#include "pac_varfield.h"
FlowDecl::FlowDecl(ID *id,
ParamList *params,
AnalyzerElementList *elemlist)
FlowDecl::FlowDecl(ID* id, ParamList* params, AnalyzerElementList* elemlist)
: AnalyzerDecl(id, FLOW, params)
{
dataunit_ = 0;
@ -32,9 +30,9 @@ FlowDecl::~FlowDecl()
delete dataunit_;
}
ParameterizedType *FlowDecl::flow_buffer_type_ = 0;
ParameterizedType* FlowDecl::flow_buffer_type_ = 0;
ParameterizedType *FlowDecl::flow_buffer_type()
ParameterizedType* FlowDecl::flow_buffer_type()
{
if ( ! flow_buffer_type_ )
{
@ -43,24 +41,21 @@ ParameterizedType *FlowDecl::flow_buffer_type()
return flow_buffer_type_;
}
void FlowDecl::AddBaseClass(vector<string> *base_classes) const
void FlowDecl::AddBaseClass(vector<string>* base_classes) const
{
base_classes->push_back("binpac::FlowAnalyzer");
}
void FlowDecl::ProcessFlowElement(AnalyzerFlow *flow_elem)
void FlowDecl::ProcessFlowElement(AnalyzerFlow* flow_elem)
{
throw Exception(
flow_elem,
"flow should be defined in only a connection declaration");
throw Exception(flow_elem, "flow should be defined in only a connection declaration");
}
void FlowDecl::ProcessDataUnitElement(AnalyzerDataUnit *dataunit_elem)
void FlowDecl::ProcessDataUnitElement(AnalyzerDataUnit* dataunit_elem)
{
if ( dataunit_ )
{
throw Exception(dataunit_elem,
"dataunit already defined");
throw Exception(dataunit_elem, "dataunit already defined");
}
dataunit_ = dataunit_elem;
@ -68,17 +63,15 @@ void FlowDecl::ProcessDataUnitElement(AnalyzerDataUnit *dataunit_elem)
{
dataunit_->data_type()->MarkIncrementalInput();
flow_buffer_var_field_ = new PubVarField(
flow_buffer_id->clone(),
FlowDecl::flow_buffer_type()->Clone());
flow_buffer_var_field_ = new PubVarField(flow_buffer_id->clone(),
FlowDecl::flow_buffer_type()->Clone());
type_->AddField(flow_buffer_var_field_);
ASSERT(AnalyzerContextDecl::current_analyzer_context());
AnalyzerContextDecl::current_analyzer_context()->AddFlowBuffer();
// Add an argument to the context initiation
dataunit_->context_type()->AddParamArg(
new Expr(flow_buffer_var_field_->id()->clone()));
dataunit_->context_type()->AddParamArg(new Expr(flow_buffer_var_field_->id()->clone()));
}
}
@ -87,28 +80,25 @@ void FlowDecl::Prepare()
// Add the connection parameter
if ( ! conn_decl_ )
{
throw Exception(this,
"no connection is not declared for the flow");
throw Exception(this, "no connection is not declared for the flow");
}
if ( ! params_ )
params_ = new ParamList();
params_->insert(params_->begin(),
new Param(connection_id->clone(),
conn_decl_->DataType()));
params_->insert(params_->begin(), new Param(connection_id->clone(), conn_decl_->DataType()));
AnalyzerDecl::Prepare();
dataunit_->Prepare(env_);
}
void FlowDecl::GenPubDecls(Output *out_h, Output *out_cc)
void FlowDecl::GenPubDecls(Output* out_h, Output* out_cc)
{
AnalyzerDecl::GenPubDecls(out_h, out_cc);
}
void FlowDecl::GenPrivDecls(Output *out_h, Output *out_cc)
void FlowDecl::GenPrivDecls(Output* out_h, Output* out_cc)
{
// Declare the data unit
dataunit_->dataunit_var_field()->GenPrivDecls(out_h, env_);
@ -119,14 +109,12 @@ void FlowDecl::GenPrivDecls(Output *out_h, Output *out_cc)
AnalyzerDecl::GenPrivDecls(out_h, out_cc);
}
void FlowDecl::GenInitCode(Output *out_cc)
void FlowDecl::GenInitCode(Output* out_cc)
{
AnalyzerDecl::GenInitCode(out_cc);
out_cc->println("%s = 0;",
env_->LValue(dataunit_id));
out_cc->println("%s = 0;",
env_->LValue(analyzer_context_id));
out_cc->println("%s = 0;", env_->LValue(dataunit_id));
out_cc->println("%s = 0;", env_->LValue(analyzer_context_id));
if ( dataunit_->type() == AnalyzerDataUnit::FLOWUNIT )
{
@ -135,13 +123,13 @@ void FlowDecl::GenInitCode(Output *out_cc)
}
}
void FlowDecl::GenCleanUpCode(Output *out_cc)
void FlowDecl::GenCleanUpCode(Output* out_cc)
{
GenDeleteDataUnit(out_cc);
AnalyzerDecl::GenCleanUpCode(out_cc);
}
void FlowDecl::GenEOFFunc(Output *out_h, Output *out_cc)
void FlowDecl::GenEOFFunc(Output* out_h, Output* out_cc)
{
string proto = strfmt("%s()", kFlowEOF);
@ -151,15 +139,14 @@ void FlowDecl::GenEOFFunc(Output *out_h, Output *out_cc)
out_cc->inc_indent();
out_cc->println("{");
foreach(i, AnalyzerHelperList, eof_helpers_)
foreach (i, AnalyzerHelperList, eof_helpers_)
{
(*i)->GenCode(0, out_cc, this);
}
if ( dataunit_->type() == AnalyzerDataUnit::FLOWUNIT )
{
out_cc->println("%s->set_eof();",
env_->LValue(flow_buffer_id));
out_cc->println("%s->set_eof();", env_->LValue(flow_buffer_id));
out_cc->println("%s(0, 0);", kNewData);
}
@ -167,7 +154,7 @@ void FlowDecl::GenEOFFunc(Output *out_h, Output *out_cc)
out_cc->dec_indent();
}
void FlowDecl::GenGapFunc(Output *out_h, Output *out_cc)
void FlowDecl::GenGapFunc(Output* out_h, Output* out_cc)
{
string proto = strfmt("%s(int gap_length)", kFlowGap);
@ -179,24 +166,20 @@ void FlowDecl::GenGapFunc(Output *out_h, Output *out_cc)
if ( dataunit_->type() == AnalyzerDataUnit::FLOWUNIT )
{
out_cc->println("%s->NewGap(gap_length);",
env_->LValue(flow_buffer_id));
out_cc->println("%s->NewGap(gap_length);", env_->LValue(flow_buffer_id));
}
out_cc->println("}");
out_cc->dec_indent();
}
void FlowDecl::GenProcessFunc(Output *out_h, Output *out_cc)
void FlowDecl::GenProcessFunc(Output* out_h, Output* out_cc)
{
env_->AddID(begin_of_data, TEMP_VAR, extern_type_const_byteptr);
env_->AddID(end_of_data, TEMP_VAR, extern_type_const_byteptr);
string proto =
strfmt("%s(const_byteptr %s, const_byteptr %s)",
kNewData,
env_->LValue(begin_of_data),
env_->LValue(end_of_data));
string proto = strfmt("%s(const_byteptr %s, const_byteptr %s)", kNewData,
env_->LValue(begin_of_data), env_->LValue(end_of_data));
out_h->println("void %s;", proto.c_str());
@ -232,8 +215,7 @@ void FlowDecl::GenProcessFunc(Output *out_h, Output *out_cc)
GenCleanUpCode(out_cc);
if ( dataunit_->type() == AnalyzerDataUnit::FLOWUNIT )
{
out_cc->println("%s->DiscardData();",
env_->LValue(flow_buffer_id));
out_cc->println("%s->DiscardData();", env_->LValue(flow_buffer_id));
}
out_cc->println("throw;");
out_cc->println("}");
@ -244,21 +226,19 @@ void FlowDecl::GenProcessFunc(Output *out_h, Output *out_cc)
out_cc->println("");
}
void FlowDecl::GenNewDataUnit(Output *out_cc)
void FlowDecl::GenNewDataUnit(Output* out_cc)
{
Type *unit_datatype = dataunit_->data_type();
Type* unit_datatype = dataunit_->data_type();
// dataunit_->data_type()->GenPreParsing(out_cc, env_);
dataunit_->GenNewDataUnit(out_cc, env_);
if ( unit_datatype->buffer_input() &&
unit_datatype->buffer_mode() == Type::BUFFER_BY_LENGTH )
if ( unit_datatype->buffer_input() && unit_datatype->buffer_mode() == Type::BUFFER_BY_LENGTH )
{
out_cc->println("%s->NewFrame(0, false);",
env_->LValue(flow_buffer_id));
out_cc->println("%s->NewFrame(0, false);", env_->LValue(flow_buffer_id));
}
dataunit_->GenNewContext(out_cc, env_);
}
void FlowDecl::GenDeleteDataUnit(Output *out_cc)
void FlowDecl::GenDeleteDataUnit(Output* out_cc)
{
// Do not just delete dataunit, because we may just want to Unref it.
// out_cc->println("delete %s;", env_->LValue(dataunit_id));
@ -266,28 +246,24 @@ void FlowDecl::GenDeleteDataUnit(Output *out_cc)
dataunit_->context_type()->GenCleanUpCode(out_cc, env_);
}
void FlowDecl::GenCodeFlowUnit(Output *out_cc)
void FlowDecl::GenCodeFlowUnit(Output* out_cc)
{
Type *unit_datatype = dataunit_->data_type();
Type* unit_datatype = dataunit_->data_type();
out_cc->println("%s->NewData(%s, %s);",
env_->LValue(flow_buffer_id),
env_->RValue(begin_of_data),
env_->RValue(end_of_data));
out_cc->println("%s->NewData(%s, %s);", env_->LValue(flow_buffer_id),
env_->RValue(begin_of_data), env_->RValue(end_of_data));
out_cc->println("while ( %s->data_available() && ",
env_->LValue(flow_buffer_id));
out_cc->println("while ( %s->data_available() && ", env_->LValue(flow_buffer_id));
out_cc->inc_indent();
out_cc->println("( !%s->have_pending_request() || %s->ready() ) )",
env_->LValue(flow_buffer_id), env_->LValue(flow_buffer_id));
env_->LValue(flow_buffer_id), env_->LValue(flow_buffer_id));
out_cc->println("{");
// Generate a new dataunit if necessary
out_cc->println("if ( ! %s )", env_->LValue(dataunit_id));
out_cc->inc_indent();
out_cc->println("{");
out_cc->println("BINPAC_ASSERT(!%s);",
env_->LValue(analyzer_context_id));
out_cc->println("BINPAC_ASSERT(!%s);", env_->LValue(analyzer_context_id));
GenNewDataUnit(out_cc);
out_cc->println("}");
out_cc->dec_indent();
@ -295,8 +271,7 @@ void FlowDecl::GenCodeFlowUnit(Output *out_cc)
DataPtr data(env_, 0, 0);
unit_datatype->GenParseCode(out_cc, env_, data, 0);
out_cc->println("if ( %s )",
unit_datatype->parsing_complete(env_).c_str());
out_cc->println("if ( %s )", unit_datatype->parsing_complete(env_).c_str());
out_cc->inc_indent();
out_cc->println("{");
out_cc->println("// Clean up the flow unit after parsing");
@ -308,8 +283,7 @@ void FlowDecl::GenCodeFlowUnit(Output *out_cc)
out_cc->inc_indent();
out_cc->println("{");
out_cc->println("// Resume upon next input segment");
out_cc->println("BINPAC_ASSERT(!%s->ready());",
env_->RValue(flow_buffer_id));
out_cc->println("BINPAC_ASSERT(!%s->ready());", env_->RValue(flow_buffer_id));
out_cc->println("break;");
out_cc->println("}");
out_cc->dec_indent();
@ -318,14 +292,12 @@ void FlowDecl::GenCodeFlowUnit(Output *out_cc)
out_cc->dec_indent();
}
void FlowDecl::GenCodeDatagram(Output *out_cc)
void FlowDecl::GenCodeDatagram(Output* out_cc)
{
Type *unit_datatype = dataunit_->data_type();
Type* unit_datatype = dataunit_->data_type();
GenNewDataUnit(out_cc);
string parse_params = strfmt("%s, %s",
env_->RValue(begin_of_data),
env_->RValue(end_of_data));
string parse_params = strfmt("%s, %s", env_->RValue(begin_of_data), env_->RValue(end_of_data));
if ( RequiresAnalyzerContext::compute(unit_datatype) )
{

View file

@ -4,44 +4,44 @@
#include "pac_analyzer.h"
class FlowDecl : public AnalyzerDecl
{
{
public:
FlowDecl(ID *flow_id, ParamList *params, AnalyzerElementList *elemlist);
FlowDecl(ID* flow_id, ParamList* params, AnalyzerElementList* elemlist);
~FlowDecl();
void Prepare();
void set_conn_decl(ConnDecl *c) { conn_decl_ = c; }
void set_conn_decl(ConnDecl* c) { conn_decl_ = c; }
static ParameterizedType *flow_buffer_type();
static ParameterizedType* flow_buffer_type();
protected:
void AddBaseClass(vector<string> *base_classes) const;
void AddBaseClass(vector<string>* base_classes) const;
void GenInitCode(Output *out_cc);
void GenCleanUpCode(Output *out_cc);
void GenProcessFunc(Output *out_h, Output *out_cc);
void GenEOFFunc(Output *out_h, Output *out_cc);
void GenGapFunc(Output *out_h, Output *out_cc);
void GenInitCode(Output* out_cc);
void GenCleanUpCode(Output* out_cc);
void GenProcessFunc(Output* out_h, Output* out_cc);
void GenEOFFunc(Output* out_h, Output* out_cc);
void GenGapFunc(Output* out_h, Output* out_cc);
void GenPubDecls(Output *out_h, Output *out_cc);
void GenPrivDecls(Output *out_h, Output *out_cc);
void GenPubDecls(Output* out_h, Output* out_cc);
void GenPrivDecls(Output* out_h, Output* out_cc);
void ProcessFlowElement(AnalyzerFlow *flow_elem);
void ProcessDataUnitElement(AnalyzerDataUnit *dataunit_elem);
void ProcessFlowElement(AnalyzerFlow* flow_elem);
void ProcessDataUnitElement(AnalyzerDataUnit* dataunit_elem);
private:
void GenNewDataUnit(Output *out_cc);
void GenDeleteDataUnit(Output *out_cc);
void GenCodeFlowUnit(Output *out_cc);
void GenCodeDatagram(Output *out_cc);
void GenNewDataUnit(Output* out_cc);
void GenDeleteDataUnit(Output* out_cc);
void GenCodeFlowUnit(Output* out_cc);
void GenCodeDatagram(Output* out_cc);
AnalyzerDataUnit *dataunit_;
ConnDecl *conn_decl_;
AnalyzerDataUnit* dataunit_;
ConnDecl* conn_decl_;
Field *flow_buffer_var_field_;
Field* flow_buffer_var_field_;
static ParameterizedType *flow_buffer_type_;
};
static ParameterizedType* flow_buffer_type_;
};
#endif // pac_flow_h
#endif // pac_flow_h

View file

@ -1,12 +1,13 @@
#include "pac_func.h"
#include "pac_embedded.h"
#include "pac_expr.h"
#include "pac_func.h"
#include "pac_output.h"
#include "pac_param.h"
#include "pac_type.h"
Function::Function(ID *id, Type *type, ParamList *params)
: id_(id), type_(type), params_(params), expr_(0), code_(0)
Function::Function(ID* id, Type* type, ParamList* params)
: id_(id), type_(type), params_(params), expr_(0), code_(0)
{
analyzer_decl_ = 0;
env_ = 0;
@ -22,16 +23,16 @@ Function::~Function()
delete code_;
}
void Function::Prepare(Env *env)
void Function::Prepare(Env* env)
{
env->AddID(id_, FUNC_ID, type_);
env->SetEvaluated(id_);
env_ = new Env(env, this);
foreach(i, ParamList, params_)
foreach (i, ParamList, params_)
{
Param *p = *i;
Param* p = *i;
env_->AddID(p->id(), FUNC_PARAM, p->type());
env_->SetEvaluated(p->id());
}
@ -44,22 +45,17 @@ void Function::GenForwardDeclaration(Output* out_h)
void Function::GenCode(Output* out_h, Output* out_cc)
{
out_h->println("%s %s(%s);",
type_->DataTypeStr().c_str(),
id_->Name(),
ParamDecls(params_).c_str());
out_h->println("%s %s(%s);", type_->DataTypeStr().c_str(), id_->Name(),
ParamDecls(params_).c_str());
string class_str = "";
if ( analyzer_decl_ )
class_str = strfmt("%s::", analyzer_decl_->id()->Name());
string proto_str = strfmt("%s %s%s(%s)",
type_->DataTypeStr().c_str(),
class_str.c_str(),
id_->Name(),
ParamDecls(params_).c_str());
string proto_str = strfmt("%s %s%s(%s)", type_->DataTypeStr().c_str(), class_str.c_str(),
id_->Name(), ParamDecls(params_).c_str());
ASSERT(!(expr_ && code_));
ASSERT(! (expr_ && code_));
if ( expr_ )
{
@ -68,9 +64,8 @@ void Function::GenCode(Output* out_h, Output* out_cc)
out_cc->inc_indent();
out_cc->println("{");
out_cc->println("return static_cast<%s>(%s);",
type_->DataTypeStr().c_str(),
expr_->EvalExpr(out_cc, env_));
out_cc->println("return static_cast<%s>(%s);", type_->DataTypeStr().c_str(),
expr_->EvalExpr(out_cc, env_));
out_cc->println("}");
out_cc->dec_indent();
@ -92,8 +87,7 @@ void Function::GenCode(Output* out_h, Output* out_cc)
out_cc->println("");
}
FuncDecl::FuncDecl(Function *function)
: Decl(function->id()->clone(), FUNC), function_(function)
FuncDecl::FuncDecl(Function* function) : Decl(function->id()->clone(), FUNC), function_(function)
{
function_->Prepare(global_env());
}
@ -103,21 +97,19 @@ FuncDecl::~FuncDecl()
delete function_;
}
void FuncDecl::Prepare()
{
}
void FuncDecl::Prepare() { }
void FuncDecl::GenForwardDeclaration(Output *out_h)
void FuncDecl::GenForwardDeclaration(Output* out_h)
{
function_->GenForwardDeclaration(out_h);
}
void FuncDecl::GenCode(Output *out_h, Output *out_cc)
void FuncDecl::GenCode(Output* out_h, Output* out_cc)
{
function_->GenCode(out_h, out_cc);
}
AnalyzerFunction::AnalyzerFunction(Function *function)
AnalyzerFunction::AnalyzerFunction(Function* function)
: AnalyzerElement(FUNCTION), function_(function)
{
}

View file

@ -1,68 +1,68 @@
#ifndef pac_func_h
#define pac_func_h
#include "pac_decl.h"
#include "pac_analyzer.h"
#include "pac_decl.h"
class Function : public Object
{
{
public:
Function(ID *id, Type *type, ParamList *params);
Function(ID* id, Type* type, ParamList* params);
~Function();
ID *id() const { return id_; }
ID* id() const { return id_; }
AnalyzerDecl *analyzer_decl() const { return analyzer_decl_; }
void set_analyzer_decl(AnalyzerDecl *decl) { analyzer_decl_ = decl; }
AnalyzerDecl* analyzer_decl() const { return analyzer_decl_; }
void set_analyzer_decl(AnalyzerDecl* decl) { analyzer_decl_ = decl; }
Expr *expr() const { return expr_; }
void set_expr(Expr *expr) { expr_ = expr; }
Expr* expr() const { return expr_; }
void set_expr(Expr* expr) { expr_ = expr; }
EmbeddedCode *code() const { return code_; }
void set_code(EmbeddedCode *code) { code_ = code; }
EmbeddedCode* code() const { return code_; }
void set_code(EmbeddedCode* code) { code_ = code; }
void Prepare(Env *env);
void GenForwardDeclaration(Output *out_h);
void GenCode(Output *out_h, Output *out_cc);
void Prepare(Env* env);
void GenForwardDeclaration(Output* out_h);
void GenCode(Output* out_h, Output* out_cc);
private:
Env *env_;
Env* env_;
ID *id_;
Type *type_;
ParamList *params_;
ID* id_;
Type* type_;
ParamList* params_;
AnalyzerDecl *analyzer_decl_;
AnalyzerDecl* analyzer_decl_;
Expr *expr_;
EmbeddedCode *code_;
};
Expr* expr_;
EmbeddedCode* code_;
};
class FuncDecl : public Decl
{
{
public:
FuncDecl(Function *function);
FuncDecl(Function* function);
~FuncDecl();
Function *function() const { return function_; }
Function* function() const { return function_; }
void Prepare();
void GenForwardDeclaration(Output *out_h);
void GenCode(Output *out_h, Output *out_cc);
void GenForwardDeclaration(Output* out_h);
void GenCode(Output* out_h, Output* out_cc);
private:
Function *function_;
};
Function* function_;
};
class AnalyzerFunction : public AnalyzerElement
{
{
public:
AnalyzerFunction(Function *function);
AnalyzerFunction(Function* function);
Function *function() const { return function_; }
Function* function() const { return function_; }
private:
Function *function_;
};
Function* function_;
};
#endif // pac_func_h

View file

@ -1,56 +1,57 @@
#include "pac_id.h"
#include "pac_exception.h"
#include "pac_expr.h"
#include "pac_exttype.h"
#include "pac_field.h"
#include "pac_id.h"
#include "pac_type.h"
#include "pac_utils.h"
const ID *default_value_var = 0;
const ID *null_id = 0;
const ID *null_byteseg_id = 0;
const ID *null_decl_id = 0;
const ID *begin_of_data = 0;
const ID *end_of_data = 0;
const ID *len_of_data = 0;
const ID *byteorder_id = 0;
const ID *bigendian_id = 0;
const ID *littleendian_id = 0;
const ID *unspecified_byteorder_id = 0;
const ID *const_true_id = 0;
const ID *const_false_id = 0;
const ID *analyzer_context_id = 0;
const ID *context_macro_id = 0;
const ID *this_id = 0;
const ID *sourcedata_id = 0;
const ID *connection_id = 0;
const ID *upflow_id = 0;
const ID *downflow_id = 0;
const ID *dataunit_id = 0;
const ID *flow_buffer_id = 0;
const ID *element_macro_id = 0;
const ID *input_macro_id = 0;
const ID *cxt_connection_id = 0;
const ID *cxt_flow_id = 0;
const ID *parsing_state_id = 0;
const ID *buffering_state_id = 0;
const ID* default_value_var = 0;
const ID* null_id = 0;
const ID* null_byteseg_id = 0;
const ID* null_decl_id = 0;
const ID* begin_of_data = 0;
const ID* end_of_data = 0;
const ID* len_of_data = 0;
const ID* byteorder_id = 0;
const ID* bigendian_id = 0;
const ID* littleendian_id = 0;
const ID* unspecified_byteorder_id = 0;
const ID* const_true_id = 0;
const ID* const_false_id = 0;
const ID* analyzer_context_id = 0;
const ID* context_macro_id = 0;
const ID* this_id = 0;
const ID* sourcedata_id = 0;
const ID* connection_id = 0;
const ID* upflow_id = 0;
const ID* downflow_id = 0;
const ID* dataunit_id = 0;
const ID* flow_buffer_id = 0;
const ID* element_macro_id = 0;
const ID* input_macro_id = 0;
const ID* cxt_connection_id = 0;
const ID* cxt_flow_id = 0;
const ID* parsing_state_id = 0;
const ID* buffering_state_id = 0;
int ID::anonymous_id_seq = 0;
ID *ID::NewAnonymousID(const string &prefix)
ID* ID::NewAnonymousID(const string& prefix)
{
ID *id = new ID(strfmt("%s%03d", prefix.c_str(), ++anonymous_id_seq));
ID* id = new ID(strfmt("%s%03d", prefix.c_str(), ++anonymous_id_seq));
id->anonymous_id_ = true;
return id;
}
IDRecord::IDRecord(Env *arg_env, const ID* arg_id, IDType arg_id_type)
IDRecord::IDRecord(Env* arg_env, const ID* arg_id, IDType arg_id_type)
: env(arg_env), id(arg_id), id_type(arg_id_type)
{
eval = 0;
evaluated = in_evaluation = false;
setfunc = ""; // except for STATE_VAR
switch (id_type)
setfunc = ""; // except for STATE_VAR
switch ( id_type )
{
case MEMBER_VAR:
rvalue = strfmt("%s()", id->Name());
@ -96,9 +97,7 @@ IDRecord::IDRecord(Env *arg_env, const ID* arg_id, IDType arg_id_type)
macro = 0;
}
IDRecord::~IDRecord()
{
}
IDRecord::~IDRecord() { }
void IDRecord::SetConstant(int c)
{
@ -107,20 +106,20 @@ void IDRecord::SetConstant(int c)
constant = c;
}
bool IDRecord::GetConstant(int *pc) const
bool IDRecord::GetConstant(int* pc) const
{
if ( constant_set )
*pc = constant;
return constant_set;
}
void IDRecord::SetMacro(Expr *e)
void IDRecord::SetMacro(Expr* e)
{
ASSERT(id_type == MACRO);
macro = e;
}
Expr *IDRecord::GetMacro() const
Expr* IDRecord::GetMacro() const
{
ASSERT(id_type == MACRO);
return macro;
@ -187,7 +186,7 @@ Env::~Env()
}
}
void Env::AddID(const ID* id, IDType id_type, Type *data_type)
void Env::AddID(const ID* id, IDType id_type, Type* data_type)
{
DEBUG_MSG("To add ID `%s'...\n", id->Name());
id_map_t::iterator it = id_map.find(id);
@ -202,25 +201,25 @@ void Env::AddID(const ID* id, IDType id_type, Type *data_type)
SetDataType(id, data_type);
}
void Env::AddConstID(const ID* id, const int c, Type *type)
void Env::AddConstID(const ID* id, const int c, Type* type)
{
if ( ! type )
type = extern_type_int;
AddID(id, CONST, type);
SetConstant(id, c);
SetEvaluated(id); // a constant is always evaluated
SetEvaluated(id); // a constant is always evaluated
}
void Env::AddMacro(const ID *id, Expr *macro)
void Env::AddMacro(const ID* id, Expr* macro)
{
AddID(id, MACRO, macro->DataType(this));
SetMacro(id, macro);
SetEvaluated(id);
}
ID *Env::AddTempID(Type *type)
ID* Env::AddTempID(Type* type)
{
ID *id = ID::NewAnonymousID("t_var_");
ID* id = ID::NewAnonymousID("t_var_");
AddID(id, TEMP_VAR, type);
return id;
}
@ -249,7 +248,7 @@ IDType Env::GetIDType(const ID* id) const
const char* Env::RValue(const ID* id) const
{
IDRecord *r = lookup(id, true, false);
IDRecord* r = lookup(id, true, false);
if ( r )
return r->RValue();
else
@ -273,14 +272,14 @@ void Env::SetEvalMethod(const ID* id, Evaluatable* eval)
void Env::Evaluate(Output* out, const ID* id)
{
IDRecord *r = lookup(id, true, !allow_undefined_id());
IDRecord* r = lookup(id, true, ! allow_undefined_id());
if ( r )
r->Evaluate(out, this);
}
bool Env::Evaluated(const ID* id) const
{
IDRecord *r = lookup(id, true, !allow_undefined_id());
IDRecord* r = lookup(id, true, ! allow_undefined_id());
if ( r )
return r->Evaluated();
else
@ -292,23 +291,20 @@ void Env::SetEvaluated(const ID* id, bool v)
{
if ( in_branch() )
{
Field *f = GetField(id);
if (f && f->tof() == LET_FIELD)
Field* f = GetField(id);
if ( f && f->tof() == LET_FIELD )
{
throw Exception(
context_object_,
strfmt("INTERNAL ERROR: "
"evaluating let field '%s' in a branch! "
"To work around this problem, "
"add '&requires(%s)' to the case type. "
"Sorry for the inconvenience.\n",
id->Name(),
id->Name()));
throw Exception(context_object_, strfmt("INTERNAL ERROR: "
"evaluating let field '%s' in a branch! "
"To work around this problem, "
"add '&requires(%s)' to the case type. "
"Sorry for the inconvenience.\n",
id->Name(), id->Name()));
ASSERT(0);
}
}
IDRecord *r = lookup(id, false, false);
IDRecord* r = lookup(id, false, false);
if ( r )
r->SetEvaluated(v);
else if ( parent )
@ -334,16 +330,16 @@ void Env::SetDataType(const ID* id, Type* type)
Type* Env::GetDataType(const ID* id) const
{
IDRecord *r = lookup(id, true, false);
IDRecord* r = lookup(id, true, false);
if ( r )
return r->GetDataType();
else
return 0;
}
string Env::DataTypeStr(const ID *id) const
string Env::DataTypeStr(const ID* id) const
{
Type *type = GetDataType(id);
Type* type = GetDataType(id);
if ( ! type )
throw Exception(id, "data type not defined");
return type->DataTypeStr();
@ -365,7 +361,7 @@ bool Env::GetConstant(const ID* id, int* pc) const
return false;
}
void Env::SetMacro(const ID* id, Expr *macro)
void Env::SetMacro(const ID* id, Expr* macro)
{
lookup(id, true, true)->SetMacro(macro);
}
@ -409,7 +405,7 @@ void init_builtin_identifiers()
Env* global_env()
{
static Env *the_global_env = 0;
static Env* the_global_env = 0;
if ( ! the_global_env )
{
@ -436,7 +432,7 @@ Env* global_env()
return the_global_env;
}
string set_function(const ID *id)
string set_function(const ID* id)
{
return strfmt("set_%s", id->Name());
}

View file

@ -22,7 +22,8 @@ using namespace std;
// Env -- a mapping from ID names to their L/R-value expressions and evaluation
// methods.
enum IDType {
enum IDType
{
CONST,
GLOBAL_VAR,
TEMP_VAR,
@ -33,7 +34,7 @@ enum IDType {
MACRO,
FUNC_ID,
FUNC_PARAM,
};
};
class ID;
class IDRecord;
@ -41,206 +42,201 @@ class Env;
class Evaluatable;
class ID : public Object
{
{
public:
ID(string arg_name)
: name(arg_name), anonymous_id_(false)
ID(string arg_name) : name(arg_name), anonymous_id_(false)
{
locname = nfmt("%s:%s", Location(), Name());
}
~ID()
{
delete [] locname;
}
~ID() { delete[] locname; }
bool operator==(ID const &x) const { return name == x.Name(); }
bool operator==(ID const& x) const { return name == x.Name(); }
const char *Name() const { return name.c_str(); }
const char *LocName() const { return locname; }
bool is_anonymous() const { return anonymous_id_; }
const char* Name() const { return name.c_str(); }
const char* LocName() const { return locname; }
bool is_anonymous() const { return anonymous_id_; }
ID *clone() const { return new ID(Name()); }
ID* clone() const { return new ID(Name()); }
protected:
string name;
bool anonymous_id_;
char *locname;
char* locname;
friend class ID_ptr_cmp;
public:
static ID *NewAnonymousID(const string &prefix);
static ID* NewAnonymousID(const string& prefix);
private:
static int anonymous_id_seq;
};
};
// A comparison operator for pointers to ID's.
class ID_ptr_cmp
{
{
public:
bool operator()(const ID *const & id1, const ID *const & id2) const
bool operator()(const ID* const& id1, const ID* const& id2) const
{
ASSERT(id1);
ASSERT(id2);
return id1->name < id2->name;
}
};
};
class IDRecord
{
{
public:
IDRecord(Env *env, const ID *id, IDType id_type);
IDRecord(Env* env, const ID* id, IDType id_type);
~IDRecord();
IDType GetType() const { return id_type; }
IDType GetType() const { return id_type; }
void SetDataType(Type *type) { data_type = type; }
Type *GetDataType() const { return data_type; }
void SetDataType(Type* type) { data_type = type; }
Type* GetDataType() const { return data_type; }
void SetEvalMethod(Evaluatable *arg_eval) { eval = arg_eval; }
void Evaluate(Output *out, Env *env);
void SetEvalMethod(Evaluatable* arg_eval) { eval = arg_eval; }
void Evaluate(Output* out, Env* env);
void SetEvaluated(bool v);
bool Evaluated() const { return evaluated; }
bool Evaluated() const { return evaluated; }
void SetField(Field *f) { field = f; }
Field *GetField() const { return field; }
void SetField(Field* f) { field = f; }
Field* GetField() const { return field; }
void SetConstant(int c);
bool GetConstant(int *pc) const;
bool GetConstant(int* pc) const;
void SetMacro(Expr *expr);
Expr *GetMacro() const;
void SetMacro(Expr* expr);
Expr* GetMacro() const;
const char * RValue() const;
const char * LValue() const;
const char* RValue() const;
const char* LValue() const;
protected:
Env *env;
const ID *id;
Env* env;
const ID* id;
IDType id_type;
string rvalue;
string lvalue;
string setfunc;
Type *data_type;
Type* data_type;
Field *field;
Field* field;
int constant;
bool constant_set;
Expr *macro;
Expr* macro;
bool evaluated;
bool in_evaluation; // to detect cyclic dependence
Evaluatable *eval;
};
bool in_evaluation; // to detect cyclic dependence
Evaluatable* eval;
};
class Evaluatable
{
{
public:
virtual ~Evaluatable() {}
virtual void GenEval(Output *out, Env *env) = 0;
};
virtual ~Evaluatable() { }
virtual void GenEval(Output* out, Env* env) = 0;
};
class Env
{
{
public:
Env(Env *parent_env, Object *context_object);
Env(Env* parent_env, Object* context_object);
~Env();
bool allow_undefined_id() const { return allow_undefined_id_; }
void set_allow_undefined_id(bool x) { allow_undefined_id_ = x; }
bool allow_undefined_id() const { return allow_undefined_id_; }
void set_allow_undefined_id(bool x) { allow_undefined_id_ = x; }
bool in_branch() const { return in_branch_; }
void set_in_branch(bool x) { in_branch_ = x; }
bool in_branch() const { return in_branch_; }
void set_in_branch(bool x) { in_branch_ = x; }
void AddID(const ID *id, IDType id_type, Type *type);
void AddConstID(const ID *id, const int c, Type *type = 0);
void AddMacro(const ID *id, Expr *expr);
void AddID(const ID* id, IDType id_type, Type* type);
void AddConstID(const ID* id, const int c, Type* type = 0);
void AddMacro(const ID* id, Expr* expr);
// Generate a temp ID with a unique name
ID *AddTempID(Type *type);
ID* AddTempID(Type* type);
IDType GetIDType(const ID *id) const;
const char * RValue(const ID *id) const;
const char * LValue(const ID *id) const;
IDType GetIDType(const ID* id) const;
const char* RValue(const ID* id) const;
const char* LValue(const ID* id) const;
// const char *SetFunc(const ID *id) const;
// Set evaluation method for the ID
void SetEvalMethod(const ID *id, Evaluatable *eval);
void SetEvalMethod(const ID* id, Evaluatable* eval);
// Evaluate the ID according to the evaluation method. It
// assumes the ID has an evaluation emthod. It does nothing
// if the ID has already been evaluated.
void Evaluate(Output *out, const ID *id);
void Evaluate(Output* out, const ID* id);
// Whether the ID has already been evaluated.
bool Evaluated(const ID *id) const;
bool Evaluated(const ID* id) const;
// Set the ID as evaluated (or not).
void SetEvaluated(const ID *id, bool v = true);
void SetEvaluated(const ID* id, bool v = true);
void SetField(const ID *id, Field *field);
Field *GetField(const ID *id) const;
void SetField(const ID* id, Field* field);
Field* GetField(const ID* id) const;
bool GetConstant(const ID *id, int *pc) const;
bool GetConstant(const ID* id, int* pc) const;
Expr *GetMacro(const ID *id) const;
Expr* GetMacro(const ID* id) const;
Type *GetDataType(const ID *id) const;
Type* GetDataType(const ID* id) const;
string DataTypeStr(const ID *id) const;
string DataTypeStr(const ID* id) const;
protected:
IDRecord *lookup(const ID *id,
bool recursive,
bool raise_exception) const;
IDRecord* lookup(const ID* id, bool recursive, bool raise_exception) const;
void SetDataType(const ID *id, Type *type);
void SetConstant(const ID *id, int constant);
void SetMacro(const ID *id, Expr *macro);
void SetDataType(const ID* id, Type* type);
void SetConstant(const ID* id, int constant);
void SetMacro(const ID* id, Expr* macro);
private:
Env *parent;
Object *context_object_;
Env* parent;
Object* context_object_;
typedef map<const ID*, IDRecord*, ID_ptr_cmp> id_map_t;
id_map_t id_map;
bool allow_undefined_id_;
bool in_branch_;
};
};
extern const ID *default_value_var;
extern const ID *null_id;
extern const ID *null_byteseg_id;
extern const ID *begin_of_data;
extern const ID *end_of_data;
extern const ID *len_of_data;
extern const ID *byteorder_id;
extern const ID *bigendian_id;
extern const ID *littleendian_id;
extern const ID *unspecified_byteorder_id;
extern const ID *analyzer_context_id;
extern const ID *context_macro_id;
extern const ID *this_id;
extern const ID *sourcedata_id;
extern const ID* default_value_var;
extern const ID* null_id;
extern const ID* null_byteseg_id;
extern const ID* begin_of_data;
extern const ID* end_of_data;
extern const ID* len_of_data;
extern const ID* byteorder_id;
extern const ID* bigendian_id;
extern const ID* littleendian_id;
extern const ID* unspecified_byteorder_id;
extern const ID* analyzer_context_id;
extern const ID* context_macro_id;
extern const ID* this_id;
extern const ID* sourcedata_id;
// extern const ID *sourcedata_begin_id;
// extern const ID *sourcedata_end_id;
extern const ID *connection_id;
extern const ID *upflow_id;
extern const ID *downflow_id;
extern const ID *dataunit_id;
extern const ID *flow_buffer_id;
extern const ID *element_macro_id;
extern const ID *cxt_connection_id;
extern const ID *cxt_flow_id;
extern const ID *input_macro_id;
extern const ID *parsing_state_id;
extern const ID *buffering_state_id;
extern const ID* connection_id;
extern const ID* upflow_id;
extern const ID* downflow_id;
extern const ID* dataunit_id;
extern const ID* flow_buffer_id;
extern const ID* element_macro_id;
extern const ID* cxt_connection_id;
extern const ID* cxt_flow_id;
extern const ID* input_macro_id;
extern const ID* parsing_state_id;
extern const ID* buffering_state_id;
extern void init_builtin_identifiers();
extern Env *global_env();
extern Env* global_env();
extern string set_function(const ID *id);
extern string set_function(const ID* id);
#endif // pac_id_h

View file

@ -1,16 +1,14 @@
#include "pac_inputbuf.h"
#include "pac_expr.h"
#include "pac_exttype.h"
#include "pac_id.h"
#include "pac_inputbuf.h"
#include "pac_output.h"
#include "pac_type.h"
InputBuffer::InputBuffer(Expr *expr)
: DataDepElement(INPUT_BUFFER), expr_(expr)
{
}
InputBuffer::InputBuffer(Expr* expr) : DataDepElement(INPUT_BUFFER), expr_(expr) { }
bool InputBuffer::DoTraverse(DataDepVisitor *visitor)
bool InputBuffer::DoTraverse(DataDepVisitor* visitor)
{
if ( expr_ && ! expr_->Traverse(visitor) )
return false;
@ -22,20 +20,16 @@ bool InputBuffer::RequiresAnalyzerContext() const
return expr_->RequiresAnalyzerContext();
}
DataPtr InputBuffer::GenDataBeginEnd(Output *out_cc, Env *env)
DataPtr InputBuffer::GenDataBeginEnd(Output* out_cc, Env* env)
{
env->AddID(begin_of_data, TEMP_VAR, extern_type_const_byteptr);
env->AddID(end_of_data, TEMP_VAR, extern_type_const_byteptr);
out_cc->println("%s %s, %s;",
extern_type_const_byteptr->DataTypeStr().c_str(),
env->LValue(begin_of_data),
env->LValue(end_of_data));
out_cc->println("%s %s, %s;", extern_type_const_byteptr->DataTypeStr().c_str(),
env->LValue(begin_of_data), env->LValue(end_of_data));
out_cc->println("get_pointers(%s, &%s, &%s);",
expr_->EvalExpr(out_cc, env),
env->LValue(begin_of_data),
env->LValue(end_of_data));
out_cc->println("get_pointers(%s, &%s, &%s);", expr_->EvalExpr(out_cc, env),
env->LValue(begin_of_data), env->LValue(end_of_data));
env->SetEvaluated(begin_of_data);
env->SetEvaluated(end_of_data);

View file

@ -7,18 +7,18 @@
class Expr;
class InputBuffer : public Object, public DataDepElement
{
{
public:
InputBuffer(Expr *expr);
InputBuffer(Expr* expr);
bool RequiresAnalyzerContext() const;
DataPtr GenDataBeginEnd(Output *out_cc, Env *env);
DataPtr GenDataBeginEnd(Output* out_cc, Env* env);
protected:
bool DoTraverse(DataDepVisitor *visitor);
bool DoTraverse(DataDepVisitor* visitor);
private:
Expr *expr_;
};
Expr* expr_;
};
#endif // pac_inputbuf_h

View file

@ -1,21 +1,19 @@
#include "pac_let.h"
#include "pac_expr.h"
#include "pac_exttype.h"
#include "pac_let.h"
#include "pac_output.h"
#include "pac_type.h"
namespace {
void GenLetEval(const ID *id, Expr *expr, string prefix, Output* out, Env* env)
namespace
{
}
} // private namespace
void GenLetEval(const ID* id, Expr* expr, string prefix, Output* out, Env* env) { }
LetField::LetField(ID* id, Type *type, Expr* expr)
: Field(LET_FIELD,
TYPE_NOT_TO_BE_PARSED | CLASS_MEMBER | PUBLIC_READABLE,
id, type),
} // private namespace
LetField::LetField(ID* id, Type* type, Expr* expr)
: Field(LET_FIELD, TYPE_NOT_TO_BE_PARSED | CLASS_MEMBER | PUBLIC_READABLE, id, type),
expr_(expr)
{
ASSERT(expr_);
@ -26,16 +24,14 @@ LetField::~LetField()
delete expr_;
}
bool LetField::DoTraverse(DataDepVisitor *visitor)
bool LetField::DoTraverse(DataDepVisitor* visitor)
{
return Field::DoTraverse(visitor) &&
expr()->Traverse(visitor);
return Field::DoTraverse(visitor) && expr()->Traverse(visitor);
}
bool LetField::RequiresAnalyzerContext() const
{
return Field::RequiresAnalyzerContext() ||
(expr() && expr()->RequiresAnalyzerContext());
return Field::RequiresAnalyzerContext() || (expr() && expr()->RequiresAnalyzerContext());
}
void LetField::Prepare(Env* env)
@ -49,7 +45,7 @@ void LetField::Prepare(Env* env)
else
type_ = extern_type_int->Clone();
foreach(i, AttrList, attrs_)
foreach (i, AttrList, attrs_)
ProcessAttr(*i);
}
@ -83,15 +79,12 @@ void LetField::GenParseCode(Output* out_cc, Env* env)
// force evaluation of IDs contained in this expr
expr()->ForceIDEval(out_cc, env);
out_cc->println("if ( %s )",
env->RValue(type_->has_value_var()));
out_cc->println("if ( %s )", env->RValue(type_->has_value_var()));
out_cc->inc_indent();
out_cc->println("{");
}
out_cc->println("%s = %s;",
env->LValue(id_),
expr()->EvalExpr(out_cc, env));
out_cc->println("%s = %s;", env->LValue(id_), expr()->EvalExpr(out_cc, env));
if ( ! env->Evaluated(id_) )
env->SetEvaluated(id_);
@ -107,20 +100,19 @@ void LetField::GenEval(Output* out_cc, Env* env)
GenParseCode(out_cc, env);
}
LetDecl::LetDecl(ID *id, Type *type, Expr *expr)
: Decl(id, LET), type_(type), expr_(expr)
LetDecl::LetDecl(ID* id, Type* type, Expr* expr) : Decl(id, LET), type_(type), expr_(expr)
{
if ( ! type_ )
{
ASSERT(expr_);
type_ = expr_->DataType(global_env());
type_ = expr_->DataType(global_env());
if ( type_ )
type_ = type_->Clone();
else
type_ = extern_type_int->Clone();
}
Env *env = global_env();
Env* env = global_env();
int c;
if ( expr_ && expr_->ConstFold(env, &c) )
env->AddConstID(id_, c, type);
@ -134,30 +126,21 @@ LetDecl::~LetDecl()
delete expr_;
}
void LetDecl::Prepare()
{
}
void LetDecl::Prepare() { }
void LetDecl::GenForwardDeclaration(Output* out_h)
{
}
void LetDecl::GenForwardDeclaration(Output* out_h) { }
void LetDecl::GenCode(Output * out_h, Output *out_cc)
void LetDecl::GenCode(Output* out_h, Output* out_cc)
{
out_h->println("extern %s const %s;",
type_->DataTypeStr().c_str(),
global_env()->RValue(id_));
out_h->println("extern %s const %s;", type_->DataTypeStr().c_str(), global_env()->RValue(id_));
GenEval(out_cc, global_env());
}
void LetDecl::GenEval(Output *out_cc, Env * /* env */)
void LetDecl::GenEval(Output* out_cc, Env* /* env */)
{
Env *env = global_env();
Env* env = global_env();
string tmp = strfmt("%s const", type_->DataTypeStr().c_str());
out_cc->println("%s %s = %s;",
tmp.c_str(),
env->LValue(id_),
expr_->EvalExpr(out_cc, env));
out_cc->println("%s %s = %s;", tmp.c_str(), env->LValue(id_), expr_->EvalExpr(out_cc, env));
if ( ! env->Evaluated(id_) )
env->SetEvaluated(id_);

View file

@ -5,12 +5,12 @@
#include "pac_field.h"
class LetField : public Field, Evaluatable
{
{
public:
LetField(ID* arg_id, Type *type, Expr* arg_expr);
LetField(ID* arg_id, Type* type, Expr* arg_expr);
~LetField();
Expr *expr() const { return expr_; }
Expr* expr() const { return expr_; }
void Prepare(Env* env);
@ -21,28 +21,28 @@ public:
bool RequiresAnalyzerContext() const;
protected:
bool DoTraverse(DataDepVisitor *visitor);
bool DoTraverse(DataDepVisitor* visitor);
protected:
Expr* expr_;
};
};
class LetDecl : public Decl, Evaluatable
{
{
public:
LetDecl(ID *id, Type *type, Expr *expr);
LetDecl(ID* id, Type* type, Expr* expr);
~LetDecl();
Expr *expr() const { return expr_; }
Expr* expr() const { return expr_; }
void Prepare();
void GenForwardDeclaration(Output *out_h);
void GenCode(Output *out_h, Output *out_cc);
void GenForwardDeclaration(Output* out_h);
void GenCode(Output* out_h, Output* out_cc);
void GenEval(Output* out, Env* env);
private:
Type *type_;
Expr *expr_;
};
Type* type_;
Expr* expr_;
};
#endif // pac_let_h
#endif // pac_let_h

View file

@ -1,17 +1,16 @@
#include <unistd.h>
#include <ctype.h>
#include <unistd.h>
#include "config.h"
#include "pac_common.h"
#include "pac_decl.h"
#include "pac_exception.h"
#include "pac_exttype.h"
#include "pac_id.h"
#include "pac_output.h"
#include "pac_parse.h"
#include "pac_type.h"
#include "pac_utils.h"
#include "pac_exception.h"
#include "config.h"
extern int yydebug;
extern int yyparse();
@ -31,7 +30,7 @@ void add_to_include_directories(string dirs)
unsigned int dir_begin = 0, dir_end;
while ( dir_begin < dirs.length() )
{
for ( dir_end = dir_begin; dir_end < dirs.length(); ++dir_end)
for ( dir_end = dir_begin; dir_end < dirs.length(); ++dir_end )
if ( dirs[dir_end] == ':' )
break;
@ -54,8 +53,7 @@ void pac_init()
void insert_comments(Output* out, const char* source_filename)
{
out->println("// This file is automatically generated from %s.\n",
source_filename);
out->println("// This file is automatically generated from %s.\n", source_filename);
}
void insert_basictype_defs(Output* out)
@ -90,7 +88,7 @@ const char* to_id(const char* s)
{
static char t[1024];
int i;
for ( i = 0; s[i] && i < (int) sizeof(t) - 1; ++i )
for ( i = 0; s[i] && i < (int)sizeof(t) - 1; ++i )
t[i] = isalnum(s[i]) ? s[i] : '_';
if ( isdigit(t[0]) )
t[0] = '_';
@ -114,7 +112,7 @@ int compile(const char* filename)
if ( ! FLAGS_output_directory.empty() )
{
// Strip leading directories of filename
const char *last_slash = strrchr(filename, '/');
const char* last_slash = strrchr(filename, '/');
if ( last_slash )
basename = last_slash + 1;
else
@ -125,8 +123,7 @@ int compile(const char* filename)
basename = filename;
// If the file name ends with ".pac"
if ( basename.length() > 4 &&
basename.substr(basename.length() - 4) == ".pac" )
if ( basename.length() > 4 && basename.substr(basename.length() - 4) == ".pac" )
{
basename = basename.substr(0, basename.length() - 4);
}
@ -176,8 +173,7 @@ int compile(const char* filename)
}
catch ( OutputException& e )
{
fprintf(stderr, "Error in compiling %s: %s\n",
filename, e.errmsg());
fprintf(stderr, "Error in compiling %s: %s\n", filename, e.errmsg());
ret = 1;
}
catch ( Exception& e )
@ -211,21 +207,21 @@ void usage()
// GCC uses __SANITIZE_ADDRESS__, Clang uses __has_feature
#if defined(__SANITIZE_ADDRESS__)
#define USING_ASAN
#define USING_ASAN
#endif
#if defined(__has_feature)
#if __has_feature(address_sanitizer)
#define USING_ASAN
#endif
#if __has_feature(address_sanitizer)
#define USING_ASAN
#endif
#endif
// FreeBSD doesn't support LeakSanitizer
#if defined(USING_ASAN) && !defined(__FreeBSD__)
#include <sanitizer/lsan_interface.h>
#define BINPAC_LSAN_DISABLE(x) __lsan_disable(x)
#if defined(USING_ASAN) && ! defined(__FreeBSD__)
#include <sanitizer/lsan_interface.h>
#define BINPAC_LSAN_DISABLE(x) __lsan_disable(x)
#else
#define BINPAC_LSAN_DISABLE(x)
#define BINPAC_LSAN_DISABLE(x)
#endif
int main(int argc, char* argv[])
@ -236,12 +232,12 @@ int main(int argc, char* argv[])
BINPAC_LSAN_DISABLE();
#ifdef HAVE_MALLOC_OPTIONS
extern char *malloc_options;
extern char* malloc_options;
#endif
int o;
while ( (o = getopt(argc, argv, "DqI:d:h")) != -1 )
{
switch(o)
switch ( o )
{
case 'D':
yydebug = 1;
@ -271,10 +267,9 @@ int main(int argc, char* argv[])
}
// Strip the trailing '/'s
while ( ! FLAGS_output_directory.empty() &&
*(FLAGS_output_directory.end() - 1) == '/' )
while ( ! FLAGS_output_directory.empty() && *(FLAGS_output_directory.end() - 1) == '/' )
{
FLAGS_output_directory.erase(FLAGS_output_directory.end()-1);
FLAGS_output_directory.erase(FLAGS_output_directory.end() - 1);
}
// Add the current directory to FLAGS_include_directories
@ -294,4 +289,3 @@ int main(int argc, char* argv[])
return ret;
}

View file

@ -4,18 +4,16 @@
#include "pac_common.h"
class Number : public Object
{
{
public:
Number(int arg_n)
: s(strfmt("%d", arg_n)), n(arg_n) {}
Number(const char* arg_s, int arg_n)
: s(arg_s), n(arg_n) {}
const char* Str() const { return s.c_str(); }
int Num() const { return n; }
Number(int arg_n) : s(strfmt("%d", arg_n)), n(arg_n) { }
Number(const char* arg_s, int arg_n) : s(arg_s), n(arg_n) { }
const char* Str() const { return s.c_str(); }
int Num() const { return n; }
protected:
const string s;
const int n;
};
};
#endif // pac_number_h
#endif // pac_number_h

View file

@ -1,19 +1,18 @@
#include <string.h>
#include "pac_output.h"
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include "pac_utils.h"
#include "pac_output.h"
OutputException::OutputException(const char* arg_msg)
{
msg = arg_msg;
}
OutputException::~OutputException()
{
}
OutputException::~OutputException() { }
Output::Output(string filename)
{

View file

@ -1,13 +1,14 @@
#ifndef pac_output_h
#define pac_output_h
#include <stdio.h>
#include <stdarg.h>
#include <stdio.h>
#include <string>
using namespace std;
class OutputException {
class OutputException
{
public:
OutputException(const char* arg_msg);
~OutputException();
@ -15,9 +16,10 @@ public:
protected:
string msg;
};
};
class Output {
class Output
{
public:
Output(string filename);
~Output();
@ -35,6 +37,6 @@ protected:
FILE* fp;
int indent_;
};
};
#endif /* pac_output_h */

View file

@ -1,3 +1,5 @@
#include "pac_param.h"
#include "pac_decl.h"
#include "pac_exttype.h"
#include "pac_field.h"
@ -6,61 +8,51 @@
#include "pac_type.h"
#include "pac_utils.h"
#include "pac_param.h"
Param::Param(ID* id, Type *type)
: id_(id), type_(type)
Param::Param(ID* id, Type* type) : id_(id), type_(type)
{
if ( ! type_ )
type_ = extern_type_int->Clone();
decl_str_ = strfmt("%s %s",
type_->DataTypeConstRefStr().c_str(),
id_->Name());
decl_str_ = strfmt("%s %s", type_->DataTypeConstRefStr().c_str(), id_->Name());
param_field_ = new ParamField(this);
}
Param::~Param()
{
}
Param::~Param() { }
const string &Param::decl_str() const
const string& Param::decl_str() const
{
ASSERT(!decl_str_.empty());
ASSERT(! decl_str_.empty());
return decl_str_;
}
string ParamDecls(ParamList *params)
string ParamDecls(ParamList* params)
{
string param_decls;
int first = 1;
foreach (i, ParamList, params)
{
Param* p = *i;
const char* decl_str = p->decl_str().c_str();
if ( first )
first = 0;
else
param_decls += ", ";
param_decls += decl_str;
}
{
Param* p = *i;
const char* decl_str = p->decl_str().c_str();
if ( first )
first = 0;
else
param_decls += ", ";
param_decls += decl_str;
}
return param_decls;
}
ParamField::ParamField(const Param *param)
: Field(PARAM_FIELD,
TYPE_NOT_TO_BE_PARSED | CLASS_MEMBER | PUBLIC_READABLE,
param->id(),
param->type())
ParamField::ParamField(const Param* param)
: Field(PARAM_FIELD, TYPE_NOT_TO_BE_PARSED | CLASS_MEMBER | PUBLIC_READABLE, param->id(),
param->type())
{
}
void ParamField::GenInitCode(Output *out_cc, Env *env)
void ParamField::GenInitCode(Output* out_cc, Env* env)
{
out_cc->println("%s = %s;",
env->LValue(id()), id()->Name());
out_cc->println("%s = %s;", env->LValue(id()), id()->Name());
env->SetEvaluated(id());
}

View file

@ -5,34 +5,34 @@
#include "pac_field.h"
class Param : public Object
{
{
public:
Param(ID* id, Type* type);
~Param();
ID *id() const { return id_; }
Type *type() const { return type_; }
const string & decl_str() const;
Field *param_field() const { return param_field_; }
ID* id() const { return id_; }
Type* type() const { return type_; }
const string& decl_str() const;
Field* param_field() const { return param_field_; }
private:
ID* id_;
Type* type_;
string decl_str_;
Field *param_field_;
};
Field* param_field_;
};
class ParamField : public Field
{
{
public:
ParamField(const Param *param);
ParamField(const Param* param);
void GenInitCode(Output *out, Env *env);
void GenInitCode(Output* out, Env* env);
void GenCleanUpCode(Output* out, Env* env);
};
};
// Returns the string with a list of param declarations separated by ','.
string ParamDecls(ParamList *params);
string ParamDecls(ParamList* params);
#if 0
// Generate assignments to parameters, in the form of "%s_ = %s;" % (id, id).
@ -45,4 +45,4 @@ void GenParamPubDecls(ParamList *params, Output *out_h, Env *env);
void GenParamPrivDecls(ParamList *params, Output *out_h, Env *env);
#endif
#endif // pac_param_h
#endif // pac_param_h

View file

@ -1,9 +1,10 @@
#include "pac_paramtype.h"
#include "pac_context.h"
#include "pac_dataptr.h"
#include "pac_exception.h"
#include "pac_expr.h"
#include "pac_output.h"
#include "pac_paramtype.h"
#include "pac_typedecl.h"
ParameterizedType::ParameterizedType(ID* type_id, ExprList* args)
@ -12,13 +13,11 @@ ParameterizedType::ParameterizedType(ID* type_id, ExprList* args)
checking_requires_analyzer_context_ = false;
}
ParameterizedType::~ParameterizedType()
{
}
ParameterizedType::~ParameterizedType() { }
string ParameterizedType::EvalMember(const ID *member_id) const
string ParameterizedType::EvalMember(const ID* member_id) const
{
Type *ty = ReferredDataType(true);
Type* ty = ReferredDataType(true);
return strfmt("->%s", ty->env()->RValue(member_id));
}
@ -27,12 +26,12 @@ string ParameterizedType::class_name() const
return type_id_->Name();
}
Type *ParameterizedType::DoClone() const
Type* ParameterizedType::DoClone() const
{
return new ParameterizedType(type_id_->clone(), args_);
}
void ParameterizedType::AddParamArg(Expr *arg)
void ParameterizedType::AddParamArg(Expr* arg)
{
args_->push_back(arg);
}
@ -47,21 +46,20 @@ string ParameterizedType::DataTypeStr() const
return strfmt("%s *", type_id_->Name());
}
Type *ParameterizedType::MemberDataType(const ID *member_id) const
Type* ParameterizedType::MemberDataType(const ID* member_id) const
{
Type *ref_type = TypeDecl::LookUpType(type_id_);
Type* ref_type = TypeDecl::LookUpType(type_id_);
if ( ! ref_type )
return 0;
return ref_type->MemberDataType(member_id);
}
Type *ParameterizedType::ReferredDataType(bool throw_exception) const
Type* ParameterizedType::ReferredDataType(bool throw_exception) const
{
Type* type = TypeDecl::LookUpType(type_id_);
if ( ! type )
{
DEBUG_MSG("WARNING: cannot find referenced type for %s\n",
type_id_->Name());
DEBUG_MSG("WARNING: cannot find referenced type for %s\n", type_id_->Name());
if ( throw_exception )
throw ExceptionIDNotFound(type_id_);
}
@ -75,7 +73,7 @@ int ParameterizedType::StaticSize(Env* env) const
void ParameterizedType::DoMarkIncrementalInput()
{
Type *ty = ReferredDataType(true);
Type* ty = ReferredDataType(true);
ty->MarkIncrementalInput();
@ -93,7 +91,7 @@ Type::BufferMode ParameterizedType::buffer_mode() const
// use &length.
//
BufferMode mode = Type::buffer_mode();
Type *ty = ReferredDataType(true);
Type* ty = ReferredDataType(true);
if ( mode != NOT_BUFFERABLE )
return mode;
@ -110,16 +108,16 @@ bool ParameterizedType::ByteOrderSensitive() const
return ReferredDataType(true)->RequiresByteOrder();
}
bool ParameterizedType::DoTraverse(DataDepVisitor *visitor)
bool ParameterizedType::DoTraverse(DataDepVisitor* visitor)
{
if ( ! Type::DoTraverse(visitor) )
return false;
foreach(i, ExprList, args_)
foreach (i, ExprList, args_)
if ( ! (*i)->Traverse(visitor) )
return false;
Type *ty = ReferredDataType(false);
Type* ty = ReferredDataType(false);
if ( ty && ! ty->Traverse(visitor) )
return false;
@ -134,20 +132,19 @@ bool ParameterizedType::RequiresAnalyzerContext()
bool ret = false;
// If any argument expression refers to analyzer context
foreach(i, ExprList, args_)
foreach (i, ExprList, args_)
if ( (*i)->RequiresAnalyzerContext() )
{
ret = true;
break;
}
ret = ret ||
Type::RequiresAnalyzerContext();
ret = ret || Type::RequiresAnalyzerContext();
if ( ! ret )
{
Type *ty = ReferredDataType(false);
Type* ty = ReferredDataType(false);
if ( ty )
ret = ty->RequiresAnalyzerContext();
ret = ty->RequiresAnalyzerContext();
}
checking_requires_analyzer_context_ = false;
@ -163,7 +160,7 @@ void ParameterizedType::GenInitCode(Output* out_cc, Env* env)
void ParameterizedType::GenCleanUpCode(Output* out_cc, Env* env)
{
Type *ty = ReferredDataType(false);
Type* ty = ReferredDataType(false);
if ( ty && ty->attr_refcount() )
out_cc->println("Unref(%s);", lvalue());
else
@ -172,7 +169,7 @@ void ParameterizedType::GenCleanUpCode(Output* out_cc, Env* env)
Type::GenCleanUpCode(out_cc, env);
}
string ParameterizedType::EvalParameters(Output* out_cc, Env *env) const
string ParameterizedType::EvalParameters(Output* out_cc, Env* env) const
{
string arg_str;
@ -190,27 +187,24 @@ string ParameterizedType::EvalParameters(Output* out_cc, Env *env) const
return arg_str;
}
void ParameterizedType::GenNewInstance(Output *out_cc, Env *env)
void ParameterizedType::GenNewInstance(Output* out_cc, Env* env)
{
out_cc->println("%s = new %s(%s);",
lvalue(),
type_id_->Name(),
EvalParameters(out_cc, env).c_str());
out_cc->println("%s = new %s(%s);", lvalue(), type_id_->Name(),
EvalParameters(out_cc, env).c_str());
}
void ParameterizedType::DoGenParseCode(Output* out_cc, Env* env,
const DataPtr& data, int flags)
void ParameterizedType::DoGenParseCode(Output* out_cc, Env* env, const DataPtr& data, int flags)
{
DEBUG_MSG("DoGenParseCode for %s\n", type_id_->Name());
Type *ref_type = ReferredDataType(true);
Type* ref_type = ReferredDataType(true);
const char *parse_func;
const char* parse_func;
string parse_params;
if ( buffer_mode() == BUFFER_NOTHING )
{
ASSERT(!ref_type->incremental_input());
{
ASSERT(! ref_type->incremental_input());
parse_func = kParseFuncWithoutBuffer;
parse_params = "0, 0";
}
@ -222,9 +216,7 @@ void ParameterizedType::DoGenParseCode(Output* out_cc, Env* env,
else
{
parse_func = kParseFuncWithoutBuffer;
parse_params = strfmt("%s, %s",
data.ptr_expr(),
env->RValue(end_of_data));
parse_params = strfmt("%s, %s", data.ptr_expr(), env->RValue(end_of_data));
}
if ( RequiresAnalyzerContext::compute(ref_type) )
@ -239,51 +231,43 @@ void ParameterizedType::DoGenParseCode(Output* out_cc, Env* env,
}
string call_parse_func = strfmt("%s->%s(%s)",
lvalue(), // parse() needs an LValue
parse_func,
parse_params.c_str());
lvalue(), // parse() needs an LValue
parse_func, parse_params.c_str());
if ( incremental_input() )
{
if ( buffer_mode() == BUFFER_NOTHING )
{
out_cc->println("%s;", call_parse_func.c_str());
out_cc->println("%s = true;",
env->LValue(parsing_complete_var()));
{
out_cc->println("%s;", call_parse_func.c_str());
out_cc->println("%s = true;", env->LValue(parsing_complete_var()));
}
else
{
{
ASSERT(parsing_complete_var());
out_cc->println("%s = %s;",
env->LValue(parsing_complete_var()),
call_parse_func.c_str());
out_cc->println("%s = %s;", env->LValue(parsing_complete_var()),
call_parse_func.c_str());
// parsing_complete_var might have been already
// evaluated when set to false
if ( ! env->Evaluated(parsing_complete_var()) )
env->SetEvaluated(parsing_complete_var());
env->SetEvaluated(parsing_complete_var());
}
}
else
{
if ( AddSizeVar(out_cc, env) )
{
out_cc->println("%s = %s;",
env->LValue(size_var()),
call_parse_func.c_str());
out_cc->println("%s = %s;", env->LValue(size_var()), call_parse_func.c_str());
env->SetEvaluated(size_var());
}
else
{
out_cc->println("%s;",
call_parse_func.c_str());
out_cc->println("%s;", call_parse_func.c_str());
}
}
}
void ParameterizedType::GenDynamicSize(Output* out_cc, Env* env,
const DataPtr& data)
void ParameterizedType::GenDynamicSize(Output* out_cc, Env* env, const DataPtr& data)
{
GenParseCode(out_cc, env, data, 0);
}

View file

@ -5,57 +5,57 @@
// An instantiated type: ID + expression list
class ParameterizedType : public Type
{
{
public:
ParameterizedType(ID *type_id, ExprList *args);
ParameterizedType(ID* type_id, ExprList* args);
~ParameterizedType();
Type *clone() const;
Type* clone() const;
string EvalMember(const ID *member_id) const;
string EvalMember(const ID* member_id) const;
// Env *member_env() const;
void AddParamArg(Expr *arg);
void AddParamArg(Expr* arg);
bool DefineValueVar() const;
string DataTypeStr() const;
string DefaultValue() const { return "0"; }
Type *MemberDataType(const ID *member_id) const;
string DefaultValue() const { return "0"; }
Type* MemberDataType(const ID* member_id) const;
// "throw_exception" specifies whether to throw an exception
// if the referred data type is not found
Type *ReferredDataType(bool throw_exception) const;
Type* ReferredDataType(bool throw_exception) const;
void GenCleanUpCode(Output *out, Env *env);
void GenCleanUpCode(Output* out, Env* env);
int StaticSize(Env *env) const;
int StaticSize(Env* env) const;
bool IsPointerType() const { return true; }
bool IsPointerType() const { return true; }
bool ByteOrderSensitive() const;
bool RequiresAnalyzerContext();
void GenInitCode(Output *out_cc, Env *env);
void GenInitCode(Output* out_cc, Env* env);
string class_name() const;
string EvalParameters(Output *out_cc, Env *env) const;
string EvalParameters(Output* out_cc, Env* env) const;
BufferMode buffer_mode() const;
protected:
void GenNewInstance(Output *out, Env *env);
void GenNewInstance(Output* out, Env* env);
bool DoTraverse(DataDepVisitor *visitor);
Type *DoClone() const;
bool DoTraverse(DataDepVisitor* visitor);
Type* DoClone() const;
void DoMarkIncrementalInput();
private:
ID *type_id_;
ExprList *args_;
ID* type_id_;
ExprList* args_;
bool checking_requires_analyzer_context_;
void DoGenParseCode(Output *out, Env *env, const DataPtr& data, int flags);
void GenDynamicSize(Output *out, Env *env, const DataPtr& data);
};
void DoGenParseCode(Output* out, Env* env, const DataPtr& data, int flags);
void GenDynamicSize(Output* out, Env* env, const DataPtr& data);
};
#endif // pac_paramtype_h
#endif // pac_paramtype_h

View file

@ -1,36 +1,34 @@
#include "pac_primitive.h"
#include "pac_dbg.h"
#include "pac_expr.h"
#include "pac_id.h"
#include "pac_primitive.h"
#include "pac_type.h"
string PPVal::ToCode(Env *env)
string PPVal::ToCode(Env* env)
{
ASSERT(expr_);
return string(expr_->EvalExpr(0, env));
}
string PPSet::ToCode(Env *env)
string PPSet::ToCode(Env* env)
{
ASSERT(expr_);
return expr_->SetFunc(0, env);
}
string PPType::ToCode(Env *env)
string PPType::ToCode(Env* env)
{
Type *type = expr_->DataType(env);
Type* type = expr_->DataType(env);
return type->DataTypeStr();
}
string PPConstDef::ToCode(Env *env)
string PPConstDef::ToCode(Env* env)
{
Type *type = expr_->DataType(env);
Type* type = expr_->DataType(env);
env->AddID(id_, TEMP_VAR, type);
env->SetEvaluated(id_);
string type_str = type->DataTypeStr();
return strfmt("%s %s = %s",
type_str.c_str(),
env->LValue(id_),
expr_->EvalExpr(0, env));
return strfmt("%s %s = %s", type_str.c_str(), env->LValue(id_), expr_->EvalExpr(0, env));
}

View file

@ -4,72 +4,75 @@
#include "pac_common.h"
class PacPrimitive
{
{
public:
enum PrimitiveType { VAL, SET, TYPE, CONST_DEF };
enum PrimitiveType
{
VAL,
SET,
TYPE,
CONST_DEF
};
explicit PacPrimitive(PrimitiveType type) : type_(type) {}
virtual ~PacPrimitive() {}
explicit PacPrimitive(PrimitiveType type) : type_(type) { }
virtual ~PacPrimitive() { }
PrimitiveType type() const { return type_; }
PrimitiveType type() const { return type_; }
virtual string ToCode(Env *env) = 0;
virtual string ToCode(Env* env) = 0;
private:
PrimitiveType type_;
};
};
class PPVal : public PacPrimitive
{
{
public:
PPVal(Expr *expr) : PacPrimitive(VAL), expr_(expr) {}
Expr *expr() const { return expr_; }
PPVal(Expr* expr) : PacPrimitive(VAL), expr_(expr) { }
Expr* expr() const { return expr_; }
string ToCode(Env *env);
string ToCode(Env* env);
private:
Expr *expr_;
};
Expr* expr_;
};
class PPSet : public PacPrimitive
{
{
public:
PPSet(Expr *expr) : PacPrimitive(SET), expr_(expr) {}
Expr *expr() const { return expr_; }
PPSet(Expr* expr) : PacPrimitive(SET), expr_(expr) { }
Expr* expr() const { return expr_; }
string ToCode(Env *env);
string ToCode(Env* env);
private:
Expr *expr_;
};
Expr* expr_;
};
class PPType : public PacPrimitive
{
{
public:
PPType(Expr *expr) : PacPrimitive(TYPE), expr_(expr) {}
Expr *expr() const { return expr_; }
PPType(Expr* expr) : PacPrimitive(TYPE), expr_(expr) { }
Expr* expr() const { return expr_; }
string ToCode(Env *env);
string ToCode(Env* env);
private:
Expr *expr_;
};
Expr* expr_;
};
class PPConstDef : public PacPrimitive
{
{
public:
PPConstDef(const ID *id, Expr *expr)
: PacPrimitive(CONST_DEF),
id_(id),
expr_(expr) {}
const ID *id() const { return id_; }
Expr *expr() const { return expr_; }
PPConstDef(const ID* id, Expr* expr) : PacPrimitive(CONST_DEF), id_(id), expr_(expr) { }
const ID* id() const { return id_; }
Expr* expr() const { return expr_; }
string ToCode(Env *env);
string ToCode(Env* env);
private:
const ID *id_;
Expr *expr_;
};
const ID* id_;
Expr* expr_;
};
#endif // pac_primitive_h
#endif // pac_primitive_h

View file

@ -1,3 +1,5 @@
#include "pac_record.h"
#include "pac_attr.h"
#include "pac_dataptr.h"
#include "pac_exception.h"
@ -5,15 +7,12 @@
#include "pac_exttype.h"
#include "pac_field.h"
#include "pac_output.h"
#include "pac_record.h"
#include "pac_type.h"
#include "pac_typedecl.h"
#include "pac_utils.h"
#include "pac_varfield.h"
RecordType::RecordType(RecordFieldList* record_fields)
: Type(RECORD)
RecordType::RecordType(RecordFieldList* record_fields) : Type(RECORD)
{
// Here we assume that the type is a standalone type.
value_var_ = 0;
@ -36,10 +35,9 @@ RecordType::~RecordType()
delete parsing_dataptr_var_field_;
}
const ID *RecordType::parsing_dataptr_var() const
const ID* RecordType::parsing_dataptr_var() const
{
return parsing_dataptr_var_field_ ?
parsing_dataptr_var_field_->id() : 0;
return parsing_dataptr_var_field_ ? parsing_dataptr_var_field_->id() : 0;
}
bool RecordType::DefineValueVar() const
@ -57,12 +55,12 @@ void RecordType::Prepare(Env* env, int flags)
{
ASSERT(flags & TO_BE_PARSED);
RecordField *prev = 0;
RecordField* prev = 0;
int offset = 0;
int seq = 0;
foreach (i, RecordFieldList, record_fields_)
{
RecordField *f = *i;
RecordField* f = *i;
f->set_record_type(this);
f->set_prev(prev);
if ( prev )
@ -120,71 +118,62 @@ void RecordType::GenCleanUpCode(Output* out_cc, Env* env)
Type::GenCleanUpCode(out_cc, env);
}
void RecordType::DoGenParseCode(Output* out_cc, Env* env,
const DataPtr& data, int flags)
void RecordType::DoGenParseCode(Output* out_cc, Env* env, const DataPtr& data, int flags)
{
if ( !incremental_input() && StaticSize(env) >= 0 )
if ( ! incremental_input() && StaticSize(env) >= 0 )
GenBoundaryCheck(out_cc, env, data);
if ( incremental_parsing() )
{
out_cc->println("switch ( %s ) {",
env->LValue(parsing_state_id));
out_cc->println("switch ( %s ) {", env->LValue(parsing_state_id));
out_cc->println("case 0:");
out_cc->inc_indent();
foreach (i, RecordFieldList, record_fields_)
{
RecordField *f = *i;
RecordField* f = *i;
f->GenParseCode(out_cc, env);
out_cc->println("");
}
out_cc->println("");
out_cc->println("%s = true;",
env->LValue(parsing_complete_var()));
out_cc->println("%s = true;", env->LValue(parsing_complete_var()));
out_cc->dec_indent();
out_cc->println("}");
}
else
{
ASSERT( data.id() == begin_of_data &&
data.offset() == 0 );
ASSERT(data.id() == begin_of_data && data.offset() == 0);
foreach (i, RecordFieldList, record_fields_)
{
RecordField *f = *i;
RecordField* f = *i;
f->GenParseCode(out_cc, env);
out_cc->println("");
}
if ( incremental_input() )
{
ASSERT(parsing_complete_var());
out_cc->println("%s = true;",
env->LValue(parsing_complete_var()));
out_cc->println("%s = true;", env->LValue(parsing_complete_var()));
}
}
if ( ! incremental_input() && AddSizeVar(out_cc, env) )
{
const DataPtr& end_of_record_dataptr =
record_fields_->back()->getFieldEnd(out_cc, env);
const DataPtr& end_of_record_dataptr = record_fields_->back()->getFieldEnd(out_cc, env);
out_cc->println("%s = %s - %s;",
env->LValue(size_var()),
end_of_record_dataptr.ptr_expr(),
env->RValue(begin_of_data));
out_cc->println("%s = %s - %s;", env->LValue(size_var()), end_of_record_dataptr.ptr_expr(),
env->RValue(begin_of_data));
env->SetEvaluated(size_var());
}
if ( ! boundary_checked() )
{
RecordField *last_field = record_fields_->back();
RecordField* last_field = record_fields_->back();
if ( ! last_field->BoundaryChecked() )
GenBoundaryCheck(out_cc, env, data);
}
}
void RecordType::GenDynamicSize(Output* out_cc, Env* env,
const DataPtr& data)
void RecordType::GenDynamicSize(Output* out_cc, Env* env, const DataPtr& data)
{
GenParseCode(out_cc, env, data, 0);
}
@ -194,7 +183,7 @@ int RecordType::StaticSize(Env* env) const
int tot_w = 0;
foreach (i, RecordFieldList, record_fields_)
{
RecordField *f = *i;
RecordField* f = *i;
int w = f->StaticSize(env, tot_w);
if ( w < 0 )
return -1;
@ -215,7 +204,7 @@ void RecordType::SetBoundaryChecked()
foreach (i, RecordFieldList, record_fields_)
{
RecordField *f = *i;
RecordField* f = *i;
f->SetBoundaryChecked();
}
}
@ -224,12 +213,12 @@ void RecordType::DoMarkIncrementalInput()
{
foreach (i, RecordFieldList, record_fields_)
{
RecordField *f = *i;
RecordField* f = *i;
f->type()->MarkIncrementalInput();
}
}
bool RecordType::DoTraverse(DataDepVisitor *visitor)
bool RecordType::DoTraverse(DataDepVisitor* visitor)
{
return Type::DoTraverse(visitor);
}
@ -238,17 +227,15 @@ bool RecordType::ByteOrderSensitive() const
{
foreach (i, RecordFieldList, record_fields_)
{
RecordField *f = *i;
RecordField* f = *i;
if ( f->RequiresByteOrder() )
return true;
}
return false;
}
RecordField::RecordField(FieldType tof, ID *id, Type *type)
: Field(tof,
TYPE_TO_BE_PARSED | CLASS_MEMBER | PUBLIC_READABLE,
id, type)
RecordField::RecordField(FieldType tof, ID* id, Type* type)
: Field(tof, TYPE_TO_BE_PARSED | CLASS_MEMBER | PUBLIC_READABLE, id, type)
{
begin_of_field_dataptr = 0;
end_of_field_dataptr = 0;
@ -267,8 +254,8 @@ RecordField::~RecordField()
{
delete begin_of_field_dataptr;
delete end_of_field_dataptr;
delete [] field_size_expr;
delete [] field_offset_expr;
delete[] field_size_expr;
delete[] field_offset_expr;
delete end_of_field_dataptr_var;
}
@ -281,8 +268,7 @@ const DataPtr& RecordField::getFieldBegin(Output* out_cc, Env* env)
// The first field
if ( ! begin_of_field_dataptr )
{
begin_of_field_dataptr =
new DataPtr(env, begin_of_data, 0);
begin_of_field_dataptr = new DataPtr(env, begin_of_data, 0);
}
return *begin_of_field_dataptr;
}
@ -300,12 +286,10 @@ const DataPtr& RecordField::getFieldEnd(Output* out_cc, Env* env)
ASSERT(0);
if ( ! end_of_field_dataptr )
{
const ID *dataptr_var =
record_type()->parsing_dataptr_var();
const ID* dataptr_var = record_type()->parsing_dataptr_var();
ASSERT(dataptr_var);
end_of_field_dataptr =
new DataPtr(env, dataptr_var, 0);
end_of_field_dataptr = new DataPtr(env, dataptr_var, 0);
}
}
else
@ -314,31 +298,23 @@ const DataPtr& RecordField::getFieldEnd(Output* out_cc, Env* env)
if ( begin_ptr.id() == begin_of_data )
field_offset = begin_ptr.offset();
else
field_offset = -1; // unknown
field_offset = -1; // unknown
int field_size = StaticSize(env, field_offset);
if ( field_size >= 0 ) // can be statically determinted
{
end_of_field_dataptr = new DataPtr(
env,
begin_ptr.id(),
begin_ptr.offset() + field_size);
end_of_field_dataptr = new DataPtr(env, begin_ptr.id(),
begin_ptr.offset() + field_size);
}
else
{
// If not, we add a variable for the offset after the field
end_of_field_dataptr_var = new ID(
strfmt("dataptr_after_%s", id()->Name()));
env->AddID(end_of_field_dataptr_var,
TEMP_VAR,
extern_type_const_byteptr);
end_of_field_dataptr_var = new ID(strfmt("dataptr_after_%s", id()->Name()));
env->AddID(end_of_field_dataptr_var, TEMP_VAR, extern_type_const_byteptr);
GenFieldEnd(out_cc, env, begin_ptr);
end_of_field_dataptr = new DataPtr(
env,
end_of_field_dataptr_var,
0);
end_of_field_dataptr = new DataPtr(env, end_of_field_dataptr_var, 0);
}
}
@ -368,8 +344,7 @@ const char* RecordField::FieldOffset(Output* out_cc, Env* env)
if ( begin.id() == begin_of_data )
field_offset_expr = nfmt("%d", begin.offset());
else
field_offset_expr = nfmt("(%s - %s)",
begin.ptr_expr(), env->RValue(begin_of_data));
field_offset_expr = nfmt("(%s - %s)", begin.ptr_expr(), env->RValue(begin_of_data));
return field_offset_expr;
}
@ -400,15 +375,12 @@ bool RecordField::AttemptBoundaryCheck(Output* out_cc, Env* env)
return GenBoundaryCheck(out_cc, env);
}
RecordDataField::RecordDataField(ID* id, Type* type)
: RecordField(RECORD_FIELD, id, type)
RecordDataField::RecordDataField(ID* id, Type* type) : RecordField(RECORD_FIELD, id, type)
{
ASSERT(type_);
}
RecordDataField::~RecordDataField()
{
}
RecordDataField::~RecordDataField() { }
void RecordDataField::Prepare(Env* env)
{
@ -435,8 +407,7 @@ void RecordDataField::GenParseCode(Output* out_cc, Env* env)
Expr* len_expr = record_type()->attr_length_expr();
int len;
if ( ! record_type()->buffer_input() ||
(len_expr && len_expr->ConstFold(env, &len)) )
if ( ! record_type()->buffer_input() || (len_expr && len_expr->ConstFold(env, &len)) )
AttemptBoundaryCheck(out_cc, env);
}
@ -449,9 +420,7 @@ void RecordDataField::GenParseCode(Output* out_cc, Env* env)
if ( type_->incremental_input() )
{
// The enclosing record type must be incrementally parsed
out_cc->println("%s = %d;",
env->LValue(parsing_state_id),
parsing_state_seq());
out_cc->println("%s = %d;", env->LValue(parsing_state_id), parsing_state_seq());
out_cc->println("/* fall through */");
out_cc->dec_indent();
out_cc->println("case %d:", parsing_state_seq());
@ -465,8 +434,7 @@ void RecordDataField::GenParseCode(Output* out_cc, Env* env)
{
ASSERT(type_->incremental_input());
out_cc->println("if ( ! (%s) )",
type_->parsing_complete(env).c_str());
out_cc->println("if ( ! (%s) )", type_->parsing_complete(env).c_str());
out_cc->inc_indent();
out_cc->println("goto %s;", kNeedMoreData);
out_cc->dec_indent();
@ -493,18 +461,14 @@ void RecordDataField::GenEval(Output* out_cc, Env* env)
GenParseCode(out_cc, env);
}
void RecordDataField::GenFieldEnd(Output* out_cc, Env* env,
const DataPtr& field_begin)
void RecordDataField::GenFieldEnd(Output* out_cc, Env* env, const DataPtr& field_begin)
{
out_cc->println("const_byteptr const %s = %s + (%s);",
env->LValue(end_of_field_dataptr_var),
field_begin.ptr_expr(),
type_->DataSize(out_cc, env, field_begin).c_str());
out_cc->println("const_byteptr const %s = %s + (%s);", env->LValue(end_of_field_dataptr_var),
field_begin.ptr_expr(), type_->DataSize(out_cc, env, field_begin).c_str());
env->SetEvaluated(end_of_field_dataptr_var);
out_cc->println("BINPAC_ASSERT(%s <= %s);",
env->RValue(end_of_field_dataptr_var),
env->RValue(end_of_data));
out_cc->println("BINPAC_ASSERT(%s <= %s);", env->RValue(end_of_field_dataptr_var),
env->RValue(end_of_data));
}
void RecordDataField::SetBoundaryChecked()
@ -524,15 +488,14 @@ bool RecordDataField::GenBoundaryCheck(Output* out_cc, Env* env)
return true;
}
bool RecordDataField::DoTraverse(DataDepVisitor *visitor)
bool RecordDataField::DoTraverse(DataDepVisitor* visitor)
{
return Field::DoTraverse(visitor);
}
bool RecordDataField::RequiresAnalyzerContext() const
{
return Field::RequiresAnalyzerContext() ||
type()->RequiresAnalyzerContext();
return Field::RequiresAnalyzerContext() || type()->RequiresAnalyzerContext();
}
RecordPaddingField::RecordPaddingField(ID* id, PaddingType ptype, Expr* expr)
@ -541,9 +504,7 @@ RecordPaddingField::RecordPaddingField(ID* id, PaddingType ptype, Expr* expr)
wordsize_ = -1;
}
RecordPaddingField::~RecordPaddingField()
{
}
RecordPaddingField::~RecordPaddingField() { }
void RecordPaddingField::Prepare(Env* env)
{
@ -551,8 +512,7 @@ void RecordPaddingField::Prepare(Env* env)
if ( ptype_ == PAD_TO_NEXT_WORD )
{
if ( ! expr_->ConstFold(env, &wordsize_) )
throw ExceptionPaddingError(this,
strfmt("padding word size not a constant"));
throw ExceptionPaddingError(this, strfmt("padding word size not a constant"));
}
}
@ -589,11 +549,9 @@ int RecordPaddingField::StaticSize(Env* env, int offset) const
// can be statically computed, we can get its
// static size
if ( offset > target_offset )
throw ExceptionPaddingError(
this,
strfmt("current offset = %d, "
"target offset = %d",
offset, target_offset));
throw ExceptionPaddingError(this, strfmt("current offset = %d, "
"target offset = %d",
offset, target_offset));
return target_offset - offset;
case PAD_TO_NEXT_WORD:
@ -601,8 +559,7 @@ int RecordPaddingField::StaticSize(Env* env, int offset) const
return -1;
offset_in_word = offset % wordsize_;
return ( offset_in_word == 0 ) ?
0 : wordsize_ - offset_in_word;
return (offset_in_word == 0) ? 0 : wordsize_ - offset_in_word;
}
return -1;
@ -620,86 +577,67 @@ void RecordPaddingField::GenFieldEnd(Output* out_cc, Env* env, const DataPtr& fi
expr_->EvalExpr(out_cc, env));
out_cc->inc_indent();
out_cc->println("{");
out_cc->println("throw binpac::ExceptionInvalidStringLength(\"%s\", %s);",
Location(), expr_->EvalExpr(out_cc, env));
out_cc->println("throw binpac::ExceptionInvalidStringLength(\"%s\", %s);", Location(),
expr_->EvalExpr(out_cc, env));
out_cc->println("}");
out_cc->dec_indent();
out_cc->println("");
out_cc->println("const_byteptr const %s = %s + (%s);",
env->LValue(end_of_field_dataptr_var),
field_begin.ptr_expr(),
expr_->EvalExpr(out_cc, env));
env->LValue(end_of_field_dataptr_var), field_begin.ptr_expr(),
expr_->EvalExpr(out_cc, env));
out_cc->println("// Checking out-of-bound padding for \"%s\"", field_id_str_.c_str());
out_cc->println("if ( %s > %s || %s < %s )",
env->LValue(end_of_field_dataptr_var),
env->RValue(end_of_data),
env->LValue(end_of_field_dataptr_var),
out_cc->println("if ( %s > %s || %s < %s )", env->LValue(end_of_field_dataptr_var),
env->RValue(end_of_data), env->LValue(end_of_field_dataptr_var),
field_begin.ptr_expr());
out_cc->inc_indent();
out_cc->println("{");
out_cc->println("throw binpac::ExceptionOutOfBound(\"%s\",", field_id_str_.c_str());
out_cc->println(" (%s), ",
expr_->EvalExpr(out_cc, env));
out_cc->println(" (%s) - (%s));",
env->RValue(end_of_data), env->LValue(end_of_field_dataptr_var));
out_cc->println(" (%s), ", expr_->EvalExpr(out_cc, env));
out_cc->println(" (%s) - (%s));", env->RValue(end_of_data),
env->LValue(end_of_field_dataptr_var));
out_cc->println("}");
out_cc->dec_indent();
out_cc->println("");
break;
case PAD_TO_OFFSET:
out_cc->println("const_byteptr %s = %s + (%s);",
env->LValue(end_of_field_dataptr_var),
env->RValue(begin_of_data),
expr_->EvalExpr(out_cc, env));
out_cc->println("if ( %s < %s )",
env->LValue(end_of_field_dataptr_var),
field_begin.ptr_expr());
out_cc->println("const_byteptr %s = %s + (%s);", env->LValue(end_of_field_dataptr_var),
env->RValue(begin_of_data), expr_->EvalExpr(out_cc, env));
out_cc->println("if ( %s < %s )", env->LValue(end_of_field_dataptr_var),
field_begin.ptr_expr());
out_cc->inc_indent();
out_cc->println("{");
out_cc->println("// throw binpac::ExceptionInvalidOffset(\"%s\", %s - %s, %s);",
id_->LocName(),
field_begin.ptr_expr(),
env->RValue(begin_of_data),
expr_->EvalExpr(out_cc, env));
out_cc->println("%s = %s;",
env->LValue(end_of_field_dataptr_var),
field_begin.ptr_expr());
id_->LocName(), field_begin.ptr_expr(), env->RValue(begin_of_data),
expr_->EvalExpr(out_cc, env));
out_cc->println("%s = %s;", env->LValue(end_of_field_dataptr_var),
field_begin.ptr_expr());
out_cc->println("}");
out_cc->dec_indent();
out_cc->println("if ( %s > %s )",
env->LValue(end_of_field_dataptr_var),
env->RValue(end_of_data));
out_cc->println("if ( %s > %s )", env->LValue(end_of_field_dataptr_var),
env->RValue(end_of_data));
out_cc->inc_indent();
out_cc->println("{");
out_cc->println("throw binpac::ExceptionOutOfBound(\"%s\",", field_id_str_.c_str());
out_cc->println(" (%s), ",
expr_->EvalExpr(out_cc, env));
out_cc->println(" (%s) - (%s));",
env->RValue(end_of_data), env->LValue(end_of_field_dataptr_var));
out_cc->println(" (%s), ", expr_->EvalExpr(out_cc, env));
out_cc->println(" (%s) - (%s));", env->RValue(end_of_data),
env->LValue(end_of_field_dataptr_var));
out_cc->println("}");
out_cc->dec_indent();
break;
case PAD_TO_NEXT_WORD:
padding_var = nfmt("%s__size", id()->Name());
out_cc->println("int %s = (%s - %s) %% %d;",
padding_var,
field_begin.ptr_expr(),
env->RValue(begin_of_data),
wordsize_);
out_cc->println("%s = (%s == 0) ? 0 : %d - %s;",
padding_var,
padding_var,
wordsize_,
padding_var);
out_cc->println("int %s = (%s - %s) %% %d;", padding_var, field_begin.ptr_expr(),
env->RValue(begin_of_data), wordsize_);
out_cc->println("%s = (%s == 0) ? 0 : %d - %s;", padding_var, padding_var, wordsize_,
padding_var);
out_cc->println("const_byteptr const %s = %s + %s;",
env->LValue(end_of_field_dataptr_var),
field_begin.ptr_expr(),
padding_var);
delete [] padding_var;
env->LValue(end_of_field_dataptr_var), field_begin.ptr_expr(),
padding_var);
delete[] padding_var;
break;
}
@ -715,20 +653,18 @@ bool RecordPaddingField::GenBoundaryCheck(Output* out_cc, Env* env)
char* size;
int ss = StaticSize(env, begin.AbsOffset(begin_of_data));
ASSERT ( ss >= 0 );
size = nfmt("%d", ss);
ASSERT(ss >= 0);
size = nfmt("%d", ss);
begin.GenBoundaryCheck(out_cc, env, size, field_id_str_.c_str());
delete [] size;
delete[] size;
SetBoundaryChecked();
return true;
}
bool RecordPaddingField::DoTraverse(DataDepVisitor *visitor)
bool RecordPaddingField::DoTraverse(DataDepVisitor* visitor)
{
return Field::DoTraverse(visitor) &&
(! expr_ || expr_->Traverse(visitor));
return Field::DoTraverse(visitor) && (! expr_ || expr_->Traverse(visitor));
}

View file

@ -8,7 +8,7 @@
#include "pac_type.h"
class RecordType : public Type
{
{
public:
RecordType(RecordFieldList* fields);
~RecordType();
@ -28,58 +28,62 @@ public:
void SetBoundaryChecked();
const ID *parsing_dataptr_var() const;
const ID* parsing_dataptr_var() const;
bool IsPointerType() const { ASSERT(0); return false; }
bool IsPointerType() const
{
ASSERT(0);
return false;
}
protected:
void DoGenParseCode(Output* out, Env* env, const DataPtr& data, int flags);
void GenDynamicSize(Output* out, Env* env, const DataPtr& data);
Type *DoClone() const { return 0; }
Type* DoClone() const { return 0; }
void DoMarkIncrementalInput();
bool DoTraverse(DataDepVisitor *visitor);
bool DoTraverse(DataDepVisitor* visitor);
bool ByteOrderSensitive() const;
private:
Field *parsing_dataptr_var_field_;
Field* parsing_dataptr_var_field_;
RecordFieldList* record_fields_;
};
};
// A data field of a record type. A RecordField corresponds to a
// segment of input data, and therefore RecordField's are ordered---each
// of them has a known previous and next field.
class RecordField : public Field
{
{
public:
RecordField(FieldType tof, ID* id, Type *type);
RecordField(FieldType tof, ID* id, Type* type);
~RecordField();
RecordType *record_type() const { return record_type_; }
void set_record_type(RecordType* ty) { record_type_ = ty; }
RecordType* record_type() const { return record_type_; }
void set_record_type(RecordType* ty) { record_type_ = ty; }
virtual void GenParseCode(Output* out, Env* env) = 0;
RecordField* prev() const { return prev_; }
RecordField* next() const { return next_; }
void set_prev(RecordField* f) { prev_ = f; }
void set_next(RecordField* f) { next_ = f; }
RecordField* prev() const { return prev_; }
RecordField* next() const { return next_; }
void set_prev(RecordField* f) { prev_ = f; }
void set_next(RecordField* f) { next_ = f; }
int static_offset() const { return static_offset_; }
void set_static_offset(int offset) { static_offset_ = offset; }
int static_offset() const { return static_offset_; }
void set_static_offset(int offset) { static_offset_ = offset; }
int parsing_state_seq() const { return parsing_state_seq_; }
void set_parsing_state_seq(int x) { parsing_state_seq_ = x; }
int parsing_state_seq() const { return parsing_state_seq_; }
void set_parsing_state_seq(int x) { parsing_state_seq_ = x; }
virtual int StaticSize(Env* env, int offset) const = 0;
const char* FieldSize(Output* out, Env* env);
const char* FieldOffset(Output* out, Env* env);
virtual bool BoundaryChecked() const { return boundary_checked_; }
virtual void SetBoundaryChecked() { boundary_checked_ = true; }
virtual bool BoundaryChecked() const { return boundary_checked_; }
virtual void SetBoundaryChecked() { boundary_checked_ = true; }
virtual bool RequiresByteOrder() const = 0;
@ -105,10 +109,10 @@ protected:
bool AttemptBoundaryCheck(Output* out_cc, Env* env);
virtual bool GenBoundaryCheck(Output* out_cc, Env* env) = 0;
};
};
class RecordDataField : public RecordField, public Evaluatable
{
{
public:
RecordDataField(ID* arg_id, Type* arg_type);
~RecordDataField();
@ -120,50 +124,62 @@ public:
// Instantiates abstract class Evaluatable
void GenEval(Output* out, Env* env);
int StaticSize(Env* env, int) const { return type()->StaticSize(env); }
int StaticSize(Env* env, int) const { return type()->StaticSize(env); }
void SetBoundaryChecked();
bool RequiresByteOrder() const
{ return type()->RequiresByteOrder(); }
bool RequiresByteOrder() const { return type()->RequiresByteOrder(); }
bool RequiresAnalyzerContext() const;
protected:
void GenFieldEnd(Output* out, Env* env, const DataPtr& begin);
bool GenBoundaryCheck(Output* out_cc, Env* env);
bool DoTraverse(DataDepVisitor *visitor);
};
bool DoTraverse(DataDepVisitor* visitor);
};
enum PaddingType { PAD_BY_LENGTH, PAD_TO_OFFSET, PAD_TO_NEXT_WORD };
enum PaddingType
{
PAD_BY_LENGTH,
PAD_TO_OFFSET,
PAD_TO_NEXT_WORD
};
class RecordPaddingField : public RecordField
{
{
public:
RecordPaddingField(ID* id, PaddingType ptype, Expr* expr);
~RecordPaddingField();
void Prepare(Env* env);
void GenPubDecls(Output* out, Env* env) { /* nothing */ }
void GenPrivDecls(Output* out, Env* env) { /* nothing */ }
void GenPubDecls(Output* out, Env* env)
{ /* nothing */
}
void GenPrivDecls(Output* out, Env* env)
{ /* nothing */
}
void GenInitCode(Output* out, Env* env) { /* nothing */ }
void GenCleanUpCode(Output* out, Env* env) { /* nothing */ }
void GenInitCode(Output* out, Env* env)
{ /* nothing */
}
void GenCleanUpCode(Output* out, Env* env)
{ /* nothing */
}
void GenParseCode(Output* out, Env* env);
int StaticSize(Env* env, int offset) const;
bool RequiresByteOrder() const { return false; }
bool RequiresByteOrder() const { return false; }
protected:
void GenFieldEnd(Output* out, Env* env, const DataPtr& begin);
bool GenBoundaryCheck(Output* out_cc, Env* env);
bool DoTraverse(DataDepVisitor *visitor);
bool DoTraverse(DataDepVisitor* visitor);
private:
PaddingType ptype_;
Expr* expr_;
int wordsize_;
};
};
#endif // pac_record_h
#endif // pac_record_h

View file

@ -1,151 +1,133 @@
#include "pac_redef.h"
#include "pac_analyzer.h"
#include "pac_case.h"
#include "pac_exception.h"
#include "pac_expr.h"
#include "pac_func.h"
#include "pac_record.h"
#include "pac_redef.h"
#include "pac_type.h"
#include "pac_typedecl.h"
namespace {
Decl *find_decl(const ID *id)
namespace
{
Decl *decl = Decl::LookUpDecl(id);
Decl* find_decl(const ID* id)
{
Decl* decl = Decl::LookUpDecl(id);
if ( ! decl )
{
throw Exception(id,
strfmt("cannot find declaration for %s",
id->Name()));
throw Exception(id, strfmt("cannot find declaration for %s", id->Name()));
}
return decl;
}
}
}
Decl *ProcessTypeRedef(const ID *id, FieldList *fieldlist)
Decl* ProcessTypeRedef(const ID* id, FieldList* fieldlist)
{
Decl *decl = find_decl(id);
Decl* decl = find_decl(id);
if ( decl->decl_type() != Decl::TYPE )
{
throw Exception(id,
strfmt("not a type declaration: %s",
id->Name()));
throw Exception(id, strfmt("not a type declaration: %s", id->Name()));
}
TypeDecl *type_decl = static_cast<TypeDecl *>(decl);
TypeDecl* type_decl = static_cast<TypeDecl*>(decl);
ASSERT(type_decl);
Type *type = type_decl->type();
Type* type = type_decl->type();
foreach(i, FieldList, fieldlist)
foreach (i, FieldList, fieldlist)
{
Field *f = *i;
Field* f = *i;
// One cannot change data layout in 'redef'.
// Only 'let' or 'action' can be added
if ( f->tof() == LET_FIELD ||
f->tof() == WITHINPUT_FIELD )
if ( f->tof() == LET_FIELD || f->tof() == WITHINPUT_FIELD )
{
type->AddField(f);
}
else if ( f->tof() == RECORD_FIELD ||
f->tof() == PADDING_FIELD )
else if ( f->tof() == RECORD_FIELD || f->tof() == PADDING_FIELD )
{
throw Exception(f,
"cannot change data layout in redef");
throw Exception(f, "cannot change data layout in redef");
}
else if ( f->tof() == CASE_FIELD )
{
throw Exception(f,
"use 'redef case' adding cases");
throw Exception(f, "use 'redef case' adding cases");
}
}
return decl;
}
Decl *ProcessCaseTypeRedef(const ID *id, CaseFieldList *casefieldlist)
Decl* ProcessCaseTypeRedef(const ID* id, CaseFieldList* casefieldlist)
{
Decl *decl = find_decl(id);
Decl* decl = find_decl(id);
if ( decl->decl_type() != Decl::TYPE )
{
throw Exception(id,
strfmt("not a type declaration: %s",
id->Name()));
throw Exception(id, strfmt("not a type declaration: %s", id->Name()));
}
TypeDecl *type_decl = static_cast<TypeDecl *>(decl);
TypeDecl* type_decl = static_cast<TypeDecl*>(decl);
ASSERT(type_decl);
Type *type = type_decl->type();
Type* type = type_decl->type();
if ( type->tot() != Type::CASE )
{
throw Exception(id,
strfmt("not a case type: %s",
id->Name()));
throw Exception(id, strfmt("not a case type: %s", id->Name()));
}
CaseType *casetype = static_cast<CaseType*>(type);
CaseType* casetype = static_cast<CaseType*>(type);
ASSERT(casetype);
foreach(i, CaseFieldList, casefieldlist)
foreach (i, CaseFieldList, casefieldlist)
{
CaseField *f = *i;
CaseField* f = *i;
casetype->AddCaseField(f);
}
return decl;
}
Decl *ProcessCaseExprRedef(const ID *id, CaseExprList *caseexprlist)
Decl* ProcessCaseExprRedef(const ID* id, CaseExprList* caseexprlist)
{
Decl *decl = find_decl(id);
Decl* decl = find_decl(id);
if ( decl->decl_type() != Decl::FUNC )
{
throw Exception(id,
strfmt("not a function declaration: %s",
id->Name()));
throw Exception(id, strfmt("not a function declaration: %s", id->Name()));
}
FuncDecl *func_decl = static_cast<FuncDecl *>(decl);
FuncDecl* func_decl = static_cast<FuncDecl*>(decl);
ASSERT(func_decl);
Expr *expr = func_decl->function()->expr();
if ( ! expr ||expr->expr_type() != Expr::EXPR_CASE )
Expr* expr = func_decl->function()->expr();
if ( ! expr || expr->expr_type() != Expr::EXPR_CASE )
{
throw Exception(id,
strfmt("function not defined by a case expression: %s",
id->Name()));
throw Exception(id, strfmt("function not defined by a case expression: %s", id->Name()));
}
foreach(i, CaseExprList, caseexprlist)
foreach (i, CaseExprList, caseexprlist)
{
CaseExpr *e = *i;
CaseExpr* e = *i;
expr->AddCaseExpr(e);
}
return decl;
}
Decl *ProcessAnalyzerRedef(const ID *id,
Decl::DeclType decl_type,
AnalyzerElementList *elements)
Decl* ProcessAnalyzerRedef(const ID* id, Decl::DeclType decl_type, AnalyzerElementList* elements)
{
Decl *decl = find_decl(id);
Decl* decl = find_decl(id);
if ( decl->decl_type() != decl_type )
{
throw Exception(id,
strfmt("not a connection/flow declaration: %s",
id->Name()));
throw Exception(id, strfmt("not a connection/flow declaration: %s", id->Name()));
}
AnalyzerDecl *analyzer_decl = static_cast<AnalyzerDecl *>(decl);
AnalyzerDecl* analyzer_decl = static_cast<AnalyzerDecl*>(decl);
ASSERT(analyzer_decl);
analyzer_decl->AddElements(elements);
@ -153,18 +135,16 @@ Decl *ProcessAnalyzerRedef(const ID *id,
return decl;
}
Decl *ProcessTypeAttrRedef(const ID *id, AttrList *attrlist)
Decl* ProcessTypeAttrRedef(const ID* id, AttrList* attrlist)
{
Decl *decl = find_decl(id);
Decl* decl = find_decl(id);
if ( decl->decl_type() != Decl::TYPE )
{
throw Exception(id,
strfmt("not a type declaration: %s",
id->Name()));
throw Exception(id, strfmt("not a type declaration: %s", id->Name()));
}
TypeDecl *type_decl = static_cast<TypeDecl *>(decl);
TypeDecl* type_decl = static_cast<TypeDecl*>(decl);
ASSERT(type_decl);
type_decl->AddAttrs(attrlist);

View file

@ -3,11 +3,9 @@
#include "pac_decl.h"
Decl *ProcessCaseTypeRedef(const ID *id, CaseFieldList *casefieldlist);
Decl *ProcessCaseExprRedef(const ID *id, CaseExprList *caseexprlist);
Decl *ProcessAnalyzerRedef(const ID *id,
Decl::DeclType decl_type,
AnalyzerElementList *elements);
Decl *ProcessTypeAttrRedef(const ID *id, AttrList *attrlist);
Decl* ProcessCaseTypeRedef(const ID* id, CaseFieldList* casefieldlist);
Decl* ProcessCaseExprRedef(const ID* id, CaseExprList* caseexprlist);
Decl* ProcessAnalyzerRedef(const ID* id, Decl::DeclType decl_type, AnalyzerElementList* elements);
Decl* ProcessTypeAttrRedef(const ID* id, AttrList* attrlist);
#endif // pac_redef_h
#endif // pac_redef_h

View file

@ -1,27 +1,28 @@
#include "pac_regex.h"
#include "pac_exttype.h"
#include "pac_id.h"
#include "pac_output.h"
#include "pac_regex.h"
#include "pac_type.h"
// Depends on the regular expression library we are using
const char *RegEx::kREMatcherType = "RegExMatcher";
const char *RegEx::kMatchPrefix = "MatchPrefix";
const char* RegEx::kREMatcherType = "RegExMatcher";
const char* RegEx::kMatchPrefix = "MatchPrefix";
string escape_char(const string &s)
string escape_char(const string& s)
{
char* buf = new char[s.length() * 2 + 1];
int j = 0;
for ( int i = 0; i < (int) s.length(); ++i )
for ( int i = 0; i < (int)s.length(); ++i )
{
if ( s[i] == '\\' )
{
if ( i + 1 < (int) s.length() )
if ( i + 1 < (int)s.length() )
{
buf[j++] = '\\';
if ( s[i+1] == '/' )
buf[j-1] = s[++i];
else if ( s[i+1] == '/' || s[i+1] == '\\' || s[i+1] == '"' )
if ( s[i + 1] == '/' )
buf[j - 1] = s[++i];
else if ( s[i + 1] == '/' || s[i + 1] == '\\' || s[i + 1] == '"' )
buf[j++] = s[++i];
else
buf[j++] = '\\';
@ -41,11 +42,11 @@ string escape_char(const string &s)
buf[j++] = '\0';
string rval = buf;
delete [] buf;
delete[] buf;
return rval;
}
RegEx::RegEx(const string &s)
RegEx::RegEx(const string& s)
{
str_ = escape_char(s);
string prefix = strfmt("%s_re_", current_decl_id->Name());
@ -53,12 +54,9 @@ RegEx::RegEx(const string &s)
decl_ = new RegExDecl(this);
}
RegEx::~RegEx()
{
}
RegEx::~RegEx() { }
RegExDecl::RegExDecl(RegEx *regex)
: Decl(regex->matcher_id(), REGEX)
RegExDecl::RegExDecl(RegEx* regex) : Decl(regex->matcher_id(), REGEX)
{
regex_ = regex;
}
@ -68,17 +66,14 @@ void RegExDecl::Prepare()
global_env()->AddID(id(), GLOBAL_VAR, extern_type_re_matcher);
}
void RegExDecl::GenForwardDeclaration(Output *out_h)
void RegExDecl::GenForwardDeclaration(Output* out_h)
{
out_h->println("extern %s %s;\n",
RegEx::kREMatcherType,
global_env()->LValue(regex_->matcher_id()));
out_h->println("extern %s %s;\n", RegEx::kREMatcherType,
global_env()->LValue(regex_->matcher_id()));
}
void RegExDecl::GenCode(Output *out_h, Output *out_cc)
void RegExDecl::GenCode(Output* out_h, Output* out_cc)
{
out_cc->println("%s %s(\"%s\");\n",
RegEx::kREMatcherType,
global_env()->LValue(regex_->matcher_id()),
regex_->str().c_str());
out_cc->println("%s %s(\"%s\");\n", RegEx::kREMatcherType,
global_env()->LValue(regex_->matcher_id()), regex_->str().c_str());
}

View file

@ -7,35 +7,35 @@
class RegExDecl;
class RegEx : public Object
{
{
public:
RegEx(const string &str);
RegEx(const string& str);
~RegEx();
const string &str() const { return str_; }
ID *matcher_id() const { return matcher_id_; }
const string& str() const { return str_; }
ID* matcher_id() const { return matcher_id_; }
private:
string str_;
ID *matcher_id_;
RegExDecl *decl_;
ID* matcher_id_;
RegExDecl* decl_;
public:
static const char *kREMatcherType;
static const char *kMatchPrefix;
};
static const char* kREMatcherType;
static const char* kMatchPrefix;
};
class RegExDecl : public Decl
{
{
public:
RegExDecl(RegEx *regex);
RegExDecl(RegEx* regex);
void Prepare();
void GenForwardDeclaration(Output *out_h);
void GenCode(Output *out_h, Output *out_cc);
void GenForwardDeclaration(Output* out_h);
void GenCode(Output* out_h, Output* out_cc);
private:
RegEx *regex_;
};
RegEx* regex_;
};
#endif // pac_regex_h
#endif // pac_regex_h

View file

@ -1,36 +1,26 @@
#include "pac_state.h"
#include "pac_id.h"
#include "pac_output.h"
#include "pac_type.h"
#include "pac_state.h"
void StateVar::GenDecl(Output *out_h, Env *env)
void StateVar::GenDecl(Output* out_h, Env* env)
{
out_h->println("%s %s;",
type_->DataTypeStr().c_str(),
env->LValue(id_));
out_h->println("%s %s;", type_->DataTypeStr().c_str(), env->LValue(id_));
}
void StateVar::GenAccessFunction(Output *out_h, Env *env)
void StateVar::GenAccessFunction(Output* out_h, Env* env)
{
out_h->println("%s %s const { return %s; }",
type_->DataTypeConstRefStr().c_str(),
env->RValue(id_),
env->LValue(id_));
out_h->println("%s %s const { return %s; }", type_->DataTypeConstRefStr().c_str(),
env->RValue(id_), env->LValue(id_));
}
void StateVar::GenSetFunction(Output *out_h, Env *env)
void StateVar::GenSetFunction(Output* out_h, Env* env)
{
out_h->println("void %s(%s x) { %s = x; }",
set_function(id_).c_str(),
type_->DataTypeConstRefStr().c_str(),
env->LValue(id_));
out_h->println("void %s(%s x) { %s = x; }", set_function(id_).c_str(),
type_->DataTypeConstRefStr().c_str(), env->LValue(id_));
}
void StateVar::GenInitCode(Output *out_cc, Env *env)
{
}
void StateVar::GenInitCode(Output* out_cc, Env* env) { }
void StateVar::GenCleanUpCode(Output *out_cc, Env *env)
{
}
void StateVar::GenCleanUpCode(Output* out_cc, Env* env) { }

View file

@ -6,23 +6,22 @@
#include "pac_common.h"
class StateVar
{
{
public:
StateVar(ID *id, Type *type)
: id_(id), type_(type) {}
StateVar(ID* id, Type* type) : id_(id), type_(type) { }
const ID *id() const { return id_; }
Type *type() const { return type_; }
const ID* id() const { return id_; }
Type* type() const { return type_; }
void GenDecl(Output *out_h, Env *env);
void GenAccessFunction(Output *out_h, Env *env);
void GenSetFunction(Output *out_h, Env *env);
void GenInitCode(Output *out_cc, Env *env);
void GenCleanUpCode(Output *out_cc, Env *env);
void GenDecl(Output* out_h, Env* env);
void GenAccessFunction(Output* out_h, Env* env);
void GenSetFunction(Output* out_h, Env* env);
void GenInitCode(Output* out_cc, Env* env);
void GenCleanUpCode(Output* out_cc, Env* env);
private:
ID *id_;
Type *type_;
};
ID* id_;
Type* type_;
};
#endif // pac_state_h
#endif // pac_state_h

View file

@ -1,3 +1,5 @@
#include "pac_strtype.h"
#include "pac_attr.h"
#include "pac_btype.h"
#include "pac_cstr.h"
@ -8,27 +10,23 @@
#include "pac_id.h"
#include "pac_output.h"
#include "pac_regex.h"
#include "pac_strtype.h"
#include "pac_varfield.h"
const char *StringType::kStringTypeName = "bytestring";
const char *StringType::kConstStringTypeName = "const_bytestring";
const char* StringType::kStringTypeName = "bytestring";
const char* StringType::kConstStringTypeName = "const_bytestring";
StringType::StringType(StringTypeEnum anystr)
: Type(STRING), type_(ANYSTR), str_(0), regex_(0)
StringType::StringType(StringTypeEnum anystr) : Type(STRING), type_(ANYSTR), str_(0), regex_(0)
{
ASSERT(anystr == ANYSTR);
init();
}
StringType::StringType(ConstString *str)
: Type(STRING), type_(CSTR), str_(str), regex_(0)
StringType::StringType(ConstString* str) : Type(STRING), type_(CSTR), str_(str), regex_(0)
{
init();
}
StringType::StringType(RegEx *regex)
: Type(STRING), type_(REGEX), str_(0), regex_(regex)
StringType::StringType(RegEx* regex) : Type(STRING), type_(REGEX), str_(0), regex_(regex)
{
ASSERT(regex_);
init();
@ -52,9 +50,9 @@ StringType::~StringType()
delete elem_datatype_;
}
Type *StringType::DoClone() const
Type* StringType::DoClone() const
{
StringType *clone;
StringType* clone;
switch ( type_ )
{
@ -82,16 +80,15 @@ bool StringType::DefineValueVar() const
string StringType::DataTypeStr() const
{
return strfmt("%s",
persistent() ? kStringTypeName : kConstStringTypeName);
return strfmt("%s", persistent() ? kStringTypeName : kConstStringTypeName);
}
Type *StringType::ElementDataType() const
Type* StringType::ElementDataType() const
{
return elem_datatype_;
}
void StringType::ProcessAttr(Attr *a)
void StringType::ProcessAttr(Attr* a)
{
Type::ProcessAttr(a);
@ -101,9 +98,8 @@ void StringType::ProcessAttr(Attr *a)
{
if ( type_ != ANYSTR )
{
throw Exception(a,
"&chunked can be applied"
" to only type bytestring");
throw Exception(a, "&chunked can be applied"
" to only type bytestring");
}
attr_chunked_ = true;
SetBoundaryChecked();
@ -114,9 +110,8 @@ void StringType::ProcessAttr(Attr *a)
{
if ( type_ != ANYSTR )
{
throw Exception(a,
"&restofdata can be applied"
" to only type bytestring");
throw Exception(a, "&restofdata can be applied"
" to only type bytestring");
}
attr_restofdata_ = true;
// As the string automatically extends to the end of
@ -129,9 +124,8 @@ void StringType::ProcessAttr(Attr *a)
{
if ( type_ != ANYSTR )
{
throw Exception(a,
"&restofflow can be applied"
" to only type bytestring");
throw Exception(a, "&restofflow can be applied"
" to only type bytestring");
}
attr_restofflow_ = true;
// As the string automatically extends to the end of
@ -149,10 +143,9 @@ void StringType::Prepare(Env* env, int flags)
{
if ( (flags & TO_BE_PARSED) && StaticSize(env) < 0 )
{
ID *string_length_var = new ID(strfmt("%s_string_length",
value_var() ? value_var()->Name() : "val"));
string_length_var_field_ = new TempVarField(
string_length_var, extern_type_int->Clone());
ID* string_length_var = new ID(
strfmt("%s_string_length", value_var() ? value_var()->Name() : "val"));
string_length_var_field_ = new TempVarField(string_length_var, extern_type_int->Clone());
string_length_var_field_->Prepare(env);
}
Type::Prepare(env, flags);
@ -211,17 +204,15 @@ int StringType::StaticSize(Env* env) const
}
}
const ID *StringType::string_length_var() const
const ID* StringType::string_length_var() const
{
return string_length_var_field_ ? string_length_var_field_->id() : 0;
}
void StringType::GenDynamicSize(Output* out_cc, Env* env,
const DataPtr& data)
void StringType::GenDynamicSize(Output* out_cc, Env* env, const DataPtr& data)
{
ASSERT(StaticSize(env) < 0);
DEBUG_MSG("Generating dynamic size for string `%s'\n",
value_var()->Name());
DEBUG_MSG("Generating dynamic size for string `%s'\n", value_var()->Name());
if ( env->Evaluated(string_length_var()) )
return;
@ -244,15 +235,12 @@ void StringType::GenDynamicSize(Output* out_cc, Env* env,
if ( ! incremental_input() && AddSizeVar(out_cc, env) )
{
out_cc->println("%s = %s;",
env->LValue(size_var()),
env->RValue(string_length_var()));
out_cc->println("%s = %s;", env->LValue(size_var()), env->RValue(string_length_var()));
env->SetEvaluated(size_var());
}
}
string StringType::GenStringSize(Output* out_cc, Env* env,
const DataPtr& data)
string StringType::GenStringSize(Output* out_cc, Env* env, const DataPtr& data)
{
int static_size = StaticSize(env);
if ( static_size >= 0 )
@ -261,8 +249,7 @@ string StringType::GenStringSize(Output* out_cc, Env* env,
return env->RValue(string_length_var());
}
void StringType::DoGenParseCode(Output* out_cc, Env* env,
const DataPtr& data, int flags)
void StringType::DoGenParseCode(Output* out_cc, Env* env, const DataPtr& data, int flags)
{
string str_size = GenStringSize(out_cc, env, data);
@ -283,8 +270,7 @@ void StringType::DoGenParseCode(Output* out_cc, Env* env,
int len;
if ( type_ == ANYSTR && attr_length_expr_ &&
attr_length_expr_->ConstFold(env, &len) )
if ( type_ == ANYSTR && attr_length_expr_ && attr_length_expr_->ConstFold(env, &len) )
{
// can check for a negative length now
if ( len < 0 )
@ -293,41 +279,31 @@ void StringType::DoGenParseCode(Output* out_cc, Env* env,
else
{
out_cc->println("// check for negative sizes");
out_cc->println("if ( %s < 0 )",
str_size.c_str());
out_cc->println(
"throw binpac::ExceptionInvalidStringLength(\"%s\", %s);",
Location(), str_size.c_str());
out_cc->println("if ( %s < 0 )", str_size.c_str());
out_cc->println("throw binpac::ExceptionInvalidStringLength(\"%s\", %s);", Location(),
str_size.c_str());
}
out_cc->println("%s.init(%s, %s);",
env->LValue(value_var()),
data.ptr_expr(),
str_size.c_str());
out_cc->println("%s.init(%s, %s);", env->LValue(value_var()), data.ptr_expr(),
str_size.c_str());
}
if ( parsing_complete_var() )
{
out_cc->println("%s = true;",
env->LValue(parsing_complete_var()));
out_cc->println("%s = true;", env->LValue(parsing_complete_var()));
}
}
void StringType::GenStringMismatch(Output* out_cc, Env* env,
const DataPtr& data, string pattern)
void StringType::GenStringMismatch(Output* out_cc, Env* env, const DataPtr& data, string pattern)
{
string tmp =
strfmt("string((const char *) (%s), (const char *) %s).c_str()",
data.ptr_expr(),
env->RValue(end_of_data));
out_cc->println("throw binpac::ExceptionStringMismatch(\"%s\", %s, %s);",
Location(),
pattern.c_str(),
tmp.c_str());
string tmp = strfmt("string((const char *) (%s), (const char *) %s).c_str()", data.ptr_expr(),
env->RValue(end_of_data));
out_cc->println("throw binpac::ExceptionStringMismatch(\"%s\", %s, %s);", Location(),
pattern.c_str(), tmp.c_str());
}
void StringType::GenCheckingCStr(Output* out_cc, Env* env,
const DataPtr& data, const string &str_size)
void StringType::GenCheckingCStr(Output* out_cc, Env* env, const DataPtr& data,
const string& str_size)
{
// TODO: extend it for dynamic strings
ASSERT(type_ == CSTR);
@ -337,10 +313,8 @@ void StringType::GenCheckingCStr(Output* out_cc, Env* env,
string str_val = str_->str();
// Compare the string and report error on mismatch
out_cc->println("if ( memcmp(%s, %s, %s) != 0 )",
data.ptr_expr(),
str_val.c_str(),
str_size.c_str());
out_cc->println("if ( memcmp(%s, %s, %s) != 0 )", data.ptr_expr(), str_val.c_str(),
str_size.c_str());
out_cc->inc_indent();
out_cc->println("{");
GenStringMismatch(out_cc, env, data, str_val);
@ -348,36 +322,28 @@ void StringType::GenCheckingCStr(Output* out_cc, Env* env,
out_cc->dec_indent();
}
void StringType::GenDynamicSizeRegEx(Output* out_cc, Env* env,
const DataPtr& data)
void StringType::GenDynamicSizeRegEx(Output* out_cc, Env* env, const DataPtr& data)
{
// string_length_var =
// matcher.match_prefix(
// begin,
// end);
out_cc->println("%s = ",
env->LValue(string_length_var()));
out_cc->println("%s = ", env->LValue(string_length_var()));
out_cc->inc_indent();
out_cc->println("%s.%s(",
env->RValue(regex_->matcher_id()),
RegEx::kMatchPrefix);
out_cc->println("%s.%s(", env->RValue(regex_->matcher_id()), RegEx::kMatchPrefix);
out_cc->inc_indent();
out_cc->println("%s,",
data.ptr_expr());
out_cc->println("%s - %s);",
env->RValue(end_of_data),
data.ptr_expr());
out_cc->println("%s,", data.ptr_expr());
out_cc->println("%s - %s);", env->RValue(end_of_data), data.ptr_expr());
out_cc->dec_indent();
out_cc->dec_indent();
env->SetEvaluated(string_length_var());
out_cc->println("if ( %s < 0 )",
env->RValue(string_length_var()));
out_cc->println("if ( %s < 0 )", env->RValue(string_length_var()));
out_cc->inc_indent();
out_cc->println("{");
string tmp = strfmt("\"%s\"", regex_->str().c_str());
@ -386,41 +352,34 @@ void StringType::GenDynamicSizeRegEx(Output* out_cc, Env* env,
out_cc->dec_indent();
}
void StringType::GenDynamicSizeAnyStr(Output* out_cc, Env* env,
const DataPtr& data)
void StringType::GenDynamicSizeAnyStr(Output* out_cc, Env* env, const DataPtr& data)
{
ASSERT(type_ == ANYSTR);
if ( attr_restofdata_ || attr_oneline_ )
{
out_cc->println("%s = (%s) - (%s);",
env->LValue(string_length_var()),
env->RValue(end_of_data),
data.ptr_expr());
out_cc->println("%s = (%s) - (%s);", env->LValue(string_length_var()),
env->RValue(end_of_data), data.ptr_expr());
}
else if ( attr_restofflow_ )
{
out_cc->println("%s = (%s) - (%s);",
env->LValue(string_length_var()),
env->RValue(end_of_data),
data.ptr_expr());
out_cc->println("%s = (%s) - (%s);", env->LValue(string_length_var()),
env->RValue(end_of_data), data.ptr_expr());
}
else if ( attr_length_expr_ )
{
out_cc->println("%s = %s;",
env->LValue(string_length_var()),
attr_length_expr_->EvalExpr(out_cc, env));
out_cc->println("%s = %s;", env->LValue(string_length_var()),
attr_length_expr_->EvalExpr(out_cc, env));
}
else
{
throw Exception(this,
"cannot determine length of bytestring");
throw Exception(this, "cannot determine length of bytestring");
}
env->SetEvaluated(string_length_var());
}
bool StringType::DoTraverse(DataDepVisitor *visitor)
bool StringType::DoTraverse(DataDepVisitor* visitor)
{
if ( ! Type::DoTraverse(visitor) )
return false;

View file

@ -5,19 +5,24 @@
// TODO: question: shall we merge it with ArrayType?
class StringType : public Type
{
{
public:
enum StringTypeEnum { CSTR, REGEX, ANYSTR };
enum StringTypeEnum
{
CSTR,
REGEX,
ANYSTR
};
explicit StringType(StringTypeEnum anystr);
explicit StringType(ConstString *str);
explicit StringType(RegEx *regex);
explicit StringType(ConstString* str);
explicit StringType(RegEx* regex);
~StringType();
bool DefineValueVar() const;
string DataTypeStr() const;
string DefaultValue() const { return "0"; }
Type *ElementDataType() const;
string DefaultValue() const { return "0"; }
Type* ElementDataType() const;
void Prepare(Env* env, int flags);
@ -31,9 +36,9 @@ public:
int StaticSize(Env* env) const;
bool IsPointerType() const { return false; }
bool IsPointerType() const { return false; }
void ProcessAttr(Attr *a);
void ProcessAttr(Attr* a);
protected:
void init();
@ -43,40 +48,39 @@ protected:
string GenStringSize(Output* out_cc, Env* env, const DataPtr& data);
// Generate a string mismatch exception
void GenStringMismatch(Output* out_cc, Env* env,
const DataPtr& data, string pattern);
void GenStringMismatch(Output* out_cc, Env* env, const DataPtr& data, string pattern);
void DoGenParseCode(Output* out, Env* env, const DataPtr& data, int flags);
void GenCheckingCStr(Output* out, Env* env,
const DataPtr& data, const string &str_size);
void GenCheckingCStr(Output* out, Env* env, const DataPtr& data, const string& str_size);
void GenDynamicSize(Output* out, Env* env, const DataPtr& data);
void GenDynamicSizeAnyStr(Output* out_cc, Env* env, const DataPtr& data);
void GenDynamicSizeRegEx(Output* out_cc, Env* env, const DataPtr& data);
Type *DoClone() const;
Type* DoClone() const;
// TODO: insensitive towards byte order till we support unicode
bool ByteOrderSensitive() const { return false; }
bool ByteOrderSensitive() const { return false; }
protected:
bool DoTraverse(DataDepVisitor *visitor);
bool DoTraverse(DataDepVisitor* visitor);
private:
const ID *string_length_var() const;
const ID* string_length_var() const;
StringTypeEnum type_;
ConstString *str_;
RegEx *regex_;
Field *string_length_var_field_;
Type *elem_datatype_;
ConstString* str_;
RegEx* regex_;
Field* string_length_var_field_;
Type* elem_datatype_;
public:
static void static_init();
private:
static const char *kStringTypeName;
static const char *kConstStringTypeName;
};
#endif // pac_strtype_h
private:
static const char* kStringTypeName;
static const char* kConstStringTypeName;
};
#endif // pac_strtype_h

View file

@ -1,3 +1,5 @@
#include "pac_type.h"
#include "pac_action.h"
#include "pac_array.h"
#include "pac_attr.h"
@ -14,16 +16,13 @@
#include "pac_output.h"
#include "pac_paramtype.h"
#include "pac_strtype.h"
#include "pac_type.h"
#include "pac_utils.h"
#include "pac_varfield.h"
#include "pac_withinput.h"
Type::type_map_t Type::type_map_;
Type::Type(TypeType tot)
: DataDepElement(DataDepElement::TYPE), tot_(tot)
Type::Type(TypeType tot) : DataDepElement(DataDepElement::TYPE), tot_(tot)
{
type_decl_ = 0;
type_decl_id_ = current_decl_id;
@ -75,7 +74,7 @@ Type::~Type()
delete parsing_state_var_field_;
delete buffering_state_var_field_;
delete has_value_field_;
delete [] size_expr_;
delete[] size_expr_;
delete_list(FieldList, fields_);
delete attrs_;
delete attr_byteorder_expr_;
@ -86,43 +85,43 @@ Type::~Type()
delete_list(ExprList, attr_requires_);
}
Type *Type::Clone() const
Type* Type::Clone() const
{
Type *clone = DoClone();
Type* clone = DoClone();
if ( clone )
{
foreach(i, FieldList, fields_)
foreach (i, FieldList, fields_)
{
Field *f = *i;
Field* f = *i;
clone->AddField(f);
}
foreach(i, AttrList, attrs_)
foreach (i, AttrList, attrs_)
{
Attr *a = *i;
Attr* a = *i;
clone->ProcessAttr(a);
}
}
return clone;
}
string Type::EvalMember(const ID *member_id) const
string Type::EvalMember(const ID* member_id) const
{
ASSERT(0);
return "@@@";
}
string Type::EvalElement(const string &array, const string &index) const
string Type::EvalElement(const string& array, const string& index) const
{
return strfmt("%s[%s]", array.c_str(), index.c_str());
}
const ID *Type::decl_id() const
const ID* Type::decl_id() const
{
return type_decl_id_;
}
void Type::set_type_decl(const TypeDecl *decl, bool declared_as_type)
void Type::set_type_decl(const TypeDecl* decl, bool declared_as_type)
{
type_decl_ = decl;
type_decl_id_ = decl->id();
@ -130,7 +129,7 @@ void Type::set_type_decl(const TypeDecl *decl, bool declared_as_type)
}
void Type::set_value_var(const ID* arg_id, int arg_id_type)
{
{
value_var_ = arg_id;
value_var_type_ = arg_id_type;
@ -138,12 +137,12 @@ void Type::set_value_var(const ID* arg_id, int arg_id_type)
anonymous_value_var_ = value_var_->is_anonymous();
}
const ID *Type::size_var() const
const ID* Type::size_var() const
{
return size_var_field_ ? size_var_field_->id() : 0;
}
void Type::AddField(Field *f)
void Type::AddField(Field* f)
{
ASSERT(f);
fields_->push_back(f);
@ -179,23 +178,22 @@ void Type::ProcessAttr(Attr* a)
case ATTR_LET:
{
LetAttr *letattr = static_cast<LetAttr *>(a);
LetAttr* letattr = static_cast<LetAttr*>(a);
if ( ! attr_letfields_ )
attr_letfields_ = letattr->letfields();
else
{
// Append to attr_letfields_
attr_letfields_->insert(
attr_letfields_->end(),
letattr->letfields()->begin(),
letattr->letfields()->end());
attr_letfields_->insert(attr_letfields_->end(), letattr->letfields()->begin(),
letattr->letfields()->end());
}
}
break;
case ATTR_LINEBREAKER:
if (strlen(a->expr()->orig()) != 6 )
throw Exception(this, "invalid line breaker length, must be a single ASCII character. (Ex: \"\\001\".)");
if ( strlen(a->expr()->orig()) != 6 )
throw Exception(this, "invalid line breaker length, must be a single ASCII "
"character. (Ex: \"\\001\".)");
attr_linebreaker_ = a->expr();
break;
@ -232,7 +230,7 @@ void Type::ProcessAttr(Attr* a)
attrs_->push_back(a);
}
string Type::EvalByteOrder(Output *out_cc, Env *env) const
string Type::EvalByteOrder(Output* out_cc, Env* env) const
{
// If &byteorder is specified for a field, rather
// than a type declaration, we do not add a byteorder variable
@ -251,8 +249,7 @@ void Type::Prepare(Env* env, int flags)
// The name of the value variable
if ( value_var() )
{
data_id_str_ = strfmt("%s:%s",
decl_id()->Name(), value_var()->Name());
data_id_str_ = strfmt("%s:%s", decl_id()->Name(), value_var()->Name());
}
else
{
@ -261,13 +258,11 @@ void Type::Prepare(Env* env, int flags)
if ( value_var() )
{
env_->AddID(value_var(),
static_cast<IDType>(value_var_type_),
this);
env_->AddID(value_var(), static_cast<IDType>(value_var_type_), this);
lvalue_ = strfmt("%s", env_->LValue(value_var()));
}
foreach(i, FieldList, attr_letfields_)
foreach (i, FieldList, attr_letfields_)
{
AddField(*i);
}
@ -275,55 +270,47 @@ void Type::Prepare(Env* env, int flags)
if ( attr_exportsourcedata_ )
{
ASSERT(flags & TO_BE_PARSED);
AddField(new PubVarField(sourcedata_id->clone(),
extern_type_const_bytestring->Clone()));
AddField(new PubVarField(sourcedata_id->clone(), extern_type_const_bytestring->Clone()));
}
// An optional field
if ( attr_if_expr() )
{
ASSERT(value_var());
ID *has_value_id = new ID(strfmt("has_%s", value_var()->Name()));
has_value_field_ = new LetField(has_value_id,
extern_type_bool->Clone(),
attr_if_expr());
ID* has_value_id = new ID(strfmt("has_%s", value_var()->Name()));
has_value_field_ = new LetField(has_value_id, extern_type_bool->Clone(), attr_if_expr());
AddField(has_value_field_);
}
if ( incremental_input() )
{
ASSERT(flags & TO_BE_PARSED);
ID *parsing_complete_var =
new ID(strfmt("%s_parsing_complete",
value_var() ? value_var()->Name() : "val"));
DEBUG_MSG("Adding parsing complete var: %s\n",
parsing_complete_var->Name());
parsing_complete_var_field_ = new TempVarField(
parsing_complete_var, extern_type_bool->Clone());
ID* parsing_complete_var = new ID(
strfmt("%s_parsing_complete", value_var() ? value_var()->Name() : "val"));
DEBUG_MSG("Adding parsing complete var: %s\n", parsing_complete_var->Name());
parsing_complete_var_field_ = new TempVarField(parsing_complete_var,
extern_type_bool->Clone());
parsing_complete_var_field_->Prepare(env);
if ( NeedsBufferingStateVar() &&
! env->GetDataType(buffering_state_id) )
if ( NeedsBufferingStateVar() && ! env->GetDataType(buffering_state_id) )
{
buffering_state_var_field_ = new PrivVarField(
buffering_state_id->clone(),
extern_type_int->Clone());
buffering_state_var_field_ = new PrivVarField(buffering_state_id->clone(),
extern_type_int->Clone());
AddField(buffering_state_var_field_);
}
if ( incremental_parsing() && tot_ == RECORD )
{
ASSERT(! parsing_state_var_field_);
parsing_state_var_field_ = new PrivVarField(
parsing_state_id->clone(),
extern_type_int->Clone());
parsing_state_var_field_ = new PrivVarField(parsing_state_id->clone(),
extern_type_int->Clone());
AddField(parsing_state_var_field_);
}
}
foreach (i, FieldList, fields_)
{
Field *f = *i;
Field* f = *i;
f->Prepare(env);
}
}
@ -333,19 +320,17 @@ void Type::GenPubDecls(Output* out_h, Env* env)
if ( DefineValueVar() )
{
if ( attr_if_expr_ )
out_h->println("%s %s const { BINPAC_ASSERT(%s); return %s; }",
DataTypeConstRefStr().c_str(),
env->RValue(value_var()),
env->RValue(has_value_var()), lvalue());
out_h->println("%s %s const { BINPAC_ASSERT(%s); return %s; }",
DataTypeConstRefStr().c_str(), env->RValue(value_var()),
env->RValue(has_value_var()), lvalue());
else
out_h->println("%s %s const { return %s; }",
DataTypeConstRefStr().c_str(),
env->RValue(value_var()), lvalue());
out_h->println("%s %s const { return %s; }", DataTypeConstRefStr().c_str(),
env->RValue(value_var()), lvalue());
}
foreach (i, FieldList, fields_)
{
Field *f = *i;
Field* f = *i;
f->GenPubDecls(out_h, env);
}
}
@ -354,14 +339,12 @@ void Type::GenPrivDecls(Output* out_h, Env* env)
{
if ( DefineValueVar() )
{
out_h->println("%s %s;",
DataTypeStr().c_str(),
env->LValue(value_var()));
out_h->println("%s %s;", DataTypeStr().c_str(), env->LValue(value_var()));
}
foreach (i, FieldList, fields_)
{
Field *f = *i;
Field* f = *i;
f->GenPrivDecls(out_h, env);
}
}
@ -370,20 +353,18 @@ void Type::GenInitCode(Output* out_cc, Env* env)
{
foreach (i, FieldList, fields_)
{
Field *f = *i;
Field* f = *i;
f->GenInitCode(out_cc, env);
}
if ( parsing_state_var_field_ )
{
out_cc->println("%s = 0;",
env->LValue(parsing_state_var_field_->id()));
out_cc->println("%s = 0;", env->LValue(parsing_state_var_field_->id()));
}
if ( buffering_state_var_field_ )
{
out_cc->println("%s = 0;",
env->LValue(buffering_state_var_field_->id()));
out_cc->println("%s = 0;", env->LValue(buffering_state_var_field_->id()));
}
}
@ -391,13 +372,13 @@ void Type::GenCleanUpCode(Output* out_cc, Env* env)
{
foreach (i, FieldList, fields_)
{
Field *f = *i;
Field* f = *i;
if ( f->tof() != CASE_FIELD )
f->GenCleanUpCode(out_cc, env);
}
}
void Type::GenBufferConfiguration(Output *out_cc, Env *env)
void Type::GenBufferConfiguration(Output* out_cc, Env* env)
{
ASSERT(buffer_input());
@ -410,12 +391,11 @@ void Type::GenBufferConfiguration(Output *out_cc, Env *env)
case BUFFER_BY_LENGTH:
if ( ! NeedsBufferingStateVar() )
break;
break;
if ( buffering_state_var_field_ )
{
out_cc->println("if ( %s == 0 )",
env->RValue(buffering_state_id));
out_cc->println("if ( %s == 0 )", env->RValue(buffering_state_id));
out_cc->inc_indent();
out_cc->println("{");
}
@ -435,36 +415,30 @@ void Type::GenBufferConfiguration(Output *out_cc, Env *env)
ASSERT(0);
}
out_cc->println("%s->NewFrame(%s, %s);",
env->LValue(flow_buffer_id),
frame_buffer_arg.c_str(),
attr_chunked() ? "true" : "false");
out_cc->println("%s->NewFrame(%s, %s);", env->LValue(flow_buffer_id),
frame_buffer_arg.c_str(), attr_chunked() ? "true" : "false");
if ( buffering_state_var_field_ )
{
out_cc->println("%s = 1;",
env->LValue(buffering_state_id));
out_cc->println("%s = 1;", env->LValue(buffering_state_id));
out_cc->println("}");
out_cc->dec_indent();
}
break;
case BUFFER_BY_LINE:
out_cc->println("if ( %s == 0 )",
env->RValue(buffering_state_id));
out_cc->println("if ( %s == 0 )", env->RValue(buffering_state_id));
out_cc->inc_indent();
out_cc->println("{");
if ( BufferableWithLineBreaker() )
out_cc->println("%s->SetLineBreaker((unsigned char*)%s);",
env->LValue(flow_buffer_id), LineBreaker()->orig());
env->LValue(flow_buffer_id), LineBreaker()->orig());
else
out_cc->println("%s->UnsetLineBreaker();",
env->LValue(flow_buffer_id));
out_cc->println("%s->NewLine();",
env->LValue(flow_buffer_id));
out_cc->println("%s->UnsetLineBreaker();", env->LValue(flow_buffer_id));
out_cc->println("%s = 1;",
env->LValue(buffering_state_id));
out_cc->println("%s->NewLine();", env->LValue(flow_buffer_id));
out_cc->println("%s = 1;", env->LValue(buffering_state_id));
out_cc->println("}");
out_cc->dec_indent();
break;
@ -475,7 +449,7 @@ void Type::GenBufferConfiguration(Output *out_cc, Env *env)
}
}
void Type::GenPreParsing(Output *out_cc, Env *env)
void Type::GenPreParsing(Output* out_cc, Env* env)
{
if ( incremental_input() && IsPointerType() )
{
@ -519,14 +493,12 @@ void Type::GenParseCode(Output* out_cc, Env* env, const DataPtr& data, int flags
{
parsing_complete_var_field_->GenTempDecls(out_cc, env);
out_cc->println("%s = false;",
env->LValue(parsing_complete_var()));
out_cc->println("%s = false;", env->LValue(parsing_complete_var()));
env->SetEvaluated(parsing_complete_var());
if ( buffer_mode() == BUFFER_NOTHING )
{
out_cc->println("%s = true;",
env->LValue(parsing_complete_var()));
out_cc->println("%s = true;", env->LValue(parsing_complete_var()));
}
else if ( buffer_input() )
{
@ -540,20 +512,17 @@ void Type::GenParseCode(Output* out_cc, Env* env, const DataPtr& data, int flags
}
else
{
if ( attr_length_expr_)
if ( attr_length_expr_ )
{
EvalLengthExpr(out_cc, env);
GenBoundaryCheck(out_cc, env, data);
out_cc->println("{");
out_cc->println("// Setting %s with &length",
env->RValue(end_of_data));
out_cc->println("%s %s = %s + %s;",
extern_type_const_byteptr->DataTypeStr().c_str(),
env->LValue(end_of_data),
data.ptr_expr(),
EvalLengthExpr(out_cc, env).c_str());
out_cc->println("// Setting %s with &length", env->RValue(end_of_data));
out_cc->println("%s %s = %s + %s;", extern_type_const_byteptr->DataTypeStr().c_str(),
env->LValue(end_of_data), data.ptr_expr(),
EvalLengthExpr(out_cc, env).c_str());
GenParseCode2(out_cc, env, data, flags);
@ -568,9 +537,8 @@ void Type::GenParseCode(Output* out_cc, Env* env, const DataPtr& data, int flags
void Type::GenBufferingLoop(Output* out_cc, Env* env, int flags)
{
out_cc->println("while ( ! %s && %s->ready() )",
env->LValue(parsing_complete_var()),
env->LValue(flow_buffer_id));
out_cc->println("while ( ! %s && %s->ready() )", env->LValue(parsing_complete_var()),
env->LValue(flow_buffer_id));
out_cc->inc_indent();
out_cc->println("{");
@ -586,22 +554,18 @@ void Type::GenParseBuffer(Output* out_cc, Env* env, int flags)
{
ASSERT(incremental_input());
const ID *data_begin;
const ID* data_begin;
if ( ! incremental_parsing() )
{
env->AddID(begin_of_data, TEMP_VAR, extern_type_const_byteptr);
env->AddID(end_of_data, TEMP_VAR, extern_type_const_byteptr);
out_cc->println("%s %s = %s->begin();",
env->DataTypeStr(begin_of_data).c_str(),
env->LValue(begin_of_data),
env->RValue(flow_buffer_id));
out_cc->println("%s %s = %s->begin();", env->DataTypeStr(begin_of_data).c_str(),
env->LValue(begin_of_data), env->RValue(flow_buffer_id));
out_cc->println("%s %s = %s->end();",
env->DataTypeStr(end_of_data).c_str(),
env->LValue(end_of_data),
env->RValue(flow_buffer_id));
out_cc->println("%s %s = %s->end();", env->DataTypeStr(end_of_data).c_str(),
env->LValue(end_of_data), env->RValue(flow_buffer_id));
env->SetEvaluated(begin_of_data);
env->SetEvaluated(end_of_data);
@ -615,9 +579,8 @@ void Type::GenParseBuffer(Output* out_cc, Env* env, int flags)
{
if ( incremental_parsing() )
{
throw Exception(this,
"cannot handle &until($input...) "
"for incrementally parsed type");
throw Exception(this, "cannot handle &until($input...) "
"for incrementally parsed type");
}
array_until_input_->GenUntilInputCheck(out_cc, env);
}
@ -627,8 +590,7 @@ void Type::GenParseBuffer(Output* out_cc, Env* env, int flags)
if ( attr_length_expr() )
{
ASSERT(buffer_mode() == BUFFER_BY_LENGTH);
out_cc->println("switch ( %s )",
env->LValue(buffering_state_id));
out_cc->println("switch ( %s )", env->LValue(buffering_state_id));
out_cc->inc_indent();
out_cc->println("{");
out_cc->println("case 0:");
@ -646,9 +608,8 @@ void Type::GenParseBuffer(Output* out_cc, Env* env, int flags)
out_cc->println("%s = 2;", env->LValue(buffering_state_id));
Env frame_length_env(env, this);
out_cc->println("%s->GrowFrame(%s);",
env->LValue(flow_buffer_id),
attr_length_expr_->EvalExpr(out_cc, &frame_length_env));
out_cc->println("%s->GrowFrame(%s);", env->LValue(flow_buffer_id),
attr_length_expr_->EvalExpr(out_cc, &frame_length_env));
out_cc->println("}");
out_cc->println("break;");
@ -656,20 +617,16 @@ void Type::GenParseBuffer(Output* out_cc, Env* env, int flags)
out_cc->println("case 2:");
out_cc->inc_indent();
out_cc->println("BINPAC_ASSERT(%s->ready());",
env->RValue(flow_buffer_id));
out_cc->println("if ( %s->ready() )",
env->RValue(flow_buffer_id));
out_cc->println("BINPAC_ASSERT(%s->ready());", env->RValue(flow_buffer_id));
out_cc->println("if ( %s->ready() )", env->RValue(flow_buffer_id));
out_cc->inc_indent();
out_cc->println("{");
Env parse_env(env, this);
GenParseCode2(out_cc, &parse_env, data, 0);
out_cc->println("BINPAC_ASSERT(%s);",
parsing_complete(env).c_str());
out_cc->println("%s = 0;",
env->LValue(buffering_state_id));
out_cc->println("BINPAC_ASSERT(%s);", parsing_complete(env).c_str());
out_cc->println("%s = 0;", env->LValue(buffering_state_id));
out_cc->println("}");
out_cc->dec_indent();
@ -679,8 +636,7 @@ void Type::GenParseBuffer(Output* out_cc, Env* env, int flags)
out_cc->println("default:");
out_cc->inc_indent();
out_cc->println("BINPAC_ASSERT(%s <= 2);",
env->LValue(buffering_state_id));
out_cc->println("BINPAC_ASSERT(%s <= 2);", env->LValue(buffering_state_id));
out_cc->println("break;");
out_cc->dec_indent();
@ -689,8 +645,7 @@ void Type::GenParseBuffer(Output* out_cc, Env* env, int flags)
}
else if ( attr_restofflow_ )
{
out_cc->println("BINPAC_ASSERT(%s->eof());",
env->RValue(flow_buffer_id));
out_cc->println("BINPAC_ASSERT(%s->eof());", env->RValue(flow_buffer_id));
GenParseCode2(out_cc, env, data, 0);
}
else if ( buffer_mode() == BUFFER_BY_LINE )
@ -702,8 +657,7 @@ void Type::GenParseBuffer(Output* out_cc, Env* env, int flags)
GenParseCode2(out_cc, env, data, 0);
}
void Type::GenParseCode2(Output* out_cc, Env* env,
const DataPtr& data, int flags)
void Type::GenParseCode2(Output* out_cc, Env* env, const DataPtr& data, int flags)
{
DEBUG_MSG("GenParseCode2 for %s\n", data_id_str_.c_str());
@ -711,23 +665,18 @@ void Type::GenParseCode2(Output* out_cc, Env* env,
{
if ( incremental_parsing() )
{
throw Exception(this,
"cannot export raw data for incrementally parsed types");
throw Exception(this, "cannot export raw data for incrementally parsed types");
}
out_cc->println("%s = const_bytestring(%s, %s);",
env->LValue(sourcedata_id),
data.ptr_expr(),
env->RValue(end_of_data));
out_cc->println("%s = const_bytestring(%s, %s);", env->LValue(sourcedata_id),
data.ptr_expr(), env->RValue(end_of_data));
env->SetEvaluated(sourcedata_id);
GenParseCode3(out_cc, env, data, flags);
string datasize_str = DataSize(out_cc, env, data);
out_cc->println("%s.set_end(%s + %s);",
env->LValue(sourcedata_id),
data.ptr_expr(),
datasize_str.c_str());
out_cc->println("%s.set_end(%s + %s);", env->LValue(sourcedata_id), data.ptr_expr(),
datasize_str.c_str());
}
else
{
@ -737,15 +686,15 @@ void Type::GenParseCode2(Output* out_cc, Env* env,
void Type::GenParseCode3(Output* out_cc, Env* env, const DataPtr& data, int flags)
{
foreach(i, ExprList, attr_requires_)
foreach (i, ExprList, attr_requires_)
{
Expr *req = *i;
Expr* req = *i;
req->EvalExpr(out_cc, env);
}
foreach(i, FieldList, fields_)
foreach (i, FieldList, fields_)
{
Field *f = *i;
Field* f = *i;
f->GenTempDecls(out_cc, env);
}
@ -759,17 +708,17 @@ void Type::GenParseCode3(Output* out_cc, Env* env, const DataPtr& data, int flag
}
out_cc->println("// Evaluate 'let' and 'withinput' fields");
foreach(i, FieldList, fields_)
foreach (i, FieldList, fields_)
{
Field *f = *i;
Field* f = *i;
if ( f->tof() == LET_FIELD )
{
LetField *lf = static_cast<LetField *>(f);
LetField* lf = static_cast<LetField*>(f);
lf->GenParseCode(out_cc, env);
}
else if ( f->tof() == WITHINPUT_FIELD )
{
WithInputField *af = static_cast<WithInputField *>(f);
WithInputField* af = static_cast<WithInputField*>(f);
af->GenParseCode(out_cc, env);
}
}
@ -791,7 +740,7 @@ void Type::GenParseCode3(Output* out_cc, Env* env, const DataPtr& data, int flag
if ( size_var() )
ASSERT(env->Evaluated(size_var()));
foreach(i, ExprList, attr_enforces_)
foreach (i, ExprList, attr_enforces_)
{
Expr* enforce = *i;
const char* enforce_expr = enforce->EvalExpr(out_cc, env);
@ -803,20 +752,19 @@ void Type::GenParseCode3(Output* out_cc, Env* env, const DataPtr& data, int flag
out_cc->println("}");
out_cc->dec_indent();
}
}
Type *Type::MemberDataType(const ID *member_id) const
Type* Type::MemberDataType(const ID* member_id) const
{
DEBUG_MSG("MemberDataType: %s::%s\n", type_decl_id_->Name(), member_id->Name());
ASSERT(env_);
env_->set_allow_undefined_id(true);
Type *t = env_->GetDataType(member_id);
Type* t = env_->GetDataType(member_id);
env_->set_allow_undefined_id(false);
return t;
}
Type *Type::ElementDataType() const
Type* Type::ElementDataType() const
{
return 0;
}
@ -837,13 +785,12 @@ bool Type::AddSizeVar(Output* out_cc, Env* env)
ASSERT(! incremental_input());
ID *size_var_id = new ID(strfmt("%s__size",
value_var() ? value_var()->Name() : decl_id()->Name()));
ID* size_var_id = new ID(
strfmt("%s__size", value_var() ? value_var()->Name() : decl_id()->Name()));
DEBUG_MSG("adding size var `%s' to env %p\n", size_var_id->Name(), env);
size_var_field_ = new TempVarField(
size_var_id, extern_type_int->Clone());
size_var_field_ = new TempVarField(size_var_id, extern_type_int->Clone());
size_var_field_->Prepare(env);
size_var_field_->GenTempDecls(out_cc, env);
@ -852,7 +799,7 @@ bool Type::AddSizeVar(Output* out_cc, Env* env)
string Type::EvalLengthExpr(Output* out_cc, Env* env)
{
ASSERT(!incremental_input());
ASSERT(! incremental_input());
ASSERT(attr_length_expr_);
int static_length;
if ( attr_length_expr_->ConstFold(env, &static_length) )
@ -860,9 +807,8 @@ string Type::EvalLengthExpr(Output* out_cc, Env* env)
// How do we make sure size_var is evaluated with attr_length_expr_?
if ( AddSizeVar(out_cc, env) )
{
out_cc->println("%s = %s;",
env->LValue(size_var()),
attr_length_expr_->EvalExpr(out_cc, env));
out_cc->println("%s = %s;", env->LValue(size_var()),
attr_length_expr_->EvalExpr(out_cc, env));
env->SetEvaluated(size_var());
}
return env->RValue(size_var());
@ -890,15 +836,12 @@ string Type::DataSize(Output* out_cc, Env* env, const DataPtr& data)
}
}
void Type::GenBoundaryCheck(Output* out_cc, Env* env,
const DataPtr& data)
void Type::GenBoundaryCheck(Output* out_cc, Env* env, const DataPtr& data)
{
if ( boundary_checked() )
return;
data.GenBoundaryCheck(out_cc, env,
DataSize(out_cc, env, data).c_str(),
data_id_str_.c_str());
data.GenBoundaryCheck(out_cc, env, DataSize(out_cc, env, data).c_str(), data_id_str_.c_str());
SetBoundaryChecked();
}
@ -928,7 +871,7 @@ bool Type::RequiresByteOrder() const
bool Type::NeedsBufferingStateVar() const
{
if ( !incremental_input() )
if ( ! incremental_input() )
return false;
switch ( buffer_mode() )
{
@ -938,14 +881,14 @@ bool Type::NeedsBufferingStateVar() const
case BUFFER_BY_LINE:
return true;
case BUFFER_BY_LENGTH:
return ( attr_length_expr_ || attr_restofflow_ );
return (attr_length_expr_ || attr_restofflow_);
default:
ASSERT(0);
return false;
}
}
bool Type::DoTraverse(DataDepVisitor *visitor)
bool Type::DoTraverse(DataDepVisitor* visitor)
{
foreach (i, FieldList, fields_)
{
@ -953,7 +896,7 @@ bool Type::DoTraverse(DataDepVisitor *visitor)
return false;
}
foreach(i, AttrList, attrs_)
foreach (i, AttrList, attrs_)
{
if ( ! (*i)->Traverse(visitor) )
return false;
@ -971,12 +914,12 @@ bool Type::RequiresAnalyzerContext()
foreach (i, FieldList, fields_)
{
Field *f = *i;
Field* f = *i;
if ( f->RequiresAnalyzerContext() )
return true;
}
foreach(i, AttrList, attrs_)
foreach (i, AttrList, attrs_)
if ( (*i)->RequiresAnalyzerContext() )
return true;
@ -985,14 +928,13 @@ bool Type::RequiresAnalyzerContext()
bool Type::IsEmptyType() const
{
return ( StaticSize(global_env()) == 0 );
return (StaticSize(global_env()) == 0);
}
void Type::MarkIncrementalInput()
{
DEBUG_MSG("Handle incremental input for %s.%s\n",
decl_id()->Name(),
value_var() ? value_var()->Name() : "*");
DEBUG_MSG("Handle incremental input for %s.%s\n", decl_id()->Name(),
value_var() ? value_var()->Name() : "*");
incremental_input_ = true;
if ( Bufferable() )
@ -1049,7 +991,7 @@ Type::BufferMode Type::buffer_mode() const
return NOT_BUFFERABLE;
}
const ID *Type::parsing_complete_var() const
const ID* Type::parsing_complete_var() const
{
if ( parsing_complete_var_field_ )
return parsing_complete_var_field_->id();
@ -1057,13 +999,13 @@ const ID *Type::parsing_complete_var() const
return 0;
}
string Type::parsing_complete(Env *env) const
string Type::parsing_complete(Env* env) const
{
ASSERT(parsing_complete_var());
return env->RValue(parsing_complete_var());
}
const ID *Type::has_value_var() const
const ID* Type::has_value_var() const
{
if ( has_value_field_ )
return has_value_field_->id();
@ -1078,7 +1020,7 @@ int Type::InitialBufferLength() const
return attr_length_expr_->MinimalHeaderSize(env());
}
bool Type::CompatibleTypes(Type *type1, Type *type2)
bool Type::CompatibleTypes(Type* type1, Type* type2)
{
// If we cannot deduce one of the data types, assume that
// they are compatible.
@ -1097,17 +1039,15 @@ bool Type::CompatibleTypes(Type *type1, Type *type2)
return false;
}
switch( type1->tot() )
switch ( type1->tot() )
{
case UNDEF:
case EMPTY:
return true;
case BUILTIN:
{
BuiltInType *t1 =
static_cast<BuiltInType *>(type1);
BuiltInType *t2 =
static_cast<BuiltInType *>(type2);
BuiltInType* t1 = static_cast<BuiltInType*>(type1);
BuiltInType* t2 = static_cast<BuiltInType*>(type2);
return BuiltInType::CompatibleBuiltInTypes(t1, t2);
}
@ -1120,12 +1060,9 @@ bool Type::CompatibleTypes(Type *type1, Type *type2)
case ARRAY:
{
ArrayType *t1 =
static_cast<ArrayType *>(type1);
ArrayType *t2 =
static_cast<ArrayType *>(type2);
return CompatibleTypes(t1->ElementDataType(),
t2->ElementDataType());
ArrayType* t1 = static_cast<ArrayType*>(type1);
ArrayType* t2 = static_cast<ArrayType*>(type2);
return CompatibleTypes(t1->ElementDataType(), t2->ElementDataType());
}
default:
@ -1134,7 +1071,7 @@ bool Type::CompatibleTypes(Type *type1, Type *type2)
}
}
Type *Type::LookUpByID(ID *id)
Type* Type::LookUpByID(ID* id)
{
// 1. Is it a pre-defined type?
string name = id->Name();
@ -1144,7 +1081,7 @@ Type *Type::LookUpByID(ID *id)
}
// 2. Is it a simple declared type?
Type *type = TypeDecl::LookUpType(id);
Type* type = TypeDecl::LookUpType(id);
if ( type )
{
// Note: as a Type is always associated with a variable,
@ -1153,10 +1090,10 @@ Type *Type::LookUpByID(ID *id)
{
case Type::BUILTIN:
case Type::EXTERN:
case Type::STRING:
case Type::STRING:
return type->Clone();
case Type::ARRAY:
case Type::ARRAY:
default:
break;
}
@ -1165,7 +1102,7 @@ Type *Type::LookUpByID(ID *id)
return new ParameterizedType(id, 0);
}
void Type::AddPredefinedType(const string &type_name, Type *type)
void Type::AddPredefinedType(const string& type_name, Type* type)
{
ASSERT(type_map_.find(type_name) == type_map_.end());
type_map_[type_name] = type;

View file

@ -9,9 +9,10 @@ using namespace std;
#include "pac_dbg.h"
class Type : public Object, public DataDepElement
{
{
public:
enum TypeType {
enum TypeType
{
UNDEF = -1,
EMPTY,
BUILTIN,
@ -22,31 +23,31 @@ public:
STRING,
EXTERN,
DUMMY,
};
};
explicit Type(TypeType tot);
virtual ~Type();
Type *Clone() const;
Type* Clone() const;
// Type of type
TypeType tot() const { return tot_; }
TypeType tot() const { return tot_; }
////////////////////////////////////////
// Code generation
virtual void Prepare(Env *env, int flags);
virtual void Prepare(Env* env, int flags);
// Flag(s) for Prepare()
static const int TO_BE_PARSED = 1;
virtual void GenPubDecls(Output *out, Env *env);
virtual void GenPrivDecls(Output *out, Env *env);
virtual void GenPubDecls(Output* out, Env* env);
virtual void GenPrivDecls(Output* out, Env* env);
virtual void GenInitCode(Output *out, Env *env);
virtual void GenCleanUpCode(Output *out, Env *env);
virtual void GenInitCode(Output* out, Env* env);
virtual void GenCleanUpCode(Output* out, Env* env);
void GenPreParsing(Output *out, Env *env);
void GenParseCode(Output *out, Env *env, const DataPtr& data, int flags);
void GenPreParsing(Output* out, Env* env);
void GenParseCode(Output* out, Env* env, const DataPtr& data, int flags);
////////////////////////////////////////
// TODO: organize the various methods below
@ -57,50 +58,51 @@ public:
// if the type appears in a type decl, then the lvalue is the
// default value var.
//
const char *lvalue() const { return lvalue_.c_str(); }
const char* lvalue() const { return lvalue_.c_str(); }
// The TypeDecl that defined the type.
//
const TypeDecl *type_decl() const { return type_decl_; }
void set_type_decl(const TypeDecl *decl, bool declared_as_type);
const TypeDecl* type_decl() const { return type_decl_; }
void set_type_decl(const TypeDecl* decl, bool declared_as_type);
// Returns whether the type appears in a type declaration
// (true) or as type specification of a field (false).
//
bool declared_as_type() const { return declared_as_type_; }
bool declared_as_type() const { return declared_as_type_; }
// The ID of the decl in which the type appear.
//
const ID *decl_id() const;
const ID* decl_id() const;
Env *env() const { return env_; }
Env* env() const { return env_; }
string EvalByteOrder(Output *out_cc, Env *env) const;
string EvalByteOrder(Output* out_cc, Env* env) const;
virtual string EvalMember(const ID *member_id) const;
virtual string EvalElement(const string &array,
const string &index) const;
virtual string EvalMember(const ID* member_id) const;
virtual string EvalElement(const string& array, const string& index) const;
// The variable defined by the type
const ID *value_var() const { return value_var_; }
void set_value_var(const ID *arg_id, int arg_id_type);
const ID* value_var() const { return value_var_; }
void set_value_var(const ID* arg_id, int arg_id_type);
bool anonymous_value_var() const { return anonymous_value_var_; }
bool anonymous_value_var() const { return anonymous_value_var_; }
const ID *size_var() const;
const ID* size_var() const;
// Adds a variable to env to represent the size of this type.
// Returns false if we do not need a size variable (because
// the type has a static size) or the size variable is already added.
bool AddSizeVar(Output *out, Env *env);
bool AddSizeVar(Output* out, Env* env);
const ID *parsing_state_var() const;
const ID* parsing_state_var() const;
const ID *has_value_var() const;
const ID* has_value_var() const;
void AddField(Field *f);
void AddField(Field* f);
void AddCheck(Expr *expr) { /* TODO */ }
void AddCheck(Expr* expr)
{ /* TODO */
}
virtual bool DefineValueVar() const = 0;
@ -120,14 +122,15 @@ public:
// Returns a default value for the type
virtual string DefaultValue() const
{
ASSERT(0); return "@@@";
ASSERT(0);
return "@@@";
}
// Returns the data type of the member field/case
virtual Type *MemberDataType(const ID *member_id) const;
virtual Type* MemberDataType(const ID* member_id) const;
// Returns the data type of the element type of an array
virtual Type *ElementDataType() const;
virtual Type* ElementDataType() const;
// Whether the type needs clean-up at deallocation.
bool NeedsCleanUp() const;
@ -139,37 +142,34 @@ public:
virtual bool RequiresAnalyzerContext();
virtual bool IsPointerType() const = 0;
virtual bool IsNumericType() const { return false; }
virtual bool IsNumericType() const { return false; }
bool IsEmptyType() const;
////////////////////////////////////////
// Attributes
virtual void ProcessAttr(Attr *a);
virtual void ProcessAttr(Attr* a);
bool attr_chunked() const { return attr_chunked_; }
Expr *attr_byteorder_expr() const { return attr_byteorder_expr_; }
Expr *attr_if_expr() const { return attr_if_expr_; }
bool attr_chunked() const { return attr_chunked_; }
Expr* attr_byteorder_expr() const { return attr_byteorder_expr_; }
Expr* attr_if_expr() const { return attr_if_expr_; }
// TODO: generate the length expression automatically.
Expr *attr_length_expr() const { return attr_length_expr_; }
bool attr_refcount() const { return attr_refcount_; }
bool attr_transient() const { return attr_transient_; }
Expr* attr_length_expr() const { return attr_length_expr_; }
bool attr_refcount() const { return attr_refcount_; }
bool attr_transient() const { return attr_transient_; }
// Whether the value remains valid outside the parse function
bool persistent() const
{
return ! attr_transient() && ! attr_chunked();
}
bool persistent() const { return ! attr_transient() && ! attr_chunked(); }
void SetUntilCheck(ArrayType *t) { array_until_input_ = t; }
void SetUntilCheck(ArrayType* t) { array_until_input_ = t; }
////////////////////////////////////////
// Size and boundary checking
virtual int StaticSize(Env *env) const = 0;
string DataSize(Output *out, Env *env, const DataPtr& data);
virtual int StaticSize(Env* env) const = 0;
string DataSize(Output* out, Env* env, const DataPtr& data);
bool boundary_checked() const { return boundary_checked_; }
virtual void SetBoundaryChecked() { boundary_checked_ = true; }
void GenBoundaryCheck(Output *out, Env *env, const DataPtr& data);
bool boundary_checked() const { return boundary_checked_; }
virtual void SetBoundaryChecked() { boundary_checked_ = true; }
void GenBoundaryCheck(Output* out, Env* env, const DataPtr& data);
////////////////////////////////////////
// Handling incremental input
@ -185,17 +185,17 @@ public:
virtual void DoMarkIncrementalInput();
// Whether the type may receive incremental input
bool incremental_input() const { return incremental_input_; }
bool incremental_input() const { return incremental_input_; }
// Whether parsing should also be incremental
bool incremental_parsing() const { return incremental_parsing_; }
bool incremental_parsing() const { return incremental_parsing_; }
// Whether we should buffer the input
bool buffer_input() const { return buffer_input_; }
bool buffer_input() const { return buffer_input_; }
// Whether parsing of the type is completed
const ID *parsing_complete_var() const;
string parsing_complete(Env *env) const;
const ID* parsing_complete_var() const;
string parsing_complete(Env* env) const;
// Whether the input is bufferable
bool Bufferable() const;
@ -204,20 +204,21 @@ public:
bool BufferableWithLineBreaker() const;
Expr* LineBreaker() const;
enum BufferMode {
enum BufferMode
{
NOT_BUFFERABLE,
BUFFER_NOTHING, // for type "empty"
BUFFER_NOTHING, // for type "empty"
BUFFER_BY_LENGTH,
BUFFER_BY_LINE,
};
};
virtual BufferMode buffer_mode() const;
void GenBufferConfiguration(Output *out, Env *env);
void GenBufferConfiguration(Output* out, Env* env);
int InitialBufferLength() const;
protected:
virtual void GenNewInstance(Output *out, Env *env) {}
virtual void GenNewInstance(Output* out, Env* env) { }
virtual bool ByteOrderSensitive() const = 0;
@ -228,86 +229,83 @@ protected:
void GenParseCode2(Output* out_cc, Env* env, const DataPtr& data, int flags);
void GenParseCode3(Output* out_cc, Env* env, const DataPtr& data, int flags);
virtual void DoGenParseCode(Output *out, Env *env,
const DataPtr& data,
int flags) = 0;
virtual void DoGenParseCode(Output* out, Env* env, const DataPtr& data, int flags) = 0;
string EvalLengthExpr(Output* out_cc, Env* env);
// Generate code for computing the dynamic size of the type
virtual void GenDynamicSize(Output *out, Env *env,
const DataPtr& data) = 0;
virtual void GenDynamicSize(Output* out, Env* env, const DataPtr& data) = 0;
bool DoTraverse(DataDepVisitor *visitor);
bool DoTraverse(DataDepVisitor* visitor);
virtual Type *DoClone() const = 0;
virtual Type* DoClone() const = 0;
protected:
TypeType tot_;
const TypeDecl *type_decl_;
const TypeDecl* type_decl_;
bool declared_as_type_;
const ID *type_decl_id_;
Env *env_;
const ID* type_decl_id_;
Env* env_;
const ID *value_var_;
bool anonymous_value_var_; // whether the ID is anonymous
const ID* value_var_;
bool anonymous_value_var_; // whether the ID is anonymous
string data_id_str_;
int value_var_type_;
Field *size_var_field_;
char *size_expr_;
Field* size_var_field_;
char* size_expr_;
bool boundary_checked_;
string lvalue_;
FieldList *fields_;
FieldList* fields_;
bool incremental_input_;
bool incremental_parsing_;
bool buffer_input_;
// A boolean variable on whether parsing of the type is completed
Field *parsing_complete_var_field_;
Field* parsing_complete_var_field_;
// An integer variable holding the parsing state
Field *parsing_state_var_field_;
Field* parsing_state_var_field_;
Field *buffering_state_var_field_;
Field* buffering_state_var_field_;
// The array type with &until($input...) condition, if
// "this" is the element type
ArrayType *array_until_input_;
ArrayType* array_until_input_;
// A "has_*" member var for fields with &if
LetField *has_value_field_;
LetField* has_value_field_;
// Attributes
AttrList *attrs_;
AttrList* attrs_;
Expr *attr_byteorder_expr_;
ExprList *attr_checks_;
ExprList *attr_enforces_;
Expr* attr_byteorder_expr_;
ExprList* attr_checks_;
ExprList* attr_enforces_;
bool attr_chunked_;
bool attr_exportsourcedata_;
Expr *attr_if_expr_;
Expr *attr_length_expr_;
FieldList *attr_letfields_;
Expr *attr_multiline_end_;
Expr *attr_linebreaker_;
Expr* attr_if_expr_;
Expr* attr_length_expr_;
FieldList* attr_letfields_;
Expr* attr_multiline_end_;
Expr* attr_linebreaker_;
bool attr_oneline_;
bool attr_refcount_;
ExprList *attr_requires_;
ExprList* attr_requires_;
bool attr_restofdata_;
bool attr_restofflow_;
bool attr_transient_;
public:
static void init();
static bool CompatibleTypes(Type *type1, Type *type2);
static void AddPredefinedType(const string &type_name, Type *type);
static Type *LookUpByID(ID *id);
static bool CompatibleTypes(Type* type1, Type* type2);
static void AddPredefinedType(const string& type_name, Type* type);
static Type* LookUpByID(ID* id);
protected:
typedef map<string, Type *> type_map_t;
typedef map<string, Type*> type_map_t;
static type_map_t type_map_;
};
};
#endif // pac_type_h
#endif // pac_type_h

View file

@ -1,3 +1,5 @@
#include "pac_typedecl.h"
#include "pac_attr.h"
#include "pac_context.h"
#include "pac_dataptr.h"
@ -12,7 +14,6 @@
#include "pac_paramtype.h"
#include "pac_record.h"
#include "pac_type.h"
#include "pac_typedecl.h"
#include "pac_utils.h"
TypeDecl::TypeDecl(ID* id, ParamList* params, Type* type)
@ -35,7 +36,7 @@ void TypeDecl::ProcessAttr(Attr* a)
type_->ProcessAttr(a);
}
void TypeDecl::AddParam(Param *param)
void TypeDecl::AddParam(Param* param)
{
// Cannot work after Prepare()
ASSERT(! env_);
@ -65,11 +66,9 @@ void TypeDecl::Prepare()
if ( type_->attr_byteorder_expr() )
{
DEBUG_MSG("Adding byteorder field to %s\n",
id()->Name());
type_->AddField(new LetField(byteorder_id->clone(),
extern_type_int,
type_->attr_byteorder_expr()));
DEBUG_MSG("Adding byteorder field to %s\n", id()->Name());
type_->AddField(
new LetField(byteorder_id->clone(), extern_type_int, type_->attr_byteorder_expr()));
}
type_->Prepare(env_, Type::TO_BE_PARSED);
@ -99,13 +98,11 @@ void TypeDecl::GenCode(Output* out_h, Output* out_cc)
if ( RequiresAnalyzerContext::compute(type_) )
{
DEBUG_MSG("%s requires analyzer context\n",
id()->Name());
Type *param_type = analyzer_context()->param_type();
DEBUG_MSG("%s requires analyzer context\n", id()->Name());
Type* param_type = analyzer_context()->param_type();
env_->AddID(analyzer_context_id, TEMP_VAR, param_type);
env_->SetEvaluated(analyzer_context_id);
env_->AddMacro(context_macro_id,
new Expr(analyzer_context_id->clone()));
env_->AddMacro(context_macro_id, new Expr(analyzer_context_id->clone()));
}
// Add parameter "byteorder"
@ -170,30 +167,25 @@ void TypeDecl::GenCode(Output* out_h, Output* out_cc)
out_h->println("};\n");
}
void TypeDecl::GenPubDecls(Output* out_h, Output *out_cc)
void TypeDecl::GenPubDecls(Output* out_h, Output* out_cc)
{
// GenParamPubDecls(params_, out_h, env_);
}
void TypeDecl::GenPrivDecls(Output* out_h, Output *out_cc)
void TypeDecl::GenPrivDecls(Output* out_h, Output* out_cc)
{
// GenParamPrivDecls(params_, out_h, env_);
}
void TypeDecl::GenInitCode(Output *out_cc)
{
}
void TypeDecl::GenInitCode(Output* out_cc) { }
void TypeDecl::GenCleanUpCode(Output *out_cc)
{
}
void TypeDecl::GenCleanUpCode(Output* out_cc) { }
void TypeDecl::GenConstructorFunc(Output* out_h, Output* out_cc)
{
string params_str = ParamDecls(params_);
string proto =
strfmt("%s(%s)", class_name().c_str(), params_str.c_str());
string proto = strfmt("%s(%s)", class_name().c_str(), params_str.c_str());
out_h->println("%s;", proto.c_str());
@ -230,32 +222,29 @@ void TypeDecl::GenDestructorFunc(Output* out_h, Output* out_cc)
string TypeDecl::ParseFuncPrototype(Env* env)
{
const char *func_name = 0;
const char *return_type = 0;
const char* func_name = 0;
const char* return_type = 0;
string params;
if ( type_->incremental_input() )
{
func_name = kParseFuncWithBuffer;
return_type = "bool";
params = strfmt("flow_buffer_t %s",
env->LValue(flow_buffer_id));
params = strfmt("flow_buffer_t %s", env->LValue(flow_buffer_id));
}
else
{
func_name = kParseFuncWithoutBuffer;
return_type = "int";
params = strfmt("const_byteptr const %s, const_byteptr const %s",
env->LValue(begin_of_data),
env->LValue(end_of_data));
env->LValue(begin_of_data), env->LValue(end_of_data));
}
if ( RequiresAnalyzerContext::compute(type_) )
{
Type *param_type = analyzer_context()->param_type();
params += strfmt(", %s %s",
param_type->DataTypeConstRefStr().c_str(),
env->LValue(analyzer_context_id));
Type* param_type = analyzer_context()->param_type();
params += strfmt(", %s %s", param_type->DataTypeConstRefStr().c_str(),
env->LValue(analyzer_context_id));
}
// Add parameter "byteorder"
@ -265,11 +254,10 @@ string TypeDecl::ParseFuncPrototype(Env* env)
}
// Returns "<return type> %s<func name>(<params>)%s".
return strfmt("%s %%s%s(%s)%%s",
return_type, func_name, params.c_str());
return strfmt("%s %%s%s(%s)%%s", return_type, func_name, params.c_str());
}
void TypeDecl::GenParsingEnd(Output *out_cc, Env *env, const DataPtr &data)
void TypeDecl::GenParsingEnd(Output* out_cc, Env* env, const DataPtr& data)
{
string ret_val_0, ret_val_1;
@ -283,27 +271,23 @@ void TypeDecl::GenParsingEnd(Output *out_cc, Env *env, const DataPtr &data)
ret_val_0 = type_->DataSize(0, env, data).c_str();
ret_val_1 = "@@@";
out_cc->println("BINPAC_ASSERT(%s + (%s) <= %s);",
env->RValue(begin_of_data),
ret_val_0.c_str(),
env->RValue(end_of_data));
out_cc->println("BINPAC_ASSERT(%s + (%s) <= %s);", env->RValue(begin_of_data),
ret_val_0.c_str(), env->RValue(end_of_data));
}
if ( type_->incremental_parsing() &&
( type_->tot() == Type::RECORD || type_->tot() == Type::ARRAY ) )
(type_->tot() == Type::RECORD || type_->tot() == Type::ARRAY) )
{
// In which case parsing may jump to label
// "need_more_data" ...
out_cc->println("BINPAC_ASSERT(%s);",
type_->parsing_complete(env).c_str());
out_cc->println("BINPAC_ASSERT(%s);", type_->parsing_complete(env).c_str());
out_cc->println("return %s;", ret_val_0.c_str());
out_cc->println("");
out_cc->dec_indent();
out_cc->println("%s:", kNeedMoreData);
out_cc->inc_indent();
out_cc->println("BINPAC_ASSERT(!(%s));",
type_->parsing_complete(env).c_str());
out_cc->println("BINPAC_ASSERT(!(%s));", type_->parsing_complete(env).c_str());
out_cc->println("return %s;", ret_val_1.c_str());
}
else if ( type_->incremental_input() )
@ -323,7 +307,7 @@ void TypeDecl::GenParseFunc(Output* out_h, Output* out_cc)
// Env within the parse function
Env p_func_env(env_, this);
Env *env = &p_func_env;
Env* env = &p_func_env;
if ( type_->incremental_input() )
{
@ -380,21 +364,19 @@ void TypeDecl::GenInitialBufferLengthFunc(Output* out_h, Output* out_cc)
int init_buffer_length = type_->InitialBufferLength();
if ( init_buffer_length < 0 ) // cannot be statically determined
if ( init_buffer_length < 0 ) // cannot be statically determined
{
throw Exception(type()->attr_length_expr(),
strfmt("cannot determine initial buffer length"
" for type %s", id_->Name()));
throw Exception(type()->attr_length_expr(), strfmt("cannot determine initial buffer length"
" for type %s",
id_->Name()));
}
out_h->println("int %s() const { return %d; }",
func.c_str(),
init_buffer_length);
out_h->println("int %s() const { return %d; }", func.c_str(), init_buffer_length);
}
Type* TypeDecl::LookUpType(const ID *id)
Type* TypeDecl::LookUpType(const ID* id)
{
Decl *decl = LookUpDecl(id);
Decl* decl = LookUpDecl(id);
if ( ! decl )
return 0;
switch ( decl->decl_type() )
@ -402,11 +384,10 @@ Type* TypeDecl::LookUpType(const ID *id)
case TYPE:
case CONN:
case FLOW:
return static_cast<TypeDecl *>(decl)->type();
return static_cast<TypeDecl*>(decl)->type();
case ENUM:
return static_cast<EnumDecl *>(decl)->DataType();
return static_cast<EnumDecl*>(decl)->DataType();
default:
return 0;
}
}

View file

@ -4,44 +4,44 @@
#include "pac_decl.h"
class TypeDecl : public Decl
{
{
public:
TypeDecl(ID *arg_id, ParamList *arg_params, Type *arg_type);
TypeDecl(ID* arg_id, ParamList* arg_params, Type* arg_type);
~TypeDecl();
void Prepare();
void GenForwardDeclaration(Output *out_h);
void GenCode(Output *out_h, Output *out_cc);
void GenForwardDeclaration(Output* out_h);
void GenCode(Output* out_h, Output* out_cc);
Env *env() const { return env_; }
Type *type() const { return type_; }
Env* env() const { return env_; }
Type* type() const { return type_; }
string class_name() const;
static Type *LookUpType(const ID *id);
static Type* LookUpType(const ID* id);
protected:
void AddParam(Param *param);
virtual void AddBaseClass(vector<string> *base_classes) const {}
void ProcessAttr(Attr *a);
void AddParam(Param* param);
virtual void AddBaseClass(vector<string>* base_classes) const { }
void ProcessAttr(Attr* a);
virtual void GenPubDecls(Output *out_h, Output *out_cc);
virtual void GenPrivDecls(Output *out_h, Output *out_cc);
virtual void GenInitCode(Output *out_cc);
virtual void GenCleanUpCode(Output *out_cc);
virtual void GenPubDecls(Output* out_h, Output* out_cc);
virtual void GenPrivDecls(Output* out_h, Output* out_cc);
virtual void GenInitCode(Output* out_cc);
virtual void GenCleanUpCode(Output* out_cc);
void GenConstructorFunc(Output *out_h, Output *out_cc);
void GenDestructorFunc(Output *out_h, Output *out_cc);
void GenConstructorFunc(Output* out_h, Output* out_cc);
void GenDestructorFunc(Output* out_h, Output* out_cc);
string ParseFuncPrototype(Env* env);
void GenParseFunc(Output *out_h, Output *out_cc);
void GenParseFunc(Output* out_h, Output* out_cc);
void GenParsingEnd(Output *out_cc, Env *env, const DataPtr &data);
void GenParsingEnd(Output* out_cc, Env* env, const DataPtr& data);
void GenInitialBufferLengthFunc(Output *out_h, Output *out_cc);
void GenInitialBufferLengthFunc(Output* out_h, Output* out_cc);
protected:
Env *env_;
Env* env_;
ParamList *params_;
Type *type_;
};
ParamList* params_;
Type* type_;
};
#endif // pac_typedecl_h
#endif // pac_typedecl_h

View file

@ -1,17 +1,18 @@
#include <stdarg.h>
#include <string.h>
#include <stdio.h>
#include "pac_utils.h"
char* copy_string(const char* s)
{
char* c = new char[strlen(s)+1];
strcpy(c, s);
return c;
}
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
namespace {
char* copy_string(const char* s)
{
char* c = new char[strlen(s) + 1];
strcpy(c, s);
return c;
}
namespace
{
const char* do_fmt(const char* format, va_list ap)
{
@ -20,7 +21,7 @@ const char* do_fmt(const char* format, va_list ap)
return buf;
}
}
}
string strfmt(const char* format, ...)
{

View file

@ -1,6 +1,6 @@
#include "pac_varfield.h"
void PrivVarField::Prepare(Env *env)
void PrivVarField::Prepare(Env* env)
{
Field::Prepare(env);
}

View file

@ -5,47 +5,53 @@
// A private variable evaluated with parsing
class ParseVarField : public Field
{
{
public:
ParseVarField(int is_class_member, ID* id, Type *type)
: Field(PARSE_VAR_FIELD,
TYPE_TO_BE_PARSED | is_class_member | NOT_PUBLIC_READABLE,
id, type) {}
void GenPubDecls(Output* out, Env* env) { /* do nothing */ }
};
ParseVarField(int is_class_member, ID* id, Type* type)
: Field(PARSE_VAR_FIELD, TYPE_TO_BE_PARSED | is_class_member | NOT_PUBLIC_READABLE, id,
type)
{
}
void GenPubDecls(Output* out, Env* env)
{ /* do nothing */
}
};
// A public variable
class PubVarField : public Field
{
{
public:
PubVarField(ID* id, Type *type)
: Field(PUB_VAR_FIELD,
TYPE_NOT_TO_BE_PARSED | CLASS_MEMBER | PUBLIC_READABLE,
id, type) {}
~PubVarField() {}
};
PubVarField(ID* id, Type* type)
: Field(PUB_VAR_FIELD, TYPE_NOT_TO_BE_PARSED | CLASS_MEMBER | PUBLIC_READABLE, id, type)
{
}
~PubVarField() { }
};
// A private variable
class PrivVarField : public Field
{
{
public:
PrivVarField(ID* id, Type *type)
: Field(PRIV_VAR_FIELD,
TYPE_NOT_TO_BE_PARSED | CLASS_MEMBER | NOT_PUBLIC_READABLE,
id, type) {}
~PrivVarField() {}
PrivVarField(ID* id, Type* type)
: Field(PRIV_VAR_FIELD, TYPE_NOT_TO_BE_PARSED | CLASS_MEMBER | NOT_PUBLIC_READABLE, id,
type)
{
}
~PrivVarField() { }
void GenPubDecls(Output* out, Env* env) { /* do nothing */ }
};
void GenPubDecls(Output* out, Env* env)
{ /* do nothing */
}
};
class TempVarField : public Field
{
{
public:
TempVarField(ID* id, Type *type)
: Field(TEMP_VAR_FIELD,
TYPE_NOT_TO_BE_PARSED | NOT_CLASS_MEMBER,
id, type) {}
~TempVarField() {}
};
TempVarField(ID* id, Type* type)
: Field(TEMP_VAR_FIELD, TYPE_NOT_TO_BE_PARSED | NOT_CLASS_MEMBER, id, type)
{
}
~TempVarField() { }
};
#endif // pac_varfield_h
#endif // pac_varfield_h

View file

@ -1,14 +1,13 @@
#include "pac_withinput.h"
#include "pac_dataptr.h"
#include "pac_expr.h"
#include "pac_inputbuf.h"
#include "pac_output.h"
#include "pac_type.h"
WithInputField::WithInputField(ID* id, Type *type, InputBuffer* input)
: Field(WITHINPUT_FIELD,
TYPE_TO_BE_PARSED | CLASS_MEMBER | PUBLIC_READABLE,
id, type),
WithInputField::WithInputField(ID* id, Type* type, InputBuffer* input)
: Field(WITHINPUT_FIELD, TYPE_TO_BE_PARSED | CLASS_MEMBER | PUBLIC_READABLE, id, type),
input_(input)
{
ASSERT(type_);
@ -20,16 +19,14 @@ WithInputField::~WithInputField()
delete input_;
}
bool WithInputField::DoTraverse(DataDepVisitor *visitor)
bool WithInputField::DoTraverse(DataDepVisitor* visitor)
{
return Field::DoTraverse(visitor) &&
input()->Traverse(visitor);
return Field::DoTraverse(visitor) && input()->Traverse(visitor);
}
bool WithInputField::RequiresAnalyzerContext() const
{
return Field::RequiresAnalyzerContext() ||
(input() && input()->RequiresAnalyzerContext());
return Field::RequiresAnalyzerContext() || (input() && input()->RequiresAnalyzerContext());
}
void WithInputField::Prepare(Env* env)
@ -43,8 +40,7 @@ void WithInputField::GenEval(Output* out_cc, Env* env)
GenParseCode(out_cc, env);
if ( type_->attr_if_expr() )
{
out_cc->println("BINPAC_ASSERT(%s);",
env->RValue(type_->has_value_var()));
out_cc->println("BINPAC_ASSERT(%s);", env->RValue(type_->has_value_var()));
}
}
@ -55,8 +51,7 @@ void WithInputField::GenParseCode(Output* out_cc, Env* env)
{
// A conditional field
env->Evaluate(out_cc, type_->has_value_var());
out_cc->println("if ( %s )",
env->RValue(type_->has_value_var()));
out_cc->println("if ( %s )", env->RValue(type_->has_value_var()));
out_cc->inc_indent();
out_cc->println("{");
}
@ -66,9 +61,7 @@ void WithInputField::GenParseCode(Output* out_cc, Env* env)
Env field_env(env, this);
ASSERT(! type_->incremental_input());
type_->GenPreParsing(out_cc, &field_env);
type_->GenParseCode(out_cc, &field_env,
input()->GenDataBeginEnd(out_cc, &field_env),
0);
type_->GenParseCode(out_cc, &field_env, input()->GenDataBeginEnd(out_cc, &field_env), 0);
if ( type_->attr_if_expr() )
{

View file

@ -6,12 +6,12 @@
#include "pac_field.h"
class WithInputField : public Field, public Evaluatable
{
{
public:
WithInputField(ID* id, Type *type, InputBuffer* input);
WithInputField(ID* id, Type* type, InputBuffer* input);
virtual ~WithInputField();
InputBuffer *input() const { return input_; }
InputBuffer* input() const { return input_; }
void Prepare(Env* env);
@ -29,10 +29,10 @@ public:
bool RequiresAnalyzerContext() const;
protected:
bool DoTraverse(DataDepVisitor *visitor);
bool DoTraverse(DataDepVisitor* visitor);
protected:
InputBuffer *input_;
};
InputBuffer* input_;
};
#endif // pac_withinput_h
#endif // pac_withinput_h