Skip to content

Commit

Permalink
directory::treat_trailing_separator won't add a separator to empty paths
Browse files Browse the repository at this point in the history
explicitly matched lexer rules are returned even if they are set to ignored in current context
added @order special value in metagen script to return the current filtered array element number
an empty token $$ is interpreted as a literal $ in metagen script
charstr ins() and del() methods now take integer position, with negative values addressing the position from end
  • Loading branch information
cameni committed Sep 9, 2012
1 parent a110b36 commit f5f78e4
Show file tree
Hide file tree
Showing 6 changed files with 135 additions and 135 deletions.
2 changes: 1 addition & 1 deletion dir.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ class directory
if( is_separator(c) ) {
if(!shouldbe) path.resize(-1);
}
else if(shouldbe)
else if(shouldbe && c!=0) //don't add separator to an empty path, that would make it absolute
path.append( separator() );
return path;
}
Expand Down
10 changes: 5 additions & 5 deletions doc/metagen.html
Original file line number Diff line number Diff line change
Expand Up @@ -901,11 +901,11 @@ <h4>Generating sequences from arrays</h4>

</tbody>
</table>

<br>
Special array variables:<br>
@index - return current element index (0 based)<br>
@value - write value?<br>

<br>
Special array variables:<br>
@index - return current element index (0 based) in array<br>@order - return the position of the current element in a filtered array<br>
@value - return array element&nbsp;value (arrays of primitive types)<br>
@size - return the array size<br>


Expand Down
82 changes: 57 additions & 25 deletions lexer.h
Original file line number Diff line number Diff line change
Expand Up @@ -683,6 +683,12 @@ class lexer
token ne = nested.cut_left(' ');
if(ne.is_empty()) break;

