Cppcheck
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
tokenize.h
Go to the documentation of this file.
1 /*
2  * Cppcheck - A tool for static C/C++ code analysis
3  * Copyright (C) 2007-2015 Daniel Marjam√§ki and Cppcheck team.
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 //---------------------------------------------------------------------------
20 #ifndef tokenizeH
21 #define tokenizeH
22 //---------------------------------------------------------------------------
23 
24 #include "errorlogger.h"
25 #include "tokenlist.h"
26 #include "config.h"
27 
28 #include <string>
29 #include <map>
30 #include <set>
31 #include <list>
32 #include <ctime>
33 
34 class Settings;
35 class SymbolDatabase;
36 class TimerResults;
37 
38 /// @addtogroup Core
39 /// @{
40 
41 /** @brief The main purpose is to tokenize the source code. It also has functions that simplify the token list */
43 public:
44  Tokenizer();
45  Tokenizer(const Settings * settings, ErrorLogger *errorLogger);
46  ~Tokenizer();
47 
49  m_timerResults = tr;
50  }
51 
52  /** Is the code C. Used for bailouts */
53  bool isC() const {
54  return list.isC();
55  }
56 
57  /** Is the code CPP. Used for bailouts */
58  bool isCPP() const {
59  return list.isCPP();
60  }
61 
62  /**
63  * Check if inner scope ends with a call to a noreturn function
64  * \param endScopeToken The '}' token
65  * \param unknown set to true if it's unknown if the scope is noreturn
66  * \return true if scope ends with a function call that might be 'noreturn'
67  */
68  bool IsScopeNoReturn(const Token *endScopeToken, bool *unknown = nullptr) const;
69 
70  /**
71  * Tokenize code
72  * @param code input stream for code, e.g.
73  * \code
74  * #file "p.h"
75  * class Foo
76  * {
77  * private:
78  * void Bar();
79  * };
80  *
81  * #endfile
82  * void Foo::Bar()
83  * {
84  * }
85  * \endcode
86  *
87  * @param FileName The filename
88  * @param configuration E.g. "A" for code where "#ifdef A" is true
89  * @param noSymbolDB_AST Disable creation of SymbolDatabase and AST
90  * @return false if source code contains syntax errors
91  */
92  bool tokenize(std::istream &code,
93  const char FileName[],
94  const std::string &configuration = emptyString,
95  bool noSymbolDB_AST = false);
96  /**
97  * tokenize condition and run simple simplifications on it
98  * @param code code
99  * @return true if success.
100  */
101  bool tokenizeCondition(const std::string &code);
102 
103  /** Set variable id */
104  void setVarId();
105 
106  /**
107  * Basic simplification of tokenlist
108  *
109  * @param FileName The filename to run; used to do
110  * markup checks.
111  *
112  * @return false if there is an error that requires aborting
113  * the checking of this file.
114  */
115  bool simplifyTokenList1(const char FileName[]);
116 
117  /**
118  * Most aggressive simplification of tokenlist
119  *
120  * @return false if there is an error that requires aborting
121  * the checking of this file.
122  */
123  bool simplifyTokenList2();
124 
125  /**
126  * Deletes dead code between 'begin' and 'end'.
127  * In general not everything can be erased, such as:
128  * - code after labels;
129  * - code outside the scope where the function is called;
130  * - code after a change of scope caused by 'switch(...);'
131  * instructions, like 'case %any%;' or 'default;'
132  * Also, if the dead code contains a 'switch' block
133  * and inside it there's a label, the function removes all
134  * the 'switch(..)' tokens and every occurrence of 'case %any%; | default;'
135  * expression, such as the 'switch' block is reduced to a simple block.
136  *
137  * @param begin Tokens after this have a possibility to be erased.
138  * @param end Tokens before this have a possibility to be erased.
139  */
140  static void eraseDeadCode(Token *begin, const Token *end);
141 
142  /**
143  * Simplify '* & ( %name% ) =' or any combination of '* &' and '()'
144  * parentheses around '%name%' to '%name% ='
145  */
146  void simplifyMulAndParens();
147 
148  /**
149  * Calculates sizeof value for given type.
150  * @param type Token which will contain e.g. "int", "*", or string.
151  * @return sizeof for given type, or 0 if it can't be calculated.
152  */
153  unsigned int sizeOfType(const Token *type) const;
154 
155  /**
156  * Try to determine if function parameter is passed by value by looking
157  * at the function declaration.
158  * @param fpar token for function parameter in the function call
159  * @return true if the parameter is passed by value. if unsure, false is returned
160  */
161  bool isFunctionParameterPassedByValue(const Token *fpar) const;
162 
163  /**
164  * get error messages that the tokenizer generate
165  */
166  static void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings);
167 
168  /** Simplify assignment in function call "f(x=g());" => "x=g();f(x);"
169  */
170  void simplifyAssignmentInFunctionCall();
171 
172  /** Simplify assignment where rhs is a block : "x=({123;});" => "{x=123;}" */
173  void simplifyAssignmentBlock();
174 
175  /**
176  * Simplify constant calculations such as "1+2" => "3"
177  * @return true if modifications to token-list are done.
178  * false if no modifications are done.
179  */
180  bool simplifyCalculations();
181 
182  /**
183  * Simplify dereferencing a pointer offset by a number:
184  * "*(ptr + num)" => "ptr[num]"
185  * "*(ptr - num)" => "ptr[-num]"
186  */
187  void simplifyOffsetPointerDereference();
188 
189  /** Insert array size where it isn't given */
190  void arraySize();
191 
192  /** Simplify labels and 'case|default' syntaxes.
193  */
194  void simplifyLabelsCaseDefault();
195 
196  /** Remove macros in global scope */
197  void removeMacrosInGlobalScope();
198 
199  /** Remove undefined macro in class definition:
200  * class DLLEXPORT Fred { };
201  * class Fred FINAL : Base { };
202  */
203  void removeMacroInClassDef();
204 
205  /** Remove unknown macro in variable declarations: PROGMEM char x; */
206  void removeMacroInVarDecl();
207 
208  /** Remove redundant assignment */
209  void removeRedundantAssignment();
210 
211  /** Simplifies some realloc usage like
212  * 'x = realloc (0, n);' => 'x = malloc(n);'
213  * 'x = realloc (y, 0);' => 'x = 0; free(y);'
214  */
215  void simplifyRealloc();
216 
217  /** Add parentheses for sizeof: sizeof x => sizeof(x) */
218  void sizeofAddParentheses();
219 
220  /**
221  * Replace sizeof() to appropriate size.
222  * @return true if modifications to token-list are done.
223  * false if no modifications are done.
224  */
225  bool simplifySizeof();
226 
227  /**
228  * Simplify variable declarations (split up)
229  * \param only_k_r_fpar Only simplify K&R function parameters
230  */
231  void simplifyVarDecl(bool only_k_r_fpar);
232  void simplifyVarDecl(Token * tokBegin, Token * tokEnd, bool only_k_r_fpar);
233 
234  /**
235  * Simplify variable initialization
236  * '; int *p(0);' => '; int *p = 0;'
237  */
238  void simplifyInitVar();
239  Token * initVar(Token * tok);
240 
241  /**
242  * Convert platform dependent types to standard types.
243  * 32 bits: size_t -> unsigned long
244  * 64 bits: size_t -> unsigned long long
245  */
246  void simplifyPlatformTypes();
247 
248  /**
249  * Collapse compound standard types into a single token.
250  * unsigned long long int => long _isUnsigned=true,_isLong=true
251  */
252  void simplifyStdType();
253 
254  /**
255  * Simplify easy constant '?:' operation
256  * Example: 0 ? (2/0) : 0 => 0
257  * @return true if something is modified
258  * false if nothing is done.
259  */
260  bool simplifyConstTernaryOp();
261 
262  /**
263  * Simplify compound assignments
264  * Example: ";a+=b;" => ";a=a+b;"
265  */
266  void simplifyCompoundAssignment();
267 
268  /**
269  * Simplify the location of "static" and "const" qualifiers in
270  * a variable declaration or definition.
271  * Example: "int static const a;" => "static const a;"
272  * Example: "long long const static b;" => "static const long long b;"
273  */
274  void simplifyStaticConst();
275 
276  /**
277  * Simplify assignments in "if" and "while" conditions
278  * Example: "if(a=b);" => "a=b;if(a);"
279  * Example: "while(a=b) { f(a); }" => "a = b; while(a){ f(a); a = b; }"
280  * Example: "do { f(a); } while(a=b);" => "do { f(a); a = b; } while(a);"
281  */
282  void simplifyIfAndWhileAssign();
283 
284  /**
285  * Simplify multiple assignments.
286  * Example: "a = b = c = 0;" => "a = 0; b = 0; c = 0;"
287  */
288  void simplifyVariableMultipleAssign();
289 
290  /**
291  * simplify if-not
292  * Example: "if(0==x);" => "if(!x);"
293  */
294  void simplifyIfNot();
295 
296  /**
297  * simplify if-not NULL
298  * Example: "if(0!=x);" => "if(x);"
299  * Special case: 'x = (0 != x);' is removed.
300  */
301  void simplifyIfNotNull();
302 
303  /** @brief simplify if (a) { if (a) */
304  void simplifyIfSameInnerCondition();
305 
306  /**
307  * Simplify the 'C Alternative Tokens'
308  * Examples:
309  * "if(s and t)" => "if(s && t)"
310  * "while((r bitand s) and not t)" => while((r & s) && !t)"
311  * "a and_eq b;" => "a &= b;"
312  */
313  bool simplifyCAlternativeTokens();
314 
315  /**
316  * Simplify comma into a semicolon when possible:
317  * - "delete a, delete b" => "delete a; delete b;"
318  * - "a = 0, b = 0;" => "a = 0; b = 0;"
319  * - "return a(), b;" => "a(); return b;"
320  */
321  void simplifyComma();
322 
323  /** Add braces to an if-block, for-block, etc.
324  * @return true if no syntax errors
325  */
326  bool simplifyAddBraces();
327 
328  /** Add braces to an if-block, for-block, etc.
329  * for command starting at token including else-block
330  * @return last token of command
331  * or input token in case of an error where no braces are added
332  * or NULL when syntaxError is called
333  */
334  Token * simplifyAddBracesToCommand(Token * tok);
335 
336  /** Add pair of braces to an single if-block, else-block, for-block, etc.
337  * for command starting at token
338  * @return last token of command
339  * or input token in case of an error where no braces are added
340  * or NULL when syntaxError is called
341  */
342  Token * simplifyAddBracesPair(Token *tok, bool commandWithCondition);
343 
344  /**
345  * typedef A mytype;
346  * mytype c;
347  *
348  * Becomes:
349  * typedef A mytype;
350  * A c;
351  */
352  void simplifyTypedef();
353 
354  /**
355  * Simplify float casts (float)1 => 1.0
356  */
357  void simplifyFloatCasts();
358 
359  /**
360  * Simplify casts
361  */
362  void simplifyCasts();
363 
364  /**
365  * Change (multiple) arrays to (multiple) pointers.
366  */
367  void simplifyUndefinedSizeArray();
368 
369  /**
370  * A simplify function that replaces a variable with its value in cases
371  * when the value is known. e.g. "x=10; if(x)" => "x=10;if(10)"
372  *
373  * @return true if modifications to token-list are done.
374  * false if no modifications are done.
375  */
376  bool simplifyKnownVariables();
377 
378  /**
379  * Utility function for simplifyKnownVariables. Get data about an
380  * assigned variable.
381  */
382  static bool simplifyKnownVariablesGetData(unsigned int varid, Token **_tok2, Token **_tok3, std::string &value, unsigned int &valueVarId, bool &valueIsPointer, bool floatvar);
383 
384  /**
385  * utility function for simplifyKnownVariables. Perform simplification
386  * of a given variable
387  */
388  bool simplifyKnownVariablesSimplify(Token **tok2, Token *tok3, unsigned int varid, const std::string &structname, std::string &value, unsigned int valueVarId, bool valueIsPointer, const Token * const valueToken, int indentlevel) const;
389 
390  /** Simplify useless C++ empty namespaces, like: 'namespace %name% { }'*/
391  void simplifyEmptyNamespaces();
392 
393  /** Simplify redundant code placed after control flow statements :
394  * 'return', 'throw', 'goto', 'break' and 'continue'
395  */
396  void simplifyFlowControl();
397 
398  /** Expand nested strcat() calls. */
399  void simplifyNestedStrcat();
400 
401  /** Simplify "if else" */
402  void elseif();
403 
404  /** Simplify conditions
405  * @return true if something is modified
406  * false if nothing is done.
407  */
408  bool simplifyConditions();
409 
410  /** Remove redundant code, e.g. if( false ) { int a; } should be
411  * removed, because it is never executed.
412  * @return true if something is modified
413  * false if nothing is done.
414  */
415  bool removeRedundantConditions();
416 
417  /**
418  * Remove redundant for:
419  * "for (x=0;x<1;x++) { }" => "{ x = 1; }"
420  */
421  void removeRedundantFor();
422 
423 
424  /**
425  * Reduces "; ;" to ";", except in "( ; ; )"
426  */
427  void removeRedundantSemicolons();
428 
429  /** Simplify function calls - constant return value
430  * @return true if something is modified
431  * false if nothing is done.
432  */
433  bool simplifyFunctionReturn();
434 
435  /** Struct initialization */
436  void simplifyStructInit();
437 
438  /** Struct simplification
439  * "struct S { } s;" => "struct S { }; S s;"
440  */
441 
442  void simplifyStructDecl();
443 
444  /**
445  * Remove redundant parentheses:
446  * - "((x))" => "(x)"
447  * - "(function())" => "function()"
448  * - "(delete x)" => "delete x"
449  * - "(delete [] x)" => "delete [] x"
450  * @return true if modifications to token-list are done.
451  * false if no modifications are done.
452  */
453  bool simplifyRedundantParentheses();
454 
455  void simplifyCharAt();
456 
457  /** Simplify references */
458  void simplifyReference();
459 
460  /**
461  * Simplify functions like "void f(x) int x; {"
462  * into "void f(int x) {"
463  */
464  void simplifyFunctionParameters();
465 
466  /**
467  * Simplify templates
468  */
469  void simplifyTemplates();
470 
471  void simplifyDoublePlusAndDoubleMinus();
472 
473  void simplifyRedundantConsecutiveBraces();
474 
475  void simplifyArrayAccessSyntax();
476 
477  void simplifyParameterVoid();
478 
479  void fillTypeSizes();
480 
481  void combineOperators();
482 
483  void combineStrings();
484 
485  void concatenateDoubleSharp();
486 
487  void simplifyFileAndLineMacro();
488 
489  void simplifyNull();
490 
491  void concatenateNegativeNumberAndAnyPositive();
492 
493  void simplifyExternC();
494 
495  void simplifyRoundCurlyParentheses();
496 
497  void simplifyDebugNew();
498 
499  void simplifySQL();
500 
501  bool hasEnumsWithTypedef();
502 
503  void simplifyDefaultAndDeleteInsideClass();
504 
505  void findComplicatedSyntaxErrorsInTemplates();
506 
507  /**
508  * Simplify e.g. 'atol("0")' into '0'
509  */
510  void simplifyMathFunctions();
511 
512  /**
513  * Simplify e.g. 'sin(0)' into '0'
514  */
515  void simplifyMathExpressions();
516 
517  /**
518  * Modify strings in the token list by replacing hex and oct
519  * values. E.g. "\x61" -> "a" and "\000" -> "\0"
520  * @param source The string to be modified, e.g. "\x61"
521  * @return Modified string, e.g. "a"
522  */
523  static std::string simplifyString(const std::string &source);
524 
525  /**
526  * Change "int const x;" into "const int x;"
527  */
528  void simplifyConst();
529 
530  /**
531  * simplify "while (0)"
532  */
533  void simplifyWhile0();
534 
535  /**
536  * Simplify while(func() && errno==EINTR)
537  */
538  void simplifyErrNoInWhile();
539 
540  /**
541  * Simplify while(func(f))
542  */
543  void simplifyFuncInWhile();
544 
545  /**
546  * Replace enum with constant value
547  */
548  void simplifyEnum();
549 
550  /**
551  * Remove "std::" before some function names
552  */
553  void simplifyStd();
554 
555  /** Simplify pointer to standard type (C only) */
556  void simplifyPointerToStandardType();
557 
558  /** Simplify function pointers */
559  void simplifyFunctionPointers();
560 
561  /**
562  * Remove exception specifications.
563  */
564  void removeExceptionSpecifications();
565 
566 
567  /**
568  * Send error message to error logger about internal bug.
569  * @param tok the token that this bug concerns.
570  */
571  void cppcheckError(const Token *tok) const;
572 
573  /**
574  * Setup links for tokens so that one can call Token::link().
575  */
576  void createLinks();
577 
578  /**
579  * Setup links between < and >.
580  */
581  void createLinks2();
582 
583  /** Syntax error */
584  void syntaxError(const Token *tok) const;
585 
586  /** Syntax error. Example: invalid number of ')' */
587  void syntaxError(const Token *tok, char c) const;
588 
589  /** Report that there is an unhandled "class x y {" code */
590  void unhandled_macro_class_x_y(const Token *tok) const;
591 
592  /**
593  * assert that tokens are ok - used during debugging for example
594  * to catch problems in simplifyTokenList1/2.
595  */
596  void validate() const;
597 
598  /**
599  * Remove __declspec()
600  */
601  void simplifyDeclspec();
602 
603  /**
604  * Remove calling convention
605  */
606  void simplifyCallingConvention();
607 
608  /**
609  * Remove __attribute__ ((?))
610  */
611  void simplifyAttribute();
612 
613  /**
614  * Remove keywords "volatile", "inline", "register", and "restrict"
615  */
616  void simplifyKeyword();
617 
618  /**
619  * Remove __asm
620  */
621  void simplifyAsm();
622 
623  /**
624  * Simplify bitfields - the field width is removed as we don't use it.
625  */
626  void simplifyBitfields();
627 
628  /**
629  * Remove __builtin_expect(...), likely(...), and unlikely(...)
630  */
631  void simplifyBuiltinExpect();
632 
633  /**
634  * Remove unnecessary member qualification
635  */
636  void removeUnnecessaryQualification();
637 
638  /**
639  * unnecessary member qualification error
640  */
641  void unnecessaryQualificationError(const Token *tok, const std::string &qualification) const;
642 
643  /**
644  * Add std:: in front of std classes, when using namespace std; was given
645  */
646  void simplifyNamespaceStd();
647 
648  /**
649  * Remove Microsoft MFC 'DECLARE_MESSAGE_MAP()'
650  */
651  void simplifyMicrosoftMFC();
652 
653  /**
654  * Convert Microsoft memory functions
655  * CopyMemory(dst, src, len) -> memcpy(dst, src, len)
656  * FillMemory(dst, len, val) -> memset(dst, val, len)
657  * MoveMemory(dst, src, len) -> memmove(dst, src, len)
658  * ZeroMemory(dst, len) -> memset(dst, 0, len)
659  */
660  void simplifyMicrosoftMemoryFunctions();
661 
662  /**
663  * Convert Microsoft string functions
664  * _tcscpy -> strcpy
665  */
666  void simplifyMicrosoftStringFunctions();
667 
668  /**
669  * Remove Borland code
670  */
671  void simplifyBorland();
672 
673  /**
674  * Remove Qt signals and slots
675  */
676  void simplifyQtSignalsSlots();
677 
678  /**
679  * Collapse operator name tokens into single token
680  * operator = => operator=
681  */
682  void simplifyOperatorName();
683 
684  /**
685  * check for duplicate enum definition
686  */
687  bool duplicateDefinition(Token **tokPtr, const Token *name) const;
688 
689  /**
690  * report error message
691  */
692  void reportError(const Token* tok, const Severity::SeverityType severity, const std::string& id, const std::string& msg, bool inconclusive = false) const;
693  void reportError(const std::list<const Token*>& callstack, Severity::SeverityType severity, const std::string& id, const std::string& msg, bool inconclusive = false) const;
694 
695  /**
696  * duplicate enum definition error
697  */
698  void duplicateEnumError(const Token *tok1, const Token *tok2, const std::string & type) const;
699 
700  bool duplicateTypedef(Token **tokPtr, const Token *name, const Token *typeDef, const std::set<std::string>& structs) const;
701  void duplicateTypedefError(const Token *tok1, const Token *tok2, const std::string & type) const;
702 
703  /**
704  * Report error - duplicate declarations
705  */
706  void duplicateDeclarationError(const Token *tok1, const Token *tok2, const std::string &type) const;
707 
708  void unsupportedTypedef(const Token *tok) const;
709 
710  /** Was there templates in the code? */
711  bool codeWithTemplates() const {
712  return _codeWithTemplates;
713  }
714 
715  void setSettings(const Settings *settings) {
716  _settings = settings;
717  list.setSettings(settings);
718  }
719 
721  return _symbolDatabase;
722  }
723  void createSymbolDatabase();
724  void deleteSymbolDatabase();
725 
726  void printDebugOutput() const;
727 
728  void dump(std::ostream &out) const;
729 
730  Token *deleteInvalidTypedef(Token *typeDef);
731 
732  /**
733  * Get variable count.
734  * @return number of variables
735  */
736  unsigned int varIdCount() const {
737  return _varId;
738  }
739 
740  /**
741  * Simplify e.g. 'return(strncat(temp,"a",1));' into
742  * strncat(temp,"a",1); return temp;
743  */
744  void simplifyReturnStrncat();
745 
746  /**
747  * Output list of unknown types.
748  */
749  void printUnknownTypes() const;
750 
751 
752  /**
753  * Token list: stores all tokens.
754  */
756  // Implement tokens() as a wrapper for convinience when using the TokenList
757  const Token* tokens() const {
758  return list.front();
759  }
760 
761  /**
762  * Copy tokens.
763  * @param dest destination token where copied tokens will be inserted after
764  * @param first first token to copy
765  * @param last last token to copy
766  * @param one_line true=>copy all tokens to the same line as dest. false=>copy all tokens to dest while keeping the 'line breaks'
767  * @return new location of last token copied
768  */
769  static Token *copyTokens(Token *dest, const Token *first, const Token *last, bool one_line = true);
770 
771  /**
772  * Helper function to check whether number is zero (0 or 0.0 or 0E+0) or not?
773  * @param s the string to check
774  * @return true in case is is zero and false otherwise.
775  */
776  static bool isZeroNumber(const std::string &s);
777 
778  /**
779  * Helper function to check whether number is one (1 or 0.1E+1 or 1E+0) or not?
780  * @param s the string to check
781  * @return true in case is is one and false otherwise.
782  */
783  static bool isOneNumber(const std::string &s);
784 
785  /**
786  * Helper function to check whether number is two (2 or 0.2E+1 or 2E+0) or not?
787  * @param s the string to check
788  * @return true in case is is two and false otherwise.
789  */
790  static bool isTwoNumber(const std::string &s);
791 
792  /**
793  * Helper function to check for start of function execution scope.
794  * Do not use this in checks. Use the symbol database.
795  * @param tok --> pointer to end parentheses of parameter list
796  * @return pointer to start brace of function scope or nullptr if not start.
797  */
798  static const Token * startOfExecutableScope(const Token * tok);
799 
800 private:
801  /** Disable copy constructor, no implementation */
802  Tokenizer(const Tokenizer &);
803 
804  /** Disable assignment operator, no implementation */
805  Tokenizer &operator=(const Tokenizer &);
806 
807  static Token * startOfFunction(Token * tok);
809  return const_cast<Token*>(startOfExecutableScope(const_cast<const Token *>(tok)));
810  }
811 
812  /** Set pod types */
813  void setPodTypes();
814 
815  /** settings */
817 
818  /** errorlogger */
820 
821  /** Symbol database that all checks etc can use */
823 
824  /** E.g. "A" for code where "#ifdef A" is true. This is used to
825  print additional information in error situations. */
826  std::string _configuration;
827 
828  /** sizeof information for known types */
829  std::map<std::string, unsigned int> _typeSize;
830 
831  /** variable count */
832  unsigned int _varId;
833 
834  /**
835  * was there any templates? templates that are "unused" are
836  * removed from the token list
837  */
839 
840  /**
841  * TimerResults
842  */
844 #ifdef MAXTIME
845  /** Tokenizer maxtime */
846  std::time_t maxtime;
847 #endif
848 };
849 
850 /// @}
851 
852 //---------------------------------------------------------------------------
853 #endif // tokenizeH