Commit 5b6a68e0 by alokp@chromium.org

Replaced pp::Token::value with pp::Token::text. The term value will be used for…

Replaced pp::Token::value with pp::Token::text. The term value will be used for a function which will convert text to integer/float constant. git-svn-id: https://angleproject.googlecode.com/svn/trunk@1175 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent fadc2058
...@@ -407,9 +407,9 @@ int string_input(char* buf, int max_size, yyscan_t yyscanner) { ...@@ -407,9 +407,9 @@ int string_input(char* buf, int max_size, yyscan_t yyscanner) {
#if ANGLE_USE_NEW_PREPROCESSOR #if ANGLE_USE_NEW_PREPROCESSOR
pp::Token token; pp::Token token;
yyget_extra(yyscanner)->preprocessor.lex(&token); yyget_extra(yyscanner)->preprocessor.lex(&token);
len = token.type == pp::Token::LAST ? 0 : token.value.size(); len = token.type == pp::Token::LAST ? 0 : token.text.size();
if ((len > 0) && (len < max_size)) if ((len > 0) && (len < max_size))
memcpy(buf, token.value.c_str(), len); memcpy(buf, token.text.c_str(), len);
yyset_lineno(EncodeSourceLoc(token.location.file, token.location.line), yyscanner); yyset_lineno(EncodeSourceLoc(token.location.file, token.location.line), yyscanner);
#else #else
len = yylex_CPP(buf, max_size); len = yylex_CPP(buf, max_size);
......
...@@ -3083,9 +3083,9 @@ int string_input(char* buf, int max_size, yyscan_t yyscanner) { ...@@ -3083,9 +3083,9 @@ int string_input(char* buf, int max_size, yyscan_t yyscanner) {
#if ANGLE_USE_NEW_PREPROCESSOR #if ANGLE_USE_NEW_PREPROCESSOR
pp::Token token; pp::Token token;
yyget_extra(yyscanner)->preprocessor.lex(&token); yyget_extra(yyscanner)->preprocessor.lex(&token);
len = token.type == pp::Token::LAST ? 0 : token.value.size(); len = token.type == pp::Token::LAST ? 0 : token.text.size();
if ((len > 0) && (len < max_size)) if ((len > 0) && (len < max_size))
memcpy(buf, token.value.c_str(), len); memcpy(buf, token.text.c_str(), len);
yyset_lineno(EncodeSourceLoc(token.location.file, token.location.line),yyscanner); yyset_lineno(EncodeSourceLoc(token.location.file, token.location.line),yyscanner);
#else #else
len = yylex_CPP(buf, max_size); len = yylex_CPP(buf, max_size);
......
...@@ -1846,7 +1846,7 @@ int yylex(YYSTYPE* lvalp, Context* context) ...@@ -1846,7 +1846,7 @@ int yylex(YYSTYPE* lvalp, Context* context)
switch (token->type) switch (token->type)
{ {
case pp::Token::CONST_INT: case pp::Token::CONST_INT:
*lvalp = strtoll(token->value.c_str(), NULL, 0); *lvalp = strtoll(token->text.c_str(), NULL, 0);
type = CONST_INT; type = CONST_INT;
break; break;
......
...@@ -193,7 +193,7 @@ int yylex(YYSTYPE* lvalp, Context* context) ...@@ -193,7 +193,7 @@ int yylex(YYSTYPE* lvalp, Context* context)
switch (token->type) switch (token->type)
{ {
case pp::Token::CONST_INT: case pp::Token::CONST_INT:
*lvalp = strtoll(token->value.c_str(), NULL, 0); *lvalp = strtoll(token->text.c_str(), NULL, 0);
type = CONST_INT; type = CONST_INT;
break; break;
......
...@@ -73,7 +73,7 @@ void MacroExpander::lex(Token* token) ...@@ -73,7 +73,7 @@ void MacroExpander::lex(Token* token)
if (token->expansionDisabled()) if (token->expansionDisabled())
break; break;
MacroSet::const_iterator iter = mMacroSet->find(token->value); MacroSet::const_iterator iter = mMacroSet->find(token->text);
if (iter == mMacroSet->end()) if (iter == mMacroSet->end())
break; break;
...@@ -152,7 +152,7 @@ bool MacroExpander::pushMacro(const Macro& macro, const Token& identifier) ...@@ -152,7 +152,7 @@ bool MacroExpander::pushMacro(const Macro& macro, const Token& identifier)
assert(!macro.disabled); assert(!macro.disabled);
assert(!identifier.expansionDisabled()); assert(!identifier.expansionDisabled());
assert(identifier.type == Token::IDENTIFIER); assert(identifier.type == Token::IDENTIFIER);
assert(identifier.value == macro.name); assert(identifier.text == macro.name);
std::vector<Token> replacements; std::vector<Token> replacements;
if (!expandMacro(macro, identifier, &replacements)) if (!expandMacro(macro, identifier, &replacements))
...@@ -202,13 +202,13 @@ bool MacroExpander::expandMacro(const Macro& macro, ...@@ -202,13 +202,13 @@ bool MacroExpander::expandMacro(const Macro& macro,
{ {
std::stringstream stream; std::stringstream stream;
stream << identifier.location.line; stream << identifier.location.line;
repl.value = stream.str(); repl.text = stream.str();
} }
else if (macro.name == kFile) else if (macro.name == kFile)
{ {
std::stringstream stream; std::stringstream stream;
stream << identifier.location.file; stream << identifier.location.file;
repl.value = stream.str(); repl.text = stream.str();
} }
} }
} }
...@@ -254,7 +254,7 @@ bool MacroExpander::collectMacroArgs(const Macro& macro, ...@@ -254,7 +254,7 @@ bool MacroExpander::collectMacroArgs(const Macro& macro,
if (token.type == Token::LAST) if (token.type == Token::LAST)
{ {
mDiagnostics->report(Diagnostics::MACRO_UNTERMINATED_INVOCATION, mDiagnostics->report(Diagnostics::MACRO_UNTERMINATED_INVOCATION,
identifier.location, identifier.value); identifier.location, identifier.text);
// Do not lose EOF token. // Do not lose EOF token.
ungetToken(token); ungetToken(token);
return false; return false;
...@@ -303,7 +303,7 @@ bool MacroExpander::collectMacroArgs(const Macro& macro, ...@@ -303,7 +303,7 @@ bool MacroExpander::collectMacroArgs(const Macro& macro,
Diagnostics::ID id = args->size() < macro.parameters.size() ? Diagnostics::ID id = args->size() < macro.parameters.size() ?
Diagnostics::MACRO_TOO_FEW_ARGS : Diagnostics::MACRO_TOO_FEW_ARGS :
Diagnostics::MACRO_TOO_MANY_ARGS; Diagnostics::MACRO_TOO_MANY_ARGS;
mDiagnostics->report(id, identifier.location, identifier.value); mDiagnostics->report(id, identifier.location, identifier.text);
return false; return false;
} }
...@@ -344,7 +344,7 @@ void MacroExpander::replaceMacroParams(const Macro& macro, ...@@ -344,7 +344,7 @@ void MacroExpander::replaceMacroParams(const Macro& macro,
// There is no need to search for macro params every time. // There is no need to search for macro params every time.
// The param index can be cached with the replacement token. // The param index can be cached with the replacement token.
Macro::Parameters::const_iterator iter = std::find( Macro::Parameters::const_iterator iter = std::find(
macro.parameters.begin(), macro.parameters.end(), repl.value); macro.parameters.begin(), macro.parameters.end(), repl.text);
if (iter == macro.parameters.end()) if (iter == macro.parameters.end())
{ {
replacements->push_back(repl); replacements->push_back(repl);
......
...@@ -70,7 +70,7 @@ void Preprocessor::predefineMacro(const char* name, int value) ...@@ -70,7 +70,7 @@ void Preprocessor::predefineMacro(const char* name, int value)
Token token; Token token;
token.type = Token::CONST_INT; token.type = Token::CONST_INT;
token.value = stream.str(); token.text = stream.str();
Macro macro; Macro macro;
macro.predefined = true; macro.predefined = true;
...@@ -97,11 +97,11 @@ void Preprocessor::lex(Token* token) ...@@ -97,11 +97,11 @@ void Preprocessor::lex(Token* token)
break; break;
case Token::PP_NUMBER: case Token::PP_NUMBER:
mImpl->diagnostics->report(Diagnostics::INVALID_NUMBER, mImpl->diagnostics->report(Diagnostics::INVALID_NUMBER,
token->location, token->value); token->location, token->text);
break; break;
case Token::PP_OTHER: case Token::PP_OTHER:
mImpl->diagnostics->report(Diagnostics::INVALID_CHARACTER, mImpl->diagnostics->report(Diagnostics::INVALID_CHARACTER,
token->location, token->value); token->location, token->text);
break; break;
default: default:
validToken = true; validToken = true;
......
...@@ -14,7 +14,7 @@ void Token::reset() ...@@ -14,7 +14,7 @@ void Token::reset()
type = 0; type = 0;
flags = 0; flags = 0;
location = SourceLocation(); location = SourceLocation();
value.clear(); text.clear();
} }
bool Token::equals(const Token& other) const bool Token::equals(const Token& other) const
...@@ -22,7 +22,7 @@ bool Token::equals(const Token& other) const ...@@ -22,7 +22,7 @@ bool Token::equals(const Token& other) const
return (type == other.type) && return (type == other.type) &&
(flags == other.flags) && (flags == other.flags) &&
(location == other.location) && (location == other.location) &&
(value == other.value); (text == other.text);
} }
void Token::setAtStartOfLine(bool start) void Token::setAtStartOfLine(bool start)
...@@ -54,7 +54,7 @@ std::ostream& operator<<(std::ostream& out, const Token& token) ...@@ -54,7 +54,7 @@ std::ostream& operator<<(std::ostream& out, const Token& token)
if (token.hasLeadingSpace()) if (token.hasLeadingSpace())
out << " "; out << " ";
out << token.value; out << token.text;
return out; return out;
} }
......
...@@ -81,7 +81,7 @@ struct Token ...@@ -81,7 +81,7 @@ struct Token
int type; int type;
unsigned int flags; unsigned int flags;
SourceLocation location; SourceLocation location;
std::string value; std::string text;
}; };
inline bool operator==(const Token& lhs, const Token& rhs) inline bool operator==(const Token& lhs, const Token& rhs)
......
...@@ -2313,7 +2313,7 @@ void Tokenizer::setLineNumber(int line) ...@@ -2313,7 +2313,7 @@ void Tokenizer::setLineNumber(int line)
void Tokenizer::lex(Token* token) void Tokenizer::lex(Token* token)
{ {
token->type = pplex(&token->value,&token->location,mHandle); token->type = pplex(&token->text,&token->location,mHandle);
token->flags = 0; token->flags = 0;
token->setAtStartOfLine(mContext.lineStart); token->setAtStartOfLine(mContext.lineStart);
......
...@@ -297,7 +297,7 @@ void Tokenizer::setLineNumber(int line) ...@@ -297,7 +297,7 @@ void Tokenizer::setLineNumber(int line)
void Tokenizer::lex(Token* token) void Tokenizer::lex(Token* token)
{ {
token->type = yylex(&token->value, &token->location, mHandle); token->type = yylex(&token->text, &token->location, mHandle);
token->flags = 0; token->flags = 0;
token->setAtStartOfLine(mContext.lineStart); token->setAtStartOfLine(mContext.lineStart);
......
...@@ -88,7 +88,7 @@ TEST_P(CharTest, Identified) ...@@ -88,7 +88,7 @@ TEST_P(CharTest, Identified)
pp::Token token; pp::Token token;
mPreprocessor.lex(&token); mPreprocessor.lex(&token);
EXPECT_EQ(expectedType, token.type); EXPECT_EQ(expectedType, token.type);
EXPECT_EQ(expectedValue, token.value); EXPECT_EQ(expectedValue, token.text);
}; };
// Note +1 for the max-value in range. It is there because the max-value // Note +1 for the max-value in range. It is there because the max-value
......
...@@ -51,7 +51,7 @@ TEST_F(BlockCommentTest, CommentReplacedWithSpace) ...@@ -51,7 +51,7 @@ TEST_F(BlockCommentTest, CommentReplacedWithSpace)
pp::Token token; pp::Token token;
mPreprocessor.lex(&token); mPreprocessor.lex(&token);
EXPECT_EQ(pp::Token::IDENTIFIER, token.type); EXPECT_EQ(pp::Token::IDENTIFIER, token.type);
EXPECT_EQ("bar", token.value); EXPECT_EQ("bar", token.text);
EXPECT_TRUE(token.hasLeadingSpace()); EXPECT_TRUE(token.hasLeadingSpace());
} }
......
...@@ -855,7 +855,7 @@ TEST_F(DefineTest, Predefined_LINE1) ...@@ -855,7 +855,7 @@ TEST_F(DefineTest, Predefined_LINE1)
pp::Token token; pp::Token token;
mPreprocessor.lex(&token); mPreprocessor.lex(&token);
EXPECT_EQ(pp::Token::CONST_INT, token.type); EXPECT_EQ(pp::Token::CONST_INT, token.type);
EXPECT_EQ("3", token.value); EXPECT_EQ("3", token.text);
} }
TEST_F(DefineTest, Predefined_LINE2) TEST_F(DefineTest, Predefined_LINE2)
...@@ -867,7 +867,7 @@ TEST_F(DefineTest, Predefined_LINE2) ...@@ -867,7 +867,7 @@ TEST_F(DefineTest, Predefined_LINE2)
pp::Token token; pp::Token token;
mPreprocessor.lex(&token); mPreprocessor.lex(&token);
EXPECT_EQ(pp::Token::CONST_INT, token.type); EXPECT_EQ(pp::Token::CONST_INT, token.type);
EXPECT_EQ("10", token.value); EXPECT_EQ("10", token.text);
} }
TEST_F(DefineTest, Predefined_FILE1) TEST_F(DefineTest, Predefined_FILE1)
...@@ -878,7 +878,7 @@ TEST_F(DefineTest, Predefined_FILE1) ...@@ -878,7 +878,7 @@ TEST_F(DefineTest, Predefined_FILE1)
pp::Token token; pp::Token token;
mPreprocessor.lex(&token); mPreprocessor.lex(&token);
EXPECT_EQ(pp::Token::CONST_INT, token.type); EXPECT_EQ(pp::Token::CONST_INT, token.type);
EXPECT_EQ("2", token.value); EXPECT_EQ("2", token.text);
} }
TEST_F(DefineTest, Predefined_FILE2) TEST_F(DefineTest, Predefined_FILE2)
...@@ -889,5 +889,5 @@ TEST_F(DefineTest, Predefined_FILE2) ...@@ -889,5 +889,5 @@ TEST_F(DefineTest, Predefined_FILE2)
pp::Token token; pp::Token token;
mPreprocessor.lex(&token); mPreprocessor.lex(&token);
EXPECT_EQ(pp::Token::CONST_INT, token.type); EXPECT_EQ(pp::Token::CONST_INT, token.type);
EXPECT_EQ("21", token.value); EXPECT_EQ("21", token.text);
} }
...@@ -20,7 +20,7 @@ protected: ...@@ -20,7 +20,7 @@ protected:
pp::Token token; pp::Token token;
mPreprocessor.lex(&token); mPreprocessor.lex(&token);
EXPECT_EQ(pp::Token::IDENTIFIER, token.type); EXPECT_EQ(pp::Token::IDENTIFIER, token.type);
EXPECT_EQ(str, token.value); EXPECT_EQ(str, token.text);
} }
}; };
......
...@@ -20,7 +20,7 @@ protected: ...@@ -20,7 +20,7 @@ protected:
pp::Token token; pp::Token token;
mPreprocessor.lex(&token); mPreprocessor.lex(&token);
EXPECT_EQ(pp::Token::IDENTIFIER, token.type); EXPECT_EQ(pp::Token::IDENTIFIER, token.type);
EXPECT_EQ("foo", token.value); EXPECT_EQ("foo", token.text);
EXPECT_EQ(location.file, token.location.file); EXPECT_EQ(location.file, token.location.file);
EXPECT_EQ(location.line, token.location.line); EXPECT_EQ(location.line, token.location.line);
...@@ -114,7 +114,7 @@ TEST_F(LocationTest, EndOfFileWithoutNewline) ...@@ -114,7 +114,7 @@ TEST_F(LocationTest, EndOfFileWithoutNewline)
pp::Token token; pp::Token token;
mPreprocessor.lex(&token); mPreprocessor.lex(&token);
EXPECT_EQ(pp::Token::IDENTIFIER, token.type); EXPECT_EQ(pp::Token::IDENTIFIER, token.type);
EXPECT_EQ("foo", token.value); EXPECT_EQ("foo", token.text);
EXPECT_EQ(0, token.location.file); EXPECT_EQ(0, token.location.file);
EXPECT_EQ(1, token.location.line); EXPECT_EQ(1, token.location.line);
...@@ -132,7 +132,7 @@ TEST_F(LocationTest, EndOfFileAfterNewline) ...@@ -132,7 +132,7 @@ TEST_F(LocationTest, EndOfFileAfterNewline)
pp::Token token; pp::Token token;
mPreprocessor.lex(&token); mPreprocessor.lex(&token);
EXPECT_EQ(pp::Token::IDENTIFIER, token.type); EXPECT_EQ(pp::Token::IDENTIFIER, token.type);
EXPECT_EQ("foo", token.value); EXPECT_EQ("foo", token.text);
EXPECT_EQ(0, token.location.file); EXPECT_EQ(0, token.location.file);
EXPECT_EQ(1, token.location.line); EXPECT_EQ(1, token.location.line);
...@@ -150,7 +150,7 @@ TEST_F(LocationTest, EndOfFileAfterEmptyString) ...@@ -150,7 +150,7 @@ TEST_F(LocationTest, EndOfFileAfterEmptyString)
pp::Token token; pp::Token token;
mPreprocessor.lex(&token); mPreprocessor.lex(&token);
EXPECT_EQ(pp::Token::IDENTIFIER, token.type); EXPECT_EQ(pp::Token::IDENTIFIER, token.type);
EXPECT_EQ("foo", token.value); EXPECT_EQ("foo", token.text);
EXPECT_EQ(0, token.location.file); EXPECT_EQ(0, token.location.file);
EXPECT_EQ(1, token.location.line); EXPECT_EQ(1, token.location.line);
......
...@@ -50,7 +50,7 @@ TEST_P(IntegerTest, Identified) ...@@ -50,7 +50,7 @@ TEST_P(IntegerTest, Identified)
pp::Token token; pp::Token token;
mPreprocessor.lex(&token); mPreprocessor.lex(&token);
EXPECT_EQ(pp::Token::CONST_INT, token.type); EXPECT_EQ(pp::Token::CONST_INT, token.type);
EXPECT_EQ(str, token.value); EXPECT_EQ(str, token.text);
} }
INSTANTIATE_TEST_CASE_P(DecimalInteger, INSTANTIATE_TEST_CASE_P(DecimalInteger,
...@@ -89,7 +89,7 @@ class FloatTest : public PreprocessorTest ...@@ -89,7 +89,7 @@ class FloatTest : public PreprocessorTest
pp::Token token; pp::Token token;
mPreprocessor.lex(&token); mPreprocessor.lex(&token);
EXPECT_EQ(pp::Token::CONST_FLOAT, token.type); EXPECT_EQ(pp::Token::CONST_FLOAT, token.type);
EXPECT_EQ(str, token.value); EXPECT_EQ(str, token.text);
} }
}; };
......
...@@ -27,7 +27,7 @@ TEST_P(OperatorTest, Identified) ...@@ -27,7 +27,7 @@ TEST_P(OperatorTest, Identified)
pp::Token token; pp::Token token;
mPreprocessor.lex(&token); mPreprocessor.lex(&token);
EXPECT_EQ(param.op, token.type); EXPECT_EQ(param.op, token.type);
EXPECT_EQ(param.str, token.value); EXPECT_EQ(param.str, token.text);
} }
static const OperatorTestParam kOperators[] = { static const OperatorTestParam kOperators[] = {
......
...@@ -19,7 +19,7 @@ class SpaceTest : public PreprocessorTest ...@@ -19,7 +19,7 @@ class SpaceTest : public PreprocessorTest
// "foo" is returned after ignoring the whitespace characters. // "foo" is returned after ignoring the whitespace characters.
mPreprocessor.lex(&token); mPreprocessor.lex(&token);
EXPECT_EQ(pp::Token::IDENTIFIER, token.type); EXPECT_EQ(pp::Token::IDENTIFIER, token.type);
EXPECT_EQ("foo", token.value); EXPECT_EQ("foo", token.text);
// The whitespace character is however recorded with the next token. // The whitespace character is however recorded with the next token.
EXPECT_TRUE(token.hasLeadingSpace()); EXPECT_TRUE(token.hasLeadingSpace());
} }
...@@ -88,7 +88,7 @@ TEST_F(SpaceTest, LeadingSpace) ...@@ -88,7 +88,7 @@ TEST_F(SpaceTest, LeadingSpace)
pp::Token token; pp::Token token;
mPreprocessor.lex(&token); mPreprocessor.lex(&token);
EXPECT_EQ(pp::Token::IDENTIFIER, token.type); EXPECT_EQ(pp::Token::IDENTIFIER, token.type);
EXPECT_EQ("foo", token.value); EXPECT_EQ("foo", token.text);
EXPECT_TRUE(token.hasLeadingSpace()); EXPECT_TRUE(token.hasLeadingSpace());
mPreprocessor.lex(&token); mPreprocessor.lex(&token);
...@@ -101,6 +101,6 @@ TEST_F(SpaceTest, LeadingSpace) ...@@ -101,6 +101,6 @@ TEST_F(SpaceTest, LeadingSpace)
mPreprocessor.lex(&token); mPreprocessor.lex(&token);
EXPECT_EQ(pp::Token::IDENTIFIER, token.type); EXPECT_EQ(pp::Token::IDENTIFIER, token.type);
EXPECT_EQ("bar", token.value); EXPECT_EQ("bar", token.text);
EXPECT_FALSE(token.hasLeadingSpace()); EXPECT_FALSE(token.hasLeadingSpace());
} }
...@@ -15,7 +15,7 @@ TEST(TokenTest, DefaultConstructor) ...@@ -15,7 +15,7 @@ TEST(TokenTest, DefaultConstructor)
EXPECT_EQ(0, token.flags); EXPECT_EQ(0, token.flags);
EXPECT_EQ(0, token.location.line); EXPECT_EQ(0, token.location.line);
EXPECT_EQ(0, token.location.file); EXPECT_EQ(0, token.location.file);
EXPECT_EQ("", token.value); EXPECT_EQ("", token.text);
} }
TEST(TokenTest, Assignment) TEST(TokenTest, Assignment)
...@@ -25,14 +25,14 @@ TEST(TokenTest, Assignment) ...@@ -25,14 +25,14 @@ TEST(TokenTest, Assignment)
token.flags = 1; token.flags = 1;
token.location.line = 1; token.location.line = 1;
token.location.file = 1; token.location.file = 1;
token.value.assign("foo"); token.text.assign("foo");
token = pp::Token(); token = pp::Token();
EXPECT_EQ(0, token.type); EXPECT_EQ(0, token.type);
EXPECT_EQ(0, token.flags); EXPECT_EQ(0, token.flags);
EXPECT_EQ(0, token.location.line); EXPECT_EQ(0, token.location.line);
EXPECT_EQ(0, token.location.file); EXPECT_EQ(0, token.location.file);
EXPECT_EQ("", token.value); EXPECT_EQ("", token.text);
} }
TEST(TokenTest, Equals) TEST(TokenTest, Equals)
...@@ -56,9 +56,9 @@ TEST(TokenTest, Equals) ...@@ -56,9 +56,9 @@ TEST(TokenTest, Equals)
EXPECT_FALSE(token.equals(pp::Token())); EXPECT_FALSE(token.equals(pp::Token()));
token.location.file = 0; token.location.file = 0;
token.value.assign("foo"); token.text.assign("foo");
EXPECT_FALSE(token.equals(pp::Token())); EXPECT_FALSE(token.equals(pp::Token()));
token.value.clear(); token.text.clear();
EXPECT_TRUE(token.equals(pp::Token())); EXPECT_TRUE(token.equals(pp::Token()));
} }
...@@ -76,7 +76,7 @@ TEST(TokenTest, HasLeadingSpace) ...@@ -76,7 +76,7 @@ TEST(TokenTest, HasLeadingSpace)
TEST(TokenTest, Write) TEST(TokenTest, Write)
{ {
pp::Token token; pp::Token token;
token.value.assign("foo"); token.text.assign("foo");
std::stringstream out1; std::stringstream out1;
out1 << token; out1 << token;
EXPECT_TRUE(out1.good()); EXPECT_TRUE(out1.good());
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment