kjeron Posted September 14, 2018 Share Posted September 14, 2018 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 Quote Link to comment
Sam. Posted September 14, 2018 Share Posted September 14, 2018 Isn't it more elegant to format your INI file as valid WeiDU variable assignments and INCLUDE it? Quote Link to comment
AL|EN Posted September 14, 2018 Author Share Posted September 14, 2018 Can you attach your config file? ;timer11 timer11=0 ;timer12 timer12=0 ;timer13 timer13=0 Same as 3rd post. Quote Link to comment
DavidW Posted September 14, 2018 Share Posted September 14, 2018 You can do that, but you will have to copy it somewhere and strip out the comments. (Also, elegance is in the eye of the beholder; I prefer a more rigid separation of code and data, where I can get it.) Quote Link to comment
AL|EN Posted September 14, 2018 Author Share Posted September 14, 2018 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 Quote Link to comment
Gwendolyne Posted September 14, 2018 Share Posted September 14, 2018 (edited) 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/endTO_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 September 14, 2018 by Gwendolyne Quote Link to comment
AL|EN Posted September 14, 2018 Author Share Posted September 14, 2018 (edited) 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 @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 September 14, 2018 by ALIENQuake Quote Link to comment
DavidW Posted September 14, 2018 Share Posted September 14, 2018 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.) Quote Link to comment
kjeron Posted September 14, 2018 Share Posted September 14, 2018 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. Quote Link to comment
AL|EN Posted September 14, 2018 Author Share Posted September 14, 2018 This one is breaking format rules: text =value key cannot have spaces before '='. However next one is correct: text=value spaces before key should be ignored, so key name should be 'text'. Quote Link to comment
AL|EN Posted September 14, 2018 Author Share Posted September 14, 2018 (edited) 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 October 1, 2018 by ALIENQuake Quote Link to comment
subtledoctor Posted September 14, 2018 Share Posted September 14, 2018 (edited) 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 September 14, 2018 by subtledoctor Quote Link to comment
DavidW Posted September 14, 2018 Share Posted September 14, 2018 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... Quote Link to comment
subtledoctor Posted September 14, 2018 Share Posted September 14, 2018 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. Quote Link to comment
Jarno Mikkola Posted September 14, 2018 Share Posted September 14, 2018 (edited) 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 September 14, 2018 by Jarno Mikkola 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.