MOOSE - Multiscale Object Oriented Simulation Environment
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
Wildcard.cpp
Go to the documentation of this file.
1 /**********************************************************************
2 ** This program is part of 'MOOSE', the
3 ** Messaging Object Oriented Simulation Environment.
4 ** Copyright (C) 2003-2007 Upinder S. Bhalla. and NCBS
5 ** It is made available under the terms of the
6 ** GNU Lesser General Public License version 2.1
7 ** See the file COPYING.LIB for the full notice.
8 **********************************************************************/
9 
10 #include "header.h"
11 #include <stdio.h>
12 #include "Neutral.h"
13 #include "Shell.h"
14 #include "Wildcard.h"
15 // #define NOINDEX (UINT_MAX - 2)
16 
17 static int wildcardRelativeFind( ObjId start, const vector< string >& path,
18  unsigned int depth, vector< ObjId >& ret );
19 
20 static unsigned int findBraceContent( const string& path,
21  string& beforeBrace, string& insideBrace );
22 
23 static bool matchName( ObjId id, unsigned int index,
24  const string& beforeBrace, const string& insideBrace );
25 
26 // static bool matchBeforeBrace( ObjId id, const string& name );
27 
28 static bool matchInsideBrace( ObjId id, const string& inside );
35 static bool wildcardFieldComparison( ObjId oid, const string& mid )
36 {
37  // where = could be the usual comparison operators and val
38  // could be a number. No strings yet
39 
40  string::size_type pos = mid.find(')');
41  if ( pos == string::npos )
42  return 0;
43  string fieldName = mid.substr( 0, pos );
44  string::size_type pos2 = mid.find_last_of( "=<>" );
45  if ( pos2 == string::npos )
46  return 0;
47  string op = mid.substr( pos + 1, pos2 - pos );
48 
49  string testValue = mid.substr( pos2 + 1 );
50 
51  if ( testValue.length() == 0 )
52  return 0;
53 
54  /*
55  const Finfo* f = id()->findFinfo( fieldName );
56  if ( !f )
57  return 0;
58 
59  string actualValue;
60  bool ret = f->strGet( id.eref(), actualValue );
61  */
62  string actualValue;
63 
64  bool ret = SetGet::strGet( oid, fieldName, actualValue );
65  if ( ret == 0 )
66  return 0;
67  if ( op == "==" || op == "=" )
68  return ( testValue == actualValue );
69  if ( op == "!=" )
70  return ( testValue != actualValue );
71 
72  double v1 = atof( actualValue.c_str() );
73  double v2 = atof( testValue.c_str() );
74  if ( op == ">" )
75  return ( v1 > v2 );
76  if ( op == ">=" )
77  return ( v1 >= v2 );
78  if ( op == "<" )
79  return ( v1 < v2 );
80  if ( op == "<=" )
81  return ( v1 <= v2 );
82 
83  return 0;
84 }
85 
89 static int innerFind( const string& path, vector< ObjId >& ret)
90 {
91  if ( path == "/" || path == "/root")
92  {
93  ret.push_back( Id() );
94  return 1;
95  }
96 
97  vector< string > names;
98  vector< vector< unsigned int > > indices;
99  bool isAbsolute = Shell::chopString( path, names, '/' );
100  ObjId start; // set to root id.
101  if ( !isAbsolute )
102  {
103  Shell* s = reinterpret_cast< Shell* >( ObjId().data() );
104  start = s->getCwe();
105  }
106 
107  /*
108  if ( path[0] == '/' ) {
109  // separateString puts in a blank first entry if the first char
110  // is a separator.
111  separateString( path.substr( 1 ) , names, "/" );
112  } else {
113  Shell* s = reinterpret_cast< Shell* >( Id.eref().data() );
114  separateString( path, names, "/" );
115  start = s->getCwe();
116  }
117  */
118  return wildcardRelativeFind( start, names, 0, ret );
119 }
120 
121 /*
122 static int wildcardRelativeFind( Id start, const vector< string >& path,
123  unsigned int depth, vector< Id >& ret )
124  */
125 
137 int simpleWildcardFind( const string& path, vector< ObjId >& ret)
138 {
139  if ( path.length() == 0 )
140  return 0;
141  unsigned int n = ret.size();
142  vector< string > wildcards;
143  Shell::chopString( path, wildcards, ',' );
144  // separateString( path, wildcards, "," );
145  vector< string >::iterator i;
146  for ( i = wildcards.begin(); i != wildcards.end(); ++i )
147  innerFind( *i, ret );
148 
149  return ret.size() - n;
150 }
151 
152 static void myUnique(vector<ObjId>& ret)
153 {
154  sort(ret.begin(), ret.end());
155  unsigned int i, j;
156  j = 0;
157  for (i = 1; i < ret.size(); i++)
158  {
159  if (ret[j] != ret[i])
160  {
161  ret[++j] = ret[i];
162  }
163  }
164  j++;
165  if (j < ret.size())
166  ret.resize(j);
167 }
168 
169 int wildcardFind(const string& path, vector<ObjId>& ret)
170 {
171  ret.resize( 0 );
172  simpleWildcardFind( path, ret );
173  myUnique( ret );
174  return ret.size();
175 }
176 
183 int singleLevelWildcard( ObjId start, const string& path, vector< ObjId >& ret )
184 {
185  if ( path.length() == 0 )
186  return 0;
187  unsigned int nret = ret.size();
188 
189  string beforeBrace;
190  string insideBrace;
191  // This has to handle ghastly cases like foo[][FIELD(x)=12.3]
192  unsigned int index = findBraceContent( path, beforeBrace, insideBrace );
193  if ( beforeBrace == "##" )
194  // recursive.
195  return allChildren( start, index, insideBrace, ret );
196 
197  vector< Id > kids;
198  Neutral::children( start.eref(), kids );
199  vector< Id >::iterator i;
200  for ( i = kids.begin(); i != kids.end(); i++ )
201  {
202  if ( matchName( ObjId( *i, ALLDATA ),
203  index, beforeBrace, insideBrace ) )
204  {
205  if ( index == ALLDATA )
206  {
207  for ( unsigned int j = 0; j < i->element()->numData(); ++j )
208  ret.push_back( ObjId( *i, j ) );
209  }
210  else if ( i->element()->hasFields() && index < i->element()->numField( start.dataIndex ) )
211  {
212  ret.push_back( ObjId( *i, start.dataIndex, index ) );
213  }
214  else if ( !i->element()->hasFields() && index < i->element()->numData() )
215  {
216  ret.push_back( ObjId( *i, index ) );
217  }
218  }
219  }
220 
221  return ret.size() - nret;
222 }
223 
243 unsigned int findBraceContent( const string& path, string& beforeBrace,
244  string& insideBrace )
245 {
246  int index = 0;
247  beforeBrace = "";
248  insideBrace = "";
249 
250  if ( path.length() == 0 )
251  return 0;
252  vector< string > names;
253  Shell::chopString( path, names, '[' );
254  if ( names.size() == 0 )
255  return 0;
256  if ( names.size() >= 1 )
257  beforeBrace = names[0];
258  unsigned int len = beforeBrace.length();
259  if ( len > 0 && beforeBrace[len -1] == '#' )
260  index = ALLDATA;
261  if ( names.size() >= 2 )
262  {
263  const string& n = names[1];
264  if ( n == "]" ) // A [] construct means use all indices.
265  {
266  index = ALLDATA;
267  }
268  else if ( isdigit( n[0] ) )
269  {
270  index = atoi( n.c_str() );
271  }
272  else // some complicated text construct for the brace
273  {
274  insideBrace = n.substr( 0, n.length() - 1 );
275  return index;
276  }
277  if ( names.size() == 3 ) // name[number][another_string]
278  {
279  string n1 = names[2].substr( 0, names[2].length() - 1 );
280  insideBrace = n1;
281  }
282  }
283  return index;
284 }
285 
293 bool matchName( ObjId id, unsigned int index,
294  const string& beforeBrace, const string& insideBrace )
295 {
296  string temp = id.element()->getName();
297  if ( temp.length() <= 0 )
298  {
299  return false;
300  }
301 
302  // if ( index == ALLDATA || index == id.dataIndex ) {
303  if ( matchBeforeBrace( id, beforeBrace ) )
304  {
305  if ( insideBrace.length() == 0 )
306  {
307  return true;
308  }
309  else
310  {
311  return matchInsideBrace( id, insideBrace );
312  }
313  }
314  // }
315  return 0;
316 }
317 
322 bool matchInsideBrace( ObjId id, const string& inside )
323 {
324  /* Map from Genesis class names to Moose class names */
325  // const map< string, string >& classNameMap = sliClassNameConvert();
326  if ( inside == "" )
327  return true; // empty means that there is no condition to apply.
328 
329  if ( inside.substr(0, 4 ) == "TYPE" ||
330  inside.substr(0, 5 ) == "CLASS" ||
331  inside.substr(0, 3 ) == "ISA" )
332  {
333  string::size_type pos = inside.rfind( "=" );
334  if ( pos == string::npos )
335  return false;
336  bool isEquality = ( inside[ pos - 1 ] != '!' );
337  string typeName = inside.substr( pos + 1 );
338  if ( typeName == "membrane" )
339  typeName = "Compartment";
340 
341  if ( inside.substr( 0, 5 ) == "CLASS" && typeName == "channel" )
342  typeName = "HHChannel";
343 
344  bool isEqual;
345  if ( inside.substr( 0, 3 ) == "ISA" )
346  {
347  isEqual = id.element()->cinfo()->isA( typeName );
348  }
349  else
350  {
351  isEqual = ( typeName == id.element()->cinfo()->name() );
352  }
353  /*
354  map< string, string >::const_iterator iter = classNameMap.find( typeName );
355  if ( iter != classNameMap.end() )
356  isEqual = ( iter->second == id()->className() );
357  else
358  isEqual = ( typeName == id()->className() );
359  */
360 
361  return ( isEqual == isEquality );
362  }
363  else if ( inside.substr( 0, 6 ) == "FIELD(" )
364  {
365  if ( id.dataIndex == ALLDATA )
366  {
367  return wildcardFieldComparison( id.id, inside.substr( 6 ) );
368  }
369  else
370  {
371  return wildcardFieldComparison( id, inside.substr( 6 ) );
372  }
373  }
374 
375  return false;
376 }
377 
383 bool alignedSingleWildcardMatch( const string& name, const string& wild )
384 {
385  unsigned int len = wild.length();
386  if ( name.length() < len )
387  return false;
388  for ( unsigned int i = 0; i < len; i++ )
389  {
390  if ( wild[i] != '?' && name[i] != wild[i] )
391  return false;
392  }
393  return true;
394 }
395 
406  const string& name, unsigned int start, const string& wild )
407 {
408  unsigned int len = wild.length();
409  if ( len + start > name.length() )
410  return ~0;
411  unsigned int end = 1 + name.length() - len;
412  for ( unsigned int i = start; i < end; ++i )
413  {
414  if ( alignedSingleWildcardMatch( name.substr(i), wild ) )
415  return i;
416  }
417  return ~0;
418 }
419 
432 bool matchBeforeBrace( ObjId id, const string& wild )
433 {
434  if ( wild == "#" || wild == "##" )
435  return true;
436 
437  string ename = id.element()->getName();
438  if ( wild == ename )
439  return true;
440 
441  // Check if the wildcard string has any # or ? symbols.
442  if ( wild.find_first_of( "#?" ) == string::npos )
443  return false;
444 
445  // Break the 'wild' into the sections that must match, at the #s.
446  // Then go through each of these sections doing a match to ename.
447  // If not found, then return false.
448  vector< string > chops;
449  Shell::chopString( wild, chops, '#' );
450  unsigned int prev = 0;
451  unsigned int start = 0;
452 
453  for ( vector< string >::iterator
454  i = chops.begin(); i != chops.end(); ++i )
455  {
456  start = findWithSingleCharWildcard( ename, prev, *i );
457  if ( start == ~0U )
458  return false;
459  if ( prev == 0 && start > 0 && wild[0] != '#' )
460  return false;
461  prev = start + i->length();
462  }
463  return true;
464 
465  /*
466 
467  string::size_type pre = name.find( "#" );
468  string::size_type post = name.rfind( "#" );
469 
470  // # may only be used once in the wildcard, but substitutes for any
471  // number of characters.
472  if ( pre != string::npos && post == pre ) {
473  if ( ename.length() < ( name.length() - post - 1 ) )
474  return false;
475  unsigned int epos = ename.length() - ( name.length() - post - 1 );
476  return ( name.substr( 0, pre ) == ename.substr( 0, pre ) &&
477  name.substr( post + 1 ) == ename.substr( epos ) );
478  }
479 
480  // ? may be used any number of times in the wildcard, and
481  // must substitute exactly for characters.
482  if ( name.length() != ename.length() )
483  return 0;
484  for ( unsigned int i = 0; i < name.length(); i++ )
485  if ( name[i] != '?' && name[i] != ename[i] )
486  return false;
487  return true;
488  */
489 }
490 
495 int allChildren( ObjId start,
496  unsigned int index, const string& insideBrace, vector< ObjId >& ret )
497 {
498  unsigned int nret = ret.size();
499  vector< Id > kids;
500  Neutral::children( start.eref(), kids );
501  vector< Id >::iterator i;
502  for ( i = kids.begin(); i != kids.end(); i++ )
503  {
504  if ( i->element()->hasFields() )
505  {
506  if ( matchInsideBrace( *i, insideBrace ) )
507  {
508  if ( index == ALLDATA )
509  {
510  ObjId oid( *i, start.dataIndex );
511  ret.push_back( oid );
512  }
513  else if (index < i->element()->numField( start.dataIndex ) )
514  {
515  ObjId oid( *i, start.dataIndex, index );
516  ret.push_back( oid );
517  }
518  }
519  }
520  else
521  {
522  for ( unsigned int j = 0; j < i->element()->numData(); ++j )
523  {
524  ObjId oid( *i, j );
525  allChildren( oid, index, insideBrace, ret );
526  if ( (index == ALLDATA || index == j) && matchInsideBrace( oid, insideBrace ) )
527  ret.push_back( oid );
528  }
529  }
530  }
531  return ret.size() - nret;
532 }
533 
544 int wildcardRelativeFind( ObjId start, const vector< string >& path,
545  unsigned int depth, vector< ObjId >& ret )
546 {
547  int nret = 0;
548  vector< ObjId > currentLevelIds;
549  if ( depth == path.size() )
550  {
551  if ( ret.size() == 0 || ret.back() != start )
552  {
553  ret.push_back( start );
554  }
555  return 1;
556  }
557 
558  if ( singleLevelWildcard( start, path[depth], currentLevelIds ) > 0 )
559  {
560  vector< ObjId >::iterator i;
561  for ( i = currentLevelIds.begin(); i != currentLevelIds.end(); ++i )
562  nret += wildcardRelativeFind( *i, path, depth + 1, ret );
563  }
564  return nret;
565 }
566 
567 void wildcardTestFunc( ObjId* elist, unsigned int ne, const string& path )
568 {
569  vector< ObjId > ret;
570  simpleWildcardFind( path, ret );
571  if ( ne != ret.size() )
572  {
573  cout << "!\nAssert '" << path << "' : expected " <<
574  ne << ", found " << ret.size() << "\n";
575  assert( 0 );
576  }
577  sort( ret.begin(), ret.end() );
578  for ( unsigned int i = 0; i < ne ; i++ )
579  {
580  if ( elist[ i ] != ret[ i ] )
581  {
582  cout << "!\nAssert " << path << ": item " << i <<
583  ": " << elist[i].element()->getName() << " != " <<
584  ret[i].element()->getName() << "\n";
585  assert( 0 );
586  }
587  }
588  cout << ".";
589 }
590 
592 {
593  unsigned long i;
594  string bb;
595  string ib;
596  i = findBraceContent( "foo[23][TYPE=Compartment]", bb, ib );
597  assert( bb == "foo" );
598  assert( i == 23 );
599  assert( ib == "TYPE=Compartment" );
600  i = findBraceContent( "foo[][TYPE=Channel]", bb, ib );
601  assert( i == ALLDATA );
602  assert( bb == "foo" );
603  assert( ib == "TYPE=Channel" );
604  i = findBraceContent( "foo[TYPE=membrane]", bb, ib );
605  assert( i == 0 );
606  assert( bb == "foo" );
607  assert( ib == "TYPE=membrane" );
608  i = findBraceContent( "bar[]", bb, ib );
609  assert( i == ALLDATA );
610  assert( bb == "bar" );
611  assert( ib == "" );
612  i = findBraceContent( "zod[24]", bb, ib );
613  assert( i == 24 );
614  assert( bb == "zod" );
615  assert( ib == "" );
616 
617  i = findBraceContent( "zod#", bb, ib );
618  assert( i == ALLDATA );
619  assert( bb == "zod#" );
620  assert( ib == "" );
621  i = findBraceContent( "zod#[]", bb, ib );
622  assert( i == ALLDATA );
623  assert( bb == "zod#" );
624  assert( ib == "" );
625  i = findBraceContent( "zod#[ISA=hippo]", bb, ib );
626  assert( i == ALLDATA );
627  assert( bb == "zod#" );
628  assert( ib == "ISA=hippo" );
629  i = findBraceContent( "zod#[3]", bb, ib );
630  assert( i == 3 );
631  assert( bb == "zod#" );
632  assert( ib == "" );
633  i = findBraceContent( "zod##", bb, ib );
634  assert( i == ALLDATA );
635  assert( bb == "zod##" );
636  assert( ib == "" );
637 
638  bool ret = alignedSingleWildcardMatch( "a123456", "a123" );
639  assert( ret == true );
640  ret = alignedSingleWildcardMatch( "a123456", "1234" );
641  assert( ret == false );
642  ret = alignedSingleWildcardMatch( "a123456", "?1234" );
643  assert( ret == true );
644  ret = alignedSingleWildcardMatch( "a123456", "a????" );
645  assert( ret == true );
646  ret = alignedSingleWildcardMatch( "a123456", "??2??" );
647  assert( ret == true );
648  ret = alignedSingleWildcardMatch( "a123456", "??3??" );
649  assert( ret == false );
650  ret = alignedSingleWildcardMatch( "a1", "a?" );
651  assert( ret == true );
652 
653  unsigned int j = findWithSingleCharWildcard( "a12345678", 0, "a123" );
654  assert( j == 0 );
655  j = findWithSingleCharWildcard( "a12345678", 0, "123" );
656  assert( j == 1 );
657  j = findWithSingleCharWildcard( "a12345678", 0, "?123" );
658  assert( j == 0 );
659  j = findWithSingleCharWildcard( "a12345678", 0, "?23456?" );
660  assert( j == 1 );
661  j = findWithSingleCharWildcard( "a12345678", 0, "??6?" );
662  assert( j == 4 );
663 
664  Shell* shell = reinterpret_cast< Shell* >( Id().eref().data() );
665  Id a1 = shell->doCreate( "Neutral", Id(), "a1", 1 );
666  Id c1 = shell->doCreate( "Arith", a1, "c1", 1 );
667  Id c2 = shell->doCreate( "Arith", a1, "c2", 1 );
668  Id c3 = shell->doCreate( "Arith", a1, "c3", 1 );
669  Id cIndex = shell->doCreate( "Neutral", a1, "c4", 1 );
670  Id c5 = shell->doCreate( "Neutral", a1, "Seg5_apical_1234_spine_234",1);
671 
672  ret = matchBeforeBrace( a1, "a1" );
673  assert( ret );
674  ret = matchBeforeBrace( a1, "a2" );
675  assert( ret == 0 );
676  ret = matchBeforeBrace( a1, "a?" );
677  assert( ret == 1 );
678  ret = matchBeforeBrace( a1, "?1" );
679  assert( ret == 1 );
680  ret = matchBeforeBrace( a1, "??" );
681  assert( ret == 1 );
682  ret = matchBeforeBrace( a1, "#" );
683  assert( ret == 1 );
684  ret = matchBeforeBrace( a1, "a#" );
685  assert( ret == 1 );
686  ret = matchBeforeBrace( a1, "#1" );
687  assert( ret == 1 );
688 
689  ret = matchBeforeBrace( cIndex, "c4" );
690  assert( ret == 1 );
691  ret = matchBeforeBrace( cIndex, "##" );
692  assert( ret == 1 );
693  ret = matchBeforeBrace( cIndex, "#4" );
694  assert( ret == 1 );
695  ret = matchBeforeBrace( cIndex, "#" );
696  assert( ret == 1 );
697  ret = matchBeforeBrace( cIndex, "?4" );
698  assert( ret == 1 );
699  ret = matchBeforeBrace( cIndex, "c1" );
700  assert( ret == 0 );
701  ret = matchBeforeBrace( cIndex, "c?" );
702  assert( ret == 1 );
703  ret = matchBeforeBrace( cIndex, "??" );
704  assert( ret == 1 );
705 
706  ret = matchBeforeBrace( c5, "Seg?_apical_#_spine_#" );
707  assert( ret == true );
708  ret = matchBeforeBrace( c5, "#Seg?_apical_#_spine_#" );
709  assert( ret == true );
710  ret = matchBeforeBrace( c5, "#?_apical_#_spine_#" );
711  assert( ret == true );
712  ret = matchBeforeBrace( c5, "#5_apical_#_spine_#" );
713  assert( ret == true );
714  ret = matchBeforeBrace( c5, "#e?5_apical_#_spine_#" );
715  assert( ret == true );
716  ret = matchBeforeBrace( c5, "#e5_apical_#_spine_#" );
717  assert( ret == false );
718  ret = matchBeforeBrace( c5, "#Seg5_apical_#_spine_#" );
719  assert( ret == true );
720  ret = matchBeforeBrace( c5, "#Seg#_apical_#_spine_#" );
721  assert( ret == true );
722  ret = matchBeforeBrace( c5, "Seg#_apical_#_spine_#" );
723  assert( ret == true );
724  ret = matchBeforeBrace( c5, "Seg#_a????l_#_spine_#" );
725  assert( ret == true );
726  ret = matchBeforeBrace( c5, "#?_a????l_#_spine_#" );
727  assert( ret == true );
728  ret = matchBeforeBrace( c5, "Seg?_a?????l_#_spine_#" );
729  assert( ret == false );
730  ret = matchBeforeBrace( c5, "Seg#_spine_#" );
731  assert( ret == true );
732 
733 
734  ret = matchInsideBrace( a1, "TYPE=Neutral" );
735  assert( ret );
736  ret = matchInsideBrace( a1, "TYPE==Neutral" );
737  assert( ret );
738  ret = matchInsideBrace( a1, "CLASS=Neutral" );
739  assert( ret );
740  ret = matchInsideBrace( a1, "ISA=Neutral" );
741  assert( ret );
742  ret = matchInsideBrace( a1, "CLASS=Neutral" );
743  assert( ret );
744  ret = matchInsideBrace( a1, "TYPE!=Channel" );
745  assert( ret );
746  ret = matchInsideBrace( a1, "CLASS!=Channel" );
747  assert( ret );
748  ret = matchInsideBrace( a1, "ISA!=Channel" );
749  assert( ret );
750  ret = matchInsideBrace( c3, "ISA==Neutral" ); // Everything is a Neutral
751  assert( ret );
752  ret = matchInsideBrace( c3, "ISA=Arith" );
753  assert( ret );
754  ret = matchInsideBrace( c3, "TYPE=membrane" );
755  assert( !ret );
756 
757  Field<double>::set( ObjId( c3, 0 ), "outputValue", 123.5 );
758  ret = matchInsideBrace( c3, "FIELD(outputValue)=123.5" );
759  assert( ret );
760  ret = matchInsideBrace( c3, "FIELD(outputValue)==123.5" );
761  assert( ret );
762  ret = matchInsideBrace( c3, "FIELD(outputValue)!=123.4" );
763  assert( ret );
764  ret = matchInsideBrace( c3, "FIELD(outputValue)>123.4" );
765  assert( ret );
766  ret = matchInsideBrace( c3, "FIELD(outputValue)<123.6" );
767  assert( ret );
768  ret = matchInsideBrace( c3, "FIELD(outputValue)>=123.4" );
769  assert( ret );
770  ret = matchInsideBrace( c3, "FIELD(outputValue)<=123.6" );
771  assert( ret );
772  ret = matchInsideBrace( c3, "FIELD(outputValue)>=123.5" );
773  assert( ret );
774  ret = matchInsideBrace( c3, "FIELD(outputValue)<=123.5" );
775  assert( ret );
776  ret = matchInsideBrace( c3, "FIELD(outputValue)==123.4" );
777  assert( !ret );
778  ret = matchInsideBrace( c3, "FIELD(outputValue)<123.4" );
779  assert( !ret );
780 
781 
782  ObjId el1[] = { ObjId(), a1, c1 };
783  wildcardTestFunc( el1, 3, "/,/a1,/a1/c1" );
784  ObjId el3[] = { c1, c2, c3, cIndex };
785  wildcardTestFunc( el3, 4, "/a1/c#" );
786  wildcardTestFunc( el3, 3, "/a1/c#[TYPE=Arith]" );
787 
788  ObjId el2[ 100 ];
789  for ( i = 0 ; i < 100; i++ )
790  {
791  char name[10];
792  sprintf( name, "ch%ld", i );
793  el2[i] = shell->doCreate( "Annotator", c1, name, 1 );
794  //el2[i] = Neutral::create( "HHChannel", name, c1->id(), Id::scratchId() );
795  Field< double >::set( ObjId( el2[i], 0 ), "z", i );
796  }
797 
798  wildcardTestFunc( el2, 100, "/a1/c1/##" );
799  wildcardTestFunc( el2, 100, "/a1/c1/#" );
800 
801  wildcardTestFunc( el2, 0, "/a1/##[TYPE=IntFire]" );
802  wildcardTestFunc( el2, 100, "/a1/##[TYPE=Annotator]" );
803  wildcardTestFunc( el2, 50, "/a1/c1/##[][FIELD(z)<50]" );
804 
805  // Here we set up some thoroughly ugly nesting.
806  // Note the sequence: The wildcarding goes depth first,
807  // and then in order of creation.
808  ObjId el4[12];
809  i = 0;
810  el4[i] = shell->doCreate( "IntFire", el2[0], "g0", 1 );
811  ++i;
812  el4[i] = shell->doCreate( "IntFire", el2[1], "g1", 1 );
813  ++i;
814  el4[i] = shell->doCreate( "IntFire", el2[1], "g2", 1 );
815  ++i;
816  el4[i] = shell->doCreate( "IntFire", el2[2], "g3", 1 );
817  ++i;
818  el4[i] = shell->doCreate( "IntFire", el2[2], "g4", 1 );
819  ++i;
820  el4[i] = shell->doCreate( "IntFire", el2[4], "g5", 1 );
821  ++i;
822  el4[i] = shell->doCreate( "IntFire", el2[5], "g6", 1 );
823  ++i;
824  el4[i] = shell->doCreate( "IntFire", el2[6], "g7", 1 );
825  ++i;
826  el4[i] = shell->doCreate( "IntFire", el2[1], "g8", 1 );
827  ++i;
828  el4[i] = shell->doCreate( "IntFire", el2[1], "g9", 1 );
829  ++i;
830  el4[i] = shell->doCreate( "IntFire", c2, "g10", 1 );
831  ++i;
832  el4[i] = shell->doCreate( "IntFire", c3, "g11", 1 );
833  ++i;
834 
835  wildcardTestFunc( el4, 12, "/a1/##[TYPE=IntFire]" );
836  wildcardTestFunc( el4, 12, "/##[TYPE=IntFire]" );
837 
838  // Here I test wildcards with array Elements.
839  Id x = shell->doCreate( "Arith", a1, "x", 5 );
840  Id y = shell->doCreate( "Arith", ObjId( x, 2 ), "y", 5 );
841  Id z = shell->doCreate( "Arith", ObjId( y, 3 ), "z", 5 );
842  vector< ObjId > vec;
843  simpleWildcardFind( "/a1/x[]/##", vec );
844  assert( vec.size() == 10 );
845  vec.clear();
846  simpleWildcardFind( "/a1/x[]/##,/a1/x[]", vec );
847  assert( vec.size() == 15 );
848  vec.clear();
849  simpleWildcardFind( "/a1/x[2]/y[]", vec );
850  assert( vec.size() == 5 );
851 
852  // Here I test exclusive wildcards, should NOT get additional terms.
853  Id xyzzy = shell->doCreate( "Arith", a1, "xyzzy", 5 );
854  Id xdotp = shell->doCreate( "Arith", a1, "x.P", 5 );
855  vec.clear();
856  simpleWildcardFind( "/a1/x", vec );
857  assert( vec.size() == 1 );
858  vec.clear();
859  simpleWildcardFind( "/a1/x[0]", vec );
860  assert( vec.size() == 1 );
861  vec.clear();
862  simpleWildcardFind( "/a1/x[2]", vec );
863  assert( vec.size() == 1 );
864  vec.clear();
865  simpleWildcardFind( "/a1/x[]", vec );
866  assert( vec.size() == 5 );
867 
868  //a1.destroy();
869  shell->doDelete( a1 );
870  cout << "." << flush;
871 }
872 
static int wildcardRelativeFind(ObjId start, const vector< string > &path, unsigned int depth, vector< ObjId > &ret)
Definition: Wildcard.cpp:544
int wildcardFind(const string &path, vector< ObjId > &ret)
Definition: Wildcard.cpp:169
static int innerFind(const string &path, vector< ObjId > &ret)
Definition: Wildcard.cpp:89
char * data() const
Definition: Eref.cpp:41
static bool chopString(const string &path, vector< string > &ret, char separator= '/')
Definition: Shell.cpp:459
char * data() const
Definition: ObjId.cpp:113
static double op(double x)
int simpleWildcardFind(const string &path, vector< ObjId > &ret)
Definition: Wildcard.cpp:137
Definition: ObjId.h:20
int singleLevelWildcard(ObjId start, const string &path, vector< ObjId > &ret)
Definition: Wildcard.cpp:183
Eref eref() const
Definition: Id.cpp:125
static void children(const Eref &e, vector< Id > &ret)
Definition: Neutral.cpp:342
static bool set(const ObjId &dest, const string &field, A arg)
Definition: SetGet.h:245
Id doCreate(string type, ObjId parent, string name, unsigned int numData, NodePolicy nodePolicy=MooseBlockBalance, unsigned int preferredNode=1)
Definition: Shell.cpp:181
ObjId getCwe() const
Definition: Shell.cpp:615
bool alignedSingleWildcardMatch(const string &name, const string &wild)
Definition: Wildcard.cpp:383
const unsigned int ALLDATA
Used by ObjId and Eref.
Definition: consts.cpp:22
void wildcardTestFunc(ObjId *elist, unsigned int ne, const string &path)
Definition: Wildcard.cpp:567
static char dataIndex[]
Definition: mfield.cpp:406
static bool matchName(ObjId id, unsigned int index, const string &beforeBrace, const string &insideBrace)
Definition: Wildcard.cpp:293
static bool strGet(const ObjId &tgt, const string &field, string &ret)
Definition: SetGet.cpp:72
bool matchBeforeBrace(ObjId id, const string &wild)
Definition: Wildcard.cpp:432
int allChildren(ObjId start, unsigned int index, const string &insideBrace, vector< ObjId > &ret)
Definition: Wildcard.cpp:495
static bool wildcardFieldComparison(ObjId oid, const string &mid)
Definition: Wildcard.cpp:35
static void myUnique(vector< ObjId > &ret)
Definition: Wildcard.cpp:152
static bool matchInsideBrace(ObjId id, const string &inside)
Definition: Wildcard.cpp:322
Element * element() const
Definition: ObjId.cpp:124
unsigned int findWithSingleCharWildcard(const string &name, unsigned int start, const string &wild)
Definition: Wildcard.cpp:405
static char name[]
Definition: mfield.cpp:401
Eref eref() const
Definition: ObjId.cpp:66
bool doDelete(ObjId oid)
Definition: Shell.cpp:259
Definition: Id.h:17
void testWildcard()
Definition: Wildcard.cpp:591
static unsigned int findBraceContent(const string &path, string &beforeBrace, string &insideBrace)
Definition: Wildcard.cpp:243
const string & getName() const
Definition: Element.cpp:56
static char path[]
Definition: mfield.cpp:403
Definition: Shell.h:43
unsigned int dataIndex
Definition: ObjId.h:99