mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 06:38:20 +00:00
binpac: Add pre-commit hooks and run clang-format on everything
This commit is contained in:
parent
090ac0a6e0
commit
090325df40
91 changed files with 3086 additions and 3665 deletions
|
@ -1,25 +1,26 @@
|
|||
#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 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 void NewData(const unsigned char* begin_of_data, const unsigned char* end_of_data) = 0;
|
||||
};
|
||||
|
||||
} // namespace binpac
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h> // for memcpy
|
||||
|
||||
#define binpac_regex_h
|
||||
|
@ -7,11 +7,13 @@
|
|||
#include "binpac.h"
|
||||
#include "binpac_buffer.h"
|
||||
|
||||
namespace binpac {
|
||||
namespace binpac
|
||||
{
|
||||
|
||||
extern double network_time();
|
||||
|
||||
namespace {
|
||||
namespace
|
||||
{
|
||||
const unsigned char CR = '\r';
|
||||
const unsigned char LF = '\n';
|
||||
}
|
||||
|
@ -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,8 +118,7 @@ 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());
|
||||
}
|
||||
|
||||
|
@ -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_;
|
||||
}
|
||||
|
@ -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,8 +374,7 @@ found_end_of_line:
|
|||
message_complete_ = true;
|
||||
|
||||
#if DEBUG_FLOW_BUFFER
|
||||
fprintf(stderr, "%.6f Line complete: [%s]\n",
|
||||
network_time(),
|
||||
fprintf(stderr, "%.6f Line complete: [%s]\n", network_time(),
|
||||
string((const char*)begin(), (const char*)end()).c_str());
|
||||
#endif
|
||||
}
|
||||
|
@ -442,8 +437,7 @@ found_end_of_line:
|
|||
message_complete_ = true;
|
||||
|
||||
#if DEBUG_FLOW_BUFFER
|
||||
fprintf(stderr, "%.6f Line complete: [%s]\n",
|
||||
network_time(),
|
||||
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(),
|
||||
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,8 +508,7 @@ 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;
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
|
|
@ -2,19 +2,24 @@
|
|||
#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 {
|
||||
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
|
||||
|
@ -44,8 +49,7 @@ public:
|
|||
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,8 +71,7 @@ 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_;
|
||||
|
@ -88,8 +91,7 @@ public:
|
|||
|
||||
int data_seq() const
|
||||
{
|
||||
int data_seq_at_orig_data_begin =
|
||||
data_seq_at_orig_data_end_ -
|
||||
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;
|
||||
|
@ -101,8 +103,7 @@ public:
|
|||
|
||||
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
|
||||
|
@ -152,13 +153,15 @@ protected:
|
|||
LineBreakStyle linebreak_style_default;
|
||||
unsigned char linebreaker_;
|
||||
|
||||
enum {
|
||||
enum
|
||||
{
|
||||
UNKNOWN_MODE,
|
||||
LINE_MODE,
|
||||
FRAME_MODE,
|
||||
} mode_;
|
||||
|
||||
enum {
|
||||
enum
|
||||
{
|
||||
CR_OR_LF_0,
|
||||
CR_OR_LF_1,
|
||||
STRICT_CRLF_0,
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
#define binpac_regex_h
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "binpac_bytestring.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
namespace binpac
|
||||
{
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
|
||||
#include "binpac.h"
|
||||
|
||||
namespace binpac
|
||||
|
@ -10,29 +11,16 @@ namespace binpac
|
|||
|
||||
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)
|
||||
{
|
||||
|
@ -44,17 +32,13 @@ public:
|
|||
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)
|
||||
{
|
||||
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; }
|
||||
|
@ -67,34 +51,18 @@ private:
|
|||
|
||||
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)
|
||||
{
|
||||
|
@ -111,7 +79,8 @@ public:
|
|||
|
||||
void clear()
|
||||
{
|
||||
data_ = 0; length_ = 0;
|
||||
data_ = 0;
|
||||
length_ = 0;
|
||||
}
|
||||
|
||||
void free()
|
||||
|
@ -121,10 +90,7 @@ public:
|
|||
clear();
|
||||
}
|
||||
|
||||
void clone()
|
||||
{
|
||||
set_const(begin(), length());
|
||||
}
|
||||
void clone() { set_const(begin(), length()); }
|
||||
|
||||
datastring const& operator=(const_datastring<T> const& x)
|
||||
{
|
||||
|
@ -133,10 +99,7 @@ public:
|
|||
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_; }
|
||||
|
@ -180,15 +143,13 @@ 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();
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
#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);
|
||||
|
@ -39,23 +39,17 @@ 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:
|
||||
|
@ -67,13 +61,10 @@ protected:
|
|||
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:
|
||||
|
@ -84,13 +75,11 @@ protected:
|
|||
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:
|
||||
|
@ -101,8 +90,7 @@ protected:
|
|||
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));
|
||||
|
@ -114,8 +102,7 @@ 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));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
|
||||
class RE_Matcher;
|
||||
|
||||
namespace binpac {
|
||||
namespace binpac
|
||||
{
|
||||
|
||||
std::vector<RE_Matcher*>* uncompiled_re_matchers = 0;
|
||||
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
#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
|
||||
{
|
||||
|
@ -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*);
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
@ -43,21 +36,15 @@ void AnalyzerAction::InstallHook(AnalyzerDecl *analyzer)
|
|||
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(),
|
||||
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("{");
|
||||
|
||||
|
@ -81,8 +68,7 @@ Type *ActionParam::MainDataType() const
|
|||
|
||||
if ( ! main_type )
|
||||
{
|
||||
throw Exception(type()->type_id(),
|
||||
"type not defined");
|
||||
throw Exception(type()->type_id(), "type not defined");
|
||||
}
|
||||
|
||||
return main_type;
|
||||
|
@ -98,13 +84,11 @@ 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(),
|
||||
strfmt("cannot find member type for `%s.%s'", type()->type_id()->Name(),
|
||||
type()->field_id()->Name()));
|
||||
}
|
||||
return member_type;
|
||||
|
@ -113,7 +97,5 @@ Type *ActionParam::DataType() 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()));
|
||||
}
|
||||
|
|
|
@ -3,18 +3,19 @@
|
|||
|
||||
// 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();
|
||||
|
||||
|
@ -43,8 +44,7 @@ private:
|
|||
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_; }
|
||||
|
@ -62,7 +62,9 @@ class ActionParamType
|
|||
{
|
||||
public:
|
||||
ActionParamType(const ID* type_id, const ID* field_id = 0)
|
||||
: type_id_(type_id), field_id_(field_id) {}
|
||||
: type_id_(type_id), field_id_(field_id)
|
||||
{
|
||||
}
|
||||
|
||||
const ID* type_id() const { return type_id_; }
|
||||
const ID* field_id() const { return field_id_; }
|
||||
|
|
|
@ -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;
|
||||
|
@ -58,26 +56,21 @@ void AnalyzerDecl::AddElements(AnalyzerElementList *elemlist)
|
|||
case AnalyzerElement::STATE:
|
||||
{
|
||||
ASSERT(0);
|
||||
AnalyzerState *state_elem =
|
||||
(AnalyzerState *) elem;
|
||||
statevars_->insert(
|
||||
statevars_->end(),
|
||||
state_elem->statevars()->begin(),
|
||||
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() )
|
||||
{
|
||||
|
@ -97,8 +90,7 @@ void AnalyzerDecl::AddElements(AnalyzerElementList *elemlist)
|
|||
break;
|
||||
case AnalyzerElement::FUNCTION:
|
||||
{
|
||||
AnalyzerFunction *func_elem =
|
||||
(AnalyzerFunction *) elem;
|
||||
AnalyzerFunction* func_elem = (AnalyzerFunction*)elem;
|
||||
Function* func = func_elem->function();
|
||||
func->set_analyzer_decl(this);
|
||||
functions_->push_back(func);
|
||||
|
@ -106,15 +98,13 @@ void AnalyzerDecl::AddElements(AnalyzerElementList *elemlist)
|
|||
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;
|
||||
|
@ -304,9 +294,7 @@ void AnalyzerHelper::GenCode(Output *out_h, Output *out_cc, AnalyzerDecl *decl)
|
|||
}
|
||||
|
||||
FlowField::FlowField(ID* flow_id, ParameterizedType* flow_type)
|
||||
: Field(FLOW_FIELD,
|
||||
TYPE_NOT_TO_BE_PARSED | CLASS_MEMBER | PUBLIC_READABLE,
|
||||
flow_id, flow_type)
|
||||
: Field(FLOW_FIELD, TYPE_NOT_TO_BE_PARSED | CLASS_MEMBER | PUBLIC_READABLE, flow_id, flow_type)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -316,9 +304,7 @@ void FlowField::GenInitCode(Output *out_cc, Env *env)
|
|||
}
|
||||
|
||||
AnalyzerFlow::AnalyzerFlow(Direction dir, ID* type_id, ExprList* params)
|
||||
: AnalyzerElement(FLOW),
|
||||
dir_(dir),
|
||||
type_id_(type_id)
|
||||
: AnalyzerElement(FLOW), dir_(dir), type_id_(type_id)
|
||||
{
|
||||
if ( ! params )
|
||||
params = new ExprList();
|
||||
|
@ -350,8 +336,7 @@ FlowDecl *AnalyzerFlow::flow_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_;
|
||||
|
|
|
@ -84,9 +84,16 @@ protected:
|
|||
class AnalyzerElement : public Object
|
||||
{
|
||||
public:
|
||||
enum ElementType { STATE, ACTION, FUNCTION, HELPER, FLOW, DATAUNIT };
|
||||
AnalyzerElement(ElementType type)
|
||||
: type_(type) {}
|
||||
enum ElementType
|
||||
{
|
||||
STATE,
|
||||
ACTION,
|
||||
FUNCTION,
|
||||
HELPER,
|
||||
FLOW,
|
||||
DATAUNIT
|
||||
};
|
||||
AnalyzerElement(ElementType type) : type_(type) { }
|
||||
virtual ~AnalyzerElement() { }
|
||||
|
||||
ElementType type() const { return type_; }
|
||||
|
@ -99,9 +106,7 @@ private:
|
|||
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_; }
|
||||
|
@ -114,16 +119,17 @@ private:
|
|||
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) {}
|
||||
: AnalyzerElement(HELPER), helper_type_(helper_type), code_(code)
|
||||
{
|
||||
}
|
||||
~AnalyzerHelper();
|
||||
|
||||
Type helper_type() const { return helper_type_; }
|
||||
|
@ -149,7 +155,11 @@ public:
|
|||
class AnalyzerFlow : public AnalyzerElement
|
||||
{
|
||||
public:
|
||||
enum Direction { UP, DOWN };
|
||||
enum Direction
|
||||
{
|
||||
UP,
|
||||
DOWN
|
||||
};
|
||||
AnalyzerFlow(Direction dir, ID* type_id, ExprList* params);
|
||||
~AnalyzerFlow();
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#include "pac_array.h"
|
||||
|
||||
#include "pac_attr.h"
|
||||
#include "pac_dataptr.h"
|
||||
#include "pac_exception.h"
|
||||
|
@ -9,8 +11,6 @@
|
|||
#include "pac_utils.h"
|
||||
#include "pac_varfield.h"
|
||||
|
||||
#include "pac_array.h"
|
||||
|
||||
ArrayType::ArrayType(Type* elemtype, Expr* length)
|
||||
: Type(ARRAY), elemtype_(elemtype), length_(length)
|
||||
{
|
||||
|
@ -133,14 +133,12 @@ void ArrayType::ProcessAttr(Attr *a)
|
|||
{
|
||||
if ( elemtype_->StaticSize(env()) != 1 )
|
||||
{
|
||||
throw Exception(elemtype_,
|
||||
"&restofdata can be applied"
|
||||
throw Exception(elemtype_, "&restofdata can be applied"
|
||||
" to only byte arrays");
|
||||
}
|
||||
if ( length_ )
|
||||
{
|
||||
throw Exception(length_,
|
||||
"&restofdata cannot be applied"
|
||||
throw Exception(length_, "&restofdata cannot be applied"
|
||||
" to arrays with specified length");
|
||||
}
|
||||
attr_restofdata_ = true;
|
||||
|
@ -161,8 +159,7 @@ 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 "
|
||||
throw Exception(a->expr(), "cannot reference both $element and $input "
|
||||
"in the same &until---please separate them.");
|
||||
}
|
||||
|
||||
|
@ -170,8 +167,7 @@ void ArrayType::ProcessAttr(Attr *a)
|
|||
{
|
||||
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();
|
||||
}
|
||||
|
@ -209,42 +203,33 @@ void ArrayType::Prepare(Env *env, int flags)
|
|||
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,
|
||||
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()),
|
||||
elem_dataptr_until_expr_ = new Expr(Expr::EXPR_GE, new Expr(elem_dataptr_var->clone()),
|
||||
new Expr(end_of_data->clone()));
|
||||
}
|
||||
|
||||
|
@ -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,35 +302,28 @@ 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());
|
||||
}
|
||||
}
|
||||
|
@ -368,11 +338,9 @@ void ArrayType::GenPubDecls(Output *out_h, Env *env)
|
|||
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()),
|
||||
elemtype_->DataTypeConstRefStr().c_str(), env->RValue(value_var()),
|
||||
env->RValue(value_var()));
|
||||
}
|
||||
}
|
||||
|
@ -393,8 +361,7 @@ 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()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -406,11 +373,7 @@ void ArrayType::GenCleanUpCode(Output *out_cc, Env *env)
|
|||
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_);
|
||||
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();
|
||||
|
@ -443,21 +403,18 @@ string ArrayType::GenArrayInit(Output *out_cc, Env *env, bool known_array_length
|
|||
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,8 +426,8 @@ 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_ )
|
||||
{
|
||||
|
@ -482,21 +439,16 @@ void ArrayType::GenElementAssignment(Output *out_cc, Env *env,
|
|||
// Assign the element
|
||||
if ( ! use_vector )
|
||||
{
|
||||
out_cc->println("%s[%s] = %s;",
|
||||
array_str.c_str(),
|
||||
env->LValue(elem_it_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);
|
||||
|
||||
|
@ -530,8 +482,7 @@ void ArrayType::DoGenParseCode(Output *out_cc, Env *env,
|
|||
|
||||
if ( ! incremental_parsing() &&
|
||||
(StaticSize(env) >= 0 ||
|
||||
( env->Evaluated(arraylength_var()) &&
|
||||
elemtype_->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,11 +553,9 @@ void ArrayType::DoGenParseCode(Output *out_cc, Env *env,
|
|||
|
||||
if ( elem_dataptr_var() )
|
||||
{
|
||||
out_cc->println("%s += %s;",
|
||||
env->LValue(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()),
|
||||
out_cc->println("BINPAC_ASSERT(%s <= %s);", env->RValue(elem_dataptr_var()),
|
||||
env->RValue(end_of_data));
|
||||
}
|
||||
|
||||
|
@ -632,9 +575,7 @@ 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()),
|
||||
out_cc->println("%s = %s - (%s);", env->LValue(size_var()), env->RValue(elem_dataptr_var()),
|
||||
data.ptr_expr());
|
||||
env->SetEvaluated(size_var());
|
||||
}
|
||||
|
@ -642,45 +583,37 @@ void ArrayType::DoGenParseCode(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),
|
||||
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,17 +629,13 @@ 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_ &&
|
||||
if ( elem_w >= 0 && ! attr_until_element_expr_ && ! attr_until_input_expr_ &&
|
||||
(length_ || attr_restofdata_) )
|
||||
{
|
||||
// If the elements have a fixed size,
|
||||
|
@ -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
|
||||
|
@ -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,8 +695,7 @@ void ArrayType::DoMarkIncrementalInput()
|
|||
|
||||
bool ArrayType::RequiresAnalyzerContext()
|
||||
{
|
||||
return Type::RequiresAnalyzerContext() ||
|
||||
( length_ && length_->RequiresAnalyzerContext() ) ||
|
||||
return Type::RequiresAnalyzerContext() || (length_ && length_->RequiresAnalyzerContext()) ||
|
||||
elemtype_->RequiresAnalyzerContext();
|
||||
}
|
||||
|
||||
|
|
|
@ -43,15 +43,10 @@ protected:
|
|||
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 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;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "pac_attr.h"
|
||||
|
||||
#include "pac_expr.h"
|
||||
|
||||
bool Attr::DoTraverse(DataDepVisitor* visitor)
|
||||
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -4,7 +4,8 @@
|
|||
#include "pac_common.h"
|
||||
#include "pac_datadep.h"
|
||||
|
||||
enum AttrType {
|
||||
enum AttrType
|
||||
{
|
||||
ATTR_BYTEORDER,
|
||||
ATTR_CHECK,
|
||||
ATTR_CHUNKED,
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "pac_btype.h"
|
||||
|
||||
#include "pac_dataptr.h"
|
||||
#include "pac_id.h"
|
||||
#include "pac_output.h"
|
||||
|
@ -11,12 +12,11 @@ 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();
|
||||
}
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -66,8 +64,7 @@ string BuiltInType::DataTypeStr() const
|
|||
|
||||
int BuiltInType::StaticSize(Env* /* env */) const
|
||||
{
|
||||
static const size_t basic_type_size[] =
|
||||
{
|
||||
static const size_t basic_type_size[] = {
|
||||
#define TYPE_DEF(name, pactype, ctype, size) size,
|
||||
#include "pac_type.def"
|
||||
#undef TYPE_DEF
|
||||
|
@ -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(),
|
||||
out_cc->println("%s = FixByteOrder(%s, *((%s const *) (%s)));", lvalue(),
|
||||
EvalByteOrder(out_cc, env).c_str(), DataTypeStr().c_str(),
|
||||
data.ptr_expr());
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,8 @@
|
|||
class BuiltInType : public Type
|
||||
{
|
||||
public:
|
||||
enum BITType {
|
||||
enum BITType
|
||||
{
|
||||
#define TYPE_DEF(name, pactype, ctype, size) name,
|
||||
#include "pac_type.def"
|
||||
#undef TYPE_DEF
|
||||
|
@ -15,8 +16,9 @@ public:
|
|||
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_; }
|
||||
|
||||
|
@ -45,8 +47,7 @@ protected:
|
|||
|
||||
public:
|
||||
static void static_init();
|
||||
static bool CompatibleBuiltInTypes(BuiltInType *type1,
|
||||
BuiltInType *type2);
|
||||
static bool CompatibleBuiltInTypes(BuiltInType* type1, BuiltInType* type2);
|
||||
};
|
||||
|
||||
#endif // pac_btype_h
|
||||
|
|
|
@ -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,12 +11,6 @@
|
|||
#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)
|
||||
|
@ -73,8 +73,7 @@ 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
|
||||
CaseFieldList::iterator default_case_it = cases_->end(); // to avoid warning
|
||||
CaseField* default_case = 0;
|
||||
|
||||
foreach (i, CaseFieldList, cases_)
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -176,8 +173,7 @@ void CaseType::DoGenParseCode(Output* out_cc, Env* env,
|
|||
foreach (i, CaseFieldList, cases_)
|
||||
{
|
||||
CaseField* c = *i;
|
||||
c->GenParseCode(out_cc, env, data,
|
||||
compute_size_var ? size_var() : 0);
|
||||
c->GenParseCode(out_cc, env, data, compute_size_var ? size_var() : 0);
|
||||
if ( c->IsDefaultCase() )
|
||||
has_default_case = true;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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,8 +413,7 @@ 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();
|
||||
|
@ -441,15 +427,13 @@ void CaseField::GenParseCode(Output* out_cc, Env* env,
|
|||
type_->GenParseCode(out_cc, &case_env, data, 0);
|
||||
if ( size_var )
|
||||
{
|
||||
out_cc->println("%s = %s;",
|
||||
case_env.LValue(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()),
|
||||
out_cc->println("%s = %s;", case_env.LValue(case_type()->parsing_complete_var()),
|
||||
case_env.RValue(type_->parsing_complete_var()));
|
||||
}
|
||||
out_cc->println("}");
|
||||
|
@ -461,12 +445,10 @@ void CaseField::GenParseCode(Output* out_cc, Env* env,
|
|||
|
||||
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();
|
||||
}
|
||||
|
|
|
@ -74,8 +74,7 @@ public:
|
|||
|
||||
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 GenParseCode(Output* out, Env* env, const DataPtr& data, const ID* size_var);
|
||||
|
||||
int StaticSize(Env* env) const { return type_->StaticSize(env); }
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
@ -31,9 +30,7 @@ public:
|
|||
location = strfmt("%s:%d", filename.c_str(), line_number);
|
||||
}
|
||||
|
||||
~Object()
|
||||
{
|
||||
}
|
||||
~Object() { }
|
||||
|
||||
const char* Location() const { return location.c_str(); }
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
@ -44,8 +42,7 @@ 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;
|
||||
|
@ -54,9 +51,7 @@ void ConnDecl::ProcessFlowElement(AnalyzerFlow *flow_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()
|
||||
|
@ -89,15 +84,11 @@ 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_)
|
||||
{
|
||||
|
@ -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("}");
|
||||
|
@ -141,9 +128,7 @@ void ConnDecl::GenGapFunc(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("}");
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#ifndef pac_conn_h
|
||||
#define pac_conn_h
|
||||
|
||||
#include "pac_decl.h"
|
||||
#include "pac_analyzer.h"
|
||||
#include "pac_decl.h"
|
||||
|
||||
class ConnDecl : public AnalyzerDecl
|
||||
{
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#include "pac_context.h"
|
||||
|
||||
#include "pac_analyzer.h"
|
||||
#include "pac_exception.h"
|
||||
#include "pac_exttype.h"
|
||||
|
@ -9,18 +11,15 @@
|
|||
#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)
|
||||
: Field(CONTEXT_FIELD, TYPE_NOT_TO_BE_PARSED | CLASS_MEMBER | PUBLIC_READABLE, id, type)
|
||||
{
|
||||
}
|
||||
|
||||
AnalyzerContextDecl* AnalyzerContextDecl::current_analyzer_context_ = 0;
|
||||
|
||||
namespace {
|
||||
namespace
|
||||
{
|
||||
ParamList* ContextFieldsToParams(ContextFieldList* context_fields)
|
||||
{
|
||||
// Convert context fields to parameters
|
||||
|
@ -28,26 +27,20 @@ namespace {
|
|||
foreach (i, ContextFieldList, context_fields)
|
||||
{
|
||||
ContextField* f = *i;
|
||||
params->push_back(
|
||||
new Param(f->id()->clone(),
|
||||
f->type()));
|
||||
params->push_back(new Param(f->id()->clone(), f->type()));
|
||||
}
|
||||
return params;
|
||||
}
|
||||
} // namespace private
|
||||
|
||||
AnalyzerContextDecl::AnalyzerContextDecl(
|
||||
ID *id,
|
||||
ContextFieldList *context_fields)
|
||||
: TypeDecl(new ID(strfmt("Context%s", id->Name())),
|
||||
ContextFieldsToParams(context_fields),
|
||||
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; "
|
||||
throw Exception(this, strfmt("multiple declaration of analyzer context; "
|
||||
"the previous one is `%s'",
|
||||
current_analyzer_context_->id()->Name()));
|
||||
}
|
||||
|
@ -98,9 +91,7 @@ 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;
|
||||
}
|
||||
|
@ -109,9 +100,7 @@ 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
|
||||
|
|
|
@ -56,10 +56,7 @@ private:
|
|||
|
||||
// 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);
|
||||
|
||||
|
@ -73,21 +70,30 @@ public:
|
|||
DummyType() : Type(DUMMY) { }
|
||||
|
||||
bool DefineValueVar() const { return false; }
|
||||
string DataTypeStr() const { ASSERT(0); return ""; }
|
||||
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;
|
||||
|
|
|
@ -1,16 +1,15 @@
|
|||
#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_; }
|
||||
|
||||
|
@ -21,17 +20,31 @@ private:
|
|||
// 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':
|
||||
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;
|
||||
|
@ -59,8 +72,7 @@ int expand_escape(const char*& s)
|
|||
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)
|
||||
for ( int len = 0; len < 2 && isascii(*s) && isxdigit(*s); ++s, ++len )
|
||||
;
|
||||
|
||||
int result;
|
||||
|
@ -77,8 +89,7 @@ int expand_escape(const char*& s)
|
|||
|
||||
} // private namespace
|
||||
|
||||
ConstString::ConstString(const string &s)
|
||||
: str_(s)
|
||||
ConstString::ConstString(const string& s) : str_(s)
|
||||
{
|
||||
// Copied from scan.l of Zeek
|
||||
try
|
||||
|
@ -118,4 +129,3 @@ ConstString::ConstString(const string &s)
|
|||
throw Exception(this, e.msg().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
#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)
|
||||
{
|
||||
|
@ -61,8 +59,7 @@ void RequiresAnalyzerContext::ProcessExpr(Expr *expr)
|
|||
{
|
||||
if ( expr->expr_type() == Expr::EXPR_ID )
|
||||
{
|
||||
requires_analyzer_context_ =
|
||||
(requires_analyzer_context_ ||
|
||||
requires_analyzer_context_ = (requires_analyzer_context_ ||
|
||||
*expr->id() == *analyzer_context_id ||
|
||||
*expr->id() == *context_macro_id);
|
||||
}
|
||||
|
|
|
@ -9,9 +9,11 @@
|
|||
|
||||
class DataDepVisitor;
|
||||
|
||||
class DataDepElement {
|
||||
class DataDepElement
|
||||
{
|
||||
public:
|
||||
enum DDE_Type {
|
||||
enum DDE_Type
|
||||
{
|
||||
ATTR,
|
||||
CASEEXPR,
|
||||
EXPR,
|
||||
|
@ -39,7 +41,8 @@ protected:
|
|||
bool in_traversal;
|
||||
};
|
||||
|
||||
class DataDepVisitor {
|
||||
class DataDepVisitor
|
||||
{
|
||||
public:
|
||||
virtual ~DataDepVisitor() { }
|
||||
// Returns whether to continue traversal
|
||||
|
@ -47,7 +50,8 @@ public:
|
|||
virtual bool PostProcess(DataDepElement* element) = 0;
|
||||
};
|
||||
|
||||
class RequiresAnalyzerContext : public DataDepVisitor {
|
||||
class RequiresAnalyzerContext : public DataDepVisitor
|
||||
{
|
||||
public:
|
||||
RequiresAnalyzerContext() : requires_analyzer_context_(false) { }
|
||||
|
||||
|
@ -55,10 +59,7 @@ public:
|
|||
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);
|
||||
|
||||
|
|
|
@ -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_ )
|
||||
{
|
||||
|
@ -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;
|
||||
|
||||
out_cc->println("}");
|
||||
out_cc->dec_indent();
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,9 @@
|
|||
#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.
|
||||
|
@ -34,9 +36,7 @@ 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,
|
||||
void GenBoundaryCheck(Output* out, Env* env, const char* data_size,
|
||||
const char* data_name) const;
|
||||
|
||||
protected:
|
||||
|
|
|
@ -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,
|
||||
AnalyzerDataUnit::AnalyzerDataUnit(DataUnitType type, ID* id, ExprList* type_params,
|
||||
ExprList* context_params)
|
||||
: AnalyzerElement(DATAUNIT),
|
||||
type_(type),
|
||||
id_(id),
|
||||
type_params_(type_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()
|
||||
|
@ -43,18 +32,14 @@ void AnalyzerDataUnit::Prepare(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(),
|
||||
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)
|
||||
{
|
||||
out_cc->println("%s = new %s(%s);",
|
||||
env->LValue(analyzer_context_id),
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -9,12 +9,12 @@
|
|||
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);
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
extern bool FLAGS_pac_debug;
|
||||
|
||||
#define ASSERT(x) assert(x)
|
||||
#define DEBUG_MSG(x...) if ( FLAGS_pac_debug ) fprintf(stderr, x)
|
||||
#define DEBUG_MSG(x...) \
|
||||
if ( FLAGS_pac_debug ) \
|
||||
fprintf(stderr, x)
|
||||
|
||||
#endif /* pac_dbg_h */
|
||||
|
|
|
@ -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;
|
||||
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_ )
|
||||
|
@ -56,12 +55,10 @@ void Decl::ProcessAttr(Attr *attr)
|
|||
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -87,8 +84,7 @@ 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_)
|
||||
{
|
||||
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -9,15 +9,25 @@ 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);
|
||||
virtual ~Decl();
|
||||
|
||||
const ID* id() const { return id_; }
|
||||
DeclType decl_type() const { return decl_type_; }
|
||||
AnalyzerContextDecl *analyzer_context() const
|
||||
{ return analyzer_context_; }
|
||||
AnalyzerContextDecl* analyzer_context() const { return analyzer_context_; }
|
||||
|
||||
// NULL except for TypeDecl or AnalyzerDecl
|
||||
virtual Env* env() const { return 0; }
|
||||
|
@ -25,7 +35,9 @@ public:
|
|||
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;
|
||||
|
@ -57,15 +69,20 @@ private:
|
|||
class HelperDecl : public Decl
|
||||
{
|
||||
public:
|
||||
enum HelperType {
|
||||
HEADER, CODE, EXTERN,
|
||||
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 GenForwardDeclaration(Output* out_h)
|
||||
{ /* do nothing */
|
||||
}
|
||||
void GenCode(Output* out_h, Output* out_cc);
|
||||
|
||||
private:
|
||||
|
|
|
@ -1,18 +1,13 @@
|
|||
#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(const string& s) : s_(s), primitive_(0) { }
|
||||
|
||||
EmbeddedCodeSegment::EmbeddedCodeSegment(PacPrimitive* primitive)
|
||||
: s_(""), primitive_(primitive)
|
||||
{
|
||||
}
|
||||
: s_(""), primitive_(primitive) { }
|
||||
|
||||
EmbeddedCodeSegment::~EmbeddedCodeSegment()
|
||||
{
|
||||
|
|
|
@ -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()
|
||||
{
|
||||
|
@ -30,8 +28,7 @@ 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();
|
||||
datatype_ = new ExternType(type_id, ExternType::NUMBER);
|
||||
|
@ -67,4 +64,3 @@ void EnumDecl::GenCode(Output* out_h, Output* /* out_cc */)
|
|||
{
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
|
|
|
@ -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()));
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
@ -44,8 +45,7 @@ string EvalExprList(ExprList *exprlist, Output *out, Env *env)
|
|||
return val_list;
|
||||
}
|
||||
|
||||
static const char* expr_fmt[] =
|
||||
{
|
||||
static const char* expr_fmt[] = {
|
||||
#define EXPR_DEF(type, num_op, fmt) fmt,
|
||||
#include "pac_expr.def"
|
||||
#undef EXPR_DEF
|
||||
|
@ -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;
|
||||
|
@ -163,9 +154,7 @@ Expr::Expr(Expr *index, CaseExprList *cases)
|
|||
foreach (i, CaseExprList, cases_)
|
||||
{
|
||||
CaseExpr* c = *i;
|
||||
orig_ += strfmt("%s => %s; ",
|
||||
OrigExprList(c->index()).c_str(),
|
||||
c->value()->orig());
|
||||
orig_ += strfmt("%s => %s; ", OrigExprList(c->index()).c_str(), c->value()->orig());
|
||||
}
|
||||
orig_ += "}";
|
||||
}
|
||||
|
@ -196,18 +185,13 @@ 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(),
|
||||
str_ = strfmt(expr_fmt[expr_type_], operand_[0]->str(), operand_[1]->str(),
|
||||
operand_[2]->str());
|
||||
break;
|
||||
default:
|
||||
|
@ -217,14 +201,14 @@ 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 )
|
||||
if ( field->tof() != RECORD_FIELD && field->tof() != PADDING_FIELD )
|
||||
throw Exception(id, "not a record field");
|
||||
RecordField* r = static_cast<RecordField*>(field);
|
||||
ASSERT(r);
|
||||
|
@ -247,9 +231,7 @@ void Expr::GenCaseEval(Output *out_cc, Env *env)
|
|||
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);
|
||||
|
@ -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();
|
||||
|
@ -337,16 +316,13 @@ void Expr::GenEval(Output* out_cc, Env* 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;
|
||||
|
@ -464,7 +440,6 @@ void Expr::ForceIDEval(Output* out_cc, Env* env)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
const char* Expr::EvalExpr(Output* out_cc, Env* env)
|
||||
{
|
||||
GenEval(out_cc, env);
|
||||
|
@ -510,8 +485,7 @@ Type *Expr::DataType(Env *env) const
|
|||
if ( ! Type::CompatibleTypes(type1, type2) )
|
||||
{
|
||||
throw Exception(this,
|
||||
strfmt("type mismatch: %s vs %s",
|
||||
type1->DataTypeStr().c_str(),
|
||||
strfmt("type mismatch: %s vs %s", type1->DataTypeStr().c_str(),
|
||||
type2->DataTypeStr().c_str()));
|
||||
}
|
||||
data_type = type1;
|
||||
|
@ -526,18 +500,15 @@ 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_)
|
||||
{
|
||||
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",
|
||||
throw Exception(this, strfmt("type mismatch: %s vs %s",
|
||||
type1->DataTypeStr().c_str(),
|
||||
type2->DataTypeStr().c_str()));
|
||||
}
|
||||
|
@ -617,9 +588,7 @@ string Expr::DataTypeStr(Env *env) const
|
|||
|
||||
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();
|
||||
|
@ -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,7 +631,8 @@ 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)
|
||||
|
@ -711,8 +679,7 @@ namespace {
|
|||
{
|
||||
case LET_FIELD:
|
||||
{
|
||||
LetField *f =
|
||||
static_cast<LetField *>(field);
|
||||
LetField* f = static_cast<LetField*>(field);
|
||||
ASSERT(f);
|
||||
mhs = mhs_letfield(env, f);
|
||||
}
|
||||
|
@ -730,8 +697,7 @@ namespace {
|
|||
case RECORD_FIELD:
|
||||
case PADDING_FIELD:
|
||||
{
|
||||
RecordField *f =
|
||||
static_cast<RecordField *>(field);
|
||||
RecordField* f = static_cast<RecordField*>(field);
|
||||
ASSERT(f);
|
||||
mhs = mhs_recordfield(env, f);
|
||||
}
|
||||
|
@ -739,8 +705,7 @@ namespace {
|
|||
|
||||
case CASE_FIELD:
|
||||
{
|
||||
CaseField *f =
|
||||
static_cast<CaseField *>(field);
|
||||
CaseField* f = static_cast<CaseField*>(field);
|
||||
ASSERT(f);
|
||||
mhs = mhs_casefield(env, f);
|
||||
}
|
||||
|
@ -829,8 +794,7 @@ int Expr::MinimalHeaderSize(Env *env)
|
|||
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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -1053,8 +1014,7 @@ bool Expr::RequiresAnalyzerContext() const
|
|||
}
|
||||
|
||||
CaseExpr::CaseExpr(ExprList* index, Expr* value)
|
||||
: DataDepElement(DataDepElement::CASEEXPR),
|
||||
index_(index), value_(value)
|
||||
: DataDepElement(DataDepElement::CASEEXPR), index_(index), value_(value)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,8 @@ class CaseExpr;
|
|||
class Expr : public Object, public DataDepElement
|
||||
{
|
||||
public:
|
||||
enum ExprType {
|
||||
enum ExprType
|
||||
{
|
||||
#define EXPR_DEF(type, x, y) type,
|
||||
#include "pac_expr.def"
|
||||
#undef EXPR_DEF
|
||||
|
|
|
@ -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
|
||||
|
@ -36,9 +37,7 @@ bool ExternType::ByteOrderSensitive() 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)
|
||||
|
|
|
@ -11,11 +11,13 @@
|
|||
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;
|
||||
|
|
|
@ -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)
|
||||
: 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());
|
||||
|
@ -47,11 +47,9 @@ 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 "
|
||||
throw Exception(a, "&if can only be applied to a "
|
||||
"let field");
|
||||
}
|
||||
break;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,8 @@
|
|||
|
||||
// A "field" is a member of class.
|
||||
|
||||
enum FieldType {
|
||||
enum FieldType
|
||||
{
|
||||
CASE_FIELD,
|
||||
CONTEXT_FIELD,
|
||||
FLOW_FIELD,
|
||||
|
|
|
@ -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;
|
||||
|
@ -50,17 +48,14 @@ void FlowDecl::AddBaseClass(vector<string> *base_classes) const
|
|||
|
||||
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)
|
||||
{
|
||||
if ( dataunit_ )
|
||||
{
|
||||
throw Exception(dataunit_elem,
|
||||
"dataunit already defined");
|
||||
throw Exception(dataunit_elem, "dataunit already defined");
|
||||
}
|
||||
dataunit_ = dataunit_elem;
|
||||
|
||||
|
@ -68,8 +63,7 @@ void FlowDecl::ProcessDataUnitElement(AnalyzerDataUnit *dataunit_elem)
|
|||
{
|
||||
dataunit_->data_type()->MarkIncrementalInput();
|
||||
|
||||
flow_buffer_var_field_ = new PubVarField(
|
||||
flow_buffer_id->clone(),
|
||||
flow_buffer_var_field_ = new PubVarField(flow_buffer_id->clone(),
|
||||
FlowDecl::flow_buffer_type()->Clone());
|
||||
type_->AddField(flow_buffer_var_field_);
|
||||
|
||||
|
@ -77,8 +71,7 @@ void FlowDecl::ProcessDataUnitElement(AnalyzerDataUnit *dataunit_elem)
|
|||
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,16 +80,13 @@ 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();
|
||||
|
||||
|
@ -123,10 +113,8 @@ 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 )
|
||||
{
|
||||
|
@ -158,8 +146,7 @@ void FlowDecl::GenEOFFunc(Output *out_h, Output *out_cc)
|
|||
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -179,8 +166,7 @@ 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("}");
|
||||
|
@ -192,11 +178,8 @@ 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("}");
|
||||
|
@ -249,11 +231,9 @@ void FlowDecl::GenNewDataUnit(Output *out_cc)
|
|||
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_);
|
||||
}
|
||||
|
@ -270,13 +250,10 @@ void FlowDecl::GenCodeFlowUnit(Output *out_cc)
|
|||
{
|
||||
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));
|
||||
|
@ -286,8 +263,7 @@ void FlowDecl::GenCodeFlowUnit(Output *out_cc)
|
|||
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();
|
||||
|
@ -323,9 +297,7 @@ void FlowDecl::GenCodeDatagram(Output *out_cc)
|
|||
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) )
|
||||
{
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#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"
|
||||
|
@ -44,20 +45,15 @@ 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(),
|
||||
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_));
|
||||
|
||||
|
@ -68,8 +64,7 @@ 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(),
|
||||
out_cc->println("return static_cast<%s>(%s);", type_->DataTypeStr().c_str(),
|
||||
expr_->EvalExpr(out_cc, env_));
|
||||
|
||||
out_cc->println("}");
|
||||
|
@ -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,9 +97,7 @@ FuncDecl::~FuncDecl()
|
|||
delete function_;
|
||||
}
|
||||
|
||||
void FuncDecl::Prepare()
|
||||
{
|
||||
}
|
||||
void FuncDecl::Prepare() { }
|
||||
|
||||
void FuncDecl::GenForwardDeclaration(Output* out_h)
|
||||
{
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#ifndef pac_func_h
|
||||
#define pac_func_h
|
||||
|
||||
#include "pac_decl.h"
|
||||
#include "pac_analyzer.h"
|
||||
#include "pac_decl.h"
|
||||
|
||||
class Function : public Object
|
||||
{
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
#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"
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -295,15 +294,12 @@ void Env::SetEvaluated(const ID* id, bool v)
|
|||
Field* f = GetField(id);
|
||||
if ( f && f->tof() == LET_FIELD )
|
||||
{
|
||||
throw Exception(
|
||||
context_object_,
|
||||
strfmt("INTERNAL ERROR: "
|
||||
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()));
|
||||
id->Name(), id->Name()));
|
||||
ASSERT(0);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
@ -43,15 +44,11 @@ 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(); }
|
||||
|
||||
|
@ -69,6 +66,7 @@ protected:
|
|||
|
||||
public:
|
||||
static ID* NewAnonymousID(const string& prefix);
|
||||
|
||||
private:
|
||||
static int anonymous_id_seq;
|
||||
};
|
||||
|
@ -193,9 +191,7 @@ public:
|
|||
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);
|
||||
|
|
|
@ -1,14 +1,12 @@
|
|||
#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)
|
||||
{
|
||||
|
@ -27,15 +25,11 @@ 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);
|
||||
|
|
|
@ -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
|
||||
{
|
||||
}
|
||||
|
||||
void GenLetEval(const ID* id, Expr* expr, string prefix, Output* out, Env* env) { }
|
||||
|
||||
} // private namespace
|
||||
|
||||
LetField::LetField(ID* id, Type* type, Expr* expr)
|
||||
: Field(LET_FIELD,
|
||||
TYPE_NOT_TO_BE_PARSED | CLASS_MEMBER | PUBLIC_READABLE,
|
||||
id, type),
|
||||
: Field(LET_FIELD, TYPE_NOT_TO_BE_PARSED | CLASS_MEMBER | PUBLIC_READABLE, id, type),
|
||||
expr_(expr)
|
||||
{
|
||||
ASSERT(expr_);
|
||||
|
@ -28,14 +26,12 @@ LetField::~LetField()
|
|||
|
||||
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)
|
||||
|
@ -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,8 +100,7 @@ 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_ )
|
||||
{
|
||||
|
@ -134,19 +126,13 @@ 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)
|
||||
{
|
||||
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());
|
||||
}
|
||||
|
||||
|
@ -154,10 +140,7 @@ void LetDecl::GenEval(Output *out_cc, Env * /* 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_);
|
||||
|
|
|
@ -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();
|
||||
|
@ -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)
|
||||
|
@ -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 )
|
||||
|
@ -271,8 +267,7 @@ 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);
|
||||
}
|
||||
|
@ -294,4 +289,3 @@ int main(int argc, char* argv[])
|
|||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -6,10 +6,8 @@
|
|||
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) {}
|
||||
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; }
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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();
|
||||
|
@ -17,7 +18,8 @@ protected:
|
|||
string msg;
|
||||
};
|
||||
|
||||
class Output {
|
||||
class Output
|
||||
{
|
||||
public:
|
||||
Output(string filename);
|
||||
~Output();
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#include "pac_param.h"
|
||||
|
||||
#include "pac_decl.h"
|
||||
#include "pac_exttype.h"
|
||||
#include "pac_field.h"
|
||||
|
@ -6,24 +8,17 @@
|
|||
#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
|
||||
{
|
||||
|
@ -50,17 +45,14 @@ string ParamDecls(ParamList *params)
|
|||
}
|
||||
|
||||
ParamField::ParamField(const Param* param)
|
||||
: Field(PARAM_FIELD,
|
||||
TYPE_NOT_TO_BE_PARSED | CLASS_MEMBER | PUBLIC_READABLE,
|
||||
param->id(),
|
||||
: Field(PARAM_FIELD, TYPE_NOT_TO_BE_PARSED | CLASS_MEMBER | PUBLIC_READABLE, param->id(),
|
||||
param->type())
|
||||
{
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
|
|
|
@ -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,9 +13,7 @@ ParameterizedType::ParameterizedType(ID* type_id, ExprList* args)
|
|||
checking_requires_analyzer_context_ = false;
|
||||
}
|
||||
|
||||
ParameterizedType::~ParameterizedType()
|
||||
{
|
||||
}
|
||||
ParameterizedType::~ParameterizedType() { }
|
||||
|
||||
string ParameterizedType::EvalMember(const ID* member_id) const
|
||||
{
|
||||
|
@ -60,8 +59,7 @@ 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_);
|
||||
}
|
||||
|
@ -140,8 +138,7 @@ bool ParameterizedType::RequiresAnalyzerContext()
|
|||
ret = true;
|
||||
break;
|
||||
}
|
||||
ret = ret ||
|
||||
Type::RequiresAnalyzerContext();
|
||||
ret = ret || Type::RequiresAnalyzerContext();
|
||||
|
||||
if ( ! ret )
|
||||
{
|
||||
|
@ -192,14 +189,11 @@ string ParameterizedType::EvalParameters(Output* out_cc, Env *env) const
|
|||
|
||||
void ParameterizedType::GenNewInstance(Output* out_cc, Env* env)
|
||||
{
|
||||
out_cc->println("%s = new %s(%s);",
|
||||
lvalue(),
|
||||
type_id_->Name(),
|
||||
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());
|
||||
|
||||
|
@ -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) )
|
||||
|
@ -240,22 +232,19 @@ 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());
|
||||
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 = true;", env->LValue(parsing_complete_var()));
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT(parsing_complete_var());
|
||||
out_cc->println("%s = %s;",
|
||||
env->LValue(parsing_complete_var()),
|
||||
out_cc->println("%s = %s;", env->LValue(parsing_complete_var()),
|
||||
call_parse_func.c_str());
|
||||
|
||||
// parsing_complete_var might have been already
|
||||
|
@ -268,22 +257,17 @@ void ParameterizedType::DoGenParseCode(Output* out_cc, Env* env,
|
|||
{
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
#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)
|
||||
|
@ -29,8 +30,5 @@ string PPConstDef::ToCode(Env *env)
|
|||
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));
|
||||
}
|
||||
|
|
|
@ -6,7 +6,13 @@
|
|||
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() { }
|
||||
|
@ -58,10 +64,7 @@ private:
|
|||
class PPConstDef : public PacPrimitive
|
||||
{
|
||||
public:
|
||||
PPConstDef(const ID *id, Expr *expr)
|
||||
: PacPrimitive(CONST_DEF),
|
||||
id_(id),
|
||||
expr_(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_; }
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
@ -38,8 +37,7 @@ RecordType::~RecordType()
|
|||
|
||||
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
|
||||
|
@ -120,16 +118,14 @@ 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 )
|
||||
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();
|
||||
|
@ -140,15 +136,13 @@ void RecordType::DoGenParseCode(Output* out_cc, Env* 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;
|
||||
|
@ -158,19 +152,15 @@ void RecordType::DoGenParseCode(Output* out_cc, Env* env,
|
|||
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(),
|
||||
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());
|
||||
}
|
||||
|
@ -183,8 +173,7 @@ void RecordType::DoGenParseCode(Output* out_cc, Env* env,
|
|||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
@ -246,9 +235,7 @@ bool RecordType::ByteOrderSensitive() const
|
|||
}
|
||||
|
||||
RecordField::RecordField(FieldType tof, ID* id, Type* type)
|
||||
: Field(tof,
|
||||
TYPE_TO_BE_PARSED | CLASS_MEMBER | PUBLIC_READABLE,
|
||||
id, type)
|
||||
: Field(tof, TYPE_TO_BE_PARSED | CLASS_MEMBER | PUBLIC_READABLE, id, type)
|
||||
{
|
||||
begin_of_field_dataptr = 0;
|
||||
end_of_field_dataptr = 0;
|
||||
|
@ -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
|
||||
|
@ -319,26 +303,18 @@ const DataPtr& RecordField::getFieldEnd(Output* out_cc, Env* env)
|
|||
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(),
|
||||
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,17 +461,13 @@ 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),
|
||||
out_cc->println("BINPAC_ASSERT(%s <= %s);", env->RValue(end_of_field_dataptr_var),
|
||||
env->RValue(end_of_data));
|
||||
}
|
||||
|
||||
|
@ -531,8 +495,7 @@ bool RecordDataField::DoTraverse(DataDepVisitor *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,9 +549,7 @@ 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, "
|
||||
throw ExceptionPaddingError(this, strfmt("current offset = %d, "
|
||||
"target offset = %d",
|
||||
offset, target_offset));
|
||||
return target_offset - offset;
|
||||
|
@ -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,84 +577,65 @@ 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(),
|
||||
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),
|
||||
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),
|
||||
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),
|
||||
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),
|
||||
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_,
|
||||
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(),
|
||||
env->LValue(end_of_field_dataptr_var), field_begin.ptr_expr(),
|
||||
padding_var);
|
||||
delete[] padding_var;
|
||||
break;
|
||||
|
@ -728,7 +666,5 @@ bool RecordPaddingField::GenBoundaryCheck(Output* out_cc, Env* env)
|
|||
|
||||
bool RecordPaddingField::DoTraverse(DataDepVisitor* visitor)
|
||||
{
|
||||
return Field::DoTraverse(visitor) &&
|
||||
(! expr_ || expr_->Traverse(visitor));
|
||||
return Field::DoTraverse(visitor) && (! expr_ || expr_->Traverse(visitor));
|
||||
}
|
||||
|
||||
|
|
|
@ -30,7 +30,11 @@ public:
|
|||
|
||||
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);
|
||||
|
@ -124,8 +128,7 @@ public:
|
|||
|
||||
void SetBoundaryChecked();
|
||||
|
||||
bool RequiresByteOrder() const
|
||||
{ return type()->RequiresByteOrder(); }
|
||||
bool RequiresByteOrder() const { return type()->RequiresByteOrder(); }
|
||||
bool RequiresAnalyzerContext() const;
|
||||
|
||||
protected:
|
||||
|
@ -134,7 +137,12 @@ protected:
|
|||
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
|
||||
{
|
||||
|
@ -144,11 +152,19 @@ public:
|
|||
|
||||
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;
|
||||
|
|
|
@ -1,23 +1,23 @@
|
|||
#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 {
|
||||
namespace
|
||||
{
|
||||
|
||||
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;
|
||||
|
@ -31,9 +31,7 @@ Decl *ProcessTypeRedef(const ID *id, FieldList *fieldlist)
|
|||
|
||||
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);
|
||||
|
@ -46,21 +44,17 @@ Decl *ProcessTypeRedef(const ID *id, FieldList *fieldlist)
|
|||
|
||||
// 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");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -73,9 +67,7 @@ Decl *ProcessCaseTypeRedef(const ID *id, CaseFieldList *casefieldlist)
|
|||
|
||||
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);
|
||||
|
@ -84,9 +76,7 @@ Decl *ProcessCaseTypeRedef(const ID *id, CaseFieldList *casefieldlist)
|
|||
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);
|
||||
|
@ -107,9 +97,7 @@ Decl *ProcessCaseExprRedef(const ID *id, CaseExprList *caseexprlist)
|
|||
|
||||
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);
|
||||
|
@ -118,9 +106,7 @@ Decl *ProcessCaseExprRedef(const ID *id, CaseExprList *caseexprlist)
|
|||
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)
|
||||
|
@ -132,17 +118,13 @@ Decl *ProcessCaseExprRedef(const ID *id, CaseExprList *caseexprlist)
|
|||
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);
|
||||
|
||||
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);
|
||||
|
@ -159,9 +141,7 @@ Decl *ProcessTypeAttrRedef(const ID *id, AttrList *attrlist)
|
|||
|
||||
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);
|
||||
|
|
|
@ -5,9 +5,7 @@
|
|||
|
||||
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* ProcessAnalyzerRedef(const ID* id, Decl::DeclType decl_type, AnalyzerElementList* elements);
|
||||
Decl* ProcessTypeAttrRedef(const ID* id, AttrList* attrlist);
|
||||
|
||||
#endif // pac_redef_h
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
#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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -70,15 +68,12 @@ void RegExDecl::Prepare()
|
|||
|
||||
void RegExDecl::GenForwardDeclaration(Output* out_h)
|
||||
{
|
||||
out_h->println("extern %s %s;\n",
|
||||
RegEx::kREMatcherType,
|
||||
out_h->println("extern %s %s;\n", RegEx::kREMatcherType,
|
||||
global_env()->LValue(regex_->matcher_id()));
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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) { }
|
||||
|
|
|
@ -8,8 +8,7 @@
|
|||
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_; }
|
||||
|
|
|
@ -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";
|
||||
|
||||
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();
|
||||
|
@ -82,8 +80,7 @@ bool StringType::DefineValueVar() const
|
|||
|
||||
string StringType::DataTypeStr() const
|
||||
{
|
||||
return strfmt("%s",
|
||||
persistent() ? kStringTypeName : kConstStringTypeName);
|
||||
return strfmt("%s", persistent() ? kStringTypeName : kConstStringTypeName);
|
||||
}
|
||||
|
||||
Type* StringType::ElementDataType() const
|
||||
|
@ -101,8 +98,7 @@ void StringType::ProcessAttr(Attr *a)
|
|||
{
|
||||
if ( type_ != ANYSTR )
|
||||
{
|
||||
throw Exception(a,
|
||||
"&chunked can be applied"
|
||||
throw Exception(a, "&chunked can be applied"
|
||||
" to only type bytestring");
|
||||
}
|
||||
attr_chunked_ = true;
|
||||
|
@ -114,8 +110,7 @@ void StringType::ProcessAttr(Attr *a)
|
|||
{
|
||||
if ( type_ != ANYSTR )
|
||||
{
|
||||
throw Exception(a,
|
||||
"&restofdata can be applied"
|
||||
throw Exception(a, "&restofdata can be applied"
|
||||
" to only type bytestring");
|
||||
}
|
||||
attr_restofdata_ = true;
|
||||
|
@ -129,8 +124,7 @@ void StringType::ProcessAttr(Attr *a)
|
|||
{
|
||||
if ( type_ != ANYSTR )
|
||||
{
|
||||
throw Exception(a,
|
||||
"&restofflow can be applied"
|
||||
throw Exception(a, "&restofflow can be applied"
|
||||
" to only type bytestring");
|
||||
}
|
||||
attr_restofflow_ = true;
|
||||
|
@ -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);
|
||||
|
@ -216,12 +209,10 @@ 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 )",
|
||||
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(
|
||||
"throw binpac::ExceptionInvalidStringLength(\"%s\", %s);",
|
||||
Location(), str_size.c_str());
|
||||
}
|
||||
|
||||
out_cc->println("%s.init(%s, %s);",
|
||||
env->LValue(value_var()),
|
||||
data.ptr_expr(),
|
||||
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(),
|
||||
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());
|
||||
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,9 +313,7 @@ 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(),
|
||||
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("{");
|
||||
|
@ -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,35 +352,28 @@ 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()),
|
||||
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());
|
||||
|
|
|
@ -7,7 +7,12 @@
|
|||
class StringType : public Type
|
||||
{
|
||||
public:
|
||||
enum StringTypeEnum { CSTR, REGEX, ANYSTR };
|
||||
enum StringTypeEnum
|
||||
{
|
||||
CSTR,
|
||||
REGEX,
|
||||
ANYSTR
|
||||
};
|
||||
|
||||
explicit StringType(StringTypeEnum anystr);
|
||||
explicit StringType(ConstString* str);
|
||||
|
@ -43,13 +48,11 @@ 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);
|
||||
|
@ -74,6 +77,7 @@ private:
|
|||
|
||||
public:
|
||||
static void static_init();
|
||||
|
||||
private:
|
||||
static const char* kStringTypeName;
|
||||
static const char* kConstStringTypeName;
|
||||
|
|
|
@ -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;
|
||||
|
@ -185,9 +184,7 @@ void Type::ProcessAttr(Attr* a)
|
|||
else
|
||||
{
|
||||
// Append to attr_letfields_
|
||||
attr_letfields_->insert(
|
||||
attr_letfields_->end(),
|
||||
letattr->letfields()->begin(),
|
||||
attr_letfields_->insert(attr_letfields_->end(), letattr->letfields()->begin(),
|
||||
letattr->letfields()->end());
|
||||
}
|
||||
}
|
||||
|
@ -195,7 +192,8 @@ void Type::ProcessAttr(Attr* a)
|
|||
|
||||
case ATTR_LINEBREAKER:
|
||||
if ( strlen(a->expr()->orig()) != 6 )
|
||||
throw Exception(this, "invalid line breaker length, must be a single ASCII character. (Ex: \"\\001\".)");
|
||||
throw Exception(this, "invalid line breaker length, must be a single ASCII "
|
||||
"character. (Ex: \"\\001\".)");
|
||||
attr_linebreaker_ = a->expr();
|
||||
break;
|
||||
|
||||
|
@ -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,9 +258,7 @@ 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()));
|
||||
}
|
||||
|
||||
|
@ -275,8 +270,7 @@ 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
|
||||
|
@ -284,29 +278,23 @@ void Type::Prepare(Env* env, int flags)
|
|||
{
|
||||
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());
|
||||
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(),
|
||||
buffering_state_var_field_ = new PrivVarField(buffering_state_id->clone(),
|
||||
extern_type_int->Clone());
|
||||
AddField(buffering_state_var_field_);
|
||||
}
|
||||
|
@ -314,8 +302,7 @@ void Type::Prepare(Env* env, int flags)
|
|||
if ( incremental_parsing() && tot_ == RECORD )
|
||||
{
|
||||
ASSERT(! parsing_state_var_field_);
|
||||
parsing_state_var_field_ = new PrivVarField(
|
||||
parsing_state_id->clone(),
|
||||
parsing_state_var_field_ = new PrivVarField(parsing_state_id->clone(),
|
||||
extern_type_int->Clone());
|
||||
AddField(parsing_state_var_field_);
|
||||
}
|
||||
|
@ -334,12 +321,10 @@ void Type::GenPubDecls(Output* out_h, Env* env)
|
|||
{
|
||||
if ( attr_if_expr_ )
|
||||
out_h->println("%s %s const { BINPAC_ASSERT(%s); return %s; }",
|
||||
DataTypeConstRefStr().c_str(),
|
||||
env->RValue(value_var()),
|
||||
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(),
|
||||
out_h->println("%s %s const { return %s; }", DataTypeConstRefStr().c_str(),
|
||||
env->RValue(value_var()), lvalue());
|
||||
}
|
||||
|
||||
|
@ -354,9 +339,7 @@ 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_)
|
||||
|
@ -376,14 +359,12 @@ void Type::GenInitCode(Output* out_cc, Env* 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()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -414,8 +395,7 @@ void Type::GenBufferConfiguration(Output *out_cc, Env *env)
|
|||
|
||||
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());
|
||||
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;
|
||||
|
@ -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() )
|
||||
{
|
||||
|
@ -547,12 +519,9 @@ void Type::GenParseCode(Output* out_cc, Env* env, const DataPtr& data, int flags
|
|||
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(),
|
||||
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,8 +537,7 @@ 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()),
|
||||
out_cc->println("while ( ! %s && %s->ready() )", env->LValue(parsing_complete_var()),
|
||||
env->LValue(flow_buffer_id));
|
||||
|
||||
out_cc->inc_indent();
|
||||
|
@ -593,15 +561,11 @@ void Type::GenParseBuffer(Output* out_cc, Env* env, int flags)
|
|||
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,8 +579,7 @@ void Type::GenParseBuffer(Output* out_cc, Env* env, int flags)
|
|||
{
|
||||
if ( incremental_parsing() )
|
||||
{
|
||||
throw Exception(this,
|
||||
"cannot handle &until($input...) "
|
||||
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,8 +608,7 @@ 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),
|
||||
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,22 +665,17 @@ 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(),
|
||||
out_cc->println("%s.set_end(%s + %s);", env->LValue(sourcedata_id), data.ptr_expr(),
|
||||
datasize_str.c_str());
|
||||
}
|
||||
else
|
||||
|
@ -803,7 +752,6 @@ 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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -860,8 +807,7 @@ 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()),
|
||||
out_cc->println("%s = %s;", env->LValue(size_var()),
|
||||
attr_length_expr_->EvalExpr(out_cc, env));
|
||||
env->SetEvaluated(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();
|
||||
}
|
||||
|
@ -990,8 +933,7 @@ bool Type::IsEmptyType() const
|
|||
|
||||
void Type::MarkIncrementalInput()
|
||||
{
|
||||
DEBUG_MSG("Handle incremental input for %s.%s\n",
|
||||
decl_id()->Name(),
|
||||
DEBUG_MSG("Handle incremental input for %s.%s\n", decl_id()->Name(),
|
||||
value_var() ? value_var()->Name() : "*");
|
||||
|
||||
incremental_input_ = true;
|
||||
|
@ -1104,10 +1046,8 @@ bool Type::CompatibleTypes(Type *type1, Type *type2)
|
|||
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:
|
||||
|
|
|
@ -11,7 +11,8 @@ using namespace std;
|
|||
class Type : public Object, public DataDepElement
|
||||
{
|
||||
public:
|
||||
enum TypeType {
|
||||
enum TypeType
|
||||
{
|
||||
UNDEF = -1,
|
||||
EMPTY,
|
||||
BUILTIN,
|
||||
|
@ -78,8 +79,7 @@ public:
|
|||
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 EvalElement(const string& array, const string& index) const;
|
||||
|
||||
// The variable defined by the type
|
||||
const ID* value_var() const { return value_var_; }
|
||||
|
@ -100,7 +100,9 @@ public:
|
|||
|
||||
void AddField(Field* f);
|
||||
|
||||
void AddCheck(Expr *expr) { /* TODO */ }
|
||||
void AddCheck(Expr* expr)
|
||||
{ /* TODO */
|
||||
}
|
||||
|
||||
virtual bool DefineValueVar() const = 0;
|
||||
|
||||
|
@ -120,7 +122,8 @@ 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
|
||||
|
@ -155,10 +158,7 @@ public:
|
|||
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; }
|
||||
|
||||
|
@ -204,7 +204,8 @@ public:
|
|||
bool BufferableWithLineBreaker() const;
|
||||
Expr* LineBreaker() const;
|
||||
|
||||
enum BufferMode {
|
||||
enum BufferMode
|
||||
{
|
||||
NOT_BUFFERABLE,
|
||||
BUFFER_NOTHING, // for type "empty"
|
||||
BUFFER_BY_LENGTH,
|
||||
|
@ -228,15 +229,12 @@ 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);
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
@ -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());
|
||||
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"
|
||||
|
@ -180,20 +177,15 @@ 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());
|
||||
|
||||
|
@ -238,23 +230,20 @@ string TypeDecl::ParseFuncPrototype(Env* env)
|
|||
{
|
||||
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(),
|
||||
params += strfmt(", %s %s", param_type->DataTypeConstRefStr().c_str(),
|
||||
env->LValue(analyzer_context_id));
|
||||
}
|
||||
|
||||
|
@ -265,8 +254,7 @@ 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)
|
||||
|
@ -283,10 +271,8 @@ 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() &&
|
||||
|
@ -294,16 +280,14 @@ void TypeDecl::GenParsingEnd(Output *out_cc, Env *env, const DataPtr &data)
|
|||
{
|
||||
// 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() )
|
||||
|
@ -382,14 +366,12 @@ void TypeDecl::GenInitialBufferLengthFunc(Output* out_h, Output* out_cc)
|
|||
|
||||
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)
|
||||
|
@ -409,4 +391,3 @@ Type* TypeDecl::LookUpType(const ID *id)
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "pac_utils.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
char* copy_string(const char* s)
|
||||
{
|
||||
char* c = new char[strlen(s) + 1];
|
||||
|
@ -11,7 +11,8 @@ char* copy_string(const char* s)
|
|||
return c;
|
||||
}
|
||||
|
||||
namespace {
|
||||
namespace
|
||||
{
|
||||
|
||||
const char* do_fmt(const char* format, va_list ap)
|
||||
{
|
||||
|
|
|
@ -8,10 +8,13 @@ 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 */ }
|
||||
: 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
|
||||
|
@ -19,9 +22,9 @@ 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) {}
|
||||
: Field(PUB_VAR_FIELD, TYPE_NOT_TO_BE_PARSED | CLASS_MEMBER | PUBLIC_READABLE, id, type)
|
||||
{
|
||||
}
|
||||
~PubVarField() { }
|
||||
};
|
||||
|
||||
|
@ -30,21 +33,24 @@ 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) {}
|
||||
: 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) {}
|
||||
: Field(TEMP_VAR_FIELD, TYPE_NOT_TO_BE_PARSED | NOT_CLASS_MEMBER, id, type)
|
||||
{
|
||||
}
|
||||
~TempVarField() { }
|
||||
};
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "pac_withinput.h"
|
||||
|
||||
#include "pac_dataptr.h"
|
||||
#include "pac_expr.h"
|
||||
#include "pac_inputbuf.h"
|
||||
|
@ -6,9 +7,7 @@
|
|||
#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),
|
||||
: Field(WITHINPUT_FIELD, TYPE_TO_BE_PARSED | CLASS_MEMBER | PUBLIC_READABLE, id, type),
|
||||
input_(input)
|
||||
{
|
||||
ASSERT(type_);
|
||||
|
@ -22,14 +21,12 @@ WithInputField::~WithInputField()
|
|||
|
||||
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() )
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue