AutoHotkey Community

It is currently May 27th, 2012, 8:23 am

All times are UTC [ DST ]




Post new topic Reply to topic  [ 12 posts ] 
Author Message
PostPosted: May 27th, 2011, 11:35 pm 
Offline
User avatar

Joined: December 30th, 2009, 10:30 pm
Posts: 160
Location: Worcester, Massachusetts
IniRead() - Read some/all values from an ini file

Warning: code has been updated more recently than documentation. So stuff might not work as documented. See comments in code :(



    Ini files are often used to store some general configuration settings for a program. The settings must be read from the ini file each time the program loads. Subsequently, however, the ini file is only accessed when a value is changed by the user. (This can be avoided by forcing manual editing of ini file values, e.g. with notepad.exe.)

    IniRead() aims to take care of the initial loading of settings with a single function call. It does this by assuming that the structure of your ini file mirrors variables that store settings information within your script. For my scripts at least, this is usually the case.
ImageImageImage


ImageImageImageImageImageImageIniRead(_IniFile="", _Options="")


    Usage: IniRead() reads an ini file and translates each key into an AutoHotkey variable initialized with the given value. Basically it is an alternate way to initialize variables at the top of your script.
    You will probably be using IniRead() only once, inside your script's autorun section. The exception would be if there are multiple sections of the .ini file that you want to read at different times or under different conditions
    Code:
    IniRead("MyApp.ini", "sSettings") ; reads the [Settings] section from the ini file MyApp.ini into the script's memory.

    The function returns the number of keys read, or a string containing each key read if the d option is used. This can be used to check if all the necessary values were read.
    Code:
    DesiredKeys = Color`nHeight`nHotkey`nTimeout`nTitle`nWidth ; in alphabetical order
    FoundKeys := IniRead("MyApp.ini", "sSettings d") ; using d option, which defaults to a newline (`n)
    Sort, FoundKeys ; sorts the list of keys so the order they are found in the file won't matter
    If (FoundKeys <> DesiredKeys) ; if the list of keys that were found does not match the list given then display an error
       MsgBox, Some of the settings were missing!
ImageImageImage

Parameters:
I've changed the parameters but haven't updated this forum post. Look in the comments at the top of the code for more information.
  • IniFile: The file to read. If this parameter is blank the function will use the first .ini file alphabetically in the working directory.
  • Options: A space-delimited string in which you can indicate additional options, such as you see in the GUI command’s Options parameter. More info here: http://www.autohotkey.com/forum/topic77824.html.
    • s - Section: Section to use out of whole file. Specify an asterisk (*) to only read the first section. Leave blank to read the entire file
    • p - Prepend: Prepend this string to the variables. An asterisk (*) will be replaced by the current section name
    • d - Delimited List: Instead of returning the number of keys read, the function will return a string of all variables created (i.e. all keys read with any additional modifications made by _r or _p) delimited by the indicated character
    • r - Replace Bad Chars: One or more characters in key or section names that are unsuitable for AutoHotkey variable names will be replaced by this character
    • e - Error Behavior: Indicate/omit any combination of f/s/o/r to display an error dialog/exit silently if the ini file cannot be found/the desired section cannot be found/a preexisting variable will be overwritten/r will replace any inappropriate characters

ImageImageImage

Why use IniRead()

    There are many advantages to storing user settings in an ini file instead of inside the AutoHotkey code:
    • Values can be edited even if the script is compiled
    • Tampering with the file cannot break AutoHotkey code
    • An ini file is a familiar format for storing settings information
    IniRead() merely aims to simplify the process of moving configuration settings into ini files. Normally this process requires the addition of many lines of AutoHotkey code; with IniRead() it should only take one short line.
ImageImageImage

Example:

    The below screenshot demonstrates the results of IniRead(). From right to left you can see the script that was executed, the contents of the ini file that script read, and the script's global variables after calling IniRead() as reported by ListVars. Notice the p option was used; otherwise duplicate variables would have been created.

      Image
ImageImageImage

