summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdrian Thurston <thurston@colm.net>2021-11-07 21:25:13 -0800
committerAdrian Thurston <thurston@colm.net>2021-11-07 21:25:13 -0800
commit8d66d3956abd64c4ebc89f14debc46ebc16f85da (patch)
tree20474e2a9276d5284f2bc24cc3bb5eafa6322e41
parentc7c7742f7038694cb20ce5bee33679d42f065d94 (diff)
downloadcolm-8d66d3956abd64c4ebc89f14debc46ebc16f85da.tar.gz
remaining parts of common.cc moved over to ragel
This includes output filter, file name functions, and line directive generation
-rw-r--r--src/libfsm/Makefile.am2
-rw-r--r--src/libfsm/common.cc240
-rw-r--r--src/libfsm/common.h94
-rw-r--r--src/libfsm/gendata.cc18
4 files changed, 16 insertions, 338 deletions
diff --git a/src/libfsm/Makefile.am b/src/libfsm/Makefile.am
index 42d009ee..3fc5cbcc 100644
--- a/src/libfsm/Makefile.am
+++ b/src/libfsm/Makefile.am
@@ -25,7 +25,7 @@ libfsm_la_CPPFLAGS = -I$(top_srcdir)/src/aapl
dist_libfsm_la_SOURCES = \
idbase.cc fsmstate.cc fsmbase.cc fsmattach.cc fsmmin.cc fsmgraph.cc \
- fsmap.cc fsmcond.cc fsmnfa.cc common.cc redfsm.cc gendata.cc \
+ fsmap.cc fsmcond.cc fsmnfa.cc redfsm.cc gendata.cc \
allocgen.cc codegen.cc \
actexp.cc binvar.cc \
tables.cc tabgoto.cc tabbreak.cc tabvar.cc \
diff --git a/src/libfsm/common.cc b/src/libfsm/common.cc
deleted file mode 100644
index 7a4df841..00000000
--- a/src/libfsm/common.cc
+++ /dev/null
@@ -1,240 +0,0 @@
-/*
- * Copyright 2006-2018 Adrian Thurston <thurston@colm.net>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include "common.h"
-#include "stdlib.h"
-#include <string.h>
-#include <assert.h>
-#include "ragel.h"
-
-std::streamsize output_filter::countAndWrite( const char *s, std::streamsize n )
-{
- for ( int i = 0; i < n; i++ ) {
- switch ( s[i] ) {
- case '\n':
- line += 1;
- break;
- case '{':
- /* If we detec an open block then eliminate the single-indent
- * addition, which is to account for single statements. */
- singleIndent = false;
- level += 1;
- break;
- case '}':
- level -= 1;
- break;
- }
- }
-
- return std::filebuf::xsputn( s, n );
-}
-
-bool openSingleIndent( const char *s, int n )
-{
- if ( n >= 3 && memcmp( s, "if ", 3 ) == 0 )
- return true;
-
- if ( n >= 8 && memcmp( s, "else if ", 8 ) == 0 )
- return true;
-
- if ( n >= 5 && memcmp( s, "else\n", 4 ) == 0 )
- return true;
-
- return false;
-}
-
-/* Counts newlines before sending sync. */
-int output_filter::sync( )
-{
- line += 1;
- return std::filebuf::sync();
-}
-
-/* Counts newlines before sending data out to file. */
-std::streamsize output_filter::xsputn( const char *s, std::streamsize n )
-{
- std::streamsize ret = n;
- int l;
-
-restart:
- if ( indent ) {
- /* Consume mode Looking for the first non-whitespace. */
- while ( n > 0 && ( *s == ' ' || *s == '\t' ) ) {
- s += 1;
- n -= 1;
- }
-
- if ( n > 0 ) {
- int tabs = level + ( singleIndent ? 1 : 0 );
-
- if ( *s == '}' ) {
- /* If the next char is de-dent, then reduce the tabs. This is
- * not a stream state change. The level reduction will be
- * computed in write. */
- tabs -= 1;
- }
-
- /* Note that the count and write will eliminate this if it detects
- * an open block. */
- if ( openSingleIndent( s, n ) )
- singleIndent = true;
- else
- singleIndent = false;
-
- if ( *s != '#' ) {
- /* Found some data, print the indentation and turn off indentation
- * mode. */
- for ( l = 0; l < tabs; l++ )
- countAndWrite( "\t", 1 );
- }
-
-
- indent = 0;
-
- goto restart;
- }
- }
- else {
- char *nl;
- if ( (nl = (char*)memchr( s, '\n', n )) ) {
- /* Print up to and including the newline. */
- int wl = nl - s + 1;
- countAndWrite( s, wl );
-
- /* Go into consume state. If we see more non-indentation chars we
- * will generate the appropriate indentation level. */
- s += wl;
- n -= wl;
- indent = true;
- goto restart;
- }
- else {
- /* Indentation off, or no indent trigger (newline). */
- countAndWrite( s, n );
- }
- }
-
- // What to do here?
- return ret;
-}
-
-/* Scans a string looking for the file extension. If there is a file
- * extension then pointer returned points to inside the string
- * passed in. Otherwise returns null. */
-const char *findFileExtension( const char *stemFile )
-{
- const char *ppos = stemFile + strlen(stemFile) - 1;
-
- /* Scan backwards from the end looking for the first dot.
- * If we encounter a '/' before the first dot, then stop the scan. */
- while ( 1 ) {
- /* If we found a dot or got to the beginning of the string then
- * we are done. */
- if ( ppos == stemFile || *ppos == '.' )
- break;
-
- /* If we hit a / then there is no extension. Done. */
- if ( *ppos == '/' ) {
- ppos = stemFile;
- break;
- }
- ppos--;
- }
-
- /* If we got to the front of the string then bail we
- * did not find an extension */
- if ( ppos == stemFile )
- ppos = 0;
-
- return ppos;
-}
-
-/* Make a file name from a stem. Removes the old filename suffix and
- * replaces it with a new one. Returns a newed up string. */
-const char *fileNameFromStem( const char *stemFile, const char *suffix )
-{
- long len = strlen( stemFile );
- assert( len > 0 );
-
- /* Get the extension. */
- const char *ppos = findFileExtension( stemFile );
-
- /* If an extension was found, then shorten what we think the len is. */
- if ( ppos != 0 )
- len = ppos - stemFile;
-
- /* Make the return string from the stem and the suffix. */
- char *retVal = new char[ len + strlen( suffix ) + 1 ];
- strncpy( retVal, stemFile, len );
- strcpy( retVal + len, suffix );
-
- return retVal;
-}
-
-exit_object endp;
-
-void operator<<( std::ostream &out, exit_object & )
-{
- out << std::endl;
- throw AbortCompile( 1 );
-}
-
-void genLineDirectiveC( std::ostream &out, bool lineDirectives, int line, const char *fileName )
-{
- if ( !lineDirectives )
- out << "/* ";
-
- out << "#line " << line << " \"";
- for ( const char *pc = fileName; *pc != 0; pc++ ) {
- if ( *pc == '\\' )
- out << "\\\\";
- else if ( *pc == '"' )
- out << "\\\"";
- else
- out << *pc;
- }
- out << '"';
-
- if ( !lineDirectives )
- out << " */";
-
- out << '\n';
-}
-
-void genLineDirectiveAsm( std::ostream &out, bool lineDirectives, int line, const char *fileName )
-{
- out << "/* #line " << line << " \"";
- for ( const char *pc = fileName; *pc != 0; pc++ ) {
- if ( *pc == '\\' )
- out << "\\\\";
- else if ( *pc == '"' )
- out << "\\\"";
- else
- out << *pc;
- }
- out << '"';
- out << " */\n";
-}
-
-void genLineDirectiveTrans( std::ostream &out, bool lineDirectives, int line, const char *fileName )
-{
-}
diff --git a/src/libfsm/common.h b/src/libfsm/common.h
index 964a3908..3739db3c 100644
--- a/src/libfsm/common.h
+++ b/src/libfsm/common.h
@@ -217,12 +217,7 @@ struct HostType
unsigned int size;
};
-typedef void (*GenLineDirectiveT)( std::ostream &out, bool nld, int line, const char *file );
-typedef const char *(*DefaultOutFnT)( const char *inputFileName );
-
-void genLineDirectiveC( std::ostream &out, bool nld, int line, const char *file );
-void genLineDirectiveAsm( std::ostream &out, bool nld, int line, const char *file );
-void genLineDirectiveTrans( std::ostream &out, bool nld, int line, const char *file );
+typedef void (*GenLineDirectiveT)( std::ostream &out, bool nld, int line, const char *fileName );
/* An abstraction of the key operators that manages key operations such as
* comparison and increment according the signedness of the key. */
@@ -360,93 +355,6 @@ inline void CondKey::increment()
key = key + 1;
}
-
-/* Filter on the output stream that keeps track of the number of lines
- * output. */
-class output_filter
-:
- public std::filebuf
-{
-public:
- output_filter( const char *fileName )
- :
- fileName(fileName),
- line(1),
- level(0),
- indent(false),
- singleIndent(false)
- {}
-
- virtual int sync();
- virtual std::streamsize xsputn( const char* s, std::streamsize n );
-
- std::streamsize countAndWrite( const char* s, std::streamsize n );
-
- const char *fileName;
- int line;
- int level;
- bool indent;
- bool singleIndent;
-};
-
-class nullbuf
-:
- public std::streambuf
-{
-public:
- virtual std::streamsize xsputn( const char * s, std::streamsize n )
- { return n; }
-
- virtual int overflow( int c )
- { return 1; }
-};
-
-class cfilebuf : public std::streambuf
-{
-public:
- cfilebuf( char *fileName, FILE* file ) : fileName(fileName), file(file) { }
- char *fileName;
- FILE *file;
-
- int sync()
- {
- fflush( file );
- return 0;
- }
-
- int overflow( int c )
- {
- if ( c != EOF )
- fputc( c, file );
- return 0;
- }
-
- std::streamsize xsputn( const char* s, std::streamsize n )
- {
- std::streamsize written = fwrite( s, 1, n, file );
- return written;
- }
-};
-
-class costream : public std::ostream
-{
-public:
- costream( cfilebuf *b ) :
- std::ostream(b), b(b) {}
-
- ~costream()
- { delete b; }
-
- void fclose()
- { ::fclose( b->file ); }
-
- cfilebuf *b;
-};
-
-
-const char *findFileExtension( const char *stemFile );
-const char *fileNameFromStem( const char *stemFile, const char *suffix );
-
struct Export
{
Export( std::string name, Key key )
diff --git a/src/libfsm/gendata.cc b/src/libfsm/gendata.cc
index 8226ae60..6242159c 100644
--- a/src/libfsm/gendata.cc
+++ b/src/libfsm/gendata.cc
@@ -1591,10 +1591,7 @@ void Reducer::analyzeMachine()
void CodeGenData::genOutputLineDirective( std::ostream &out ) const
{
- std::streambuf *sbuf = out.rdbuf();
- output_filter *filter = dynamic_cast<output_filter*>(sbuf);
- if ( filter != 0 )
- (*genLineDirective)( out, lineDirectives, filter->line + 1, filter->fileName );
+ (*genLineDirective)( out, lineDirectives, -1, 0 );
}
void CodeGenData::write_option_error( InputLoc &loc, std::string arg )
@@ -1618,6 +1615,19 @@ void CodeGenData::writeClear()
cleared = true;
}
+class nullbuf
+:
+ public std::streambuf
+{
+public:
+ virtual std::streamsize xsputn( const char * s, std::streamsize n )
+ { return n; }
+
+ virtual int overflow( int c )
+ { return 1; }
+};
+
+
void CodeGenData::collectReferences()
{
/* Do this once only. */