AL|EN Posted September 13, 2018 Share Posted September 13, 2018 (edited) 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 September 13, 2018 by ALIENQuake Quote Link to comment
DavidW Posted September 13, 2018 Share Posted September 13, 2018 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 Quote Link to comment
AL|EN Posted September 13, 2018 Author Share Posted September 13, 2018 (edited) // "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 September 13, 2018 by ALIENQuake Quote Link to comment
DavidW Posted September 13, 2018 Share Posted September 13, 2018 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%" Quote Link to comment
Gwendolyne Posted September 14, 2018 Share Posted September 14, 2018 (edited) 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 September 14, 2018 by Gwendolyne Quote Link to comment
AL|EN Posted September 14, 2018 Author Share Posted September 14, 2018 (edited) 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 September 14, 2018 by ALIENQuake Quote Link to comment
Gwendolyne Posted September 14, 2018 Share Posted September 14, 2018 (edited) 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 September 14, 2018 by Gwendolyne Quote Link to comment
AL|EN Posted September 14, 2018 Author Share Posted September 14, 2018 I wanted to ask about possible differences but what you say is indeed that's true. I will modify my code example. Quote Link to comment
AL|EN Posted September 14, 2018 Author Share Posted September 14, 2018 @Gwendolyne Does you code assumes that Ini keys are case insensitive? Quote Link to comment
AL|EN Posted September 14, 2018 Author Share Posted September 14, 2018 You code skips last key=value from ini if there is no end line character/EOL. Can you check it please? Quote Link to comment
Gwendolyne Posted September 14, 2018 Share Posted September 14, 2018 (edited) 1. No, but READ_ASCII (ofsStart) label (ofsValue - ofsStart) TO_LOWER label might work. 2. Will check. Edited September 14, 2018 by Gwendolyne Quote Link to comment
AL|EN Posted September 14, 2018 Author Share Posted September 14, 2018 Since we we treat keys as case insensitive, variable count should be counted by unique keys, not '=' characters. But that only for debugging etc. Quote Link to comment
Gwendolyne Posted September 14, 2018 Share Posted September 14, 2018 (edited) 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 September 14, 2018 by Gwendolyne Quote Link to comment
AL|EN Posted September 14, 2018 Author Share Posted September 14, 2018 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 :/ Quote Link to comment
Gwendolyne Posted September 14, 2018 Share Posted September 14, 2018 Can you attach your config file? Quote Link to comment
Recommended Posts
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.