if(ne == "*.") {
//enable all global rules
br->stbenabled = UMAX64;
br->stbignored = _root.stbignored;
continue;
}
if(ne == '*') {
//inherit all global rules
br->stbenabled = _root.stbenabled;
Expand Down Expand Up @@ -1211,14 +1217,16 @@ class lexer
//@return true if next token belongs to the specified group/sequence.
//@param grp group/sequence id
//@param dst the token read
//@note Since the group is asked for explicitly, it will be returned even if it is currently set to be ignored
bool matches( int grp, charstr& dst )
{
__assert_valid_rule(grp);

next();
next(1,grp);

if( _last != grp ) {
push_back();
if(!ignored(grp))
push_back();
return false;
}

Expand All @@ -1233,14 +1241,16 @@ class lexer
//@return true if next token belongs to the specified group/sequence.
//@param grp group/sequence id
//@param dst the token read
//@note Since the group is asked for explicitly, it will be returned even if it is currently set to be ignored
bool matches( int grp, token& dst )
{
__assert_valid_rule(grp);

next();
next(1,grp);

if( _last != grp ) {
push_back();
if(!ignored(grp))
push_back();
return false;
}

Expand All @@ -1251,13 +1261,14 @@ class lexer
///Match group of characters. Pushes the read token back if not matched.
//@return true if next token belongs to the specified group/sequence.
//@param grp group/sequence id
//@note Since the group is asked for explicitly, it will be returned even if it is currently set to be ignored
bool matches( int grp )
{
__assert_valid_rule(grp);

bool res = next() == grp;
bool res = next(1,grp) == grp;

if(!res)
if(!res && !ignored(grp))
push_back();
return res;
}
Expand All @@ -1274,11 +1285,11 @@ class lexer
//@param val literal string to match
//@param peek set to true if the function should return match status instead of throwing the exception
//@return match result if @a peek was set to true (otherwise an exception is thrown)
bool match( const token& val, bool peek = false )
bool match( const token& val, const char* errmsg=0 )
{
bool res = matches(val);

if( !res && !peek )
if(!res)
{
_err = lexception::ERR_EXTERNAL_ERROR;

Expand All @@ -1297,15 +1308,18 @@ class lexer
//@param c literal character to match
//@param peek set to true if the function should return match status instead of throwing the exception
//@return match result if @a peek was set to true (otherwise an exception is thrown)
bool match( char c, bool peek = false )
bool match( char c, const char* errmsg=0 )
{
bool res = matches(c);

if( !res && !peek ) {
if(!res) {
_err = lexception::ERR_EXTERNAL_ERROR;

on_error_prefix(false, _errtext, current_line());
_errtext << "expected `" << c << "'";
if(errmsg)
_errtext << errmsg;
else
_errtext << "expected `" << c << "'";
on_error_suffix(_errtext);

throw lexception(_err, _errtext);
Expand All @@ -1319,17 +1333,20 @@ class lexer
//@param dst destination string that is to receive the matched value
//@param peek set to true if the function should return match status instead of throwing the exception
//@return match result if @a peek was set to true (otherwise an exception is thrown)
bool match( int grp, charstr& dst, bool peek = false )
bool match( int grp, charstr& dst, const char* errmsg=0 )
{
bool res = matches(grp, dst);

if( !res && !peek ) {
if(!res) {
_err = lexception::ERR_EXTERNAL_ERROR;

on_error_prefix(false, _errtext, current_line());

const entity& ent = get_entity(grp);
_errtext << "expected a " << ent.entity_type() << " <<" << ent.name << ">>";
if(errmsg)
_errtext << errmsg;
else
_errtext << "expected a " << ent.entity_type() << " <<" << ent.name << ">>";

on_error_suffix(_errtext);

Expand All @@ -1344,17 +1361,20 @@ class lexer
//@param dst destination token that is to receive the matched value
//@param peek set to true if the function should return match status instead of throwing the exception
//@return match result if @a peek was set to true (otherwise an exception is thrown)
bool match( int grp, token& dst, bool peek = false )
bool match( int grp, token& dst, const char* errmsg=0 )
{
bool res = matches(grp, dst);

if( !res && !peek ) {
if(!res) {
_err = lexception::ERR_EXTERNAL_ERROR;

on_error_prefix(false, _errtext, current_line());

const entity& ent = get_entity(grp);
_errtext << "expected a " << ent.entity_type() << " <<" << ent.name << ">>";
if(errmsg)
_errtext << errmsg;
else
_errtext << "expected a " << ent.entity_type() << " <<" << ent.name << ">>";

on_error_suffix(_errtext);

Expand All @@ -1368,17 +1388,20 @@ class lexer
//@param grp group id to match
//@param peek set to true if the function should return match status instead of throwing the exception
//@return lextoken result if @a peek was set to true (otherwise an exception is thrown)
const lextoken& match( int grp, bool peek = false )
const lextoken& match( int grp, const char* errmsg=0 )
{
bool res = matches(grp);

if( !res && !peek ) {
if(!res) {
_err = lexception::ERR_EXTERNAL_ERROR;

on_error_prefix(false, _errtext, current_line());

const entity& ent = get_entity(grp);
_errtext << "expected a " << ent.entity_type() << " <<" << ent.name << ">>";
if(errmsg)
_errtext << errmsg;
else
_errtext << "expected a " << ent.entity_type() << " <<" << ent.name << ">>";

on_error_suffix(_errtext);

Expand All @@ -1392,16 +1415,19 @@ class lexer
}

//@return true if end of file was matched
bool match_end( bool peek = false )
bool match_end( const char* errmsg=0 )
{
bool res = matches_end();

if( !res && !peek ) {
if(!res) {
_err = lexception::ERR_EXTERNAL_ERROR;

on_error_prefix(false, _errtext, current_line());

_errtext << "expected end of file";
if(errmsg)
_errtext << errmsg;
else
_errtext << "expected end of file";

on_error_suffix(_errtext);

Expand Down Expand Up @@ -1656,6 +1682,7 @@ class lexer

//@return last token read
const lextoken& last() const { return _last; }
lextoken& last() { return _last; }

///Return remainder of the input
token remainder() const { return _pushback ? _last.tok : _tok; }
Expand Down Expand Up @@ -1725,6 +1752,11 @@ class lexer
return _errtext;
}

void clear_err() {
_err = 0;
_errtext.reset();
}

///Prepare to throw an external lexer exception.
///This is used to obtain an exception with the same format as with an internal lexer exception.
///The line and column info relates to the last returned token. After using the return value to
Expand Down Expand Up @@ -2370,8 +2402,8 @@ class lexer
bool enabled( const sequence& seq ) const { return (*_stack.last())->enabled(seq.id); }
bool ignored( const sequence& seq ) const { return (*_stack.last())->ignored(seq.id); }

bool enabled( int seq ) const { return (*_stack.last())->enabled(-1-seq); }
bool ignored( int seq ) const { return (*_stack.last())->ignored(-1-seq); }
bool enabled( int seq ) const { return seq<0 ? (*_stack.last())->enabled(-1-seq) : true; }
bool ignored( int seq ) const { return seq<0 ? (*_stack.last())->ignored(-1-seq) : false; }

void enable( const sequence& seq, bool en ) {
(*_stack.last())->enable(seq.id, en);
Expand Down
36 changes: 29 additions & 7 deletions metastream/metagen.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,10 +121,11 @@ class metagen //: public binstream
Varx* varparent;
const uchar* data; ///< cache position
int index; ///< current element index for arrays
int order; ///< current filtered element index for arrays


Varx() : var(0), varparent(0), data(0), index(-1) {}
Varx( const Var* v, const uchar* d ) : var(v), varparent(0), data(d), index(-1) {}
Varx() : var(0), varparent(0), data(0), index(-1), order(-1) {}
Varx( const Var* v, const uchar* d ) : var(v), varparent(0), data(d), index(-1), order(-1) {}

bool find_containing_array_element( Varx& ch ) const
{
Expand Down Expand Up @@ -449,15 +450,21 @@ class metagen //: public binstream
const lextoken& tok = lex.last();

flags = 0;
brace = 0;
depth = 0;

if(tok == '$') {
varname = tok.tok; // $$ -> literal $
return true;
}

while( tok.tok == '-' ) {
flags += 1 << rEAT_LEFT;
lex.next();
}

if( tok.tok != '{' && tok.tok != '[' && tok.tok != '(' ) {
brace = 0;
if( tok.tok != '{' && tok.tok != '[' && tok.tok != '(' )
lex.push_back();
}
else
brace = tok.tok[0];

Expand All @@ -474,7 +481,6 @@ class metagen //: public binstream
}
varname = tok.tok;

depth = 0;
const char* p = tok.tok.ptr();
const char* pe = tok.tok.ptre();
for( ; p<pe; ++p )
Expand Down Expand Up @@ -669,6 +675,11 @@ class metagen //: public binstream
if(v.is_array_element())
mg.write_as_string(v.index);
}
else if(attrib == "@order") {
DASSERT( v.is_array_element() );
if(v.is_array_element())
mg.write_as_string(v.order);
}
else if(attrib == "@value") {
v.write_var(mg);
}
Expand Down Expand Up @@ -719,6 +730,16 @@ class metagen //: public binstream
if(!succ) return succ;

do {
if(lex.matches('$')) {
(*sequence.last())->stext.shift_end(1);

TagEmpty* etag = new TagEmpty;
*sequence.add() = etag;

bool succ = etag->parse( lex, tout.eat_right() );
if(!succ) return succ;
}

if(!tout.parse(lex))
break;

Expand Down Expand Up @@ -860,7 +881,7 @@ class metagen //: public binstream

bool evalcond = cond.size()>0;

int i=0;
int i=0,fi=0;
for( ; n>0; --n,ve.next() )
{
if( evalcond && !eval_cond(mg, ve) )
Expand All @@ -870,6 +891,7 @@ class metagen //: public binstream
else atr_rest.process(mg, ve);

ve.index = i;
ve.order = fi++;

atr_body.process(mg, ve);
++i;
Expand Down
Loading

0 comments on commit f5f78e4

Please sign in to comment.