Jump to content

Photo

Read ini file > assign variable values


45 replies to this topic

#1 ALIENQuake

ALIENQuake
  • Modders
  • 609 posts
  • Gender:Male
  • Location:Poland

Posted 13 September 2018 - 02:25 PM

Can someone help me to create a code which:
 
- read all content of the file, skip all lines with ; or # as first characters
- put each line to array
- for each line from array, split line via '=', assign first element to the 'variable name' assign second element to the 'variable value'
- set 'variable name' =  'variable value'
 
So far, I can't find any weidu function to read whole file into memory and assign this data to variable without modify the file itself.

Edited by ALIENQuake, 13 September 2018 - 02:29 PM.


#2 DavidW

DavidW
  • Gibberlings
  • 4512 posts
  • Gender:Male

Posted 13 September 2018 - 02:39 PM

I haven't checked it, but probably this:
DEFINE_ACTION_FUNCTION read_in_ini
   STR_VAR filename=""   
   RET_ARRAY ini_contents
BEGIN
  COPY - "%filename%.ini" "%override%" // COPY - means no actual changes to the file
   REPLACE_TEXTUALLY ";.*" ""
   REPLACE_TEXTUALLY "#.*" ""
   REPLACE_TEXTUALLY "=" " "
   READ_2DA_ENTRIES_NOW ini_entries 2
   FOR (i=0;i<ini_entries;i+=1) BEGIN
       READ_2DA_ENTRY_FORMER ini_entries i 0 key
       READ_2DA_ENTRY_FORMER ini_entries i 1 value
       SPRINT $ini_contents("%key%") "%value%"
   END
END
 


#3 ALIENQuake

ALIENQuake
  • Modders
  • 609 posts
  • Gender:Male
  • Location:Poland

Posted 13 September 2018 - 03:18 PM

// "COPY -" means no actual changes to the file

mother of god ... 

 

Simple mod to print those variables:

 

INITest/INITest.tp2

BACKUP ~INITest/backup~
SUPPORT ~~

AUTO_EVAL_STRINGS

BEGIN ~Component 1~ DESIGNATED 1
NO_LOG_RECORD

DEFINE_ACTION_FUNCTION read_in_ini
	STR_VAR filename="INITest/configuration-default"   
	RET_ARRAY ini_content
	BEGIN
		COPY - "%filename%.ini" "%override%" // "COPY -" means no actual changes to the file
		REPLACE_TEXTUALLY ";.*" ""
		REPLACE_TEXTUALLY "#.*" ""
		REPLACE_TEXTUALLY "=" " "
		READ_2DA_ENTRIES_NOW ini_entries 2
		FOR (i=0;i<ini_entries;i+=1) BEGIN
		   READ_2DA_ENTRY_FORMER ini_entries i 0 key
		   READ_2DA_ENTRY_FORMER ini_entries i 1 value
		   SPRINT $ini_content("%key%") "%value%"
		END
	END

LAF read_in_ini END

PRINT "%timer11%"
PRINT "%timer12%"
PRINT "%timer13%"

configuration-default.ini

;timer11
timer11=0
;timer12
timer12=0
;timer13
timer13=0

It doesn't print values probably because I miss something weidu-related, but we are getting close. One more look?


Edited by ALIENQuake, 13 September 2018 - 03:19 PM.


#4 DavidW

DavidW
  • Gibberlings
  • 4512 posts
  • Gender:Male

Posted 13 September 2018 - 03:32 PM

OK:

(1) it's a function, so you don't put the particular ini filename in the function *definition*, you put it in the function *call*.
(2) A function can't return an open-ended list of variables; it can return an associative array where each key is the variable name and its value is the variable, but you'll have to set the variables outside the function environment.

Here's some sample code that does these things (assuming the function has been defined somewhere):

LAF read_in_ini STR_VAR ini="INItest/configuration-default" RET_ARRAY ini_content END

ACTION_PHP_EACH ini_content AS key=>value BEGIN
   OUTER_SPRINT "%key%" "%value%"
END

PRINT "%timer11%"
PRINT "%timer12%"
PRINT "%timer13%"


#5 Gwendolyne

Gwendolyne
  • Members
  • 216 posts
  • Gender:Male
  • Location:France

Posted 14 September 2018 - 12:37 AM

