This file is indexed.

/usr/include/BALL/STRUCTURE/smartsParser.h is in libball1.4-dev 1.4.3~beta1-4.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
// -*- Mode: C++; tab-width: 2; -*-
// vi: set ts=2:
//

#ifndef BALL_STRUCTURE_SMARTES_PARSER_H
#define BALL_STRUCTURE_SMARTES_PARSER_H

#ifndef BALL_COMMON_H
	#	include <BALL/common.h>
#endif

#include <map>
#include <set>

// needed for MSVC:
#undef CW_DEFAULT

namespace BALL 
{
	// forward declarations
	class Bond;
	class Atom;
	class Element;

	/** SMARTS Parser.
	 
	 		This class implements the parser for SMARTS patterns. The SMARTS 
			string is converted into a tree, which is used for matching it
			to molecules. The tree has also some additional features, i.e. 
			additional edges which allows also for graph features (kind of cyclic
			structure).

			\ingroup StructureMatching
	*/
	class BALL_EXPORT SmartsParser
	{
		public:

		enum ZEIsomerType
		{
			ANY_ZE = 1,
			NONE,
			Z,
			E
		};

		/// chiral class definitions CW = clock wise, CCW = counter clock wise
		enum ChiralClass
		{
			CHIRAL_CLASS_UNSPECIFIED = 1,
	    NONCHIRAL,
			NONCHIRAL_OR_UNSPECIFIED,
			CW_DEFAULT, // TH
			CW_DEFAULT_OR_UNSPECIFIED,
			CCW_DEFAULT, // TH
			CCW_DEFAULT_OR_UNSPECIFIED,
			CW_TH, // tetrahdral
			CW_TH_OR_UNSPECIFIED,
			CCW_TH,
			CCW_TH_OR_UNSPECIFIED,
			CW_AL, // allene-like
			CW_AL_OR_UNSPECIFIED,
			CCW_AL, 
			CCW_AL_OR_UNSPECIFIED,
			CW_SP, // square planar
			CW_SP_OR_UNSPECIFIED,
			CCW_SP,
			CCW_SP_OR_UNSPECIFIED,
			CW_TB, //trigonal bipyramidal
			CW_TB_OR_UNSPECIFIED,
			CCW_TB,
			CCW_TB_OR_UNSPECIFIED,
			CW_OH, // octahedral
			CW_OH_OR_UNSPECIFIED,
			CCW_OH,
			CCW_OH_OR_UNSPECIFIED
		};

		/** The logical operator supported by SMARTS-pattern <br>
		 		'&' -> and <br>
				',' -> or <br>
				';' -> low precedence and<br>

				NOOP is just provided for convenience.
		*/
		enum LogicalOperator
		{
			AND,
			OR,
			AND_LOW,
			NOOP
		};


		/// forward declaration
		class SPAtom;

		/** @brief Bond representation of the smarts parser
		
				This class represents a bond of the smarts parser. The normal
				bond representation of BALL is not sufficient in this case, 
				because many other properties are needed for the SMARTS-patterns.
				For example the "or any" orders
		*/
		class BALL_EXPORT SPBond 
		{
			public:

				/// the bond orders supported by SMARTS-patterns
				enum SPBondOrder
				{
					SINGLE = 1,
					SINGLE_UP,
					SINGLE_UP_OR_ANY,
					SINGLE_DOWN,
					SINGLE_DOWN_OR_ANY,
					SINGLE_OR_AROMATIC,
					AROMATIC,
					DOUBLE,
					TRIPLE,
					NOT_NECESSARILY_CONNECTED,
					IN_RING,
					ANY
				};
		
				/** @name Constructors and destructors
				*/
				//@{
				/// Default constructor
				SPBond();

				/// Detailed constructor with bond order
				SPBond(SPBondOrder bond_order);

				/// Detailed constructor with 
				SPBond(SPAtom* first, SPAtom* second, SPBondOrder bond_order);

				/// Destructor
				virtual ~SPBond() ;
				//@}

				/** @name Accessors
				*/
				//@{
				/// returns the Z/E isomer type
				ZEIsomerType getZEType() const { return ze_type_; }