Code:
Code:
IniRead(_IniFile="", _Options="") ;http://www.autohotkey.com/forum/topic72442.html
{
   Local _Reading, _Prepend, _Entries, _nSec, _nKey, _t := 0, _t1, _t2, _Literal := """", _Commands := "sa|ka|sl|sr|p|d|r|e"
   ;---------------------------------OPTIONS:-----------------------------------------------------------
   ; INITIAL                 DEFAULT                 NAME                    ABOUT
   , _sa := "",              _sa_def := "Sections*"  ;sa = Section Array     Creates the specified pseudoarray containing each section header that was read. An asterisk (*) will be replaced by the item number, otherwise it will be appended to the end. Item 0 will contain the size of the ray. Only applicable if all sections are being read (s = "")
   , _ka := "",              _ka_def := "Keys*"      ;ka = Key Array         Same as above but for individual keys. Similar to the d option
   , _sl := "",              _sl_def := "*"          ;sl = Section (Literal) Section to use out of whole file. If multiple sections have the same name the first will be used. Specify an asterisk (*) to only read the first section. Leave blank to read the entire file
   , _sr := "",              _sr_def := ""           ;sr = Section (RegEx)   Same as above but will extract from all sections whose names match the given regular expression
   , _p := "",               _p_def := "*_"          ;p = Prepend            Prepend this string to the variables. An asterisk (*) will be replaced by the current section name
   , _d := "",               _d_def := "`n"          ;d = Delimited List     Instead of returning the number of keys read, the function will return a string of all variables created (i.e. all keys read with any additional modifications made by _r or _p) delimited by the indicated character(s)
   , _r := "",               _r_def := "_"           ;r = Replace Bad Chars  One or more characters in key or section names that are unsuitable for AutoHotkey variable names will be replaced by this character
   , _e := "fso",            _e_def := ""            ;e = Error Behavior     Indicate/omit any combination of f/s/o/r to display an error dialog/exit silently if the ini file cannot be found/the desired section cannot be found/a preexisting variable will be overwritten/r will replace any inappropriate characters
   ;----------------------------------------------------------------------------------------------------
   While (_t := RegExMatch(_Options, "i)\s*\K(?P<1>" _Commands ")(?P<2>" _Literal "(?:[^" _Literal "]|" _Literal _Literal ")*" _Literal "(?= |$)|[^ ]*)", _t, _t + StrLen(_t1 _t2) + 1))
      If (_t2 <> "") {
         If (SubStr(_t2, 1, 1) = _Literal) and (StrLen(_t2) > 1) and (SubStr(_t2, 0, 1) = _Literal) and (_t2 := SubStr(_t2, 2, -1))
            StringReplace, _t2, _t2, %_Literal%%_Literal%, %_Literal%, All
         _%_t1% := _t2
      } Else
         _%_t1% := _%_t1%_def
   If RegExMatch(_r, "[^\w#@$?]") or RegExMatch(_p, "[^\w*#@$?]") {
      MsgBox, 262160, %A_ScriptName% - %A_ThisFunc%(): Error, Neither the p nor r options may contain characters that are not alloewd in AutoHotkey variable names.
      Return
   }
   _Entries := _d = "" ? 0 : _d
   If !InStr(_p, "*")
      _Prepend := _p
   If (_IniFile = "") {
      Loop, *.ini
      {
         _IniFile := A_LoopFileFullPath
         Break
      }
      If (_IniFile = "") {
         If InStr(_e, "f")
            MsgBox, 262160, %A_ScriptName% - %A_ThisFunc%(): Error, No .ini file found in working directory.
         Return
      }
   } Else If !FileExist(_IniFile) {
      If InStr(_e, "f")
         MsgBox, 262160, %A_ScriptName% - %A_ThisFunc%(): Error, File "%_IniFile%" not found or does not exist.
      Return
   }
   If (_sl <> "") {
      If (_sr <> "") {
         MsgBox, 262160, %A_ScriptName% - %A_ThisFunc%(): Error, Please enter either a sl (Section - Literal) or sr (Section - RegEx) value, not both.
         Return
      }
   } Else If (_sr = "")
      _Reading := True
   If (_sa <> "") {
      If RegExMatch(_sa, "[^\w#@$?*]")
         _sa := RegExReplace(_sa, "[^\w#@$?*]")
      If !InStr(_sa, "*")
         _sa .= "*"
   }
   If (_ka <> "") {
      If RegExMatch(_ka, "[^\w#@$?*]")
         _ka := RegExReplace(_ka, "[^\w#@$?*]")
      If !InStr(_ka, "*")
         _ka .= "*"
      If (_ka = _sa) {
         MsgBox, 262160, %A_ScriptName% - %A_ThisFunc%(): Error, The section output array (sa) and key output array (ka) cannot be the same.
         Return
      }
   }
   Loop, Read, %_IniFile%
   {
      _t = %A_LoopReadLine%
      If (SubStr(_t, 1, 1) = "[") and (SubStr(_t, 0, 1) = "]") {
         If (_sr <> "")
            _Reading := RegExMatch(SubStr(_t, 2, -1), _sr) ? True : False
         Else If (_sl <> "")
            If _Reading
               Break
            Else If (SubStr(_t, 2, -1) = _sl) or (_sl = "*")
               _Reading := True
         If !_Reading
            Continue
         If InStr(_p, "*") {
            StringReplace, _Prepend, _p, *, % RegExReplace(SubStr(_t, 2, -1), "[^\w#_t$?]+", _r, _t2), All
            If _t2 and InStr(_e, "r") {
               MsgBox, 262420, %A_ScriptName% - %A_ThisFunc%(): Error, A section name contained characters not allowed in AutoHotkey variable names. Replace these characters with "%_r%" ?
               IfMsgBox NO
                  Return
            }
         }
         If _sa {
            _nSec += 1
            StringReplace, _t1, _sa, *, %_nSec%, All
            %_t1% := SubStr(_t, 2, -1)
         }
      } Else If _Reading and InStr(_t, "=") {
         _t1 := RegExReplace(SubStr(_t, 1, InStr(_t, "=") - 1), "[^\w#_t$?]+", _r, _t2)
         If _t2 and InStr(_e, "r") {
            MsgBox, 262420, %A_ScriptName% - %A_ThisFunc%(): Error, A key name contained characters not allowed in AutoHotkey variable names. Replace these characters with "%_r%" ?
            IfMsgBox NO
               Return
         }
         If (%_Prepend%%_t1% <> "") and InStr(_e, "o") {
            MsgBox, 262420, %A_ScriptName% - %A_ThisFunc%(): Error, The variable "%_Prepend%%_t1%" has already been assigned either by IniRead() or elsewhere in the script. Overwrite it with the value from the .ini file?`nTo avoid this error you can try using the p or s options
            IfMsgBox NO
               Return
         }
         %_Prepend%%_t1% := SubStr(_t, InStr(_t, "=") + 1)
         If (_d <> "") {
            StringReplace, _Entries, _Entries, %_d%%_Prepend%%_t1%%_d%, %_d%, All
            _Entries .= _Prepend _t1 _d
         } Else
            _Entries += 1
         If _ka {
            _nKey += 1
            StringReplace, _t, _ka, *, %_nKey%, All
            %_t% := _Prepend _t1
         }
      }
   }
   If (_sl <> "") and !_Reading and InStr(_e, "s")
      MsgBox, 262160, %A_ScriptName% - %A_ThisFunc%(): Error, Section "%_sl%" was not found in ini file "%_IniFile%", therefore no variables were assigned.
   If _sa {
      StringReplace, _t, _sa, *, 0, All
      %_t% := _nSec
   }
   If _ka {
      StringReplace, _t, _ka, *, 0, All
      %_t% := _nKey
   }
   Return _d = "" ? _Entries : SubStr(_Entries, 2, -1)
}




~ Created with Quick Functions for Forums by berban ~

_________________
★★★ Email me at berban at aim full stop com ★★★


Last edited by berban on March 25th, 2012, 10:30 pm, edited 11 times in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 4th, 2011, 9:28 am 
I made a similiar function globalsFromIni http://www.autohotkey.com/forum/topic27 ... alsfromini


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: June 5th, 2011, 8:44 am 
Offline
User avatar

Joined: December 30th, 2009, 10:30 pm
Posts: 160
Location: Worcester, Massachusetts
Yeah, I figured that was going to be the case :P AutoHotkey really needs a better way to categorize scripts. I know there is the wiki, and maybe I should use that more. But it is not easy to see exactly what's out there and what's been done when you would like to know.

_________________
★★★ Email me at berban at aim full stop com ★★★


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 5th, 2011, 8:59 am 
Offline

Joined: November 7th, 2006, 9:47 pm
Posts: 1934
Location: Germany
That is true, not only for AutoHotkey. For this reason, I started a project (currently freezed state, somewhat outdated and only AHK_Basic libraries) collecting such functions. May be you want throw an eye on it (hope its correct in English^^).

_________________
{1:"ahkstdlib", 2:"my libs", 3:"my apps", 4:"my license"}
--> Don't feed the troll! <--


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 6th, 2011, 7:44 pm 
Offline

Joined: March 16th, 2011, 6:12 pm
Posts: 172
Location: Worcester, Massachusetts
Awesome! Thanks I will bookmark that :)

_________________
★★★ Email me at berban at aim full stop com ★★★


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 7th, 2011, 12:13 am 
Offline
User avatar

Joined: May 18th, 2010, 3:10 pm
Posts: 1179
Location: Sweden
Tuncay wrote:
That is true, not only for AutoHotkey. For this reason, I started a project (currently freezed state, somewhat outdated and only AHK_Basic libraries) collecting such functions. May be you want throw an eye on it (hope its correct in English^^).


That's funny. I don't think it's appropiate english (maybe?), but in Sweden we literally say the same too. Kasta ett öga på det. Means something like "watch it" or "make sure an eye looks at it a bit".

Anyway, your StdLib is great, and we need to endorse either that or any successor.

_________________
~sumon Appifyer AHK Nova halted Recommended: AHK_L (Why?)


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 7th, 2011, 2:13 am 
Offline

Joined: March 16th, 2011, 6:12 pm
Posts: 172
Location: Worcester, Massachusetts
Tuncay wrote:
May be you want throw an eye on it.


In American english:

may be :arrow: maybe
you :arrow: you'll, you will - you need another verb in there
throw an eye on it :arrow: I think this construct sounds very interesting, although if you're shooting to sound natural, I'd say "keep an eye on it" instead. Very similar as you can see.

How I would optimally structure the sentence:
You might want to keep an eye on it.

;)

_________________
★★★ Email me at berban at aim full stop com ★★★


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 7th, 2011, 2:36 am 
Offline

Joined: November 7th, 2006, 9:47 pm
Posts: 1934
Location: Germany
wow :D
berban_, very good explained. Thank you. Like sumon wrote, I just literally translated and it sounded somewhat correct and understandable, which failed.

sumon, if there is an interest on it, I make an update. Everyone is welcome to make a fork on its own. The license of my work (not the third party libs) allows modifications. Next version will have a less strict license, if you care.

_________________
{1:"ahkstdlib", 2:"my libs", 3:"my apps", 4:"my license"}
--> Don't feed the troll! <--


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 7th, 2011, 3:29 am 
Offline

Joined: December 26th, 2010, 7:40 pm
Posts: 4172
Location: Awesometown, USA
very *well* explained :P
Oh well, I'm not one to pick on grammar.

I'm also interested in stdlib.

_________________
Autofire, AutoClick, Toggle, SpamWindow Control Tools
Recommended: AutoHotkey_L


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 7th, 2011, 6:07 am 
Offline

Joined: March 16th, 2011, 6:12 pm
Posts: 172
Location: Worcester, Massachusetts
Lets have a cage fight for the rights to StdLib

_________________
★★★ Email me at berban at aim full stop com ★★★


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 7th, 2011, 10:12 am 
Just to clarify, everyone have already the right to make changes and to release. You can use current one (or next one) as a starting point if you like.


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: February 3rd, 2012, 7:37 am 
Offline

Joined: March 16th, 2011, 6:12 pm
Posts: 172
Location: Worcester, Massachusetts
I had fixed this up this a while back but I just now got around to updating the forum posting :)
If anyone was/will be using this script, I hope you will find the new version much more user friendly!

_________________
★★★ Email me at berban at aim full stop com ★★★


Report this post
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 12 posts ] 

All times are UTC [ DST ]


Who is online

Users browsing this forum: AndyJenk, Aravind, Google Feedfetcher, Stigg and 10 guests


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group