Track the entire include history of a parser state to prevent duplicates.
authorthurston <thurston@052ea7fc-9027-0410-9066-f65837a77df0>
Fri, 18 Jul 2008 22:42:08 +0000 (22:42 +0000)
committerthurston <thurston@052ea7fc-9027-0410-9066-f65837a77df0>
Fri, 18 Jul 2008 22:42:08 +0000 (22:42 +0000)
git-svn-id: http://svn.complang.org/ragel/trunk@458 052ea7fc-9027-0410-9066-f65837a77df0

ragel/rlparse.kh
ragel/rlscan.h
ragel/rlscan.rl

index 6535cb6..a829d78 100644 (file)
 #define IMP_UInt 130
 #define IMP_Define 131
 
+/* This is used for tracking the include files/machine pairs. */
+struct IncludeHistoryItem
+{
+       IncludeHistoryItem( char *fileName, char *sectionName )
+               : fileName(fileName), sectionName(sectionName) {}
+
+       char *fileName;
+       char *sectionName;
+};
+
+typedef Vector<IncludeHistoryItem> IncludeHistory;
 
 struct Parser
 {
@@ -118,6 +129,7 @@ struct Parser
        NameRefList nameRefList;
 
        Vector<bool> exportContext;
+       IncludeHistory includeHistory;
 };
 
 %% write token_defs;
index acbc40b..756312d 100644 (file)
@@ -35,19 +35,6 @@ using std::ostream;
 
 extern char *Parser_lelNames[];
 
-/* This is used for tracking the current stack of include file/machine pairs. It is
- * is used to detect and recursive include structure. */
-struct IncludeStackItem
-{
-       IncludeStackItem( char *fileName, char *sectionName )
-               : fileName(fileName), sectionName(sectionName) {}
-
-       char *fileName;
-       char *sectionName;
-};
-
-typedef Vector<IncludeStackItem> IncludeStack;
-
 struct Scanner
 {
        Scanner( char *fileName, istream &input, ostream &output,
@@ -67,7 +54,7 @@ struct Scanner
                lastToken(0)
                {}
 
-       bool recursiveInclude( char *inclFileName, char *inclSectionName );
+       bool duplicateInclude( char *inclFileName, char *inclSectionName );
 
        /* Make a list of places to look for an included file. */
        char **makeIncludePathChecks( char *curFileName, char *fileName, int len );
@@ -128,7 +115,6 @@ struct Scanner
         * allowing for unnamed sections. */
        Parser *parser;
        bool ignoreSection;
-       IncludeStack includeStack;
 
        /* This is set if ragel has already emitted an error stating that
         * no section name has been seen and thus no parser exists. */
index bf4cd92..d2d93a4 100644 (file)
@@ -246,11 +246,11 @@ ostream &Scanner::scan_error()
        return cerr;
 }
 
-bool Scanner::recursiveInclude( char *inclFileName, char *inclSectionName )
+bool Scanner::duplicateInclude( char *inclFileName, char *inclSectionName )
 {
-       for ( IncludeStack::Iter si = includeStack; si.lte(); si++ ) {
-               if ( strcmp( si->fileName, inclFileName ) == 0 &&
-                               strcmp( si->sectionName, inclSectionName ) == 0 )
+       for ( IncludeHistory::Iter hi = parser->includeHistory; hi.lte(); hi++ ) {
+               if ( strcmp( hi->fileName, inclFileName ) == 0 &&
+                               strcmp( hi->sectionName, inclSectionName ) == 0 )
                {
                        return true;
                }
@@ -329,21 +329,16 @@ void Scanner::handleInclude()
                                scan_error() << "include: attempted: \"" << *tried++ << '\"' << endl;
                }
                else {
-                       /* Check for a recursive include structure. Add the current file/section
-                        * name then check if what we are including is already in the stack. */
-                       includeStack.append( IncludeStackItem( fileName, parser->sectionName ) );
+                       /* Don't include anything that's already been included. */
+                       if ( !duplicateInclude( includeChecks[found], inclSectionName ) ) {
+                               parser->includeHistory.append( IncludeHistoryItem( 
+                                               includeChecks[found], inclSectionName ) );
 
-                       if ( recursiveInclude( includeChecks[found], inclSectionName ) )
-                               scan_error() << "include: this is a recursive include operation" << endl;
-                       else {
                                Scanner scanner( includeChecks[found], *inFile, output, parser,
                                                inclSectionName, includeDepth+1, false );
                                scanner.do_scan( );
                                delete inFile;
                        }
-
-                       /* Remove the last element (len-1) */
-                       includeStack.remove( -1 );
                }
        }
 }