				/// sets the Z/E isomer type
				void setZEType(ZEIsomerType type) { ze_type_ = type; }

				/// sets the bond order
				void setBondOrder(SPBondOrder bond_order);

				/// returns the bond order
				SPBondOrder getBondOrder() const { return bond_order_; }

				/// return true if a general negation is set
				bool isNot() const { return not_; }

				/// set the general negation to the bool given
				void setNot(bool is_not) { not_ = is_not; }

				// returns true if the SPBond matches the given bond
				bool equals(const Bond* bond) const;
				//@}

			protected:

				/// Z/E isomer type
				ZEIsomerType	ze_type_;

				/// the bond order
				SPBondOrder bond_order_;

				/// general negation flag
				bool not_;
		};
		
		/** @brief Smarts Parser Atom class
		
				This class implements the representation of 
				a atom of the smarts parser. It is faster than 
				using the BALL Atom class with Properties. As all
				the possible properties are known from the definition
				of the SMARTS language, the properties are listed
				within the enumeration.
		*/
		class BALL_EXPORT SPAtom
		{
			public:

				/// enum of all properties possible for a smarts parser atom
				enum PropertyType
				{
					ISOTOPE = 1,
					CHARGE,
					AROMATIC,
					ALIPHATIC,
					IN_NUM_RINGS,
					IN_RING_SIZE,
					IN_BRACKETS,
					CONNECTED,
					EXPLICIT_HYDROGENS,
					VALENCE,
					IMPLICIT_HYDROGENS,
					DEGREE,
					RING_CONNECTED,
					CHIRALITY,
					SYMBOL
				};

				/// possible types of the properties
				union PropertyValue
				{
					int int_value;
					bool bool_value;
					const Element* element_value;
					ChiralClass chiral_class_value;
				};

				/// Property struct of smarts parser atom
				struct Property
				{
					public:
				
						/** @name Constructors and desctructors
						*/
						//@{
						/// Detailed constructor with type and int value
						Property(PropertyType type, int value);
						
						/// Detailed constructor with type and flag
						Property(PropertyType type, bool value);
						
						/// Detailed constructor with type and Element
						Property(PropertyType type, const Element* value);
						
						/// Detailed constructor with type and chiral class definition
						Property(PropertyType type, ChiralClass value);

						/// Destructor
						virtual ~Property();
						//@}

						/// assignment operator
						void operator = (const Property& rhs);

						/** @name Accessors
						*/
						//@{
						/// returns the type of the property
						PropertyType getType() const { return type_; }

						/// returns the value of the property
						PropertyValue getValue() const { return value_; }
						//@}

					private:
						
						/// Default constructor
						Property();
						
						/// type of the property
						PropertyType type_;

						/// value of the property
						PropertyValue value_;
				};
				
				/** Common properties are:
				 
				  	bool 		is_not
				  	Size		isotope 
				  	bool		not_isotope
				  	Index		charge
				  	bool 		not_charge
				  	bool		is_aromatic
				  	bool		not_aromatic
				  	bool		aliphatic
				  	bool		not_aliphatic
				  	Index		in_num_rings
				  	bool 		not_in_num_rings
				  	bool 		in_brackets
				  	Index		in_ring_size
				  	bool		not_in_ring_size
				  	Size		connected
				  	bool		not_connected_to
				  	Size		explicit_hydrogens
				  	bool		not_explicit_hydrogens
				  	Size		valence
				  	bool		not_valence
				  	Size		implicit_hydrogens
				  	bool		not_implicit_hydrogens
				  	Size		degree
				  	bool		not_degree
				  	Size		ring_connected
				  	bool		not_ring_connected
				  	bool		not_chirality
				  	String	symbol
				 
				 		all this properties can be set
				 */
			
				/** @name Constructors and destructors
				*/
				//@{
				/// Default constructor
				SPAtom();

				/// copy constructor
				SPAtom(const String& symbol);

				/// destructor
				virtual ~SPAtom() ;
				//@}


				/** @name Accessors
				*/
				//@{
				/// sets an int property
				void setProperty(PropertyType type, int int_value);
				
