Fixed, ACS script names parser: we should skip inner scopes of scripts and functions.

Updated ZDoom_DECORATE.cfg.
This commit is contained in:
MaxED 2015-04-28 08:31:06 +00:00
parent 806a71fec2
commit c2b3e92673
2 changed files with 69 additions and 61 deletions

View file

@ -65,7 +65,7 @@ keywords
//Generic monster attacks //Generic monster attacks
A_CustomMissile = "A_CustomMissile(str missiletype[, float spawnheight = 0.0[, int spawnofs_horiz = 0[, int angle = 0[, int aimflags = 0[, int pitch = 0[, int target = AAPTR_TARGET]]]]]])"; A_CustomMissile = "A_CustomMissile(str missiletype[, float spawnheight = 0.0[, int spawnofs_horiz = 0[, int angle = 0[, int aimflags = 0[, int pitch = 0[, int target = AAPTR_TARGET]]]]]])";
A_CustomBulletAttack = "A_CustomBulletAttack(float horz_spread, float vert_spread, int numbullets, int damageperbullet[, str pufftype = \"BulletPuff\"[, float range = 0.0[, int flags = 0[, int target = AAPTR_TARGET]]]])"; A_CustomBulletAttack = "A_CustomBulletAttack(float horz_spread, float vert_spread, int numbullets, int damageperbullet[, str pufftype = \"BulletPuff\"[, float range = 0.0[, int flags = 0[, int target = AAPTR_TARGET]]]])";
A_CustomRailgun = "A_CustomRailgun(int damage[, int offset[, color ringcolor[, color corecolor[, int flags[, bool aim[, float maxdiff[, str pufftype[, float spread_xy[, float spread_z[, fixed range[, int duration[, float sparsity[, float driftspeed[, str spawnclass[, float spawnofs_z]]]]]]]]]]]]]]])"; A_CustomRailgun = "A_CustomRailgun(int damage[, int offset[, color ringcolor[, color corecolor[, int flags = 0[, bool aim = false[, float maxdiff = 0.0[, str pufftype = \"\"[, float spread_xy = 0.0[, float spread_z = 0.0[, fixed range = 8192[, int duration = 35[, float sparsity = 1.0[, float driftspeed = 1.0[, str spawnclass = \"\"[, float spawnofs_z = 0[, int spiraloffset = 270]]]]]]]]]]]]]]]])";
A_CustomMeleeAttack = "A_CustomMeleeAttack(int damage[, str meleesound[, str misssound[, str damagetype[, bool bleed]]]])"; A_CustomMeleeAttack = "A_CustomMeleeAttack(int damage[, str meleesound[, str misssound[, str damagetype[, bool bleed]]]])";
A_CustomComboAttack = "A_CustomComboAttack(str missiletype, float spawnheight, int damage, str meleesound[, str damagetype = \"Melee\"[, bool bleed = true]])"; A_CustomComboAttack = "A_CustomComboAttack(str missiletype, float spawnheight, int damage, str meleesound[, str damagetype = \"Melee\"[, bool bleed = true]])";
A_MonsterRefire = "A_MonsterRefire(int chancecontinue, str abortstate) "; A_MonsterRefire = "A_MonsterRefire(int chancecontinue, str abortstate) ";
@ -244,7 +244,7 @@ keywords
A_CustomPunch = "A_CustomPunch(int damage[, bool norandom = false[, int flags = 0[, str pufftype = \"BulletPuff\"[, float range = 64.0[, float lifesteal = 0.0[, int lifestealmax = 0[, str armorbonustype = \"ArmorBonus\"]]]]]]])"; A_CustomPunch = "A_CustomPunch(int damage[, bool norandom = false[, int flags = 0[, str pufftype = \"BulletPuff\"[, float range = 64.0[, float lifesteal = 0.0[, int lifestealmax = 0[, str armorbonustype = \"ArmorBonus\"]]]]]]])";
A_FireBullets = "A_FireBullets(int spread_horz, int spread_vert, int numbullets, int damage[, str pufftype = \"\"[, int flags = FBF_USEAMMO[, float range = 0.0]]])"; A_FireBullets = "A_FireBullets(int spread_horz, int spread_vert, int numbullets, int damage[, str pufftype = \"\"[, int flags = FBF_USEAMMO[, float range = 0.0]]])";
A_FireCustomMissile = "A_FireCustomMissile(str missiletype[, int angle = 0[, bool useammo = false[, int spawnofs_horz = 0[, int spawnheight = 0[, bool aim = false OR int flags = 0[, angle pitch = 0]]]]]])"; A_FireCustomMissile = "A_FireCustomMissile(str missiletype[, int angle = 0[, bool useammo = false[, int spawnofs_horz = 0[, int spawnheight = 0[, bool aim = false OR int flags = 0[, angle pitch = 0]]]]]])";
A_RailAttack = "A_RailAttack(int damage[, int spawnofs_horz[, bool useammo[, color ringcolor[, color corecolor[, int flags[, int maxdiff[, str pufftype[, float spread_xy = 0[, float spread_z = 0.0[, fixed range = 8192[, int duration = 35[, float sparsity = 1.0[, float driftspeed = 1.0[, str spawnclass[, float spawnofs_z = 0.0]]]]]]]]]]]]]]])"; A_RailAttack = "A_RailAttack(int damage[, int spawnofs_horz[, bool useammo[, color ringcolor[, color corecolor[, int flags[, int maxdiff[, str pufftype[, float spread_xy = 0[, float spread_z = 0.0[, fixed range = 8192[, int duration = 35[, float sparsity = 1.0[, float driftspeed = 1.0[, str spawnclass[, float spawnofs_z = 0.0[, int spiraloffset = 270]]]]]]]]]]]]]]]])";
A_FireAssaultGun = "A_FireAssaultGun"; A_FireAssaultGun = "A_FireAssaultGun";
A_FireBFG = "A_FireBFG"; A_FireBFG = "A_FireBFG";
A_FireOldBFG = "A_FireOldBFG"; A_FireOldBFG = "A_FireOldBFG";

