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: Preprocess verilog code 16 /// 17 /// Authors: Wilson Snyder 18 /// 19 /// Code available from: https://www.veripool.org/verilog-perl 20 /// 21 //************************************************************************* 22 23 #ifndef _VPREPROC_H_ 24 #define _VPREPROC_H_ 1 25 26 #include <string> 27 #include <map> 28 #include <iostream> 29 using namespace std; 30 #include "VFileLine.h" 31 32 /// Generic opaque pointer to VPreProcImp implementation class. 33 struct VPreProcOpaque { ~VPreProcOpaqueVPreProcOpaque34 virtual ~VPreProcOpaque() {} 35 }; 36 class VDefine; 37 38 //********************************************************************** 39 // VPreProc 40 /// Verilog Preprocessor. 41 //// 42 /// This defines a preprocessor. Functions are virtual so users can override them. 43 /// After creating, call openFile(), then getline() in a loop. The class will to the rest... 44 45 class VPreProc { 46 public: 47 VPreProc(); 48 void configure(VFileLine* filelinep); 49 virtual ~VPreProc(); 50 51 // STATE 52 private: 53 int m_keepComments; 54 int m_keepWhitespace; 55 bool m_lineDirectives; 56 bool m_pedantic; 57 bool m_synthesis; 58 59 public: 60 // CONSTANTS 61 enum MiscConsts { 62 DEFINE_RECURSION_LEVEL_MAX = 1000, // How many `def substitutions before an error 63 INCLUDE_DEPTH_MAX = 500, // How many `includes deep before an error 64 STREAM_DEPTH_LEVEL_MAX = 2000, // How many streams deep (sometimes `def deep) before an error 65 // // Set more than DEFINE_RECURSION_LEVEL_MAX or INCLUDE_DEPTH_MAX 66 NEWLINES_VS_TICKLINE = 20 // Use `line in place of this many newlines 67 }; 68 69 // ACCESSORS 70 /// Insert given file into this point in input stream 71 void openFile(string filename, VFileLine* filelinep=NULL); 72 void debug(int level); ///< Set debugging level 73 string getall(size_t approx_chunk); ///< Return all lines, or at least approx_chunk bytes. (Null if done.) 74 string getline(); ///< Return next line/lines. (Null if done.) 75 bool isEof(); ///< Return true on EOF. 76 void insertUnreadback(string text); 77 78 VFileLine* fileline(); ///< File/Line number for last getline call 79 80 // The default behavior is to pass all unknown `defines right through. 81 // This lets the user determine how to report the errors. It also nicely 82 // allows `celldefine and such to remain in the output stream. 83 84 // CONTROL METHODS 85 // These options control how the parsing proceeds keepComments()86 int keepComments() { return m_keepComments; } keepComments(int flag)87 void keepComments(int flag) { m_keepComments=flag; } // Return comments, 0=no, 1=yes, 2=callback keepWhitespace()88 int keepWhitespace() { return m_keepWhitespace; } keepWhitespace(int flag)89 void keepWhitespace(int flag) { m_keepWhitespace=flag; } // Return extra whitespace lineDirectives()90 bool lineDirectives() { return m_lineDirectives; } lineDirectives(bool flag)91 void lineDirectives(bool flag) { m_lineDirectives=flag; } // Insert `line directives pedantic()92 bool pedantic() { return m_pedantic; } pedantic(bool flag)93 void pedantic(bool flag) { m_pedantic=flag; } // Obey standard; Don't substitute `error synthesis()94 bool synthesis() { return m_synthesis; } synthesis(bool flag)95 void synthesis(bool flag) { m_synthesis=flag; } // Ignore translate off 96 97 // CALLBACK METHODS 98 // This probably will want to be overridden for given child users of this class. 99 virtual void comment(string cmt) = 0; ///< Comment detected (if keepComments==2) 100 virtual void include(string filename) = 0; ///< Request a include file be processed 101 virtual void define(string name, string value, string params) = 0; ///< `define without any parameters 102 virtual void undef(string name) = 0; ///< Remove a definition 103 virtual void undefineall() = 0; ///< Remove all non-command-line definitions 104 virtual bool defExists(string name) = 0; ///< Return true if define exists 105 virtual string defParams(string name) = 0; ///< Return parameter list if define exists 106 virtual string defValue(string name) = 0; ///< Return value of given define (should exist) 107 virtual string defSubstitute(string substitute) = 0; ///< Return value to substitute for given post-parameter value 108 109 // UTILITIES error(string msg)110 void error(string msg) { fileline()->error(msg); } ///< Report a error fatal(string msg)111 void fatal(string msg) { fileline()->fatal(msg); } ///< Report a fatal error 112 113 private: 114 VPreProcOpaque* m_opaquep; ///< Pointer to parser's implementation data. 115 }; 116 117 #endif // Guard 118