From 8d66d3956abd64c4ebc89f14debc46ebc16f85da Mon Sep 17 00:00:00 2001 From: Adrian Thurston Date: Sun, 7 Nov 2021 21:25:13 -0800 Subject: remaining parts of common.cc moved over to ragel This includes output filter, file name functions, and line directive generation --- src/libfsm/Makefile.am | 2 +- src/libfsm/common.cc | 240 ------------------------------------------------- src/libfsm/common.h | 94 +------------------ src/libfsm/gendata.cc | 18 +++- 4 files changed, 16 insertions(+), 338 deletions(-) delete mode 100644 src/libfsm/common.cc (limited to 'src') 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 - * - * 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 -#include -#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(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. */ -- cgit v1.2.1