Jump to content

Read ini file > assign variable values


AL|EN

Recommended Posts

Would REPLACE_EVALUATE be simpler?

OUTER_SPRINT configuration-default ~%MOD_FOLDER%/configuration-default.ini~
OUTER_SPRINT configuration ~%MOD_FOLDER%/configuration.ini~

DEFINE_ACTION_FUNCTION GetIniKeyValue
	STR_VAR filename=""
	RET_ARRAY ini_content
	BEGIN
		COPY - "%filename%" "%override%" // "COPY -" means no actual changes to the file
			REPLACE_EVALUATE	~^\([^ %TAB%%WNL%]+\)=\([^%WNL%$]+\)~	BEGIN
			// key must start line and cannot contain whitespace
			// value is everything after the "=" until the newline/end
				TEXT_SPRINT $ini_content(~%MATCH1%~) ~%MATCH2%~
			END	~~
END
PRINT "%configuration-default%"
PRINT "%configuration%"

LAF GetIniKeyValue STR_VAR filename="%configuration-default%" RET_ARRAY ini_content END
ACTION_IF FILE_EXISTS ~%configuration%~ THEN BEGIN
  LAF GetIniKeyValue STR_VAR filename="%configuration%" RET_ARRAY ini_content END
END
ACTION_PHP_EACH ini_content AS key=>value BEGIN
  PRINT "%key%: %value%"
END 
Link to comment

Isn't it more elegant to format your INI file as valid WeiDU variable assignments and INCLUDE it?

It would be a hack of well defined industry file format. Ini file is not only for the mod itself, it's also for install tool. And Install Tool can't read anything except standard industry file formats like ini/json etc

Link to comment

Works fine for me:

GWnbvariables = 3

VARIABLE timer11 = 0

label = timer11

VARIABLE timer12 = 0

label = timer12

VARIABLE timer13 = 0

label = timer13

kjeron's code works fine too, and is much more elegant. ;)

I just added the following line:

 

REPLACE_EVALUATE ~^\([^ %TAB%%WNL%]+\)=\([^%WNL%$]+\)~ BEGIN
// key must start line and cannot contain whitespace
// value is everything after the "=" until the newline/end
TO_LOWER %MATCH1%

Edit : Oops! my fault. I made a mistake when I inserted two lines at the wrong place in the post. I fixed them and it should work now.

Edited by Gwendolyne
Link to comment

Works fine for me:

 

Edit : Oops! my fault. I made a mistake when I inserted two lines at the wrong place in the post. I fixed them and it should work now.

@Gwendolyne thanks it works for me also :thumbsup:

 

 

@kjeron

Would REPLACE_EVALUATE be simpler?

			// key must start line and cannot contain whitespace

 

Just for the record, you can't set you own rules for industry standard file format like "// key must start line and cannot contain whitespace". It's perfectly fine to have whitespace before key name for ini files. Nobody will create such file in the first place but in case of such whitespace, it should work. But I'm sure that the probability is extremely low so we are safe. Thanks for contribution.

Edited by ALIENQuake
Link to comment

Kjeron's trick is very nice. I should play with REPLACE_EVALUATE more often.

 

 

The use of the function isn't quite right, because of how RET_ARRAY works. (It works correctly! - this isn't a WEIDU bug.) If you do

LAF GetIniKeyValue STR_VAR filename="%configuration-default%" RET_ARRAY ini_content END
ACTION_IF FILE_EXISTS ~%configuration%~ THEN BEGIN
  LAF GetIniKeyValue STR_VAR filename="%configuration%" RET_ARRAY ini_content END
END
then the second call of GetIniKeyValue will return a new ini_content that replaces the old one. So if there is a key present in configuration-default but not in configuration, it won't be returned at all. You need to do either

 

LAF GetIniKeyValue STR_VAR filename="%configuration-default%" RET_ARRAY ini_content END
ACTION_IF FILE_EXISTS ~%configuration%~ THEN BEGIN
  LAF GetIniKeyValue STR_VAR filename="%configuration%" RET_ARRAY ini_content_extra=ini_content END
  ACTION_PHP_EACH ini_content_extra AS key=>value BEGIN
    OUTER_SPRINT $ini_content("%key%") "%value%"
  END
END
or

