Commit 47f3c595 authored by mk's avatar mk

some changes

parent 85c46d2a
// -*- C++ -*-
//*************************************************************************
//
// Copyright 2000-2013 by Wilson Snyder. This program is free software;
// you can redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License Version 2.0.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
//*************************************************************************
/// \file
/// \brief Verilog::Preproc: Error handling implementation
///
/// Authors: Wilson Snyder
///
/// Code available from: http://www.veripool.org/verilog-perl
///
//*************************************************************************
#include <cstdio>
#include <cstdlib>
#include "VFileLine.h"
int VFileLine::s_numErrors = 0; ///< Number of errors detected
//============================================================================
void VFileLine::init(const string& filename, int lineno) {
m_filename = filename;
m_lineno = lineno;
}
const string VFileLine::filebasename () const {
string name = filename();
string::size_type slash;
if ((slash = name.rfind("/")) != string::npos) {
name.erase(0,slash+1);
}
return name;
}
void VFileLine::fatal(const string& msg) {
error(msg);
error("Fatal Error detected");
abort();
}
void VFileLine::error(const string& msg) {
VFileLine::s_numErrors++;
if (msg[msg.length()-1] != '\n') {
fprintf (stderr, "%%Error: %s", msg.c_str());
} else {
fprintf (stderr, "%%Error: %s\n", msg.c_str()); // Append newline, as user omitted it.
}
}
const char* VFileLine::itoa(int i) {
static char buf[100];
sprintf(buf,"%d",i);
return buf;
}
string VFileLine::lineDirectiveStrg(int enterExit) const {
char numbuf[20]; sprintf(numbuf, "%d", lineno());
char levelbuf[20]; sprintf(levelbuf, "%d", enterExit);
return ((string)"// `line first "+numbuf+" \""+filename()+"\" "+levelbuf+"\n");
}
VFileLine* VFileLine::lineDirective(const char* textp, int& enterExitRef) {
// Handle `line directive
// Skip `line
while (*textp && isspace(*textp)) textp++;
while (*textp && !isspace(*textp)) textp++;
while (*textp && (isspace(*textp) || *textp=='"')) textp++;
// Grab linenumber
int lineno = this->lineno();
const char *ln = textp;
while (*textp && !isspace(*textp)) textp++;
if (isdigit(*ln)) {
lineno = atoi(ln);
}
while (*textp && (isspace(*textp) || *textp=='"')) textp++;
// Grab filename
string filename = this->filename();
const char* fn = textp;
while (*textp && !(isspace(*textp) || *textp=='"')) textp++;
if (textp != fn) {
string strfn = fn;
strfn = strfn.substr(0, textp-fn);
filename = strfn;
}
// Grab level
while (*textp && (isspace(*textp) || *textp=='"')) textp++;
if (isdigit(*textp)) enterExitRef = atoi(textp);
else enterExitRef = 0;
return create(filename,lineno);
}
//======================================================================
// Global scope
ostream& operator<<(ostream& os, VFileLine* flp) {
if (flp->filename()!="") {
os <<flp->filename()<<":"<<dec<<flp->lineno()<<": "<<hex;
}
return(os);
}
// -*- C++ -*-
//*************************************************************************
//
// Copyright 2000-2013 by Wilson Snyder. This program is free software;
// you can redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License Version 2.0.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
//*************************************************************************
/// \file
/// \brief Verilog::Preproc: Error handling
///
/// Authors: Wilson Snyder
///
/// Code available from: http://www.veripool.org/verilog-perl
///
//*************************************************************************
#ifndef _VFILELINE_H_
#define _VFILELINE_H_ 1
#include <string>
#include <iostream>
#include <sstream>
using namespace std;
//============================================================================
// VFileLine
/// User information and error reporting functions
////
/// Users can override this class to implement their own error handling
class VFileLine {
private:
int m_lineno; ///< Line number in file
string m_filename; ///< File name
static int s_numErrors; ///< Number of errors detected
protected:
VFileLine(int called_only_for_default) {init("",0);}
public:
// CONSTRUCTORS
/// Create a new fileline, for a new file and/or line number.
/// Member functions, so that if a user provides another class, a change in the
/// filename/linenumber will create a new element using the derived class.
virtual VFileLine* create(const string& filename, int lineno) = 0;
/// Create with same filename, new line number; just calls create(fn,ln)
virtual VFileLine* create(int lineno)
{
return create(filename(), lineno);
}
virtual void init(const string& filename, int lineno);
virtual ~VFileLine() {}
// ACCESSORS
int lineno () const { return m_lineno; } ///< Return line number
void linenoIncInPlace() { m_lineno++; } ///< Increment line IN PLACE; normally use create() instead
const string filename () const { return m_filename; } ///< Return filename
const string filebasename () const; ///< Filename with any directory stripped
string lineDirectiveStrg(int enter_exit_level) const;
// METHODS
virtual void fatal(const string& msg); ///< Report a fatal error at given location
virtual void error(const string& msg); ///< Report a error at given location
VFileLine* lineDirective(const char* textp, int& enterExitRef);
// STATIC METHODS
static int numErrors() {return s_numErrors;} ///< Return total errors detected
// Internal methods -- special use
static const char* itoa(int i); ///< Internal: Not reentrant! - for fatalSrc() only
};
ostream& operator<<(ostream& os, VFileLine* fileline);
/// Use this instead of fatal() to mention the source code line.
#define fatalSrc(msg) fatal((string)"Internal Error: "+__FILE__+":"+VFileLine::itoa(__LINE__)+": "+(msg))
template< class T> std::string cvtToStr (const T& t) {
ostringstream os; os<<t; return os.str();
}
class VerilogFileLine : public VFileLine
{
public:
VerilogFileLine(const string& file,int line):VFileLine(0)
{
init(file,line);
}
virtual VFileLine* create(const string& filename, int lineno)
{
VerilogFileLine* fnew=new VerilogFileLine(filename,lineno);
return fnew;
}
/// Create with same filename, new line number; just calls create(fn,ln)
virtual VFileLine* create(int lineno) { return create(filename(), lineno); }
};
#endif // Guard
#define yy_create_buffer VPreLex_create_buffer
#define yy_delete_buffer VPreLex_delete_buffer
#define yy_scan_buffer VPreLex_scan_buffer
#define yy_scan_string VPreLex_scan_string
#define yy_scan_bytes VPreLex_scan_bytes
#define yy_flex_debug VPreLex_flex_debug
#define yy_init_buffer VPreLex_init_buffer
#define yy_flush_buffer VPreLex_flush_buffer
#define yy_load_buffer_state VPreLex_load_buffer_state
#define yy_switch_to_buffer VPreLex_switch_to_buffer
#define yyin VPreLexin
#define yyleng VPreLexleng
#define yylex VPreLexlex
#define yyout VPreLexout
#define yyrestart VPreLexrestart
#define yytext VPreLextext
#line 19 "c:\\Boot\\doxygen\\src\\VPreLex.cpp"
/* A lexical scanner generated by flex */
/* Scanner skeleton version:
* $Header: /home/daffy/u0/vern/flex/RCS/flex.skl,v 2.91 96/09/10 16:58:48 vern Exp $
*/
#define FLEX_SCANNER
#define YY_FLEX_MAJOR_VERSION 2
#define YY_FLEX_MINOR_VERSION 5
#include <stdio.h>
/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */
#ifdef c_plusplus
#ifndef __cplusplus
#define __cplusplus
#endif
#endif
#ifdef __cplusplus
#include <stdlib.h>
#include <unistd.h>
/* Use prototypes in function declarations. */
#define YY_USE_PROTOS
/* The "const" storage-class-modifier is valid. */
#define YY_USE_CONST
#else /* ! __cplusplus */
#if __STDC__
#define YY_USE_PROTOS
#define YY_USE_CONST
#endif /* __STDC__ */
#endif /* ! __cplusplus */
#ifdef __TURBOC__
#pragma warn -rch
#pragma warn -use
#include <io.h>
#include <stdlib.h>
#define YY_USE_CONST
#define YY_USE_PROTOS
#endif
#ifdef YY_USE_CONST
#define yyconst const
#else
#define yyconst
#endif
#ifdef YY_USE_PROTOS
#define YY_PROTO(proto) proto
#else
#define YY_PROTO(proto) ()
#endif
/* Returned upon end-of-file. */
#define YY_NULL 0
/* Promotes a possibly negative, possibly signed char to an unsigned
* integer for use as an array index. If the signed char is negative,
* we want to instead treat it as an 8-bit unsigned char, hence the
* double cast.
*/
#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
/* Enter a start condition. This macro really ought to take a parameter,
* but we do it the disgusting crufty way forced on us by the ()-less
* definition of BEGIN.
*/
#define BEGIN yy_start = 1 + 2 *
/* Translate the current start state into a value that can be later handed
* to BEGIN to return to the state. The YYSTATE alias is for lex
* compatibility.
*/
#define YY_START ((yy_start - 1) / 2)
#define YYSTATE YY_START
/* Action number for EOF rule of a given start state. */
#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
/* Special action meaning "start processing a new file". */
#define YY_NEW_FILE yyrestart( yyin )
#define YY_END_OF_BUFFER_CHAR 0
/* Size of default input buffer. */
#define YY_BUF_SIZE 16384
typedef struct yy_buffer_state *YY_BUFFER_STATE;
extern int yyleng;
extern FILE *yyin, *yyout;
#define EOB_ACT_CONTINUE_SCAN 0
#define EOB_ACT_END_OF_FILE 1
#define EOB_ACT_LAST_MATCH 2
/* The funky do-while in the following #define is used to turn the definition
* int a single C statement (which needs a semi-colon terminator). This
* avoids problems with code like:
*
* if ( condition_holds )
* yyless( 5 );
* else
* do_something_else();
*
* Prior to using the do-while the compiler would get upset at the
* "else" because it interpreted the "if" statement as being all
* done when it reached the ';' after the yyless() call.
*/
/* Return all but the first 'n' matched characters back to the input stream. */
#define yyless(n) \
do \
{ \
/* Undo effects of setting up yytext. */ \
*yy_cp = yy_hold_char; \
YY_RESTORE_YY_MORE_OFFSET \
yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \
YY_DO_BEFORE_ACTION; /* set up yytext again */ \
} \
while ( 0 )
#define unput(c) yyunput( c, yytext_ptr )
/* The following is because we cannot portably get our hands on size_t
* (without autoconf's help, which isn't available because we want
* flex-generated scanners to compile on their own).
*/
typedef unsigned int yy_size_t;
struct yy_buffer_state
{
FILE *yy_input_file;
char *yy_ch_buf; /* input buffer */
char *yy_buf_pos; /* current position in input buffer */
/* Size of input buffer in bytes, not including room for EOB
* characters.
*/
yy_size_t yy_buf_size;
/* Number of characters read into yy_ch_buf, not including EOB
* characters.
*/
int yy_n_chars;
/* Whether we "own" the buffer - i.e., we know we created it,
* and can realloc() it to grow it, and should free() it to
* delete it.
*/
int yy_is_our_buffer;
/* Whether this is an "interactive" input source; if so, and
* if we're using stdio for input, then we want to use getc()
* instead of fread(), to make sure we stop fetching input after
* each newline.
*/
int yy_is_interactive;
/* Whether we're considered to be at the beginning of a line.
* If so, '^' rules will be active on the next match, otherwise
* not.
*/
int yy_at_bol;
/* Whether to try to fill the input buffer when we reach the
* end of it.
*/
int yy_fill_buffer;
int yy_buffer_status;
#define YY_BUFFER_NEW 0
#define YY_BUFFER_NORMAL 1
/* When an EOF's been seen but there's still some text to process
* then we mark the buffer as YY_EOF_PENDING, to indicate that we
* shouldn't try reading from the input source any more. We might
* still have a bunch of tokens to match, though, because of
* possible backing-up.
*
* When we actually see the EOF, we change the status to "new"
* (via yyrestart()), so that the user can continue scanning by
* just pointing yyin at a new input file.
*/
#define YY_BUFFER_EOF_PENDING 2
};
static YY_BUFFER_STATE yy_current_buffer = 0;
/* We provide macros for accessing buffer states in case in the
* future we want to put the buffer states in a more general
* "scanner state".
*/
#define YY_CURRENT_BUFFER yy_current_buffer
/* yy_hold_char holds the character lost when yytext is formed. */
static char yy_hold_char;
static int yy_n_chars; /* number of characters read into yy_ch_buf */
int yyleng;
/* Points to current character in buffer. */
static char *yy_c_buf_p = (char *) 0;
static int yy_init = 1; /* whether we need to initialize */
static int yy_start = 0; /* start state number */
/* Flag which is used to allow yywrap()'s to do buffer switches
* instead of setting up a fresh yyin. A bit of a hack ...
*/
static int yy_did_buffer_switch_on_eof;
void yyrestart YY_PROTO(( FILE *input_file ));
void yy_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer ));
void yy_load_buffer_state YY_PROTO(( void ));
YY_BUFFER_STATE yy_create_buffer YY_PROTO(( FILE *file, int size ));
void yy_delete_buffer YY_PROTO(( YY_BUFFER_STATE b ));
void yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, FILE *file ));
void yy_flush_buffer YY_PROTO(( YY_BUFFER_STATE b ));
#define YY_FLUSH_BUFFER yy_flush_buffer( yy_current_buffer )
YY_BUFFER_STATE yy_scan_buffer YY_PROTO(( char *base, yy_size_t size ));
YY_BUFFER_STATE yy_scan_string YY_PROTO(( yyconst char *yy_str ));
YY_BUFFER_STATE yy_scan_bytes YY_PROTO(( yyconst char *bytes, int len ));
static void *yy_flex_alloc YY_PROTO(( yy_size_t ));
static void *yy_flex_realloc YY_PROTO(( void *, yy_size_t ));
static void yy_flex_free YY_PROTO(( void * ));
#define yy_new_buffer yy_create_buffer
#define yy_set_interactive(is_interactive) \
{ \
if ( ! yy_current_buffer ) \
yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
yy_current_buffer->yy_is_interactive = is_interactive; \
}
#define yy_set_bol(at_bol) \
{ \
if ( ! yy_current_buffer ) \
yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
yy_current_buffer->yy_at_bol = at_bol; \
}
#define YY_AT_BOL() (yy_current_buffer->yy_at_bol)
#define yywrap() 1
#define YY_SKIP_YYWRAP
typedef unsigned char YY_CHAR;
FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;
typedef int yy_state_type;
extern char *yytext;
#define yytext_ptr yytext
static yy_state_type yy_get_previous_state YY_PROTO(( void ));
static yy_state_type yy_try_NUL_trans YY_PROTO(( yy_state_type current_state ));
static int yy_get_next_buffer YY_PROTO(( void ));
static void yy_fatal_error YY_PROTO(( yyconst char msg[] ));
/* Done after the current pattern has been matched and before the
* corresponding action - sets up yytext.
*/
#define YY_DO_BEFORE_ACTION \
yytext_ptr = yy_bp; \
yytext_ptr -= yy_more_len; \
yyleng = (int) (yy_cp - yytext_ptr); \
yy_hold_char = *yy_cp; \
*yy_cp = '\0'; \
yy_c_buf_p = yy_cp;
#define YY_NUM_RULES 100
#define YY_END_OF_BUFFER 101
static yyconst long int yy_accept[492] =
{ 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 101, 98, 96, 92, 95, 97, 14, 98,
93, 98, 98, 96, 95, 98, 89, 87, 89, 89,
88, 17, 15, 17, 20, 16, 99, 33, 32, 33,
31, 46, 39, 48, 38, 41, 34, 35, 48, 48,
44, 48, 45, 46, 55, 53, 57, 52, 57, 57,
57, 62, 60, 62, 62, 61, 62, 77, 66, 78,
65, 67, 72, 73, 78, 74, 78, 70, 71, 78,
28, 27, 28, 30, 99, 25, 24, 25, 25, 83,
81, 83, 83, 82, 96, 92, 0, 85, 84, 93,
0, 93, 21, 90, 0, 90, 90, 90, 90, 90,
90, 96, 0, 0, 0, 90, 87, 0, 86, 88,
15, 0, 16, 19, 18, 19, 32, 0, 46, 39,
0, 36, 37, 47, 40, 0, 43, 0, 55, 53,
0, 49, 51, 56, 54, 0, 60, 0, 58, 61,
59, 0, 77, 66, 0, 63, 64, 69, 75, 0,
27, 0, 29, 24, 0, 0, 81, 0, 0, 0,
82, 0, 0, 0, 0, 84, 84, 0, 84, 84,
84, 94, 93, 90, 0, 90, 0, 90, 90, 90,
90, 90, 90, 90, 90, 90, 0, 90, 0, 37,
0, 51, 51, 64, 75, 0, 75, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 84, 84, 84, 93, 91, 22, 90,
90, 90, 90, 90, 90, 90, 90, 90, 90, 90,
0, 90, 42, 50, 0, 76, 68, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
84, 84, 84, 90, 90, 90, 3, 90, 90, 90,
90, 90, 90, 90, 90, 0, 90, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 84, 84, 84, 84, 90, 90, 90, 4, 5,
13, 6, 90, 90, 90, 9, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 84, 84, 84, 84, 90,
90, 2, 7, 90, 90, 90, 0, 0, 1, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 84, 0, 84, 84,
90, 90, 8, 90, 90, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 84, 0,
84, 84, 11, 12, 90, 90, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 84, 0, 84,
23, 90, 0, 0, 0, 0, 0, 0, 0, 84,
0, 90, 0, 0, 0, 0, 84, 0, 10, 0,
0, 0, 0, 84, 0, 26, 0, 0, 0, 84,
0, 0, 0, 0, 84, 0, 0, 0, 0, 84,
0, 0, 0, 0, 84, 0, 0, 0, 0, 84,
0, 0, 0, 0, 84, 0, 0, 0, 0, 84,
0, 0, 80, 0, 79, 79, 0, 0, 80, 80,
80, 0, 0, 79, 79, 79, 79, 79, 80, 79,
0
} ;
static yyconst int yy_ec[256] =
{ 0,
1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
1, 2, 4, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 5, 1, 1, 1, 1,
1, 2, 1, 6, 1, 7, 1, 1, 1, 8,
9, 10, 1, 11, 1, 1, 12, 13, 13, 13,
13, 13, 13, 13, 13, 13, 13, 1, 1, 1,
1, 14, 1, 1, 15, 16, 17, 17, 18, 19,
20, 21, 22, 17, 17, 23, 24, 25, 26, 27,
17, 28, 29, 30, 17, 17, 17, 17, 31, 17,
32, 33, 34, 1, 35, 36, 37, 16, 38, 39,
40, 41, 20, 21, 42, 17, 17, 43, 24, 44,
45, 46, 17, 47, 48, 49, 50, 17, 17, 17,
31, 17, 32, 1, 34, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1
} ;
static yyconst int yy_meta[51] =
{ 0,
1, 2, 3, 4, 1, 5, 6, 7, 7, 8,
9, 8, 10, 1, 11, 11, 11, 11, 11, 11,
11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
11, 7, 12, 7, 11, 13, 11, 11, 11, 11,
11, 11, 11, 11, 11, 11, 11, 11, 11, 11
} ;
static yyconst long int yy_base[530] =
{ 0,
0, 36, 72, 108, 144, 180, 12, 14, 214, 248,
52, 55, 284, 320, 354, 388, 21, 88, 25, 27,
424, 460, 1374, 1375, 1371, 1375, 23, 1375, 1375, 9,
1336, 0, 491, 91, 94, 536, 1375, 1375, 48, 1359,
0, 1375, 1375, 86, 1375, 0, 96, 1375, 1375, 120,
1375, 0, 1375, 122, 0, 1375, 1375, 1375, 1375, 91,
1375, 125, 1375, 101, 0, 1375, 128, 0, 1375, 123,
133, 1375, 1375, 135, 1358, 0, 156, 0, 1375, 158,
0, 1375, 1375, 1375, 1375, 1375, 153, 1375, 1375, 137,
1375, 1375, 163, 1375, 0, 1375, 1375, 165, 1329, 1375,
1375, 168, 163, 0, 1366, 1375, 192, 585, 632, 1331,
1330, 1329, 1375, 1328, 1327, 162, 163, 157, 166, 185,
189, 204, 207, 1309, 225, 194, 1375, 231, 1375, 0,
1375, 234, 0, 1375, 1375, 238, 1375, 241, 0, 1375,
259, 1375, 0, 1375, 1375, 261, 1375, 1303, 0, 1375,
263, 1375, 1293, 1375, 1375, 265, 1375, 267, 1375, 0,
1375, 269, 0, 1375, 271, 1375, 0, 1375, 1265, 1264,
1375, 273, 1375, 1375, 275, 1255, 1375, 296, 679, 726,
0, 0, 1272, 255, 1262, 1288, 773, 820, 235, 308,
302, 1375, 1255, 1244, 1243, 1231, 1260, 278, 30, 267,
268, 272, 299, 273, 301, 274, 1212, 303, 337, 0,
1247, 1208, 341, 0, 1204, 1203, 1200, 1227, 1193, 0,
1207, 314, 1188, 0, 1180, 320, 1168, 1182, 142, 324,
1173, 322, 1165, 366, 368, 398, 1159, 1375, 1375, 349,
353, 213, 337, 342, 359, 340, 367, 51, 365, 371,
1147, 372, 1375, 1375, 406, 1375, 1375, 1144, 1173, 400,
415, 1171, 402, 429, 433, 1166, 450, 1169, 404, 454,
478, 211, 480, 454, 453, 407, 1130, 377, 408, 455,
409, 412, 451, 445, 447, 1122, 503, 1111, 481, 1137,
483, 492, 1120, 491, 478, 1112, 489, 1114, 496, 1113,
517, 515, 544, 545, 540, 468, 534, 475, 1096, 1095,
1073, 1072, 510, 514, 518, 411, 553, 556, 1062, 535,
1082, 546, 1084, 544, 1070, 550, 1072, 579, 548, 551,
570, 560, 1068, 567, 1068, 593, 600, 594, 598, 570,
572, 1050, 1049, 581, 575, 582, 616, 625, 1375, 637,
1035, 599, 615, 596, 614, 641, 620, 617, 630, 647,
880, 624, 654, 645, 626, 644, 662, 669, 659, 664,
640, 650, 869, 651, 661, 685, 855, 696, 813, 666,
701, 812, 673, 676, 681, 691, 770, 686, 715, 689,
703, 716, 748, 686, 701, 710, 671, 707, 713, 702,
720, 720, 717, 741, 723, 728, 738, 766, 749, 761,
643, 730, 618, 754, 750, 767, 758, 764, 763, 789,
769, 769, 610, 771, 772, 770, 791, 778, 531, 483,
788, 794, 802, 827, 805, 1375, 809, 811, 814, 823,
822, 825, 826, 816, 826, 823, 825, 828, 843, 860,
849, 851, 853, 477, 170, 411, 381, 346, 847, 872,
854, 856, 858, 866, 875, 867, 862, 865, 869, 877,
878, 910, 781, 911, 900, 920, 921, 339, 301, 924,
925, 928, 152, 49, 931, 932, 19, 935, 1375, 1375,
1375, 939, 952, 965, 978, 991, 1004, 1017, 1030, 1043,
1056, 1069, 1077, 1090, 1099, 1102, 1104, 1115, 1128, 1141,
1154, 1167, 1171, 1182, 1189, 1201, 1205, 1216, 1224, 1237,
1250, 1263, 1276, 1284, 1297, 1310, 1323, 1336, 1349
} ;
static yyconst long int yy_def[530] =
{ 0,
492, 492, 493, 493, 494, 494, 495, 495, 496, 496,
497, 497, 498, 498, 499, 499, 500, 500, 501, 501,
502, 502, 491, 491, 491, 491, 491, 491, 491, 491,
503, 504, 505, 491, 491, 505, 491, 491, 491, 491,
506, 491, 491, 491, 491, 507, 508, 491, 491, 491,
491, 509, 491, 491, 509, 491, 491, 491, 491, 491,
491, 510, 491, 509, 511, 491, 491, 511, 491, 491,
512, 491, 491, 491, 491, 513, 491, 514, 491, 491,
514, 491, 491, 491, 491, 491, 491, 491, 491, 515,
491, 491, 491, 491, 516, 491, 491, 491, 491, 491,
491, 491, 491, 517, 491, 491, 491, 491, 518, 503,
491, 504, 491, 519, 520, 519, 519, 519, 519, 519,
519, 491, 491, 491, 491, 519, 491, 491, 491, 506,
491, 491, 507, 491, 491, 491, 491, 491, 509, 491,
491, 491, 521, 491, 491, 491, 491, 491, 511, 491,
491, 491, 522, 491, 491, 491, 491, 491, 491, 513,
491, 491, 514, 491, 491, 491, 523, 491, 524, 525,
491, 491, 491, 491, 491, 491, 491, 491, 491, 491,
517, 108, 491, 491, 491, 518, 518, 491, 518, 518,
518, 491, 504, 519, 491, 520, 491, 519, 519, 519,
519, 519, 519, 519, 519, 519, 491, 519, 491, 521,
491, 522, 522, 523, 524, 491, 525, 491, 491, 179,
491, 491, 491, 180, 491, 491, 491, 491, 491, 491,
491, 491, 491, 518, 518, 518, 504, 491, 491, 519,
519, 519, 519, 519, 519, 519, 519, 519, 519, 519,
491, 519, 491, 491, 491, 491, 491, 491, 491, 491,
491, 491, 491, 491, 491, 491, 491, 491, 491, 491,
518, 518, 518, 519, 519, 519, 519, 519, 519, 519,
519, 519, 519, 519, 519, 491, 519, 491, 491, 491,
491, 491, 491, 491, 491, 491, 491, 491, 491, 491,
491, 518, 518, 518, 518, 519, 519, 519, 519, 519,
519, 519, 519, 519, 519, 519, 491, 526, 491, 491,
491, 491, 491, 491, 491, 491, 491, 491, 491, 491,
491, 491, 491, 491, 491, 518, 518, 518, 518, 519,
519, 519, 519, 519, 519, 519, 526, 526, 491, 526,
491, 491, 491, 491, 491, 491, 491, 491, 491, 491,
491, 491, 491, 491, 491, 491, 518, 491, 518, 518,
519, 519, 519, 519, 519, 526, 491, 491, 491, 491,
491, 491, 491, 491, 491, 491, 491, 491, 518, 491,
518, 518, 519, 519, 519, 519, 491, 491, 491, 491,
491, 491, 491, 491, 491, 491, 491, 518, 491, 518,
519, 519, 491, 491, 491, 491, 491, 491, 491, 518,
491, 519, 491, 491, 491, 491, 518, 491, 519, 491,
491, 491, 491, 518, 491, 491, 491, 491, 491, 518,
491, 491, 491, 491, 518, 491, 491, 491, 491, 518,
491, 491, 491, 491, 518, 491, 491, 491, 491, 518,
491, 491, 491, 491, 518, 491, 491, 491, 491, 518,
491, 491, 527, 491, 528, 529, 491, 491, 527, 527,
527, 491, 491, 528, 528, 529, 529, 529, 491, 491,
0, 491, 491, 491, 491, 491, 491, 491, 491, 491,
491, 491, 491, 491, 491, 491, 491, 491, 491, 491,
491, 491, 491, 491, 491, 491, 491, 491, 491, 491,
491, 491, 491, 491, 491, 491, 491, 491, 491
} ;
static yyconst long int yy_nxt[1426] =
{ 0,
24, 25, 26, 27, 28, 29, 24, 24, 24, 24,
24, 30, 24, 24, 49, 50, 49, 50, 108, 51,
109, 51, 491, 92, 93, 106, 107, 97, 98, 97,
98, 24, 32, 24, 94, 33, 24, 34, 26, 35,
28, 29, 24, 24, 24, 24, 24, 30, 24, 24,
127, 128, 491, 95, 66, 67, 68, 66, 67, 68,
99, 69, 99, 70, 69, 195, 70, 24, 32, 24,
242, 36, 37, 37, 38, 39, 37, 37, 37, 37,
37, 40, 37, 37, 71, 37, 195, 71, 131, 132,
92, 93, 122, 283, 123, 123, 106, 125, 135, 136,
142, 94, 143, 37, 37, 37, 147, 37, 37, 37,
38, 39, 37, 37, 37, 37, 37, 40, 37, 37,
95, 37, 137, 138, 140, 141, 124, 145, 146, 124,
150, 151, 152, 148, 153, 155, 156, 157, 158, 37,
37, 37, 168, 37, 42, 42, 43, 44, 42, 45,
42, 42, 42, 42, 42, 42, 266, 42, 161, 162,
164, 165, 166, 490, 167, 171, 172, 174, 175, 170,
177, 178, 179, 491, 180, 42, 47, 42, 266, 42,
42, 42, 43, 44, 42, 45, 42, 42, 42, 42,
42, 42, 195, 42, 106, 107, 198, 195, 195, 200,
201, 195, 199, 202, 460, 122, 203, 123, 123, 204,
123, 42, 47, 42, 491, 42, 53, 54, 55, 56,
195, 57, 58, 59, 195, 60, 123, 106, 125, 195,
303, 205, 206, 127, 128, 208, 131, 132, 491, 124,
135, 209, 124, 137, 138, 61, 62, 63, 195, 64,
53, 54, 55, 56, 276, 57, 58, 59, 234, 60,
124, 140, 141, 145, 146, 150, 151, 155, 156, 157,
158, 161, 162, 164, 165, 171, 172, 174, 175, 61,
62, 63, 229, 64, 72, 72, 73, 74, 72, 72,
72, 72, 72, 75, 72, 72, 240, 72, 177, 178,
241, 229, 195, 195, 491, 491, 244, 195, 195, 195,
248, 491, 250, 195, 243, 72, 77, 72, 245, 72,
72, 72, 73, 74, 72, 72, 72, 72, 72, 75,
72, 72, 236, 72, 195, 235, 195, 246, 195, 135,
209, 260, 247, 254, 255, 249, 252, 263, 267, 269,
489, 72, 77, 72, 235, 72, 79, 80, 81, 82,
260, 83, 84, 85, 86, 87, 263, 267, 269, 491,
274, 491, 195, 213, 275, 195, 277, 195, 278, 281,
463, 271, 272, 279, 195, 88, 85, 89, 195, 90,
79, 80, 81, 82, 195, 83, 84, 85, 86, 87,
195, 491, 195, 280, 272, 282, 195, 195, 254, 255,
285, 287, 195, 284, 290, 462, 293, 309, 300, 88,
85, 89, 273, 90, 100, 100, 101, 102, 100, 100,
100, 100, 100, 100, 100, 103, 290, 100, 293, 291,
300, 273, 195, 195, 195, 461, 195, 195, 310, 312,
308, 313, 346, 294, 295, 100, 100, 100, 291, 100,
100, 100, 101, 102, 100, 100, 100, 100, 100, 100,
100, 103, 294, 100, 295, 297, 306, 307, 301, 298,
195, 491, 195, 491, 315, 340, 195, 316, 195, 195,
195, 100, 100, 100, 297, 100, 113, 301, 298, 302,
314, 311, 320, 195, 318, 304, 318, 328, 322, 305,
195, 459, 323, 324, 342, 330, 326, 332, 491, 302,
327, 436, 320, 115, 304, 116, 328, 322, 305, 117,
118, 323, 119, 324, 330, 326, 120, 332, 195, 327,
121, 113, 334, 491, 336, 195, 335, 491, 491, 195,
343, 341, 344, 195, 318, 345, 318, 348, 349, 350,
339, 334, 328, 336, 352, 335, 195, 337, 115, 195,
116, 338, 354, 356, 117, 118, 358, 119, 126, 361,
360, 120, 360, 352, 328, 121, 182, 362, 182, 363,
338, 354, 356, 365, 367, 358, 368, 491, 361, 183,
378, 491, 378, 491, 371, 195, 372, 195, 363, 362,
195, 184, 365, 185, 336, 370, 195, 195, 349, 376,
373, 183, 369, 374, 379, 375, 348, 349, 350, 352,
184, 380, 185, 187, 356, 188, 336, 370, 348, 349,
350, 369, 381, 379, 381, 382, 189, 383, 360, 430,
360, 352, 386, 380, 387, 368, 356, 368, 190, 363,
191, 388, 491, 367, 382, 368, 423, 491, 189, 383,
368, 386, 368, 387, 393, 195, 384, 190, 195, 191,
220, 363, 220, 388, 394, 195, 195, 349, 376, 391,
395, 389, 392, 221, 400, 384, 195, 378, 390, 378,
396, 403, 381, 404, 381, 222, 491, 223, 413, 328,
389, 392, 405, 400, 407, 221, 409, 390, 491, 491,
403, 195, 404, 415, 222, 398, 223, 224, 328, 224,
401, 336, 405, 407, 414, 409, 195, 410, 417, 411,
225, 352, 408, 415, 398, 195, 412, 416, 356, 401,
336, 328, 226, 414, 227, 418, 363, 410, 417, 419,
352, 408, 225, 421, 491, 195, 416, 356, 424, 491,
328, 226, 422, 227, 187, 363, 188, 418, 352, 419,
420, 425, 480, 195, 481, 421, 356, 189, 426, 336,
424, 363, 491, 428, 491, 431, 432, 352, 433, 190,
406, 191, 420, 425, 195, 356, 435, 426, 336, 189,
363, 429, 428, 427, 431, 432, 437, 433, 190, 434,
191, 188, 438, 188, 439, 435, 491, 441, 444, 491,
491, 442, 427, 443, 231, 437, 446, 445, 434, 447,
448, 438, 402, 399, 439, 449, 232, 441, 233, 440,
444, 442, 451, 443, 452, 450, 231, 453, 446, 445,
454, 447, 448, 491, 449, 232, 456, 233, 457, 440,
458, 451, 464, 452, 450, 491, 453, 455, 491, 466,
491, 467, 454, 468, 469, 471, 472, 474, 456, 473,
457, 464, 458, 470, 397, 475, 476, 465, 466, 455,
467, 485, 468, 486, 195, 472, 469, 471, 473, 474,
385, 477, 482, 477, 482, 470, 465, 475, 476, 478,
483, 488, 477, 486, 477, 480, 480, 481, 481, 482,
478, 482, 485, 488, 486, 486, 488, 483, 486, 31,
31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
31, 31, 41, 41, 41, 41, 41, 41, 41, 41,
41, 41, 41, 41, 41, 46, 46, 46, 46, 46,
46, 46, 46, 46, 46, 46, 46, 46, 48, 48,
48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
48, 52, 52, 52, 52, 52, 52, 52, 52, 52,
52, 52, 52, 52, 65, 65, 65, 65, 65, 65,
65, 65, 65, 65, 65, 65, 65, 76, 76, 76,
76, 76, 76, 76, 76, 76, 76, 76, 76, 76,
78, 78, 78, 78, 78, 78, 78, 78, 78, 78,
78, 78, 78, 91, 91, 91, 91, 91, 91, 91,
91, 91, 91, 91, 91, 91, 96, 96, 96, 96,
96, 96, 96, 96, 96, 96, 96, 96, 96, 104,
104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
104, 104, 110, 377, 195, 195, 110, 110, 366, 110,
112, 364, 359, 357, 112, 112, 112, 112, 112, 112,
112, 112, 112, 114, 355, 353, 351, 195, 195, 114,
114, 130, 130, 133, 133, 134, 134, 134, 134, 134,
134, 134, 134, 134, 134, 134, 134, 134, 139, 139,
195, 195, 333, 139, 331, 329, 139, 139, 139, 325,
139, 144, 144, 144, 144, 144, 144, 144, 144, 144,
144, 144, 144, 144, 149, 149, 321, 319, 149, 149,
149, 317, 149, 149, 149, 195, 149, 154, 154, 154,
154, 154, 154, 154, 154, 154, 154, 154, 154, 154,
160, 160, 163, 163, 299, 296, 292, 163, 289, 288,
286, 163, 163, 169, 237, 270, 268, 265, 264, 169,
169, 173, 173, 262, 173, 173, 173, 173, 173, 173,
173, 173, 173, 173, 181, 181, 186, 186, 261, 186,
186, 186, 186, 186, 186, 186, 186, 186, 186, 194,
259, 258, 257, 194, 194, 216, 194, 196, 256, 216,
213, 196, 196, 196, 196, 196, 196, 196, 196, 196,
210, 210, 253, 251, 210, 210, 210, 210, 210, 210,
210, 210, 210, 212, 212, 239, 195, 212, 212, 212,
212, 212, 212, 212, 212, 212, 214, 214, 238, 195,
214, 214, 214, 214, 214, 214, 214, 214, 214, 215,
237, 491, 230, 215, 215, 228, 215, 217, 219, 218,
216, 217, 217, 217, 217, 217, 217, 217, 217, 217,
347, 347, 347, 347, 347, 347, 347, 347, 347, 347,
347, 347, 347, 479, 479, 213, 479, 479, 479, 479,
479, 479, 479, 479, 479, 479, 484, 484, 211, 484,
484, 484, 484, 484, 484, 484, 484, 484, 484, 487,
487, 207, 487, 487, 487, 487, 487, 487, 487, 487,
487, 487, 197, 195, 193, 192, 111, 105, 176, 159,
129, 111, 105, 491, 23, 491, 491, 491, 491, 491,
491, 491, 491, 491, 491, 491, 491, 491, 491, 491,
491, 491, 491, 491, 491, 491, 491, 491, 491, 491,
491, 491, 491, 491, 491, 491, 491, 491, 491, 491,
491, 491, 491, 491, 491, 491, 491, 491, 491, 491,
491, 491, 491, 491, 491
} ;
static yyconst long int yy_chk[1426] =
{ 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 7, 7, 8, 8, 30, 7,
30, 8, 487, 17, 17, 27, 27, 19, 19, 20,
20, 1, 1, 1, 17, 1, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
39, 39, 484, 17, 11, 11, 11, 12, 12, 12,
19, 11, 20, 11, 12, 199, 12, 2, 2, 2,
199, 2, 3, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 11, 3, 248, 12, 44, 44,
18, 18, 34, 248, 34, 35, 35, 35, 47, 47,
60, 18, 60, 3, 3, 3, 64, 3, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
18, 4, 50, 50, 54, 54, 34, 62, 62, 35,
67, 67, 70, 64, 70, 71, 71, 74, 74, 4,
4, 4, 90, 4, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 229, 5, 77, 77,
80, 80, 87, 483, 87, 93, 93, 98, 98, 90,
102, 102, 103, 455, 103, 5, 5, 5, 229, 5,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 118, 6, 107, 107, 116, 116, 117, 118,
118, 119, 117, 118, 455, 122, 119, 122, 123, 119,
123, 6, 6, 6, 272, 6, 9, 9, 9, 9,
120, 9, 9, 9, 121, 9, 125, 125, 125, 126,
272, 120, 121, 128, 128, 126, 132, 132, 189, 122,
136, 136, 123, 138, 138, 9, 9, 9, 242, 9,
10, 10, 10, 10, 242, 10, 10, 10, 189, 10,
125, 141, 141, 146, 146, 151, 151, 156, 156, 158,
158, 162, 162, 165, 165, 172, 172, 175, 175, 10,
10, 10, 184, 10, 13, 13, 13, 13, 13, 13,
13, 13, 13, 13, 13, 13, 198, 13, 178, 178,
198, 184, 200, 201, 479, 191, 201, 202, 204, 206,
204, 190, 206, 198, 200, 13, 13, 13, 202, 13,
14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
14, 14, 191, 14, 203, 190, 205, 203, 208, 209,
209, 222, 203, 213, 213, 205, 208, 226, 230, 232,
478, 14, 14, 14, 190, 14, 15, 15, 15, 15,
222, 15, 15, 15, 15, 15, 226, 230, 232, 234,
240, 235, 243, 213, 241, 246, 243, 244, 243, 246,
458, 234, 235, 244, 240, 15, 15, 15, 241, 15,
16, 16, 16, 16, 245, 16, 16, 16, 16, 16,
249, 236, 247, 245, 235, 247, 250, 252, 255, 255,
250, 252, 278, 249, 260, 457, 263, 278, 269, 16,
16, 16, 236, 16, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 260, 21, 263, 261,
269, 236, 276, 279, 281, 456, 316, 282, 279, 281,
276, 282, 316, 264, 265, 21, 21, 21, 261, 21,
22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
22, 22, 264, 22, 265, 267, 274, 275, 270, 267,
284, 271, 285, 273, 284, 306, 283, 285, 275, 274,
280, 22, 22, 22, 267, 22, 33, 270, 267, 271,
283, 280, 289, 306, 287, 273, 287, 295, 291, 273,
308, 454, 291, 292, 308, 297, 294, 299, 302, 271,
294, 430, 289, 33, 273, 33, 295, 291, 273, 33,
33, 291, 33, 292, 297, 294, 33, 299, 287, 294,
33, 36, 301, 305, 302, 313, 301, 303, 304, 314,
313, 307, 314, 315, 317, 315, 317, 318, 318, 318,
305, 301, 329, 302, 320, 301, 429, 303, 36, 307,
36, 304, 322, 324, 36, 36, 326, 36, 36, 330,
328, 36, 328, 320, 329, 36, 108, 331, 108, 332,
304, 322, 324, 334, 336, 326, 336, 338, 330, 108,
352, 339, 352, 337, 340, 340, 341, 341, 332, 331,
345, 108, 334, 108, 337, 339, 344, 346, 347, 347,
344, 108, 338, 345, 354, 346, 348, 348, 348, 353,
108, 355, 108, 109, 357, 109, 337, 339, 350, 350,
350, 338, 356, 354, 356, 358, 109, 359, 360, 423,
360, 353, 362, 355, 365, 363, 357, 363, 109, 364,
109, 366, 369, 367, 358, 367, 413, 370, 109, 359,
368, 362, 368, 365, 371, 371, 360, 109, 411, 109,
179, 364, 179, 366, 372, 372, 374, 376, 376, 369,
374, 367, 370, 179, 380, 360, 375, 378, 368, 378,
375, 383, 381, 384, 381, 179, 391, 179, 397, 385,
367, 370, 386, 380, 388, 179, 390, 368, 389, 392,
383, 394, 384, 400, 179, 378, 179, 180, 385, 180,
381, 391, 386, 388, 398, 390, 395, 392, 403, 395,
180, 399, 389, 400, 378, 396, 396, 401, 402, 381,
391, 405, 180, 398, 180, 404, 406, 392, 403, 407,
399, 389, 180, 409, 410, 412, 401, 402, 414, 408,
405, 180, 412, 180, 187, 406, 187, 404, 415, 407,
408, 416, 473, 393, 473, 409, 417, 187, 418, 410,
414, 419, 420, 421, 427, 424, 425, 415, 426, 187,
387, 187, 408, 416, 422, 417, 428, 418, 410, 187,
419, 422, 421, 420, 424, 425, 431, 426, 187, 427,
187, 188, 432, 188, 433, 428, 440, 435, 439, 445,
434, 437, 420, 438, 188, 431, 441, 440, 427, 442,
443, 432, 382, 379, 433, 444, 188, 435, 188, 434,
439, 437, 446, 438, 447, 445, 188, 448, 441, 440,
449, 442, 443, 450, 444, 188, 451, 188, 452, 434,
453, 446, 459, 447, 445, 460, 448, 450, 465, 461,
470, 462, 449, 463, 464, 466, 467, 469, 451, 468,
452, 459, 453, 465, 377, 470, 471, 460, 461, 450,
462, 475, 463, 475, 373, 467, 464, 466, 468, 469,
361, 472, 474, 472, 474, 465, 460, 470, 471, 472,
474, 476, 477, 476, 477, 480, 481, 480, 481, 482,
477, 482, 485, 486, 485, 486, 488, 482, 488, 492,
492, 492, 492, 492, 492, 492, 492, 492, 492, 492,
492, 492, 493, 493, 493, 493, 493, 493, 493, 493,
493, 493, 493, 493, 493, 494, 494, 494, 494, 494,
494, 494, 494, 494, 494, 494, 494, 494, 495, 495,
495, 495, 495, 495, 495, 495, 495, 495, 495, 495,
495, 496, 496, 496, 496, 496, 496, 496, 496, 496,
496, 496, 496, 496, 497, 497, 497, 497, 497, 497,
497, 497, 497, 497, 497, 497, 497, 498, 498, 498,
498, 498, 498, 498, 498, 498, 498, 498, 498, 498,
499, 499, 499, 499, 499, 499, 499, 499, 499, 499,
499, 499, 499, 500, 500, 500, 500, 500, 500, 500,
500, 500, 500, 500, 500, 500, 501, 501, 501, 501,
501, 501, 501, 501, 501, 501, 501, 501, 501, 502,
502, 502, 502, 502, 502, 502, 502, 502, 502, 502,
502, 502, 503, 351, 343, 342, 503, 503, 335, 503,
504, 333, 327, 325, 504, 504, 504, 504, 504, 504,
504, 504, 504, 505, 323, 321, 319, 312, 311, 505,
505, 506, 506, 507, 507, 508, 508, 508, 508, 508,
508, 508, 508, 508, 508, 508, 508, 508, 509, 509,
310, 309, 300, 509, 298, 296, 509, 509, 509, 293,
509, 510, 510, 510, 510, 510, 510, 510, 510, 510,
510, 510, 510, 510, 511, 511, 290, 288, 511, 511,
511, 286, 511, 511, 511, 277, 511, 512, 512, 512,
512, 512, 512, 512, 512, 512, 512, 512, 512, 512,
513, 513, 514, 514, 268, 266, 262, 514, 259, 258,
251, 514, 514, 515, 237, 233, 231, 228, 227, 515,
515, 516, 516, 225, 516, 516, 516, 516, 516, 516,
516, 516, 516, 516, 517, 517, 518, 518, 223, 518,
518, 518, 518, 518, 518, 518, 518, 518, 518, 519,
221, 219, 218, 519, 519, 217, 519, 520, 216, 215,
212, 520, 520, 520, 520, 520, 520, 520, 520, 520,
521, 521, 211, 207, 521, 521, 521, 521, 521, 521,
521, 521, 521, 522, 522, 197, 196, 522, 522, 522,
522, 522, 522, 522, 522, 522, 523, 523, 195, 194,
523, 523, 523, 523, 523, 523, 523, 523, 523, 524,
193, 186, 185, 524, 524, 183, 524, 525, 176, 170,
169, 525, 525, 525, 525, 525, 525, 525, 525, 525,
526, 526, 526, 526, 526, 526, 526, 526, 526, 526,
526, 526, 526, 527, 527, 153, 527, 527, 527, 527,
527, 527, 527, 527, 527, 527, 528, 528, 148, 528,
528, 528, 528, 528, 528, 528, 528, 528, 528, 529,
529, 124, 529, 529, 529, 529, 529, 529, 529, 529,
529, 529, 115, 114, 112, 111, 110, 105, 99, 75,
40, 31, 25, 23, 491, 491, 491, 491, 491, 491,
491, 491, 491, 491, 491, 491, 491, 491, 491, 491,
491, 491, 491, 491, 491, 491, 491, 491, 491, 491,
491, 491, 491, 491, 491, 491, 491, 491, 491, 491,
491, 491, 491, 491, 491, 491, 491, 491, 491, 491,
491, 491, 491, 491, 491
} ;
static yy_state_type yy_last_accepting_state;
static char *yy_last_accepting_cpos;
/* The intent behind this definition is that it'll catch
* any uses of REJECT which flex missed.
*/
#define REJECT reject_used_but_not_detected
static int yy_more_flag = 0;
static int yy_more_len = 0;
#define yymore() (yy_more_flag = 1)
#define YY_MORE_ADJ yy_more_len
#define YY_RESTORE_YY_MORE_OFFSET
char *yytext;
#line 1 "..\\src\\VPreLex.l"
#define INITIAL 0
#define YY_STACK_USED 1
#line 8 "..\\src\\VPreLex.l"
/******************************************************************************
* DESCRIPTION: Verilog Preprocessor Lexer
*
* This file is part of Verilog-Perl.
*
* Author: Wilson Snyder <wsnyder@wsnyder.org>
*
* Code available from: http://www.veripool.org/systemperl
*
******************************************************************************
*
* Copyright 2000-2013 by Wilson Snyder. This program is free software;
* you can redistribute it and/or modify it under the terms of either the GNU
* Lesser General Public License Version 3 or the Perl Artistic License Version 2.0.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*****************************************************************************
* Do not use Flex in C++ mode. It has bugs with yyunput() which result in
* lost characters.
*****************************************************************************/
#include "VPreProc.h"
#include "VPreLex.h"
#include <cstdio>
#include <cstdarg>
#include <cstring>
#include <iostream>
#include "qcstring.h"
#include "define.h"
// Flex 2.5.35 has compile warning in ECHO, so we'll default our own rule
#define ECHO yyerror_f("Missing VPreLex.l rule: ECHO rule invoked in state %d: %s", YY_START, yytext);
struct VPreProcImp;
VPreLex* VPreLex::s_currentLexp = NULL; // Current lexing point
#define LEXP VPreLex::s_currentLexp
#define linenoInc() { LEXP->linenoInc(); }
static bool pedantic() { return LEXP->m_pedantic; }
static bool keepWhitespace() { return LEXP->m_keepWhitespace; }
static void appendDefValue(const char* t, size_t l) { LEXP->appendDefValue(t,l); }
void yyerrorx(char* msg) { LEXP->curFilelinep()->error(msg); }
#define YY_INPUT(buf,result,max_size) \
result = LEXP->inputToLex(buf,max_size);
// Accessors, because flex keeps changing the type of yyleng
char* yyourtext() { return yytext; }
size_t yyourleng() { return (size_t)yyleng; }
void yyourtext(const char* textp, size_t size) { yytext=(char*)textp; yyleng=size; }
void yyerror_f(const char* format, ...) {
char msg[1024];
va_list ap;
va_start(ap,format);
vsprintf(msg,format,ap);
va_end(ap);
yyerrorx(msg);
}
typedef size_t ussize_t;
/**********************************************************************/
#define CMTMODE 1
#define STRMODE 2
#define DEFFPAR 3
#define DEFFORM 4
#define DEFVAL 5
#define DEFCMT 6
#define ARGMODE 7
#define INCMODE 8
#define PRTMODE 9
#define OFFMODE 10
/* drop: Drop Ctrl-Z - can't pass thru or may EOF the output too soon */
/* Where we use symb/symbdef, we must also look for a `` join */
/* Note in the preprocessor \ESCaped is *not* always special; mantis1537/bug441 */
/* Case insensitive; unfortunately ?i: isn't in flex 2.5.4 which is popular */
/**************************************************************/
#line 965 "c:\\Boot\\doxygen\\src\\VPreLex.cpp"
/* Macros after this point can all be overridden by user definitions in
* section 1.
*/
#ifndef YY_SKIP_YYWRAP
#ifdef __cplusplus
extern "C" int yywrap YY_PROTO(( void ));
#else
extern int yywrap YY_PROTO(( void ));
#endif
#endif
#ifndef YY_NO_UNPUT
static void yyunput YY_PROTO(( int c, char *buf_ptr ));
#endif
#ifndef yytext_ptr
static void yy_flex_strncpy YY_PROTO(( char *, yyconst char *, int ));
#endif
#ifdef YY_NEED_STRLEN
static int yy_flex_strlen YY_PROTO(( yyconst char * ));
#endif
#ifndef YY_NO_INPUT
#ifdef __cplusplus
static int yyinput YY_PROTO(( void ));
#else
static int input YY_PROTO(( void ));
#endif
#endif
#if YY_STACK_USED
static int yy_start_stack_ptr = 0;
static int yy_start_stack_depth = 0;
static int *yy_start_stack = 0;
#ifndef YY_NO_PUSH_STATE
static void yy_push_state YY_PROTO(( int new_state ));
#endif
#ifndef YY_NO_POP_STATE
static void yy_pop_state YY_PROTO(( void ));
#endif
#ifndef YY_NO_TOP_STATE
static int yy_top_state YY_PROTO(( void ));
#endif
#else
#define YY_NO_PUSH_STATE 1
#define YY_NO_POP_STATE 1
#define YY_NO_TOP_STATE 1
#endif
#ifdef YY_MALLOC_DECL
YY_MALLOC_DECL
#else
#if __STDC__
#ifndef __cplusplus
#include <stdlib.h>
#endif
#else
/* Just try to get by without declaring the routines. This will fail
* miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int)
* or sizeof(void*) != sizeof(int).
*/
#endif
#endif
/* Amount of stuff to slurp up with each read. */
#ifndef YY_READ_BUF_SIZE
#define YY_READ_BUF_SIZE 8192
#endif
/* Copy whatever the last rule matched to the standard output. */
#ifndef ECHO
/* This used to be an fputs(), but since the string might contain NUL's,
* we now use fwrite().
*/
#define ECHO (void) fwrite( yytext, yyleng, 1, yyout )
#endif
/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
* is returned in "result".
*/
#ifndef YY_INPUT
#define YY_INPUT(buf,result,max_size) \
if ( yy_current_buffer->yy_is_interactive ) \
{ \
int c = '*', n; \
for ( n = 0; n < max_size && \
(c = getc( yyin )) != EOF && c != '\n'; ++n ) \
buf[n] = (char) c; \
if ( c == '\n' ) \
buf[n++] = (char) c; \
if ( c == EOF && ferror( yyin ) ) \
YY_FATAL_ERROR( "input in flex scanner failed" ); \
result = n; \
} \
else if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \
&& ferror( yyin ) ) \
YY_FATAL_ERROR( "input in flex scanner failed" );
#endif
/* No semi-colon after return; correct usage is to write "yyterminate();" -
* we don't want an extra ';' after the "return" because that will cause
* some compilers to complain about unreachable statements.
*/
#ifndef yyterminate
#define yyterminate() return YY_NULL
#endif
/* Number of entries by which start-condition stack grows. */
#ifndef YY_START_STACK_INCR
#define YY_START_STACK_INCR 25
#endif
/* Report a fatal error. */
#ifndef YY_FATAL_ERROR
#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
#endif
/* Default declaration of generated scanner - a define so the user can
* easily add parameters.
*/
#ifndef YY_DECL
#define YY_DECL int yylex YY_PROTO(( void ))
#endif
/* Code executed at the beginning of each rule, after yytext and yyleng
* have been set up.
*/
#ifndef YY_USER_ACTION
#define YY_USER_ACTION
#endif
/* Code executed at the end of each rule. */
#ifndef YY_BREAK
#define YY_BREAK break;
#endif
#define YY_RULE_SETUP \
if ( yyleng > 0 ) \
yy_current_buffer->yy_at_bol = \
(yytext[yyleng - 1] == '\n'); \
YY_USER_ACTION
YY_DECL
{
register yy_state_type yy_current_state;
register char *yy_cp, *yy_bp;
register int yy_act;
#line 114 "..\\src\\VPreLex.l"
#line 1122 "c:\\Boot\\doxygen\\src\\VPreLex.cpp"
if ( yy_init )
{
yy_init = 0;
#ifdef YY_USER_INIT
YY_USER_INIT;
#endif
if ( ! yy_start )
yy_start = 1; /* first start state */
if ( ! yyin )
yyin = stdin;
if ( ! yyout )
yyout = stdout;
if ( ! yy_current_buffer )
yy_current_buffer =
yy_create_buffer( yyin, YY_BUF_SIZE );
yy_load_buffer_state();
}
while ( 1 ) /* loops until end-of-file is reached */
{
yy_more_len = 0;
if ( yy_more_flag )
{
yy_more_len = yy_c_buf_p - yytext_ptr;
yy_more_flag = 0;
}
yy_cp = yy_c_buf_p;
/* Support of yytext. */
*yy_cp = yy_hold_char;
/* yy_bp points to the position in yy_ch_buf of the start of
* the current run.
*/
yy_bp = yy_cp;
yy_current_state = yy_start;
yy_current_state += YY_AT_BOL();
yy_match:
do
{
register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
if ( yy_accept[yy_current_state] )
{
yy_last_accepting_state = yy_current_state;
yy_last_accepting_cpos = yy_cp;
}
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{
yy_current_state = (int) yy_def[yy_current_state];
if ( yy_current_state >= 492 )
yy_c = yy_meta[(unsigned int) yy_c];
}
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
++yy_cp;
}
while ( yy_base[yy_current_state] != 1375 );
yy_find_action:
yy_act = yy_accept[yy_current_state];
if ( yy_act == 0 )
{ /* have to back up */
yy_cp = yy_last_accepting_cpos;
yy_current_state = yy_last_accepting_state;
yy_act = yy_accept[yy_current_state];
}
YY_DO_BEFORE_ACTION;
do_action: /* This label is used only to access EOF actions. */
switch ( yy_act )
{ /* beginning of action switch */
case 0: /* must back up */
/* undo the effects of YY_DO_BEFORE_ACTION */
*yy_cp = yy_hold_char;
yy_cp = yy_last_accepting_cpos;
yy_current_state = yy_last_accepting_state;
goto yy_find_action;
case 1:
YY_RULE_SETUP
#line 116 "..\\src\\VPreLex.l"
{ LEXP->lineDirective(yytext);
return(VP_LINE); }
YY_BREAK
/* Special directives we recognize */
case 2:
YY_RULE_SETUP
#line 120 "..\\src\\VPreLex.l"
{ return(VP_DEFINE); }
YY_BREAK
case 3:
YY_RULE_SETUP
#line 121 "..\\src\\VPreLex.l"
{ return(VP_ELSE); }
YY_BREAK
case 4:
YY_RULE_SETUP
#line 122 "..\\src\\VPreLex.l"
{ return(VP_ELSIF); }
YY_BREAK
case 5:
YY_RULE_SETUP
#line 123 "..\\src\\VPreLex.l"
{ return(VP_ENDIF); }
YY_BREAK
case 6:
YY_RULE_SETUP
#line 124 "..\\src\\VPreLex.l"
{ return(VP_IFDEF); }
YY_BREAK
case 7:
YY_RULE_SETUP
#line 125 "..\\src\\VPreLex.l"
{ return(VP_IFNDEF); }
YY_BREAK
case 8:
YY_RULE_SETUP
#line 126 "..\\src\\VPreLex.l"
{ return(VP_INCLUDE); }
YY_BREAK
case 9:
YY_RULE_SETUP
#line 127 "..\\src\\VPreLex.l"
{ return(VP_UNDEF); }
YY_BREAK
case 10:
YY_RULE_SETUP
#line 128 "..\\src\\VPreLex.l"
{ return(VP_UNDEFINEALL); }
YY_BREAK
/* Optional directives we recognize */
case 11:
YY_RULE_SETUP
#line 131 "..\\src\\VPreLex.l"
{ static string rtnfile;
rtnfile = '"'; rtnfile += LEXP->curFilelinep()->filename();
rtnfile += '"'; yytext=(char*)rtnfile.c_str(); yyleng = rtnfile.length();
return (VP_STRING); }
YY_BREAK
case 12:
YY_RULE_SETUP
#line 135 "..\\src\\VPreLex.l"
{ static char buf[10];
sprintf(buf, "%d",LEXP->curFilelinep()->lineno());
yytext = buf; yyleng = strlen(yytext);
return (VP_TEXT); }
YY_BREAK
case 13:
YY_RULE_SETUP
#line 139 "..\\src\\VPreLex.l"
{ if (!pedantic()) return (VP_ERROR); else return(VP_DEFREF); }
YY_BREAK
/* Pass-through strings */
case 14:
YY_RULE_SETUP
#line 142 "..\\src\\VPreLex.l"
{ yy_push_state(STRMODE); yymore(); }
YY_BREAK
case YY_STATE_EOF(STRMODE):
#line 143 "..\\src\\VPreLex.l"
{ linenoInc(); yyerror_f("EOF in unterminated string"); yyleng=0; yyterminate(); }
YY_BREAK
case 15:
YY_RULE_SETUP
#line 144 "..\\src\\VPreLex.l"
{ linenoInc(); yyerror_f("Unterminated string"); BEGIN(INITIAL); }
YY_BREAK
case 16:
YY_RULE_SETUP
#line 145 "..\\src\\VPreLex.l"
{ yymore(); }
YY_BREAK
case 17:
YY_RULE_SETUP
#line 146 "..\\src\\VPreLex.l"
{ yymore(); }
YY_BREAK
case 18:
YY_RULE_SETUP
#line 147 "..\\src\\VPreLex.l"
{ linenoInc(); yymore(); }
YY_BREAK
case 19:
YY_RULE_SETUP
#line 148 "..\\src\\VPreLex.l"
{ yymore(); }
YY_BREAK
case 20:
YY_RULE_SETUP
#line 149 "..\\src\\VPreLex.l"
{ yy_pop_state();
if (LEXP->m_parenLevel || LEXP->m_formalLevel) { appendDefValue(yytext,yyleng); yyleng=0; }
else return (VP_STRING); }
YY_BREAK
/* Stringification */
case 21:
YY_RULE_SETUP
#line 154 "..\\src\\VPreLex.l"
{ return VP_STRIFY; }
YY_BREAK
case 22:
YY_RULE_SETUP
#line 155 "..\\src\\VPreLex.l"
{ return VP_BACKQUOTE; }
YY_BREAK
/* Protected blocks */
case 23:
YY_RULE_SETUP
#line 158 "..\\src\\VPreLex.l"
{ yy_push_state(PRTMODE); yymore(); }
YY_BREAK
case YY_STATE_EOF(PRTMODE):
#line 159 "..\\src\\VPreLex.l"
{ linenoInc(); yyerror_f("EOF in `protected"); yyleng=0; yyterminate(); }
YY_BREAK
case 24:
YY_RULE_SETUP
#line 160 "..\\src\\VPreLex.l"
{ linenoInc(); yymore(); }
YY_BREAK
case 25:
YY_RULE_SETUP
#line 161 "..\\src\\VPreLex.l"
{ yymore(); }
YY_BREAK
case 26:
YY_RULE_SETUP
#line 162 "..\\src\\VPreLex.l"
{ yy_pop_state(); return (VP_TEXT); }
YY_BREAK
/* Pass-through include <> filenames */
case YY_STATE_EOF(INCMODE):
#line 165 "..\\src\\VPreLex.l"
{ linenoInc(); yyerror_f("EOF in unterminated include filename"); yyleng=0; yyterminate(); }
YY_BREAK
case 27:
YY_RULE_SETUP
#line 166 "..\\src\\VPreLex.l"
{ linenoInc(); yyerror_f("Unterminated include filename"); BEGIN(INITIAL); }
YY_BREAK
case 28:
YY_RULE_SETUP
#line 167 "..\\src\\VPreLex.l"
{ yymore(); }
YY_BREAK
case 29:
YY_RULE_SETUP
#line 168 "..\\src\\VPreLex.l"
{ yymore(); }
YY_BREAK
case 30:
YY_RULE_SETUP
#line 169 "..\\src\\VPreLex.l"
{ yy_pop_state(); return (VP_STRING); }
YY_BREAK
/* Reading definition formal parenthesis (or not) to begin formal arguments */
/* Note '(' must IMMEDIATELY follow definition name */
case 31:
YY_RULE_SETUP
#line 173 "..\\src\\VPreLex.l"
{ appendDefValue("(",1); LEXP->m_formalLevel=1; BEGIN(DEFFORM); }
YY_BREAK
case 32:
YY_RULE_SETUP
#line 174 "..\\src\\VPreLex.l"
{ yy_pop_state(); yytext=(char*)"\n"; unput('\n'); yyleng=1; return VP_DEFFORM; } /* DEFVAL will later grab the return */
YY_BREAK
case YY_STATE_EOF(DEFFPAR):
#line 175 "..\\src\\VPreLex.l"
{ yy_pop_state(); return VP_DEFFORM; } /* empty formals */
YY_BREAK
case 33:
YY_RULE_SETUP
#line 176 "..\\src\\VPreLex.l"
{
QCString s=yytext;
yy_pop_state(); unput(yytext[yyleng-1]); yyleng=0; return VP_DEFFORM;
} /* empty formals */
YY_BREAK
/* Reading definition formals (declaration of a define) */
case 34:
YY_RULE_SETUP
#line 182 "..\\src\\VPreLex.l"
{ appendDefValue(yytext,yyleng); yyleng=0; ++LEXP->m_formalLevel; }
YY_BREAK
case 35:
YY_RULE_SETUP
#line 183 "..\\src\\VPreLex.l"
{ appendDefValue(yytext,yyleng); yyleng=0; if ((--LEXP->m_formalLevel)==0) { yy_pop_state(); return VP_DEFFORM; } }
YY_BREAK
case 36:
YY_RULE_SETUP
#line 184 "..\\src\\VPreLex.l"
{ yy_push_state(CMTMODE); yymore(); }
YY_BREAK
case 37:
YY_RULE_SETUP
#line 185 "..\\src\\VPreLex.l"
{ return (VP_COMMENT);}
YY_BREAK
case 38:
YY_RULE_SETUP
#line 186 "..\\src\\VPreLex.l"
{ }
YY_BREAK
case YY_STATE_EOF(DEFFORM):
#line 187 "..\\src\\VPreLex.l"
{ linenoInc(); yy_pop_state(); yyerror_f("Unterminated ( in define formal arguments."); yyleng=0; return VP_DEFFORM; }
YY_BREAK
case 39:
YY_RULE_SETUP
#line 188 "..\\src\\VPreLex.l"
{ linenoInc(); appendDefValue((char*)"\n",1); } /* Include return so can maintain output line count */
YY_BREAK
case 40:
YY_RULE_SETUP
#line 189 "..\\src\\VPreLex.l"
{ linenoInc(); appendDefValue((char*)"\\\n",2); } /* Include return so can maintain output line count */
YY_BREAK
case 41:
YY_RULE_SETUP
#line 190 "..\\src\\VPreLex.l"
{ yy_push_state(STRMODE); yymore(); } /* Legal only in default values */
YY_BREAK
case 42:
YY_RULE_SETUP
#line 191 "..\\src\\VPreLex.l"
{ appendDefValue(yytext,yyleng); } /* Maybe illegal, otherwise in default value */
YY_BREAK
case 43:
YY_RULE_SETUP
#line 192 "..\\src\\VPreLex.l"
{ appendDefValue(yytext,yyleng); } /* Maybe illegal, otherwise in default value */
YY_BREAK
case 44:
YY_RULE_SETUP
#line 193 "..\\src\\VPreLex.l"
{ LEXP->m_formalLevel++; appendDefValue(yytext,yyleng); }
YY_BREAK
case 45:
YY_RULE_SETUP
#line 194 "..\\src\\VPreLex.l"
{ LEXP->m_formalLevel--; appendDefValue(yytext,yyleng); }
YY_BREAK
case 46:
#line 196 "..\\src\\VPreLex.l"
case 47:
#line 197 "..\\src\\VPreLex.l"
case 48:
YY_RULE_SETUP
#line 197 "..\\src\\VPreLex.l"
{ appendDefValue(yytext,yyleng); }
YY_BREAK
/* Reading definition value (declaration of a define's text) */
case 49:
YY_RULE_SETUP
#line 200 "..\\src\\VPreLex.l"
{ LEXP->m_defCmtSlash=false; yy_push_state(DEFCMT); yymore(); } /* Special comment parser */
YY_BREAK
case 50:
YY_RULE_SETUP
#line 201 "..\\src\\VPreLex.l"
{ linenoInc(); appendDefValue((char*)"\n",1); } /* Spec says // not part of define value */
YY_BREAK
case 51:
YY_RULE_SETUP
#line 202 "..\\src\\VPreLex.l"
{ return (VP_COMMENT);}
YY_BREAK
case 52:
YY_RULE_SETUP
#line 203 "..\\src\\VPreLex.l"
{ }
YY_BREAK
case YY_STATE_EOF(DEFVAL):
#line 204 "..\\src\\VPreLex.l"
{ linenoInc(); yy_pop_state(); yytext=(char*)"\n"; yyleng=1; return (VP_DEFVALUE); } /* Technically illegal, but people complained */
YY_BREAK
case 53:
YY_RULE_SETUP
#line 205 "..\\src\\VPreLex.l"
{ linenoInc(); yy_pop_state(); yytext=(char*)"\n"; yyleng=1; return (VP_DEFVALUE); }
YY_BREAK
case 54:
YY_RULE_SETUP
#line 206 "..\\src\\VPreLex.l"
{ linenoInc(); appendDefValue((char*)"\\\n",2); } /* Return, AND \ is part of define value */
YY_BREAK
case 55:
#line 208 "..\\src\\VPreLex.l"
case 56:
#line 209 "..\\src\\VPreLex.l"
case 57:
YY_RULE_SETUP
#line 209 "..\\src\\VPreLex.l"
{
QCString s=yytext;
appendDefValue(yytext,yyleng);
}
YY_BREAK
/* Comments inside define values - if embedded get added to define value per spec */
/* - if no \{crnl} ending then the comment belongs to the next line, as a non-embedded comment */
/* - if all but (say) 3rd line is missing \ then it's indeterminate */
case 58:
YY_RULE_SETUP
#line 217 "..\\src\\VPreLex.l"
{ yy_pop_state(); appendDefValue(yytext,yyleng); }
YY_BREAK
case 59:
YY_RULE_SETUP
#line 218 "..\\src\\VPreLex.l"
{ linenoInc(); LEXP->m_defCmtSlash=true;
appendDefValue(yytext,yyleng-2); appendDefValue((char*)"\n",1); } /* Return but not \ */
YY_BREAK
case 60:
YY_RULE_SETUP
#line 220 "..\\src\\VPreLex.l"
{ linenoInc(); yymore(); if (LEXP->m_defCmtSlash) yyerror_f("One line of /* ... */ is missing \\ before newline");
BEGIN(CMTMODE); }
YY_BREAK
case 61:
YY_RULE_SETUP
#line 222 "..\\src\\VPreLex.l"
{ yymore(); }
YY_BREAK
case 62:
YY_RULE_SETUP
#line 223 "..\\src\\VPreLex.l"
{ yymore(); }
YY_BREAK
case YY_STATE_EOF(DEFCMT):
#line 224 "..\\src\\VPreLex.l"
{ yyerror_f("EOF in '/* ... */' block comment\n"); yyleng=0; yyterminate(); }
YY_BREAK
/* Define arguments (use of a define) */
case 63:
YY_RULE_SETUP
#line 227 "..\\src\\VPreLex.l"
{ yy_push_state(CMTMODE); yymore(); }
YY_BREAK
case 64:
YY_RULE_SETUP
#line 228 "..\\src\\VPreLex.l"
{ return (VP_COMMENT);}
YY_BREAK
case 65:
YY_RULE_SETUP
#line 229 "..\\src\\VPreLex.l"
{ }
YY_BREAK
case YY_STATE_EOF(ARGMODE):
#line 230 "..\\src\\VPreLex.l"
{ yyerror_f("EOF in define argument list\n"); yyleng = 0; yyterminate(); }
YY_BREAK
case 66:
YY_RULE_SETUP
#line 231 "..\\src\\VPreLex.l"
{ linenoInc(); yytext=(char*)"\n"; yyleng=1; return(VP_WHITE); }
YY_BREAK
case 67:
YY_RULE_SETUP
#line 232 "..\\src\\VPreLex.l"
{ yy_push_state(STRMODE); yymore(); }
YY_BREAK
case 68:
YY_RULE_SETUP
#line 233 "..\\src\\VPreLex.l"
{ appendDefValue(yytext,yyleng); } /* Literal text */
YY_BREAK
case 69:
YY_RULE_SETUP
#line 234 "..\\src\\VPreLex.l"
{ return(VP_STRIFY); }
YY_BREAK
case 70:
YY_RULE_SETUP
#line 235 "..\\src\\VPreLex.l"
{ LEXP->m_parenLevel++; appendDefValue(yytext,yyleng); }
YY_BREAK
case 71:
YY_RULE_SETUP
#line 236 "..\\src\\VPreLex.l"
{ LEXP->m_parenLevel--; appendDefValue(yytext,yyleng); }
YY_BREAK
case 72:
YY_RULE_SETUP
#line 237 "..\\src\\VPreLex.l"
{ LEXP->m_parenLevel++;
// Note paren level 0 means before "(" of starting args
// Level 1 means "," between arguments
// Level 2+ means one argument's internal ()
if (LEXP->m_parenLevel>1) {
appendDefValue(yytext,yyleng);
} else {
return (VP_TEXT);
}}
YY_BREAK
case 73:
YY_RULE_SETUP
#line 246 "..\\src\\VPreLex.l"
{ LEXP->m_parenLevel--;
if (LEXP->m_parenLevel>0) {
appendDefValue(yytext,yyleng);
} else {
yy_pop_state(); return (VP_DEFARG);
}}
YY_BREAK
case 74:
YY_RULE_SETUP
#line 252 "..\\src\\VPreLex.l"
{ if (LEXP->m_parenLevel>1) {
appendDefValue(yytext,yyleng);
} else {
yy_pop_state(); return (VP_DEFARG);
}}
YY_BREAK
case 75:
YY_RULE_SETUP
#line 257 "..\\src\\VPreLex.l"
{ appendDefValue(yytext,yyleng); } /* defref in defref - outer macro expands first */
YY_BREAK
case 76:
YY_RULE_SETUP
#line 258 "..\\src\\VPreLex.l"
{ appendDefValue(yytext,yyleng); } /* defref in defref - outer macro expands first */
YY_BREAK
case 77:
#line 260 "..\\src\\VPreLex.l"
case 78:
YY_RULE_SETUP
#line 260 "..\\src\\VPreLex.l"
{ appendDefValue(yytext,yyleng); }
YY_BREAK
/* Translate offs. Note final newline not included */
case 79:
YY_RULE_SETUP
#line 263 "..\\src\\VPreLex.l"
{
if (LEXP->m_synthesis) { yy_push_state(OFFMODE); }
return(VP_COMMENT); }
YY_BREAK
case 80:
YY_RULE_SETUP
#line 266 "..\\src\\VPreLex.l"
{
if (LEXP->m_synthesis) { yy_pop_state(); }
return(VP_COMMENT); }
YY_BREAK
case 81:
YY_RULE_SETUP
#line 269 "..\\src\\VPreLex.l"
{ linenoInc(); yymore(); } /* Need to end the / / */
YY_BREAK
case 82:
YY_RULE_SETUP
#line 270 "..\\src\\VPreLex.l"
{ }
YY_BREAK
case 83:
YY_RULE_SETUP
#line 271 "..\\src\\VPreLex.l"
{ }
YY_BREAK
case YY_STATE_EOF(OFFMODE):
#line 272 "..\\src\\VPreLex.l"
{ yyerror_f("EOF in '/*synthesis translate_off*/' region\n"); yyleng=0; yyterminate(); }
YY_BREAK
/* One line comments. Note final newline not included */
case 84:
YY_RULE_SETUP
#line 275 "..\\src\\VPreLex.l"
{ return (VP_COMMENT); }
YY_BREAK
/* C-style comments. */
/**** See also DEFCMT */
case 85:
YY_RULE_SETUP
#line 279 "..\\src\\VPreLex.l"
{ yy_push_state(CMTMODE); yymore(); }
YY_BREAK
case 86:
YY_RULE_SETUP
#line 280 "..\\src\\VPreLex.l"
{ yy_pop_state(); return(VP_COMMENT); }
YY_BREAK
case 87:
YY_RULE_SETUP
#line 281 "..\\src\\VPreLex.l"
{ linenoInc(); yymore(); }
YY_BREAK
case 88:
YY_RULE_SETUP
#line 282 "..\\src\\VPreLex.l"
{ yymore(); }
YY_BREAK
case 89:
YY_RULE_SETUP
#line 283 "..\\src\\VPreLex.l"
{ yymore(); }
YY_BREAK
case YY_STATE_EOF(CMTMODE):
#line 284 "..\\src\\VPreLex.l"
{ yyerror_f("EOF in '/* ... */' block comment\n"); yyleng=0; yyterminate(); }
YY_BREAK
/* Define calls */
/* symbdef prevents normal lex rules from making `\`"foo a symbol {`"foo} instead of a BACKQUOTE */
case 90:
YY_RULE_SETUP
#line 288 "..\\src\\VPreLex.l"
{
QCString s=yytext;
s.stripPrefix("`");
DefineDict* gDict = VerilogPreProc::getPreDefineDict();
Define *def=gDict->find(s.data());
if(def)
{
yytext=def->args.data();
yyleng=def->args.length();
return VP_TEXT;
}
return (VP_DEFREF);
}
YY_BREAK
case 91:
YY_RULE_SETUP
#line 302 "..\\src\\VPreLex.l"
{ yyleng-=2; return (VP_DEFREF_JOIN); }
YY_BREAK
/* Generics */
case YY_STATE_EOF(INITIAL):
#line 305 "..\\src\\VPreLex.l"
{ yyterminate(); } /* A "normal" EOF */
YY_BREAK
case 92:
YY_RULE_SETUP
#line 306 "..\\src\\VPreLex.l"
{ linenoInc(); yytext=(char*)"\n"; yyleng=1; return(VP_WHITE); }
YY_BREAK
case 93:
YY_RULE_SETUP
#line 307 "..\\src\\VPreLex.l"
{
static QCString s;
s.append(yytext);
s.append("#");
// yytext=s.data();
return (VP_SYMBOL);
}
YY_BREAK
case 94:
YY_RULE_SETUP
#line 314 "..\\src\\VPreLex.l"
{ yyleng-=2; return (VP_SYMBOL_JOIN); }
YY_BREAK
case 95:
YY_RULE_SETUP
#line 315 "..\\src\\VPreLex.l"
{ }
YY_BREAK
case 96:
YY_RULE_SETUP
#line 316 "..\\src\\VPreLex.l"
{ if (!keepWhitespace()) { yytext=(char*)" "; yyleng=1; } return VP_WHITE; }
YY_BREAK
case 97:
YY_RULE_SETUP
#line 317 "..\\src\\VPreLex.l"
{ }
YY_BREAK
case 98:
YY_RULE_SETUP
#line 318 "..\\src\\VPreLex.l"
{
return (VP_TEXT);
}
YY_BREAK
case 99:
YY_RULE_SETUP
#line 323 "..\\src\\VPreLex.l"
{ yymore(); } /* Prevent hitting ECHO; */
YY_BREAK
case 100:
YY_RULE_SETUP
#line 324 "..\\src\\VPreLex.l"
ECHO;
YY_BREAK
#line 1822 "c:\\Boot\\doxygen\\src\\VPreLex.cpp"
case YY_END_OF_BUFFER:
{
/* Amount of text matched not including the EOB char. */
int yy_amount_of_matched_text = (int) (yy_cp - yytext_ptr) - 1;
/* Undo the effects of YY_DO_BEFORE_ACTION. */
*yy_cp = yy_hold_char;
YY_RESTORE_YY_MORE_OFFSET
if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW )
{
/* We're scanning a new file or input source. It's
* possible that this happened because the user
* just pointed yyin at a new source and called
* yylex(). If so, then we have to assure
* consistency between yy_current_buffer and our
* globals. Here is the right place to do so, because
* this is the first action (other than possibly a
* back-up) that will match for the new input source.
*/
yy_n_chars = yy_current_buffer->yy_n_chars;
yy_current_buffer->yy_input_file = yyin;
yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL;
}
/* Note that here we test for yy_c_buf_p "<=" to the position
* of the first EOB in the buffer, since yy_c_buf_p will
* already have been incremented past the NUL character
* (since all states make transitions on EOB to the
* end-of-buffer state). Contrast this with the test
* in input().
*/
if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] )
{ /* This was really a NUL. */
yy_state_type yy_next_state;
yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text;
yy_current_state = yy_get_previous_state();
/* Okay, we're now positioned to make the NUL
* transition. We couldn't have
* yy_get_previous_state() go ahead and do it
* for us because it doesn't know how to deal
* with the possibility of jamming (and we don't
* want to build jamming into it because then it
* will run more slowly).
*/
yy_next_state = yy_try_NUL_trans( yy_current_state );
yy_bp = yytext_ptr + YY_MORE_ADJ;
if ( yy_next_state )
{
/* Consume the NUL. */
yy_cp = ++yy_c_buf_p;
yy_current_state = yy_next_state;
goto yy_match;
}
else
{
yy_cp = yy_c_buf_p;
goto yy_find_action;
}
}
else switch ( yy_get_next_buffer() )
{
case EOB_ACT_END_OF_FILE:
{
yy_did_buffer_switch_on_eof = 0;
if ( yywrap() )
{
/* Note: because we've taken care in
* yy_get_next_buffer() to have set up
* yytext, we can now set up
* yy_c_buf_p so that if some total
* hoser (like flex itself) wants to
* call the scanner after we return the
* YY_NULL, it'll still work - another
* YY_NULL will get returned.
*/
yy_c_buf_p = yytext_ptr + YY_MORE_ADJ;
yy_act = YY_STATE_EOF(YY_START);
goto do_action;
}
else
{
if ( ! yy_did_buffer_switch_on_eof )
YY_NEW_FILE;
}
break;
}
case EOB_ACT_CONTINUE_SCAN:
yy_c_buf_p =
yytext_ptr + yy_amount_of_matched_text;
yy_current_state = yy_get_previous_state();
yy_cp = yy_c_buf_p;
yy_bp = yytext_ptr + YY_MORE_ADJ;
goto yy_match;
case EOB_ACT_LAST_MATCH:
yy_c_buf_p =
&yy_current_buffer->yy_ch_buf[yy_n_chars];
yy_current_state = yy_get_previous_state();
yy_cp = yy_c_buf_p;
yy_bp = yytext_ptr + YY_MORE_ADJ;
goto yy_find_action;
}
break;
}
default:
YY_FATAL_ERROR(
"fatal flex scanner internal error--no action found" );
} /* end of action switch */
} /* end of scanning one token */
} /* end of yylex */
/* yy_get_next_buffer - try to read in a new buffer
*
* Returns a code representing an action:
* EOB_ACT_LAST_MATCH -
* EOB_ACT_CONTINUE_SCAN - continue scanning from current position
* EOB_ACT_END_OF_FILE - end of file
*/
static int yy_get_next_buffer()
{
register char *dest = yy_current_buffer->yy_ch_buf;
register char *source = yytext_ptr;
register int number_to_move, i;
int ret_val;
if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] )
YY_FATAL_ERROR(
"fatal flex scanner internal error--end of buffer missed" );
if ( yy_current_buffer->yy_fill_buffer == 0 )
{ /* Don't try to fill the buffer, so this is an EOF. */
if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 )
{
/* We matched a single character, the EOB, so
* treat this as a final EOF.
*/
return EOB_ACT_END_OF_FILE;
}
else
{
/* We matched some text prior to the EOB, first
* process it.
*/
return EOB_ACT_LAST_MATCH;
}
}
/* Try to read more data. */
/* First move last chars to start of buffer. */
number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1;
for ( i = 0; i < number_to_move; ++i )
*(dest++) = *(source++);
if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING )
/* don't do the read, it's not guaranteed to return an EOF,
* just force an EOF
*/
yy_current_buffer->yy_n_chars = yy_n_chars = 0;
else
{
int num_to_read =
yy_current_buffer->yy_buf_size - number_to_move - 1;
while ( num_to_read <= 0 )
{ /* Not enough room in the buffer - grow it. */
#ifdef YY_USES_REJECT
YY_FATAL_ERROR(
"input buffer overflow, can't enlarge buffer because scanner uses REJECT" );
#else
/* just a shorter name for the current buffer */
YY_BUFFER_STATE b = yy_current_buffer;
int yy_c_buf_p_offset =
(int) (yy_c_buf_p - b->yy_ch_buf);
if ( b->yy_is_our_buffer )
{
int new_size = b->yy_buf_size * 2;
if ( new_size <= 0 )
b->yy_buf_size += b->yy_buf_size / 8;
else
b->yy_buf_size *= 2;
b->yy_ch_buf = (char *)
/* Include room in for 2 EOB chars. */
yy_flex_realloc( (void *) b->yy_ch_buf,
b->yy_buf_size + 2 );
}
else
/* Can't grow it, we don't own it. */
b->yy_ch_buf = 0;
if ( ! b->yy_ch_buf )
YY_FATAL_ERROR(
"fatal error - scanner input buffer overflow" );
yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset];
num_to_read = yy_current_buffer->yy_buf_size -
number_to_move - 1;
#endif
}
if ( num_to_read > YY_READ_BUF_SIZE )
num_to_read = YY_READ_BUF_SIZE;
/* Read in more data. */
YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]),
yy_n_chars, num_to_read );
yy_current_buffer->yy_n_chars = yy_n_chars;
}
if ( yy_n_chars == 0 )
{
if ( number_to_move == YY_MORE_ADJ )
{
ret_val = EOB_ACT_END_OF_FILE;
yyrestart( yyin );
}
else
{
ret_val = EOB_ACT_LAST_MATCH;
yy_current_buffer->yy_buffer_status =
YY_BUFFER_EOF_PENDING;
}
}
else
ret_val = EOB_ACT_CONTINUE_SCAN;
yy_n_chars += number_to_move;
yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR;
yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
yytext_ptr = &yy_current_buffer->yy_ch_buf[0];
return ret_val;
}
/* yy_get_previous_state - get the state just before the EOB char was reached */
static yy_state_type yy_get_previous_state()
{
register yy_state_type yy_current_state;
register char *yy_cp;
yy_current_state = yy_start;
yy_current_state += YY_AT_BOL();
for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp )
{
register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
if ( yy_accept[yy_current_state] )
{
yy_last_accepting_state = yy_current_state;
yy_last_accepting_cpos = yy_cp;
}
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{
yy_current_state = (int) yy_def[yy_current_state];
if ( yy_current_state >= 492 )
yy_c = yy_meta[(unsigned int) yy_c];
}
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
}
return yy_current_state;
}
/* yy_try_NUL_trans - try to make a transition on the NUL character
*
* synopsis
* next_state = yy_try_NUL_trans( current_state );
*/
#ifdef YY_USE_PROTOS
static yy_state_type yy_try_NUL_trans( yy_state_type yy_current_state )
#else
static yy_state_type yy_try_NUL_trans( yy_current_state )
yy_state_type yy_current_state;
#endif
{
register int yy_is_jam;
register char *yy_cp = yy_c_buf_p;
register YY_CHAR yy_c = 1;
if ( yy_accept[yy_current_state] )
{
yy_last_accepting_state = yy_current_state;
yy_last_accepting_cpos = yy_cp;
}
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{
yy_current_state = (int) yy_def[yy_current_state];
if ( yy_current_state >= 492 )
yy_c = yy_meta[(unsigned int) yy_c];
}
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
yy_is_jam = (yy_current_state == 491);
return yy_is_jam ? 0 : yy_current_state;
}
#ifndef YY_NO_UNPUT
#ifdef YY_USE_PROTOS
static void yyunput( int c, register char *yy_bp )
#else
static void yyunput( c, yy_bp )
int c;
register char *yy_bp;
#endif
{
register char *yy_cp = yy_c_buf_p;
/* undo effects of setting up yytext */
*yy_cp = yy_hold_char;
if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
{ /* need to shift things up to make room */
/* +2 for EOB chars. */
register int number_to_move = yy_n_chars + 2;
register char *dest = &yy_current_buffer->yy_ch_buf[
yy_current_buffer->yy_buf_size + 2];
register char *source =
&yy_current_buffer->yy_ch_buf[number_to_move];
while ( source > yy_current_buffer->yy_ch_buf )
*--dest = *--source;
yy_cp += (int) (dest - source);
yy_bp += (int) (dest - source);
yy_current_buffer->yy_n_chars =
yy_n_chars = yy_current_buffer->yy_buf_size;
if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
YY_FATAL_ERROR( "flex scanner push-back overflow" );
}
*--yy_cp = (char) c;
yytext_ptr = yy_bp;
yy_hold_char = *yy_cp;
yy_c_buf_p = yy_cp;
}
#endif /* ifndef YY_NO_UNPUT */
#ifdef __cplusplus
static int yyinput()
#else
static int input()
#endif
{
int c;
*yy_c_buf_p = yy_hold_char;
if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR )
{
/* yy_c_buf_p now points to the character we want to return.
* If this occurs *before* the EOB characters, then it's a
* valid NUL; if not, then we've hit the end of the buffer.
*/
if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] )
/* This was really a NUL. */
*yy_c_buf_p = '\0';
else
{ /* need more input */
int offset = yy_c_buf_p - yytext_ptr;
++yy_c_buf_p;
switch ( yy_get_next_buffer() )
{
case EOB_ACT_LAST_MATCH:
/* This happens because yy_g_n_b()
* sees that we've accumulated a
* token and flags that we need to
* try matching the token before
* proceeding. But for input(),
* there's no matching to consider.
* So convert the EOB_ACT_LAST_MATCH
* to EOB_ACT_END_OF_FILE.
*/
/* Reset buffer status. */
yyrestart( yyin );
/* fall through */
case EOB_ACT_END_OF_FILE:
{
if ( yywrap() )
return EOF;
if ( ! yy_did_buffer_switch_on_eof )
YY_NEW_FILE;
#ifdef __cplusplus
return yyinput();
#else
return input();
#endif
}
case EOB_ACT_CONTINUE_SCAN:
yy_c_buf_p = yytext_ptr + offset;
break;
}
}
}
c = *(unsigned char *) yy_c_buf_p; /* cast for 8-bit char's */
*yy_c_buf_p = '\0'; /* preserve yytext */
yy_hold_char = *++yy_c_buf_p;
yy_current_buffer->yy_at_bol = (c == '\n');
return c;
}
#ifdef YY_USE_PROTOS
void yyrestart( FILE *input_file )
#else
void yyrestart( input_file )
FILE *input_file;
#endif
{
if ( ! yy_current_buffer )
yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE );
yy_init_buffer( yy_current_buffer, input_file );
yy_load_buffer_state();
}
#ifdef YY_USE_PROTOS
void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer )
#else
void yy_switch_to_buffer( new_buffer )
YY_BUFFER_STATE new_buffer;
#endif
{
if ( yy_current_buffer == new_buffer )
return;
if ( yy_current_buffer )
{
/* Flush out information for old buffer. */
*yy_c_buf_p = yy_hold_char;
yy_current_buffer->yy_buf_pos = yy_c_buf_p;
yy_current_buffer->yy_n_chars = yy_n_chars;
}
yy_current_buffer = new_buffer;
yy_load_buffer_state();
/* We don't actually know whether we did this switch during
* EOF (yywrap()) processing, but the only time this flag
* is looked at is after yywrap() is called, so it's safe
* to go ahead and always set it.
*/
yy_did_buffer_switch_on_eof = 1;
}
#ifdef YY_USE_PROTOS
void yy_load_buffer_state( void )
#else
void yy_load_buffer_state()
#endif
{
yy_n_chars = yy_current_buffer->yy_n_chars;
yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos;
yyin = yy_current_buffer->yy_input_file;
yy_hold_char = *yy_c_buf_p;
}
#ifdef YY_USE_PROTOS
YY_BUFFER_STATE yy_create_buffer( FILE *file, int size )
#else
YY_BUFFER_STATE yy_create_buffer( file, size )
FILE *file;
int size;
#endif
{
YY_BUFFER_STATE b;
b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) );
if ( ! b )
YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
b->yy_buf_size = size;
/* yy_ch_buf has to be 2 characters longer than the size given because
* we need to put in 2 end-of-buffer characters.
*/
b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 );
if ( ! b->yy_ch_buf )
YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
b->yy_is_our_buffer = 1;
yy_init_buffer( b, file );
return b;
}
#ifdef YY_USE_PROTOS
void yy_delete_buffer( YY_BUFFER_STATE b )
#else
void yy_delete_buffer( b )
YY_BUFFER_STATE b;
#endif
{
if ( ! b )
return;
if ( b == yy_current_buffer )
yy_current_buffer = (YY_BUFFER_STATE) 0;
if ( b->yy_is_our_buffer )
yy_flex_free( (void *) b->yy_ch_buf );
yy_flex_free( (void *) b );
}
#ifndef YY_ALWAYS_INTERACTIVE
#ifndef YY_NEVER_INTERACTIVE
extern int isatty YY_PROTO(( int ));
#endif
#endif
#ifdef YY_USE_PROTOS
void yy_init_buffer( YY_BUFFER_STATE b, FILE *file )
#else
void yy_init_buffer( b, file )
YY_BUFFER_STATE b;
FILE *file;
#endif
{
yy_flush_buffer( b );
b->yy_input_file = file;
b->yy_fill_buffer = 1;
#if YY_ALWAYS_INTERACTIVE
b->yy_is_interactive = 1;
#else
#if YY_NEVER_INTERACTIVE
b->yy_is_interactive = 0;
#else
b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
#endif
#endif
}
#ifdef YY_USE_PROTOS
void yy_flush_buffer( YY_BUFFER_STATE b )
#else
void yy_flush_buffer( b )
YY_BUFFER_STATE b;
#endif
{
if ( ! b )
return;
b->yy_n_chars = 0;
/* We always need two end-of-buffer characters. The first causes
* a transition to the end-of-buffer state. The second causes
* a jam in that state.
*/
b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
b->yy_buf_pos = &b->yy_ch_buf[0];
b->yy_at_bol = 1;
b->yy_buffer_status = YY_BUFFER_NEW;
if ( b == yy_current_buffer )
yy_load_buffer_state();
}
#ifndef YY_NO_SCAN_BUFFER
#ifdef YY_USE_PROTOS
YY_BUFFER_STATE yy_scan_buffer( char *base, yy_size_t size )
#else
YY_BUFFER_STATE yy_scan_buffer( base, size )
char *base;
yy_size_t size;
#endif
{
YY_BUFFER_STATE b;
if ( size < 2 ||
base[size-2] != YY_END_OF_BUFFER_CHAR ||
base[size-1] != YY_END_OF_BUFFER_CHAR )
/* They forgot to leave room for the EOB's. */
return 0;
b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) );
if ( ! b )
YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */
b->yy_buf_pos = b->yy_ch_buf = base;
b->yy_is_our_buffer = 0;
b->yy_input_file = 0;
b->yy_n_chars = b->yy_buf_size;
b->yy_is_interactive = 0;
b->yy_at_bol = 1;
b->yy_fill_buffer = 0;
b->yy_buffer_status = YY_BUFFER_NEW;
yy_switch_to_buffer( b );
return b;
}
#endif
#ifndef YY_NO_SCAN_STRING
#ifdef YY_USE_PROTOS
YY_BUFFER_STATE yy_scan_string( yyconst char *yy_str )
#else
YY_BUFFER_STATE yy_scan_string( yy_str )
yyconst char *yy_str;
#endif
{
int len;
for ( len = 0; yy_str[len]; ++len )
;
return yy_scan_bytes( yy_str, len );
}
#endif
#ifndef YY_NO_SCAN_BYTES
#ifdef YY_USE_PROTOS
YY_BUFFER_STATE yy_scan_bytes( yyconst char *bytes, int len )
#else
YY_BUFFER_STATE yy_scan_bytes( bytes, len )
yyconst char *bytes;
int len;
#endif
{
YY_BUFFER_STATE b;
char *buf;
yy_size_t n;
int i;
/* Get memory for full buffer, including space for trailing EOB's. */
n = len + 2;
buf = (char *) yy_flex_alloc( n );
if ( ! buf )
YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
for ( i = 0; i < len; ++i )
buf[i] = bytes[i];
buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR;
b = yy_scan_buffer( buf, n );
if ( ! b )
YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
/* It's okay to grow etc. this buffer, and we should throw it
* away when we're done.
*/
b->yy_is_our_buffer = 1;
return b;
}
#endif
#ifndef YY_NO_PUSH_STATE
#ifdef YY_USE_PROTOS
static void yy_push_state( int new_state )
#else
static void yy_push_state( new_state )
int new_state;
#endif
{
if ( yy_start_stack_ptr >= yy_start_stack_depth )
{
yy_size_t new_size;
yy_start_stack_depth += YY_START_STACK_INCR;
new_size = yy_start_stack_depth * sizeof( int );
if ( ! yy_start_stack )
yy_start_stack = (int *) yy_flex_alloc( new_size );
else
yy_start_stack = (int *) yy_flex_realloc(
(void *) yy_start_stack, new_size );
if ( ! yy_start_stack )
YY_FATAL_ERROR(
"out of memory expanding start-condition stack" );
}
yy_start_stack[yy_start_stack_ptr++] = YY_START;
BEGIN(new_state);
}
#endif
#ifndef YY_NO_POP_STATE
static void yy_pop_state()
{
if ( --yy_start_stack_ptr < 0 )
YY_FATAL_ERROR( "start-condition stack underflow" );
BEGIN(yy_start_stack[yy_start_stack_ptr]);
}
#endif
#ifndef YY_NO_TOP_STATE
static int yy_top_state()
{
return yy_start_stack[yy_start_stack_ptr - 1];
}
#endif
#ifndef YY_EXIT_FAILURE
#define YY_EXIT_FAILURE 2
#endif
#ifdef YY_USE_PROTOS
static void yy_fatal_error( yyconst char msg[] )
#else
static void yy_fatal_error( msg )
char msg[];
#endif
{
(void) fprintf( stderr, "%s\n", msg );
exit( YY_EXIT_FAILURE );
}
/* Redefine yyless() so it works in section 3 code. */
#undef yyless
#define yyless(n) \
do \
{ \
/* Undo effects of setting up yytext. */ \
yytext[yyleng] = yy_hold_char; \
yy_c_buf_p = yytext + n; \
yy_hold_char = *yy_c_buf_p; \
*yy_c_buf_p = '\0'; \
yyleng = n; \
} \
while ( 0 )
/* Internal utility routines. */
#ifndef yytext_ptr
#ifdef YY_USE_PROTOS
static void yy_flex_strncpy( char *s1, yyconst char *s2, int n )
#else
static void yy_flex_strncpy( s1, s2, n )
char *s1;
yyconst char *s2;
int n;
#endif
{
register int i;
for ( i = 0; i < n; ++i )
s1[i] = s2[i];
}
#endif
#ifdef YY_NEED_STRLEN
#ifdef YY_USE_PROTOS
static int yy_flex_strlen( yyconst char *s )
#else
static int yy_flex_strlen( s )
yyconst char *s;
#endif
{
register int n;
for ( n = 0; s[n]; ++n )
;
return n;
}
#endif
#ifdef YY_USE_PROTOS
static void *yy_flex_alloc( yy_size_t size )
#else
static void *yy_flex_alloc( size )
yy_size_t size;
#endif
{
return (void *) malloc( size );
}
#ifdef YY_USE_PROTOS
static void *yy_flex_realloc( void *ptr, yy_size_t size )
#else
static void *yy_flex_realloc( ptr, size )
void *ptr;
yy_size_t size;
#endif
{
/* The cast to (char *) in the following accommodates both
* implementations that use char* generic pointers, and those
* that use void* generic pointers. It works with the latter
* because both ANSI C and C++ allow castless assignment from
* any pointer type to void*, and deal with argument conversions
* as though doing an assignment.
*/
return (void *) realloc( (char *) ptr, size );
}
#ifdef YY_USE_PROTOS
static void yy_flex_free( void *ptr )
#else
static void yy_flex_free( ptr )
void *ptr;
#endif
{
free( ptr );
}
#if YY_MAIN
int main()
{
yylex();
return 0;
}
#endif
#line 324 "..\\src\\VPreLex.l"
void VPreLex::pushStateDefArg(int level) {
// Enter define substitution argument state
yy_push_state(ARGMODE);
m_parenLevel = level;
m_defValue = "";
}
void VPreLex::pushStateDefForm() {
// Enter define formal arguments state
yy_push_state(DEFFPAR); // First is an optional ( to begin args
m_parenLevel = 0;
m_defValue = "";
}
void VPreLex::pushStateDefValue() {
// Enter define value state
yy_push_state(DEFVAL);
m_parenLevel = 0;
m_defValue = "";
}
void VPreLex::pushStateIncFilename() {
// Enter include <> filename state
yy_push_state(INCMODE);
yymore();
}
void VPreLex::debug(int level) {
//#ifdef FLEX_DEBUG
// yy_flex_debug=0;
//#endif
}
int VPreLex::debug() {
#ifdef FLEX_DEBUG
return yy_flex_debug;
#else
return 0;
#endif
}
int VPreLex::lex() {
VPreLex::s_currentLexp = this; // Tell parser where to get/put data
m_tokFilelinep = curFilelinep(); // Remember token start location, may be updated by the lexer later
return yylex();
}
size_t VPreLex::inputToLex(char* buf, size_t max_size) {
// We need a custom YY_INPUT because we can't use flex buffers.
// Flex buffers are limited to 2GB, and we can't chop into 2G pieces
// because buffers can't end in the middle of tokens.
// Note if we switched streams here (which we don't) "buf" would be
// become a stale invalid pointer.
//
VPreStream* streamp = curStreamp();
if (debug()>=10) { cout<<"- pp:inputToLex ITL s="<<max_size<<" bs="<<streamp->m_buffers.size()<<endl; dumpStack(); }
// For testing, use really small chunks
//if (max_size > 13) max_size=13;
again:
size_t got = 0;
// Get from this stream
while (got < max_size // Haven't got enough
&& !streamp->m_buffers.empty()) { // And something buffered
string front = curStreamp()->m_buffers.front(); streamp->m_buffers.pop_front();
size_t len = front.length();
if (len > (max_size-got)) { // Front string too big
len = (max_size-got);
string remainder = front.substr(len);
front = front.substr(0, len);
streamp->m_buffers.push_front(remainder); // Put back remainder for next time
}
strncpy(buf+got, front.c_str(), len);
got += len;
}
if (!got) { // end of stream; try "above" file
bool again=false;
string forceOut = endOfStream(again/*ref*/);
streamp = curStreamp(); // May have been updated
if (forceOut != "") {
if (forceOut.length() > max_size) {
yyerror_f("Output buffer too small for a `line");
} else {
got = forceOut.length();
strncpy(buf, forceOut.c_str(), got);
}
} else {
if (streamp->m_eof) {
if (debug()) cout<<"- EOF\n";
}
got = 0; // 0=EOF/EOS - although got was already 0.
if (again) goto again;
}
}
// if (true) { cout<<"- pp::inputToLex got="<<got<<" '"<<string(buf,got)<<"'"<<endl; }
return got;
}
string VPreLex::endOfStream(bool& againr) {
// Switch to file or next unputString
// VPreProcImp *iimp = this->m_preimpp;
againr = false;
dumpStack();
if (debug())
{
// cout<<"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"<<endl;
// cout<<iimp->m_lineChars<<endl;
// cout<<"-EOS state="<<curStreamp()->m_termState<<" at "<<curFilelinep()<<endl;
// cout<<"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"<<endl;
}
if (curStreamp()->m_eof) return ""; // Don't delete the final "EOF" stream
bool exited_file = curStreamp()->m_file;
if (!exited_file) {
// Midpoint of stream, just change buffers
delete curStreamp();
m_streampStack.pop(); // Must work as size>1; EOF is entry 0
againr = true;
return "";
}
// Multiple steps because we need FLEX to see ending \n and EOS to end
// any illegal states, like an unterminated `protected region
else if (!curStreamp()->m_termState) {
// First shutdown phase for a file
// Terminate all files with a newline. This prevents problems if
// the user had a define without a terminating newline,
// otherwise the resumed file's next line would get tacked on.
// Also makes it likely the `line that changes files comes out
// immediately.
curStreamp()->m_termState = 1;
return "\n"; // Exit old file
}
else if (curStreamp()->m_termState == 1) {
// Now the EOF - can't be sent with other characters
curStreamp()->m_termState = 2;
return ""; // End of file
}
else if (curStreamp()->m_termState == 2) {
// Now ending `line
curStreamp()->m_termState = 3;
return curFilelinep()->lineDirectiveStrg(2); // Exit old file
}
else {
// Final shutdown phase for a stream, we can finally change the
// current fileline to the new stream
curStreamp()->m_termState = 0;
VFileLine* filelinep = curFilelinep();
delete curStreamp();
m_streampStack.pop(); // Must work as size>1; EOF is entry 0
if (curStreamp()->m_eof) {
// EOF doesn't have a "real" fileline, but a linenumber of 0 from init time
// Inherit whatever we last parsed so it's more obvious.
curFilelinep(filelinep);
}
// The caller parser remembered the start location for the text we are parsing,
// but we've discovered there was a file switch along the way, so update it.
m_tokFilelinep = curFilelinep();
//
if (curStreamp()->m_eof) {
return "";
} else {
return curFilelinep()->lineDirectiveStrg(0); // Reenter resumed file
}
}
}
void VPreLex::initFirstBuffer(VFileLine* filelinep) {
// Called from constructor to make first buffer
// yy_create_buffer also sets yy_fill_buffer=1 so reads from YY_INPUT
VPreStream* streamp = new VPreStream(filelinep, this);
streamp->m_eof = true;
m_streampStack.push(streamp);
//
m_bufferState = yy_create_buffer(NULL, YY_BUF_SIZE);
yy_switch_to_buffer(m_bufferState);
yyrestart(NULL);
}
void VPreLex::scanNewFile(VFileLine* filelinep) {
// Called on new open file. scanBytesBack will be called next.
if (streamDepth() > VPreProc::DEFINE_RECURSION_LEVEL_MAX) {
// The recursive `include in VPreProcImp should trigger first
yyerror_f("Recursive `define or other nested inclusion");
curStreamp()->m_eof = true; // Fake it to stop recursion
} else {
VPreStream* streamp = new VPreStream(filelinep, this);
m_tokFilelinep = curFilelinep();
streamp->m_file = true;
scanSwitchStream(streamp);
}
}
void VPreLex::scanBytes(const string& str) {
// Note buffers also appended in ::scanBytesBack
// Not "m_buffers.push_front(string(strp,len))" as we need a `define
// to take effect immediately, in the middle of the current buffer
// Also we don't use scan_bytes that would set yy_fill_buffer
// which would force Flex to bypass our YY_INPUT routine.
if (streamDepth() > VPreProc::DEFINE_RECURSION_LEVEL_MAX) {
// More streams if recursive `define with complex insertion
// More buffers mostly if something internal goes funky
yyerror_f("Recursive `define or other nested inclusion");
curStreamp()->m_eof = true; // Fake it to stop recursion
} else {
VPreStream* streamp = new VPreStream(curFilelinep(), this);
streamp->m_buffers.push_front(str);
scanSwitchStream(streamp);
}
}
void VPreLex::scanSwitchStream(VPreStream* streamp) {
curStreamp()->m_buffers.push_front(currentUnreadChars());
m_streampStack.push(streamp);
yyrestart(NULL);
}
void VPreLex::scanBytesBack(const string& str) {
// Initial creation, that will pull from YY_INPUT==inputToLex
// Note buffers also appended in ::scanBytes
if (curStreamp()->m_eof) yyerror_f("scanBytesBack without being under scanNewFile");
curStreamp()->m_buffers.push_back(str);
}
string VPreLex::currentUnreadChars() {
// WARNING - Peeking at internals
if (!currentBuffer()) return "";
ussize_t left = (yy_n_chars - (yy_c_buf_p - currentBuffer()->yy_ch_buf));
if (left > 0) { // left may be -1 at EOS
*(yy_c_buf_p) = (yy_hold_char);
return string(yy_c_buf_p, left);
} else {
return "";
}
}
YY_BUFFER_STATE VPreLex::currentBuffer() {
return YY_CURRENT_BUFFER;
}
char* VPreLex::getInputBuffer() {
return currentBuffer()->yy_ch_buf;
}
char* VPreLex::getInputBuffer1() {
return m_bufferState->yy_ch_buf;
}
int VPreLex::currentStartState() {
return YY_START;
}
void VPreLex::dumpSummary() {
return;
//cout<<"- pp::dumpSummary curBuf="<<(void*)(currentBuffer());
#ifdef FLEX_DEBUG // Else peeking at internals may cause portability issues
ussize_t left = (yy_n_chars
- (yy_c_buf_p
-currentBuffer()->yy_ch_buf));
// cout<<" left="<<dec<<left;
#endif
cout<<endl;
}
int VPreLex::getBufSize()
{
return (yy_n_chars - (yy_c_buf_p-currentBuffer()->yy_ch_buf));
}
void VPreLex::dumpStack() {
// For debug use
return;
dumpSummary();
stack<VPreStream*> tmpstack = LEXP->m_streampStack;
while (!tmpstack.empty()) {
VPreStream* streamp = tmpstack.top();
cout<<"- bufferStack["<<(void*)(streamp)<<"]: "
<<" at="<<streamp->m_curFilelinep
<<" nBuf="<<streamp->m_buffers.size()
<<" size0="<<(streamp->m_buffers.empty() ? 0 : streamp->m_buffers.front().length())
<<(streamp->m_eof?" [EOF]":"")
<<(streamp->m_file?" [FILE]":"");
cout<<endl;
tmpstack.pop();
}
}
string VPreLex::cleanDbgStrg(const string& in) {
string out = in;
string::size_type pos;
while ((pos=out.find("\n")) != string::npos) { out.replace(pos, 1, "\\n"); }
while ((pos=out.find("\r")) != string::npos) { out.replace(pos, 1, "\\r"); }
return out;
}
void VPreLex::unused() {
if (0) {
// Prevent unused warnings
yy_top_state();
}
}
void VPreLex::initBuffer(const string & buf) {
m_bufferState = yy_create_buffer(NULL, YY_BUF_SIZE);
yy_switch_to_buffer(m_bufferState);
yyrestart(NULL);
scanBytes(buf);
}
/*###################################################################
* Local Variables:
* mode: C++
* End:
*/
// -*- C++ -*-
//*************************************************************************
//
// Copyright 2000-2013 by Wilson Snyder. This program is free software;
// you can redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License Version 2.0.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
//*************************************************************************
/// \file
/// \brief Verilog::Preproc: Internal header for lex interfacing
///
/// Authors: Wilson Snyder
///
/// Code available from: http://www.veripool.org/verilog-perl
///
/// This header provides the interface between the lex proper VPreLex.l/.cpp
/// and the class implementation file VPreProc.cpp
/// It is not intended for user applications.
///
//*************************************************************************
#ifndef _VPREPROCLEX_H_ // Guard
#define _VPREPROCLEX_H_ 1
#include <deque>
#include <stack>
#include "VFileLine.h"
#include "VPreProc.h"
class VPreLex;
struct VPreProcImp;
//======================================================================
// Token codes
// If changing, see VPreProc.cpp's VPreProcImp::tokenName()
#define VP_EOF 0
#define VP_INCLUDE 256
#define VP_IFDEF 257
#define VP_IFNDEF 258
#define VP_ENDIF 259
#define VP_UNDEF 260
#define VP_DEFINE 261
#define VP_ELSE 262
#define VP_ELSIF 263
#define VP_LINE 264
#define VP_UNDEFINEALL 265
#define VP_SYMBOL 300
#define VP_STRING 301
#define VP_DEFVALUE 302
#define VP_COMMENT 303
#define VP_TEXT 304
#define VP_WHITE 305
#define VP_DEFREF 306
#define VP_DEFARG 307
#define VP_ERROR 308
#define VP_DEFFORM 309
#define VP_STRIFY 310
#define VP_BACKQUOTE 311
#define VP_SYMBOL_JOIN 312
#define VP_DEFREF_JOIN 313
#define VP_PSL 350
//======================================================================
// Externs created by flex
// We add a prefix so that other lexers/flexers in the same program won't collide.
#ifndef yy_create_buffer
# define yy_create_buffer VPreLex_create_buffer
# define yy_delete_buffer VPreLex_delete_buffer
# define yy_scan_buffer VPreLex_scan_buffer
# define yy_scan_string VPreLex_scan_string
# define yy_scan_bytes VPreLex_scan_bytes
# define yy_flex_debug VPreLex_flex_debug
# define yy_init_buffer VPreLex_init_buffer
# define yy_flush_buffer VPreLex_flush_buffer
# define yy_load_buffer_state VPreLex_load_buffer_state
# define yy_switch_to_buffer VPreLex_switch_to_buffer
# define yyin VPreLexin
# define yyleng VPreLexleng
# define yylex VPreLexlex
# define yyout VPreLexout
# define yyrestart VPreLexrestart
# define yytext VPreLextext
#endif
#ifndef yyourleng
# define yyourleng VPreLexourleng
# define yyourtext VPreLexourtext
#endif
#ifndef YY_BUFFER_STATE
struct yy_buffer_state;
typedef struct yy_buffer_state *YY_BUFFER_STATE;
# define YY_BUF_SIZE 16384
#endif
extern int yylex();
extern void yyrestart(FILE*);
// Accessors, because flex keeps changing the type of yyleng
extern char* yyourtext();
extern size_t yyourleng();
extern void yyourtext(const char* textp, size_t size); // Must call with static
YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size );
void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer );
void yy_delete_buffer( YY_BUFFER_STATE b );
//======================================================================
#define KEEPCMT_SUB 2
#define KEEPCMT_EXP 3
//======================================================================
// Entry for each file processed; a stack of entries included
class VPreStream {
public:
VFileLine* m_curFilelinep; // Current processing point (see also m_tokFilelinep)
VPreLex* m_lexp; // Lexer, for resource tracking
deque<string> m_buffers; // Buffer of characters to process
int m_ignNewlines; // Ignore multiline newlines
bool m_eof; // "EOF" buffer
bool m_file; // Buffer is start of new file
int m_termState; // Termination fsm
VPreStream(VFileLine* fl, VPreLex* lexp)
: m_curFilelinep(fl), m_lexp(lexp),
m_ignNewlines(0),
m_eof(false), m_file(false), m_termState(0) {
lexStreamDepthAdd(1);
}
~VPreStream() {
lexStreamDepthAdd(-1);
}
private:
void lexStreamDepthAdd(int delta);
};
//======================================================================
// Class entry for each per-lexer state
class VPreLex {
public: // Used only by VPreLex.cpp and VPreProc.cpp
VPreProcImp* m_preimpp; // Preprocessor lexor belongs to
stack<VPreStream*> m_streampStack; // Stack of processing files
int m_streamDepth; // Depth of stream processing
void debugErr()
{
// cout<<m_preimpp->m_lineChars()<<endl;
}
int getBufSize(); // return the current size of unread string
char* getInputBuffer();
char* getInputBuffer1();
void initBuffer(const string & buf);
YY_BUFFER_STATE m_bufferState; // Flex state
VFileLine* m_tokFilelinep; // Starting position of current token
// State to lexer
static VPreLex* s_currentLexp; ///< Current lexing point
int m_keepComments; ///< Emit comments in output text
int m_keepWhitespace; ///< Emit all whitespace in output text
bool m_pedantic; ///< Obey standard; don't Substitute `error
bool m_synthesis; ///< Remove translate_offs
// State from lexer
int m_formalLevel; ///< Parenthesis counting inside def formals
int m_parenLevel; ///< Parenthesis counting inside def args
bool m_defCmtSlash; ///< /*...*/ comment in define had \ ending
string m_defValue; ///< Definition value being built.
int m_enterExit; ///< For VL_LINE, the enter/exit level
// CONSTRUCTORS
VPreLex(VPreProcImp* preimpp, VFileLine* filelinep) {
m_preimpp = preimpp;
m_streamDepth = 0;
m_keepComments = 0;
m_keepWhitespace = 1;
m_pedantic = false;
m_synthesis = false;
m_formalLevel = 0;
m_parenLevel = 0;
m_defCmtSlash = false;
m_tokFilelinep = filelinep;
m_enterExit = 0;
initFirstBuffer(filelinep);
}
~VPreLex() {
while (!m_streampStack.empty()) { delete m_streampStack.top(); m_streampStack.pop(); }
yy_delete_buffer(m_bufferState); m_bufferState=NULL;
}
/// Called by VPreLex.l from lexer
VPreStream* curStreamp() { return m_streampStack.top(); } // Can't be empty, "EOF" is on top
VFileLine* curFilelinep() { return curStreamp()->m_curFilelinep; }
void curFilelinep(VFileLine* fl) { curStreamp()->m_curFilelinep = fl; }
void appendDefValue(const char* textp, size_t len)
{
m_defValue.append(textp,len);
}
void lineDirective(const char* textp) { curFilelinep(curFilelinep()->lineDirective(textp, m_enterExit/*ref*/)); }
void linenoInc() { if (curStreamp()->m_ignNewlines) curStreamp()->m_ignNewlines--;
else curFilelinep(curFilelinep()->create(curFilelinep()->lineno()+1)); }
/// Called by VPreProc.cpp to inform lexer
void pushStateDefArg(int level);
void pushStateDefForm();
void pushStateDefValue();
void pushStateIncFilename();
void scanNewFile(VFileLine* filelinep);
void scanBytes(const string& str);
void scanBytesBack(const string& str);
size_t inputToLex(char* buf, size_t max_size);
/// Called by VPreProc.cpp to get data from lexer
YY_BUFFER_STATE currentBuffer();
int lex();
int currentStartState();
void dumpSummary();
void dumpStack();
void unused();
// Called by VPreStream
void streamDepthAdd(int delta) { m_streamDepth += delta; }
int streamDepth() const { return m_streamDepth; }
/// Utility
static int debug();
static void debug(int level);
static string cleanDbgStrg(const string& in);
string currentUnreadChars();
private:
string endOfStream(bool& againr);
void initFirstBuffer(VFileLine* filelinep);
void scanSwitchStream(VPreStream* streamp);
};
inline void VPreStream::lexStreamDepthAdd(int delta) { m_lexp->streamDepthAdd(delta); }
#endif // Guard
// -*- C++ -*-
//*************************************************************************
//
// Copyright 2000-2013 by Wilson Snyder. This program is free software;
// you can redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License Version 2.0.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
//*************************************************************************
/// \file
/// \brief Verilog::Preproc: Internal implementation of default preprocessor
///
/// Authors: Wilson Snyder
///
/// Code available from: http://www.veripool.org/verilog-perl
///
//*************************************************************************
#include <cstdio>
#include <cstdlib>
#include <fstream>
#include <cstring>
#include <stack>
#include <vector>
#include <map>
#include <list>
#include <cassert>
#include <cerrno>
#include "qcstring.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "portable.h"
#include "qcstring.h"
#include "qregexp.h"
#include "verilogdocgen.h"
#if defined(_WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__)
# include <io.h>
#else
# include <unistd.h>
#endif
#include "vhdldocgen.h"
#include "VPreProc.h"
#include "VPreLex.h"
#include "define.h"
#include "config.h"
#include "qfile.h"
static string sbuffer;
static string relBuffer;
static bool bEnable=false;
//#undef yyFlexLexer
//#define yyFlexLexer xxFlexLexer
//#include <FlexLexer.h>
//*************************************************************************
DefineDict *VerilogPreProc::g_fileDefineDict;
DefineDict *VerilogPreProc::g_preDefineDict;
typedef size_t ussize_t ;
class VPreDefRef {
// One for each pending define substitution
string m_name; // Define last name being defined
string m_params; // Define parameter list for next expansion
string m_nextarg; // String being built for next argument
int m_parenLevel; // Parenthesis counting inside def args (for PARENT not child)
vector<string> m_args; // List of define arguments
public:
string name() const { return m_name; }
string params() const { return m_params; }
string nextarg() const { return m_nextarg; }
void nextarg(const string& value) { m_nextarg = value; }
int parenLevel() const { return m_parenLevel; }
void parenLevel(int value) { m_parenLevel = value; }
vector<string>& args() { return m_args; }
VPreDefRef(const string& name, const string& params)
: m_name(name), m_params(params), m_parenLevel(0) {}
~VPreDefRef() {}
};
//*************************************************************************
/// Data for parsing on/off
class VPreIfEntry {
// One for each pending ifdef/ifndef
bool m_on; // Current parse for this ifdef level is "on"
bool m_everOn; // Some if term in elsif tree has been on
public:
bool on() const { return m_on; }
bool everOn() const { return m_everOn; }
VPreIfEntry(bool on, bool everOn)
: m_on(on), m_everOn(everOn || on)
{
ifName="--XX--";
int line=0;
}
// Note everOn includes new state
VPreIfEntry(bool on, bool everOn,string ifn,int i)
{
m_on=on;
m_everOn=everOn || on;
ifName=ifn;
int line=i;
}
int line;
string ifName;
~VPreIfEntry() {}
};
//*************************************************************************
/// Data for a preprocessor instantiation.
struct VPreProcImp : public VPreProcOpaque {
typedef list<string> StrList;
int getNextStateToken(string & buf);
VPreProc* m_preprocp; ///< Object we're holding data for
int m_debug; ///< Debugging level
VPreLex* m_lexp; ///< Current lexer state (NULL = closed)
enum ProcState { ps_TOP,
ps_DEFNAME_UNDEF, ps_DEFNAME_DEFINE,
ps_DEFNAME_IFDEF, ps_DEFNAME_IFNDEF, ps_DEFNAME_ELSIF,
ps_DEFFORM, ps_DEFVALUE, ps_DEFPAREN, ps_DEFARG,
ps_INCNAME, ps_ERRORNAME, ps_JOIN, ps_STRIFY };
const char* procStateName(ProcState s) {
static const char* states[]
= {"ps_TOP",
"ps_DEFNAME_UNDEF", "ps_DEFNAME_DEFINE",
"ps_DEFNAME_IFDEF", "ps_DEFNAME_IFNDEF", "ps_DEFNAME_ELSIF",
"ps_DEFFORM", "ps_DEFVALUE", "ps_DEFPAREN", "ps_DEFARG",
"ps_INCNAME", "ps_ERRORNAME", "ps_JOIN", "ps_STRIFY" };
return states[s];
};
stack<ProcState> m_states; ///< Current state of parser
int m_off; ///< If non-zero, ifdef level is turned off, don't dump text
string m_lastSym; ///< Last symbol name found.
string m_formals; ///< Last formals found
// For getRawToken/ `line insertion
string m_lineCmt; ///< Line comment(s) to be returned
bool m_lineCmtNl; ///< Newline needed before inserting lineCmt
int m_lineAdd; ///< Empty lines to return to maintain line count
bool m_rawAtBol; ///< Last rawToken left us at beginning of line
// For getFinalToken
bool m_finAhead; ///< Have read a token ahead
int m_finToken; ///< Last token read
string m_finBuf; ///< Last yytext read
bool m_finAtBol; ///< Last getFinalToken left us at beginning of line
VFileLine* m_finFilelinep; ///< Location of last returned token (internal only)
// For stringification
string m_strify; ///< Text to be stringified
// For defines
stack<VPreDefRef> m_defRefs; // Pending definine substitution
stack<VPreIfEntry> m_ifdefStack; ///< Stack of true/false emitting evaluations
unsigned m_defDepth; ///< How many `defines deep
bool m_defPutJoin; ///< Insert `` after substitution
// For `` join
stack<string> m_joinStack; ///< Text on lhs of join
// For getline()
string m_lineChars; ///< Characters left for next line
QCString m_QC;
string relString;
VPreProcImp() {
m_debug = 0;
m_states.push(ps_TOP);
m_off = 0;
m_lineChars = "";
m_lastSym = "";
m_lineAdd = 0;
m_lineCmtNl = false;
m_rawAtBol = true;
m_finAhead = false;
m_finAtBol = true;
m_defDepth = 0;
m_defPutJoin = false;
m_finToken = 0;
m_finFilelinep = NULL;
m_lexp = NULL;
m_preprocp = NULL;
}
void insertRelString(bool b);
string checkUndoc(string & buf,string & sb,bool undoc,int tok,int line,int i);
void configure(VFileLine* filelinep, VPreProc* preprocp) {
// configure() separate from constructor to avoid calling abstract functions
m_preprocp = preprocp;
m_finFilelinep = filelinep->create(1);
// Create lexer
m_lexp = new VPreLex (this, filelinep);
m_lexp->m_keepComments = m_preprocp->keepComments();
m_lexp->m_keepWhitespace = m_preprocp->keepWhitespace();
m_lexp->m_pedantic = m_preprocp->pedantic();
m_lexp->m_synthesis = m_preprocp->synthesis();
m_lexp->debug(debug()>=10 ? debug() : 0); // See also VPreProc::debug() method
}
~VPreProcImp() {
if (m_lexp) { delete m_lexp; m_lexp = NULL; }
}
const char* tokenName(int tok);
void debugToken(int tok, const char* cmtp);
void parseTop();
void parseUndef();
string getparseline(bool stop_at_eol, size_t approx_chunk);
bool isEof() const { return m_lexp->curStreamp()->m_eof; }
bool readWholefile(const string& filename, StrList& outl);
void openFile(string filename, VFileLine* filelinep);
void insertUnreadback(const string& text) { m_lineCmt += text; }
void insertUnreadbackAtBol(const string& text);
void addLineComment(int enter_exit_level);
private:
void error(string msg) { m_lexp->m_tokFilelinep->error(msg); }
void fatal(string msg) { m_lexp->m_tokFilelinep->fatal(msg); }
int debug() const { return m_debug; }
void endOfOneFile();
string defineSubst(VPreDefRef* refp);
string trimWhitespace(const string& strg, bool trailing);
void unputString(const string& strg);
void unputDefrefString(const string& strg);
void parsingOn() {
m_off--;
if (m_off<0) fatalSrc("Underflow of parsing cmds");
// addLineComment no longer needed; getFinalToken will correct.
}
void parsingOff() { m_off++; }
int getRawToken();
int getStateToken(string& buf);
int getFinalToken(string& buf);
void statePush(ProcState state) {
m_states.push(state);
}
void statePop() {
m_states.pop();
if (m_states.empty()) {
error("InternalError: Pop of parser state with nothing on stack");
m_states.push(ps_TOP);
}
}
void stateChange(ProcState state) {
statePop(); statePush(state);
}
};
//*************************************************************************
// Creation
VPreProc::VPreProc() {
VPreProcImp* idatap = new VPreProcImp();
m_opaquep = idatap;
// Below overridden by configure()
m_keepComments = true;
m_keepWhitespace = true;
m_lineDirectives = true;
m_pedantic = false;
m_synthesis = false;
}
void VPreProc::configure(VFileLine* filelinep) {
VPreProcImp* idatap = static_cast<VPreProcImp*>(m_opaquep);
idatap->configure(filelinep, this);
}
VPreProc::~VPreProc() {
if (m_opaquep) { delete m_opaquep; m_opaquep = NULL; }
}
//************************************************************************
// VPreProc Methods. Just call the implementation functions.
void VPreProc::comment(string cmt) { }
void VPreProc::openFile(string filename, VFileLine* filelinep) {
VPreProcImp* idatap = static_cast<VPreProcImp*>(m_opaquep);
idatap->openFile (filename,filelinep);
}
int VPreProc::getNextStateToken(string & buf)
{
VPreProcImp* idatap = static_cast<VPreProcImp*>(m_opaquep);
return idatap->getNextStateToken(buf);
}
string VPreProc::getline() {
VPreProcImp* idatap = static_cast<VPreProcImp*>(m_opaquep);
return idatap->getparseline(true,0);
}
string VPreProc::getall(size_t approx_chunk) {
VPreProcImp* idatap = static_cast<VPreProcImp*>(m_opaquep);
return idatap->getparseline(false,approx_chunk);
}
void VPreProc::debug(int level) {
VPreProcImp* idatap = static_cast<VPreProcImp*>(m_opaquep);
idatap->m_debug = level;
// To see "accepting rule" debug, Makefile.PL must be changed to enable flex debug
// export VERILOGPERL_FLEX_DEBUG=1
idatap->m_lexp->debug(level>=10 ? level : 0);
}
bool VPreProc::isEof() {
VPreProcImp* idatap = static_cast<VPreProcImp*>(m_opaquep);
return idatap->isEof();
}
VFileLine* VPreProc::fileline() {
VPreProcImp* idatap = static_cast<VPreProcImp*>(m_opaquep);
return idatap->m_lexp->m_tokFilelinep;
}
void VPreProc::insertUnreadback(string text) {
VPreProcImp* idatap = static_cast<VPreProcImp*>(m_opaquep);
return idatap->insertUnreadback(text);
}
//**********************************************************************
// Parser Utilities
const char* VPreProcImp::tokenName(int tok) {
switch (tok) {
case VP_BACKQUOTE : return("BACKQUOTE");
case VP_COMMENT : return("COMMENT");
case VP_DEFARG : return("DEFARG");
case VP_DEFFORM : return("DEFFORM");
case VP_DEFINE : return("DEFINE");
case VP_DEFREF : return("DEFREF");
case VP_DEFREF_JOIN : return("DEFREF_JOIN");
case VP_DEFVALUE : return("DEFVALUE");
case VP_ELSE : return("ELSE");
case VP_ELSIF : return("ELSIF");
case VP_ENDIF : return("ENDIF");
case VP_EOF : return("EOF");
case VP_ERROR : return("ERROR");
case VP_IFDEF : return("IFDEF");
case VP_IFNDEF : return("IFNDEF");
case VP_INCLUDE : return("INCLUDE");
case VP_LINE : return("LINE");
case VP_PSL : return("PSL");
case VP_STRIFY : return("STRIFY");
case VP_STRING : return("STRING");
case VP_SYMBOL : return("SYMBOL");
case VP_SYMBOL_JOIN : return("SYMBOL_JOIN");
case VP_TEXT : return("TEXT");
case VP_UNDEF : return("UNDEF");
case VP_UNDEFINEALL : return("UNDEFINEALL");
case VP_WHITE : return("WHITE");
default: return("?");
}
}
void VPreProcImp::unputString(const string& strg) {
// Note: The preliminary call in ::openFile bypasses this function
// We used to just m_lexp->unputString(strg.c_str());
// However this can lead to "flex scanner push-back overflow"
// so instead we scan from a temporary buffer, then on EOF return.
// This is also faster than the old scheme, amazingly.
if (m_lexp->m_bufferState!=m_lexp->currentBuffer()) {
fatalSrc("bufferStack missing current buffer; will return incorrectly");
// Hard to debug lost text as won't know till much later
}
m_lexp->scanBytes(strg);
}
int VPreProcImp::getNextStateToken(string & buf)
{
int tok=getStateToken(buf);
// cout<<tokenName(tok)<<":"<<buf<<endl;
return tok;
}
void VPreProcImp::unputDefrefString(const string& strg) {
int multiline = 0;
for (size_t i=0; i<strg.length(); i++) {
if (strg[i] == '\n') multiline++;
}
unputString(strg);
// A define that inserts multiple newlines are really attributed to one source line,
// so temporarily don't increment lineno.
m_lexp->curStreamp()->m_ignNewlines += multiline; // Must be after unput - applies to new stream
}
string VPreProcImp::trimWhitespace(const string& strg, bool trailing) {
// Remove leading whitespace
string out = strg;
string::size_type leadspace = 0;
while (out.length() > leadspace
&& isspace(out[leadspace])) leadspace++;
if (leadspace) out.erase(0,leadspace);
// Remove trailing whitespace
if (trailing) {
string::size_type trailspace = 0;
while (out.length() > trailspace
&& isspace(out[out.length()-1-trailspace])) trailspace++;
// Don't remove \{space_or_newline}
if (trailspace && out.length() > trailspace && out[out.length()-1-trailspace]=='\\')
trailspace--;
if (trailspace) out.erase(out.length()-trailspace,trailspace);
}
return out;
}
string VPreProcImp::defineSubst(VPreDefRef* refp) {
// Substitute out defines in a define reference.
// (We also need to call here on non-param defines to handle `")
// We could push the define text back into the lexer, but that's slow
// and would make recursive definitions and parameter handling nasty.
//
// Note we parse the definition parameters and value here. If a
// parametrized define is used many, many times, we could cache the
// parsed result.
if (false) {
//cout<<"defineSubstIn `"<<refp->name()<<" "<<refp->params()<<endl;
for (unsigned i=0; i<refp->args().size(); i++) {
cout<<"defineArg["<<i<<"] = '"<<refp->args()[i]<<"'"<<endl;
}
}
// Grab value
string value = m_preprocp->defValue(refp->name());
QCString value1(value.data());
// if (true) cout<<"defineValue '"<<VPreLex::cleanDbgStrg(value)<<"'"<<endl;
map<string,string> argValueByName;
{ // Parse argument list into map
unsigned numArgs=0;
string argName;
int paren = 1; // (), {} and [] can use same counter, as must be matched pair per spec
string token;
bool quote = false;
bool haveDefault = false;
// Note there's a leading ( and trailing ), so parens==1 is the base parsing level
QCString valo=refp->params().c_str();
const char* cp=valo.data();//+refp->params().c_str();
if (*cp == '(') cp++;
for (; *cp; cp++) {
//if (debug()>=5) cout <<" Parse Paren="<<paren<<" Arg="<<numArgs<<" token='"<<token<<"' Parse="<<cp<<endl;
if (!quote && paren==1) {
if (*cp==')' || *cp==',') {
string value;
if (haveDefault) { value=token; } else { argName=token; }
argName = trimWhitespace(argName,true);
if (debug()>=5) cout<<" Got Arg="<<numArgs<<" argName='"<<argName<<"' default='"<<value<<"'"<<endl;
// Parse it
if (argName!="") {
if (refp->args().size() > numArgs) {
// A call `def( a ) must be equivelent to `def(a ), so trimWhitespace
// At one point we didn't trim trailing whitespace, but this confuses `"
string arg = trimWhitespace(refp->args()[numArgs], true);
if (arg != "") value = arg;
} else if (!haveDefault) {
error("Define missing argument '"+argName+"' for: "+refp->name()+"\n");
return " `"+refp->name()+" ";
}
numArgs++;
}
argValueByName[argName] = value;
// Prepare for next
argName = "";
token = "";
haveDefault = false;
continue;
}
else if (*cp=='=') {
haveDefault = true;
argName = token;
token = "";
continue;
}
}
if (cp[0]=='\\' && cp[1]) {
token += cp[0]; // \{any} Put out literal next character
token += cp[1];
cp++;
continue;
}
if (!quote) {
if (*cp=='(' || *cp=='{' || *cp=='[') paren++;
else if (*cp==')' || *cp=='}' || *cp==']') paren--;
}
if (*cp=='"') quote=!quote;
if (*cp) token += *cp;
}
int r=refp->args().size();
if (refp->args().size() > numArgs
// `define X() is ok to call with nothing
&& !(refp->args().size()==1 && numArgs==0 && trimWhitespace(refp->args()[0],false)=="")) {
error("Define passed too many arguments: "+refp->name()+"\n");
return " `"+refp->name()+" ";
}
}
string out = "";
{ // Parse substitution define using arguments
string argName;
string prev;
bool quote = false;
bool backslashesc = false; // In \.....{space} block
// Note we go through the loop once more at the NULL end-of-string
if(value1.data()==NULL) goto NEE;
for (const char* cp=value1.data(); (*cp) || argName!=""; cp=(*cp?cp+1:cp)) {
//cout << "CH "<<*cp<<" an "<<argName<<"\n";
if (!quote && *cp == '\\') { backslashesc = true; }
else if (isspace(*cp)) { backslashesc = false; }
// We don't check for quotes; some simulators expand even inside quotes
if ( isalpha(*cp) || *cp=='_'
|| *cp=='$' // Won't replace system functions, since no $ in argValueByName
|| (argName!="" && (isdigit(*cp) || *cp=='$'))) {
argName += *cp;
continue;
}
if (argName != "") {
// Found a possible variable substitution
map<string,string>::iterator iter = argValueByName.find(argName);
if (iter != argValueByName.end()) {
// Substitute
string subst = iter->second;
out += subst;
} else {
out += argName;
}
argName = "";
}
if (!quote) {
// Check for `` only after we've detected end-of-argname
if (cp[0]=='`' && cp[1]=='`') {
if (backslashesc) {
// Don't put out the ``, we're forming an escape which will not expand further later
} else {
out += "``"; // `` must get removed later, as `FOO```BAR must pre-expand FOO and BAR
}
cp++;
continue;
}
else if (cp[0]=='`' && cp[1]=='"') {
out += "`\""; // `" means to put out a " without enabling quote mode (sort of)
// however we must expand any macro calls inside it first.
// So keep it `", so we don't enter quote mode.
cp++;
continue;
}
else if (cp[0]=='`' && cp[1]=='\\' && cp[2]=='`' && cp[3]=='"') {
out += "`\\`\""; // `\`" means to put out a backslash quote
// Leave it literal until we parse the VP_STRIFY string
cp+=3;
continue;
}
else if (cp[0]=='`' && cp[1]=='\\') {
out += '\\'; // `\ means to put out a backslash
cp++;
continue;
}
else if (cp[0]=='\\' && cp[1]=='\n') {
// We kept the \\n when we lexed because we don't want whitespace
// trimming to mis-drop the final \\n
// At replacement time we need the standard newline.
out += "\n"; // \\n newline
cp++;
continue;
}
}
if (cp[0]=='\\' && cp[1]=='\"') {
out += cp[0]; // \{any} Put out literal next character
out += cp[1];
cp++;
continue;
}
else if (cp[0]=='\\') {
// Normally \{any} would put out literal next character
// Instead we allow "`define A(nm) \nm" to expand, per proposed mantis1537
out += cp[0];
continue;
}
if (*cp=='"') quote=!quote;
if (*cp) out += *cp;
}
}
NEE:
if (debug()>=5) cout<<"defineSubstOut '"<<VPreLex::cleanDbgStrg(out)<<"'"<<endl;
return out;
}
//**********************************************************************
// Parser routines
bool VPreProcImp::readWholefile(const string& filename, StrList& outl) {
// If change this code, run a test with the below size set very small
//#define INFILTER_IPC_BUFSIZ 16
#define INFILTER_IPC_BUFSIZ 64*1024
char buf[INFILTER_IPC_BUFSIZ];
FILE* fp = NULL;
int fd;
char cmd[100];
bool eof = false;
ussize_t position = filename.find_last_of(".");
if (filename.length()>3 && 0==filename.compare(filename.length()-3, 3, ".gz")) {
sprintf(cmd, "gunzip -c %s", filename.c_str());
if ((fp = portable_popen(cmd, "r")) == NULL) {
return false;
}
fd = fileno (fp);
} else {
fd = open (filename.c_str(), O_RDONLY);
if (fd<0) return false;
}
while (!eof) {
ussize_t todo = INFILTER_IPC_BUFSIZ;
ussize_t got = read (fd, buf, todo);
if (got>0) {
outl.push_back(string(buf, got));
}
else if (errno == EINTR || errno == EAGAIN
#ifdef EWOULDBLOCK
|| errno == EWOULDBLOCK
#endif
) {
} else { eof = true; break; }
}
if (fp) { portable_pclose(fp); fp=NULL; }
else close(fd);
return true;
}
void VPreProcImp::openFile(string filename, VFileLine* filelinep) {
// Open a new file, possibly overriding the current one which is active.
// Read a list<string> with the whole file.
StrList wholefile;
bool ok = readWholefile(filename, wholefile/*ref*/);
if (!ok) {
error("File not found: "+filename+"\n");
return;
}
if (!m_preprocp->isEof()) { // IE not the first file.
// We allow the same include file twice, because occasionally it pops
// up, with guards preventing a real recursion.
if (m_lexp->m_streampStack.size()>VPreProc::INCLUDE_DEPTH_MAX) {
error("Recursive inclusion of file: "+filename);
return;
}
// There's already a file active. Push it to work on the new one.
addLineComment(0);
}
// Create new stream structure
m_lexp->scanNewFile(m_preprocp->fileline()->create(filename, 1));
addLineComment(1); // Enter
// Filter all DOS CR's en-mass. This avoids bugs with lexing CRs in the wrong places.
// This will also strip them from strings, but strings aren't supposed to be multi-line without a "\"
for (StrList::iterator it=wholefile.begin(); it!=wholefile.end(); ++it) {
// We don't end-loop at \0 as we allow and strip mid-string '\0's (for now).
bool strip = false;
const char* sp = it->data();
const char* ep = sp + it->length();
// Only process if needed, as saves extra string allocations
for (const char* cp=sp; cp<ep; cp++) {
if (*cp == '\r' || *cp == '\0') {
strip = true; break;
}
}
if (strip) {
string out; out.reserve(it->length());
for (const char* cp=sp; cp<ep; cp++) {
if (!(*cp == '\r' || *cp == '\0')) {
out += *cp;
}
}
*it = out;
// cout<<out;
}
// Push the data to an internal buffer.
m_lexp->scanBytesBack(*it);
// Reclaim memory; the push saved the string contents for us
*it = "";
}
}
void VPreProcImp::insertUnreadbackAtBol(const string& text) {
// Insert insuring we're at the beginning of line, for `line
// We don't always add a leading newline, as it may result in extra unreadback(newlines).
if (m_lineCmt == "") { m_lineCmtNl = true; }
else if (m_lineCmt[m_lineCmt.length()-1]!='\n') {
insertUnreadback("\n");
}
insertUnreadback(text);
}
void VPreProcImp::addLineComment(int enter_exit_level) {
if (m_preprocp->lineDirectives()) {
insertUnreadbackAtBol(m_lexp->curFilelinep()->lineDirectiveStrg(enter_exit_level));
}
}
int VPreProcImp::getRawToken() {
// Get a token from the file, whatever it may be.
while (1) {
next_tok:
if (m_lineAdd) {
m_lineAdd--;
m_rawAtBol = true;
yyourtext("\n",1);
if (debug()>=5) debugToken(VP_WHITE, "LNA");
return (VP_WHITE);
}
if (m_lineCmt!="") {
// We have some `line directive or other processed data to return to the user.
static string rtncmt; // Keep the c string till next call
rtncmt = m_lineCmt;
if (m_lineCmtNl) {
if (!m_rawAtBol) rtncmt = "\n"+rtncmt;
m_lineCmtNl = false;
}
yyourtext(rtncmt.c_str(), rtncmt.length());
m_lineCmt = "";
if (yyourleng()) m_rawAtBol = (yyourtext()[yyourleng()-1]=='\n');
if (m_states.top()==ps_DEFVALUE) {
VPreLex::s_currentLexp->appendDefValue(yyourtext(),yyourleng());
goto next_tok;
} else {
if (debug()>=5) debugToken(VP_TEXT, "LCM");
return (VP_TEXT);
}
}
if (isEof()) return (VP_EOF);
// Snarf next token from the file
int tok = m_lexp->lex();
if (debug()>=5) debugToken(tok, "RAW");
// A EOF on an include, so we can print `line and detect mis-matched "s
if (tok==VP_EOF) {
goto next_tok; // find the EOF, after adding needed lines
}
if (yyourleng()) m_rawAtBol = (yyourtext()[yyourleng()-1]=='\n');
return tok;
}
}
void VPreProcImp::debugToken(int tok, const char* cmtp) {
if (debug()>=5) {
string buf = string (yyourtext(), yyourleng());
string::size_type pos;
while ((pos=buf.find("\n")) != string::npos) { buf.replace(pos, 1, "\\n"); }
while ((pos=buf.find("\r")) != string::npos) { buf.replace(pos, 1, "\\r"); }
fprintf (stderr, "%d: %s %s %s(%d) dr%d: <%d>%-10s: %s\n",
m_lexp->m_tokFilelinep->lineno(), cmtp, m_off?"of":"on",
procStateName(m_states.top()), (int)m_states.size(), (int)m_defRefs.size(),
m_lexp->currentStartState(), tokenName(tok), buf.c_str());
}
}
// Sorry, we're not using bison/yacc. It doesn't handle returning white space
// in the middle of parsing other tokens.
int VPreProcImp::getStateToken(string& buf) {
// Return the next state-determined token
while (1) {
next_tok:
if (isEof()) {
buf = string (yyourtext(), yyourleng());
return VP_EOF;
}
int tok = getRawToken();
string buff = string (yyourtext(), yyourleng());
//printf("\n[ %s++ %s --%s %d]",buff.data(),sbuffer.data(),buf.data(),m_off);
//if(m_off){
sbuffer+=buff;
// printf("\n[ %s++ %s --%s %d]",buff.data(),sbuffer.data(),buf.data(),m_off);
// }
//else
// sbuffer.clear();
ProcState state = m_states.top();
// Most states emit white space and comments between tokens. (Unless collecting a string)
if (tok==VP_WHITE && state !=ps_STRIFY) {
buf = string (yyourtext(), yyourleng());
return (tok);
}
if (tok==VP_BACKQUOTE && state !=ps_STRIFY) { tok = VP_TEXT; }
if (tok==VP_COMMENT) {
if (!m_off) {
if (m_lexp->m_keepComments == KEEPCMT_SUB
|| m_lexp->m_keepComments == KEEPCMT_EXP) {
string rtn; rtn.assign(yyourtext(),yyourleng());
m_preprocp->comment(rtn);
// Need to insure "foo/**/bar" becomes two tokens
insertUnreadback (" ");
} else if (m_lexp->m_keepComments) {
buf = string (yyourtext(), yyourleng());
return (tok);
} else {
// Need to insure "foo/**/bar" becomes two tokens
insertUnreadback (" ");
}
}
// We're off or processed the comment specially. If there are newlines
// in it, we also return the newlines as TEXT so that the linenumber
// count is maintained for downstream tools
for (size_t len=0; len<(size_t)yyourleng(); len++) { if (yyourtext()[len]=='\n') m_lineAdd++; }
goto next_tok;
}
if (tok==VP_LINE) {
addLineComment(m_lexp->m_enterExit);
goto next_tok;
}
if (tok==VP_DEFREF_JOIN) {
// Here's something fun and unspecified as yet:
// The existance of non-existance of a base define changes `` expansion
// `define QA_b zzz
// `define Q1 `QA``_b
// 1Q1 -> zzz
// `define QA a
// `Q1 -> a_b
// Note parenthesis make this unambiguous
// `define Q1 `QA()``_b // -> a_b
// This may be a side effect of how `UNDEFINED remains as `UNDEFINED,
// but it screws up our method here. So hardcode it.
string name (yyourtext()+1,yyourleng()-1);
if (m_preprocp->defExists(name)) { // JOIN(DEFREF)
// Put back the `` and process the defref
if (debug()>=5) cout<<"```: define "<<name<<" exists, expand first\n";
m_defPutJoin = true; // After define, unputString("``"). Not now as would loose yyourtext()
if (debug()>=5) cout<<"TOKEN now DEFREF\n";
tok = VP_DEFREF;
} else { // DEFREF(JOIN)
if (debug()>=5) cout<<"```: define "<<name<<" doesn't exist, join first\n";
// FALLTHRU, handle as with VP_SYMBOL_JOIN
}
}
if (tok==VP_SYMBOL_JOIN || tok==VP_DEFREF_JOIN) { // not else if, can fallthru from above if()
// a`` -> string doesn't include the ``, so can just grab next and continue
string out (yyourtext(),yyourleng());
if (debug()>=5) cout<<"`` LHS:"<<out<<endl;
// a``b``c can have multiple joins, so we need a stack
m_joinStack.push(out);
statePush(ps_JOIN);
goto next_tok;
}
// Deal with some special parser states
switch (state) {
case ps_TOP: {
break;
}
case ps_DEFNAME_UNDEF: // FALLTHRU
case ps_DEFNAME_DEFINE: // FALLTHRU
case ps_DEFNAME_IFDEF: // FALLTHRU
case ps_DEFNAME_IFNDEF: // FALLTHRU
case ps_DEFNAME_ELSIF: {
// sbuffer+= string (yyourtext(), yyourleng());
if (tok==VP_SYMBOL) {
m_lastSym.assign(yyourtext(),yyourleng());
if (state==ps_DEFNAME_IFDEF
|| state==ps_DEFNAME_IFNDEF) {
bool enable = m_preprocp->defExists(m_lastSym);
string l(yyourtext());
bEnable=enable;
// if (true) cout<<"Ifdef "<<m_lastSym<<(enable?" ON":" OFF")<<endl;
if (state==ps_DEFNAME_IFNDEF)
enable = !enable;
insertRelString(enable);
int t=m_lexp->m_tokFilelinep->lineno();
int v=this->m_finFilelinep->lineno();
m_ifdefStack.push(VPreIfEntry(enable,false,l, t));
if (!enable) parsingOff();
// if(!m_off) sbuffer.clear();
statePop();
goto next_tok;
}
else if (state==ps_DEFNAME_ELSIF) {
if (m_ifdefStack.empty()) {
error("`elsif with no matching `if\n");
} else {
// Handle `else portion
VPreIfEntry lastIf = m_ifdefStack.top(); m_ifdefStack.pop();
if (!lastIf.on()) parsingOn();
// Handle `if portion
;bool enable = !lastIf.everOn() && m_preprocp->defExists(m_lastSym);
bEnable=enable;
//if (true) cout<<"Elsif "<<m_lastSym<<(enable?" ON":" OFF")<<endl;
insertRelString(enable);
string l(yyourtext());
int t=m_lexp->m_tokFilelinep->lineno();
int v=this->m_finFilelinep->lineno();
m_ifdefStack.push(VPreIfEntry(enable, lastIf.everOn(),l, t));
if (!enable) parsingOff();
}
statePop();
goto next_tok;
}
else if (state==ps_DEFNAME_UNDEF) {
if (!m_off) {
if (debug()>=5) cout<<"Undef "<<m_lastSym<<endl;
m_preprocp->undef(m_lastSym);
}
statePop();
goto next_tok;
}
else if (state==ps_DEFNAME_DEFINE) {
// m_lastSym already set.
stateChange(ps_DEFFORM);
m_lexp->pushStateDefForm();
goto next_tok;
}
else fatalSrc("Bad case\n");
goto next_tok;
}
else if (tok==VP_TEXT) {
// IE, something like comment between define and symbol
if (!m_off) {
buf = string (yyourtext(), yyourleng());
return tok;
}
else goto next_tok;
}
else if (tok==VP_DEFREF) {
// IE, `ifdef `MACRO(x): Substitue and come back here when state pops.
break;
}
else {
error((string)"Expecting define name. Found: "+tokenName(tok)+"\n");
goto next_tok;
}
}
case ps_DEFFORM: {
if (tok==VP_DEFFORM) {
m_formals = m_lexp->m_defValue;
if (debug()>=5) cout<<"DefFormals='"<<VPreLex::cleanDbgStrg(m_formals)<<"'\n";
stateChange(ps_DEFVALUE);
m_lexp->pushStateDefValue();
goto next_tok;
} else if (tok==VP_TEXT) {
// IE, something like comment in formals
if (!m_off) {
buf = string (yyourtext(), yyourleng());
return tok;
}
else goto next_tok;
} else {
error((string)"Expecting define formal arguments. Found: "+tokenName(tok)+"\n");
goto next_tok;
}
}
case ps_DEFVALUE: {
static string newlines;
string mist = string (yyourtext(), yyourleng());
newlines = "\n"; // Always start with trailing return
if (tok == VP_DEFVALUE) {
if (debug()>=5) cout<<"DefValue='"<<VPreLex::cleanDbgStrg(m_lexp->m_defValue)
<<"' formals='"<<VPreLex::cleanDbgStrg(m_formals)<<"'\n";
// Add any formals
sbuffer=sbuffer.substr(0,sbuffer.length()-1);
string formals = m_formals;
sbuffer+=formals;
string value = m_lexp->m_defValue;
sbuffer+=value;
// Remove returns
// Not removing returns in values has two problems,
// 1. we need to correct line numbers with `line after each substitution
// 2. Substituting in " .... " with embedded returns requires \ escape.
// This is very difficult in the presence of `", so we keep the \ before the newline.
for (size_t i=0; i<formals.length(); i++) {
if (formals[i] == '\n') {
newlines += "\n";
}
}
for (size_t i=0; i<value.length(); i++) {
if (value[i] == '\n') {
newlines += "\n";
}
}
if (!m_off) {
// Remove leading and trailing whitespace
value = trimWhitespace(value, true);
// Define it
//if (true) cout<<"Define "<<m_lastSym<<" "<<formals
// <<" = '"<<VPreLex::cleanDbgStrg(value)<<"'"<<endl;
m_preprocp->define(m_lastSym, value, formals);
}
} else {
string msg = string("Bad define text, unexpected ")+tokenName(tok)+"\n";
fatalSrc(msg);
}
statePop();
// DEFVALUE is terminated by a return, but lex can't return both tokens.
// Thus, we emit a return here.
buf = newlines;
return(VP_WHITE);
}
case ps_DEFPAREN: {
// sbuffer.clear();
if (tok==VP_TEXT && yyourleng()==1 && yyourtext()[0]=='(') {
stateChange(ps_DEFARG);
goto next_tok;
} else {
if (m_defRefs.empty()) fatalSrc("Shouldn't be in DEFPAREN w/o active defref");
VPreDefRef* refp = &(m_defRefs.top());
error((string)"Expecting ( to begin argument list for define reference `"+refp->name()+"\n");
statePop();
goto next_tok;
}
}
case ps_DEFARG: {
if (m_defRefs.empty()) fatalSrc("Shouldn't be in DEFARG w/o active defref");
VPreDefRef* refp = &(m_defRefs.top());
refp->nextarg(refp->nextarg()+m_lexp->m_defValue); m_lexp->m_defValue="";
if (debug()>=5) cout<<"defarg++ "<<refp->nextarg()<<endl;
if (tok==VP_DEFARG && yyourleng()==1 && yyourtext()[0]==',') {
refp->args().push_back(refp->nextarg());
stateChange(ps_DEFARG);
m_lexp->pushStateDefArg(1);
refp->nextarg("");
goto next_tok;
} else if (tok==VP_DEFARG && yyourleng()==1 && yyourtext()[0]==')') {
// Substitute in and prepare for next action
// Similar code in non-parenthesized define (Search for END_OF_DEFARG)
refp->args().push_back(refp->nextarg());
string out;
if (!m_off) {
out = defineSubst(refp);
out = m_preprocp->defSubstitute(out);
}
m_defRefs.pop(); refp=NULL;
if (m_defRefs.empty()) {
statePop();
if (!m_off) unputDefrefString(out);
m_lexp->m_parenLevel = 0;
}
else { // Finished a defref inside a upper defref
// Can't subst now, or
// `define a(ign) x,y
// foo(`a(ign),`b) would break because a contains comma
refp = &(m_defRefs.top()); // We popped, so new top
refp->nextarg(refp->nextarg()+m_lexp->m_defValue+out); m_lexp->m_defValue="";
m_lexp->m_parenLevel = refp->parenLevel();
statePop(); // Will go to ps_DEFARG, as we're under another define
}
goto next_tok;
} else if (tok==VP_DEFREF) {
// Expand it, then state will come back here
// Value of building argument is data before the lower defref
// we'll append it when we push the argument.
break;
} else if (tok==VP_SYMBOL || tok==VP_STRING || VP_TEXT || VP_WHITE || VP_PSL) {
string rtn; rtn.assign(yyourtext(),yyourleng());
refp->nextarg(refp->nextarg()+rtn);
goto next_tok;
} else {
error((string)"Expecting ) or , to end argument list for define reference. Found: "+tokenName(tok));
statePop();
goto next_tok;
}
}
case ps_INCNAME: {
if (tok==VP_STRING) {
statePop();
m_lastSym.assign(yyourtext(),yyourleng());
if (debug()>=5) cout<<"Include "<<m_lastSym<<endl;
// Drop leading and trailing quotes.
m_lastSym.erase(0,1);
m_lastSym.erase(m_lastSym.length()-1,1);
// printf("\n###################22###################################");
// printf("\n %s %s",sbuffer.data(),yyourtext()) ;
// printf("\n###################77###################################");
sbuffer.insert(0,"`include ");
this->m_QC.append(sbuffer.data());
m_preprocp->include(m_lastSym);
sbuffer.clear();
goto next_tok;
}
else if (tok==VP_TEXT && yyourleng()==1 && yyourtext()[0]=='<') {
// include <filename>
stateChange(ps_INCNAME); // Still
m_lexp->pushStateIncFilename();
goto next_tok;
}
else if (tok==VP_DEFREF
|| tok==VP_STRIFY) {
// Expand it, then state will come back here
break;
}
else {
statePop();
error((string)"Expecting include filename. Found: "+tokenName(tok)+"\n");
goto next_tok;
}
}
case ps_ERRORNAME: {
if (tok==VP_STRING) {
if (!m_off) {
m_lastSym.assign(yyourtext(),yyourleng());
error(m_lastSym);
}
statePop();
goto next_tok;
}
else {
error((string)"Expecting `error string. Found: "+tokenName(tok)+"\n");
statePop();
goto next_tok;
}
}
case ps_JOIN: {
if (tok==VP_SYMBOL || tok==VP_TEXT) {
if (m_joinStack.empty()) fatalSrc("`` join stack empty, but in a ``");
string lhs = m_joinStack.top(); m_joinStack.pop();
if (debug()>=5) cout<<"`` LHS:"<<lhs<<endl;
string rhs (yyourtext(),yyourleng());
if (debug()>=5) cout<<"`` RHS:"<<rhs<<endl;
string out = lhs+rhs;
if (debug()>=5) cout<<"`` Out:"<<out<<endl;
unputString(out);
statePop();
goto next_tok;
} else if (tok==VP_EOF || tok==VP_WHITE || tok == VP_COMMENT || tok==VP_STRING) {
error((string)"Expecting symbol to terminate ``; whitespace etc cannot follow ``. Found: "+tokenName(tok)+"\n");
statePop();
goto next_tok;
} else {
// `define, etc, fall through and expand. Pop back here.
break;
}
}
case ps_STRIFY: {
if (tok==VP_STRIFY) {
// Quote what's in the middle of the stringification
// Note a `" MACRO_WITH(`") `" doesn't need to be handled (we don't need a stack)
// That behavior isn't specified, and other simulators vary widely
string out = m_strify;
m_strify = "";
// Convert any newlines to spaces, so we don't get a multiline "..." without \ escapes
// The spec is silent about this either way; simulators vary
string::size_type pos;
while ((pos=out.find("\n")) != string::npos) {
out.replace(pos, 1, " ");
}
unputString((string)"\""+out+"\"");
statePop();
goto next_tok;
}
else if (tok==VP_EOF) {
error("`\" not terminated at EOF\n");
}
else if (tok==VP_BACKQUOTE) {
m_strify += "\\\"";
goto next_tok;
}
else if (tok==VP_DEFREF) {
// Spec says to expand macros inside `"
// Substitue it into the stream, then return here
break;
}
else {
// Append token to eventual string
m_strify.append(yyourtext(),yyourleng());
goto next_tok;
}
}
default: fatalSrc("Bad case\n");
}
// Default is to do top level expansion of some tokens
switch (tok) {
case VP_INCLUDE:
if (!m_off) {
sbuffer=VerilogDocGen::removeLastWord(sbuffer.data());
statePush(ps_INCNAME);
}
goto next_tok;
case VP_UNDEF:
statePush(ps_DEFNAME_UNDEF);
goto next_tok;
case VP_DEFINE:
// No m_off check here, as a `ifdef NEVER `define FOO(`endif) should work
// sbuffer=string (yyourtext(), yyourleng());
statePush(ps_DEFNAME_DEFINE);
goto next_tok;
case VP_IFDEF:
statePush(ps_DEFNAME_IFDEF);
goto next_tok;
case VP_IFNDEF:
statePush(ps_DEFNAME_IFNDEF);
goto next_tok;
case VP_ELSIF:
statePush(ps_DEFNAME_ELSIF);
goto next_tok;
case VP_ELSE:
if (m_ifdefStack.empty()) {
error("`else with no matching `if\n");
} else {
VPreIfEntry lastIf = m_ifdefStack.top(); m_ifdefStack.pop();
bool enable = !lastIf.everOn();
bEnable=enable;
// if (true) cout<<"Else "<<(enable?" ON":" OFF")<<endl;
insertRelString(enable);
string l("else");
int t= m_lexp->m_tokFilelinep->lineno();
int g=this->m_finFilelinep->lineno();
m_ifdefStack.push(VPreIfEntry(enable, lastIf.everOn(),l, t));
if (!lastIf.on()) parsingOn();
if (!enable) parsingOff();
}
goto next_tok;
case VP_ENDIF:
if (debug()>=5) cout<<"Endif "<<endl;
if (m_ifdefStack.empty()) {
error("`endif with no matching `if\n");
} else {
VPreIfEntry lastIf = m_ifdefStack.top(); m_ifdefStack.pop();
if (!lastIf.on()) parsingOn();
// parsingOn() really only enables parsing if
// all ifdef's above this want it on
}
goto next_tok;
case VP_DEFREF: {
// m_off not right here, but inside substitution, to make this work: `ifdef NEVER `DEFUN(`endif)
sbuffer.clear();
string name (yyourtext()+1,yyourleng()-1);
if (debug()>=5) cout<<"DefRef "<<name<<endl;
if (m_defPutJoin) { m_defPutJoin = false; unputString("``"); }
if (m_defDepth++ > VPreProc::DEFINE_RECURSION_LEVEL_MAX) {
error("Recursive `define substitution: `"+name);
goto next_tok;
}
// Substitute
string params = m_preprocp->defParams(name);
if (params=="") { // Not found, return original string as-is
m_defDepth = 0;
if (debug()>=5) cout<<"Defref `"<<name<<" => not_defined"<<endl;
if (m_off) {
sbuffer+= string (yyourtext(), yyourleng());
goto next_tok;
} else {
buf = string (yyourtext(), yyourleng());
return (VP_TEXT);
}
}
else if (params=="0") { // Found, as simple substitution
if (m_off) {
goto next_tok;
}
else {
VPreDefRef tempref(name, "0");
// sbuffer.clear();
string out = defineSubst(&tempref);
// Similar code in parenthesized define (Search for END_OF_DEFARG)
out = m_preprocp->defSubstitute(out);
if (m_defRefs.empty()) {
// Just output the substitution
unputDefrefString(out);
} else { // Inside another define.
// Can't subst now, or
// `define a x,y
// foo(`a,`b) would break because a contains comma
VPreDefRef* refp = &(m_defRefs.top());
refp->nextarg(refp->nextarg()+m_lexp->m_defValue+out); m_lexp->m_defValue="";
}
goto next_tok;
}
}
else { // Found, with parameters
// if (true)
// cout<<"Defref `"<<name<<" => parametrized"<<endl;
// The CURRENT macro needs the paren saved, it's not a property of the child macro
if (!m_defRefs.empty())
m_defRefs.top().parenLevel(m_lexp->m_parenLevel);
m_defRefs.push(VPreDefRef(name, params));
statePush(ps_DEFPAREN);
m_lexp->pushStateDefArg(0);
goto next_tok;
}
fatalSrc("Bad case\n");
}
case VP_ERROR: {
statePush(ps_ERRORNAME);
goto next_tok;
}
case VP_EOF:
if (!m_ifdefStack.empty()) {
int l=m_ifdefStack.size();
#if 0
// cout<<"------------------------------------------------------------"<<endl;
while(!m_ifdefStack.empty())
{
VPreIfEntry bp=m_ifdefStack.top();
m_ifdefStack.pop();
int l=m_ifdefStack.size();
// string m_n=bp->; // Define last name being defined
// string m_params; // Define parameter list for next expansion
// string m_nextarg; // String being built for next argument
// printf("\n %s at line: %d",bp.ifName.data(),bp.line);
}
// cout<<"------------------------------------------------------------"<<endl;
#endif
error("`ifdef# not terminated at EOF\n");
}
buf = string (yyourtext(), yyourleng());
return tok;
case VP_UNDEFINEALL:
if (!m_off) {
if (debug()>=5) cout<<"Undefineall "<<endl;
m_preprocp->undefineall();
}
goto next_tok;
case VP_STRIFY:
// We must expand macros in the body of the stringification
// Then, when done, form a final string to return
// (it could be used as a include filename, for example, so need the string token)
statePush(ps_STRIFY);
goto next_tok;
case VP_SYMBOL:
case VP_STRING:
case VP_PSL:
case VP_TEXT: {
m_defDepth = 0;
if (!m_off)
{
buf = string (yyourtext(), yyourleng());
// printf("<< %s >>\n",buf.data());
return tok;
}
else goto next_tok;
}
case VP_WHITE: // Handled at top of loop
case VP_COMMENT: // Handled at top of loop
case VP_DEFFORM: // Handled by state=ps_DEFFORM;
case VP_DEFVALUE: // Handled by state=ps_DEFVALUE;
default:
fatalSrc((string)"Internal error: Unexpected token "+tokenName(tok)+"\n");
break;
}
buf = string (yyourtext(), yyourleng());
return tok;
}
}
int VPreProcImp::getFinalToken(string& buf) {
// Return the next user-visible token in the input stream.
// Includes and such are handled here, and are never seen by the caller.
if (!m_finAhead) {
m_finAhead = true;
m_finToken = getStateToken(m_finBuf);
}
int tok = m_finToken;
buf = m_finBuf;
if (false) fprintf (stderr,"%d: FIN: %-10s: %s\n",
m_lexp->m_tokFilelinep->lineno(),
tokenName(tok), VPreLex::cleanDbgStrg(buf).c_str());
// Track `line
const char* bufp = buf.c_str();
while (*bufp == '\n') bufp++;
if ((tok == VP_TEXT || tok == VP_LINE) && 0==strncmp(bufp,"`line ",6)) {
int enter;
m_finFilelinep = m_finFilelinep->lineDirective(bufp, enter/*ref*/);
}
else {
if (m_finAtBol && !(tok==VP_TEXT && buf=="\n")
&& m_preprocp->lineDirectives()) {
if (int outBehind = m_lexp->m_tokFilelinep->lineno() - m_finFilelinep->lineno()) {
if (debug()>=5) fprintf(stderr,"%d: FIN: readjust, fin at %d request at %d\n",
m_lexp->m_tokFilelinep->lineno(),
m_finFilelinep->lineno(), m_lexp->m_tokFilelinep->lineno());
m_finFilelinep = m_finFilelinep->create(m_lexp->m_tokFilelinep->filename(),m_lexp->m_tokFilelinep->lineno());
if (outBehind > 0 && outBehind <= (int)VPreProc::NEWLINES_VS_TICKLINE) {
// Output stream is behind, send newlines to get back in sync
// (Most likely because we're completing a disabled `endif)
if (m_preprocp->keepWhitespace()) {
buf = string(outBehind,'\n');
return VP_TEXT;
}
} else {
// Need to backup, use `line
buf = m_finFilelinep->lineDirectiveStrg(0);
return VP_LINE;
}
}
}
// Track newlines in prep for next token
for (const char* cp = buf.c_str(); *cp; cp++) {
if (*cp == '\n') {
m_finAtBol = true;
m_finFilelinep->linenoIncInPlace(); // Increment in place to avoid new/delete calls. It's private data.
} else {
m_finAtBol = false;
}
}
}
m_finAhead = false; // Consumed the token
// printf("\n {return : %s || %s %d}",buf.data(),sbuffer.data(),m_off);
return tok;
}
void deleteAllChars(string &s,const char* c)
{
int index=s.find(c);
while (index !=-1)
{
string qcs=s.erase(index,1);
s=qcs;
index=s.find(c);
}
}
void VPreProcImp::insertRelString(bool b)
{
//cout<<"m_off"<<m_off<<endl;
if(relString.empty()) return;
QRegExp re ("[a-z_A-Z0-9.-]+");
QRegExp reg ("[^\\s\n\r\t]+");
QCString qcs(relString.data());
int u= qcs.find(re);
int v=qcs.find(reg);
bool c=(relString.find("`ifdef")==0);
bool d=(relString.find("`ifndef")==0);
if(!b || m_off >0)
{
string s("");
s.append(relString.data());
s.append("");
// printf("\n rel",relString.data());
m_lineChars.append(s.data());
m_QC.append(s.data());
}
else {
m_lineChars.append(relString.data());
m_QC.append(relString.data());
}
relString.clear();
}
string VPreProcImp::checkUndoc(string & buf,string & sb,bool undoc,int tok,int line,int i)
{
string res;
string sbx(buf);
string s1(sb);
QRegExp reg ("[^\\s]+");
QCString qcs(sb.data());
int l=qcs.find(reg);
static bool if_def;
static bool next_def;
int z=s1.find("`ifdef");
int y=s1.find("`ifndef");
int x=s1.find("`elsif");
//int w=s1.find("`else");
if_def=(z==0 || x==0 || y==0 ) ;
//printf("\n {return : %s || %s %d [line %d %d](%d)}",buf.data(),sb.data(),undoc,i,line,bEnable);
if(if_def)
{
relString=sb;
return "";
}
else if(l==0)
relString="";
deleteAllChars(sbx,"\n");
deleteAllChars(sbx," ");
deleteAllChars(sbx,"\t");
bool equ=sbx.empty();//(buf==" " || buf == "\n" || buf=="\t");
if(!equ && !undoc)
return buf;
if(buf==sb && !undoc)
return buf;
if(undoc)
{
if(l==-1)
return sb;
string s("");
s+=sb+"";
// printf("\n {return : [%s] %d (%d)}",s.data(),line,bEnable);
return s;
}
if(equ && !undoc)
{
if(line>i && buf == "\n")
{
if(sb.empty())
sb.append("\n");
char l=sb.at(sb.length()-1);
if(l != '\n')
sb.append("\n");
}
return sb;
}
assert(0);
return sb+buf;
}
string VPreProcImp::getparseline(bool stop_at_eol, size_t approx_chunk) {
// Get a single line from the parse stream. Buffer unreturned text until the newline.
bEnable=false;
if (isEof()) return "";
while (1) {
const char* rtnp = NULL;
bool gotEof = false;
while ((stop_at_eol
? (NULL==(rtnp=strchr(m_lineChars.c_str(),'\n')))
: (approx_chunk==0 || (m_lineChars.length() < approx_chunk)))
&& !gotEof) {
string buf;
sbuffer.clear();
int tok = getFinalToken(buf/*ref*/);
bool bo;
if(m_off)
bo=true;
else
bo=false;
// cout<<"<<"<<sbuffer<<">>"<<endl;
// sbuffer.clear();
if (false) {
fprintf (stderr,"%d: GETFETC: %-10s: %s\n",
m_lexp->m_tokFilelinep->lineno(), tokenName(tok), VPreLex::cleanDbgStrg(buf).c_str());
}
if (tok==VP_EOF) {
// Add a final newline, if the user forgot the final \n.
m_lineChars.append(sbuffer);
m_QC.append(sbuffer.data());
if (m_lineChars != "" && m_lineChars[m_lineChars.length()-1] != '\n') {
m_lineChars.append(" ");
m_QC.append(" ");
}
gotEof = true;
}
else if (tok==VP_PSL) {
m_lineChars.append(" psl ");
}
else {
int z=m_finFilelinep->lineno();
int y=m_lexp->m_tokFilelinep->lineno();
string zp=checkUndoc(buf,sbuffer,bo,tok,z,y);
// printf("\n append %s:",zp.data());
m_QC.append(zp.data());
// printf("\n###################................###################################");
// printf("\n %s",m_QC.data()) ;
// printf("\n###################--------------###################################");
//sbuffer.clear();
}
}
// Make new string with data up to the newline.
size_t len = stop_at_eol ? (rtnp-m_lineChars.c_str()+1) : m_lineChars.length();
string theLine;
theLine.append(m_QC.data()); //, 0,m_QC.length());
m_lineChars = m_lineChars.erase(0,len); // Remove returned characters
m_QC.resize(0);
if (!m_preprocp->keepWhitespace() && !gotEof) {
const char* cp=theLine.c_str();
for (; *cp && (isspace(*cp) || *cp=='\n'); cp++) {}
if (!*cp) continue;
}
return theLine;
}
}
string VerilogPreProc::performPreprocessing(const QFileInfo & fi,bool include)
{
this->getPredefs();
string ssf=fi.filePath().data();
VerilogFileLine pv(ssf,0);
configure(&pv);
lineDirectives(false);
VPreProcImp* idatap = static_cast<VPreProcImp*>(this->getImp());
VPreLex* pre=idatap->m_lexp;
list<string> wholefile;
string s;
idatap->readWholefile(ssf,wholefile);
for (std::list<string>::iterator it=wholefile.begin(); it != wholefile.end(); ++it)
s+=*it;
pre->scanBytes(s);
// printf("\n FILE SIZE: %d \n",fi.size());
string res = getall(fi.size());
// cout<<"----------------------"<<endl<<res.data()<<endl<<"------.........------------ "<<endl;
return res;
}
//------------------------------------------------------------------------------------------------------------------------
void VerilogPreProc::include(string filename)
{
QCString qcs;
QCString fn=filename.data();
QFileInfo fi(fn);
if(!fi.exists())
{
QCString file=VerilogDocGen::findFile(filename.data());
QFileInfo qf(file);
if(file.isEmpty())
{
cerr<<"could not open file: "<<filename.data()<<endl;
return;
}
else
{
QFile f1(file);
fi.setFile(f1);
}
}
VPreProcImp* idatap = static_cast<VPreProcImp*>(this->getImp());
VPreLex* pre=idatap->m_lexp;
struct yy_buffer_state * buz = pre->currentBuffer();
VerilogPreProc defProc;
defProc.performPreprocessing(fi,false);
yy_switch_to_buffer(buz);
} ///< Request a include file be processed
string VerilogPreProc::defSubstitute(string substitute)
{
// cout<<"SUBSTITUDE:"<<substitute<<endl;
sbuffer.clear();
return substitute;
} ///< Return value to substitute for given post-parameter value
void VerilogPreProc::define(string name, string value, string params)
{
DefineDict* gDict = VerilogPreProc::getFileDefineDict();
// if(debug()>=4)
// cout<<"<DEFINE> "<<name<<" Value "<<value <<endl;
Define *def=new Define;
def->name = name.data();
def->definition =value.data();
def->fileName = fileline()->filename().data();
def->lineNr = fileline()->lineno();
gDict->insert(name.data(),def);
if(params.empty())
params="0";
def->args = params.data();
} ///< `define without any parameters
string VerilogPreProc::defParams(string name)
{
DefineDict* gDict = VerilogPreProc::getFileDefineDict();
Define*def=gDict->find(name.data());
if(def)
{
string ss(def->args.data());
return ss;
}
else
return "";
} ///< Return parameter list if define exists
string VerilogPreProc::defValue(string name)
{
DefineDict* gDict = VerilogPreProc::getFileDefineDict();
Define *def=gDict->find(name.data());
if(def)
{
string ss(def->definition.data());
return ss;
}
else{
assert(0);
return "";
}
} ///< Return value of given define (should exist)
bool VerilogPreProc::defExists(string name)
{
DefineDict* gDict = VerilogPreProc::getFileDefineDict();
Define *def=gDict->find(name.data());
if(def)
return true;
return false;
} ///< Return true if define exists
void VerilogPreProc::undef(string name)
{
DefineDict* gDict = VerilogPreProc::getFileDefineDict();
if(gDict->find(name.data()))
gDict->remove(name.data());
}
void VerilogPreProc::undefineall()
{
DefineDict* gDict = VerilogPreProc::getFileDefineDict();
gDict->clear();
}
void VerilogPreProc::printDict()
{
return;
DefineDict* gDict=VerilogPreProc::getFileDefineDict();
QDictIterator<Define> defDict(*gDict);
Define *def;
for (defDict.toFirst();(def=defDict.current());++defDict)
{
cerr<<"DEFINE "<<def->name.data()<<" Value "<<def->definition.data()<<endl;
}
}
string VerilogPreProc::getIndexString(const string& x,bool upper)
{
int j=x.find('|');
if(j==0 && !upper)
return "";
if(!upper)
return x.substr(0,j);
int len=x.length()-j-1;
return x.substr(j+1,len);
}
//////
void VerilogPreProc::getPredefs()
{
static bool firstTime=TRUE;
if (firstTime)
{
// add predefined macros
DefineDict* preDict=VerilogPreProc::getPreDefineDict();
char *defStr;
QStrList &predefList = Config_getList("PREDEFINED");
QStrListIterator sli(predefList);
for (sli.toFirst();(defStr=sli.current());++sli)
{
QCString ds = defStr;
int i_equals=ds.find('=');
int i_obrace=ds.find('(');
int i_cbrace=ds.find(')');
bool nonRecursive = i_equals>0 && ds.at(i_equals-1)==':';
if (i_obrace==0) continue; // no define name
if (i_obrace<i_equals && i_cbrace<i_equals &&
i_obrace!=-1 && i_cbrace!=-1 &&
i_obrace<i_cbrace
) // predefined function macro definition
{
//printf("predefined function macro '%s'\n",defStr);
QRegExp reId("[a-z_A-Z\x80-\xFF][a-z_A-Z0-9\x80-\xFF]*"); // regexp matching an id
QDict<int> argDict(17);
argDict.setAutoDelete(TRUE);
int i=i_obrace+1,p,l,count=0;
// gather the formal arguments in a dictionary
while (i<i_cbrace && (p=reId.match(ds,i,&l)))
{
argDict.insert(ds.mid(p,l),new int(count++));
i=p+l;
}
// strip definition part
QCString tmp=ds.right(ds.length()-i_equals-1);
QCString definition;
i=0;
// substitute all occurrences of formal arguments by their
// corresponding markers
while ((p=reId.match(tmp,i,&l))!=-1)
{
if (p>i) definition+=tmp.mid(i,p-i);
int *argIndex;
if ((argIndex=argDict[tmp.mid(p,l)])!=0)
{
QCString marker;
marker.sprintf(" @%d ",*argIndex);
definition+=marker;
}
else
{
definition+=tmp.mid(p,l);
}
i=p+l;
}
if (i<(int)tmp.length()) definition+=tmp.mid(i,tmp.length()-i);
// add define definition to the dictionary of defines for this file
QCString dname = ds.left(i_obrace);
if (!dname.isEmpty())
{
Define *def = new Define;
def->name = dname;
def->definition = definition;
def->args=def->definition;
def->nargs = count;
def->isPredefined = TRUE;
def->nonRecursive = nonRecursive;
// def->fileDef = g_yyFileDef;
// def->fileName = fileline()->filename().data();
preDict->insert(def->name.data(),def);
}
//printf("#define `%s' `%s' #nargs=%d\n",
// def->name.data(),def->definition.data(),def->nargs);
}
else if ((i_obrace==-1 || i_obrace>i_equals) &&
(i_cbrace==-1 || i_cbrace>i_equals) &&
!ds.isEmpty() && (int)ds.length()>i_equals
) // predefined non-function macro definition
{
//printf("predefined normal macro '%s'\n",defStr);
Define *def = new Define;
if (i_equals==-1) // simple define without argument
{
def->name = ds;
def->definition = "1"; // substitute occurrences by 1 (true)
}
else // simple define with argument
{
int ine=i_equals - (nonRecursive ? 1 : 0);
def->name = ds.left(ine);
def->definition = ds.right(ds.length()-i_equals-1);
def->args=def->definition;
}
if (!def->name.isEmpty())
{
def->nargs = -1;
def->isPredefined = TRUE;
def->nonRecursive = nonRecursive;
// def->fileName = fileline()->filename().data();
if(!def->name.isEmpty())
preDict->insert(def->name.data(),def);
}
else
{
delete def;
}
//printf("#define `%s' `%s' #nargs=%d\n",
// def->name.data(),def->definition.data(),def->nargs);
}
}
firstTime=FALSE;
}
}
//////
\ No newline at end of file
// -*- C++ -*-
//*************************************************************************
//
// Copyright 2000-2013 by Wilson Snyder. This program is free software;
// you can redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License Version 2.0.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
//*************************************************************************
/// \file
/// \brief Verilog::Preproc: Preprocess verilog code
///
/// Authors: Wilson Snyder
///
/// Code available from: http://www.veripool.org/verilog-perl
///
//*************************************************************************
#ifndef _VPREPROC_H_
#define _VPREPROC_H_ 1
#include <string>
#include <map>
#include <iostream>
#include "qmap.h"
#include "qcstring.h"
#include "assert.h"
using namespace std;
#include "VFileLine.h"
#include "define.h"
#include <deque>
#include <stack>
/// Generic opaque pointer to VPreProcImp implementation class.
struct VPreProcOpaque {
virtual ~VPreProcOpaque() {}
};
class VDefine;
//**********************************************************************
// VPreProc
/// Verilog Preprocessor.
////
/// This defines a preprocessor. Functions are virtual so users can override them.
/// After creating, call openFile(), then getline() in a loop. The class will to the rest...
class VPreProc {
public:
VPreProc();
void configure(VFileLine* filelinep);
virtual ~VPreProc();
// STATE
private:
int m_keepComments;
int m_keepWhitespace;
bool m_lineDirectives;
bool m_pedantic;
bool m_synthesis;
public:
// CONSTANTS
enum MiscConsts {
DEFINE_RECURSION_LEVEL_MAX = 1000, // How many `def substitutions before an error
INCLUDE_DEPTH_MAX = 500, // How many `includes deep before an error
STREAM_DEPTH_LEVEL_MAX = 2000, // How many streams deep (sometimes `def deep) before an error
// // Set more than DEFINE_RECURSION_LEVEL_MAX or INCLUDE_DEPTH_MAX
NEWLINES_VS_TICKLINE = 20 // Use `line in place of this many newlines
};
// ACCESSORS
/// Insert given file into this point in input stream
void openFile(string filename, VFileLine* filelinep=NULL);
void debug(int level); ///< Set debugging level
string getall(size_t approx_chunk); ///< Return all lines, or at least approx_chunk bytes. (Null if done.)
string getline(); ///< Return next line/lines. (Null if done.)
bool isEof(); ///< Return true on EOF.
void insertUnreadback(string text);
int getNextStateToken(string & buf);
VFileLine* fileline(); ///< File/Line number for last getline call
// The default behavior is to pass all unknown `defines right through.
// This lets the user determine how to report the errors. It also nicely
// allows `celldefine and such to remain in the output stream.
// CONTROL METHODS
// These options control how the parsing proceeds
int keepComments() { return m_keepComments; }
void keepComments(int flag) { m_keepComments=flag; } // Return comments, 0=no, 1=yes, 2=callback
int keepWhitespace() { return m_keepWhitespace; }
void keepWhitespace(int flag) { m_keepWhitespace=flag; } // Return extra whitespace
bool lineDirectives() { return m_lineDirectives; }
void lineDirectives(bool flag) { m_lineDirectives=flag; } // Insert `line directives
bool pedantic() { return m_pedantic; }
void pedantic(bool flag) { m_pedantic=flag; } // Obey standard; Don't substitute `error
bool synthesis() { return m_synthesis; }
void synthesis(bool flag) { m_synthesis=flag; } // Ignore translate off
// CALLBACK METHODS
// This probably will want to be overridden for given child users of this class.
virtual void comment(string cmt) = 0; ///< Comment detected (if keepComments==2)
virtual void include(string filename) = 0; ///< Request a include file be processed
virtual void define(string name, string value, string params) = 0; ///< `define without any parameters
virtual void undef(string name) = 0; ///< Remove a definition
virtual void undefineall() = 0; ///< Remove all non-command-line definitions
virtual bool defExists(string name) = 0; ///< Return true if define exists
virtual string defParams(string name) = 0; ///< Return parameter list if define exists
virtual string defValue(string name) = 0; ///< Return value of given define (should exist)
virtual string defSubstitute(string substitute) = 0; ///< Return value to substitute for given post-parameter value
// UTILITIES
void error(string msg) { fileline()->error(msg); } ///< Report a error
void fatal(string msg) { fileline()->fatal(msg); } ///< Report a fatal error
VPreProcOpaque* getImp() const { return m_opaquep;}
private:
VPreProcOpaque* m_opaquep; ///< Pointer to parser's implementation data.
};
#include "qfileinfo.h"
class VerilogPreProc: public VPreProc
{
private:
string getIndexString(const string& x,bool upper);
static DefineDict *g_fileDefineDict;
static DefineDict *g_preDefineDict;
public:
VerilogPreProc():VPreProc(){}
~VerilogPreProc(){}
static DefineDict *getFileDefineDict()
{
if(g_fileDefineDict==0)
{
g_fileDefineDict=new DefineDict();
g_fileDefineDict->setAutoDelete(true);
}
return g_fileDefineDict;
}
static DefineDict *getPreDefineDict()
{
if(g_preDefineDict==0)
{
g_preDefineDict=new DefineDict();
g_preDefineDict->setAutoDelete(true);
}
return g_preDefineDict;
}
void getPredefs();
string performPreprocessing(const QFileInfo & qf,bool include=false);
void comment(string cmt) {} ///< Comment detected (if keepComments==2)
void include(string filename) ;
void define(string name, string value, string params) ;
void undef(string name);
///< Remove all non-command-line definitions
void undefineall() ;
bool defExists(string name);
string defParams(string name) ;
string defValue(string name) ;
string defSubstitute(string substitute);
void printDict();
};
#endif // Guard
#ifndef SETTINGS_H
#define SETTINGS_H
#define USE_SQLITE3 0
#define USE_LIBCLANG 0
#define IS_SUPPORTED(x) \
((USE_SQLITE3 && strcmp("USE_SQLITE3",(x))==0) || \
(USE_LIBCLANG && strcmp("USE_LIBCLANG",(x))==0) || \
0)
#endif
/******************************************************************************
* Copyright (c) M.Kreis,2009
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*
* You may use and distribute this software under the terms of the
* GNU General Public License, version 2 or later
*****************************************************************************/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "verilogdocgen.h"
#include "verilogscanner.h"
#include "membergroup.h"
#include "vhdldocgen.h"
#include "doxygen.h"
#include "searchindex.h"
#include "commentscan.h"
#include "layout.h"
#include "arguments.h"
#include "qdir.h"
#include "util.h"
#include "definition.h"
// sets the member spec variable for global variables
// needed for writing file declarations
static void setType(MemberList* ml);
static void parseDefineConstruct(QCString&, MemberDef*,OutputList& ol);
static void writeFunctionProto(OutputList& ol,const ArgumentList* al,const MemberDef* mdef);
static QDict<MemberDef> variableDict(10007);
static QDict<MemberDef> instPortDict(10007);
static QDict<MemberDef> classPortDict(10007);
static QDict<MemberDef> functionDict(5003);
static QDict<MemberDef> globalMemDict(5003);
static QList<MemberDef> includeMemList;
static QDict<MemberDef> classglobDict(17);
static QDict<ClassDef> classInnerDict(17);
Entry* VerilogDocGen::getEntryAtLine(const Entry* ce,int line)
{
EntryListIterator eli(*ce->children());
Entry *found=0;
Entry *rt;
for (;(rt=eli.current());++eli)
{
if (rt->bodyLine==line)
{
found=rt;
} // if
if (!found)
{
found=getEntryAtLine(rt,line);
}
}
return found;
}// getEntryAtLine
static QList<Entry> lineEntry;
QList<Entry>* VerilogDocGen::getEntryAtLine1(const Entry* ce,int line)
{
EntryListIterator eli(*ce->children());
Entry *rt;
for (;(rt=eli.current());++eli)
{
if (rt->bodyLine==line)
{
lineEntry.insert(0,rt);
} // if
getEntryAtLine1(rt,line);
}
return &lineEntry;
}// getEntryAtLine
void VerilogDocGen::adjustOpName(QCString & nn)
{
QRegExp regg("[_a-zA-Z]");
int j=nn.find(regg,0);
if (j>0)
nn=nn.mid(j,nn.length());
}
void VerilogDocGen::adjustMemberName(MemberDef* md)
{
QRegExp regg("[_a-zA-Z]");
QCString nn=md->name();
int j=nn.find(regg,0);
if (j>0)
nn=nn.mid(j,nn.length());
md->setName(nn.data());
}
QCString VerilogDocGen::convertTypeToString(int type,bool sing)
{
switch(type){
case(VerilogDocGen::MODULE) :
if(sing)return "Module";
return "Modules";
case( VerilogDocGen::FUNCTION):
if(sing)return "Function";
return "Functions";
case( VerilogDocGen::TASK):
if(sing)return "Task";
return "Tasks";
case(VerilogDocGen::PRIMITIVE):
if(sing)return "Primitive";
return "Primitives";
case(VerilogDocGen::PARAMETER):
if(sing) return "Parameter";
return "Parameters";
case(VerilogDocGen::COMPONENT):
if(sing) return "Module Instance";
return "Module Instances";
case( VerilogDocGen::PORT):
if(sing) return "Port";
return "Ports";
case( VerilogDocGen::ALWAYS):
if(sing) return "Always Construct";
else
return "Always Constructs";
case( VerilogDocGen::INPUT):
if(sing)return "Input";
return "Inputs";
case( VerilogDocGen::OUTPUT):
if(sing) return "Output";
return "Outputs";
case( VerilogDocGen::INOUT):
if(sing) return "Inout";
return "Inouts";
case(VerilogDocGen::FEATURE):
if(sing) return "Define";
else
return "Defines";
case( VerilogDocGen::TIME):
return "Time";
case( VerilogDocGen::INCLUDE):
if(sing) return "Include";
return "Includes";
case(VerilogDocGen::SIGNAL):
if(sing)
return "Signal";
return "Signals";
case(VerilogDocGen::LIBRARY):
if(sing)
return "Library";
return "Libraries";
case(VerilogDocGen::CONFIGURATION):
if(sing)
return "Configuration";
return "Configurations";
case(VhdlDocGen::UCF_CONST):
if(sing)
return "Constraint";
return "Constraints";
case(VhdlDocGen::MISCELLANEOUS):
if(sing)
return "Miscellaneous";
return "Miscellaneous";
default: return "";
}
} // convertType
void setType(MemberList *ml){
if (ml==0) return ;
MemberDef *mdd=0;
MemberListIterator mmli(*ml);
for ( ; (mdd=mmli.current()); ++mmli )
{
QCString type(mdd->typeString());
if(type=="feature")
mdd->setMemberSpecifiers(VerilogDocGen::FEATURE);
else if(type=="include")
mdd->setMemberSpecifiers(VerilogDocGen::INCLUDE);
else if(type=="library")
mdd->setMemberSpecifiers(VerilogDocGen::LIBRARY);
else if(type=="configuration")
mdd->setMemberSpecifiers(VerilogDocGen::CONFIGURATION);
else if (type=="misc")
{
mdd->setMemberSpecifiers(VhdlDocGen::MISCELLANEOUS);
}
else if (type=="ucf_const")
{
mdd->setMemberSpecifiers(VhdlDocGen::UCF_CONST);
}
}
}
void VerilogDocGen::writeVerilogDeclarations(MemberList* ml,OutputList &ol,
ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd,
const char *title,const char *subtitle,bool showEnumValues,int type) {
MemberDef *mdd=NULL;
// if(ml==NULL) return;
MemberListIterator mmli(*ml);
setType(ml);
if (!VhdlDocGen::membersHaveSpecificType(ml,type)) return;
if (title)
{
ol.startMemberHeader(title);
ol.parseText(title);
ol.endMemberHeader();
ol.docify(" ");
}
if (subtitle && subtitle[0]!=0)
{
//printf("subtitle=`%s'\n",subtitle);
ol.startMemberSubtitle();
ol.generateDoc("[generated]",-1,0,0,subtitle,FALSE,FALSE);
ol.endMemberSubtitle();
}
VerilogDocGen::writePlainVerilogDeclarations(mdd,ml,ol,cd,nd,fd,gd,type);
if (ml->getMemberGroupList())
{
MemberGroupListIterator mgli(*ml->getMemberGroupList());
MemberGroup *mg;
while ((mg=mgli.current()))
{
// assert(0);
if (VhdlDocGen::membersHaveSpecificType(mg->members(),type))
{
//printf("mg->header=%s\n",mg->header().data());
bool hasHeader=mg->header()!="[NOHEADER]";
ol.startMemberGroupHeader(hasHeader);
if (hasHeader)
{
ol.parseText(mg->header());
}
ol.endMemberGroupHeader();
if (!mg->documentation().isEmpty())
{
//printf("Member group has docs!\n");
ol.startMemberGroupDocs();
ol.generateDoc("[generated]",-1,0,0,mg->documentation()+"\n",FALSE,FALSE);
ol.endMemberGroupDocs();
}
ol.startMemberGroup();
//printf("--- mg->writePlainDeclarations ---\n");
//mg->writePlainDeclarations(ol,cd,nd,fd,gd);
VerilogDocGen::writePlainVerilogDeclarations(0,mg->members(),ol,cd,nd,fd,gd,type);
ol.endMemberGroup(hasHeader);
}
++mgli;
}
}
}// writeVerilogDeclarations
void VerilogDocGen::writePlainVerilogDeclarations(MemberDef* mdef,MemberList* mlist,OutputList &ol,
ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd,int specifier){
ol.pushGeneratorState();
bool first=TRUE;
MemberDef *md;
MemberListIterator mli(*mlist);
for ( ; (md=mli.current()); ++mli )
{
int mems=md->getMemberSpecifiers();
if (md->isBriefSectionVisible() && (mems==specifier))
{
if (first) ol.startMemberList(),first=FALSE;
VerilogDocGen::writeVerilogDeclarations(md,ol,cd,nd,fd,gd,false);
}//if
}//for
if (!first) ol.endMemberList();
}//plainDeclaration
void VerilogDocGen::writeVerilogDeclarations(MemberList* ml,OutputList& ol,GroupDef* gd,ClassDef* cd,FileDef* fd){
VerilogDocGen::writeVerilogDeclarations(ml,ol,cd,0,fd,gd,VerilogDocGen::convertTypeToString(VerilogDocGen::LIBRARY,FALSE),0,FALSE,VerilogDocGen::LIBRARY);
VerilogDocGen::writeVerilogDeclarations(ml,ol,cd,0,fd,gd,VerilogDocGen::convertTypeToString(VerilogDocGen::INPUT,FALSE),0,FALSE,VerilogDocGen::INPUT);
VerilogDocGen::writeVerilogDeclarations(ml,ol,cd,0,fd,gd,VerilogDocGen::convertTypeToString(VerilogDocGen::INOUT,FALSE),0,FALSE,VerilogDocGen::INOUT);
VerilogDocGen::writeVerilogDeclarations(ml,ol,cd,0,fd,gd,VerilogDocGen::convertTypeToString(VerilogDocGen::OUTPUT,FALSE),0,FALSE,VerilogDocGen::OUTPUT);
VerilogDocGen::writeVerilogDeclarations(ml,ol,cd,0,fd,gd,VerilogDocGen::convertTypeToString(VerilogDocGen::PARAMETER,FALSE),0,FALSE,VerilogDocGen::PARAMETER);
VerilogDocGen::writeVerilogDeclarations(ml,ol,cd,0,fd,gd,VerilogDocGen::convertTypeToString(VerilogDocGen::MODULE,FALSE),0,FALSE,VerilogDocGen::MODULE);
VerilogDocGen::writeVerilogDeclarations(ml,ol,cd,0,fd,gd,VerilogDocGen::convertTypeToString(VerilogDocGen::CONFIGURATION,FALSE),0,FALSE,VerilogDocGen::CONFIGURATION);
VerilogDocGen::writeVerilogDeclarations(ml,ol,cd,0,fd,gd,VerilogDocGen::convertTypeToString(VerilogDocGen::PORT,FALSE),0,FALSE,VerilogDocGen::PORT);
VerilogDocGen::writeVerilogDeclarations(ml,ol,cd,0,fd,gd,VerilogDocGen::convertTypeToString(VerilogDocGen::FEATURE,FALSE),0,FALSE,VerilogDocGen::FEATURE);
VerilogDocGen::writeVerilogDeclarations(ml,ol,cd,0,fd,gd,VerilogDocGen::convertTypeToString(VerilogDocGen::INCLUDE,FALSE),0,FALSE,VerilogDocGen::INCLUDE);
VerilogDocGen::writeVerilogDeclarations(ml,ol,cd,0,fd,gd,VerilogDocGen::convertTypeToString(VerilogDocGen::SIGNAL,FALSE),0,FALSE,VerilogDocGen::SIGNAL);
VerilogDocGen::writeVerilogDeclarations(ml,ol,cd,0,fd,gd,VerilogDocGen::convertTypeToString(VerilogDocGen::FUNCTION,FALSE),0,FALSE,VerilogDocGen::FUNCTION);
VerilogDocGen::writeVerilogDeclarations(ml,ol,cd,0,fd,gd,VerilogDocGen::convertTypeToString(VerilogDocGen::ALWAYS,FALSE),0,FALSE,VerilogDocGen::ALWAYS);
VerilogDocGen::writeVerilogDeclarations(ml,ol,cd,0,fd,gd,VerilogDocGen::convertTypeToString(VerilogDocGen::TASK,FALSE),0,FALSE,VerilogDocGen::TASK);
VerilogDocGen::writeVerilogDeclarations(ml,ol,cd,0,fd,gd,VerilogDocGen::convertTypeToString(VerilogDocGen::COMPONENT,FALSE),0,FALSE,VerilogDocGen::COMPONENT);
VerilogDocGen::writeVerilogDeclarations(ml,ol,cd,0,fd,gd,VerilogDocGen::convertTypeToString(VhdlDocGen::MISCELLANEOUS,FALSE),0,FALSE,VhdlDocGen::MISCELLANEOUS);
VerilogDocGen::writeVerilogDeclarations(ml,ol,cd,0,fd,gd,VerilogDocGen::convertTypeToString(VhdlDocGen::UCF_CONST,FALSE),0,FALSE,VhdlDocGen::UCF_CONST);
}
void VerilogDocGen::writeTagFile(MemberDef *mdef,FTextStream &tagFile)
{
if (!Config_getString("GENERATE_TAGFILE").isEmpty())
{
int memType=mdef->getMemberSpecifiers();
tagFile << " <member kind=\"";
tagFile << VerilogDocGen::convertTypeToString(memType);
tagFile << "\">" << endl;
tagFile << " <type>" << convertToXML(mdef->typeString()) << "</type>" << endl;
tagFile << " <name>" << convertToXML(mdef->name()) << "</name>" << endl;
tagFile << " <anchorfile>" << convertToXML(mdef->getOutputFileBase()+Doxygen::htmlFileExtension) << "</anchorfile>" << endl;
tagFile << " <anchor>" << convertToXML(mdef->anchor()) << "</anchor>" << endl;
if(memType==VerilogDocGen::FUNCTION)
tagFile << " <arglist>" << convertToXML(VhdlDocGen::convertArgumentListToString(mdef->argumentList(),true)) << "</arglist>" << endl;
else if(memType==VerilogDocGen::ALWAYS)
tagFile << " <arglist>" << convertToXML(VhdlDocGen::convertArgumentListToString(mdef->argumentList(),false)) << "</arglist>" << endl;
else{
tagFile << " <arglist>" << convertToXML(mdef->argsString()) << "</arglist>" << endl;
tagFile << " <arglist>" << convertToXML(mdef->typeString()) << "</arglist>" << endl;
}
mdef->writeDocAnchorsToTagFile(tagFile);
tagFile << " </member>" << endl;
}
}
void VerilogDocGen::writeVerilogDeclarations(MemberDef* mdef,OutputList &ol,
ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd,
bool inGroup) {
static bool bComp=false;
//LockingPtr<MemberDef> lock(mdef,mdef);
Definition *d=0;
// ASSERT (cd!=0 || nd!=0 || fd!=0 || gd!=0); // member should belong to something
//static_cast<VPreProcImp*>(m_opaquep);
if (cd) d=cd;
else if (nd) d=(Definition*)nd;
else if (fd) d=fd;
else if (gd) d=(Definition*)gd;
else d=(Definition*)mdef;
//if (cd) d=cd;
// write tag file information of this member
int memType=mdef->getMemberSpecifiers();
// write search index info
if (Doxygen::searchIndex)
{
Doxygen::searchIndex->setCurrentDoc(mdef,mdef->anchor(),FALSE);
Doxygen::searchIndex->addWord(mdef->localName(),TRUE);
Doxygen::searchIndex->addWord(mdef->qualifiedName(),FALSE);
}
QCString cname = d->name();
QCString cfname = mdef->getOutputFileBase();
// HtmlHelp *htmlHelp=0;
// bool hasHtmlHelp = Config_getBool("GENERATE_HTML") && Config_getBool("GENERATE_HTMLHELP");
// if (hasHtmlHelp) htmlHelp = HtmlHelp::getInstance();
// search for the last anonymous scope in the member type
// ClassDef *annoClassDef=mdef->getClassDefOfAnonymousType();
// start a new member declaration
// bool isAnonymous = annoClassDef; // || m_impl->annMemb || m_impl->annEnumType;
///printf("startMemberItem for %s\n",name().data());
// if(mdef->getMemberSpecifiers()==VerilogDocGen::FEATURE)
// ol.startMemberItem(mdef->anchor(),3); //? 1 : m_impl->tArgList ? 3 : 0);
// else
ol.startMemberItem(mdef->anchor(), 0);// ? 1 : m_impl->tArgList ? 3 : 0);
// If there is no detailed description we need to write the anchor here.
bool detailsVisible = mdef->isDetailedSectionLinkable();
if (!detailsVisible) // && !m_impl->annMemb)
{
QCString doxyName=mdef->name().copy();
if (!cname.isEmpty()) doxyName.prepend(cname+"::");
QCString doxyArgs=mdef->argsString();
ol.startDoxyAnchor(cfname,cname,mdef->anchor(),doxyName,doxyArgs);
ol.pushGeneratorState();
ol.disable(OutputGenerator::Man);
ol.disable(OutputGenerator::Latex);
ol.docify("\n");
ol.popGeneratorState();
}
// *** write type
/*Verilog CHANGE */
VerilogDocGen::adjustMemberName(mdef);
QCString ltype(mdef->typeString());
QCString largs(mdef->argsString());
int mm=mdef->getMemberSpecifiers();
ClassDef *kl=NULL;
FileDef *fdd=NULL;
ArgumentList *alp = mdef->argumentList();
QCString nn;
if(gd)gd=NULL;
switch(mm)
{
case VhdlDocGen::MISCELLANEOUS:
VhdlDocGen::writeSource(mdef,ol,nn);
break;
case VhdlDocGen::UCF_CONST:
mm=mdef->name().findRev('_');
if(mm>0)
mdef->setName(mdef->name().left(mm));
VhdlDocGen::writeUCFLink(mdef,ol);
break;
case VerilogDocGen::INCLUDE:
bool ambig;
largs=mdef->name();
fdd=findFileDef(Doxygen::inputNameDict,largs.data(),ambig);
if(fdd){
QCString fbb=fdd->getFileBase();
fbb=fdd->getReference();
fbb= fdd->getOutputFileBase();
fbb=fdd->getSourceFileBase();
fbb=fdd->convertNameToFile(largs.data(),true);
fbb=fdd->getPath();
fbb+=fdd->getOutputFileBase()+".html";
ol.writeObjectLink(fdd->getReference(),
fdd->getOutputFileBase(),
0,
fdd->name());
}
else
VhdlDocGen::formatString(largs,ol,mdef);
break;
case VerilogDocGen::FEATURE:
parseDefineConstruct(largs,mdef,ol);
break;
case VerilogDocGen::MODULE:
ol.startBold();
VhdlDocGen::formatString(ltype,ol,mdef);
ol.endBold();
ol.insertMemberAlign();
//writeLink(mdef,ol);
case VerilogDocGen::PORT:
writeLink(mdef,ol);
ol.insertMemberAlign();
if(largs.length()>0)
VhdlDocGen::formatString(largs,ol,mdef);
if(ltype.length()>0)
VhdlDocGen::formatString(ltype,ol,mdef);
break;
case VerilogDocGen::ALWAYS:
writeLink(mdef,ol);
ol.insertMemberAlign();
VhdlDocGen::writeProcessProto(ol,alp,mdef);
break;
case VerilogDocGen::FUNCTION:
case VerilogDocGen::TASK:
writeLink(mdef,ol);
ol.docify(" ");// need for pdf has no effect in html
ol.insertMemberAlign();
if(ltype.length()>0)
VhdlDocGen::formatString(ltype,ol,mdef);
writeFunctionProto(ol,alp,mdef);
break;
case VerilogDocGen::SIGNAL:
if(largs.length()>0)
VhdlDocGen::formatString(largs,ol,mdef);
ol.docify(" ");
ol.insertMemberAlign();
writeLink(mdef,ol);
ol.docify(" ");
if(ltype.length())
VhdlDocGen::formatString(ltype,ol,mdef);
break;
case VerilogDocGen::CONFIGURATION:
case VerilogDocGen::LIBRARY:
writeLink(mdef,ol);
break;
case VerilogDocGen::INPUT:
case VerilogDocGen::OUTPUT:
case VerilogDocGen::INOUT:
case VerilogDocGen::PARAMETER:
writeLink(mdef,ol);
ol.docify(" ");
ol.insertMemberAlign();
if(ltype.length()>0){
VhdlDocGen::formatString(ltype,ol,mdef);
ol.writeString(" ");
}
//ol.insertMemberAlign();
if(largs.length()>0)
VhdlDocGen::formatString(largs,ol,mdef);
break;
case VerilogDocGen::COMPONENT:
//VhdlDocGen::writeLink(mdef,ol);
if(true)
{
nn=mdef->name();
kl=VhdlDocGen::getClass(nn);
//if(kl==NULL){
ol.startBold();
QCString inst=mdef->name()+"::"+ltype;
ol.writeObjectLink(mdef->getReference(),
mdef->getOutputFileBase(),
mdef->anchor(),
inst.data());
ol.docify(" ");
ol.endBold();
//}
ol.insertMemberAlign();
if(kl) {
nn=kl->getOutputFileBase();
ol.pushGeneratorState();
ol.disableAllBut(OutputGenerator::Html);
ol.docify(" ");
QCString name=VerilogDocGen::getClassTitle(kl);
name=VhdlDocGen::getIndexWord(name.data(),1);
// ol.insertMemberAlign();
ol.startBold();
ol.docify(name.data());
ol.endBold();
ol.startEmphasis();
ol.docify(" ");
ol.writeObjectLink(kl->getReference(),kl->getOutputFileBase(),0,mdef->name().data());
ol.endEmphasis();
ol.popGeneratorState();
}
if(largs.data())
{
ol.docify(" ");
ol.docify(largs.data());
}
}
break;
default: break;
}
bool htmlOn = ol.isEnabled(OutputGenerator::Html);
if (htmlOn && !ltype.isEmpty())
{
ol.disable(OutputGenerator::Html);
}
if (!ltype.isEmpty()) ol.docify(" ");
if (htmlOn)
{
ol.enable(OutputGenerator::Html);
}
if (!detailsVisible)// && !m_impl->annMemb)
{
ol.endDoxyAnchor(cfname,mdef->anchor());
}
//printf("endMember %s annoClassDef=%p annEnumType=%p\n",
// name().data(),annoClassDef,annEnumType);
ol.endMemberItem();
//fprintf(stderr,"\n%d %s",mdef->docLine,mdef->name().data());
if (!mdef->briefDescription().isEmpty() && Config_getBool("BRIEF_MEMBER_DESC") /* && !annMemb */)
{
ol.startMemberDescription(mdef->anchor());
ol.generateDoc(mdef->briefFile(),mdef->briefLine(),mdef->getOuterScope()?mdef->getOuterScope():d,mdef,mdef->briefDescription(),TRUE,FALSE,0,TRUE,FALSE);
if (detailsVisible)
{
ol.pushGeneratorState();
ol.disableAllBut(OutputGenerator::Html);
//ol.endEmphasis();
ol.docify(" ");
if (mdef->getGroupDef()!=0 && gd==0) // forward link to the group
{
ol.startTextLink(mdef->getOutputFileBase(),mdef->anchor());
}
else // local link
{
ol.startTextLink(0,mdef->anchor());
}
ol.endTextLink();
//ol.startEmphasis();
ol.popGeneratorState();
}
//ol.newParagraph();
ol.endMemberDescription();
// if(VhdlDocGen::isComponent(mdef))
// ol.lineBreak();
}
mdef->warnIfUndocumented();
}// end writeVerilogDeclaration
// returns the name of module/primitive
QCString VerilogDocGen::getClassTitle(const ClassDef* cdef){
if(cdef->protection()==Public)
return cdef->className()+" Module";
return cdef->className()+" Primitive";
}// getClassTitle
//-----------------< Code Parsing >------------------------------------------------
static bool buildInst=false;
void buildVariableDict(ClassDef *inst, ClassDef *cl)
{
MemberList *instPort=NULL;
MemberList *classPort=NULL;
instPortDict.clear();
classPortDict.clear();
if(inst!=NULL)
instPort=inst->getMemberList(MemberListType_variableMembers);
if(cl!=NULL)
classPort=cl->getMemberList(MemberListType_variableMembers);
if(instPort)
{
MemberListIterator mnii(*instPort);
MemberDef *md;
for (mnii.toFirst();(md=mnii.current());++mnii){
//printf("\n Inst: %s %s %s",md->name().data(),md->getOutputFileBase().data(),md->getReference().data());
instPortDict.insert(md->name().data(),md);
}
}
if(classPort)
{
MemberListIterator mnii(*classPort);
MemberDef *md;
for (mnii.toFirst();(md=mnii.current());++mnii){
// printf("\n Class: %s %s %s",md->name().data(),md->getOutputFileBase().data(),md->getReference().data());
classPortDict.insert(md->name().data(),md);
}
}
}//funct
void buildVariableDict(ClassDef *cd)
{
if(cd==0) return;
variableDict.clear();
MemberList* ml=cd->getMemberList(MemberListType_variableMembers);
if(ml)
{
MemberListIterator mnii(*ml);
MemberDef *md;
for (mnii.toFirst();(md=mnii.current());++mnii)
{
VerilogDocGen::adjustMemberName(md);
variableDict.insert(md->name().data(),md);
}
}
ml=cd->getMemberList(MemberListType_pubMethods);
if(ml)
{
MemberListIterator mnii(*ml);
MemberDef *md;
for (mnii.toFirst();(md=mnii.current());++mnii)
variableDict.insert(md->name().data(),md);
}
}
MemberDef* VerilogDocGen::findInstMember(QCString & cl,QCString & inst,QCString & key,bool b)
{
ClassDef* cdInst=0;
ClassDef* cdClass=0;
if(!cl.isEmpty())
cdClass= VhdlDocGen::getClass(cl.data());
if(!inst.isEmpty())
cdInst= VhdlDocGen::getClass(inst.data());
if(!buildInst)
{
buildVariableDict(cdInst,cdClass);
buildInst=true;
}
if(!b)
return classPortDict.find(key.data());
else
return instPortDict.find(key.data());
}//find
MemberDef* VerilogDocGen::findMember(QCString& className, QCString& memName,int type)
{
ClassDef* cd;
MemberDef *mdef=NULL;
bool feat=false;
buildInst=false;
cd= VhdlDocGen::getClass(className.data());
// if(!cd) return NULL;
if(memName.contains('`'))
memName.stripPrefix("`");
mdef=VerilogDocGen::findMemberDef(cd,memName,MemberListType_variableMembers,type,feat);
if(mdef) return mdef;
// mdef=VerilogDocGen::findMemberDef(cd,memName,MemberList:: pubMethods,type,feat);
// if(mdef) return mdef;
// QCString file=VerilogDocGen::getFileNameFromString(cd->getDefFileName().data());
// mdef = findGlobalMember(file,memName);
return mdef;
}//findMember
MemberDef* VerilogDocGen::findMemberDef(ClassDef* cd,QCString& key,MemberListType type,int spec,bool def)
{
static QCString className;
static QCString prevName;
static ClassDef* sClass=0;
MemberDef *mem=NULL;
if(cd==0)
{
mem=globalMemDict.find(key.data());
if(mem) return mem;
return NULL;
}
className=cd->name();
if(prevName != className )
{
prevName=className;
buildVariableDict(cd);
}
if(mem==0)
mem=variableDict.find(key.data());
if(mem)
{
return mem;
}
mem=globalMemDict.find(key.data());
if(mem)
return mem;
return NULL;
}//findMemberDef
void
VerilogDocGen::buildGlobalVerilogVariableDict(const FileDef* fd,bool clear,int level)
{
if(fd==0)return;
if(clear)
{
globalMemDict.clear();
classInnerDict.clear();
}
MemberDef *md=NULL;
MemberList *ml= fd->getMemberList(MemberListType_decVarMembers);
if(ml!=NULL)
{
MemberListIterator fmni(*ml);
for (fmni.toFirst();(md=fmni.current());++fmni)
{
VerilogDocGen::adjustMemberName(md);
//if(stricmp(md->typeString(),"include")==0)
/*
if(!findIncludeName(md->name().data()))
{
// printf("\n insert %s",md->name());
includeMemList.append(md);
}
*/
// printf("\n %s .... ",md->name().data());
// ClassDef *ch=md->getClassDef();
// if(ch==0)
globalMemDict.insert(md->name().data(),md);
}
}
ml= fd->getMemberList( MemberListType_decFuncMembers);
if(ml!=0)
{
MemberListIterator fmni(*ml);
for (fmni.toFirst();(md=fmni.current());++fmni)
{
VerilogDocGen::adjustMemberName(md);
globalMemDict.insert(md->name().data(),md);
}
}
}
MemberDef* VerilogDocGen::findDefinition(ClassDef *cd, QCString& memName){
MemberDef *md;
MemberList *ml= cd->getMemberList(MemberListType_variableMembers);
if(ml==NULL) return NULL;
MemberListIterator fmni(*ml);
for (fmni.toFirst();(md=fmni.current());++fmni)
{
if(md->getMemberSpecifiers()==VerilogDocGen::INCLUDE){
ClassDef* cdef= VhdlDocGen::getClass(md->name());
if(cdef){
MemberDef* mdd=VerilogDocGen::findMemberDef(cdef,memName,MemberListType_variableMembers,-1,false);
MemberList *ml= cdef->getMemberList(MemberListType_variableMembers);
assert(ml);
if(mdd) return mdd;
MemberListIterator fmni(*ml);
//assert(false);
}
}
}//for
return NULL;
}//findDefinition
/*
MemberName* VerilogDocGen::findMemberNameSDict(QCString& mName,const QCString& className)
{
MemberName *mn=0;
MemberDef *md;
MemberNameSDict::Iterator mnli(*Doxygen::memberNameSDict);
// for each member name
for (mnli.toFirst();(mn=mnli.current());++mnli)
{
QCString temp(mn->memberName());
VhdlDocGen::adjustMemberName(temp);
if(stricmp(mName.data(),temp.data())==0){
MemberNameIterator mni(*mn);
for (mni.toFirst();(md=mni.current());++mni)
{
ClassDef *cd=md->getClassDef();
if(cd){
QCString nn=cd->displayName();
if(stricmp(nn.data(),className.data())==0)
return mn;
}
}
}//if
}
return 0;
}//findMemberNameSdict
*/
void VerilogDocGen::initEntry(Entry *e)
{
e->fileName +=getVerilogParsingFile();
e->lang=SrcLangExt_VERILOG;
initGroupInfo(e);
}
/*!
* writes a function/Task prototype to the output
*/
void writeFunctionProto(OutputList& ol,const ArgumentList* al,const MemberDef* mdef)
{
if (al==0) return;
ArgumentListIterator ali(*al);
Argument *arg;
bool sem=FALSE;
int len=al->count();
ol.startBold();
ol.docify(" ( ");
ol.endBold();
if (len>2)
{
//ol.lineBreak();
ol.docify("\n ");;
}
for (;(arg=ali.current());++ali)
{
ol.startBold();
if (sem && len < 3)
{
ol.docify(" , ");
}
QCString nn=arg->name.simplifyWhiteSpace();
VerilogDocGen::adjustOpName(nn);
// nn+=" ";
VhdlDocGen::formatString(nn,ol,mdef);
QCString qargs=arg->type.simplifyWhiteSpace();
QCString att=arg->defval.simplifyWhiteSpace();
if (!att.isEmpty())
{
const QCString* str=VerilogDocGen::findKeyWord(att.data());
// att+=" ";
if (str==0)
VhdlDocGen::formatString(att,ol,mdef);
else
VhdlDocGen::startFonts(att,str->data(),ol);
}
ol.docify(":");
//VhdlDocGen::startFonts("in ","stringliteral",ol);
const QCString* str=VerilogDocGen::findKeyWord(qargs.data());
// ol.startEmphasis();
if (str==0)
VhdlDocGen::formatString(qargs,ol,mdef);
else
VhdlDocGen::startFonts(qargs,str->data(),ol);
// ol.endEmphasis();
sem=TRUE;
ol.endBold();
if (len > 2)
{
ol.docify("\n");;
//ol.lineBreak();
}
}
ol.startBold();
ol.docify(" )");
const char *exp=mdef->excpString();
if(exp)
{
ol.insertMemberAlign();
ol.docify("[ ");
ol.docify(exp);
ol.docify(" ]");
}
ol.endBold();
}
QCString VerilogDocGen::getFileNameFromString(const char* fileName){
QCString qfile(fileName);
QStringList ql=QStringList::split('/',qfile);
QCString lp=ql.last().data();
return lp;
}
void parseDefineConstruct(QCString & largs, MemberDef* mdef ,OutputList& ol)
{
// QCString largs=mdef->getDefinition();
int kr=largs.contains("\\?");
ol.startBold();
VerilogDocGen::writeLink(mdef,ol);
ol.docify(" ");
ol.insertMemberAlign();
ol.startTextBlock();
if(kr>0)
{
largs=mdef->definition();
largs.stripPrefix("feature");
while(largs.stripPrefix(" "));
largs.stripPrefix(mdef->name().data());
QStringList ql=QStringList::split("\\?",largs,false);
for(uint i=0;i<ql.count();i++)
{
// ol.startParagraph();
QCString val=ql[i].data();
//ol.codify(val.data());
VhdlDocGen::formatString(val,ol,mdef);
// ol.lineBreak();
// ol.endParagraph();
}
}
else
VhdlDocGen::formatString(largs,ol,mdef);
ol.endTextBlock(true);
ol.endBold();
}
void VerilogDocGen::writeSource(MemberDef *mdef,OutputList& ol,QCString & cname)
{
// Definition d=(Definition)mdef;
static bool optVerilog = Config_getBool("OPTIMIZE_OUTPUT_VERILOG");
/*
if(optVerilog){
VerilogDocGen::writeSource(mdef,ol,cname);
return;
}
*/
QCString fdd=mdef->getDefFileExtension();
QCString scope=mdef->getScopeString();
QCString codeFragment=mdef->documentation();
//FileDef *fd=mdef->getFileDef();
FileDef *fd=mdef->getBodyDef();
QCString defFileName;
assert(fd);
QStringList qsl=QStringList::split("\n",codeFragment);
ParserInterface *pIntf = Doxygen::parserManager->getParser(fdd.data());
pIntf->resetCodeParserState();
ol.startParagraph();
ol.startCodeFragment();
ol.endCodeFragment();
ol.endParagraph();
mdef->writeSourceDef(ol,cname);
mdef->writeSourceRefs(ol,cname);
mdef->writeSourceReffedBy(ol,cname);
}
char* VerilogDocGen::removeLastWord(const char* word)
{
QRegExp exp("[\\s]");
QCString str(word);
str=str.simplifyWhiteSpace();
int u=str.findRev(exp);
if(u==-1)
return "";
str=str.left(u);
return str.data();
}
QCString VerilogDocGen::findFile(const char *fileName)
{
QStrList &includePath = Config_getList("INCLUDE_PATH");
char *s=includePath.first();
while (s)
{
QCString absName;
absName += (QCString)s+"/"+fileName;
QFileInfo fin(absName);
if( fin.exists() && fin.isFile())
return absName;
s=includePath.next();
}
return "";
}
void VerilogDocGen::writeLink(const MemberDef* mdef,OutputList &ol)
{
QCString nn=mdef->name();
adjustOpName(nn);
ol.writeObjectLink(mdef->getReference(),
mdef->getOutputFileBase(),
mdef->anchor(),
nn);
}
/******************************************************************************
* Copyright (c) M.Kreis,2009
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*
* You may use and distribute this software under the terms of the
* GNU General Public License, version 2 or later
*****************************************************************************/
#ifndef VerilogDocGen_h
#define VerilogDocGen_h
#include "entry.h"
#include "verilogscanner.h"
//#include "vhdlscanner.h"
#include "qfileinfo.h"
#include "vhdldocgen.h"
#include "config.h"
// wrapper class for the parser
class MyParserConv
{
public:
uint iFileSize;
~MyParserConv(){}
MyParserConv(){}
int parse(MyParserConv*);
int doLex();
};
class VerilogDocGen
{
public:
// enum VerilogClasses {ENTITYCLASS,PACKBODYCLASS,ARCHITECTURECLASS,PACKAGECLASS};
enum States {STATE_FUNCTION=0x100,STATE_MODULE,STATE_UDP,STATE_TASK,STATE_GENERATE};
enum VerilogKeyWords
{
MODULE=0x1000,
FUNCTION, //4097
FEATURE,
PRIMITIVE,
COMPONENT, //4100
PORT,
PARAMETER, //4102
ALWAYS, //4103
TASK, //4104
OUTPUT, //4105
INPUT, //4106
INOUT, //4107
DEFPARAM,
SPECPARAM,
GENERATE,
INCLUDE,
TIME,
SIGNAL,
LIBRARY,
CONFIGURATION
};
// functions for verilog parser ---------------------
static void writeSource(MemberDef *mdef,OutputList& ol,QCString & cname);
static QCString convertTypeToString(int type,bool sing=true);
static void writeVerilogDeclarations(MemberList* ml,OutputList &ol,
ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd,
const char *title,const char *subtitle,bool showEnumValues,int type);
static void writeVerilogDeclarations(MemberList* ml,OutputList& ol,GroupDef* gd,ClassDef* cd,FileDef* fd=NULL);
static void writePlainVerilogDeclarations(MemberDef* mdef,MemberList* mlist,OutputList &ol,
ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd,int specifier);
static void writeVerilogDeclarations(MemberDef* mdef,OutputList &ol,
ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd,
bool inGroup);
// insert a new entry
static Entry* makeNewEntry(char* name=NULL,int sec=0,int spec=0,int line=0,bool add=true);
static MemberDef* findMember(QCString& className, QCString& memName,int type);
static MemberDef* findMemberDef(ClassDef* cd,QCString& key,MemberListType type,
int t,bool def=false);
static void setCurrVerilogClass(QCString&);
// returns the definition which is found in class
static MemberDef* findDefinition(ClassDef* cd, QCString& memName);
// return the module/primitve name
static QCString getClassTitle(const ClassDef*);
// returns the color of a keyword if one is found
static const QCString* findKeyWord(const char*);
static void initEntry(Entry *e);
static char* removeLastWord(const char* word);
static QCString getFileNameFromString(const char* fileName);
static void writeLink(const MemberDef* mdef,OutputList &ol);
static void adjustMemberName(MemberDef* md) ;
static void adjustOpName(QCString & nn) ;
// returns the entry found at line
static Entry* getEntryAtLine(const Entry* ce,int line);
static QList<Entry>* getEntryAtLine1(const Entry* ce,int line);
static void buildGlobalVerilogVariableDict(const FileDef* fileDef,bool clear=FALSE,int level=0);
static MemberDef* findInstMember(QCString& cl,QCString& inst,QCString& key,bool b);
static QCString findFile(const char *fileName);
static void writeTagFile(MemberDef *mdef,FTextStream &tagFile);
};
// start prefix for each comment
//% a one line comment
//% a
//% multi line
//% comment
static const char* vlogComment="//%";
#endif
This source diff could not be displayed because it is too large. You can view the blob instead.
/* A Bison parser, made by GNU Bison 2.4.1. */
/* Skeleton interface for Bison GLR parsers in C
Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* As a special exception, you may create a larger work that contains
part or all of the Bison parser skeleton and distribute that work
under terms of your choice, so long as that work isn't itself a
parser generator using the skeleton or a modified version thereof
as a parser skeleton. Alternatively, if you modify or redistribute
the parser skeleton itself, you may (at your option) remove this
special exception, which will cause the skeleton and the resulting
Bison output files to be licensed under the GNU General Public
License without this special exception.
This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */
/* Tokens. */
#ifndef YYTOKENTYPE
# define YYTOKENTYPE
/* Put the tokens into the symbol table, so that GDB and other debuggers
know about them. */
enum yytokentype {
NET_TOK = 258,
STR0_TOK = 259,
STR1_TOK = 260,
GATE_TOK = 261,
STRING_TOK = 262,
DIGIT_TOK = 263,
UNDERSCORE_TOK = 264,
SEM_TOK = 265,
DOT_TOK = 266,
LETTER_TOK = 267,
PLUS_TOK = 268,
MINUS_TOK = 269,
COLON_TOK = 270,
LBRACE_TOK = 271,
RBRACE_TOK = 272,
LBRACKET_TOK = 273,
RBRACKET_TOK = 274,
AND_TOK = 275,
OR_TOK = 276,
EQU_TOK = 277,
GT_TOK = 278,
LT_TOK = 279,
NOT_TOK = 280,
MULT_TOK = 281,
PERCENTAL_TOK = 282,
ENV_TOK = 283,
PARA_TOK = 284,
CHAR_TOK = 285,
AT_TOK = 286,
DOLLAR_TOK = 287,
BASE_TOK = 288,
SN_TOK = 289,
EXCLAMATION_TOK = 290,
RRAM_TOK = 291,
LRAM_TOK = 292,
PARAMETER_TOK = 293,
OUTPUT_TOK = 294,
INOUT_TOK = 295,
SMALL_TOK = 296,
MEDIUM_TOK = 297,
LARGE_TOK = 298,
VEC_TOK = 299,
SCALAR_TOK = 300,
REG_TOK = 301,
TIME_TOK = 302,
REAL_TOK = 303,
EVENT_TOK = 304,
ASSIGN_TOK = 305,
DEFPARAM_TOK = 306,
MODUL_TOK = 307,
ENDMODUL_TOK = 308,
MACRO_MODUL_TOK = 309,
ENDPRIMITIVE_TOK = 310,
PRIMITIVE_TOK = 311,
INITIAL_TOK = 312,
TABLE_TOK = 313,
ENDTABLE_TOK = 314,
ALWAYS_TOK = 315,
TASK_TOK = 316,
ENDTASK_TOK = 317,
FUNC_TOK = 318,
ENDFUNC_TOK = 319,
IF_TOK = 320,
CASE_TOK = 321,
CASEX_TOK = 322,
CASEZ_TOK = 323,
FOREVER_TOK = 324,
REPEAT_TOK = 325,
FOR_TOK = 326,
JOIN_TOK = 327,
WAIT_TOK = 328,
FORCE_TOK = 329,
RELEASE_TOK = 330,
DEASSIGN_TOK = 331,
DISABLE_TOK = 332,
WHILE_TOK = 333,
ELSE_TOK = 334,
ENDCASE_TOK = 335,
BEGIN_TOK = 336,
DEFAULT_TOK = 337,
FORK_TOK = 338,
END_TOK = 339,
SPECIFY_TOK = 340,
ENDSPECIFY_TOK = 341,
SPECPARAM_TOK = 342,
DSETUP_TOK = 343,
DHOLD_TOK = 344,
DWIDTH_TOK = 345,
DPERIOD_TOK = 346,
DSKEW_TOK = 347,
DRECOVERY_TOK = 348,
DSETUPHOLD_TOK = 349,
POSEDGE_TOK = 350,
NEGEDGE_TOK = 351,
EDGE_TOK = 352,
COMMA_TOK = 353,
QUESTION_TOK = 354,
AUTO_TOK = 355,
INPUT_TOK = 356,
SIGNED_TOK = 357,
LOCALPARAM_TOK = 358,
INTEGER_TOK = 359,
NOCHANGE_TOK = 360,
GENERATE_TOK = 361,
ENDGENERATE_TOK = 362,
GENVAR_TOK = 363,
LIBRARY_TOK = 364,
CONFIG_TOK = 365,
ENDCONFIG_TOK = 366,
INCLUDE_TOK = 367,
PULSEON_DETECT_TOK = 368,
PULSEONE_EVENT_TOK = 369,
USE_TOK = 370,
LIBLIST_TOK = 371,
INSTANCE_TOK = 372,
CELL_TOK = 373,
SHOWCANCEL_TOK = 374,
NOSHOWCANCEL_TOK = 375,
REMOVAL_TOK = 376,
FULLSKEW_TOK = 377,
TIMESKEW_TOK = 378,
RECREM_TOK = 379,
IFNONE_TOK = 380,
REALTIME_TOK = 381,
DESIGN_TOK = 382,
ATL_TOK = 383,
ATR_TOK = 384,
OOR_TOK = 385,
AAND_TOK = 386,
SNNOT_TOK = 387,
NOTSN_TOK = 388,
AAAND_TOK = 389,
DEFINE_TOK = 390
};
#endif
#ifndef YYSTYPE
typedef union YYSTYPE
{
/* Line 2638 of glr.c */
#line 99 "c:\\Boot\\doxygen\\src\\\\..\\src\\verilogparser.y"
int itype; /* for count */
char ctype; /* for char */
char cstr[VBUF_SIZE];
/* Line 2638 of glr.c */
#line 193 "c:\\Boot\\doxygen\\src\\\\..\\src\\verilogparser.hpp"
} YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
#endif
#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
typedef struct YYLTYPE
{
int first_line;
int first_column;
int last_line;
int last_column;
} YYLTYPE;
# define YYLTYPE_IS_DECLARED 1
# define YYLTYPE_IS_TRIVIAL 1
#endif
extern YYSTYPE c_lval;
extern YYLTYPE c_lloc;
This source diff could not be displayed because it is too large. You can view the blob instead.
/******************************************************************************
* Copyright (c) M.Kreis,2009
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*
* You may use and distribute this software under the terms of the
* GNU General Public License, version 2 or later
*****************************************************************************/
#ifndef verilogscanner_h
#define verilogscanner_h
#include "parserintf.h"
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <ctype.h>
#include <qarray.h>
#include <qstack.h>
//#include <unistd.h>
#include <qfile.h>
#include <qdict.h>
#include "entry.h"
#include "qcstring.h"
#include "qlist.h"
#include "qstringlist.h"
#include "filedef.h"
#include "classlist.h"
#include "classdef.h"
#include "translator.h"
#include "qregexp.h"
#include "outputlist.h"
#include "membername.h"
#include "memberdef.h"
#include "memberlist.h"
#include "verilogdocgen.h"
//#include "verilogparser.hpp"
#define VBUF_SIZE 1024
class VerilogScanner : public ParserInterface
{
public:
virtual ~VerilogScanner() {}
VerilogScanner(const char *n)
{
name+=n;
}
void finishTranslationUnit() {}
void startTranslationUnit(const char *) {}
void parseInput(const char * fileName,
const char *fileBuf,
Entry *root,
bool sameTranslationUnit,
QStrList &filesInSameTranslationUnit);
bool needsPreprocessing(const QCString &extension);
void parseCode(CodeOutputInterface &codeOutIntf,
const char *scopeName,
const QCString &input,
SrcLangExt lang,
bool isExampleBlock,
const char *exampleName=0,
FileDef *fileDef=0,
int startLine=-1,
int endLine=-1,
bool inlineFragment=FALSE,
MemberDef *memberDef=0,
bool showLineNumbers=TRUE,
Definition *searchCtx=0,
bool collectXRefs=TRUE
);
void resetCodeParserState();
void parsePrototype(const char *text);
};
//------ wrapper functions for parsing code ---------------------------------
void codifyVerilogString(char* c,char* color=NULL);
bool generateVerilogMemLink(QCString &clName,QCString& memberName,int type);
bool generateVerilogClassOrGlobalLink(char *clName);
void writeVerilogFont(const char *s,const char* text);
//void generateVerilogMemLink(QCString &clName,QCString& memberName);
bool generateVerilogCompMemLink(QCString &cl,QCString& inst,QCString & key, bool b);
bool writeVerilogColoredWord(const QCString& word );
void printVerilogBuffer(bool b=false);
void printVerilogStringList();
void writePrevVerilogWords(const QCString& qcs);
void deleteVerilogChars(QCString &s,const char* c);
bool checkString(QCString &name);
//------ functions for getting the parser states and parsed lines ---------------------------------
// clears the string buffer
void vbufreset();
// returns a pointer to the buffer in which the parsed strings are stored
const char* getVerilogString();
int getVerilogLine();
int getVerilogPrevLine();
// returns the line in which the ENDMODULE_TOKEN/ENDPRIMITIVE_TOKEN is found
int getVerilogEndLine();
// returns the last parsed token
int getVerilogToken();
// returns the current parsing file
const char* getVerilogParsingFile();
// returns the last parsed letter
QCString getLastLetter();
// return the current Entry = (current module/primitive)
Entry* getCurrVerilogEntry();
// returns the current Entry
Entry* getCurrVerilog();
void initVerilogParser(Entry* ee,bool pc);
// function for parsing and assigning comments
bool handleVerilogCommentBlock(const QCString &doc,bool brief,int iDocLine);
// returns the current module name when code parsing
QCString getCurrVerilogParsingClass();
// finds global `define/`includes
MemberDef* findGlobalMember(const QCString& file, const QCString& memName);
// finds global `define/`includes
MemberDef* findGlobalMember(const QCString& memName);
void addGlobalVerilogMember(const Entry *e);
void resetVerilogBrief();
int getVerilogEndModuleLine();
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment