Internals: Split V3OutFile into separate formatter
This commit is contained in:
parent
eb63c8dcb8
commit
a03a540156
|
|
@ -253,26 +253,19 @@ void V3File::createMakeDir() {
|
|||
}
|
||||
|
||||
//######################################################################
|
||||
// V3OutFile: A class for printing to a file, with automatic indentation of C++ code.
|
||||
// V3OutFormatter: A class for printing to a file, with automatic indentation of C++ code.
|
||||
|
||||
V3OutFile::V3OutFile(const string& filename)
|
||||
: m_filename(filename), m_lineno(1), m_column(0)
|
||||
V3OutFormatter::V3OutFormatter(const string& filename, bool verilog)
|
||||
: m_filename(filename), m_verilog(verilog)
|
||||
, m_lineno(1), m_column(0)
|
||||
, m_nobreak(false), m_prependIndent(true), m_indentLevel(0)
|
||||
, m_declSAlign(0), m_declNSAlign(0), m_declPadNum(0) {
|
||||
if ((m_fp = V3File::new_fopen_w(filename.c_str())) == NULL) {
|
||||
v3fatal("Cannot write "<<filename);
|
||||
}
|
||||
}
|
||||
|
||||
V3OutFile::~V3OutFile() {
|
||||
if (m_fp) fclose(m_fp);
|
||||
m_fp = NULL;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
const char* V3OutFile::indentStr(int num) {
|
||||
// Indent the specified levelsber of spaces. Use tabs as possible.
|
||||
const char* V3OutFormatter::indentStr(int num) {
|
||||
// Indent the specified number of spaces. Use tabs as possible.
|
||||
static char str[MAXSPACE+20];
|
||||
char* cp = str;
|
||||
if (num>MAXSPACE) num=MAXSPACE;
|
||||
|
|
@ -288,7 +281,7 @@ const char* V3OutFile::indentStr(int num) {
|
|||
return (str);
|
||||
}
|
||||
|
||||
const string V3OutFile::indentSpaces(int num) {
|
||||
const string V3OutFormatter::indentSpaces(int num) {
|
||||
// Indent the specified number of spaces. Use spaces.
|
||||
static char str[MAXSPACE+20];
|
||||
char* cp = str;
|
||||
|
|
@ -302,21 +295,20 @@ const string V3OutFile::indentSpaces(int num) {
|
|||
return (st);
|
||||
}
|
||||
|
||||
bool V3OutFile::tokenStart(const char* cp, const char* cmp) {
|
||||
bool V3OutFormatter::tokenStart(const char* cp, const char* cmp) {
|
||||
while (*cmp == *cp) { cp++; cmp++; }
|
||||
if (*cmp) return false;
|
||||
if (*cp && !isspace(*cp)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
#define VERILOG_INDENTS 0 // No verilog output yet, speed things up
|
||||
bool V3OutFile::tokenEnd(const char* cp) {
|
||||
bool V3OutFormatter::tokenEnd(const char* cp) {
|
||||
return (tokenStart(cp,"end")
|
||||
|| tokenStart(cp,"endcase")
|
||||
|| tokenStart(cp,"endmodule"));
|
||||
}
|
||||
|
||||
int V3OutFile::endLevels (const char *strg) {
|
||||
int V3OutFormatter::endLevels (const char *strg) {
|
||||
int levels=m_indentLevel;
|
||||
const char* cp=strg;
|
||||
while (isspace(*cp)) cp++;
|
||||
|
|
@ -341,7 +333,7 @@ int V3OutFile::endLevels (const char *strg) {
|
|||
levels-=INDBLK;
|
||||
break;
|
||||
case 'e':
|
||||
if (VERILOG_INDENTS && tokenEnd(cp)) {
|
||||
if (m_verilog && tokenEnd(cp)) {
|
||||
levels-=INDBLK;
|
||||
}
|
||||
break;
|
||||
|
|
@ -355,7 +347,7 @@ int V3OutFile::endLevels (const char *strg) {
|
|||
return (levels);
|
||||
}
|
||||
|
||||
void V3OutFile::puts (const char *strg) {
|
||||
void V3OutFormatter::puts (const char *strg) {
|
||||
if (m_prependIndent) {
|
||||
putsNoTracking(indentStr(endLevels(strg)));
|
||||
m_prependIndent = false;
|
||||
|
|
@ -395,13 +387,13 @@ void V3OutFile::puts (const char *strg) {
|
|||
indentDec();
|
||||
break;
|
||||
case 'b':
|
||||
if (wordstart && VERILOG_INDENTS && tokenStart(cp,"begin")) {
|
||||
if (wordstart && m_verilog && tokenStart(cp,"begin")) {
|
||||
indentInc();
|
||||
}
|
||||
wordstart = false;
|
||||
break;
|
||||
case 'c':
|
||||
if (wordstart && VERILOG_INDENTS && (tokenStart(cp,"case")
|
||||
if (wordstart && m_verilog && (tokenStart(cp,"case")
|
||||
|| tokenStart(cp,"casex")
|
||||
|| tokenStart(cp,"casez"))) {
|
||||
indentInc();
|
||||
|
|
@ -409,13 +401,13 @@ void V3OutFile::puts (const char *strg) {
|
|||
wordstart = false;
|
||||
break;
|
||||
case 'e':
|
||||
if (wordstart && VERILOG_INDENTS && tokenEnd(cp)) {
|
||||
if (wordstart && m_verilog && tokenEnd(cp)) {
|
||||
indentDec();
|
||||
}
|
||||
wordstart = false;
|
||||
break;
|
||||
case 'm':
|
||||
if (wordstart && VERILOG_INDENTS && tokenStart(cp,"module")) {
|
||||
if (wordstart && m_verilog && tokenStart(cp,"module")) {
|
||||
indentInc();
|
||||
}
|
||||
wordstart = false;
|
||||
|
|
@ -427,12 +419,12 @@ void V3OutFile::puts (const char *strg) {
|
|||
}
|
||||
}
|
||||
|
||||
void V3OutFile::putBreakExpr () {
|
||||
void V3OutFormatter::putBreakExpr () {
|
||||
if (!m_parenVec.empty()) putBreak();
|
||||
}
|
||||
|
||||
// Add a line break if too wide
|
||||
void V3OutFile::putBreak () {
|
||||
void V3OutFormatter::putBreak () {
|
||||
if (!m_nobreak) {
|
||||
//char s[1000]; sprintf(s,"{%d,%d}",m_column,m_parenVec.top()); putsNoTracking(s);
|
||||
if (exceededWidth()) {
|
||||
|
|
@ -442,7 +434,7 @@ void V3OutFile::putBreak () {
|
|||
}
|
||||
}
|
||||
|
||||
void V3OutFile::putsQuoted(const char* strg) {
|
||||
void V3OutFormatter::putsQuoted(const char* strg) {
|
||||
// Quote \ and " for use inside C programs
|
||||
// Don't use to quote a filename for #include - #include doesn't \ escape.
|
||||
putcNoTracking('"');
|
||||
|
|
@ -452,14 +444,14 @@ void V3OutFile::putsQuoted(const char* strg) {
|
|||
}
|
||||
putcNoTracking('"');
|
||||
}
|
||||
void V3OutFile::putsNoTracking (const char *strg) {
|
||||
void V3OutFormatter::putsNoTracking (const char *strg) {
|
||||
// Don't track {}'s, probably because it's a $display format string
|
||||
for (const char* cp=strg; *cp; cp++) {
|
||||
putcNoTracking (*cp);
|
||||
}
|
||||
}
|
||||
|
||||
void V3OutFile::putcNoTracking (char chr) {
|
||||
void V3OutFormatter::putcNoTracking (char chr) {
|
||||
switch (chr) {
|
||||
case '\n':
|
||||
m_lineno++;
|
||||
|
|
@ -480,10 +472,10 @@ void V3OutFile::putcNoTracking (char chr) {
|
|||
m_nobreak=false;
|
||||
break;
|
||||
}
|
||||
fputc (chr, m_fp);
|
||||
putcOutput (chr);
|
||||
}
|
||||
|
||||
void V3OutFile::putAlign (bool/*AlignClass*/ isStatic, int align, int size, const char* prefix) {
|
||||
void V3OutFormatter::putAlign (bool/*AlignClass*/ isStatic, int align, int size, const char* prefix) {
|
||||
if (size==0) size=align;
|
||||
int alignSize = size; if (alignSize>8) alignSize=8;
|
||||
int& alignr = isStatic ? m_declSAlign : m_declNSAlign;
|
||||
|
|
@ -504,7 +496,7 @@ void V3OutFile::putAlign (bool/*AlignClass*/ isStatic, int align, int size, cons
|
|||
//----------------------------------------------------------------------
|
||||
// Simple wrappers
|
||||
|
||||
void V3OutFile::printf (const char *fmt...) {
|
||||
void V3OutFormatter::printf (const char *fmt...) {
|
||||
char sbuff[5000];
|
||||
va_list ap;
|
||||
va_start(ap,fmt);
|
||||
|
|
@ -513,3 +505,17 @@ void V3OutFile::printf (const char *fmt...) {
|
|||
this->puts(sbuff);
|
||||
}
|
||||
|
||||
//######################################################################
|
||||
// V3OutFormatter: A class for printing to a file, with automatic indentation of C++ code.
|
||||
|
||||
V3OutFile::V3OutFile(const string& filename)
|
||||
: V3OutFormatter(filename, false) {
|
||||
if ((m_fp = V3File::new_fopen_w(filename.c_str())) == NULL) {
|
||||
v3fatal("Cannot write "<<filename);
|
||||
}
|
||||
}
|
||||
|
||||
V3OutFile::~V3OutFile() {
|
||||
if (m_fp) fclose(m_fp);
|
||||
m_fp = NULL;
|
||||
}
|
||||
|
|
|
|||
28
src/V3File.h
28
src/V3File.h
|
|
@ -72,9 +72,9 @@ public:
|
|||
};
|
||||
|
||||
//============================================================================
|
||||
// V3OutFile: A class for printing to a file, with automatic indentation of C++ code.
|
||||
// V3OutFormatter: A class for automatic indentation of C++ or Verilog code.
|
||||
|
||||
class V3OutFile {
|
||||
class V3OutFormatter {
|
||||
// TYPES
|
||||
enum MiscConsts {
|
||||
INDBLK = 4, // Indentation per block level
|
||||
|
|
@ -87,8 +87,8 @@ public:
|
|||
|
||||
private:
|
||||
// MEMBERS
|
||||
FILE* m_fp;
|
||||
string m_filename;
|
||||
bool m_verilog; // Indenting Verilog code
|
||||
int m_lineno;
|
||||
int m_column;
|
||||
int m_nobreak; // Basic operator or begin paren, don't break next
|
||||
|
|
@ -101,10 +101,11 @@ private:
|
|||
|
||||
int endLevels(const char* strg);
|
||||
static const char* indentStr(int levels);
|
||||
void putcNoTracking(char chr);
|
||||
|
||||
public:
|
||||
V3OutFile(const string& filename);
|
||||
~V3OutFile();
|
||||
V3OutFormatter(const string& filename, bool verilog);
|
||||
virtual ~V3OutFormatter() {}
|
||||
// ACCESSORS
|
||||
int column() const { return m_column; }
|
||||
// METHODS
|
||||
|
|
@ -132,8 +133,23 @@ public:
|
|||
void blockDec() { if (!m_parenVec.empty()) m_parenVec.pop(); }
|
||||
// STATIC METHODS
|
||||
static const string indentSpaces(int levels);
|
||||
|
||||
// CALLBACKS - MUST OVERRIDE
|
||||
virtual void putcOutput(char chr) = 0;
|
||||
};
|
||||
|
||||
//============================================================================
|
||||
// V3OutFile: A class for printing to a file, with automatic indentation of C++ code.
|
||||
|
||||
class V3OutFile : public V3OutFormatter {
|
||||
// MEMBERS
|
||||
FILE* m_fp;
|
||||
public:
|
||||
V3OutFile(const string& filename);
|
||||
virtual ~V3OutFile();
|
||||
private:
|
||||
void putcNoTracking(char chr);
|
||||
// CALLBACKS
|
||||
virtual void putcOutput(char chr) { fputc(chr, m_fp); }
|
||||
};
|
||||
|
||||
#endif // Guard
|
||||
|
|
|
|||
Loading…
Reference in New Issue