diff --git a/doomsday/client/src/m_misc.cpp b/doomsday/client/src/m_misc.cpp index e232fc2730..bec5b0b100 100644 --- a/doomsday/client/src/m_misc.cpp +++ b/doomsday/client/src/m_misc.cpp @@ -274,7 +274,7 @@ DENG_EXTERN_C AutoStr* M_ReadFileIntoString(ddstring_t const *path, dd_bool *isC if(isCustom) *isCustom = W_LumpIsCustom(lumpNum); - // Ignore zero-length scripts. + // Ignore zero-length lumps. size_t lumpLen = W_LumpLength(lumpNum); if(!lumpLen) return 0; @@ -295,6 +295,7 @@ DENG_EXTERN_C AutoStr* M_ReadFileIntoString(ddstring_t const *path, dd_bool *isC AutoStr *string = Str_PartAppend(AutoStr_New(), readBuf, 0, int(bytesRead)); Z_Free(readBuf); + // Ignore zero-length files. if(Str_IsEmpty(string)) return 0; diff --git a/doomsday/libdeng1/include/de/str.h b/doomsday/libdeng1/include/de/str.h index b7792ab9e1..5f231a847f 100644 --- a/doomsday/libdeng1/include/de/str.h +++ b/doomsday/libdeng1/include/de/str.h @@ -300,8 +300,8 @@ DENG_PUBLIC Str *Str_Strip(Str *ds); DENG_PUBLIC Str *Str_ReplaceAll(Str *ds, char from, char to); /** - * Determines if the string starts starts with the given substring. The comparison - * is done case sensitively. + * Determines if the string starts with the given substring. The comparison is done + * case sensitively. * * @param ds String instance. * @param text Text to look for at the start of @a ds. diff --git a/doomsday/plugins/common/include/hexlex.h b/doomsday/plugins/common/include/hexlex.h index 4472c64678..73ed57fa67 100644 --- a/doomsday/plugins/common/include/hexlex.h +++ b/doomsday/plugins/common/include/hexlex.h @@ -1,4 +1,4 @@ -/** @file hexlex.h Laxical analyzer for Hexen definition/script syntax. +/** @file hexlex.h Lexical analyzer for Hexen definition/script syntax. * * @authors Copyright © 2003-2013 Jaakko Keränen * @authors Copyright © 2007-2013 Daniel Swanson @@ -43,13 +43,18 @@ class HexLex void parse(Str const *script, Str const *sourcePath); bool readToken(); - Str const *token(); void unreadToken(); - Str const *mustGetString(); - int mustGetNumber(); + Str const *readString(); + int readNumber(); + + AutoStr *readLumpName(); + int readSoundId(); + int readSoundIndex(); + uint readMapNumber(); + Uri *readTextureUri(char const *defaultScheme); int lineNumber() const; diff --git a/doomsday/plugins/common/src/hexlex.cpp b/doomsday/plugins/common/src/hexlex.cpp index 1326a3eef2..cc34dd65af 100644 --- a/doomsday/plugins/common/src/hexlex.cpp +++ b/doomsday/plugins/common/src/hexlex.cpp @@ -1,4 +1,4 @@ -/** @file hexlex.cpp Hexen definition/script syntax. +/** @file hexlex.cpp HLexical analyzer for Hexen definition/script syntax. * * @authors Copyright © 2003-2013 Jaakko Keränen * @authors Copyright © 2007-2013 Daniel Swanson @@ -29,7 +29,7 @@ void HexLex::checkOpen() { - if(!_script) Con_Error("RavHexParser: No script to parse!"); + if(!_script) Con_Error("HexLex: No script to parse!"); } bool HexLex::atEnd() @@ -166,7 +166,7 @@ bool HexLex::readToken() return true; } -Str const *HexLex::mustGetString() +Str const *HexLex::readString() { if(!readToken()) { @@ -175,7 +175,7 @@ Str const *HexLex::mustGetString() return &_token; } -int HexLex::mustGetNumber() +int HexLex::readNumber() { checkOpen(); @@ -188,15 +188,55 @@ int HexLex::mustGetNumber() _tokenAsNumber = strtol(Str_Text(&_token), &stopper, 0); if(*stopper != 0) { - Con_Error("RavHexParser: Bad numeric constant \"%s\".\n" - "File: \"%s\", Line: %i", + Con_Error("HexLex: Non-numeric constant '%s' in \"%s\" on line #%i", Str_Text(&_token), F_PrettyPath(Str_Text(&_sourcePath)), _lineNumber); } return _tokenAsNumber; } -/// @note Assumes there is a valid string in sc_String. +Uri *HexLex::readTextureUri(char const *defaultScheme) +{ + if(!readToken()) // Name. + { + scriptError("Missing texture Uri"); + } + + Uri *uri = Uri_SetScheme(Uri_New(), defaultScheme); + AutoStr *path = Str_PercentEncode(Str_Copy(AutoStr_NewStd(), &_token)); + Uri_SetPath(uri, Str_Text(path)); + return uri; +} + +AutoStr *HexLex::readLumpName() +{ + return AutoStr_FromText(Str_Text(readString())); +} + +uint HexLex::readMapNumber() +{ + uint num = readNumber(); + return num > 0? num - 1 : num; +} + +int HexLex::readSoundId() +{ + return Def_Get(DD_DEF_SOUND_BY_NAME, Str_Text(readString()), 0); +} + +int HexLex::readSoundIndex() +{ + char const *name = Str_Text(readString()); + int i = Def_Get(DD_DEF_SOUND_BY_NAME, name, 0); + if(!i) + { + AutoStr *msg = Str_Appendf(AutoStr_New(), "Unknown sound '%s'", name); + scriptError(Str_Text(msg)); + } + return i; +} + +// @note Assumes there is a valid string in sc_String. void HexLex::unreadToken() { _alreadyGot = true; @@ -214,7 +254,7 @@ int HexLex::lineNumber() const void HexLex::scriptError(char const *message) { - Con_Error("RavHexParser: Error in script \"%s\" on line #%i.\n%s", + Con_Error("HexLex: Error in \"%s\" on line #%i.\n%s", F_PrettyPath(Str_Text(&_sourcePath)), _lineNumber, message); } diff --git a/doomsday/plugins/common/src/p_sound.cpp b/doomsday/plugins/common/src/p_sound.cpp index 37ed101b7d..96c1fa2b64 100644 --- a/doomsday/plugins/common/src/p_sound.cpp +++ b/doomsday/plugins/common/src/p_sound.cpp @@ -93,21 +93,6 @@ int S_GetSoundID(char const *name) return Def_Get(DD_DEF_SOUND_BY_NAME, name, 0); } -static AutoStr *parseLumpName(HexLex &lexer) -{ - return AutoStr_FromText(Str_Text(lexer.mustGetString())); -} - -static uint parseMapNumber(HexLex &lexer) -{ - return lexer.mustGetNumber() - 1; -} - -static int parseSoundId(HexLex &lexer) -{ - return Def_Get(DD_DEF_SOUND_BY_NAME, Str_Text(lexer.token()), 0); -} - void SndInfoParser(Str const *path) { AutoStr *script = M_ReadFileIntoString(path, 0); @@ -127,15 +112,15 @@ void SndInfoParser(Str const *path) // Used in combination with the -devsnd command line argument to // redirect the loading of sounds to a directory in the local file // system. - lexer.mustGetString(); + lexer.readString(); continue; } if(!Str_CompareIgnoreCase(lexer.token(), "$map")) { // $map int(map-number) string(lump-name) // Associate a music lump to a map. - uint const map = parseMapNumber(lexer); - AutoStr const *lumpName = parseLumpName(lexer); + uint const map = lexer.readMapNumber(); + AutoStr const *lumpName = lexer.readLumpName(); if(map >= 0 && map >= P_MapInfoCount()) { @@ -150,10 +135,12 @@ void SndInfoParser(Str const *path) continue; } + lexer.unreadToken(); + // string(sound-id) string(lump-name | '?') // A sound definition. - int const soundId = parseSoundId(lexer); - AutoStr const *lumpName = parseLumpName(lexer); + int const soundId = lexer.readSoundId(); + AutoStr const *lumpName = lexer.readLumpName(); if(soundId) { diff --git a/doomsday/plugins/hexen/src/p_anim.cpp b/doomsday/plugins/hexen/src/p_anim.cpp index 0ae369b7c4..0a097b4da5 100644 --- a/doomsday/plugins/hexen/src/p_anim.cpp +++ b/doomsday/plugins/hexen/src/p_anim.cpp @@ -64,17 +64,8 @@ void AnimDefsParser(Str const *path) // string(texture-scheme) string(texture-path) if(char const *scheme = textureScheme(lexer.token())) { - if(!lexer.readToken()) // Name. - { - lexer.scriptError("Missing string"); - } - - Uri *uri = Uri_SetScheme(Uri_New(), scheme); - AutoStr *path = Str_PercentEncode(Str_Copy(AutoStr_NewStd(), lexer.token())); - Uri_SetPath(uri, Str_Text(path)); - + Uri *uri = lexer.readTextureUri(scheme); int const texNumBase = Textures_UniqueId2(uri, !isCustom); - Uri_Delete(uri); bool const ignore = (texNumBase == -1); @@ -88,18 +79,18 @@ void AnimDefsParser(Str const *path) { if(!Str_CompareIgnoreCase(lexer.token(), "pic")) { - int picNum = lexer.mustGetNumber(); + int picNum = lexer.readNumber(); int min = 0, max = 0; - Str const *label = lexer.mustGetString(); + Str const *label = lexer.readString(); if(!Str_CompareIgnoreCase(label, "tics")) { - min = lexer.mustGetNumber(); + min = lexer.readNumber(); } else if(!Str_CompareIgnoreCase(label, "rand")) { - min = lexer.mustGetNumber(); - max = lexer.mustGetNumber(); + min = lexer.readNumber(); + max = lexer.readNumber(); } else { diff --git a/doomsday/plugins/hexen/src/p_mapinfo.cpp b/doomsday/plugins/hexen/src/p_mapinfo.cpp index 1274697156..8c9fd66141 100644 --- a/doomsday/plugins/hexen/src/p_mapinfo.cpp +++ b/doomsday/plugins/hexen/src/p_mapinfo.cpp @@ -1,4 +1,4 @@ -/** @file p_mapinfo.c Hexen MAPINFO parsing. +/** @file p_mapinfo.cpp Hexen MAPINFO parsing. * * @authors Copyright © 2003-2013 Jaakko Keränen * @authors Copyright © 2005-2013 Daniel Swanson @@ -22,8 +22,8 @@ #include "jhexen.h" #include "p_mapinfo.h" #include "hexlex.h" -#include -#include +#include +#include enum { CD_START, @@ -107,37 +107,37 @@ void MapInfoParser(Str const *path) { if(!Str_CompareIgnoreCase(lexer.token(), "cd_start_track")) { - setSongCDTrack(CD_START, lexer.mustGetNumber()); + setSongCDTrack(CD_START, lexer.readNumber()); continue; } if(!Str_CompareIgnoreCase(lexer.token(), "cd_end1_track")) { - setSongCDTrack(CD_END1, lexer.mustGetNumber()); + setSongCDTrack(CD_END1, lexer.readNumber()); continue; } if(!Str_CompareIgnoreCase(lexer.token(), "cd_end2_track")) { - setSongCDTrack(CD_END2, lexer.mustGetNumber()); + setSongCDTrack(CD_END2, lexer.readNumber()); continue; } if(!Str_CompareIgnoreCase(lexer.token(), "cd_end3_track")) { - setSongCDTrack(CD_END3, lexer.mustGetNumber()); + setSongCDTrack(CD_END3, lexer.readNumber()); continue; } if(!Str_CompareIgnoreCase(lexer.token(), "cd_intermission_track")) { - setSongCDTrack(CD_INTERLUDE, lexer.mustGetNumber()); + setSongCDTrack(CD_INTERLUDE, lexer.readNumber()); continue; } if(!Str_CompareIgnoreCase(lexer.token(), "cd_title_track")) { - setSongCDTrack(CD_TITLE, lexer.mustGetNumber()); + setSongCDTrack(CD_TITLE, lexer.readNumber()); continue; } if(!Str_CompareIgnoreCase(lexer.token(), "map")) { - int tmap = lexer.mustGetNumber(); + int tmap = lexer.readNumber(); if(tmap < 1 || tmap > 99) { lexer.scriptError(); @@ -163,7 +163,7 @@ void MapInfoParser(Str const *path) info->warpTrans = map; // Map name must follow the number. - strcpy(info->title, Str_Text(lexer.mustGetString())); + strcpy(info->title, Str_Text(lexer.readString())); // Process optional tokens. while(lexer.readToken()) @@ -171,7 +171,7 @@ void MapInfoParser(Str const *path) if(!Str_CompareIgnoreCase(lexer.token(), "sky1")) { ddstring_t path; Str_InitStd(&path); - Str_PercentEncode(Str_Copy(&path, lexer.mustGetString())); + Str_PercentEncode(Str_Copy(&path, lexer.readString())); Uri *uri = Uri_NewWithPath2("Textures:", RC_NULL); Uri_SetPath(uri, Str_Text(&path)); @@ -179,13 +179,13 @@ void MapInfoParser(Str const *path) Uri_Delete(uri); Str_Free(&path); - info->sky1ScrollDelta = (float) lexer.mustGetNumber() / 256; + info->sky1ScrollDelta = (float) lexer.readNumber() / 256; continue; } if(!Str_CompareIgnoreCase(lexer.token(), "sky2")) { ddstring_t path; Str_InitStd(&path); - Str_PercentEncode(Str_Copy(&path, lexer.mustGetString())); + Str_PercentEncode(Str_Copy(&path, lexer.readString())); Uri *uri = Uri_NewWithPath2("Textures:", RC_NULL); Uri_SetPath(uri, Str_Text(&path)); @@ -193,7 +193,7 @@ void MapInfoParser(Str const *path) Uri_Delete(uri); Str_Free(&path); - info->sky2ScrollDelta = (float) lexer.mustGetNumber() / 256; + info->sky2ScrollDelta = (float) lexer.readNumber() / 256; continue; } if(!Str_CompareIgnoreCase(lexer.token(), "doublesky")) @@ -208,12 +208,12 @@ void MapInfoParser(Str const *path) } if(!Str_CompareIgnoreCase(lexer.token(), "fadetable")) { - info->fadeTable = W_GetLumpNumForName(Str_Text(lexer.mustGetString())); + info->fadeTable = W_GetLumpNumForName(Str_Text(lexer.readString())); continue; } if(!Str_CompareIgnoreCase(lexer.token(), "cluster")) { - info->cluster = lexer.mustGetNumber(); + info->cluster = lexer.readNumber(); if(info->cluster < 1) { char buf[40]; @@ -224,7 +224,7 @@ void MapInfoParser(Str const *path) } if(!Str_CompareIgnoreCase(lexer.token(), "warptrans")) { - int mapWarpNum = lexer.mustGetNumber(); + int mapWarpNum = lexer.readNumber(); if(mapWarpNum < 1 || mapWarpNum > 99) lexer.scriptError(); info->warpTrans = (unsigned) mapWarpNum - 1; @@ -232,7 +232,7 @@ void MapInfoParser(Str const *path) } if(!Str_CompareIgnoreCase(lexer.token(), "next")) { - int mapId = lexer.mustGetNumber(); + int mapId = lexer.readNumber(); if(mapId < 1 || mapId > 99) lexer.scriptError(); info->nextMap = (unsigned) mapId - 1; @@ -240,7 +240,7 @@ void MapInfoParser(Str const *path) } if(!Str_CompareIgnoreCase(lexer.token(), "cdtrack")) { - info->cdTrack = lexer.mustGetNumber(); + info->cdTrack = lexer.readNumber(); continue; } diff --git a/doomsday/plugins/hexen/src/sn_sonix.cpp b/doomsday/plugins/hexen/src/sn_sonix.cpp index a061468cd3..5215e662f5 100644 --- a/doomsday/plugins/hexen/src/sn_sonix.cpp +++ b/doomsday/plugins/hexen/src/sn_sonix.cpp @@ -97,18 +97,6 @@ static void verifySequencePtr(int *base, int *ptr) } } -static int parseSoundIndex(HexLex &lexer) -{ - char const *name = Str_Text(lexer.mustGetString()); - int i = Def_Get(DD_DEF_SOUND_BY_NAME, name, 0); - if(!i) - { - AutoStr *msg = Str_Appendf(AutoStr_New(), "parseSoundIndex: Unknown sound '%s'", name); - lexer.scriptError(Str_Text(msg)); - } - return i; -} - void SndSeqParser(Str const *path) { initSequenceData(); @@ -183,7 +171,7 @@ void SndSeqParser(Str const *path) verifySequencePtr(tempDataStart, tempDataPtr); *tempDataPtr++ = SS_CMD_PLAYREPEAT; - *tempDataPtr++ = parseSoundIndex(lexer); + *tempDataPtr++ = lexer.readSoundIndex(); continue; } if(!Str_CompareIgnoreCase(lexer.token(), "playtime")) @@ -191,9 +179,9 @@ void SndSeqParser(Str const *path) verifySequencePtr(tempDataStart, tempDataPtr); *tempDataPtr++ = SS_CMD_PLAY; - *tempDataPtr++ = parseSoundIndex(lexer); + *tempDataPtr++ = lexer.readSoundIndex(); *tempDataPtr++ = SS_CMD_DELAY; - *tempDataPtr++ = lexer.mustGetNumber(); + *tempDataPtr++ = lexer.readNumber(); continue; } if(!Str_CompareIgnoreCase(lexer.token(), "playuntildone")) @@ -201,7 +189,7 @@ void SndSeqParser(Str const *path) verifySequencePtr(tempDataStart, tempDataPtr); *tempDataPtr++ = SS_CMD_PLAY; - *tempDataPtr++ = parseSoundIndex(lexer); + *tempDataPtr++ = lexer.readSoundIndex(); *tempDataPtr++ = SS_CMD_WAITUNTILDONE; continue; } @@ -210,7 +198,7 @@ void SndSeqParser(Str const *path) verifySequencePtr(tempDataStart, tempDataPtr); *tempDataPtr++ = SS_CMD_PLAY; - *tempDataPtr++ = parseSoundIndex(lexer); + *tempDataPtr++ = lexer.readSoundIndex(); continue; } if(!Str_CompareIgnoreCase(lexer.token(), "delayrand")) @@ -218,8 +206,8 @@ void SndSeqParser(Str const *path) verifySequencePtr(tempDataStart, tempDataPtr); *tempDataPtr++ = SS_CMD_DELAYRAND; - *tempDataPtr++ = lexer.mustGetNumber(); - *tempDataPtr++ = lexer.mustGetNumber(); + *tempDataPtr++ = lexer.readNumber(); + *tempDataPtr++ = lexer.readNumber(); continue; } if(!Str_CompareIgnoreCase(lexer.token(), "delay")) @@ -227,7 +215,7 @@ void SndSeqParser(Str const *path) verifySequencePtr(tempDataStart, tempDataPtr); *tempDataPtr++ = SS_CMD_DELAY; - *tempDataPtr++ = lexer.mustGetNumber(); + *tempDataPtr++ = lexer.readNumber(); continue; } if(!Str_CompareIgnoreCase(lexer.token(), "volume")) @@ -235,12 +223,12 @@ void SndSeqParser(Str const *path) verifySequencePtr(tempDataStart, tempDataPtr); *tempDataPtr++ = SS_CMD_VOLUME; - *tempDataPtr++ = lexer.mustGetNumber(); + *tempDataPtr++ = lexer.readNumber(); continue; } if(!Str_CompareIgnoreCase(lexer.token(), "stopsound")) { - SequenceTranslate[inSequence].stopSound = parseSoundIndex(lexer); + SequenceTranslate[inSequence].stopSound = lexer.readSoundIndex(); *tempDataPtr++ = SS_CMD_STOPSOUND; continue; }