ALIEN, meanwhile I wrote something that seems to work

 

default_configuration ini:

;101_ia.tph traified
; Use 1pp or IWD style female dwarf paperdolls?
; 1 = IWD - 2 = 1pp
1pp_fdwarf=2

;104_core.tph traified
; Do you want to include SoA style loading screens for ToB?
; 1 =  Yes. - 2 = Keep loading screens unchanged.
1pp_gui=1

; Install updated fonts? (may cause issues with languages using different font .BAMs)
; 1 = Yes - 2 = Keep fonts unchanged
1pp_updated_fonts=1

; Use mixed case labels?
; 1 = Yes - 2 = No
1pp_labels=1

; Softer Spell Effects
; WARNING: This component will only work properly with 3D support enabled (alpha blending). Installing this component on BG2 in software rendering mode IS NOT A GOOD IDEA.
; 1 = Yes, install - 2 = No, cancel installation
1pp_softer_spell_effects=1

; Install IWD-style Agannazar's Scorcher or alternate style?
; 1 = IWD style - 2 = BGII alternate
1pp_agannazar_scorcher=2

licorn_name=bla bla

CODE :

DEFINE_ACTION_MACRO GW_ini_array BEGIN
    OUTER_TEXT_SPRINT $GW_ini_contents(~%label%~) ~%value%~
END


DEFINE_PATCH_FUNCTION ~GW_READ_INI_VARIABLE~
    INT_VAR
        start_offset = 0 
    RET
        start_offset
        end_offset
   RET_ARRAY GW_ini_contents
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) label (ofsValue - ofsStart)
            TO_LOWER label
            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 GW_ini_array END
            END
        END
    END

END


DEFINE_ACTION_FUNCTION GW_READ_CONFIG
   STR_VAR GW_filename = ""   
   RET_ARRAY GW_ini_contents
BEGIN

    COPY - ~%MOD_FOLDER%/%GW_filename%.ini~ ~override~
        INSERT_BYTES SOURCE_SIZE (STRING_LENGTH ~%WNL%~)
        WRITE_ASCIIE SOURCE_SIZE ~%WNL%~
        REPLACE_TEXTUALLY ";.*" ""
        REPLACE_TEXTUALLY "#.*" ""

        COUNT_REGEXP_INSTANCES CASE_SENSITIVE ~=~ GWnbvariables
        PATCH_PRINT "GWnbvariables = %GWnbvariables%"
        start_offset = 0
        FOR (i = 0 ; i < GWnbvariables ; ++i) BEGIN
            LPF ~GW_READ_INI_VARIABLE~ INT_VAR start_offset RET end_offset RET_ARRAY GW_ini_contents END
            start_offset = end_offset
        END

END


LAF GW_READ_CONFIG STR_VAR GW_filename = "default_configuration" RET_ARRAY GW_array = GW_ini_contents END

ACTION_PHP_EACH GW_array AS label => value BEGIN
   OUTER_SPRINT EVAL "%label%" "%value%"
   PRINT "VARIABLE %label% = %value%"
   PRINT "label = %label%"
END


PRINT "1pp_fdwarf = %1pp_fdwarf%"
PRINT "1pp_gui = %1pp_gui%"

and the result :
 

VARIABLE 1pp_fdwarf = 2
label = 1pp_fdwarf

VARIABLE 1pp_gui = 1
label = 1pp_gui

VARIABLE 1pp_updated_fonts = 1
label = 1pp_updated_fonts

VARIABLE 1pp_labels = 1
label = 1pp_labels

VARIABLE 1pp_softer_spell_effects = 1
label = 1pp_softer_spell_effects

VARIABLE 1pp_agannazar_scorcher = 2
label = 1pp_agannazar_scorcher

VARIABLE licorn_name  = bla bla
label = licorn_name


1pp_fdwarf = 2
1pp_gui = 1

The code might be optimized, but I will test it with 1pp.


Edited by Gwendolyne, 14 September 2018 - 06:10 AM.

CARPE DIEM...



In progress : Menace sur le Royaume de Diamant Éternel

#6 ALIENQuake

ALIENQuake
  • Modders
  • 609 posts
  • Gender:Male
  • Location:Poland

Posted 14 September 2018 - 01:36 AM

This is what I did using DavidW code and advices:

