binpac: Migrate fmt() usage to strfmt()

The former is easy to misuse by accidentally storing the contents of
the temporary string return value and accessing it later.  There's also
potential pitfalls in changing it to return a pointer into a static
buffer, so instead start using strfmt() uniformly across the codebase
and change some methods to use strings instead of char*.
This commit is contained in:
Jon Siwek 2018-05-17 15:51:49 -05:00 committed by Tim Wojtulewicz
parent 0a05aa92fc
commit 5a688c2730
24 changed files with 105 additions and 94 deletions

View file

@ -103,7 +103,7 @@ Type *ActionParam::DataType() const
if ( ! member_type ) if ( ! member_type )
{ {
throw Exception(type()->field_id(), throw Exception(type()->field_id(),
fmt("cannot find member type for `%s.%s'", strfmt("cannot find member type for `%s.%s'",
type()->type_id()->Name(), type()->type_id()->Name(),
type()->field_id()->Name())); type()->field_id()->Name()));
} }

View file

@ -205,9 +205,9 @@ void ArrayType::Prepare(Env *env, int flags)
{ {
if ( flags & TO_BE_PARSED ) if ( flags & TO_BE_PARSED )
{ {
ID *arraylength_var = new ID(fmt("%s__arraylength", value_var()->Name())); ID *arraylength_var = new ID(strfmt("%s__arraylength", value_var()->Name()));
ID *elem_var = new ID(fmt("%s__elem", value_var()->Name())); ID *elem_var = new ID(strfmt("%s__elem", value_var()->Name()));
ID *elem_it_var = new ID(fmt("%s__it", elem_var->Name())); ID *elem_it_var = new ID(strfmt("%s__it", elem_var->Name()));
elem_var_field_ = elem_var_field_ =
new ParseVarField(Field::CLASS_MEMBER, elem_var, elemtype_); new ParseVarField(Field::CLASS_MEMBER, elem_var, elemtype_);
@ -235,7 +235,7 @@ void ArrayType::Prepare(Env *env, int flags)
// Add elem_dataptr_var only when not parsing incrementally // Add elem_dataptr_var only when not parsing incrementally
ID *elem_dataptr_var = ID *elem_dataptr_var =
new ID(fmt("%s__dataptr", elem_var->Name())); new ID(strfmt("%s__dataptr", elem_var->Name()));
elem_dataptr_var_field_ = new TempVarField( elem_dataptr_var_field_ = new TempVarField(
elem_dataptr_var, elem_dataptr_var,
extern_type_const_byteptr->Clone()); extern_type_const_byteptr->Clone());
@ -385,7 +385,7 @@ void ArrayType::GenCleanUpCode(Output *out_cc, Env *env)
{ {
if ( ! elem_var_field_ ) if ( ! elem_var_field_ )
{ {
ID *elem_var = new ID(fmt("%s__elem", value_var()->Name())); ID *elem_var = new ID(strfmt("%s__elem", value_var()->Name()));
elem_var_field_ = elem_var_field_ =
new ParseVarField( new ParseVarField(
Field::NOT_CLASS_MEMBER, Field::NOT_CLASS_MEMBER,
@ -623,7 +623,7 @@ void ArrayType::DoGenParseCode(Output *out_cc, Env *env,
void ArrayType::GenUntilInputCheck(Output *out_cc, Env *env) void ArrayType::GenUntilInputCheck(Output *out_cc, Env *env)
{ {
ID *elem_input_var_id = new ID( ID *elem_input_var_id = new ID(
fmt("%s__elem_input", value_var()->Name())); strfmt("%s__elem_input", value_var()->Name()));
elem_input_var_field_ = new TempVarField( elem_input_var_field_ = new TempVarField(
elem_input_var_id, extern_type_const_bytestring->Clone()); elem_input_var_id, extern_type_const_bytestring->Clone());
elem_input_var_field_->Prepare(env); elem_input_var_field_->Prepare(env);

View file

@ -63,7 +63,7 @@ void CaseType::Prepare(Env* env, int flags)
{ {
ASSERT(flags & TO_BE_PARSED); ASSERT(flags & TO_BE_PARSED);
index_var_ = new ID(fmt("%s_case_index", value_var()->Name())); index_var_ = new ID(strfmt("%s_case_index", value_var()->Name()));
env->AddID(index_var_, MEMBER_VAR, extern_type_int); env->AddID(index_var_, MEMBER_VAR, extern_type_int);
// Sort the cases_ to put the default case at the end of the list // Sort the cases_ to put the default case at the end of the list

View file

@ -43,7 +43,7 @@ void ConnDecl::ProcessFlowElement(AnalyzerFlow *flow_elem)
if ( flows_[flow_index] ) if ( flows_[flow_index] )
{ {
throw Exception(flow_elem, throw Exception(flow_elem,
fmt("%sflow already defined", strfmt("%sflow already defined",
flow_index == 0 ? "up" : "down")); flow_index == 0 ? "up" : "down"));
} }

View file

@ -39,7 +39,7 @@ namespace {
AnalyzerContextDecl::AnalyzerContextDecl( AnalyzerContextDecl::AnalyzerContextDecl(
ID *id, ID *id,
ContextFieldList *context_fields) ContextFieldList *context_fields)
: TypeDecl(new ID(fmt("Context%s", id->Name())), : TypeDecl(new ID(strfmt("Context%s", id->Name())),
ContextFieldsToParams(context_fields), ContextFieldsToParams(context_fields),
new DummyType()) new DummyType())
{ {
@ -47,7 +47,7 @@ AnalyzerContextDecl::AnalyzerContextDecl(
if ( current_analyzer_context_ != 0 ) if ( current_analyzer_context_ != 0 )
{ {
throw Exception(this, throw Exception(this,
fmt("multiple declaration of analyzer context; " strfmt("multiple declaration of analyzer context; "
"the previous one is `%s'", "the previous one is `%s'",
current_analyzer_context_->id()->Name())); current_analyzer_context_->id()->Name()));
} }
@ -108,7 +108,7 @@ string AnalyzerContextDecl::mb_buffer(Env *env)
{ {
// A hack. The orthodox way would be to build an Expr of // A hack. The orthodox way would be to build an Expr of
// context.flow_buffer_var, and then EvalExpr. // context.flow_buffer_var, and then EvalExpr.
return fmt("%s->%s()", return strfmt("%s->%s()",
env->RValue(analyzer_context_id), env->RValue(analyzer_context_id),
kFlowBufferVar); kFlowBufferVar);
} }

View file

@ -49,7 +49,7 @@ int expand_escape(const char*& s)
int result; int result;
if ( sscanf(start, "%3o", &result) != 1 ) if ( sscanf(start, "%3o", &result) != 1 )
throw EscapeException(fmt("bad octal escape: \"%s", start)); throw EscapeException(strfmt("bad octal escape: \"%s", start));
return result; return result;
} }
@ -65,7 +65,7 @@ int expand_escape(const char*& s)
int result; int result;
if ( sscanf(start, "%2x", &result) != 1 ) if ( sscanf(start, "%2x", &result) != 1 )
throw EscapeException(fmt("bad hexadecimal escape: \"%s", start)); throw EscapeException(strfmt("bad hexadecimal escape: \"%s", start));
return result; return result;
} }

View file

@ -132,7 +132,7 @@ int HelperDecl::helper_id_seq = 0;
HelperDecl::HelperDecl(HelperType helper_type, HelperDecl::HelperDecl(HelperType helper_type,
ID* context_id, ID* context_id,
EmbeddedCode* code) EmbeddedCode* code)
: Decl(new ID(fmt("helper_%d", ++helper_id_seq)), HELPER), : Decl(new ID(strfmt("helper_%d", ++helper_id_seq)), HELPER),
helper_type_(helper_type), helper_type_(helper_type),
context_id_(context_id), context_id_(context_id),
code_(code) code_(code)

View file

@ -3,15 +3,16 @@
#include "pac_id.h" #include "pac_id.h"
#include "pac_utils.h" #include "pac_utils.h"
Exception::Exception(const Object* o, const char* msg) Exception::Exception(const Object* o, string msg)
{ {
if ( o ) if ( o )
{ {
msg_ = o->Location(); msg_ = o->Location();
msg_ += ": error : "; msg_ += ": error : ";
} }
if ( msg )
msg_ += msg; msg_ += msg;
if ( FLAGS_pac_debug ) if ( FLAGS_pac_debug )
{ {
DEBUG_MSG("Exception: %s\n", msg_.c_str()); DEBUG_MSG("Exception: %s\n", msg_.c_str());
@ -22,49 +23,49 @@ Exception::Exception(const Object* o, const char* msg)
ExceptionIDNotFound::ExceptionIDNotFound(const ID* id) ExceptionIDNotFound::ExceptionIDNotFound(const ID* id)
: Exception(id), id_(id) : Exception(id), id_(id)
{ {
append(fmt("`%s' undeclared", id_->Name())); append(strfmt("`%s' undeclared", id_->Name()));
} }
ExceptionIDRedefinition::ExceptionIDRedefinition(const ID* id) ExceptionIDRedefinition::ExceptionIDRedefinition(const ID* id)
: Exception(id), id_(id) : Exception(id), id_(id)
{ {
append(fmt("`%s' redefined", id_->Name())); append(strfmt("`%s' redefined", id_->Name()));
} }
ExceptionIDNotEvaluated::ExceptionIDNotEvaluated(const ID* id) ExceptionIDNotEvaluated::ExceptionIDNotEvaluated(const ID* id)
: Exception(id), id_(id) : Exception(id), id_(id)
{ {
append(fmt("ID `%s' not evaluated before used", id->Name())); append(strfmt("ID `%s' not evaluated before used", id->Name()));
} }
ExceptionIDNotField::ExceptionIDNotField(const ID* id) ExceptionIDNotField::ExceptionIDNotField(const ID* id)
: Exception(id), id_(id) : Exception(id), id_(id)
{ {
append(fmt("ID `%s' is not a field", id_->Name())); append(strfmt("ID `%s' is not a field", id_->Name()));
} }
ExceptionMemberNotFound::ExceptionMemberNotFound(const ID* type_id, ExceptionMemberNotFound::ExceptionMemberNotFound(const ID* type_id,
const ID *member_id) const ID *member_id)
: Exception(member_id), type_id_(type_id), member_id_(member_id) : Exception(member_id), type_id_(type_id), member_id_(member_id)
{ {
append(fmt("type %s does not have member `%s'", append(strfmt("type %s does not have member `%s'",
type_id_->Name(), member_id_->Name())); type_id_->Name(), member_id_->Name()));
} }
ExceptionCyclicDependence::ExceptionCyclicDependence(const ID* id) ExceptionCyclicDependence::ExceptionCyclicDependence(const ID* id)
: Exception(id), id_(id) : Exception(id), id_(id)
{ {
append(fmt("cyclic dependence through `%s'", id_->Name())); append(strfmt("cyclic dependence through `%s'", id_->Name()));
} }
ExceptionPaddingError::ExceptionPaddingError(const Object* o, const char* msg) ExceptionPaddingError::ExceptionPaddingError(const Object* o, string msg)
: Exception(o) : Exception(o)
{ {
append(msg); append(msg.c_str());
} }
ExceptionNonConstExpr::ExceptionNonConstExpr(const Expr* expr) ExceptionNonConstExpr::ExceptionNonConstExpr(const Expr* expr)
: Exception(expr), expr(expr) : Exception(expr), expr(expr)
{ {
append(fmt("Expression `%s' is not constant", expr->orig())); append(strfmt("Expression `%s' is not constant", expr->orig()));
} }

View file

@ -9,10 +9,10 @@ using namespace std;
class Exception class Exception
{ {
public: public:
Exception(const Object* o, const char* msg = 0); Exception(const Object* o, string msg = "");
const char* msg() const { return msg_.c_str(); } const char* msg() const { return msg_.c_str(); }
void append(const char* s) { msg_ += s; } void append(string s) { msg_ += s; }
private: private:
string msg_; string msg_;
@ -61,7 +61,7 @@ private:
class ExceptionPaddingError : public Exception class ExceptionPaddingError : public Exception
{ {
public: public:
ExceptionPaddingError(const Object* o, const char* msg); ExceptionPaddingError(const Object* o, string msg);
}; };
class ExceptionIDNotField : public Exception class ExceptionIDNotField : public Exception

View file

@ -72,7 +72,7 @@ Expr::Expr(ID* arg_id)
expr_type_ = EXPR_ID; expr_type_ = EXPR_ID;
id_ = arg_id; id_ = arg_id;
num_operands_ = 0; num_operands_ = 0;
orig_ = fmt("%s", id_->Name()); orig_ = strfmt("%s", id_->Name());
} }
Expr::Expr(Number* arg_num) Expr::Expr(Number* arg_num)
@ -82,7 +82,7 @@ Expr::Expr(Number* arg_num)
expr_type_ = EXPR_NUM; expr_type_ = EXPR_NUM;
num_ = arg_num; num_ = arg_num;
num_operands_ = 0; num_operands_ = 0;
orig_ = fmt("((int) %s)", num_->Str()); orig_ = strfmt("((int) %s)", num_->Str());
} }
Expr::Expr(ConstString *cstr) Expr::Expr(ConstString *cstr)
@ -102,7 +102,7 @@ Expr::Expr(RegEx *regex)
expr_type_ = EXPR_REGEX; expr_type_ = EXPR_REGEX;
regex_ = regex; regex_ = regex;
num_operands_ = 0; num_operands_ = 0;
orig_ = fmt("/%s/", regex_->str().c_str()); orig_ = strfmt("/%s/", regex_->str().c_str());
} }
Expr::Expr(ExprType arg_type, Expr* op1) Expr::Expr(ExprType arg_type, Expr* op1)
@ -112,7 +112,7 @@ Expr::Expr(ExprType arg_type, Expr* op1)
expr_type_ = arg_type; expr_type_ = arg_type;
num_operands_ = 1; num_operands_ = 1;
operand_[0] = op1; operand_[0] = op1;
orig_ = fmt(expr_fmt[expr_type_], op1->orig()); orig_ = strfmt(expr_fmt[expr_type_], op1->orig());
} }
Expr::Expr(ExprType arg_type, Expr* op1, Expr* op2) Expr::Expr(ExprType arg_type, Expr* op1, Expr* op2)
@ -124,7 +124,7 @@ Expr::Expr(ExprType arg_type, Expr* op1, Expr* op2)
operand_[0] = op1; operand_[0] = op1;
operand_[1] = op2; operand_[1] = op2;
operand_[2] = 0; operand_[2] = 0;
orig_ = fmt(expr_fmt[expr_type_], op1->orig(), op2->orig()); orig_ = strfmt(expr_fmt[expr_type_], op1->orig(), op2->orig());
} }
Expr::Expr(ExprType arg_type, Expr* op1, Expr* op2, Expr* op3) Expr::Expr(ExprType arg_type, Expr* op1, Expr* op2, Expr* op3)
@ -136,7 +136,7 @@ Expr::Expr(ExprType arg_type, Expr* op1, Expr* op2, Expr* op3)
operand_[0] = op1; operand_[0] = op1;
operand_[1] = op2; operand_[1] = op2;
operand_[2] = op3; operand_[2] = op3;
orig_ = fmt(expr_fmt[expr_type_], op1->orig(), op2->orig(), op3->orig()); orig_ = strfmt(expr_fmt[expr_type_], op1->orig(), op2->orig(), op3->orig());
} }
Expr::Expr(ExprList *args) Expr::Expr(ExprList *args)
@ -196,16 +196,16 @@ void Expr::GenStrFromFormat(Env *env)
switch ( num_operands_ ) switch ( num_operands_ )
{ {
case 1: case 1:
str_ = fmt(expr_fmt[expr_type_], str_ = strfmt(expr_fmt[expr_type_],
operand_[0]->str()); operand_[0]->str());
break; break;
case 2: case 2:
str_ = fmt(expr_fmt[expr_type_], str_ = strfmt(expr_fmt[expr_type_],
operand_[0]->str(), operand_[0]->str(),
operand_[1]->str()); operand_[1]->str());
break; break;
case 3: case 3:
str_ = fmt(expr_fmt[expr_type_], str_ = strfmt(expr_fmt[expr_type_],
operand_[0]->str(), operand_[0]->str(),
operand_[1]->str(), operand_[1]->str(),
operand_[2]->str()); operand_[2]->str());
@ -334,11 +334,19 @@ void Expr::GenEval(Output* out_cc, Env* env)
Type *ty0 = operand_[0]->DataType(env); Type *ty0 = operand_[0]->DataType(env);
str_ = fmt("%s%s", if ( ty0 )
{
str_ = strfmt("%s%s",
operand_[0]->EvalExpr(out_cc, env), operand_[0]->EvalExpr(out_cc, env),
ty0 ? ty0->EvalMember(operand_[1]->id()).c_str());
ty0->EvalMember(operand_[1]->id()).c_str() : }
fmt("->%s()", operand_[1]->id()->Name())); else
{
string tmp = strfmt("->%s()", operand_[1]->id()->Name());
str_ = strfmt("%s%s",
operand_[0]->EvalExpr(out_cc, env),
tmp.c_str());
}
} }
break; break;
@ -354,7 +362,7 @@ void Expr::GenEval(Output* out_cc, Env* env)
if ( ty0 ) if ( ty0 )
str_ = ty0->EvalElement(v0, v1); str_ = ty0->EvalElement(v0, v1);
else else
str_ = fmt("%s[%s]", v0.c_str(), v1.c_str()); str_ = strfmt("%s[%s]", v0.c_str(), v1.c_str());
} }
break; break;
@ -368,7 +376,7 @@ void Expr::GenEval(Output* out_cc, Env* env)
{ {
if ( (rf = GetRecordField(id, env)) != 0 ) if ( (rf = GetRecordField(id, env)) != 0 )
{ {
str_ = fmt("%s", rf->FieldSize(out_cc, env)); str_ = strfmt("%s", rf->FieldSize(out_cc, env));
} }
} }
catch ( ExceptionIDNotFound &e ) catch ( ExceptionIDNotFound &e )
@ -377,7 +385,7 @@ void Expr::GenEval(Output* out_cc, Env* env)
{ {
int ty_size = ty->StaticSize(global_env()); int ty_size = ty->StaticSize(global_env());
if ( ty_size >= 0 ) if ( ty_size >= 0 )
str_ = fmt("%d", ty_size); str_ = strfmt("%d", ty_size);
else else
throw Exception(id, "unknown size"); throw Exception(id, "unknown size");
} }
@ -391,7 +399,7 @@ void Expr::GenEval(Output* out_cc, Env* env)
{ {
const ID *id = operand_[0]->id(); const ID *id = operand_[0]->id();
RecordField *rf = GetRecordField(id, env); RecordField *rf = GetRecordField(id, env);
str_ = fmt("%s", rf->FieldOffset(out_cc, env)); str_ = strfmt("%s", rf->FieldOffset(out_cc, env));
} }
break; break;
@ -501,7 +509,7 @@ Type *Expr::DataType(Env *env) const
if ( ! Type::CompatibleTypes(type1, type2) ) if ( ! Type::CompatibleTypes(type1, type2) )
{ {
throw Exception(this, throw Exception(this,
fmt("type mismatch: %s vs %s", strfmt("type mismatch: %s vs %s",
type1->DataTypeStr().c_str(), type1->DataTypeStr().c_str(),
type2->DataTypeStr().c_str())); type2->DataTypeStr().c_str()));
} }
@ -526,7 +534,7 @@ Type *Expr::DataType(Env *env) const
if ( ! Type::CompatibleTypes(type1, type2) ) if ( ! Type::CompatibleTypes(type1, type2) )
{ {
throw Exception(this, throw Exception(this,
fmt("type mismatch: %s vs %s", strfmt("type mismatch: %s vs %s",
type1->DataTypeStr().c_str(), type1->DataTypeStr().c_str(),
type2->DataTypeStr().c_str())); type2->DataTypeStr().c_str()));
} }
@ -581,7 +589,7 @@ string Expr::DataTypeStr(Env *env) const
if ( ! type ) if ( ! type )
{ {
throw Exception(this, throw Exception(this,
fmt("cannot find data type for expression `%s'", strfmt("cannot find data type for expression `%s'",
orig())); orig()));
} }
@ -605,7 +613,7 @@ string Expr::SetFunc(Output *out, Env *env)
break; break;
default: default:
throw Exception(this, throw Exception(this,
fmt("cannot generate set function " strfmt("cannot generate set function "
"for expression `%s'", orig())); "for expression `%s'", orig()));
break; break;
} }

View file

@ -39,7 +39,7 @@ int ID::anonymous_id_seq = 0;
ID *ID::NewAnonymousID(const string &prefix) ID *ID::NewAnonymousID(const string &prefix)
{ {
ID *id = new ID(fmt("%s%03d", prefix.c_str(), ++anonymous_id_seq)); ID *id = new ID(strfmt("%s%03d", prefix.c_str(), ++anonymous_id_seq));
id->anonymous_id_ = true; id->anonymous_id_ = true;
return id; return id;
} }
@ -297,7 +297,7 @@ void Env::SetEvaluated(const ID* id, bool v)
{ {
throw Exception( throw Exception(
context_object_, context_object_,
fmt("INTERNAL ERROR: " strfmt("INTERNAL ERROR: "
"evaluating let field '%s' in a branch! " "evaluating let field '%s' in a branch! "
"To work around this problem, " "To work around this problem, "
"add '&requires(%s)' to the case type. " "add '&requires(%s)' to the case type. "

View file

@ -43,7 +43,7 @@ class Evaluatable;
class ID : public Object class ID : public Object
{ {
public: public:
ID(const char *arg_name) ID(string arg_name)
: name(arg_name), anonymous_id_(false) : name(arg_name), anonymous_id_(false)
{ {
locname = nfmt("%s:%s", Location(), Name()); locname = nfmt("%s:%s", Location(), Name());

View file

@ -156,8 +156,9 @@ void LetDecl::GenCode(Output * out_h, Output *out_cc)
void LetDecl::GenEval(Output *out_cc, Env * /* env */) void LetDecl::GenEval(Output *out_cc, Env * /* env */)
{ {
Env *env = global_env(); Env *env = global_env();
string tmp = strfmt("%s const", type_->DataTypeStr().c_str());
out_cc->println("%s %s = %s;", out_cc->println("%s %s = %s;",
fmt("%s const", type_->DataTypeStr().c_str()), tmp.c_str(),
env->LValue(id_), env->LValue(id_),
expr_->EvalExpr(out_cc, env)); expr_->EvalExpr(out_cc, env));

View file

@ -103,7 +103,8 @@ int compile(const char* filename)
FILE* fp_input = fopen(filename, "r"); FILE* fp_input = fopen(filename, "r");
if ( ! fp_input ) if ( ! fp_input )
{ {
perror(fmt("Error in opening %s", filename)); string tmp = strfmt("Error in opening %s", filename);
perror(tmp.c_str());
return -1; return -1;
} }
input_filename = filename; input_filename = filename;
@ -142,8 +143,8 @@ int compile(const char* filename)
if ( yyparse() ) if ( yyparse() )
return 1; return 1;
Output out_h(fmt("%s.h", basename.c_str())); Output out_h(strfmt("%s.h", basename.c_str()));
Output out_cc(fmt("%s.cc", basename.c_str())); Output out_cc(strfmt("%s.cc", basename.c_str()));
header_output = &out_h; header_output = &out_h;
source_output = &out_cc; source_output = &out_cc;

View file

@ -7,7 +7,7 @@ class Number : public Object
{ {
public: public:
Number(int arg_n) Number(int arg_n)
: s(fmt("%d", arg_n)), n(arg_n) {} : s(strfmt("%d", arg_n)), n(arg_n) {}
Number(const char* arg_s, int arg_n) Number(const char* arg_s, int arg_n)
: s(arg_s), n(arg_n) {} : s(arg_s), n(arg_n) {}
const char* Str() const { return s.c_str(); } const char* Str() const { return s.c_str(); }

View file

@ -15,9 +15,9 @@ OutputException::~OutputException()
{ {
} }
Output::Output(const char* filename) Output::Output(string filename)
{ {
fp = fopen(filename, "w"); fp = fopen(filename.c_str(), "w");
if ( ! fp ) if ( ! fp )
throw OutputException(strerror(errno)); throw OutputException(strerror(errno));
indent_ = 0; indent_ = 0;

View file

@ -19,7 +19,7 @@ protected:
class Output { class Output {
public: public:
Output(const char *filename); Output(string filename);
~Output(); ~Output();
int println(const char* fmt, ...); int println(const char* fmt, ...);

View file

@ -328,7 +328,7 @@ const DataPtr& RecordField::getFieldEnd(Output* out_cc, Env* env)
{ {
// If not, we add a variable for the offset after the field // If not, we add a variable for the offset after the field
end_of_field_dataptr_var = new ID( end_of_field_dataptr_var = new ID(
fmt("dataptr_after_%s", id()->Name())); strfmt("dataptr_after_%s", id()->Name()));
env->AddID(end_of_field_dataptr_var, env->AddID(end_of_field_dataptr_var,
TEMP_VAR, TEMP_VAR,
extern_type_const_byteptr); extern_type_const_byteptr);
@ -546,7 +546,7 @@ void RecordPaddingField::Prepare(Env* env)
{ {
if ( ! expr_->ConstFold(env, &wordsize_) ) if ( ! expr_->ConstFold(env, &wordsize_) )
throw ExceptionPaddingError(this, throw ExceptionPaddingError(this,
fmt("padding word size not a constant")); strfmt("padding word size not a constant"));
} }
} }
@ -585,7 +585,7 @@ int RecordPaddingField::StaticSize(Env* env, int offset) const
if ( offset > target_offset ) if ( offset > target_offset )
throw ExceptionPaddingError( throw ExceptionPaddingError(
this, this,
fmt("current offset = %d, " strfmt("current offset = %d, "
"target offset = %d", "target offset = %d",
offset, target_offset)); offset, target_offset));
return target_offset - offset; return target_offset - offset;

View file

@ -16,7 +16,7 @@ Decl *find_decl(const ID *id)
if ( ! decl ) if ( ! decl )
{ {
throw Exception(id, throw Exception(id,
fmt("cannot find declaration for %s", strfmt("cannot find declaration for %s",
id->Name())); id->Name()));
} }
@ -32,7 +32,7 @@ Decl *ProcessTypeRedef(const ID *id, FieldList *fieldlist)
if ( decl->decl_type() != Decl::TYPE ) if ( decl->decl_type() != Decl::TYPE )
{ {
throw Exception(id, throw Exception(id,
fmt("not a type declaration: %s", strfmt("not a type declaration: %s",
id->Name())); id->Name()));
} }
@ -74,7 +74,7 @@ Decl *ProcessCaseTypeRedef(const ID *id, CaseFieldList *casefieldlist)
if ( decl->decl_type() != Decl::TYPE ) if ( decl->decl_type() != Decl::TYPE )
{ {
throw Exception(id, throw Exception(id,
fmt("not a type declaration: %s", strfmt("not a type declaration: %s",
id->Name())); id->Name()));
} }
@ -85,7 +85,7 @@ Decl *ProcessCaseTypeRedef(const ID *id, CaseFieldList *casefieldlist)
if ( type->tot() != Type::CASE ) if ( type->tot() != Type::CASE )
{ {
throw Exception(id, throw Exception(id,
fmt("not a case type: %s", strfmt("not a case type: %s",
id->Name())); id->Name()));
} }
@ -108,7 +108,7 @@ Decl *ProcessCaseExprRedef(const ID *id, CaseExprList *caseexprlist)
if ( decl->decl_type() != Decl::FUNC ) if ( decl->decl_type() != Decl::FUNC )
{ {
throw Exception(id, throw Exception(id,
fmt("not a function declaration: %s", strfmt("not a function declaration: %s",
id->Name())); id->Name()));
} }
@ -119,7 +119,7 @@ Decl *ProcessCaseExprRedef(const ID *id, CaseExprList *caseexprlist)
if ( ! expr ||expr->expr_type() != Expr::EXPR_CASE ) if ( ! expr ||expr->expr_type() != Expr::EXPR_CASE )
{ {
throw Exception(id, throw Exception(id,
fmt("function not defined by a case expression: %s", strfmt("function not defined by a case expression: %s",
id->Name())); id->Name()));
} }
@ -141,7 +141,7 @@ Decl *ProcessAnalyzerRedef(const ID *id,
if ( decl->decl_type() != decl_type ) if ( decl->decl_type() != decl_type )
{ {
throw Exception(id, throw Exception(id,
fmt("not a connection/flow declaration: %s", strfmt("not a connection/flow declaration: %s",
id->Name())); id->Name()));
} }
@ -160,7 +160,7 @@ Decl *ProcessTypeAttrRedef(const ID *id, AttrList *attrlist)
if ( decl->decl_type() != Decl::TYPE ) if ( decl->decl_type() != Decl::TYPE )
{ {
throw Exception(id, throw Exception(id,
fmt("not a type declaration: %s", strfmt("not a type declaration: %s",
id->Name())); id->Name()));
} }

View file

@ -149,7 +149,7 @@ void StringType::Prepare(Env* env, int flags)
{ {
if ( (flags & TO_BE_PARSED) && StaticSize(env) < 0 ) if ( (flags & TO_BE_PARSED) && StaticSize(env) < 0 )
{ {
ID *string_length_var = new ID(fmt("%s_string_length", ID *string_length_var = new ID(strfmt("%s_string_length",
value_var() ? value_var()->Name() : "val")); value_var() ? value_var()->Name() : "val"));
string_length_var_field_ = new TempVarField( string_length_var_field_ = new TempVarField(
string_length_var, extern_type_int->Clone()); string_length_var, extern_type_int->Clone());
@ -314,14 +314,16 @@ void StringType::DoGenParseCode(Output* out_cc, Env* env,
} }
void StringType::GenStringMismatch(Output* out_cc, Env* env, void StringType::GenStringMismatch(Output* out_cc, Env* env,
const DataPtr& data, const char *pattern) const DataPtr& data, string pattern)
{ {
string tmp =
strfmt("string((const char *) (%s), (const char *) %s).c_str()",
data.ptr_expr(),
env->RValue(end_of_data));
out_cc->println("throw binpac::ExceptionStringMismatch(\"%s\", %s, %s);", out_cc->println("throw binpac::ExceptionStringMismatch(\"%s\", %s, %s);",
Location(), Location(),
pattern, pattern.c_str(),
fmt("string((const char *) (%s), (const char *) %s).c_str()", tmp.c_str());
data.ptr_expr(),
env->RValue(end_of_data)));
} }
void StringType::GenCheckingCStr(Output* out_cc, Env* env, void StringType::GenCheckingCStr(Output* out_cc, Env* env,
@ -341,7 +343,7 @@ void StringType::GenCheckingCStr(Output* out_cc, Env* env,
str_size.c_str()); str_size.c_str());
out_cc->inc_indent(); out_cc->inc_indent();
out_cc->println("{"); out_cc->println("{");
GenStringMismatch(out_cc, env, data, str_val.c_str()); GenStringMismatch(out_cc, env, data, str_val);
out_cc->println("}"); out_cc->println("}");
out_cc->dec_indent(); out_cc->dec_indent();
} }
@ -378,8 +380,8 @@ void StringType::GenDynamicSizeRegEx(Output* out_cc, Env* env,
env->RValue(string_length_var())); env->RValue(string_length_var()));
out_cc->inc_indent(); out_cc->inc_indent();
out_cc->println("{"); out_cc->println("{");
GenStringMismatch(out_cc, env, data, string tmp = strfmt("\"%s\"", regex_->str().c_str());
fmt("\"%s\"", regex_->str().c_str())); GenStringMismatch(out_cc, env, data, tmp);
out_cc->println("}"); out_cc->println("}");
out_cc->dec_indent(); out_cc->dec_indent();
} }

View file

@ -44,7 +44,7 @@ protected:
// Generate a string mismatch exception // Generate a string mismatch exception
void GenStringMismatch(Output* out_cc, Env* env, void GenStringMismatch(Output* out_cc, Env* env,
const DataPtr& data, const char *pattern); const DataPtr& data, string pattern);
void DoGenParseCode(Output* out, Env* env, const DataPtr& data, int flags); void DoGenParseCode(Output* out, Env* env, const DataPtr& data, int flags);

View file

@ -283,7 +283,7 @@ void Type::Prepare(Env* env, int flags)
if ( attr_if_expr() ) if ( attr_if_expr() )
{ {
ASSERT(value_var()); ASSERT(value_var());
ID *has_value_id = new ID(fmt("has_%s", value_var()->Name())); ID *has_value_id = new ID(strfmt("has_%s", value_var()->Name()));
has_value_field_ = new LetField(has_value_id, has_value_field_ = new LetField(has_value_id,
extern_type_bool->Clone(), extern_type_bool->Clone(),
attr_if_expr()); attr_if_expr());
@ -294,7 +294,7 @@ void Type::Prepare(Env* env, int flags)
{ {
ASSERT(flags & TO_BE_PARSED); ASSERT(flags & TO_BE_PARSED);
ID *parsing_complete_var = ID *parsing_complete_var =
new ID(fmt("%s_parsing_complete", new ID(strfmt("%s_parsing_complete",
value_var() ? value_var()->Name() : "val")); value_var() ? value_var()->Name() : "val"));
DEBUG_MSG("Adding parsing complete var: %s\n", DEBUG_MSG("Adding parsing complete var: %s\n",
parsing_complete_var->Name()); parsing_complete_var->Name());
@ -837,7 +837,7 @@ bool Type::AddSizeVar(Output* out_cc, Env* env)
ASSERT(! incremental_input()); ASSERT(! incremental_input());
ID *size_var_id = new ID(fmt("%s__size", ID *size_var_id = new ID(strfmt("%s__size",
value_var() ? value_var()->Name() : decl_id()->Name())); value_var() ? value_var()->Name() : decl_id()->Name()));
DEBUG_MSG("adding size var `%s' to env %p\n", size_var_id->Name(), env); DEBUG_MSG("adding size var `%s' to env %p\n", size_var_id->Name(), env);

View file

@ -253,7 +253,7 @@ string TypeDecl::ParseFuncPrototype(Env* env)
if ( RequiresAnalyzerContext::compute(type_) ) if ( RequiresAnalyzerContext::compute(type_) )
{ {
Type *param_type = analyzer_context()->param_type(); Type *param_type = analyzer_context()->param_type();
params += fmt(", %s %s", params += strfmt(", %s %s",
param_type->DataTypeConstRefStr().c_str(), param_type->DataTypeConstRefStr().c_str(),
env->LValue(analyzer_context_id)); env->LValue(analyzer_context_id));
} }
@ -261,7 +261,7 @@ string TypeDecl::ParseFuncPrototype(Env* env)
// Add parameter "byteorder" // Add parameter "byteorder"
if ( type_->RequiresByteOrder() && ! type_->attr_byteorder_expr() ) if ( type_->RequiresByteOrder() && ! type_->attr_byteorder_expr() )
{ {
params += fmt(", int %s", env->LValue(byteorder_id)); params += strfmt(", int %s", env->LValue(byteorder_id));
} }
// Returns "<return type> %s<func name>(<params>)%s". // Returns "<return type> %s<func name>(<params>)%s".
@ -358,7 +358,8 @@ void TypeDecl::GenParseFunc(Output* out_h, Output* out_cc)
out_h->println(proto.c_str(), "", ";"); out_h->println(proto.c_str(), "", ";");
out_cc->println(proto.c_str(), fmt("%s::", class_name().c_str()), ""); string tmp = strfmt("%s::", class_name().c_str());
out_cc->println(proto.c_str(), tmp.c_str(), "");
out_cc->inc_indent(); out_cc->inc_indent();
out_cc->println("{"); out_cc->println("{");
@ -382,7 +383,7 @@ void TypeDecl::GenInitialBufferLengthFunc(Output* out_h, Output* out_cc)
if ( init_buffer_length < 0 ) // cannot be statically determined if ( init_buffer_length < 0 ) // cannot be statically determined
{ {
throw Exception(type()->attr_length_expr(), throw Exception(type()->attr_length_expr(),
fmt("cannot determine initial buffer length" strfmt("cannot determine initial buffer length"
" for type %s", id_->Name())); " for type %s", id_->Name()));
} }

View file

@ -9,7 +9,4 @@ char* copy_string(const char* s);
string strfmt(const char* fmt, ...); string strfmt(const char* fmt, ...);
char* nfmt(const char* fmt, ...); char* nfmt(const char* fmt, ...);
// const char* fmt(const char* fmt, ...);
#define fmt(x...) strfmt(x).c_str()
#endif /* pac_utils_h */ #endif /* pac_utils_h */