LAF GetIniKeyValue STR_VAR filename="%configuration-default%" RET_ARRAY ini_content END
ACTION_PHP_EACH ini_content AS key=>value BEGIN
   OUTER_SPRINT "%key%" "%value%"
END
ACTION_IF FILE_EXISTS ~%configuration%~ THEN BEGIN
  LAF GetIniKeyValue STR_VAR filename="%configuration%" RET_ARRAY ini_content END
  ACTION_PHP_EACH ini_content AS key=>value BEGIN
      OUTER_SPRINT "%key%" "%value%"
  END
END
depending on whether you want your ini data in an array or (as in Alien's original use case) a variety of variables. (I prefer the former to avoid having to worry about namespace clashes, but that's a matter of taste.)
Link to comment

Just for the record, you can't set you own rules for industry standard file format like "// key must start line and cannot contain whitespace". It's perfectly fine to have whitespace before key name for ini files. Nobody will create such file in the first place but in case of such whitespace, it should work. But I'm sure that the probability is extremely low so we are safe. Thanks for contribution.

I was just listing the limitations of what I wrote. I wasn't sure how whitespace should be treated. If the line is:

 text =value

is key variable " text", "text ", " text ", or "text"?

I'm sure the regexp can be adjusted to match.

Link to comment

Version 0.0.3:

BACKUP "GlobalVariableFromIni/backup"
SUPPORT ""
VERSION "0.0.3"

AUTO_EVAL_STRINGS

ALWAYS

    OUTER_SPRINT config-default "%MOD_FOLDER%/config-default.ini" // default config file to read initial variable values
    OUTER_SPRINT config "%MOD_FOLDER%/config.ini" // user created file, not included inside mod archive, if exist it will overwrite variable values from default config file

    DEFINE_ACTION_MACRO Set-GlobalIniArray BEGIN OUTER_TEXT_SPRINT $GlobalIniArray("%key%") "%value%" END

    DEFINE_PATCH_FUNCTION Get-IniArray
        INT_VAR
            start_offset = 0 
        RET
            start_offset
            end_offset
        RET_ARRAY GlobalIniArray
        BEGIN
            SET offset = start_offset
            PATCH_IF (offset < 0) BEGIN SET offset = 0 END
            PATCH_IF (offset > BUFFER_LENGTH) BEGIN SET offset = BUFFER_LENGTH END
            SET start_offset = "-1"
            SET end_offset = "-1"

            SET ofsStart = INDEX_BUFFER("[0-9a-zA-Z]" offset) 
            PATCH_IF (ofsStart >= 0) BEGIN
                SET ofsValue = INDEX_BUFFER("=" ofsStart) 
                PATCH_IF (ofsValue >= 0) BEGIN
                    READ_ASCII (ofsStart) key (ofsValue - ofsStart)
                    TO_LOWER key
                    SET ofsEnd = INDEX_BUFFER("[%WNL%]" ofsValue)
                    PATCH_IF (ofsEnd >= 0) BEGIN
                        READ_ASCII (ofsValue + 1) value (ofsEnd - ofsValue -1)
                        SET start_offset = ofsStart
                        SET end_offset = ofsEnd
                        INNER_ACTION BEGIN LAM Set-GlobalIniArray END
                    END
                END
            END
        END

    DEFINE_ACTION_FUNCTION GlobalVariableFromIni
        STR_VAR filename = ""   
        RET_ARRAY GlobalIniArray
        BEGIN
            COPY - "%filename%" "override"
            INSERT_BYTES SOURCE_SIZE (STRING_LENGTH "%WNL%")
            WRITE_ASCIIE SOURCE_SIZE "%WNL%"
            REPLACE_TEXTUALLY ";.*" ""
            REPLACE_TEXTUALLY "#.*" ""

            COUNT_REGEXP_INSTANCES CASE_SENSITIVE "=" variable
            start_offset = 0
            FOR (i = 0 ; i < variable ; ++i) BEGIN
                LPF Get-IniArray INT_VAR start_offset RET end_offset RET_ARRAY GlobalIniArray END
                start_offset = end_offset
            END
        END

    PRINT "%config-default%"
    LAF GlobalVariableFromIni STR_VAR filename = "%config-default%" RET_ARRAY IniArray = GlobalIniArray END
    ACTION_IF FILE_EXISTS ~%config%~ THEN BEGIN
        PRINT "%config%"
        LAF GlobalVariableFromIni STR_VAR filename = "%config%" RET_ARRAY IniArray = GlobalIniArray END
    END