View file

@ -12,44 +12,41 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom
internal delegate void IncludeDelegate(AcsParserSE parser, string includefile); internal delegate void IncludeDelegate(AcsParserSE parser, string includefile);
internal IncludeDelegate OnInclude; internal IncludeDelegate OnInclude;
private readonly List<string> parsedLumps; private readonly List<string> parsedlumps;
private readonly List<string> includes; private readonly List<string> includes;
private readonly List<ScriptItem> namedScripts; private readonly List<ScriptItem> namedscripts;
private readonly List<ScriptItem> numberedScripts; private readonly List<ScriptItem> numberedscripts;
private readonly List<ScriptItem> functions; private readonly List<ScriptItem> functions;
internal List<ScriptItem> NamedScripts { get { return namedScripts; } } internal List<ScriptItem> NamedScripts { get { return namedscripts; } }
internal List<ScriptItem> NumberedScripts { get { return numberedScripts; } } internal List<ScriptItem> NumberedScripts { get { return numberedscripts; } }
internal List<ScriptItem> Functions { get { return functions; } } internal List<ScriptItem> Functions { get { return functions; } }
internal IEnumerable<string> Includes { get { return includes; } }
internal AcsParserSE() internal AcsParserSE()
{ {
namedScripts = new List<ScriptItem>(); namedscripts = new List<ScriptItem>();
numberedScripts = new List<ScriptItem>(); numberedscripts = new List<ScriptItem>();
functions = new List<ScriptItem>(); functions = new List<ScriptItem>();
parsedLumps = new List<string>(); parsedlumps = new List<string>();
includes = new List<string>(); includes = new List<string>();
} }
internal List<string> Includes
{
get { return includes; }
}
public override bool Parse(Stream stream, string sourcefilename) public override bool Parse(Stream stream, string sourcefilename)
{ {
return Parse(stream, sourcefilename, false, false); return Parse(stream, sourcefilename, false, false);
} }
public bool Parse(Stream stream, string sourcefilename, bool processIncludes, bool isinclude) public bool Parse(Stream stream, string sourcefilename, bool processincludes, bool isinclude)
{ {
base.Parse(stream, sourcefilename); base.Parse(stream, sourcefilename);
//already parsed this? //already parsed this?
if (parsedLumps.Contains(sourcefilename)) return false; if (parsedlumps.Contains(sourcefilename)) return false;
parsedLumps.Add(sourcefilename); parsedlumps.Add(sourcefilename);
if (isinclude) includes.Add(sourcefilename); if (isinclude) includes.Add(sourcefilename);
int bracelevel = 0;
// Keep local data // Keep local data
Stream localstream = datastream; Stream localstream = datastream;
@ -60,28 +57,32 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom
while (SkipWhitespace(true)) while (SkipWhitespace(true))
{ {
string token = ReadToken(); string token = ReadToken();
if(string.IsNullOrEmpty(token)) continue;
if (!string.IsNullOrEmpty(token)) // Ignore inner scope stuff
if(token == "{") { bracelevel++; continue; }
if(token == "}") { bracelevel--; continue; }
if(bracelevel > 0) continue;
switch (token.ToLowerInvariant())
{ {
token = token.ToLowerInvariant(); case "script":
if (token == "script")
{ {
SkipWhitespace(true); SkipWhitespace(true);
int startPos = (int)stream.Position; int startpos = (int)stream.Position;
token = ReadToken(); token = ReadToken();
//is it named script? //is it named script?
if (token.IndexOf('"') != -1) if (token.IndexOf('"') != -1)
{ {
startPos += 1; startpos += 1;
//check if we have something like '"mycoolscript"(void)' as a token //check if we have something like '"mycoolscript"(void)' as a token
if(token.LastIndexOf('"') != token.Length - 1) if(token.LastIndexOf('"') != token.Length - 1)
token = token.Substring(0, token.LastIndexOf('"')); token = token.Substring(0, token.LastIndexOf('"'));
token = StripTokenQuotes(token); token = StripTokenQuotes(token);
ScriptItem i = new ScriptItem(0, token, startPos, isinclude); ScriptItem i = new ScriptItem(0, token, startpos, isinclude);
namedScripts.Add(i); namedscripts.Add(i);
} }
else //should be numbered script else //should be numbered script
{ {
@ -100,27 +101,30 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom
token = ReadLine(); token = ReadLine();
string name = ""; string name = "";
bracelevel = 1;
if (!string.IsNullOrEmpty(token)) if (!string.IsNullOrEmpty(token))
{ {
int commentStart = token.IndexOf("//"); int commentstart = token.IndexOf("//");
if (commentStart != -1) //found comment if (commentstart != -1) //found comment
{ {
commentStart += 2; commentstart += 2;
name = token.Substring(commentStart, token.Length - commentStart).Trim(); name = token.Substring(commentstart, token.Length - commentstart).Trim();
} }
} }
name = (name.Length > 0 ? name + " [" + n + "]" : "Script " + n); name = (name.Length > 0 ? name + " [" + n + "]" : "Script " + n);
ScriptItem i = new ScriptItem(n, name, startPos, isinclude); ScriptItem i = new ScriptItem(n, name, startpos, isinclude);
numberedScripts.Add(i); numberedscripts.Add(i);
} }
} }
} }
else if(token == "function") break;
case "function":
{ {
SkipWhitespace(true); SkipWhitespace(true);
int startPos = (int) stream.Position; int startpos = (int)stream.Position;
string funcname = ReadToken(); //read return type string funcname = ReadToken(); //read return type
SkipWhitespace(true); SkipWhitespace(true);
funcname += " " + ReadToken(); //read function name funcname += " " + ReadToken(); //read function name
@ -147,23 +151,26 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom
} while(!string.IsNullOrEmpty(token) && !token.Contains(")")); } while(!string.IsNullOrEmpty(token) && !token.Contains(")"));
} }
ScriptItem i = new ScriptItem(0, funcname, startPos, isinclude); ScriptItem i = new ScriptItem(0, funcname, startpos, isinclude);
functions.Add(i); functions.Add(i);
} }
else if (processIncludes && (token == "#include" || token == "#import")) break;
default:
if (processincludes && (token == "#include" || token == "#import"))
{ {
SkipWhitespace(true); SkipWhitespace(true);
string includeLump = StripTokenQuotes(ReadToken()).ToLowerInvariant(); string includelump = StripTokenQuotes(ReadToken()).ToLowerInvariant();
if (!string.IsNullOrEmpty(includeLump)) if (!string.IsNullOrEmpty(includelump))
{ {
string includeName = Path.GetFileName(includeLump); string includename = Path.GetFileName(includelump);
if (includeName == "zcommon.acs" || includeName == "common.acs" || includes.Contains(includeName)) if (includename == "zcommon.acs" || includename == "common.acs" || includes.Contains(includename))
continue; continue;
// Callback to parse this file // Callback to parse this file
if (OnInclude != null) OnInclude(this, includeLump.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar)); if (OnInclude != null) OnInclude(this, includelump.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar));
// Set our buffers back to continue parsing // Set our buffers back to continue parsing
datastream = localstream; datastream = localstream;
@ -175,6 +182,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom
General.ErrorLogger.Add(ErrorType.Error, "Error in '" + sourcefilename + "' at line " + GetCurrentLineNumber() + ": got #include directive without include path!"); General.ErrorLogger.Add(ErrorType.Error, "Error in '" + sourcefilename + "' at line " + GetCurrentLineNumber() + ": got #include directive without include path!");
} }
} }
break;
} }
} }
return true; return true;