				/// sets a flag
				void setProperty(PropertyType type, bool  flag);

				/// sets a Element
				void setProperty(PropertyType type, const Element* element);

				/// sets a chirality value
				void setProperty(PropertyType type, ChiralClass chirality);

				/// sets a property
				void setProperty(Property property);

				/// adds properties from another SPAtom
				void addPropertiesFromSPAtom(SPAtom* sp_atom);

				/// negotiates the property definition
				void setNotProperty(PropertyType type);

				/// returns true if the property is set
				bool hasProperty(PropertyType type) const;

				/// returns a value of the given property type
				PropertyValue getProperty(PropertyType type);

				/// returns the number of properties
				Size countProperties() const;

				/// return the number of valences of the given atom
				Size getDefaultValence(const Atom* atom) const;
				
				/// returns the number of available valences of the given atom
				Size countRealValences(const Atom* atom) const;
				
				/// returns the number of implicit hydrogens of the given atom
				Size getNumberOfImplicitHydrogens(const Atom* atom) const;
				//@}

				/** @name Predicates
				*/
				//@{
				/// returns true if the local properties of the atoms match
				bool equals(const Atom* atom) const;
				//@}
				
			protected:

				/// the atom which this sp_atom belongs to
				Atom* atom_;

				/// the properties of this SPAtom
				std::map<PropertyType, PropertyValue> properties_;

				/// the properties which are negated
				std::set<PropertyType> not_properties_;
		};

		/// forward declaration	
		class SPNode;

		/** @brief Edge representation of the smarts parser graph
		*/
		class BALL_EXPORT SPEdge
		{
			public:

				/** @name Constructors and destructors
				*/
				//@{
				/// Default constructor
				SPEdge();

				/// Copy constructor
				SPEdge(const SPEdge& sp_edge);

				/// Destructor
				virtual ~SPEdge();
				//@}
				
				/** @name Acessors
				*/
				//@{
				/// returns true if this is a internal edge
				bool isInternal() const { return internal_; }

				/// set this edge to a internal edge
				void setInternal(bool internal) { internal_ = internal; }
				
				/// sets the corresponding SPBond of this edge 
				void setSPBond(SPBond* sp_bond) { bond_ = sp_bond; }

				/// returns the corresponding SPBond of this edge
				SPBond* getSPBond() const { return bond_; }
				
				/// set the first SPNode of this edge
				void setFirstSPNode(SPNode* first) { first_ = first; }

				/// returns the first SPNode of this edge
				SPNode* getFirstSPNode() const { return first_; } 
				
				/// sets the second SPNode of this edge
				void setSecondSPNode(SPNode* second) { second_ = second; }

				/// returns the second SPNode of this edge
				SPNode* getSecondSPNode() const { return second_; }
				
				/// returns the partner; either the first or the second SPNode
				SPNode* getPartnerSPNode(SPNode* node) { return node == first_ ? second_ : first_; }
				
				/// returns true if negation is enabled
				bool isNot() const { return is_not_; }

				/// set the negation flag
				void setNot(bool is_not) { is_not_ = is_not; }
			
				/// set the first SPEdge (first tree child)
				void setFirstSPEdge(SPEdge* first) { first_edge_ = first; }

				/// returns the first SPEdge (first tree child)
				SPEdge* getFirstSPEdge() const { return first_edge_; }

				/// set the second SPEdge (second tree child)
				void setSecondSPEdge(SPEdge* second) { second_edge_ = second; }

				/// returns the second SPEdge (second tree child)
				SPEdge* getSecondSPEdge() const { return second_edge_; }
		
				/// sets the associated logical operator (for the child edges)
				void setLogicalOperator(LogicalOperator log_op) { log_op_ = log_op; }

				/// returns the asociated logical operator (for the child edges)
				LogicalOperator getLogicalOperator() const { return log_op_; }
				//@}
			
			protected:

				/// internal flag
				bool internal_;

				/// negation flag
				bool is_not_;

				/// first SPNode
				SPNode* first_;

				/// second SPNode
				SPNode* second_;

				/// associated bond
				SPBond* bond_;

