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