BACKUP ~GetIniSetVariable/backup~
SUPPORT ~GetIniSetVariable~
VERSION ~0.0.1~

AUTO_EVAL_STRINGS

ALWAYS

    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_TEXTUALLY ";.*" ""
			REPLACE_TEXTUALLY "#.*" ""
			REPLACE_TEXTUALLY "=" " "
			READ_2DA_ENTRIES_NOW ini_entries 2
			FOR ( i = 0 ; i < ini_entries ; i += 1 ) BEGIN
			   READ_2DA_ENTRY_FORMER ini_entries i 0 key
			   READ_2DA_ENTRY_FORMER ini_entries i 1 value
			   SPRINT $ini_content("%key%") "%value%"
			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

END

BEGIN ~Component 1~ DESIGNATED 1000

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

Very simple code, but it does what we need.


Edited by ALIENQuake, 14 September 2018 - 01:53 AM.


#7 Gwendolyne

Gwendolyne
  • Members
  • 216 posts
  • Gender:Male
  • Location:France

Posted 14 September 2018 - 02:11 AM

Are you sure it does work with string variables and that READ_2DA can read game_unicorn="choose a name for your unicorn"?

 

Edit : it DOES NOT WORK. Using your code returns game_unicorn = bla, and not bla bla.

If you want to check string variables, you can't read ini file as a 2da one.


Edited by Gwendolyne, 14 September 2018 - 02:21 AM.

CARPE DIEM...



In progress : Menace sur le Royaume de Diamant Éternel

#8 ALIENQuake

ALIENQuake
  • Modders
  • 609 posts
  • Gender:Male
  • Location:Poland

Posted 14 September 2018 - 02:38 AM

 I wanted to ask about possible differences but what you say is indeed that's true. I will modify my code example.



#9 ALIENQuake

ALIENQuake
  • Modders
  • 609 posts
  • Gender:Male
  • Location:Poland

Posted 14 September 2018 - 03:02 AM

@Gwendolyne Does you code assumes that Ini keys are case insensitive?



#10 ALIENQuake

ALIENQuake
  • Modders
  • 609 posts
  • Gender:Male
  • Location:Poland

Posted 14 September 2018 - 03:39 AM

You code skips last key=value from ini if there is no end line character/EOL. Can you check it please?



#11 Gwendolyne

Gwendolyne
  • Members
  • 216 posts
  • Gender:Male
  • Location:France

Posted 14 September 2018 - 03:42 AM

1. No, but

READ_ASCII (ofsStart) label (ofsValue - ofsStart)
TO_LOWER label

might work.

 

2. Will check.


Edited by Gwendolyne, 14 September 2018 - 03:46 AM.

CARPE DIEM...



In progress : Menace sur le Royaume de Diamant Éternel

#12 ALIENQuake

ALIENQuake
  • Modders
  • 609 posts
  • Gender:Male
  • Location:Poland

Posted 14 September 2018 - 04:06 AM

Since we we treat keys as case insensitive, variable count should be counted by unique keys, not '=' characters. But that only for debugging etc.



#13 Gwendolyne

Gwendolyne
  • Members
  • 216 posts
  • Gender:Male
  • Location:France

Posted 14 September 2018 - 04:28 AM

Try the modified code. Tested with my config-default without EOF blank lines and sensitive variables (1PP_xxx, 1pp_AVehD...). Seems to work and returns 1pp_xxx, 1pp_avend...


Edited by Gwendolyne, 14 September 2018 - 04:29 AM.

CARPE DIEM...



In progress : Menace sur le Royaume de Diamant Éternel

#14 ALIENQuake

ALIENQuake
  • Modders
  • 609 posts
  • Gender:Male
  • Location:Poland

Posted 14 September 2018 - 05:24 AM

I'm keep getting 

INSERT_BYTES out of bounds - file is long 34, point given is 61
ERROR: [GetIniSetVariable/default_configuration.ini] -> [override] Patching Failed (COPY) (Failure("INSERT_BYTES out of bounds"))

error :/



#15 Gwendolyne

Gwendolyne
  • Members
  • 216 posts
  • Gender:Male
  • Location:France

Posted 14 September 2018 - 05:28 AM

Can you attach your config file?


CARPE DIEM...



In progress : Menace sur le Royaume de Diamant Éternel



Reply to this topic



  


0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users