2013-04-11 11:04:16 +00:00
using System.IO ;
2012-07-10 10:20:45 +00:00
using System.Collections.Generic ;
using System.Globalization ;
using CodeImp.DoomBuilder.ZDoom ;
using CodeImp.DoomBuilder.GZBuilder.Data ;
2012-07-12 22:34:12 +00:00
//mxd. ACS parser used to create ScriptItems for use in script editor's navigator
namespace CodeImp.DoomBuilder.GZBuilder.GZDoom
2012-07-10 10:20:45 +00:00
{
2012-07-12 22:34:12 +00:00
internal sealed class AcsParserSE : ZDTextParser
2012-07-10 10:20:45 +00:00
{
2012-07-23 21:28:23 +00:00
internal delegate void IncludeDelegate ( AcsParserSE parser , string includefile ) ;
internal IncludeDelegate OnInclude ;
private List < string > parsedLumps ;
2013-03-29 11:24:30 +00:00
private List < string > includes ;
2012-07-23 21:28:23 +00:00
2012-07-10 10:20:45 +00:00
private List < ScriptItem > namedScripts ;
private List < ScriptItem > numberedScripts ;
2012-07-12 22:34:12 +00:00
internal List < ScriptItem > NamedScripts { get { return namedScripts ; } }
internal List < ScriptItem > NumberedScripts { get { return numberedScripts ; } }
2012-07-10 10:20:45 +00:00
2012-07-12 22:34:12 +00:00
internal AcsParserSE ( ) {
2012-07-10 10:20:45 +00:00
namedScripts = new List < ScriptItem > ( ) ;
numberedScripts = new List < ScriptItem > ( ) ;
2012-07-23 21:28:23 +00:00
parsedLumps = new List < string > ( ) ;
2013-03-29 11:24:30 +00:00
includes = new List < string > ( ) ;
}
internal List < string > Includes {
get { return includes ; }
2012-07-10 10:20:45 +00:00
}
public override bool Parse ( Stream stream , string sourcefilename ) {
2013-03-29 11:24:30 +00:00
return Parse ( stream , sourcefilename , false , false ) ;
2012-07-23 21:28:23 +00:00
}
public bool Parse ( Stream stream , string sourcefilename , bool processIncludes ) {
2013-03-29 11:24:30 +00:00
return Parse ( stream , sourcefilename , processIncludes , false ) ;
}
public bool Parse ( Stream stream , string sourcefilename , bool processIncludes , bool isinclude ) {
2012-07-10 10:20:45 +00:00
base . Parse ( stream , sourcefilename ) ;
2012-07-23 21:28:23 +00:00
//already parsed this?
2013-08-05 13:03:08 +00:00
if ( parsedLumps . Contains ( sourcefilename ) ) return false ;
2012-07-23 21:28:23 +00:00
parsedLumps . Add ( sourcefilename ) ;
2013-08-05 13:03:08 +00:00
if ( isinclude ) includes . Add ( sourcefilename ) ;
2012-07-23 21:28:23 +00:00
// Keep local data
Stream localstream = datastream ;
string localsourcename = sourcename ;
BinaryReader localreader = datareader ;
2012-07-10 10:20:45 +00:00
// Continue until at the end of the stream
while ( SkipWhitespace ( true ) ) {
string token = ReadToken ( ) ;
if ( ! string . IsNullOrEmpty ( token ) ) {
token = token . ToLowerInvariant ( ) ;
if ( token = = "script" ) {
int startPos = ( int ) stream . Position - 7 ;
SkipWhitespace ( true ) ;
token = ReadToken ( ) ;
//is it named script?
if ( token . IndexOf ( '"' ) ! = - 1 ) {
token = StripTokenQuotes ( token ) ;
ScriptItem i = new ScriptItem ( 0 , token , startPos , ( int ) stream . Position - 1 ) ;
namedScripts . Add ( i ) ;
} else { //should be numbered script
int n = 0 ;
if ( int . TryParse ( token , NumberStyles . Integer , CultureInfo . InvariantCulture , out n ) ) {
int endPos = ( int ) stream . Position - 1 ;
//now find opening brace
do {
SkipWhitespace ( true ) ;
token = ReadToken ( ) ;
} while ( token ! = "{" ) ;
token = ReadLine ( ) ;
string name = "" ;
if ( token . Length > 0 ) {
int commentStart = token . IndexOf ( "//" ) ;
if ( commentStart ! = - 1 ) { //found comment
commentStart + = 2 ;
name = token . Substring ( commentStart , token . Length - commentStart ) ;
}
}
2013-03-18 13:52:27 +00:00
name = ( name . Length > 0 ? name + " [" + n + "]" : "Script " + n ) ;
2012-07-10 10:20:45 +00:00
ScriptItem i = new ScriptItem ( n , name , startPos , endPos ) ;
numberedScripts . Add ( i ) ;
}
}
2012-07-23 21:28:23 +00:00
} else if ( ( token = = "#include" | | token = = "#import" ) & & processIncludes ) {
SkipWhitespace ( true ) ;
string includeLump = StripTokenQuotes ( ReadToken ( ) ) . ToLowerInvariant ( ) ;
if ( ! string . IsNullOrEmpty ( includeLump ) ) {
2013-08-05 13:03:08 +00:00
string includeName = Path . GetFileName ( includeLump ) ;
if ( includeName = = "zcommon.acs" | | includeName = = "common.acs" | | includes . Contains ( includeName ) )
2012-07-23 21:28:23 +00:00
continue ;
// Callback to parse this file
if ( OnInclude ! = null ) OnInclude ( this , includeLump . Replace ( Path . AltDirectorySeparatorChar , Path . DirectorySeparatorChar ) ) ;
// Set our buffers back to continue parsing
datastream = localstream ;
datareader = localreader ;
sourcename = localsourcename ;
} else {
2013-03-18 13:52:27 +00:00
General . ErrorLogger . Add ( ErrorType . Error , "Error in '" + sourcefilename + "' at line " + GetCurrentLineNumber ( ) + ": got #include directive without include path!" ) ;
2012-07-23 21:28:23 +00:00
}
2012-07-10 10:20:45 +00:00
}
}
}
return true ;
}
}
2012-07-10 14:14:53 +00:00
}