				/// first SPEdge
				SPEdge* first_edge_;

				/// second SPEdge
				SPEdge* second_edge_;

				/// logical operator associated with the SPEdges
				LogicalOperator log_op_;
		};

		/** @brief Representation of a node in the smarts parser graph
		*/
		class BALL_EXPORT SPNode
		{
			public:
		
				/** @name Iterators
				*/
				//@{
				/// non-constant edge iterator
				typedef std::vector<SPEdge*>::iterator EdgeIterator;

				/// constant edge iterator
				typedef std::vector<SPEdge*>::const_iterator EdgeConstIterator;
				//@}
	

				/** @name Constructors and destructors
				*/
				//@{
				/// Default constructor
				SPNode();

				/// Detailed constructor with an atom
				SPNode(SPAtom* atom);

				/// Detailed constructor with two nodes and a logical operator
				SPNode(SPNode* first, LogicalOperator log_op, SPNode* second);

				/// Copy constructor
				SPNode(const SPNode& sp_node);

				/// Destructor
				virtual ~SPNode();
				//@}
				

				/** @name Accessors
				*/
				//@{
				/// returns true if the SPNode is an internal node
				bool isInternal() const { return internal_; }

				/// sets the internal flag
				void setInternal(bool internal) { internal_ = internal; }
				
				/// returns true if the SPNode is a recursive node (from recursive SMARTS)
				bool isRecursive() const { return recursive_; }

				/// sets the recursive flag
				void setRecursive(bool recursive); 
			
				/// set the component no of the component level grouping
				void setComponentNumber(int no) { component_no_ = no; }

				/// returns the component number
				Size getComponentNumber() const { return component_no_; }
			
				/// returns the associated SPAtom
				SPAtom* getSPAtom() const { return sp_atom_; }

				/// set the associated SPAtom
				void setSPAtom(SPAtom* sp_atom) { sp_atom_ = sp_atom; }
		
				/// returns the first edge (for tree use)
				SPEdge* getFirstEdge() const { return first_edge_; }

				/// sets the first edge (for tree use)
				void setFirstEdge(SPEdge* first) { first_edge_ = first; }

				/// returns the second edge (for tree use)
				SPEdge* getSecondEdge() const { return second_edge_; }

				/// sets the second edge (for tree use)
				void setSecondEdge(SPEdge* second) { second_edge_ = second; }
		
				/// returns the negation flag
				bool getNot() const { return is_not_; }

				/// sets the negation flag
				void setNot(bool is_not) { is_not_ = is_not; }
	

				/// flag whether the pattern is in brackets
				//void setInBrackets() { in_brackets_ = true; }

				/// adds a new SPEdge (not for tree use)
				void addSPEdge(SPEdge* sp_edge) { edges_.push_back(sp_edge); }

				/// sets the logical operator associated with the SPNode
				void setLogicalOperator(LogicalOperator log_op) { log_op_ = log_op; }

				/// returns the logical operator of the SPNode
				LogicalOperator getLogicalOperator() const { return log_op_; }	

				/// counts the number of edges
				Size countEdges() const { return edges_.size(); }
				//@}

				/** @name Iterators
				*/
				//@{
				/// mutable access to begin of edges list
				EdgeIterator begin() { return edges_.begin(); }

				/// mutable access to end of edges list
				EdgeIterator end() { return edges_.end(); }

				/// non-mutable access to begin of edges list
				EdgeConstIterator begin() const { return edges_.begin(); }

				/// non-mutable access to end of edges list
				EdgeConstIterator end() const { return edges_.end(); }
				//@}

			protected:
				
				/// internal flag
				bool internal_;

				/// negotiation flag
				bool is_not_;

				/// recursive flag
				bool recursive_;

				/// in brackets flag
				//bool in_brackets_;

				/// logical operator associated with this SPNode
				LogicalOperator log_op_;

				/// edges list
				std::vector<SPEdge*> edges_;

				/// first edge
				SPEdge* first_edge_;

				/// second edge
				SPEdge* second_edge_;

				/// SPAtom associated with this SPNode
				SPAtom* sp_atom_;

