1 // -*- C++ -*-
2 //*************************************************************************
3 //
4 // Copyright 2000-2021 by Wilson Snyder. This program is free software;
5 // you can redistribute it and/or modify it under the terms of either the GNU
6 // Lesser General Public License Version 3 or the Perl Artistic License Version 2.0.
7 //
8 // This program is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 // GNU General Public License for more details.
12 //
13 //*************************************************************************
14 /// \file
15 /// \brief Verilog::Preproc: Error handling
16 ///
17 /// Authors: Wilson Snyder
18 ///
19 /// Code available from: https://www.veripool.org/verilog-perl
20 ///
21 //*************************************************************************
22
23 #ifndef _VFILELINE_H_
24 #define _VFILELINE_H_ 1
25 #include <string>
26 #include <iostream>
27 #include <sstream>
28 using namespace std;
29
30 //============================================================================
31 // VFileLine
32 /// User information and error reporting functions
33 ////
34 /// Users can override this class to implement their own error handling
35
36 class VFileLine {
37 private:
38 int m_lineno; ///< Line number in file
39 string m_filename; ///< File name
40 static int s_numErrors; ///< Number of errors detected
41
42 protected:
VFileLine(int called_only_for_default)43 VFileLine(int called_only_for_default) {init("",0);}
44
45 public:
46 // CONSTRUCTORS
47 /// Create a new fileline, for a new file and/or line number.
48 /// Member functions, so that if a user provides another class, a change in the
49 /// filename/linenumber will create a new element using the derived class.
50 virtual VFileLine* create(const string& filename, int lineno) = 0;
51 /// Create with same filename, new line number; just calls create(fn,ln)
create(int lineno)52 virtual VFileLine* create(int lineno) { return create(filename(), lineno); }
53 virtual void init(const string& filename, int lineno);
~VFileLine()54 virtual ~VFileLine() {}
55 // ACCESSORS
lineno()56 int lineno() const { return m_lineno; } ///< Return line number
linenoIncInPlace()57 void linenoIncInPlace() { m_lineno++; } ///< Increment line IN PLACE; normally use create() instead
filename()58 const string filename() const { return m_filename; } ///< Return filename
59 const string filebasename() const; ///< Filename with any directory stripped
60 string lineDirectiveStrg(int enter_exit_level) const;
61 // METHODS
62 virtual void fatal(const string& msg); ///< Report a fatal error at given location
63 virtual void error(const string& msg); ///< Report a error at given location
64 VFileLine* lineDirective(const char* textp, int& enterExitRef);
65 // STATIC METHODS
numErrors()66 static int numErrors() { return s_numErrors; } ///< Return total errors detected
67
68 // Internal methods -- special use
69 static const char* itoa(int i); ///< Internal: Not reentrant! - for fatalSrc() only
70 };
71 ostream& operator<<(ostream& os, VFileLine* fileline);
72
73 /// Use this instead of fatal() to mention the source code line.
74 #define fatalSrc(msg) fatal((string)"Internal Error: "+__FILE__+":"+VFileLine::itoa(__LINE__)+": "+(msg))
75
cvtToStr(const T & t)76 template< class T> std::string cvtToStr(const T& t) {
77 ostringstream os; os<<t; return os.str();
78 }
79
80 #endif // Guard
81