I've made some file parsing functions to help with loading maps/entities/missions in my current project. Here's the code:
Rem Project: LIAR Data Management
Rem Created: Sunday, January 11, 2009
Rem ***** Main Source File *****
Type TProperty
IntegerVal Integer
FloatVal as Float
StringVal as String
Name as String
EndType
Dim FileLines( -1 ) as String
Dim FileDataBlocks( -1 ) as String
Dim Properties( -1 ) as TProperty
Set Display Mode 1024, 768, 32
Sync On
Sync Rate 60
OpenFile( "Test.txt" )
ParseFileDataBlocks( )
ParseFileProperties( )
Do
CLS
Print GetPropertyStringVal( "Level->LevelName" )
Sync
Loop
Function OpenFile( FileName as String )
R as String
Open To Read 1, FileName
For I = 1 to 1000
Read String 1, R
If R = ""
Exit
EndIf
Array Insert at Bottom FileLines( )
FileLines( I - 1 ) = R
Next I
Close File 1
EndFunction
Function ParseFileDataBlocks( )
CurrentDataBlock = -1
CurrentScope as String
ParentScope as String
For I = 0 to Array Count( FileLines( ) )
If I < Array Count( FileLines( ) )
If FileLines( I ) = "{"
ParentScope = CurrentScope
CurrentScope = FileLines( I - 1 )
Inc CurrentDataBlock
Array Insert at Bottom FileDataBlocks( )
FileDataBlocks( CurrentDataBlock ) = ParentScope + "->" + FileLines( I - 1 )
EndIf
If FileLines( I ) = "}"
CurrentScope = ParentScope
EndIf
EndIf
Next I
EndFunction
Function ParseFileProperties( )
CurrentScope as String
ParentScope as String
For I = 0 to Array Count( FileLines( ) )
If I < Array Count( FileLines( ) )
If FileLines( I ) = "{"
ParentScope = CurrentScope
CurrentScope = FileLines( I - 1 )
EndIf
If FileLines( I ) = "}"
CurrentScope = ParentScope
EndIf
For A = 1 to Len( FileLines( I ) )
If Mid$( FileLines( I ), A ) = "="
Array Insert At Bottom Properties( )
Properties( Array Count( Properties( ) ) ).IntegerVal = Int( Val( Right$( FileLines( I ), Len( FileLines( I ) ) - A ) ) )
Properties( Array Count( Properties( ) ) ).FloatVal = Val( Right$( FileLines( I ), Len( FileLines( I ) ) - A ) )
Properties( Array Count( Properties( ) ) ).StringVal = Right$( FileLines( I ), Len( FileLines( I ) ) - A )
If Len( ParentScope ) > 0
Properties( Array Count( Properties( ) ) ).Name = ParentScope + "->" + CurrentScope + "->" + Left$( FileLines( I ), A - 1 )
Else
Properties( Array Count( Properties( ) ) ).Name = CurrentScope + "->" + Left$( FileLines( I ), A - 1 )
EndIf
EndIf
Next A
EndIf
Next I
EndFunction
Function GetPropertyIntegerVal( PropertyName as String )
For I = 0 to Array Count( Properties( ) )
If Properties( I ).Name = PropertyName
TEMP as Integer
TEMP = Properties( I ).IntegerVal
ExitFunction TEMP
EndIf
Next I
EndFunction -1000000
Function GetPropertyFloatVal( PropertyName as String )
For I = 0 to Array Count( Properties( ) )
If Properties( I ).Name = PropertyName
TEMP as Float
TEMP = Properties( I ).FloatVal
ExitFunction TEMP
EndIf
Next I
EndFunction -1000000.0
Function GetPropertyStringVal( PropertyName as String )
For I = 0 to Array Count( Properties( ) )
If Properties( I ).Name = PropertyName
TEMP as String
TEMP = Properties( I ).StringVal
ExitFunction TEMP
EndIf
Next I
EndFunction "Problem Retrieving Property Value"
Function GetDataBlockByID( ID as Integer )
TEMP as String
TEMP = FileDataBlocks( ID - 1 )
EndFunction TEMP
Function GetFileLine( LineNum as Integer )
TEMP as String
TEMP = FileLines( LineNum - 1 )
EndFunction TEMP
Function GetFileLineCount( )
TEMP = Array Count( FileLines( ) ) + 1
EndFunction TEMP
And here's a list of the functions and explanations:
OpenFile( FileName as String ) - This function will open a file and store it's contents inside an array. This must be called before any others.
ParseFileDataBlocks( ) - This function will retrieve the name of every 'DataBlock' and store it in an array. This must be called right after OpenFile( ).
ParseFileProperties( ) - This function find the name and value of every propertie within the text file last opened and stores them in an array. This must also be called right after OpenFile( ).
GetPropertyIntegerVal( PropertName as string ) - This function will retrieve the integer value of the specified property.
GetPropertyFloatVal( PropertName as string ) - This function will retrieve the float value of the specified property.
GetPropertyStringVal( PropertName as string ) - This function will retrieve the string value of the specified property.
GetDataBlockByID( ID as Integer ) - This function will retrieve the specified datablock name according to the ID.
GetFileLine( LineNum as Integer ) - This function will retrieve the text on a specific line.
GetFileLineCount( ) - This function will retrieve the number of lines in the currently open file.
Here's how it works:
If you have a MyFile.txt that looks like this:
HideMouse=1
FullScreen=0
AppTitle="MyApp"
You'd get the values like so:
OpenFile( "MyFile.txt" )
ParseFileDataBlocks( )
ParseFileProperties( )
HideMouse = GetPropertyIntegerVal( "HideMouse" )
FullScreen = GetPropertyIntegerVal( "FullScreen" )
AppTitle$ = GetPropertyStringVal( "AppTitle" )
You can also use datablocks if you have more complex data, like in a level file:
Level
{
Name=MyLevel
SpawnPoint
{
PosX=5.0
PosY=3.0
PosZ=7.0
}
}
And get values like this:
OpenFile( "MyMapFile.txt" )
ParseFileDataBlocks( )
ParseFileProperties( )
LevelName$ = GetPropertyStringVal( "Level->Name" )
SpawnPosX# = GetPropertyFloatVal( "Level->SpawnPoint->PosX" )
SpawnPosY# = GetPropertyFloatVal( "Level->SpawnPoint->PosY" )
SpawnPosZ# = GetPropertyFloatVal( "Level->SpawnPoint->PosZ" )
The "->" symbol is used to access nested values. The functions also do not support tabs ATM so:
Level
{
Name=MyLevel
SpawnPoint
{
PosX=5.0
PosY=3.0
PosZ=7.0
}
}
Would not work.
If you have any questions just ask.