END

BEGIN "Component 1" DESIGNATED 1000 LABEL "Main"

ACTION_PHP_EACH IniArray AS key => value BEGIN
    PRINT "key: %key%"
    PRINT "value: %value%"
    OUTER_SPRINT "%key%" "%value%"
END  

Looks good?

Edited by ALIENQuake
Link to comment

Isn't it more elegant to format your INI file as valid WeiDU variable assignments and INCLUDE it?

 

Works great for me. Even better: wrap the variable assignments up as a macro. Then in the .tp2 file INCLUDE the file and LAM the macro. And, for ultimate safety, use a modder prefix in all of the variables. That should make damn sure that someone else's mod can't do any harm with it... means the file can live in /override, so players can make use of it regardless of which Weidu install tool they are using, and regardless of whether said install tool re-downloads the mod.

 

It would be a hack of well defined industry file format. Ini file is not only for the mod itself, it's also for install tool. And Install Tool can't read anything except standard industry file formats like ini/json etc

 

Well, it would be using the same language used to actually install mods, which is what we're all doing here. I mean Weidu isn't an "industry standard," but it works just fine for our purposes...

 

Can the tool not, perhaps, run some Weidu code to find and parse peoples' ".ini" files? I mean the tool really just executes Weidu mods... so "install" a "mod" that reads .ini files and generates json or whatever, and then the tool itself can use the output.

Edited by subtledoctor
Link to comment

Isn't it more elegant to format your INI file as valid WeiDU variable assignments and INCLUDE it?

 

Works great for me. Even better: wrap the variable assignments up as a macro. Then in the .tp2 file INCLUDE the file and LAM the macro. And, for ultimate safety, use a modder prefix in all of the variables.

 

If your mod's own internal data needs a modder prefix, your design has some serious problems with encapsulation...

Link to comment

As I said (possibly in an edit, though) the .ini file can live in /override, so putting a modder prefix on everything is warranted, as far as I'm concerned.

 

The idea is, players can edit the file, drop it in /override, then run BWS. The unmodified version of the .ini file downloaded by BWS will defer to the user-modified one it encounters in /override. If and when AL|EN settles on a solution to using .ini files with his install tool, I'll happily embrace it (probably). But this way works well right now.

Link to comment

As I said (possibly in an edit, though) the .ini file can live in /override, so putting a modder prefix on everything is warranted, as far as I'm concerned.

Well, if you wish to do such a dumpass thing, then go right ahead... make your D5xxxx.ini into the games overwrite folder... but wouldn't the mods own folder do just as well ? Why trheF would you ever do this sort of asshatting ?

Just like Alien showed, the regular config file can be in the mods own folder, where if it's copied and renamed as another file in the very same folder -instructed perhaps via a readme file, it can overwrite the originals values without a need to be overwritten as instructed and you get a user customization file for them to use in an autoinstall tool too, as the later file doesn't need to exist without the users specific use case. Aka they want to use it... they use the copy-rename-edit method, or just have the autoinstalltool to make the file on the fly.

 

I intent to use this in a specific component's. Aka I make a component that uses a .ini file's insets, timer11... timer19, timer20 and so forth.

... well it's more like a .tpa in weidu-usage, as it's used to only set a few variables, 20 or so... which the specific components then can use, while the other components use manually inserted variables via ACTION_READLN. These components are part of the same sub-components group with the .ini insert usage ones, so only either one can be used, never both. Hey, I made such things in the past, I can go back and recopy my old versions code. Wov, this is like I never learned a darn thing.

Why would I reinvent the wheel, cause the ones under our car work fairly well as is.

 

And nobody can ever talk me into using the ALWAYS -condition in weidu.

Say you want to insert code in a component, you insert it inside the component, not out of it. The .ini can have 10000 variables and a component can use 1st or the 9879th, and the others doen't need to be used, by this specific component.

And in case it's not clear, multiple components can read the same .ini file each time they are installed and take the needed variables from it, while leaving the rest as is.

Edited by Jarno Mikkola
Link to comment

Join the conversation

You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...