Advanced Strategic Command
textfile_evaluation.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  textfile_evaluation.cpp - description
3  -------------------
4  begin : Thu Oct 06 2002
5  copyright : (C) 2002 by Martin Bickel
6  email : bickel@asc-hq.org
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 
18 #include <vector>
19 #include <algorithm>
20 #include <iostream>
21 #include "global.h"
22 #include "ascstring.h"
23 #include "textfileparser.h"
24 #include "textfile_evaluation.h"
25 #include "stringtokenizer.h"
26 #ifdef ParserLoadImages
27  #include <SDL_image.h>
28  // #include "basegfx.h"
29  #include "typen.h"
30  #include "graphics/blitter.h"
31  #include "fieldimageloader.h"
32  #include "graphics/surface2png.h"
33 #endif
34 
35 #ifdef WIN32
36 #include "Windows.h"
37 #endif
38 
39 #include <boost/regex.hpp>
40 
41 
42  template <class T>
44  void operation_not_defined( const TextPropertyGroup::Entry& entry ) const;
45  protected:
46 
49 
50  virtual T parse ( const TextPropertyGroup::Entry& entry ) const;
51  virtual T operation_mult ( const TextPropertyGroup::Entry& entry ) const;
52  virtual T operation_add ( const TextPropertyGroup::Entry& entry ) const;
53  virtual T operation_sub ( const TextPropertyGroup::Entry& entry ) const;
54  virtual T operation_eq ( const TextPropertyGroup::Entry& entry ) const;
55 
56 
57  public:
58  void evaluate ( );
59 
60  PropertyTemplate ( T& property_ ) : PropertyContainer::Property ( false ), property ( property_ ) {};
61  PropertyTemplate ( T& property_, const T& defaultValue_ ) : PropertyContainer::Property ( true ), property ( property_ ), defaultValue ( defaultValue_) {};
62  };
63 
64 
66  class IntegerProperty : public PTI {
67  protected:
68  ASCString toString ( ) const ;
69  int operation_eq ( const TextPropertyGroup::Entry& entry ) const;
70  int operation_add ( const TextPropertyGroup::Entry& entry ) const;
71  int operation_sub ( const TextPropertyGroup::Entry& entry ) const;
72  int operation_mult ( const TextPropertyGroup::Entry& entry ) const;
73  public:
74  IntegerProperty ( int& property_ ) : PTI ( property_ ) {};
75  IntegerProperty ( int& property_, int defaultValue_ ) : PTI ( property_, defaultValue_ ) {};
76  };
77 
79  class FloatProperty : public PTD {
80  protected:
81  ASCString toString ( ) const ;
82  double operation_eq ( const TextPropertyGroup::Entry& entry ) const;
83  double operation_add ( const TextPropertyGroup::Entry& entry ) const;
84  double operation_mult ( const TextPropertyGroup::Entry& entry ) const;
85  public:
86  FloatProperty ( double& property_ ) : PTD ( property_ ) {};
87  FloatProperty ( double& property_, double defaultValue_ ) : PTD ( property_, defaultValue_ ) {};
88  };
89 
90 
92  class BoolProperty : public PTB {
93  protected:
94  ASCString toString ( ) const;
95  bool operation_eq ( const TextPropertyGroup::Entry& entry ) const;
96  public:
97  BoolProperty ( bool& property_ ) : PTB ( property_ ) {};
98  BoolProperty ( bool& property_, bool defaultValue_ ) : PTB ( property_, defaultValue_ ) {};
99  };
100 
102  class StringProperty : public PTS {
103  protected:
104  ASCString toString ( ) const;
106  ASCString operation_add ( const TextPropertyGroup::Entry& entry ) const;
107  public:
108  StringProperty ( ASCString& property_ ) : PTS ( property_ ) {};
109  StringProperty ( ASCString& property_, const ASCString& defaultValue ) : PTS ( property_, defaultValue ) {};
110  };
111 
113  class StringArrayProperty : public PTSA {
114  typedef vector<ASCString> PropertyType;
115  protected:
116  ASCString toString ( ) const;
117  PropertyType operation_eq ( const TextPropertyGroup::Entry& entry ) const ;
118  public:
119  StringArrayProperty ( vector<ASCString>& property_ ) : PTSA ( property_ ) {};
120  };
121 
122 
123  template <class T>
124  class ValArrayProperty: public PropertyTemplate< vector<T> > {
125  protected:
126  typedef vector<T> PropertyType;
130  ValArrayProperty ( PropertyType& property_ ) : PropertyTemplate<vector<T> > ( property_ ) {};
131 
132  };
133 
135  class IntegerArrayProperty : public PTIA {
136  protected:
138  ASCString toString ( ) const;
139  bool required;
140  bool hasDefault() {return !required; };
141  public:
142  IntegerArrayProperty ( vector<int>& property_, bool _required ) : PTIA ( property_ ), required(_required) {};
143  };
144 
146  class DoubleArrayProperty : public PTDA {
147  protected:
149  ASCString toString ( ) const;
150  public:
151  DoubleArrayProperty ( vector<double>& property_ ) : PTDA ( property_ ) {};
152  };
153 
154 
156  class IntRangeArrayProperty : public PTIRA {
157  typedef vector<IntRange> PropertyType;
158  bool required;
159  bool hasDefault() {return !required; };
160  protected:
161  PropertyType operation_eq ( const TextPropertyGroup::Entry& entry ) const ;
162  ASCString toString ( ) const;
163  public:
164  IntRangeArrayProperty ( vector<IntRange>& property_, bool _required ) : PTIRA ( property_ ), required(_required) {};
165  };
166 
168  class TagArrayProperty : public PTTA {
169  int tagNum;
170  const char** tags;
171  bool inverted;
172  protected:
174  BitSet operation_add ( const TextPropertyGroup::Entry& entry ) const;
175  BitSet operation_sub ( const TextPropertyGroup::Entry& entry ) const;
176  ASCString toString ( ) const;
177  public:
178  TagArrayProperty ( BitSet& property_, int tagNum_, const char** tags_, bool inverted_ ) : PTTA ( property_ ), tagNum (tagNum_), tags ( tags_ ), inverted ( inverted_ ) {};
179  };
180 
182  class TagIntProperty : public PTTI {
183  int tagNum;
184  const char** tags;
185  bool inverted;
186  protected:
187  int operation_eq ( const TextPropertyGroup::Entry& entry ) const ;
188  int operation_add ( const TextPropertyGroup::Entry& entry ) const ;
189  int operation_sub ( const TextPropertyGroup::Entry& entry ) const ;
190  ASCString toString ( ) const;
191  public:
192  TagIntProperty ( int& property_, int tagNum_, const char** tags_, bool inverted_ ) : PTTI ( property_ ), tagNum (tagNum_), tags ( tags_ ), inverted ( inverted_ ) {};
193  TagIntProperty ( int& property_, int tagNum_, const char** tags_, int defaultValue_, bool inverted_ ) : PTTI ( property_, defaultValue_ ), tagNum (tagNum_), tags ( tags_ ), inverted ( inverted_ ) {};
194  };
195 
197  class NamedIntProperty : public PTNI {
198  int tagNum;
199  const char** tags;
200  protected:
201  int operation_eq ( const TextPropertyGroup::Entry& entry ) const ;
202  ASCString toString ( ) const;
203  public:
204  NamedIntProperty ( int& property_, int tagNum_, const char** tags_ ) : PTNI ( property_ ), tagNum (tagNum_), tags ( tags_ ) {};
205  NamedIntProperty ( int& property_, int tagNum_, const char** tags_, int defaultValue_ ) : PTNI ( property_, defaultValue_ ), tagNum (tagNum_), tags ( tags_ ) {};
206  };
207 
208 /*
209  typedef PropertyTemplate<void*> PTIMG;
210  class ImageProperty : public PTIMG {
211  ASCString fileName;
212  protected:
213  void* operation_eq ( const TextPropertyGroup::Entry& entry ) const ;
214  ASCString toString ( ) const;
215  public:
216  ImageProperty ( void* &property_, const ASCString& fileName_ ) : PTIMG ( property_ ), fileName ( fileName_ ) {};
217  };
218 */
220  class ASCImageProperty : public PTIMG2 {
221  typedef Surface PropertyType;
222  ASCString& fileName;
223  bool fieldMask;
224  protected:
226  ASCString toString ( ) const;
227  public:
228  ASCImageProperty ( Surface &property_, ASCString& fileName_, bool applyFieldMask ) : PTIMG2 ( property_ ), fileName ( fileName_ ), fieldMask( applyFieldMask ) {};
229  };
230 /*
231  typedef PropertyTemplate< vector<void*> > PTIMGA;
232  class ImageArrayProperty : public PTIMGA {
233  typedef vector<void*> PropertyType;
234  ASCString fileName;
235  protected:
236  PropertyType operation_eq ( const TextPropertyGroup::Entry& entry ) const ;
237  ASCString toString ( ) const;
238  public:
239  ImageArrayProperty ( PropertyType &property_, const ASCString& fileName_ ) : PTIMGA ( property_ ), fileName ( fileName_ ) {};
240  };
241 */
242 
245  typedef vector<Surface> PropertyType;
246  ASCString& fileName;
247  protected:
248  PropertyType operation_eq ( const TextPropertyGroup::Entry& entry ) const ;
249  ASCString toString ( ) const;
250  public:
251  ASCImageArrayProperty ( PropertyType &property_, ASCString& fileName_ ) : PTIMGA2 ( property_ ), fileName ( fileName_ ) {};
252  };
253 
254 
255 
256 /*
257 void PropertyContainer :: run ( )
258 {
259  if ( isReading() )
260  for ( Properties::iterator i = properties.begin(); i != properties.end(); i++ )
261  if ( !(*i)->evaluated )
262  (*i)->evaluate();
263 
264  closeBracket();
265  if ( levelDepth )
266  error ( "PropertyReadingContainer :: ~PropertyReadingContainer - still brackets open" );
267 }
268 */
269 
271 {
272  fatalError ( "Attempt to use PropertyReadingContainer :: writeProperty !");
273 }
274 
276 {
277  ASCString output;
278  for ( int i = 0; i < levelDepth; i++ )
279  output += " ";
280 
281  output += p.getLastName();
282  output += " = ";
283 
284  size_t indent = output.length();
285  ASCString::size_type pos = value.find ( "\n" );
286  if ( pos != ASCString::npos ) {
287  output += "[";
288  ASCString::size_type oldpos = 0;
289  do {
290  output += value.substr( oldpos, pos-oldpos+1 );
291  oldpos = pos+1;
292  for ( int i = 0; i < indent; i++ )
293  output += " ";
294  if ( pos+1 < value.length() )
295  pos = value.find ( "\n", pos+1 );
296  else
297  pos = ASCString::npos;
298  } while ( pos != ASCString::npos );
299  output += value.substr( oldpos );
300  output += "]";
301  } else
302  output += value;
303 
304  output += "\n";
305 
306  stream.writeString ( output, false );
307 }
308 
309 
311 {
312  ASCString s;
313  for ( Level::iterator i = level.begin(); i != level.end(); ++i ) {
314  if ( s.length() )
315  s += ".";
316  s += *i;
317  }
318  return s;
319 }
320 
322 {
323  level.push_back ( name );
324  levelDepth++;
325 }
326 
328 {
329  level.pop_back();
330  levelDepth--;
331 }
332 
333 
335 {
336  for ( int i = 0; i < levelDepth; i++ )
337  stream.writeString ( " ", false );
338  stream.writeString ( name + " { \n", false );
339 
341 }
342 
344 {
345  ASCString name = level.back();
346 
348 
349  for ( int i = 0; i < levelDepth; i++ )
350  stream.writeString ( " ", false );
351  stream.writeString ( "} " + name + "\n", false );
352 }
353 
354 
355 void PropertyContainer::setup ( Property* p, const ASCString& name_ )
356 {
357  ASCString name;
358  for ( Level::iterator i = level.begin(); i != level.end(); i++ )
359  name += *i + ".";
360  name += name_;
361  p->setName( name, name_ );
362  p->setPropertyContainer ( this );
363  properties.push_back ( p );
364 
365  p->evaluate();
366 }
367 
368 
369 void PropertyContainer::addInteger ( const ASCString& name, int& property )
370 {
371  IntegerProperty* ip = new IntegerProperty ( property );
372  setup ( ip, name );
373 }
374 
375 void PropertyContainer::addInteger ( const ASCString& name, int& property, int defaultValue )
376 {
377  IntegerProperty* ip = new IntegerProperty ( property, defaultValue );
378  setup ( ip, name );
379 }
380 
381 void PropertyContainer::addDFloat ( const ASCString& name, double& property )
382 {
383  FloatProperty* ip = new FloatProperty ( property );
384  setup ( ip, name );
385 }
386 
387 void PropertyContainer::addDFloat ( const ASCString& name, double& property, double defaultValue )
388 {
389  FloatProperty* ip = new FloatProperty ( property, defaultValue );
390  setup ( ip, name );
391 }
392 
393 
394 
395 void PropertyContainer::addBool ( const ASCString& name, bool& property )
396 {
397  BoolProperty* ip = new BoolProperty ( property );
398  setup ( ip, name );
399 }
400 
401 void PropertyContainer::addBool ( const ASCString& name, bool& property, bool defaultValue )
402 {
403  BoolProperty* ip = new BoolProperty ( property, defaultValue );
404  setup ( ip, name );
405 }
406 
407 void PropertyContainer::addString ( const ASCString& name, ASCString& property )
408 {
409  StringProperty* ip = new StringProperty ( property );
410  setup ( ip, name );
411 }
412 
413 void PropertyContainer::addString ( const ASCString& name, ASCString& property, const ASCString& defaultValue )
414 {
415  StringProperty* ip = new StringProperty ( property, defaultValue );
416  setup ( ip, name );
417 }
418 
419 
420 void PropertyContainer::addStringArray ( const ASCString& name, vector<ASCString>& property )
421 {
422  StringArrayProperty* ip = new StringArrayProperty ( property );
423  setup ( ip, name );
424 }
425 
426 
427 void PropertyContainer::addIntegerArray ( const ASCString& name, vector<int>& property, bool required )
428 {
429  IntegerArrayProperty* ip = new IntegerArrayProperty ( property, required );
430  setup ( ip, name );
431 }
432 
433 void PropertyContainer::addDFloatArray ( const ASCString& name, vector<double>& property )
434 {
435  DoubleArrayProperty* dp = new DoubleArrayProperty ( property );
436  setup ( dp, name );
437 }
438 
439 void PropertyContainer::addDFloatArray ( const ASCString& name, vector<int>& property )
440 {
441  vector<double> dproperty;
442  for ( vector<int>::iterator i = property.begin(); i != property.end(); i++ )
443  dproperty.push_back (*i);
444  DoubleArrayProperty* dp = new DoubleArrayProperty ( dproperty );
445  setup ( dp, name );
446 
447  property.clear();
448  for ( vector<double>::iterator i = dproperty.begin(); i != dproperty.end(); i++ )
449  property.push_back ( int(*i) );
450 }
451 
452 
453 void PropertyContainer::addIntRangeArray ( const ASCString& name, vector<IntRange>& property, bool required )
454 {
455  IntRangeArrayProperty* ip = new IntRangeArrayProperty ( property, required );
456  setup ( ip, name );
457 }
458 
459 
460 void PropertyContainer::addTagArray ( const ASCString& name, BitSet& property, int tagNum, const char** tags, bool inverted )
461 {
462  TagArrayProperty* ip = new TagArrayProperty ( property, tagNum, tags, inverted );
463  setup ( ip, name );
464 }
465 
466 void PropertyContainer::addTagInteger ( const ASCString& name, int& property, int tagNum, const char** tags, bool inverted )
467 {
468  TagIntProperty* ip = new TagIntProperty ( property, tagNum, tags, inverted );
469  setup ( ip, name );
470 }
471 
472 void PropertyContainer::addTagInteger ( const ASCString& name, int& property, int tagNum, const char** tags, int defaultValue, bool inverted )
473 {
474  TagIntProperty* ip = new TagIntProperty ( property, tagNum, tags, defaultValue, inverted );
475  setup ( ip, name );
476 }
477 
478 void PropertyContainer::addNamedInteger ( const ASCString& name, int& property, int tagNum, const char** tags )
479 {
480  NamedIntProperty* ip = new NamedIntProperty ( property, tagNum, tags );
481  setup ( ip, name );
482 }
483 
484 void PropertyContainer::addNamedInteger ( const ASCString& name, int& property, int tagNum, const char** tags, int defaultValue )
485 {
486  NamedIntProperty* ip = new NamedIntProperty ( property, tagNum, tags, defaultValue );
487  setup ( ip, name );
488 }
489 
491 {
492  bool breakpoint = false;
493  if ( isReading() ) {
494  addBool( "breakpoint", breakpoint, false);
495  if ( breakpoint ) {
496  #ifdef WIN32
497  DebugBreak();
498  #else
499  cerr << "breakpoint hit";
500  #endif
501  }
502  }
503 }
504 
505 
507 {
508  storedContext[label] = make_pair( levelDepth, level );
509 }
510 
512 {
513  StoredContext::iterator pos = storedContext.find( label );
514  if ( pos != storedContext.end() ) {
515  levelDepth = pos->second.first;
516  level = pos->second.second;
517  return true;
518  }
519  return false;
520 }
521 
522 
523 #ifdef ParserLoadImages
524 
525 void PropertyContainer::addImageArray ( const ASCString& name, vector<Surface> &property, ASCString& filename )
526 {
527  ASCImageArrayProperty* ip = new ASCImageArrayProperty ( property, filename );
528  setup ( ip, name );
529 }
530 
531 
532 void PropertyContainer::addImage ( const ASCString& name, Surface &property, ASCString& filename, bool applyFieldMask )
533 {
534  ASCImageProperty* ip = new ASCImageProperty ( property, filename, applyFieldMask );
535  setup ( ip, name );
536 }
537 
538 
539 #endif
540 
541 void PropertyContainer::warning ( const ASCString& errmsg )
542 {
543  #ifdef converter
544  fatalError ( errmsg );
545  #else
546  ::warningMessage( "file " + textPropertyGroup->fileName+ ": " + errmsg );
547  #endif
548 }
549 
550 void PropertyContainer::error ( const ASCString& errmsg )
551 {
552  displayLogMessage ( 0, getLocation() + " : " + errmsg + "\n" );
553  throw ParsingError ( getLocation() + " : " + errmsg );
554 }
555 
556 bool PropertyContainer::find ( const ASCString& name )
557 {
558  ASCString n;
559  for ( Level::iterator i = level.begin(); i != level.end(); i++ )
560  n += *i + ".";
561  n += name;
562  n.toLower();
563 
564  return textPropertyGroup->find ( n ) != NULL;
565 }
566 
567 
568 
570 {
571  openBracket ( baseName );
572 }
573 
574 
576 {
577 }
578 
579 PropertyWritingContainer :: PropertyWritingContainer ( const ASCString& baseName, tnstream& stream ) : PropertyContainer ( baseName, NULL, false ), stream ( stream )
580 {
584  openBracket ( baseName );
585 }
586 
588 {
589  closeBracket();
590  if ( levelDepth )
591  error ( "PropertyWritingContainer :: ~PropertyWritingContainer - still brackets open" );
592  delete textPropertyGroup;
593 }
594 
595 
597 
598 
599 void PropertyContainer::Property::setName ( const ASCString& name_, const ASCString& lastName_ )
600 {
601  name = name_ ;
602  name.toLower();
603  lastName = lastName_;
604 }
605 
607 {
608  if ( !propertyContainer )
609  fatalError ( "PropertyContainer::Property::evaluate - no propertyContainer ");
610 
611  name.toLower();
612 
613  if (!entry )
614  entry = propertyContainer->textPropertyGroup->find ( name );
615 
616  if ( !entry && !hasDefault() )
617  propertyContainer->error ( "entry " + name +" not found" );
618 }
619 
621 {
622  propertyContainer->writeProperty ( *this, toString() );
623 }
624 
625 
626 template <class T>
628 {
629  if ( entry.op == TextPropertyGroup::Entry::eq )
630  return operation_eq( entry );
631 
633  operation_not_defined( entry );
634 
635  if ( !entry.parent )
636  propertyContainer->error ( ASCString("PropertyContainer::PropertyTemplate::parse - no parent for operator ") + TextFormatParser::operations[entry.op] + " at entry " + entry.propertyName + " !");
637 
638  switch ( entry.op ) {
639  case TextPropertyGroup::Entry::mult_eq : return operation_mult ( entry );
640  case TextPropertyGroup::Entry::add_eq : return operation_add ( entry );
641  case TextPropertyGroup::Entry::sub_eq : return operation_sub ( entry );
642  default:;
643  }
644 
645  propertyContainer->error ( "PropertyTemplate::parse - invalid operator !");
646  return defaultValue;
647 }
648 
649 template <class T>
651 {
652  propertyContainer->error ( ASCString("operator ") + TextFormatParser::operations[entry.op] + " not defined for this type !\nEntry " + entry.propertyName);
653 }
654 
655 
656 template <class T>
658 {
659  operation_not_defined( entry );
660  return T();
661 }
662 
663 template <class T>
665 {
666  operation_not_defined( entry );
667  return T();
668 }
669 
670 template <class T>
672 {
673  operation_not_defined( entry );
674  return T();
675 }
676 
677 template <class T>
679 {
680  operation_not_defined( entry );
681  return T();
682 }
683 
684 
685 template <class T>
687 {
688  if ( evaluated )
689  return;
690 
691  if ( propertyContainer->isReading() ) {
692  findEntry();
693 
694  if ( entry ) {
695  property = parse ( *entry );
696  } else
697  property = defaultValue;
698 
699  evaluated = true;
700  } else {
701  writeProperty();
702  evaluated = true;
703  }
704 }
705 
707 {
708  char* p = NULL;
709 
710  ASCString value = entry.value;
711  ASCString::size_type i;
712  while ( (i = value.find_first_of( " \t\n\r" )) != ASCString::npos )
713  value.erase( i, 1 );
714 
715  while ( value.find( "0") == 0 && value.find( "0x") != 0) // removing leading zeroes
716  value.erase(0,1);
717 
718 
719  int res = strtol ( value.c_str(), &p, 0 ); // strtol(nptr, NULL, 10);
720  if ( *p != 0 && *p != ';' ) {
721  ASCString s = name + ": value "+ entry.value +" is no numerical value \n" ;
722  // propertyContainer->error ( s );
723  fprintf(stderr, "%s", s.c_str() );
724  }
725 
726  return res;
727 }
728 
729 
731 {
732  return parse ( *entry.parent ) + operation_eq ( entry );
733 }
734 
736 {
737  return parse ( *entry.parent ) - operation_eq ( entry );
738 }
739 
740 
742 {
743  return int ( double ( parse ( *entry.parent )) * atof ( entry.value.c_str() ));
744 }
745 
746 
748 {
749  return strrr ( property );
750 }
751 
752 
753 
755 {
756  return atof ( entry.value.c_str() ); // strtol(nptr, NULL, 10);
757 }
758 
759 
761 {
762  return parse ( *entry.parent ) + operation_eq ( entry );
763 }
764 
766 {
767  return double ( parse ( *entry.parent )) * atof ( entry.value.c_str() );
768 }
769 
770 
772 {
773  ASCString s;
774  s.format("%f", property );
775  return s;
776 }
777 
778 
780 {
781  StringTokenizer st ( entry.value );
782  ASCString s = st.getNextToken();
783  if ( s.compare_ci ( "true" )==0 || s.compare_ci ( "1" )==0 )
784  return true;
785  else
786  if ( s.compare_ci ( "false" )==0 || s.compare_ci ( "0" )==0 )
787  return false;
788  else {
789  propertyContainer->error ( name + ": token "+ s +" unknown" );
790  return false;
791  }
792 }
793 
794 
796 {
797  if ( property )
798  return "true";
799  else
800  return "false";
801 }
802 
803 
804 
806 {
807 /* ASCString s = entry.value;
808  while ( s.find ( "%s" ) != ASCString::npos )
809  s.replace ( s.find ( "%s" ), 2, parse ( *entry.parent ));
810  return s;
811  */
812  return parse( *entry.parent ) + entry.value;
813 }
814 
816 {
817  ASCString s = entry.value;
818  ASCString::size_type pos = s.find_first_not_of ( TextFormatParser::whiteSpace );
819  if ( pos == ASCString::npos )
820  s.erase();
821  else
822  s.erase ( 0, pos );
823 
824  pos = s.find_last_not_of ( TextFormatParser::whiteSpace );
825  if ( pos != ASCString::npos )
826  s.erase ( pos+1 );
827 
828  return s;
829 }
830 
831 
833 {
834  ASCString valueToWrite = property ;
835 
836  ASCString::size_type pos = 0;
837  static const int linewidth = 60;
838  do {
839  if ( pos + linewidth < valueToWrite.length() ) {
840  pos = valueToWrite.find_first_of ( TextFormatParser::whiteSpace, pos + linewidth );
841  if ( pos != ASCString::npos )
842  valueToWrite[pos] = '\n';
843  } else
844  pos = ASCString::npos;
845  } while ( pos != ASCString::npos );
846 
847  return valueToWrite;
848 }
849 
850 
851 StringArrayProperty::PropertyType StringArrayProperty::operation_eq ( const TextPropertyGroup::Entry& entry ) const
852 {
853  PropertyType sa;
854  StringTokenizer st ( entry.value, true );
855  ASCString s = st.getNextToken();
856  while ( !s.empty() ) {
857  sa.push_back ( s );
858  s = st.getNextToken();
859  }
860  return sa;
861 }
862 
864 {
865  ASCString valueToWrite;
866  for ( PropertyType::iterator i = property.begin(); i != property.end(); i++ ) {
867  valueToWrite += *i;
868  valueToWrite += " ";
869  }
870  return valueToWrite;
871 }
872 
873 
874 template<class T>
876 {
877  PropertyType child = this->operation_eq( entry );
878  PropertyType parent = this->parse ( *entry.parent );
879 
880  if ( child.size() == parent.size() ) {
881  PropertyType res;
882  for ( int i = 0; i < child.size(); i++ )
883  res.push_back ( parent[i] + child[i] );
884  return res;
885  }
886  if ( child.size() == 1 ) {
887  PropertyType res;
888  for ( int i = 0; i < parent.size(); i++ )
889  res.push_back ( parent[i] + child[0] );
890  return res;
891  }
892  if ( parent.size() == 1 ) {
893  PropertyType res;
894  for ( int i = 0; i < child.size(); i++ )
895  res.push_back ( parent[0] + child[i] );
896  return res;
897  }
898 
899  this->propertyContainer->error ( this->name + ": array dimensions do not agree" );
900  return child;
901 }
902 
903 template<class T>
905 {
906  PropertyType child = this->operation_eq( entry );
907  PropertyType parent = this->parse ( *entry.parent );
908 
909  if ( child.size() == parent.size() ) {
910  PropertyType res;
911  for ( int i = 0; i < child.size(); i++ )
912  res.push_back ( parent[i] - child[i] );
913  return res;
914  }
915  if ( child.size() == 1 ) {
916  PropertyType res;
917  for ( int i = 0; i < parent.size(); i++ )
918  res.push_back ( parent[i] - child[0] );
919  return res;
920  }
921  if ( parent.size() == 1 ) {
922  PropertyType res;
923  for ( int i = 0; i < child.size(); i++ )
924  res.push_back ( parent[0] - child[i] );
925  return res;
926  }
927 
928  this->propertyContainer->error ( this->name + ": array dimensions do not agree" );
929  return child;
930 }
931 
932 
933 template<class T>
935 {
936  PropertyType child = this->operation_eq( entry );
937  PropertyType parent = this->parse ( *entry.parent );
938 
939  if ( child.size() == parent.size() ) {
940  PropertyType res;
941  for ( int i = 0; i < child.size(); i++ )
942  res.push_back ( int( double(parent[i]) * child[i]) );
943  return res;
944  }
945  if ( child.size() == 1 ) {
946  PropertyType res;
947  for ( int i = 0; i < parent.size(); i++ )
948  res.push_back ( int( double(parent[i]) * child[0]) );
949  return res;
950  }
951  if ( parent.size() == 1 ) {
952  PropertyType res;
953  for ( int i = 0; i < child.size(); i++ )
954  res.push_back ( int( double(parent[0]) * child[i]) );
955  return res;
956  }
957 
958  this->propertyContainer->error ( this->name + ": array dimensions do not agree" );
959  return parent;
960 }
961 
962 
964 {
965  PropertyType ia;
966  StringTokenizer st ( entry.value, true );
967  ASCString s = st.getNextToken();
968  while ( !s.empty() ) {
969 
970  /*
971  if ( s.find( ";") == 0 )
972  st.skipTill('\n');
973  else
974  */
975  ia.push_back ( atoi ( s.c_str() ));
976 
977  s = st.getNextToken();
978  }
979  return ia;
980 }
981 
982 
983 
985 {
986  ASCString valueToWrite;
987  for ( PropertyType::iterator i = property.begin(); i != property.end(); i++ ) {
988  ASCString s;
989  s.format ( "%f", *i );
990  valueToWrite += s;
991  valueToWrite += " ";
992  }
993  return valueToWrite;
994 }
995 
996 
998 {
999  PropertyType ia;
1000  StringTokenizer st ( entry.value, true );
1001  ASCString s = st.getNextToken();
1002  while ( !s.empty() ) {
1003  ia.push_back ( atof ( s.c_str() ));
1004  s = st.getNextToken();
1005  }
1006  return ia;
1007 }
1008 
1009 
1010 
1012 {
1013  ASCString valueToWrite;
1014  for ( PropertyType::iterator i = property.begin(); i != property.end(); i++ ) {
1015  valueToWrite += strrr ( *i );
1016  valueToWrite += " ";
1017  }
1018  return valueToWrite;
1019 }
1020 
1021 
1022 
1023 
1024 IntRangeArrayProperty::PropertyType IntRangeArrayProperty::operation_eq ( const TextPropertyGroup::Entry& entry ) const
1025 {
1026  return String2IntRangeVector( entry.value );
1027 }
1028 
1030 {
1031  ASCString valueToWrite;
1032  for ( PropertyType::iterator i = property.begin(); i != property.end(); i++ ) {
1033  if ( i->from != i->to ) {
1034  valueToWrite += strrr ( i->from );
1035  valueToWrite += "-";
1036  valueToWrite += strrr ( i->to );
1037  } else
1038  valueToWrite += strrr ( i->from );
1039  valueToWrite += " ";
1040  }
1041  return valueToWrite;
1042 }
1043 
1044 
1046 {
1047  return parse ( *entry.parent ) | operation_eq ( entry );
1048 }
1049 
1051 {
1052  return parse ( *entry.parent ) & ~operation_eq ( entry );
1053 }
1054 
1055 
1057 {
1058  BitSet bs;
1059 
1060  if ( inverted )
1061  bs.set();
1062  else
1063  bs.reset();
1064  StringTokenizer st ( entry.value );
1065  ASCString s = st.getNextToken();
1066  while ( !s.empty() ) {
1067  bool found = false;
1068  for ( int i = 0; i < tagNum; i++ )
1069  if ( s.compare_ci ( tags[i] )==0 ) {
1070  if ( inverted )
1071  bs.reset ( i );
1072  else
1073  bs.set ( i );
1074  found = true;
1075  break;
1076  }
1077 
1078  if ( !found )
1079  propertyContainer->error ( name + ": token "+ s +" unknown" );
1080  s = st.getNextToken();
1081  }
1082 
1083  return bs;
1084 }
1085 
1087 {
1088  ASCString valueToWrite;
1089  for ( int i = 0; i < tagNum; i++ )
1090  if ( property.test(i) != inverted ) {
1091  valueToWrite += tags[i];
1092  valueToWrite += " ";
1093  }
1094  return valueToWrite;
1095 }
1096 
1097 
1099 {
1100  return parse ( *entry.parent ) | operation_eq ( entry );
1101 }
1102 
1104 {
1105  return parse ( *entry.parent ) & ~operation_eq ( entry );
1106 }
1107 
1108 
1110 {
1111  int i;
1112 
1113  if ( inverted )
1114  i = -1;
1115  else
1116  i = 0;
1117 
1118  StringTokenizer st ( entry.value );
1119  ASCString s = st.getNextToken();
1120  while ( !s.empty() ) {
1121  bool found = false;
1122  for ( int j = 0; j < tagNum; j++ )
1123  if ( s.compare_ci ( tags[j] )==0 ) {
1124  i ^= 1 << j;
1125  found = true;
1126  break;
1127  }
1128 
1129  if ( !found )
1130  propertyContainer->error ( name + ": token "+ s +" unknown" );
1131  s = st.getNextToken();
1132  }
1133  return i;
1134 }
1135 
1136 
1138 {
1139  ASCString valueToWrite;
1140  for ( int i = 0; i < tagNum; i++ )
1141  if ( !!(property & (1 << i)) != inverted ) {
1142  valueToWrite += tags[i];
1143  valueToWrite += " ";
1144  }
1145  return valueToWrite;
1146 }
1147 
1148 
1150 {
1151  int i = 0;
1152 
1153  StringTokenizer st ( entry.value );
1154  ASCString s = st.getNextToken();
1155  if ( !s.empty() ) {
1156  bool found = false;
1157  for ( int j = 0; j < tagNum; j++ )
1158  if ( s.compare_ci ( tags[j] )==0 ) {
1159  i = j;
1160  found = true;
1161  break;
1162  }
1163 
1164  if ( !found )
1165  propertyContainer->error ( name + ": token "+ s +" unknown" );
1166  }
1167 
1168  return i;
1169 }
1170 
1172 {
1173  return tags[property];
1174 }
1175 
1176 #ifdef ParserLoadImages
1177 
1178 
1180 {
1181  try {
1182  fileName = entry.value;
1183  return loadASCFieldImage( entry.value, fieldMask );
1184  }
1185  catch ( ASCexception ){
1186  }
1187  propertyContainer->error( "error accessing file " + entry.value );
1188  return Surface();
1189 }
1190 
1192 {
1193  ASCString valueToWrite = constructFileName( 0, "", extractFileName_withoutSuffix(fileName) + ".png");
1194  writePNG( valueToWrite, property );
1195  return valueToWrite;
1196 }
1197 
1198 
1199 ASCImageArrayProperty::PropertyType ASCImageArrayProperty::operation_eq ( const TextPropertyGroup::Entry& entry ) const
1200 {
1201  try {
1202  boost::smatch what;
1203  static boost::regex splitter( "\\s*(\\S+)\\s+(\\d+)\\s*");
1204  if( boost::regex_match( entry.value, what, splitter)) {
1205  ASCString imgName;
1206  imgName.assign( what[1].first, what[1].second );
1207 
1208  ASCString imgNumS;
1209  imgNumS.assign( what[2].first, what[2].second );
1210  int imgNum = atoi ( imgNumS.c_str() );
1211 
1212  fileName = entry.value;
1213 
1214  return loadASCFieldImageArray ( imgName, imgNum );
1215  } else
1216  propertyContainer->error( name + ": invalid format. Syntax is <ImageName> <ImageNum>" );
1217  }
1218  catch ( ASCexception ){
1219  propertyContainer->error( "error accessing file " + entry.value );
1220  }
1221  return PropertyType();
1222 }
1223 
1224 
1226 {
1227  int num = property.size();
1228 
1229  Surface s = Surface::createSurface( 1100, 100 * (num / 10 + 1), property.front().GetPixelFormat().BitsPerPixel(), 0 );
1230 
1231  int cnt = 0;
1232  for ( PropertyType::iterator i = property.begin(); i != property.end(); i++ ) {
1233  if ( i->valid() )
1234  megaBlitter<ColorTransform_None, ColorMerger_AlphaOverwrite, SourcePixelSelector_Plain, TargetPixelSelector_All> ( *i, s, SPoint( (cnt % 10) * 100, (cnt / 10) * 100), nullParam, nullParam, nullParam, nullParam);
1235  cnt++;
1236  }
1237 
1238  ASCString valueToWrite = constructFileName( 0, "", extractFileName_withoutSuffix(fileName) + ".png");
1239  writePNG ( valueToWrite , s );
1240  return valueToWrite + " " + ASCString::toString(cnt);
1241 }
1242 
1243 
1244 #endif
1245 
1246 
PropertyType operation_eq(const TextPropertyGroup::Entry &entry) const
IntegerProperty(int &property_)
int operation_sub(const TextPropertyGroup::Entry &entry) const
ASCString toString() const
PropertyTemplate< ASCString > PTS
int operation_add(const TextPropertyGroup::Entry &entry) const
vector< Surface > loadASCFieldImageArray(const ASCString &file, int num)
StringArrayProperty(vector< ASCString > &property_)
void addBool(const ASCString &name, bool &property)
PropertyTemplate< vector< Surface > > PTIMGA2
BoolProperty(bool &property_, bool defaultValue_)
ASCString & toLower()
Definition: ascstring.cpp:36
PropertyTemplate< double > PTD
ValArrayProperty< int > PTIA
PropertyTemplate< BitSet > PTTA
ASCString toString() const
void writeProperty(Property &p, const ASCString &value)
virtual ASCString getLocation()=0
double atof(const std::string &s)
Definition: misc.cpp:157
ASCString toString() const
virtual T operation_add(const TextPropertyGroup::Entry &entry) const
ValArrayProperty(PropertyType &property_)
IntegerProperty(int &property_, int defaultValue_)
virtual ASCString getLocation()
returns the location of the stream.
Definition: basestrm.cpp:274
bool operation_eq(const TextPropertyGroup::Entry &entry) const
PropertyType operation_eq(const TextPropertyGroup::Entry &entry) const
BitSet operation_eq(const TextPropertyGroup::Entry &entry) const
NullParamType nullParam
Definition: blitter.cpp:30
virtual ASCString getDeviceName()
returns the name of the stream.
Definition: basestrm.cpp:269
ASCString toString() const
void addImage(const ASCString &name, Surface &property, ASCString &fileName, bool applyFieldMask)
enum TextPropertyGroup::Entry::Operator op
IntegerArrayProperty(vector< int > &property_, bool _required)
void addIntegerArray(const ASCString &name, vector< int > &property, bool required=true)
vector< IntRange > String2IntRangeVector(const ASCString &t)
parses a string repesenting a number of int ranges Example input: "10-20; 25 ; 30-125" ...
Definition: typen.cpp:326
Surface loadASCFieldImage(const ASCString &file, bool applyFieldMaskToImage)
PropertyReadingContainer(const ASCString &baseName, TextPropertyGroup *tpg)
Functions to evaluate the parsed *.asctxt files.
int operation_mult(const TextPropertyGroup::Entry &entry) const
double operation_add(const TextPropertyGroup::Entry &entry) const
void addTagInteger(const ASCString &name, int &property, int tagNum, const char **tags, bool inverted=false)
static const char * whiteSpace
void warningMessage(const ASCString &str)
static Surface createSurface(int width, int height, SDLmm::Color color=255)
Definition: surface.cpp:387
Global platform dependant definitions. This file just branches to the platform specific files in thei...
The interface for all kinds of IO stream.
ASCString & format(const charT *pFormat,...)
Definition: ascstring.cpp:78
PropertyTemplate< vector< IntRange > > PTIRA
NamedIntProperty(int &property_, int tagNum_, const char **tags_)
int operation_sub(const TextPropertyGroup::Entry &entry) const
The ASCString class provides an abstract way to manipulate strings.
Definition: ascstring.h:14
PropertyType operation_eq(const TextPropertyGroup::Entry &entry) const
TextPropertyGroup::Entry * entry
virtual T operation_mult(const TextPropertyGroup::Entry &entry) const
void storeContext(const ASCString &label)
DoubleArrayProperty(vector< double > &property_)
Entry * find(const ASCString &n)
StringProperty(ASCString &property_, const ASCString &defaultValue)
void addStringArray(const ASCString &name, vector< ASCString > &property)
ASCString extractFileName_withoutSuffix(const ASCString &filename)
Definition: basestrm.cpp:2585
virtual void writeString(const string &pc, bool binary=true)
writes the C++ String pc to the stream.
Definition: basestrm.cpp:545
ASCImageArrayProperty(PropertyType &property_, ASCString &fileName_)
PropertyType operation_eq(const TextPropertyGroup::Entry &entry) const
TagIntProperty(int &property_, int tagNum_, const char **tags_, bool inverted_)
PropertyType operation_mult(const TextPropertyGroup::Entry &entry) const
static ASCString toString(int i)
converts the parameter to a String
Definition: ascstring.cpp:193
virtual T operation_sub(const TextPropertyGroup::Entry &entry) const
TagIntProperty(int &property_, int tagNum_, const char **tags_, int defaultValue_, bool inverted_)
PropertyType operation_sub(const TextPropertyGroup::Entry &entry) const
void error(const ASCString &errmsg)
BoolProperty(bool &property_)
ASCString toString() const
char * strrr(int a)
converts a to a string.
Definition: misc.cpp:66
void applyFieldMask(Surface &s, int x, int y, bool detecColorKey)
Definition: surface.cpp:593
void writePNG(const ASCString &filename, const Surface &s)
Definition: surface2png.cpp:31
ASCString operation_eq(const TextPropertyGroup::Entry &entry) const
NamedIntProperty(int &property_, int tagNum_, const char **tags_, int defaultValue_)
StringProperty(ASCString &property_)
ASCImageProperty(Surface &property_, ASCString &fileName_, bool applyFieldMask)
TagArrayProperty(BitSet &property_, int tagNum_, const char **tags_, bool inverted_)
A simple string tokenizer.
FloatProperty(double &property_)
void displayLogMessage(int msgVerbosity, const char *message,...)
void warning(const ASCString &errmsg)
ASCString value
Entry * parent
ASCString getNextToken()
PropertyWritingContainer(const ASCString &baseName, tnstream &stream)
FloatProperty(double &property_, double defaultValue_)
ASCString toString() const
BitSet operation_sub(const TextPropertyGroup::Entry &entry) const
BitSet operation_add(const TextPropertyGroup::Entry &entry) const
void writeProperty(Property &p, const ASCString &value)
char * constructFileName(char *buf, int directoryLevel, const char *path, const char *filename)
Definition: basestrm.cpp:873
PropertyTemplate< int > PTI
int operation_add(const TextPropertyGroup::Entry &entry) const
const ASCString & getLastName()
void addDFloatArray(const ASCString &name, vector< double > &property)
Property(bool defaultValueAvail_)
double operation_mult(const TextPropertyGroup::Entry &entry) const
StoredContext storedContext
SDLmm::SPoint SPoint
Definition: surface.h:27
ASCString toString() const
PropertyTemplate(T &property_, const T &defaultValue_)
Class that stores all the (preparsed) entries of an .ASCTXT file.
int operation_eq(const TextPropertyGroup::Entry &entry) const
void addInteger(const ASCString &name, int &property)
ASCString toString() const
int atoi(const std::string &s)
Definition: misc.cpp:152
PropertyTemplate< bool > PTB
virtual void closeBracket()
ValArrayProperty< double > PTDA
ASCString toString() const
PropertyType operation_add(const TextPropertyGroup::Entry &entry) const
void addNamedInteger(const ASCString &name, int &property, int tagNum, const char **tags)
void addImageArray(const ASCString &name, vector< Surface > &property, ASCString &fileName)
virtual T parse(const TextPropertyGroup::Entry &entry) const
This String Tokenizer is NOT intended to be a general purpose tool. It is exclusively used by the Tex...
PropertyTemplate(T &property_)
static const char * operations[]
PropertyTemplate< vector< ASCString > > PTSA
PropertyTemplate< int > PTTI
virtual void openBracket(const ASCString &name)
ASCString toString() const
PropertyTemplate< int > PTNI
PropertyType operation_eq(const TextPropertyGroup::Entry &entry) const
ASCString operation_add(const TextPropertyGroup::Entry &entry) const
void addString(const ASCString &name, ASCString &property)
TextPropertyGroup * textPropertyGroup
void addIntRangeArray(const ASCString &name, vector< IntRange > &property, bool required=true)
int operation_eq(const TextPropertyGroup::Entry &entry) const
double operation_eq(const TextPropertyGroup::Entry &entry) const
int operation_eq(const TextPropertyGroup::Entry &entry) const
bool find(const ASCString &name)
std::bitset< 64 > BitSet
Definition: basictypes.h:48
ASCString propertyName
IntRangeArrayProperty(vector< IntRange > &property_, bool _required)
void fatalError(const ASCString &string)
void addTagArray(const ASCString &name, BitSet &property, int tagNum, const char **tags, bool inverted=false)
bool restoreContext(const ASCString &label)
virtual T operation_eq(const TextPropertyGroup::Entry &entry) const
void addDFloat(const ASCString &name, double &property)
void setName(const ASCString &name_, const ASCString &lastName_)
PropertyTemplate< Surface > PTIMG2
int compare_ci(const ASCCharTString &s) const
Definition: ascstring.h:296
Functions to parse the *.asctxt files.
ASCString toString() const
virtual void openBracket(const ASCString &name)
PropertyType operation_eq(const TextPropertyGroup::Entry &entry) const