				/// component level
				int component_no_;
		};

	
		/**	@name Constructors and Destructors
		*/
		//@{
		/// Default constructor
		SmartsParser();
			
		/// Copy constructor
		SmartsParser(const SmartsParser& parser);

		/// Destructor
		virtual ~SmartsParser();
		//@}
		
		/**	@name	Parsing
		*/
		//@{
		/**	Parse a SMARTS string.
		*/
		void parse(const String& s)
			throw(Exception::ParseError);

		/**	@name Accessors
		*/
		//@{
		/// creates a new atom of symbol
		SPAtom* createAtom(const String& symbol, bool in_bracket = false);

		/// sets the root SPNode of the tree
		void setRoot(SPNode* root) { root_ = root; }

		/// returns the root SPNode of the tree
		SPNode* getRoot() const { return root_; }

		/// dumps the tree to cerr
		void dumpTree();
		
		/// clear the tree
		void clear();
		
		/// adds a ring connection, SPNode with an index used in the SMARTS pattern
		void addRingConnection(SPNode* spnode, Size index);
		
		/// returns the ring connections sorted by index from SMARTS pattern
		std::map<Size, std::vector<SPNode*> > getRingConnections() const;
	
		/// sets the SSSR
		void setSSSR(const std::vector<std::vector<Atom*> >& sssr);

		/// sets the sssr needed flag
		void setNeedsSSSR(bool needs_sssr) { needs_SSSR_ = needs_sssr; }

		/// returns true if the SMARTS pattern contains ring related parts
		bool getNeedsSSSR() const { return needs_SSSR_; }

		/// sets the recursive flag
		void setRecursive(bool recursive) { recursive_ = recursive; }

		/// returns true if the tree represents a recursive SMARTS pattern
		bool isRecursive() const { return recursive_; }

		/// sets the component level flag
		void setComponentGrouping(bool component_grouping) { component_grouping_ = component_grouping; }

		/// returns true if the component level grouping was enabled
		bool hasComponentGrouping() const { return component_grouping_; }

		/// Parser state (used by the parser itself)
		struct State
		{
			Size					char_count;
			SmartsParser*	current_parser;
			const char*		buffer;
		};
		
		/// static member for the parser itself 
		static State state;

		/// returns the eodes stored in the tree
		const std::set<SPNode*>& getNodes() const { return nodes_; }

		/// returns the edges stored in the tree
		const std::set<SPEdge*>& getEdges() const { return edges_; }

		/// adds an edge to the tree
		void addEdge(SPEdge* edge) { edges_.insert(edge); }

		/// adds a node to the tree
		void addNode(SPNode* node) { nodes_.insert(node); }

		/// returns true if the tree has the given recursive edge
		bool hasRecursiveEdge(SPEdge* edge) const { return rec_edges_.find(edge) != rec_edges_.end(); }

		/// adds a recursive edge to the tree
		void addRecursiveEdge(SPEdge* edge) { rec_edges_.insert(edge); }

		/// gets the next component no and assigns it to the subtree 
		void setNextComponentNumberToSubTree(SPNode* spnode);
		//@}

		protected:

			/// sssr needed flag
			bool needs_SSSR_;

			/// recursive flag
			bool recursive_;

			/// component level grouping flag
			bool component_grouping_;

			/// the sssr 
			static vector<std::set<const Atom*> >* sssr_;

			/// dump method for the tree
			void dumpTreeRecursive_(SPNode* node, Size depth);

			/// dump method for the tree
			void dumpTreeRecursive_(SPEdge* edge, Size depth);
			
			/// the ring connection sorted by index of the SMARTS pattern
			std::map<Size, std::vector<SPNode*>	> ring_connections_;
		
			/// current instance
			static SmartsParser* current_parser_;
			
			/// the edges 
			std::set<SPEdge*> edges_;
			
			/// the nodes
			std::set<SPNode*> nodes_;

			/// the recursive edges
			std::set<SPEdge*> rec_edges_;

			/// the root node of the tree
			SPNode* root_;

			/// the actual component number
			int component_no_;
	};
  
} // namespace BALL

#endif // BALL_STRUCTURE_SMARTS_PARSER_H